mirror of
https://github.com/XRPLF/rippled.git
synced 2025-12-02 00:45:58 +00:00
Ensure no offers cancel each other out
This commit is contained in:
committed by
Vinnie Falco
parent
bf1843be9e
commit
8d5378a2ca
@@ -2,16 +2,18 @@
|
|||||||
|
|
||||||
# This gives coffee-script proper file/lines in the exceptions
|
# This gives coffee-script proper file/lines in the exceptions
|
||||||
|
|
||||||
async = require("async")
|
async = require 'async'
|
||||||
assert = require 'assert'
|
assert = require 'assert'
|
||||||
Amount = require("ripple-lib").Amount
|
{
|
||||||
Remote = require("ripple-lib").Remote
|
Amount
|
||||||
Seed = require("ripple-lib").Seed
|
Remote
|
||||||
Base = require("ripple-lib").Base
|
Seed
|
||||||
Transaction = require("ripple-lib").Transaction
|
Base
|
||||||
sjcl = require("ripple-lib").sjcl
|
Transaction
|
||||||
Server = require("./server").Server
|
sjcl
|
||||||
testutils = require("./testutils")
|
} = require 'ripple-lib'
|
||||||
|
{Server} = require './server'
|
||||||
|
testutils = require './testutils'
|
||||||
|
|
||||||
#################################### HELPERS ###################################
|
#################################### HELPERS ###################################
|
||||||
|
|
||||||
@@ -21,14 +23,18 @@ exports.TestAccount = class TestAccount
|
|||||||
SHA256_RIPEMD160: (bits) ->
|
SHA256_RIPEMD160: (bits) ->
|
||||||
sjcl.hash.ripemd160.hash sjcl.hash.sha256.hash(bits)
|
sjcl.hash.ripemd160.hash sjcl.hash.sha256.hash(bits)
|
||||||
|
|
||||||
get_address: (passphrase) ->
|
derive_pair: (passphrase) ->
|
||||||
key_pair = Seed.from_json(passphrase).get_key()
|
seed = Seed.from_json(passphrase)
|
||||||
|
master_seed = seed.to_json()
|
||||||
|
key_pair = seed.get_key()
|
||||||
pubKey = sjcl.codec.hex.toBits key_pair.to_hex_pub()
|
pubKey = sjcl.codec.hex.toBits key_pair.to_hex_pub()
|
||||||
Base.encode_check(0,sjcl.codec.bytes.fromBits(@SHA256_RIPEMD160 pubKey))
|
address = Base.encode_check(0,
|
||||||
|
sjcl.codec.bytes.fromBits(@SHA256_RIPEMD160 pubKey))
|
||||||
|
[address, master_seed, key_pair]
|
||||||
|
|
||||||
constructor: (passphrase) ->
|
constructor: (passphrase) ->
|
||||||
@passphrase = passphrase
|
@passphrase = passphrase
|
||||||
@address = @get_address(passphrase)
|
[@address, @master_seed, @key_pair] = @derive_pair(passphrase)
|
||||||
|
|
||||||
############################# LEDGER STATE COMPILER ############################
|
############################# LEDGER STATE COMPILER ############################
|
||||||
|
|
||||||
@@ -46,25 +52,17 @@ exports.LedgerState = class LedgerState
|
|||||||
@realias_issuer = (str) -> str.replace(realias, (match) ->lookup[match])
|
@realias_issuer = (str) -> str.replace(realias, (match) ->lookup[match])
|
||||||
|
|
||||||
parse_amount: (amt_val) ->
|
parse_amount: (amt_val) ->
|
||||||
try
|
amt = Amount.from_json(amt_val)
|
||||||
amt = Amount.from_json(amt_val)
|
if not amt.is_valid()
|
||||||
if not amt.is_valid()
|
|
||||||
throw new Error()
|
|
||||||
catch e
|
|
||||||
try
|
|
||||||
amt = Amount.from_human(amt_val)
|
amt = Amount.from_human(amt_val)
|
||||||
if not amt.is_valid()
|
if not amt.is_valid()
|
||||||
throw new Error()
|
amt = null
|
||||||
catch e
|
|
||||||
amt = null
|
|
||||||
amt
|
amt
|
||||||
|
|
||||||
amount_key: (amt) ->
|
amount_key: (amt) ->
|
||||||
currency = amt.currency().to_json()
|
currency = amt.currency().to_json()
|
||||||
issuer = @realias_issuer amt.issuer().to_json()
|
issuer = @realias_issuer amt.issuer().to_json()
|
||||||
key = "#{currency}/#{issuer}"
|
"#{currency}/#{issuer}"
|
||||||
key.issuer = issuer
|
|
||||||
key
|
|
||||||
|
|
||||||
apply: (context)->
|
apply: (context)->
|
||||||
@create_accounts_by_issuing_xrp_from_root(context)
|
@create_accounts_by_issuing_xrp_from_root(context)
|
||||||
@@ -112,6 +110,8 @@ exports.LedgerState = class LedgerState
|
|||||||
"Trust amount #{amt_val} specified for #{account_id} is not valid"
|
"Trust amount #{amt_val} specified for #{account_id} is not valid"
|
||||||
@record_trust(account_id, amt, false)
|
@record_trust(account_id, amt, false)
|
||||||
|
|
||||||
|
undefined
|
||||||
|
|
||||||
compile_accounts_balances_and_implicit_trusts: ->
|
compile_accounts_balances_and_implicit_trusts: ->
|
||||||
for account_id, account of @declaration.accounts
|
for account_id, account of @declaration.accounts
|
||||||
xrp_balance = null
|
xrp_balance = null
|
||||||
@@ -133,6 +133,8 @@ exports.LedgerState = class LedgerState
|
|||||||
@assert xrp_balance,
|
@assert xrp_balance,
|
||||||
"No XRP balanced declared for #{account_id}"
|
"No XRP balanced declared for #{account_id}"
|
||||||
|
|
||||||
|
undefined
|
||||||
|
|
||||||
compile_offers: ->
|
compile_offers: ->
|
||||||
for account_id, account of @declaration.accounts
|
for account_id, account of @declaration.accounts
|
||||||
if not account.offers?
|
if not account.offers?
|
||||||
@@ -147,28 +149,31 @@ exports.LedgerState = class LedgerState
|
|||||||
@assert pays_amt != null,
|
@assert pays_amt != null,
|
||||||
"For account #{account_id} taker_pays amount #{pays} is invalid"
|
"For account #{account_id} taker_pays amount #{pays} is invalid"
|
||||||
|
|
||||||
a_offers = @ensure(account_id, @offers_by_ci)
|
offers = @ensure(account_id, @offers_by_ci)
|
||||||
a_offers = @ensure(account_id, @offers_by_ci)
|
offers = @ensure(account_id, @offers_by_ci)
|
||||||
offers_all = @ensure('offers', a_offers, [])
|
offers_all = @ensure('offers', offers, [])
|
||||||
|
|
||||||
if gets_amt.is_native()
|
if gets_amt.is_native()
|
||||||
total = a_offers.xrp_total ?= new Amount.from_json('0')
|
total = offers.xrp_total ?= new Amount.from_json('0')
|
||||||
new_total = total.add(gets_amt)
|
new_total = total.add(gets_amt)
|
||||||
@assert @accounts[account_id].compareTo(new_total) != - 1,
|
@assert @accounts[account_id].compareTo(new_total) != - 1,
|
||||||
"Account #{account_id}s doesn't have enough xrp to place #{offer}"
|
"Account #{account_id}s doesn't have enough xrp to place #{offer}"
|
||||||
else
|
else
|
||||||
key = @amount_key gets_amt
|
key = @amount_key gets_amt
|
||||||
key_offers = @ensure(key, a_offers, {})
|
|
||||||
|
if key.split('/')[1] != account_id
|
||||||
|
key_offers = @ensure(key, offers, {})
|
||||||
|
|
||||||
total = key_offers.total ?= Amount.from_json("0/#{key}")
|
total = key_offers.total ?= Amount.from_json("0/#{key}")
|
||||||
new_total = total.add(gets_amt)
|
new_total = total.add(gets_amt)
|
||||||
a_ious = @ensure(account_id, @ious)
|
a_ious = @ensure(account_id, @ious)
|
||||||
@assert a_ious[key]?,
|
@assert a_ious[key]?,
|
||||||
"Account #{account_id} doesn't hold any #{key}"
|
"Account #{account_id} doesn't hold any #{key}"
|
||||||
@assert a_ious[key].compareTo(new_total) != - 1,
|
@assert a_ious[key].compareTo(new_total) != - 1,
|
||||||
"Account #{account_id} doesn't have enough #{key} to place #{offer}"
|
"Account #{account_id} doesn't have enough #{key}"
|
||||||
|
" to place #{offer}"
|
||||||
|
|
||||||
key_offers.total = new_total
|
key_offers.total = new_total
|
||||||
|
|
||||||
offers_all.push [pays_amt, gets_amt, splat...]
|
offers_all.push [pays_amt, gets_amt, splat...]
|
||||||
|
|
||||||
@@ -180,11 +185,13 @@ exports.LedgerState = class LedgerState
|
|||||||
@offers.push sliced
|
@offers.push sliced
|
||||||
# @offers[account_id] = obj.offers
|
# @offers[account_id] = obj.offers
|
||||||
|
|
||||||
|
@offers
|
||||||
|
|
||||||
base_reserve: ->
|
base_reserve: ->
|
||||||
@declaration.reserve?.base ? "50.0"
|
@declaration.reserve?.base ? "200.0"
|
||||||
|
|
||||||
incr_reserve: ->
|
incr_reserve: ->
|
||||||
@declaration.reserve?.base ? "12.5"
|
@declaration.reserve?.base ? "50.0"
|
||||||
|
|
||||||
check_reserves: ->
|
check_reserves: ->
|
||||||
base_reserve_amt = @base_reserve()
|
base_reserve_amt = @base_reserve()
|
||||||
@@ -203,11 +210,11 @@ exports.LedgerState = class LedgerState
|
|||||||
total_needed = base_reserve.clone()
|
total_needed = base_reserve.clone()
|
||||||
owner_count = 0
|
owner_count = 0
|
||||||
|
|
||||||
a_offers = @offers_by_ci[account_id]
|
offers = @offers_by_ci[account_id]
|
||||||
if a_offers?
|
if offers?
|
||||||
if a_offers.xrp_total?
|
if offers.xrp_total?
|
||||||
total_needed = total_needed.add a_offers.xrp_total
|
total_needed = total_needed.add offers.xrp_total
|
||||||
if a_offers.offers?
|
if offers.offers?
|
||||||
owner_count += @offers_by_ci[account_id].offers.length
|
owner_count += @offers_by_ci[account_id].offers.length
|
||||||
|
|
||||||
if @trusts_by_ci[account_id]?
|
if @trusts_by_ci[account_id]?
|
||||||
@@ -232,12 +239,16 @@ exports.LedgerState = class LedgerState
|
|||||||
src = @realias_issuer amt.issuer().to_json()
|
src = @realias_issuer amt.issuer().to_json()
|
||||||
dst = account_id
|
dst = account_id
|
||||||
@iou_payments.push [src, dst, amt]
|
@iou_payments.push [src, dst, amt]
|
||||||
|
|
||||||
|
undefined
|
||||||
|
|
||||||
format_trusts: ->
|
format_trusts: ->
|
||||||
for account_id, trusts of @trusts_by_ci
|
for account_id, trusts of @trusts_by_ci
|
||||||
for curr_issuer, amt of trusts
|
for curr_issuer, amt of trusts
|
||||||
@trusts.push [account_id, amt]
|
@trusts.push [account_id, amt]
|
||||||
|
|
||||||
|
undefined
|
||||||
|
|
||||||
transactor: (fn, args_list, on_each, callback) ->
|
transactor: (fn, args_list, on_each, callback) ->
|
||||||
if args_list.length == 0
|
if args_list.length == 0
|
||||||
return callback()
|
return callback()
|
||||||
@@ -256,9 +267,10 @@ exports.LedgerState = class LedgerState
|
|||||||
|
|
||||||
async.concatSeries(args_list, ((args, callback) =>
|
async.concatSeries(args_list, ((args, callback) =>
|
||||||
tx = @remote.transaction()
|
tx = @remote.transaction()
|
||||||
on_each?(args..., tx)
|
fn.apply(tx, args)
|
||||||
fn.apply(tx, args).on("proposed", (m) =>
|
on_each?(args..., tx) # after payment() offer_create() etc so set_flags works
|
||||||
@assert m.engine_result is "tesSUCCESS", "Transactor failure: #{pretty_json m}"
|
tx.on("proposed", (m) =>
|
||||||
|
@assert m.engine_result is "tesSUCCESS", "Transactor failure: #{@pretty_json m}"
|
||||||
callback()
|
callback()
|
||||||
).on('final', (m) =>
|
).on('final', (m) =>
|
||||||
finalized.one()
|
finalized.one()
|
||||||
@@ -270,7 +282,7 @@ exports.LedgerState = class LedgerState
|
|||||||
=> testutils.ledger_close @remote, ->
|
=> testutils.ledger_close @remote, ->
|
||||||
)
|
)
|
||||||
|
|
||||||
requester: (fn, args_list, on_each, callback) ->
|
requester: (fn, args_list, on_each, callback, on_results) ->
|
||||||
if not callback?
|
if not callback?
|
||||||
callback = on_each
|
callback = on_each
|
||||||
on_each = null
|
on_each = null
|
||||||
@@ -282,12 +294,16 @@ exports.LedgerState = class LedgerState
|
|||||||
on_each?(args..., req)
|
on_each?(args..., req)
|
||||||
req.on("success", (m) =>
|
req.on("success", (m) =>
|
||||||
if m.status?
|
if m.status?
|
||||||
@assert m.status is "success", "requester failure: #{pretty_json m}"
|
@assert m.status is "success", "requester failure: #{@pretty_json m}"
|
||||||
callback()
|
callback(null, m)
|
||||||
).on("error", (m) =>
|
).on("error", (m) =>
|
||||||
@assert false, pretty_json m
|
@assert false, @pretty_json m
|
||||||
).request()
|
).request()
|
||||||
), -> callback())
|
),
|
||||||
|
(error, results_list) ->
|
||||||
|
on_results?(results_list);
|
||||||
|
callback()
|
||||||
|
)
|
||||||
|
|
||||||
ensure_config_has_test_accounts: ->
|
ensure_config_has_test_accounts: ->
|
||||||
for account of @declaration.accounts
|
for account of @declaration.accounts
|
||||||
@@ -295,7 +311,7 @@ exports.LedgerState = class LedgerState
|
|||||||
acc = @config.accounts[account] = {}
|
acc = @config.accounts[account] = {}
|
||||||
user = new TestAccount(account)
|
user = new TestAccount(account)
|
||||||
acc.account = user.address
|
acc.account = user.address
|
||||||
acc.secret = user.passphrase
|
acc.secret = user.master_seed
|
||||||
# Index by nickname ...
|
# Index by nickname ...
|
||||||
@remote.set_secret account, acc.secret
|
@remote.set_secret account, acc.secret
|
||||||
# ... and by account ID
|
# ... and by account ID
|
||||||
@@ -333,7 +349,7 @@ exports.LedgerState = class LedgerState
|
|||||||
|
|
||||||
accounts = (k for k,ac of @accounts).sort()
|
accounts = (k for k,ac of @accounts).sort()
|
||||||
@remote.set_account_seq(seq, 1) for seq in accounts.concat 'root' # <--
|
@remote.set_account_seq(seq, 1) for seq in accounts.concat 'root' # <--
|
||||||
accounts_apply_arguments = ([ac] for ac in @accounts)
|
accounts_apply_arguments = ([ac] for ac, _ of @accounts)
|
||||||
self = this
|
self = this
|
||||||
|
|
||||||
async.waterfall [
|
async.waterfall [
|
||||||
@@ -367,9 +383,10 @@ exports.LedgerState = class LedgerState
|
|||||||
self.transactor(
|
self.transactor(
|
||||||
Transaction::offer_create,
|
Transaction::offer_create,
|
||||||
self.offers,
|
self.offers,
|
||||||
((src, pays, gets) ->
|
((src, pays, gets, tx) ->
|
||||||
LOG("Account `#{src}` is selling #{gets.to_text_full()}
|
tx.set_flags('Passive')
|
||||||
for #{pays.to_text_full()}")),
|
LOG("Account `#{src}` is selling #{gets.to_text_full()}
|
||||||
|
for #{pays.to_text_full()}")),
|
||||||
cb)
|
cb)
|
||||||
(cb) ->
|
(cb) ->
|
||||||
testutils.ledger_close self.remote, cb
|
testutils.ledger_close self.remote, cb
|
||||||
@@ -378,6 +395,31 @@ exports.LedgerState = class LedgerState
|
|||||||
((acc) ->
|
((acc) ->
|
||||||
LOG("Checking account_lines for #{acc}")),
|
LOG("Checking account_lines for #{acc}")),
|
||||||
cb)
|
cb)
|
||||||
|
(cb) ->
|
||||||
|
self.requester(Remote::request_account_offers, accounts_apply_arguments,
|
||||||
|
((acc) ->
|
||||||
|
LOG("Checking account_offers for #{acc}")),
|
||||||
|
cb, (results) ->
|
||||||
|
|
||||||
|
for [ac], ix in accounts_apply_arguments
|
||||||
|
account = self.declaration.accounts[ac]
|
||||||
|
offers_declared = (account.offers ? []).length
|
||||||
|
actual = results[ix].offers
|
||||||
|
offers_made = actual.length
|
||||||
|
if offers_made != offers_declared
|
||||||
|
shortened = []
|
||||||
|
for offer in actual
|
||||||
|
keys = ['taker_pays', 'taker_gets']
|
||||||
|
pair = (Amount.from_json(offer[k]).to_text_full() for k in keys)
|
||||||
|
shortened.push pair
|
||||||
|
|
||||||
|
shortened_text = self.pretty_json shortened
|
||||||
|
self.assert offers_made == offers_declared,
|
||||||
|
"Account #{ac} has failed offer\n"+
|
||||||
|
"Declared: #{pretty_json account.offers}\n"+
|
||||||
|
"Actual: #{shortened_text}"
|
||||||
|
|
||||||
|
)
|
||||||
(cb) ->
|
(cb) ->
|
||||||
self.requester(Remote::request_account_info, accounts_apply_arguments,
|
self.requester(Remote::request_account_info, accounts_apply_arguments,
|
||||||
((acc) ->
|
((acc) ->
|
||||||
|
|||||||
@@ -74,6 +74,7 @@ The tests are written in a declarative style:
|
|||||||
#################################### HELPERS ###################################
|
#################################### HELPERS ###################################
|
||||||
|
|
||||||
assert = simple_assert
|
assert = simple_assert
|
||||||
|
|
||||||
refute = (cond, msg) -> assert(!cond, msg)
|
refute = (cond, msg) -> assert(!cond, msg)
|
||||||
prettyj = pretty_json = (v) -> JSON.stringify(v, undefined, 2)
|
prettyj = pretty_json = (v) -> JSON.stringify(v, undefined, 2)
|
||||||
|
|
||||||
@@ -131,7 +132,7 @@ expand_alternative = (alt) ->
|
|||||||
prev_issuer = hop.issuer
|
prev_issuer = hop.issuer
|
||||||
else if hop.account?
|
else if hop.account?
|
||||||
prev_issuer = hop.account
|
prev_issuer = hop.account
|
||||||
|
|
||||||
return alt
|
return alt
|
||||||
|
|
||||||
create_shorthand = (alternatives) ->
|
create_shorthand = (alternatives) ->
|
||||||
@@ -268,7 +269,7 @@ test_alternatives_factory = (realias_pp, realias_text) ->
|
|||||||
[t_amt_txt, a_amt_txt] = amounts_text(t_amt, a_amt)
|
[t_amt_txt, a_amt_txt] = amounts_text(t_amt, a_amt)
|
||||||
|
|
||||||
# console.log typeof t_amt
|
# console.log typeof t_amt
|
||||||
|
|
||||||
assert t_amt.equals(a_amt),
|
assert t_amt.equals(a_amt),
|
||||||
"Expecting alternative[#{ti}].amount: "+
|
"Expecting alternative[#{ti}].amount: "+
|
||||||
"#{t_amt_txt} == #{a_amt_txt}"
|
"#{t_amt_txt} == #{a_amt_txt}"
|
||||||
@@ -300,8 +301,6 @@ test_alternatives_factory = (realias_pp, realias_text) ->
|
|||||||
|
|
||||||
create_path_test = (pth) ->
|
create_path_test = (pth) ->
|
||||||
return (done) ->
|
return (done) ->
|
||||||
propagates = propagater done
|
|
||||||
|
|
||||||
self = this
|
self = this
|
||||||
WHAT = self.log_what
|
WHAT = self.log_what
|
||||||
ledger = self.ledger
|
ledger = self.ledger
|
||||||
@@ -319,7 +318,11 @@ create_path_test = (pth) ->
|
|||||||
one_message (m) -> sent = m
|
one_message (m) -> sent = m
|
||||||
|
|
||||||
error_info = (m, more) ->
|
error_info = (m, more) ->
|
||||||
info = path_expected: pth, path_find_request: sent, path_find_updates: m
|
info =
|
||||||
|
path_expected: pth,
|
||||||
|
path_find_request: sent,
|
||||||
|
path_find_updates: messages
|
||||||
|
|
||||||
extend(info, more) if more?
|
extend(info, more) if more?
|
||||||
ledger.pretty_json(info)
|
ledger.pretty_json(info)
|
||||||
|
|
||||||
@@ -337,6 +340,8 @@ create_path_test = (pth) ->
|
|||||||
max_seen = 0
|
max_seen = 0
|
||||||
messages = {}
|
messages = {}
|
||||||
|
|
||||||
|
propagates = propagater done
|
||||||
|
|
||||||
pf.on "error", propagates (m) -> # <--
|
pf.on "error", propagates (m) -> # <--
|
||||||
assert false, "fail (error): #{error_info(m)}"
|
assert false, "fail (error): #{error_info(m)}"
|
||||||
done()
|
done()
|
||||||
@@ -402,17 +407,16 @@ skip_or_only = (title, test_or_suite) ->
|
|||||||
else
|
else
|
||||||
test_or_suite
|
test_or_suite
|
||||||
|
|
||||||
|
definer_factory = (group, title, path) ->
|
||||||
|
path.title = "#{[group, title].join('.')}"
|
||||||
|
test_func = skip_or_only path.title, test
|
||||||
|
->
|
||||||
|
test_func(path.title, create_path_test(path) )
|
||||||
|
|
||||||
gather_path_definers = (path_expected) ->
|
gather_path_definers = (path_expected) ->
|
||||||
tests = []
|
tests = []
|
||||||
|
|
||||||
for group, subgroup of path_expected
|
for group, subgroup of path_expected
|
||||||
for title, path of subgroup
|
for title, path of subgroup
|
||||||
definer_factory = (group, title, path) ->
|
|
||||||
path.title = "#{[group, title].join('.')}"
|
|
||||||
test_func = skip_or_only path.title, test
|
|
||||||
->
|
|
||||||
test_func(path.title, create_path_test(path) )
|
|
||||||
|
|
||||||
tests.push definer_factory(group, title, path)
|
tests.push definer_factory(group, title, path)
|
||||||
tests
|
tests
|
||||||
|
|
||||||
@@ -425,9 +429,9 @@ suite_factory = (declaration) ->
|
|||||||
@log_what = ->
|
@log_what = ->
|
||||||
|
|
||||||
testutils.build_setup().call @, ->
|
testutils.build_setup().call @, ->
|
||||||
context.ledger = new LedgerState(declaration.ledger,
|
context.ledger = new LedgerState(declaration.ledger,
|
||||||
assert,
|
assert,
|
||||||
context.remote,
|
context.remote,
|
||||||
config)
|
config)
|
||||||
|
|
||||||
context.ledger.setup(context.log_what, done)
|
context.ledger.setup(context.log_what, done)
|
||||||
@@ -456,6 +460,142 @@ path_finding_cases = JSON.parse path_finding_cases_string
|
|||||||
# gateway and holds its currency, and a destination that trusts the other.
|
# gateway and holds its currency, and a destination that trusts the other.
|
||||||
|
|
||||||
extend path_finding_cases,
|
extend path_finding_cases,
|
||||||
|
"CNY test":
|
||||||
|
paths_expected:
|
||||||
|
BS:
|
||||||
|
P101: src: "SRC", dst: "GATEWAY_DST", send: "10.1/CNY/GATEWAY_DST", via: "XRP", n_alternatives: 1
|
||||||
|
|
||||||
|
ledger:
|
||||||
|
accounts:
|
||||||
|
SRC:
|
||||||
|
balance: ["4999.999898"]
|
||||||
|
trusts: []
|
||||||
|
offers: []
|
||||||
|
|
||||||
|
GATEWAY_DST:
|
||||||
|
balance: ["10846.168060"]
|
||||||
|
trusts: []
|
||||||
|
offers: []
|
||||||
|
|
||||||
|
MONEY_MAKER_1:
|
||||||
|
balance: ["4291.430036"]
|
||||||
|
trusts: []
|
||||||
|
offers: []
|
||||||
|
|
||||||
|
MONEY_MAKER_2:
|
||||||
|
balance: [
|
||||||
|
"106839375770"
|
||||||
|
"0.0000000003599/CNY/MONEY_MAKER_1"
|
||||||
|
"137.6852546843001/CNY/GATEWAY_DST"
|
||||||
|
]
|
||||||
|
trusts: [
|
||||||
|
"1001/CNY/MONEY_MAKER_1"
|
||||||
|
"1001/CNY/GATEWAY_DST"
|
||||||
|
]
|
||||||
|
offers: [
|
||||||
|
[
|
||||||
|
"1000000"
|
||||||
|
"1/CNY/GATEWAY_DST"
|
||||||
|
# []
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"1/CNY/GATEWAY_DST"
|
||||||
|
"1000000"
|
||||||
|
# []
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"318000/CNY/GATEWAY_DST"
|
||||||
|
"53000000000"
|
||||||
|
# ["Sell"]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"209000000"
|
||||||
|
"4.18/CNY/MONEY_MAKER_2"
|
||||||
|
# []
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"990000/CNY/MONEY_MAKER_1"
|
||||||
|
"10000000000"
|
||||||
|
# ["Sell"]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"9990000/CNY/MONEY_MAKER_1"
|
||||||
|
"10000000000"
|
||||||
|
# ["Sell"]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"8870000/CNY/GATEWAY_DST"
|
||||||
|
"10000000000"
|
||||||
|
# ["Sell"]
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"232000000"
|
||||||
|
"5.568/CNY/MONEY_MAKER_2"
|
||||||
|
# []
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
A1:
|
||||||
|
balance: [
|
||||||
|
# "240.997150"
|
||||||
|
"1240.997150"
|
||||||
|
"0.0000000119761/CNY/MONEY_MAKER_1"
|
||||||
|
"33.047994/CNY/GATEWAY_DST"
|
||||||
|
]
|
||||||
|
trusts: [
|
||||||
|
"1000000/CNY/MONEY_MAKER_1"
|
||||||
|
"100000/USD/MONEY_MAKER_1"
|
||||||
|
"10000/BTC/MONEY_MAKER_1"
|
||||||
|
"1000/USD/GATEWAY_DST"
|
||||||
|
"1000/CNY/GATEWAY_DST"
|
||||||
|
]
|
||||||
|
offers: []
|
||||||
|
|
||||||
|
A2:
|
||||||
|
balance: [
|
||||||
|
"14115.046893"
|
||||||
|
"209.3081873019994/CNY/MONEY_MAKER_1"
|
||||||
|
"694.6251706504019/CNY/GATEWAY_DST"
|
||||||
|
]
|
||||||
|
trusts: [
|
||||||
|
"3000/CNY/MONEY_MAKER_1"
|
||||||
|
"3000/CNY/GATEWAY_DST"
|
||||||
|
]
|
||||||
|
offers: [
|
||||||
|
[
|
||||||
|
"2000000000"
|
||||||
|
"66.8/CNY/MONEY_MAKER_1"
|
||||||
|
# []
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"1200000000"
|
||||||
|
"42/CNY/GATEWAY_DST"
|
||||||
|
# []
|
||||||
|
]
|
||||||
|
[
|
||||||
|
"43.2/CNY/MONEY_MAKER_1"
|
||||||
|
"900000000"
|
||||||
|
# ["Sell"]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|
||||||
|
A3:
|
||||||
|
balance: [
|
||||||
|
"512087.883181"
|
||||||
|
"23.617050013581/CNY/MONEY_MAKER_1"
|
||||||
|
"70.999614649799/CNY/GATEWAY_DST"
|
||||||
|
]
|
||||||
|
trusts: [
|
||||||
|
"10000/CNY/MONEY_MAKER_1"
|
||||||
|
"10000/CNY/GATEWAY_DST"
|
||||||
|
]
|
||||||
|
offers: [[
|
||||||
|
"2240/CNY/MONEY_MAKER_1"
|
||||||
|
"50000000000"
|
||||||
|
# ["Sell"]
|
||||||
|
]]
|
||||||
|
|
||||||
|
|
||||||
"Path Tests (Bitstamp + SnapSwap account holders | liquidity provider with no offers)":
|
"Path Tests (Bitstamp + SnapSwap account holders | liquidity provider with no offers)":
|
||||||
ledger:
|
ledger:
|
||||||
accounts:
|
accounts:
|
||||||
|
|||||||
Reference in New Issue
Block a user