diff --git a/hook/makefile b/hook/makefile index a0e7e55d7..953e86441 100644 --- a/hook/makefile +++ b/hook/makefile @@ -140,32 +140,6 @@ mint: --avoid-reinterprets \ -Oz hook-cleaner mint.wasm - wasm-opt mint.wasm -o mint.wasm \ - --shrink-level=100000000 \ - --coalesce-locals-learning \ - --vacuum \ - --merge-blocks \ - --merge-locals \ - --flatten \ - --ignore-implicit-traps \ - -ffm \ - --const-hoisting \ - --code-folding \ - --code-pushing \ - --dae-optimizing \ - --dce \ - --simplify-globals-optimizing \ - --simplify-locals-nonesting \ - --reorder-locals \ - --rereloop \ - --precompute-propagate \ - --local-cse \ - --remove-unused-brs \ - --memory-packing \ - -c \ - --avoid-reinterprets \ - -Oz - hook-cleaner mint.wasm guard_checker mint.wasm nftoken: wasmcc nftoken.c -o nftoken.wasm -Oz -Wl,--allow-undefined -I../ diff --git a/hook/mint.c b/hook/mint.c index ca753ca12..3ecdefda7 100644 --- a/hook/mint.c +++ b/hook/mint.c @@ -3,11 +3,11 @@ #include "hookapi.h" #define ASSERT(x)\ if (!(x))\ - rollback(SBUF("Reward: Assertion failure."),__LINE__); + rollback(SBUF("MintTest: Assertion failure."),__LINE__); #define DEBUG 1 -uint8_t txn_mint[13850] = +uint8_t txn_mint[60000] = { /* size,upto */ /* 3, 0 */ 0x12U, 0x00U, 0x60U, /* tt = GenesisMint */ @@ -39,30 +39,6 @@ uint8_t txn_mint[13850] = // 210 bytes + 34 bytes per entry * number of entries + any alignment padding desired }; - -uint8_t entry[40] = { -/* 0, 2 */ 0xE0U, 0x60U, // obj start -/* 2, 1 */ 0x61U, // amount header -/* 3, 8 */ 0,0,0,0,0,0,0,0, // amount payload -/* 11, 2 */ 0x83U, 0x14U, // account header -/* 13, 20 */ 0,0,0,0,0,0,0,0,0,0, - 0,0,0,0,0,0,0,0,0,0, // account payload -/* 33, 1 */ 0xE1U // obj end -}; - -#define ENTRY_DROPS(drops_tmp)\ -{\ - uint8_t* b = entry + 3U;\ - *b++ = 0b01000000 + (( drops_tmp >> 56 ) & 0b00111111 );\ - *b++ = (drops_tmp >> 48) & 0xFFU;\ - *b++ = (drops_tmp >> 40) & 0xFFU;\ - *b++ = (drops_tmp >> 32) & 0xFFU;\ - *b++ = (drops_tmp >> 24) & 0xFFU;\ - *b++ = (drops_tmp >> 16) & 0xFFU;\ - *b++ = (drops_tmp >> 8) & 0xFFU;\ - *b++ = (drops_tmp >> 0) & 0xFFU;\ -} - #define BE_DROPS(drops)\ {\ uint64_t drops_tmp = drops;\ @@ -77,60 +53,43 @@ uint8_t entry[40] = { *b++ = (drops_tmp >> 0) & 0xFFU;\ } -//uint8_t preamble[4] = {0xE0U, 0x60U, 0x61U, 0x00}; int64_t hook(uint32_t r) { etxn_reserve(1); _g(1,1); + hook_account(txn_mint + 71, 20); - // emit the txn - uint64_t drops = 12345; + otxn_slot(1); + ASSERT(slot_subfield(1, sfBlob, 2) == 2); - ENTRY_DROPS(drops); - -#define COUNT 400 - uint8_t* upto = txn_mint + 209U; - uint8_t* end = upto + (34U * COUNT); - - for (; GUARD(COUNT), upto < end; upto += 34) - { - uint64_t* d = (uint64_t*)upto; - uint64_t* s = (uint64_t*)entry; - *d++ = *s++; - *d++ = *s++; - //*d++ = *s++; - //*d++ = *s++; - - *(d+2) = *(s+2); - - otxn_field(upto + 13, 20, sfDestination); - *((uint32_t*)(upto + 13)) = upto; + int64_t bytes = slot(txn_mint + 207, 60000 - 207, 2); -/* - * - *upto++ = 0xE0U; // obj start - *upto++ = 0x60U; - *upto++ = 0x61U; // amt - *((uint32_t*)upto) = preamble; - upto += 3; + ASSERT(bytes > 0); - *((uint64_t*)upto) = drops; - upto += 8; + bytes += 207; - *upto++ = 0x83U; // acc - *upto++ = 0x14U; - *((uint16_t*)upto) = preamble2; - upto += 2; - */ + // nop out any vl encoding + uint8_t x = txn_mint[207]; + uint8_t y = txn_mint[208]; + uint8_t z = txn_mint[209]; + txn_mint[207] = 0x99U; + if (x > 192U) + { + txn_mint[208] = 0x99U; + if (y > 240) + txn_mint[209] = 0x99U; } - *upto++ = 0xF1U; // array end - etxn_details(txn_mint + 91, 116); - int64_t fee = etxn_fee_base(txn_mint, upto - txn_mint); + + trace(SBUF("Txn:"), txn_mint, bytes, 1); + + ASSERT(etxn_details(txn_mint + 91, 116) > 0); + + int64_t fee = etxn_fee_base(txn_mint, bytes); BE_DROPS(fee); *((uint64_t*)(txn_mint + 26)) = fee; @@ -148,10 +107,10 @@ int64_t hook(uint32_t r) txn_mint[24] = seq & 0xFFU; - trace(SBUF("emit:"), txn_mint, upto-txn_mint, 1); + trace(SBUF("emit:"), txn_mint, bytes, 1); uint8_t emithash[32]; - int64_t emit_result = emit(SBUF(emithash), txn_mint, upto - txn_mint); + int64_t emit_result = emit(SBUF(emithash), txn_mint, bytes); if (DEBUG) TRACEVAR(emit_result); diff --git a/src/ripple/app/hook/xahau.h b/src/ripple/app/hook/xahau.h index f78fc8724..7d1e8cee9 100644 --- a/src/ripple/app/hook/xahau.h +++ b/src/ripple/app/hook/xahau.h @@ -1231,4 +1231,113 @@ static const std::vector AcceptHook = 0x80U,0x00U,0x1AU,0x20U,0x01U,0x0BU }; +static const std::vector MintTestHook = +{ + 0x00U,0x61U,0x73U,0x6DU,0x01U,0x00U,0x00U,0x00U,0x01U,0x35U, + 0x08U,0x60U,0x01U,0x7FU,0x01U,0x7EU,0x60U,0x02U,0x7FU,0x7FU, + 0x01U,0x7FU,0x60U,0x02U,0x7FU,0x7FU,0x01U,0x7EU,0x60U,0x03U, + 0x7FU,0x7FU,0x7FU,0x01U,0x7EU,0x60U,0x03U,0x7FU,0x7FU,0x7EU, + 0x01U,0x7EU,0x60U,0x05U,0x7FU,0x7FU,0x7FU,0x7FU,0x7FU,0x01U, + 0x7EU,0x60U,0x00U,0x01U,0x7EU,0x60U,0x04U,0x7FU,0x7FU,0x7FU, + 0x7FU,0x01U,0x7EU,0x02U,0xDAU,0x01U,0x0EU,0x03U,0x65U,0x6EU, + 0x76U,0x0CU,0x65U,0x74U,0x78U,0x6EU,0x5FU,0x72U,0x65U,0x73U, + 0x65U,0x72U,0x76U,0x65U,0x00U,0x00U,0x03U,0x65U,0x6EU,0x76U, + 0x02U,0x5FU,0x67U,0x00U,0x01U,0x03U,0x65U,0x6EU,0x76U,0x0CU, + 0x68U,0x6FU,0x6FU,0x6BU,0x5FU,0x61U,0x63U,0x63U,0x6FU,0x75U, + 0x6EU,0x74U,0x00U,0x02U,0x03U,0x65U,0x6EU,0x76U,0x09U,0x6FU, + 0x74U,0x78U,0x6EU,0x5FU,0x73U,0x6CU,0x6FU,0x74U,0x00U,0x00U, + 0x03U,0x65U,0x6EU,0x76U,0x0DU,0x73U,0x6CU,0x6FU,0x74U,0x5FU, + 0x73U,0x75U,0x62U,0x66U,0x69U,0x65U,0x6CU,0x64U,0x00U,0x03U, + 0x03U,0x65U,0x6EU,0x76U,0x08U,0x72U,0x6FU,0x6CU,0x6CU,0x62U, + 0x61U,0x63U,0x6BU,0x00U,0x04U,0x03U,0x65U,0x6EU,0x76U,0x04U, + 0x73U,0x6CU,0x6FU,0x74U,0x00U,0x03U,0x03U,0x65U,0x6EU,0x76U, + 0x05U,0x74U,0x72U,0x61U,0x63U,0x65U,0x00U,0x05U,0x03U,0x65U, + 0x6EU,0x76U,0x0CU,0x65U,0x74U,0x78U,0x6EU,0x5FU,0x64U,0x65U, + 0x74U,0x61U,0x69U,0x6CU,0x73U,0x00U,0x02U,0x03U,0x65U,0x6EU, + 0x76U,0x0DU,0x65U,0x74U,0x78U,0x6EU,0x5FU,0x66U,0x65U,0x65U, + 0x5FU,0x62U,0x61U,0x73U,0x65U,0x00U,0x02U,0x03U,0x65U,0x6EU, + 0x76U,0x0AU,0x6CU,0x65U,0x64U,0x67U,0x65U,0x72U,0x5FU,0x73U, + 0x65U,0x71U,0x00U,0x06U,0x03U,0x65U,0x6EU,0x76U,0x04U,0x65U, + 0x6DU,0x69U,0x74U,0x00U,0x07U,0x03U,0x65U,0x6EU,0x76U,0x09U, + 0x74U,0x72U,0x61U,0x63U,0x65U,0x5FU,0x6EU,0x75U,0x6DU,0x00U, + 0x04U,0x03U,0x65U,0x6EU,0x76U,0x06U,0x61U,0x63U,0x63U,0x65U, + 0x70U,0x74U,0x00U,0x04U,0x03U,0x02U,0x01U,0x00U,0x05U,0x03U, + 0x01U,0x00U,0x02U,0x06U,0x28U,0x06U,0x7FU,0x01U,0x41U,0xD0U, + 0xDDU,0x07U,0x0BU,0x7FU,0x00U,0x41U,0xCFU,0xDDU,0x03U,0x0BU, + 0x7FU,0x00U,0x41U,0x80U,0x08U,0x0BU,0x7FU,0x00U,0x41U,0xD0U, + 0xDDU,0x07U,0x0BU,0x7FU,0x00U,0x41U,0x80U,0x08U,0x0BU,0x7FU, + 0x00U,0x41U,0x80U,0x08U,0x0BU,0x07U,0x08U,0x01U,0x04U,0x68U, + 0x6FU,0x6FU,0x6BU,0x00U,0x0EU,0x0AU,0xEDU,0x83U,0x00U,0x01U, + 0xE9U,0x83U,0x00U,0x02U,0x01U,0x7FU,0x02U,0x7EU,0x23U,0x00U, + 0x41U,0x20U,0x6BU,0x22U,0x00U,0x24U,0x00U,0x41U,0x01U,0x10U, + 0x00U,0x1AU,0x41U,0x01U,0x41U,0x01U,0x10U,0x01U,0x1AU,0x41U, + 0xC7U,0x08U,0x41U,0x14U,0x10U,0x02U,0x1AU,0x41U,0x01U,0x10U, + 0x03U,0x1AU,0x41U,0x01U,0x41U,0x9AU,0x80U,0x1CU,0x41U,0x02U, + 0x10U,0x04U,0x42U,0x02U,0x52U,0x04U,0x40U,0x41U,0xE0U,0xDCU, + 0x03U,0x41U,0x1DU,0x42U,0xC1U,0x00U,0x10U,0x05U,0x1AU,0x0BU, + 0x41U,0xCFU,0x09U,0x41U,0x91U,0xD3U,0x03U,0x41U,0x02U,0x10U, + 0x06U,0x22U,0x02U,0x42U,0x00U,0x57U,0x04U,0x40U,0x41U,0xE0U, + 0xDCU,0x03U,0x41U,0x1DU,0x42U,0xC6U,0x00U,0x10U,0x05U,0x1AU, + 0x0BU,0x41U,0xCFU,0x09U,0x2DU,0x00U,0x00U,0x41U,0xCFU,0x09U, + 0x41U,0x99U,0x01U,0x3AU,0x00U,0x00U,0x41U,0xC1U,0x01U,0x4FU, + 0x04U,0x40U,0x02U,0x40U,0x41U,0xD0U,0x09U,0x2DU,0x00U,0x00U, + 0x41U,0xD0U,0x09U,0x41U,0x99U,0x01U,0x3AU,0x00U,0x00U,0x41U, + 0xF1U,0x01U,0x49U,0x0DU,0x00U,0x41U,0xD1U,0x09U,0x41U,0x99U, + 0x01U,0x3AU,0x00U,0x00U,0x0BU,0x0BU,0x41U,0xFDU,0xDCU,0x03U, + 0x41U,0x05U,0x41U,0x80U,0x08U,0x20U,0x02U,0xA7U,0x41U,0xCFU, + 0x01U,0x6AU,0x22U,0x01U,0x41U,0x01U,0x10U,0x07U,0x1AU,0x41U, + 0xDBU,0x08U,0x41U,0xF4U,0x00U,0x10U,0x08U,0x42U,0x00U,0x57U, + 0x04U,0x40U,0x41U,0xE0U,0xDCU,0x03U,0x41U,0x1DU,0x42U,0xDAU, + 0x00U,0x10U,0x05U,0x1AU,0x0BU,0x41U,0x9AU,0x08U,0x41U,0x80U, + 0x08U,0x20U,0x01U,0x10U,0x09U,0x22U,0x02U,0x42U,0x38U,0x86U, + 0x20U,0x02U,0x42U,0x38U,0x88U,0x42U,0x3FU,0x83U,0x84U,0x20U, + 0x02U,0x42U,0x28U,0x86U,0x42U,0x80U,0x80U,0x80U,0x80U,0x80U, + 0x80U,0xC0U,0xFFU,0x00U,0x83U,0x84U,0x20U,0x02U,0x42U,0x18U, + 0x86U,0x42U,0x80U,0x80U,0x80U,0x80U,0x80U,0xE0U,0x3FU,0x83U, + 0x84U,0x20U,0x02U,0x42U,0x08U,0x86U,0x42U,0x80U,0x80U,0x80U, + 0x80U,0xF0U,0x1FU,0x83U,0x84U,0x20U,0x02U,0x42U,0x08U,0x88U, + 0x42U,0x80U,0x80U,0x80U,0xF8U,0x0FU,0x83U,0x84U,0x20U,0x02U, + 0x42U,0x18U,0x88U,0x42U,0x80U,0x80U,0xFCU,0x07U,0x83U,0x84U, + 0x20U,0x02U,0x42U,0x28U,0x88U,0x42U,0x80U,0xFEU,0x03U,0x83U, + 0x84U,0x42U,0xC0U,0x00U,0x84U,0x37U,0x03U,0x00U,0x41U,0x98U, + 0x08U,0x10U,0x0AU,0x22U,0x03U,0x42U,0x05U,0x7CU,0x22U,0x02U, + 0x3CU,0x00U,0x00U,0x41U,0x92U,0x08U,0x20U,0x03U,0x42U,0x01U, + 0x7CU,0x22U,0x03U,0x3CU,0x00U,0x00U,0x41U,0x97U,0x08U,0x20U, + 0x02U,0x42U,0x08U,0x88U,0x3CU,0x00U,0x00U,0x41U,0x96U,0x08U, + 0x20U,0x02U,0x42U,0x10U,0x88U,0x3CU,0x00U,0x00U,0x41U,0x95U, + 0x08U,0x20U,0x02U,0x42U,0x18U,0x88U,0x3CU,0x00U,0x00U,0x41U, + 0x91U,0x08U,0x20U,0x03U,0x42U,0x08U,0x88U,0x3CU,0x00U,0x00U, + 0x41U,0x90U,0x08U,0x20U,0x03U,0x42U,0x10U,0x88U,0x3CU,0x00U, + 0x00U,0x41U,0x8FU,0x08U,0x20U,0x03U,0x42U,0x18U,0x88U,0x3CU, + 0x00U,0x00U,0x41U,0x82U,0xDDU,0x03U,0x41U,0x06U,0x41U,0x80U, + 0x08U,0x20U,0x01U,0x41U,0x01U,0x10U,0x07U,0x1AU,0x41U,0x88U, + 0xDDU,0x03U,0x41U,0x0BU,0x20U,0x00U,0x41U,0x20U,0x41U,0x80U, + 0x08U,0x20U,0x01U,0x10U,0x0BU,0x22U,0x02U,0x10U,0x0CU,0x1AU, + 0x20U,0x02U,0x42U,0x7FU,0x57U,0x04U,0x40U,0x41U,0x94U,0xDDU, + 0x03U,0x41U,0x17U,0x42U,0xF7U,0x00U,0x10U,0x05U,0x1AU,0x0BU, + 0x41U,0xABU,0xDDU,0x03U,0x41U,0x24U,0x42U,0xFAU,0x00U,0x10U, + 0x0DU,0x1AU,0x20U,0x00U,0x41U,0x20U,0x6AU,0x24U,0x00U,0x20U, + 0x02U,0x0BU,0x0BU,0xC4U,0x01U,0x04U,0x00U,0x41U,0x80U,0x08U, + 0x0BU,0x24U,0x12U,0x00U,0x60U,0x22U,0x80U,0x00U,0x00U,0x00U, + 0x24U,0x00U,0x00U,0x00U,0x00U,0x20U,0x1AU,0x00U,0x00U,0x00U, + 0x00U,0x20U,0x1BU,0x00U,0x00U,0x00U,0x00U,0x68U,0x40U,0x00U, + 0x00U,0x00U,0x00U,0x00U,0x00U,0x00U,0x73U,0x21U,0x00U,0x41U, + 0xC5U,0x08U,0x0BU,0x16U,0x81U,0x14U,0xB5U,0xF7U,0x62U,0x79U, + 0x8AU,0x53U,0xD5U,0x43U,0xA0U,0x14U,0xCAU,0xF8U,0xB2U,0x97U, + 0xCFU,0xF8U,0xF2U,0xF9U,0x37U,0xE8U,0x00U,0x41U,0xCFU,0x09U, + 0x0BU,0x02U,0xF0U,0x60U,0x00U,0x41U,0xE0U,0xDCU,0x03U,0x0BU, + 0x6EU,0x4DU,0x69U,0x6EU,0x74U,0x54U,0x65U,0x73U,0x74U,0x3AU, + 0x20U,0x41U,0x73U,0x73U,0x65U,0x72U,0x74U,0x69U,0x6FU,0x6EU, + 0x20U,0x66U,0x61U,0x69U,0x6CU,0x75U,0x72U,0x65U,0x2EU,0x00U, + 0x54U,0x78U,0x6EU,0x3AU,0x00U,0x65U,0x6DU,0x69U,0x74U,0x3AU, + 0x00U,0x65U,0x6DU,0x69U,0x74U,0x5FU,0x72U,0x65U,0x73U,0x75U, + 0x6CU,0x74U,0x00U,0x4DU,0x69U,0x6EU,0x74U,0x54U,0x65U,0x73U, + 0x74U,0x3AU,0x20U,0x45U,0x6DU,0x69U,0x74U,0x20U,0x66U,0x61U, + 0x69U,0x6CU,0x65U,0x64U,0x2EU,0x00U,0x4DU,0x69U,0x6EU,0x74U, + 0x54U,0x65U,0x73U,0x74U,0x3AU,0x20U,0x45U,0x6DU,0x69U,0x74U, + 0x74U,0x65U,0x64U,0x20U,0x74U,0x78U,0x6EU,0x20U,0x73U,0x75U, + 0x63U,0x63U,0x65U,0x73U,0x73U,0x66U,0x75U,0x6CU,0x6CU,0x79U, + 0x2EU +}; + #endif // XAHAU_GENESIS_HOOKS diff --git a/src/ripple/app/tx/impl/GenesisMint.cpp b/src/ripple/app/tx/impl/GenesisMint.cpp index bc104b9e6..bec0cf3cf 100644 --- a/src/ripple/app/tx/impl/GenesisMint.cpp +++ b/src/ripple/app/tx/impl/GenesisMint.cpp @@ -85,6 +85,12 @@ GenesisMint::preflight(PreflightContext const& ctx) return temMALFORMED; } + if (!dest.isFieldPresent(sfDestination)) + { + JLOG(ctx.j.warn()) + << "GenesisMint: DestinationField missing in array entry."; + return temMALFORMED; + } bool const hasAmt = dest.isFieldPresent(sfAmount); bool const hasMarks = dest.isFieldPresent(sfGovernanceMarks); diff --git a/src/ripple/protocol/jss.h b/src/ripple/protocol/jss.h index 3c5e36d80..75aba981e 100644 --- a/src/ripple/protocol/jss.h +++ b/src/ripple/protocol/jss.h @@ -50,6 +50,7 @@ JSS(AccountSet); // transaction type. JSS(Amendments); // ledger type. JSS(Amount); // in: TransactionSign; field. JSS(Authorize); // field +JSS(Blob); JSS(Check); // ledger type. JSS(CheckCancel); // transaction type. JSS(CheckCash); // transaction type. @@ -73,6 +74,9 @@ JSS(FIELDS); // out: RPC server_definitions JSS(Flags); // in/out: TransactionSign; field. JSS(incomplete_shards); // out: OverlayImpl, PeerImp JSS(GenesisMint); // tt +JSS(GenesisMints); +JSS(GovernanceMarks); +JSS(GovernanceFlags); JSS(HookApiVersion); // field JSS(HookHash); // field JSS(HookNamespace); // field diff --git a/src/test/app/GenesisMint_test.cpp b/src/test/app/GenesisMint_test.cpp index b51edc0af..d5e0bde16 100644 --- a/src/test/app/GenesisMint_test.cpp +++ b/src/test/app/GenesisMint_test.cpp @@ -16,51 +16,261 @@ //============================================================================== #include +#include #include +#include namespace ripple { namespace test { struct GenesisMint_test : public beast::unit_test::suite { - - static Json::Value - claim(jtx::Account const& account) +/* + void + injectEmitted(jtx::Env& env, STTx const txIn) { - using namespace jtx; - Json::Value jv; - jv[jss::TransactionType] = jss::ClaimReward; - jv[jss::Account] = account.human(); - return jv; - } + env.app().openLedger().modify( + [&](OpenView& view, beast::Journal j) -> bool + { + STTx tx (txIn->getTxnType(), [&](auto& obj) { - static Json::Value - mint(jtx::Account const& account) + obj = txIn; + + + obj.setAccountID(sfAccount, AccountID()); + obj.setFieldH256(sfAmendment, featureXahauGenesis); + obj.setFieldU32(sfLedgerSequence, startLgr); + if (testFlag) + obj.setFieldU32(sfFlags, tfTestSuite); + }); + + uint256 txID = tx.getTransactionID(); + auto s = std::make_shared(); + tx.add(*s); + env.app().getHashRouter().setFlags(txID, SF_PRIVATE2); + view.rawTxInsert(txID, std::move(s), nullptr); + + return true; + }); + + // close the ledger + env.close(); + } +*/ + + + struct GenMint + { + std::optional dest; + std::optional amt; + std::optional marks; + std::optional flags; + + GenMint(AccountID const& dst, jtx::PrettyAmount const& x, + std::optional m = std::nullopt, std::optional f = std::nullopt): + dest(toBase58(dst)), amt(x), marks(m), flags(f) + { + } + }; + + Json::Value + mint(jtx::Account const& account, std::vector mints) { using namespace jtx; Json::Value jv; jv[jss::TransactionType] = jss::GenesisMint; jv[jss::Account] = account.human(); + jv[jss::GenesisMints] = Json::arrayValue; + + uint32_t counter = 0; + for (auto const& m: mints) + { + Json::Value inner = Json::objectValue; + if (m.dest) + inner[jss::Destination] = *m.dest; + if (m.amt) + inner[jss::Amount] = (*m.amt).value().getJson(JsonOptions::none); + if (m.marks) + inner[jss::GovernanceMarks] = *m.marks; + if (m.flags) + inner[jss::GovernanceFlags] = *m.flags; + + jv[jss::GenesisMints][counter] = Json::objectValue; + jv[jss::GenesisMints][counter][jss::GenesisMint] = inner; + counter++; + } return jv; } - std::unique_ptr - makeNetworkConfig(uint32_t networkID) + Json::Value + setMintHook(jtx::Account const& account) { using namespace jtx; - return envconfig([&](std::unique_ptr cfg) { - cfg->NETWORK_ID = networkID; - Section config; - config.append( - {"reference_fee = 10", - "account_reserve = 1000000", - "owner_reserve = 200000"}); - auto setup = setup_FeeVote(config); - cfg->FEES = setup; - return cfg; - }); + Json::Value tx; + tx[jss::Account] = account.human(); + tx[jss::TransactionType] = "SetHook"; + tx[jss::Hooks] = Json::arrayValue; + tx[jss::Hooks][0u] = Json::objectValue; + tx[jss::Hooks][0u][jss::Hook] = Json::objectValue; + tx[jss::Hooks][0u][jss::Hook][jss::HookOn] = + "0000000000000000000000000000000000000000000000000000000000000000"; + tx[jss::Hooks][0u][jss::Hook][jss::HookNamespace] = + "0000000000000000000000000000000000000000000000000000000000000000"; + tx[jss::Hooks][0u][jss::Hook][jss::HookApiVersion] = 0; + + tx[jss::Hooks][0u][jss::Hook][jss::CreateCode] = strHex(XahauGenesis::MintTestHook); + return tx; } + void + testDisabled(FeatureBitset features) + { + testcase("Disabled"); + using namespace jtx; + using namespace std::literals::chrono_literals; + + { + test::jtx::Env env(*this, features - featureXahauGenesis); + + auto const alice = Account("alice"); + auto const bob = Account("bob"); + + env.fund(XRP(10000), alice, bob); + env.close(); + + env(mint(env.master, { + GenMint(bob.id(), XRP(123)) + }), ter(temDISABLED)); + } + + { + test::jtx::Env env(*this, features - featureHooks); + + auto const alice = Account("alice"); + auto const bob = Account("bob"); + + env.fund(XRP(10000), alice, bob); + env.close(); + + env(mint(env.master, { + {bob.id(), XRP(123)} + }), ter(temDISABLED)); + } + } + + std::string + makeBlob(std::vector> entries) + { + std::string blob = "F060"; + + for (auto const& e : entries) + { + STObject m(sfGenesisMint); + m.setAccountID(sfDestination, e.first); + m.setFieldAmount(sfAmount, e.second); + Serializer s; + m.add(s); + blob += "E060" + strHex(s.getData()) + "E1"; + } + + blob += "F1"; + return blob; + } + + + Json::Value + invoke(jtx::Account const& account, jtx::Account const& destination, std::string blob) + { + Json::Value tx = Json::objectValue; + tx[jss::Account] = account.human(); + tx[jss::TransactionType] = "Invoke"; + tx[jss::Destination] = destination.human(); + tx[jss::Blob] = blob; + return tx; + } + + void + testNonGenesisEmit(FeatureBitset features) + { + testcase("Non Genesis Emit"); + using namespace jtx; + using namespace std::literals::chrono_literals; + + Env env{*this, envconfig(), features, nullptr, + beast::severities::kWarning +// beast::severities::kTrace + }; + auto const alice = Account("alice"); + auto const bob = Account("bob"); + auto const invoker = Account("invoker"); + env.fund(XRP(10000), alice, bob, invoker); + env.close(); + + // set the test hook + env(setMintHook(alice), fee(XRP(10))); + env.close(); + + // this should fail because emitted txns are preflighted + // and the preflight checks the account and will find it's not genesis + env(invoke(invoker, alice, + makeBlob( + { + {bob.id(), XRP(123).value()}, + })), fee(XRP(1)), ter(tecHOOK_REJECTED)); + } + + void + testGenesisEmit(FeatureBitset features) + { + testcase("Genesis Emit"); + using namespace jtx; + using namespace std::literals::chrono_literals; + + Env env{*this, envconfig(), features, nullptr, +// beast::severities::kWarning + beast::severities::kTrace + }; + auto const alice = Account("alice"); + auto const bob = Account("bob"); + auto const invoker = Account("invoker"); + env.fund(XRP(10000), alice, bob, invoker); + env.close(); + + // set the test hook + env(setMintHook(env.master), fee(XRP(10))); + env.close(); + + { + auto acc = env.le(keylet::account(bob.id())); + BEAST_EXPECT(acc->getFieldAmount(sfBalance).xrp().drops() == 10000000000ULL); + } + + // this should fail because emitted txns are preflighted + // and the preflight checks the account and will find it's not genesis + env(invoke(invoker, env.master, + makeBlob( + { + {bob.id(), XRP(123).value()}, + })), fee(XRP(1)), ter(tesSUCCESS)); + + env.close(); + env.close(); + + { + auto acc = env.le(keylet::account(bob.id())); + BEAST_EXPECT(acc->getFieldAmount(sfBalance).xrp().drops() == 10123000000ULL); + } + } + + // RH UPTO: make a blob + // invoke + // get emit txn hash + // close ledger + // test emit failure + + + +/* void testEnabled(FeatureBitset features) { @@ -232,18 +442,20 @@ struct GenesisMint_test : public beast::unit_test::suite BEAST_EXPECT(1 == 1); // testEnabled(features); } - +*/ public: void run() override { using namespace test::jtx; auto const sa = supported_amendments(); - testWithFeats(sa); + testDisabled(sa); + testNonGenesisEmit(sa); + testGenesisEmit(sa); } }; BEAST_DEFINE_TESTSUITE(GenesisMint, app, ripple); } // namespace test -} // namespace ripple \ No newline at end of file +} // namespace ripple