Skip to content

Commit

Permalink
take genesis block transactions into account
Browse files Browse the repository at this point in the history
  • Loading branch information
oXtxNt9U committed Jan 21, 2025
1 parent de0ad70 commit ef50fe3
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,13 @@ describe<{
}
});

it("#getSchema - gasPrice should be integer, min 0, max 1000", ({ validator }) => {
it("#getSchema - gasPrice should be integer, min 5, max 1000", ({ sandbox, validator }) => {
validator.addSchema(EvmCallTransaction.getSchema());

const validValues = [0, 5, 6, 1000];
const configuration = sandbox.app.get<Configuration>(Identifiers.Cryptography.Configuration);
configuration.setHeight(1);

const validValues = [5, 6, 1000];
for (const value of validValues) {
const transaction = {
...transactionOriginal,
Expand All @@ -104,7 +107,7 @@ describe<{
assert.undefined(validator.validate("evmCall", transaction).error);
}

const invalidValues = [-1, 1.1, "test", null, undefined, {}];
const invalidValues = [0, -1, 1.1, "test", null, undefined, {}];
for (const value of invalidValues) {
const transaction = {
...transactionOriginal,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,6 @@ describe<{
assert.defined(context.validator.validate("test", -1).error);
assert.defined(context.validator.validate("test", 10001).error);
assert.defined(context.validator.validate("test", Number.MAX_SAFE_INTEGER).error);

// Simulate genesis block
configuration.setHeight(0);

assert.defined(context.validator.validate("test", 1).error); // still fails
assert.undefined(context.validator.validate("test", 0).error); // now passes
});

it("keyword transactionGasLimit should be ok", (context) => {
Expand Down
28 changes: 26 additions & 2 deletions packages/crypto-transaction/source/validation/keywords.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,10 @@ export const makeKeywords = (configuration: Contracts.Crypto.Configuration) => {
const transactionGasPrice: FuncKeywordDefinition = {
// @ts-ignore
compile(schema) {
return (data) => {
// Used as lazy cache
const genesisTransactionsLookup: Set<string> = new Set();

return (data, parentSchema: AnySchemaObject) => {
const {
gas: { minimumGasPrice, maximumGasPrice },
} = configuration.getMilestone();
Expand All @@ -45,8 +48,29 @@ export const makeKeywords = (configuration: Contracts.Crypto.Configuration) => {
const bignum = BigNumber.make(data);
if (bignum.isLessThan(minimumGasPrice)) {
// Accept 0 gasFee when processing genesis block only
if (!bignum.isZero()) {
return false;
}

// The height check is needed for when e.g. the genesis block itself is being built.
const height = configuration.getHeight();
return height === 0 && bignum.isZero();
let valid = height === 0;

// Otherwise lookup by transaction id
if (!valid && parentSchema && parentSchema.parentData && parentSchema.parentData.id) {
if (genesisTransactionsLookup.size === 0) {
const genesisBlock = configuration.get<Contracts.Crypto.BlockData | undefined>(
"genesisBlock.block",
);
for (const transaction of genesisBlock?.transactions || []) {
genesisTransactionsLookup.add(transaction.id);
}
}

valid = genesisTransactionsLookup.has(parentSchema.parentData.id);
}

return valid;
}

// The upper limit technically isn't needed and solely acts as a safeguard
Expand Down
17 changes: 13 additions & 4 deletions packages/crypto-transaction/source/validation/schemas.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Identifiers } from "@mainsail/contracts";
import { Contracts, Identifiers } from "@mainsail/contracts";
import { schemas as addressSchemas } from "@mainsail/crypto-address-keccak256";
import { Configuration } from "@mainsail/crypto-config";
import { schemas as keyPairSchemas } from "@mainsail/crypto-key-pair-ecdsa";
Expand Down Expand Up @@ -192,7 +192,10 @@ describe<{
});

it("transactionBaseSchema - gasPrice should accept 0 for genesis block", ({ sandbox, validator }) => {
sandbox.app.get<Configuration>(Identifiers.Cryptography.Configuration).setHeight(0);
const configuration = sandbox.app.get<Configuration>(Identifiers.Cryptography.Configuration);
configuration.setHeight(1);

const genesisBlock: Contracts.Crypto.BlockData = configuration.get("genesisBlock.block");

validator.addSchema(schema);

Expand All @@ -201,11 +204,17 @@ describe<{
gasPrice: 0,
};

assert.undefined(validator.validate("transaction", transaction).error);
genesisBlock.transactions.push(transaction as unknown as Contracts.Crypto.TransactionData);

sandbox.app.get<Configuration>(Identifiers.Cryptography.Configuration).setHeight(1);
assert.undefined(validator.validate("transaction", transaction).error);

// Fails for non-genesis tx
transaction.id = "2".repeat(64);
assert.true(validator.validate("transaction", transaction).error.includes("gasPrice"));

// But works on height 0
configuration.setHeight(0);
assert.undefined(validator.validate("transaction", transaction).error);
});

it("transactionBaseSchema - id should be transactionId", ({ validator }) => {
Expand Down

0 comments on commit ef50fe3

Please sign in to comment.