mirror of
https://github.com/Xahau/xahaud.git
synced 2026-07-24 23:50:10 +00:00
feat: pack entropy status metadata
This commit is contained in:
@@ -361,9 +361,9 @@ xport_cancel(uint32_t read_ptr, uint32_t read_len, uint32_t flags);
|
||||
1 = consensus_fallback, 2 = participant_aligned,
|
||||
3 = validator_quorum, 4 = validator_full.
|
||||
|
||||
entropy_status writes five big-endian bytes:
|
||||
tier:u8, count:u16, denominator:u16
|
||||
and returns ledger age (0 current, 1 previous, >1 stale).
|
||||
entropy_status returns a packed non-negative value:
|
||||
bits 32..39 tier, 16..31 count, 0..15 denominator.
|
||||
Check for a negative error before using the ENTROPY_* macros.
|
||||
|
||||
Classify tier before count/denominator arithmetic: fallback is tier 1
|
||||
with count=denominator=0. Common policies are denominator-count <= 1,
|
||||
@@ -380,7 +380,7 @@ extern int64_t
|
||||
random(uint32_t write_ptr, uint32_t write_len, uint32_t min_tier);
|
||||
|
||||
extern int64_t
|
||||
entropy_status(uint32_t write_ptr, uint32_t write_len);
|
||||
entropy_status();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
@@ -50,9 +50,9 @@ APPLY_HOOK="$SCRIPT_DIR/../include/xrpl/hook/hook_api.macro"
|
||||
print " 1 = consensus_fallback, 2 = participant_aligned,";
|
||||
print " 3 = validator_quorum, 4 = validator_full.";
|
||||
print "";
|
||||
print " entropy_status writes five big-endian bytes:";
|
||||
print " tier:u8, count:u16, denominator:u16";
|
||||
print " and returns ledger age (0 current, 1 previous, >1 stale).";
|
||||
print " entropy_status returns a packed non-negative value:";
|
||||
print " bits 32..39 tier, 16..31 count, 0..15 denominator.";
|
||||
print " Check for a negative error before using the ENTROPY_* macros.";
|
||||
print "";
|
||||
print " Classify tier before count/denominator arithmetic: fallback is tier 1";
|
||||
print " with count=denominator=0. Common policies are denominator-count <= 1,";
|
||||
|
||||
@@ -145,6 +145,10 @@ int out_len = 0;\
|
||||
#define SUB_OFFSET(x) ((int32_t)(x >> 32))
|
||||
#define SUB_LENGTH(x) ((int32_t)(x & 0xFFFFFFFFULL))
|
||||
|
||||
#define ENTROPY_TIER(x) (((uint64_t)(x) >> 32U) & 0xFFU)
|
||||
#define ENTROPY_COUNT(x) (((uint64_t)(x) >> 16U) & 0xFFFFU)
|
||||
#define ENTROPY_DENOMINATOR(x) ((uint64_t)(x) & 0xFFFFU)
|
||||
|
||||
#define BUFFER_EQUAL_20(buf1, buf2)\
|
||||
(\
|
||||
*(((uint64_t*)(buf1)) + 0) == *(((uint64_t*)(buf2)) + 0) &&\
|
||||
@@ -378,4 +382,3 @@ int out_len = 0;\
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
@@ -398,7 +398,7 @@ HOOK_API_DEFINITION(
|
||||
int64_t, random, (uint32_t, uint32_t, uint32_t),
|
||||
featureConsensusEntropy)
|
||||
|
||||
// int64_t entropy_status(uint32_t write_ptr, uint32_t write_len);
|
||||
// int64_t entropy_status();
|
||||
HOOK_API_DEFINITION(
|
||||
int64_t, entropy_status, (uint32_t, uint32_t),
|
||||
int64_t, entropy_status, (),
|
||||
featureConsensusEntropy)
|
||||
|
||||
@@ -482,45 +482,34 @@ class ConsensusEntropy_test : public beast::unit_test::suite
|
||||
#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 entropy_status(uint32_t write_ptr, uint32_t write_len);
|
||||
#define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1)
|
||||
#define OUT_OF_BOUNDS (-1)
|
||||
#define TOO_SMALL (-4)
|
||||
extern int64_t entropy_status();
|
||||
#define ENTROPY_TIER(x) (((uint64_t)(x) >> 32U) & 0xFFU)
|
||||
#define ENTROPY_COUNT(x) (((uint64_t)(x) >> 16U) & 0xFFFFU)
|
||||
#define ENTROPY_DENOMINATOR(x) ((uint64_t)(x) & 0xFFFFU)
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t status[5] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5};
|
||||
|
||||
if (entropy_status((uint32_t)status, 4) != TOO_SMALL)
|
||||
return accept(0, 0, 10);
|
||||
for (int i = 0; GUARD(5), i < 5; ++i)
|
||||
if (status[i] != 0xA5)
|
||||
return accept(0, 0, 11);
|
||||
|
||||
if (entropy_status(0xFFFFFFFEU, 5) != OUT_OF_BOUNDS)
|
||||
return accept(0, 0, 12);
|
||||
|
||||
int64_t age = entropy_status((uint32_t)status, 5);
|
||||
if (age < 0 || age > 1)
|
||||
int64_t status = entropy_status();
|
||||
if (status < 0)
|
||||
return accept(0, 0, 13);
|
||||
|
||||
uint32_t count = ((uint32_t)status[1] << 8) | status[2];
|
||||
uint32_t denominator =
|
||||
((uint32_t)status[3] << 8) | status[4];
|
||||
if (status[0] != 3 || count != 19 || denominator != 20)
|
||||
uint32_t tier = ENTROPY_TIER(status);
|
||||
uint32_t count = ENTROPY_COUNT(status);
|
||||
uint32_t denominator = ENTROPY_DENOMINATOR(status);
|
||||
if (tier != 3 || count != 19 || denominator != 20)
|
||||
return accept(0, 0, 14);
|
||||
|
||||
// Common caller-side policies: tolerate one absent, require
|
||||
// 4/5 participation, and require an absolute floor of 19.
|
||||
if (status[0] < 2 || denominator - count > 1)
|
||||
if (tier < 2 || denominator - count > 1)
|
||||
return accept(0, 0, 15);
|
||||
if ((uint64_t)5 * count < (uint64_t)4 * denominator)
|
||||
return accept(0, 0, 16);
|
||||
if (count < 19)
|
||||
return accept(0, 0, 17);
|
||||
|
||||
return accept(0, 0, age);
|
||||
return accept(0, 0, 0);
|
||||
}
|
||||
)[test.hook]"];
|
||||
|
||||
@@ -541,8 +530,6 @@ class ConsensusEntropy_test : public beast::unit_test::suite
|
||||
auto const hookExecutions = meta->getFieldArray(sfHookExecutions);
|
||||
BEAST_REQUIRE(hookExecutions.size() == 1);
|
||||
|
||||
// Open-ledger preview accepts age 1; final ordered execution sees the
|
||||
// current-ledger pseudo first and records age 0 in final metadata.
|
||||
BEAST_EXPECT(hookReturnCode(hookExecutions[0]) == 0);
|
||||
BEAST_EXPECT(hookExecutions[0].getFieldU8(sfHookResult) == 3);
|
||||
}
|
||||
@@ -581,18 +568,20 @@ class ConsensusEntropy_test : public beast::unit_test::suite
|
||||
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 dice(uint32_t sides, uint32_t min_tier);
|
||||
extern int64_t entropy_status(uint32_t write_ptr, uint32_t write_len);
|
||||
extern int64_t entropy_status();
|
||||
#define ENTROPY_TIER(x) (((uint64_t)(x) >> 32U) & 0xFFU)
|
||||
#define ENTROPY_COUNT(x) (((uint64_t)(x) >> 16U) & 0xFFFFU)
|
||||
#define ENTROPY_DENOMINATOR(x) ((uint64_t)(x) & 0xFFFFU)
|
||||
#define TOO_LITTLE_ENTROPY (-48)
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t status[5];
|
||||
int64_t age = entropy_status((uint32_t)status, 5);
|
||||
if (age < 0 || age > 1)
|
||||
int64_t status = entropy_status();
|
||||
if (status < 0)
|
||||
return accept(0, 0, 20);
|
||||
if (status[0] != 1 || status[1] != 0 || status[2] != 0 ||
|
||||
status[3] != 0 || status[4] != 0)
|
||||
if (ENTROPY_TIER(status) != 1 || ENTROPY_COUNT(status) != 0 ||
|
||||
ENTROPY_DENOMINATOR(status) != 0)
|
||||
return accept(0, 0, 21);
|
||||
|
||||
int64_t allowed = dice(6, 1);
|
||||
@@ -601,7 +590,7 @@ class ConsensusEntropy_test : public beast::unit_test::suite
|
||||
if (dice(6, 2) != TOO_LITTLE_ENTROPY)
|
||||
return accept(0, 0, 23);
|
||||
|
||||
return accept(0, 0, age);
|
||||
return accept(0, 0, 0);
|
||||
}
|
||||
)[test.hook]"];
|
||||
|
||||
@@ -694,7 +683,7 @@ class ConsensusEntropy_test : public beast::unit_test::suite
|
||||
void
|
||||
testDiceWithoutAmendment()
|
||||
{
|
||||
testcase("Hook dice() import fails without ConsensusEntropy amendment");
|
||||
testcase("Hook entropy imports independently require amendment");
|
||||
using namespace jtx;
|
||||
|
||||
Env env{*this, supported_amendments()};
|
||||
@@ -705,31 +694,126 @@ class ConsensusEntropy_test : public beast::unit_test::suite
|
||||
|
||||
BEAST_EXPECT(!env.le(keylet::consensusEntropy()));
|
||||
|
||||
// The CE hook APIs are amendment-scoped at install time. Without
|
||||
// featureConsensusEntropy, a hook importing dice() is not installable,
|
||||
// so the runtime path cannot be reached with the API disabled.
|
||||
TestHook hook = consensusentropy_test_wasm[R"[test.hook](
|
||||
TestHook diceHook = consensusentropy_test_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 dice(uint32_t sides, uint32_t min_tier);
|
||||
extern int64_t entropy_status(uint32_t write_ptr, uint32_t write_len);
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t status[5];
|
||||
int64_t result = entropy_status((uint32_t)status, 5);
|
||||
if (result >= 0)
|
||||
result = dice(6, 3);
|
||||
return accept(0, 0, result);
|
||||
return accept(0, 0, dice(6, 3));
|
||||
}
|
||||
)[test.hook]"];
|
||||
|
||||
TestHook randomHook = consensusentropy_test_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 random(uint32_t write_ptr, uint32_t write_len, uint32_t min_tier);
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t buf[32];
|
||||
return accept(0, 0, random((uint32_t)buf, 32, 3));
|
||||
}
|
||||
)[test.hook]"];
|
||||
|
||||
TestHook statusHook = consensusentropy_test_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 entropy_status();
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
return accept(0, 0, entropy_status());
|
||||
}
|
||||
)[test.hook]"];
|
||||
|
||||
env(ripple::test::jtx::hook(alice, {{hso(diceHook, overrideFlag)}}, 0),
|
||||
M("set dice-no-amendment hook"),
|
||||
HSFEE,
|
||||
ter(temMALFORMED));
|
||||
env(ripple::test::jtx::hook(
|
||||
alice, {{hso(randomHook, overrideFlag)}}, 0),
|
||||
M("set random-no-amendment hook"),
|
||||
HSFEE,
|
||||
ter(temMALFORMED));
|
||||
env(ripple::test::jtx::hook(
|
||||
alice, {{hso(statusHook, overrideFlag)}}, 0),
|
||||
M("set entropy-status-no-amendment hook"),
|
||||
HSFEE,
|
||||
ter(temMALFORMED));
|
||||
}
|
||||
|
||||
void
|
||||
testRandomTierRequirementNotMet()
|
||||
{
|
||||
testcase("Hook random() fails before write below min_tier");
|
||||
using namespace jtx;
|
||||
|
||||
Env env{
|
||||
*this,
|
||||
envconfig(),
|
||||
supported_amendments() | featureConsensusEntropy,
|
||||
nullptr};
|
||||
|
||||
ConsensusTestConfig cfg;
|
||||
cfg.standaloneEntropyTier = entropyTierValidatorQuorum;
|
||||
cfg.standaloneEntropyCount = 19;
|
||||
cfg.standaloneEntropyDenominator = 20;
|
||||
env.app().getRuntimeConfig().setGlobalConfig(cfg);
|
||||
|
||||
auto const alice = Account{"alice"};
|
||||
env.fund(XRP(10000), alice);
|
||||
env.close();
|
||||
|
||||
TestHook hook = consensusentropy_test_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 random(uint32_t write_ptr, uint32_t write_len, uint32_t min_tier);
|
||||
#define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1)
|
||||
#define TOO_LITTLE_ENTROPY (-48)
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t buf[32];
|
||||
for (int i = 0; GUARD(32), i < 32; ++i)
|
||||
buf[i] = 0xA5;
|
||||
|
||||
if (random((uint32_t)buf, 32, 4) != TOO_LITTLE_ENTROPY)
|
||||
return accept(0, 0, 30);
|
||||
for (int i = 0; GUARD(32), i < 32; ++i)
|
||||
if (buf[i] != 0xA5)
|
||||
return accept(0, 0, 31);
|
||||
|
||||
return accept(0, 0, 0);
|
||||
}
|
||||
)[test.hook]"];
|
||||
|
||||
env(ripple::test::jtx::hook(alice, {{hso(hook, overrideFlag)}}, 0),
|
||||
M("set dice-no-amendment hook"),
|
||||
HSFEE,
|
||||
ter(temMALFORMED));
|
||||
M("set random-tier-requirement hook"),
|
||||
HSFEE);
|
||||
env.close();
|
||||
|
||||
Json::Value invoke;
|
||||
invoke[jss::TransactionType] = "Invoke";
|
||||
invoke[jss::Account] = alice.human();
|
||||
env(invoke, M("test random min_tier unmet"), fee(XRP(1)));
|
||||
|
||||
auto meta = env.meta();
|
||||
BEAST_REQUIRE(meta);
|
||||
BEAST_REQUIRE(meta->isFieldPresent(sfHookExecutions));
|
||||
auto const hookExecutions = meta->getFieldArray(sfHookExecutions);
|
||||
BEAST_REQUIRE(hookExecutions.size() == 1);
|
||||
BEAST_EXPECT(hookReturnCode(hookExecutions[0]) == 0);
|
||||
BEAST_EXPECT(hookExecutions[0].getFieldU8(sfHookResult) == 3);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -825,6 +909,7 @@ class ConsensusEntropy_test : public beast::unit_test::suite
|
||||
testEntropyStatusFallback();
|
||||
testDiceTierRequirementNotMet();
|
||||
testDiceWithoutAmendment();
|
||||
testRandomTierRequirementNotMet();
|
||||
testInvalidEntropyRequirements();
|
||||
testRandom();
|
||||
testDiceConsecutiveCallsDiffer();
|
||||
|
||||
@@ -221,95 +221,54 @@ inline std::map<std::string, std::vector<uint8_t>> consensusentropy_test_wasm =
|
||||
#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 entropy_status(uint32_t write_ptr, uint32_t write_len);
|
||||
#define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1)
|
||||
#define OUT_OF_BOUNDS (-1)
|
||||
#define TOO_SMALL (-4)
|
||||
extern int64_t entropy_status();
|
||||
#define ENTROPY_TIER(x) (((uint64_t)(x) >> 32U) & 0xFFU)
|
||||
#define ENTROPY_COUNT(x) (((uint64_t)(x) >> 16U) & 0xFFFFU)
|
||||
#define ENTROPY_DENOMINATOR(x) ((uint64_t)(x) & 0xFFFFU)
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t status[5] = {0xA5, 0xA5, 0xA5, 0xA5, 0xA5};
|
||||
|
||||
if (entropy_status((uint32_t)status, 4) != TOO_SMALL)
|
||||
return accept(0, 0, 10);
|
||||
for (int i = 0; GUARD(5), i < 5; ++i)
|
||||
if (status[i] != 0xA5)
|
||||
return accept(0, 0, 11);
|
||||
|
||||
if (entropy_status(0xFFFFFFFEU, 5) != OUT_OF_BOUNDS)
|
||||
return accept(0, 0, 12);
|
||||
|
||||
int64_t age = entropy_status((uint32_t)status, 5);
|
||||
if (age < 0 || age > 1)
|
||||
int64_t status = entropy_status();
|
||||
if (status < 0)
|
||||
return accept(0, 0, 13);
|
||||
|
||||
uint32_t count = ((uint32_t)status[1] << 8) | status[2];
|
||||
uint32_t denominator =
|
||||
((uint32_t)status[3] << 8) | status[4];
|
||||
if (status[0] != 3 || count != 19 || denominator != 20)
|
||||
uint32_t tier = ENTROPY_TIER(status);
|
||||
uint32_t count = ENTROPY_COUNT(status);
|
||||
uint32_t denominator = ENTROPY_DENOMINATOR(status);
|
||||
if (tier != 3 || count != 19 || denominator != 20)
|
||||
return accept(0, 0, 14);
|
||||
|
||||
// Common caller-side policies: tolerate one absent, require
|
||||
// 4/5 participation, and require an absolute floor of 19.
|
||||
if (status[0] < 2 || denominator - count > 1)
|
||||
if (tier < 2 || denominator - count > 1)
|
||||
return accept(0, 0, 15);
|
||||
if ((uint64_t)5 * count < (uint64_t)4 * denominator)
|
||||
return accept(0, 0, 16);
|
||||
if (count < 19)
|
||||
return accept(0, 0, 17);
|
||||
|
||||
return accept(0, 0, age);
|
||||
return accept(0, 0, 0);
|
||||
}
|
||||
)[test.hook]",
|
||||
{
|
||||
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U,
|
||||
0x19U, 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U,
|
||||
0x02U, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU,
|
||||
0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U,
|
||||
0x2CU, 0x03U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U,
|
||||
0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0EU, 0x65U, 0x6EU,
|
||||
0x74U, 0x72U, 0x6FU, 0x70U, 0x79U, 0x5FU, 0x73U, 0x74U, 0x61U,
|
||||
0x74U, 0x75U, 0x73U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U,
|
||||
0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U,
|
||||
0x03U, 0x02U, 0x01U, 0x03U, 0x05U, 0x03U, 0x01U, 0x00U, 0x01U,
|
||||
0x06U, 0x08U, 0x01U, 0x7FU, 0x01U, 0x41U, 0x80U, 0x80U, 0x04U,
|
||||
0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU,
|
||||
0x00U, 0x03U, 0x0AU, 0xB2U, 0x02U, 0x01U, 0xAFU, 0x02U, 0x01U,
|
||||
0x01U, 0x7EU, 0x23U, 0x00U, 0x41U, 0x10U, 0x6BU, 0x22U, 0x00U,
|
||||
0x24U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x00U, 0x1AU,
|
||||
0x20U, 0x00U, 0x41U, 0xA5U, 0x01U, 0x3AU, 0x00U, 0x0CU, 0x20U,
|
||||
0x00U, 0x41U, 0xA5U, 0xCBU, 0x96U, 0xADU, 0x7AU, 0x36U, 0x02U,
|
||||
0x08U, 0x02U, 0x40U, 0x20U, 0x00U, 0x41U, 0x08U, 0x6AU, 0x41U,
|
||||
0x04U, 0x10U, 0x01U, 0x42U, 0x7CU, 0x52U, 0x04U, 0x40U, 0x42U,
|
||||
0x0AU, 0x21U, 0x01U, 0x0CU, 0x01U, 0x0BU, 0x41U, 0x91U, 0x80U,
|
||||
0x80U, 0x80U, 0x78U, 0x41U, 0x06U, 0x10U, 0x00U, 0x1AU, 0x42U,
|
||||
0x0BU, 0x21U, 0x01U, 0x20U, 0x00U, 0x2DU, 0x00U, 0x08U, 0x41U,
|
||||
0xA5U, 0x01U, 0x47U, 0x0DU, 0x00U, 0x41U, 0x91U, 0x80U, 0x80U,
|
||||
0x80U, 0x78U, 0x41U, 0x06U, 0x10U, 0x00U, 0x1AU, 0x20U, 0x00U,
|
||||
0x2DU, 0x00U, 0x09U, 0x41U, 0xA5U, 0x01U, 0x47U, 0x0DU, 0x00U,
|
||||
0x41U, 0x91U, 0x80U, 0x80U, 0x80U, 0x78U, 0x41U, 0x06U, 0x10U,
|
||||
0x00U, 0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0x0AU, 0x41U, 0xA5U,
|
||||
0x01U, 0x47U, 0x0DU, 0x00U, 0x41U, 0x91U, 0x80U, 0x80U, 0x80U,
|
||||
0x78U, 0x41U, 0x06U, 0x10U, 0x00U, 0x1AU, 0x20U, 0x00U, 0x2DU,
|
||||
0x00U, 0x0BU, 0x41U, 0xA5U, 0x01U, 0x47U, 0x0DU, 0x00U, 0x41U,
|
||||
0x91U, 0x80U, 0x80U, 0x80U, 0x78U, 0x41U, 0x06U, 0x10U, 0x00U,
|
||||
0x1AU, 0x20U, 0x00U, 0x2DU, 0x00U, 0x0CU, 0x41U, 0xA5U, 0x01U,
|
||||
0x47U, 0x0DU, 0x00U, 0x41U, 0x91U, 0x80U, 0x80U, 0x80U, 0x78U,
|
||||
0x41U, 0x06U, 0x10U, 0x00U, 0x1AU, 0x41U, 0x7EU, 0x41U, 0x05U,
|
||||
0x10U, 0x01U, 0x42U, 0x7FU, 0x52U, 0x04U, 0x40U, 0x42U, 0x0CU,
|
||||
0x21U, 0x01U, 0x0CU, 0x01U, 0x0BU, 0x20U, 0x00U, 0x41U, 0x08U,
|
||||
0x6AU, 0x41U, 0x05U, 0x10U, 0x01U, 0x22U, 0x01U, 0x42U, 0x01U,
|
||||
0x56U, 0x04U, 0x40U, 0x42U, 0x0DU, 0x21U, 0x01U, 0x0CU, 0x01U,
|
||||
0x0BU, 0x42U, 0x0EU, 0x42U, 0x0EU, 0x42U, 0x0EU, 0x20U, 0x01U,
|
||||
0x20U, 0x00U, 0x2DU, 0x00U, 0x0CU, 0x20U, 0x00U, 0x2DU, 0x00U,
|
||||
0x0BU, 0x41U, 0x08U, 0x74U, 0x72U, 0x41U, 0x14U, 0x47U, 0x1BU,
|
||||
0x20U, 0x00U, 0x2DU, 0x00U, 0x0AU, 0x20U, 0x00U, 0x2DU, 0x00U,
|
||||
0x09U, 0x41U, 0x08U, 0x74U, 0x72U, 0x41U, 0x13U, 0x47U, 0x1BU,
|
||||
0x20U, 0x00U, 0x2DU, 0x00U, 0x08U, 0x41U, 0x03U, 0x47U, 0x1BU,
|
||||
0x21U, 0x01U, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x01U,
|
||||
0x10U, 0x02U, 0x21U, 0x01U, 0x20U, 0x00U, 0x41U, 0x10U, 0x6AU,
|
||||
0x24U, 0x00U, 0x20U, 0x01U, 0x0BU,
|
||||
0x17U, 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U,
|
||||
0x00U, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, 0x01U,
|
||||
0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, 0x2CU, 0x03U,
|
||||
0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, 0x00U,
|
||||
0x03U, 0x65U, 0x6EU, 0x76U, 0x0EU, 0x65U, 0x6EU, 0x74U, 0x72U,
|
||||
0x6FU, 0x70U, 0x79U, 0x5FU, 0x73U, 0x74U, 0x61U, 0x74U, 0x75U,
|
||||
0x73U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U,
|
||||
0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U, 0x03U, 0x02U,
|
||||
0x01U, 0x03U, 0x05U, 0x03U, 0x01U, 0x00U, 0x01U, 0x07U, 0x08U,
|
||||
0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x03U, 0x0AU,
|
||||
0x33U, 0x01U, 0x31U, 0x01U, 0x01U, 0x7EU, 0x41U, 0x01U, 0x41U,
|
||||
0x01U, 0x10U, 0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x42U,
|
||||
0x0DU, 0x42U, 0x0EU, 0x42U, 0x00U, 0x10U, 0x01U, 0x22U, 0x01U,
|
||||
0x42U, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x1FU, 0x83U, 0x42U,
|
||||
0x94U, 0x80U, 0xCCU, 0x80U, 0x30U, 0x52U, 0x1BU, 0x20U, 0x01U,
|
||||
0x42U, 0x00U, 0x53U, 0x1BU, 0x10U, 0x02U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 5 ==== */
|
||||
@@ -318,18 +277,20 @@ inline std::map<std::string, std::vector<uint8_t>> consensusentropy_test_wasm =
|
||||
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 dice(uint32_t sides, uint32_t min_tier);
|
||||
extern int64_t entropy_status(uint32_t write_ptr, uint32_t write_len);
|
||||
extern int64_t entropy_status();
|
||||
#define ENTROPY_TIER(x) (((uint64_t)(x) >> 32U) & 0xFFU)
|
||||
#define ENTROPY_COUNT(x) (((uint64_t)(x) >> 16U) & 0xFFFFU)
|
||||
#define ENTROPY_DENOMINATOR(x) ((uint64_t)(x) & 0xFFFFU)
|
||||
#define TOO_LITTLE_ENTROPY (-48)
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t status[5];
|
||||
int64_t age = entropy_status((uint32_t)status, 5);
|
||||
if (age < 0 || age > 1)
|
||||
int64_t status = entropy_status();
|
||||
if (status < 0)
|
||||
return accept(0, 0, 20);
|
||||
if (status[0] != 1 || status[1] != 0 || status[2] != 0 ||
|
||||
status[3] != 0 || status[4] != 0)
|
||||
if (ENTROPY_TIER(status) != 1 || ENTROPY_COUNT(status) != 0 ||
|
||||
ENTROPY_DENOMINATOR(status) != 0)
|
||||
return accept(0, 0, 21);
|
||||
|
||||
int64_t allowed = dice(6, 1);
|
||||
@@ -338,40 +299,33 @@ inline std::map<std::string, std::vector<uint8_t>> consensusentropy_test_wasm =
|
||||
if (dice(6, 2) != TOO_LITTLE_ENTROPY)
|
||||
return accept(0, 0, 23);
|
||||
|
||||
return accept(0, 0, age);
|
||||
return accept(0, 0, 0);
|
||||
}
|
||||
)[test.hook]",
|
||||
{
|
||||
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U,
|
||||
0x19U, 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U,
|
||||
0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x03U, 0x7FU, 0x7FU,
|
||||
0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U,
|
||||
0x37U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U,
|
||||
0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0EU, 0x65U, 0x6EU,
|
||||
0x74U, 0x72U, 0x6FU, 0x70U, 0x79U, 0x5FU, 0x73U, 0x74U, 0x61U,
|
||||
0x74U, 0x75U, 0x73U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U,
|
||||
0x04U, 0x64U, 0x69U, 0x63U, 0x65U, 0x00U, 0x00U, 0x03U, 0x65U,
|
||||
0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U,
|
||||
0x00U, 0x02U, 0x03U, 0x02U, 0x01U, 0x03U, 0x05U, 0x03U, 0x01U,
|
||||
0x00U, 0x01U, 0x06U, 0x08U, 0x01U, 0x7FU, 0x01U, 0x41U, 0x80U,
|
||||
0x80U, 0x04U, 0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU,
|
||||
0x6FU, 0x6BU, 0x00U, 0x04U, 0x0AU, 0x90U, 0x01U, 0x01U, 0x8DU,
|
||||
0x01U, 0x01U, 0x02U, 0x7EU, 0x23U, 0x00U, 0x41U, 0x10U, 0x6BU,
|
||||
0x22U, 0x00U, 0x24U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U,
|
||||
0x00U, 0x1AU, 0x02U, 0x40U, 0x20U, 0x00U, 0x41U, 0x0BU, 0x6AU,
|
||||
0x41U, 0x05U, 0x10U, 0x01U, 0x22U, 0x02U, 0x42U, 0x01U, 0x56U,
|
||||
0x04U, 0x40U, 0x42U, 0x14U, 0x21U, 0x01U, 0x0CU, 0x01U, 0x0BU,
|
||||
0x42U, 0x15U, 0x21U, 0x01U, 0x20U, 0x00U, 0x2DU, 0x00U, 0x0BU,
|
||||
0x41U, 0x01U, 0x47U, 0x0DU, 0x00U, 0x20U, 0x00U, 0x2DU, 0x00U,
|
||||
0x0CU, 0x0DU, 0x00U, 0x20U, 0x00U, 0x2DU, 0x00U, 0x0DU, 0x0DU,
|
||||
0x00U, 0x20U, 0x00U, 0x2DU, 0x00U, 0x0EU, 0x0DU, 0x00U, 0x20U,
|
||||
0x00U, 0x2DU, 0x00U, 0x0FU, 0x0DU, 0x00U, 0x41U, 0x06U, 0x41U,
|
||||
0x01U, 0x10U, 0x02U, 0x42U, 0x05U, 0x56U, 0x04U, 0x40U, 0x42U,
|
||||
0x16U, 0x21U, 0x01U, 0x0CU, 0x01U, 0x0BU, 0x42U, 0x17U, 0x20U,
|
||||
0x02U, 0x41U, 0x06U, 0x41U, 0x02U, 0x10U, 0x02U, 0x42U, 0x50U,
|
||||
0x52U, 0x1BU, 0x21U, 0x01U, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U,
|
||||
0x20U, 0x01U, 0x10U, 0x03U, 0x21U, 0x01U, 0x20U, 0x00U, 0x41U,
|
||||
0x10U, 0x6AU, 0x24U, 0x00U, 0x20U, 0x01U, 0x0BU,
|
||||
0x1DU, 0x05U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U,
|
||||
0x00U, 0x01U, 0x7EU, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7EU,
|
||||
0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U,
|
||||
0x7FU, 0x01U, 0x7EU, 0x02U, 0x37U, 0x04U, 0x03U, 0x65U, 0x6EU,
|
||||
0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU,
|
||||
0x76U, 0x0EU, 0x65U, 0x6EU, 0x74U, 0x72U, 0x6FU, 0x70U, 0x79U,
|
||||
0x5FU, 0x73U, 0x74U, 0x61U, 0x74U, 0x75U, 0x73U, 0x00U, 0x01U,
|
||||
0x03U, 0x65U, 0x6EU, 0x76U, 0x04U, 0x64U, 0x69U, 0x63U, 0x65U,
|
||||
0x00U, 0x02U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U, 0x63U,
|
||||
0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x03U, 0x03U, 0x02U, 0x01U,
|
||||
0x04U, 0x05U, 0x03U, 0x01U, 0x00U, 0x01U, 0x07U, 0x08U, 0x01U,
|
||||
0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x04U, 0x0AU, 0x54U,
|
||||
0x01U, 0x52U, 0x01U, 0x01U, 0x7EU, 0x41U, 0x01U, 0x41U, 0x01U,
|
||||
0x10U, 0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x02U, 0x7EU,
|
||||
0x42U, 0x14U, 0x10U, 0x01U, 0x22U, 0x01U, 0x42U, 0x00U, 0x53U,
|
||||
0x0DU, 0x00U, 0x1AU, 0x42U, 0x15U, 0x20U, 0x01U, 0x42U, 0xFFU,
|
||||
0xFFU, 0xFFU, 0xFFU, 0xFFU, 0x1FU, 0x83U, 0x42U, 0x80U, 0x80U,
|
||||
0x80U, 0x80U, 0x10U, 0x52U, 0x0DU, 0x00U, 0x1AU, 0x42U, 0x16U,
|
||||
0x41U, 0x06U, 0x41U, 0x01U, 0x10U, 0x02U, 0x42U, 0x05U, 0x56U,
|
||||
0x0DU, 0x00U, 0x1AU, 0x42U, 0x17U, 0x42U, 0x00U, 0x41U, 0x06U,
|
||||
0x41U, 0x02U, 0x10U, 0x02U, 0x42U, 0x50U, 0x52U, 0x1BU, 0x0BU,
|
||||
0x10U, 0x03U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 6 ==== */
|
||||
@@ -410,43 +364,156 @@ inline std::map<std::string, std::vector<uint8_t>> consensusentropy_test_wasm =
|
||||
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 dice(uint32_t sides, uint32_t min_tier);
|
||||
extern int64_t entropy_status(uint32_t write_ptr, uint32_t write_len);
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t status[5];
|
||||
int64_t result = entropy_status((uint32_t)status, 5);
|
||||
if (result >= 0)
|
||||
result = dice(6, 3);
|
||||
return accept(0, 0, result);
|
||||
return accept(0, 0, dice(6, 3));
|
||||
}
|
||||
)[test.hook]",
|
||||
{
|
||||
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U,
|
||||
0x19U, 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U,
|
||||
0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U, 0x03U, 0x7FU, 0x7FU,
|
||||
0x19U, 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U,
|
||||
0x02U, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU,
|
||||
0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U,
|
||||
0x37U, 0x04U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U,
|
||||
0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x0EU, 0x65U, 0x6EU,
|
||||
0x74U, 0x72U, 0x6FU, 0x70U, 0x79U, 0x5FU, 0x73U, 0x74U, 0x61U,
|
||||
0x74U, 0x75U, 0x73U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U,
|
||||
0x04U, 0x64U, 0x69U, 0x63U, 0x65U, 0x00U, 0x00U, 0x03U, 0x65U,
|
||||
0x22U, 0x03U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U,
|
||||
0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x04U, 0x64U, 0x69U,
|
||||
0x63U, 0x65U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U,
|
||||
0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U, 0x03U,
|
||||
0x02U, 0x01U, 0x03U, 0x05U, 0x03U, 0x01U, 0x00U, 0x01U, 0x07U,
|
||||
0x08U, 0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x03U,
|
||||
0x0AU, 0x17U, 0x01U, 0x15U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U,
|
||||
0x10U, 0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x41U, 0x06U,
|
||||
0x41U, 0x03U, 0x10U, 0x01U, 0x10U, 0x02U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 8 ==== */
|
||||
{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 random(uint32_t write_ptr, uint32_t write_len, uint32_t min_tier);
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t buf[32];
|
||||
return accept(0, 0, random((uint32_t)buf, 32, 3));
|
||||
}
|
||||
)[test.hook]",
|
||||
{
|
||||
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U,
|
||||
0x1AU, 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U,
|
||||
0x03U, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU,
|
||||
0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU,
|
||||
0x02U, 0x24U, 0x03U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU,
|
||||
0x67U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x72U,
|
||||
0x61U, 0x6EU, 0x64U, 0x6FU, 0x6DU, 0x00U, 0x01U, 0x03U, 0x65U,
|
||||
0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U,
|
||||
0x00U, 0x02U, 0x03U, 0x02U, 0x01U, 0x03U, 0x05U, 0x03U, 0x01U,
|
||||
0x00U, 0x01U, 0x06U, 0x08U, 0x01U, 0x7FU, 0x01U, 0x41U, 0x80U,
|
||||
0x80U, 0x04U, 0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU,
|
||||
0x6FU, 0x6BU, 0x00U, 0x04U, 0x0AU, 0x41U, 0x01U, 0x3FU, 0x01U,
|
||||
0x01U, 0x7EU, 0x23U, 0x00U, 0x41U, 0x10U, 0x6BU, 0x22U, 0x00U,
|
||||
0x6FU, 0x6BU, 0x00U, 0x03U, 0x0AU, 0x2FU, 0x01U, 0x2DU, 0x01U,
|
||||
0x01U, 0x7EU, 0x23U, 0x00U, 0x41U, 0x20U, 0x6BU, 0x22U, 0x00U,
|
||||
0x24U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U, 0x00U, 0x1AU,
|
||||
0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x00U, 0x41U, 0x0BU, 0x6AU,
|
||||
0x41U, 0x05U, 0x10U, 0x01U, 0x22U, 0x01U, 0x42U, 0x00U, 0x59U,
|
||||
0x04U, 0x7EU, 0x41U, 0x06U, 0x41U, 0x03U, 0x10U, 0x02U, 0x05U,
|
||||
0x20U, 0x01U, 0x0BU, 0x10U, 0x03U, 0x21U, 0x01U, 0x20U, 0x00U,
|
||||
0x41U, 0x10U, 0x6AU, 0x24U, 0x00U, 0x20U, 0x01U, 0x0BU,
|
||||
0x41U, 0x00U, 0x41U, 0x00U, 0x20U, 0x00U, 0x41U, 0x20U, 0x41U,
|
||||
0x03U, 0x10U, 0x01U, 0x10U, 0x02U, 0x21U, 0x01U, 0x20U, 0x00U,
|
||||
0x41U, 0x20U, 0x6AU, 0x24U, 0x00U, 0x20U, 0x01U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 8 ==== */
|
||||
/* ==== WASM: 9 ==== */
|
||||
{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 entropy_status();
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
return accept(0, 0, entropy_status());
|
||||
}
|
||||
)[test.hook]",
|
||||
{
|
||||
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U,
|
||||
0x17U, 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U,
|
||||
0x00U, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU, 0x7FU, 0x7EU, 0x01U,
|
||||
0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x02U, 0x2CU, 0x03U,
|
||||
0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU, 0x67U, 0x00U, 0x00U,
|
||||
0x03U, 0x65U, 0x6EU, 0x76U, 0x0EU, 0x65U, 0x6EU, 0x74U, 0x72U,
|
||||
0x6FU, 0x70U, 0x79U, 0x5FU, 0x73U, 0x74U, 0x61U, 0x74U, 0x75U,
|
||||
0x73U, 0x00U, 0x01U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x61U,
|
||||
0x63U, 0x63U, 0x65U, 0x70U, 0x74U, 0x00U, 0x02U, 0x03U, 0x02U,
|
||||
0x01U, 0x03U, 0x05U, 0x03U, 0x01U, 0x00U, 0x01U, 0x07U, 0x08U,
|
||||
0x01U, 0x04U, 0x68U, 0x6FU, 0x6FU, 0x6BU, 0x00U, 0x03U, 0x0AU,
|
||||
0x13U, 0x01U, 0x11U, 0x00U, 0x41U, 0x01U, 0x41U, 0x01U, 0x10U,
|
||||
0x00U, 0x1AU, 0x41U, 0x00U, 0x41U, 0x00U, 0x10U, 0x01U, 0x10U,
|
||||
0x02U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 10 ==== */
|
||||
{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 random(uint32_t write_ptr, uint32_t write_len, uint32_t min_tier);
|
||||
#define GUARD(maxiter) _g((1ULL << 31U) + __LINE__, (maxiter)+1)
|
||||
#define TOO_LITTLE_ENTROPY (-48)
|
||||
|
||||
int64_t hook(uint32_t r)
|
||||
{
|
||||
_g(1,1);
|
||||
uint8_t buf[32];
|
||||
for (int i = 0; GUARD(32), i < 32; ++i)
|
||||
buf[i] = 0xA5;
|
||||
|
||||
if (random((uint32_t)buf, 32, 4) != TOO_LITTLE_ENTROPY)
|
||||
return accept(0, 0, 30);
|
||||
for (int i = 0; GUARD(32), i < 32; ++i)
|
||||
if (buf[i] != 0xA5)
|
||||
return accept(0, 0, 31);
|
||||
|
||||
return accept(0, 0, 0);
|
||||
}
|
||||
)[test.hook]",
|
||||
{
|
||||
0x00U, 0x61U, 0x73U, 0x6DU, 0x01U, 0x00U, 0x00U, 0x00U, 0x01U,
|
||||
0x1AU, 0x04U, 0x60U, 0x02U, 0x7FU, 0x7FU, 0x01U, 0x7FU, 0x60U,
|
||||
0x03U, 0x7FU, 0x7FU, 0x7FU, 0x01U, 0x7EU, 0x60U, 0x03U, 0x7FU,
|
||||
0x7FU, 0x7EU, 0x01U, 0x7EU, 0x60U, 0x01U, 0x7FU, 0x01U, 0x7EU,
|
||||
0x02U, 0x24U, 0x03U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x02U, 0x5FU,
|
||||
0x67U, 0x00U, 0x00U, 0x03U, 0x65U, 0x6EU, 0x76U, 0x06U, 0x72U,
|
||||
0x61U, 0x6EU, 0x64U, 0x6FU, 0x6DU, 0x00U, 0x01U, 0x03U, 0x65U,
|
||||
0x6EU, 0x76U, 0x06U, 0x61U, 0x63U, 0x63U, 0x65U, 0x70U, 0x74U,
|
||||
0x00U, 0x02U, 0x03U, 0x02U, 0x01U, 0x03U, 0x05U, 0x03U, 0x01U,
|
||||
0x00U, 0x01U, 0x06U, 0x08U, 0x01U, 0x7FU, 0x01U, 0x41U, 0x80U,
|
||||
0x80U, 0x04U, 0x0BU, 0x07U, 0x08U, 0x01U, 0x04U, 0x68U, 0x6FU,
|
||||
0x6FU, 0x6BU, 0x00U, 0x03U, 0x0AU, 0xC7U, 0x01U, 0x01U, 0xC4U,
|
||||
0x01U, 0x02U, 0x01U, 0x7FU, 0x01U, 0x7EU, 0x23U, 0x00U, 0x41U,
|
||||
0x20U, 0x6BU, 0x22U, 0x01U, 0x24U, 0x00U, 0x41U, 0x01U, 0x41U,
|
||||
0x01U, 0x10U, 0x00U, 0x1AU, 0x41U, 0x8DU, 0x80U, 0x80U, 0x80U,
|
||||
0x78U, 0x41U, 0x21U, 0x10U, 0x00U, 0x1AU, 0x41U, 0x00U, 0x21U,
|
||||
0x00U, 0x03U, 0x40U, 0x41U, 0x8DU, 0x80U, 0x80U, 0x80U, 0x78U,
|
||||
0x41U, 0x21U, 0x10U, 0x00U, 0x1AU, 0x20U, 0x00U, 0x20U, 0x01U,
|
||||
0x6AU, 0x41U, 0xA5U, 0x01U, 0x3AU, 0x00U, 0x00U, 0x01U, 0x01U,
|
||||
0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U,
|
||||
0x20U, 0x00U, 0x41U, 0x01U, 0x6AU, 0x22U, 0x00U, 0x41U, 0x20U,
|
||||
0x47U, 0x0DU, 0x00U, 0x0BU, 0x41U, 0x00U, 0x41U, 0x00U, 0x02U,
|
||||
0x7EU, 0x42U, 0x1EU, 0x20U, 0x01U, 0x41U, 0x20U, 0x41U, 0x04U,
|
||||
0x10U, 0x01U, 0x42U, 0x50U, 0x52U, 0x0DU, 0x00U, 0x1AU, 0x41U,
|
||||
0x92U, 0x80U, 0x80U, 0x80U, 0x78U, 0x41U, 0x21U, 0x10U, 0x00U,
|
||||
0x1AU, 0x41U, 0x00U, 0x21U, 0x00U, 0x02U, 0x40U, 0x03U, 0x40U,
|
||||
0x41U, 0x92U, 0x80U, 0x80U, 0x80U, 0x78U, 0x41U, 0x21U, 0x10U,
|
||||
0x00U, 0x1AU, 0x20U, 0x00U, 0x20U, 0x01U, 0x6AU, 0x2DU, 0x00U,
|
||||
0x00U, 0x41U, 0xA5U, 0x01U, 0x47U, 0x0DU, 0x01U, 0x01U, 0x01U,
|
||||
0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U, 0x01U,
|
||||
0x20U, 0x00U, 0x41U, 0x01U, 0x6AU, 0x22U, 0x00U, 0x41U, 0x20U,
|
||||
0x47U, 0x0DU, 0x00U, 0x0BU, 0x42U, 0x00U, 0x0CU, 0x01U, 0x0BU,
|
||||
0x42U, 0x1FU, 0x0BU, 0x10U, 0x02U, 0x21U, 0x02U, 0x20U, 0x01U,
|
||||
0x41U, 0x20U, 0x6AU, 0x24U, 0x00U, 0x20U, 0x02U, 0x0BU,
|
||||
}},
|
||||
|
||||
/* ==== WASM: 11 ==== */
|
||||
{R"[test.hook](
|
||||
#include <stdint.h>
|
||||
extern int32_t _g(uint32_t, uint32_t);
|
||||
|
||||
@@ -131,8 +131,8 @@ Hooks state `min_tier` explicitly on every draw (no hidden network default).
|
||||
Entropy is served iff it is **fresh** (current or previous ledger) **and** meets
|
||||
that class floor; otherwise the call **fails closed**
|
||||
(`TOO_LITTLE_ENTROPY`). `entropy_status()` separately exposes the stored tier,
|
||||
contributor count, denominator, and ledger age so hooks can impose proportional
|
||||
or absolute policies without freezing those policies into the host ABI.
|
||||
contributor count, and denominator so hooks can impose proportional or absolute
|
||||
policies without freezing those policies into the host ABI.
|
||||
Fallback is tier 1 with count/denominator `0/0`, so callers must classify tier
|
||||
before arithmetic. Draws are also domain-separated by the hook execution role
|
||||
that can share a transaction and hook hash: strong vs weak, callback vs direct
|
||||
|
||||
@@ -383,9 +383,10 @@ fallback-grade randomness must do so explicitly at the call site. Valid
|
||||
`INVALID_ARGUMENT`, while valid-but-unmet requirements return
|
||||
`TOO_LITTLE_ENTROPY`.
|
||||
|
||||
`entropy_status(write_ptr, write_len)` writes the fixed five-byte big-endian
|
||||
tuple `(tier:u8, count:u16, denominator:u16)` and returns the metadata's ledger
|
||||
age. This lets Hook code implement policies such as one-absent tolerance,
|
||||
`entropy_status()` returns a packed non-negative scalar with tier in bits
|
||||
32..39, contributor count in bits 16..31, and denominator in bits 0..15.
|
||||
Negative values remain Hook API errors. This lets Hook code implement policies
|
||||
such as one-absent tolerance,
|
||||
proportional participation, or an absolute floor without widening the frozen
|
||||
draw API. It exposes no digest. Callers must classify tier before count or
|
||||
denominator arithmetic because fallback deliberately reports tier 1 and
|
||||
@@ -393,9 +394,9 @@ denominator arithmetic because fallback deliberately reports tier 1 and
|
||||
|
||||
Open-ledger hook execution is provisional. During speculative open-ledger
|
||||
execution, `dice()`/`random()` and `entropy_status()` can only use the previous
|
||||
ledger's finalized entropy (status age 1); final buildLCL execution sees the
|
||||
current ledger's entropy pseudo-tx after it updates the SLE (status age 0).
|
||||
Hooks that need final entropy must treat open-ledger RNG results as previews.
|
||||
ledger's finalized entropy; final buildLCL execution sees the current ledger's
|
||||
entropy pseudo-tx after it updates the SLE. Hooks that need final entropy must
|
||||
treat open-ledger RNG results as previews.
|
||||
|
||||
The fallback digest derives from the agreed pre-injection tx set hash to avoid
|
||||
circularity, and entropy pseudo-tx deduplication is value-based: if the agreed
|
||||
|
||||
@@ -4266,38 +4266,17 @@ DEFINE_HOOK_FUNCTION(
|
||||
HOOK_TEARDOWN();
|
||||
}
|
||||
|
||||
DEFINE_HOOK_FUNCTION(
|
||||
int64_t,
|
||||
entropy_status,
|
||||
uint32_t write_ptr,
|
||||
uint32_t write_len)
|
||||
DEFINE_HOOK_FUNCTION(int64_t, entropy_status)
|
||||
{
|
||||
HOOK_SETUP();
|
||||
|
||||
constexpr std::size_t statusSize = 5;
|
||||
if (write_len < statusSize)
|
||||
return TOO_SMALL;
|
||||
|
||||
if (NOT_IN_BOUNDS(write_ptr, statusSize, memory_length))
|
||||
return OUT_OF_BOUNDS;
|
||||
|
||||
auto snapshot = readEntropySnapshot(view);
|
||||
if (std::holds_alternative<hook_api::hook_return_code>(snapshot))
|
||||
return std::get<hook_api::hook_return_code>(snapshot);
|
||||
|
||||
auto const& entropy = std::get<EntropySnapshot>(snapshot);
|
||||
std::array<std::uint8_t, statusSize> const status{
|
||||
entropy.tier,
|
||||
static_cast<std::uint8_t>(entropy.count >> 8),
|
||||
static_cast<std::uint8_t>(entropy.count),
|
||||
static_cast<std::uint8_t>(entropy.denominator >> 8),
|
||||
static_cast<std::uint8_t>(entropy.denominator)};
|
||||
|
||||
if (!WasmEdge_ResultOK(WasmEdge_MemoryInstanceSetData(
|
||||
memoryCtx, status.data(), write_ptr, status.size())))
|
||||
return INTERNAL_ERROR;
|
||||
|
||||
return entropy.age;
|
||||
return (std::uint64_t{entropy.tier} << 32U) |
|
||||
(std::uint64_t{entropy.count} << 16U) | entropy.denominator;
|
||||
|
||||
HOOK_TEARDOWN();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user