From f781bd6c00c22cfde24407d293d33890e56bd8fe Mon Sep 17 00:00:00 2001 From: CJ Cobb Date: Tue, 9 Mar 2021 16:33:24 -0500 Subject: [PATCH] ledger rpc accepts more flags. binary options for all rpcs. tests to verify ledger and account_info --- handlers/AccountInfo.cpp | 7 +- handlers/AccountTx.cpp | 17 +++- handlers/Ledger.cpp | 115 +++++++++++++++++------ handlers/Tx.cpp | 17 +++- reporting/BackendInterface.h | 4 + reporting/CassandraBackend.cpp | 39 ++++++-- reporting/CassandraBackend.h | 10 +- reporting/PostgresBackend.cpp | 34 ++++++- reporting/PostgresBackend.h | 3 + reporting/ReportingETL.cpp | 2 + test.py | 163 +++++++++++++++++++++++++++------ 11 files changed, 335 insertions(+), 76 deletions(-) diff --git a/handlers/AccountInfo.cpp b/handlers/AccountInfo.cpp index 6176004a..98794172 100644 --- a/handlers/AccountInfo.cpp +++ b/handlers/AccountInfo.cpp @@ -56,6 +56,8 @@ doAccountInfo( response["error"] = "missing account field"; return response; } + bool binary = + request.contains("binary") ? request.at("binary").as_bool() : false; auto ledgerSequence = ledgerSequenceFromRequest(request, backend); if (!ledgerSequence) { @@ -98,7 +100,10 @@ doAccountInfo( else { response["success"] = "fetched successfully!"; - response["object"] = getJson(sle); + if (!binary) + response["object"] = getJson(sle); + else + response["object"] = ripple::strHex(*dbResponse); response["db_time"] = time; return response; } diff --git a/handlers/AccountTx.cpp b/handlers/AccountTx.cpp index beab1071..908b0439 100644 --- a/handlers/AccountTx.cpp +++ b/handlers/AccountTx.cpp @@ -144,6 +144,8 @@ doAccountTx(boost::json::object const& request, BackendInterface const& backend) response["error"] = "account malformed"; return response; } + bool binary = + request.contains("binary") ? request.at("binary").as_bool() : false; std::optional cursor; if (request.contains("cursor")) @@ -179,9 +181,18 @@ doAccountTx(boost::json::object const& request, BackendInterface const& backend) for (auto const& txnPlusMeta : blobs) { boost::json::object obj; - auto [txn, meta] = deserializeTxPlusMeta(txnPlusMeta); - obj["transaction"] = getJson(*txn); - obj["metadata"] = getJson(*meta); + if (!binary) + { + auto [txn, meta] = deserializeTxPlusMeta(txnPlusMeta); + obj["transaction"] = getJson(*txn); + obj["metadata"] = getJson(*meta); + } + else + { + obj["transaction"] = ripple::strHex(txnPlusMeta.transaction); + obj["metadata"] = ripple::strHex(txnPlusMeta.metadata); + } + obj["ledger_sequence"] = txnPlusMeta.ledgerSequence; txns.push_back(obj); } response["transactions"] = txns; diff --git a/handlers/Ledger.cpp b/handlers/Ledger.cpp index b5ec7cec..96dd3e83 100644 --- a/handlers/Ledger.cpp +++ b/handlers/Ledger.cpp @@ -1,5 +1,21 @@ #include #include +std::vector +ledgerInfoToBlob(ripple::LedgerInfo const& info) +{ + ripple::Serializer s; + s.add32(info.seq); + s.add64(info.drops.drops()); + s.addBitString(info.parentHash); + s.addBitString(info.txHash); + s.addBitString(info.accountHash); + s.add32(info.parentCloseTime.time_since_epoch().count()); + s.add32(info.closeTime.time_since_epoch().count()); + s.add8(info.closeTimeResolution.count()); + s.add8(info.closeFlags); + // s.addBitString(info.hash); + return s.peekData(); +} boost::json::object doLedger(boost::json::object const& request, BackendInterface const& backend) @@ -10,6 +26,13 @@ doLedger(boost::json::object const& request, BackendInterface const& backend) response["error"] = "Please specify a ledger index"; return response; } + bool binary = + request.contains("binary") ? request.at("binary").as_bool() : false; + bool getTransactions = request.contains("transactions") + ? request.at("transactions").as_bool() + : false; + bool expand = + request.contains("expand") ? request.at("expand").as_bool() : false; auto ledgerSequence = ledgerSequenceFromRequest(request, backend); if (!ledgerSequence) { @@ -24,35 +47,71 @@ doLedger(boost::json::object const& request, BackendInterface const& backend) return response; } boost::json::object header; - header["ledger_sequence"] = lgrInfo->seq; - header["ledger_hash"] = ripple::strHex(lgrInfo->hash); - header["txns_hash"] = ripple::strHex(lgrInfo->txHash); - header["state_hash"] = ripple::strHex(lgrInfo->accountHash); - header["parent_hash"] = ripple::strHex(lgrInfo->parentHash); - header["total_coins"] = ripple::to_string(lgrInfo->drops); - header["close_flags"] = lgrInfo->closeFlags; + if (binary) + { + header["blob"] = ripple::strHex(ledgerInfoToBlob(*lgrInfo)); + } + else + { + header["ledger_sequence"] = lgrInfo->seq; + header["ledger_hash"] = ripple::strHex(lgrInfo->hash); + header["txns_hash"] = ripple::strHex(lgrInfo->txHash); + header["state_hash"] = ripple::strHex(lgrInfo->accountHash); + header["parent_hash"] = ripple::strHex(lgrInfo->parentHash); + header["total_coins"] = ripple::to_string(lgrInfo->drops); + header["close_flags"] = lgrInfo->closeFlags; - // Always show fields that contribute to the ledger hash - header["parent_close_time"] = - lgrInfo->parentCloseTime.time_since_epoch().count(); - header["close_time"] = lgrInfo->closeTime.time_since_epoch().count(); - header["close_time_resolution"] = lgrInfo->closeTimeResolution.count(); - auto txns = backend.fetchAllTransactionsInLedger(*ledgerSequence); - response["transactions"] = boost::json::value(boost::json::array_kind); - boost::json::array& jsonTransactions = - response.at("transactions").as_array(); - - std::transform( - std::move_iterator(txns.begin()), - std::move_iterator(txns.end()), - std::back_inserter(jsonTransactions), - [](auto obj) { - boost::json::object entry; - auto [sttx, meta] = deserializeTxPlusMeta(obj); - entry["transaction"] = getJson(*sttx); - entry["meta"] = getJson(*meta); - return entry; - }); + // Always show fields that contribute to the ledger hash + header["parent_close_time"] = + lgrInfo->parentCloseTime.time_since_epoch().count(); + header["close_time"] = lgrInfo->closeTime.time_since_epoch().count(); + header["close_time_resolution"] = lgrInfo->closeTimeResolution.count(); + } + response["header"] = header; + if (getTransactions) + { + response["transactions"] = boost::json::value(boost::json::array_kind); + boost::json::array& jsonTransactions = + response.at("transactions").as_array(); + if (expand) + { + auto txns = backend.fetchAllTransactionsInLedger(*ledgerSequence); + std::transform( + std::move_iterator(txns.begin()), + std::move_iterator(txns.end()), + std::back_inserter(jsonTransactions), + [binary](auto obj) { + boost::json::object entry; + if (!binary) + { + auto [sttx, meta] = deserializeTxPlusMeta(obj); + entry["transaction"] = getJson(*sttx); + entry["metadata"] = getJson(*meta); + } + else + { + entry["transaction"] = ripple::strHex(obj.transaction); + entry["metadata"] = ripple::strHex(obj.metadata); + } + entry["ledger_sequence"] = obj.ledgerSequence; + return entry; + }); + } + else + { + auto hashes = + backend.fetchAllTransactionHashesInLedger(*ledgerSequence); + std::transform( + std::move_iterator(hashes.begin()), + std::move_iterator(hashes.end()), + std::back_inserter(jsonTransactions), + [](auto hash) { + boost::json::object entry; + entry["hash"] = ripple::strHex(hash); + return entry; + }); + } + } return response; } diff --git a/handlers/Tx.cpp b/handlers/Tx.cpp index ee9304a5..14390ddb 100644 --- a/handlers/Tx.cpp +++ b/handlers/Tx.cpp @@ -58,9 +58,20 @@ doTx(boost::json::object const& request, BackendInterface const& backend) return response; } - auto [sttx, meta] = deserializeTxPlusMeta(dbResponse.value()); - response["transaction"] = getJson(*sttx); - response["meta"] = getJson(*meta); + bool binary = + request.contains("binary") ? request.at("binary").as_bool() : false; + if (!binary) + { + auto [sttx, meta] = deserializeTxPlusMeta(dbResponse.value()); + response["transaction"] = getJson(*sttx); + response["metadata"] = getJson(*meta); + } + else + { + response["transaction"] = ripple::strHex(dbResponse->transaction); + response["metadata"] = ripple::strHex(dbResponse->metadata); + } + response["ledger_sequence"] = dbResponse->ledgerSequence; return response; } diff --git a/reporting/BackendInterface.h b/reporting/BackendInterface.h index 287605a2..8f13c494 100644 --- a/reporting/BackendInterface.h +++ b/reporting/BackendInterface.h @@ -19,6 +19,7 @@ struct TransactionAndMetadata { Blob transaction; Blob metadata; + uint32_t ledgerSequence; }; struct AccountTransactionsCursor @@ -57,6 +58,9 @@ public: virtual std::vector fetchAllTransactionsInLedger(uint32_t ledgerSequence) const = 0; + virtual std::vector + fetchAllTransactionHashesInLedger(uint32_t ledgerSequence) const = 0; + virtual LedgerPage fetchLedgerPage( std::optional const& cursor, diff --git a/reporting/CassandraBackend.cpp b/reporting/CassandraBackend.cpp index 56cc0c17..5eff09f2 100644 --- a/reporting/CassandraBackend.cpp +++ b/reporting/CassandraBackend.cpp @@ -178,7 +178,8 @@ flatMapReadCallback(CassFuture* fut, void* cbData) if (!!result) { - requestParams.result = {result.getBytes(), result.getBytes()}; + requestParams.result = { + result.getBytes(), result.getBytes(), result.getUInt32()}; } } @@ -239,10 +240,30 @@ CassandraBackend::fetchAllTransactionsInLedger(uint32_t ledgerSequence) const std::vector txns; do { - txns.push_back({result.getBytes(), result.getBytes()}); + txns.push_back( + {result.getBytes(), result.getBytes(), result.getUInt32()}); } while (result.nextRow()); return txns; } +std::vector +CassandraBackend::fetchAllTransactionHashesInLedger( + uint32_t ledgerSequence) const +{ + CassandraStatement statement{selectAllTransactionHashesInLedger_}; + statement.bindInt(ledgerSequence); + CassandraResult result = executeSyncRead(statement); + if (!result) + { + BOOST_LOG_TRIVIAL(error) << __func__ << " - no rows"; + return {}; + } + std::vector hashes; + do + { + hashes.push_back(result.getUInt256()); + } while (result.nextRow()); + return hashes; +} void CassandraBackend::open() @@ -622,19 +643,25 @@ CassandraBackend::open() continue; query = {}; - query << "SELECT transaction,metadata FROM " << tablePrefix - << "transactions" + query << "SELECT transaction, metadata, ledger_sequence FROM " + << tablePrefix << "transactions" << " WHERE hash = ?"; if (!selectTransaction_.prepareStatement(query, session_.get())) continue; query = {}; - query << "SELECT transaction,metadata FROM " << tablePrefix - << "transactions" + query << "SELECT transaction, metadata, ledger_sequence FROM " + << tablePrefix << "transactions" << " WHERE ledger_sequence = ?"; if (!selectAllTransactionsInLedger_.prepareStatement( query, session_.get())) continue; + query = {}; + query << "SELECT hash FROM " << tablePrefix << "transactions" + << " WHERE ledger_sequence = ?"; + if (!selectAllTransactionHashesInLedger_.prepareStatement( + query, session_.get())) + continue; query = {}; query << "SELECT key FROM " << tablePrefix << "keys " diff --git a/reporting/CassandraBackend.h b/reporting/CassandraBackend.h index c6b91f8b..79d5659c 100644 --- a/reporting/CassandraBackend.h +++ b/reporting/CassandraBackend.h @@ -542,6 +542,7 @@ private: CassandraPreparedStatement insertTransaction_; CassandraPreparedStatement selectTransaction_; CassandraPreparedStatement selectAllTransactionsInLedger_; + CassandraPreparedStatement selectAllTransactionHashesInLedger_; CassandraPreparedStatement selectObject_; CassandraPreparedStatement selectLedgerPageKeys_; CassandraPreparedStatement selectLedgerPage_; @@ -806,6 +807,9 @@ public: std::vector fetchAllTransactionsInLedger(uint32_t ledgerSequence) const override; + std::vector + fetchAllTransactionHashesInLedger(uint32_t ledgerSequence) const override; + // Synchronously fetch the object with key key and store the result in // pno // @param key the key of the object @@ -859,7 +863,7 @@ public: BOOST_LOG_TRIVIAL(error) << __func__ << " - no rows"; return {}; } - return {{result.getBytes(), result.getBytes()}}; + return {{result.getBytes(), result.getBytes(), result.getUInt32()}}; } LedgerPage fetchLedgerPage2( @@ -1212,8 +1216,8 @@ public: , isDeleted(isDeleted) , book(std::move(book)) { - if (isCreated or isDeleted) - ++refs; + // if (isCreated or isDeleted) + // ++refs; if (book) ++refs; } diff --git a/reporting/PostgresBackend.cpp b/reporting/PostgresBackend.cpp index f1a662ba..62335b93 100644 --- a/reporting/PostgresBackend.cpp +++ b/reporting/PostgresBackend.cpp @@ -263,7 +263,10 @@ PostgresBackend::fetchTransaction(ripple::uint256 const& hash) const auto res = pgQuery(sql.str().data()); if (checkResult(res, 3)) { - return {{res.asUnHexedBlob(0, 0), res.asUnHexedBlob(0, 1)}}; + return { + {res.asUnHexedBlob(0, 0), + res.asUnHexedBlob(0, 1), + res.asBigInt(0, 2)}}; } return {}; @@ -281,12 +284,35 @@ PostgresBackend::fetchAllTransactionsInLedger(uint32_t ledgerSequence) const std::vector txns; for (size_t i = 0; i < numRows; ++i) { - txns.push_back({res.asUnHexedBlob(i, 0), res.asUnHexedBlob(i, 1)}); + txns.push_back( + {res.asUnHexedBlob(i, 0), + res.asUnHexedBlob(i, 1), + res.asBigInt(i, 2)}); } return txns; } return {}; } +std::vector +PostgresBackend::fetchAllTransactionHashesInLedger( + uint32_t ledgerSequence) const +{ + PgQuery pgQuery(pgPool_); + std::stringstream sql; + sql << "SELECT hash FROM transactions WHERE " + << "ledger_seq = " << std::to_string(ledgerSequence); + auto res = pgQuery(sql.str().data()); + if (size_t numRows = checkResult(res, 3)) + { + std::vector hashes; + for (size_t i = 0; i < numRows; ++i) + { + hashes.push_back(res.asUInt256(i, 0)); + } + return hashes; + } + return {}; +} LedgerPage PostgresBackend::fetchLedgerPage( @@ -384,7 +410,9 @@ PostgresBackend::fetchTransactions( for (size_t i = 0; i < numRows; ++i) { results.push_back( - {res.asUnHexedBlob(i, 0), res.asUnHexedBlob(i, 1)}); + {res.asUnHexedBlob(i, 0), + res.asUnHexedBlob(i, 1), + res.asBigInt(i, 2)}); } return results; } diff --git a/reporting/PostgresBackend.h b/reporting/PostgresBackend.h index 0757f3e4..238d5749 100644 --- a/reporting/PostgresBackend.h +++ b/reporting/PostgresBackend.h @@ -38,6 +38,9 @@ public: std::vector fetchAllTransactionsInLedger(uint32_t ledgerSequence) const override; + std::vector + fetchAllTransactionHashesInLedger(uint32_t ledgerSequence) const override; + LedgerPage fetchLedgerPage( std::optional const& cursor, diff --git a/reporting/ReportingETL.cpp b/reporting/ReportingETL.cpp index 90d616be..0c45821c 100644 --- a/reporting/ReportingETL.cpp +++ b/reporting/ReportingETL.cpp @@ -643,5 +643,7 @@ ReportingETL::ReportingETL( ioc) { flatMapBackend_->open(); + if (config.contains("start_sequence")) + startSequence_ = config.at("start_sequence").as_int64(); } diff --git a/test.py b/test.py index 9d30d78f..13811f8a 100755 --- a/test.py +++ b/test.py @@ -10,55 +10,81 @@ import argparse import time import threading +def checkAccountInfo(aldous, p2p): + return isSubset(aldous["object"], p2p["result"]["account_data"]) + +def isSubset(sub, sup): + for x in sub: + if x == "deserialization_time_microsecond": + continue + if not x in sup: + return False + elif not sub[x] == sup[x]: + return False + return True -async def account_info(ip, port, account, ledger): +def compareAccountInfo(aldous, p2p): + p2p = p2p["result"]["account_data"] + aldous = aldous["object"] + if isSubset(p2p,aldous): + print("Responses match!!") + else: + print("Response mismatch") + print(aldous) + print(p2p) + + + +async def account_info(ip, port, account, ledger, binary): address = 'ws://' + str(ip) + ':' + str(port) + print(binary) try: async with websockets.connect(address) as ws: if ledger is None: - await ws.send(json.dumps({"command":"account_info","account":account})) + await ws.send(json.dumps({"command":"account_info","account":account, "binary":bool(binary)})) res = json.loads(await ws.recv()) print(json.dumps(res,indent=4,sort_keys=True)) else: - await ws.send(json.dumps({"command":"account_info","account":account, "ledger_index":int(ledger)})) + await ws.send(json.dumps({"command":"account_info","account":account, "ledger_index":int(ledger), "binary":bool(binary)})) res = json.loads(await ws.recv()) print(json.dumps(res,indent=4,sort_keys=True)) + return res except websockets.exceptions.ConnectionClosedError as e: print(e) -async def account_tx(ip, port, account): +async def account_tx(ip, port, account, binary): address = 'ws://' + str(ip) + ':' + str(port) try: async with websockets.connect(address) as ws: - await ws.send(json.dumps({"command":"account_tx","account":account})) + await ws.send(json.dumps({"command":"account_tx","account":account, "binary":bool(binary)})) res = json.loads(await ws.recv()) print(json.dumps(res,indent=4,sort_keys=True)) except websockets.exceptions.ConnectionClosedError as e: print(e) -async def tx(ip, port, tx_hash): +async def tx(ip, port, tx_hash, binary): address = 'ws://' + str(ip) + ':' + str(port) try: async with websockets.connect(address) as ws: - await ws.send(json.dumps({"command":"tx","transaction":tx_hash})) + await ws.send(json.dumps({"command":"tx","transaction":tx_hash,"binary":bool(binary)})) res = json.loads(await ws.recv()) print(json.dumps(res,indent=4,sort_keys=True)) except websockets.exceptions.connectionclosederror as e: print(e) -async def ledger_data(ip, port, ledger, limit): +async def ledger_data(ip, port, ledger, limit, binary): address = 'ws://' + str(ip) + ':' + str(port) try: async with websockets.connect(address) as ws: - await ws.send(json.dumps({"command":"ledger_data","ledger_index":int(ledger),"binary":True})) + await ws.send(json.dumps({"command":"ledger_data","ledger_index":int(ledger),"binary":bool(binary)})) res = json.loads(await ws.recv()) print(json.dumps(res,indent=4,sort_keys=True)) except websockets.exceptions.connectionclosederror as e: print(e) -async def ledger_data_full(ip, port, ledger): +async def ledger_data_full(ip, port, ledger, binary): address = 'ws://' + str(ip) + ':' + str(port) try: @@ -66,12 +92,12 @@ async def ledger_data_full(ip, port, ledger): marker = None while True: if marker is None: - await ws.send(json.dumps({"command":"ledger_data","ledger_index":int(ledger),"binary":True})) + await ws.send(json.dumps({"command":"ledger_data","ledger_index":int(ledger),"binary":bool(binary)})) res = json.loads(await ws.recv()) else: - await ws.send(json.dumps({"command":"ledger_data","ledger_index":int(ledger),"cursor":marker, "binary":True})) + await ws.send(json.dumps({"command":"ledger_data","ledger_index":int(ledger),"cursor":marker, "binary":bool(binary)})) res = json.loads(await ws.recv()) if "cursor" in res: @@ -87,7 +113,7 @@ async def ledger_data_full(ip, port, ledger): print(e) -async def book_offers(ip, port, ledger, pay_currency, pay_issuer, get_currency, get_issuer): +async def book_offers(ip, port, ledger, pay_currency, pay_issuer, get_currency, get_issuer, binary): address = 'ws://' + str(ip) + ':' + str(port) try: @@ -100,23 +126,77 @@ async def book_offers(ip, port, ledger, pay_currency, pay_issuer, get_currency, if pay_issuer is not None: taker_pays["issuer"] = pay_issuer - await ws.send(json.dumps({"command":"book_offers","ledger_index":int(ledger), "taker_pays":taker_pays, "taker_gets":taker_gets})) + await ws.send(json.dumps({"command":"book_offers","ledger_index":int(ledger), "taker_pays":taker_pays, "taker_gets":taker_gets, "binary":bool(binary)})) res = json.loads(await ws.recv()) print(json.dumps(res,indent=4,sort_keys=True)) except websockets.exceptions.connectionclosederror as e: print(e) -async def ledger(ip, port, ledger): +def compareLedger(aldous, p2p): + p2p = p2p["result"]["ledger"] + p2pHeader = p2p["ledger_data"] + aldousHeader = aldous["header"]["blob"] + if p2pHeader == aldousHeader: + print("Headers match!!!") + else: + print("Header mismatch") + print(aldousHeader) + print(p2pHeader) + return + + p2pTxns = [] + p2pMetas = [] + for x in p2p["transactions"]: + p2pTxns.append(x["tx_blob"]) + p2pMetas.append(x["meta"]) + aldousTxns = [] + aldousMetas = [] + for x in aldous["transactions"]: + aldousTxns.append(x["transaction"]) + aldousMetas.append(x["metadata"]) + + + + p2pTxns.sort() + p2pMetas.sort() + aldousTxns.sort() + aldousMetas.sort() + if p2pTxns == aldousTxns and p2pMetas == aldousMetas: + print("Responses match!!!") + else: + print("Mismatch responses") + print(aldous) + print(p2p) + + +def getHashes(res): + if "result" in res: + res = res["result"]["ledger"] + + hashes = [] + for x in res["transactions"]: + if "hash" in x: + hashes.append(x["hash"]) + elif "transaction" in x and "hash" in x["transaction"]: + hashes.append(x["transaction"]["hash"]) + return hashes + + +async def ledger(ip, port, ledger, binary, transactions, expand): address = 'ws://' + str(ip) + ':' + str(port) + hashes = [] try: async with websockets.connect(address) as ws: - await ws.send(json.dumps({"command":"ledger","ledger_index":int(ledger)})) + await ws.send(json.dumps({"command":"ledger","ledger_index":int(ledger),"binary":bool(binary), "transactions":bool(transactions),"expand":bool(expand)})) res = json.loads(await ws.recv()) - print(json.dumps(res,indent=4,sort_keys=True)) + print(res) + return res + except websockets.exceptions.connectionclosederror as e: print(e) + return hashes async def ledger_range(ip, port): address = 'ws://' + str(ip) + ':' + str(port) try: @@ -124,6 +204,11 @@ async def ledger_range(ip, port): await ws.send(json.dumps({"command":"ledger_range"})) res = json.loads(await ws.recv()) print(json.dumps(res,indent=4,sort_keys=True)) + if "error" in res: + await ws.send(json.dumps({"command":"server_info"})) + res = json.loads(await ws.recv()) + print(res) + return res["result"]["info"]["validated_ledger"]["seq"] return res["ledger_index_max"] except websockets.exceptions.connectionclosederror as e: print(e) @@ -133,13 +218,19 @@ parser.add_argument('action', choices=["account_info", "tx", "account_tx", "ledg parser.add_argument('--ip', default='127.0.0.1') parser.add_argument('--port', default='8080') parser.add_argument('--hash') -parser.add_argument('--account', default="rLC64xxNif3GiY9FQnbaM4kcE6VvDhwRod") +parser.add_argument('--account', default="rw2ciyaNshpHe7bCHo4bRWq6pqqynnWKQg") parser.add_argument('--ledger') parser.add_argument('--limit', default='200') parser.add_argument('--taker_pays_issuer',default='rvYAfWj5gh67oV6fW32ZzP3Aw4Eubs59B') parser.add_argument('--taker_pays_currency',default='USD') parser.add_argument('--taker_gets_issuer') parser.add_argument('--taker_gets_currency',default='XRP') +parser.add_argument('--p2pIp', default='127.0.0.1') +parser.add_argument('--p2pPort', default='6005') +parser.add_argument('--verify',default=False) +parser.add_argument('--binary',default=False) +parser.add_argument('--expand',default=False) +parser.add_argument('--transactions',default=False) @@ -147,35 +238,49 @@ parser.add_argument('--taker_gets_currency',default='XRP') args = parser.parse_args() def run(args): + asyncio.set_event_loop(asyncio.new_event_loop()) if(args.ledger is None): args.ledger = asyncio.get_event_loop().run_until_complete(ledger_range(args.ip, args.port)); - asyncio.set_event_loop(asyncio.new_event_loop()) if args.action == "account_info": - asyncio.get_event_loop().run_until_complete( - account_info(args.ip, args.port, args.account, args.ledger)) + res1 = asyncio.get_event_loop().run_until_complete( + account_info(args.ip, args.port, args.account, args.ledger, args.binary)) + if args.verify: + res2 = asyncio.get_event_loop().run_until_complete( + account_info(args.p2pIp, args.p2pPort, args.account, args.ledger, args.binary)) + print(compareAccountInfo(res1,res2)) elif args.action == "tx": + if args.hash is None: + args.hash = getHashes(asyncio.get_event_loop().run_until_complete(ledger(args.ip,args.port,args.ledger,False,True,False)))[0] asyncio.get_event_loop().run_until_complete( - tx(args.ip, args.port, args.hash)) + tx(args.ip, args.port, args.hash, args.binary)) elif args.action == "account_tx": asyncio.get_event_loop().run_until_complete( - account_tx(args.ip, args.port, args.account)) + account_tx(args.ip, args.port, args.account, args.binary)) elif args.action == "ledger_data": asyncio.get_event_loop().run_until_complete( - ledger_data(args.ip, args.port, args.ledger, args.limit)) + ledger_data(args.ip, args.port, args.ledger, args.limit, args.binary)) elif args.action == "ledger_data_full": asyncio.get_event_loop().run_until_complete( - ledger_data_full(args.ip, args.port, args.ledger)) + ledger_data_full(args.ip, args.port, args.ledger, args.binary)) elif args.action == "ledger": - asyncio.get_event_loop().run_until_complete( - ledger(args.ip, args.port, args.ledger)) + + res = asyncio.get_event_loop().run_until_complete( + ledger(args.ip, args.port, args.ledger, args.binary, args.transactions, args.expand)) + if args.verify: + res2 = asyncio.get_event_loop().run_until_complete( + ledger(args.p2pIp, args.p2pPort, args.ledger, args.binary, args.transactions, args.expand)) + print(compareLedger(res,res2)) + elif args.action == "ledger_range": asyncio.get_event_loop().run_until_complete( ledger_range(args.ip, args.port)) elif args.action == "book_offers": asyncio.get_event_loop().run_until_complete( - book_offers(args.ip, args.port, args.ledger, args.taker_pays_currency, args.taker_pays_issuer, args.taker_gets_currency, args.taker_gets_issuer)) + book_offers(args.ip, args.port, args.ledger, args.taker_pays_currency, args.taker_pays_issuer, args.taker_gets_currency, args.taker_gets_issuer, args.binary)) else: print("incorrect arguments") -run(args) + + +run(args)