@aztec-labs/p2p 6.0.0-rc.1 → 6.0.0-rc.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dest/bootstrap/bootstrap.d.ts +2 -2
- package/dest/bootstrap/bootstrap.d.ts.map +1 -1
- package/dest/bootstrap/bootstrap.js +4 -2
- package/dest/client/factory.d.ts +3 -3
- package/dest/client/factory.d.ts.map +1 -1
- package/dest/client/factory.js +6 -6
- package/dest/client/interface.d.ts +1 -1
- package/dest/client/p2p_client.d.ts +1 -1
- package/dest/client/p2p_client.js +1 -1
- package/dest/config.d.ts +11 -1
- package/dest/config.d.ts.map +1 -1
- package/dest/config.js +16 -0
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts +15 -3
- package/dest/mem_pools/attestation_pool/attestation_pool.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool.js +15 -0
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.d.ts.map +1 -1
- package/dest/mem_pools/attestation_pool/attestation_pool_test_suite.js +21 -0
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts +6 -2
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/eviction_manager.js +9 -0
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts +10 -8
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.js +22 -11
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts +6 -2
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/eviction/interfaces.js +2 -1
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts +11 -5
- package/dest/mem_pools/tx_pool_v2/interfaces.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.d.ts.map +1 -1
- package/dest/mem_pools/tx_pool_v2/tx_pool_v2_impl.js +111 -44
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.d.ts.map +1 -1
- package/dest/msg_validators/attestation_validator/attestation_validator.js +3 -24
- package/dest/msg_validators/epoch_cache_lookup.d.ts +18 -0
- package/dest/msg_validators/epoch_cache_lookup.d.ts.map +1 -0
- package/dest/msg_validators/epoch_cache_lookup.js +29 -0
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.d.ts.map +1 -1
- package/dest/msg_validators/proposal_validator/proposal_validator.js +80 -82
- package/dest/msg_validators/tx_validator/data_validator.d.ts +1 -1
- package/dest/msg_validators/tx_validator/data_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/data_validator.js +4 -3
- package/dest/msg_validators/tx_validator/factory.d.ts +40 -11
- package/dest/msg_validators/tx_validator/factory.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/factory.js +36 -5
- package/dest/msg_validators/tx_validator/gas_validator.d.ts +18 -10
- package/dest/msg_validators/tx_validator/gas_validator.d.ts.map +1 -1
- package/dest/msg_validators/tx_validator/gas_validator.js +37 -27
- package/dest/services/discv5/discV5_service.d.ts +2 -2
- package/dest/services/discv5/discV5_service.d.ts.map +1 -1
- package/dest/services/discv5/discV5_service.js +3 -1
- package/dest/services/libp2p/libp2p_service.d.ts +18 -9
- package/dest/services/libp2p/libp2p_service.d.ts.map +1 -1
- package/dest/services/libp2p/libp2p_service.js +127 -29
- package/dest/services/peer-manager/peer_manager.d.ts +1 -1
- package/dest/services/peer-manager/peer_manager.d.ts.map +1 -1
- package/dest/services/peer-manager/peer_manager.js +14 -0
- package/dest/services/tx_provider.d.ts +1 -1
- package/dest/services/tx_provider.d.ts.map +1 -1
- package/dest/services/tx_provider.js +3 -0
- package/dest/test-helpers/make-test-p2p-clients.d.ts +1 -1
- package/dest/test-helpers/make-test-p2p-clients.d.ts.map +1 -1
- package/dest/test-helpers/make-test-p2p-clients.js +3 -1
- package/dest/test-helpers/mock-pubsub.js +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts +1 -1
- package/dest/test-helpers/reqresp-nodes.d.ts.map +1 -1
- package/dest/test-helpers/reqresp-nodes.js +3 -1
- package/dest/test-helpers/testbench-utils.d.ts +4 -2
- package/dest/test-helpers/testbench-utils.d.ts.map +1 -1
- package/dest/test-helpers/testbench-utils.js +6 -0
- package/dest/testbench/p2p_client_testbench_worker.js +6 -2
- package/package.json +14 -14
- package/src/bootstrap/bootstrap.ts +3 -2
- package/src/client/factory.ts +7 -7
- package/src/client/interface.ts +1 -1
- package/src/client/p2p_client.ts +1 -1
- package/src/config.ts +11 -0
- package/src/mem_pools/attestation_pool/attestation_pool.ts +25 -0
- package/src/mem_pools/attestation_pool/attestation_pool_test_suite.ts +31 -0
- package/src/mem_pools/tx_pool_v2/README.md +1 -1
- package/src/mem_pools/tx_pool_v2/eviction/eviction_manager.ts +13 -1
- package/src/mem_pools/tx_pool_v2/eviction/insufficient_fee_per_gas_eviction_rule.ts +17 -9
- package/src/mem_pools/tx_pool_v2/eviction/interfaces.ts +6 -1
- package/src/mem_pools/tx_pool_v2/interfaces.ts +10 -4
- package/src/mem_pools/tx_pool_v2/tx_pool_v2_impl.ts +95 -40
- package/src/msg_validators/attestation_validator/attestation_validator.ts +3 -23
- package/src/msg_validators/epoch_cache_lookup.ts +33 -0
- package/src/msg_validators/proposal_validator/README.md +3 -3
- package/src/msg_validators/proposal_validator/proposal_validator.ts +78 -77
- package/src/msg_validators/tx_validator/README.md +12 -8
- package/src/msg_validators/tx_validator/data_validator.ts +4 -3
- package/src/msg_validators/tx_validator/factory.ts +60 -14
- package/src/msg_validators/tx_validator/gas_validator.ts +46 -34
- package/src/services/discv5/discV5_service.ts +2 -1
- package/src/services/libp2p/libp2p_service.ts +138 -34
- package/src/services/peer-manager/peer_manager.ts +14 -0
- package/src/services/tx_provider.ts +3 -0
- package/src/test-helpers/make-test-p2p-clients.ts +5 -1
- package/src/test-helpers/mock-pubsub.ts +3 -3
- package/src/test-helpers/reqresp-nodes.ts +5 -1
- package/src/test-helpers/testbench-utils.ts +13 -1
- package/src/testbench/p2p_client_testbench_worker.ts +10 -2
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { NoCommitteeError } from '@aztec-labs/ethereum/contracts';
|
|
2
1
|
import { createLogger } from '@aztec-labs/foundation/log';
|
|
3
2
|
import { MAX_ATTESTABLE_BLOCKS_PER_CHECKPOINT, MAX_TXS_PER_CHECKPOINT } from '@aztec-labs/stdlib/deserialization';
|
|
4
3
|
import { PeerErrorSeverity, hasValidSignatureContext } from '@aztec-labs/stdlib/p2p';
|
|
4
|
+
import { mapEpochCacheLookupFailure } from '../epoch_cache_lookup.js';
|
|
5
5
|
import { classifyReceiveWindowArrival } from '../receive_window.js';
|
|
6
6
|
/** Validates header-level and tx-level fields of block and checkpoint proposals. */ export class ProposalValidator {
|
|
7
7
|
epochCache;
|
|
@@ -23,93 +23,91 @@ import { classifyReceiveWindowArrival } from '../receive_window.js';
|
|
|
23
23
|
this.logger = createLogger(loggerName);
|
|
24
24
|
}
|
|
25
25
|
/** Validates header-level fields: slot, signature, and proposer. */ async validate(proposal) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
windowDeadlineSeconds: deadlineSeconds
|
|
62
|
-
});
|
|
63
|
-
return windowMiss.outcome;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
// Signature validity
|
|
67
|
-
const proposer = proposal.getSender();
|
|
68
|
-
if (!proposer) {
|
|
69
|
-
this.logger.warn(`Penalizing peer for proposal with invalid signature`);
|
|
70
|
-
return {
|
|
71
|
-
result: 'reject',
|
|
72
|
-
severity: PeerErrorSeverity.MidToleranceError
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
// An undefined proposer means an empty committee (anyone may propose), so skip the
|
|
76
|
-
// proposer-equality check and keep validating. A missing committee instead throws
|
|
77
|
-
// NoCommitteeError, handled as a reject below.
|
|
78
|
-
const expectedProposer = await this.epochCache.getProposerAttesterAddressInSlot(slotNumber);
|
|
79
|
-
if (expectedProposer !== undefined && !proposer.equals(expectedProposer)) {
|
|
80
|
-
this.logger.warn(`Penalizing peer for invalid proposer for current slot ${slotNumber}`, {
|
|
81
|
-
expectedProposer,
|
|
82
|
-
proposer: proposer.toString()
|
|
26
|
+
// Cross-chain replay check: reject proposals that carry a foreign signing domain.
|
|
27
|
+
if (!hasValidSignatureContext(proposal, this.signatureContext)) {
|
|
28
|
+
this.logger.warn(`Penalizing peer for proposal with foreign signature context`, {
|
|
29
|
+
chainId: proposal.signatureContext.chainId,
|
|
30
|
+
rollupAddress: proposal.signatureContext.rollupAddress.toString(),
|
|
31
|
+
expectedChainId: this.signatureContext.chainId,
|
|
32
|
+
expectedRollupAddress: this.signatureContext.rollupAddress.toString()
|
|
33
|
+
});
|
|
34
|
+
return {
|
|
35
|
+
result: 'reject',
|
|
36
|
+
severity: PeerErrorSeverity.LowToleranceError
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// Slot check: the tight checkpoint proposal receive window (`[receiveStart - δ, target_slot_start -
|
|
40
|
+
// E - D + δ]`) is the sole acceptance gate, applied to both block and checkpoint proposals. The
|
|
41
|
+
// window itself bounds which slots are valid, so far/wrong slots fall outside it. Every block
|
|
42
|
+
// proposal for slot N is sent before the checkpoint proposal for slot N, so nothing legitimate can
|
|
43
|
+
// arrive after the checkpoint receive deadline; gating block proposals on the same window rejects
|
|
44
|
+
// late block proposals at p2p ingress. The attestation deadline remains their re-execution/
|
|
45
|
+
// validation deadline downstream, not their arrival gate.
|
|
46
|
+
const slotNumber = proposal.slotNumber;
|
|
47
|
+
if (!this.skipSlotValidation) {
|
|
48
|
+
// Proposal receive window: [checkpoint_proposal_receive_start, checkpoint_proposal_receive_deadline],
|
|
49
|
+
// widened by the configured clock-disparity tolerance on both ends.
|
|
50
|
+
const startSeconds = this.timetable.getCheckpointProposalReceiveStart(slotNumber);
|
|
51
|
+
const deadlineSeconds = this.timetable.getCheckpointProposalReceiveDeadline(slotNumber);
|
|
52
|
+
const nowMs = Number(this.epochCache.getEpochAndSlotNow().nowMs);
|
|
53
|
+
const windowMiss = classifyReceiveWindowArrival(nowMs, startSeconds * 1000 - this.clockDisparityMs, deadlineSeconds * 1000 + this.clockDisparityMs);
|
|
54
|
+
if (windowMiss) {
|
|
55
|
+
this.logger.warn(`Proposal for slot ${slotNumber} is outside its receive window (${windowMiss.outcome.result})`, {
|
|
56
|
+
slotNumber,
|
|
57
|
+
nowMs,
|
|
58
|
+
missMs: windowMiss.missMs,
|
|
59
|
+
windowStartSeconds: startSeconds,
|
|
60
|
+
windowDeadlineSeconds: deadlineSeconds
|
|
83
61
|
});
|
|
84
|
-
return
|
|
85
|
-
result: 'reject',
|
|
86
|
-
severity: PeerErrorSeverity.MidToleranceError
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
// A block proposal whose index lands at or beyond the hard attestable ceiling is structurally
|
|
90
|
-
// impossible garbage, so reject it immediately at ingress. Indices in
|
|
91
|
-
// `[maxBlocksPerCheckpoint, MAX_ATTESTABLE_BLOCKS_PER_CHECKPOINT)` are over the consensus limit
|
|
92
|
-
// but structurally valid proposer misbehavior; they pass gossip validation here so the offending
|
|
93
|
-
// proposal can be retained and re-broadcast as slashing evidence (handled downstream in the p2p
|
|
94
|
-
// service), rather than penalizing the relaying peer.
|
|
95
|
-
if ('indexWithinCheckpoint' in proposal) {
|
|
96
|
-
const indexResult = this.validateBlockIndexWithinCheckpoint(proposal);
|
|
97
|
-
if (indexResult.result !== 'accept') {
|
|
98
|
-
return indexResult;
|
|
99
|
-
}
|
|
62
|
+
return windowMiss.outcome;
|
|
100
63
|
}
|
|
64
|
+
}
|
|
65
|
+
// Signature validity
|
|
66
|
+
const proposer = proposal.getSender();
|
|
67
|
+
if (!proposer) {
|
|
68
|
+
this.logger.warn(`Penalizing peer for proposal with invalid signature`);
|
|
101
69
|
return {
|
|
102
|
-
result: '
|
|
70
|
+
result: 'reject',
|
|
71
|
+
severity: PeerErrorSeverity.MidToleranceError
|
|
103
72
|
};
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
73
|
+
}
|
|
74
|
+
// A block proposal whose index lands at or beyond the hard attestable ceiling is structurally
|
|
75
|
+
// impossible garbage, so reject it immediately at ingress. This is peer-attributable and needs no
|
|
76
|
+
// epoch-cache lookup, so it runs before the proposer lookup: a structurally-invalid index must be
|
|
77
|
+
// rejected even when a local lookup fails. Indices in
|
|
78
|
+
// `[maxBlocksPerCheckpoint, MAX_ATTESTABLE_BLOCKS_PER_CHECKPOINT)` are over the consensus limit
|
|
79
|
+
// but structurally valid proposer misbehavior; they pass gossip validation here so the offending
|
|
80
|
+
// proposal can be retained and re-broadcast as slashing evidence (handled downstream in the p2p
|
|
81
|
+
// service), rather than penalizing the relaying peer.
|
|
82
|
+
if ('indexWithinCheckpoint' in proposal) {
|
|
83
|
+
const indexResult = this.validateBlockIndexWithinCheckpoint(proposal);
|
|
84
|
+
if (indexResult.result !== 'accept') {
|
|
85
|
+
return indexResult;
|
|
110
86
|
}
|
|
111
|
-
throw e;
|
|
112
87
|
}
|
|
88
|
+
// An undefined proposer means an empty committee (anyone may propose), so skip the
|
|
89
|
+
// proposer-equality check and keep validating. Only this lookup can fail on a receiver-local
|
|
90
|
+
// cause (L1 RPC down, or this node behind); mapEpochCacheLookupFailure ignores that (it is not the
|
|
91
|
+
// relaying peer's fault) and rejects a missing committee (which is).
|
|
92
|
+
let expectedProposer;
|
|
93
|
+
try {
|
|
94
|
+
expectedProposer = await this.epochCache.getProposerAttesterAddressInSlot(slotNumber);
|
|
95
|
+
} catch (e) {
|
|
96
|
+
return mapEpochCacheLookupFailure(e, this.logger, 'proposal', slotNumber);
|
|
97
|
+
}
|
|
98
|
+
if (expectedProposer !== undefined && !proposer.equals(expectedProposer)) {
|
|
99
|
+
this.logger.warn(`Penalizing peer for invalid proposer for current slot ${slotNumber}`, {
|
|
100
|
+
expectedProposer,
|
|
101
|
+
proposer: proposer.toString()
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
result: 'reject',
|
|
105
|
+
severity: PeerErrorSeverity.MidToleranceError
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
return {
|
|
109
|
+
result: 'accept'
|
|
110
|
+
};
|
|
113
111
|
}
|
|
114
112
|
/**
|
|
115
113
|
* Rejects a block proposal whose index within its checkpoint lands at or beyond the hard attestable
|
|
@@ -6,4 +6,4 @@ export declare class DataTxValidator implements TxValidator<Tx> {
|
|
|
6
6
|
constructor(bindings?: LoggerBindings);
|
|
7
7
|
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
8
8
|
}
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0YV92YWxpZGF0b3IuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9tc2dfdmFsaWRhdG9ycy90eF92YWxpZGF0b3IvZGF0YV92YWxpZGF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFlLEtBQUssY0FBYyxFQUFnQixNQUFNLDRCQUE0QixDQUFDO0FBSTVGLE9BQU8sRUFZTCxFQUFFLEVBQ0YsS0FBSyxrQkFBa0IsRUFDdkIsS0FBSyxXQUFXLEVBQ2pCLE1BQU0sdUJBQXVCLENBQUM7QUFFL0IscUJBQWEsZUFBZ0IsWUFBVyxXQUFXLENBQUMsRUFBRSxDQUFDOztJQUNyRCxTQUFnQixVQUFVLEVBQUUsTUFBTSxDQUE2QjtJQUkvRCxZQUFZLFFBQVEsQ0FBQyxFQUFFLGNBQWMsRUFFcEM7SUFFSyxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxPQUFPLENBQUMsa0JBQWtCLENBQUMsQ0FRcEQ7Q0EwSkYifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/data_validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,4BAA4B,CAAC;AAI5F,OAAO,EAYL,EAAE,EACF,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAE/B,qBAAa,eAAgB,YAAW,WAAW,CAAC,EAAE,CAAC;;IACrD,SAAgB,UAAU,EAAE,MAAM,CAA6B;IAI/D,YAAY,QAAQ,CAAC,EAAE,cAAc,EAEpC;IAEK,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAQpD;
|
|
1
|
+
{"version":3,"file":"data_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/data_validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,4BAA4B,CAAC;AAI5F,OAAO,EAYL,EAAE,EACF,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAE/B,qBAAa,eAAgB,YAAW,WAAW,CAAC,EAAE,CAAC;;IACrD,SAAgB,UAAU,EAAE,MAAM,CAA6B;IAI/D,YAAY,QAAQ,CAAC,EAAE,cAAc,EAEpC;IAEK,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAQpD;CA0JF"}
|
|
@@ -72,9 +72,10 @@ export class DataTxValidator {
|
|
|
72
72
|
return TX_ERROR_CONTRACT_CLASS_LOGS;
|
|
73
73
|
}
|
|
74
74
|
}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
75
|
+
// The tx base requires exactly the trimmed length; any other length makes the tx unprovable.
|
|
76
|
+
const expectedLength = 1 + tx.contractClassLogFields[i].fields.findLastIndex((f)=>!f.isZero());
|
|
77
|
+
if (logHash.logHash.length !== expectedLength) {
|
|
78
|
+
this.#log.verbose(`Rejecting tx ${tx.getTxHash().toString()} because of incorrect contract class log length. Expected ${expectedLength}. Got ${logHash.logHash.length}.`);
|
|
78
79
|
return TX_ERROR_CONTRACT_CLASS_LOG_LENGTH;
|
|
79
80
|
}
|
|
80
81
|
}
|
|
@@ -33,7 +33,7 @@ import { BlockNumber } from '@aztec-labs/foundation/branded-types';
|
|
|
33
33
|
import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
34
34
|
import type { LoggerBindings } from '@aztec-labs/foundation/log';
|
|
35
35
|
import type { ContractDataSource } from '@aztec-labs/stdlib/contract';
|
|
36
|
-
import
|
|
36
|
+
import { GasFees } from '@aztec-labs/stdlib/gas';
|
|
37
37
|
import type { AllowedElement, ClientProtocolCircuitVerifier, MerkleTreeReadOperations, PublicProcessorValidator, WorldStateSynchronizer } from '@aztec-labs/stdlib/interfaces/server';
|
|
38
38
|
import { PeerErrorSeverity } from '@aztec-labs/stdlib/p2p';
|
|
39
39
|
import type { GlobalVariables, Tx, TxValidationResult, TxValidator } from '@aztec-labs/stdlib/tx';
|
|
@@ -41,30 +41,59 @@ import type { UInt64 } from '@aztec-labs/stdlib/types';
|
|
|
41
41
|
import type { TxMetaData } from '../../mem_pools/tx_pool_v2/tx_metadata.js';
|
|
42
42
|
import { TxValidationCache } from './tx_validation_cache.js';
|
|
43
43
|
/**
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
* with the associated severity level.
|
|
44
|
+
* Marks a gossip validator whose failure is not attributable to the sending peer: the tx is dropped without
|
|
45
|
+
* being added to the pool or propagated, and the peer's score is left alone.
|
|
47
46
|
*/
|
|
48
|
-
export
|
|
47
|
+
export declare const IgnoreWithoutPenalty = "ignore-without-penalty";
|
|
48
|
+
/**
|
|
49
|
+
* Consequence of a gossip validator failing: the sending peer is penalized with this severity, unless the
|
|
50
|
+
* failure is local policy rather than peer misbehavior, in which case it is {@link IgnoreWithoutPenalty}.
|
|
51
|
+
*/
|
|
52
|
+
export type GossipValidationFailure = PeerErrorSeverity | typeof IgnoreWithoutPenalty;
|
|
53
|
+
/**
|
|
54
|
+
* The fees a gossiped tx is checked against. A tx below `admission` is not relayed. A tx below `penaltyFloor` as
|
|
55
|
+
* well is priced lower than any view of the chain this node considers plausible, so its sender is penalized.
|
|
56
|
+
* `penaltyFloor` is never above `admission`.
|
|
57
|
+
*/
|
|
58
|
+
export type GossipMinFees = {
|
|
59
|
+
admission: GasFees;
|
|
60
|
+
penaltyFloor: GasFees;
|
|
61
|
+
};
|
|
62
|
+
/**
|
|
63
|
+
* Fraction of the lower of the admission and L1-forward fees below which a gossiped tx gets its sender penalized.
|
|
64
|
+
* A peer can legitimately price the next block below both: one that has seen a checkpoint this node has not can
|
|
65
|
+
* see the congestion fee drop, and the L1 gas components move with every L1 block. Halving leaves room for
|
|
66
|
+
* several such steps while still penalizing zero-fee and negligible-fee spam.
|
|
67
|
+
*/
|
|
68
|
+
export declare const GOSSIP_FEE_PENALTY_FLOOR_FRACTION = 0.5;
|
|
69
|
+
/** Derives the gossip fee thresholds from this node's admission fee and its L1-forward fee. */
|
|
70
|
+
export declare function computeGossipMinFees(admission: GasFees, l1Forward: GasFees): GossipMinFees;
|
|
71
|
+
/**
|
|
72
|
+
* A validator paired with the consequence of its failure.
|
|
73
|
+
* Used for gossip validation where each validator's failure triggers a peer penalization with the associated
|
|
74
|
+
* severity level. Only stages that can also fail on local policy widen `F` to include
|
|
75
|
+
* {@link IgnoreWithoutPenalty}.
|
|
76
|
+
*/
|
|
77
|
+
export interface TransactionValidator<F extends GossipValidationFailure = PeerErrorSeverity> {
|
|
49
78
|
validator: {
|
|
50
79
|
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
51
80
|
};
|
|
52
|
-
severity:
|
|
81
|
+
severity: F;
|
|
53
82
|
}
|
|
54
83
|
/**
|
|
55
84
|
* First stage of gossip validation — fast checks run before the pool pre-check.
|
|
56
85
|
*
|
|
57
|
-
* If any validator fails, the
|
|
58
|
-
*
|
|
86
|
+
* If any validator fails, the tx is rejected immediately, without consulting the pool or running proof
|
|
87
|
+
* verification. The peer is penalized unless the only failures are marked {@link IgnoreWithoutPenalty}.
|
|
59
88
|
*
|
|
60
89
|
* The `doubleSpendValidator` failure is special-cased by the caller (`handleGossipedTx`)
|
|
61
90
|
* to determine severity based on how recently the nullifier appeared. The caller reports the
|
|
62
91
|
* first failing entry among equally severe ones.
|
|
63
92
|
*/
|
|
64
|
-
export declare function createFirstStageTxValidationsForGossipedTransactions(timestamp: UInt64, blockNumber: BlockNumber, worldStateSynchronizer: WorldStateSynchronizer, gasFees:
|
|
93
|
+
export declare function createFirstStageTxValidationsForGossipedTransactions(timestamp: UInt64, blockNumber: BlockNumber, worldStateSynchronizer: WorldStateSynchronizer, gasFees: GossipMinFees, l1ChainId: number, rollupVersion: number, protocolContractsHash: Fr, contractDataSource: ContractDataSource, txsPermitted: boolean, allowedInSetup?: AllowedElement[], bindings?: LoggerBindings, gasLimitOpts?: {
|
|
65
94
|
maxTxL2Gas?: number;
|
|
66
95
|
maxTxDAGas?: number;
|
|
67
|
-
}): Record<string, TransactionValidator
|
|
96
|
+
}): Record<string, TransactionValidator<GossipValidationFailure>>;
|
|
68
97
|
/**
|
|
69
98
|
* Second stage of gossip validation — expensive proof verification.
|
|
70
99
|
*
|
|
@@ -145,4 +174,4 @@ export declare function createTxValidatorForTransactionsEnteringPendingTxPool(wo
|
|
|
145
174
|
* migration validator can check it without needing the full Tx or its dependencies.
|
|
146
175
|
*/
|
|
147
176
|
export declare function createCheckAllowedSetupCalls(contractDataSource: ContractDataSource, setupAllowList: AllowedElement[], getTimestamp: () => UInt64): (tx: Tx) => Promise<boolean>;
|
|
148
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
177
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmFjdG9yeS5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21zZ192YWxpZGF0b3JzL3R4X3ZhbGlkYXRvci9mYWN0b3J5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0E4Qkc7QUFDSCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDbkUsT0FBTyxFQUFFLEVBQUUsRUFBRSxNQUFNLHFDQUFxQyxDQUFDO0FBQ3pELE9BQU8sS0FBSyxFQUFFLGNBQWMsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBSWpFLE9BQU8sS0FBSyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFDdEUsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pELE9BQU8sS0FBSyxFQUNWLGNBQWMsRUFDZCw2QkFBNkIsRUFDN0Isd0JBQXdCLEVBQ3hCLHdCQUF3QixFQUN4QixzQkFBc0IsRUFDdkIsTUFBTSxzQ0FBc0MsQ0FBQztBQUM5QyxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUUzRCxPQUFPLEtBQUssRUFBRSxlQUFlLEVBQUUsRUFBRSxFQUFFLGtCQUFrQixFQUFFLFdBQVcsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xHLE9BQU8sS0FBSyxFQUFFLE1BQU0sRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRXZELE9BQU8sS0FBSyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJDQUEyQyxDQUFDO0FBaUI1RSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUU3RDs7O0dBR0c7QUFDSCxlQUFPLE1BQU0sb0JBQW9CLDJCQUEyQixDQUFDO0FBRTdEOzs7R0FHRztBQUNILE1BQU0sTUFBTSx1QkFBdUIsR0FBRyxpQkFBaUIsR0FBRyxPQUFPLG9CQUFvQixDQUFDO0FBRXRGOzs7O0dB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,sCAAsC,CAAC;AACnE,OAAO,EAAE,EAAE,EAAE,MAAM,qCAAqC,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAIjE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/factory.ts"],"names":[],"mappings":"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"}
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
*/ import { Fr } from '@aztec-labs/foundation/curves/bn254';
|
|
32
32
|
import { getVKTreeRoot } from '@aztec-labs/noir-protocol-circuits-types/vk-tree';
|
|
33
33
|
import { ProtocolContractAddress, protocolContractsHash } from '@aztec-labs/protocol-contracts';
|
|
34
|
+
import { GasFees } from '@aztec-labs/stdlib/gas';
|
|
34
35
|
import { PeerErrorSeverity } from '@aztec-labs/stdlib/p2p';
|
|
35
36
|
import { DatabasePublicStateSource, MerkleTreeId } from '@aztec-labs/stdlib/trees';
|
|
36
37
|
import { AggregateTxValidator } from './aggregate_tx_validator.js';
|
|
@@ -41,7 +42,7 @@ import { ContractInstanceTxValidator } from './contract_instance_validator.js';
|
|
|
41
42
|
import { DataTxValidator } from './data_validator.js';
|
|
42
43
|
import { DoubleSpendTxValidator } from './double_spend_validator.js';
|
|
43
44
|
import { MaxGasLimitsValidator, MinGasLimitsValidator } from './gas_limits_validator.js';
|
|
44
|
-
import { GasTxValidator, MaxFeePerGasValidator } from './gas_validator.js';
|
|
45
|
+
import { FeePayerBalanceValidator, GasTxValidator, MaxFeePerGasValidator } from './gas_validator.js';
|
|
45
46
|
import { MetadataTxValidator } from './metadata_validator.js';
|
|
46
47
|
import { NullifierCache } from './nullifier_cache.js';
|
|
47
48
|
import { AllowedSetupCallsMetaValidator, PhasesTxValidator } from './phases_validator.js';
|
|
@@ -49,11 +50,27 @@ import { SizeTxValidator } from './size_validator.js';
|
|
|
49
50
|
import { TimestampTxValidator } from './timestamp_validator.js';
|
|
50
51
|
import { TxPermittedValidator } from './tx_permitted_validator.js';
|
|
51
52
|
import { TxProofValidator } from './tx_proof_validator.js';
|
|
53
|
+
/**
|
|
54
|
+
* Marks a gossip validator whose failure is not attributable to the sending peer: the tx is dropped without
|
|
55
|
+
* being added to the pool or propagated, and the peer's score is left alone.
|
|
56
|
+
*/ export const IgnoreWithoutPenalty = 'ignore-without-penalty';
|
|
57
|
+
/**
|
|
58
|
+
* Fraction of the lower of the admission and L1-forward fees below which a gossiped tx gets its sender penalized.
|
|
59
|
+
* A peer can legitimately price the next block below both: one that has seen a checkpoint this node has not can
|
|
60
|
+
* see the congestion fee drop, and the L1 gas components move with every L1 block. Halving leaves room for
|
|
61
|
+
* several such steps while still penalizing zero-fee and negligible-fee spam.
|
|
62
|
+
*/ export const GOSSIP_FEE_PENALTY_FLOOR_FRACTION = 0.5;
|
|
63
|
+
/** Derives the gossip fee thresholds from this node's admission fee and its L1-forward fee. */ export function computeGossipMinFees(admission, l1Forward) {
|
|
64
|
+
return {
|
|
65
|
+
admission,
|
|
66
|
+
penaltyFloor: GasFees.min(admission, l1Forward).mul(GOSSIP_FEE_PENALTY_FLOOR_FRACTION)
|
|
67
|
+
};
|
|
68
|
+
}
|
|
52
69
|
/**
|
|
53
70
|
* First stage of gossip validation — fast checks run before the pool pre-check.
|
|
54
71
|
*
|
|
55
|
-
* If any validator fails, the
|
|
56
|
-
*
|
|
72
|
+
* If any validator fails, the tx is rejected immediately, without consulting the pool or running proof
|
|
73
|
+
* verification. The peer is penalized unless the only failures are marked {@link IgnoreWithoutPenalty}.
|
|
57
74
|
*
|
|
58
75
|
* The `doubleSpendValidator` failure is special-cased by the caller (`handleGossipedTx`)
|
|
59
76
|
* to determine severity based on how recently the nullifier appeared. The caller reports the
|
|
@@ -114,8 +131,22 @@ import { TxProofValidator } from './tx_proof_validator.js';
|
|
|
114
131
|
}),
|
|
115
132
|
severity: PeerErrorSeverity.MidToleranceError
|
|
116
133
|
},
|
|
117
|
-
|
|
118
|
-
|
|
134
|
+
// The max-fee comparisons and the fee-payer balance check are separate entries because their failures mean
|
|
135
|
+
// different things. A tx below our admission fee is only invalid against a fee this node resolved: a peer
|
|
136
|
+
// ahead of us may be relaying against a lower checkpoint fee it legitimately sees, so the tx is dropped
|
|
137
|
+
// without penalizing the sender. That excuse only stretches down to the penalty floor, so a tx below it fails
|
|
138
|
+
// both entries and the harshest failure wins. An underfunded fee payer is invalid against shared state, so
|
|
139
|
+
// it stays penalized.
|
|
140
|
+
maxFeePerGasValidator: {
|
|
141
|
+
validator: new MaxFeePerGasValidator(gasFees.admission, bindings),
|
|
142
|
+
severity: IgnoreWithoutPenalty
|
|
143
|
+
},
|
|
144
|
+
maxFeePerGasFloorValidator: {
|
|
145
|
+
validator: new MaxFeePerGasValidator(gasFees.penaltyFloor, bindings),
|
|
146
|
+
severity: PeerErrorSeverity.MidToleranceError
|
|
147
|
+
},
|
|
148
|
+
feePayerBalanceValidator: {
|
|
149
|
+
validator: new FeePayerBalanceValidator(new DatabasePublicStateSource(merkleTree), ProtocolContractAddress.FeeJuice, bindings),
|
|
119
150
|
severity: PeerErrorSeverity.MidToleranceError
|
|
120
151
|
},
|
|
121
152
|
dataValidator: {
|
|
@@ -36,30 +36,38 @@ export declare class MaxFeePerGasValidator<T extends HasMaxFeePerGasData> implem
|
|
|
36
36
|
/** Checks maxFeesPerGas >= current block gas fees on both dimensions. */
|
|
37
37
|
validateMaxFeePerGas(tx: T): TxValidationResult;
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Validates that a transaction's fee payer can cover its fee limit: reads the fee payer's FeeJuice balance from
|
|
41
|
+
* public state, adds any pending claim from a setup-phase `_increase_public_balance` call, and rejects if the total
|
|
42
|
+
* is less than the tx's fee limit (gasLimits * maxFeePerGas).
|
|
43
|
+
*
|
|
44
|
+
* Does not check max fee per gas against any fee: a tx with zero max fees has a zero fee limit and passes here with
|
|
45
|
+
* no balance, so every caller must also run a {@link MaxFeePerGasValidator}, as {@link GasTxValidator} does.
|
|
46
|
+
*/
|
|
47
|
+
export declare class FeePayerBalanceValidator implements TxValidator<Tx> {
|
|
48
|
+
#private;
|
|
49
|
+
constructor(publicDataSource: PublicStateSource, feeJuiceAddress: AztecAddress, bindings?: LoggerBindings);
|
|
50
|
+
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
51
|
+
}
|
|
39
52
|
/**
|
|
40
53
|
* Validates that a transaction can pay its gas fees.
|
|
41
54
|
*
|
|
42
55
|
* Runs two checks in order:
|
|
43
56
|
* 1. **Max fee per gas** (delegates to {@link MaxFeePerGasValidator}) — rejects the tx if its
|
|
44
57
|
* maxFeesPerGas is below the current block's gas fees.
|
|
45
|
-
* 2. **Fee payer balance** —
|
|
46
|
-
*
|
|
47
|
-
* rejects if the total is less than the tx's fee limit (gasLimits * maxFeePerGas).
|
|
58
|
+
* 2. **Fee payer balance** (delegates to {@link FeePayerBalanceValidator}) — rejects if the fee payer cannot
|
|
59
|
+
* cover the tx's fee limit (gasLimits * maxFeePerGas).
|
|
48
60
|
*
|
|
49
61
|
* Gas limits are deliberately not checked here: they are owned by {@link MinGasLimitsValidator} and
|
|
50
62
|
* {@link MaxGasLimitsValidator}, which factories include separately so that exemptions (e.g. gas estimation)
|
|
51
63
|
* don't change fee enforcement.
|
|
52
64
|
*
|
|
53
|
-
* Used by:
|
|
65
|
+
* Used by: RPC and block building validators. Gossip runs the two checks as separate entries, since their
|
|
66
|
+
* failures carry different peer penalties.
|
|
54
67
|
*/
|
|
55
68
|
export declare class GasTxValidator implements TxValidator<Tx> {
|
|
56
69
|
#private;
|
|
57
70
|
constructor(publicDataSource: PublicStateSource, feeJuiceAddress: AztecAddress, gasFees: GasFees, bindings?: LoggerBindings);
|
|
58
71
|
validateTx(tx: Tx): Promise<TxValidationResult>;
|
|
59
|
-
/**
|
|
60
|
-
* Checks the fee payer has enough FeeJuice balance to cover the tx's fee limit.
|
|
61
|
-
* Accounts for any pending claim from a setup-phase `_increase_public_balance` call.
|
|
62
|
-
*/
|
|
63
|
-
validateTxFee(tx: Tx): Promise<TxValidationResult>;
|
|
64
72
|
}
|
|
65
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
73
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2FzX3ZhbGlkYXRvci5kLnRzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vc3JjL21zZ192YWxpZGF0b3JzL3R4X3ZhbGlkYXRvci9nYXNfdmFsaWRhdG9yLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxLQUFLLGNBQWMsRUFBZ0IsTUFBTSw0QkFBNEIsQ0FBQztBQUU1RixPQUFPLEtBQUssRUFBRSxZQUFZLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQUNyRSxPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN0RCxPQUFPLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2xFLE9BQU8sRUFHTCxLQUFLLEVBQUUsRUFDUCxLQUFLLGtCQUFrQixFQUN2QixLQUFLLFdBQVcsRUFDakIsTUFBTSx1QkFBdUIsQ0FBQztBQUkvQiw2R0FBNkc7QUFDN0csTUFBTSxXQUFXLG1CQUFtQjtJQUNsQyxNQUFNLEVBQUU7UUFBRSxRQUFRLElBQUksTUFBTSxDQUFBO0tBQUUsQ0FBQztJQUMvQixJQUFJLEVBQUU7UUFDSixTQUFTLEVBQUU7WUFDVCxTQUFTLEVBQUU7Z0JBQ1QsV0FBVyxFQUFFO29CQUFFLGFBQWEsRUFBRSxPQUFPLENBQUE7aUJBQUUsQ0FBQzthQUN6QyxDQUFDO1NBQ0gsQ0FBQztLQUNILENBQUM7Q0FDSDtBQUVEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxxQkFBYSxxQkFBcUIsQ0FBQyxDQUFDLFNBQVMsbUJBQW1CLENBQUUsWUFBVyxXQUFXLENBQUMsQ0FBQyxDQUFDOztJQUl6RixZQUFZLE9BQU8sRUFBRSxPQUFPLEVBQUUsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUd0RDtJQUVELFVBQVUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQUU3QztJQUVELHlFQUF5RTtJQUN6RSxvQkFBb0IsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLGtCQUFrQixDQWtCOUM7Q0FDRjtBQUVEOzs7Ozs7O0dBT0c7QUFDSCxxQkFBYSx3QkFBeUIsWUFBVyxXQUFXLENBQUMsRUFBRSxDQUFDOztJQUs5RCxZQUFZLGdCQUFnQixFQUFFLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsUUFBUSxDQUFDLEVBQUUsY0FBYyxFQUl4RztJQUVLLFVBQVUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxHQUFHLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxDQTRCcEQ7Q0FDRjtBQUVEOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNILHFCQUFhLGNBQWUsWUFBVyxXQUFXLENBQUMsRUFBRSxDQUFDOztJQUlwRCxZQUNFLGdCQUFnQixFQUFFLGlCQUFpQixFQUNuQyxlQUFlLEVBQUUsWUFBWSxFQUM3QixPQUFPLEVBQUUsT0FBTyxFQUNoQixRQUFRLENBQUMsRUFBRSxjQUFjLEVBSTFCO0lBRUssVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBTXBEO0NBQ0YifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gas_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/gas_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,4BAA4B,CAAC;AAE5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAGL,KAAK,EAAE,EACP,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAI/B,6GAA6G;AAC7G,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE;QAAE,QAAQ,IAAI,MAAM,CAAA;KAAE,CAAC;IAC/B,IAAI,EAAE;QACJ,SAAS,EAAE;YACT,SAAS,EAAE;gBACT,WAAW,EAAE;oBAAE,aAAa,EAAE,OAAO,CAAA;iBAAE,CAAC;aACzC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED;;;;;;;;;;GAUG;AACH,qBAAa,qBAAqB,CAAC,CAAC,SAAS,mBAAmB,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;IAIzF,YAAY,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,cAAc,EAGtD;IAED,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAE7C;IAED,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,EAAE,CAAC,GAAG,kBAAkB,CAkB9C;CACF;AAED
|
|
1
|
+
{"version":3,"file":"gas_validator.d.ts","sourceRoot":"","sources":["../../../src/msg_validators/tx_validator/gas_validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,cAAc,EAAgB,MAAM,4BAA4B,CAAC;AAE5F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAGL,KAAK,EAAE,EACP,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,uBAAuB,CAAC;AAI/B,6GAA6G;AAC7G,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE;QAAE,QAAQ,IAAI,MAAM,CAAA;KAAE,CAAC;IAC/B,IAAI,EAAE;QACJ,SAAS,EAAE;YACT,SAAS,EAAE;gBACT,WAAW,EAAE;oBAAE,aAAa,EAAE,OAAO,CAAA;iBAAE,CAAC;aACzC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED;;;;;;;;;;GAUG;AACH,qBAAa,qBAAqB,CAAC,CAAC,SAAS,mBAAmB,CAAE,YAAW,WAAW,CAAC,CAAC,CAAC;;IAIzF,YAAY,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,cAAc,EAGtD;IAED,UAAU,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAE7C;IAED,yEAAyE;IACzE,oBAAoB,CAAC,EAAE,EAAE,CAAC,GAAG,kBAAkB,CAkB9C;CACF;AAED;;;;;;;GAOG;AACH,qBAAa,wBAAyB,YAAW,WAAW,CAAC,EAAE,CAAC;;IAK9D,YAAY,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,cAAc,EAIxG;IAEK,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CA4BpD;CACF;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,cAAe,YAAW,WAAW,CAAC,EAAE,CAAC;;IAIpD,YACE,gBAAgB,EAAE,iBAAiB,EACnC,eAAe,EAAE,YAAY,EAC7B,OAAO,EAAE,OAAO,EAChB,QAAQ,CAAC,EAAE,cAAc,EAI1B;IAEK,UAAU,CAAC,EAAE,EAAE,EAAE,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAMpD;CACF"}
|
|
@@ -43,42 +43,22 @@ import { getFeePayerClaimAmount, getTxFeeLimit } from './fee_payer_balance.js';
|
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
|
-
* Validates that a transaction can
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* 1. **Max fee per gas** (delegates to {@link MaxFeePerGasValidator}) — rejects the tx if its
|
|
50
|
-
* maxFeesPerGas is below the current block's gas fees.
|
|
51
|
-
* 2. **Fee payer balance** — reads the fee payer's FeeJuice balance from public state,
|
|
52
|
-
* adds any pending claim from a setup-phase `_increase_public_balance` call, and
|
|
53
|
-
* rejects if the total is less than the tx's fee limit (gasLimits * maxFeePerGas).
|
|
46
|
+
* Validates that a transaction's fee payer can cover its fee limit: reads the fee payer's FeeJuice balance from
|
|
47
|
+
* public state, adds any pending claim from a setup-phase `_increase_public_balance` call, and rejects if the total
|
|
48
|
+
* is less than the tx's fee limit (gasLimits * maxFeePerGas).
|
|
54
49
|
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
|
|
58
|
-
*
|
|
59
|
-
* Used by: gossip (stage 1), RPC, and block building validators.
|
|
60
|
-
*/ export class GasTxValidator {
|
|
50
|
+
* Does not check max fee per gas against any fee: a tx with zero max fees has a zero fee limit and passes here with
|
|
51
|
+
* no balance, so every caller must also run a {@link MaxFeePerGasValidator}, as {@link GasTxValidator} does.
|
|
52
|
+
*/ export class FeePayerBalanceValidator {
|
|
61
53
|
#log;
|
|
62
54
|
#publicDataSource;
|
|
63
55
|
#feeJuiceAddress;
|
|
64
|
-
|
|
65
|
-
constructor(publicDataSource, feeJuiceAddress, gasFees, bindings){
|
|
56
|
+
constructor(publicDataSource, feeJuiceAddress, bindings){
|
|
66
57
|
this.#log = createLogger('sequencer:tx_validator:tx_gas', bindings);
|
|
67
58
|
this.#publicDataSource = publicDataSource;
|
|
68
59
|
this.#feeJuiceAddress = feeJuiceAddress;
|
|
69
|
-
this.#maxFeePerGasValidator = new MaxFeePerGasValidator(gasFees, bindings);
|
|
70
60
|
}
|
|
71
61
|
async validateTx(tx) {
|
|
72
|
-
const maxFeeValidation = this.#maxFeePerGasValidator.validateMaxFeePerGas(tx);
|
|
73
|
-
if (maxFeeValidation.result === 'invalid') {
|
|
74
|
-
return maxFeeValidation;
|
|
75
|
-
}
|
|
76
|
-
return await this.validateTxFee(tx);
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* Checks the fee payer has enough FeeJuice balance to cover the tx's fee limit.
|
|
80
|
-
* Accounts for any pending claim from a setup-phase `_increase_public_balance` call.
|
|
81
|
-
*/ async validateTxFee(tx) {
|
|
82
62
|
const feePayer = tx.data.feePayer;
|
|
83
63
|
// Compute the maximum fee that this tx may pay, based on its gasLimits and maxFeePerGas
|
|
84
64
|
const feeLimit = getTxFeeLimit(tx);
|
|
@@ -105,3 +85,33 @@ import { getFeePayerClaimAmount, getTxFeeLimit } from './fee_payer_balance.js';
|
|
|
105
85
|
};
|
|
106
86
|
}
|
|
107
87
|
}
|
|
88
|
+
/**
|
|
89
|
+
* Validates that a transaction can pay its gas fees.
|
|
90
|
+
*
|
|
91
|
+
* Runs two checks in order:
|
|
92
|
+
* 1. **Max fee per gas** (delegates to {@link MaxFeePerGasValidator}) — rejects the tx if its
|
|
93
|
+
* maxFeesPerGas is below the current block's gas fees.
|
|
94
|
+
* 2. **Fee payer balance** (delegates to {@link FeePayerBalanceValidator}) — rejects if the fee payer cannot
|
|
95
|
+
* cover the tx's fee limit (gasLimits * maxFeePerGas).
|
|
96
|
+
*
|
|
97
|
+
* Gas limits are deliberately not checked here: they are owned by {@link MinGasLimitsValidator} and
|
|
98
|
+
* {@link MaxGasLimitsValidator}, which factories include separately so that exemptions (e.g. gas estimation)
|
|
99
|
+
* don't change fee enforcement.
|
|
100
|
+
*
|
|
101
|
+
* Used by: RPC and block building validators. Gossip runs the two checks as separate entries, since their
|
|
102
|
+
* failures carry different peer penalties.
|
|
103
|
+
*/ export class GasTxValidator {
|
|
104
|
+
#maxFeePerGasValidator;
|
|
105
|
+
#feePayerBalanceValidator;
|
|
106
|
+
constructor(publicDataSource, feeJuiceAddress, gasFees, bindings){
|
|
107
|
+
this.#maxFeePerGasValidator = new MaxFeePerGasValidator(gasFees, bindings);
|
|
108
|
+
this.#feePayerBalanceValidator = new FeePayerBalanceValidator(publicDataSource, feeJuiceAddress, bindings);
|
|
109
|
+
}
|
|
110
|
+
async validateTx(tx) {
|
|
111
|
+
const maxFeeValidation = this.#maxFeePerGasValidator.validateMaxFeePerGas(tx);
|
|
112
|
+
if (maxFeeValidation.result === 'invalid') {
|
|
113
|
+
return maxFeeValidation;
|
|
114
|
+
}
|
|
115
|
+
return await this.#feePayerBalanceValidator.validateTx(tx);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
@@ -5,7 +5,7 @@ import type { PeerId } from '@libp2p/interface';
|
|
|
5
5
|
import { type IDiscv5CreateOptions } from '@nethermindeth/discv5';
|
|
6
6
|
import { ENR } from '@nethermindeth/enr';
|
|
7
7
|
import EventEmitter from 'events';
|
|
8
|
-
import type
|
|
8
|
+
import { type P2PConfig } from '../../config.js';
|
|
9
9
|
import { type PeerDiscoveryService, PeerDiscoveryState } from '../service.js';
|
|
10
10
|
/**
|
|
11
11
|
* Peer discovery service using Discv5.
|
|
@@ -51,4 +51,4 @@ export declare class DiscV5Service extends EventEmitter implements PeerDiscovery
|
|
|
51
51
|
private onDiscovered;
|
|
52
52
|
private validateEnr;
|
|
53
53
|
}
|
|
54
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
54
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlzY1Y1X3NlcnZpY2UuZC50cyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zZXJ2aWNlcy9kaXNjdjUvZGlzY1Y1X3NlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBQzVELE9BQU8sS0FBSyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFOUQsT0FBTyxFQUFzQixLQUFLLGVBQWUsRUFBc0IsTUFBTSw4QkFBOEIsQ0FBQztBQUM1RyxPQUFPLEtBQUssRUFBRSxNQUFNLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUVoRCxPQUFPLEVBQW1DLEtBQUssb0JBQW9CLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNuRyxPQUFPLEVBQUUsR0FBRyxFQUFlLE1BQU0sb0JBQW9CLENBQUM7QUFDdEQsT0FBTyxZQUFZLE1BQU0sUUFBUSxDQUFDO0FBRWxDLE9BQU8sRUFBNEIsS0FBSyxTQUFTLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUkzRSxPQUFPLEVBQUUsS0FBSyxvQkFBb0IsRUFBRSxrQkFBa0IsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQVE5RTs7R0FFRztBQUNILHFCQUFhLGFBQWMsU0FBUSxZQUFhLFlBQVcsb0JBQW9CO0lBZ0MzRSxPQUFPLENBQUMsTUFBTTtJQUNkLE9BQU8sQ0FBQyxNQUFNO0lBQ2QsT0FBTyxDQUFDLFFBQVEsQ0FBQyxjQUFjO0lBRS9CLE9BQU8sQ0FBQyxNQUFNO0lBR2QsT0FBTyxDQUFDLFFBQVEsQ0FBQyxZQUFZO0lBdEMvQiwwQkFBMEI7SUFDMUIsT0FBTyxDQUFDLE1BQU0sQ0FBcUI7SUFFbkMsMEJBQTBCO0lBQzFCLE9BQU8sQ0FBQyxHQUFHLENBQWM7SUFFekIsMkJBQTJCO0lBQzNCLE9BQU8sQ0FBQyxRQUFRLENBQXFCO0lBRXJDLE9BQU8sQ0FBQyxZQUFZLENBQThCO0lBRWxELE9BQU8sQ0FBQyxvQkFBb0IsQ0FBZ0I7SUFDckMsaUJBQWlCLEVBQUUsR0FBRyxFQUFFLENBQU07SUFDckMsT0FBTyxDQUFDLGVBQWUsQ0FBYTtJQUNwQyxzR0FBc0c7SUFDdEcsT0FBTyxDQUFDLFFBQVEsQ0FBQyxxQkFBcUIsQ0FBYztJQUVwRCxPQUFPLENBQUMsU0FBUyxDQUFLO0lBRXRCLE9BQU8sQ0FBQyxTQUFTLENBQXFCO0lBRXRDLDJGQUEyRjtJQUMzRixPQUFPLENBQUMsUUFBUSxDQUFDLGFBQWEsQ0FBQyxDQUFvQjtJQUVuRCxPQUFPLENBQUMsUUFBUSxDQUlkO0lBRUYsWUFDVSxNQUFNLEVBQUUsTUFBTSxFQUNkLE1BQU0sRUFBRSxTQUFTLEVBQ1IsY0FBYyxFQUFFLE1BQU0sRUFDdkMsU0FBUyxHQUFFLGVBQXNDLEVBQ3pDLE1BQU0sOENBQXFDLEVBQ25ELEtBQUssQ0FBQyxFQUFFLGlCQUFpQixFQUN6QixlQUFlLEdBQUUsT0FBTyxDQUFDLG9CQUFvQixDQUFNLEVBQ2xDLFlBQVksR0FBRSxZQUFpQyxFQXVGakU7SUFFRCxPQUFPLENBQUMsa0JBQWtCO0lBK0JiLEtBQUssSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBOEVsQztJQUVZLG1CQUFtQixJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FpQmhEO0lBRU0sWUFBWSxJQUFJLEdBQUcsRUFBRSxDQUUzQjtJQUVNLE1BQU0sSUFBSSxHQUFHLENBRW5CO0lBRU0sU0FBUyxJQUFJLE1BQU0sQ0FFekI7SUFFTSxTQUFTLElBQUksa0JBQWtCLENBRXJDO0lBRU0sZUFBZSxDQUFDLE1BQU0sRUFBRSxNQUFNLEdBQUcsT0FBTyxDQUU5QztJQUVZLElBQUksSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBV2pDO1lBRWEsVUFBVTtZQWtCVixnQkFBZ0I7SUFVOUIsd0dBQXdHO0lBQ3hHLE9BQU8sQ0FBQyxhQUFhO0lBSXJCLE9BQU8sQ0FBQyxhQUFhO0lBSXJCLE9BQU8sQ0FBQyxZQUFZO0lBcUJwQixPQUFPLENBQUMsV0FBVztDQXFDcEIifQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discV5_service.d.ts","sourceRoot":"","sources":["../../../src/services/discv5/discV5_service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAAsB,KAAK,eAAe,EAAsB,MAAM,8BAA8B,CAAC;AAC5G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAmC,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACnG,OAAO,EAAE,GAAG,EAAe,MAAM,oBAAoB,CAAC;AACtD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"discV5_service.d.ts","sourceRoot":"","sources":["../../../src/services/discv5/discV5_service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAE9D,OAAO,EAAsB,KAAK,eAAe,EAAsB,MAAM,8BAA8B,CAAC;AAC5G,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAmC,KAAK,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AACnG,OAAO,EAAE,GAAG,EAAe,MAAM,oBAAoB,CAAC;AACtD,OAAO,YAAY,MAAM,QAAQ,CAAC;AAElC,OAAO,EAA4B,KAAK,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI3E,OAAO,EAAE,KAAK,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAQ9E;;GAEG;AACH,qBAAa,aAAc,SAAQ,YAAa,YAAW,oBAAoB;IAgC3E,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,QAAQ,CAAC,cAAc;IAE/B,OAAO,CAAC,MAAM;IAGd,OAAO,CAAC,QAAQ,CAAC,YAAY;IAtC/B,0BAA0B;IAC1B,OAAO,CAAC,MAAM,CAAqB;IAEnC,0BAA0B;IAC1B,OAAO,CAAC,GAAG,CAAc;IAEzB,2BAA2B;IAC3B,OAAO,CAAC,QAAQ,CAAqB;IAErC,OAAO,CAAC,YAAY,CAA8B;IAElD,OAAO,CAAC,oBAAoB,CAAgB;IACrC,iBAAiB,EAAE,GAAG,EAAE,CAAM;IACrC,OAAO,CAAC,eAAe,CAAa;IACpC,sGAAsG;IACtG,OAAO,CAAC,QAAQ,CAAC,qBAAqB,CAAc;IAEpD,OAAO,CAAC,SAAS,CAAK;IAEtB,OAAO,CAAC,SAAS,CAAqB;IAEtC,2FAA2F;IAC3F,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAoB;IAEnD,OAAO,CAAC,QAAQ,CAId;IAEF,YACU,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,SAAS,EACR,cAAc,EAAE,MAAM,EACvC,SAAS,GAAE,eAAsC,EACzC,MAAM,8CAAqC,EACnD,KAAK,CAAC,EAAE,iBAAiB,EACzB,eAAe,GAAE,OAAO,CAAC,oBAAoB,CAAM,EAClC,YAAY,GAAE,YAAiC,EAuFjE;IAED,OAAO,CAAC,kBAAkB;IA+Bb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA8ElC;IAEY,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAiBhD;IAEM,YAAY,IAAI,GAAG,EAAE,CAE3B;IAEM,MAAM,IAAI,GAAG,CAEnB;IAEM,SAAS,IAAI,MAAM,CAEzB;IAEM,SAAS,IAAI,kBAAkB,CAErC;IAEM,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE9C;IAEY,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAWjC;YAEa,UAAU;YAkBV,gBAAgB;IAU9B,wGAAwG;IACxG,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,YAAY;IAqBpB,OAAO,CAAC,WAAW;CAqCpB"}
|