auction-ruby-base 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +15 -0
- data/.yardopts +8 -0
- data/CHANGELOG.md +58 -0
- data/CONTRIBUTING.md +48 -0
- data/Gemfile +15 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +202 -0
- data/README.md +83 -0
- data/Rakefile +4 -0
- data/auction-ruby-base.gemspec +35 -0
- data/examples/create_account.rb +26 -0
- data/examples/low_level_transaction_post.rb +46 -0
- data/examples/mid_level_transaction_post.rb +33 -0
- data/examples/non_native_payment.rb +60 -0
- data/examples/offer.rb +75 -0
- data/examples/transaction_merge.rb +23 -0
- data/generated/stellar-base-generated.rb +174 -0
- data/generated/stellar/account_entry.rb +55 -0
- data/generated/stellar/account_entry/ext.rb +24 -0
- data/generated/stellar/account_flags.rb +31 -0
- data/generated/stellar/account_merge_result.rb +26 -0
- data/generated/stellar/account_merge_result_code.rb +30 -0
- data/generated/stellar/affirm_fail_op.rb +22 -0
- data/generated/stellar/affirm_fail_result.rb +25 -0
- data/generated/stellar/affirm_fail_result_code.rb +22 -0
- data/generated/stellar/affirm_pass_op.rb +24 -0
- data/generated/stellar/affirm_pass_result.rb +25 -0
- data/generated/stellar/affirm_pass_result_code.rb +22 -0
- data/generated/stellar/allow_trust_op.rb +38 -0
- data/generated/stellar/allow_trust_op/asset.rb +33 -0
- data/generated/stellar/allow_trust_result.rb +25 -0
- data/generated/stellar/allow_trust_result_code.rb +31 -0
- data/generated/stellar/asset.rb +47 -0
- data/generated/stellar/asset/alpha_num12.rb +22 -0
- data/generated/stellar/asset/alpha_num4.rb +22 -0
- data/generated/stellar/asset_type.rb +24 -0
- data/generated/stellar/auth.rb +20 -0
- data/generated/stellar/auth_cert.rb +22 -0
- data/generated/stellar/authenticated_message.rb +32 -0
- data/generated/stellar/authenticated_message/v0.rb +24 -0
- data/generated/stellar/bucket_entry.rb +28 -0
- data/generated/stellar/bucket_entry_type.rb +22 -0
- data/generated/stellar/change_trust_op.rb +22 -0
- data/generated/stellar/change_trust_result.rb +25 -0
- data/generated/stellar/change_trust_result_code.rb +31 -0
- data/generated/stellar/claim_offer_atom.rb +33 -0
- data/generated/stellar/create_account_op.rb +20 -0
- data/generated/stellar/create_account_result.rb +25 -0
- data/generated/stellar/create_account_result_code.rb +32 -0
- data/generated/stellar/create_bid_op.rb +20 -0
- data/generated/stellar/create_bid_result.rb +25 -0
- data/generated/stellar/create_bid_result_code.rb +22 -0
- data/generated/stellar/create_lot_op.rb +46 -0
- data/generated/stellar/create_lot_result.rb +25 -0
- data/generated/stellar/create_lot_result_code.rb +22 -0
- data/generated/stellar/create_passive_offer_op.rb +24 -0
- data/generated/stellar/crypto_key_type.rb +20 -0
- data/generated/stellar/curve25519_public.rb +18 -0
- data/generated/stellar/curve25519_secret.rb +18 -0
- data/generated/stellar/decorated_signature.rb +20 -0
- data/generated/stellar/dont_have.rb +20 -0
- data/generated/stellar/envelope_type.rb +24 -0
- data/generated/stellar/error.rb +20 -0
- data/generated/stellar/error_code.rb +28 -0
- data/generated/stellar/hello.rb +34 -0
- data/generated/stellar/hmac_sha256_key.rb +18 -0
- data/generated/stellar/hmac_sha256_mac.rb +18 -0
- data/generated/stellar/inflation_payout.rb +20 -0
- data/generated/stellar/inflation_result.rb +26 -0
- data/generated/stellar/inflation_result_code.rb +24 -0
- data/generated/stellar/ip_addr_type.rb +22 -0
- data/generated/stellar/ledger_entry.rb +52 -0
- data/generated/stellar/ledger_entry/data.rb +49 -0
- data/generated/stellar/ledger_entry/ext.rb +24 -0
- data/generated/stellar/ledger_entry_change.rb +35 -0
- data/generated/stellar/ledger_entry_change_type.rb +26 -0
- data/generated/stellar/ledger_entry_type.rb +32 -0
- data/generated/stellar/ledger_header.rb +69 -0
- data/generated/stellar/ledger_header/ext.rb +24 -0
- data/generated/stellar/ledger_header_history_entry.rb +33 -0
- data/generated/stellar/ledger_header_history_entry/ext.rb +24 -0
- data/generated/stellar/ledger_key.rb +87 -0
- data/generated/stellar/ledger_key/account.rb +20 -0
- data/generated/stellar/ledger_key/lot.rb +22 -0
- data/generated/stellar/ledger_key/message.rb +22 -0
- data/generated/stellar/ledger_key/offer.rb +22 -0
- data/generated/stellar/ledger_key/participant.rb +22 -0
- data/generated/stellar/ledger_key/proof.rb +22 -0
- data/generated/stellar/ledger_key/trust_line.rb +22 -0
- data/generated/stellar/ledger_scp_messages.rb +20 -0
- data/generated/stellar/ledger_upgrade.rb +31 -0
- data/generated/stellar/ledger_upgrade_type.rb +24 -0
- data/generated/stellar/lot_branch.rb +21 -0
- data/generated/stellar/lot_entry.rb +64 -0
- data/generated/stellar/lot_entry/ext.rb +24 -0
- data/generated/stellar/lot_type.rb +21 -0
- data/generated/stellar/manage_offer_effect.rb +24 -0
- data/generated/stellar/manage_offer_op.rb +28 -0
- data/generated/stellar/manage_offer_result.rb +26 -0
- data/generated/stellar/manage_offer_result_code.rb +50 -0
- data/generated/stellar/manage_offer_success_result.rb +34 -0
- data/generated/stellar/manage_offer_success_result/offer.rb +30 -0
- data/generated/stellar/memo.rb +38 -0
- data/generated/stellar/memo_type.rb +28 -0
- data/generated/stellar/message_entry.rb +38 -0
- data/generated/stellar/message_entry/ext.rb +24 -0
- data/generated/stellar/message_type.rb +51 -0
- data/generated/stellar/offer_entry.rb +49 -0
- data/generated/stellar/offer_entry/ext.rb +24 -0
- data/generated/stellar/offer_entry_flags.rb +21 -0
- data/generated/stellar/operation.rb +65 -0
- data/generated/stellar/operation/body.rb +88 -0
- data/generated/stellar/operation_meta.rb +18 -0
- data/generated/stellar/operation_result.rb +67 -0
- data/generated/stellar/operation_result/tr.rb +89 -0
- data/generated/stellar/operation_result_code.rb +25 -0
- data/generated/stellar/operation_type.rb +52 -0
- data/generated/stellar/participant_entry.rb +39 -0
- data/generated/stellar/participant_entry/ext.rb +24 -0
- data/generated/stellar/participant_state.rb +25 -0
- data/generated/stellar/path_payment_op.rb +32 -0
- data/generated/stellar/path_payment_result.rb +38 -0
- data/generated/stellar/path_payment_result/success.rb +22 -0
- data/generated/stellar/path_payment_result_code.rb +47 -0
- data/generated/stellar/payment_op.rb +22 -0
- data/generated/stellar/payment_result.rb +25 -0
- data/generated/stellar/payment_result_code.rb +41 -0
- data/generated/stellar/peer_address.rb +33 -0
- data/generated/stellar/peer_address/ip.rb +29 -0
- data/generated/stellar/price.rb +20 -0
- data/generated/stellar/proof_entry.rb +42 -0
- data/generated/stellar/proof_entry/ext.rb +24 -0
- data/generated/stellar/provide_proof_op.rb +24 -0
- data/generated/stellar/provide_proof_result.rb +25 -0
- data/generated/stellar/provide_proof_result_code.rb +22 -0
- data/generated/stellar/public_key.rb +23 -0
- data/generated/stellar/register_participant_op.rb +22 -0
- data/generated/stellar/register_participant_result.rb +25 -0
- data/generated/stellar/register_participant_result_code.rb +22 -0
- data/generated/stellar/scp_ballot.rb +20 -0
- data/generated/stellar/scp_envelope.rb +20 -0
- data/generated/stellar/scp_history_entry.rb +23 -0
- data/generated/stellar/scp_history_entry_v0.rb +20 -0
- data/generated/stellar/scp_nomination.rb +22 -0
- data/generated/stellar/scp_quorum_set.rb +22 -0
- data/generated/stellar/scp_statement.rb +58 -0
- data/generated/stellar/scp_statement/pledges.rb +63 -0
- data/generated/stellar/scp_statement/pledges/confirm.rb +30 -0
- data/generated/stellar/scp_statement/pledges/externalize.rb +26 -0
- data/generated/stellar/scp_statement/pledges/prepare.rb +32 -0
- data/generated/stellar/scp_statement_type.rb +26 -0
- data/generated/stellar/send_message_op.rb +22 -0
- data/generated/stellar/send_message_result.rb +25 -0
- data/generated/stellar/send_message_result_code.rb +22 -0
- data/generated/stellar/set_options_op.rb +41 -0
- data/generated/stellar/set_options_result.rb +25 -0
- data/generated/stellar/set_options_result_code.rb +40 -0
- data/generated/stellar/signer.rb +20 -0
- data/generated/stellar/simple_payment_result.rb +22 -0
- data/generated/stellar/stellar_message.rb +74 -0
- data/generated/stellar/stellar_value.rb +41 -0
- data/generated/stellar/stellar_value/ext.rb +24 -0
- data/generated/stellar/threshold_indexes.rb +26 -0
- data/generated/stellar/time_bounds.rb +20 -0
- data/generated/stellar/transaction.rb +50 -0
- data/generated/stellar/transaction/ext.rb +24 -0
- data/generated/stellar/transaction_envelope.rb +20 -0
- data/generated/stellar/transaction_history_entry.rb +33 -0
- data/generated/stellar/transaction_history_entry/ext.rb +24 -0
- data/generated/stellar/transaction_history_result_entry.rb +33 -0
- data/generated/stellar/transaction_history_result_entry/ext.rb +24 -0
- data/generated/stellar/transaction_meta.rb +23 -0
- data/generated/stellar/transaction_result.rb +43 -0
- data/generated/stellar/transaction_result/ext.rb +24 -0
- data/generated/stellar/transaction_result/result.rb +30 -0
- data/generated/stellar/transaction_result_code.rb +45 -0
- data/generated/stellar/transaction_result_pair.rb +20 -0
- data/generated/stellar/transaction_result_set.rb +18 -0
- data/generated/stellar/transaction_set.rb +20 -0
- data/generated/stellar/trust_line_entry.rb +41 -0
- data/generated/stellar/trust_line_entry/ext.rb +24 -0
- data/generated/stellar/trust_line_flags.rb +21 -0
- data/lib/stellar-base.rb +33 -0
- data/lib/stellar/account_flags.rb +28 -0
- data/lib/stellar/asset.rb +69 -0
- data/lib/stellar/base.rb +1 -0
- data/lib/stellar/base/version.rb +5 -0
- data/lib/stellar/convert.rb +32 -0
- data/lib/stellar/key_pair.rb +112 -0
- data/lib/stellar/networks.rb +45 -0
- data/lib/stellar/operation.rb +384 -0
- data/lib/stellar/path_payment_result.rb +17 -0
- data/lib/stellar/price.rb +32 -0
- data/lib/stellar/thresholds.rb +39 -0
- data/lib/stellar/transaction.rb +205 -0
- data/lib/stellar/transaction_envelope.rb +32 -0
- data/lib/stellar/util/continued_fraction.rb +96 -0
- data/lib/stellar/util/strkey.rb +43 -0
- data/spec/lib/stellar/account_flags_spec.rb +19 -0
- data/spec/lib/stellar/asset_spec.rb +45 -0
- data/spec/lib/stellar/convert_spec.rb +61 -0
- data/spec/lib/stellar/key_pair_spec.rb +238 -0
- data/spec/lib/stellar/networks_spec.rb +77 -0
- data/spec/lib/stellar/operation_spec.rb +13 -0
- data/spec/lib/stellar/path_payment_result_spec.rb +95 -0
- data/spec/lib/stellar/price_spec.rb +34 -0
- data/spec/lib/stellar/thresholds_spec.rb +62 -0
- data/spec/lib/stellar/transaction_envelope_spec.rb +93 -0
- data/spec/lib/stellar/transaction_spec.rb +83 -0
- data/spec/lib/stellar/util/strkey_spec.rb +46 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/matchers/be_strkey.rb +9 -0
- data/spec/support/matchers/eq_bytes.rb +5 -0
- data/spec/support/matchers/have_length.rb +5 -0
- data/tasks/rspec.rake +6 -0
- data/tasks/travis.rake +1 -0
- data/tasks/xdr.rake +50 -0
- data/xdr/Stellar-SCP.x +86 -0
- data/xdr/Stellar-ledger-entries.x +351 -0
- data/xdr/Stellar-ledger.x +288 -0
- data/xdr/Stellar-overlay.x +146 -0
- data/xdr/Stellar-transaction.x +936 -0
- data/xdr/Stellar-types.x +55 -0
- metadata +495 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Stellar::Price, "#from_f" do
|
|
4
|
+
subject{ Stellar::Price }
|
|
5
|
+
let(:seed){ 225571644875421139403973254661022579608 } #generated using Random.new
|
|
6
|
+
let(:random){ Random.new(seed) }
|
|
7
|
+
let(:iterations){ ENV["SMOKE_ITERATIONS"].present? ? ENV["SMOKE_ITERATIONS"].to_i : 2000}
|
|
8
|
+
|
|
9
|
+
it "withstands a random smoke test" do
|
|
10
|
+
iterations.times do |i|
|
|
11
|
+
expected = random.rand
|
|
12
|
+
actual_p = subject.from_f(expected)
|
|
13
|
+
actual = actual_p.to_f
|
|
14
|
+
|
|
15
|
+
expect(actual).to be_within(0.000000001).of(actual)
|
|
16
|
+
expect(actual_p.n).to be <= Stellar::Price::MAX_PRECISION
|
|
17
|
+
expect(actual_p.d).to be <= Stellar::Price::MAX_PRECISION
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
it "works with bigdecimal" do
|
|
22
|
+
whole = random.rand(1_000_000)
|
|
23
|
+
fractional = random.rand(10_000_000) # seven significant digits available for fractional
|
|
24
|
+
|
|
25
|
+
expected = BigDecimal.new("#{whole}.#{fractional}")
|
|
26
|
+
actual_p = subject.from_f(expected)
|
|
27
|
+
actual = BigDecimal.new(actual_p.n) / BigDecimal.new(actual_p.d)
|
|
28
|
+
|
|
29
|
+
expect(actual).to be_within(BigDecimal.new("0.000000001")).of(actual)
|
|
30
|
+
expect(actual_p.n).to be <= Stellar::Price::MAX_PRECISION
|
|
31
|
+
expect(actual_p.d).to be <= Stellar::Price::MAX_PRECISION
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Stellar::Thresholds, ".parse" do
|
|
4
|
+
subject{ Stellar::Thresholds }
|
|
5
|
+
let(:raw) { "\x01\x02\x03\x04" }
|
|
6
|
+
let(:result) { subject.parse raw }
|
|
7
|
+
|
|
8
|
+
it "sets master_weight as the 1st byte" do
|
|
9
|
+
expect(result[:master_weight]).to eq(1)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "sets low as the 2nd byte" do
|
|
13
|
+
expect(result[:low]).to eq(2)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
it "sets medium as the 3rd byte" do
|
|
17
|
+
expect(result[:medium]).to eq(3)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it "sets high as the 4th byte" do
|
|
21
|
+
expect(result[:high]).to eq(4)
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
describe Stellar::Thresholds, ".make" do
|
|
26
|
+
subject{ Stellar::Thresholds }
|
|
27
|
+
let(:good){{master_weight: 1, low: 2, medium: 3, high: 4}}
|
|
28
|
+
|
|
29
|
+
it "works" do
|
|
30
|
+
expect(subject.make(good)).to eq("\x01\x02\x03\x04")
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "errors unless all components are provided" do
|
|
34
|
+
expect{ subject.make(good.except(:master_weight)) }.to raise_error(ArgumentError)
|
|
35
|
+
expect{ subject.make(good.except(:low)) }.to raise_error(ArgumentError)
|
|
36
|
+
expect{ subject.make(good.except(:medium)) }.to raise_error(ArgumentError)
|
|
37
|
+
expect{ subject.make(good.except(:high)) }.to raise_error(ArgumentError)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it "errors unless all components are numbers" do
|
|
41
|
+
expect{ subject.make(good.merge(master_weight: "hello")) }.to raise_error(ArgumentError)
|
|
42
|
+
expect{ subject.make(good.merge(low: "hello")) }.to raise_error(ArgumentError)
|
|
43
|
+
expect{ subject.make(good.merge(medium: "hello")) }.to raise_error(ArgumentError)
|
|
44
|
+
expect{ subject.make(good.merge(high: "hello")) }.to raise_error(ArgumentError)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "errors unless all components are in (0..255)" do
|
|
48
|
+
expect{ subject.make(good.merge(master_weight: -1)) }.to raise_error(ArgumentError)
|
|
49
|
+
expect{ subject.make(good.merge(master_weight: 256)) }.to raise_error(ArgumentError)
|
|
50
|
+
expect{ subject.make(good.merge(low: -1)) }.to raise_error(ArgumentError)
|
|
51
|
+
expect{ subject.make(good.merge(low: 256)) }.to raise_error(ArgumentError)
|
|
52
|
+
expect{ subject.make(good.merge(medium: -1)) }.to raise_error(ArgumentError)
|
|
53
|
+
expect{ subject.make(good.merge(medium: 256)) }.to raise_error(ArgumentError)
|
|
54
|
+
expect{ subject.make(good.merge(high: -1)) }.to raise_error(ArgumentError)
|
|
55
|
+
expect{ subject.make(good.merge(high: 256)) }.to raise_error(ArgumentError)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
it "ignores additional keys" do
|
|
59
|
+
expect{ subject.make(good.merge(foo: "a string")) }.not_to raise_error
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Stellar::TransactionEnvelope do
|
|
4
|
+
let(:sender) { Stellar::KeyPair.random }
|
|
5
|
+
let(:receiver){ Stellar::KeyPair.random }
|
|
6
|
+
let(:transaction) do
|
|
7
|
+
Stellar::Transaction.payment({
|
|
8
|
+
account: sender,
|
|
9
|
+
destination: receiver,
|
|
10
|
+
sequence: 1,
|
|
11
|
+
amount: [:native, 20000000]
|
|
12
|
+
})
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
let(:envelope){ transaction.to_envelope(*signers) }
|
|
16
|
+
|
|
17
|
+
describe "#signed_correctly?" do
|
|
18
|
+
subject{ envelope.signed_correctly?(*verifiers) }
|
|
19
|
+
|
|
20
|
+
context "when unsigned" do
|
|
21
|
+
let(:signers) { [] }
|
|
22
|
+
let(:verifiers){ [sender] }
|
|
23
|
+
|
|
24
|
+
it{ should be_falsey }
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
context "when signed by a single account" do
|
|
28
|
+
let(:signers) { [sender] }
|
|
29
|
+
let(:verifiers){ signers }
|
|
30
|
+
|
|
31
|
+
context "and signed correctly" do
|
|
32
|
+
it{ should be_truthy }
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "and the signature is corrupted" do
|
|
36
|
+
before(:each){ envelope.signatures.first.signature = "\xFF" * 32}
|
|
37
|
+
it{ should be_falsey }
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
context "and the signature is from a different message" do
|
|
41
|
+
before(:each){ envelope.signatures = [sender.sign_decorated("hello")]}
|
|
42
|
+
it{ should be_falsey }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
context "and the key for the signing account is not provided" do
|
|
46
|
+
let(:verifiers){ [] }
|
|
47
|
+
it{ should be_falsey }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
context "and the key for the signing account is wrong" do
|
|
51
|
+
let(:verifiers){ [receiver] }
|
|
52
|
+
it{ should be_falsey }
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
context "when signed by a multiple accounts" do
|
|
57
|
+
let(:alternate_signer){ Stellar::KeyPair.random }
|
|
58
|
+
let(:signers) { [sender, alternate_signer] }
|
|
59
|
+
let(:verifiers){ signers }
|
|
60
|
+
|
|
61
|
+
context "and all public keys are provided" do
|
|
62
|
+
it{ should be_truthy }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "and all public keys are provided, with additional unused keys provided" do
|
|
66
|
+
let(:verifiers){ signers + [Stellar::KeyPair.random] }
|
|
67
|
+
it{ should be_truthy }
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
context "and not all public keys for the signers are provided" do
|
|
71
|
+
let(:verifiers){ [alternate_signer] }
|
|
72
|
+
it{ should be_falsey }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
context "and one of the signatures is corrupted" do
|
|
76
|
+
before(:each){ envelope.signatures.last.signature = "\xFF" * 32}
|
|
77
|
+
it{ should be_falsey }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
context "and the signature is from a different message" do
|
|
81
|
+
before(:each){ envelope.signatures = signers.map{|s| s.sign_decorated("hello")}}
|
|
82
|
+
it{ should be_falsey }
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
describe "#hash" do
|
|
89
|
+
let(:signers) { [sender] }
|
|
90
|
+
subject{ envelope.hash }
|
|
91
|
+
it{ should eq(Digest::SHA256.digest envelope.to_xdr)}
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Stellar::Transaction do
|
|
4
|
+
subject do
|
|
5
|
+
Stellar::Transaction.new({
|
|
6
|
+
source_account: Stellar::AccountID.new(:key_type_ed25519, "\x00" * 32),
|
|
7
|
+
fee: 10,
|
|
8
|
+
seq_num: 1,
|
|
9
|
+
memo: Stellar::Memo.new(:memo_none),
|
|
10
|
+
ext: Stellar::Transaction::Ext.new(0),
|
|
11
|
+
operations: [
|
|
12
|
+
Stellar::Operation.new(body: Stellar::Operation::Body.new(:inflation))
|
|
13
|
+
]
|
|
14
|
+
})
|
|
15
|
+
end
|
|
16
|
+
let(:key_pair){ Stellar::KeyPair.random }
|
|
17
|
+
|
|
18
|
+
describe "#sign" do
|
|
19
|
+
let(:result){ subject.sign(key_pair) }
|
|
20
|
+
|
|
21
|
+
it "returns a signature of SHA256(signature_base of the transaction)" do
|
|
22
|
+
hash = Digest::SHA256.digest(subject.signature_base)
|
|
23
|
+
expected = key_pair.sign(hash)
|
|
24
|
+
expect(result).to eq(expected)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe "#to_envelope" do
|
|
29
|
+
let(:result){ subject.to_envelope(key_pair) }
|
|
30
|
+
|
|
31
|
+
it "return a Stellar::TransactionEnvelope" do
|
|
32
|
+
expect(result).to be_a(Stellar::TransactionEnvelope)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "correctly signs the transaction" do
|
|
36
|
+
expect(result.signatures.length).to eq(1)
|
|
37
|
+
expect(result.signatures.first).to be_a(Stellar::DecoratedSignature)
|
|
38
|
+
expect(result.signatures.first.hint).to eq(key_pair.signature_hint)
|
|
39
|
+
expect(result.signatures.first.signature).to eq(subject.sign(key_pair))
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
describe "#signature_base" do
|
|
44
|
+
|
|
45
|
+
it "is prefixed with the current network id" do
|
|
46
|
+
expect(subject.signature_base).to start_with(Stellar.current_network_id)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it "includes the envelope type" do
|
|
50
|
+
expect(subject.signature_base[32...36]).to eql("\x00\x00\x00\x02")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
describe ".for_account's memo assignment" do
|
|
56
|
+
let(:attrs){{account: Stellar::KeyPair.random, sequence: 1}}
|
|
57
|
+
|
|
58
|
+
def make(memo)
|
|
59
|
+
tx = Stellar::Transaction.for_account(attrs.merge(memo: memo))
|
|
60
|
+
tx.memo
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
it "sets to an ID memo when a number is provided" do
|
|
64
|
+
expect(make(3)).to eql(Stellar::Memo.new(:memo_id, 3))
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it "sets to an text memo when a number is provided" do
|
|
68
|
+
expect(make("hello")).to eql(Stellar::Memo.new(:memo_text, "hello"))
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
it "uses the provided value directly if already a memo" do
|
|
72
|
+
expect(make(Stellar::Memo.new(:memo_text, "hello"))).to eql(Stellar::Memo.new(:memo_text, "hello"))
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
it "allows a 2-element array as shorthand" do
|
|
77
|
+
expect(make([:id, 3])).to eql(Stellar::Memo.new(:memo_id, 3))
|
|
78
|
+
expect(make([:text, "h"])).to eql(Stellar::Memo.new(:memo_text, "h"))
|
|
79
|
+
expect(make([:hash, "h"])).to eql(Stellar::Memo.new(:memo_hash, "h"))
|
|
80
|
+
expect(make([:return, "h"])).to eql(Stellar::Memo.new(:memo_return, "h"))
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Stellar::Util::StrKey do
|
|
4
|
+
|
|
5
|
+
subject{ Stellar::Util::StrKey }
|
|
6
|
+
|
|
7
|
+
describe "#check_decode" do
|
|
8
|
+
it "properly decodes" do
|
|
9
|
+
expect(decode :seed, "SAAAAAAAAAADST3H").to eq_bytes("\x00\x00\x00\x00\x00\x00\x39")
|
|
10
|
+
expect(decode :account_id, "GD777777777764TU").to eq_bytes("\xFF\xFF\xFF\xFF\xFF\xFF\xFF")
|
|
11
|
+
expect(decode :account_id, "GBQWWBFLRP3BXZD5").to eq_bytes("\x61\x6b\x04\xab\x8b\xf6\x1b")
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it "raises an ArgumentError if the decoded version byte does not match the expected value" do
|
|
15
|
+
expect{ decode :seed, "GD777777777764TU" }.to raise_error(ArgumentError)
|
|
16
|
+
expect{ decode :account_id, "SAAAAAAAAAADST3M" }.to raise_error(ArgumentError)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it "raises an ArgumentError if the decoded value cannot be validated by the checksum" do
|
|
20
|
+
expect{decode :seed, "SAAAAAAAAAADST3M"}.to raise_error(ArgumentError)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def decode(version, bytes)
|
|
24
|
+
subject.check_decode(version, bytes)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
describe"#check_encode" do
|
|
29
|
+
it "properly encodes" do
|
|
30
|
+
expect(encode :seed, "\x00\x00\x00\x00\x00\x00\x39").to eq("SAAAAAAAAAADST3H")
|
|
31
|
+
expect(encode :account_id, "\xFF\xFF\xFF\xFF\xFF\xFF\xFF").to eq("GD777777777764TU")
|
|
32
|
+
expect(encode :account_id, "\x61\x6b\x04\xab\x8b\xf6\x1b").to eq("GBQWWBFLRP3BXZD5")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
it "raises an ArgumentError when an invalid version is provided" do
|
|
36
|
+
expect{ encode :floob, "\x39" }.to raise_error(ArgumentError)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def encode(version, bytes)
|
|
40
|
+
subject.check_encode(version, bytes)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'bundler/setup'
|
|
2
|
+
Bundler.setup
|
|
3
|
+
|
|
4
|
+
require 'simplecov'
|
|
5
|
+
SimpleCov.start
|
|
6
|
+
|
|
7
|
+
require 'pry'
|
|
8
|
+
require 'stellar-base'
|
|
9
|
+
|
|
10
|
+
SPEC_ROOT = File.dirname(__FILE__)
|
|
11
|
+
|
|
12
|
+
Dir["#{SPEC_ROOT}/support/**/*.rb"].each { |f| require f }
|
|
13
|
+
|
|
14
|
+
RSpec.configure do |config|
|
|
15
|
+
|
|
16
|
+
end
|
data/tasks/rspec.rake
ADDED
data/tasks/travis.rake
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
task :travis => %w(spec)
|
data/tasks/xdr.rake
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
namespace :xdr do
|
|
2
|
+
|
|
3
|
+
# As Hayashi adds more .x files, we'll need to update this array
|
|
4
|
+
# Prior to launch, we should be separating our .x files into a separate
|
|
5
|
+
# repo, and should be able to improve this integration.
|
|
6
|
+
HAYASHI_XDR = [
|
|
7
|
+
"src/xdr/Stellar-types.x",
|
|
8
|
+
"src/xdr/Stellar-ledger-entries.x",
|
|
9
|
+
"src/xdr/Stellar-transaction.x",
|
|
10
|
+
"src/xdr/Stellar-ledger.x",
|
|
11
|
+
"src/xdr/Stellar-overlay.x",
|
|
12
|
+
"src/xdr/Stellar-SCP.x",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
LOCAL_XDR_PATHS = HAYASHI_XDR.map{ |src| "xdr/" + File.basename(src) }
|
|
16
|
+
|
|
17
|
+
task :update => [:download, :generate]
|
|
18
|
+
|
|
19
|
+
task :download do
|
|
20
|
+
require 'octokit'
|
|
21
|
+
require 'base64'
|
|
22
|
+
FileUtils.rm_rf "xdr/"
|
|
23
|
+
FileUtils.mkdir_p "xdr"
|
|
24
|
+
|
|
25
|
+
client = Octokit::Client.new(:netrc => true)
|
|
26
|
+
|
|
27
|
+
HAYASHI_XDR.each do |src|
|
|
28
|
+
local_path = "xdr/" + File.basename(src)
|
|
29
|
+
encoded = client.contents("stellar/stellar-core", path: src).content
|
|
30
|
+
decoded = Base64.decode64 encoded
|
|
31
|
+
|
|
32
|
+
IO.write(local_path, decoded)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
task :generate do
|
|
37
|
+
require "pathname"
|
|
38
|
+
require "xdrgen"
|
|
39
|
+
require 'fileutils'
|
|
40
|
+
FileUtils.rm_rf "generated"
|
|
41
|
+
|
|
42
|
+
compilation = Xdrgen::Compilation.new(
|
|
43
|
+
LOCAL_XDR_PATHS,
|
|
44
|
+
output_dir: "generated",
|
|
45
|
+
namespace: "stellar-base-generated",
|
|
46
|
+
language: :ruby
|
|
47
|
+
)
|
|
48
|
+
compilation.compile
|
|
49
|
+
end
|
|
50
|
+
end
|
data/xdr/Stellar-SCP.x
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// Copyright 2015 Stellar Development Foundation and contributors. Licensed
|
|
2
|
+
// under the Apache License, Version 2.0. See the COPYING file at the root
|
|
3
|
+
// of this distribution or at http://www.apache.org/licenses/LICENSE-2.0
|
|
4
|
+
|
|
5
|
+
%#include "xdr/Stellar-types.h"
|
|
6
|
+
|
|
7
|
+
namespace stellar
|
|
8
|
+
{
|
|
9
|
+
|
|
10
|
+
typedef opaque Value<>;
|
|
11
|
+
|
|
12
|
+
struct SCPBallot
|
|
13
|
+
{
|
|
14
|
+
uint32 counter; // n
|
|
15
|
+
Value value; // x
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
enum SCPStatementType
|
|
19
|
+
{
|
|
20
|
+
SCP_ST_PREPARE = 0,
|
|
21
|
+
SCP_ST_CONFIRM = 1,
|
|
22
|
+
SCP_ST_EXTERNALIZE = 2,
|
|
23
|
+
SCP_ST_NOMINATE = 3
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
struct SCPNomination
|
|
27
|
+
{
|
|
28
|
+
Hash quorumSetHash; // D
|
|
29
|
+
Value votes<>; // X
|
|
30
|
+
Value accepted<>; // Y
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
struct SCPStatement
|
|
34
|
+
{
|
|
35
|
+
NodeID nodeID; // v
|
|
36
|
+
uint64 slotIndex; // i
|
|
37
|
+
|
|
38
|
+
union switch (SCPStatementType type)
|
|
39
|
+
{
|
|
40
|
+
case SCP_ST_PREPARE:
|
|
41
|
+
struct
|
|
42
|
+
{
|
|
43
|
+
Hash quorumSetHash; // D
|
|
44
|
+
SCPBallot ballot; // b
|
|
45
|
+
SCPBallot* prepared; // p
|
|
46
|
+
SCPBallot* preparedPrime; // p'
|
|
47
|
+
uint32 nC; // c.n
|
|
48
|
+
uint32 nH; // h.n
|
|
49
|
+
} prepare;
|
|
50
|
+
case SCP_ST_CONFIRM:
|
|
51
|
+
struct
|
|
52
|
+
{
|
|
53
|
+
SCPBallot ballot; // b
|
|
54
|
+
uint32 nPrepared; // p.n
|
|
55
|
+
uint32 nCommit; // c.n
|
|
56
|
+
uint32 nH; // h.n
|
|
57
|
+
Hash quorumSetHash; // D
|
|
58
|
+
} confirm;
|
|
59
|
+
case SCP_ST_EXTERNALIZE:
|
|
60
|
+
struct
|
|
61
|
+
{
|
|
62
|
+
SCPBallot commit; // c
|
|
63
|
+
uint32 nH; // h.n
|
|
64
|
+
Hash commitQuorumSetHash; // D used before EXTERNALIZE
|
|
65
|
+
} externalize;
|
|
66
|
+
case SCP_ST_NOMINATE:
|
|
67
|
+
SCPNomination nominate;
|
|
68
|
+
}
|
|
69
|
+
pledges;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
struct SCPEnvelope
|
|
73
|
+
{
|
|
74
|
+
SCPStatement statement;
|
|
75
|
+
Signature signature;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
// supports things like: A,B,C,(D,E,F),(G,H,(I,J,K,L))
|
|
79
|
+
// only allows 2 levels of nesting
|
|
80
|
+
struct SCPQuorumSet
|
|
81
|
+
{
|
|
82
|
+
uint32 threshold;
|
|
83
|
+
PublicKey validators<>;
|
|
84
|
+
SCPQuorumSet innerSets<>;
|
|
85
|
+
};
|
|
86
|
+
}
|