ledger_nonce test

This commit is contained in:
Richard Holland
2022-12-28 17:52:44 +00:00
parent f1c5cf99be
commit 77c76c044e
4 changed files with 124 additions and 1 deletions

View File

@@ -3164,12 +3164,24 @@ DEFINE_HOOK_FUNCTION(
auto hash = ripple::sha512Half( auto hash = ripple::sha512Half(
ripple::HashPrefix::hookNonce, ripple::HashPrefix::hookNonce,
view.info().seq, view.info().seq,
view.info().parentCloseTime, view.info().parentCloseTime.time_since_epoch().count(),
applyCtx.app.getLedgerMaster().getValidatedLedger()->info().hash, applyCtx.app.getLedgerMaster().getValidatedLedger()->info().hash,
applyCtx.tx.getTransactionID(), applyCtx.tx.getTransactionID(),
hookCtx.ledger_nonce_counter++, hookCtx.ledger_nonce_counter++,
hookCtx.result.account hookCtx.result.account
); );
/*
std::cout <<
"seq: " << view.info().seq <<
", llc: " << view.info().parentCloseTime.time_since_epoch().count() <<
", llh: " << applyCtx.app.getLedgerMaster().getValidatedLedger()->info().hash <<
", txid: " << applyCtx.tx.getTransactionID() <<
", count: " << hookCtx.ledger_nonce_counter <<
", acc: " << hookCtx.result.account <<
", nonce: " << hash << "\n";
*/
WRITE_WASM_MEMORY_AND_RETURN( WRITE_WASM_MEMORY_AND_RETURN(
write_ptr, 32, write_ptr, 32,

View File

@@ -4074,6 +4074,107 @@ public:
void void
test_ledger_nonce() test_ledger_nonce()
{ {
testcase("Test ledger_nonce");
using namespace jtx;
Env env{*this, supported_amendments()};
auto const alice = Account{"alice"};
auto const bob = Account{"bob"};
env.fund(XRP(10000), alice);
env.fund(XRP(10000), bob);
TestHook hook = wasm[R"[test.hook](
#include <stdint.h>
extern int32_t _g (uint32_t id, uint32_t maxiter);
#define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1)
extern int64_t accept (uint32_t read_ptr, uint32_t read_len, int64_t error_code);
extern int64_t rollback (uint32_t read_ptr, uint32_t read_len, int64_t error_code);
extern int64_t ledger_nonce (uint32_t, uint32_t);
#define TOO_SMALL -4
#define OUT_OF_BOUNDS -1
#define ASSERT(x)\
if (!(x))\
rollback((uint32_t)#x, sizeof(#x), __LINE__);
int64_t hook(uint32_t reserved )
{
_g(1,1);
uint8_t nonce[64];
// Test out of bounds check
ASSERT(ledger_nonce(1000000, 32) == OUT_OF_BOUNDS);
ASSERT(ledger_nonce((uint32_t)nonce, 31) == TOO_SMALL);
ASSERT(ledger_nonce((uint32_t)nonce, 32) == 32);
ASSERT(ledger_nonce((uint32_t)(nonce + 32), 32) == 32);
// return the two nonces as the return string
accept((uint32_t)nonce, 64, 0);
}
)[test.hook]"];
// install the hook on alice
env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0),
M("set ledger_nonce"),
HSFEE);
env.close();
// invoke the hook
auto const seq = env.app().getLedgerMaster().getCurrentLedger()->info().seq;
auto const llc = env.app().getLedgerMaster().getCurrentLedger()->info().parentCloseTime.time_since_epoch().count();
auto const llh = env.app().getLedgerMaster().getCurrentLedger()->info().hash;
env(pay(bob, alice, XRP(1)), M("test ledger_nonce"), fee(XRP(1)));
auto const txid = env.txid();
auto meta = env.meta();
// ensure hook execution occured
BEAST_REQUIRE(meta);
BEAST_REQUIRE(meta->isFieldPresent(sfHookExecutions));
// ensure there was only one hook execution
auto const hookExecutions =
meta->getFieldArray(sfHookExecutions);
BEAST_REQUIRE(hookExecutions.size() == 1);
// get the data in the return string of the extention
auto const retStr =
hookExecutions[0].getFieldVL(sfHookReturnString);
// check that it matches the expected size (two nonces = 64 bytes)
BEAST_EXPECT(retStr.size() == 64);
auto const computed_hash_1 = ripple::sha512Half(
ripple::HashPrefix::hookNonce,
seq, llc, llh,
txid,
(uint16_t)0UL,
alice.id()
);
auto const computed_hash_2 = ripple::sha512Half(
ripple::HashPrefix::hookNonce,
seq, llc, llh,
txid,
(uint16_t)1UL, // second nonce
alice.id()
);
/*
std::cout <<
"seq: " << seq <<
", llc: " << llc <<
", llh: " << llh <<
", txid: " << txid <<
", count: 0" <<
", acc: " << alice.human() <<
", nonce: " << computed_hash_1 << ", " << computed_hash_2 << "\n";
*/
BEAST_EXPECT(computed_hash_1 == uint256::fromVoid(retStr.data()));
BEAST_EXPECT(computed_hash_2 == uint256::fromVoid(retStr.data() + 32));
} }
void void

View File

@@ -596,6 +596,9 @@ public:
if constexpr (sizeof...(args) > 0) if constexpr (sizeof...(args) > 0)
fund(amount, args...); fund(amount, args...);
} }
// get the last txn id
uint256 txid() const;
/** Establish trust lines. /** Establish trust lines.
@@ -637,6 +640,7 @@ protected:
uint256 txid_; uint256 txid_;
TER ter_ = tesSUCCESS; TER ter_ = tesSUCCESS;
Json::Value Json::Value
do_rpc( do_rpc(
std::vector<std::string> const& args, std::vector<std::string> const& args,

View File

@@ -395,6 +395,12 @@ Env::tx() const
return current()->txRead(txid_).first; return current()->txRead(txid_).first;
} }
uint256
Env::txid() const
{
return txid_;
}
void void
Env::autofill_sig(JTx& jt) Env::autofill_sig(JTx& jt)
{ {