diff --git a/.gitmodules b/.gitmodules index 142b52ef..0bf9a465 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,6 @@ [submodule "bolt-contracts/lib/openzeppelin-contracts"] path = bolt-contracts/lib/openzeppelin-contracts url = https://github.com/OpenZeppelin/openzeppelin-contracts -[submodule "bolt-contracts/lib/relic-sdk"] - path = bolt-contracts/lib/relic-sdk - url = https://github.com/Relic-Protocol/relic-sdk [submodule "bolt-contracts/lib/core"] path = bolt-contracts/lib/core url = https://github.com/symbioticfi/core diff --git a/bolt-contracts/.gas-snapshot b/bolt-contracts/.gas-snapshot new file mode 100644 index 00000000..bd8495e9 --- /dev/null +++ b/bolt-contracts/.gas-snapshot @@ -0,0 +1,33 @@ +BoltChallengerTest:testCommitmentDigestAndSignature() (gas: 4626) +BoltChallengerTest:testCommitmentSignature() (gas: 6754) +BoltChallengerTest:testOpenAlreadyExistingChallenge() (gas: 112649) +BoltChallengerTest:testOpenChallengeInvalidSignature() (gas: 25461) +BoltChallengerTest:testOpenChallengeSingleTx() (gas: 407773) +BoltChallengerTest:testOpenChallengeWithIncorrectBond() (gas: 17130) +BoltChallengerTest:testOpenChallengeWithLargebond() (gas: 17141) +BoltChallengerTest:testOpenChallengeWithSlotInTheFuture() (gas: 17517) +BoltChallengerTest:testProveAccountData() (gas: 355542) +BoltChallengerTest:testProveHeaderData() (gas: 46228) +BoltChallengerTest:testProveTransactionInclusion() (gas: 176543) +BoltChallengerTest:testResolveChallengeFullDefenseSingleTx() (gas: 697131) +BoltChallengerTest:testResolveChallengeFullDefenseStackedTxs() (gas: 1166625) +BoltManagerEigenLayerTest:testGetNonExistentProposerStatus() (gas: 921620) +BoltManagerEigenLayerTest:testGetWhitelistedCollaterals() (gas: 99988) +BoltManagerEigenLayerTest:testNonWhitelistedCollateral() (gas: 103013) +BoltManagerEigenLayerTest:testProposersLookaheadStatus() (gas: 2142632) +BoltManagerEigenLayerTest:test_deregisterEigenLayerOperatorFromAVS() (gas: 898067) +BoltManagerEigenLayerTest:test_getEigenLayerOperatorStake() (gas: 935483) +BoltManagerEigenLayerTest:test_getEigenLayerProposerStatus() (gas: 938074) +BoltManagerTest:testGetNonExistentProposerStatus() (gas: 1197534) +BoltManagerTest:testGetProposerStatus() (gas: 1431371) +BoltManagerTest:testGetWhitelistedCollaterals() (gas: 16818) +BoltManagerTest:testNonWhitelistedCollateral() (gas: 41889) +BoltManagerTest:testProposersLookaheadStatus() (gas: 2421869) +BoltManagerTest:testReadOperatorStake() (gas: 1520048) +BoltValidatorsTest:testUnsafeRegistration() (gas: 145625) +BoltValidatorsTest:testUnsafeRegistrationFailsIfAlreadyRegistered() (gas: 143729) +BoltValidatorsTest:testUnsafeRegistrationInvalidCollateralProvider() (gas: 18821) +BoltValidatorsTest:testUnsafeRegistrationInvalidOperator() (gas: 19050) +BoltValidatorsTest:testUnsafeRegistrationWhenNotAllowed() (gas: 22565) +TransactionDecoderTest:testDecodeAllTestCases() (gas: 0) +TransactionDecoderTest:testDecodeGasUsage() (gas: 53281) \ No newline at end of file diff --git a/bolt-contracts/.gitignore b/bolt-contracts/.gitignore index fb58f1df..5ffcbef2 100644 --- a/bolt-contracts/.gitignore +++ b/bolt-contracts/.gitignore @@ -3,3 +3,6 @@ out/ broadcast/ .env + +node_modules/ +target/ diff --git a/bolt-contracts/README.md b/bolt-contracts/README.md index bed5a661..c7c007b0 100644 --- a/bolt-contracts/README.md +++ b/bolt-contracts/README.md @@ -91,7 +91,7 @@ The opt-in process requires the following steps: > Operator (NO), since the same steps apply to solo stakers. As a Node Operator you will be an ["Operator"](https://docs.eigenlayer.xyz/eigenlayer/overview/key-terms) -in the Bolt AVS built on top of EigenLayer. This requires +in the Bolt AVS built on top of EigenLayer. This requires running an Ethereum validator and the Bolt sidecar in order issue preconfirmations. @@ -151,7 +151,63 @@ The steps required are the following: ## Fault Proof Challenge and Slashing: `BoltChallenger` -WIP +The [`BoltChallenger`](./src/contracts/BoltChallenger.sol) contract is the component responsible +for handling fault attribution in the case of a validator failing to meet their commitments. + +In short, the challenger contract allows any user to challenge a validator's commitment by opening +a dispute with the following inputs: + +1. The signed commitment made by the validator (or a list of commitments on the same slot) +2. An ETH bond to cover the cost of the dispute and disincentivize frivolous challenges + +The entrypoint is the `openChallenge` function. Once a challenge is opened, a `ChallengeOpened` event +is emitted, and any arbitrator has a time window to submit a valid response to settle the dispute. + +### Dispute resolution + +The dispute resolution process is one-shot and requires the arbitrator to submit all necessary evidence +of the validator's correct behaviour within the challenge time window. + +The arbitrator is _anyone_ who can submit a valid response to the challenge. It doesn't have to be the +validator themselves. There is however one limitation: the time window for submitting a response must be +respected in the following way: + +- Start: the target block must be justified by LMD-GHOST: a minimum of 32 slots must have passed +- End: depending on the EVM block hash oracle: + - . If using the `BLOCKHASH` EVM opcode, the window is limited to 256 blocks (roughly 1 hour) + - . If using the [EIP-2935](https://eips.ethereum.org/EIPS/eip-2935) historical oracle, the window is limited to 8192 blocks (roughly 1 day) + +The inputs to the resolution process are as follows: + +1. The ID of the challenge to respond to: this is emitted in the `ChallengeOpened` event and is unique. +2. The [inclusion proofs](https://github.com/chainbound/bolt/blob/6c0f1b696cfe3de7e7e3830ac28c369c6ddf271e/bolt-contracts/src/interfaces/IBoltChallenger.sol#L39), consisting of the following components: + a. the block number of the block containing the committed transactions (we call it "inclusionBlock") + b. the RLP-encoded block header of the block **before** the one containing the committed transactions (we call it "previousBlock") + b. the RLP-encoded block header of the block containing the included transactions (aka "inclusionBlock") + c. the account merkle proofs of the sender of the committed transactions against the previousBlock's state root + d. the transaction merkle proofs of the included transactions against the inclusionBlock's transaction root + e. the transaction index in the block of each included transaction + +If the arbitrator submits a valid response that satisfies the requirements for the challenge, the +challenge is considered `DEFENDED` and the challenger's bond is slashed to cover the cost of the dispute +and to incentivize speedy resolution. + +If no arbitrators respond successfully within the challenge time window, the challenge is considered +`BREACHED` and anyone can call the `resolveExpiredChallenge()` method. The `BoltChallenger` will keep +track of this information for future reference. + +### Slashing of validators + +If a challenge is `BREACHED` (as per the above definition), the validator's stake should be slashed to cover +the cost of a missed commitment. This is done by calling the `slash` function on the correct staking adapter +and reading into the `BoltChallenger` contract to trustlessly determine if the challenge was lost. + +In practice, slashing behaviour is abstracted behind any staking adapter – an example is Symbiotic's `VetoSlasher` +which will receive a request to slash a validator's stake and will have a last opportunity to veto +the slashing request before it is executed on-chain. + +Subscribing to breached challenge events from the `BoltChallenger` is a trustless way to determine if a slashing +request is valid according to Bolt Protocol rules. ## Testing @@ -186,11 +242,3 @@ The following considerations should be taken into account before interacting wit - Restaking is a complex process that involves trusting external systems and smart contracts. - Validators should be aware of the potential for slashing if they fail to meet their commitments or engage in malicious behavior. - Smart contracts are susceptible to bugs and vulnerabilities that could be exploited by attackers. - -## Conclusion - -The Bolt smart contracts provide a robust and flexible framework for integrating validator registration, -delegation, and restaking mechanism within the Bolt Ecosystem. - -By leveraging the power and security of Symbiotic and Eigenlayer solutions, Bolt offers a sophisticated -solution for staking pools that wish to opt-in to multiple conditions with extreme granularity. diff --git a/bolt-contracts/foundry.toml b/bolt-contracts/foundry.toml index 4e4a9a7a..8b403efc 100644 --- a/bolt-contracts/foundry.toml +++ b/bolt-contracts/foundry.toml @@ -21,6 +21,7 @@ remappings = [ "@relic/=lib/relic-sdk/packages/contracts", "@symbiotic/=lib/core/src/", "@eigenlayer/=lib/eigenlayer-contracts/", + "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts", # Symbiotic remappings contexts "lib/core/:forge-std/=lib/core/lib/forge-std/src/", diff --git a/bolt-contracts/lib/relic-sdk b/bolt-contracts/lib/relic-sdk deleted file mode 160000 index 8d6c88e4..00000000 --- a/bolt-contracts/lib/relic-sdk +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 8d6c88e4437eade19a08aca6457d6bd14b06e454 diff --git a/bolt-contracts/src/contracts/BoltChallenger.sol b/bolt-contracts/src/contracts/BoltChallenger.sol new file mode 100644 index 00000000..f436b665 --- /dev/null +++ b/bolt-contracts/src/contracts/BoltChallenger.sol @@ -0,0 +1,487 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {EnumerableSet} from "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; +import {Time} from "@openzeppelin/contracts/utils/types/Time.sol"; + +import {SecureMerkleTrie} from "../lib/trie/SecureMerkleTrie.sol"; +import {MerkleTrie} from "../lib/trie/MerkleTrie.sol"; +import {RLPReader} from "../lib/rlp/RLPReader.sol"; +import {RLPWriter} from "../lib/rlp/RLPWriter.sol"; +import {BeaconChainUtils} from "../lib/BeaconChainUtils.sol"; +import {TransactionDecoder} from "../lib/TransactionDecoder.sol"; +import {IBoltChallenger} from "../interfaces/IBoltChallenger.sol"; + +contract BoltChallenger is IBoltChallenger { + using RLPReader for bytes; + using RLPReader for RLPReader.RLPItem; + using TransactionDecoder for bytes; + using TransactionDecoder for TransactionDecoder.Transaction; + using EnumerableSet for EnumerableSet.Bytes32Set; + + // ========= STORAGE ========= + + /// @notice The set of existing unique challenge IDs. + EnumerableSet.Bytes32Set internal challengeIDs; + + /// @notice The mapping of challenge IDs to their respective challenges. + mapping(bytes32 => Challenge) internal challenges; + + // ========= CONSTANTS ========= + + /// @notice The challenge bond required to open a challenge. + uint256 public constant CHALLENGE_BOND = 1 ether; + + /// @notice The maximum duration of a challenge to be considered valid. + uint256 public constant MAX_CHALLENGE_DURATION = 7 days; + + /// @notice The maximum number of blocks to look back for block hashes in the EVM. + uint256 public constant BLOCKHASH_EVM_LOOKBACK = 256; + + // ========= CONSTRUCTOR ========= + + constructor() {} + + // ========= VIEW FUNCTIONS ========= + + /// @notice Get all existing challenges. + /// @dev Should be used in view contexts only to avoid unnecessary gas costs. + /// @return allChallenges The array of all existing challenges. + function getAllChallenges() public view returns (Challenge[] memory) { + Challenge[] memory allChallenges = new Challenge[](challengeIDs.length()); + + for (uint256 i = 0; i < challengeIDs.length(); i++) { + allChallenges[i] = challenges[challengeIDs.at(i)]; + } + + return allChallenges; + } + + /// @notice Get all currently non-resolved challenges. + /// @dev Should be used in view contexts only to avoid unnecessary gas costs. + /// @return openChallenges The array of all currently non-resolved challenges. + function getOpenChallenges() public view returns (Challenge[] memory) { + uint256 openCount = 0; + for (uint256 i = 0; i < challengeIDs.length(); i++) { + if (challenges[challengeIDs.at(i)].status == ChallengeStatus.Open) { + openCount++; + } + } + + Challenge[] memory openChallenges = new Challenge[](openCount); + + uint256 j = 0; + for (uint256 i = 0; i < challengeIDs.length(); i++) { + Challenge memory challenge = challenges[challengeIDs.at(i)]; + if (challenge.status == ChallengeStatus.Open) { + openChallenges[j] = challenge; + j++; + } + } + + return openChallenges; + } + + /// @notice Get a challenge by its ID. + /// @param challengeID The ID of the challenge to get. + /// @return challenge The challenge with the given ID. + function getChallengeByID( + bytes32 challengeID + ) public view returns (Challenge memory) { + if (!challengeIDs.contains(challengeID)) { + revert ChallengeDoesNotExist(); + } + + return challenges[challengeID]; + } + + // ========= CHALLENGE CREATION ========= + + /// @notice Open a challenge against a bundle of committed transactions. + /// @dev The challenge bond must be paid in order to open a challenge. + /// @param commitments The signed commitments to open a challenge for. + function openChallenge( + SignedCommitment[] calldata commitments + ) public payable { + if (commitments.length == 0) { + revert EmptyCommitments(); + } + + // Check that the attached bond amount is correct + if (msg.value != CHALLENGE_BOND) { + revert IncorrectChallengeBond(); + } + + // Compute the unique challenge ID, based on the signatures of the provided commitments + bytes32 challengeID = _computeChallengeID(commitments); + + // Check that a challenge for this commitment bundle does not already exist + if (challengeIDs.contains(challengeID)) { + revert ChallengeAlreadyExists(); + } + + uint256 targetSlot = commitments[0].slot; + if (targetSlot > BeaconChainUtils._getCurrentSlot() - BeaconChainUtils.JUSTIFICATION_DELAY_SLOTS) { + // We cannot open challenges for slots that are not finalized by Ethereum consensus yet. + // This is admittedly a bit strict, since 32-slot deep reorgs are very unlikely. + revert BlockIsNotFinalized(); + } + + // Check that all commitments are for the same slot and signed by the same sender + // and store the parsed transaction data for each commitment + TransactionData[] memory transactionsData = new TransactionData[](commitments.length); + (address txSender, address commitmentSigner, TransactionData memory firstTransactionData) = + _recoverCommitmentData(commitments[0]); + + transactionsData[0] = firstTransactionData; + + for (uint256 i = 1; i < commitments.length; i++) { + (address otherTxSender, address otherCommitmentSigner, TransactionData memory otherTransactionData) = + _recoverCommitmentData(commitments[i]); + + transactionsData[i] = otherTransactionData; + + // check that all commitments are for the same slot + if (commitments[i].slot != targetSlot) { + revert UnexpectedMixedSlots(); + } + + // check that all commitments are signed by the same sender + if (otherTxSender != txSender) { + revert UnexpectedMixedSenders(); + } + + // check that all commitments are signed by the same signer (aka "operator") + if (otherCommitmentSigner != commitmentSigner) { + revert UnexpectedMixedSigners(); + } + + // check that the nonces are strictly sequentially increasing in the bundle + if (otherTransactionData.nonce != transactionsData[i - 1].nonce + 1) { + revert UnexpectedNonceOrder(); + } + } + + // Add the challenge to the set of challenges + challengeIDs.add(challengeID); + challenges[challengeID] = Challenge({ + id: challengeID, + openedAt: Time.timestamp(), + status: ChallengeStatus.Open, + targetSlot: targetSlot, + challenger: msg.sender, + commitmentSigner: commitmentSigner, + commitmentReceiver: txSender, + committedTxs: transactionsData + }); + emit ChallengeOpened(challengeID, msg.sender, commitmentSigner); + } + + // ========= CHALLENGE RESOLUTION ========= + + /// @notice Resolve a challenge by providing proofs of the inclusion of the committed transactions. + /// @dev Challenges are DEFENDED if the resolver successfully defends the inclusion of the transactions. + /// In the event of no valid defense in the challenge time window, the challenge is considered BREACHED + /// and anyone can call `resolveExpiredChallenge()` to settle the challenge. + /// @param challengeID The ID of the challenge to resolve. + /// @param proof The proof data to resolve the challenge. + function resolveOpenChallenge(bytes32 challengeID, Proof calldata proof) public { + // Check that the challenge exists + if (!challengeIDs.contains(challengeID)) { + revert ChallengeDoesNotExist(); + } + + // The visibility of the BLOCKHASH opcode is limited to the 256 most recent blocks. + // For simplicity we restrict this to 256 slots even though 256 blocks would be more accurate. + if (challenges[challengeID].targetSlot < BeaconChainUtils._getCurrentSlot() - BLOCKHASH_EVM_LOOKBACK) { + revert BlockIsTooOld(); + } + + // Check that the previous block is within the EVM lookback window for block hashes. + // Clearly, if the previous block is available, the inclusion one will be too. + uint256 previousBlockNumber = proof.inclusionBlockNumber - 1; + if (previousBlockNumber > block.number || previousBlockNumber < block.number - BLOCKHASH_EVM_LOOKBACK) { + revert InvalidBlockNumber(); + } + + // Get the trusted block hash for the block number in which the transactions were included. + bytes32 trustedPreviousBlockHash = blockhash(proof.inclusionBlockNumber); + + // Finally resolve the challenge with the trusted block hash and the provided proofs + _resolve(challengeID, trustedPreviousBlockHash, proof); + } + + /// @notice Resolve a challenge that has expired without being resolved. + /// @dev This will result in the challenge being considered breached, without need to provide + /// additional proofs of inclusion, as the time window has elapsed. + /// @param challengeID The ID of the challenge to resolve. + function resolveExpiredChallenge( + bytes32 challengeID + ) public { + if (!challengeIDs.contains(challengeID)) { + revert ChallengeDoesNotExist(); + } + + Challenge storage challenge = challenges[challengeID]; + + if (challenge.status != ChallengeStatus.Open) { + revert ChallengeAlreadyResolved(); + } + + if (challenge.openedAt + MAX_CHALLENGE_DURATION >= Time.timestamp()) { + revert ChallengeNotExpired(); + } + + // If the challenge has expired without being resolved, it is considered breached. + _settleChallengeResolution(ChallengeStatus.Breached, challenge); + } + + /// @notice Resolve a challenge by providing proofs of the inclusion of the committed transactions. + /// @dev Challenges are DEFENDED if the resolver successfully defends the inclusion of the transactions. + /// In the event of no valid defense in the challenge time window, the challenge is considered BREACHED. + /// @param challengeID The ID of the challenge to resolve. + /// @param trustedPreviousBlockHash The block hash of the block before the inclusion block of the committed txs. + /// @param proof The proof data to resolve the challenge. See `IBoltChallenger.Proof` struct for more details. + function _resolve(bytes32 challengeID, bytes32 trustedPreviousBlockHash, Proof calldata proof) internal { + if (!challengeIDs.contains(challengeID)) { + revert ChallengeDoesNotExist(); + } + + Challenge storage challenge = challenges[challengeID]; + + if (challenge.status != ChallengeStatus.Open) { + revert ChallengeAlreadyResolved(); + } + + if (challenge.openedAt + MAX_CHALLENGE_DURATION < Time.timestamp()) { + // If the challenge has expired without being resolved, it is considered breached. + // This should be handled by calling the `resolveExpiredChallenge()` function instead. + revert ChallengeExpired(); + } + + // Check the integrity of the proof data + uint256 committedTxsCount = challenge.committedTxs.length; + if (proof.txMerkleProofs.length != committedTxsCount || proof.txIndexesInBlock.length != committedTxsCount) { + revert InvalidProofsLength(); + } + + // Check the integrity of the trusted block hash + bytes32 previousBlockHash = keccak256(proof.previousBlockHeaderRLP); + if (previousBlockHash != trustedPreviousBlockHash) { + revert InvalidBlockHash(); + } + + // Decode the RLP-encoded block header of the previous block to the inclusion block. + // + // The previous block's state root is necessary to verify the account had the correct balance and + // nonce at the top of the inclusion block (before any transactions were applied). + BlockHeaderData memory previousBlockHeader = _decodeBlockHeaderRLP(proof.previousBlockHeaderRLP); + + // Decode the RLP-encoded block header of the inclusion block. + // + // The inclusion block is necessary to extract the transaction root and verify the inclusion of the + // committed transactions. By checking against the previous block's parent hash we can ensure this + // is the correct block trusting a single block hash. + BlockHeaderData memory inclusionBlockHeader = _decodeBlockHeaderRLP(proof.inclusionBlockHeaderRLP); + + // Check that the inclusion block is a child of the previous block + if (inclusionBlockHeader.parentHash != previousBlockHash) { + revert InvalidParentBlockHash(); + } + + // Decode the account fields by checking the account proof against the state root of the previous block header. + // The key in the account trie is the account pubkey (address) that sent the committed transactions. + (bool accountExists, bytes memory accountRLP) = SecureMerkleTrie.get( + abi.encodePacked(challenge.commitmentReceiver), proof.accountMerkleProof, previousBlockHeader.stateRoot + ); + + if (!accountExists) { + revert AccountDoesNotExist(); + } + + // Extract the nonce and balance of the account from the RLP-encoded data + AccountData memory account = _decodeAccountRLP(accountRLP); + + // Loop through each committed transaction and verify its inclusion in the block + // along with the sender's balance and nonce (starting from the account state at the top of the block). + for (uint256 i = 0; i < committedTxsCount; i++) { + TransactionData memory committedTx = challenge.committedTxs[i]; + + if (account.nonce > committedTx.nonce) { + // The tx sender (aka "challenge.commitmentReceiver") has sent a transaction with a higher nonce + // than the committed transaction, before the proposer could include it. Consider the challenge + // defended, as the proposer is not at fault. + _settleChallengeResolution(ChallengeStatus.Defended, challenge); + return; + } + + if (account.balance < inclusionBlockHeader.baseFee * committedTx.gasLimit) { + // The tx sender account doesn't have enough balance to pay for the worst-case baseFee of the committed + // transaction. Consider the challenge defended, as the proposer is not at fault. + _settleChallengeResolution(ChallengeStatus.Defended, challenge); + return; + } + + // Over/Underflow is checked in the previous if statements. + // + // Note: This is the same logic applied by the Bolt Sidecar's off-chain checks + // before deciding to sign a new commitment for a particular account. + account.balance -= inclusionBlockHeader.baseFee * committedTx.gasLimit; + account.nonce++; + + // The key in the transaction trie is the RLP-encoded index of the transaction in the block + bytes memory txLeaf = RLPWriter.writeUint(proof.txIndexesInBlock[i]); + + // Verify transaction inclusion proof + // + // The transactions trie is built with raw leaves, without hashing them first + // (This denotes why we use `MerkleTrie.get()` as opposed to `SecureMerkleTrie.get()`). + (bool txExists, bytes memory txRLP) = + MerkleTrie.get(txLeaf, proof.txMerkleProofs[i], inclusionBlockHeader.txRoot); + + if (!txExists) { + revert TransactionNotIncluded(); + } + + // Check if the committed transaction hash matches the hash of the included transaction + if (committedTx.txHash != keccak256(txRLP)) { + revert WrongTransactionHashProof(); + } + } + + // If all checks pass, the challenge is considered DEFENDED as the proposer provided valid proofs. + _settleChallengeResolution(ChallengeStatus.Defended, challenge); + } + + // ========= HELPERS ========= + + /// @notice Settle the resolution of a challenge based on the outcome. + /// @dev The outcome must be either DEFENDED or BREACHED. + /// @param outcome The outcome of the challenge resolution. + /// @param challenge The challenge to settle the resolution for. + function _settleChallengeResolution(ChallengeStatus outcome, Challenge storage challenge) internal { + if (outcome == ChallengeStatus.Defended) { + // If the challenge is considered DEFENDED, the proposer has provided valid proofs. + // The bond will be shared between the resolver and commitment signer. + challenge.status = ChallengeStatus.Defended; + _transferHalfBond(msg.sender); + _transferHalfBond(challenge.commitmentSigner); + emit ChallengeDefended(challenge.id); + } else if (outcome == ChallengeStatus.Breached) { + // If the challenge is considered BREACHED, the proposer has failed to provide valid proofs. + // The bond will be transferred back to the challenger in full. + challenge.status = ChallengeStatus.Breached; + _transferFullBond(challenge.challenger); + emit ChallengeBreached(challenge.id); + } + + // Remove the challenge from the set of challenges + delete challenges[challenge.id]; + challengeIDs.remove(challenge.id); + } + + /// @notice Recover the commitment data from a signed commitment. + /// @param commitment The signed commitment to recover the data from. + /// @return txSender The sender of the committed transaction. + /// @return commitmentSigner The signer of the commitment. + /// @return transactionData The decoded transaction data of the committed transaction. + function _recoverCommitmentData( + SignedCommitment calldata commitment + ) internal pure returns (address txSender, address commitmentSigner, TransactionData memory transactionData) { + commitmentSigner = ECDSA.recover(_computeCommitmentID(commitment), commitment.signature); + TransactionDecoder.Transaction memory decodedTx = commitment.signedTx.decodeEnveloped(); + txSender = decodedTx.recoverSender(); + transactionData = TransactionData({ + txHash: keccak256(commitment.signedTx), + nonce: decodedTx.nonce, + gasLimit: decodedTx.gasLimit + }); + } + + /// @notice Compute the challenge ID for a given set of signed commitments. + /// @dev Formula: `keccak( keccak(signature_1) || keccak(signature_2) || ... )` + /// @param commitments The signed commitments to compute the ID for. + /// @return challengeID The computed challenge ID. + function _computeChallengeID( + SignedCommitment[] calldata commitments + ) internal pure returns (bytes32) { + bytes32[] memory signatures = new bytes32[](commitments.length); + for (uint256 i = 0; i < commitments.length; i++) { + signatures[i] = keccak256(commitments[i].signature); + } + + return keccak256(abi.encodePacked(signatures)); + } + + /// @notice Compute the commitment ID for a given signed commitment. + /// @param commitment The signed commitment to compute the ID for. + /// @return commitmentID The computed commitment ID. + function _computeCommitmentID( + SignedCommitment calldata commitment + ) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(keccak256(commitment.signedTx), _toLittleEndian(commitment.slot))); + } + + /// @notice Helper to convert a u64 to a little-endian bytes + /// @param x The u64 to convert + /// @return b The little-endian bytes + function _toLittleEndian( + uint64 x + ) internal pure returns (bytes memory) { + bytes memory b = new bytes(8); + for (uint256 i = 0; i < 8; i++) { + b[i] = bytes1(uint8(x >> (8 * i))); + } + return b; + } + + /// @notice Decode the block header fields from an RLP-encoded block header. + /// @param headerRLP The RLP-encoded block header to decode + function _decodeBlockHeaderRLP( + bytes calldata headerRLP + ) internal pure returns (BlockHeaderData memory blockHeader) { + RLPReader.RLPItem[] memory headerFields = headerRLP.toRLPItem().readList(); + + blockHeader.parentHash = headerFields[0].readBytes32(); + blockHeader.stateRoot = headerFields[3].readBytes32(); + blockHeader.txRoot = headerFields[4].readBytes32(); + blockHeader.blockNumber = headerFields[8].readUint256(); + blockHeader.timestamp = headerFields[11].readUint256(); + blockHeader.baseFee = headerFields[15].readUint256(); + } + + /// @notice Decode the account fields from an RLP-encoded account. + /// @param accountRLP The RLP-encoded account to decode + /// @return account The decoded account data. + function _decodeAccountRLP( + bytes memory accountRLP + ) internal pure returns (AccountData memory account) { + RLPReader.RLPItem[] memory accountFields = accountRLP.toRLPItem().readList(); + + account.nonce = accountFields[0].readUint256(); + account.balance = accountFields[1].readUint256(); + } + + /// @notice Transfer the full challenge bond to a recipient. + /// @param recipient The address to transfer the bond to. + function _transferFullBond( + address recipient + ) internal { + (bool success,) = payable(recipient).call{value: CHALLENGE_BOND}(""); + if (!success) { + revert BondTransferFailed(); + } + } + + /// @notice Transfer half of the challenge bond to a recipient. + /// @param recipient The address to transfer half of the bond to. + function _transferHalfBond( + address recipient + ) internal { + (bool success,) = payable(recipient).call{value: CHALLENGE_BOND / 2}(""); + if (!success) { + revert BondTransferFailed(); + } + } +} diff --git a/bolt-contracts/src/interfaces/IBoltChallenger.sol b/bolt-contracts/src/interfaces/IBoltChallenger.sol new file mode 100644 index 00000000..7ec5189a --- /dev/null +++ b/bolt-contracts/src/interfaces/IBoltChallenger.sol @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +interface IBoltChallenger { + enum ChallengeStatus { + Open, + Defended, + Breached + } + + struct Challenge { + bytes32 id; + uint48 openedAt; + ChallengeStatus status; + uint256 targetSlot; + address challenger; + address commitmentSigner; + address commitmentReceiver; + TransactionData[] committedTxs; + } + + struct SignedCommitment { + uint64 slot; + bytes signature; + bytes signedTx; + } + + struct TransactionData { + bytes32 txHash; + uint256 nonce; + uint256 gasLimit; + } + + struct BlockHeaderData { + bytes32 parentHash; + bytes32 stateRoot; + bytes32 txRoot; + uint256 blockNumber; + uint256 timestamp; + uint256 baseFee; + } + + struct AccountData { + uint256 nonce; + uint256 balance; + } + + struct Proof { + // block number where the transactions are included + uint256 inclusionBlockNumber; + // RLP-encoded block header of the previous block of the inclusion block + // (for clarity: `previousBlockHeader.number == inclusionBlockNumber - 1`) + bytes previousBlockHeaderRLP; + // RLP-encoded block header where the committed transactions are included + bytes inclusionBlockHeaderRLP; + // merkle inclusion proof of the account in the state trie of the previous block + // (checked against the previousBlockHeader.stateRoot) + bytes accountMerkleProof; + // merkle inclusion proof of the transactions in the transaction trie of the inclusion block + // (checked against the inclusionBlockHeader.txRoot). The order of the proofs should match + // the order of the committed transactions in the challenge: `Challenge.committedTxs`. + bytes[] txMerkleProofs; + // indexes of the committed transactions in the block. The order of the indexes should match + // the order of the committed transactions in the challenge: `Challenge.committedTxs`. + uint256[] txIndexesInBlock; + } + + error SlotInTheFuture(); + error BlockIsNotFinalized(); + error IncorrectChallengeBond(); + error ChallengeAlreadyExists(); + error ChallengeAlreadyResolved(); + error ChallengeDoesNotExist(); + error BlockIsTooOld(); + error InvalidBlockHash(); + error InvalidParentBlockHash(); + error AccountDoesNotExist(); + error TransactionNotIncluded(); + error WrongTransactionHashProof(); + error InvalidBlockNumber(); + error BondTransferFailed(); + error ChallengeNotExpired(); + error ChallengeExpired(); + error EmptyCommitments(); + error UnexpectedMixedSenders(); + error UnexpectedMixedSlots(); + error UnexpectedMixedSigners(); + error UnexpectedNonceOrder(); + error InvalidProofsLength(); + + event ChallengeOpened(bytes32 indexed challengeId, address indexed challenger, address indexed commitmentSigner); + event ChallengeDefended(bytes32 indexed challengeId); + event ChallengeBreached(bytes32 indexed challengeId); + + function getAllChallenges() external view returns (Challenge[] memory); + + function getOpenChallenges() external view returns (Challenge[] memory); + + function getChallengeByID( + bytes32 challengeID + ) external view returns (Challenge memory); + + function openChallenge( + SignedCommitment[] calldata commitments + ) external payable; + + function resolveExpiredChallenge( + bytes32 challengeID + ) external; + + function resolveOpenChallenge(bytes32 challengeID, Proof calldata proof) external; +} diff --git a/bolt-contracts/src/lib/BeaconChainUtils.sol b/bolt-contracts/src/lib/BeaconChainUtils.sol index a40d4eee..5c665574 100644 --- a/bolt-contracts/src/lib/BeaconChainUtils.sol +++ b/bolt-contracts/src/lib/BeaconChainUtils.sol @@ -12,6 +12,9 @@ library BeaconChainUtils { /// @notice The duration of a slot in seconds uint256 internal constant SLOT_TIME = 12; + /// @notice The number of slots to wait before considering a block justified by LMD-GHOST. + uint256 internal constant JUSTIFICATION_DELAY_SLOTS = 32; + /// @notice The timestamp of the genesis of the eth2 chain uint256 internal constant ETH2_GENESIS_TIMESTAMP = 1_606_824_023; diff --git a/bolt-contracts/src/lib/BytesUtils.sol b/bolt-contracts/src/lib/BytesUtils.sol new file mode 100644 index 00000000..036640ad --- /dev/null +++ b/bolt-contracts/src/lib/BytesUtils.sol @@ -0,0 +1,192 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +// Credits: Optimism contributors. +// Ref: https://github.com/ethereum-optimism/optimism/blob/05deae54595b0e6bdd33580de81cb9ad194898bc/packages/contracts-bedrock/src/libraries/Bytes.sol + +/** + * @title BytesUtils + */ +library BytesUtils { + /** + * + * Internal Functions * + * + */ + function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) { + unchecked { + require(_length + 31 >= _length, "slice_overflow"); + require(_start + _length >= _start, "slice_overflow"); + require(_bytes.length >= _start + _length, "slice_outOfBounds"); + + bytes memory tempBytes; + + assembly { + switch iszero(_length) + case 0 { + // Get a location of some free memory and store it in tempBytes as + // Solidity does for memory variables. + tempBytes := mload(0x40) + + // The first word of the slice result is potentially a partial + // word read from the original array. To read it, we calculate + // the length of that partial word and start copying that many + // bytes into the array. The first word we copy will start with + // data we don't care about, but the last `lengthmod` bytes will + // land at the beginning of the contents of the new array. When + // we're done copying, we overwrite the full first word with + // the actual length of the slice. + let lengthmod := and(_length, 31) + + // The multiplication in the next line is necessary + // because when slicing multiples of 32 bytes (lengthmod == 0) + // the following copy loop was copying the origin's length + // and then ending prematurely not copying everything it should. + let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) + let end := add(mc, _length) + + for { + // The multiplication in the next line has the same exact purpose + // as the one above. + let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) + } lt(mc, end) { + mc := add(mc, 0x20) + cc := add(cc, 0x20) + } { mstore(mc, mload(cc)) } + + mstore(tempBytes, _length) + + //update free-memory pointer + //allocating the array padded to 32 bytes like the compiler does now + mstore(0x40, and(add(mc, 31), not(31))) + } + //if we want a zero-length slice let's just return a zero-length array + default { + tempBytes := mload(0x40) + + //zero out the 32 bytes slice we are about to return + //we need to do it because Solidity does not garbage collect + mstore(tempBytes, 0) + + mstore(0x40, add(tempBytes, 0x20)) + } + } + + return tempBytes; + } + } + + function slice(bytes memory _bytes, uint256 _start) internal pure returns (bytes memory) { + unchecked { + if (_bytes.length - _start == 0) { + return bytes(""); + } + + return slice(_bytes, _start, _bytes.length - _start); + } + } + + function toBytes32PadLeft( + bytes memory _bytes + ) internal pure returns (bytes32) { + unchecked { + bytes32 ret; + uint256 len = _bytes.length <= 32 ? _bytes.length : 32; + assembly { + ret := shr(mul(sub(32, len), 8), mload(add(_bytes, 32))) + } + return ret; + } + } + + function toBytes32( + bytes memory _bytes + ) internal pure returns (bytes32) { + unchecked { + if (_bytes.length < 32) { + bytes32 ret; + assembly { + ret := mload(add(_bytes, 32)) + } + return ret; + } + + return abi.decode(_bytes, (bytes32)); // will truncate if input length > 32 bytes + } + } + + function toUint256( + bytes memory _bytes + ) internal pure returns (uint256) { + return uint256(toBytes32(_bytes)); + } + + function toUint24(bytes memory _bytes, uint256 _start) internal pure returns (uint24) { + require(_start + 3 >= _start, "toUint24_overflow"); + require(_bytes.length >= _start + 3, "toUint24_outOfBounds"); + uint24 tempUint; + + assembly { + tempUint := mload(add(add(_bytes, 0x3), _start)) + } + + return tempUint; + } + + function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) { + require(_start + 1 >= _start, "toUint8_overflow"); + require(_bytes.length >= _start + 1, "toUint8_outOfBounds"); + uint8 tempUint; + + assembly { + tempUint := mload(add(add(_bytes, 0x1), _start)) + } + + return tempUint; + } + + function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) { + require(_start + 20 >= _start, "toAddress_overflow"); + require(_bytes.length >= _start + 20, "toAddress_outOfBounds"); + address tempAddress; + + assembly { + tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) + } + + return tempAddress; + } + + function toNibbles( + bytes memory _bytes + ) internal pure returns (bytes memory) { + unchecked { + bytes memory nibbles = new bytes(_bytes.length * 2); + + for (uint256 i = 0; i < _bytes.length; i++) { + nibbles[i * 2] = _bytes[i] >> 4; + nibbles[i * 2 + 1] = bytes1(uint8(_bytes[i]) % 16); + } + + return nibbles; + } + } + + function fromNibbles( + bytes memory _bytes + ) internal pure returns (bytes memory) { + unchecked { + bytes memory ret = new bytes(_bytes.length / 2); + + for (uint256 i = 0; i < ret.length; i++) { + ret[i] = (_bytes[i * 2] << 4) | (_bytes[i * 2 + 1]); + } + + return ret; + } + } + + function equal(bytes memory _bytes, bytes memory _other) internal pure returns (bool) { + return keccak256(_bytes) == keccak256(_other); + } +} diff --git a/bolt-contracts/src/lib/MapWithTimeData.sol b/bolt-contracts/src/lib/MapWithTimeData.sol index a5f1512a..fa0a10af 100644 --- a/bolt-contracts/src/lib/MapWithTimeData.sol +++ b/bolt-contracts/src/lib/MapWithTimeData.sol @@ -1,9 +1,12 @@ // SPDX-License-Identifier: MIT pragma solidity 0.8.25; -import {Checkpoints} from "lib/openzeppelin-contracts/contracts/utils/structs/Checkpoints.sol"; -import {Time} from "lib/openzeppelin-contracts/contracts/utils/types/Time.sol"; -import {EnumerableMap} from "lib/openzeppelin-contracts/contracts/utils/structs/EnumerableMap.sol"; +// Credits: Symbiotic contributors. +// Ref: https://github.com/symbioticfi/cosmos-sdk/blob/c25b6d5f320eb8ea4189584fa04d28c47362c2a7/middleware/src/libraries/MapWithTimeData.sol + +import {Checkpoints} from "@openzeppelin/contracts/utils/structs/Checkpoints.sol"; +import {Time} from "@openzeppelin/contracts/utils/types/Time.sol"; +import {EnumerableMap} from "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; library MapWithTimeData { using EnumerableMap for EnumerableMap.AddressToUintMap; diff --git a/bolt-contracts/src/lib/TransactionDecoder.sol b/bolt-contracts/src/lib/TransactionDecoder.sol new file mode 100644 index 00000000..3bd7cfc6 --- /dev/null +++ b/bolt-contracts/src/lib/TransactionDecoder.sol @@ -0,0 +1,451 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +import {RLPReader} from "./rlp/RLPReader.sol"; +import {RLPWriter} from "./rlp/RLPWriter.sol"; +import {BytesUtils} from "./BytesUtils.sol"; + +/// @title TransactionDecoder +/// @notice A library to decode Ethereum transactions in EIP-2718 format +/// into a structured transaction object, and to recover the sender. +library TransactionDecoder { + using BytesUtils for bytes; + using RLPReader for bytes; + using RLPReader for RLPReader.RLPItem; + + /// @notice The type of transaction + enum TxType { + Legacy, + Eip2930, + Eip1559, + Eip4844 + } + + /// @notice A decoded transaction object + struct Transaction { + TxType txType; + uint64 chainId; + // As Solidity doesn't have NULL values, we use this flag to differentiate between + // an explicit chainId of 0 and a missing chainID. The difference is important for + // encoding unsigned eip-155 legacy transactions. + bool isChainIdSet; + uint256 nonce; + uint256 gasPrice; + uint256 maxPriorityFeePerGas; + uint256 maxFeePerGas; + uint256 gasLimit; + address to; + uint256 value; + bytes data; + bytes[] accessList; + uint256 maxFeePerBlobGas; + bytes32[] blobVersionedHashes; + bytes sig; + uint64 legacyV; + } + + error NoSignature(); + error InvalidYParity(); + error UnsupportedTxType(); + error InvalidFieldCount(); + error InvalidSignatureLength(); + + /// @notice Decode a raw transaction into a transaction object + /// @param raw The raw transaction bytes + /// @return transaction The decoded transaction object + function decodeEnveloped( + bytes memory raw + ) internal pure returns (Transaction memory transaction) { + bytes1 prefix = raw[0]; + + if (prefix >= 0x7F) { + return _decodeLegacy(raw); + } else if (prefix == 0x01) { + return _decodeEip2930(raw); + } else if (prefix == 0x02) { + return _decodeEip1559(raw); + } else if (prefix == 0x03) { + return _decodeEip4844(raw); + } else { + revert UnsupportedTxType(); + } + } + + /// @notice Recover the sender of a transaction + /// @param transaction The transaction object + /// @return sender The address of the sender + function recoverSender( + Transaction memory transaction + ) internal pure returns (address) { + return ECDSA.recover(preimage(transaction), signature(transaction)); + } + + /// @notice Compute the preimage of a transaction object + /// @dev This is the hash of the transaction that is signed by the sender to obtain the signature + /// @param transaction The transaction object + /// @return preimg The preimage hash of the transaction + function preimage( + Transaction memory transaction + ) internal pure returns (bytes32 preimg) { + preimg = keccak256(unsigned(transaction)); + } + + /// @notice Compute the unsigned transaction object + /// @dev This is the transaction object without the signature + /// @param transaction The transaction object + /// @return unsignedTx The unsigned transaction object + function unsigned( + Transaction memory transaction + ) internal pure returns (bytes memory unsignedTx) { + if (transaction.txType == TxType.Legacy) { + unsignedTx = _unsignedLegacy(transaction); + } else if (transaction.txType == TxType.Eip2930) { + unsignedTx = _unsignedEip2930(transaction); + } else if (transaction.txType == TxType.Eip1559) { + unsignedTx = _unsignedEip1559(transaction); + } else if (transaction.txType == TxType.Eip4844) { + unsignedTx = _unsignedEip4844(transaction); + } else { + revert UnsupportedTxType(); + } + } + + /// @notice Return the hex-encoded signature of a transaction object + /// @param transaction The transaction object + /// @return sig The hex-encoded signature + function signature( + Transaction memory transaction + ) internal pure returns (bytes memory sig) { + if (transaction.sig.length == 0) { + revert NoSignature(); + } else if (transaction.sig.length != 65) { + revert InvalidSignatureLength(); + } else { + sig = transaction.sig; + } + } + + /// @notice Helper to decode a legacy (type 0) transaction + /// @param raw The raw transaction bytes + /// @return transaction The decoded transaction object + function _decodeLegacy( + bytes memory raw + ) private pure returns (Transaction memory transaction) { + transaction.txType = TxType.Legacy; + + // Legacy transactions don't have a type prefix, so we can decode directly + RLPReader.RLPItem[] memory fields = raw.toRLPItem().readList(); + + if (fields.length != 9 && fields.length != 6) { + revert InvalidFieldCount(); + } + + transaction.nonce = fields[0].readUint256(); + transaction.gasPrice = fields[1].readUint256(); + transaction.gasLimit = fields[2].readUint256(); + transaction.to = fields[3].readAddress(); + transaction.value = fields[4].readUint256(); + transaction.data = fields[5].readBytes(); + + // Legacy unsigned transaction + if (fields.length == 6) { + return transaction; + } + + // rlp expects signature values in (v, r, s) order + uint64 v = uint64(fields[6].readUint256()); + uint256 r = fields[7].readUint256(); + uint256 s = fields[8].readUint256(); + + if (r == 0 && s == 0) { + // EIP-155 unsigned transaction + transaction.chainId = v; + transaction.isChainIdSet = true; + } else { + if (v >= 35) { + // Compute the EIP-155 chain ID (or 0 for legacy) + transaction.chainId = (v - 35) / 2; + transaction.legacyV = v; + transaction.isChainIdSet = true; + } + + // Compute the signature + uint8 parityV = uint8(((v ^ 1) % 2) + 27); + transaction.sig = abi.encodePacked(bytes32(r), bytes32(s), parityV); + } + } + + /// @notice Helper to decode an EIP-2930 (type 1) transaction + /// @param raw The raw transaction bytes + /// @return transaction The decoded transaction object + function _decodeEip2930( + bytes memory raw + ) private pure returns (Transaction memory transaction) { + transaction.txType = TxType.Eip2930; + + // Skip the first byte (transaction type) + bytes memory rlpData = raw.slice(1, raw.length - 1); + RLPReader.RLPItem[] memory fields = rlpData.toRLPItem().readList(); + + if (fields.length != 8 && fields.length != 11) { + revert InvalidFieldCount(); + } + + transaction.chainId = uint64(fields[0].readUint256()); + transaction.nonce = fields[1].readUint256(); + transaction.gasPrice = fields[2].readUint256(); + transaction.gasLimit = fields[3].readUint256(); + transaction.to = fields[4].readAddress(); + transaction.value = fields[5].readUint256(); + transaction.data = fields[6].readBytes(); + + RLPReader.RLPItem[] memory accessListItems = fields[7].readList(); + transaction.accessList = new bytes[](accessListItems.length); + for (uint256 i = 0; i < accessListItems.length; i++) { + transaction.accessList[i] = accessListItems[i].readRawBytes(); + } + + // EIP-2930 Unsigned transaction + if (fields.length == 8) { + return transaction; + } + + uint8 v = uint8(fields[8].readUint256()) + 27; + bytes32 r = fields[9].readBytes32(); + bytes32 s = fields[10].readBytes32(); + + // compute the signature + transaction.sig = abi.encodePacked(r, s, v); + } + + /// @notice Helper to decode an EIP-1559 (type 2) transaction + /// @param raw The raw transaction bytes + /// @return transaction The decoded transaction object + function _decodeEip1559( + bytes memory raw + ) private pure returns (Transaction memory transaction) { + transaction.txType = TxType.Eip1559; + + // Skip the first byte (transaction type) + bytes memory rlpData = raw.slice(1, raw.length - 1); + RLPReader.RLPItem[] memory fields = rlpData.toRLPItem().readList(); + + if (fields.length != 9 && fields.length != 12) { + revert InvalidFieldCount(); + } + + transaction.chainId = uint64(fields[0].readUint256()); + transaction.nonce = fields[1].readUint256(); + transaction.maxPriorityFeePerGas = fields[2].readUint256(); + transaction.maxFeePerGas = fields[3].readUint256(); + transaction.gasLimit = fields[4].readUint256(); + transaction.to = fields[5].readAddress(); + transaction.value = fields[6].readUint256(); + transaction.data = fields[7].readBytes(); + + RLPReader.RLPItem[] memory accessListItems = fields[8].readList(); + transaction.accessList = new bytes[](accessListItems.length); + for (uint256 i = 0; i < accessListItems.length; i++) { + transaction.accessList[i] = accessListItems[i].readRawBytes(); + } + + if (fields.length == 9) { + // EIP-1559 Unsigned transaction + return transaction; + } + + uint8 v = uint8(fields[9].readUint256()) + 27; + bytes32 r = fields[10].readBytes32(); + bytes32 s = fields[11].readBytes32(); + + // compute the signature + transaction.sig = abi.encodePacked(r, s, v); + } + + /// @notice Helper to decode an EIP-4844 (type 3) transaction + /// @param raw The raw transaction bytes + /// @return transaction The decoded transaction object + function _decodeEip4844( + bytes memory raw + ) private pure returns (Transaction memory transaction) { + transaction.txType = TxType.Eip4844; + + // Skip the first byte (transaction type) + bytes memory rlpData = raw.slice(1, raw.length - 1); + RLPReader.RLPItem[] memory fields = rlpData.toRLPItem().readList(); + + if (fields.length != 11 && fields.length != 14) { + revert InvalidFieldCount(); + } + + transaction.chainId = uint64(fields[0].readUint256()); + transaction.nonce = fields[1].readUint256(); + transaction.maxPriorityFeePerGas = fields[2].readUint256(); + transaction.maxFeePerGas = fields[3].readUint256(); + transaction.gasLimit = fields[4].readUint256(); + transaction.to = fields[5].readAddress(); + transaction.value = fields[6].readUint256(); + transaction.data = fields[7].readBytes(); + + RLPReader.RLPItem[] memory accessListItems = fields[8].readList(); + transaction.accessList = new bytes[](accessListItems.length); + for (uint256 i = 0; i < accessListItems.length; i++) { + transaction.accessList[i] = accessListItems[i].readRawBytes(); + } + + transaction.maxFeePerBlobGas = fields[9].readUint256(); + + RLPReader.RLPItem[] memory blobVersionedHashesItems = fields[10].readList(); + transaction.blobVersionedHashes = new bytes32[](blobVersionedHashesItems.length); + for (uint256 i = 0; i < blobVersionedHashesItems.length; i++) { + transaction.blobVersionedHashes[i] = blobVersionedHashesItems[i].readBytes32(); + } + + if (fields.length == 11) { + // Unsigned transaction + return transaction; + } + + uint8 v = uint8(fields[11].readUint256()) + 27; + bytes32 r = fields[12].readBytes32(); + bytes32 s = fields[13].readBytes32(); + + // compute the signature + transaction.sig = abi.encodePacked(r, s, v); + } + + /// @notice Helper to RLP-encode an unsigned legacy transaction + /// @param transaction The transaction object + /// @return unsignedTx The unsigned transaction bytes + function _unsignedLegacy( + Transaction memory transaction + ) private pure returns (bytes memory unsignedTx) { + uint64 chainId = 0; + if (transaction.chainId != 0) { + // A chainId was provided: if non-zero, we'll use EIP-155 + chainId = transaction.chainId; + } else if (transaction.sig.length != 0) { + // No explicit chainId, but EIP-155 have a derived implicit chainId + // based on the V value of the signature + if (transaction.legacyV >= 35) { + chainId = (transaction.legacyV - 35) / 2; + } + } + + uint256 fieldsCount = 6 + (transaction.isChainIdSet ? 3 : 0); + bytes[] memory fields = new bytes[](fieldsCount); + + fields[0] = RLPWriter.writeUint(transaction.nonce); + fields[1] = RLPWriter.writeUint(transaction.gasPrice); + fields[2] = RLPWriter.writeUint(transaction.gasLimit); + fields[3] = RLPWriter.writeAddress(transaction.to); + fields[4] = RLPWriter.writeUint(transaction.value); + fields[5] = RLPWriter.writeBytes(transaction.data); + + if (transaction.isChainIdSet) { + if (transaction.chainId == 0) { + // Edge case: chainId is 0, but we still need to encode it + // as a single empty byte. + fields[6] = abi.encodePacked(bytes1(0)); + } else { + fields[6] = RLPWriter.writeUint(chainId); + } + + fields[7] = RLPWriter.writeBytes(new bytes(0)); + fields[8] = RLPWriter.writeBytes(new bytes(0)); + } + + unsignedTx = RLPWriter.writeList(fields); + } + + /// @notice Helper to RLP-encode an unsigned EIP-2930 transaction + /// @param transaction The transaction object + /// @return unsignedTx The unsigned transaction bytes + function _unsignedEip2930( + Transaction memory transaction + ) private pure returns (bytes memory unsignedTx) { + bytes[] memory fields = new bytes[](8); + + fields[0] = RLPWriter.writeUint(transaction.chainId); + fields[1] = RLPWriter.writeUint(transaction.nonce); + fields[2] = RLPWriter.writeUint(transaction.gasPrice); + fields[3] = RLPWriter.writeUint(transaction.gasLimit); + fields[4] = RLPWriter.writeAddress(transaction.to); + fields[5] = RLPWriter.writeUint(transaction.value); + fields[6] = RLPWriter.writeBytes(transaction.data); + + bytes[] memory accessList = new bytes[](transaction.accessList.length); + for (uint256 i = 0; i < transaction.accessList.length; i++) { + accessList[i] = transaction.accessList[i]; + } + fields[7] = RLPWriter.writeList(accessList); + + // EIP-2718 envelope + unsignedTx = abi.encodePacked(uint8(TxType.Eip2930), RLPWriter.writeList(fields)); + } + + /// @notice Helper to RLP-encode an unsigned EIP-1559 transaction + /// @param transaction The transaction object + /// @return unsignedTx The unsigned transaction bytes + function _unsignedEip1559( + Transaction memory transaction + ) private pure returns (bytes memory unsignedTx) { + bytes[] memory fields = new bytes[](9); + + fields[0] = RLPWriter.writeUint(transaction.chainId); + fields[1] = RLPWriter.writeUint(transaction.nonce); + fields[2] = RLPWriter.writeUint(transaction.maxPriorityFeePerGas); + fields[3] = RLPWriter.writeUint(transaction.maxFeePerGas); + fields[4] = RLPWriter.writeUint(transaction.gasLimit); + fields[5] = RLPWriter.writeAddress(transaction.to); + fields[6] = RLPWriter.writeUint(transaction.value); + fields[7] = RLPWriter.writeBytes(transaction.data); + + bytes[] memory accessList = new bytes[](transaction.accessList.length); + for (uint256 i = 0; i < transaction.accessList.length; i++) { + accessList[i] = transaction.accessList[i]; + } + fields[8] = RLPWriter.writeList(accessList); + + // EIP-2718 envelope + unsignedTx = abi.encodePacked(uint8(TxType.Eip1559), RLPWriter.writeList(fields)); + } + + /// @notice Helper to RLP-encode an unsigned EIP-4844 transaction + /// @param transaction The transaction object + /// @return unsignedTx The unsigned transaction bytes + function _unsignedEip4844( + Transaction memory transaction + ) private pure returns (bytes memory unsignedTx) { + bytes[] memory fields = new bytes[](11); + + fields[0] = RLPWriter.writeUint(transaction.chainId); + fields[1] = RLPWriter.writeUint(transaction.nonce); + fields[2] = RLPWriter.writeUint(transaction.maxPriorityFeePerGas); + fields[3] = RLPWriter.writeUint(transaction.maxFeePerGas); + fields[4] = RLPWriter.writeUint(transaction.gasLimit); + fields[5] = RLPWriter.writeAddress(transaction.to); + fields[6] = RLPWriter.writeUint(transaction.value); + fields[7] = RLPWriter.writeBytes(transaction.data); + + bytes[] memory accessList = new bytes[](transaction.accessList.length); + for (uint256 i = 0; i < transaction.accessList.length; i++) { + accessList[i] = transaction.accessList[i]; + } + fields[8] = RLPWriter.writeList(accessList); + + fields[9] = RLPWriter.writeUint(transaction.maxFeePerBlobGas); + + bytes[] memory blobVersionedHashes = new bytes[](transaction.blobVersionedHashes.length); + for (uint256 i = 0; i < transaction.blobVersionedHashes.length; i++) { + // Decode bytes32 as uint256 (RLPWriter doesn't support bytes32 but they are equivalent) + blobVersionedHashes[i] = RLPWriter.writeUint(uint256(transaction.blobVersionedHashes[i])); + } + fields[10] = RLPWriter.writeList(blobVersionedHashes); + + // EIP-2718 envelope + unsignedTx = abi.encodePacked(uint8(TxType.Eip4844), RLPWriter.writeList(fields)); + } +} diff --git a/bolt-contracts/src/lib/rlp/RLPReader.sol b/bolt-contracts/src/lib/rlp/RLPReader.sol new file mode 100644 index 00000000..a8620e48 --- /dev/null +++ b/bolt-contracts/src/lib/rlp/RLPReader.sol @@ -0,0 +1,418 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +// Credits: Optimism contributors. +// Ref: https://github.com/ethereum-optimism/optimism/blob/05deae54595b0e6bdd33580de81cb9ad194898bc/packages/contracts-bedrock/src/libraries/rlp/RLPReader.sol + +/** + * @title RLPReader + * @dev Adapted from "RLPReader" by Hamdi Allam (hamdi.allam97@gmail.com). + */ +library RLPReader { + /** + * + * Constants * + * + */ + uint256 internal constant MAX_LIST_LENGTH = 32; + + /** + * + * Enums * + * + */ + enum RLPItemType { + DATA_ITEM, + LIST_ITEM + } + + /** + * + * Structs * + * + */ + struct RLPItem { + uint256 length; + uint256 ptr; + } + + /** + * + * Internal Functions * + * + */ + + /** + * Converts bytes to a reference to memory position and length. + * @param _in Input bytes to convert. + * @return Output memory reference. + */ + function toRLPItem( + bytes memory _in + ) internal pure returns (RLPItem memory) { + uint256 ptr; + assembly { + ptr := add(_in, 32) + } + + return RLPItem({length: _in.length, ptr: ptr}); + } + + /** + * Reads an RLP list value into a list of RLP items. + * @param _in RLP list value. + * @return Decoded RLP list items. + */ + function readList( + RLPItem memory _in + ) internal pure returns (RLPItem[] memory) { + (uint256 listOffset,, RLPItemType itemType) = _decodeLength(_in); + + require(itemType == RLPItemType.LIST_ITEM, "Invalid RLP list value."); + + // Solidity in-memory arrays can't be increased in size, but *can* be decreased in size by + // writing to the length. Since we can't know the number of RLP items without looping over + // the entire input, we'd have to loop twice to accurately size this array. It's easier to + // simply set a reasonable maximum list length and decrease the size before we finish. + RLPItem[] memory out = new RLPItem[](MAX_LIST_LENGTH); + + uint256 itemCount = 0; + uint256 offset = listOffset; + while (offset < _in.length) { + require(itemCount < MAX_LIST_LENGTH, "Provided RLP list exceeds max list length."); + + (uint256 itemOffset, uint256 itemLength,) = + _decodeLength(RLPItem({length: _in.length - offset, ptr: _in.ptr + offset})); + + out[itemCount] = RLPItem({length: itemLength + itemOffset, ptr: _in.ptr + offset}); + + itemCount += 1; + offset += itemOffset + itemLength; + } + + // Decrease the array size to match the actual item count. + assembly { + mstore(out, itemCount) + } + + return out; + } + + /** + * Reads an RLP list value into a list of RLP items. + * @param _in RLP list value. + * @return Decoded RLP list items. + */ + function readList( + bytes memory _in + ) internal pure returns (RLPItem[] memory) { + return readList(toRLPItem(_in)); + } + + /** + * Reads an RLP bytes value into bytes. + * @param _in RLP bytes value. + * @return Decoded bytes. + */ + function readBytes( + RLPItem memory _in + ) internal pure returns (bytes memory) { + (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); + + require(itemType == RLPItemType.DATA_ITEM, "Invalid RLP bytes value."); + + return _copy(_in.ptr, itemOffset, itemLength); + } + + /** + * Reads an RLP bytes value into bytes. + * @param _in RLP bytes value. + * @return Decoded bytes. + */ + function readBytes( + bytes memory _in + ) internal pure returns (bytes memory) { + return readBytes(toRLPItem(_in)); + } + + /** + * Reads an RLP string value into a string. + * @param _in RLP string value. + * @return Decoded string. + */ + function readString( + RLPItem memory _in + ) internal pure returns (string memory) { + return string(readBytes(_in)); + } + + /** + * Reads an RLP string value into a string. + * @param _in RLP string value. + * @return Decoded string. + */ + function readString( + bytes memory _in + ) internal pure returns (string memory) { + return readString(toRLPItem(_in)); + } + + /** + * Reads an RLP bytes32 value into a bytes32. + * @param _in RLP bytes32 value. + * @return Decoded bytes32. + */ + function readBytes32( + RLPItem memory _in + ) internal pure returns (bytes32) { + require(_in.length <= 33, "Invalid RLP bytes32 value."); + + (uint256 itemOffset, uint256 itemLength, RLPItemType itemType) = _decodeLength(_in); + + require(itemType == RLPItemType.DATA_ITEM, "Invalid RLP bytes32 value."); + + uint256 ptr = _in.ptr + itemOffset; + bytes32 out; + assembly { + out := mload(ptr) + + // Shift the bytes over to match the item size. + if lt(itemLength, 32) { out := div(out, exp(256, sub(32, itemLength))) } + } + + return out; + } + + /** + * Reads an RLP bytes32 value into a bytes32. + * @param _in RLP bytes32 value. + * @return Decoded bytes32. + */ + function readBytes32( + bytes memory _in + ) internal pure returns (bytes32) { + return readBytes32(toRLPItem(_in)); + } + + /** + * Reads an RLP uint256 value into a uint256. + * @param _in RLP uint256 value. + * @return Decoded uint256. + */ + function readUint256( + RLPItem memory _in + ) internal pure returns (uint256) { + return uint256(readBytes32(_in)); + } + + /** + * Reads an RLP uint256 value into a uint256. + * @param _in RLP uint256 value. + * @return Decoded uint256. + */ + function readUint256( + bytes memory _in + ) internal pure returns (uint256) { + return readUint256(toRLPItem(_in)); + } + + /** + * Reads an RLP bool value into a bool. + * @param _in RLP bool value. + * @return Decoded bool. + */ + function readBool( + RLPItem memory _in + ) internal pure returns (bool) { + require(_in.length == 1, "Invalid RLP boolean value."); + + uint256 ptr = _in.ptr; + uint256 out; + assembly { + out := byte(0, mload(ptr)) + } + + require(out == 0 || out == 1, "RLPReader: Invalid RLP boolean value, must be 0 or 1"); + + return out != 0; + } + + /** + * Reads an RLP bool value into a bool. + * @param _in RLP bool value. + * @return Decoded bool. + */ + function readBool( + bytes memory _in + ) internal pure returns (bool) { + return readBool(toRLPItem(_in)); + } + + /** + * Reads an RLP address value into a address. + * @param _in RLP address value. + * @return Decoded address. + */ + function readAddress( + RLPItem memory _in + ) internal pure returns (address) { + if (_in.length == 1) { + return address(0); + } + + require(_in.length == 21, "Invalid RLP address value."); + + return address(uint160(readUint256(_in))); + } + + /** + * Reads an RLP address value into a address. + * @param _in RLP address value. + * @return Decoded address. + */ + function readAddress( + bytes memory _in + ) internal pure returns (address) { + return readAddress(toRLPItem(_in)); + } + + /** + * Reads the raw bytes of an RLP item. + * @param _in RLP item to read. + * @return Raw RLP bytes. + */ + function readRawBytes( + RLPItem memory _in + ) internal pure returns (bytes memory) { + return _copy(_in); + } + + /** + * + * Private Functions * + * + */ + + /** + * Decodes the length of an RLP item. + * @param _in RLP item to decode. + * @return Offset of the encoded data. + * @return Length of the encoded data. + * @return RLP item type (LIST_ITEM or DATA_ITEM). + */ + function _decodeLength( + RLPItem memory _in + ) private pure returns (uint256, uint256, RLPItemType) { + unchecked { + require(_in.length > 0, "RLP item cannot be null."); + + uint256 ptr = _in.ptr; + uint256 prefix; + assembly { + prefix := byte(0, mload(ptr)) + } + + if (prefix <= 0x7f) { + // Single byte. + + return (0, 1, RLPItemType.DATA_ITEM); + } else if (prefix <= 0xb7) { + // Short string. + + uint256 strLen = prefix - 0x80; + + require(_in.length > strLen, "Invalid RLP short string."); + + return (1, strLen, RLPItemType.DATA_ITEM); + } else if (prefix <= 0xbf) { + // Long string. + uint256 lenOfStrLen = prefix - 0xb7; + + require(_in.length > lenOfStrLen, "Invalid RLP long string length."); + + uint256 strLen; + assembly { + // Pick out the string length. + strLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfStrLen))) + } + + require(_in.length > lenOfStrLen + strLen, "Invalid RLP long string."); + + return (1 + lenOfStrLen, strLen, RLPItemType.DATA_ITEM); + } else if (prefix <= 0xf7) { + // Short list. + uint256 listLen = prefix - 0xc0; + + require(_in.length > listLen, "Invalid RLP short list."); + + return (1, listLen, RLPItemType.LIST_ITEM); + } else { + // Long list. + uint256 lenOfListLen = prefix - 0xf7; + + require(_in.length > lenOfListLen, "Invalid RLP long list length."); + + uint256 listLen; + assembly { + // Pick out the list length. + listLen := div(mload(add(ptr, 1)), exp(256, sub(32, lenOfListLen))) + } + + require(_in.length > lenOfListLen + listLen, "Invalid RLP long list."); + + return (1 + lenOfListLen, listLen, RLPItemType.LIST_ITEM); + } + } + } + + /** + * Copies the bytes from a memory location. + * @param _src Pointer to the location to read from. + * @param _offset Offset to start reading from. + * @param _length Number of bytes to read. + * @return Copied bytes. + */ + function _copy(uint256 _src, uint256 _offset, uint256 _length) private pure returns (bytes memory) { + unchecked { + bytes memory out = new bytes(_length); + if (out.length == 0) { + return out; + } + + uint256 src = _src + _offset; + uint256 dest; + assembly { + dest := add(out, 32) + } + + // Copy over as many complete words as we can. + for (uint256 i = 0; i < _length / 32; i++) { + assembly { + mstore(dest, mload(src)) + } + + src += 32; + dest += 32; + } + + // Pick out the remaining bytes. + uint256 mask = 256 ** (32 - (_length % 32)) - 1; + assembly { + mstore(dest, or(and(mload(src), not(mask)), and(mload(dest), mask))) + } + + return out; + } + } + + /** + * Copies an RLP item into bytes. + * @param _in RLP item to copy. + * @return Copied bytes. + */ + function _copy( + RLPItem memory _in + ) private pure returns (bytes memory) { + return _copy(_in.ptr, 0, _in.length); + } +} diff --git a/bolt-contracts/src/lib/rlp/RLPWriter.sol b/bolt-contracts/src/lib/rlp/RLPWriter.sol new file mode 100644 index 00000000..fad2365a --- /dev/null +++ b/bolt-contracts/src/lib/rlp/RLPWriter.sol @@ -0,0 +1,225 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; +pragma experimental ABIEncoderV2; + +// Credits: Optimism contributors. +// Ref: https://github.com/ethereum-optimism/optimism/blob/05deae54595b0e6bdd33580de81cb9ad194898bc/packages/contracts-bedrock/src/libraries/rlp/RLPWriter.sol + +/** + * @title RLPWriter + * @author Bakaoh (with modifications) + */ +library RLPWriter { + /** + * + * Internal Functions * + * + */ + + /** + * RLP encodes a byte string. + * @param _in The byte string to encode. + * @return _out The RLP encoded string in bytes. + */ + function writeBytes( + bytes memory _in + ) internal pure returns (bytes memory _out) { + bytes memory encoded; + + if (_in.length == 1 && uint8(_in[0]) < 128) { + encoded = _in; + } else { + encoded = abi.encodePacked(_writeLength(_in.length, 128), _in); + } + + return encoded; + } + + /** + * RLP encodes a list of RLP encoded byte byte strings. + * @param _in The list of RLP encoded byte strings. + * @return _out The RLP encoded list of items in bytes. + */ + function writeList( + bytes[] memory _in + ) internal pure returns (bytes memory _out) { + bytes memory list = _flatten(_in); + return abi.encodePacked(_writeLength(list.length, 192), list); + } + + /** + * RLP encodes a string. + * @param _in The string to encode. + * @return _out The RLP encoded string in bytes. + */ + function writeString( + string memory _in + ) internal pure returns (bytes memory _out) { + return writeBytes(bytes(_in)); + } + + /** + * RLP encodes an address. + * @param _in The address to encode. + * @return _out The RLP encoded address in bytes. + */ + function writeAddress( + address _in + ) internal pure returns (bytes memory _out) { + return writeBytes(abi.encodePacked(_in)); + } + + /** + * RLP encodes a uint. + * @param _in The uint256 to encode. + * @return _out The RLP encoded uint256 in bytes. + */ + function writeUint( + uint256 _in + ) internal pure returns (bytes memory _out) { + return writeBytes(_toBinary(_in)); + } + + /** + * RLP encodes a bool. + * @param _in The bool to encode. + * @return _out The RLP encoded bool in bytes. + */ + function writeBool( + bool _in + ) internal pure returns (bytes memory _out) { + bytes memory encoded = new bytes(1); + encoded[0] = (_in ? bytes1(0x01) : bytes1(0x80)); + return encoded; + } + + /** + * + * Private Functions * + * + */ + + /** + * Encode the first byte, followed by the `len` in binary form if `length` is more than 55. + * @param _len The length of the string or the payload. + * @param _offset 128 if item is string, 192 if item is list. + * @return _encoded RLP encoded bytes. + */ + function _writeLength(uint256 _len, uint256 _offset) private pure returns (bytes memory _encoded) { + bytes memory encoded; + + if (_len < 56) { + encoded = new bytes(1); + encoded[0] = bytes1(uint8(_len) + uint8(_offset)); + } else { + uint256 lenLen; + uint256 i = 1; + while (_len / i != 0) { + lenLen++; + i *= 256; + } + + encoded = new bytes(lenLen + 1); + encoded[0] = bytes1(uint8(lenLen) + uint8(_offset) + 55); + for (i = 1; i <= lenLen; i++) { + encoded[i] = bytes1(uint8((_len / (256 ** (lenLen - i))) % 256)); + } + } + + return encoded; + } + + /** + * Encode integer in big endian binary form with no leading zeroes. + * @notice TODO: This should be optimized with assembly to save gas costs. + * @param _x The integer to encode. + * @return _binary RLP encoded bytes. + */ + function _toBinary( + uint256 _x + ) private pure returns (bytes memory _binary) { + bytes memory b = abi.encodePacked(_x); + + uint256 i = 0; + for (; i < 32; i++) { + if (b[i] != 0) { + break; + } + } + + bytes memory res = new bytes(32 - i); + for (uint256 j = 0; j < res.length; j++) { + res[j] = b[i++]; + } + + return res; + } + + /** + * Copies a piece of memory to another location. + * @notice From: https://github.com/Arachnid/solidity-stringutils/blob/master/src/strings.sol. + * @param _dest Destination location. + * @param _src Source location. + * @param _len Length of memory to copy. + */ + function _memcpy(uint256 _dest, uint256 _src, uint256 _len) private pure { + uint256 dest = _dest; + uint256 src = _src; + uint256 len = _len; + + for (; len >= 32; len -= 32) { + assembly { + mstore(dest, mload(src)) + } + dest += 32; + src += 32; + } + + uint256 mask = 256 ** (32 - len) - 1; + assembly { + let srcpart := and(mload(src), not(mask)) + let destpart := and(mload(dest), mask) + mstore(dest, or(destpart, srcpart)) + } + } + + /** + * Flattens a list of byte strings into one byte string. + * @notice From: https://github.com/sammayo/solidity-rlp-encoder/blob/master/RLPEncode.sol. + * @param _list List of byte strings to flatten. + * @return _flattened The flattened byte string. + */ + function _flatten( + bytes[] memory _list + ) private pure returns (bytes memory _flattened) { + if (_list.length == 0) { + return new bytes(0); + } + + uint256 len; + uint256 i = 0; + for (; i < _list.length; i++) { + len += _list[i].length; + } + + bytes memory flattened = new bytes(len); + uint256 flattenedPtr; + assembly { + flattenedPtr := add(flattened, 0x20) + } + + for (i = 0; i < _list.length; i++) { + bytes memory item = _list[i]; + + uint256 listPtr; + assembly { + listPtr := add(item, 0x20) + } + + _memcpy(flattenedPtr, listPtr, item.length); + flattenedPtr += _list[i].length; + } + + return flattened; + } +} diff --git a/bolt-contracts/src/lib/trie/MerkleTrie.sol b/bolt-contracts/src/lib/trie/MerkleTrie.sol new file mode 100644 index 00000000..d861e509 --- /dev/null +++ b/bolt-contracts/src/lib/trie/MerkleTrie.sol @@ -0,0 +1,761 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +// Credits: Optimism contributors. +// Ref: https://github.com/ethereum-optimism/optimism/blob/05deae54595b0e6bdd33580de81cb9ad194898bc/packages/contracts-bedrock/src/libraries/trie/MerkleTrie.sol + +/* Library Imports */ +import {BytesUtils} from "../BytesUtils.sol"; +import {RLPReader} from "../rlp/RLPReader.sol"; +import {RLPWriter} from "../rlp/RLPWriter.sol"; + +/** + * @title MerkleTrie + */ +library MerkleTrie { + /** + * + * Data Structures * + * + */ + enum NodeType { + BranchNode, + ExtensionNode, + LeafNode + } + + struct TrieNode { + bytes encoded; + RLPReader.RLPItem[] decoded; + } + + /** + * + * Contract Constants * + * + */ + + // TREE_RADIX determines the number of elements per branch node. + uint256 constant TREE_RADIX = 16; + // Branch nodes have TREE_RADIX elements plus an additional `value` slot. + uint256 constant BRANCH_NODE_LENGTH = TREE_RADIX + 1; + // Leaf nodes and extension nodes always have two elements, a `path` and a `value`. + uint256 constant LEAF_OR_EXTENSION_NODE_LENGTH = 2; + + // Prefixes are prepended to the `path` within a leaf or extension node and + // allow us to differentiate between the two node types. `ODD` or `EVEN` is + // determined by the number of nibbles within the unprefixed `path`. If the + // number of nibbles if even, we need to insert an extra padding nibble so + // the resulting prefixed `path` has an even number of nibbles. + uint8 constant PREFIX_EXTENSION_EVEN = 0; + uint8 constant PREFIX_EXTENSION_ODD = 1; + uint8 constant PREFIX_LEAF_EVEN = 2; + uint8 constant PREFIX_LEAF_ODD = 3; + + // Just a utility constant. RLP represents `NULL` as 0x80. + bytes1 constant RLP_NULL = bytes1(0x80); + bytes constant RLP_NULL_BYTES = hex"80"; + bytes32 internal constant KECCAK256_RLP_NULL_BYTES = keccak256(RLP_NULL_BYTES); + + /** + * + * Internal Functions * + * + */ + + /** + * @notice Verifies a proof that a given key/value pair is present in the + * Merkle trie. + * @param _key Key of the node to search for, as a hex string. + * @param _value Value of the node to search for, as a hex string. + * @param _proof Merkle trie inclusion proof for the desired node. Unlike + * traditional Merkle trees, this proof is executed top-down and consists + * of a list of RLP-encoded nodes that make a path down to the target node. + * @param _root Known root of the Merkle trie. Used to verify that the + * included proof is correctly constructed. + * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise. + */ + function verifyInclusionProof( + bytes memory _key, + bytes memory _value, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _verified) { + (bool exists, bytes memory value) = get(_key, _proof, _root); + + return (exists && BytesUtils.equal(_value, value)); + } + + /** + * @notice Verifies a proof that a given key is *not* present in + * the Merkle trie. + * @param _key Key of the node to search for, as a hex string. + * @param _proof Merkle trie inclusion proof for the node *nearest* the + * target node. + * @param _root Known root of the Merkle trie. Used to verify that the + * included proof is correctly constructed. + * @return _verified `true` if the key is absent in the trie, `false` otherwise. + */ + function verifyExclusionProof( + bytes memory _key, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _verified) { + (bool exists,) = get(_key, _proof, _root); + + return exists == false; + } + + /** + * @notice Updates a Merkle trie and returns a new root hash. + * @param _key Key of the node to update, as a hex string. + * @param _value Value of the node to update, as a hex string. + * @param _proof Merkle trie inclusion proof for the node *nearest* the + * target node. If the key exists, we can simply update the value. + * Otherwise, we need to modify the trie to handle the new k/v pair. + * @param _root Known root of the Merkle trie. Used to verify that the + * included proof is correctly constructed. + * @return _updatedRoot Root hash of the newly constructed trie. + */ + function update( + bytes memory _key, + bytes memory _value, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bytes32 _updatedRoot) { + // Special case when inserting the very first node. + if (_root == KECCAK256_RLP_NULL_BYTES) { + return getSingleNodeRootHash(_key, _value); + } + + TrieNode[] memory proof = _parseProof(_proof); + (uint256 pathLength, bytes memory keyRemainder,) = _walkNodePath(proof, _key, _root); + TrieNode[] memory newPath = _getNewPath(proof, pathLength, keyRemainder, _value); + + return _getUpdatedTrieRoot(newPath, _key); + } + + /** + * @notice Retrieves the value associated with a given key. + * @param _key Key to search for, as hex bytes. + * @param _proof Merkle trie inclusion proof for the key. + * @param _root Known root of the Merkle trie. + * @return _exists Whether or not the key exists. + * @return _value Value of the key if it exists. + */ + function get( + bytes memory _key, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _exists, bytes memory _value) { + TrieNode[] memory proof = _parseProof(_proof); + (uint256 pathLength, bytes memory keyRemainder, bool isFinalNode) = _walkNodePath(proof, _key, _root); + + bool exists = keyRemainder.length == 0; + + require(exists || isFinalNode, "Provided proof is invalid."); + + bytes memory value = exists ? _getNodeValue(proof[pathLength - 1]) : bytes(""); + + return (exists, value); + } + + /** + * Computes the root hash for a trie with a single node. + * @param _key Key for the single node. + * @param _value Value for the single node. + * @return _updatedRoot Hash of the trie. + */ + function getSingleNodeRootHash( + bytes memory _key, + bytes memory _value + ) internal pure returns (bytes32 _updatedRoot) { + return keccak256(_makeLeafNode(BytesUtils.toNibbles(_key), _value).encoded); + } + + /** + * + * Private Functions * + * + */ + + /** + * @notice Walks through a proof using a provided key. + * @param _proof Inclusion proof to walk through. + * @param _key Key to use for the walk. + * @param _root Known root of the trie. + * @return _pathLength Length of the final path + * @return _keyRemainder Portion of the key remaining after the walk. + * @return _isFinalNode Whether or not we've hit a dead end. + */ + function _walkNodePath( + TrieNode[] memory _proof, + bytes memory _key, + bytes32 _root + ) private pure returns (uint256 _pathLength, bytes memory _keyRemainder, bool _isFinalNode) { + uint256 pathLength = 0; + bytes memory key = BytesUtils.toNibbles(_key); + + bytes32 currentNodeID = _root; + uint256 currentKeyIndex = 0; + uint256 currentKeyIncrement = 0; + TrieNode memory currentNode; + + // Proof is top-down, so we start at the first element (root). + for (uint256 i = 0; i < _proof.length; i++) { + currentNode = _proof[i]; + currentKeyIndex += currentKeyIncrement; + + // Keep track of the proof elements we actually need. + // It's expensive to resize arrays, so this simply reduces gas costs. + pathLength += 1; + + if (currentKeyIndex == 0) { + // First proof element is always the root node. + require(keccak256(currentNode.encoded) == currentNodeID, "Invalid root hash"); + } else if (currentNode.encoded.length >= 32) { + // Nodes 32 bytes or larger are hashed inside branch nodes. + require(keccak256(currentNode.encoded) == currentNodeID, "Invalid large internal hash"); + } else { + // Nodes smaller than 31 bytes aren't hashed. + require(BytesUtils.toBytes32(currentNode.encoded) == currentNodeID, "Invalid internal node hash"); + } + + if (currentNode.decoded.length == BRANCH_NODE_LENGTH) { + if (currentKeyIndex == key.length) { + // We've hit the end of the key, meaning the value should be within this branch node. + break; + } else { + // We're not at the end of the key yet. + // Figure out what the next node ID should be and continue. + uint8 branchKey = uint8(key[currentKeyIndex]); + RLPReader.RLPItem memory nextNode = currentNode.decoded[branchKey]; + currentNodeID = _getNodeID(nextNode); + currentKeyIncrement = 1; + continue; + } + } else if (currentNode.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) { + bytes memory path = _getNodePath(currentNode); + uint8 prefix = uint8(path[0]); + uint8 offset = 2 - prefix % 2; + bytes memory pathRemainder = BytesUtils.slice(path, offset); + bytes memory keyRemainder = BytesUtils.slice(key, currentKeyIndex); + uint256 sharedNibbleLength = _getSharedNibbleLength(pathRemainder, keyRemainder); + + if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) { + if (pathRemainder.length == sharedNibbleLength && keyRemainder.length == sharedNibbleLength) { + // The key within this leaf matches our key exactly. + // Increment the key index to reflect that we have no remainder. + currentKeyIndex += sharedNibbleLength; + } + + // We've hit a leaf node, so our next node should be NULL. + currentNodeID = bytes32(RLP_NULL); + break; + } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) { + if (sharedNibbleLength == 0) { + // Our extension node doesn't share any part of our key. + // We've hit the end of this path, updates will need to modify this extension. + currentNodeID = bytes32(RLP_NULL); + break; + } else { + // Our extension shares some nibbles. + // Carry on to the next node. + currentNodeID = _getNodeID(currentNode.decoded[1]); + currentKeyIncrement = sharedNibbleLength; + continue; + } + } else { + revert("Received a node with an unknown prefix"); + } + } else { + revert("Received an unparseable node."); + } + } + + // If our node ID is NULL, then we're at a dead end. + bool isFinalNode = currentNodeID == bytes32(RLP_NULL); + return (pathLength, BytesUtils.slice(key, currentKeyIndex), isFinalNode); + } + + /** + * @notice Creates new nodes to support a k/v pair insertion into a given + * Merkle trie path. + * @param _path Path to the node nearest the k/v pair. + * @param _pathLength Length of the path. Necessary because the provided + * path may include additional nodes (e.g., it comes directly from a proof) + * and we can't resize in-memory arrays without costly duplication. + * @param _keyRemainder Portion of the initial key that must be inserted + * into the trie. + * @param _value Value to insert at the given key. + * @return _newPath A new path with the inserted k/v pair and extra supporting nodes. + */ + function _getNewPath( + TrieNode[] memory _path, + uint256 _pathLength, + bytes memory _keyRemainder, + bytes memory _value + ) private pure returns (TrieNode[] memory _newPath) { + bytes memory keyRemainder = _keyRemainder; + + // Most of our logic depends on the status of the last node in the path. + TrieNode memory lastNode = _path[_pathLength - 1]; + NodeType lastNodeType = _getNodeType(lastNode); + + // Create an array for newly created nodes. + // We need up to three new nodes, depending on the contents of the last node. + // Since array resizing is expensive, we'll keep track of the size manually. + // We're using an explicit `totalNewNodes += 1` after insertions for clarity. + TrieNode[] memory newNodes = new TrieNode[](3); + uint256 totalNewNodes = 0; + + if (keyRemainder.length == 0 && lastNodeType == NodeType.LeafNode) { + // We've found a leaf node with the given key. + // Simply need to update the value of the node to match. + newNodes[totalNewNodes] = _makeLeafNode(_getNodeKey(lastNode), _value); + totalNewNodes += 1; + } else if (lastNodeType == NodeType.BranchNode) { + if (keyRemainder.length == 0) { + // We've found a branch node with the given key. + // Simply need to update the value of the node to match. + newNodes[totalNewNodes] = _editBranchValue(lastNode, _value); + totalNewNodes += 1; + } else { + // We've found a branch node, but it doesn't contain our key. + // Reinsert the old branch for now. + newNodes[totalNewNodes] = lastNode; + totalNewNodes += 1; + // Create a new leaf node, slicing our remainder since the first byte points + // to our branch node. + newNodes[totalNewNodes] = _makeLeafNode(BytesUtils.slice(keyRemainder, 1), _value); + totalNewNodes += 1; + } + } else { + // Our last node is either an extension node or a leaf node with a different key. + bytes memory lastNodeKey = _getNodeKey(lastNode); + uint256 sharedNibbleLength = _getSharedNibbleLength(lastNodeKey, keyRemainder); + + if (sharedNibbleLength != 0) { + // We've got some shared nibbles between the last node and our key remainder. + // We'll need to insert an extension node that covers these shared nibbles. + bytes memory nextNodeKey = BytesUtils.slice(lastNodeKey, 0, sharedNibbleLength); + newNodes[totalNewNodes] = _makeExtensionNode(nextNodeKey, _getNodeHash(_value)); + totalNewNodes += 1; + + // Cut down the keys since we've just covered these shared nibbles. + lastNodeKey = BytesUtils.slice(lastNodeKey, sharedNibbleLength); + keyRemainder = BytesUtils.slice(keyRemainder, sharedNibbleLength); + } + + // Create an empty branch to fill in. + TrieNode memory newBranch = _makeEmptyBranchNode(); + + if (lastNodeKey.length == 0) { + // Key remainder was larger than the key for our last node. + // The value within our last node is therefore going to be shifted into + // a branch value slot. + newBranch = _editBranchValue(newBranch, _getNodeValue(lastNode)); + } else { + // Last node key was larger than the key remainder. + // We're going to modify some index of our branch. + uint8 branchKey = uint8(lastNodeKey[0]); + // Move on to the next nibble. + lastNodeKey = BytesUtils.slice(lastNodeKey, 1); + + if (lastNodeType == NodeType.LeafNode) { + // We're dealing with a leaf node. + // We'll modify the key and insert the old leaf node into the branch index. + TrieNode memory modifiedLastNode = _makeLeafNode(lastNodeKey, _getNodeValue(lastNode)); + newBranch = _editBranchIndex(newBranch, branchKey, _getNodeHash(modifiedLastNode.encoded)); + } else if (lastNodeKey.length != 0) { + // We're dealing with a shrinking extension node. + // We need to modify the node to decrease the size of the key. + TrieNode memory modifiedLastNode = _makeExtensionNode(lastNodeKey, _getNodeValue(lastNode)); + newBranch = _editBranchIndex(newBranch, branchKey, _getNodeHash(modifiedLastNode.encoded)); + } else { + // We're dealing with an unnecessary extension node. + // We're going to delete the node entirely. + // Simply insert its current value into the branch index. + newBranch = _editBranchIndex(newBranch, branchKey, _getNodeValue(lastNode)); + } + } + + if (keyRemainder.length == 0) { + // We've got nothing left in the key remainder. + // Simply insert the value into the branch value slot. + newBranch = _editBranchValue(newBranch, _value); + // Push the branch into the list of new nodes. + newNodes[totalNewNodes] = newBranch; + totalNewNodes += 1; + } else { + // We've got some key remainder to work with. + // We'll be inserting a leaf node into the trie. + // First, move on to the next nibble. + keyRemainder = BytesUtils.slice(keyRemainder, 1); + // Push the branch into the list of new nodes. + newNodes[totalNewNodes] = newBranch; + totalNewNodes += 1; + // Push a new leaf node for our k/v pair. + newNodes[totalNewNodes] = _makeLeafNode(keyRemainder, _value); + totalNewNodes += 1; + } + } + + // Finally, join the old path with our newly created nodes. + // Since we're overwriting the last node in the path, we use `_pathLength - 1`. + return _joinNodeArrays(_path, _pathLength - 1, newNodes, totalNewNodes); + } + + /** + * @notice Computes the trie root from a given path. + * @param _nodes Path to some k/v pair. + * @param _key Key for the k/v pair. + * @return _updatedRoot Root hash for the updated trie. + */ + function _getUpdatedTrieRoot( + TrieNode[] memory _nodes, + bytes memory _key + ) private pure returns (bytes32 _updatedRoot) { + bytes memory key = BytesUtils.toNibbles(_key); + + // Some variables to keep track of during iteration. + TrieNode memory currentNode; + NodeType currentNodeType; + bytes memory previousNodeHash; + + // Run through the path backwards to rebuild our root hash. + for (uint256 i = _nodes.length; i > 0; i--) { + // Pick out the current node. + currentNode = _nodes[i - 1]; + currentNodeType = _getNodeType(currentNode); + + if (currentNodeType == NodeType.LeafNode) { + // Leaf nodes are already correctly encoded. + // Shift the key over to account for the nodes key. + bytes memory nodeKey = _getNodeKey(currentNode); + key = BytesUtils.slice(key, 0, key.length - nodeKey.length); + } else if (currentNodeType == NodeType.ExtensionNode) { + // Shift the key over to account for the nodes key. + bytes memory nodeKey = _getNodeKey(currentNode); + key = BytesUtils.slice(key, 0, key.length - nodeKey.length); + + // If this node is the last element in the path, it'll be correctly encoded + // and we can skip this part. + if (previousNodeHash.length > 0) { + // Re-encode the node based on the previous node. + currentNode = _makeExtensionNode(nodeKey, previousNodeHash); + } + } else if (currentNodeType == NodeType.BranchNode) { + // If this node is the last element in the path, it'll be correctly encoded + // and we can skip this part. + if (previousNodeHash.length > 0) { + // Re-encode the node based on the previous node. + uint8 branchKey = uint8(key[key.length - 1]); + key = BytesUtils.slice(key, 0, key.length - 1); + currentNode = _editBranchIndex(currentNode, branchKey, previousNodeHash); + } + } + + // Compute the node hash for the next iteration. + previousNodeHash = _getNodeHash(currentNode.encoded); + } + + // Current node should be the root at this point. + // Simply return the hash of its encoding. + return keccak256(currentNode.encoded); + } + + /** + * @notice Parses an RLP-encoded proof into something more useful. + * @param _proof RLP-encoded proof to parse. + * @return _parsed Proof parsed into easily accessible structs. + */ + function _parseProof( + bytes memory _proof + ) private pure returns (TrieNode[] memory _parsed) { + RLPReader.RLPItem[] memory nodes = RLPReader.readList(_proof); + TrieNode[] memory proof = new TrieNode[](nodes.length); + + for (uint256 i = 0; i < nodes.length; i++) { + bytes memory encoded = RLPReader.readBytes(nodes[i]); + proof[i] = TrieNode({encoded: encoded, decoded: RLPReader.readList(encoded)}); + } + + return proof; + } + + /** + * @notice Picks out the ID for a node. Node ID is referred to as the + * "hash" within the specification, but nodes < 32 bytes are not actually + * hashed. + * @param _node Node to pull an ID for. + * @return _nodeID ID for the node, depending on the size of its contents. + */ + function _getNodeID( + RLPReader.RLPItem memory _node + ) private pure returns (bytes32 _nodeID) { + bytes memory nodeID; + + if (_node.length < 32) { + // Nodes smaller than 32 bytes are RLP encoded. + nodeID = RLPReader.readRawBytes(_node); + } else { + // Nodes 32 bytes or larger are hashed. + nodeID = RLPReader.readBytes(_node); + } + + return BytesUtils.toBytes32(nodeID); + } + + /** + * @notice Gets the path for a leaf or extension node. + * @param _node Node to get a path for. + * @return _path Node path, converted to an array of nibbles. + */ + function _getNodePath( + TrieNode memory _node + ) private pure returns (bytes memory _path) { + return BytesUtils.toNibbles(RLPReader.readBytes(_node.decoded[0])); + } + + /** + * @notice Gets the key for a leaf or extension node. Keys are essentially + * just paths without any prefix. + * @param _node Node to get a key for. + * @return _key Node key, converted to an array of nibbles. + */ + function _getNodeKey( + TrieNode memory _node + ) private pure returns (bytes memory _key) { + return _removeHexPrefix(_getNodePath(_node)); + } + + /** + * @notice Gets the path for a node. + * @param _node Node to get a value for. + * @return _value Node value, as hex bytes. + */ + function _getNodeValue( + TrieNode memory _node + ) private pure returns (bytes memory _value) { + return RLPReader.readBytes(_node.decoded[_node.decoded.length - 1]); + } + + /** + * @notice Computes the node hash for an encoded node. Nodes < 32 bytes + * are not hashed, all others are keccak256 hashed. + * @param _encoded Encoded node to hash. + * @return _hash Hash of the encoded node. Simply the input if < 32 bytes. + */ + function _getNodeHash( + bytes memory _encoded + ) private pure returns (bytes memory _hash) { + if (_encoded.length < 32) { + return _encoded; + } else { + return abi.encodePacked(keccak256(_encoded)); + } + } + + /** + * @notice Determines the type for a given node. + * @param _node Node to determine a type for. + * @return _type Type of the node; BranchNode/ExtensionNode/LeafNode. + */ + function _getNodeType( + TrieNode memory _node + ) private pure returns (NodeType _type) { + if (_node.decoded.length == BRANCH_NODE_LENGTH) { + return NodeType.BranchNode; + } else if (_node.decoded.length == LEAF_OR_EXTENSION_NODE_LENGTH) { + bytes memory path = _getNodePath(_node); + uint8 prefix = uint8(path[0]); + + if (prefix == PREFIX_LEAF_EVEN || prefix == PREFIX_LEAF_ODD) { + return NodeType.LeafNode; + } else if (prefix == PREFIX_EXTENSION_EVEN || prefix == PREFIX_EXTENSION_ODD) { + return NodeType.ExtensionNode; + } + } + + revert("Invalid node type"); + } + + /** + * @notice Utility; determines the number of nibbles shared between two + * nibble arrays. + * @param _a First nibble array. + * @param _b Second nibble array. + * @return _shared Number of shared nibbles. + */ + function _getSharedNibbleLength(bytes memory _a, bytes memory _b) private pure returns (uint256 _shared) { + uint256 i = 0; + while (_a.length > i && _b.length > i && _a[i] == _b[i]) { + i++; + } + return i; + } + + /** + * @notice Utility; converts an RLP-encoded node into our nice struct. + * @param _raw RLP-encoded node to convert. + * @return _node Node as a TrieNode struct. + */ + function _makeNode( + bytes[] memory _raw + ) private pure returns (TrieNode memory _node) { + bytes memory encoded = RLPWriter.writeList(_raw); + + return TrieNode({encoded: encoded, decoded: RLPReader.readList(encoded)}); + } + + /** + * @notice Utility; converts an RLP-decoded node into our nice struct. + * @param _items RLP-decoded node to convert. + * @return _node Node as a TrieNode struct. + */ + function _makeNode( + RLPReader.RLPItem[] memory _items + ) private pure returns (TrieNode memory _node) { + bytes[] memory raw = new bytes[](_items.length); + for (uint256 i = 0; i < _items.length; i++) { + raw[i] = RLPReader.readRawBytes(_items[i]); + } + return _makeNode(raw); + } + + /** + * @notice Creates a new extension node. + * @param _key Key for the extension node, unprefixed. + * @param _value Value for the extension node. + * @return _node New extension node with the given k/v pair. + */ + function _makeExtensionNode(bytes memory _key, bytes memory _value) private pure returns (TrieNode memory _node) { + bytes[] memory raw = new bytes[](2); + bytes memory key = _addHexPrefix(_key, false); + raw[0] = RLPWriter.writeBytes(BytesUtils.fromNibbles(key)); + raw[1] = RLPWriter.writeBytes(_value); + return _makeNode(raw); + } + + /** + * @notice Creates a new leaf node. + * @dev This function is essentially identical to `_makeExtensionNode`. + * Although we could route both to a single method with a flag, it's + * more gas efficient to keep them separate and duplicate the logic. + * @param _key Key for the leaf node, unprefixed. + * @param _value Value for the leaf node. + * @return _node New leaf node with the given k/v pair. + */ + function _makeLeafNode(bytes memory _key, bytes memory _value) private pure returns (TrieNode memory _node) { + bytes[] memory raw = new bytes[](2); + bytes memory key = _addHexPrefix(_key, true); + raw[0] = RLPWriter.writeBytes(BytesUtils.fromNibbles(key)); + raw[1] = RLPWriter.writeBytes(_value); + return _makeNode(raw); + } + + /** + * @notice Creates an empty branch node. + * @return _node Empty branch node as a TrieNode struct. + */ + function _makeEmptyBranchNode() private pure returns (TrieNode memory _node) { + bytes[] memory raw = new bytes[](BRANCH_NODE_LENGTH); + for (uint256 i = 0; i < raw.length; i++) { + raw[i] = RLP_NULL_BYTES; + } + return _makeNode(raw); + } + + /** + * @notice Modifies the value slot for a given branch. + * @param _branch Branch node to modify. + * @param _value Value to insert into the branch. + * @return _updatedNode Modified branch node. + */ + function _editBranchValue( + TrieNode memory _branch, + bytes memory _value + ) private pure returns (TrieNode memory _updatedNode) { + bytes memory encoded = RLPWriter.writeBytes(_value); + _branch.decoded[_branch.decoded.length - 1] = RLPReader.toRLPItem(encoded); + return _makeNode(_branch.decoded); + } + + /** + * @notice Modifies a slot at an index for a given branch. + * @param _branch Branch node to modify. + * @param _index Slot index to modify. + * @param _value Value to insert into the slot. + * @return _updatedNode Modified branch node. + */ + function _editBranchIndex( + TrieNode memory _branch, + uint8 _index, + bytes memory _value + ) private pure returns (TrieNode memory _updatedNode) { + bytes memory encoded = _value.length < 32 ? _value : RLPWriter.writeBytes(_value); + _branch.decoded[_index] = RLPReader.toRLPItem(encoded); + return _makeNode(_branch.decoded); + } + + /** + * @notice Utility; adds a prefix to a key. + * @param _key Key to prefix. + * @param _isLeaf Whether or not the key belongs to a leaf. + * @return _prefixedKey Prefixed key. + */ + function _addHexPrefix(bytes memory _key, bool _isLeaf) private pure returns (bytes memory _prefixedKey) { + uint8 prefix = _isLeaf ? uint8(0x02) : uint8(0x00); + uint8 offset = uint8(_key.length % 2); + bytes memory prefixed = new bytes(2 - offset); + prefixed[0] = bytes1(prefix + offset); + return abi.encodePacked(prefixed, _key); + } + + /** + * @notice Utility; removes a prefix from a path. + * @param _path Path to remove the prefix from. + * @return _unprefixedKey Unprefixed key. + */ + function _removeHexPrefix( + bytes memory _path + ) private pure returns (bytes memory _unprefixedKey) { + if (uint8(_path[0]) % 2 == 0) { + return BytesUtils.slice(_path, 2); + } else { + return BytesUtils.slice(_path, 1); + } + } + + /** + * @notice Utility; combines two node arrays. Array lengths are required + * because the actual lengths may be longer than the filled lengths. + * Array resizing is extremely costly and should be avoided. + * @param _a First array to join. + * @param _aLength Length of the first array. + * @param _b Second array to join. + * @param _bLength Length of the second array. + * @return _joined Combined node array. + */ + function _joinNodeArrays( + TrieNode[] memory _a, + uint256 _aLength, + TrieNode[] memory _b, + uint256 _bLength + ) private pure returns (TrieNode[] memory _joined) { + TrieNode[] memory ret = new TrieNode[](_aLength + _bLength); + + // Copy elements from the first array. + for (uint256 i = 0; i < _aLength; i++) { + ret[i] = _a[i]; + } + + // Copy elements from the second array. + for (uint256 i = 0; i < _bLength; i++) { + ret[i + _aLength] = _b[i]; + } + + return ret; + } +} diff --git a/bolt-contracts/src/lib/trie/SecureMerkleTrie.sol b/bolt-contracts/src/lib/trie/SecureMerkleTrie.sol new file mode 100644 index 00000000..d25b90aa --- /dev/null +++ b/bolt-contracts/src/lib/trie/SecureMerkleTrie.sol @@ -0,0 +1,130 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; +pragma experimental ABIEncoderV2; + +// Credits: Optimism contributors. +// Ref: https://github.com/ethereum-optimism/optimism/blob/05deae54595b0e6bdd33580de81cb9ad194898bc/packages/contracts-bedrock/src/libraries/trie/SecureMerkleTrie.sol + +/* Library Imports */ +import {MerkleTrie} from "./MerkleTrie.sol"; + +/** + * @title SecureMerkleTrie + */ +library SecureMerkleTrie { + /** + * + * Internal Functions * + * + */ + + /** + * @notice Verifies a proof that a given key/value pair is present in the + * Merkle trie. + * @param _key Key of the node to search for, as a hex string. + * @param _value Value of the node to search for, as a hex string. + * @param _proof Merkle trie inclusion proof for the desired node. Unlike + * traditional Merkle trees, this proof is executed top-down and consists + * of a list of RLP-encoded nodes that make a path down to the target node. + * @param _root Known root of the Merkle trie. Used to verify that the + * included proof is correctly constructed. + * @return _verified `true` if the k/v pair exists in the trie, `false` otherwise. + */ + function verifyInclusionProof( + bytes memory _key, + bytes memory _value, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _verified) { + bytes memory key = _getSecureKey(_key); + return MerkleTrie.verifyInclusionProof(key, _value, _proof, _root); + } + + /** + * @notice Verifies a proof that a given key is *not* present in + * the Merkle trie. + * @param _key Key of the node to search for, as a hex string. + * @param _proof Merkle trie inclusion proof for the node *nearest* the + * target node. + * @param _root Known root of the Merkle trie. Used to verify that the + * included proof is correctly constructed. + * @return _verified `true` if the key is not present in the trie, `false` otherwise. + */ + function verifyExclusionProof( + bytes memory _key, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _verified) { + bytes memory key = _getSecureKey(_key); + return MerkleTrie.verifyExclusionProof(key, _proof, _root); + } + + /** + * @notice Updates a Merkle trie and returns a new root hash. + * @param _key Key of the node to update, as a hex string. + * @param _value Value of the node to update, as a hex string. + * @param _proof Merkle trie inclusion proof for the node *nearest* the + * target node. If the key exists, we can simply update the value. + * Otherwise, we need to modify the trie to handle the new k/v pair. + * @param _root Known root of the Merkle trie. Used to verify that the + * included proof is correctly constructed. + * @return _updatedRoot Root hash of the newly constructed trie. + */ + function update( + bytes memory _key, + bytes memory _value, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bytes32 _updatedRoot) { + bytes memory key = _getSecureKey(_key); + return MerkleTrie.update(key, _value, _proof, _root); + } + + /** + * @notice Retrieves the value associated with a given key. + * @param _key Key to search for, as hex bytes. + * @param _proof Merkle trie inclusion proof for the key. + * @param _root Known root of the Merkle trie. + * @return _exists Whether or not the key exists. + * @return _value Value of the key if it exists. + */ + function get( + bytes memory _key, + bytes memory _proof, + bytes32 _root + ) internal pure returns (bool _exists, bytes memory _value) { + bytes memory key = _getSecureKey(_key); + return MerkleTrie.get(key, _proof, _root); + } + + /** + * Computes the root hash for a trie with a single node. + * @param _key Key for the single node. + * @param _value Value for the single node. + * @return _updatedRoot Hash of the trie. + */ + function getSingleNodeRootHash( + bytes memory _key, + bytes memory _value + ) internal pure returns (bytes32 _updatedRoot) { + bytes memory key = _getSecureKey(_key); + return MerkleTrie.getSingleNodeRootHash(key, _value); + } + + /** + * + * Private Functions * + * + */ + + /** + * Computes the secure counterpart to a key. + * @param _key Key to get a secure key from. + * @return _secureKey Secure version of the key. + */ + function _getSecureKey( + bytes memory _key + ) private pure returns (bytes memory _secureKey) { + return abi.encodePacked(keccak256(_key)); + } +} diff --git a/bolt-contracts/test/BoltChallenger.t.sol b/bolt-contracts/test/BoltChallenger.t.sol new file mode 100644 index 00000000..3a860588 --- /dev/null +++ b/bolt-contracts/test/BoltChallenger.t.sol @@ -0,0 +1,575 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {Test, console} from "forge-std/Test.sol"; + +import {ECDSA} from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol"; + +import {BoltChallenger} from "../src/contracts/BoltChallenger.sol"; +import {IBoltChallenger} from "../src/interfaces/IBoltChallenger.sol"; +import {RLPReader} from "../src/lib/rlp/RLPReader.sol"; +import {RLPWriter} from "../src/lib/rlp/RLPWriter.sol"; +import {BytesUtils} from "../src/lib/BytesUtils.sol"; +import {MerkleTrie} from "../src/lib/trie/MerkleTrie.sol"; +import {SecureMerkleTrie} from "../src/lib/trie/SecureMerkleTrie.sol"; +import {BeaconChainUtils} from "../src/lib/BeaconChainUtils.sol"; +import {TransactionDecoder} from "../src/lib/TransactionDecoder.sol"; + +// re-export the internal resolver function for testing +contract BoltChallengerExt is BoltChallenger { + function _resolveExt( + bytes32 _challengeID, + bytes32 _trustedBlockHash, + IBoltChallenger.Proof calldata _proof + ) external { + _resolve(_challengeID, _trustedBlockHash, _proof); + } + + function _decodeBlockHeaderRLPExt( + bytes calldata _blockHeaderRLP + ) external pure returns (IBoltChallenger.BlockHeaderData memory) { + return _decodeBlockHeaderRLP(_blockHeaderRLP); + } +} + +contract BoltChallengerTest is Test { + using RLPReader for bytes; + using RLPReader for RLPReader.RLPItem; + using BytesUtils for bytes; + using TransactionDecoder for TransactionDecoder.Transaction; + using TransactionDecoder for bytes; + + BoltChallengerExt boltChallenger; + + address challenger = makeAddr("challenger"); + address resolver = makeAddr("resolver"); + + address target; + uint256 targetPK; + + function setUp() public { + vm.pauseGasMetering(); + (target, targetPK) = makeAddrAndKey("target"); + + boltChallenger = new BoltChallengerExt(); + + vm.deal(challenger, 100 ether); + vm.deal(resolver, 100 ether); + vm.roll(12_456_789); + vm.warp(1_726_564_072); + } + + // =========== Proving data inclusion on-chain =========== + + function testProveHeaderData() public { + // Note: In prod, how we obtain the trusted block hash would depend on the context. + // For recent blocks, we can simply use the blockhash function in the EVM. + bytes32 trustedBlockHash = 0x0fc7c840f5b4b451e99dc8adb0d475eab2ac7d36278d9601d7f4b2dd05e8022f; + + // Read the RLP-encoded block header from a file (obtained via `debug_getRawHeader` RPC call) + string memory file = vm.readFile("./test/testdata/header_20785012.json"); + bytes memory headerRLP = vm.parseJsonBytes(file, ".result"); + + assertEq(keccak256(headerRLP), trustedBlockHash); + + // RLP decode the header + vm.resumeGasMetering(); + IBoltChallenger.BlockHeaderData memory header = boltChallenger._decodeBlockHeaderRLPExt(headerRLP); + vm.pauseGasMetering(); + + assertEq(header.stateRoot, 0x214389f55a96edbd4d5295a17ada4dbc68a3b276145bf824b060635f9905cefc); + assertEq(header.txRoot, 0x87bb9183296ce9e3b7a3246f6d3a778b99a5d7daaba2174750707407c7297365); + assertEq(header.blockNumber, 20_785_012); + assertEq(header.timestamp, 1_726_753_391); + assertEq(header.baseFee, 21_575_309_588); + } + + function testProveAccountData() public { + // The account we want to prove + address accountToProve = 0x0D9f5045B604bA0c050b5eb06D0b25d01c525Ea5; + + // Note: in prod the state root should be obtained from the block header proof. + // this way we can trust it comes from the right block number. This comes from Mainnet block 20_728_344. + bytes32 stateRootAtBlock = 0x214389f55a96edbd4d5295a17ada4dbc68a3b276145bf824b060635f9905cefc; + + // Read the RLP-encoded account proof from a file. This is obtained from the `eth_getProof` + // RPC call + ABI-encoding of the resulting accountProof array. + string memory file = vm.readFile("./test/testdata/eth_proof_20785012.json"); + bytes[] memory accountProofJson = vm.parseJsonBytesArray(file, ".result.accountProof"); + bytes memory accountProof = _RLPEncodeList(accountProofJson); + + // Perform a sanity check to see if the state root matches the expected trie node + RLPReader.RLPItem[] memory nodes = RLPReader.readList(accountProof); + MerkleTrie.TrieNode[] memory proof = new MerkleTrie.TrieNode[](nodes.length); + for (uint256 i = 0; i < nodes.length; i++) { + bytes memory encoded = RLPReader.readBytes(nodes[i]); + proof[i] = MerkleTrie.TrieNode({encoded: encoded, decoded: RLPReader.readList(encoded)}); + } + assertEq(keccak256(proof[0].encoded), stateRootAtBlock, "Roots should match"); + + vm.resumeGasMetering(); + (bool exists, bytes memory accountRLP) = + SecureMerkleTrie.get(abi.encodePacked(accountToProve), accountProof, stateRootAtBlock); + vm.pauseGasMetering(); + assertEq(exists, true); + + // decode the account RLP into nonce and balance + RLPReader.RLPItem[] memory accountFields = accountRLP.toRLPItem().readList(); + uint256 nonce = accountFields[0].readUint256(); + uint256 balance = accountFields[1].readUint256(); + + assertEq(nonce, 236); + assertEq(balance, 136_481_368_234_605_997); + } + + function testProveTransactionInclusion() public { + // The transaction we want to prove inclusion of + bytes32 txHash = 0x9ec2c56ca36e445a46bc77ca77510f0ef21795d00834269f3752cbd29d63ba1f; + + // MPT proof, obtained with the `trie-proofs` CLI tool from HerodotusDev + // ref: + string memory file = vm.readFile("./test/testdata/tx_mpt_proof_20785012.json"); + bytes[] memory txProofJson = vm.parseJsonBytesArray(file, ".proof"); + bytes memory txProof = _RLPEncodeList(txProofJson); + + // The transactions root and index in the block, also included in the CLI response + bytes32 txRootAtBlock = vm.parseJsonBytes32(file, ".root"); + uint256 txIndexInBlock = vm.parseJsonUint(file, ".index"); + + bytes memory key = RLPWriter.writeUint(txIndexInBlock); + + vm.resumeGasMetering(); + // Gotcha: SecureMerkleTrie.get expects the key to be hashed with keccak256 + // but the transaction trie skips this step and uses the raw index as the key. + (bool exists, bytes memory transactionRLP) = MerkleTrie.get(key, txProof, txRootAtBlock); + vm.pauseGasMetering(); + + assertEq(exists, true); + assertEq(keccak256(transactionRLP), txHash); + + // Decode the transaction RLP into its fields + TransactionDecoder.Transaction memory decodedTx = transactionRLP.decodeEnveloped(); + assertEq(uint8(decodedTx.txType), 2); + assertEq(decodedTx.chainId, 1); + assertEq(decodedTx.nonce, 0xeb); + assertEq(decodedTx.maxPriorityFeePerGas, 0x73a20d00); + assertEq(decodedTx.maxFeePerGas, 0x7e172a822); + assertEq(decodedTx.gasLimit, 0x5208); + assertEq(decodedTx.to, 0x0ff71973B5243005b192D5BCF552Fc2532b7bdEc); + assertEq(decodedTx.value, 0x15842095ebc4000); + assertEq(decodedTx.data.length, 0); + assertEq(decodedTx.recoverSender(), 0x0D9f5045B604bA0c050b5eb06D0b25d01c525Ea5); + } + + // =========== Verifying Signatures =========== + + function testCommitmentDigestAndSignature() public { + // The test commitment has been created in the Bolt sidecar using the Rust + // methods to compute the digest() and recover the signer from the signature. + IBoltChallenger.SignedCommitment memory commitment = _parseTestCommitment(); + + // Reconstruct the commitment digest: `keccak( keccak(signed tx) || le_bytes(slot) )` + bytes32 commitmentID = _computeCommitmentID(commitment.signedTx, commitment.slot); + + assertEq(commitmentID, 0x52ecc7832625c3d107aaba5b55d4509b48cd9f4f7ce375d6696d09bbf3310525); + assertEq(commitment.signature.length, 65); + + // Verify the commitment signature against the digest + vm.resumeGasMetering(); + address commitmentSigner = ECDSA.recover(commitmentID, commitment.signature); + assertEq(commitmentSigner, 0x27083ED52464625660f3e30Aa5B9C20A30D7E110); + vm.pauseGasMetering(); + } + + function testCommitmentSignature() public { + bytes memory signedTx = vm.parseJsonBytes(vm.readFile("./test/testdata/signed_tx_20785012_1.json"), ".raw"); + uint64 slot = 20_728_344; + + // Reconstruct the commitment digest + bytes32 commitmentID = _computeCommitmentID(signedTx, slot); + + // Sign the commitment digest with the target + (uint8 v, bytes32 r, bytes32 s) = vm.sign(targetPK, commitmentID); + bytes memory commitmentSignature = abi.encodePacked(r, s, v); + + // Verify the commitment signature against the digest + vm.resumeGasMetering(); + address commitmentSigner = ECDSA.recover(commitmentID, commitmentSignature); + assertEq(commitmentSigner, target); + vm.pauseGasMetering(); + } + + // =========== Opening a challenge =========== + + function testOpenChallengeSingleTx() public { + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _parseTestCommitment(); + + assertEq(challenger.balance, 100 ether); + + // Open a challenge with the commitment + vm.resumeGasMetering(); + vm.prank(challenger); + boltChallenger.openChallenge{value: 1 ether}(commitments); + vm.pauseGasMetering(); + + assertEq(challenger.balance, 99 ether); + + // Check the challenge was opened + IBoltChallenger.Challenge[] memory challenges = boltChallenger.getAllChallenges(); + assertEq(challenges.length, 1); + + IBoltChallenger.Challenge memory challenge = challenges[0]; + assertEq(challenge.openedAt, block.timestamp); + assertEq(uint256(challenge.status), 0); + assertEq(challenge.challenger, challenger); + assertEq(challenge.commitmentSigner, 0x27083ED52464625660f3e30Aa5B9C20A30D7E110); + assertEq(challenge.targetSlot, commitments[0].slot); + } + + function testOpenChallengeWithIncorrectBond() public { + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _parseTestCommitment(); + + // Open a challenge with insufficient bond + vm.resumeGasMetering(); + vm.prank(challenger); + vm.expectRevert(IBoltChallenger.IncorrectChallengeBond.selector); + boltChallenger.openChallenge{value: 0.1 ether}(commitments); + vm.pauseGasMetering(); + } + + function testOpenChallengeWithLargebond() public { + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _parseTestCommitment(); + + // Open a challenge with a large bond, making sure that the rest is refunded + vm.resumeGasMetering(); + vm.prank(challenger); + vm.expectRevert(IBoltChallenger.IncorrectChallengeBond.selector); + boltChallenger.openChallenge{value: 50 ether}(commitments); + vm.pauseGasMetering(); + + assertEq(challenger.balance, 100 ether); + } + + function testOpenAlreadyExistingChallenge() public { + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _parseTestCommitment(); + + // Open a challenge + vm.prank(challenger); + boltChallenger.openChallenge{value: 1 ether}(commitments); + + // Try to open the same challenge again + vm.resumeGasMetering(); + vm.prank(challenger); + vm.expectRevert(IBoltChallenger.ChallengeAlreadyExists.selector); + boltChallenger.openChallenge{value: 1 ether}(commitments); + vm.pauseGasMetering(); + } + + function testOpenChallengeWithSlotInTheFuture() public { + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _parseTestCommitment(); + + commitments[0].slot = uint64(BeaconChainUtils._getCurrentSlot()) + 10; + + // Open a challenge with a slot in the future + vm.resumeGasMetering(); + vm.prank(challenger); + vm.expectRevert(IBoltChallenger.BlockIsNotFinalized.selector); + boltChallenger.openChallenge{value: 1 ether}(commitments); + vm.pauseGasMetering(); + } + + function testOpenChallengeInvalidSignature() public { + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _parseTestCommitment(); + + // Modify the signature to make it invalid + commitments[0].signature[0] = bytes1(uint8(commitments[0].signature[0]) + 5); + + // Open a challenge with an invalid signature + vm.resumeGasMetering(); + vm.prank(challenger); + vm.expectRevert(ECDSA.ECDSAInvalidSignature.selector); + boltChallenger.openChallenge{value: 1 ether}(commitments); + vm.pauseGasMetering(); + } + + // =========== Resolving a challenge =========== + + function testResolveChallengeFullDefenseSingleTx() public { + // Prove the full defense of a challenge: the block headers, account proof, and tx proofs + // are all valid and the proposer has included the transaction in their slot. + + uint256 inclusionBlockNumber = 20_785_012; + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _createRecentBoltCommitment(inclusionBlockNumber, 1); + + // Open a challenge + vm.prank(challenger); + boltChallenger.openChallenge{value: 1 ether}(commitments); + + // Get the challenge ID + IBoltChallenger.Challenge[] memory challenges = boltChallenger.getAllChallenges(); + assertEq(challenges.length, 1); + bytes32 challengeID = challenges[0].id; + + string memory rawPreviousHeader = vm.readFile("./test/testdata/header_20785011.json"); + string memory rawInclusionHeader = vm.readFile("./test/testdata/header_20785012.json"); + string memory ethProof = vm.readFile("./test/testdata/eth_proof_20785011.json"); + string memory txProof = vm.readFile("./test/testdata/tx_mpt_proof_20785012.json"); + + bytes[] memory txProofs = new bytes[](1); + txProofs[0] = _RLPEncodeList(vm.parseJsonBytesArray(txProof, ".proof")); + + uint256[] memory txIndexesInBlock = new uint256[](1); + txIndexesInBlock[0] = vm.parseJsonUint(txProof, ".index"); + + IBoltChallenger.Proof memory proof = IBoltChallenger.Proof({ + inclusionBlockNumber: inclusionBlockNumber, + previousBlockHeaderRLP: vm.parseJsonBytes(rawPreviousHeader, ".result"), + inclusionBlockHeaderRLP: vm.parseJsonBytes(rawInclusionHeader, ".result"), + accountMerkleProof: _RLPEncodeList(vm.parseJsonBytesArray(ethProof, ".result.accountProof")), + txMerkleProofs: txProofs, + txIndexesInBlock: txIndexesInBlock + }); + + // check that the inclusion block transactions root matches the root in the tx proof data. + bytes32 inclusionTxRoot = boltChallenger._decodeBlockHeaderRLPExt(proof.inclusionBlockHeaderRLP).txRoot; + assertEq(inclusionTxRoot, vm.parseJsonBytes32(txProof, ".root")); + + bytes32 trustedPreviousBlockHash = 0x6be050fe1f6c7ffe8f30a350250a9ecc08ff3c031d129f65e1c10e5119d7a28b; + + // Resolve the challenge + vm.resumeGasMetering(); + vm.prank(resolver); + vm.expectEmit(); + + emit IBoltChallenger.ChallengeDefended(challengeID); + boltChallenger._resolveExt(challengeID, trustedPreviousBlockHash, proof); + } + + function testResolveChallengeFullDefenseStackedTxs() public { + // Prove the full defense of a challenge: the block headers, account proof, and tx proofs + // are all valid and the proposer has included the transaction in their slot. + // This time, the proposer has committed to multiple transactions in their slot. + // + // The test data for this test was generated by querying for an Ethereum block with a + // sender that has sent multiple transactions in the same block. + // Check out https://etherscan.io/block/20817618 + + uint256 inclusionBlockNumber = 20_817_618; + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](5); + commitments[0] = _createRecentBoltCommitment(inclusionBlockNumber, 1); + commitments[1] = _createRecentBoltCommitment(inclusionBlockNumber, 2); + commitments[2] = _createRecentBoltCommitment(inclusionBlockNumber, 3); + commitments[3] = _createRecentBoltCommitment(inclusionBlockNumber, 4); + commitments[4] = _createRecentBoltCommitment(inclusionBlockNumber, 5); + + // Sanity check senders of the transactions: they should all be the same + for (uint256 i = 0; i < commitments.length; i++) { + address recovered = commitments[i].signedTx.decodeEnveloped().recoverSender(); + assertEq(recovered, 0xc21fb45Eeb45D883B838E30ABBd2896aE5AC888c); + } + + // Sanity check signers of the commitments: they should all be the same + for (uint256 i = 0; i < commitments.length; i++) { + bytes32 cid = _computeCommitmentID(commitments[i].signedTx, commitments[i].slot); + address signer = ECDSA.recover(cid, commitments[i].signature); + assertEq(signer, target); + } + + // Open a challenge + vm.prank(challenger); + boltChallenger.openChallenge{value: 1 ether}(commitments); + + // Get the challenge ID + IBoltChallenger.Challenge[] memory challenges = boltChallenger.getAllChallenges(); + assertEq(challenges.length, 1); + bytes32 challengeID = challenges[0].id; + + // headers + string memory rawPreviousHeader = vm.readFile("./test/testdata/header_20817617.json"); + string memory rawInclusionHeader = vm.readFile("./test/testdata/header_20817618.json"); + + // account + string memory ethProof = vm.readFile("./test/testdata/eth_proof_20817617.json"); + + // transactions + string memory txProof1 = vm.readFile("./test/testdata/tx_mpt_proof_20817618_1.json"); + string memory txProof2 = vm.readFile("./test/testdata/tx_mpt_proof_20817618_2.json"); + string memory txProof3 = vm.readFile("./test/testdata/tx_mpt_proof_20817618_3.json"); + string memory txProof4 = vm.readFile("./test/testdata/tx_mpt_proof_20817618_4.json"); + string memory txProof5 = vm.readFile("./test/testdata/tx_mpt_proof_20817618_5.json"); + + bytes[] memory txProofs = new bytes[](5); + txProofs[0] = _RLPEncodeList(vm.parseJsonBytesArray(txProof1, ".proof")); + txProofs[1] = _RLPEncodeList(vm.parseJsonBytesArray(txProof2, ".proof")); + txProofs[2] = _RLPEncodeList(vm.parseJsonBytesArray(txProof3, ".proof")); + txProofs[3] = _RLPEncodeList(vm.parseJsonBytesArray(txProof4, ".proof")); + txProofs[4] = _RLPEncodeList(vm.parseJsonBytesArray(txProof5, ".proof")); + + uint256[] memory txIndexesInBlock = new uint256[](5); + txIndexesInBlock[0] = vm.parseJsonUint(txProof1, ".index"); + txIndexesInBlock[1] = vm.parseJsonUint(txProof2, ".index"); + txIndexesInBlock[2] = vm.parseJsonUint(txProof3, ".index"); + txIndexesInBlock[3] = vm.parseJsonUint(txProof4, ".index"); + txIndexesInBlock[4] = vm.parseJsonUint(txProof5, ".index"); + + IBoltChallenger.Proof memory proof = IBoltChallenger.Proof({ + inclusionBlockNumber: inclusionBlockNumber, + previousBlockHeaderRLP: vm.parseJsonBytes(rawPreviousHeader, ".result"), + inclusionBlockHeaderRLP: vm.parseJsonBytes(rawInclusionHeader, ".result"), + accountMerkleProof: _RLPEncodeList(vm.parseJsonBytesArray(ethProof, ".result.accountProof")), + txMerkleProofs: txProofs, + txIndexesInBlock: txIndexesInBlock + }); + + // check that the inclusion block transactions root matches the root in the tx proof data. + bytes32 inclusionTxRoot = boltChallenger._decodeBlockHeaderRLPExt(proof.inclusionBlockHeaderRLP).txRoot; + assertEq(inclusionTxRoot, vm.parseJsonBytes32(txProof1, ".root")); + + // block hash of https://etherscan.io/block/20817617 + bytes32 trustedPreviousBlockHash = 0xb410d12f92ed268b184c1e6523b7d3fea5fcd0ba3f9bc6c6cb9a7e5b1523d225; + + // Resolve the challenge + vm.resumeGasMetering(); + vm.prank(resolver); + + vm.expectEmit(); + emit IBoltChallenger.ChallengeDefended(challengeID); + + boltChallenger._resolveExt(challengeID, trustedPreviousBlockHash, proof); + } + + function testResolveExpiredChallenge() public { + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _parseTestCommitment(); + + // Open a challenge with the commitment + vm.resumeGasMetering(); + vm.prank(challenger); + boltChallenger.openChallenge{value: 1 ether}(commitments); + vm.pauseGasMetering(); + + // Check the challenge was opened + IBoltChallenger.Challenge[] memory challenges = boltChallenger.getAllChallenges(); + assertEq(challenges.length, 1); + + // Warp time to make the challenge expire + vm.warp(block.timestamp + 2 weeks); + + // Try to resolve the challenge + vm.prank(resolver); + + // Get the challenge + IBoltChallenger.Challenge memory challenge = boltChallenger.getAllChallenges()[0]; + + vm.expectEmit(); + emit IBoltChallenger.ChallengeBreached(challenge.id); + + boltChallenger.resolveExpiredChallenge(challenge.id); + } + + function testCannotResolveChallengeBeforeExpiration() public { + IBoltChallenger.SignedCommitment[] memory commitments = new IBoltChallenger.SignedCommitment[](1); + commitments[0] = _parseTestCommitment(); + + // Open a challenge with the commitment + vm.resumeGasMetering(); + vm.prank(challenger); + boltChallenger.openChallenge{value: 1 ether}(commitments); + vm.pauseGasMetering(); + + // Check the challenge was opened + IBoltChallenger.Challenge[] memory challenges = boltChallenger.getAllChallenges(); + assertEq(challenges.length, 1); + bytes32 id = challenges[0].id; + + // Try to resolve the challenge before it expires + vm.resumeGasMetering(); + vm.prank(resolver); + vm.expectRevert(IBoltChallenger.ChallengeNotExpired.selector); + boltChallenger.resolveExpiredChallenge(id); + vm.pauseGasMetering(); + } + + // =========== Helper functions =========== + + // Helper to create a test commitment with a recent slot, valid for a recent challenge + function _createRecentBoltCommitment( + uint256 blockNumber, + uint256 id + ) internal view returns (IBoltChallenger.SignedCommitment memory commitment) { + // pattern: ./test/testdata/signed_tx_{blockNumber}_{id}.json + string memory base = "./test/testdata/signed_tx_"; + string memory extension = string.concat(vm.toString(blockNumber), "_", vm.toString(id), ".json"); + string memory path = string.concat(base, extension); + commitment.signedTx = vm.parseJsonBytes(vm.readFile(path), ".raw"); + + // pick a recent slot, 100 slots behind the current slot + commitment.slot = uint64(BeaconChainUtils._getCurrentSlot() - 100); + + // sign the new commitment with the target's private key + bytes32 commitmentID = _computeCommitmentID(commitment.signedTx, commitment.slot); + (uint8 v, bytes32 r, bytes32 s) = vm.sign(targetPK, commitmentID); + commitment.signature = abi.encodePacked(r, s, v); + + // Normalize v to 27 or 28 + if (uint8(commitment.signature[64]) < 27) { + commitment.signature[64] = bytes1(uint8(commitment.signature[64]) + 0x1B); + } + + // Sanity check + assertEq(ECDSA.recover(commitmentID, commitment.signature), target); + + return commitment; + } + + // Helper to parse the test commitment from a file + function _parseTestCommitment() internal view returns (IBoltChallenger.SignedCommitment memory) { + string memory file = vm.readFile("./test/testdata/bolt_commitment.json"); + IBoltChallenger.SignedCommitment memory commitment = IBoltChallenger.SignedCommitment({ + slot: uint64(vm.parseJsonUint(file, ".slot")), + signature: vm.parseJsonBytes(file, ".signature"), + signedTx: vm.parseJsonBytes(file, ".tx") + }); + + // Normalize v to 27 or 28 + if (uint8(commitment.signature[64]) < 27) { + commitment.signature[64] = bytes1(uint8(commitment.signature[64]) + 0x1B); + } + + return commitment; + } + + // Helper to compute the commitment ID + function _computeCommitmentID(bytes memory signedTx, uint64 slot) internal pure returns (bytes32) { + return keccak256(abi.encodePacked(keccak256(signedTx), _toLittleEndian(slot))); + } + + // Helper to encode a list of bytes[] into an RLP list with each item RLP-encoded + function _RLPEncodeList( + bytes[] memory _items + ) internal pure returns (bytes memory) { + bytes[] memory encodedItems = new bytes[](_items.length); + for (uint256 i = 0; i < _items.length; i++) { + encodedItems[i] = RLPWriter.writeBytes(_items[i]); + } + return RLPWriter.writeList(encodedItems); + } + + // Helper to convert a u64 to a little-endian bytes + function _toLittleEndian( + uint64 x + ) internal pure returns (bytes memory) { + bytes memory b = new bytes(8); + for (uint256 i = 0; i < 8; i++) { + b[i] = bytes1(uint8(x >> (8 * i))); + } + return b; + } +} diff --git a/bolt-contracts/test/TransactionDecoder.t.sol b/bolt-contracts/test/TransactionDecoder.t.sol new file mode 100644 index 00000000..3f911f85 --- /dev/null +++ b/bolt-contracts/test/TransactionDecoder.t.sol @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: MIT +pragma solidity 0.8.25; + +import {Test, console} from "forge-std/Test.sol"; + +import {TransactionDecoder} from "../src/lib/TransactionDecoder.sol"; +import {BytesUtils} from "../src/lib/BytesUtils.sol"; + +// We use a contract to expose internal library functions +contract DecoderImpl { + function decodeEnveloped( + bytes memory raw + ) public pure returns (TransactionDecoder.Transaction memory) { + return TransactionDecoder.decodeEnveloped(raw); + } + + function preimage( + TransactionDecoder.Transaction memory transaction + ) public pure returns (bytes32) { + return TransactionDecoder.preimage(transaction); + } + + function signature( + TransactionDecoder.Transaction memory transaction + ) public pure returns (bytes memory) { + return TransactionDecoder.signature(transaction); + } +} + +contract TransactionDecoderTest is Test { + using TransactionDecoder for TransactionDecoder.Transaction; + + DecoderImpl decoder; + + struct TestCase { + string name; + uint256 privateKey; + bytes unsignedLegacy; + bytes unsignedEip155; + bytes unsignedBerlin; + bytes unsignedLondon; + bytes unsignedCancun; + bytes signedLegacy; + bytes signedEip155; + bytes signedBerlin; + bytes signedLondon; + bytes signedCancun; + TransactionDecoder.Transaction transaction; + } + + function setUp() public { + vm.pauseGasMetering(); + decoder = new DecoderImpl(); + } + + function testDecodeAllTestCases() public { + uint256 i = 0; + while (true) { + string memory path = _getTestCasePath(i); + if (!vm.isFile(path)) break; + + // Cycle through all test cases and run them one by one + _decodeTestCase(i); + i++; + } + } + + function testDecodeGasUsage() public { + // Decode a single transaction to measure gas usage + bytes memory encoded = _readTestCase(0).signedLondon; + + vm.resumeGasMetering(); + decoder.decodeEnveloped(encoded); + vm.pauseGasMetering(); + } + + function _decodeTestCase( + uint256 id + ) internal view { + TestCase memory testCase = _readTestCase(id); + + // Type 0 pre eip-155 (with chainId = 0) + TransactionDecoder.Transaction memory decodedSignedLegacy = decoder.decodeEnveloped(testCase.signedLegacy); + _assertTransaction(TransactionDecoder.TxType.Legacy, decodedSignedLegacy, testCase.transaction, false); + assertEq(decodedSignedLegacy.unsigned(), testCase.unsignedLegacy); + assertEq(decodedSignedLegacy.recoverSender(), vm.addr(testCase.privateKey)); + + // Type 0 post eip-155 (with optional legacy chainId) + TransactionDecoder.Transaction memory decodedSignedEip155 = decoder.decodeEnveloped(testCase.signedEip155); + _assertTransaction(TransactionDecoder.TxType.Legacy, decodedSignedEip155, testCase.transaction, true); + assertEq(decodedSignedEip155.unsigned(), testCase.unsignedEip155); + assertEq(decodedSignedEip155.recoverSender(), vm.addr(testCase.privateKey)); + + // Type 1 with optional access list + TransactionDecoder.Transaction memory decodedSignedBerlin = decoder.decodeEnveloped(testCase.signedBerlin); + _assertTransaction(TransactionDecoder.TxType.Eip2930, decodedSignedBerlin, testCase.transaction, true); + assertEq(decodedSignedBerlin.unsigned(), testCase.unsignedBerlin); + assertEq(decodedSignedBerlin.recoverSender(), vm.addr(testCase.privateKey)); + + // Type 2 with fee market fields + TransactionDecoder.Transaction memory decodedSignedLondon = decoder.decodeEnveloped(testCase.signedLondon); + _assertTransaction(TransactionDecoder.TxType.Eip1559, decodedSignedLondon, testCase.transaction, true); + assertEq(decodedSignedLondon.unsigned(), testCase.unsignedLondon); + assertEq(decodedSignedLondon.recoverSender(), vm.addr(testCase.privateKey)); + + // Type 3 with blob fields + TransactionDecoder.Transaction memory decodedSignedCancun = decoder.decodeEnveloped(testCase.signedCancun); + _assertTransaction(TransactionDecoder.TxType.Eip4844, decodedSignedCancun, testCase.transaction, true); + assertEq(decodedSignedCancun.unsigned(), testCase.unsignedCancun); + assertEq(decodedSignedCancun.recoverSender(), vm.addr(testCase.privateKey)); + } + + // Helper to get the path of a test case file based on its index + function _getTestCasePath( + uint256 id + ) internal pure returns (string memory) { + // Location of the test cases on disk (relative to the project root) + // Example: ./test/testdata/transactions/random_10.json + return string.concat("./test/testdata/transactions/random_", vm.toString(id), ".json"); + } + + function _assertTransaction( + TransactionDecoder.TxType txType, + TransactionDecoder.Transaction memory decoded, + TransactionDecoder.Transaction memory expected, + bool isEip155 + ) internal pure { + assertEq(uint8(decoded.txType), uint8(txType)); + + if (!isEip155) { + // Pre-EIP-155 transactions have a chainId of 0 + assertEq(decoded.chainId, 0); + } else { + assertEq(decoded.chainId, expected.chainId); + } + + assertEq(decoded.data, expected.data); + assertEq(decoded.gasLimit, expected.gasLimit); + assertEq(decoded.nonce, expected.nonce); + assertEq(decoded.to, expected.to); + assertEq(decoded.value, expected.value); + + if (uint8(txType) < 2) { + assertEq(decoded.gasPrice, expected.gasPrice); + } + + if (uint8(txType) >= 1) { + // We keep access lists as opaque bytes for now, because we simply re-encode + // them to obtain the unsigned transaction. So we can't compare them directly. + // assertEq(decoded.accessList, expected.accessList); + } + + if (uint8(txType) >= 2) { + assertEq(decoded.maxFeePerGas, expected.maxFeePerGas); + assertEq(decoded.maxPriorityFeePerGas, expected.maxPriorityFeePerGas); + } + + if (uint8(txType) == 3) { + assertEq(decoded.maxFeePerBlobGas, expected.maxFeePerBlobGas); + assertEq(decoded.blobVersionedHashes.length, expected.blobVersionedHashes.length); + for (uint256 i = 0; i < decoded.blobVersionedHashes.length; i++) { + assertEq(decoded.blobVersionedHashes[i], expected.blobVersionedHashes[i]); + } + } + } + + function _readTestCase( + uint256 id + ) public view returns (TestCase memory) { + string memory file = vm.readFile(_getTestCasePath(id)); + + TransactionDecoder.Transaction memory transaction = TransactionDecoder.Transaction({ + chainId: uint64(_parseUintFromBytes(vm.parseJsonBytes(file, ".transaction.chainId"))), + data: vm.parseJsonBytes(file, ".transaction.data"), + gasLimit: _parseUintFromBytes(vm.parseJsonBytes(file, ".transaction.gasLimit")), + gasPrice: _parseUintFromBytes(vm.parseJsonBytes(file, ".transaction.gasPrice")), + maxFeePerGas: _parseUintFromBytes(vm.parseJsonBytes(file, ".transaction.maxFeePerGas")), + maxPriorityFeePerGas: _parseUintFromBytes(vm.parseJsonBytes(file, ".transaction.maxPriorityFeePerGas")), + nonce: vm.parseJsonUint(file, ".transaction.nonce"), + to: vm.parseJsonAddress(file, ".transaction.to"), + value: _parseUintFromBytes(vm.parseJsonBytes(file, ".transaction.value")), + maxFeePerBlobGas: _parseUintFromBytes(vm.parseJsonBytes(file, ".transaction.maxFeePerBlobGas")), + blobVersionedHashes: vm.parseJsonBytes32Array(file, ".transaction.blobVersionedHashes"), + // Note: These fields aren't present in the test cases so they can be skipped. + // These are tested indirectly by the signature and preimage checks. + txType: TransactionDecoder.TxType.Legacy, + accessList: new bytes[](0), + // Signature is checked by recovering the sender and comparing it to the pubkey + // derived from the private key in the test case. + sig: "", + // Note: these fields are just internal helpers for the decoder library. + legacyV: 0, + isChainIdSet: false + }); + + return TestCase({ + name: vm.parseJsonString(file, ".name"), + privateKey: uint256(vm.parseJsonBytes32(file, ".privateKey")), + unsignedLegacy: vm.parseJsonBytes(file, ".unsignedLegacy"), + unsignedEip155: vm.parseJsonBytes(file, ".unsignedEip155"), + unsignedBerlin: vm.parseJsonBytes(file, ".unsignedBerlin"), + unsignedLondon: vm.parseJsonBytes(file, ".unsignedLondon"), + unsignedCancun: vm.parseJsonBytes(file, ".unsignedCancun"), + signedLegacy: vm.parseJsonBytes(file, ".signedLegacy"), + signedEip155: vm.parseJsonBytes(file, ".signedEip155"), + signedBerlin: vm.parseJsonBytes(file, ".signedBerlin"), + signedLondon: vm.parseJsonBytes(file, ".signedLondon"), + signedCancun: vm.parseJsonBytes(file, ".signedCancun"), + transaction: transaction + }); + } + + // Helper to parse an uint from bytes padded to the left + function _parseUintFromBytes( + bytes memory data + ) internal pure returns (uint256) { + return uint256(BytesUtils.toBytes32PadLeft(data)); + } + + function _parseOpaqueAccessList( + bytes memory data + ) internal pure returns (bytes[] memory) {} +} diff --git a/bolt-contracts/test/testdata/bolt_commitment.json b/bolt-contracts/test/testdata/bolt_commitment.json new file mode 100644 index 00000000..596ee674 --- /dev/null +++ b/bolt-contracts/test/testdata/bolt_commitment.json @@ -0,0 +1,5 @@ +{ + "slot": 633067, + "signature": "0xcdd20b2abbd8cdfb77ec2608e1227f8ce0f66133b9d0ec0ea68102c2152b82193e3be0d6967b7c20b83e1a2530daa3a07713556541dc2aa16a46d922e6145a2b01", + "tx": "0xf86b82016e84042343e0830f424094deaddeaddeaddeaddeaddeaddeaddeaddeaddead0780850344281a21a0e525fc31b5574722ff064bdd127c4441b0fc66de7dc44928e163cb68e9d807e5a00b3ec02fc1e34b0209f252369ad10b745cd5a51c88384a340f7a150d0e45e471" +} diff --git a/bolt-contracts/test/testdata/eth_proof_20785011.json b/bolt-contracts/test/testdata/eth_proof_20785011.json new file mode 100644 index 00000000..bb504555 --- /dev/null +++ b/bolt-contracts/test/testdata/eth_proof_20785011.json @@ -0,0 +1,22 @@ +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "address": "0x0d9f5045b604ba0c050b5eb06d0b25d01c525ea5", + "accountProof": [ + "0xf90211a06c5341556789e53964fe2a77e0bf2b540f9c9aef92d508eedbe496183c5fb0d4a088d9fcfc0d596047f887fe0b6e76a22833ed33d90e475a97515c135afc1a358ca0a2d140e4eb080e7154ab4732922dc09ba5e6f7bb66ca085cce4a33a2485cefb3a01550fc55f997ebd8ff3194813c0a83668219d5aab1adea1e4aa8416ed5e086c2a04ce40dbcc710d91c6583912c4bd9e9980998ef0399346a7d488d4807153ffb7fa0a4aed92a1d67dbd794e18c588b0bf690373517a96d1c2028337a17bdb1955522a08a352007fbbbb15880b3ab7f3732a2f0f35513ec3704a97a1c0d6958a855182fa0ab93816f2baef5e33eda09193295d14a76b68ab71b264bbc145f7bbcbab6de44a08c22010d9488cebd377914768e0f105e4468d86843fc8dbe3f0026ea81ea4428a02748a9e18e6560d907ed69f7313239ab489c443e8517a6da153126c1b1f4295ea07e3eac4ab2437783df515ea778b89489991230aa14724147af45cc36027773eda046487f3e599ab8a8d627425936e9490e26c0242526ac83caa777390783efa078a0b9bac1565b8e64fe494b62be9eaf5ba81cfbb477532b5425cb85cc19cdb664f4a024eb0480fbad22741077e53fd0e209b80f721058e000bec1c67904f0a419dc68a09bba4884ab92553333120f0548bc347db14eeb098a903e533b41940a8b3c48d5a0f400d123b1957c29ce7dcab8ffd18a0da9bf7d754c544452391334b05831707280", + "0xf90211a05b4f1080ce2ddb2a07b1093f8248df994bf78d2e0902def84faa02d3e8b4932ba0c75ea41d0704a50f6ef436fede8ff700a2d3c0edbf5c7066f2e7e2346a1b6b15a0a99a258a63cda78ff4fcb4bcdcef99e8f8f125da55ecaba58034408a3c10c03ba08d6ede7b83392f11041c9e9b6403162ddfe0a87de3a26c903b819d81c5d1d68fa09c33fbdc36ea41febe74608a116bd1a6118f9c2a8802d307525e35b31062ed56a0dfd19dec7ac4c6e74eb81bbfe2e9af6dfdb6b8c131f419dcea0bebfba80c4129a06d302c5ad7c218e7772a6fdd426b07ee6a151529f2993e07fa3fe728e03a1016a010184894262fd8c80d8596760e68e39bbe17864fca10d5caf0803c3f9c77ecf1a02c01f8486b37c883b0169b3593a28b70881b03fc4887048a318feb5141140a3da0ecb89cd38ba3499731c19946c2e108cb2977824058bcda585cca702cb231fbada0218c4bba8f633a0c22aa2fe39cae6fc0ddc83c471099709055c4b3953de34685a008948be35bc1607efce7877f13f1cde290b3ec45e026a180d058fe90a314034ca087d839d5da8e87d3fc45f782e128243a4a555b3850ea790f084d2cfc2d775b3da02d09a195dae74c1075bfd63342af74ff5fe4cb6777fc1cc44ea03ab258ba3e43a0219c2f1156d413196b274acb0234c2fcb41ed66aecd1e5011ad83da73b047ce7a090be7be27cf1be666f7835cd80feecb0904d50403adabb86ad1fae00a8cb29da80", + "0xf90211a0a85deaca1adffdb7713b02a33af6ec05b09237d060963af84d7dc1a269178845a0cfd70f233bd4eb4ac42209a0578808f9e24498297af9a3e902233c1839a3a3cda0d6975a90005a1966ddae9b0f978161fb032ea2ca2d8db2453fc6be2710d48388a0d33abb2b6de28462b483a584224b30c079986bed9599023f28c81db7ee324b29a054911488c612caf55eaa494f0cc84ba25485ee49ce40f49b434098951036517da0cc4c54ed2de6d2b8fcc3bcc6d1fc490e8d26e24d4ca1ff3d81c7492fa23e4c3ba06249e67a29f9ed1713043324faf5b666d790977fad710f1a0a9e660ccb48c97da0ed8f59ba4a2766bb4035cc489fbe5f34795c2c36e16bd2d00b7b08a5a6f42507a0d2d4d82c9452c5b78a807c5da31db61357c211c84e90bdb983940f344a9984e3a05c2e1286d8a66758e1c1fcb3c85f28791f95ee85615a39c1d6780f6a54e1b3a6a0ae4bf704ff1b38570d255bb7c2b2917a54b025e6e8185929b4d977f453a8d9e8a0ac9228bf16f7c15155965d5eb5d7aa2e2f31e8f937d52a7203abef348b843632a0a193e1b44b2441cbed3d8cd20862d7f11b0121b957a82d63168b67809dbaf3b2a09aba1e3d0feb612998294bd3645247790107e619bf8728819fbe463fec342f5ca09336f5d7c3d7ddb6e987ac5f7c0e78e3936e05f6da27a7c87813a6e5250e9c38a021c230f247db23bd8d948d68a24891afd58c29864f1d74551060c10067e386a380", + "0xf90211a09d93666285cfbada2d91c81fb96b5e30ff75a51353c69a30c0a1431f51867880a05efd44e1b30767c66f02d79e93b2c45efcd56018050605c08818645ddb7a46c5a05e5bdbdd63d64f58a34f47a42d70b83febf924c08cdfa8d5673db3c6bd71df67a05d67553cf6620c67dead6ee37a48a5dfddddd4adce333c4a7771c25140ecdd92a07d5eb9550d7f807d7e0dd86a52f3d111b4359ac2928ca3e07c34bd6551055537a0fc0e43113716fdd77ec45220d5afcc0953d8357478872de3c6f36fc2d75c9610a03230ce2ec5fa8173fca250ac63df602e3a6d2bff691edc8552ab8bdea458bf07a01e7ad54a56fcd625d6066ec05b6efc30bf90a65b756277f79a65ceb0eb108a32a0089ff36bd32acfeef1b5faf546e54ac7646086d1c2c764239cc9b98da8c460e7a00905f00f493594ce1c13274c2bb5ad018fab388de860f1cae6af64cb3ad3b46fa0ad7d4f9200d8f0ae34bf0cbece04d61b13c6daa0b7ea0e9d732522c5d46feacda075da3fc2991d7d32cb0be70210c7cbe3bd5883cfc52f58e8e04d07b9977f816fa0c7bc6aab1b71efc9ffc459cfda04d930f1652d53179a38b43f8e0980b40ab48ca0ae012ca5c6a3363d5f850e060001c90cd3a022aa44e325d5d832021ebef4fafea06ee58a40e8abba2a3be093fdefd9d9871558f4fa11f6d6721307117a17260b51a07cc44d713e05b70e6749fedd7cb1b4b47d2102638bf93ffd0e8ebf404af6940080", + "0xf90211a0b1689af6f7f511cc59773684cb467f33c3dcc5dc1a08f451c851544dca6b1a3aa039a80eb019a427f8b32dfdd88a0b5d95a21521444c67fca8f1e875f1898e16c4a06652a79c42cf0d23532b84d47d58b6c898076d88147030581ff121d25407e25ba0cd2b62c08885a27becfd0077ccdfdd5d77d4cdc5a0ab1ec2ad1303c93a9aae3ba0333e03e837b7838cc45d8f30b17ec09933b77debdfceea6cc31033c34cb25b88a025c683f0ff00593e3b96caa6a45153e1907e263c2815064492ea29d2ae467d16a0b1f927c724f5f7425c5d47ff064d099a13982ddb528ac5526829ffefb2502c91a086a4177c69624728a862d160c303dda7010e4d317f60b2945a517f2b8cfe71f5a0436081588c2e0ceec3e3b2298c97085410d971d8da9eedcdc48e62fdbd125a2ba02f24c969da88b0cfe6318383edf10cbf2174c883ecd007d6bb79562663723099a0a9cbc30a1d257e3b651b3c304be3c253948c373f6980b22898af778ef9955b0fa0a343404514e213b6e5832f4621e6a6b1f0eb977811d759f06b7ad6da445092fba02eeb6ec27797e59283781b12f56e315f35b16395560a9c34bdd21280e942cfe1a0c874d2114c306baf91f0d43c2c76e30a6ad0da45273fb6d82246565d84c2538ea071a72e0b7d80490d26f95d3714cf8dd0c8b3c7b232980607aee525a9162e6308a04b4d1cf635eab18bbbb9e64109b0d992d759df23a96aab3d4a40e39a7c3becba80", + "0xf90211a023c9514b2fac99cd172f93d2db4d6578ec69fc2e0ef5c79fc76499ded09130eda00c645327db795a8a9c69282d86e3acece2901bdbb8047528ee8c78681b0e14b1a01e76e1109e1936249fdf08a4f583f91c01c6a4672794657bd74cbdd6ab3c2f3aa0a6b7b10c53412201d9ca7461b7210d6457a6b275b95033e2d8ca9778e5071c05a03e6f50fedb2b9f9f963356fc2899800e46a38169a794a1e6906c02ce8e8f0d59a0d4cec6a796cbab7e9cb28063423fcf157bac02de0cf1f0931303a701006019a2a0fb7e5187937b4203cf97bce2f345c9161bfbb9eb431a105356009e6ce18a1fbca0486a40cde9b6a65b5534609ae4f56cc97c00dbc4c4447385f8a42da3b1ac40d3a01c91aad4f4d391df268007fee771caedccc43369e07d6eb22fd45dab6beb0986a0672ca6ccfd8ac83f8974afefc9c9c2b58376991580158b16fd98cb9076cf8ea9a06cb3234503ad7116bb0e66257c646b2bce7603d774474a4f100cf93dde3eb594a085d0406435a6562f3370dd4b5de47a2b7d1084b9f25f0dbf49f54d2f46a2fc32a08bba9249e073397de4c46dd27688e9467b20fb8e61e04fd2594136cae26cd5c7a0a43fd38e14c38b64b84bb579b9a3cfab05cd5cc69c3a812a68e458acf72ea96ca0d848b40a2dbd5d8a4179e89fe8533f21db91982a0b8ecc1542c08ea27aec522aa0e03bc889898881f7ecb7caf0db5fb95125e26ff9e26bb85c33cbe360b50c9f1f80", + "0xf90191a017e9f741d070bfe3d975719f75663dabd5acdeb3678c50bd4872b817d7713d0b80a073811d2e7576e6bdac9804597d153d4e0a4cbf8400b8331f67605f6810ecbd53a0363162c748099d6ed114ead87c481972c1b0c124730b341c4ef1f963e0835a9880a09ef90c2a9ad234a08cbf4ea4ced535f227bc48becd22c1b05f2cbd586f018b73a0ae59576b0c1089b2828db7e54602ad0fabe4eff312ee5e0c21a04ac09b0e04d180a0fdbde0b4dbc02bb2ec472517c6f543de3673d33a6246a602479b43042ae9222da0c8d33ec13b89d8fd0ba487fe9cd61d18deff49bed48dc073384dc086a7361273a021253bb1110de615cede8c708a94cd6b898a61b5b1aaef8760b3341f232d63f0a06e7fbd4a6404e4acae007bb6147c58aebf6f19b3914a8d48b831bc3e50e5c05ea0c72d502ed522a796f823edefb721e64ff9d38904c9913b5be76f1e759c899b9da0fcc3a12a432daa29cb33f4a198624f6391124579ab7cbfae1eb30de076cfdd7980a0ab5019c60fef28581a93f0707739bbb24dcfbc2ffc550fb57aea59d91c79c04780", + "0xf86f9d3a1698215d94a53d304dacf1ae39aec65065a3307b0d96cd2acd29de94b84ff84d81eb88033ee43ef5fd164da056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" + ], + "balance": "0x33ee43ef5fd164d", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "nonce": "0xeb", + "storageHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "storageProof": [] + } +} diff --git a/bolt-contracts/test/testdata/eth_proof_20785012.json b/bolt-contracts/test/testdata/eth_proof_20785012.json new file mode 100644 index 00000000..25d98aa9 --- /dev/null +++ b/bolt-contracts/test/testdata/eth_proof_20785012.json @@ -0,0 +1,22 @@ +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "address": "0x0d9f5045b604ba0c050b5eb06d0b25d01c525ea5", + "accountProof": [ + "0xf90211a097ed06a390ed9c16ec9299e19125791653b9201b784bf9a42d84e0974b664cb3a0f3a9aa3a6f2cdc6b910d4734c0c8fec4b3bd8a676c711eb0c533295a68ce43bfa01f7ed42296ea93615febab61c43d9cc467789f55851549452858136b9efe9e42a077b8504dbe1ba2d05802efbaa36630fa5b10558c6a13de736375997b5e14c9a2a08ea3f8e0bdb950843d81846528ee71d6eca46c9a273528843aea374b5c355ccca0eeaab1a08eb462bb3efe98d852fbea54769095de57beb60de9c8c72331304401a0cd3c794240e0de405bfee95babf6f505979983a37f79590be3b862e53f960807a04dd46005f5c29ebfb69815f918853bcff3af08a2f9c3b3493033fc0dc0a773eca005ca774fdb64b89b25f07f7e960fdfc9b4149ca9c6e7751fcb55824f04eb3ff3a021c51f7e644285567f75772792cb66c39f34f0509a50af2da12af26cf1ac9b10a072ccec3415e7904da03a2bf677708cdcd8d1d29b59c9c0e408ee8608fe3b3823a010d8c53e6bf134e70476d64f41cf8d1e219aece6c969809225a269027eee6a6ca06effeb1ca18e2254df42d2d0cd42825178409d6b210127a0a6c07fc95680dcdfa01c1b854f1606365826b1153586d98342ecacdf0acebe933a00256fdee7af5a59a0306fb9c170aa24d20350f7277392adb78557f48ecb62b3d6cf23698988eac284a0daaa352a43bdd737c9524a8cb3a98802ae5185e3b71eb865c71473540edb7ef280", + "0xf90211a03550162fce21c8be10d224e61acebee31945d54a9d576f11758526190e5bf987a0c75ea41d0704a50f6ef436fede8ff700a2d3c0edbf5c7066f2e7e2346a1b6b15a0a99a258a63cda78ff4fcb4bcdcef99e8f8f125da55ecaba58034408a3c10c03ba028b51ffb8812262e563d86724920a7b7b8d13573ccc747e01b4cc5db45b9c2e9a0ec8f2eab33b3c5a1f2e6c1dc8984299f07a5be7f41cc82e103ec8b5aca0a9e90a0b57d1ae6538304a97d74f19dcf5b5999ce74a8b3818e4f1ba6f2a55c7d3933aca06d302c5ad7c218e7772a6fdd426b07ee6a151529f2993e07fa3fe728e03a1016a010184894262fd8c80d8596760e68e39bbe17864fca10d5caf0803c3f9c77ecf1a04a2fa9ae91770be3477bd857ca876b629e8d74f15b36a2545c888d17396bff0fa0ae4da4e3330f57b5f57956e648c7c7385a5a5d366b0463ddb0add15e47c588f6a0bfcd3d5bf7b55f88d34e1f6d7760bf18b3547ae2004a05db706c6d6d41d2ce0da07d9caa8bb424afe94efc92b3f2207b480231c6a46bd2c6e67e33b8335eabe14fa0c05d5e0666734ea57d97a9ea74f16698b05db5282f973fb6f3f5f3de1c2b458ca0ac81cc5c382467c74df9f355e220cabdba514a01b59ba5779639611e87b88b8da0219c2f1156d413196b274acb0234c2fcb41ed66aecd1e5011ad83da73b047ce7a090be7be27cf1be666f7835cd80feecb0904d50403adabb86ad1fae00a8cb29da80", + "0xf90211a0a85deaca1adffdb7713b02a33af6ec05b09237d060963af84d7dc1a269178845a0cfd70f233bd4eb4ac42209a0578808f9e24498297af9a3e902233c1839a3a3cda0d6975a90005a1966ddae9b0f978161fb032ea2ca2d8db2453fc6be2710d48388a0d33abb2b6de28462b483a584224b30c079986bed9599023f28c81db7ee324b29a054911488c612caf55eaa494f0cc84ba25485ee49ce40f49b434098951036517da0cc4c54ed2de6d2b8fcc3bcc6d1fc490e8d26e24d4ca1ff3d81c7492fa23e4c3ba06249e67a29f9ed1713043324faf5b666d790977fad710f1a0a9e660ccb48c97da0ed8f59ba4a2766bb4035cc489fbe5f34795c2c36e16bd2d00b7b08a5a6f42507a0e2caaa014febfa0bdc9179bf519a963a05e36c634ce616c744ae2bd0b48824c0a05c2e1286d8a66758e1c1fcb3c85f28791f95ee85615a39c1d6780f6a54e1b3a6a05fe7bca3ef5fb8a2c8be1b987976a40c0345cf92e5117b3898159e4ed5ada800a0ac9228bf16f7c15155965d5eb5d7aa2e2f31e8f937d52a7203abef348b843632a0a193e1b44b2441cbed3d8cd20862d7f11b0121b957a82d63168b67809dbaf3b2a09aba1e3d0feb612998294bd3645247790107e619bf8728819fbe463fec342f5ca09336f5d7c3d7ddb6e987ac5f7c0e78e3936e05f6da27a7c87813a6e5250e9c38a021c230f247db23bd8d948d68a24891afd58c29864f1d74551060c10067e386a380", + "0xf90211a09d93666285cfbada2d91c81fb96b5e30ff75a51353c69a30c0a1431f51867880a05efd44e1b30767c66f02d79e93b2c45efcd56018050605c08818645ddb7a46c5a05e5bdbdd63d64f58a34f47a42d70b83febf924c08cdfa8d5673db3c6bd71df67a05d67553cf6620c67dead6ee37a48a5dfddddd4adce333c4a7771c25140ecdd92a07d5eb9550d7f807d7e0dd86a52f3d111b4359ac2928ca3e07c34bd6551055537a0faba45751c6566255746b31a67d0cd73163a115d0aca516c0625668a20439846a03230ce2ec5fa8173fca250ac63df602e3a6d2bff691edc8552ab8bdea458bf07a01e7ad54a56fcd625d6066ec05b6efc30bf90a65b756277f79a65ceb0eb108a32a0089ff36bd32acfeef1b5faf546e54ac7646086d1c2c764239cc9b98da8c460e7a00905f00f493594ce1c13274c2bb5ad018fab388de860f1cae6af64cb3ad3b46fa0ad7d4f9200d8f0ae34bf0cbece04d61b13c6daa0b7ea0e9d732522c5d46feacda075da3fc2991d7d32cb0be70210c7cbe3bd5883cfc52f58e8e04d07b9977f816fa0c7bc6aab1b71efc9ffc459cfda04d930f1652d53179a38b43f8e0980b40ab48ca0ae012ca5c6a3363d5f850e060001c90cd3a022aa44e325d5d832021ebef4fafea06ee58a40e8abba2a3be093fdefd9d9871558f4fa11f6d6721307117a17260b51a07cc44d713e05b70e6749fedd7cb1b4b47d2102638bf93ffd0e8ebf404af6940080", + "0xf90211a0b1689af6f7f511cc59773684cb467f33c3dcc5dc1a08f451c851544dca6b1a3aa039a80eb019a427f8b32dfdd88a0b5d95a21521444c67fca8f1e875f1898e16c4a06652a79c42cf0d23532b84d47d58b6c898076d88147030581ff121d25407e25ba0cd2b62c08885a27becfd0077ccdfdd5d77d4cdc5a0ab1ec2ad1303c93a9aae3ba0333e03e837b7838cc45d8f30b17ec09933b77debdfceea6cc31033c34cb25b88a025c683f0ff00593e3b96caa6a45153e1907e263c2815064492ea29d2ae467d16a0b1f927c724f5f7425c5d47ff064d099a13982ddb528ac5526829ffefb2502c91a0fa6b40da08a9bebf3b0b320e4895d4bee360047a7d48efb0f8a0a6e5fcdcb338a0436081588c2e0ceec3e3b2298c97085410d971d8da9eedcdc48e62fdbd125a2ba02f24c969da88b0cfe6318383edf10cbf2174c883ecd007d6bb79562663723099a0a9cbc30a1d257e3b651b3c304be3c253948c373f6980b22898af778ef9955b0fa0a343404514e213b6e5832f4621e6a6b1f0eb977811d759f06b7ad6da445092fba02eeb6ec27797e59283781b12f56e315f35b16395560a9c34bdd21280e942cfe1a0c874d2114c306baf91f0d43c2c76e30a6ad0da45273fb6d82246565d84c2538ea071a72e0b7d80490d26f95d3714cf8dd0c8b3c7b232980607aee525a9162e6308a04b4d1cf635eab18bbbb9e64109b0d992d759df23a96aab3d4a40e39a7c3becba80", + "0xf90211a023c9514b2fac99cd172f93d2db4d6578ec69fc2e0ef5c79fc76499ded09130eda00c645327db795a8a9c69282d86e3acece2901bdbb8047528ee8c78681b0e14b1a01e76e1109e1936249fdf08a4f583f91c01c6a4672794657bd74cbdd6ab3c2f3aa0a6b7b10c53412201d9ca7461b7210d6457a6b275b95033e2d8ca9778e5071c05a03e6f50fedb2b9f9f963356fc2899800e46a38169a794a1e6906c02ce8e8f0d59a0d4cec6a796cbab7e9cb28063423fcf157bac02de0cf1f0931303a701006019a2a0fb7e5187937b4203cf97bce2f345c9161bfbb9eb431a105356009e6ce18a1fbca02e63f3f119a82cedbf5e64e31aefeaa62892816846065c408c13f9bf9669d3d5a01c91aad4f4d391df268007fee771caedccc43369e07d6eb22fd45dab6beb0986a0672ca6ccfd8ac83f8974afefc9c9c2b58376991580158b16fd98cb9076cf8ea9a06cb3234503ad7116bb0e66257c646b2bce7603d774474a4f100cf93dde3eb594a085d0406435a6562f3370dd4b5de47a2b7d1084b9f25f0dbf49f54d2f46a2fc32a08bba9249e073397de4c46dd27688e9467b20fb8e61e04fd2594136cae26cd5c7a0a43fd38e14c38b64b84bb579b9a3cfab05cd5cc69c3a812a68e458acf72ea96ca0d848b40a2dbd5d8a4179e89fe8533f21db91982a0b8ecc1542c08ea27aec522aa0e03bc889898881f7ecb7caf0db5fb95125e26ff9e26bb85c33cbe360b50c9f1f80", + "0xf90191a017e9f741d070bfe3d975719f75663dabd5acdeb3678c50bd4872b817d7713d0b80a068f1f1d4e6b9697c43cffb6125e3bd1f4f10d57cb9dbd0938388fffd555a6457a0363162c748099d6ed114ead87c481972c1b0c124730b341c4ef1f963e0835a9880a09ef90c2a9ad234a08cbf4ea4ced535f227bc48becd22c1b05f2cbd586f018b73a0ae59576b0c1089b2828db7e54602ad0fabe4eff312ee5e0c21a04ac09b0e04d180a0fdbde0b4dbc02bb2ec472517c6f543de3673d33a6246a602479b43042ae9222da0c8d33ec13b89d8fd0ba487fe9cd61d18deff49bed48dc073384dc086a7361273a021253bb1110de615cede8c708a94cd6b898a61b5b1aaef8760b3341f232d63f0a06e7fbd4a6404e4acae007bb6147c58aebf6f19b3914a8d48b831bc3e50e5c05ea0c72d502ed522a796f823edefb721e64ff9d38904c9913b5be76f1e759c899b9da0fcc3a12a432daa29cb33f4a198624f6391124579ab7cbfae1eb30de076cfdd7980a0ab5019c60fef28581a93f0707739bbb24dcfbc2ffc550fb57aea59d91c79c04780", + "0xf86f9d3a1698215d94a53d304dacf1ae39aec65065a3307b0d96cd2acd29de94b84ff84d81ec8801e4e114d0153dada056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" + ], + "balance": "0x1e4e114d0153dad", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "nonce": "0xec", + "storageHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "storageProof": [] + } +} diff --git a/bolt-contracts/test/testdata/eth_proof_20817617.json b/bolt-contracts/test/testdata/eth_proof_20817617.json new file mode 100644 index 00000000..e3447e81 --- /dev/null +++ b/bolt-contracts/test/testdata/eth_proof_20817617.json @@ -0,0 +1,23 @@ +{ + "jsonrpc": "2.0", + "id": 1, + "result": { + "address": "0xc21fb45eeb45d883b838e30abbd2896ae5ac888c", + "accountProof": [ + "0xf90211a09d63f98f913479f3896c84699548d56e7664f7abd187f56544e9b5d8af62d06da09fb4628824ac085d2bd2b5b87ac98aac9fdfe06b8f539f4a811f9127546238fba0908dae3356ca023e940a75e59f9a43ce84aa64144017ec4bbf0c9ce32f8e211da0dead54c42fc1852cf7676bb06c3bf24e7e36a362892eedbb55a2099f46184840a053d3e971dc35dc1d221d50deaf816c55c363748d40b2371762a249eed7177aeba086c7b11320b032936528b27716c71491b08ca99d6020c4969ba41d23229ce0bda0b8318ab3806049d7290b0473916dc890d42cc788c237256e43cf7916eab2d8a9a01d48463ff710835bf05f70632f333a8897fbb98bd94fa11ad0c55e016fcc8e55a02bb21d34e1c563361fac6b818fa815180d93b943284a0094bba706504b09b1e3a0d572335532de9097855e8101578f5e7d784df383c0eccaf1a8e03e8b2531fc0aa01bef35cd30119d0cd52dd30943d60f672ccec38d9e78a526f7147a200a8c920ea0bb7fbbeee717776d53b0605a975f7be626869e3639626edc5d1ea82d7256ceb3a078330e172b00a00b2be82fb1c239a855d3b115c2b05732a0da136b640a4bc991a0034f3050dbf66de7fbc5e7fdb705db7f266136f09d5af946f2ec2d13552e1f60a082a08128a5cd66737106304cad57c04edc61a7cd01e8d8bb34b1aaf2e7d5f384a06e0ee61de15716b08d9bb6b382c7a2935df7aaf3604663c8b141ebe4765f559e80", + "0xf90211a0ca41f42416743bddd631b8d111c47fb6a399adff1dce745e6102c198f42e3934a09b0ed7c6bebeaf23aeb5be74431ff7f654549969cf2657f9be99db7046309e05a0a9432bb9292db7ef90ec70f49fb01604baac0c47a121c8474f6a7b4ac3fee143a0772fca178a87cffb9699d83c4011ea9171fd97f02100dfcfb8104d36419f8ec9a022f78994b65aa6f4c6812c0cbd3dcded7343c5b8e97ce9e31d9595a1809cef52a096b54ba6f10fde5e840add6e9fa04e6243443dee45520f46427d527db7111779a02601c850c714949f180389e6271b74f48db4d1819a97e071d0b930a901e56ebea024d802aea5c6a59daaea1f7633b430a97c5b234e18062eee828e1e80d8f47105a085d478a1022a1e77290b0e7c3603d4af848af379ac734ae98fc01995676d441fa09d016f78675c86c68fe3e8a9c6024d34a753863612c75e1aefd1e83bf1fb7996a0ec7a6ad23010d2524751f8d34e4e14317ebea692f2b3c190989b3c0edfd72a43a00fe8c19621357b2a3cc3aded49523f7e438587b43729e679c5a751382f10a6a7a011e2b91321938e3762866e534fdf8ee6f38addf632f6ab9852f3011f0760da53a0b4142fc246d402037ff282a9ded94b26ca60ed32aee664b9bbcb62f0451bb9b3a0b0a71fbb993cfd1f7d101c0fea2a3221d64e0df142c2a25de846ca70fa04e91da03b3256cc9177a07d8237cc3429fbc0d334a9a723ab6d4e6739aa6ec317fd5b1c80", + "0xf90211a09563f3ad7021bb4ba964dbda89142678f69c9220ddc595a7176fee6a77e6dde2a0c03d7e898d9f019dc509c34a0507beb42e5d81f48d9f89ccfbf888d5622a119fa06c795fb9599852d8a27902d72c94de183fadfa304d8dca88881e5486650e047aa0a1095a0a6206c956ef87213a33863dda73e503eebc6d4d0b0303d304ce380bf5a00c0f870fa662cbabbe0efeb0d7092d794a44ffbc9b9f3dc78a0f5820bdb9ef08a0e3b486d3c7ab4ee5bc82aa53062cc0ac7518e50a28f023a3bec79e098d50a1e1a08fa0db4c80f774c25b45aa693c36ba543a0da17859a5ed298947ff0625d3240ea0719bbb5fa0cbbabf2c58d9de555a4c7fda5a3db3bd8f8dcb52f0331ac50da39fa0aa7b34db1dd20cc8082fa64b4571edf4a425fae384632eb1da1cafe31bf1aa7ea017466a7e9a8b545e8c087f4952f16c07d93ecbacbcd80aa4e9964ee4999da0eca0bfbcee522d04a97e863cb4a143161e6935bf2d9f213caef397f19eb0d444955aa0c603f4da9f3b8ce90e3c1e0692b4203e92d0da7aeb7c199c310573b47353a072a0c69a3e3392e217907b7b2fa341e2d1d753319cc0c6f2f098c6bcda7d07045fcba0a3ffebaca1076434c36a77df31d5149ec533f109e458ec1faf436a8e9cbeb063a0875415f1688fc04aa42448b584d522e647a58a56d8a10754717c91b7792d2079a09be0e333cbdded096276ebacf84a0bec134db2a76c44c909969155dae645bda080", + "0xf90211a0fe04c098ac8b48787e56020b1ecc3b5c5c3c6e5171d10a01cdb0c335c2d51a0ea0fc79b69308a70197e2f0dac13429e9ac40fde63afd94055f99cc4083d7e47a9da07ea9fda13a8b6e625cc3103397841e950c401db0590bffd19c88784d66ae8ac2a0eb80e847a0bb1d9ea51785e9df87b8a3cc2c7952e6b1c8b8936d3dbc711f8903a050c6a7b82b0b885b0e7eba783dcc5b8ae987309cd7dfbca12468b03dd0bac239a0a0ee1c4e530bce49c428d03595a5cbcd1d3a305bf574dc3c31cf7fb5a3c142aba0babb7e1b216a15528e50a34fc0f0df5d7a3f772e16769bfe5cde5dca3676d653a0339248dbbdf1b8ffad0c8a9aa7570d84f9c98f628781a38f91283b0ca3aeb44da04bca75e34b823c7cd1b115f6a9062c86d5cf1adc4eee6c07e1f8d14702f9eee2a0c56ff0772873872ddf79cfc6b5ab00928b5a7fe729007cf862fb5db730479098a0ef63d3c6b20257e68fa2985b5df37f283f264d3cfced52e0616026d67aae5174a05235bf4b2037762e034ae4de3f9ec91a7430c033985b296dd7e4511c38852ed9a0f094fb6c0f946cc1daa5c461b1780f58fc2f7cf8c0267b6ce7dcbc72f706335ba086854e8d0a94808be2decde59cf160dc0d3076f03aa0317572bde03f2b320873a04c4c3c0736b931b89b7852c58058edfc5bbe3d5fa8ecb1b6adf260b5a55169b5a03eb45261c45524b9eb254d1e9be2c454c15dca3e9830c233e65098874962c33680", + "0xf90211a092f305a8404f17b6e931179883c08395739bd9cded1d6d0383c5ea78eba0e9eea01b435be6b1b8953faa119ff904d9dc631a0ce9caefbbcf31238f2f1f85dd3101a08cc07a9faf111aa08259fb765d362816eaf830be9c53f5d0a0f80675ab93b815a0e4d58240ddd3d78e1ce5a2d12e1c45e82dcd2185b13ffc177968099ea757cdf5a0f85d2519788a25516c7686f33b03d76de697ec327cbe5c081f069ad85dd02963a001a4641ea4b49fd406ec717d9cf5bda08da097ff8e8f31f47ed9f81fdb1d277fa015ea349963312a679f9e8a95bd835ab8d10323b8df0e33a0f5649c0c43370646a00eaca4b6b9b0ea916d29627a4fbc27922f319cc1d54e1b79a79e5a577aae02e3a00a036924e0cb949a6f2f9c6bd832875db5c46cf43e1be6349b4b6b6531004928a09ef5c65a8581263ac6664606c7f1a151fa72513a1c42a5c980d34fc7cb52d942a0eb8096a937ff16967616dc01e382a32921301b14f4e342f2db3e0979958fdb93a04432cb0b5a0a6e88c885795324164a59870d38c8784c1c51089a3c667f93dc66a0557b8b232b8845e9b522068e259d5292149773319185be73deb68b2acc00869ba097de648ff70c532cb137c8d451ab7d6f219f4198cea0f7e004a44483290ba517a03b7502565bd4afbbdf3e0e5bf8cdab3bc2d311baf540aedbeb989ea98371e4eca02806b9535ce6e675559225b8d2109260017428129690f6361b6489d87c49fae180", + "0xf90211a0503b618293d23441985112f140f5d7afa5ef9d31d19fa62fb99017d4514902c8a0311ed3758bc90dda00ff970a1660bf6cc4adf0ed5b655077e8eef10e02a20ddda0c97eb281c77a1a0be95849a7e7ef57f1463892c5f1e81c28988e2de89f1003c3a00db3fee85f1671f42cb022c701753a8bd0a327a335706fd98c34fdb191187acda0be40e8d8fbc8e2e2cfe867916e6e29b3b5051b0f9f15a9255dffafc956501d37a049486782a5f47a956d3c393f7373ef8bf89c6dcb605abb3d0554f71ba3f71b47a0ba560b379073ffaac72ede1c7cdae34269b9cf17d21f00587a01d4a1ce05714ca0d77cfbdeeb50804494e76228d8961ddbe6c3d8ea554f2a4aae2a711bddd436a2a0e0d0b4ccc7d6b05e5c32e622a9d55297cf382971b0efd188b717437a677d6e60a039d60e2d14f5bed0190930c46386751cc9469a7016d95273ab09dc0037942cffa02474efc4317192c3188209b5e3a4f0bfe624c586300d65362105aaf02abf3fd4a0990cefa23e70fdd28aaccfb96d9ac861347623dba7ec59d5753bae8e4d0421b8a08207ae46bdb4dc6edf83ca4a30fb9260d9d203e69bb694c11c205c4c924de371a039bb8f12a2ca0e97d5220a439381493a3802117bb73406a85f76e325bcf2ffe9a07e9cf71d04326d2c7344c2cf71a552a75ec095d13af30646e903721baf6f968ea032996daa77895aa8e0383c211146b54270a10aa9b4c58e23880d2a243301eca680", + "0xf90151a0b3ad1158c0656d2fa69da4aa9a3060a85073d90819b84522f0c3377047247540a0a1f7c4b2a015e11c26d62fc727eef67a0faa780040ae0adebe93a1e341a6f4d980a031c20c39dfbdd0c7142ef4e8a9128dec5ac324319ec8475d5a4bd73cecfbe9e780a05ac2833f0e6de75df686dad2955041acdfaa9cbe57b8eb90ee18e0e616e7561f80a0dd57fe766ac44d32e7784778660b650ef59bf3855c6f8ceeb57bac3a14cb4247a0b558e61b73ce931037cb132603bbcd0633d1803aa3df1e6cc4fc6adeb78f117da0fd56b8e86e95cd1b8f123394a96685d273e917f924024f114c1c279599250e9b80a08c1d302bcf60d6253bd7cb2567c5f45aae41ef30cdd0acd16ddac78591c6957680a069f601199a401cb6eb42de37258d32c77956ea7c010c34ea5785b94a264f34b980a0da64c248f908ec75a352f1ddd1992df661cbe60623af5cc90707feda609b111a80", + "0xf8518080808080a031d211162636a06229e43cee3301dc559d43c39dc70a35c1f9db384c8ea8f3b580a052ae106948915f7db6155b87fdc9f0bb2c8cd12e475aa3cccad0b60d18a80794808080808080808080", + "0xf8719d20decd5f57411491cdc23220f75184426f294b3c88918fe2e3b802964fb851f84f823385890936f1a77faadf9ca7a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" + ], + "balance": "0x936f1a77faadf9ca7", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "nonce": "0x3385", + "storageHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "storageProof": [] + } +} diff --git a/bolt-contracts/test/testdata/header_20785011.json b/bolt-contracts/test/testdata/header_20785011.json new file mode 100644 index 00000000..c4d63aa8 --- /dev/null +++ b/bolt-contracts/test/testdata/header_20785011.json @@ -0,0 +1,5 @@ +{ + "jsonrpc": "2.0", + "result": "0xf9025aa00595a77df480da86f42f0f339fc55fc6a40886cd320de3a3ec3df6286c867503a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347941f9090aae28b8a3dceadf281b0f12828e676c326a0d6b6ae210398562833e4ac414eb120db14aed11fb8adf5ff5939a20bdd9fbc6fa0a9c4dc0b0e382f1f800d1581d4001bfc33bd384a6f50978e19ab60e92a283f37a020fcda2771063409aefb2669c4e7579d270234d44055c996de915e95ec9caf01b90100d0f9414739b00184f00e04f08d310c80718d32249441f88082897d3830b2a854950fc41563202a9022080028471a29204227c0a8af36a184dae6a6662def6988186c1e0a609449e97ab949b9a07134a1a6210ac1d5651e4114a8c6389926140162011995324058a1346953f321800cf3202e50a05c066d218641101d171b10860450625e0b0c67488d4c09fe03e272d75c514595113100c8112984e2fd90a26a3385185d1f8020044a2190c0ac199d070479854502981a2522046e10d58f1a7b7b583c82005cb3cb29a1823a811124d0328101175569421f64d64002d9b1e630b871202e43622604014484b4810b82dccb057441009700f809c07d01903816558084013d27738401c9c38083a09ebf8466ec2a63917273796e632d6275696c6465722e78797aa0cfe02ed4afd27cd0a42cb0f802a57672daac70511e3b860d7a7ea6b69d4e0d6d880000000000000000850537c96c32a073cb76da1e69871e3400088fa509333d96c3ac5fa307e6f64892202222885f6280830a0000a0ede6709250535a0c48e856b76e415c907d018c3c5f4d1b34e2ae14aa61a8eba1", + "id": 1 +} diff --git a/bolt-contracts/test/testdata/header_20785012.json b/bolt-contracts/test/testdata/header_20785012.json new file mode 100644 index 00000000..49a4b9a6 --- /dev/null +++ b/bolt-contracts/test/testdata/header_20785012.json @@ -0,0 +1,5 @@ +{ + "jsonrpc": "2.0", + "result": "0xf9025ca06be050fe1f6c7ffe8f30a350250a9ecc08ff3c031d129f65e1c10e5119d7a28ba01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d493479495222290dd7278aa3ddd389cc1e1d165cc4bafe5a0214389f55a96edbd4d5295a17ada4dbc68a3b276145bf824b060635f9905cefca087bb9183296ce9e3b7a3246f6d3a778b99a5d7daaba2174750707407c7297365a077c5d55d916e8abd4ca46cc769eb4b70b2693d25c8b67f3036a4a746fc512976b90100936ff6cbcd3707ce33a3e9fcf8b4ba995f7f0d23fedf7227548fefe25c19c8a878efed486844dc1942347a33dddb3fe703b5eadc8abe3cc43d9f1c72012f6132e7b4950acc4e1bed490f5eaab2e853b504b31dfb9e7d6cf8cae89d6c9ff0c6f3af0ce24e667c26f1c5cc78b791983eef172c1f6b80de7e2a1a627836b05ffc1a35683650b3c1e9e9bddf836e46eb4efc4d2a7dcba7e3defe7dbd8aceedbb93f263bf10ef5bb0fb1cf249d0c1ba9dddf3448fc4f5a6b3f3250ab9697089ad3f78119f203f2b3e7b1983198889c4fbd9347a33f93f9463dad70cf5ff6ff6b4e1867bfcb559e1c1bc2df2c5dedbf1244bb65f7cbc816bfeaad22f6fc8217a0516478084013d27748401c9c38084012a47bd8466ec2a6f8f6265617665726275696c642e6f7267a03417ec3f517a20587f89d4802cf478b2faea06b296b1637a8b87200c26433be1880000000000000000850505fd1914a08ae76a6bfb85b813966e007e021e8b4970c8cb02f8be771f5242b45f2e3946028302000083040000a04fa17978dd1135edb87244b53dbee105502454087c389d3638a6b2ac3bc6340c", + "id": 1 +} diff --git a/bolt-contracts/test/testdata/header_20817617.json b/bolt-contracts/test/testdata/header_20817617.json new file mode 100644 index 00000000..96c10c96 --- /dev/null +++ b/bolt-contracts/test/testdata/header_20817617.json @@ -0,0 +1,5 @@ +{ + "jsonrpc": "2.0", + "result": "0xf90261a0f0c271606d68097149e0d89ff622d2690323d65deded9ac9c435c2ea73ed68e6a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944838b106fce9647bdf1e7877bf73ce8b0bad5f97a07bf2e876a6609017c05940b6020e206c0e80006c0b902e5d073c80efd57ee12aa0f866c5389896ec1b8adb85b5b786841a7f8162d820eb35adc626f932fcd9bbcea06e1b5cb518185b799d3726b482abd5333ad733e5d88019686dd2c2457df5de2ab901001ba5662209ca280836180055961846269b09e1adcc814ca5065145909c6f18f0854367868469022d23305ad00c2439700ef190808bb3282520c92c6785780110e09286187180893f4e0a63aad177d0f48e262201c1d40820aca6b780a5a56604acd13160424ac534093df03402841ff2440f126210f8a404c042a852087b08d1800310d98380c058005c3322f0b9024bf4961ca5b320059c853b44d760932ad59ac48560791aa8520a035ce4ce837d1ccfa34e4642e4a207846e8492421a44414341310ea85090e201028e6c180382d34272082f06086030002bf30a50a8e03068fc2a05ba007640d4dc53604d0f138407ec9100815e40c4903b304050c155568084013da6d18401c9c38083b5043a8466f22aff98546974616e2028746974616e6275696c6465722e78797a29a013ea190d046dbfc659b21f36a6ab93951e04cc4430f979ea1970e828bb02f2878800000000000000008502ebb83b87a0089ec82e885d150f3de310102fb40d5a634dafae12a0dedeaec791ad804c686b80830c0000a08ed15ad048af706cacebcc6acfc3a2a32623f4823fd82a78b9ff5678fdc98b95", + "id": 1 +} diff --git a/bolt-contracts/test/testdata/header_20817618.json b/bolt-contracts/test/testdata/header_20817618.json new file mode 100644 index 00000000..d1a2918d --- /dev/null +++ b/bolt-contracts/test/testdata/header_20817618.json @@ -0,0 +1,5 @@ +{ + "jsonrpc": "2.0", + "result": "0xf90262a0b410d12f92ed268b184c1e6523b7d3fea5fcd0ba3f9bc6c6cb9a7e5b1523d225a01dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347944838b106fce9647bdf1e7877bf73ce8b0bad5f97a0ee16bd5a83967bd2073fae8ddffb5f19aa990fb58e1bc912e5d6e53d3279eb4ba0b152ed53b02e03a51211b1f1260d58f5a90ff87a6f209954bd70e8a108112c13a0b5f80761011b50c50f0a85ea83895cef3454c84b3c982225ea1754c2c921a7aeb9010013e55e8278cd3cb8f26a28f0c437340411c98280c5e10c8fc60b693d4677c7ab61dfaf029410826e020438d82a1b8155cfe98038c9136d31b12aede0853e6510e090e519149281abffa6c80a902fbcf6a93ae62994450e309c340766ebb44ba09cd2f4221accc4372529cc0e49302d3d5228d8601a260cecd4454cfc11591ae2341932dc2084755459cf7629a2b5c8605dba3805f325a13ce42e71d871b21b659b5502f01613a81082cad8e52e25bdce0553a8544c30ce3a0d578d06a09da3248888ec021d6df371118426a783b1b05c52faba46b7d75a3522139a3af0aa702c9a7ae87799101e4da4d547a80053dec2cf8c581152dc56c00810e2116105174f8084013da6d28401c9c3808401c98c1a8466f22b0b98546974616e2028746974616e6275696c6465722e78797a29a05856c04e6738317c95ef58b272f7e8611bc2e31bda48d54d86a8d169d842d7468800000000000000008502d82c7313a07b49c83936b895f1331b9e71b5314c53e8cce3952ec29d015301c72cf87499688083060000a049ccb3d7e4a517a48fe3aaf8d81c73286b0694598d40b5bf13e7428cea4f0f77", + "id": 1 +} diff --git a/bolt-contracts/test/testdata/signed_tx_20785012_1.json b/bolt-contracts/test/testdata/signed_tx_20785012_1.json new file mode 100644 index 00000000..1551308e --- /dev/null +++ b/bolt-contracts/test/testdata/signed_tx_20785012_1.json @@ -0,0 +1,6 @@ +{ + "hash": "0x9ec2c56ca36e445a46bc77ca77510f0ef21795d00834269f3752cbd29d63ba1f", + "sender": "0x0D9f5045B604bA0c050b5eb06D0b25d01c525Ea5", + "raw": "0x02f8740181eb8473a20d008507e172a822825208940ff71973b5243005b192d5bcf552fc2532b7bdec88015842095ebc400080c080a07a955ea50e980729226f547245bcf1e0e4ab69467cf82490a4bb0dbe9f35ae84a05f17d1a8f65b60905535ef0c36a8ec6d560c355949aeee2d3ab9791e7fe18fb4", + "blockNumber": 20785012 +} diff --git a/bolt-contracts/test/testdata/signed_tx_20817618_1.json b/bolt-contracts/test/testdata/signed_tx_20817618_1.json new file mode 100644 index 00000000..eb48e2cc --- /dev/null +++ b/bolt-contracts/test/testdata/signed_tx_20817618_1.json @@ -0,0 +1,3 @@ +{ + "raw": "0xf8ab8233858502de59ddef82b59b94dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000331b7670016c6be29d0ac211f6f8aceeb38f0d42000000000000000000000000000000000000000000000000000000000726bbf826a0abf062f0d6ebbb4910392d3bdac921b384f12aea2aa43169a2e866674ae90382a02849acdddc6d86036169e250dea502db87e9a91d6e1ffe8a6a30e54fbb327c5e" +} diff --git a/bolt-contracts/test/testdata/signed_tx_20817618_2.json b/bolt-contracts/test/testdata/signed_tx_20817618_2.json new file mode 100644 index 00000000..1dee3381 --- /dev/null +++ b/bolt-contracts/test/testdata/signed_tx_20817618_2.json @@ -0,0 +1,3 @@ +{ + "raw": "0xf86d8233868504216ca9e78252089415086dc2a2ea37c844e554b65d17c5183f15ab74870326bfc40e1c008025a06db3917cf09951d0107da89bc605ae88623a7690647ac8a5bc3c1638c8c9de59a032a2121306e6a5e1713d99595a65c14cfd1b1978922173cf69bf5f2d4a0b1a60" +} diff --git a/bolt-contracts/test/testdata/signed_tx_20817618_3.json b/bolt-contracts/test/testdata/signed_tx_20817618_3.json new file mode 100644 index 00000000..68339c62 --- /dev/null +++ b/bolt-contracts/test/testdata/signed_tx_20817618_3.json @@ -0,0 +1,3 @@ +{ + "raw": "0xf8ab823387850340375aa882fa2b94dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000009b26d899b1ac6ec07488929c0fdc5b40455275480000000000000000000000000000000000000000000000000000000006e438a025a06194e5ecbf6742f5f7919b39950f452eb0024344977576bb8ceafeff4410e199a007569f10b4d88cd2e185fb30c10f7a507ee6badebfd65b7e4cb884ca8acc5e11" +} diff --git a/bolt-contracts/test/testdata/signed_tx_20817618_4.json b/bolt-contracts/test/testdata/signed_tx_20817618_4.json new file mode 100644 index 00000000..8b2fc67e --- /dev/null +++ b/bolt-contracts/test/testdata/signed_tx_20817618_4.json @@ -0,0 +1,3 @@ +{ + "raw": "0xf86d8233888503439d541b8252089415086dc2a2ea37c844e554b65d17c5183f15ab7487027d84f7cd40008026a0d69512e3b47f74fc7d8a2c02f0497580299494544c53860198510433385d6658a043aed084197ff3a3b05e0a0020e4802da7f50c0078dff2e197ad4b0affb36929" +} diff --git a/bolt-contracts/test/testdata/signed_tx_20817618_5.json b/bolt-contracts/test/testdata/signed_tx_20817618_5.json new file mode 100644 index 00000000..eb01965c --- /dev/null +++ b/bolt-contracts/test/testdata/signed_tx_20817618_5.json @@ -0,0 +1,3 @@ +{ + "raw": "0xf86d82338985058af3f6c28252089415086dc2a2ea37c844e554b65d17c5183f15ab7487040a50523970008026a05bee04d6213c636154c3c2e87038ffdb3d384c23fb9af65fcc85a890c9cabfe6a02231204d5fe346497f035994acec2dece4efa5109d466e7ce834b7576c237f9e" +} diff --git a/bolt-contracts/test/testdata/transactions/README.md b/bolt-contracts/test/testdata/transactions/README.md new file mode 100644 index 00000000..6ef0d5f2 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/README.md @@ -0,0 +1,4 @@ +# Ethereum transaction test cases + +This directory contains test cases for Ethereum transactions taken from the +[Ethers.js test suite](https://github.com/ethers-io/ethers.js/blob/5aba4963e3e8ddfc912747076f5b7fe7a743cfe2/testcases/transactions.json.gz). diff --git a/bolt-contracts/test/testdata/transactions/random_0.json b/bolt-contracts/test/testdata/transactions/random_0.json new file mode 100644 index 00000000..6d588f57 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_0.json @@ -0,0 +1,56 @@ +{ + "name": "random-0", + "transaction": { + "to": "0x6Eb893e3466931517a04a17D153a6330c3f2f1dD", + "nonce": 648, + "gasLimit": "0x9d", + "gasPrice": "0x237e", + "maxFeePerGas": "0x346d9246", + "maxPriorityFeePerGas": "0x2c7e63", + "data": "0x889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33c", + "value": "0xc854", + "accessList": [], + "chainId": "0x8404bf1f", + "maxFeePerBlobGas": "0x2ddc4988", + "blobVersionedHashes": [ + "0x01ecbc98026bec75cc99701e9dbf9d1a7edf9db4106e01c171822da8b1f7f392", + "0x016b567cab2d2fa35658d3bac34b81cf3cc667b9a9fbae9ed58ac961dfc5d96b" + ] + }, + "privateKey": "0x2bf558dce44ca98616ee629199215ae5401c97040664637c48e3b74e66bcb3ae", + "unsignedLegacy": "0xf85682028882237e819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33c", + "unsignedEip155": "0xf85d82028882237e819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33c848404bf1f8080", + "unsignedBerlin": "0x01f85c848404bf1f82028882237e819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33cc0", + "unsignedLondon": "0x02f862848404bf1f820288832c7e6384346d9246819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33cc0", + "unsignedCancun": "0x03f8ab848404bf1f820288832c7e6384346d9246819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33cc0842ddc4988f842a001ecbc98026bec75cc99701e9dbf9d1a7edf9db4106e01c171822da8b1f7f392a0016b567cab2d2fa35658d3bac34b81cf3cc667b9a9fbae9ed58ac961dfc5d96b", + "signedLegacy": "0xf89982028882237e819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33c1ba0ba61344dc955b2f0e5dbc3c65e023e1c718539465131acb8a51b2ef75620114aa03366e9f2294bf2eca7322f3954b9b38745c40602239e3d7fa693667206907518", + "signedEip155": "0xf89e82028882237e819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33c850108097e62a0f141fe1b7e2fc1ed5d2b6ea4f04f92053e18f07274e2bda1c6852438c1895229a075553a7ae158a3fd46f75b547e847b59e2876f9a42de7a26d016db33232516de", + "signedBerlin": "0x01f89f848404bf1f82028882237e819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33cc080a0775f29642af1045b40e5beae8e6bce2dc9e222023b7a50372be6824dbb7434fba05dacfff85752a0b9fd860bc751c17235a670d318a8b9494d664c1b87e33ac8dd", + "signedLondon": "0x02f8a5848404bf1f820288832c7e6384346d9246819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33cc080a0f1003f96c6c6620dd46db36d2ae9f12d363947eb0db088c678b6ad1cf494aa6fa06085b5abbf448de5d622dc820da590cfdb6bb77b41c6650962b998a941f8d701", + "signedCancun": "0x03f8ee848404bf1f820288832c7e6384346d9246819d946eb893e3466931517a04a17d153a6330c3f2f1dd82c854b5889e365e59664fb881554ba1175519b5195b1d20390beb806d8f2cda7893e6f79848195dba4c905db6d7257ffb5eefea35f18ae33cc0842ddc4988f842a001ecbc98026bec75cc99701e9dbf9d1a7edf9db4106e01c171822da8b1f7f392a0016b567cab2d2fa35658d3bac34b81cf3cc667b9a9fbae9ed58ac961dfc5d96b01a092109dabedb5dcd157eddaee3ce39c4c467589b338878b3434181d93ea09c099a0015f8b0ca76ad70e4a69a15078232b77871b8c59b30b2279066064dff3afef47", + "signatureLegacy": { + "r": "0xba61344dc955b2f0e5dbc3c65e023e1c718539465131acb8a51b2ef75620114a", + "s": "0x3366e9f2294bf2eca7322f3954b9b38745c40602239e3d7fa693667206907518", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0xf141fe1b7e2fc1ed5d2b6ea4f04f92053e18f07274e2bda1c6852438c1895229", + "s": "0x75553a7ae158a3fd46f75b547e847b59e2876f9a42de7a26d016db33232516de", + "v": "0x108097e62" + }, + "signatureBerlin": { + "r": "0x775f29642af1045b40e5beae8e6bce2dc9e222023b7a50372be6824dbb7434fb", + "s": "0x5dacfff85752a0b9fd860bc751c17235a670d318a8b9494d664c1b87e33ac8dd", + "v": "0x0" + }, + "signatureLondon": { + "r": "0xf1003f96c6c6620dd46db36d2ae9f12d363947eb0db088c678b6ad1cf494aa6f", + "s": "0x6085b5abbf448de5d622dc820da590cfdb6bb77b41c6650962b998a941f8d701", + "v": "0x0" + }, + "signatureCancun": { + "r": "0x92109dabedb5dcd157eddaee3ce39c4c467589b338878b3434181d93ea09c099", + "s": "0x015f8b0ca76ad70e4a69a15078232b77871b8c59b30b2279066064dff3afef47", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_1.json b/bolt-contracts/test/testdata/transactions/random_1.json new file mode 100644 index 00000000..2fa99168 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_1.json @@ -0,0 +1,55 @@ +{ + "name": "random-1", + "transaction": { + "to": "0x2E806e1F4B2C1Bc500E41b882213648Af39Dd4A2", + "nonce": 613, + "gasLimit": "0x3a", + "gasPrice": "0xf6", + "maxFeePerGas": "0x76cf803ef8c9", + "maxPriorityFeePerGas": "0x45", + "data": "0xb2f1646d", + "value": "0x45", + "accessList": [], + "chainId": "0xdf", + "maxFeePerBlobGas": "0x2e070f634f12e6", + "blobVersionedHashes": [ + "0x0155aa189900c1c076d1a6ca7d1e65f09e62c5e4f0e929c0607c1ab2582b658a" + ] + }, + "privateKey": "0xdde87f54e7dc562364d8559a1777b684a9121d132c4b4237e2534bd5a090166c", + "unsignedLegacy": "0xe182026581f63a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646d", + "unsignedEip155": "0xe582026581f63a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646d81df8080", + "unsignedBerlin": "0x01e481df82026581f63a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646dc0", + "unsignedLondon": "0x02ea81df820265458676cf803ef8c93a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646dc0", + "unsignedCancun": "0x03f85481df820265458676cf803ef8c93a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646dc0872e070f634f12e6e1a00155aa189900c1c076d1a6ca7d1e65f09e62c5e4f0e929c0607c1ab2582b658a", + "signedLegacy": "0xf86482026581f63a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646d1ca0c02ac8b415eefbe6ea2437788d50774aad5eda4c66a8c146b599b08ab67fac62a0491bf160ad32783a281f77c86f12483e1ce9a661680f05e54f6836f3048338f8", + "signedEip155": "0xf86682026581f63a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646d8201e1a0f08888fa9e155e7bbab69c3c1b30f8979de3dabcfe4ee848c99c5130a2dc6628a05e9b300a85b9ca65dabfa1b4718171abbd8393e9f9f01c6b0c628b575808bc84", + "signedBerlin": "0x01f86781df82026581f63a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646dc001a0f87200f49113aac563b703d7056f0bc21961cf72d4bd16ce814bb972182d95b8a023fca36c0c37daadeb1d067efb3e574089c77aa1832f83b6e6a5d48f7900ca33", + "signedLondon": "0x02f86d81df820265458676cf803ef8c93a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646dc001a00633d97e07870e5c1fa9e4f9f8beb169396225d5c691fddcf41ce3a3ea121e1ca0057f715c06932e29d5a4d8b70019c974a34d59e44e4ded4df7f5726ec8e87780", + "signedCancun": "0x03f89781df820265458676cf803ef8c93a942e806e1f4b2c1bc500e41b882213648af39dd4a24584b2f1646dc0872e070f634f12e6e1a00155aa189900c1c076d1a6ca7d1e65f09e62c5e4f0e929c0607c1ab2582b658a80a0392799f17b5f8c1cc8bfb7a29381a717c1b1298e4e3b9218be14c05ec32e50a3a03678448fa6438aee13af5e189fd4e45bd13b014882bc66fdcd9897e9732fb93b", + "signatureLegacy": { + "r": "0xc02ac8b415eefbe6ea2437788d50774aad5eda4c66a8c146b599b08ab67fac62", + "s": "0x491bf160ad32783a281f77c86f12483e1ce9a661680f05e54f6836f3048338f8", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0xf08888fa9e155e7bbab69c3c1b30f8979de3dabcfe4ee848c99c5130a2dc6628", + "s": "0x5e9b300a85b9ca65dabfa1b4718171abbd8393e9f9f01c6b0c628b575808bc84", + "v": "0x1e1" + }, + "signatureBerlin": { + "r": "0xf87200f49113aac563b703d7056f0bc21961cf72d4bd16ce814bb972182d95b8", + "s": "0x23fca36c0c37daadeb1d067efb3e574089c77aa1832f83b6e6a5d48f7900ca33", + "v": "0x1" + }, + "signatureLondon": { + "r": "0x0633d97e07870e5c1fa9e4f9f8beb169396225d5c691fddcf41ce3a3ea121e1c", + "s": "0x057f715c06932e29d5a4d8b70019c974a34d59e44e4ded4df7f5726ec8e87780", + "v": "0x1" + }, + "signatureCancun": { + "r": "0x392799f17b5f8c1cc8bfb7a29381a717c1b1298e4e3b9218be14c05ec32e50a3", + "s": "0x3678448fa6438aee13af5e189fd4e45bd13b014882bc66fdcd9897e9732fb93b", + "v": "0x0" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_10.json b/bolt-contracts/test/testdata/transactions/random_10.json new file mode 100644 index 00000000..d9d5ee86 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_10.json @@ -0,0 +1,63 @@ +{ + "name": "random-10", + "transaction": { + "to": "0xe80B2a2b7a84c886319faB83dF55E63C7539D2E7", + "nonce": 11, + "gasLimit": "0x66745b0460", + "gasPrice": "0x19b27a8a", + "maxFeePerGas": "0x9bc10525", + "maxPriorityFeePerGas": "0xde6421", + "data": "0xc67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184", + "value": "0x452f964f", + "accessList": [ + { + "address": "0x9C1010eBD297f0af2110e4Be1356a99e088B70b0", + "storageKeys": [ + "0x8f4489956d5c84285dd2337de059733fd7caff5e3bc562d2e19f4c8416f7adcd", + "0xecacb47c7f3b429a188ae196d5f6905999bdd4909022d3d5b3566399ef44b513" + ] + } + ], + "chainId": "0x4e33268bd8", + "maxFeePerBlobGas": "0x5b8180c72d", + "blobVersionedHashes": [ + "0x01fe39328d1867749d23972d03954f13d7025f6c7db432c678156c81b87ca044" + ] + }, + "privateKey": "0x937f09851dd891844eee05f469dc776fe07a398b47ee3d064460f74fb00b8454", + "unsignedLegacy": "0xf8710b8419b27a8a8566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184", + "unsignedEip155": "0xf8790b8419b27a8a8566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184854e33268bd88080", + "unsignedBerlin": "0x01f8d4854e33268bd80b8419b27a8a8566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184f85bf859949c1010ebd297f0af2110e4be1356a99e088b70b0f842a08f4489956d5c84285dd2337de059733fd7caff5e3bc562d2e19f4c8416f7adcda0ecacb47c7f3b429a188ae196d5f6905999bdd4909022d3d5b3566399ef44b513", + "unsignedLondon": "0x02f8d8854e33268bd80b83de6421849bc105258566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184f85bf859949c1010ebd297f0af2110e4be1356a99e088b70b0f842a08f4489956d5c84285dd2337de059733fd7caff5e3bc562d2e19f4c8416f7adcda0ecacb47c7f3b429a188ae196d5f6905999bdd4909022d3d5b3566399ef44b513", + "unsignedCancun": "0x03f90100854e33268bd80b83de6421849bc105258566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184f85bf859949c1010ebd297f0af2110e4be1356a99e088b70b0f842a08f4489956d5c84285dd2337de059733fd7caff5e3bc562d2e19f4c8416f7adcda0ecacb47c7f3b429a188ae196d5f6905999bdd4909022d3d5b3566399ef44b513855b8180c72de1a001fe39328d1867749d23972d03954f13d7025f6c7db432c678156c81b87ca044", + "signedLegacy": "0xf8b40b8419b27a8a8566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a9531841ba0f9c1a46fcbbeaa4915050ffc5e33043e372ab5b8e55e40c99bcea824b07ae62ba03a78b26033934d062ab52ac1b527df5b27bd08ced030d392832c89ca779dcc93", + "signedEip155": "0xf8b90b8419b27a8a8566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184859c664d17d4a008a210072105a1ad68dc2b2811abd43dcd1dabaa2c2d2a2f669fb0dea7903535a028817f47aa0014375ed11fde0b733a5b3b648e5ffb2f66e3b4a0fc8db3000bcf", + "signedBerlin": "0x01f90117854e33268bd80b8419b27a8a8566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184f85bf859949c1010ebd297f0af2110e4be1356a99e088b70b0f842a08f4489956d5c84285dd2337de059733fd7caff5e3bc562d2e19f4c8416f7adcda0ecacb47c7f3b429a188ae196d5f6905999bdd4909022d3d5b3566399ef44b51380a0a972d4365dac9b214ae1c1cdbdb70d5c10877eac1edaee2398012e6f084b99fca0184054b4a0b98483664b9469564eb21a28439982883f61bb1e538e968f74ce9d", + "signedLondon": "0x02f9011b854e33268bd80b83de6421849bc105258566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184f85bf859949c1010ebd297f0af2110e4be1356a99e088b70b0f842a08f4489956d5c84285dd2337de059733fd7caff5e3bc562d2e19f4c8416f7adcda0ecacb47c7f3b429a188ae196d5f6905999bdd4909022d3d5b3566399ef44b51301a0abb1f9fd744bd588e3cc73caf61ea9a023aa8b486356f5bc97910ca01fe6453ca062ae4642f50df606c7587957e497e3867510554f88ba57a2bb93a4f8883329e5", + "signedCancun": "0x03f90143854e33268bd80b83de6421849bc105258566745b046094e80b2a2b7a84c886319fab83df55e63c7539d2e784452f964fb849c67a6a742250a5b9144dbfac7342e66a31df07bc2de714d5700d4a328600e6c274a8713cd12df6c64ca6f8088e1a49108dc171457cfcc9a4daf0625786bdf689e568fd61a63a953184f85bf859949c1010ebd297f0af2110e4be1356a99e088b70b0f842a08f4489956d5c84285dd2337de059733fd7caff5e3bc562d2e19f4c8416f7adcda0ecacb47c7f3b429a188ae196d5f6905999bdd4909022d3d5b3566399ef44b513855b8180c72de1a001fe39328d1867749d23972d03954f13d7025f6c7db432c678156c81b87ca04480a042db40cd1ebb1117bc52c8a9d2d467b008203571b1be9ad32db67ba24758cd27a024ac6a399e3a135a5986333a933bd431df1969ca12fdc5217aa7cc778110898b", + "signatureLegacy": { + "r": "0xf9c1a46fcbbeaa4915050ffc5e33043e372ab5b8e55e40c99bcea824b07ae62b", + "s": "0x3a78b26033934d062ab52ac1b527df5b27bd08ced030d392832c89ca779dcc93", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0x08a210072105a1ad68dc2b2811abd43dcd1dabaa2c2d2a2f669fb0dea7903535", + "s": "0x28817f47aa0014375ed11fde0b733a5b3b648e5ffb2f66e3b4a0fc8db3000bcf", + "v": "0x9c664d17d4" + }, + "signatureBerlin": { + "r": "0xa972d4365dac9b214ae1c1cdbdb70d5c10877eac1edaee2398012e6f084b99fc", + "s": "0x184054b4a0b98483664b9469564eb21a28439982883f61bb1e538e968f74ce9d", + "v": "0x0" + }, + "signatureLondon": { + "r": "0xabb1f9fd744bd588e3cc73caf61ea9a023aa8b486356f5bc97910ca01fe6453c", + "s": "0x62ae4642f50df606c7587957e497e3867510554f88ba57a2bb93a4f8883329e5", + "v": "0x1" + }, + "signatureCancun": { + "r": "0x42db40cd1ebb1117bc52c8a9d2d467b008203571b1be9ad32db67ba24758cd27", + "s": "0x24ac6a399e3a135a5986333a933bd431df1969ca12fdc5217aa7cc778110898b", + "v": "0x0" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_11.json b/bolt-contracts/test/testdata/transactions/random_11.json new file mode 100644 index 00000000..9af3b0e7 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_11.json @@ -0,0 +1,78 @@ +{ + "name": "random-11", + "transaction": { + "to": "0x84c0Ab0b0Bb392Fc645293Fd9F88ce734F520C3d", + "nonce": 152, + "gasLimit": "0x27", + "gasPrice": "0x5d0f93b5b0", + "maxFeePerGas": "0x5966bba5", + "maxPriorityFeePerGas": "0x5017", + "data": "0x0c5c6b4f63948ee9bd3027", + "value": "0x6e555229e2", + "accessList": [ + { + "address": "0x43b314A73dd9368a2C0227F3cc1315818Db914D8", + "storageKeys": [ + "0xe0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef" + ] + }, + { + "address": "0x4eA79A74f60B6Bf2688B46fa9Ba5db593098740b", + "storageKeys": [ + "0xe0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef" + ] + }, + { + "address": "0x6eB7Fd5fdfD7F48e137da1b368287f2C6Cc12b45", + "storageKeys": [ + "0xe0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef" + ] + }, + { + "address": "0xb8EcE452e0840B0b30D0BCB4d1400B545cfb746F", + "storageKeys": [ + "0xe0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef" + ] + } + ], + "chainId": "0xdb4137d499", + "maxFeePerBlobGas": "0x1ba30e3498", + "blobVersionedHashes": [] + }, + "privateKey": "0x335dca53da48dba1ac89b63618acd056621774dd60a7ef7f891f64c8c659e7b3", + "unsignedLegacy": "0xf08198855d0f93b5b0279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd3027", + "unsignedEip155": "0xf8388198855d0f93b5b0279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd302785db4137d4998080", + "unsignedBerlin": "0x01f9011885db4137d4998198855d0f93b5b0279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd3027f8e0f79443b314a73dd9368a2c0227f3cc1315818db914d8e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7944ea79a74f60b6bf2688b46fa9ba5db593098740be1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7946eb7fd5fdfd7f48e137da1b368287f2c6cc12b45e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff794b8ece452e0840b0b30d0bcb4d1400b545cfb746fe1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef", + "unsignedLondon": "0x02f9011a85db4137d4998198825017845966bba5279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd3027f8e0f79443b314a73dd9368a2c0227f3cc1315818db914d8e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7944ea79a74f60b6bf2688b46fa9ba5db593098740be1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7946eb7fd5fdfd7f48e137da1b368287f2c6cc12b45e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff794b8ece452e0840b0b30d0bcb4d1400b545cfb746fe1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef", + "unsignedCancun": "0x03f9012185db4137d4998198825017845966bba5279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd3027f8e0f79443b314a73dd9368a2c0227f3cc1315818db914d8e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7944ea79a74f60b6bf2688b46fa9ba5db593098740be1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7946eb7fd5fdfd7f48e137da1b368287f2c6cc12b45e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff794b8ece452e0840b0b30d0bcb4d1400b545cfb746fe1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef851ba30e3498c0", + "signedLegacy": "0xf8738198855d0f93b5b0279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd30271ca07cf7847c9f6bf2ac5b12866c8977bffe203b8674bc35a0c789e60913803298c4a02388e993aa07c5f28a6e31bd8189597ccd314b6ff803b202cc700add8bb907e8", + "signedEip155": "0xf8798198855d0f93b5b0279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd30278601b6826fa956a016821219866f3c43a9d6705be5c99bed3443b663be66036ed3cd6d1b922cf6dca013496a38cc9a45ae5f04a7539adfd4961b6527d8ca203438db0538fa13ee07a3", + "signedBerlin": "0x01f9015b85db4137d4998198855d0f93b5b0279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd3027f8e0f79443b314a73dd9368a2c0227f3cc1315818db914d8e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7944ea79a74f60b6bf2688b46fa9ba5db593098740be1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7946eb7fd5fdfd7f48e137da1b368287f2c6cc12b45e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff794b8ece452e0840b0b30d0bcb4d1400b545cfb746fe1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef80a0c09b02589bf56592b078fa358f37f0349debe1561378ddda9c195c8cbbad6aaca02ce613405a1a0fb0cf7c11e2ae6a13d16dc05b4b54fa29fe659f0d3486b0748d", + "signedLondon": "0x02f9015d85db4137d4998198825017845966bba5279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd3027f8e0f79443b314a73dd9368a2c0227f3cc1315818db914d8e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7944ea79a74f60b6bf2688b46fa9ba5db593098740be1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7946eb7fd5fdfd7f48e137da1b368287f2c6cc12b45e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff794b8ece452e0840b0b30d0bcb4d1400b545cfb746fe1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef01a00291267b646d31657e80c87018fac49779ec0b4b8acfea5b5e5875b2bc574389a028c4e6e7dc6aa417199de1a0ba1deb90fbd9c42818cd926c4d50c5de61cf733a", + "signedCancun": "0x03f9016485db4137d4998198825017845966bba5279484c0ab0b0bb392fc645293fd9f88ce734f520c3d856e555229e28b0c5c6b4f63948ee9bd3027f8e0f79443b314a73dd9368a2c0227f3cc1315818db914d8e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7944ea79a74f60b6bf2688b46fa9ba5db593098740be1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff7946eb7fd5fdfd7f48e137da1b368287f2c6cc12b45e1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051eff794b8ece452e0840b0b30d0bcb4d1400b545cfb746fe1a0e0e82939483d467088aae991d873c23719321b29648506c612ad2a06194051ef851ba30e3498c080a0b0b4ec97964ed7aa3a66e0053ab4163c8b346b2150f581ae09ac7c62f810543ba00e27aac4faaa5fc4634ed8b64f50aaf74156b90d561db528b255242fe624ae0e", + "signatureLegacy": { + "r": "0x7cf7847c9f6bf2ac5b12866c8977bffe203b8674bc35a0c789e60913803298c4", + "s": "0x2388e993aa07c5f28a6e31bd8189597ccd314b6ff803b202cc700add8bb907e8", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x16821219866f3c43a9d6705be5c99bed3443b663be66036ed3cd6d1b922cf6dc", + "s": "0x13496a38cc9a45ae5f04a7539adfd4961b6527d8ca203438db0538fa13ee07a3", + "v": "0x1b6826fa956" + }, + "signatureBerlin": { + "r": "0xc09b02589bf56592b078fa358f37f0349debe1561378ddda9c195c8cbbad6aac", + "s": "0x2ce613405a1a0fb0cf7c11e2ae6a13d16dc05b4b54fa29fe659f0d3486b0748d", + "v": "0x0" + }, + "signatureLondon": { + "r": "0x0291267b646d31657e80c87018fac49779ec0b4b8acfea5b5e5875b2bc574389", + "s": "0x28c4e6e7dc6aa417199de1a0ba1deb90fbd9c42818cd926c4d50c5de61cf733a", + "v": "0x1" + }, + "signatureCancun": { + "r": "0xb0b4ec97964ed7aa3a66e0053ab4163c8b346b2150f581ae09ac7c62f810543b", + "s": "0x0e27aac4faaa5fc4634ed8b64f50aaf74156b90d561db528b255242fe624ae0e", + "v": "0x0" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_12.json b/bolt-contracts/test/testdata/transactions/random_12.json new file mode 100644 index 00000000..7c104ce7 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_12.json @@ -0,0 +1,78 @@ +{ + "name": "random-12", + "transaction": { + "to": "0x4F18B878B82C8931c4A6d67FC28b857AaFf6D764", + "nonce": 547, + "gasLimit": "0xfa26c05691", + "gasPrice": "0x892d19ea64", + "maxFeePerGas": "0x6bf86f84", + "maxPriorityFeePerGas": "0xf627", + "data": "0x57d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f8", + "value": "0x64660ccd", + "accessList": [ + { + "address": "0x275677ef49D8315ed641fe3b6519C4dC3f099112", + "storageKeys": [ + "0x819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457b", + "0xb76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d" + ] + }, + { + "address": "0xa02363D8A2921bF57F7Dc48B42Ccc04548554E81", + "storageKeys": [ + "0x819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457b", + "0xb76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d" + ] + }, + { + "address": "0x8D6796be448CEFf2333157dEE56C74AF0aFb0BD5", + "storageKeys": [ + "0x819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457b", + "0xb76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d" + ] + } + ], + "chainId": "0x44af2c", + "maxFeePerBlobGas": "0x12027a6466afd6", + "blobVersionedHashes": [ + "0x01c67453c9a170645c5784da796dc3aaaf4933d5e8d9c99ae1fd3d8032b0631f", + "0x016865cb3a8b41dabbd03465926a9bedfb91914dd973d05e325f3d77a7db1d8e" + ] + }, + "privateKey": "0x3d04ff4d2657142a58d3cc787e089ca7f20a6b66776ed5b04dc9d4dceef253d7", + "unsignedLegacy": "0xf87182022385892d19ea6485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f8", + "unsignedEip155": "0xf87782022385892d19ea6485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f88344af2c8080", + "unsignedBerlin": "0x01f901898344af2c82022385892d19ea6485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f8f90111f85994275677ef49d8315ed641fe3b6519c4dc3f099112f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df85994a02363d8a2921bf57f7dc48b42ccc04548554e81f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df859948d6796be448ceff2333157dee56c74af0afb0bd5f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d", + "unsignedLondon": "0x02f9018b8344af2c82022382f627846bf86f8485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f8f90111f85994275677ef49d8315ed641fe3b6519c4dc3f099112f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df85994a02363d8a2921bf57f7dc48b42ccc04548554e81f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df859948d6796be448ceff2333157dee56c74af0afb0bd5f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d", + "unsignedCancun": "0x03f901d78344af2c82022382f627846bf86f8485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f8f90111f85994275677ef49d8315ed641fe3b6519c4dc3f099112f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df85994a02363d8a2921bf57f7dc48b42ccc04548554e81f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df859948d6796be448ceff2333157dee56c74af0afb0bd5f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d8712027a6466afd6f842a001c67453c9a170645c5784da796dc3aaaf4933d5e8d9c99ae1fd3d8032b0631fa0016865cb3a8b41dabbd03465926a9bedfb91914dd973d05e325f3d77a7db1d8e", + "signedLegacy": "0xf8b482022385892d19ea6485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f81ca01c1a043ba56d5a6edec9efd4b24695f996204caec12978d32bf086d8e21bcf96a04a5144d22ab0ddd5335bc3e1b22cd24e66bd742865f1a4447e2675ee00a2227f", + "signedEip155": "0xf8b782022385892d19ea6485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f883895e7ca06d75cb007c3b91b7465c095e28b841d93da110bbb66280a0f5920083ad4e80f2a026b07e9427fd6dc320c23ced73fb8aae9872af808f20db04f0bb67287da0373b", + "signedBerlin": "0x01f901cc8344af2c82022385892d19ea6485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f8f90111f85994275677ef49d8315ed641fe3b6519c4dc3f099112f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df85994a02363d8a2921bf57f7dc48b42ccc04548554e81f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df859948d6796be448ceff2333157dee56c74af0afb0bd5f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d80a0f69b776f4eee48cf9a220abb4e132d2cd915b320e409fe99376535aa6984f69ea045b9071a002c820e368070525657f2cd47053ea600d24c1da75b7adbd076cfcf", + "signedLondon": "0x02f901ce8344af2c82022382f627846bf86f8485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f8f90111f85994275677ef49d8315ed641fe3b6519c4dc3f099112f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df85994a02363d8a2921bf57f7dc48b42ccc04548554e81f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df859948d6796be448ceff2333157dee56c74af0afb0bd5f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d01a074ffa09bd37c038326cebdd9794d5f90fe95aa9210e903fb6a5c44a735bbafc6a01605e0f1db258100a878445341892825483f14cfa7b9bde7bd001f4f3e6eed4a", + "signedCancun": "0x03f9021a8344af2c82022382f627846bf86f8485fa26c05691944f18b878b82c8931c4a6d67fc28b857aaff6d7648464660ccdb84657d10e77f6d8cd44acf5914b7b73eca98b9afe235e07b9db2d1712c4adc287e3e474a377404de19203f5127b676c88c839a76e15e665f183709a3460025556e5fd5f2a2f17f8f90111f85994275677ef49d8315ed641fe3b6519c4dc3f099112f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df85994a02363d8a2921bf57f7dc48b42ccc04548554e81f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6df859948d6796be448ceff2333157dee56c74af0afb0bd5f842a0819da32335b67b104a5c786c41f2811e1167a1245b4998eb9297d0b777db457ba0b76e298e9f4a7cb7e30809076edbb99bcbc310ec27d7a563cbc24cddd0a2ae6d8712027a6466afd6f842a001c67453c9a170645c5784da796dc3aaaf4933d5e8d9c99ae1fd3d8032b0631fa0016865cb3a8b41dabbd03465926a9bedfb91914dd973d05e325f3d77a7db1d8e01a06bb2134653010ab0cec4aa5e51d66acf4b9c0835477bed4a96949fe0cc15db35a06432039ef421f4cf53ada8b7149e0852cc705668a6713d00aa0ddbfc9b84604f", + "signatureLegacy": { + "r": "0x1c1a043ba56d5a6edec9efd4b24695f996204caec12978d32bf086d8e21bcf96", + "s": "0x4a5144d22ab0ddd5335bc3e1b22cd24e66bd742865f1a4447e2675ee00a2227f", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x6d75cb007c3b91b7465c095e28b841d93da110bbb66280a0f5920083ad4e80f2", + "s": "0x26b07e9427fd6dc320c23ced73fb8aae9872af808f20db04f0bb67287da0373b", + "v": "0x895e7c" + }, + "signatureBerlin": { + "r": "0xf69b776f4eee48cf9a220abb4e132d2cd915b320e409fe99376535aa6984f69e", + "s": "0x45b9071a002c820e368070525657f2cd47053ea600d24c1da75b7adbd076cfcf", + "v": "0x0" + }, + "signatureLondon": { + "r": "0x74ffa09bd37c038326cebdd9794d5f90fe95aa9210e903fb6a5c44a735bbafc6", + "s": "0x1605e0f1db258100a878445341892825483f14cfa7b9bde7bd001f4f3e6eed4a", + "v": "0x1" + }, + "signatureCancun": { + "r": "0x6bb2134653010ab0cec4aa5e51d66acf4b9c0835477bed4a96949fe0cc15db35", + "s": "0x6432039ef421f4cf53ada8b7149e0852cc705668a6713d00aa0ddbfc9b84604f", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_13.json b/bolt-contracts/test/testdata/transactions/random_13.json new file mode 100644 index 00000000..e46f587f --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_13.json @@ -0,0 +1,88 @@ +{ + "name": "random-13", + "transaction": { + "to": "0x02CA24BF68010E087C89FBBBBA726265f75F453f", + "nonce": 230, + "gasLimit": "0x9b", + "gasPrice": "0xee0c40da", + "maxFeePerGas": "0x6911bd4911", + "maxPriorityFeePerGas": "0x8d", + "data": "0x9057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18c", + "value": "0xe5cf3dc063", + "accessList": [ + { + "address": "0x9a39070F38D75E2c56dbb0f5992F87D4B8c4516f", + "storageKeys": [ + "0x5a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6f", + "0xbb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6", + "0x573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63" + ] + }, + { + "address": "0x727e5f27d18F70fDA8F234082421872B68C3Dda0", + "storageKeys": [ + "0x5a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6f", + "0xbb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6", + "0x573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63" + ] + }, + { + "address": "0x81df03F5cd0f415eAB92E0593998Dd288B02d583", + "storageKeys": [ + "0x5a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6f", + "0xbb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6", + "0x573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63" + ] + }, + { + "address": "0x3C465948C080239deECAbc2b8A7fccbe4130B3E6", + "storageKeys": [ + "0x5a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6f", + "0xbb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6", + "0x573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63" + ] + } + ], + "chainId": "0x2a", + "maxFeePerBlobGas": "0x8d5e0eac8355", + "blobVersionedHashes": [ + "0x014fe494c02bd67264c92caae4891a3b0888fdc0bd520c0872ba0d540991d2ef" + ] + }, + "privateKey": "0x70dae63ff96bc4831355131fc24468c3e57dbac4c0a82334953baa752df10cff", + "unsignedLegacy": "0xf88b81e684ee0c40da819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18c", + "unsignedEip155": "0xf88e81e684ee0c40da819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18c2a8080", + "unsignedBerlin": "0x01f9027f2a81e684ee0c40da819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18cf901f0f87a949a39070f38d75e2c56dbb0f5992f87d4b8c4516ff863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a94727e5f27d18f70fda8f234082421872b68c3dda0f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a9481df03f5cd0f415eab92e0593998dd288b02d583f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a943c465948c080239deecabc2b8a7fccbe4130b3e6f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63", + "unsignedLondon": "0x02f902822a81e6818d856911bd4911819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18cf901f0f87a949a39070f38d75e2c56dbb0f5992f87d4b8c4516ff863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a94727e5f27d18f70fda8f234082421872b68c3dda0f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a9481df03f5cd0f415eab92e0593998dd288b02d583f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a943c465948c080239deecabc2b8a7fccbe4130b3e6f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63", + "unsignedCancun": "0x03f902ab2a81e6818d856911bd4911819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18cf901f0f87a949a39070f38d75e2c56dbb0f5992f87d4b8c4516ff863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a94727e5f27d18f70fda8f234082421872b68c3dda0f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a9481df03f5cd0f415eab92e0593998dd288b02d583f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a943c465948c080239deecabc2b8a7fccbe4130b3e6f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63868d5e0eac8355e1a0014fe494c02bd67264c92caae4891a3b0888fdc0bd520c0872ba0d540991d2ef", + "signedLegacy": "0xf8ce81e684ee0c40da819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18c1ca01f91e4f825a52eb8bbaa3be1cb1cb861857cf6d0db05543a91f4e201afe63634a030680d1f0dec57bf64f8fa85a835fcfca06aa5108c7a46b60df9da8572518087", + "signedEip155": "0xf8ce81e684ee0c40da819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18c78a05cb862c473f3dfdeaa0e8520291cb4ba8c3a62550a6ca0e404d51ef8791cf7f8a052d4ad17f007fa089126d119c609adb461436fd4e07640c0fc487bb444caea99", + "signedBerlin": "0x01f902c22a81e684ee0c40da819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18cf901f0f87a949a39070f38d75e2c56dbb0f5992f87d4b8c4516ff863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a94727e5f27d18f70fda8f234082421872b68c3dda0f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a9481df03f5cd0f415eab92e0593998dd288b02d583f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a943c465948c080239deecabc2b8a7fccbe4130b3e6f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab6301a04f2bb0a31a56bb2b1aed5089f7a05c1dd10d759fafdc07ad9ed698885981412ba0042167f0f1ba66c56f1b39f5ab4ad95442cf98c2e4b0a4066f4995b22a663bf3", + "signedLondon": "0x02f902c52a81e6818d856911bd4911819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18cf901f0f87a949a39070f38d75e2c56dbb0f5992f87d4b8c4516ff863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a94727e5f27d18f70fda8f234082421872b68c3dda0f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a9481df03f5cd0f415eab92e0593998dd288b02d583f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a943c465948c080239deecabc2b8a7fccbe4130b3e6f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab6301a03fd00e5a6b50a78f53922d62a73777ccfe7695f1e6e30f8be33323119bc2c0efa0050ac86674b894e33b3292bb153eb1fbefa4efdaf5775eba835391477f6831c4", + "signedCancun": "0x03f902ee2a81e6818d856911bd4911819b9402ca24bf68010e087c89fbbbba726265f75f453f85e5cf3dc063b8659057177cbea0fcc2e52f03fd99ae750cd5e1df00a897ae7cc0a37f609358089d09690aa727fc2a5514964930ebcdfaa64d48ca730848ba3bdf55dfafcdbc2615fcc0aff5b5804bc592b4a9129b30858f7e56d895e655ee66b8d39a5fd8e22590fec373b18cf901f0f87a949a39070f38d75e2c56dbb0f5992f87d4b8c4516ff863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a94727e5f27d18f70fda8f234082421872b68c3dda0f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a9481df03f5cd0f415eab92e0593998dd288b02d583f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63f87a943c465948c080239deecabc2b8a7fccbe4130b3e6f863a05a2edcbe00c7f2a4054eb642539fc70f3b18e636eee4a800a307d1b38bf2cf6fa0bb923a5c3ae3b14becbfc2ce1f9bcac3ac7f9e529bf121ebe45589f97ea7a5d6a0573a0bef0d2674001e858247d3fe613ca0c17a6b733979e6516af7fa8ef3ab63868d5e0eac8355e1a0014fe494c02bd67264c92caae4891a3b0888fdc0bd520c0872ba0d540991d2ef01a061188dabcd2879c18c49f3f83cb4663d597da58f856390b87921f64182ea9745a0757d18b772ff141ddff69196b2755bd76ef422a102a3a0fa1ca68b2e901b468c", + "signatureLegacy": { + "r": "0x1f91e4f825a52eb8bbaa3be1cb1cb861857cf6d0db05543a91f4e201afe63634", + "s": "0x30680d1f0dec57bf64f8fa85a835fcfca06aa5108c7a46b60df9da8572518087", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x5cb862c473f3dfdeaa0e8520291cb4ba8c3a62550a6ca0e404d51ef8791cf7f8", + "s": "0x52d4ad17f007fa089126d119c609adb461436fd4e07640c0fc487bb444caea99", + "v": "0x78" + }, + "signatureBerlin": { + "r": "0x4f2bb0a31a56bb2b1aed5089f7a05c1dd10d759fafdc07ad9ed698885981412b", + "s": "0x042167f0f1ba66c56f1b39f5ab4ad95442cf98c2e4b0a4066f4995b22a663bf3", + "v": "0x1" + }, + "signatureLondon": { + "r": "0x3fd00e5a6b50a78f53922d62a73777ccfe7695f1e6e30f8be33323119bc2c0ef", + "s": "0x050ac86674b894e33b3292bb153eb1fbefa4efdaf5775eba835391477f6831c4", + "v": "0x1" + }, + "signatureCancun": { + "r": "0x61188dabcd2879c18c49f3f83cb4663d597da58f856390b87921f64182ea9745", + "s": "0x757d18b772ff141ddff69196b2755bd76ef422a102a3a0fa1ca68b2e901b468c", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_14.json b/bolt-contracts/test/testdata/transactions/random_14.json new file mode 100644 index 00000000..b2bec042 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_14.json @@ -0,0 +1,71 @@ +{ + "name": "random-14", + "transaction": { + "to": "0xd4Ed79414A9F8bF363E9CAaa5A74380716F7dBE0", + "nonce": 355, + "gasLimit": "0xc3393abf8e", + "gasPrice": "0x530f336b", + "maxFeePerGas": "0xc4550ba0e2", + "maxPriorityFeePerGas": "0xf9fe", + "data": "0x9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe82", + "value": "0x5590f0f87b", + "accessList": [ + { + "address": "0x3acE6cc41a8DF5B6518B24e6ecd490c13aCfC677", + "storageKeys": [] + }, + { + "address": "0x65F3540A4A7aa93d074A77313622786513f0199d", + "storageKeys": [] + }, + { + "address": "0x0dad5e012C02f680FB256bf6b0e0d9999c8c74A0", + "storageKeys": [] + } + ], + "chainId": "0x602a", + "maxFeePerBlobGas": "0xe61327d8d776ed", + "blobVersionedHashes": [ + "0x0122070325084d4e3cba54d4dffef3501e22290c965e099620b3dbd48626b731", + "0x018df851a2bdd53f12054dc427d35171bbc81e2141c0ef7afe94964e4cdd3c1f", + "0x01386600d37c5951685dc66bc09b1a3e98c040621dde84b172cf93c30d66842f", + "0x017f6d70f99ec3a8937f73f2da032c78dde8a6f831befc31fd23189ff66e4b07" + ] + }, + "privateKey": "0x6c268eef2efdb15a96ae69774e732b9214a3ebb03c0fd01602bc7a5fcd21c060", + "unsignedLegacy": "0xf85782016384530f336b85c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe82", + "unsignedEip155": "0xf85c82016384530f336b85c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe8282602a8080", + "unsignedBerlin": "0x01f8a182602a82016384530f336b85c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe82f845d6943ace6cc41a8df5b6518b24e6ecd490c13acfc677c0d69465f3540a4a7aa93d074a77313622786513f0199dc0d6940dad5e012c02f680fb256bf6b0e0d9999c8c74a0c0", + "unsignedLondon": "0x02f8a582602a82016382f9fe85c4550ba0e285c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe82f845d6943ace6cc41a8df5b6518b24e6ecd490c13acfc677c0d69465f3540a4a7aa93d074a77313622786513f0199dc0d6940dad5e012c02f680fb256bf6b0e0d9999c8c74a0c0", + "unsignedCancun": "0x03f9013382602a82016382f9fe85c4550ba0e285c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe82f845d6943ace6cc41a8df5b6518b24e6ecd490c13acfc677c0d69465f3540a4a7aa93d074a77313622786513f0199dc0d6940dad5e012c02f680fb256bf6b0e0d9999c8c74a0c087e61327d8d776edf884a00122070325084d4e3cba54d4dffef3501e22290c965e099620b3dbd48626b731a0018df851a2bdd53f12054dc427d35171bbc81e2141c0ef7afe94964e4cdd3c1fa001386600d37c5951685dc66bc09b1a3e98c040621dde84b172cf93c30d66842fa0017f6d70f99ec3a8937f73f2da032c78dde8a6f831befc31fd23189ff66e4b07", + "signedLegacy": "0xf89a82016384530f336b85c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe821ca03e5ece8f862a9b5d42b42c314dceef20c98a55ae8e89e76ea36574f2dbcd0a6fa06cf670f45c89f30ccf175619d7a48c30c0303d723e8c942afe3bf99bb622a365", + "signedEip155": "0xf89c82016384530f336b85c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe8282c077a07984b5662bf52721770ca23a49f719f0dca47263a736a7cb6da28b359c3275d5a0080a94bd846cb4d5d71a41c78f5f4a893f9cd8316a52f3bba02b2e6d5865d13e", + "signedBerlin": "0x01f8e482602a82016384530f336b85c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe82f845d6943ace6cc41a8df5b6518b24e6ecd490c13acfc677c0d69465f3540a4a7aa93d074a77313622786513f0199dc0d6940dad5e012c02f680fb256bf6b0e0d9999c8c74a0c001a0a0983d54539712f6f848fe9fad8631479338d8277207d75ccf4a26ae3ed34e79a00acd07196e5fa670c9109ced9ccf4722f2c33ae49eec06f14ea3766c6d0e7c3e", + "signedLondon": "0x02f8e882602a82016382f9fe85c4550ba0e285c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe82f845d6943ace6cc41a8df5b6518b24e6ecd490c13acfc677c0d69465f3540a4a7aa93d074a77313622786513f0199dc0d6940dad5e012c02f680fb256bf6b0e0d9999c8c74a0c001a0990f968b8f06d13ac77614e1acd01591259050753e76bc7419062bdf6ac71a11a0201883043f4f176b82d7cc14ffd524f28fcf9cc490cea858bacac84d7373261a", + "signedCancun": "0x03f9017682602a82016382f9fe85c4550ba0e285c3393abf8e94d4ed79414a9f8bf363e9caaa5a74380716f7dbe0855590f0f87bad9421f8e15d313f08424f56798539e338ff345b530bef1256810200922813e50a176ca7e987dbedb94917acfe82f845d6943ace6cc41a8df5b6518b24e6ecd490c13acfc677c0d69465f3540a4a7aa93d074a77313622786513f0199dc0d6940dad5e012c02f680fb256bf6b0e0d9999c8c74a0c087e61327d8d776edf884a00122070325084d4e3cba54d4dffef3501e22290c965e099620b3dbd48626b731a0018df851a2bdd53f12054dc427d35171bbc81e2141c0ef7afe94964e4cdd3c1fa001386600d37c5951685dc66bc09b1a3e98c040621dde84b172cf93c30d66842fa0017f6d70f99ec3a8937f73f2da032c78dde8a6f831befc31fd23189ff66e4b0780a0da2f7f2f95d6b3207aeb56b5b6aa5aa30a2674f90d338427674c8e5e7850f078a0646d4c7d050a38c73bf1f22b8ba41e2a84430c3550ec20843e885248cc90b53b", + "signatureLegacy": { + "r": "0x3e5ece8f862a9b5d42b42c314dceef20c98a55ae8e89e76ea36574f2dbcd0a6f", + "s": "0x6cf670f45c89f30ccf175619d7a48c30c0303d723e8c942afe3bf99bb622a365", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x7984b5662bf52721770ca23a49f719f0dca47263a736a7cb6da28b359c3275d5", + "s": "0x080a94bd846cb4d5d71a41c78f5f4a893f9cd8316a52f3bba02b2e6d5865d13e", + "v": "0xc077" + }, + "signatureBerlin": { + "r": "0xa0983d54539712f6f848fe9fad8631479338d8277207d75ccf4a26ae3ed34e79", + "s": "0x0acd07196e5fa670c9109ced9ccf4722f2c33ae49eec06f14ea3766c6d0e7c3e", + "v": "0x1" + }, + "signatureLondon": { + "r": "0x990f968b8f06d13ac77614e1acd01591259050753e76bc7419062bdf6ac71a11", + "s": "0x201883043f4f176b82d7cc14ffd524f28fcf9cc490cea858bacac84d7373261a", + "v": "0x1" + }, + "signatureCancun": { + "r": "0xda2f7f2f95d6b3207aeb56b5b6aa5aa30a2674f90d338427674c8e5e7850f078", + "s": "0x646d4c7d050a38c73bf1f22b8ba41e2a84430c3550ec20843e885248cc90b53b", + "v": "0x0" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_15.json b/bolt-contracts/test/testdata/transactions/random_15.json new file mode 100644 index 00000000..1be8cfac --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_15.json @@ -0,0 +1,76 @@ +{ + "name": "random-15", + "transaction": { + "to": "0x2C4Ad0E9a08DD6fE31Ba497fd4a893A0C1fc6B34", + "nonce": 252, + "gasLimit": "0x50ef8434", + "gasPrice": "0xd9ca73", + "maxFeePerGas": "0x280244cd52ab", + "maxPriorityFeePerGas": "0x143b17", + "data": "0x59a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92d", + "value": "0x6f9f", + "accessList": [ + { + "address": "0x3266CE0AB053240CE5d95993d420c6b9a1dA1fDC", + "storageKeys": [ + "0xa0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211", + "0x80b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0", + "0xa628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8", + "0x35167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1" + ] + }, + { + "address": "0xf199b9f871065E2E18291CdeC3BF7C1eD32FBa0a", + "storageKeys": [ + "0xa0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211", + "0x80b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0", + "0xa628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8", + "0x35167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1" + ] + } + ], + "chainId": "0x18314c", + "maxFeePerBlobGas": "0x81ec2df3d713c4", + "blobVersionedHashes": [ + "0x01d63574eb4fd029b67d6233aeae60815e225597f647de565b8050d2b5a876b3", + "0x01224249cfed8dce6d9785f85c2ca29b6496d91ca16dbafabf1581ef75f47b29", + "0x01a4547275516123b7b2ea3413c57c4caea24441dd9956f7308f09b5bb0947df" + ] + }, + "privateKey": "0xffe260f37af5da6e4a18799bc6b7f0fab7d57bc456346bca7261a53cb04fb48d", + "unsignedLegacy": "0xf85781fc83d9ca738450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92d", + "unsignedEip155": "0xf85d81fc83d9ca738450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92d8318314c8080", + "unsignedBerlin": "0x01f901988318314c81fc83d9ca738450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92df9013af89b943266ce0ab053240ce5d95993d420c6b9a1da1fdcf884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1f89b94f199b9f871065e2e18291cdec3bf7c1ed32fba0af884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1", + "unsignedLondon": "0x02f9019f8318314c81fc83143b1786280244cd52ab8450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92df9013af89b943266ce0ab053240ce5d95993d420c6b9a1da1fdcf884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1f89b94f199b9f871065e2e18291cdec3bf7c1ed32fba0af884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1", + "unsignedCancun": "0x03f9020c8318314c81fc83143b1786280244cd52ab8450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92df9013af89b943266ce0ab053240ce5d95993d420c6b9a1da1fdcf884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1f89b94f199b9f871065e2e18291cdec3bf7c1ed32fba0af884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b18781ec2df3d713c4f863a001d63574eb4fd029b67d6233aeae60815e225597f647de565b8050d2b5a876b3a001224249cfed8dce6d9785f85c2ca29b6496d91ca16dbafabf1581ef75f47b29a001a4547275516123b7b2ea3413c57c4caea24441dd9956f7308f09b5bb0947df", + "signedLegacy": "0xf89a81fc83d9ca738450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92d1ba0c32aaeca7f3f7d189f6493edfb99452baa5e5a4c3ba136275b92c28a722a59f7a07073e03733555ceb1a3479c3193cfac043530c657b1c26cf2d12ffac912d132d", + "signedEip155": "0xf89d81fc83d9ca738450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92d833062bca02a5acf0ccf63515e394899176fdc70cfc880e8f34ba5199de5baa72e0dc11e8fa07560075eef0250df34dd68a1854864b219ab0972e96e3d70017b21f608c5e928", + "signedBerlin": "0x01f901db8318314c81fc83d9ca738450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92df9013af89b943266ce0ab053240ce5d95993d420c6b9a1da1fdcf884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1f89b94f199b9f871065e2e18291cdec3bf7c1ed32fba0af884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b101a0c46f5930fbf08b22c97615c2d8db15697dfa5d0a269bb91a9afd7ddb7ac44768a066e4c7ad9c783be0dd722b4b85dc6518892f8c632c09b2ec2c0980c84fb897b7", + "signedLondon": "0x02f901e28318314c81fc83143b1786280244cd52ab8450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92df9013af89b943266ce0ab053240ce5d95993d420c6b9a1da1fdcf884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1f89b94f199b9f871065e2e18291cdec3bf7c1ed32fba0af884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b180a0bdebff14388befbaf0d7c8509f82355aafd0cbdad7ba5d721fa6357e239cf380a06efc7089e04a05f4e52b43fb3799e6ebd9274128566e870efef293a9d8624271", + "signedCancun": "0x03f9024f8318314c81fc83143b1786280244cd52ab8450ef8434942c4ad0e9a08dd6fe31ba497fd4a893a0c1fc6b34826f9fb359a1b826916e4a012ffaaf5e21251e27317a1f565a716b8ff184d8c689f93f5a7359abcbffd18d7bea36ee123ce5cddbbdd92df9013af89b943266ce0ab053240ce5d95993d420c6b9a1da1fdcf884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b1f89b94f199b9f871065e2e18291cdec3bf7c1ed32fba0af884a0a0568d48a6cc9e0c92080dec2155382a276181f25c746da97f8199f3a8464211a080b165a49183e897da692ca460c5c88a0597e5e4ad7b43471bac25bfd9a780e0a0a628e4d1cfbcc69964473b21b3df585f15eca27bdd2e0c0d7e2f1db3e2c0a1f8a035167ab9f9061b5f986f5c960aebe912340a5a72935aa334afa8fbfe586d05b18781ec2df3d713c4f863a001d63574eb4fd029b67d6233aeae60815e225597f647de565b8050d2b5a876b3a001224249cfed8dce6d9785f85c2ca29b6496d91ca16dbafabf1581ef75f47b29a001a4547275516123b7b2ea3413c57c4caea24441dd9956f7308f09b5bb0947df80a04214e832f45d5ba706f01b7dce5941397c8f0850ddfc30d0bf70e896e542bbd1a027208b27598709a564ca5981d54c0c3aa4b33b7c618de45f378576b229bf07f5", + "signatureLegacy": { + "r": "0xc32aaeca7f3f7d189f6493edfb99452baa5e5a4c3ba136275b92c28a722a59f7", + "s": "0x7073e03733555ceb1a3479c3193cfac043530c657b1c26cf2d12ffac912d132d", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0x2a5acf0ccf63515e394899176fdc70cfc880e8f34ba5199de5baa72e0dc11e8f", + "s": "0x7560075eef0250df34dd68a1854864b219ab0972e96e3d70017b21f608c5e928", + "v": "0x3062bc" + }, + "signatureBerlin": { + "r": "0xc46f5930fbf08b22c97615c2d8db15697dfa5d0a269bb91a9afd7ddb7ac44768", + "s": "0x66e4c7ad9c783be0dd722b4b85dc6518892f8c632c09b2ec2c0980c84fb897b7", + "v": "0x1" + }, + "signatureLondon": { + "r": "0xbdebff14388befbaf0d7c8509f82355aafd0cbdad7ba5d721fa6357e239cf380", + "s": "0x6efc7089e04a05f4e52b43fb3799e6ebd9274128566e870efef293a9d8624271", + "v": "0x0" + }, + "signatureCancun": { + "r": "0x4214e832f45d5ba706f01b7dce5941397c8f0850ddfc30d0bf70e896e542bbd1", + "s": "0x27208b27598709a564ca5981d54c0c3aa4b33b7c618de45f378576b229bf07f5", + "v": "0x0" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_16.json b/bolt-contracts/test/testdata/transactions/random_16.json new file mode 100644 index 00000000..10608fce --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_16.json @@ -0,0 +1,64 @@ +{ + "name": "random-16", + "transaction": { + "to": "0xb26832F9Eebe1bb94cb67D5C6bABF358d15f834E", + "nonce": 306, + "gasLimit": "0xfb38", + "gasPrice": "0x7029692f45", + "maxFeePerGas": "0xf631d7b0a81f", + "maxPriorityFeePerGas": "0xb5", + "data": "0x3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779", + "value": "0xb3", + "accessList": [ + { + "address": "0x820A408021ed575Bd94e89AF5672C9C4FaAA93AD", + "storageKeys": [] + } + ], + "chainId": "0x03", + "maxFeePerBlobGas": "0x9b643a13", + "blobVersionedHashes": [ + "0x0106f3b8583c3b187099347666d5b01b3ae85b5458a2291ca45884084bf8a728", + "0x012d5ba14538fe600b4f258429247337527a13d6a28c3b4b445f00d3098df94f", + "0x011a4647e1b61123ab33b318dff3609fc11da8c4cfa9abe25f99c41923a9f581", + "0x01cb8b689043f5bdcc56fce5c26490ca28a88b0a2f53a6d1f51e3f298e65d295", + "0x01531f010e1e10d3d3332b2caef340f0a6af1e366a98126ef035c3ce80b8a1db" + ] + }, + "privateKey": "0x504264c14141b98fdad31cff441c443d69458e4033c11eeb0b4928ce9452c5a1", + "unsignedLegacy": "0xf890820132857029692f4582fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779", + "unsignedEip155": "0xf893820132857029692f4582fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779038080", + "unsignedBerlin": "0x01f8a903820132857029692f4582fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779d7d694820a408021ed575bd94e89af5672c9c4faaa93adc0", + "unsignedLondon": "0x02f8ac0382013281b586f631d7b0a81f82fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779d7d694820a408021ed575bd94e89af5672c9c4faaa93adc0", + "unsignedCancun": "0x03f901580382013281b586f631d7b0a81f82fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779d7d694820a408021ed575bd94e89af5672c9c4faaa93adc0849b643a13f8a5a00106f3b8583c3b187099347666d5b01b3ae85b5458a2291ca45884084bf8a728a0012d5ba14538fe600b4f258429247337527a13d6a28c3b4b445f00d3098df94fa0011a4647e1b61123ab33b318dff3609fc11da8c4cfa9abe25f99c41923a9f581a001cb8b689043f5bdcc56fce5c26490ca28a88b0a2f53a6d1f51e3f298e65d295a001531f010e1e10d3d3332b2caef340f0a6af1e366a98126ef035c3ce80b8a1db", + "signedLegacy": "0xf8d3820132857029692f4582fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b0596297791ca09eb445c3fb16cea6f435cca3fd89869351b0152442c77013ee2787ab9363c64fa012daa8f1bbc55ef013376a0b10a608634e9fe03ce051bcf11874132f4b37b1c1", + "signedEip155": "0xf8d3820132857029692f4582fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b05962977929a03aacb5053d4586e75d7c2f59a16aa559f1b335a1e5b81d5e04ee3f10370e0b78a00c4062ee9c4f3c10b72331bdbbe8b8f896cecaa7f79d291dca3cb6182473d6f3", + "signedBerlin": "0x01f8ec03820132857029692f4582fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779d7d694820a408021ed575bd94e89af5672c9c4faaa93adc080a0cc30fef0ed85c2d3df5dae8321402cd6ee6cfec5778a191674d295a861be14b3a00874a36ad883e39d70744772063a504ff5887f020ece23afa159ec3d092f7dac", + "signedLondon": "0x02f8ef0382013281b586f631d7b0a81f82fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779d7d694820a408021ed575bd94e89af5672c9c4faaa93adc080a0fe006607f7e8089cc51cafca96b281cd8c3a95d6f88a5a1175b3a8cc958b6b74a0105054c0d7d120b19d8eb03a67dccd82c2add7b8c04e6438fd30ab6e31cd4364", + "signedCancun": "0x03f9019b0382013281b586f631d7b0a81f82fb3894b26832f9eebe1bb94cb67d5c6babf358d15f834e81b3b86b3c5c6cbe06f0c46868590f0951afc1b55f38598f5caf4d2f811ed3bbb8a87de83f074bc2cf19ca7225a65533cbe03aed1f43fa7cd1ef178e1ec2de6076d3ec1a22729c8645de5442bc8e3c3c7781d68293d34ae667c247189089a4959ef7c0d35e4600be23b5b059629779d7d694820a408021ed575bd94e89af5672c9c4faaa93adc0849b643a13f8a5a00106f3b8583c3b187099347666d5b01b3ae85b5458a2291ca45884084bf8a728a0012d5ba14538fe600b4f258429247337527a13d6a28c3b4b445f00d3098df94fa0011a4647e1b61123ab33b318dff3609fc11da8c4cfa9abe25f99c41923a9f581a001cb8b689043f5bdcc56fce5c26490ca28a88b0a2f53a6d1f51e3f298e65d295a001531f010e1e10d3d3332b2caef340f0a6af1e366a98126ef035c3ce80b8a1db80a0bbe878a38e5cf8d2e439fe021d2063d07b41b2a2ffe78edde5e50ae8c908c6dfa00386dfa5733210ac6b5fb0ddc0fdd493190417ddbd8573c3db375b811b59f970", + "signatureLegacy": { + "r": "0x9eb445c3fb16cea6f435cca3fd89869351b0152442c77013ee2787ab9363c64f", + "s": "0x12daa8f1bbc55ef013376a0b10a608634e9fe03ce051bcf11874132f4b37b1c1", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x3aacb5053d4586e75d7c2f59a16aa559f1b335a1e5b81d5e04ee3f10370e0b78", + "s": "0x0c4062ee9c4f3c10b72331bdbbe8b8f896cecaa7f79d291dca3cb6182473d6f3", + "v": "0x29" + }, + "signatureBerlin": { + "r": "0xcc30fef0ed85c2d3df5dae8321402cd6ee6cfec5778a191674d295a861be14b3", + "s": "0x0874a36ad883e39d70744772063a504ff5887f020ece23afa159ec3d092f7dac", + "v": "0x0" + }, + "signatureLondon": { + "r": "0xfe006607f7e8089cc51cafca96b281cd8c3a95d6f88a5a1175b3a8cc958b6b74", + "s": "0x105054c0d7d120b19d8eb03a67dccd82c2add7b8c04e6438fd30ab6e31cd4364", + "v": "0x0" + }, + "signatureCancun": { + "r": "0xbbe878a38e5cf8d2e439fe021d2063d07b41b2a2ffe78edde5e50ae8c908c6df", + "s": "0x0386dfa5733210ac6b5fb0ddc0fdd493190417ddbd8573c3db375b811b59f970", + "v": "0x0" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_17.json b/bolt-contracts/test/testdata/transactions/random_17.json new file mode 100644 index 00000000..7f276271 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_17.json @@ -0,0 +1,92 @@ +{ + "name": "random-17", + "transaction": { + "to": "0x7b9830530eFD81a5BB21Ed03A1E20ac977c13003", + "nonce": 103, + "gasLimit": "0xa193e9", + "gasPrice": "0xfcb9", + "maxFeePerGas": "0x9288e311910556", + "maxPriorityFeePerGas": "0xac", + "data": "0xee2035dab48b94002f3fa4ba662590127a2fcb9e978af4", + "value": "0xf9eff8", + "accessList": [ + { + "address": "0x469ED43B08A100e13e84b7746fA7206d3A11a5F7", + "storageKeys": [ + "0x434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950", + "0x56498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5", + "0xe83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e" + ] + }, + { + "address": "0x588C330B029E06B820Dfb1d3a5b774EdcF6a9FEE", + "storageKeys": [ + "0x434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950", + "0x56498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5", + "0xe83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e" + ] + }, + { + "address": "0xd7Bb918eB068B37E44b12A19402F5112dE656566", + "storageKeys": [ + "0x434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950", + "0x56498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5", + "0xe83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e" + ] + }, + { + "address": "0x29EFB653e6b98eA36995EC81968b0EAC36678A60", + "storageKeys": [ + "0x434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950", + "0x56498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5", + "0xe83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e" + ] + } + ], + "chainId": "0x6653a6", + "maxFeePerBlobGas": "0xe34d8405aa", + "blobVersionedHashes": [ + "0x01bd0963b45ef67408366b1293b5f94b4fb19340d15f8337a4512a83ae40004d", + "0x013058ace831dd6002ac010bbe261fa4b1087a1a22ef376e8af21c68881cd6a6", + "0x01529e39d8bda59658a661cd10747b680b8f944a5f4276f794859265c718c25c", + "0x010b500df39903a4f96523b8fc5e742898222ec23fcc06facf7384ebd6712236", + "0x01d8fc2341c6b3a4c2aa2aba23344939f851119c19299c9aac4594425577e5ee" + ] + }, + "privateKey": "0x58f3d57fde2c0dae771d5cb66092b8905ba5691226740d7398459c60712a5793", + "unsignedLegacy": "0xf8396782fcb983a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af4", + "unsignedEip155": "0xf83f6782fcb983a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af4836653a68080", + "unsignedBerlin": "0x01f90230836653a66782fcb983a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af4f901f0f87a94469ed43b08a100e13e84b7746fa7206d3a11a5f7f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94588c330b029e06b820dfb1d3a5b774edcf6a9feef863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94d7bb918eb068b37e44b12a19402f5112de656566f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a9429efb653e6b98ea36995ec81968b0eac36678a60f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e", + "unsignedLondon": "0x02f90237836653a66781ac879288e31191055683a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af4f901f0f87a94469ed43b08a100e13e84b7746fa7206d3a11a5f7f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94588c330b029e06b820dfb1d3a5b774edcf6a9feef863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94d7bb918eb068b37e44b12a19402f5112de656566f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a9429efb653e6b98ea36995ec81968b0eac36678a60f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e", + "unsignedCancun": "0x03f902e4836653a66781ac879288e31191055683a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af4f901f0f87a94469ed43b08a100e13e84b7746fa7206d3a11a5f7f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94588c330b029e06b820dfb1d3a5b774edcf6a9feef863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94d7bb918eb068b37e44b12a19402f5112de656566f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a9429efb653e6b98ea36995ec81968b0eac36678a60f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e85e34d8405aaf8a5a001bd0963b45ef67408366b1293b5f94b4fb19340d15f8337a4512a83ae40004da0013058ace831dd6002ac010bbe261fa4b1087a1a22ef376e8af21c68881cd6a6a001529e39d8bda59658a661cd10747b680b8f944a5f4276f794859265c718c25ca0010b500df39903a4f96523b8fc5e742898222ec23fcc06facf7384ebd6712236a001d8fc2341c6b3a4c2aa2aba23344939f851119c19299c9aac4594425577e5ee", + "signedLegacy": "0xf87c6782fcb983a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af41ca0b889cf400786bc43a9bc32317a5368a1f0898b5f60fec9c4da7931867fe5c3fca06dd97c8b894c3a14ec5099eaa39b76f369f49c0ad9330dd852f797b22fb6962e", + "signedEip155": "0xf87f6782fcb983a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af483cca770a04ad07bd0c147962802aee8e943f48a5adfadbc5d14c502e10fe108b6a3206691a039150202e4bacfbda9757c56c93858d0dc2ae5c36d69e7f5d61e6d2fb9a4d7e0", + "signedBerlin": "0x01f90273836653a66782fcb983a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af4f901f0f87a94469ed43b08a100e13e84b7746fa7206d3a11a5f7f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94588c330b029e06b820dfb1d3a5b774edcf6a9feef863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94d7bb918eb068b37e44b12a19402f5112de656566f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a9429efb653e6b98ea36995ec81968b0eac36678a60f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e80a0bbeb29da87bb1efcc76efc18dc3fb4d06c2fbe9d0a8695e3bc887f84ab35796ea046f04724d13b40f6e5f8ca963862c821857f58772169706ab4a286feec54196f", + "signedLondon": "0x02f9027a836653a66781ac879288e31191055683a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af4f901f0f87a94469ed43b08a100e13e84b7746fa7206d3a11a5f7f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94588c330b029e06b820dfb1d3a5b774edcf6a9feef863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94d7bb918eb068b37e44b12a19402f5112de656566f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a9429efb653e6b98ea36995ec81968b0eac36678a60f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e80a0d6593cf036acec58fa43ac9b1a19b961b26acf1b27f23ed3cfa5fc2dd63b1b73a06cf24189b044480b469c1b6bbe97bd3caf522e0a9c141d9d8a5b7e5ad225bebc", + "signedCancun": "0x03f90327836653a66781ac879288e31191055683a193e9947b9830530efd81a5bb21ed03a1e20ac977c1300383f9eff897ee2035dab48b94002f3fa4ba662590127a2fcb9e978af4f901f0f87a94469ed43b08a100e13e84b7746fa7206d3a11a5f7f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94588c330b029e06b820dfb1d3a5b774edcf6a9feef863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a94d7bb918eb068b37e44b12a19402f5112de656566f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94ef87a9429efb653e6b98ea36995ec81968b0eac36678a60f863a0434cab87455b41c8023691c4e836ec1e1d90fd639e1207274b07574059394950a056498d76fcc165010f94437317015d8a9a939ab1fd21216c5fcfed335f5d6ad5a0e83f7815e6bf7d521dd0341e9445415ab565b2471ab4dbbf0a0ddcc564bdb94e85e34d8405aaf8a5a001bd0963b45ef67408366b1293b5f94b4fb19340d15f8337a4512a83ae40004da0013058ace831dd6002ac010bbe261fa4b1087a1a22ef376e8af21c68881cd6a6a001529e39d8bda59658a661cd10747b680b8f944a5f4276f794859265c718c25ca0010b500df39903a4f96523b8fc5e742898222ec23fcc06facf7384ebd6712236a001d8fc2341c6b3a4c2aa2aba23344939f851119c19299c9aac4594425577e5ee01a0cff1301e6d636143fc801005349c6d64687f4e6d0c3cf0efcaf4f04863adb321a00f46aa1d9c1c2006e42981f19e75db3c5087f7535b759faabafa3642cde03879", + "signatureLegacy": { + "r": "0xb889cf400786bc43a9bc32317a5368a1f0898b5f60fec9c4da7931867fe5c3fc", + "s": "0x6dd97c8b894c3a14ec5099eaa39b76f369f49c0ad9330dd852f797b22fb6962e", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x4ad07bd0c147962802aee8e943f48a5adfadbc5d14c502e10fe108b6a3206691", + "s": "0x39150202e4bacfbda9757c56c93858d0dc2ae5c36d69e7f5d61e6d2fb9a4d7e0", + "v": "0xcca770" + }, + "signatureBerlin": { + "r": "0xbbeb29da87bb1efcc76efc18dc3fb4d06c2fbe9d0a8695e3bc887f84ab35796e", + "s": "0x46f04724d13b40f6e5f8ca963862c821857f58772169706ab4a286feec54196f", + "v": "0x0" + }, + "signatureLondon": { + "r": "0xd6593cf036acec58fa43ac9b1a19b961b26acf1b27f23ed3cfa5fc2dd63b1b73", + "s": "0x6cf24189b044480b469c1b6bbe97bd3caf522e0a9c141d9d8a5b7e5ad225bebc", + "v": "0x0" + }, + "signatureCancun": { + "r": "0xcff1301e6d636143fc801005349c6d64687f4e6d0c3cf0efcaf4f04863adb321", + "s": "0x0f46aa1d9c1c2006e42981f19e75db3c5087f7535b759faabafa3642cde03879", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_18.json b/bolt-contracts/test/testdata/transactions/random_18.json new file mode 100644 index 00000000..7a6eaf1f --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_18.json @@ -0,0 +1,65 @@ +{ + "name": "random-18", + "transaction": { + "to": "0x0bbe326563703D26cB074Ef29Ed04404Ab1Fd0cC", + "nonce": 503, + "gasLimit": "0xa5cdc1", + "gasPrice": "0x2a", + "maxFeePerGas": "0x52b5f1114c1a", + "maxPriorityFeePerGas": "0x59d1ad", + "data": "0xb477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871", + "value": "0x8a1d", + "accessList": [ + { + "address": "0x47421DbF48444B1c15748fFB721AC9b341c35347", + "storageKeys": [ + "0x1e4e2be542b128bf053d245b5efe9be008785740189d3b5b2324a395630c3279", + "0xed8dbc976b685b16dc203291d38dd688d247ae09d2fea99189d5171ddcd7c90e", + "0x4ba4902e9df30d2ea5dc662cfa7887d327dc09fcd28d3dbf5c64f5e78f5e599b" + ] + } + ], + "chainId": "0x27", + "maxFeePerBlobGas": "0x6a1ab8a28e74c2", + "blobVersionedHashes": [ + "0x0135a251a4d47cbb2e3ec7eab672f3505d49261cb433895e559539ba21441daa", + "0x0125f41da5f8e7146e8e5e4508967f0379dd4ae378ddf56f6f379814c056913a" + ] + }, + "privateKey": "0xea795d7cacc6025f7bd6650aedd689f688617f9d8ca86236fa8ca5e654b767c4", + "unsignedLegacy": "0xf8418201f72a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871", + "unsignedEip155": "0xf8448201f72a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871278080", + "unsignedBerlin": "0x01f8c0278201f72a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871f87cf87a9447421dbf48444b1c15748ffb721ac9b341c35347f863a01e4e2be542b128bf053d245b5efe9be008785740189d3b5b2324a395630c3279a0ed8dbc976b685b16dc203291d38dd688d247ae09d2fea99189d5171ddcd7c90ea04ba4902e9df30d2ea5dc662cfa7887d327dc09fcd28d3dbf5c64f5e78f5e599b", + "unsignedLondon": "0x02f8ca278201f78359d1ad8652b5f1114c1a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871f87cf87a9447421dbf48444b1c15748ffb721ac9b341c35347f863a01e4e2be542b128bf053d245b5efe9be008785740189d3b5b2324a395630c3279a0ed8dbc976b685b16dc203291d38dd688d247ae09d2fea99189d5171ddcd7c90ea04ba4902e9df30d2ea5dc662cfa7887d327dc09fcd28d3dbf5c64f5e78f5e599b", + "unsignedCancun": "0x03f90116278201f78359d1ad8652b5f1114c1a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871f87cf87a9447421dbf48444b1c15748ffb721ac9b341c35347f863a01e4e2be542b128bf053d245b5efe9be008785740189d3b5b2324a395630c3279a0ed8dbc976b685b16dc203291d38dd688d247ae09d2fea99189d5171ddcd7c90ea04ba4902e9df30d2ea5dc662cfa7887d327dc09fcd28d3dbf5c64f5e78f5e599b876a1ab8a28e74c2f842a00135a251a4d47cbb2e3ec7eab672f3505d49261cb433895e559539ba21441daaa00125f41da5f8e7146e8e5e4508967f0379dd4ae378ddf56f6f379814c056913a", + "signedLegacy": "0xf8848201f72a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a8711ca0c888e9068c768fa7d14a6298902c6b4be841794498ab8f5a5b4ec8027197ee14a04561fbe2803fd2d4ffd8f491c6371816b213832776a93dc48c922887e8bbc671", + "signedEip155": "0xf8848201f72a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a87172a052aea6be6b07d11486dc584c42cf1bd34ff8ec9096894fbd34cb7cc0d1aecce8a074220e1ac0c3ef2b2b60d1dea95db96d17872e1a55dc55b4835333d2c4ecdf95", + "signedBerlin": "0x01f90103278201f72a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871f87cf87a9447421dbf48444b1c15748ffb721ac9b341c35347f863a01e4e2be542b128bf053d245b5efe9be008785740189d3b5b2324a395630c3279a0ed8dbc976b685b16dc203291d38dd688d247ae09d2fea99189d5171ddcd7c90ea04ba4902e9df30d2ea5dc662cfa7887d327dc09fcd28d3dbf5c64f5e78f5e599b80a0e6a87722ab1ce90d062a73fe2fe3ebf7135d9b3946b7bd7edb3b4b298504e8c5a01cfad4408ddaa8e38d031b99277a81b7cd118f760acc8946b5025d2d77200197", + "signedLondon": "0x02f9010d278201f78359d1ad8652b5f1114c1a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871f87cf87a9447421dbf48444b1c15748ffb721ac9b341c35347f863a01e4e2be542b128bf053d245b5efe9be008785740189d3b5b2324a395630c3279a0ed8dbc976b685b16dc203291d38dd688d247ae09d2fea99189d5171ddcd7c90ea04ba4902e9df30d2ea5dc662cfa7887d327dc09fcd28d3dbf5c64f5e78f5e599b01a0f8825407a5607db5184718258869e3ba1eef9bd4c1bf4826315cfc8693593894a07aad01abea832c052973a749a3a623d63922fbbb090f5bbdb4582992d5bd508f", + "signedCancun": "0x03f90159278201f78359d1ad8652b5f1114c1a83a5cdc1940bbe326563703d26cb074ef29ed04404ab1fd0cc828a1da0b477bf440adf79ace31d2590393c7bbd5c191c2e40b4523e94b9c75afce3a871f87cf87a9447421dbf48444b1c15748ffb721ac9b341c35347f863a01e4e2be542b128bf053d245b5efe9be008785740189d3b5b2324a395630c3279a0ed8dbc976b685b16dc203291d38dd688d247ae09d2fea99189d5171ddcd7c90ea04ba4902e9df30d2ea5dc662cfa7887d327dc09fcd28d3dbf5c64f5e78f5e599b876a1ab8a28e74c2f842a00135a251a4d47cbb2e3ec7eab672f3505d49261cb433895e559539ba21441daaa00125f41da5f8e7146e8e5e4508967f0379dd4ae378ddf56f6f379814c056913a01a0dd72f86ce46f065e917d86c73aa3ca7e683bfeb711a84bc10d3f253161a30cdaa00c4e90ba71f6c3ee0f989353e221408330e877d65cbd0adea67e2414dd5308d7", + "signatureLegacy": { + "r": "0xc888e9068c768fa7d14a6298902c6b4be841794498ab8f5a5b4ec8027197ee14", + "s": "0x4561fbe2803fd2d4ffd8f491c6371816b213832776a93dc48c922887e8bbc671", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x52aea6be6b07d11486dc584c42cf1bd34ff8ec9096894fbd34cb7cc0d1aecce8", + "s": "0x74220e1ac0c3ef2b2b60d1dea95db96d17872e1a55dc55b4835333d2c4ecdf95", + "v": "0x72" + }, + "signatureBerlin": { + "r": "0xe6a87722ab1ce90d062a73fe2fe3ebf7135d9b3946b7bd7edb3b4b298504e8c5", + "s": "0x1cfad4408ddaa8e38d031b99277a81b7cd118f760acc8946b5025d2d77200197", + "v": "0x0" + }, + "signatureLondon": { + "r": "0xf8825407a5607db5184718258869e3ba1eef9bd4c1bf4826315cfc8693593894", + "s": "0x7aad01abea832c052973a749a3a623d63922fbbb090f5bbdb4582992d5bd508f", + "v": "0x1" + }, + "signatureCancun": { + "r": "0xdd72f86ce46f065e917d86c73aa3ca7e683bfeb711a84bc10d3f253161a30cda", + "s": "0x0c4e90ba71f6c3ee0f989353e221408330e877d65cbd0adea67e2414dd5308d7", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_19.json b/bolt-contracts/test/testdata/transactions/random_19.json new file mode 100644 index 00000000..5a46f993 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_19.json @@ -0,0 +1,73 @@ +{ + "name": "random-19", + "transaction": { + "to": "0x6D9186AD35Ba39086D341c03B212a22dAd55A70c", + "nonce": 47, + "gasLimit": "0x8e2d", + "gasPrice": "0xed", + "maxFeePerGas": "0x8f001cace664", + "maxPriorityFeePerGas": "0x86495d", + "data": "0xa6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad9", + "value": "0x4028", + "accessList": [ + { + "address": "0x27CBC99f4161665Fc37a013015B0B99A959f6fcb", + "storageKeys": [] + }, + { + "address": "0x296e9Be34584A14761c7b4cE82E99d4394A5f109", + "storageKeys": [] + }, + { + "address": "0xeD1C55cDE477E627081Ac4D17376f4Bf9A2dc51E", + "storageKeys": [] + }, + { + "address": "0x7a46971171Aa87E7Ef026C381053940714f4Ad91", + "storageKeys": [] + } + ], + "chainId": "0xf9bf2e", + "maxFeePerBlobGas": "0xfcaa613f0b5f", + "blobVersionedHashes": [ + "0x010e2214c267eb6c514aaf6eab956c7043760e0cf06f8b854ce38a637c886a92", + "0x01971b32a91a83e04ef14d049bf10a13377c3f18bde9c5ea313f8c2da061bb62" + ] + }, + "privateKey": "0x1b01010d8955e5cecc6705b73064baa37a703d65cb970a5b97c1cc9b76aa9473", + "unsignedLegacy": "0xf89d2f81ed828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad9", + "unsignedEip155": "0xf8a32f81ed828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad983f9bf2e8080", + "unsignedBerlin": "0x01f8ff83f9bf2e2f81ed828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad9f85cd69427cbc99f4161665fc37a013015b0b99a959f6fcbc0d694296e9be34584a14761c7b4ce82e99d4394a5f109c0d694ed1c55cde477e627081ac4d17376f4bf9a2dc51ec0d6947a46971171aa87e7ef026c381053940714f4ad91c0", + "unsignedLondon": "0x02f9010883f9bf2e2f8386495d868f001cace664828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad9f85cd69427cbc99f4161665fc37a013015b0b99a959f6fcbc0d694296e9be34584a14761c7b4ce82e99d4394a5f109c0d694ed1c55cde477e627081ac4d17376f4bf9a2dc51ec0d6947a46971171aa87e7ef026c381053940714f4ad91c0", + "unsignedCancun": "0x03f9015383f9bf2e2f8386495d868f001cace664828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad9f85cd69427cbc99f4161665fc37a013015b0b99a959f6fcbc0d694296e9be34584a14761c7b4ce82e99d4394a5f109c0d694ed1c55cde477e627081ac4d17376f4bf9a2dc51ec0d6947a46971171aa87e7ef026c381053940714f4ad91c086fcaa613f0b5ff842a0010e2214c267eb6c514aaf6eab956c7043760e0cf06f8b854ce38a637c886a92a001971b32a91a83e04ef14d049bf10a13377c3f18bde9c5ea313f8c2da061bb62", + "signedLegacy": "0xf8e02f81ed828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad91ba0804162984a09f440a312f2231b192dc7b43fb49546ede924e1ef2b4b54abcd31a04635d7370c171b9e6ac7fa3bca544d0c227d32f0a1c5d065cc0bb02b79e8eaa1", + "signedEip155": "0xf8e42f81ed828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad98401f37e80a05914063f10cf79eea0d3c5cf10bf7765ffc648638c656ddf0c678057b6d570aaa00a89d79bcfa95f96290ec7938ab7c5552423736a16e0a39d84b140c5307a8bab", + "signedBerlin": "0x01f9014283f9bf2e2f81ed828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad9f85cd69427cbc99f4161665fc37a013015b0b99a959f6fcbc0d694296e9be34584a14761c7b4ce82e99d4394a5f109c0d694ed1c55cde477e627081ac4d17376f4bf9a2dc51ec0d6947a46971171aa87e7ef026c381053940714f4ad91c080a0888f5e0b4c258b4f7c488d4e1f7dafc82d7835381b5470bc1e9571ad6bd21929a07a8a19227f4f2cb93bccbc7b4bcb0b731701a0284df8ed3fb90936e6ac0a18d1", + "signedLondon": "0x02f9014b83f9bf2e2f8386495d868f001cace664828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad9f85cd69427cbc99f4161665fc37a013015b0b99a959f6fcbc0d694296e9be34584a14761c7b4ce82e99d4394a5f109c0d694ed1c55cde477e627081ac4d17376f4bf9a2dc51ec0d6947a46971171aa87e7ef026c381053940714f4ad91c001a0f9ba41389da7c4a5471d8af8235fb765d90ec76b370516ec0108d43eda880c84a00bca4f8cb35a6023cbeee50d38e0b62588b6cfc47d3e8023413f2bdfb04f3a8e", + "signedCancun": "0x03f9019683f9bf2e2f8386495d868f001cace664828e2d946d9186ad35ba39086d341c03b212a22dad55a70c824028b87da6e0079be77374ee2617550eadd15e206a8c7eb76eca2de96d48c4824b4646206720dfeb24956f1e712b58b9ef96fc92e637cf4c30614d86532d3110f670c5a70e5bdeef3dc5cf94ef8d3afffc50151c00a5ad1289fae8168bb120e9dbdb24c422eacfc4d8291c6dc942a872545c76b5c697806c84f478d361026a2ad9f85cd69427cbc99f4161665fc37a013015b0b99a959f6fcbc0d694296e9be34584a14761c7b4ce82e99d4394a5f109c0d694ed1c55cde477e627081ac4d17376f4bf9a2dc51ec0d6947a46971171aa87e7ef026c381053940714f4ad91c086fcaa613f0b5ff842a0010e2214c267eb6c514aaf6eab956c7043760e0cf06f8b854ce38a637c886a92a001971b32a91a83e04ef14d049bf10a13377c3f18bde9c5ea313f8c2da061bb6201a0e5af277a499dbd89c8b25adfab873a4bade8e963e403dbaaba3398c1b4f6d0c1a00282b21217a21a6e57c3713da3700265dc4e86803f364175d26d3ab727f812e3", + "signatureLegacy": { + "r": "0x804162984a09f440a312f2231b192dc7b43fb49546ede924e1ef2b4b54abcd31", + "s": "0x4635d7370c171b9e6ac7fa3bca544d0c227d32f0a1c5d065cc0bb02b79e8eaa1", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0x5914063f10cf79eea0d3c5cf10bf7765ffc648638c656ddf0c678057b6d570aa", + "s": "0x0a89d79bcfa95f96290ec7938ab7c5552423736a16e0a39d84b140c5307a8bab", + "v": "0x1f37e80" + }, + "signatureBerlin": { + "r": "0x888f5e0b4c258b4f7c488d4e1f7dafc82d7835381b5470bc1e9571ad6bd21929", + "s": "0x7a8a19227f4f2cb93bccbc7b4bcb0b731701a0284df8ed3fb90936e6ac0a18d1", + "v": "0x0" + }, + "signatureLondon": { + "r": "0xf9ba41389da7c4a5471d8af8235fb765d90ec76b370516ec0108d43eda880c84", + "s": "0x0bca4f8cb35a6023cbeee50d38e0b62588b6cfc47d3e8023413f2bdfb04f3a8e", + "v": "0x1" + }, + "signatureCancun": { + "r": "0xe5af277a499dbd89c8b25adfab873a4bade8e963e403dbaaba3398c1b4f6d0c1", + "s": "0x0282b21217a21a6e57c3713da3700265dc4e86803f364175d26d3ab727f812e3", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_2.json b/bolt-contracts/test/testdata/transactions/random_2.json new file mode 100644 index 00000000..f42ea1ed --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_2.json @@ -0,0 +1,64 @@ +{ + "name": "random-2", + "transaction": { + "to": "0xD0F118AFa9C2c9cc50F10d94cCC1cbDda2758b36", + "nonce": 15, + "gasLimit": "0x331bce0f90", + "gasPrice": "0xe15a1b", + "maxFeePerGas": "0x58e8d1dda1", + "maxPriorityFeePerGas": "0x91bcff", + "data": "0xe0d1a7227d34c2ca72e3c0", + "value": "0x91e32e2f5a", + "accessList": [ + { + "address": "0x032f5546f1B932555cB43e2b16C844d118078430", + "storageKeys": [] + } + ], + "chainId": "0xac9f74e3", + "maxFeePerBlobGas": "0xb301566e1b", + "blobVersionedHashes": [ + "0x01ffa0354a85a918e71cda7e37145c0a2f7c6fb1f10ff992ef1de8ebe3c40fd5", + "0x01cf50b584016c19732d845cc9c8d3a43ce413626a4f67acb98ccb3b2f1843cd", + "0x01d391295779890c162f2833ea186b025e6808b615b03854e2ec2664686711bc", + "0x01eac2c29509cb2843deba916c97d9607d460eb0cd6e58744d823f568ab4e89e", + "0x01873bc19156620621a96fe8bc4a0038cbac0737aa0453777816cc6ba916e9c2" + ] + }, + "privateKey": "0xa248ca1e9bd9c10fb163baefd567da6658f7419f3b7ec8bb13800ef2c546cdc9", + "unsignedLegacy": "0xf20f83e15a1b85331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c0", + "unsignedEip155": "0xf8390f83e15a1b85331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c084ac9f74e38080", + "unsignedBerlin": "0x01f84f84ac9f74e30f83e15a1b85331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c0d7d694032f5546f1b932555cb43e2b16c844d118078430c0", + "unsignedLondon": "0x02f85584ac9f74e30f8391bcff8558e8d1dda185331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c0d7d694032f5546f1b932555cb43e2b16c844d118078430c0", + "unsignedCancun": "0x03f9010284ac9f74e30f8391bcff8558e8d1dda185331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c0d7d694032f5546f1b932555cb43e2b16c844d118078430c085b301566e1bf8a5a001ffa0354a85a918e71cda7e37145c0a2f7c6fb1f10ff992ef1de8ebe3c40fd5a001cf50b584016c19732d845cc9c8d3a43ce413626a4f67acb98ccb3b2f1843cda001d391295779890c162f2833ea186b025e6808b615b03854e2ec2664686711bca001eac2c29509cb2843deba916c97d9607d460eb0cd6e58744d823f568ab4e89ea001873bc19156620621a96fe8bc4a0038cbac0737aa0453777816cc6ba916e9c2", + "signedLegacy": "0xf8750f83e15a1b85331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c01ba0bde01f2c9907b076015708bff05e24058fd153bfc2f551a0adafcd7d61a088a0a01035bfd65df2799749536217c832d8d81b915448ac0ab31935d50917136e4c18", + "signedEip155": "0xf87a0f83e15a1b85331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c08501593ee9e9a0f42dbeea4337d8b48ed8f2bc257c83eb16725af6f3077e99fba6bac48c5e65f8a01869eaf77bc621843ba6c8b23919f7c9ebf0ac0001a840045609e1e96f14ab5a", + "signedBerlin": "0x01f89284ac9f74e30f83e15a1b85331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c0d7d694032f5546f1b932555cb43e2b16c844d118078430c080a05cc5457e6561e9831b8e52fb09765dc00eaa07ba68f05dc7558ad0dab2d2b8c3a020c19425fafafdc458dd119f6a59780fc4dd3bbd7ae65f351d3adf5b217d2f4e", + "signedLondon": "0x02f89884ac9f74e30f8391bcff8558e8d1dda185331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c0d7d694032f5546f1b932555cb43e2b16c844d118078430c001a0e97853a3f394ebb19b1a152324c7f3f7ffde2e2a0dfa295dc61f8788dcfebe00a02f0c9626e967c4494ccd02f4e60c840ecce64216438f051efa95f0b8f196f7c9", + "signedCancun": "0x03f9014584ac9f74e30f8391bcff8558e8d1dda185331bce0f9094d0f118afa9c2c9cc50f10d94ccc1cbdda2758b368591e32e2f5a8be0d1a7227d34c2ca72e3c0d7d694032f5546f1b932555cb43e2b16c844d118078430c085b301566e1bf8a5a001ffa0354a85a918e71cda7e37145c0a2f7c6fb1f10ff992ef1de8ebe3c40fd5a001cf50b584016c19732d845cc9c8d3a43ce413626a4f67acb98ccb3b2f1843cda001d391295779890c162f2833ea186b025e6808b615b03854e2ec2664686711bca001eac2c29509cb2843deba916c97d9607d460eb0cd6e58744d823f568ab4e89ea001873bc19156620621a96fe8bc4a0038cbac0737aa0453777816cc6ba916e9c201a0840ee8400c949196bddbf386e82d5479a7607e5356f03a03360af4c466b309eaa026456727b69c25a095f29fed6375752693270a9989bfa3bb45fa01df37faf4dd", + "signatureLegacy": { + "r": "0xbde01f2c9907b076015708bff05e24058fd153bfc2f551a0adafcd7d61a088a0", + "s": "0x1035bfd65df2799749536217c832d8d81b915448ac0ab31935d50917136e4c18", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0xf42dbeea4337d8b48ed8f2bc257c83eb16725af6f3077e99fba6bac48c5e65f8", + "s": "0x1869eaf77bc621843ba6c8b23919f7c9ebf0ac0001a840045609e1e96f14ab5a", + "v": "0x1593ee9e9" + }, + "signatureBerlin": { + "r": "0x5cc5457e6561e9831b8e52fb09765dc00eaa07ba68f05dc7558ad0dab2d2b8c3", + "s": "0x20c19425fafafdc458dd119f6a59780fc4dd3bbd7ae65f351d3adf5b217d2f4e", + "v": "0x0" + }, + "signatureLondon": { + "r": "0xe97853a3f394ebb19b1a152324c7f3f7ffde2e2a0dfa295dc61f8788dcfebe00", + "s": "0x2f0c9626e967c4494ccd02f4e60c840ecce64216438f051efa95f0b8f196f7c9", + "v": "0x1" + }, + "signatureCancun": { + "r": "0x840ee8400c949196bddbf386e82d5479a7607e5356f03a03360af4c466b309ea", + "s": "0x26456727b69c25a095f29fed6375752693270a9989bfa3bb45fa01df37faf4dd", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_20.json b/bolt-contracts/test/testdata/transactions/random_20.json new file mode 100644 index 00000000..75ecbcc3 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_20.json @@ -0,0 +1,75 @@ +{ + "name": "random-20", + "transaction": { + "to": "0x60fC630156D46bF9b1BF5B7d251C6CbE64702BF3", + "nonce": 812, + "gasLimit": "0xe010b5", + "gasPrice": "0x41f1af255d", + "maxFeePerGas": "0xc2214fa5", + "maxPriorityFeePerGas": "0x4a", + "data": "0x647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d94", + "value": "0x6e7b", + "accessList": [ + { + "address": "0x36aAaa454aAB9A9409b890C32E9304C42EC8b05A", + "storageKeys": [] + }, + { + "address": "0x7F7Ac0f60Be35f1e8F7c70A7AA5d596bC7648745", + "storageKeys": [] + }, + { + "address": "0xf9Fb9Bb09b08C0Fa137E76615BBd50B5cc63BCc4", + "storageKeys": [] + }, + { + "address": "0x69C6c93f57A0C11a765F2B9076a9575c4b015d03", + "storageKeys": [] + } + ], + "chainId": "0x08454b", + "maxFeePerBlobGas": "0xdd2ab7977e4979", + "blobVersionedHashes": [ + "0x013b327d88c9e88e3e246eeca1cc70db85b0bb0f98984ad796047d4baaea4373", + "0x01b7bd6841fda1dfb6cebfe85366cedd754408fdf1431865ab3a5744a4e17507", + "0x01136b560d707867f29fdaa25db50e2b926bb89e032a28fbd78f06a995088288", + "0x01d5dc7ebc9a67d8b006f15c809dfb1e4dfc5298eb1ba049d24847314bb3ac62" + ] + }, + "privateKey": "0x6efb2ce4981ad5555974b8b6b4f767d774c32f9e09e0009d5d914e29614ec739", + "unsignedLegacy": "0xf89e82032c8541f1af255d83e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d94", + "unsignedEip155": "0xf8a482032c8541f1af255d83e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d948308454b8080", + "unsignedBerlin": "0x01f901008308454b82032c8541f1af255d83e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d94f85cd69436aaaa454aab9a9409b890c32e9304c42ec8b05ac0d6947f7ac0f60be35f1e8f7c70a7aa5d596bc7648745c0d694f9fb9bb09b08c0fa137e76615bbd50b5cc63bcc4c0d69469c6c93f57a0c11a765f2b9076a9575c4b015d03c0", + "unsignedLondon": "0x02f901008308454b82032c4a84c2214fa583e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d94f85cd69436aaaa454aab9a9409b890c32e9304c42ec8b05ac0d6947f7ac0f60be35f1e8f7c70a7aa5d596bc7648745c0d694f9fb9bb09b08c0fa137e76615bbd50b5cc63bcc4c0d69469c6c93f57a0c11a765f2b9076a9575c4b015d03c0", + "unsignedCancun": "0x03f9018e8308454b82032c4a84c2214fa583e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d94f85cd69436aaaa454aab9a9409b890c32e9304c42ec8b05ac0d6947f7ac0f60be35f1e8f7c70a7aa5d596bc7648745c0d694f9fb9bb09b08c0fa137e76615bbd50b5cc63bcc4c0d69469c6c93f57a0c11a765f2b9076a9575c4b015d03c087dd2ab7977e4979f884a0013b327d88c9e88e3e246eeca1cc70db85b0bb0f98984ad796047d4baaea4373a001b7bd6841fda1dfb6cebfe85366cedd754408fdf1431865ab3a5744a4e17507a001136b560d707867f29fdaa25db50e2b926bb89e032a28fbd78f06a995088288a001d5dc7ebc9a67d8b006f15c809dfb1e4dfc5298eb1ba049d24847314bb3ac62", + "signedLegacy": "0xf8e182032c8541f1af255d83e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d941ca0707fd3dbc3b260752493e64be389a2689bf3b8b181a4e7baa7eeb0176ba84283a04868672b9d487c34906166770fd51f0598b026b3368bb5f4d0a99ca4fc0706e9", + "signedEip155": "0xf8e482032c8541f1af255d83e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d9483108abaa014c49179d7be5caf2590610b76eeace610c536ff3e1d1eab3b43c164fe90e472a06bb4caad9a679371ce6527da4f3a404d3cd1b36712a47774112f19add1ca4d2e", + "signedBerlin": "0x01f901438308454b82032c8541f1af255d83e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d94f85cd69436aaaa454aab9a9409b890c32e9304c42ec8b05ac0d6947f7ac0f60be35f1e8f7c70a7aa5d596bc7648745c0d694f9fb9bb09b08c0fa137e76615bbd50b5cc63bcc4c0d69469c6c93f57a0c11a765f2b9076a9575c4b015d03c001a0b445c3c80cfa7df6401a7f0c46094a0fcb63749ff073b44d72c6d1f88f5212a6a07d418e8c1f5bb3a928ea11e3049943f7c60bacbaef1c78c90f9899331574336e", + "signedLondon": "0x02f901438308454b82032c4a84c2214fa583e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d94f85cd69436aaaa454aab9a9409b890c32e9304c42ec8b05ac0d6947f7ac0f60be35f1e8f7c70a7aa5d596bc7648745c0d694f9fb9bb09b08c0fa137e76615bbd50b5cc63bcc4c0d69469c6c93f57a0c11a765f2b9076a9575c4b015d03c080a0dafce44a782685fd338895386a5b13b4183706b3621c55b92dc0e43b3dd947d0a0697a9b17a80710efd85c62104a68156c67399c69b50bc951c4888a2f6446cad4", + "signedCancun": "0x03f901d18308454b82032c4a84c2214fa583e010b59460fc630156d46bf9b1bf5b7d251c6cbe64702bf3826e7bb877647daf6b789306d2daeb51be942c40d66194d5e0e9dca946aa830d686d493c1d1a07090d9cde8d73c6b982f5d00161b6ee0b302cdc24f29ebd146e99149adc7666f4d1d12146f077cc6e7f78addae71d399b445a14ff15a67efb8f39dcfd32af41968639dd3665d282e4065caef58441e6ac3ebc4b8d94f85cd69436aaaa454aab9a9409b890c32e9304c42ec8b05ac0d6947f7ac0f60be35f1e8f7c70a7aa5d596bc7648745c0d694f9fb9bb09b08c0fa137e76615bbd50b5cc63bcc4c0d69469c6c93f57a0c11a765f2b9076a9575c4b015d03c087dd2ab7977e4979f884a0013b327d88c9e88e3e246eeca1cc70db85b0bb0f98984ad796047d4baaea4373a001b7bd6841fda1dfb6cebfe85366cedd754408fdf1431865ab3a5744a4e17507a001136b560d707867f29fdaa25db50e2b926bb89e032a28fbd78f06a995088288a001d5dc7ebc9a67d8b006f15c809dfb1e4dfc5298eb1ba049d24847314bb3ac6201a0ffd7654221802fa30c1c1be235fb78ca7b16d538a395476d890f0ff4132e852da05977fdaa1bf697432d5c6533adb63e77251c2ca149b2b2a629c752838a36f749", + "signatureLegacy": { + "r": "0x707fd3dbc3b260752493e64be389a2689bf3b8b181a4e7baa7eeb0176ba84283", + "s": "0x4868672b9d487c34906166770fd51f0598b026b3368bb5f4d0a99ca4fc0706e9", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x14c49179d7be5caf2590610b76eeace610c536ff3e1d1eab3b43c164fe90e472", + "s": "0x6bb4caad9a679371ce6527da4f3a404d3cd1b36712a47774112f19add1ca4d2e", + "v": "0x108aba" + }, + "signatureBerlin": { + "r": "0xb445c3c80cfa7df6401a7f0c46094a0fcb63749ff073b44d72c6d1f88f5212a6", + "s": "0x7d418e8c1f5bb3a928ea11e3049943f7c60bacbaef1c78c90f9899331574336e", + "v": "0x1" + }, + "signatureLondon": { + "r": "0xdafce44a782685fd338895386a5b13b4183706b3621c55b92dc0e43b3dd947d0", + "s": "0x697a9b17a80710efd85c62104a68156c67399c69b50bc951c4888a2f6446cad4", + "v": "0x0" + }, + "signatureCancun": { + "r": "0xffd7654221802fa30c1c1be235fb78ca7b16d538a395476d890f0ff4132e852d", + "s": "0x5977fdaa1bf697432d5c6533adb63e77251c2ca149b2b2a629c752838a36f749", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_3.json b/bolt-contracts/test/testdata/transactions/random_3.json new file mode 100644 index 00000000..4fdd11f6 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_3.json @@ -0,0 +1,58 @@ +{ + "name": "random-3", + "transaction": { + "to": "0x8Bee13B1D7E29953a7484A3aE8e344D86b4Ad2C5", + "nonce": 530, + "gasLimit": "0xccb4", + "gasPrice": "0x18956c24", + "maxFeePerGas": "0x57f3c57a41", + "maxPriorityFeePerGas": "0x5a492a", + "data": "0x4c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbd", + "value": "0x3b04", + "accessList": [], + "chainId": "0xb3", + "maxFeePerBlobGas": "0x7b0f34f9", + "blobVersionedHashes": [ + "0x01b64c9600d28c83309131198d984f79284d6e2a5dd8ffeebc05f8bdcc21b03b", + "0x013305753b09589c2a8015bb6f975e2654a2164a41dc51812a439560bdd6d16d", + "0x013e6ffbf81a5911cc365712aa5511e93c28b14e4ead53ac786db6506caa1b4a", + "0x0146c688afbb49d2c0798642bbdbe25bfe7cdaa37632c32023aacce933f48dae" + ] + }, + "privateKey": "0xa9e5fdc17c2302fce888f2dc9d6ec2b3d3fc06aa212ec06b07f4035f64fcc58f", + "unsignedLegacy": "0xf8688202128418956c2482ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbd", + "unsignedEip155": "0xf86c8202128418956c2482ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbd81b38080", + "unsignedBerlin": "0x01f86b81b38202128418956c2482ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbdc0", + "unsignedLondon": "0x02f87081b3820212835a492a8557f3c57a4182ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbdc0", + "unsignedCancun": "0x03f8fb81b3820212835a492a8557f3c57a4182ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbdc0847b0f34f9f884a001b64c9600d28c83309131198d984f79284d6e2a5dd8ffeebc05f8bdcc21b03ba0013305753b09589c2a8015bb6f975e2654a2164a41dc51812a439560bdd6d16da0013e6ffbf81a5911cc365712aa5511e93c28b14e4ead53ac786db6506caa1b4aa00146c688afbb49d2c0798642bbdbe25bfe7cdaa37632c32023aacce933f48dae", + "signedLegacy": "0xf8ab8202128418956c2482ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbd1ca07be350194f44b6a86cd7199f2c6a2dea34815d20abbd0f389cf3c55ef5a13566a0239482099fd9289999f06db6fb95194ac1a92fcd13c1639d2e99e3b66ab2f0b1", + "signedEip155": "0xf8ad8202128418956c2482ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbd820189a0541bc2b78ae53dd11ac2c9845fe30878c493d34311513dfda43a92dbee1b4121a03f4ff8d77c247fc2238c02e2d5ca68dcd77e8f7a20d0d2f99145925af07beec0", + "signedBerlin": "0x01f8ae81b38202128418956c2482ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbdc001a035a7324dd7552976ee86c94623e89be43fddfa1ceed1354822a33726db13d9fba047347aee2460910314bbf20fbc091befb91a0ac236d30905312f828af49b2420", + "signedLondon": "0x02f8b381b3820212835a492a8557f3c57a4182ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbdc080a0c458cee1b97cfb1f6fa52b2adaa135d8501d63ba908c113f48796d40884496b1a03abaf292f68e0fc6a5c1012455d49d2d566cb4cf2eeebc8d52f1f5e3e20c808b", + "signedCancun": "0x03f9013e81b3820212835a492a8557f3c57a4182ccb4948bee13b1d7e29953a7484a3ae8e344d86b4ad2c5823b04b8434c4aaeceaa35f9cd275639e2319057a18f3c4d8bf242707b08a1a2a32531d3975a4dc67b8a92f5a11adbf12b6f8d8809d1544aed6f9da9b1f5e753307165e3e85afdbdc0847b0f34f9f884a001b64c9600d28c83309131198d984f79284d6e2a5dd8ffeebc05f8bdcc21b03ba0013305753b09589c2a8015bb6f975e2654a2164a41dc51812a439560bdd6d16da0013e6ffbf81a5911cc365712aa5511e93c28b14e4ead53ac786db6506caa1b4aa00146c688afbb49d2c0798642bbdbe25bfe7cdaa37632c32023aacce933f48dae01a0fb445840df9e94369942979f7c47b640f948a2fe812b497350ce00a04d0205ffa02c555565381a70547f13b807647a202705f67535104fa92524c5bd5507ba010f", + "signatureLegacy": { + "r": "0x7be350194f44b6a86cd7199f2c6a2dea34815d20abbd0f389cf3c55ef5a13566", + "s": "0x239482099fd9289999f06db6fb95194ac1a92fcd13c1639d2e99e3b66ab2f0b1", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x541bc2b78ae53dd11ac2c9845fe30878c493d34311513dfda43a92dbee1b4121", + "s": "0x3f4ff8d77c247fc2238c02e2d5ca68dcd77e8f7a20d0d2f99145925af07beec0", + "v": "0x189" + }, + "signatureBerlin": { + "r": "0x35a7324dd7552976ee86c94623e89be43fddfa1ceed1354822a33726db13d9fb", + "s": "0x47347aee2460910314bbf20fbc091befb91a0ac236d30905312f828af49b2420", + "v": "0x1" + }, + "signatureLondon": { + "r": "0xc458cee1b97cfb1f6fa52b2adaa135d8501d63ba908c113f48796d40884496b1", + "s": "0x3abaf292f68e0fc6a5c1012455d49d2d566cb4cf2eeebc8d52f1f5e3e20c808b", + "v": "0x0" + }, + "signatureCancun": { + "r": "0xfb445840df9e94369942979f7c47b640f948a2fe812b497350ce00a04d0205ff", + "s": "0x2c555565381a70547f13b807647a202705f67535104fa92524c5bd5507ba010f", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_4.json b/bolt-contracts/test/testdata/transactions/random_4.json new file mode 100644 index 00000000..d5eb37ae --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_4.json @@ -0,0 +1,58 @@ +{ + "name": "random-4", + "transaction": { + "to": "0xf5c58b3aC42d718024e914d90a0C17CeB4487F08", + "nonce": 150, + "gasLimit": "0x9b", + "gasPrice": "0x75fa", + "maxFeePerGas": "0x92719aae8f72c2", + "maxPriorityFeePerGas": "0xa16d", + "data": "0xfdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8a", + "value": "0x9c5b0d", + "accessList": [], + "chainId": "0x100800", + "maxFeePerBlobGas": "0xeac37693", + "blobVersionedHashes": [ + "0x017a6fb74091418b95e7679cdb19efd23cb1a7de4f8d818ae3206e33b8e524eb", + "0x01e4398d25da2fec20b713fe51b4cc7f555a473c4928e7e5a0f7be47761d4d9c", + "0x01fa7aff790b19c63de804524b5e37b459fd5b8614008d0ef4fd513dcb9361fc", + "0x01af1c40ffd00db8e91a537456d387c8e788276b13212ce917514456bb7b69bb" + ] + }, + "privateKey": "0xaf7e4892d96c6cd39bb8048b699386b24539fb8fb078f67e190fd3703f972f55", + "unsignedLegacy": "0xf88381968275fa819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8a", + "unsignedEip155": "0xf88981968275fa819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8a831008008080", + "unsignedBerlin": "0x01f8888310080081968275fa819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8ac0", + "unsignedLondon": "0x02f89083100800819682a16d8792719aae8f72c2819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8ac0", + "unsignedCancun": "0x03f9011b83100800819682a16d8792719aae8f72c2819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8ac084eac37693f884a0017a6fb74091418b95e7679cdb19efd23cb1a7de4f8d818ae3206e33b8e524eba001e4398d25da2fec20b713fe51b4cc7f555a473c4928e7e5a0f7be47761d4d9ca001fa7aff790b19c63de804524b5e37b459fd5b8614008d0ef4fd513dcb9361fca001af1c40ffd00db8e91a537456d387c8e788276b13212ce917514456bb7b69bb", + "signedLegacy": "0xf8c681968275fa819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8a1ba079230da6c89f320a59fe2f291f51e758e1e642851e2c6b6b8c4b3a32b1a75c4ba04a160e0e100e4244596580586abe09d7d3423e967ca417d3d3980a6609e94030", + "signedEip155": "0xf8c981968275fa819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8a83201023a08cbd6e5a98913d543e56fc8b8865adb020e081501c3549d54bfa5f1250666e84a04c364c7a1fdbc76a890b4468e2f7957fb340c78ea98793c304141a449adfa9b0", + "signedBerlin": "0x01f8cb8310080081968275fa819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8ac080a05c5fd1ac646c437d17e22ea102147265371d1358814c57346d1448ed6703d042a01e525dbe3024c1ac10b1229c7d69b4af119c60ae3b45eab73ee9c61926dbd91a", + "signedLondon": "0x02f8d383100800819682a16d8792719aae8f72c2819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8ac080a0c5817c5fca256b8084f994686f21a22e815f49049c1d7126dba60578a8dcecfba07756dd3accb21c6994c079795e3edc068e1c434c33109580215073701958f29d", + "signedCancun": "0x03f9015e83100800819682a16d8792719aae8f72c2819b94f5c58b3ac42d718024e914d90a0c17ceb4487f08839c5b0db861fdcd0c62ddc8b8c99d6768d3fe3097a66b388998e8f6294b69c95751da898430b9c9e7b02602393a9dc2026918c7741f4097e1de373a5b8d884d02e66b06742b29cc539a22675f5713a1ba9d247b9c9eaabf54f9cb48cc8f7429c80c31b3cbfa8ac084eac37693f884a0017a6fb74091418b95e7679cdb19efd23cb1a7de4f8d818ae3206e33b8e524eba001e4398d25da2fec20b713fe51b4cc7f555a473c4928e7e5a0f7be47761d4d9ca001fa7aff790b19c63de804524b5e37b459fd5b8614008d0ef4fd513dcb9361fca001af1c40ffd00db8e91a537456d387c8e788276b13212ce917514456bb7b69bb01a0b96f5303bcbb749f5fbf6c1d918eb08bfefe05242bfd2c4b9a9a55efb5b686ffa050b83d2a4dfcaa66b0339df55910ea553bbce6f22d4ab5e8c8562ddb15a03999", + "signatureLegacy": { + "r": "0x79230da6c89f320a59fe2f291f51e758e1e642851e2c6b6b8c4b3a32b1a75c4b", + "s": "0x4a160e0e100e4244596580586abe09d7d3423e967ca417d3d3980a6609e94030", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0x8cbd6e5a98913d543e56fc8b8865adb020e081501c3549d54bfa5f1250666e84", + "s": "0x4c364c7a1fdbc76a890b4468e2f7957fb340c78ea98793c304141a449adfa9b0", + "v": "0x201023" + }, + "signatureBerlin": { + "r": "0x5c5fd1ac646c437d17e22ea102147265371d1358814c57346d1448ed6703d042", + "s": "0x1e525dbe3024c1ac10b1229c7d69b4af119c60ae3b45eab73ee9c61926dbd91a", + "v": "0x0" + }, + "signatureLondon": { + "r": "0xc5817c5fca256b8084f994686f21a22e815f49049c1d7126dba60578a8dcecfb", + "s": "0x7756dd3accb21c6994c079795e3edc068e1c434c33109580215073701958f29d", + "v": "0x0" + }, + "signatureCancun": { + "r": "0xb96f5303bcbb749f5fbf6c1d918eb08bfefe05242bfd2c4b9a9a55efb5b686ff", + "s": "0x50b83d2a4dfcaa66b0339df55910ea553bbce6f22d4ab5e8c8562ddb15a03999", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_5.json b/bolt-contracts/test/testdata/transactions/random_5.json new file mode 100644 index 00000000..de4413b8 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_5.json @@ -0,0 +1,92 @@ +{ + "name": "random-5", + "transaction": { + "to": "0x4d1060d970674619005137921969b4bfe3EeA6B8", + "nonce": 577, + "gasLimit": "0xbe431918", + "gasPrice": "0xb3b1aaeb58", + "maxFeePerGas": "0x6bb02a65c7", + "maxPriorityFeePerGas": "0xa5", + "data": "0x7f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60f", + "value": "0x95927b2d76", + "accessList": [ + { + "address": "0x8A632C23BF807681570c3fb6632Ce99FD98BdB23", + "storageKeys": [ + "0x1c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25c", + "0x2b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919", + "0xc266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5", + "0xf49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e" + ] + }, + { + "address": "0x2D78B31bA09E8a2888d655e3d000FE95c63789c4", + "storageKeys": [ + "0x1c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25c", + "0x2b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919", + "0xc266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5", + "0xf49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e" + ] + }, + { + "address": "0x3199b3433EE7f3eDcAE901cbce64C4E81125F7da", + "storageKeys": [ + "0x1c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25c", + "0x2b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919", + "0xc266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5", + "0xf49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e" + ] + }, + { + "address": "0xb8d669949683a728f76919fe2CC9896216E00A81", + "storageKeys": [ + "0x1c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25c", + "0x2b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919", + "0xc266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5", + "0xf49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e" + ] + } + ], + "chainId": "0x60a7", + "maxFeePerBlobGas": "0x13c4c123e2373d", + "blobVersionedHashes": [ + "0x014a782765b51a031ac55ad44ba18bc6f003634892312bc06ee169486aabeab0" + ] + }, + "privateKey": "0x77065b8ddb2f89d3d2d83f46d0147efc081e3a3f1012406c698a9ce364b324e9", + "unsignedLegacy": "0xf89c82024185b3b1aaeb5884be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60f", + "unsignedEip155": "0xf8a182024185b3b1aaeb5884be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60f8260a78080", + "unsignedBerlin": "0x01f903168260a782024185b3b1aaeb5884be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60ff90274f89b948a632c23bf807681570c3fb6632ce99fd98bdb23f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b942d78b31ba09e8a2888d655e3d000fe95c63789c4f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b943199b3433ee7f3edcae901cbce64c4e81125f7daf884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b94b8d669949683a728f76919fe2cc9896216e00a81f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e", + "unsignedLondon": "0x02f903188260a782024181a5856bb02a65c784be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60ff90274f89b948a632c23bf807681570c3fb6632ce99fd98bdb23f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b942d78b31ba09e8a2888d655e3d000fe95c63789c4f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b943199b3433ee7f3edcae901cbce64c4e81125f7daf884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b94b8d669949683a728f76919fe2cc9896216e00a81f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e", + "unsignedCancun": "0x03f903428260a782024181a5856bb02a65c784be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60ff90274f89b948a632c23bf807681570c3fb6632ce99fd98bdb23f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b942d78b31ba09e8a2888d655e3d000fe95c63789c4f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b943199b3433ee7f3edcae901cbce64c4e81125f7daf884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b94b8d669949683a728f76919fe2cc9896216e00a81f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e8713c4c123e2373de1a0014a782765b51a031ac55ad44ba18bc6f003634892312bc06ee169486aabeab0", + "signedLegacy": "0xf8df82024185b3b1aaeb5884be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60f1ba098cadec7a4cd4297f92828b79459baed65817cd8fcd40cb2025b750c8bb3d046a00c2e6848654d045d1502a9c1777bc917a63718e8a494dae94720f519ff07b3db", + "signedEip155": "0xf8e182024185b3b1aaeb5884be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60f82c172a009f309ce844417f1035eff7a0b3bc191253843fb29068769f09fed81a464e622a0722660636b83fcac33759285b9704a5976b7cf9aeeceacab451702ff454469dc", + "signedBerlin": "0x01f903598260a782024185b3b1aaeb5884be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60ff90274f89b948a632c23bf807681570c3fb6632ce99fd98bdb23f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b942d78b31ba09e8a2888d655e3d000fe95c63789c4f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b943199b3433ee7f3edcae901cbce64c4e81125f7daf884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b94b8d669949683a728f76919fe2cc9896216e00a81f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e01a07c8b37dd82c37b9783d328b99528bdbf4abdc7956d5e3da3a65f4a165e4acb74a04db2486fbb725825041d85e055d0adf75e02790041d668d13662717695436410", + "signedLondon": "0x02f9035b8260a782024181a5856bb02a65c784be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60ff90274f89b948a632c23bf807681570c3fb6632ce99fd98bdb23f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b942d78b31ba09e8a2888d655e3d000fe95c63789c4f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b943199b3433ee7f3edcae901cbce64c4e81125f7daf884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b94b8d669949683a728f76919fe2cc9896216e00a81f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e01a09f9feb4b5bf570aa4f121fcc51de36dd7de80d0e4398f3dc99a6a615d12570c9a05d6f01ed28fda456c5f63f5f652735161cb5eede641262e296d62d94c7b628f8", + "signedCancun": "0x03f903858260a782024181a5856bb02a65c784be431918944d1060d970674619005137921969b4bfe3eea6b88595927b2d76b8717f2239c398167e747939f64b2ed9458db8aa10eb367bfab1976a0bc6693cf152dd8d13aa16e4d655a38d6ac64eae0932e13d649f9516fca834cd5a49c7b6e5ba1286a30eea1ac2e89c78441c5418250f8e307cc72c95ef36a8e4cee60b56ece34984ed3302672e6183d28ef30f3e43d60ff90274f89b948a632c23bf807681570c3fb6632ce99fd98bdb23f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b942d78b31ba09e8a2888d655e3d000fe95c63789c4f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b943199b3433ee7f3edcae901cbce64c4e81125f7daf884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824ef89b94b8d669949683a728f76919fe2cc9896216e00a81f884a01c3124f271ea52d9e881bdd52c63020fb7c08a1b96263030415e4bc8146db25ca02b6d4aa754fa44f0e86e6fa0a936048674ffc4fef24c5a2b317c740630901919a0c266c51508b93a8f933e2e64505e458ac26cdb93e8e0bc7bd1609552b6210aa5a0f49934500a155bedea4f0bf25bfc62161fcb74fbf17ca480333f4747d5ad824e8713c4c123e2373de1a0014a782765b51a031ac55ad44ba18bc6f003634892312bc06ee169486aabeab001a033925f057eeeebb09785c26ff18a561741d30577c4eb97a064262592c279995ca04dd3a7404520f2d9b23fddc520c09fddccf0757248627616a6f7ea4f97e9e452", + "signatureLegacy": { + "r": "0x98cadec7a4cd4297f92828b79459baed65817cd8fcd40cb2025b750c8bb3d046", + "s": "0x0c2e6848654d045d1502a9c1777bc917a63718e8a494dae94720f519ff07b3db", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0x09f309ce844417f1035eff7a0b3bc191253843fb29068769f09fed81a464e622", + "s": "0x722660636b83fcac33759285b9704a5976b7cf9aeeceacab451702ff454469dc", + "v": "0xc172" + }, + "signatureBerlin": { + "r": "0x7c8b37dd82c37b9783d328b99528bdbf4abdc7956d5e3da3a65f4a165e4acb74", + "s": "0x4db2486fbb725825041d85e055d0adf75e02790041d668d13662717695436410", + "v": "0x1" + }, + "signatureLondon": { + "r": "0x9f9feb4b5bf570aa4f121fcc51de36dd7de80d0e4398f3dc99a6a615d12570c9", + "s": "0x5d6f01ed28fda456c5f63f5f652735161cb5eede641262e296d62d94c7b628f8", + "v": "0x1" + }, + "signatureCancun": { + "r": "0x33925f057eeeebb09785c26ff18a561741d30577c4eb97a064262592c279995c", + "s": "0x4dd3a7404520f2d9b23fddc520c09fddccf0757248627616a6f7ea4f97e9e452", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_6.json b/bolt-contracts/test/testdata/transactions/random_6.json new file mode 100644 index 00000000..bf778827 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_6.json @@ -0,0 +1,56 @@ +{ + "name": "random-6", + "transaction": { + "to": "0x47F8627a7925083e80e0d94dBB979ce2c44A2c74", + "nonce": 432, + "gasLimit": "0xa1fca9f195", + "gasPrice": "0x39", + "maxFeePerGas": "0x98501809f1", + "maxPriorityFeePerGas": "0xfb", + "data": "0xc90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a8", + "value": "0x79ef27", + "accessList": [], + "chainId": "0xf76e64", + "maxFeePerBlobGas": "0x50799034", + "blobVersionedHashes": [ + "0x01b7a799435fabc095b12caf67e311027aa01ac411f8c004f4ea493a982f3995", + "0x01ec2843771aeee34beaff5727081888ad2e7367f88c14eec961fceb476b63a1" + ] + }, + "privateKey": "0xd9f6e52112da85a6f822054409e83460b9da070ce6c48843e4793c5720ad6910", + "unsignedLegacy": "0xf84b8201b03985a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a8", + "unsignedEip155": "0xf8518201b03985a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a883f76e648080", + "unsignedBerlin": "0x01f85083f76e648201b03985a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a8c0", + "unsignedLondon": "0x02f85783f76e648201b081fb8598501809f185a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a8c0", + "unsignedCancun": "0x03f8a083f76e648201b081fb8598501809f185a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a8c08450799034f842a001b7a799435fabc095b12caf67e311027aa01ac411f8c004f4ea493a982f3995a001ec2843771aeee34beaff5727081888ad2e7367f88c14eec961fceb476b63a1", + "signedLegacy": "0xf88e8201b03985a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a81ba091ad22bc10dbc50ad469a26c6be65d65213a54b5de2ea949f8b7f47ee641d0aba03e69a58405b8bdcd6e41097b828b222b02fa2bfd6b001616a15241c41275c2df", + "signedEip155": "0xf8928201b03985a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a88401eedceba0b19933ddedae4fae6d63ed9ea7a4df4d1e48be652394203245429ef61e2728d6a033d8ab838c3eb536725ccd32ce73e75551eb660acd0608344887e838c41d7e3f", + "signedBerlin": "0x01f89383f76e648201b03985a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a8c001a0538d5ec11ad5bc2755057e684243d103469145984c437d317a231cd4ed7f891fa02f6051be9067d1e9322dc667dbd22f423a27354134b5070819f262eb85e8f754", + "signedLondon": "0x02f89a83f76e648201b081fb8598501809f185a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a8c080a07e88de3723e5ed269a26ebb27c5edf39da43e0246506f7c20861c286ed2e0118a0304a806691fee1223b8b505dc97142ad8eefaf949a7d8828e0483659accecfdd", + "signedCancun": "0x03f8e383f76e648201b081fb8598501809f185a1fca9f1959447f8627a7925083e80e0d94dbb979ce2c44a2c748379ef27a7c90411dca095641b87f3229df9e7613b2e73477c57fc4e28b4c06f436f9825b5aa4d839c3d07a8c08450799034f842a001b7a799435fabc095b12caf67e311027aa01ac411f8c004f4ea493a982f3995a001ec2843771aeee34beaff5727081888ad2e7367f88c14eec961fceb476b63a180a0b5f9efc37373be1d360b8f6a5dc88e111e4cad78b320aee3196fa8a413034a19a00747b3ad2aa3abce5b73d940d7f10990cd7ef496e6315e8143b122f83b9ae149", + "signatureLegacy": { + "r": "0x91ad22bc10dbc50ad469a26c6be65d65213a54b5de2ea949f8b7f47ee641d0ab", + "s": "0x3e69a58405b8bdcd6e41097b828b222b02fa2bfd6b001616a15241c41275c2df", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0xb19933ddedae4fae6d63ed9ea7a4df4d1e48be652394203245429ef61e2728d6", + "s": "0x33d8ab838c3eb536725ccd32ce73e75551eb660acd0608344887e838c41d7e3f", + "v": "0x1eedceb" + }, + "signatureBerlin": { + "r": "0x538d5ec11ad5bc2755057e684243d103469145984c437d317a231cd4ed7f891f", + "s": "0x2f6051be9067d1e9322dc667dbd22f423a27354134b5070819f262eb85e8f754", + "v": "0x1" + }, + "signatureLondon": { + "r": "0x7e88de3723e5ed269a26ebb27c5edf39da43e0246506f7c20861c286ed2e0118", + "s": "0x304a806691fee1223b8b505dc97142ad8eefaf949a7d8828e0483659accecfdd", + "v": "0x0" + }, + "signatureCancun": { + "r": "0xb5f9efc37373be1d360b8f6a5dc88e111e4cad78b320aee3196fa8a413034a19", + "s": "0x0747b3ad2aa3abce5b73d940d7f10990cd7ef496e6315e8143b122f83b9ae149", + "v": "0x0" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_7.json b/bolt-contracts/test/testdata/transactions/random_7.json new file mode 100644 index 00000000..e4804a03 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_7.json @@ -0,0 +1,84 @@ +{ + "name": "random-7", + "transaction": { + "to": "0xD6E75AAf5C27963b31DD4Ad638e4C1d07b2Cc010", + "nonce": 667, + "gasLimit": "0x95ead5c7", + "gasPrice": "0x86", + "maxFeePerGas": "0x2e54dcae", + "maxPriorityFeePerGas": "0x0cb9", + "data": "0xe931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d4977910294", + "value": "0x632af6c3", + "accessList": [ + { + "address": "0xD0a4e08ACDA2A8B3AE50Db94DB3246C4a2F34b60", + "storageKeys": [ + "0xe85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11", + "0x2c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b" + ] + }, + { + "address": "0x3e4eE3DE26502A40C8dc33886c1bB7e079916194", + "storageKeys": [ + "0xe85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11", + "0x2c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b" + ] + }, + { + "address": "0xe54E80bd490910C719D5F11602a97FaE4D5C0F11", + "storageKeys": [ + "0xe85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11", + "0x2c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b" + ] + }, + { + "address": "0x6D1fd21ed3E7D4DE1F58361cB78De7a882dEcC79", + "storageKeys": [ + "0xe85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11", + "0x2c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b" + ] + } + ], + "chainId": "0x295d", + "maxFeePerBlobGas": "0xd76e69ca95e7", + "blobVersionedHashes": [ + "0x01a7921375f6c2798377acd9c4db7719b9980b28c49dbc0ef3962381d961d725" + ] + }, + "privateKey": "0xa6fe9bfe96da66b7788f98b3107c588bee30ccc844e129a7772df540c3193239", + "unsignedLegacy": "0xf86f82029b81868495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d4977910294", + "unsignedEip155": "0xf87482029b81868495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d497791029482295d8080", + "unsignedBerlin": "0x01f901e182295d82029b81868495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d4977910294f9016cf85994d0a4e08acda2a8b3ae50db94db3246c4a2f34b60f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859943e4ee3de26502a40c8dc33886c1bb7e079916194f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf85994e54e80bd490910c719d5f11602a97fae4d5c0f11f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859946d1fd21ed3e7d4de1f58361cb78de7a882decc79f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b", + "unsignedLondon": "0x02f901e782295d82029b820cb9842e54dcae8495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d4977910294f9016cf85994d0a4e08acda2a8b3ae50db94db3246c4a2f34b60f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859943e4ee3de26502a40c8dc33886c1bb7e079916194f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf85994e54e80bd490910c719d5f11602a97fae4d5c0f11f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859946d1fd21ed3e7d4de1f58361cb78de7a882decc79f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b", + "unsignedCancun": "0x03f9021082295d82029b820cb9842e54dcae8495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d4977910294f9016cf85994d0a4e08acda2a8b3ae50db94db3246c4a2f34b60f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859943e4ee3de26502a40c8dc33886c1bb7e079916194f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf85994e54e80bd490910c719d5f11602a97fae4d5c0f11f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859946d1fd21ed3e7d4de1f58361cb78de7a882decc79f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b86d76e69ca95e7e1a001a7921375f6c2798377acd9c4db7719b9980b28c49dbc0ef3962381d961d725", + "signedLegacy": "0xf8b282029b81868495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d49779102941ca02bacdc3053183b5f2a6f56ed6c2f126a6bbb592ef64d912bc704293d5620e188a0163d3e7cb0ad4ab63d10314c24728248699e5f5acebf84e84d67ca21ebe835ca", + "signedEip155": "0xf8b482029b81868495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d49779102948252dda0988356e8e6b000200035901fa00b736677e25d01022d8e7ff0c6f9a9f44cb530a01d04ca133497f2a7f07a36022a132027df576c9d53935fee792fa6a01e2d18d0", + "signedBerlin": "0x01f9022482295d82029b81868495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d4977910294f9016cf85994d0a4e08acda2a8b3ae50db94db3246c4a2f34b60f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859943e4ee3de26502a40c8dc33886c1bb7e079916194f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf85994e54e80bd490910c719d5f11602a97fae4d5c0f11f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859946d1fd21ed3e7d4de1f58361cb78de7a882decc79f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b01a0f243d534dfae5cfb18cf59a41daa31520d91f03fc9b5830ee8a512dca82bbdcda02507b456d89080c847848fa2199998ffc363cbb0d4835ce8d03621980a3f135a", + "signedLondon": "0x02f9022a82295d82029b820cb9842e54dcae8495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d4977910294f9016cf85994d0a4e08acda2a8b3ae50db94db3246c4a2f34b60f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859943e4ee3de26502a40c8dc33886c1bb7e079916194f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf85994e54e80bd490910c719d5f11602a97fae4d5c0f11f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859946d1fd21ed3e7d4de1f58361cb78de7a882decc79f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b80a08e1d67786ffd5edb50e2aff66566c76a1523e9dcabc667b92f540f536d47bccea05d6a00e50ad155e59fbba841afda7592ec16788da4cfd895b447f4c13197d1ab", + "signedCancun": "0x03f9025382295d82029b820cb9842e54dcae8495ead5c794d6e75aaf5c27963b31dd4ad638e4c1d07b2cc01084632af6c3b849e931d4333e6bb3d32f215bfdb13209a0905f740b180cadcea26405d9c79e108e50e87b78a1e7192c313e22f09632ed2882774f8e7536b7dfa987f7d063fc8db54ad5bd8d4977910294f9016cf85994d0a4e08acda2a8b3ae50db94db3246c4a2f34b60f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859943e4ee3de26502a40c8dc33886c1bb7e079916194f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf85994e54e80bd490910c719d5f11602a97fae4d5c0f11f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0bf859946d1fd21ed3e7d4de1f58361cb78de7a882decc79f842a0e85938a8c29ab7b82264cc2e0822673fe17637364d6b384eb49f89e1adf61a11a02c10ec7831da9a49dbf10818882d783f6511dda96c06b8ad2999aeb9f9f82d0b86d76e69ca95e7e1a001a7921375f6c2798377acd9c4db7719b9980b28c49dbc0ef3962381d961d72501a006f7d3d75727c212f2e3fe74af34e4b7db7825291f919e1f291a36161c4d7867a07706e6e9c6b49b83157519cb113dab63707214ad2d9d3af77c65b671bd2958d8", + "signatureLegacy": { + "r": "0x2bacdc3053183b5f2a6f56ed6c2f126a6bbb592ef64d912bc704293d5620e188", + "s": "0x163d3e7cb0ad4ab63d10314c24728248699e5f5acebf84e84d67ca21ebe835ca", + "v": "0x1c" + }, + "signatureEip155": { + "r": "0x988356e8e6b000200035901fa00b736677e25d01022d8e7ff0c6f9a9f44cb530", + "s": "0x1d04ca133497f2a7f07a36022a132027df576c9d53935fee792fa6a01e2d18d0", + "v": "0x52dd" + }, + "signatureBerlin": { + "r": "0xf243d534dfae5cfb18cf59a41daa31520d91f03fc9b5830ee8a512dca82bbdcd", + "s": "0x2507b456d89080c847848fa2199998ffc363cbb0d4835ce8d03621980a3f135a", + "v": "0x1" + }, + "signatureLondon": { + "r": "0x8e1d67786ffd5edb50e2aff66566c76a1523e9dcabc667b92f540f536d47bcce", + "s": "0x5d6a00e50ad155e59fbba841afda7592ec16788da4cfd895b447f4c13197d1ab", + "v": "0x0" + }, + "signatureCancun": { + "r": "0x06f7d3d75727c212f2e3fe74af34e4b7db7825291f919e1f291a36161c4d7867", + "s": "0x7706e6e9c6b49b83157519cb113dab63707214ad2d9d3af77c65b671bd2958d8", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_8.json b/bolt-contracts/test/testdata/transactions/random_8.json new file mode 100644 index 00000000..edc2787d --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_8.json @@ -0,0 +1,60 @@ +{ + "name": "random-8", + "transaction": { + "to": "0x74A3Ddaa5CD03Ba0e9B7cd5535BDa1E23F691932", + "nonce": 965, + "gasLimit": "0x35", + "gasPrice": "0x11ac8f05", + "maxFeePerGas": "0xae07efb83ed7ae", + "maxPriorityFeePerGas": "0xdeb8", + "data": "0xb7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142", + "value": "0xa62ec77a", + "accessList": [ + { + "address": "0xE125F9D848135f52ecc65FcF216146541688f4ec", + "storageKeys": [] + } + ], + "chainId": "0x473eafa7", + "maxFeePerBlobGas": "0x1a6c2938773134", + "blobVersionedHashes": [ + "0x01244e9f27106e77da21d39868d5400854a0cf90e2f58a1134b655704acb213e" + ] + }, + "privateKey": "0xbcc0a8d59a4ebe22dbcc8a52e2975f634f6e3095716602f08e214e4017684180", + "unsignedLegacy": "0xf8688203c58411ac8f05359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142", + "unsignedEip155": "0xf86f8203c58411ac8f05359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f14284473eafa78080", + "unsignedBerlin": "0x01f88584473eafa78203c58411ac8f05359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142d7d694e125f9d848135f52ecc65fcf216146541688f4ecc0", + "unsignedLondon": "0x02f88b84473eafa78203c582deb887ae07efb83ed7ae359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142d7d694e125f9d848135f52ecc65fcf216146541688f4ecc0", + "unsignedCancun": "0x03f8b584473eafa78203c582deb887ae07efb83ed7ae359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142d7d694e125f9d848135f52ecc65fcf216146541688f4ecc0871a6c2938773134e1a001244e9f27106e77da21d39868d5400854a0cf90e2f58a1134b655704acb213e", + "signedLegacy": "0xf8ab8203c58411ac8f05359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f1421ba049a9667e37b4619f39fb925cac786d8ec36b44f7f524cf936ce36cc97ebb04eda074679d25c7bd881450bb623002cb1d5b09b45e9435ebc469b9cea2d05feae86a", + "signedEip155": "0xf8af8203c58411ac8f05359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142848e7d5f72a0e211ba6a21a4ae8bf4cafb29b98d2382bcee9435181a5261964f517ca91b33ffa038351fa3cfe37c88b2bd3aa16421bd37abf6356491f05789624c9f0e25682a38", + "signedBerlin": "0x01f8c884473eafa78203c58411ac8f05359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142d7d694e125f9d848135f52ecc65fcf216146541688f4ecc001a0cf7dfd4507fb9331f4344fe787ecdbfb74d5c09cf71f2fcccb84d12be2a11f5fa07359816992767a631758506f7000bd4cb576cc62388bc490922ab96ee353cc82", + "signedLondon": "0x02f8ce84473eafa78203c582deb887ae07efb83ed7ae359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142d7d694e125f9d848135f52ecc65fcf216146541688f4ecc080a04b1e128faa1365b45eacf1da245d78a3c6c10619a265e268657bd8db50c2ac3ea02538dcbc52e6648a320c641268b5eef3bd9eb24d5f17aa1a3535c194b1404e58", + "signedCancun": "0x03f8f884473eafa78203c582deb887ae07efb83ed7ae359474a3ddaa5cd03ba0e9b7cd5535bda1e23f69193284a62ec77ab843b7c4964ed0cebae0f12c2cbb2adadd2b7ef1b2183c1d5df71354ba8da3bff86e14975031ee08b2239ded1369a235c68a72cc994af2744f70a7214babec31160cd6f142d7d694e125f9d848135f52ecc65fcf216146541688f4ecc0871a6c2938773134e1a001244e9f27106e77da21d39868d5400854a0cf90e2f58a1134b655704acb213e80a0e0e7119acfae63aabe8754ff93738fba1714ef044cbf0cf00bb155e5fd32a629a064c04c7a22c0070cc3f6fa061677be23c3336359cdb428f02f53945d73fd4e77", + "signatureLegacy": { + "r": "0x49a9667e37b4619f39fb925cac786d8ec36b44f7f524cf936ce36cc97ebb04ed", + "s": "0x74679d25c7bd881450bb623002cb1d5b09b45e9435ebc469b9cea2d05feae86a", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0xe211ba6a21a4ae8bf4cafb29b98d2382bcee9435181a5261964f517ca91b33ff", + "s": "0x38351fa3cfe37c88b2bd3aa16421bd37abf6356491f05789624c9f0e25682a38", + "v": "0x8e7d5f72" + }, + "signatureBerlin": { + "r": "0xcf7dfd4507fb9331f4344fe787ecdbfb74d5c09cf71f2fcccb84d12be2a11f5f", + "s": "0x7359816992767a631758506f7000bd4cb576cc62388bc490922ab96ee353cc82", + "v": "0x1" + }, + "signatureLondon": { + "r": "0x4b1e128faa1365b45eacf1da245d78a3c6c10619a265e268657bd8db50c2ac3e", + "s": "0x2538dcbc52e6648a320c641268b5eef3bd9eb24d5f17aa1a3535c194b1404e58", + "v": "0x0" + }, + "signatureCancun": { + "r": "0xe0e7119acfae63aabe8754ff93738fba1714ef044cbf0cf00bb155e5fd32a629", + "s": "0x64c04c7a22c0070cc3f6fa061677be23c3336359cdb428f02f53945d73fd4e77", + "v": "0x0" + } +} diff --git a/bolt-contracts/test/testdata/transactions/random_9.json b/bolt-contracts/test/testdata/transactions/random_9.json new file mode 100644 index 00000000..3e9f1867 --- /dev/null +++ b/bolt-contracts/test/testdata/transactions/random_9.json @@ -0,0 +1,56 @@ +{ + "name": "random-9", + "transaction": { + "to": "0x671a63481F6AdF6E231296c3ec838D21919b5Ec0", + "nonce": 776, + "gasLimit": "0x905469", + "gasPrice": "0xe8", + "maxFeePerGas": "0x64b085b92ba07f", + "maxPriorityFeePerGas": "0xbe", + "data": "0x6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6f", + "value": "0x4f88", + "accessList": [], + "chainId": "0x348f3fcb", + "maxFeePerBlobGas": "0xb8cc0be94a", + "blobVersionedHashes": [ + "0x0134b8b105e49b6c97a9aade76ec97bd4357053c030b7f4370241fca10ab6ef3", + "0x0198df85d8142d33554e7369ed5695dc0a351b38741626e573f918812fa994ae" + ] + }, + "privateKey": "0x63dd633e51d725e1f444b9a724729fb8bd052ec4737eceba804e846a32b4530c", + "unsignedLegacy": "0xf87d82030881e88390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6f", + "unsignedEip155": "0xf88482030881e88390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6f84348f3fcb8080", + "unsignedBerlin": "0x01f88384348f3fcb82030881e88390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6fc0", + "unsignedLondon": "0x02f88b84348f3fcb82030881be8764b085b92ba07f8390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6fc0", + "unsignedCancun": "0x03f8d584348f3fcb82030881be8764b085b92ba07f8390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6fc085b8cc0be94af842a00134b8b105e49b6c97a9aade76ec97bd4357053c030b7f4370241fca10ab6ef3a00198df85d8142d33554e7369ed5695dc0a351b38741626e573f918812fa994ae", + "signedLegacy": "0xf8c082030881e88390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6f1ba0d567c29e1775043d150df4e740d0e581d723f4950b2d35a5adb5a3a1b527686ea00fbcddbd1e8f33eb73a957c985b1ab85c333a42074c8801fe230ace1f246f826", + "signedEip155": "0xf8c482030881e88390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6f84691e7fb9a0900464b1bcd8e581911e8761960913c5b23ef063886533b4a9759c74ffcd4d80a0319be70fd62d7b2722aa1572b456755ae71fc7d1d3c02cdaafebbf4941033409", + "signedBerlin": "0x01f8c684348f3fcb82030881e88390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6fc080a0d2418f0ef98efb8120c5f35803fcc2b0def21e7bad27537fa8be144169393df7a0561b3ee3efe7f4cc07ff4289897c8b316eb6d4de32f60eddd71833d70c13c488", + "signedLondon": "0x02f8ce84348f3fcb82030881be8764b085b92ba07f8390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6fc080a04dfe6f43e3da767dcb2d717d7555f67448a47d8329ba40ba0b25e19ef217837da01612656de7ebf9929a66b7479a63927bb895b225af797adf3d32a890b279ab82", + "signedCancun": "0x03f9011884348f3fcb82030881be8764b085b92ba07f8390546994671a63481f6adf6e231296c3ec838d21919b5ec0824f88b85a6e8a5785fbcffa9d6303b7a22818c0c67aa5e3b1c097aa35af45f95038224f7b1e0724b14a2de88e07469fa80c6c1e172353269d5bd75af8c91b77585a6aa1b99c462b9fbf7010a9b8f4194260bfb307da9ba5b6202da6f0ef6fc085b8cc0be94af842a00134b8b105e49b6c97a9aade76ec97bd4357053c030b7f4370241fca10ab6ef3a00198df85d8142d33554e7369ed5695dc0a351b38741626e573f918812fa994ae01a051e0cac495af080a3d0777ccd5d6a514edfbcc156c0aa4f4218a8bb9259a5e3da00c17cfe7183fd3a1df95478e37f1b75442f4229f9f8ed61e364cfd5407b1a6d2", + "signatureLegacy": { + "r": "0xd567c29e1775043d150df4e740d0e581d723f4950b2d35a5adb5a3a1b527686e", + "s": "0x0fbcddbd1e8f33eb73a957c985b1ab85c333a42074c8801fe230ace1f246f826", + "v": "0x1b" + }, + "signatureEip155": { + "r": "0x900464b1bcd8e581911e8761960913c5b23ef063886533b4a9759c74ffcd4d80", + "s": "0x319be70fd62d7b2722aa1572b456755ae71fc7d1d3c02cdaafebbf4941033409", + "v": "0x691e7fb9" + }, + "signatureBerlin": { + "r": "0xd2418f0ef98efb8120c5f35803fcc2b0def21e7bad27537fa8be144169393df7", + "s": "0x561b3ee3efe7f4cc07ff4289897c8b316eb6d4de32f60eddd71833d70c13c488", + "v": "0x0" + }, + "signatureLondon": { + "r": "0x4dfe6f43e3da767dcb2d717d7555f67448a47d8329ba40ba0b25e19ef217837d", + "s": "0x1612656de7ebf9929a66b7479a63927bb895b225af797adf3d32a890b279ab82", + "v": "0x0" + }, + "signatureCancun": { + "r": "0x51e0cac495af080a3d0777ccd5d6a514edfbcc156c0aa4f4218a8bb9259a5e3d", + "s": "0x0c17cfe7183fd3a1df95478e37f1b75442f4229f9f8ed61e364cfd5407b1a6d2", + "v": "0x1" + } +} diff --git a/bolt-contracts/test/testdata/tx_mpt_proof_20785012.json b/bolt-contracts/test/testdata/tx_mpt_proof_20785012.json new file mode 100644 index 00000000..82b1faea --- /dev/null +++ b/bolt-contracts/test/testdata/tx_mpt_proof_20785012.json @@ -0,0 +1,11 @@ +{ + "root": "0x87bb9183296ce9e3b7a3246f6d3a778b99a5d7daaba2174750707407c7297365", + "proof": [ + "f90131a060b2a2267b5925093805abbff6a9427865d9b0277666178def5e6d7f74cbea7da02d03b55bc0b1007e572b92e13d09e02cd1d740d81fc52c25fb522dcdc3c25717a08ce7808266f8a29dffb636d860c7fc13dccb47cfb5c1869d50da5f847faee9dda02d872b0e5b790bfd8f8851a539bdd67c8324812698ef8420bd3db06063f23383a046d720b85dbd71b53f9b46dc5908aafd65e0dc8d2a73bde7b548a6e59cdc1789a076e14ef77554b242d92b4832fbce89211b7b140ae202a4e4f465ef823204c9f7a0af30522b1024223eb65217ebcb5ddc22c1a62fbf43147fb43413e96eef821f66a02b8f47754c761574aa5ee4c348efc736b533c61aa7fa17051a5ea59fbeb3d7d2a08c8cc819bcd01c3ac2ba2d4926fba56579bc06722695d883d4ca1ea303a8f8c68080808080808080", + "f851a083516ffb4e11ae53aeb06863db356a756ef78cebe38802d69417148d369b986ca0351cee818717275e8e3962a54e1fa98e4b1b990aaad376b3d3e346cfb8fe4be6808080808080808080808080808080", + "f8d18080808080808080a05fd1f4eb5d94e828602fc1e19f03aae255efe360d81b9fc59099e21099327a7ba0219f99f84f7c704ca56575a4a3c59eaef6ee3ee3209cdc3ee4abe33c3c070c24a0afb31c1b8e96e6123e8a992d07ad7c0fe67648fbf5a6e4596f09be1affe80915a0572ca737439b54219818239a4420435dcd1546106e9f8074e00249eaf3127bb7a048862625cbbaffc46c2660d39f118c330e9fb3a3ceb2ca014e1ce285cf3e5e3ea0aec03c27f570694d19c676635151ee2abee5f19c2bf8c4701d5200df98d12ccd808080", + "f90211a008159cadb4be04f22dc7d9ee2f553720d7376797be70180f9860d9e6678d2b5fa0ba8725a1ca2023b727390f3fdb6dbddc51f23f95688c62a965a2d92d592dc074a0d27651ea59c6b3c5a7aa0b85d72b738d67a4cb9a1b6641e27fce330c12cbcc90a0448680ef94e3a42fa2045aa621bd984539c977927828b1690cd3f490f8f28202a0ddfa57de1a8e6477bfca9e07f7d567e8f9ead53e12dd6b26e46af8bb9ab2d42ba098de76237020aed42e4764dacf726cab9549f279a811158ef7d0a1865da49981a05ee4fbdd47c61ae9d9af574b90b3b14cbe146b3a377b6168662393a5799c53b0a05a710ac33be934301f2ec6d0d0eb911112c9ad90a783f1be56b3ea7a7751e856a0bf6171383c71ae373d3f86f4c1bf2bf0b34e117ea83ee8cdb0127e6f995b1b72a090cd396cf68946d396acc5b6b52474360ff402f21b622131b5e7ba0d370c8c07a06eb177bcd78f1db1138999efd996a1bfa9b32fe044b098bb0f8812798bfcad59a05cb6ed66df666831a1f9e01d2c809020d162024e066d5aa1248c4eb8137e4a71a020289d8787475543406639e2a9757c3e271b4947117ba617cd3f4791a7a0bd9aa0306aba70af61802a577df56b1dbe4bc93658e75fc6300f53e80ec8fd4f9fd8b6a0c88b6ebfdee7e968ef2f0eeec5d9d9001111df281a806b2326499472f3705937a0aa2a3290eda38ae66d13186f452410332f1a0e30ee9c5719cd420871779b830380", + "f87a20b87702f8740181eb8473a20d008507e172a822825208940ff71973b5243005b192d5bcf552fc2532b7bdec88015842095ebc400080c080a07a955ea50e980729226f547245bcf1e0e4ab69467cf82490a4bb0dbe9f35ae84a05f17d1a8f65b60905535ef0c36a8ec6d560c355949aeee2d3ab9791e7fe18fb4" + ], + "index": 179 +} diff --git a/bolt-contracts/test/testdata/tx_mpt_proof_20817618_1.json b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_1.json new file mode 100644 index 00000000..168a80b8 --- /dev/null +++ b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_1.json @@ -0,0 +1,10 @@ +{ + "txHash": "0x7387d381729e956b176a46c892ade005b674f3c1c700eeae7fd5212fd87cf85d", + "root": "0xb152ed53b02e03a51211b1f1260d58f5a90ff87a6f209954bd70e8a108112c13", + "proof": [ + "f90131a08054ac06deeff9e3269b58b3cf8cfead2012586326e2d51edfdc64603ea92fcfa0c6974714547104b94fac6f0da4e95b50534d960d1ee5e1f21932a212d9a4f42ca052dae1479e618740ffff9885fe9b55a17026903922d16cfd4b1c0733b18f2f24a0acbe9dc865421d745cb159af2cfcd8be5deaf64683d19c77857e5fc25744ac2ca00a6a250aff5ab4711dc9cea5b812f8080caceafa95d5ec578d43285ab27fd562a09a719127a63e2242a33fc5b9232c0d87892c8314c3ed5933527cb6fb95f50278a018cfbac9d7ed346d221124c0e28dfd4e92be373f3170cc62421327084e2bc221a0b74eae762f631f76b434632d03de4862d45e2d5c6a23f5d8b6b4fb806f0070d7a00cc848fcc361f3e01dd562909867bc8a7ab1d329aab2410a500a888f1b6f968a8080808080808080", + "f90211a089437c8fb79d4e0278f780cd90e1d47d2c25096271a1a680e762077778f498e5a065f5057f982b971e6624cfbb2d2acab8ae4a10425bd81b4401b69bc1a2ab31d6a0418f8fc6dceed29c186fa782f71f88f91b133c9070ec598eff02cbcf93d7d634a0d26549a8dd9285213e60286a8e2f8714c86a02bd13939c33fedde54c505a5573a02755be69f4b8e2560a1e4c8476dda8cb80334118bcbeb1f4621ee96aa7f8a418a0ef2ceefc457b6af22d2da599e6017e3ffe7c64dd6a229cad956189ddfeba521ba0df34b08748c2fad457380901f01d06550edab0fb2f176b85fe1b8e8767b58b08a07d30d5330a32f2831e471ecd3249d9561a6ebb91c17627b3cf836d77c9e2f8b3a087e09e649a43bc9c669e21844332f14d207c13cc4455ace13580bf6ef483a0eea005a73cbf870ca0c564dfa07b9f90cdc7d3e47f8545f6f06b9556e5a6fcf30f22a0eebdad0cdb60e30a3b3626d77ece2219a9f25eea0d8c2bb8de751fd727a371f1a0adc316aafc459d35adea06c3b4df1929fe9e48e043b2adc80154666634038352a04cc9eef47849e1aff9e18af286a80a0a72bfdb67c4d9ccad3866806993caa3b0a0fa37400267248ba993971f439e7cd650c0b5a65477e08b5df55c1b4159d23337a066314a563a10591582bdb2f69e0cb6160a2faa91d73a00aad0b54d7e24c6f3cda0376f6e26446a1600cbaa22f7f611482c109f149cf0d27f9f1bc48664b4d21c2d80", + "f8b020b8adf8ab8233858502de59ddef82b59b94dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb000000000000000000000000331b7670016c6be29d0ac211f6f8aceeb38f0d42000000000000000000000000000000000000000000000000000000000726bbf826a0abf062f0d6ebbb4910392d3bdac921b384f12aea2aa43169a2e866674ae90382a02849acdddc6d86036169e250dea502db87e9a91d6e1ffe8a6a30e54fbb327c5e" + ], + "index": 77 +} diff --git a/bolt-contracts/test/testdata/tx_mpt_proof_20817618_2.json b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_2.json new file mode 100644 index 00000000..3b4f33f6 --- /dev/null +++ b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_2.json @@ -0,0 +1,10 @@ +{ + "txHash": "0x9646df26d6c781600205f63717ffc428c78f4e17cf65511c9ce1893bfcc8939e", + "root": "0xb152ed53b02e03a51211b1f1260d58f5a90ff87a6f209954bd70e8a108112c13", + "proof": [ + "f90131a08054ac06deeff9e3269b58b3cf8cfead2012586326e2d51edfdc64603ea92fcfa0c6974714547104b94fac6f0da4e95b50534d960d1ee5e1f21932a212d9a4f42ca052dae1479e618740ffff9885fe9b55a17026903922d16cfd4b1c0733b18f2f24a0acbe9dc865421d745cb159af2cfcd8be5deaf64683d19c77857e5fc25744ac2ca00a6a250aff5ab4711dc9cea5b812f8080caceafa95d5ec578d43285ab27fd562a09a719127a63e2242a33fc5b9232c0d87892c8314c3ed5933527cb6fb95f50278a018cfbac9d7ed346d221124c0e28dfd4e92be373f3170cc62421327084e2bc221a0b74eae762f631f76b434632d03de4862d45e2d5c6a23f5d8b6b4fb806f0070d7a00cc848fcc361f3e01dd562909867bc8a7ab1d329aab2410a500a888f1b6f968a8080808080808080", + "f90211a089437c8fb79d4e0278f780cd90e1d47d2c25096271a1a680e762077778f498e5a065f5057f982b971e6624cfbb2d2acab8ae4a10425bd81b4401b69bc1a2ab31d6a0418f8fc6dceed29c186fa782f71f88f91b133c9070ec598eff02cbcf93d7d634a0d26549a8dd9285213e60286a8e2f8714c86a02bd13939c33fedde54c505a5573a02755be69f4b8e2560a1e4c8476dda8cb80334118bcbeb1f4621ee96aa7f8a418a0ef2ceefc457b6af22d2da599e6017e3ffe7c64dd6a229cad956189ddfeba521ba0df34b08748c2fad457380901f01d06550edab0fb2f176b85fe1b8e8767b58b08a07d30d5330a32f2831e471ecd3249d9561a6ebb91c17627b3cf836d77c9e2f8b3a087e09e649a43bc9c669e21844332f14d207c13cc4455ace13580bf6ef483a0eea005a73cbf870ca0c564dfa07b9f90cdc7d3e47f8545f6f06b9556e5a6fcf30f22a0eebdad0cdb60e30a3b3626d77ece2219a9f25eea0d8c2bb8de751fd727a371f1a0adc316aafc459d35adea06c3b4df1929fe9e48e043b2adc80154666634038352a04cc9eef47849e1aff9e18af286a80a0a72bfdb67c4d9ccad3866806993caa3b0a0fa37400267248ba993971f439e7cd650c0b5a65477e08b5df55c1b4159d23337a066314a563a10591582bdb2f69e0cb6160a2faa91d73a00aad0b54d7e24c6f3cda0376f6e26446a1600cbaa22f7f611482c109f149cf0d27f9f1bc48664b4d21c2d80", + "f87220b86ff86d8233868504216ca9e78252089415086dc2a2ea37c844e554b65d17c5183f15ab74870326bfc40e1c008025a06db3917cf09951d0107da89bc605ae88623a7690647ac8a5bc3c1638c8c9de59a032a2121306e6a5e1713d99595a65c14cfd1b1978922173cf69bf5f2d4a0b1a60" + ], + "index": 78 +} diff --git a/bolt-contracts/test/testdata/tx_mpt_proof_20817618_3.json b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_3.json new file mode 100644 index 00000000..5f8c1475 --- /dev/null +++ b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_3.json @@ -0,0 +1,10 @@ +{ + "txHash": "0x134665d7d342a678a6c1033df5fe09a4f993708dfca7d1208f4b97662840efc9", + "root": "0xb152ed53b02e03a51211b1f1260d58f5a90ff87a6f209954bd70e8a108112c13", + "proof": [ + "f90131a08054ac06deeff9e3269b58b3cf8cfead2012586326e2d51edfdc64603ea92fcfa0c6974714547104b94fac6f0da4e95b50534d960d1ee5e1f21932a212d9a4f42ca052dae1479e618740ffff9885fe9b55a17026903922d16cfd4b1c0733b18f2f24a0acbe9dc865421d745cb159af2cfcd8be5deaf64683d19c77857e5fc25744ac2ca00a6a250aff5ab4711dc9cea5b812f8080caceafa95d5ec578d43285ab27fd562a09a719127a63e2242a33fc5b9232c0d87892c8314c3ed5933527cb6fb95f50278a018cfbac9d7ed346d221124c0e28dfd4e92be373f3170cc62421327084e2bc221a0b74eae762f631f76b434632d03de4862d45e2d5c6a23f5d8b6b4fb806f0070d7a00cc848fcc361f3e01dd562909867bc8a7ab1d329aab2410a500a888f1b6f968a8080808080808080", + "f90211a089437c8fb79d4e0278f780cd90e1d47d2c25096271a1a680e762077778f498e5a065f5057f982b971e6624cfbb2d2acab8ae4a10425bd81b4401b69bc1a2ab31d6a0418f8fc6dceed29c186fa782f71f88f91b133c9070ec598eff02cbcf93d7d634a0d26549a8dd9285213e60286a8e2f8714c86a02bd13939c33fedde54c505a5573a02755be69f4b8e2560a1e4c8476dda8cb80334118bcbeb1f4621ee96aa7f8a418a0ef2ceefc457b6af22d2da599e6017e3ffe7c64dd6a229cad956189ddfeba521ba0df34b08748c2fad457380901f01d06550edab0fb2f176b85fe1b8e8767b58b08a07d30d5330a32f2831e471ecd3249d9561a6ebb91c17627b3cf836d77c9e2f8b3a087e09e649a43bc9c669e21844332f14d207c13cc4455ace13580bf6ef483a0eea005a73cbf870ca0c564dfa07b9f90cdc7d3e47f8545f6f06b9556e5a6fcf30f22a0eebdad0cdb60e30a3b3626d77ece2219a9f25eea0d8c2bb8de751fd727a371f1a0adc316aafc459d35adea06c3b4df1929fe9e48e043b2adc80154666634038352a04cc9eef47849e1aff9e18af286a80a0a72bfdb67c4d9ccad3866806993caa3b0a0fa37400267248ba993971f439e7cd650c0b5a65477e08b5df55c1b4159d23337a066314a563a10591582bdb2f69e0cb6160a2faa91d73a00aad0b54d7e24c6f3cda0376f6e26446a1600cbaa22f7f611482c109f149cf0d27f9f1bc48664b4d21c2d80", + "f8b020b8adf8ab823387850340375aa882fa2b94dac17f958d2ee523a2206206994597c13d831ec780b844a9059cbb0000000000000000000000009b26d899b1ac6ec07488929c0fdc5b40455275480000000000000000000000000000000000000000000000000000000006e438a025a06194e5ecbf6742f5f7919b39950f452eb0024344977576bb8ceafeff4410e199a007569f10b4d88cd2e185fb30c10f7a507ee6badebfd65b7e4cb884ca8acc5e11" + ], + "index": 79 +} diff --git a/bolt-contracts/test/testdata/tx_mpt_proof_20817618_4.json b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_4.json new file mode 100644 index 00000000..45a9a9ae --- /dev/null +++ b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_4.json @@ -0,0 +1,10 @@ +{ + "txHash": "0x66cd8977690a1b8bcc4c0dccf4e241146d8ecd08f65aeaaa2b96002fa06a8b28", + "root": "0xb152ed53b02e03a51211b1f1260d58f5a90ff87a6f209954bd70e8a108112c13", + "proof": [ + "f90131a08054ac06deeff9e3269b58b3cf8cfead2012586326e2d51edfdc64603ea92fcfa0c6974714547104b94fac6f0da4e95b50534d960d1ee5e1f21932a212d9a4f42ca052dae1479e618740ffff9885fe9b55a17026903922d16cfd4b1c0733b18f2f24a0acbe9dc865421d745cb159af2cfcd8be5deaf64683d19c77857e5fc25744ac2ca00a6a250aff5ab4711dc9cea5b812f8080caceafa95d5ec578d43285ab27fd562a09a719127a63e2242a33fc5b9232c0d87892c8314c3ed5933527cb6fb95f50278a018cfbac9d7ed346d221124c0e28dfd4e92be373f3170cc62421327084e2bc221a0b74eae762f631f76b434632d03de4862d45e2d5c6a23f5d8b6b4fb806f0070d7a00cc848fcc361f3e01dd562909867bc8a7ab1d329aab2410a500a888f1b6f968a8080808080808080", + "f90211a035c6919f9a75bb19e1af47bef00f47c3f702234fe69a3c2e596711cb9aa129a9a0fa06ad9a8d7a5c5bb841ccdbda97bf92dafa1288837287eb7f1fefac33d00980a0197b18a0170309d9510ec708102c29dd0a06fbfe3a7ed8ec7aacf4cf5ab7a625a0a1be1616a0c134caba1d7d24e3bdb10ad529017eb0f3b98f64ef6a8ab3562674a03eaafff1a78cb8ae018ccd58e8c318e928666c6499ad08cdb693fbab847adc59a032d58358743500d2fa2383200527972324910b8ecee76a859003163aee609549a09f0da441bddf2bbb5fce05c8a07385d29a09e21e3423401bce63fcdfb85cc97ea0e464722c37f377e3999e77caa5d38bd6240b9462457e93faf2d3b1bda3d788dfa05149eee71192d612c65d00ac434ce8b6f2f7d4f4c77012e919a37f4fb9ebc4f5a019dcf5d5b265d9263758e66afb5c24d7fd36cbbf55b7ff7799f361230a066361a06166f16fd0dc59da6313987d228e6a1d178ad5b0f2d3bfaceafd45c09780020fa07e460796b13f8e4855b8d0aac4f517872aad6b5d8e6aadddd0a799c23cd9deaca09f8690880be03f5f355f2cbcc4a8925d1f8d3b42d082f874098ce41581fec299a0ae79026df571e097a3a9e181e49a2a392a3a01f2fb882398c0df93b3b0668641a0479579fc287b5558020279332ed9735dbfbcb46eaff28b0bdca8950f6eec7c30a0baa5c5d8f1b5dd556ab4149ba70d847727b8755b6bba972ae6791d1c8d9751f480", + "f87220b86ff86d8233888503439d541b8252089415086dc2a2ea37c844e554b65d17c5183f15ab7487027d84f7cd40008026a0d69512e3b47f74fc7d8a2c02f0497580299494544c53860198510433385d6658a043aed084197ff3a3b05e0a0020e4802da7f50c0078dff2e197ad4b0affb36929" + ], + "index": 80 +} diff --git a/bolt-contracts/test/testdata/tx_mpt_proof_20817618_5.json b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_5.json new file mode 100644 index 00000000..6264b659 --- /dev/null +++ b/bolt-contracts/test/testdata/tx_mpt_proof_20817618_5.json @@ -0,0 +1,10 @@ +{ + "txHash": "0x5f505bec39cdbbe03b9566085e87a4fc19f9a3346e128d01fa0088a6b274f654", + "root": "0xb152ed53b02e03a51211b1f1260d58f5a90ff87a6f209954bd70e8a108112c13", + "proof": [ + "f90131a08054ac06deeff9e3269b58b3cf8cfead2012586326e2d51edfdc64603ea92fcfa0c6974714547104b94fac6f0da4e95b50534d960d1ee5e1f21932a212d9a4f42ca052dae1479e618740ffff9885fe9b55a17026903922d16cfd4b1c0733b18f2f24a0acbe9dc865421d745cb159af2cfcd8be5deaf64683d19c77857e5fc25744ac2ca00a6a250aff5ab4711dc9cea5b812f8080caceafa95d5ec578d43285ab27fd562a09a719127a63e2242a33fc5b9232c0d87892c8314c3ed5933527cb6fb95f50278a018cfbac9d7ed346d221124c0e28dfd4e92be373f3170cc62421327084e2bc221a0b74eae762f631f76b434632d03de4862d45e2d5c6a23f5d8b6b4fb806f0070d7a00cc848fcc361f3e01dd562909867bc8a7ab1d329aab2410a500a888f1b6f968a8080808080808080", + "f90211a035c6919f9a75bb19e1af47bef00f47c3f702234fe69a3c2e596711cb9aa129a9a0fa06ad9a8d7a5c5bb841ccdbda97bf92dafa1288837287eb7f1fefac33d00980a0197b18a0170309d9510ec708102c29dd0a06fbfe3a7ed8ec7aacf4cf5ab7a625a0a1be1616a0c134caba1d7d24e3bdb10ad529017eb0f3b98f64ef6a8ab3562674a03eaafff1a78cb8ae018ccd58e8c318e928666c6499ad08cdb693fbab847adc59a032d58358743500d2fa2383200527972324910b8ecee76a859003163aee609549a09f0da441bddf2bbb5fce05c8a07385d29a09e21e3423401bce63fcdfb85cc97ea0e464722c37f377e3999e77caa5d38bd6240b9462457e93faf2d3b1bda3d788dfa05149eee71192d612c65d00ac434ce8b6f2f7d4f4c77012e919a37f4fb9ebc4f5a019dcf5d5b265d9263758e66afb5c24d7fd36cbbf55b7ff7799f361230a066361a06166f16fd0dc59da6313987d228e6a1d178ad5b0f2d3bfaceafd45c09780020fa07e460796b13f8e4855b8d0aac4f517872aad6b5d8e6aadddd0a799c23cd9deaca09f8690880be03f5f355f2cbcc4a8925d1f8d3b42d082f874098ce41581fec299a0ae79026df571e097a3a9e181e49a2a392a3a01f2fb882398c0df93b3b0668641a0479579fc287b5558020279332ed9735dbfbcb46eaff28b0bdca8950f6eec7c30a0baa5c5d8f1b5dd556ab4149ba70d847727b8755b6bba972ae6791d1c8d9751f480", + "f87220b86ff86d82338985058af3f6c28252089415086dc2a2ea37c844e554b65d17c5183f15ab7487040a50523970008026a05bee04d6213c636154c3c2e87038ffdb3d384c23fb9af65fcc85a890c9cabfe6a02231204d5fe346497f035994acec2dece4efa5109d466e7ce834b7576c237f9e" + ], + "index": 81 +} diff --git a/bolt-sidecar/src/primitives/commitment.rs b/bolt-sidecar/src/primitives/commitment.rs index 5364f02b..0b5e8a4a 100644 --- a/bolt-sidecar/src/primitives/commitment.rs +++ b/bolt-sidecar/src/primitives/commitment.rs @@ -251,8 +251,38 @@ impl ECDSASignatureExt for Signature { #[cfg(test)] mod tests { + use std::str::FromStr; + + use alloy::{ + hex, + primitives::{Address, Signature}, + }; + use super::{CommitmentRequest, InclusionRequest}; + #[test] + fn test_create_digest() { + let json_req = r#"{ + "slot": 633067, + "txs": ["0xf86b82016e84042343e0830f424094deaddeaddeaddeaddeaddeaddeaddeaddeaddead0780850344281a21a0e525fc31b5574722ff064bdd127c4441b0fc66de7dc44928e163cb68e9d807e5a00b3ec02fc1e34b0209f252369ad10b745cd5a51c88384a340f7a150d0e45e471"] + }"#; + + let req: InclusionRequest = serde_json::from_str(json_req).unwrap(); + let digest = req.digest(); + assert_eq!( + hex::encode(digest.as_slice()), + "52ecc7832625c3d107aaba5b55d4509b48cd9f4f7ce375d6696d09bbf3310525" + ); + + // Verify signature over the digest + let sig = Signature::from_str("0xcdd20b2abbd8cdfb77ec2608e1227f8ce0f66133b9d0ec0ea68102c2152b82193e3be0d6967b7c20b83e1a2530daa3a07713556541dc2aa16a46d922e6145a2b01").unwrap(); + let recovered = sig.recover_address_from_prehash(&digest).unwrap(); + assert_eq!( + recovered, + Address::from_str("0x27083ED52464625660f3e30Aa5B9C20A30D7E110").unwrap() + ); + } + #[test] fn test_deserialize_inclusion_request() { let json_req = r#"{