mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-02 00:15:50 +00:00
preliminary version of emit test cases
This commit is contained in:
@@ -2795,9 +2795,12 @@ DEFINE_HOOK_FUNCTION(
|
||||
if (NOT_IN_BOUNDS(read_ptr, read_len, memory_length))
|
||||
return OUT_OF_BOUNDS;
|
||||
|
||||
if (NOT_IN_BOUNDS(write_ptr, 32, memory_length))
|
||||
if (NOT_IN_BOUNDS(write_ptr, write_len, memory_length))
|
||||
return OUT_OF_BOUNDS;
|
||||
|
||||
if (write_len < 32)
|
||||
return TOO_SMALL;
|
||||
|
||||
auto& app = hookCtx.applyCtx.app;
|
||||
|
||||
if (hookCtx.expected_etxn_count < 0)
|
||||
|
||||
@@ -1873,6 +1873,343 @@ public:
|
||||
void
|
||||
test_emit()
|
||||
{
|
||||
testcase("Test float_compare");
|
||||
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, uint32_t);
|
||||
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 emit (uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
extern int64_t etxn_reserve(uint32_t);
|
||||
extern int64_t otxn_param(uint32_t, uint32_t, uint32_t, uint32_t);
|
||||
extern int64_t hook_account(uint32_t, uint32_t);
|
||||
#define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1)
|
||||
#define OUT_OF_BOUNDS (-1)
|
||||
#define ttPAYMENT 0
|
||||
#define tfCANONICAL 0x80000000UL
|
||||
#define amAMOUNT 1U
|
||||
#define amFEE 8U
|
||||
#define atACCOUNT 1U
|
||||
#define DOESNT_EXIST (-5)
|
||||
#define atDESTINATION 3U
|
||||
#define SBUF(x) (uint32_t)x,sizeof(x)
|
||||
|
||||
#define ENCODE_DROPS_SIZE 9
|
||||
#define ENCODE_DROPS(buf_out, drops, amount_type ) \
|
||||
{\
|
||||
uint8_t uat = amount_type; \
|
||||
uint64_t udrops = drops; \
|
||||
buf_out[0] = 0x60U +(uat & 0x0FU ); \
|
||||
buf_out[1] = 0b01000000 + (( udrops >> 56 ) & 0b00111111 ); \
|
||||
buf_out[2] = (udrops >> 48) & 0xFFU; \
|
||||
buf_out[3] = (udrops >> 40) & 0xFFU; \
|
||||
buf_out[4] = (udrops >> 32) & 0xFFU; \
|
||||
buf_out[5] = (udrops >> 24) & 0xFFU; \
|
||||
buf_out[6] = (udrops >> 16) & 0xFFU; \
|
||||
buf_out[7] = (udrops >> 8) & 0xFFU; \
|
||||
buf_out[8] = (udrops >> 0) & 0xFFU; \
|
||||
buf_out += ENCODE_DROPS_SIZE; \
|
||||
}
|
||||
|
||||
#define _06_XX_ENCODE_DROPS(buf_out, drops, amount_type )\
|
||||
ENCODE_DROPS(buf_out, drops, amount_type );
|
||||
|
||||
#define ENCODE_DROPS_AMOUNT(buf_out, drops )\
|
||||
ENCODE_DROPS(buf_out, drops, amAMOUNT );
|
||||
#define _06_01_ENCODE_DROPS_AMOUNT(buf_out, drops )\
|
||||
ENCODE_DROPS_AMOUNT(buf_out, drops );
|
||||
|
||||
#define ENCODE_DROPS_FEE(buf_out, drops )\
|
||||
ENCODE_DROPS(buf_out, drops, amFEE );
|
||||
#define _06_08_ENCODE_DROPS_FEE(buf_out, drops )\
|
||||
ENCODE_DROPS_FEE(buf_out, drops );
|
||||
|
||||
#define ENCODE_TT_SIZE 3
|
||||
#define ENCODE_TT(buf_out, tt )\
|
||||
{\
|
||||
uint8_t utt = tt;\
|
||||
buf_out[0] = 0x12U;\
|
||||
buf_out[1] =(utt >> 8 ) & 0xFFU;\
|
||||
buf_out[2] =(utt >> 0 ) & 0xFFU;\
|
||||
buf_out += ENCODE_TT_SIZE; \
|
||||
}
|
||||
#define _01_02_ENCODE_TT(buf_out, tt)\
|
||||
ENCODE_TT(buf_out, tt);
|
||||
|
||||
|
||||
#define ENCODE_ACCOUNT_SIZE 22
|
||||
#define ENCODE_ACCOUNT(buf_out, account_id, account_type)\
|
||||
{\
|
||||
uint8_t uat = account_type;\
|
||||
buf_out[0] = 0x80U + uat;\
|
||||
buf_out[1] = 0x14U;\
|
||||
*(uint64_t*)(buf_out + 2) = *(uint64_t*)(account_id + 0);\
|
||||
*(uint64_t*)(buf_out + 10) = *(uint64_t*)(account_id + 8);\
|
||||
*(uint32_t*)(buf_out + 18) = *(uint32_t*)(account_id + 16);\
|
||||
buf_out += ENCODE_ACCOUNT_SIZE;\
|
||||
}
|
||||
#define _08_XX_ENCODE_ACCOUNT(buf_out, account_id, account_type)\
|
||||
ENCODE_ACCOUNT(buf_out, account_id, account_type);
|
||||
|
||||
#define ENCODE_ACCOUNT_SRC_SIZE 22
|
||||
#define ENCODE_ACCOUNT_SRC(buf_out, account_id)\
|
||||
ENCODE_ACCOUNT(buf_out, account_id, atACCOUNT);
|
||||
#define _08_01_ENCODE_ACCOUNT_SRC(buf_out, account_id)\
|
||||
ENCODE_ACCOUNT_SRC(buf_out, account_id);
|
||||
|
||||
#define ENCODE_ACCOUNT_DST_SIZE 22
|
||||
#define ENCODE_ACCOUNT_DST(buf_out, account_id)\
|
||||
ENCODE_ACCOUNT(buf_out, account_id, atDESTINATION);
|
||||
#define _08_03_ENCODE_ACCOUNT_DST(buf_out, account_id)\
|
||||
ENCODE_ACCOUNT_DST(buf_out, account_id);
|
||||
|
||||
#define ENCODE_ACCOUNT_OWNER_SIZE 22
|
||||
#define ENCODE_ACCOUNT_OWNER(buf_out, account_id) \
|
||||
ENCODE_ACCOUNT(buf_out, account_id, atOWNER);
|
||||
#define _08_02_ENCODE_ACCOUNT_OWNER(buf_out, account_id) \
|
||||
ENCODE_ACCOUNT_OWNER(buf_out, account_id);
|
||||
|
||||
#define ENCODE_UINT32_COMMON_SIZE 5U
|
||||
#define ENCODE_UINT32_COMMON(buf_out, i, field)\
|
||||
{\
|
||||
uint32_t ui = i; \
|
||||
uint8_t uf = field; \
|
||||
buf_out[0] = 0x20U +(uf & 0x0FU); \
|
||||
buf_out[1] =(ui >> 24 ) & 0xFFU; \
|
||||
buf_out[2] =(ui >> 16 ) & 0xFFU; \
|
||||
buf_out[3] =(ui >> 8 ) & 0xFFU; \
|
||||
buf_out[4] =(ui >> 0 ) & 0xFFU; \
|
||||
buf_out += ENCODE_UINT32_COMMON_SIZE; \
|
||||
}
|
||||
#define _02_XX_ENCODE_UINT32_COMMON(buf_out, i, field)\
|
||||
ENCODE_UINT32_COMMON(buf_out, i, field)\
|
||||
|
||||
#define ENCODE_UINT32_UNCOMMON_SIZE 6U
|
||||
#define ENCODE_UINT32_UNCOMMON(buf_out, i, field)\
|
||||
{\
|
||||
uint32_t ui = i; \
|
||||
uint8_t uf = field; \
|
||||
buf_out[0] = 0x20U; \
|
||||
buf_out[1] = uf; \
|
||||
buf_out[2] =(ui >> 24 ) & 0xFFU; \
|
||||
buf_out[3] =(ui >> 16 ) & 0xFFU; \
|
||||
buf_out[4] =(ui >> 8 ) & 0xFFU; \
|
||||
buf_out[5] =(ui >> 0 ) & 0xFFU; \
|
||||
buf_out += ENCODE_UINT32_UNCOMMON_SIZE; \
|
||||
}
|
||||
#define _02_XX_ENCODE_UINT32_UNCOMMON(buf_out, i, field)\
|
||||
ENCODE_UINT32_UNCOMMON(buf_out, i, field)\
|
||||
|
||||
#define ENCODE_LLS_SIZE 6U
|
||||
#define ENCODE_LLS(buf_out, lls )\
|
||||
ENCODE_UINT32_UNCOMMON(buf_out, lls, 0x1B );
|
||||
#define _02_27_ENCODE_LLS(buf_out, lls )\
|
||||
ENCODE_LLS(buf_out, lls );
|
||||
|
||||
#define ENCODE_FLS_SIZE 6U
|
||||
#define ENCODE_FLS(buf_out, fls )\
|
||||
ENCODE_UINT32_UNCOMMON(buf_out, fls, 0x1A );
|
||||
#define _02_26_ENCODE_FLS(buf_out, fls )\
|
||||
ENCODE_FLS(buf_out, fls );
|
||||
|
||||
#define ENCODE_TAG_SRC_SIZE 5
|
||||
#define ENCODE_TAG_SRC(buf_out, tag )\
|
||||
ENCODE_UINT32_COMMON(buf_out, tag, 0x3U );
|
||||
#define _02_03_ENCODE_TAG_SRC(buf_out, tag )\
|
||||
ENCODE_TAG_SRC(buf_out, tag );
|
||||
|
||||
#define ENCODE_TAG_DST_SIZE 5
|
||||
#define ENCODE_TAG_DST(buf_out, tag )\
|
||||
ENCODE_UINT32_COMMON(buf_out, tag, 0xEU );
|
||||
#define _02_14_ENCODE_TAG_DST(buf_out, tag )\
|
||||
ENCODE_TAG_DST(buf_out, tag );
|
||||
|
||||
#define ENCODE_SEQUENCE_SIZE 5
|
||||
#define ENCODE_SEQUENCE(buf_out, sequence )\
|
||||
ENCODE_UINT32_COMMON(buf_out, sequence, 0x4U );
|
||||
#define _02_04_ENCODE_SEQUENCE(buf_out, sequence )\
|
||||
ENCODE_SEQUENCE(buf_out, sequence );
|
||||
|
||||
#define ENCODE_FLAGS_SIZE 5
|
||||
#define ENCODE_FLAGS(buf_out, tag )\
|
||||
ENCODE_UINT32_COMMON(buf_out, tag, 0x2U );
|
||||
#define _02_02_ENCODE_FLAGS(buf_out, tag )\
|
||||
ENCODE_FLAGS(buf_out, tag );
|
||||
|
||||
#define ENCODE_SIGNING_PUBKEY_SIZE 35
|
||||
#define ENCODE_SIGNING_PUBKEY(buf_out, pkey )\
|
||||
{\
|
||||
buf_out[0] = 0x73U;\
|
||||
buf_out[1] = 0x21U;\
|
||||
*(uint64_t*)(buf_out + 2) = *(uint64_t*)(pkey + 0);\
|
||||
*(uint64_t*)(buf_out + 10) = *(uint64_t*)(pkey + 8);\
|
||||
*(uint64_t*)(buf_out + 18) = *(uint64_t*)(pkey + 16);\
|
||||
*(uint64_t*)(buf_out + 26) = *(uint64_t*)(pkey + 24);\
|
||||
buf[34] = pkey[32];\
|
||||
buf_out += ENCODE_SIGNING_PUBKEY_SIZE;\
|
||||
}
|
||||
|
||||
#define _07_03_ENCODE_SIGNING_PUBKEY(buf_out, pkey )\
|
||||
ENCODE_SIGNING_PUBKEY(buf_out, pkey );
|
||||
|
||||
#define ENCODE_SIGNING_PUBKEY_NULL_SIZE 35
|
||||
#define ENCODE_SIGNING_PUBKEY_NULL(buf_out )\
|
||||
{\
|
||||
buf_out[0] = 0x73U;\
|
||||
buf_out[1] = 0x21U;\
|
||||
*(uint64_t*)(buf_out+2) = 0;\
|
||||
*(uint64_t*)(buf_out+10) = 0;\
|
||||
*(uint64_t*)(buf_out+18) = 0;\
|
||||
*(uint64_t*)(buf_out+25) = 0;\
|
||||
buf_out += ENCODE_SIGNING_PUBKEY_NULL_SIZE;\
|
||||
}
|
||||
|
||||
#define _07_03_ENCODE_SIGNING_PUBKEY_NULL(buf_out )\
|
||||
ENCODE_SIGNING_PUBKEY_NULL(buf_out );
|
||||
|
||||
extern int64_t etxn_fee_base (
|
||||
uint32_t read_ptr,
|
||||
uint32_t read_len
|
||||
);
|
||||
extern int64_t etxn_details (
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len
|
||||
);
|
||||
extern int64_t ledger_seq (void);
|
||||
|
||||
#define PREPARE_PAYMENT_SIMPLE_SIZE 270U
|
||||
#define PREPARE_PAYMENT_SIMPLE(buf_out_master, drops_amount_raw, to_address, dest_tag_raw, src_tag_raw)\
|
||||
{\
|
||||
uint8_t* buf_out = buf_out_master;\
|
||||
uint8_t acc[20];\
|
||||
uint64_t drops_amount = (drops_amount_raw);\
|
||||
uint32_t dest_tag = (dest_tag_raw);\
|
||||
uint32_t src_tag = (src_tag_raw);\
|
||||
uint32_t cls = (uint32_t)ledger_seq();\
|
||||
hook_account(SBUF(acc));\
|
||||
_01_02_ENCODE_TT (buf_out, ttPAYMENT ); /* uint16 | size 3 */ \
|
||||
_02_02_ENCODE_FLAGS (buf_out, tfCANONICAL ); /* uint32 | size 5 */ \
|
||||
_02_03_ENCODE_TAG_SRC (buf_out, src_tag ); /* uint32 | size 5 */ \
|
||||
_02_04_ENCODE_SEQUENCE (buf_out, 0 ); /* uint32 | size 5 */ \
|
||||
_02_14_ENCODE_TAG_DST (buf_out, dest_tag ); /* uint32 | size 5 */ \
|
||||
_02_26_ENCODE_FLS (buf_out, cls + 1 ); /* uint32 | size 6 */ \
|
||||
_02_27_ENCODE_LLS (buf_out, cls + 5 ); /* uint32 | size 6 */ \
|
||||
_06_01_ENCODE_DROPS_AMOUNT (buf_out, drops_amount ); /* amount | size 9 */ \
|
||||
uint8_t* fee_ptr = buf_out;\
|
||||
_06_08_ENCODE_DROPS_FEE (buf_out, 0 ); /* amount | size 9 */ \
|
||||
_07_03_ENCODE_SIGNING_PUBKEY_NULL (buf_out ); /* pk | size 35 */ \
|
||||
_08_01_ENCODE_ACCOUNT_SRC (buf_out, acc ); /* account | size 22 */ \
|
||||
_08_03_ENCODE_ACCOUNT_DST (buf_out, to_address ); /* account | size 22 */ \
|
||||
int64_t edlen = etxn_details((uint32_t)buf_out, PREPARE_PAYMENT_SIMPLE_SIZE); /* emitdet | size 1?? */ \
|
||||
int64_t fee = etxn_fee_base(buf_out_master, PREPARE_PAYMENT_SIMPLE_SIZE); \
|
||||
_06_08_ENCODE_DROPS_FEE (fee_ptr, fee ); \
|
||||
}
|
||||
|
||||
#define UINT16_FROM_BUF(buf)\
|
||||
(((uint64_t)((buf)[0]) << 8U) +\
|
||||
((uint64_t)((buf)[1]) << 0U))
|
||||
|
||||
#define BUFFER_EQUAL_32(buf1, buf2)\
|
||||
(\
|
||||
*(((uint64_t*)(buf1)) + 0) == *(((uint64_t*)(buf2)) + 0) &&\
|
||||
*(((uint64_t*)(buf1)) + 1) == *(((uint64_t*)(buf2)) + 1) &&\
|
||||
*(((uint64_t*)(buf1)) + 2) == *(((uint64_t*)(buf2)) + 2) &&\
|
||||
*(((uint64_t*)(buf1)) + 3) == *(((uint64_t*)(buf2)) + 3) &&\
|
||||
*(((uint64_t*)(buf1)) + 4) == *(((uint64_t*)(buf2)) + 4) &&\
|
||||
*(((uint64_t*)(buf1)) + 5) == *(((uint64_t*)(buf2)) + 5) &&\
|
||||
*(((uint64_t*)(buf1)) + 6) == *(((uint64_t*)(buf2)) + 6) &&\
|
||||
*(((uint64_t*)(buf1)) + 7) == *(((uint64_t*)(buf2)) + 7))
|
||||
|
||||
#define ASSERT(x)\
|
||||
if (!(x))\
|
||||
rollback((uint32_t)#x,sizeof(#x),__LINE__)
|
||||
|
||||
int64_t cbak(uint32_t r)
|
||||
{
|
||||
}
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
|
||||
|
||||
// emit txns based on otxn_params
|
||||
uint8_t emitcount[2];
|
||||
ASSERT(otxn_param(SBUF(emitcount), "count", 5) == 2);
|
||||
|
||||
uint16_t ec = UINT16_FROM_BUF(emitcount);
|
||||
ASSERT(ec > 0);
|
||||
etxn_reserve(ec);
|
||||
|
||||
// bounds checks
|
||||
ASSERT(emit(1000000, 32, 0, 32) == OUT_OF_BOUNDS);
|
||||
ASSERT(emit(0,1000000, 0, 32) == OUT_OF_BOUNDS);
|
||||
ASSERT(emit(0,32, 1000000, 32) == OUT_OF_BOUNDS);
|
||||
ASSERT(emit(0,32, 0, 1000000) == OUT_OF_BOUNDS);
|
||||
|
||||
|
||||
uint8_t bob[20];
|
||||
ASSERT(otxn_param(SBUF(bob), "bob", 3) == 20);
|
||||
|
||||
uint8_t tx[PREPARE_PAYMENT_SIMPLE_SIZE];
|
||||
PREPARE_PAYMENT_SIMPLE(tx, 1000, bob, 0, 0);
|
||||
|
||||
uint8_t tmp[32];
|
||||
uint8_t incr = otxn_param(SBUF(tmp), "inc", 3) != DOESNT_EXIST;
|
||||
|
||||
uint8_t hashes[64];
|
||||
|
||||
for (int i = 0; GUARD(64), i < ec; ++i)
|
||||
{
|
||||
if (incr)
|
||||
{
|
||||
tx[6] = (uint8_t)(i >> 8U);
|
||||
tx[7] = (uint8_t)(i & 0xFFU);
|
||||
}
|
||||
ASSERT(emit(hashes + (i % 2) * 32, 32, SBUF(tx)) == 32);
|
||||
|
||||
// assert the hash isn't the same as the previous txn
|
||||
ASSERT(!BUFFER_EQUAL_32(hashes, hashes + 32));
|
||||
}
|
||||
|
||||
return accept(0,0,0);
|
||||
}
|
||||
)[test.hook]"];
|
||||
|
||||
env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0),
|
||||
M("set emit"),
|
||||
HSFEE);
|
||||
env.close();
|
||||
|
||||
Json::Value invoke;
|
||||
invoke[jss::TransactionType] = "Invoke";
|
||||
invoke[jss::Account] = alice.human();
|
||||
|
||||
Json::Value params{Json::arrayValue};
|
||||
params[0U][jss::HookParameter][jss::HookParameterName ] = strHex(std::string("bob"));
|
||||
params[0U][jss::HookParameter][jss::HookParameterValue] = strHex(bob.id());
|
||||
|
||||
params[1U][jss::HookParameter][jss::HookParameterName ] = strHex(std::string("count"));
|
||||
params[1U][jss::HookParameter][jss::HookParameterValue] = "0001";
|
||||
|
||||
invoke[jss::HookParameters] = params;
|
||||
|
||||
env(invoke, M("test otxn_param"), fee(XRP(1)));
|
||||
|
||||
// RH UPTO: check emit count = 1, check that the emitted txn is correct
|
||||
// cbak
|
||||
// add to another account and make a fork bomb
|
||||
// test burden and generation logic
|
||||
// test emit failure
|
||||
env.close();
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
Reference in New Issue
Block a user