diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index f2dcc3ae96..41defedd00 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -122,6 +122,27 @@ jobs: LINUX_SIGNING_KEY: ${{ secrets.LINUX_SIGNING_KEY }} AZURE_BLOBSTORE_TOKEN: ${{ secrets.AZURE_BLOBSTORE_TOKEN }} + keeper: + name: Keeper Build + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: 1.24 + cache: false + + - name: Install cross toolchain + run: | + apt-get update + apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib + + - name: Build (amd64) + run: | + go run build/ci.go keeper -dlgo + windows: name: Windows Build runs-on: "win-11" diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 900ff52e52..4bc13aff92 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -19,7 +19,7 @@ eth/tracers/ @s1na ethclient/ @fjl ethdb/ @rjl493456442 event/ @fjl -trie/ @rjl493456442 +trie/ @rjl493456442 @gballet triedb/ @rjl493456442 core/tracing/ @s1na graphql/ @s1na diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 13f97898bb..50c9fe7f75 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -10,7 +10,7 @@ on: jobs: lint: name: Lint - runs-on: self-hosted-ghr + runs-on: [self-hosted-ghr, size-s-x64] steps: - uses: actions/checkout@v4 with: @@ -25,7 +25,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: 1.24 + go-version: 1.25 cache: false - name: Run linters @@ -34,15 +34,56 @@ jobs: go run build/ci.go check_generate go run build/ci.go check_baddeps + keeper: + name: Keeper Builds + needs: test + runs-on: [self-hosted-ghr, size-l-x64] + steps: + - uses: actions/checkout@v4 + with: + submodules: true + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.25' + cache: false + + - name: Build + run: go run build/ci.go keeper + + test-32bit: + name: "32bit tests" + needs: test + runs-on: [self-hosted-ghr, size-l-x64] + steps: + - uses: actions/checkout@v4 + with: + submodules: false + + - name: Set up Go + uses: actions/setup-go@v5 + with: + go-version: '1.25' + cache: false + + - name: Install cross toolchain + run: | + apt-get update + apt-get -yq --no-install-suggests --no-install-recommends install gcc-multilib + + - name: Build + run: go run build/ci.go test -arch 386 -short -p 8 + test: name: Test needs: lint - runs-on: self-hosted-ghr + runs-on: [self-hosted-ghr, size-l-x64] strategy: matrix: go: + - '1.25' - '1.24' - - '1.23' steps: - uses: actions/checkout@v4 with: @@ -55,4 +96,4 @@ jobs: cache: false - name: Run tests - run: go test ./... + run: go run build/ci.go test -p 8 diff --git a/.github/workflows/validate_pr.yml b/.github/workflows/validate_pr.yml new file mode 100644 index 0000000000..aa3c74cc67 --- /dev/null +++ b/.github/workflows/validate_pr.yml @@ -0,0 +1,83 @@ +name: PR Format Validation + +on: + pull_request: + types: [opened, edited, synchronize] + +jobs: + validate-pr: + runs-on: ubuntu-latest + steps: + - name: Check for Spam PR + uses: actions/github-script@v7 + with: + script: | + const prTitle = context.payload.pull_request.title; + const spamRegex = /^(feat|chore|fix)(\(.*\))?\s*:/i; + + if (spamRegex.test(prTitle)) { + // Leave a comment explaining why + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.payload.pull_request.number, + body: `## PR Closed as Spam + + This PR was automatically closed because the title format \`feat:\`, \`fix:\`, or \`chore:\` is commonly associated with spam contributions. + + If this is a legitimate contribution, please: + 1. Review our contribution guidelines + 2. Use the correct PR title format: \`directory, ...: description\` + 3. Open a new PR with the proper title format + + Thank you for your understanding.` + }); + + // Close the PR + await github.rest.pulls.update({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.payload.pull_request.number, + state: 'closed' + }); + + core.setFailed('PR closed as spam due to suspicious title format'); + return; + } + + console.log('✅ PR passed spam check'); + + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Check PR Title Format + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = require('path'); + const prTitle = context.payload.pull_request.title; + const titleRegex = /^([\w\s,{}/.]+): .+/; + + if (!titleRegex.test(prTitle)) { + core.setFailed(`PR title "${prTitle}" does not match required format: directory, ...: description`); + return; + } + + const match = prTitle.match(titleRegex); + const dirPart = match[1]; + const directories = dirPart.split(',').map(d => d.trim()); + const missingDirs = []; + for (const dir of directories) { + const fullPath = path.join(process.env.GITHUB_WORKSPACE, dir); + if (!fs.existsSync(fullPath)) { + missingDirs.push(dir); + } + } + + if (missingDirs.length > 0) { + core.setFailed(`The following directories in the PR title do not exist: ${missingDirs.join(', ')}`); + return; + } + + console.log('✅ PR title format is valid'); diff --git a/.gitignore b/.gitignore index 269455db7a..293359a669 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,5 @@ cmd/ethkey/ethkey cmd/evm/evm cmd/geth/geth cmd/rlpdump/rlpdump -cmd/workload/workload \ No newline at end of file +cmd/workload/workload +cmd/keeper/keeper diff --git a/README.md b/README.md index 78a56baece..639286ba9f 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,7 @@ https://pkg.go.dev/badge/github.com/ethereum/go-ethereum [![Go Report Card](https://goreportcard.com/badge/github.com/ethereum/go-ethereum)](https://goreportcard.com/report/github.com/ethereum/go-ethereum) [![Travis](https://app.travis-ci.com/ethereum/go-ethereum.svg?branch=master)](https://app.travis-ci.com/github/ethereum/go-ethereum) [![Discord](https://img.shields.io/badge/discord-join%20chat-blue.svg)](https://discord.gg/nthXNEv) +[![Twitter](https://img.shields.io/twitter/follow/go_ethereum)](https://x.com/go_ethereum) Automated builds are available for stable releases and the unstable master branch. Binary archives are published at https://geth.ethereum.org/downloads/. diff --git a/SECURITY.md b/SECURITY.md index 0b497b44ae..d497248de5 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -21,7 +21,6 @@ Audit reports are published in the `docs` folder: https://github.com/ethereum/go To find out how to disclose a vulnerability in Ethereum visit [https://bounty.ethereum.org](https://bounty.ethereum.org) or email bounty@ethereum.org. Please read the [disclosure page](https://github.com/ethereum/go-ethereum/security/advisories?state=published) for more information about publicly disclosed security vulnerabilities. -Use the built-in `geth version-check` feature to check whether the software is affected by any known vulnerability. This command will fetch the latest [`vulnerabilities.json`](https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json) file which contains known security vulnerabilities concerning `geth`, and cross-check the data against its own version number. The following key may be used to communicate sensitive information to developers. diff --git a/accounts/abi/abigen/bind_test.go b/accounts/abi/abigen/bind_test.go index b3c52e81e5..1651e637c8 100644 --- a/accounts/abi/abigen/bind_test.go +++ b/accounts/abi/abigen/bind_test.go @@ -485,13 +485,13 @@ var bindTests = []struct { contract Defaulter { address public caller; - function() { + fallback() external payable { caller = msg.sender; } } `, - []string{`6060604052606a8060106000396000f360606040523615601d5760e060020a6000350463fc9c8d3981146040575b605e6000805473ffffffffffffffffffffffffffffffffffffffff191633179055565b606060005473ffffffffffffffffffffffffffffffffffffffff1681565b005b6060908152602090f3`}, - []string{`[{"constant":true,"inputs":[],"name":"caller","outputs":[{"name":"","type":"address"}],"type":"function"}]`}, + []string{`608060405234801561000f575f80fd5b5061013d8061001d5f395ff3fe608060405260043610610021575f3560e01c8063fc9c8d391461006257610022565b5b335f806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055005b34801561006d575f80fd5b5061007661008c565b60405161008391906100ee565b60405180910390f35b5f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6100d8826100af565b9050919050565b6100e8816100ce565b82525050565b5f6020820190506101015f8301846100df565b9291505056fea26469706673582212201e9273ecfb1f534644c77f09a25c21baaba81cf1c444ebc071e12a225a23c72964736f6c63430008140033`}, + []string{`[{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"caller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]`}, ` "math/big" diff --git a/accounts/abi/abigen/source2.go.tpl b/accounts/abi/abigen/source2.go.tpl index 8ef906b8d6..3d98cbb700 100644 --- a/accounts/abi/abigen/source2.go.tpl +++ b/accounts/abi/abigen/source2.go.tpl @@ -183,7 +183,7 @@ var ( // Solidity: {{.Original.String}} func ({{ decapitalise $contract.Type}} *{{$contract.Type}}) Unpack{{.Normalized.Name}}Event(log *types.Log) (*{{$contract.Type}}{{.Normalized.Name}}, error) { event := "{{.Original.Name}}" - if log.Topics[0] != {{ decapitalise $contract.Type}}.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != {{ decapitalise $contract.Type}}.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new({{$contract.Type}}{{.Normalized.Name}}) diff --git a/accounts/abi/abigen/testdata/v2/crowdsale.go.txt b/accounts/abi/abigen/testdata/v2/crowdsale.go.txt index b2183c91ea..b548b6cdae 100644 --- a/accounts/abi/abigen/testdata/v2/crowdsale.go.txt +++ b/accounts/abi/abigen/testdata/v2/crowdsale.go.txt @@ -360,7 +360,7 @@ func (CrowdsaleFundTransfer) ContractEventName() string { // Solidity: event FundTransfer(address backer, uint256 amount, bool isContribution) func (crowdsale *Crowdsale) UnpackFundTransferEvent(log *types.Log) (*CrowdsaleFundTransfer, error) { event := "FundTransfer" - if log.Topics[0] != crowdsale.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != crowdsale.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(CrowdsaleFundTransfer) diff --git a/accounts/abi/abigen/testdata/v2/dao.go.txt b/accounts/abi/abigen/testdata/v2/dao.go.txt index 75fa95df91..c246771d6d 100644 --- a/accounts/abi/abigen/testdata/v2/dao.go.txt +++ b/accounts/abi/abigen/testdata/v2/dao.go.txt @@ -606,7 +606,7 @@ func (DAOChangeOfRules) ContractEventName() string { // Solidity: event ChangeOfRules(uint256 minimumQuorum, uint256 debatingPeriodInMinutes, int256 majorityMargin) func (dAO *DAO) UnpackChangeOfRulesEvent(log *types.Log) (*DAOChangeOfRules, error) { event := "ChangeOfRules" - if log.Topics[0] != dAO.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(DAOChangeOfRules) @@ -648,7 +648,7 @@ func (DAOMembershipChanged) ContractEventName() string { // Solidity: event MembershipChanged(address member, bool isMember) func (dAO *DAO) UnpackMembershipChangedEvent(log *types.Log) (*DAOMembershipChanged, error) { event := "MembershipChanged" - if log.Topics[0] != dAO.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(DAOMembershipChanged) @@ -692,7 +692,7 @@ func (DAOProposalAdded) ContractEventName() string { // Solidity: event ProposalAdded(uint256 proposalID, address recipient, uint256 amount, string description) func (dAO *DAO) UnpackProposalAddedEvent(log *types.Log) (*DAOProposalAdded, error) { event := "ProposalAdded" - if log.Topics[0] != dAO.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(DAOProposalAdded) @@ -736,7 +736,7 @@ func (DAOProposalTallied) ContractEventName() string { // Solidity: event ProposalTallied(uint256 proposalID, int256 result, uint256 quorum, bool active) func (dAO *DAO) UnpackProposalTalliedEvent(log *types.Log) (*DAOProposalTallied, error) { event := "ProposalTallied" - if log.Topics[0] != dAO.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(DAOProposalTallied) @@ -780,7 +780,7 @@ func (DAOVoted) ContractEventName() string { // Solidity: event Voted(uint256 proposalID, bool position, address voter, string justification) func (dAO *DAO) UnpackVotedEvent(log *types.Log) (*DAOVoted, error) { event := "Voted" - if log.Topics[0] != dAO.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != dAO.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(DAOVoted) diff --git a/accounts/abi/abigen/testdata/v2/eventchecker.go.txt b/accounts/abi/abigen/testdata/v2/eventchecker.go.txt index 92558c5efe..8ad59e63b1 100644 --- a/accounts/abi/abigen/testdata/v2/eventchecker.go.txt +++ b/accounts/abi/abigen/testdata/v2/eventchecker.go.txt @@ -72,7 +72,7 @@ func (EventCheckerDynamic) ContractEventName() string { // Solidity: event dynamic(string indexed idxStr, bytes indexed idxDat, string str, bytes dat) func (eventChecker *EventChecker) UnpackDynamicEvent(log *types.Log) (*EventCheckerDynamic, error) { event := "dynamic" - if log.Topics[0] != eventChecker.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(EventCheckerDynamic) @@ -112,7 +112,7 @@ func (EventCheckerEmpty) ContractEventName() string { // Solidity: event empty() func (eventChecker *EventChecker) UnpackEmptyEvent(log *types.Log) (*EventCheckerEmpty, error) { event := "empty" - if log.Topics[0] != eventChecker.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(EventCheckerEmpty) @@ -154,7 +154,7 @@ func (EventCheckerIndexed) ContractEventName() string { // Solidity: event indexed(address indexed addr, int256 indexed num) func (eventChecker *EventChecker) UnpackIndexedEvent(log *types.Log) (*EventCheckerIndexed, error) { event := "indexed" - if log.Topics[0] != eventChecker.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(EventCheckerIndexed) @@ -196,7 +196,7 @@ func (EventCheckerMixed) ContractEventName() string { // Solidity: event mixed(address indexed addr, int256 num) func (eventChecker *EventChecker) UnpackMixedEvent(log *types.Log) (*EventCheckerMixed, error) { event := "mixed" - if log.Topics[0] != eventChecker.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(EventCheckerMixed) @@ -238,7 +238,7 @@ func (EventCheckerUnnamed) ContractEventName() string { // Solidity: event unnamed(uint256 indexed arg0, uint256 indexed arg1) func (eventChecker *EventChecker) UnpackUnnamedEvent(log *types.Log) (*EventCheckerUnnamed, error) { event := "unnamed" - if log.Topics[0] != eventChecker.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != eventChecker.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(EventCheckerUnnamed) diff --git a/accounts/abi/abigen/testdata/v2/nameconflict.go.txt b/accounts/abi/abigen/testdata/v2/nameconflict.go.txt index fbc61a5c6c..3fbabee5a5 100644 --- a/accounts/abi/abigen/testdata/v2/nameconflict.go.txt +++ b/accounts/abi/abigen/testdata/v2/nameconflict.go.txt @@ -134,7 +134,7 @@ func (NameConflictLog) ContractEventName() string { // Solidity: event log(int256 msg, int256 _msg) func (nameConflict *NameConflict) UnpackLogEvent(log *types.Log) (*NameConflictLog, error) { event := "log" - if log.Topics[0] != nameConflict.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != nameConflict.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(NameConflictLog) diff --git a/accounts/abi/abigen/testdata/v2/numericmethodname.go.txt b/accounts/abi/abigen/testdata/v2/numericmethodname.go.txt index 9d698a2657..d962583e48 100644 --- a/accounts/abi/abigen/testdata/v2/numericmethodname.go.txt +++ b/accounts/abi/abigen/testdata/v2/numericmethodname.go.txt @@ -136,7 +136,7 @@ func (NumericMethodNameE1TestEvent) ContractEventName() string { // Solidity: event _1TestEvent(address _param) func (numericMethodName *NumericMethodName) UnpackE1TestEventEvent(log *types.Log) (*NumericMethodNameE1TestEvent, error) { event := "_1TestEvent" - if log.Topics[0] != numericMethodName.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != numericMethodName.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(NumericMethodNameE1TestEvent) diff --git a/accounts/abi/abigen/testdata/v2/overload.go.txt b/accounts/abi/abigen/testdata/v2/overload.go.txt index 3b9a95a125..ddddd10186 100644 --- a/accounts/abi/abigen/testdata/v2/overload.go.txt +++ b/accounts/abi/abigen/testdata/v2/overload.go.txt @@ -114,7 +114,7 @@ func (OverloadBar) ContractEventName() string { // Solidity: event bar(uint256 i) func (overload *Overload) UnpackBarEvent(log *types.Log) (*OverloadBar, error) { event := "bar" - if log.Topics[0] != overload.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != overload.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(OverloadBar) @@ -156,7 +156,7 @@ func (OverloadBar0) ContractEventName() string { // Solidity: event bar(uint256 i, uint256 j) func (overload *Overload) UnpackBar0Event(log *types.Log) (*OverloadBar0, error) { event := "bar0" - if log.Topics[0] != overload.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != overload.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(OverloadBar0) diff --git a/accounts/abi/abigen/testdata/v2/token.go.txt b/accounts/abi/abigen/testdata/v2/token.go.txt index 69294f375a..6ebc96861b 100644 --- a/accounts/abi/abigen/testdata/v2/token.go.txt +++ b/accounts/abi/abigen/testdata/v2/token.go.txt @@ -386,7 +386,7 @@ func (TokenTransfer) ContractEventName() string { // Solidity: event Transfer(address indexed from, address indexed to, uint256 value) func (token *Token) UnpackTransferEvent(log *types.Log) (*TokenTransfer, error) { event := "Transfer" - if log.Topics[0] != token.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != token.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(TokenTransfer) diff --git a/accounts/abi/abigen/testdata/v2/tuple.go.txt b/accounts/abi/abigen/testdata/v2/tuple.go.txt index 76a1f58d52..4724fdd351 100644 --- a/accounts/abi/abigen/testdata/v2/tuple.go.txt +++ b/accounts/abi/abigen/testdata/v2/tuple.go.txt @@ -193,7 +193,7 @@ func (TupleTupleEvent) ContractEventName() string { // Solidity: event TupleEvent((uint256,uint256[],(uint256,uint256)[]) a, (uint256,uint256)[2][] b, (uint256,uint256)[][2] c, (uint256,uint256[],(uint256,uint256)[])[] d, uint256[] e) func (tuple *Tuple) UnpackTupleEventEvent(log *types.Log) (*TupleTupleEvent, error) { event := "TupleEvent" - if log.Topics[0] != tuple.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != tuple.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(TupleTupleEvent) @@ -234,7 +234,7 @@ func (TupleTupleEvent2) ContractEventName() string { // Solidity: event TupleEvent2((uint8,uint8)[] arg0) func (tuple *Tuple) UnpackTupleEvent2Event(log *types.Log) (*TupleTupleEvent2, error) { event := "TupleEvent2" - if log.Topics[0] != tuple.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != tuple.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(TupleTupleEvent2) diff --git a/accounts/abi/bind/v2/base.go b/accounts/abi/bind/v2/base.go index 535c0ed4fd..4f2013b4a3 100644 --- a/accounts/abi/bind/v2/base.go +++ b/accounts/abi/bind/v2/base.go @@ -150,6 +150,11 @@ func NewBoundContract(address common.Address, abi abi.ABI, caller ContractCaller } } +// Address returns the deployment address of the contract. +func (c *BoundContract) Address() common.Address { + return c.address +} + // Call invokes the (constant) contract method with params as input values and // sets the output to result. The result type might be a single field for simple // returns, a slice of interfaces for anonymous returns and a struct for named @@ -272,8 +277,10 @@ func (c *BoundContract) RawCreationTransact(opts *TransactOpts, calldata []byte) // Transfer initiates a plain transaction to move funds to the contract, calling // its default method if one is available. func (c *BoundContract) Transfer(opts *TransactOpts) (*types.Transaction, error) { - // todo(rjl493456442) check the payable fallback or receive is defined - // or not, reject invalid transaction at the first place + // Check if payable fallback or receive is defined + if !c.abi.HasReceive() && !(c.abi.HasFallback() && c.abi.Fallback.IsPayable()) { + return nil, fmt.Errorf("contract does not have a payable fallback or receive function") + } return c.transact(opts, &c.address, nil) } diff --git a/accounts/abi/bind/v2/dep_tree_test.go b/accounts/abi/bind/v2/dep_tree_test.go index e686e3fec4..b2470d8a16 100644 --- a/accounts/abi/bind/v2/dep_tree_test.go +++ b/accounts/abi/bind/v2/dep_tree_test.go @@ -158,10 +158,10 @@ func testLinkCase(tcInput linkTestCaseInput) error { overrideAddrs = make(map[rune]common.Address) ) // generate deterministic addresses for the override set. - rand.Seed(42) + rng := rand.New(rand.NewSource(42)) for contract := range tcInput.overrides { var addr common.Address - rand.Read(addr[:]) + rng.Read(addr[:]) overrideAddrs[contract] = addr overridesAddrs[addr] = struct{}{} } diff --git a/accounts/abi/bind/v2/internal/contracts/db/bindings.go b/accounts/abi/bind/v2/internal/contracts/db/bindings.go index fc00a555b5..4ac1652ff7 100644 --- a/accounts/abi/bind/v2/internal/contracts/db/bindings.go +++ b/accounts/abi/bind/v2/internal/contracts/db/bindings.go @@ -276,7 +276,7 @@ func (DBInsert) ContractEventName() string { // Solidity: event Insert(uint256 key, uint256 value, uint256 length) func (dB *DB) UnpackInsertEvent(log *types.Log) (*DBInsert, error) { event := "Insert" - if log.Topics[0] != dB.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != dB.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(DBInsert) @@ -318,7 +318,7 @@ func (DBKeyedInsert) ContractEventName() string { // Solidity: event KeyedInsert(uint256 indexed key, uint256 value) func (dB *DB) UnpackKeyedInsertEvent(log *types.Log) (*DBKeyedInsert, error) { event := "KeyedInsert" - if log.Topics[0] != dB.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != dB.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(DBKeyedInsert) diff --git a/accounts/abi/bind/v2/internal/contracts/events/bindings.go b/accounts/abi/bind/v2/internal/contracts/events/bindings.go index ba4fdc71e3..40d2c44a44 100644 --- a/accounts/abi/bind/v2/internal/contracts/events/bindings.go +++ b/accounts/abi/bind/v2/internal/contracts/events/bindings.go @@ -115,7 +115,7 @@ func (CBasic1) ContractEventName() string { // Solidity: event basic1(uint256 indexed id, uint256 data) func (c *C) UnpackBasic1Event(log *types.Log) (*CBasic1, error) { event := "basic1" - if log.Topics[0] != c.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != c.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(CBasic1) @@ -157,7 +157,7 @@ func (CBasic2) ContractEventName() string { // Solidity: event basic2(bool indexed flag, uint256 data) func (c *C) UnpackBasic2Event(log *types.Log) (*CBasic2, error) { event := "basic2" - if log.Topics[0] != c.abi.Events[event].ID { + if len(log.Topics) == 0 || log.Topics[0] != c.abi.Events[event].ID { return nil, errors.New("event signature mismatch") } out := new(CBasic2) diff --git a/accounts/abi/bind/v2/lib_test.go b/accounts/abi/bind/v2/lib_test.go index ee1db9cf86..11360fc7dd 100644 --- a/accounts/abi/bind/v2/lib_test.go +++ b/accounts/abi/bind/v2/lib_test.go @@ -367,3 +367,28 @@ func TestErrors(t *testing.T) { t.Fatalf("bad unpacked error result: expected Arg4 to be false. got true") } } + +func TestEventUnpackEmptyTopics(t *testing.T) { + c := events.NewC() + + for _, log := range []*types.Log{ + {Topics: []common.Hash{}}, + {Topics: nil}, + } { + _, err := c.UnpackBasic1Event(log) + if err == nil { + t.Fatal("expected error when unpacking event with empty topics, got nil") + } + if err.Error() != "event signature mismatch" { + t.Fatalf("expected 'event signature mismatch' error, got: %v", err) + } + + _, err = c.UnpackBasic2Event(log) + if err == nil { + t.Fatal("expected error when unpacking event with empty topics, got nil") + } + if err.Error() != "event signature mismatch" { + t.Fatalf("expected 'event signature mismatch' error, got: %v", err) + } + } +} diff --git a/accounts/abi/bind/v2/util_test.go b/accounts/abi/bind/v2/util_test.go index b1b647a7b9..5beb0a4fae 100644 --- a/accounts/abi/bind/v2/util_test.go +++ b/accounts/abi/bind/v2/util_test.go @@ -100,22 +100,29 @@ func TestWaitDeployed(t *testing.T) { } func TestWaitDeployedCornerCases(t *testing.T) { - backend := simulated.NewBackend( - types.GenesisAlloc{ - crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)}, - }, + var ( + backend = simulated.NewBackend( + types.GenesisAlloc{ + crypto.PubkeyToAddress(testKey.PublicKey): {Balance: big.NewInt(10000000000000000)}, + }, + ) + head, _ = backend.Client().HeaderByNumber(t.Context(), nil) // Should be child's, good enough + gasPrice = new(big.Int).Add(head.BaseFee, big.NewInt(1)) + signer = types.LatestSigner(params.AllDevChainProtocolChanges) + code = common.FromHex("6060604052600a8060106000396000f360606040526008565b00") + ctx, cancel = context.WithCancel(t.Context()) ) defer backend.Close() - head, _ := backend.Client().HeaderByNumber(context.Background(), nil) // Should be child's, good enough - gasPrice := new(big.Int).Add(head.BaseFee, big.NewInt(1)) - - // Create a transaction to an account. - code := "6060604052600a8060106000396000f360606040526008565b00" - tx := types.NewTransaction(0, common.HexToAddress("0x01"), big.NewInt(0), 3000000, gasPrice, common.FromHex(code)) - tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey) - ctx, cancel := context.WithCancel(context.Background()) - defer cancel() + // 1. WaitDeploy on a transaction that does not deploy a contract, verify it + // returns an error. + tx := types.MustSignNewTx(testKey, signer, &types.LegacyTx{ + Nonce: 0, + To: &common.Address{0x01}, + Gas: 300000, + GasPrice: gasPrice, + Data: code, + }) if err := backend.Client().SendTransaction(ctx, tx); err != nil { t.Errorf("failed to send transaction: %q", err) } @@ -124,14 +131,22 @@ func TestWaitDeployedCornerCases(t *testing.T) { t.Errorf("error mismatch: want %q, got %q, ", bind.ErrNoAddressInReceipt, err) } - // Create a transaction that is not mined. - tx = types.NewContractCreation(1, big.NewInt(0), 3000000, gasPrice, common.FromHex(code)) - tx, _ = types.SignTx(tx, types.LatestSigner(params.AllDevChainProtocolChanges), testKey) + // 2. Create a contract, but cancel the WaitDeploy before it is mined. + tx = types.MustSignNewTx(testKey, signer, &types.LegacyTx{ + Nonce: 1, + Gas: 300000, + GasPrice: gasPrice, + Data: code, + }) + // Wait in another thread so that we can quickly cancel it after submitting + // the transaction. + done := make(chan struct{}) go func() { - contextCanceled := errors.New("context canceled") - if _, err := bind.WaitDeployed(ctx, backend.Client(), tx.Hash()); err.Error() != contextCanceled.Error() { - t.Errorf("error mismatch: want %q, got %q, ", contextCanceled, err) + defer close(done) + _, err := bind.WaitDeployed(ctx, backend.Client(), tx.Hash()) + if !errors.Is(err, context.Canceled) { + t.Errorf("error mismatch: want %v, got %v", context.Canceled, err) } }() @@ -139,4 +154,11 @@ func TestWaitDeployedCornerCases(t *testing.T) { t.Errorf("failed to send transaction: %q", err) } cancel() + + // Wait for goroutine to exit or for a timeout. + select { + case <-done: + case <-time.After(time.Second * 2): + t.Fatalf("failed to cancel wait deploy") + } } diff --git a/accounts/abi/reflect.go b/accounts/abi/reflect.go index 729ca93c54..f6696ea978 100644 --- a/accounts/abi/reflect.go +++ b/accounts/abi/reflect.go @@ -53,7 +53,7 @@ func ConvertType(in interface{}, proto interface{}) interface{} { // indirect recursively dereferences the value until it either gets the value // or finds a big.Int func indirect(v reflect.Value) reflect.Value { - if v.Kind() == reflect.Ptr && v.Elem().Type() != reflect.TypeOf(big.Int{}) { + if v.Kind() == reflect.Ptr && v.Elem().Type() != reflect.TypeFor[big.Int]() { return indirect(v.Elem()) } return v @@ -65,32 +65,32 @@ func reflectIntType(unsigned bool, size int) reflect.Type { if unsigned { switch size { case 8: - return reflect.TypeOf(uint8(0)) + return reflect.TypeFor[uint8]() case 16: - return reflect.TypeOf(uint16(0)) + return reflect.TypeFor[uint16]() case 32: - return reflect.TypeOf(uint32(0)) + return reflect.TypeFor[uint32]() case 64: - return reflect.TypeOf(uint64(0)) + return reflect.TypeFor[uint64]() } } switch size { case 8: - return reflect.TypeOf(int8(0)) + return reflect.TypeFor[int8]() case 16: - return reflect.TypeOf(int16(0)) + return reflect.TypeFor[int16]() case 32: - return reflect.TypeOf(int32(0)) + return reflect.TypeFor[int32]() case 64: - return reflect.TypeOf(int64(0)) + return reflect.TypeFor[int64]() } - return reflect.TypeOf(&big.Int{}) + return reflect.TypeFor[*big.Int]() } // mustArrayToByteSlice creates a new byte slice with the exact same size as value // and copies the bytes in value to the new slice. func mustArrayToByteSlice(value reflect.Value) reflect.Value { - slice := reflect.MakeSlice(reflect.TypeOf([]byte{}), value.Len(), value.Len()) + slice := reflect.ValueOf(make([]byte, value.Len())) reflect.Copy(slice, value) return slice } @@ -104,7 +104,7 @@ func set(dst, src reflect.Value) error { switch { case dstType.Kind() == reflect.Interface && dst.Elem().IsValid() && (dst.Elem().Type().Kind() == reflect.Ptr || dst.Elem().CanSet()): return set(dst.Elem(), src) - case dstType.Kind() == reflect.Ptr && dstType.Elem() != reflect.TypeOf(big.Int{}): + case dstType.Kind() == reflect.Ptr && dstType.Elem() != reflect.TypeFor[big.Int](): return set(dst.Elem(), src) case srcType.AssignableTo(dstType) && dst.CanSet(): dst.Set(src) diff --git a/accounts/abi/reflect_test.go b/accounts/abi/reflect_test.go index 577fa6ca71..f5e509c52f 100644 --- a/accounts/abi/reflect_test.go +++ b/accounts/abi/reflect_test.go @@ -204,12 +204,12 @@ func TestConvertType(t *testing.T) { var fields []reflect.StructField fields = append(fields, reflect.StructField{ Name: "X", - Type: reflect.TypeOf(new(big.Int)), + Type: reflect.TypeFor[*big.Int](), Tag: "json:\"" + "x" + "\"", }) fields = append(fields, reflect.StructField{ Name: "Y", - Type: reflect.TypeOf(new(big.Int)), + Type: reflect.TypeFor[*big.Int](), Tag: "json:\"" + "y" + "\"", }) val := reflect.New(reflect.StructOf(fields)) diff --git a/accounts/abi/type.go b/accounts/abi/type.go index e59456f15a..2fd11ac123 100644 --- a/accounts/abi/type.go +++ b/accounts/abi/type.go @@ -238,9 +238,9 @@ func (t Type) GetType() reflect.Type { case UintTy: return reflectIntType(true, t.Size) case BoolTy: - return reflect.TypeOf(false) + return reflect.TypeFor[bool]() case StringTy: - return reflect.TypeOf("") + return reflect.TypeFor[string]() case SliceTy: return reflect.SliceOf(t.Elem.GetType()) case ArrayTy: @@ -248,19 +248,15 @@ func (t Type) GetType() reflect.Type { case TupleTy: return t.TupleType case AddressTy: - return reflect.TypeOf(common.Address{}) + return reflect.TypeFor[common.Address]() case FixedBytesTy: - return reflect.ArrayOf(t.Size, reflect.TypeOf(byte(0))) + return reflect.ArrayOf(t.Size, reflect.TypeFor[byte]()) case BytesTy: - return reflect.SliceOf(reflect.TypeOf(byte(0))) - case HashTy: - // hashtype currently not used - return reflect.ArrayOf(32, reflect.TypeOf(byte(0))) - case FixedPointTy: - // fixedpoint type currently not used - return reflect.ArrayOf(32, reflect.TypeOf(byte(0))) + return reflect.TypeFor[[]byte]() + case HashTy, FixedPointTy: // currently not used + return reflect.TypeFor[[32]byte]() case FunctionTy: - return reflect.ArrayOf(24, reflect.TypeOf(byte(0))) + return reflect.TypeFor[[24]byte]() default: panic("Invalid type") } diff --git a/accounts/keystore/keystore.go b/accounts/keystore/keystore.go index 3e85b0433b..29c4bdf2ca 100644 --- a/accounts/keystore/keystore.go +++ b/accounts/keystore/keystore.go @@ -50,7 +50,7 @@ var ( ) // KeyStoreType is the reflect type of a keystore backend. -var KeyStoreType = reflect.TypeOf(&KeyStore{}) +var KeyStoreType = reflect.TypeFor[*KeyStore]() // KeyStoreScheme is the protocol scheme prefixing account and wallet URLs. const KeyStoreScheme = "keystore" @@ -99,9 +99,10 @@ func (ks *KeyStore) init(keydir string) { // TODO: In order for this finalizer to work, there must be no references // to ks. addressCache doesn't keep a reference but unlocked keys do, // so the finalizer will not trigger until all timed unlocks have expired. - runtime.SetFinalizer(ks, func(m *KeyStore) { - m.cache.close() - }) + runtime.AddCleanup(ks, func(c *accountCache) { + c.close() + }, ks.cache) + // Create the initial list of wallets from the cache accs := ks.cache.accounts() ks.wallets = make([]accounts.Wallet, len(accs)) @@ -195,11 +196,14 @@ func (ks *KeyStore) Subscribe(sink chan<- accounts.WalletEvent) event.Subscripti // forces a manual refresh (only triggers for systems where the filesystem notifier // is not running). func (ks *KeyStore) updater() { + ticker := time.NewTicker(walletRefreshCycle) + defer ticker.Stop() + for { // Wait for an account update or a refresh timeout select { case <-ks.changes: - case <-time.After(walletRefreshCycle): + case <-ticker.C: } // Run the wallet refresher ks.refreshWallets() @@ -414,6 +418,7 @@ func (ks *KeyStore) Export(a accounts.Account, passphrase, newPassphrase string) if err != nil { return nil, err } + defer zeroKey(key.PrivateKey) var N, P int if store, ok := ks.storage.(*keyStorePassphrase); ok { N, P = store.scryptN, store.scryptP @@ -473,6 +478,7 @@ func (ks *KeyStore) Update(a accounts.Account, passphrase, newPassphrase string) if err != nil { return err } + defer zeroKey(key.PrivateKey) return ks.storage.StoreKey(a.URL.Path, key, newPassphrase) } diff --git a/accounts/keystore/presale.go b/accounts/keystore/presale.go index 0664dc2cdd..6311e8d90a 100644 --- a/accounts/keystore/presale.go +++ b/accounts/keystore/presale.go @@ -81,6 +81,9 @@ func decryptPreSaleKey(fileContent []byte, password string) (key *Key, err error */ passBytes := []byte(password) derivedKey := pbkdf2.Key(passBytes, passBytes, 2000, 16, sha256.New) + if len(cipherText)%aes.BlockSize != 0 { + return nil, errors.New("ciphertext must be a multiple of block size") + } plainText, err := aesCBCDecrypt(derivedKey, cipherText, iv) if err != nil { return nil, err diff --git a/accounts/scwallet/securechannel.go b/accounts/scwallet/securechannel.go index b3a7be8df0..1e0230dc45 100644 --- a/accounts/scwallet/securechannel.go +++ b/accounts/scwallet/securechannel.go @@ -300,6 +300,10 @@ func (s *SecureChannelSession) decryptAPDU(data []byte) ([]byte, error) { return nil, err } + if len(data) == 0 || len(data)%aes.BlockSize != 0 { + return nil, fmt.Errorf("invalid ciphertext length: %d", len(data)) + } + ret := make([]byte, len(data)) crypter := cipher.NewCBCDecrypter(a, s.iv) diff --git a/accounts/scwallet/wallet.go b/accounts/scwallet/wallet.go index 58cfc88301..7612953c22 100644 --- a/accounts/scwallet/wallet.go +++ b/accounts/scwallet/wallet.go @@ -472,6 +472,11 @@ func (w *Wallet) selfDerive() { continue } pairing := w.Hub.pairing(w) + if pairing == nil { + w.lock.Unlock() + reqc <- struct{}{} + continue + } // Device lock obtained, derive the next batch of accounts var ( @@ -631,13 +636,13 @@ func (w *Wallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Accoun } if pin { - pairing := w.Hub.pairing(w) - pairing.Accounts[account.Address] = path - if err := w.Hub.setPairing(w, pairing); err != nil { - return accounts.Account{}, err + if pairing := w.Hub.pairing(w); pairing != nil { + pairing.Accounts[account.Address] = path + if err := w.Hub.setPairing(w, pairing); err != nil { + return accounts.Account{}, err + } } } - return account, nil } @@ -774,11 +779,11 @@ func (w *Wallet) SignTxWithPassphrase(account accounts.Account, passphrase strin // It first checks for the address in the list of pinned accounts, and if it is // not found, attempts to parse the derivation path from the account's URL. func (w *Wallet) findAccountPath(account accounts.Account) (accounts.DerivationPath, error) { - pairing := w.Hub.pairing(w) - if path, ok := pairing.Accounts[account.Address]; ok { - return path, nil + if pairing := w.Hub.pairing(w); pairing != nil { + if path, ok := pairing.Accounts[account.Address]; ok { + return path, nil + } } - // Look for the path in the URL if account.URL.Scheme != w.Hub.scheme { return nil, fmt.Errorf("scheme %s does not match wallet scheme %s", account.URL.Scheme, w.Hub.scheme) diff --git a/accounts/usbwallet/ledger.go b/accounts/usbwallet/ledger.go index 2be6edd44f..80e63f1864 100644 --- a/accounts/usbwallet/ledger.go +++ b/accounts/usbwallet/ledger.go @@ -166,7 +166,7 @@ func (w *ledgerDriver) SignTx(path accounts.DerivationPath, tx *types.Transactio return common.Address{}, nil, accounts.ErrWalletClosed } // Ensure the wallet is capable of signing the given transaction - if chainID != nil && w.version[0] <= 1 && w.version[1] <= 0 && w.version[2] <= 2 { + if chainID != nil && (w.version[0] < 1 || (w.version[0] == 1 && w.version[1] == 0 && w.version[2] < 3)) { //lint:ignore ST1005 brand name displayed on the console return common.Address{}, nil, fmt.Errorf("Ledger v%d.%d.%d doesn't support signing this transaction, please update to v1.0.3 at least", w.version[0], w.version[1], w.version[2]) } @@ -184,7 +184,7 @@ func (w *ledgerDriver) SignTypedMessage(path accounts.DerivationPath, domainHash return nil, accounts.ErrWalletClosed } // Ensure the wallet is capable of signing the given transaction - if w.version[0] < 1 && w.version[1] < 5 { + if w.version[0] < 1 || (w.version[0] == 1 && w.version[1] < 5) { //lint:ignore ST1005 brand name displayed on the console return nil, fmt.Errorf("Ledger version >= 1.5.0 required for EIP-712 signing (found version v%d.%d.%d)", w.version[0], w.version[1], w.version[2]) } diff --git a/accounts/usbwallet/wallet.go b/accounts/usbwallet/wallet.go index 0fd0415a9e..f1597ca1a7 100644 --- a/accounts/usbwallet/wallet.go +++ b/accounts/usbwallet/wallet.go @@ -632,7 +632,7 @@ func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID // data is not supported for Ledger wallets, so this method will always return // an error. func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { - return w.SignText(account, accounts.TextHash(text)) + return w.SignText(account, text) } // SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given diff --git a/appveyor.yml b/appveyor.yml index ae1c74c18e..aeafcfc838 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,6 @@ clone_depth: 5 version: "{branch}.{build}" image: - - Ubuntu - Visual Studio 2019 environment: @@ -17,25 +16,6 @@ install: - go version for: - # Linux has its own script without -arch and -cc. - # The linux builder also runs lint. - - matrix: - only: - - image: Ubuntu - build_script: - - go run build/ci.go lint - - go run build/ci.go check_generate - - go run build/ci.go check_baddeps - - go run build/ci.go install -dlgo - test_script: - - go run build/ci.go test -dlgo -short - - # linux/386 is disabled. - - matrix: - exclude: - - image: Ubuntu - GETH_ARCH: 386 - # Windows builds for amd64 + 386. - matrix: only: diff --git a/beacon/blsync/block_sync_test.go b/beacon/blsync/block_sync_test.go index e7c2c4d163..e471766738 100644 --- a/beacon/blsync/block_sync_test.go +++ b/beacon/blsync/block_sync_test.go @@ -32,7 +32,7 @@ var ( testServer2 = testServer("testServer2") testBlock1 = types.NewBeaconBlock(&deneb.BeaconBlock{ - Slot: 123, + Slot: 127, Body: deneb.BeaconBlockBody{ ExecutionPayload: deneb.ExecutionPayload{ BlockNumber: 456, @@ -41,7 +41,7 @@ var ( }, }) testBlock2 = types.NewBeaconBlock(&deneb.BeaconBlock{ - Slot: 124, + Slot: 128, Body: deneb.BeaconBlockBody{ ExecutionPayload: deneb.ExecutionPayload{ BlockNumber: 457, @@ -49,6 +49,14 @@ var ( }, }, }) + testFinal1 = types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{ + BlockNumber: 395, + BlockHash: zrntcommon.Hash32(common.HexToHash("abbe7625624bf8ddd84723709e2758956289465dd23475f02387e0854942666")), + }) + testFinal2 = types.NewExecutionHeader(&deneb.ExecutionPayloadHeader{ + BlockNumber: 420, + BlockHash: zrntcommon.Hash32(common.HexToHash("9182a6ef8723654de174283750932ccc092378549836bf4873657eeec474598")), + }) ) type testServer string @@ -66,9 +74,10 @@ func TestBlockSync(t *testing.T) { ts.AddServer(testServer1, 1) ts.AddServer(testServer2, 1) - expHeadBlock := func(expHead *types.BeaconBlock) { + expHeadEvent := func(expHead *types.BeaconBlock, expFinal *types.ExecutionHeader) { t.Helper() var expNumber, headNumber uint64 + var expFinalHash, finalHash common.Hash if expHead != nil { p, err := expHead.ExecutionPayload() if err != nil { @@ -76,19 +85,26 @@ func TestBlockSync(t *testing.T) { } expNumber = p.NumberU64() } + if expFinal != nil { + expFinalHash = expFinal.BlockHash() + } select { case event := <-headCh: headNumber = event.Block.NumberU64() + finalHash = event.Finalized default: } if headNumber != expNumber { t.Errorf("Wrong head block, expected block number %d, got %d)", expNumber, headNumber) } + if finalHash != expFinalHash { + t.Errorf("Wrong finalized block, expected block hash %064x, got %064x)", expFinalHash[:], finalHash[:]) + } } // no block requests expected until head tracker knows about a head ts.Run(1) - expHeadBlock(nil) + expHeadEvent(nil, nil) // set block 1 as prefetch head, announced by server 2 head1 := blockHeadInfo(testBlock1) @@ -103,12 +119,13 @@ func TestBlockSync(t *testing.T) { ts.AddAllowance(testServer2, 1) ts.Run(3) // head block still not expected as the fetched block is not the validated head yet - expHeadBlock(nil) + expHeadEvent(nil, nil) // set as validated head, expect no further requests but block 1 set as head block ht.validated.Header = testBlock1.Header() + ht.finalized, ht.finalizedPayload = testBlock1.Header(), testFinal1 ts.Run(4) - expHeadBlock(testBlock1) + expHeadEvent(testBlock1, testFinal1) // set block 2 as prefetch head, announced by server 1 head2 := blockHeadInfo(testBlock2) @@ -126,17 +143,26 @@ func TestBlockSync(t *testing.T) { // expect req2 retry to server 2 ts.Run(7, testServer2, sync.ReqBeaconBlock(head2.BlockRoot)) // now head block should be unavailable again - expHeadBlock(nil) + expHeadEvent(nil, nil) // valid response, now head block should be block 2 immediately as it is already validated + // but head event is still not expected because an epoch boundary was crossed and the + // expected finality update has not arrived yet ts.RequestEvent(request.EvResponse, ts.Request(7, 1), testBlock2) ts.Run(8) - expHeadBlock(testBlock2) + expHeadEvent(nil, nil) + + // expected finality update arrived, now a head event is expected + ht.finalized, ht.finalizedPayload = testBlock2.Header(), testFinal2 + ts.Run(9) + expHeadEvent(testBlock2, testFinal2) } type testHeadTracker struct { - prefetch types.HeadInfo - validated types.SignedHeader + prefetch types.HeadInfo + validated types.SignedHeader + finalized types.Header + finalizedPayload *types.ExecutionHeader } func (h *testHeadTracker) PrefetchHead() types.HeadInfo { @@ -151,13 +177,14 @@ func (h *testHeadTracker) ValidatedOptimistic() (types.OptimisticUpdate, bool) { }, h.validated.Header != (types.Header{}) } -// TODO add test case for finality func (h *testHeadTracker) ValidatedFinality() (types.FinalityUpdate, bool) { - finalized := types.NewExecutionHeader(new(deneb.ExecutionPayloadHeader)) + if h.validated.Header == (types.Header{}) || h.finalizedPayload == nil { + return types.FinalityUpdate{}, false + } return types.FinalityUpdate{ - Attested: types.HeaderWithExecProof{Header: h.validated.Header}, - Finalized: types.HeaderWithExecProof{PayloadHeader: finalized}, + Attested: types.HeaderWithExecProof{Header: h.finalized}, + Finalized: types.HeaderWithExecProof{Header: h.finalized, PayloadHeader: h.finalizedPayload}, Signature: h.validated.Signature, SignatureSlot: h.validated.SignatureSlot, - }, h.validated.Header != (types.Header{}) + }, true } diff --git a/beacon/blsync/engineclient.go b/beacon/blsync/engineclient.go index f9821fc6f3..9fc6a18a57 100644 --- a/beacon/blsync/engineclient.go +++ b/beacon/blsync/engineclient.go @@ -101,7 +101,16 @@ func (ec *engineClient) callNewPayload(fork string, event types.ChainHeadEvent) params = []any{execData} ) switch fork { - case "electra": + case "altair", "bellatrix": + method = "engine_newPayloadV1" + case "capella": + method = "engine_newPayloadV2" + case "deneb": + method = "engine_newPayloadV3" + parentBeaconRoot := event.BeaconHead.ParentRoot + blobHashes := collectBlobHashes(event.Block) + params = append(params, blobHashes, parentBeaconRoot) + default: // electra, fulu and above method = "engine_newPayloadV4" parentBeaconRoot := event.BeaconHead.ParentRoot blobHashes := collectBlobHashes(event.Block) @@ -110,15 +119,6 @@ func (ec *engineClient) callNewPayload(fork string, event types.ChainHeadEvent) hexRequests[i] = hexutil.Bytes(event.ExecRequests[i]) } params = append(params, blobHashes, parentBeaconRoot, hexRequests) - case "deneb": - method = "engine_newPayloadV3" - parentBeaconRoot := event.BeaconHead.ParentRoot - blobHashes := collectBlobHashes(event.Block) - params = append(params, blobHashes, parentBeaconRoot) - case "capella": - method = "engine_newPayloadV2" - default: - method = "engine_newPayloadV1" } ctx, cancel := context.WithTimeout(ec.rootCtx, time.Second*5) @@ -145,12 +145,12 @@ func (ec *engineClient) callForkchoiceUpdated(fork string, event types.ChainHead var method string switch fork { - case "deneb", "electra": - method = "engine_forkchoiceUpdatedV3" + case "altair", "bellatrix": + method = "engine_forkchoiceUpdatedV1" case "capella": method = "engine_forkchoiceUpdatedV2" - default: - method = "engine_forkchoiceUpdatedV1" + default: // deneb, electra, fulu and above + method = "engine_forkchoiceUpdatedV3" } ctx, cancel := context.WithTimeout(ec.rootCtx, time.Second*5) diff --git a/beacon/engine/gen_ed.go b/beacon/engine/gen_ed.go index 0ae5a3b8f1..6893d64a16 100644 --- a/beacon/engine/gen_ed.go +++ b/beacon/engine/gen_ed.go @@ -17,24 +17,23 @@ var _ = (*executableDataMarshaling)(nil) // MarshalJSON marshals as JSON. func (e ExecutableData) MarshalJSON() ([]byte, error) { type ExecutableData struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` - StateRoot common.Hash `json:"stateRoot" gencodec:"required"` - ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"` - Random common.Hash `json:"prevRandao" gencodec:"required"` - Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"` - GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` - ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"` - BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` - BlockHash common.Hash `json:"blockHash" gencodec:"required"` - Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` - ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` + StateRoot common.Hash `json:"stateRoot" gencodec:"required"` + ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` + LogsBloom hexutil.Bytes `json:"logsBloom" gencodec:"required"` + Random common.Hash `json:"prevRandao" gencodec:"required"` + Number hexutil.Uint64 `json:"blockNumber" gencodec:"required"` + GasLimit hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Timestamp hexutil.Uint64 `json:"timestamp" gencodec:"required"` + ExtraData hexutil.Bytes `json:"extraData" gencodec:"required"` + BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` + BlockHash common.Hash `json:"blockHash" gencodec:"required"` + Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` + Withdrawals []*types.Withdrawal `json:"withdrawals"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` } var enc ExecutableData enc.ParentHash = e.ParentHash @@ -59,31 +58,29 @@ func (e ExecutableData) MarshalJSON() ([]byte, error) { enc.Withdrawals = e.Withdrawals enc.BlobGasUsed = (*hexutil.Uint64)(e.BlobGasUsed) enc.ExcessBlobGas = (*hexutil.Uint64)(e.ExcessBlobGas) - enc.ExecutionWitness = e.ExecutionWitness return json.Marshal(&enc) } // UnmarshalJSON unmarshals from JSON. func (e *ExecutableData) UnmarshalJSON(input []byte) error { type ExecutableData struct { - ParentHash *common.Hash `json:"parentHash" gencodec:"required"` - FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"` - StateRoot *common.Hash `json:"stateRoot" gencodec:"required"` - ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"` - Random *common.Hash `json:"prevRandao" gencodec:"required"` - Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"` - GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` - GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` - Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"` - ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"` - BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` - BlockHash *common.Hash `json:"blockHash" gencodec:"required"` - Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` - BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` - ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` - ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` + ParentHash *common.Hash `json:"parentHash" gencodec:"required"` + FeeRecipient *common.Address `json:"feeRecipient" gencodec:"required"` + StateRoot *common.Hash `json:"stateRoot" gencodec:"required"` + ReceiptsRoot *common.Hash `json:"receiptsRoot" gencodec:"required"` + LogsBloom *hexutil.Bytes `json:"logsBloom" gencodec:"required"` + Random *common.Hash `json:"prevRandao" gencodec:"required"` + Number *hexutil.Uint64 `json:"blockNumber" gencodec:"required"` + GasLimit *hexutil.Uint64 `json:"gasLimit" gencodec:"required"` + GasUsed *hexutil.Uint64 `json:"gasUsed" gencodec:"required"` + Timestamp *hexutil.Uint64 `json:"timestamp" gencodec:"required"` + ExtraData *hexutil.Bytes `json:"extraData" gencodec:"required"` + BaseFeePerGas *hexutil.Big `json:"baseFeePerGas" gencodec:"required"` + BlockHash *common.Hash `json:"blockHash" gencodec:"required"` + Transactions []hexutil.Bytes `json:"transactions" gencodec:"required"` + Withdrawals []*types.Withdrawal `json:"withdrawals"` + BlobGasUsed *hexutil.Uint64 `json:"blobGasUsed"` + ExcessBlobGas *hexutil.Uint64 `json:"excessBlobGas"` } var dec ExecutableData if err := json.Unmarshal(input, &dec); err != nil { @@ -157,8 +154,5 @@ func (e *ExecutableData) UnmarshalJSON(input []byte) error { if dec.ExcessBlobGas != nil { e.ExcessBlobGas = (*uint64)(dec.ExcessBlobGas) } - if dec.ExecutionWitness != nil { - e.ExecutionWitness = dec.ExecutionWitness - } return nil } diff --git a/beacon/engine/gen_epe.go b/beacon/engine/gen_epe.go index deada06166..cf7bd9ee3f 100644 --- a/beacon/engine/gen_epe.go +++ b/beacon/engine/gen_epe.go @@ -17,7 +17,7 @@ func (e ExecutionPayloadEnvelope) MarshalJSON() ([]byte, error) { type ExecutionPayloadEnvelope struct { ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` - BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` + BlobsBundle *BlobsBundle `json:"blobsBundle"` Requests []hexutil.Bytes `json:"executionRequests"` Override bool `json:"shouldOverrideBuilder"` Witness *hexutil.Bytes `json:"witness,omitempty"` @@ -42,7 +42,7 @@ func (e *ExecutionPayloadEnvelope) UnmarshalJSON(input []byte) error { type ExecutionPayloadEnvelope struct { ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` BlockValue *hexutil.Big `json:"blockValue" gencodec:"required"` - BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` + BlobsBundle *BlobsBundle `json:"blobsBundle"` Requests []hexutil.Bytes `json:"executionRequests"` Override *bool `json:"shouldOverrideBuilder"` Witness *hexutil.Bytes `json:"witness,omitempty"` diff --git a/beacon/engine/types.go b/beacon/engine/types.go index 76bfd22a23..da9b6568f2 100644 --- a/beacon/engine/types.go +++ b/beacon/engine/types.go @@ -33,8 +33,22 @@ import ( type PayloadVersion byte var ( + // PayloadV1 is the identifier of ExecutionPayloadV1 introduced in paris fork. + // https://github.com/ethereum/execution-apis/blob/main/src/engine/paris.md#executionpayloadv1 PayloadV1 PayloadVersion = 0x1 + + // PayloadV2 is the identifier of ExecutionPayloadV2 introduced in shanghai fork. + // + // https://github.com/ethereum/execution-apis/blob/main/src/engine/shanghai.md#executionpayloadv2 + // ExecutionPayloadV2 has the syntax of ExecutionPayloadV1 and appends a + // single field: withdrawals. PayloadV2 PayloadVersion = 0x2 + + // PayloadV3 is the identifier of ExecutionPayloadV3 introduced in cancun fork. + // + // https://github.com/ethereum/execution-apis/blob/main/src/engine/cancun.md#executionpayloadv3 + // ExecutionPayloadV3 has the syntax of ExecutionPayloadV2 and appends the new + // fields: blobGasUsed and excessBlobGas. PayloadV3 PayloadVersion = 0x3 ) @@ -59,24 +73,23 @@ type payloadAttributesMarshaling struct { // ExecutableData is the data necessary to execute an EL payload. type ExecutableData struct { - ParentHash common.Hash `json:"parentHash" gencodec:"required"` - FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` - StateRoot common.Hash `json:"stateRoot" gencodec:"required"` - ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` - LogsBloom []byte `json:"logsBloom" gencodec:"required"` - Random common.Hash `json:"prevRandao" gencodec:"required"` - Number uint64 `json:"blockNumber" gencodec:"required"` - GasLimit uint64 `json:"gasLimit" gencodec:"required"` - GasUsed uint64 `json:"gasUsed" gencodec:"required"` - Timestamp uint64 `json:"timestamp" gencodec:"required"` - ExtraData []byte `json:"extraData" gencodec:"required"` - BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"` - BlockHash common.Hash `json:"blockHash" gencodec:"required"` - Transactions [][]byte `json:"transactions" gencodec:"required"` - Withdrawals []*types.Withdrawal `json:"withdrawals"` - BlobGasUsed *uint64 `json:"blobGasUsed"` - ExcessBlobGas *uint64 `json:"excessBlobGas"` - ExecutionWitness *types.ExecutionWitness `json:"executionWitness,omitempty"` + ParentHash common.Hash `json:"parentHash" gencodec:"required"` + FeeRecipient common.Address `json:"feeRecipient" gencodec:"required"` + StateRoot common.Hash `json:"stateRoot" gencodec:"required"` + ReceiptsRoot common.Hash `json:"receiptsRoot" gencodec:"required"` + LogsBloom []byte `json:"logsBloom" gencodec:"required"` + Random common.Hash `json:"prevRandao" gencodec:"required"` + Number uint64 `json:"blockNumber" gencodec:"required"` + GasLimit uint64 `json:"gasLimit" gencodec:"required"` + GasUsed uint64 `json:"gasUsed" gencodec:"required"` + Timestamp uint64 `json:"timestamp" gencodec:"required"` + ExtraData []byte `json:"extraData" gencodec:"required"` + BaseFeePerGas *big.Int `json:"baseFeePerGas" gencodec:"required"` + BlockHash common.Hash `json:"blockHash" gencodec:"required"` + Transactions [][]byte `json:"transactions" gencodec:"required"` + Withdrawals []*types.Withdrawal `json:"withdrawals"` + BlobGasUsed *uint64 `json:"blobGasUsed"` + ExcessBlobGas *uint64 `json:"excessBlobGas"` } // JSON type overrides for executableData. @@ -106,13 +119,18 @@ type StatelessPayloadStatusV1 struct { type ExecutionPayloadEnvelope struct { ExecutionPayload *ExecutableData `json:"executionPayload" gencodec:"required"` BlockValue *big.Int `json:"blockValue" gencodec:"required"` - BlobsBundle *BlobsBundleV1 `json:"blobsBundle"` + BlobsBundle *BlobsBundle `json:"blobsBundle"` Requests [][]byte `json:"executionRequests"` Override bool `json:"shouldOverrideBuilder"` Witness *hexutil.Bytes `json:"witness,omitempty"` } -type BlobsBundleV1 struct { +// BlobsBundle includes the marshalled sidecar data. Note this structure is +// shared by BlobsBundleV1 and BlobsBundleV2 for the sake of simplicity. +// +// - BlobsBundleV1: proofs contain exactly len(blobs) kzg proofs. +// - BlobsBundleV2: proofs contain exactly CELLS_PER_EXT_BLOB * len(blobs) cell proofs. +type BlobsBundle struct { Commitments []hexutil.Bytes `json:"commitments"` Proofs []hexutil.Bytes `json:"proofs"` Blobs []hexutil.Bytes `json:"blobs"` @@ -125,7 +143,7 @@ type BlobAndProofV1 struct { type BlobAndProofV2 struct { Blob hexutil.Bytes `json:"blob"` - CellProofs []hexutil.Bytes `json:"proofs"` + CellProofs []hexutil.Bytes `json:"proofs"` // proofs MUST contain exactly CELLS_PER_EXT_BLOB cell proofs. } // JSON type overrides for ExecutionPayloadEnvelope. @@ -297,8 +315,7 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H RequestsHash: requestsHash, } return types.NewBlockWithHeader(header). - WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals}). - WithWitness(data.ExecutionWitness), + WithBody(types.Body{Transactions: txs, Uncles: nil, Withdrawals: data.Withdrawals}), nil } @@ -306,39 +323,47 @@ func ExecutableDataToBlockNoHash(data ExecutableData, versionedHashes []common.H // fields from the given block. It assumes the given block is post-merge block. func BlockToExecutableData(block *types.Block, fees *big.Int, sidecars []*types.BlobTxSidecar, requests [][]byte) *ExecutionPayloadEnvelope { data := &ExecutableData{ - BlockHash: block.Hash(), - ParentHash: block.ParentHash(), - FeeRecipient: block.Coinbase(), - StateRoot: block.Root(), - Number: block.NumberU64(), - GasLimit: block.GasLimit(), - GasUsed: block.GasUsed(), - BaseFeePerGas: block.BaseFee(), - Timestamp: block.Time(), - ReceiptsRoot: block.ReceiptHash(), - LogsBloom: block.Bloom().Bytes(), - Transactions: encodeTransactions(block.Transactions()), - Random: block.MixDigest(), - ExtraData: block.Extra(), - Withdrawals: block.Withdrawals(), - BlobGasUsed: block.BlobGasUsed(), - ExcessBlobGas: block.ExcessBlobGas(), - ExecutionWitness: block.ExecutionWitness(), + BlockHash: block.Hash(), + ParentHash: block.ParentHash(), + FeeRecipient: block.Coinbase(), + StateRoot: block.Root(), + Number: block.NumberU64(), + GasLimit: block.GasLimit(), + GasUsed: block.GasUsed(), + BaseFeePerGas: block.BaseFee(), + Timestamp: block.Time(), + ReceiptsRoot: block.ReceiptHash(), + LogsBloom: block.Bloom().Bytes(), + Transactions: encodeTransactions(block.Transactions()), + Random: block.MixDigest(), + ExtraData: block.Extra(), + Withdrawals: block.Withdrawals(), + BlobGasUsed: block.BlobGasUsed(), + ExcessBlobGas: block.ExcessBlobGas(), } // Add blobs. - bundle := BlobsBundleV1{ + bundle := BlobsBundle{ Commitments: make([]hexutil.Bytes, 0), Blobs: make([]hexutil.Bytes, 0), Proofs: make([]hexutil.Bytes, 0), } for _, sidecar := range sidecars { for j := range sidecar.Blobs { - bundle.Blobs = append(bundle.Blobs, hexutil.Bytes(sidecar.Blobs[j][:])) - bundle.Commitments = append(bundle.Commitments, hexutil.Bytes(sidecar.Commitments[j][:])) + bundle.Blobs = append(bundle.Blobs, sidecar.Blobs[j][:]) + bundle.Commitments = append(bundle.Commitments, sidecar.Commitments[j][:]) } + // - Before the Osaka fork, only version-0 blob transactions should be packed, + // with the proof length equal to len(blobs). + // + // - After the Osaka fork, only version-1 blob transactions should be packed, + // with the proof length equal to CELLS_PER_EXT_BLOB * len(blobs). + // + // Ideally, length validation should be performed based on the bundle version. + // In practice, this is unnecessary because blob transaction filtering is + // already done during payload construction. for _, proof := range sidecar.Proofs { - bundle.Proofs = append(bundle.Proofs, hexutil.Bytes(proof[:])) + bundle.Proofs = append(bundle.Proofs, proof[:]) } } diff --git a/beacon/light/canonical.go b/beacon/light/canonical.go index b5371493b4..56622425b2 100644 --- a/beacon/light/canonical.go +++ b/beacon/light/canonical.go @@ -69,7 +69,10 @@ func newCanonicalStore[T any](db ethdb.Iteratee, keyPrefix []byte) (*canonicalSt // databaseKey returns the database key belonging to the given period. func (cs *canonicalStore[T]) databaseKey(period uint64) []byte { - return binary.BigEndian.AppendUint64(append([]byte{}, cs.keyPrefix...), period) + key := make([]byte, len(cs.keyPrefix)+8) + copy(key, cs.keyPrefix) + binary.BigEndian.PutUint64(key[len(cs.keyPrefix):], period) + return key } // add adds the given item to the database. It also ensures that the range remains diff --git a/beacon/light/request/scheduler.go b/beacon/light/request/scheduler.go index e80daf805e..242ed56d28 100644 --- a/beacon/light/request/scheduler.go +++ b/beacon/light/request/scheduler.go @@ -269,7 +269,7 @@ func (s *Scheduler) addEvent(event Event) { s.Trigger() } -// filterEvent sorts each Event either as a request event or a server event, +// filterEvents sorts each Event either as a request event or a server event, // depending on its type. Request events are also sorted in a map based on the // module that originally initiated the request. It also ensures that no events // related to a server are returned before EvRegistered or after EvUnregistered. diff --git a/beacon/light/sync/head_sync.go b/beacon/light/sync/head_sync.go index 5e41258053..7189767d9c 100644 --- a/beacon/light/sync/head_sync.go +++ b/beacon/light/sync/head_sync.go @@ -105,6 +105,7 @@ func (s *HeadSync) Process(requester request.Requester, events []request.Event) delete(s.serverHeads, event.Server) delete(s.unvalidatedOptimistic, event.Server) delete(s.unvalidatedFinality, event.Server) + delete(s.reqFinalityEpoch, event.Server) } } } diff --git a/beacon/params/checkpoint_hoodi.hex b/beacon/params/checkpoint_hoodi.hex index 2885d7c996..7bac591f96 100644 --- a/beacon/params/checkpoint_hoodi.hex +++ b/beacon/params/checkpoint_hoodi.hex @@ -1 +1 @@ -0x1bbf958008172591b6cbdb3d8d52e26998258e83d4bdb9eec10969d84519a6bd \ No newline at end of file +0xbb7a7f3c40d8ea0b450f91587db65d0f1c079669277e01a0426c8911702a863a \ No newline at end of file diff --git a/beacon/params/checkpoint_mainnet.hex b/beacon/params/checkpoint_mainnet.hex index 417e69a24b..c2886cc564 100644 --- a/beacon/params/checkpoint_mainnet.hex +++ b/beacon/params/checkpoint_mainnet.hex @@ -1 +1 @@ -0x2fe39a39b6f7cbd549e0f74d259de6db486005a65bd3bd92840dd6ce21d6f4c8 \ No newline at end of file +0x2af778d703186526a1b6304b423f338f11556206f618643c3f7fa0d7b1ef5c9b \ No newline at end of file diff --git a/beacon/params/checkpoint_sepolia.hex b/beacon/params/checkpoint_sepolia.hex index 02faf72187..55842f8ac0 100644 --- a/beacon/params/checkpoint_sepolia.hex +++ b/beacon/params/checkpoint_sepolia.hex @@ -1 +1 @@ -0x86686b2b366e24134e0e3969a9c5f3759f92e5d2b04785b42e22cc7d468c2107 \ No newline at end of file +0x48a89c9ea7ba19de2931797974cf8722344ab231c0edada278b108ef74125478 \ No newline at end of file diff --git a/beacon/params/config.go b/beacon/params/config.go index 2f6ba082c5..437aa53788 100644 --- a/beacon/params/config.go +++ b/beacon/params/config.go @@ -20,6 +20,7 @@ import ( "crypto/sha256" "fmt" "math" + "math/big" "os" "slices" "sort" @@ -37,7 +38,7 @@ import ( // across signing different data structures. const syncCommitteeDomain = 7 -var knownForks = []string{"GENESIS", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB"} +var knownForks = []string{"GENESIS", "ALTAIR", "BELLATRIX", "CAPELLA", "DENEB", "ELECTRA", "FULU"} // ClientConfig contains beacon light client configuration. type ClientConfig struct { @@ -90,12 +91,8 @@ func (c *ChainConfig) AddFork(name string, epoch uint64, version []byte) *ChainC // LoadForks parses the beacon chain configuration file (config.yaml) and extracts // the list of forks. -func (c *ChainConfig) LoadForks(path string) error { - file, err := os.ReadFile(path) - if err != nil { - return fmt.Errorf("failed to read beacon chain config file: %v", err) - } - config := make(map[string]string) +func (c *ChainConfig) LoadForks(file []byte) error { + config := make(map[string]any) if err := yaml.Unmarshal(file, &config); err != nil { return fmt.Errorf("failed to parse beacon chain config file: %v", err) } @@ -106,20 +103,45 @@ func (c *ChainConfig) LoadForks(path string) error { epochs["GENESIS"] = 0 for key, value := range config { + if value == nil { + continue + } if strings.HasSuffix(key, "_FORK_VERSION") { name := key[:len(key)-len("_FORK_VERSION")] - if v, err := hexutil.Decode(value); err == nil { + switch version := value.(type) { + case int: + versions[name] = new(big.Int).SetUint64(uint64(version)).FillBytes(make([]byte, 4)) + case int64: + versions[name] = new(big.Int).SetUint64(uint64(version)).FillBytes(make([]byte, 4)) + case uint64: + versions[name] = new(big.Int).SetUint64(version).FillBytes(make([]byte, 4)) + case string: + v, err := hexutil.Decode(version) + if err != nil { + return fmt.Errorf("failed to decode hex fork id %q in beacon chain config file: %v", version, err) + } versions[name] = v - } else { - return fmt.Errorf("failed to decode hex fork id %q in beacon chain config file: %v", value, err) + default: + return fmt.Errorf("invalid fork version %q in beacon chain config file", version) } } if strings.HasSuffix(key, "_FORK_EPOCH") { name := key[:len(key)-len("_FORK_EPOCH")] - if v, err := strconv.ParseUint(value, 10, 64); err == nil { + switch epoch := value.(type) { + case int: + epochs[name] = uint64(epoch) + case int64: + epochs[name] = uint64(epoch) + case uint64: + epochs[name] = epoch + case string: + v, err := strconv.ParseUint(epoch, 10, 64) + if err != nil { + return fmt.Errorf("failed to parse epoch number %q in beacon chain config file: %v", epoch, err) + } epochs[name] = v - } else { - return fmt.Errorf("failed to parse epoch number %q in beacon chain config file: %v", value, err) + default: + return fmt.Errorf("invalid fork epoch %q in beacon chain config file", epoch) } } } diff --git a/beacon/params/config_test.go b/beacon/params/config_test.go new file mode 100644 index 0000000000..0b569b604c --- /dev/null +++ b/beacon/params/config_test.go @@ -0,0 +1,37 @@ +package params + +import ( + "bytes" + "testing" +) + +func TestChainConfig_LoadForks(t *testing.T) { + const config = ` +GENESIS_FORK_VERSION: 0x00000000 + +ALTAIR_FORK_VERSION: 0x00000001 +ALTAIR_FORK_EPOCH: 1 + +EIP7928_FORK_VERSION: 0xb0000038 +EIP7928_FORK_EPOCH: 18446744073709551615 + +EIP7XXX_FORK_VERSION: +EIP7XXX_FORK_EPOCH: + +BLOB_SCHEDULE: [] +` + c := &ChainConfig{} + err := c.LoadForks([]byte(config)) + if err != nil { + t.Fatal(err) + } + + for _, fork := range c.Forks { + if fork.Name == "GENESIS" && (fork.Epoch != 0) { + t.Errorf("unexpected genesis fork epoch %d", fork.Epoch) + } + if fork.Name == "ALTAIR" && (fork.Epoch != 1 || !bytes.Equal(fork.Version, []byte{0, 0, 0, 1})) { + t.Errorf("unexpected altair fork epoch %d version %x", fork.Epoch, fork.Version) + } + } +} diff --git a/beacon/params/networks.go b/beacon/params/networks.go index b35db34fd6..5dcf08cc5d 100644 --- a/beacon/params/networks.go +++ b/beacon/params/networks.go @@ -40,36 +40,39 @@ var ( GenesisTime: 1606824023, Checkpoint: common.HexToHash(checkpointMainnet), }). - AddFork("GENESIS", 0, []byte{0, 0, 0, 0}). - AddFork("ALTAIR", 74240, []byte{1, 0, 0, 0}). - AddFork("BELLATRIX", 144896, []byte{2, 0, 0, 0}). - AddFork("CAPELLA", 194048, []byte{3, 0, 0, 0}). - AddFork("DENEB", 269568, []byte{4, 0, 0, 0}). - AddFork("ELECTRA", 364032, []byte{5, 0, 0, 0}) + AddFork("GENESIS", 0, common.FromHex("0x00000000")). + AddFork("ALTAIR", 74240, common.FromHex("0x01000000")). + AddFork("BELLATRIX", 144896, common.FromHex("0x02000000")). + AddFork("CAPELLA", 194048, common.FromHex("0x03000000")). + AddFork("DENEB", 269568, common.FromHex("0x04000000")). + AddFork("ELECTRA", 364032, common.FromHex("0x05000000")). + AddFork("FULU", 411392, common.FromHex("0x06000000")) SepoliaLightConfig = (&ChainConfig{ GenesisValidatorsRoot: common.HexToHash("0xd8ea171f3c94aea21ebc42a1ed61052acf3f9209c00e4efbaaddac09ed9b8078"), GenesisTime: 1655733600, Checkpoint: common.HexToHash(checkpointSepolia), }). - AddFork("GENESIS", 0, []byte{144, 0, 0, 105}). - AddFork("ALTAIR", 50, []byte{144, 0, 0, 112}). - AddFork("BELLATRIX", 100, []byte{144, 0, 0, 113}). - AddFork("CAPELLA", 56832, []byte{144, 0, 0, 114}). - AddFork("DENEB", 132608, []byte{144, 0, 0, 115}). - AddFork("ELECTRA", 222464, []byte{144, 0, 0, 116}) + AddFork("GENESIS", 0, common.FromHex("0x90000069")). + AddFork("ALTAIR", 50, common.FromHex("0x90000070")). + AddFork("BELLATRIX", 100, common.FromHex("0x90000071")). + AddFork("CAPELLA", 56832, common.FromHex("0x90000072")). + AddFork("DENEB", 132608, common.FromHex("0x90000073")). + AddFork("ELECTRA", 222464, common.FromHex("0x90000074")). + AddFork("FULU", 272640, common.FromHex("0x90000075")) HoleskyLightConfig = (&ChainConfig{ GenesisValidatorsRoot: common.HexToHash("0x9143aa7c615a7f7115e2b6aac319c03529df8242ae705fba9df39b79c59fa8b1"), GenesisTime: 1695902400, Checkpoint: common.HexToHash(checkpointHolesky), }). - AddFork("GENESIS", 0, []byte{1, 1, 112, 0}). - AddFork("ALTAIR", 0, []byte{2, 1, 112, 0}). - AddFork("BELLATRIX", 0, []byte{3, 1, 112, 0}). - AddFork("CAPELLA", 256, []byte{4, 1, 112, 0}). - AddFork("DENEB", 29696, []byte{5, 1, 112, 0}). - AddFork("ELECTRA", 115968, []byte{6, 1, 112, 0}) + AddFork("GENESIS", 0, common.FromHex("0x01017000")). + AddFork("ALTAIR", 0, common.FromHex("0x02017000")). + AddFork("BELLATRIX", 0, common.FromHex("0x03017000")). + AddFork("CAPELLA", 256, common.FromHex("0x04017000")). + AddFork("DENEB", 29696, common.FromHex("0x05017000")). + AddFork("ELECTRA", 115968, common.FromHex("0x06017000")). + AddFork("FULU", 165120, common.FromHex("0x07017000")) HoodiLightConfig = (&ChainConfig{ GenesisValidatorsRoot: common.HexToHash("0x212f13fc4df078b6cb7db228f1c8307566dcecf900867401a92023d7ba99cb5f"), @@ -82,5 +85,5 @@ var ( AddFork("CAPELLA", 0, common.FromHex("0x40000910")). AddFork("DENEB", 0, common.FromHex("0x50000910")). AddFork("ELECTRA", 2048, common.FromHex("0x60000910")). - AddFork("FULU", 18446744073709551615, common.FromHex("0x70000910")) + AddFork("FULU", 50688, common.FromHex("0x70000910")) ) diff --git a/beacon/types/beacon_block.go b/beacon/types/beacon_block.go index a2e31d5abf..82a0814a9f 100644 --- a/beacon/types/beacon_block.go +++ b/beacon/types/beacon_block.go @@ -52,7 +52,7 @@ func BlockFromJSON(forkName string, data []byte) (*BeaconBlock, error) { obj = new(capella.BeaconBlock) case "deneb": obj = new(deneb.BeaconBlock) - case "electra": + case "electra", "fulu": obj = new(electra.BeaconBlock) default: return nil, fmt.Errorf("unsupported fork: %s", forkName) diff --git a/beacon/types/exec_header.go b/beacon/types/exec_header.go index ae79b00841..dbf5c54b36 100644 --- a/beacon/types/exec_header.go +++ b/beacon/types/exec_header.go @@ -45,7 +45,7 @@ func ExecutionHeaderFromJSON(forkName string, data []byte) (*ExecutionHeader, er switch forkName { case "capella": obj = new(capella.ExecutionPayloadHeader) - case "deneb", "electra": // note: the payload type was not changed in electra + case "deneb", "electra", "fulu": // note: the payload type was not changed in electra/fulu obj = new(deneb.ExecutionPayloadHeader) default: return nil, fmt.Errorf("unsupported fork: %s", forkName) diff --git a/build/checksums.txt b/build/checksums.txt index 7641b9ae62..98ee3a91ef 100644 --- a/build/checksums.txt +++ b/build/checksums.txt @@ -1,113 +1,85 @@ # This file contains sha256 checksums of optional build dependencies. -# version:spec-tests fusaka-devnet-3%40v1.0.0 +# version:spec-tests v5.1.0 # https://github.com/ethereum/execution-spec-tests/releases -# https://github.com/ethereum/execution-spec-tests/releases/download/fusaka-devnet-3%40v1.0.0 -576261e1280e5300c458aa9b05eccb2fec5ff80a0005940dc52fa03fdd907249 fixtures_fusaka-devnet-3.tar.gz +# https://github.com/ethereum/execution-spec-tests/releases/download/v5.1.0 +a3192784375acec7eaec492799d5c5d0c47a2909a3cc40178898e4ecd20cc416 fixtures_develop.tar.gz -# version:golang 1.24.4 +# version:golang 1.25.1 # https://go.dev/dl/ -5a86a83a31f9fa81490b8c5420ac384fd3d95a3e71fba665c7b3f95d1dfef2b4 go1.24.4.src.tar.gz -0d2af78e3b6e08f8013dbbdb26ae33052697b6b72e03ec17d496739c2a1aed68 go1.24.4.aix-ppc64.tar.gz -69bef555e114b4a2252452b6e7049afc31fbdf2d39790b669165e89525cd3f5c go1.24.4.darwin-amd64.tar.gz -c4d74453a26f488bdb4b0294da4840d9020806de4661785334eb6d1803ee5c27 go1.24.4.darwin-amd64.pkg -27973684b515eaf461065054e6b572d9390c05e69ba4a423076c160165336470 go1.24.4.darwin-arm64.tar.gz -2fe1f8746745c4bfebd494583aaef24cad42594f6d25ed67856879d567ee66e7 go1.24.4.darwin-arm64.pkg -70b2de9c1cafe5af7be3eb8f80753cce0501ef300db3f3bd59be7ccc464234e1 go1.24.4.dragonfly-amd64.tar.gz -8d529839db29ee171505b89dc9c3de76003a4ab56202d84bddbbecacbfb6d7c9 go1.24.4.freebsd-386.tar.gz -6cbc3ad6cc21bdcc7283824d3ac0e85512c02022f6a35eb2e844882ea6e8448c go1.24.4.freebsd-amd64.tar.gz -d49ae050c20aff646a7641dd903f03eb674570790b90ffb298076c4d41e36655 go1.24.4.freebsd-arm.tar.gz -e31924abef2a28456b7103c0a5d333dcc11ecf19e76d5de1a383ad5fe0b42457 go1.24.4.freebsd-arm64.tar.gz -b5bca135eae8ebddf22972611ac1c58ae9fbb5979fd953cc5245c5b1b2517546 go1.24.4.freebsd-riscv64.tar.gz -7d5efda511ff7e3114b130acee5d0bffbb078fedbfa9b2c1b6a807107e1ca23a go1.24.4.illumos-amd64.tar.gz -130c9b061082eca15513e595e9952a2ded32e737e609dd0e49f7dfa74eba026d go1.24.4.linux-386.tar.gz -77e5da33bb72aeaef1ba4418b6fe511bc4d041873cbf82e5aa6318740df98717 go1.24.4.linux-amd64.tar.gz -d5501ee5aca0f258d5fe9bfaed401958445014495dc115f202d43d5210b45241 go1.24.4.linux-arm64.tar.gz -6a554e32301cecae3162677e66d4264b81b3b1a89592dd1b7b5c552c7a49fe37 go1.24.4.linux-armv6l.tar.gz -b208eb25fe244408cbe269ed426454bc46e59d0e0a749b6240d39e884e969875 go1.24.4.linux-loong64.tar.gz -fddfcb28fd36fe63d2ae181026798f86f3bbd3a7bb0f1e1f617dd3d604bf3fe4 go1.24.4.linux-mips.tar.gz -7934b924d5ab8c8ae3134a09a6ae74d3c39f63f6c4322ec289364dbbf0bac3ca go1.24.4.linux-mips64.tar.gz -fa763d8673f94d6e534bb72c3cf675d4c2b8da4a6da42a89f08c5586106db39c go1.24.4.linux-mips64le.tar.gz -84363dbfe49b41d43df84420a09bd53a4770053d63bfa509868c46a5f8eb3ff7 go1.24.4.linux-mipsle.tar.gz -28fcbd5d3b56493606873c33f2b4bdd84ba93c633f37313613b5a1e6495c6fe5 go1.24.4.linux-ppc64.tar.gz -9ca4afef813a2578c23843b640ae0290aa54b2e3c950a6cc4c99e16a57dec2ec go1.24.4.linux-ppc64le.tar.gz -1d7034f98662d8f2c8abd7c700ada4093acb4f9c00e0e51a30344821d0785c77 go1.24.4.linux-riscv64.tar.gz -0449f3203c39703ab27684be763e9bb78ca9a051e0e4176727aead9461b6deb5 go1.24.4.linux-s390x.tar.gz -954b49ccc2cfcf4b5f7cd33ff662295e0d3b74e7590c8e25fc2abb30bce120ba go1.24.4.netbsd-386.tar.gz -370fabcdfee7c18857c96fdd5b706e025d4fb86a208da88ba56b1493b35498e9 go1.24.4.netbsd-amd64.tar.gz -7935ef95d4d1acc48587b1eb4acab98b0a7d9569736a32398b9c1d2e89026865 go1.24.4.netbsd-arm.tar.gz -ead78fd0fa29fbb176cc83f1caa54032e1a44f842affa56a682c647e0759f237 go1.24.4.netbsd-arm64.tar.gz -913e217394b851a636b99de175f0c2f9ab9938b41c557f047168f77ee485d776 go1.24.4.openbsd-386.tar.gz -24568da3dcbcdb24ec18b631f072faf0f3763e3d04f79032dc56ad9ec35379c4 go1.24.4.openbsd-amd64.tar.gz -45abf523f870632417ab007de3841f64dd906bde546ffc8c6380ccbe91c7fb73 go1.24.4.openbsd-arm.tar.gz -7c57c69b5dd1e946b28a3034c285240a48e2861bdcb50b7d9c0ed61bcf89c879 go1.24.4.openbsd-arm64.tar.gz -91ed711f704829372d6931e1897631ef40288b8f9e3cd6ef4a24df7126d1066a go1.24.4.openbsd-ppc64.tar.gz -de5e270d971c8790e8880168d56a2ea103979927c10ded136d792bbdf9bce3d3 go1.24.4.openbsd-riscv64.tar.gz -ff429d03f00bcd32a50f445320b8329d0fadb2a2fff899c11e95e0922a82c543 go1.24.4.plan9-386.tar.gz -39d6363a43fd16b60ae9ad7346a264e982e4fa653dee3b45f83e03cd2f7a6647 go1.24.4.plan9-amd64.tar.gz -1964ae2571259de77b930e97f2891aa92706ff81aac9909d45bb107b0fab16c8 go1.24.4.plan9-arm.tar.gz -a7f9af424e8fb87886664754badca459513f64f6a321d17f1d219b8edf519821 go1.24.4.solaris-amd64.tar.gz -d454d3cb144432f1726bf00e28c6017e78ccb256a8d01b8e3fb1b2e6b5650f28 go1.24.4.windows-386.zip -966ecace1cdbb3497a2b930bdb0f90c3ad32922fa1a7c655b2d4bbeb7e4ac308 go1.24.4.windows-386.msi -b751a1136cb9d8a2e7ebb22c538c4f02c09b98138c7c8bfb78a54a4566c013b1 go1.24.4.windows-amd64.zip -0cbb6e83865747dbe69b3d4155f92e88fcf336ff5d70182dba145e9d7bd3d8f6 go1.24.4.windows-amd64.msi -d17da51bc85bd010754a4063215d15d2c033cc289d67ca9201a03c9041b2969d go1.24.4.windows-arm64.zip -47dbe734b6a829de45654648a7abcf05bdceef5c80e03ea0b208eeebef75a852 go1.24.4.windows-arm64.msi +d010c109cee94d80efe681eab46bdea491ac906bf46583c32e9f0dbb0bd1a594 go1.25.1.src.tar.gz +1d622468f767a1b9fe1e1e67bd6ce6744d04e0c68712adc689748bbeccb126bb go1.25.1.darwin-amd64.tar.gz +68deebb214f39d542e518ebb0598a406ab1b5a22bba8ec9ade9f55fb4dd94a6c go1.25.1.darwin-arm64.tar.gz +d03cdcbc9bd8baf5cf028de390478e9e2b3e4d0afe5a6582dedc19bfe6a263b2 go1.25.1.linux-386.tar.gz +7716a0d940a0f6ae8e1f3b3f4f36299dc53e31b16840dbd171254312c41ca12e go1.25.1.linux-amd64.tar.gz +65a3e34fb2126f55b34e1edfc709121660e1be2dee6bdf405fc399a63a95a87d go1.25.1.linux-arm64.tar.gz +eb949be683e82a99e9861dafd7057e31ea40b161eae6c4cd18fdc0e8c4ae6225 go1.25.1.linux-armv6l.tar.gz +be13d5479b8c75438f2efcaa8c191fba3af684b3228abc9c99c7aa8502f34424 go1.25.1.windows-386.zip +4a974de310e7ee1d523d2fcedb114ba5fa75408c98eb3652023e55ccf3fa7cab go1.25.1.windows-amd64.zip +45ab4290adbd6ee9e7f18f0d57eaa9008fdbef590882778ed93eac3c8cca06c5 go1.25.1.aix-ppc64.tar.gz +2e3c1549bed3124763774d648f291ac42611232f48320ebbd23517c909c09b81 go1.25.1.dragonfly-amd64.tar.gz +dc0198dd4ec520e13f26798def8750544edf6448d8e9c43fd2a814e4885932af go1.25.1.freebsd-386.tar.gz +c4f1a7e7b258406e6f3b677ecdbd97bbb23ff9c0d44be4eb238a07d360f69ac8 go1.25.1.freebsd-amd64.tar.gz +7772fc5ff71ed39297ec0c1599fc54e399642c9b848eac989601040923b0de9c go1.25.1.freebsd-arm.tar.gz +5bb011d5d5b6218b12189f07aa0be618ab2002662fff1ca40afba7389735c207 go1.25.1.freebsd-arm64.tar.gz +ccac716240cb049bebfafcb7eebc3758512178a4c51fc26da9cc032035d850c8 go1.25.1.freebsd-riscv64.tar.gz +cc53910ffb9fcfdd988a9fa25b5423bae1cfa01b19616be646700e1f5453b466 go1.25.1.illumos-amd64.tar.gz +efe809f923bcedab44bf7be2b3af8d182b512b1bf9c07d302e0c45d26c8f56f3 go1.25.1.linux-loong64.tar.gz +c0de33679f6ed68991dc42dc4a602e74a666e3e166c1748ee1b5d1a7ea2ffbb2 go1.25.1.linux-mips.tar.gz +c270f7b0c0bdfbcd54fef4481227c40d41bb518f9ae38ee930870f04a0a6a589 go1.25.1.linux-mips64.tar.gz +80be871ba9c944f34d1868cdf5047e1cf2e1289fe08cdb90e2453d2f0d6965ae go1.25.1.linux-mips64le.tar.gz +9f09defa9bb22ebf2cde76162f40958564e57ce5c2b3649bc063bebcbc9294c1 go1.25.1.linux-mipsle.tar.gz +2c76b7d278c1d43ad19d478ad3f0f05e7b782b64b90870701b314fa48b5f43c6 go1.25.1.linux-ppc64.tar.gz +8b0c8d3ee5b1b5c28b6bd63dc4438792012e01d03b4bf7a61d985c87edab7d1f go1.25.1.linux-ppc64le.tar.gz +22fe934a9d0c9c57275716c55b92d46ebd887cec3177c9140705efa9f84ba1e2 go1.25.1.linux-riscv64.tar.gz +9cfe517ba423f59f3738ca5c3d907c103253cffbbcc2987142f79c5de8c1bf93 go1.25.1.linux-s390x.tar.gz +6af8a08353e76205d5b743dd7a3f0126684f96f62be0a31b75daf9837e512c46 go1.25.1.netbsd-386.tar.gz +e5d534ff362edb1bd8c8e10892b6a027c4c1482454245d1529167676498684c7 go1.25.1.netbsd-amd64.tar.gz +88bcf39254fdcea6a199c1c27d787831b652427ce60851ae9e41a3d7eb477f45 go1.25.1.netbsd-arm.tar.gz +d7c2eabe1d04ee47bcaea2816fdd90dbd25d90d4dfa756faa9786c788e4f3a4e go1.25.1.netbsd-arm64.tar.gz +14a2845977eb4dde11d929858c437a043467c427db87899935e90cee04a38d72 go1.25.1.openbsd-386.tar.gz +d27ac54b38a13a09c81e67c82ac70d387037341c85c3399291c73e13e83fdd8c go1.25.1.openbsd-amd64.tar.gz +0f4ab5f02500afa4befd51fed1e8b45e4d07ca050f641cc3acc76eaa4027b2c3 go1.25.1.openbsd-arm.tar.gz +d46c3bd156843656f7f3cb0dec27ea51cd926ec3f7b80744bf8156e67c1c812f go1.25.1.openbsd-arm64.tar.gz +c550514c67f22e409be10e40eace761e2e43069f4ef086ae6e60aac736c2b679 go1.25.1.openbsd-ppc64.tar.gz +8a09a8714a2556eb13fc1f10b7ce2553fcea4971e3330fc3be0efd24aab45734 go1.25.1.openbsd-riscv64.tar.gz +b0e1fefaf0c7abd71f139a54eee9767944aff5f0bc9d69c968234804884e552f go1.25.1.plan9-386.tar.gz +e94732c94f149690aa0ab11c26090577211b4a988137cb2c03ec0b54e750402e go1.25.1.plan9-amd64.tar.gz +7eb80e9de1e817d9089a54e8c7c5c8d8ed9e5fb4d4a012fc0f18fc422a484f0c go1.25.1.plan9-arm.tar.gz +1261dfad7c4953c0ab90381bc1242dc54e394db7485c59349428d532b2273343 go1.25.1.solaris-amd64.tar.gz +04bc3c078e9e904c4d58d6ac2532a5bdd402bd36a9ff0b5949b3c5e6006a05ee go1.25.1.windows-arm64.zip -# version:golangci 2.0.2 +# version:golangci 2.4.0 # https://github.com/golangci/golangci-lint/releases/ -# https://github.com/golangci/golangci-lint/releases/download/v2.0.2/ -a88cbdc86b483fe44e90bf2dcc3fec2af8c754116e6edf0aa6592cac5baa7a0e golangci-lint-2.0.2-darwin-amd64.tar.gz -664550e7954f5f4451aae99b4f7382c1a47039c66f39ca605f5d9af1a0d32b49 golangci-lint-2.0.2-darwin-arm64.tar.gz -bda0f0f27d300502faceda8428834a76ca25986f6d9fc2bd41d201c3ed73f08e golangci-lint-2.0.2-freebsd-386.tar.gz -1cbd0c7ade3fb027d61d38a646ec1b51be5846952b4b04a5330e7f4687f2270c golangci-lint-2.0.2-freebsd-amd64.tar.gz -1e828a597726198b2e35acdbcc5f3aad85244d79846d2d2bdb05241c5a535f9e golangci-lint-2.0.2-freebsd-armv6.tar.gz -848b49315dc5cddd0c9ce35e96ab33d584db0ea8fb57bcbf9784f1622bec0269 golangci-lint-2.0.2-freebsd-armv7.tar.gz -cabf9a6beab574c7f98581eb237919e580024759e3cdc05c4d516b044dce6770 golangci-lint-2.0.2-illumos-amd64.tar.gz -2fde80d15ed6527791f106d606120620e913c3a663c90a8596861d0a4461169e golangci-lint-2.0.2-linux-386.deb -804bc6e350a8c613aaa0a33d8d45414a80157b0ba1b2c2335ac859f85ad98ebd golangci-lint-2.0.2-linux-386.rpm -e64beb72fecf581e57d88ae3adb1c9d4bf022694b6bd92e3c8e460910bbdc37d golangci-lint-2.0.2-linux-386.tar.gz -9c55aed174d7a52bb1d4006b36e7edee9023631f6b814a80cb39c9860d6f75c3 golangci-lint-2.0.2-linux-amd64.deb -c55a2ef741a687b4c679696931f7fd4a467babd64c9457cf17bb9632fd1cecd1 golangci-lint-2.0.2-linux-amd64.rpm -89cc8a7810dc63b9a37900da03e37c3601caf46d42265d774e0f1a5d883d53e2 golangci-lint-2.0.2-linux-amd64.tar.gz -a3e78583c4e7ea1b63e82559f126bb3a5b12788676f158526752d53e67824b99 golangci-lint-2.0.2-linux-arm64.deb -bd5dd52b5c9f18aa7a2904eda9a9f91c628e98623fe70b7afcbb847e2de84422 golangci-lint-2.0.2-linux-arm64.rpm -789d5b91219ac68c2336f77d41cd7e33a910420594780f455893f8453d09595b golangci-lint-2.0.2-linux-arm64.tar.gz -534cd4c464a66178714ed68152c1ed7aa73e5700bf409e4ed1a8363adf96afca golangci-lint-2.0.2-linux-armv6.deb -cf7d02905a5fc80b96c9a64621693b4cc7337b1ce29986c19fd72608dafe66c5 golangci-lint-2.0.2-linux-armv6.rpm -a0d81cb527d8fe878377f2356b5773e219b0b91832a6b59e7b9bcf9a90fe0b0e golangci-lint-2.0.2-linux-armv6.tar.gz -dedd5be7fff8cba8fe15b658a59347ea90d7d02a9fff87f09c7687e6da05a8b6 golangci-lint-2.0.2-linux-armv7.deb -85521b6f3ad2f5a2bc9bfe14b9b08623f764964048f75ed6dfcfaf8eb7d57cc1 golangci-lint-2.0.2-linux-armv7.rpm -96471046c7780dda4ea680f65e92c2ef56ff58d40bcffaf6cfe9d6d48e3c27aa golangci-lint-2.0.2-linux-armv7.tar.gz -815d914a7738e4362466b2d11004e8618b696b49e8ace13df2c2b25f28fb1e17 golangci-lint-2.0.2-linux-loong64.deb -f16381e3d8a0f011b95e086d83d620248432b915d01f4beab4d29cfe4dc388b0 golangci-lint-2.0.2-linux-loong64.rpm -1bd8d7714f9c92db6a0f23bae89f39c85ba047bec8eeb42b8748d30ae3228d18 golangci-lint-2.0.2-linux-loong64.tar.gz -ea6e9d4aabb526aa298e47e8b026d8893d918c5eb919ba0ab403e315def74cc5 golangci-lint-2.0.2-linux-mips64.deb -519d8d53af83fdc9c25cc3fba8b663331ac22ef68131d4b0084cb6f425b6f79a golangci-lint-2.0.2-linux-mips64.rpm -80d655a0a1ac1b19dcef4b58fa2a7dadb646cc50ad08d460b5c53cdb421165e4 golangci-lint-2.0.2-linux-mips64.tar.gz -aa0e75384bb482c865d4dfc95d23ceb25666bf20461b67a832f0eea6670312ec golangci-lint-2.0.2-linux-mips64le.deb -f2a8b500fb69bdea1b01df6267aaa5218fa4a58aeb781c1a20d0d802fe465a52 golangci-lint-2.0.2-linux-mips64le.rpm -e66a0c0c9a275f02d27a7caa9576112622306f001d73dfc082cf1ae446fc1242 golangci-lint-2.0.2-linux-mips64le.tar.gz -e85ad51aac6428be2d8a37000d053697371a538a5bcbc1644caa7c5e77f6d0af golangci-lint-2.0.2-linux-ppc64le.deb -906798365eac1944af2a9b9a303e6fd49ec9043307bc681b7a96277f7f8beea5 golangci-lint-2.0.2-linux-ppc64le.rpm -f7f1a271b0af274d6c9ce000f5dc6e1fb194350c67bcc62494f96f791882ba92 golangci-lint-2.0.2-linux-ppc64le.tar.gz -eea8bf643a42bf05de9780530db22923e5ab0d588f0e173594dc6518f2a25d2a golangci-lint-2.0.2-linux-riscv64.deb -4ff40f9fe2954400836e2a011ba4744d00ffab5068a51368552dfce6aba3b81b golangci-lint-2.0.2-linux-riscv64.rpm -531d8f225866674977d630afbf0533eb02f9bec607fb13895f7a2cd7b2e0a648 golangci-lint-2.0.2-linux-riscv64.tar.gz -6f827647046c603f40d97ea5aadc6f48cd0bb5d19f7a3d56500c3b833d2a0342 golangci-lint-2.0.2-linux-s390x.deb -387a090e9576d19ca86aac738172e58e07c19f2784a13bb387f4f0d75fb9c8d3 golangci-lint-2.0.2-linux-s390x.rpm -57de1fb7722a9feb2d11ed0a007a93959d05b9db5929a392abc222e30012467e golangci-lint-2.0.2-linux-s390x.tar.gz -ed95e0492ea86bf79eb661f0334474b2a4255093685ff587eccd797c5a54db7e golangci-lint-2.0.2-netbsd-386.tar.gz -eab81d729778166415d349a80e568b2f2b3a781745a9be3212a92abb1e732daf golangci-lint-2.0.2-netbsd-amd64.tar.gz -d20add73f7c2de2c3b01ed4fd7b63ffcf0a6597d5ea228d1699e92339a3cd047 golangci-lint-2.0.2-netbsd-arm64.tar.gz -4e4f44e6057879cd62424ff1800a767d25a595c0e91d6d48809eea9186b4c739 golangci-lint-2.0.2-netbsd-armv6.tar.gz -51ec17b16d8743ae4098a0171f04f0ed4d64561e3051b982778b0e6c306a1b03 golangci-lint-2.0.2-netbsd-armv7.tar.gz -5482cf27b93fae1765c70ee2a95d4074d038e9dee61bdd61d017ce8893d3a4a8 golangci-lint-2.0.2-source.tar.gz -a35d8fdf3e14079a10880dbbb7586b46faec89be96f086b244b3e565aac80313 golangci-lint-2.0.2-windows-386.zip -fe4b946cc01366b989001215687003a9c4a7098589921f75e6228d6d8cffc15c golangci-lint-2.0.2-windows-amd64.zip -646bd9250ef8c771d85cd22fe8e6f2397ae39599179755e3bbfa9ef97ad44090 golangci-lint-2.0.2-windows-arm64.zip -ce1dc0bad6f8a61d64e6b3779eeb773479c175125d6f686b0e67ef9c8432d16e golangci-lint-2.0.2-windows-armv6.zip -92684a48faabe792b11ac27ca8b25551eff940b0a1e84ad7244e98b4994962db golangci-lint-2.0.2-windows-armv7.zip +# https://github.com/golangci/golangci-lint/releases/download/v2.4.0/ +7904ce63f79db44934939cf7a063086ea0ea98e9b19eba0a9d52ccdd0d21951c golangci-lint-2.4.0-darwin-amd64.tar.gz +cd4dd53fa09b6646baff5fd22b8c64d91db02c21c7496df27992d75d34feec59 golangci-lint-2.4.0-darwin-arm64.tar.gz +d58f426ebe14cc257e81562b4bf37a488ffb4ffbbb3ec73041eb3b38bb25c0e1 golangci-lint-2.4.0-freebsd-386.tar.gz +6ec4a6177fc6c0dd541fbcb3a7612845266d020d35cc6fa92959220cdf64ca39 golangci-lint-2.4.0-freebsd-amd64.tar.gz +4d473e3e71c01feaa915a0604fb35758b41284fb976cdeac3f842118d9ee7e17 golangci-lint-2.4.0-freebsd-armv6.tar.gz +58727746c6530801a3f9a702a5945556a5eb7e88809222536dd9f9d54cafaeff golangci-lint-2.4.0-freebsd-armv7.tar.gz +fbf28c662760e24c32f82f8d16dffdb4a82de7726a52ba1fad94f890c22997ea golangci-lint-2.4.0-illumos-amd64.tar.gz +a15a000a8981ef665e971e0f67e2acda9066a9e37a59344393b7351d8fb49c81 golangci-lint-2.4.0-linux-386.tar.gz +fae792524c04424c0ac369f5b8076f04b45cf29fc945a370e55d369a8dc11840 golangci-lint-2.4.0-linux-amd64.tar.gz +70ac11f55b80ec78fd3a879249cc9255121b8dfd7f7ed4fc46ed137f4abf17e7 golangci-lint-2.4.0-linux-arm64.tar.gz +4acdc40e5cebe99e4e7ced358a05b2e71789f409b41cb4f39bbb86ccfa14b1dc golangci-lint-2.4.0-linux-armv6.tar.gz +2a68749568fa22b4a97cb88dbea655595563c795076536aa6c087f7968784bf3 golangci-lint-2.4.0-linux-armv7.tar.gz +9e3369afb023711036dcb0b4f45c9fe2792af962fa1df050c9f6ac101a6c5d73 golangci-lint-2.4.0-linux-loong64.tar.gz +bb9143d6329be2c4dbfffef9564078e7da7d88e7dde6c829b6263d98e072229e golangci-lint-2.4.0-linux-mips64.tar.gz +5ad1765b40d56cd04d4afd805b3ba6f4bfd9b36181da93c31e9b17e483d8608d golangci-lint-2.4.0-linux-mips64le.tar.gz +918936fb9c0d5ba96bef03cf4348b03938634cfcced49be1e9bb29cb5094fa73 golangci-lint-2.4.0-linux-ppc64le.tar.gz +f7474c638e1fb67ebbdc654b55ca0125377ea0bc88e8fee8d964a4f24eacf828 golangci-lint-2.4.0-linux-riscv64.tar.gz +b617a9543997c8bfceaffa88a75d4e595030c6add69fba800c1e4d8f5fe253dd golangci-lint-2.4.0-linux-s390x.tar.gz +7db027b03a9ba328f795215b04f594036837bc7dd0dd7cd16776b02a6167981c golangci-lint-2.4.0-netbsd-386.tar.gz +52d8f9393f4313df0a62b752c37775e3af0b818e43e8dd28954351542d7c60bc golangci-lint-2.4.0-netbsd-amd64.tar.gz +5c0086027fb5a4af3829e530c8115db4b35d11afe1914322eef528eb8cd38c69 golangci-lint-2.4.0-netbsd-arm64.tar.gz +6b779d6ed1aed87cefe195cc11759902b97a76551b593312c6833f2635a3488f golangci-lint-2.4.0-netbsd-armv6.tar.gz +f00d1f4b7ec3468a0f9fffd0d9ea036248b029b7621cbc9a59c449ef94356d09 golangci-lint-2.4.0-netbsd-armv7.tar.gz +3ce671b0b42b58e35066493aab75a7e2826c9e079988f1ba5d814a4029faaf87 golangci-lint-2.4.0-windows-386.zip +003112f7a56746feaabf20b744054bf9acdf900c9e77176383623c4b1d76aaa9 golangci-lint-2.4.0-windows-amd64.zip +dc0c2092af5d47fc2cd31a1dfe7b4c7e765fab22de98bd21ef2ffcc53ad9f54f golangci-lint-2.4.0-windows-arm64.zip +0263d23e20a260cb1592d35e12a388f99efe2c51b3611fdc66fbd9db1fce664d golangci-lint-2.4.0-windows-armv6.zip +9403c03bf648e6313036e0273149d44bad1b9ad53889b6d00e4ccb842ba3c058 golangci-lint-2.4.0-windows-armv7.zip # This is the builder on PPA that will build Go itself (inception-y), don't modify! # diff --git a/build/ci.go b/build/ci.go index 5126793c3d..abb7c4997f 100644 --- a/build/ci.go +++ b/build/ci.go @@ -31,6 +31,9 @@ Available commands are: install [ -arch architecture ] [ -cc compiler ] [ packages... ] -- builds packages and executables test [ -coverage ] [ packages... ] -- runs the tests + keeper [ -dlgo ] + keeper-archive [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] + archive [ -arch architecture ] [ -type zip|tar ] [ -signer key-envvar ] [ -signify key-envvar ] [ -upload dest ] -- archives build artifacts importkeys -- imports signing keys from env debsrc [ -signer key-id ] [ -upload dest ] -- creates a debian source package @@ -57,6 +60,7 @@ import ( "time" "github.com/cespare/cp" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto/signify" "github.com/ethereum/go-ethereum/internal/build" "github.com/ethereum/go-ethereum/internal/download" @@ -64,6 +68,11 @@ import ( ) var ( + goModules = []string{ + ".", + "./cmd/keeper", + } + // Files that end up in the geth*.zip archive. gethArchiveFiles = []string{ "COPYING", @@ -80,6 +89,42 @@ var ( executablePath("clef"), } + // Keeper build targets with their configurations + keeperTargets = []struct { + Name string + GOOS string + GOARCH string + CC string + Tags string + Env map[string]string + }{ + { + Name: "ziren", + GOOS: "linux", + GOARCH: "mipsle", + // enable when cgo works + // CC: "mipsel-linux-gnu-gcc", + Tags: "ziren", + Env: map[string]string{"GOMIPS": "softfloat", "CGO_ENABLED": "0"}, + }, + { + Name: "wasm-js", + GOOS: "js", + GOARCH: "wasm", + Tags: "example", + }, + { + Name: "wasm-wasi", + GOOS: "wasip1", + GOARCH: "wasm", + Tags: "example", + }, + { + Name: "example", + Tags: "example", + }, + } + // A debian package is created for all executables listed here. debExecutables = []debExecutable{ { @@ -124,6 +169,7 @@ var ( "jammy", // 22.04, EOL: 04/2032 "noble", // 24.04, EOL: 04/2034 "oracular", // 24.10, EOL: 07/2025 + "plucky", // 25.04, EOL: 01/2026 } // This is where the tests should be unpacked. @@ -142,7 +188,7 @@ func executablePath(name string) string { func main() { log.SetFlags(log.Lshortfile) - if !build.FileExist(filepath.Join("build", "ci.go")) { + if !common.FileExist(filepath.Join("build", "ci.go")) { log.Fatal("this script must be run from the root of the repository") } if len(os.Args) < 2 { @@ -171,6 +217,10 @@ func main() { doPurge(os.Args[2:]) case "sanitycheck": doSanityCheck() + case "keeper": + doInstallKeeper(os.Args[2:]) + case "keeper-archive": + doKeeperArchive(os.Args[2:]) default: log.Fatal("unknown command ", os.Args[1]) } @@ -205,9 +255,6 @@ func doInstall(cmdline []string) { // Configure the build. gobuild := tc.Go("build", buildFlags(env, *staticlink, buildTags)...) - // We use -trimpath to avoid leaking local paths into the built executables. - gobuild.Args = append(gobuild.Args, "-trimpath") - // Show packages during build. gobuild.Args = append(gobuild.Args, "-v") @@ -215,7 +262,7 @@ func doInstall(cmdline []string) { // Default: collect all 'main' packages in cmd/ and build those. packages := flag.Args() if len(packages) == 0 { - packages = build.FindMainPackages("./cmd") + packages = build.FindMainPackages(&tc, "./cmd/...") } // Do the build! @@ -227,6 +274,43 @@ func doInstall(cmdline []string) { } } +// doInstallKeeper builds keeper binaries for all supported targets. +func doInstallKeeper(cmdline []string) { + var dlgo = flag.Bool("dlgo", false, "Download Go and build with it") + + flag.CommandLine.Parse(cmdline) + env := build.Env() + + // Configure the toolchain. + tc := build.GoToolchain{} + if *dlgo { + csdb := download.MustLoadChecksums("build/checksums.txt") + tc.Root = build.DownloadGo(csdb) + } + + for _, target := range keeperTargets { + log.Printf("Building keeper-%s", target.Name) + + // Configure the build. + tc.GOARCH = target.GOARCH + tc.GOOS = target.GOOS + tc.CC = target.CC + gobuild := tc.Go("build", buildFlags(env, true, []string{target.Tags})...) + gobuild.Dir = "./cmd/keeper" + gobuild.Args = append(gobuild.Args, "-v") + + for key, value := range target.Env { + gobuild.Env = append(gobuild.Env, key+"="+value) + } + outputName := fmt.Sprintf("keeper-%s", target.Name) + + args := slices.Clone(gobuild.Args) + args = append(args, "-o", executablePath(outputName)) + args = append(args, ".") + build.MustRun(&exec.Cmd{Path: gobuild.Path, Args: args, Env: gobuild.Env}) + } +} + // buildFlags returns the go tool flags for building. func buildFlags(env build.Environment, staticLinking bool, buildTags []string) (flags []string) { var ld []string @@ -259,12 +343,18 @@ func buildFlags(env build.Environment, staticLinking bool, buildTags []string) ( } ld = append(ld, "-extldflags", "'"+strings.Join(extld, " ")+"'") } + // TODO(gballet): revisit after the input api has been defined + if runtime.GOARCH == "wasm" { + ld = append(ld, "-gcflags=all=-d=softfloat") + } if len(ld) > 0 { flags = append(flags, "-ldflags", strings.Join(ld, " ")) } if len(buildTags) > 0 { flags = append(flags, "-tags", strings.Join(buildTags, ",")) } + // We use -trimpath to avoid leaking local paths into the built executables. + flags = append(flags, "-trimpath") return flags } @@ -282,18 +372,24 @@ func doTest(cmdline []string) { race = flag.Bool("race", false, "Execute the race detector") short = flag.Bool("short", false, "Pass the 'short'-flag to go test") cachedir = flag.String("cachedir", "./build/cache", "directory for caching downloads") + threads = flag.Int("p", 1, "Number of CPU threads to use for testing") ) flag.CommandLine.Parse(cmdline) - // Get test fixtures. + // Load checksums file (needed for both spec tests and dlgo) csdb := download.MustLoadChecksums("build/checksums.txt") - downloadSpecTestFixtures(csdb, *cachedir) + + // Get test fixtures. + if !*short { + downloadSpecTestFixtures(csdb, *cachedir) + } // Configure the toolchain. tc := build.GoToolchain{GOARCH: *arch, CC: *cc} if *dlgo { tc.Root = build.DownloadGo(csdb) } + gotest := tc.Go("test") // CI needs a bit more time for the statetests (default 45m). @@ -307,7 +403,7 @@ func doTest(cmdline []string) { // Test a single package at a time. CI builders are slow // and some tests run into timeouts under load. - gotest.Args = append(gotest.Args, "-p", "1") + gotest.Args = append(gotest.Args, "-p", fmt.Sprintf("%d", *threads)) if *coverage { gotest.Args = append(gotest.Args, "-covermode=atomic", "-cover") } @@ -321,18 +417,26 @@ func doTest(cmdline []string) { gotest.Args = append(gotest.Args, "-short") } - packages := []string{"./..."} - if len(flag.CommandLine.Args()) > 0 { - packages = flag.CommandLine.Args() + packages := flag.CommandLine.Args() + if len(packages) > 0 { + gotest.Args = append(gotest.Args, packages...) + build.MustRun(gotest) + return + } + + // No packages specified, run all tests for all modules. + gotest.Args = append(gotest.Args, "./...") + for _, mod := range goModules { + test := *gotest + test.Dir = mod + build.MustRun(&test) } - gotest.Args = append(gotest.Args, packages...) - build.MustRun(gotest) } // downloadSpecTestFixtures downloads and extracts the execution-spec-tests fixtures. func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string { ext := ".tar.gz" - base := "fixtures_fusaka-devnet-3" + base := "fixtures_develop" archivePath := filepath.Join(cachedir, base+ext) if err := csdb.DownloadFileFromKnownURL(archivePath); err != nil { log.Fatal(err) @@ -343,10 +447,6 @@ func downloadSpecTestFixtures(csdb *download.ChecksumDB, cachedir string) string return filepath.Join(cachedir, base) } -// doCheckTidy assets that the Go modules files are tidied already. -func doCheckTidy() { -} - // doCheckGenerate ensures that re-generating generated files does not cause // any mutations in the source file tree. func doCheckGenerate() { @@ -354,40 +454,51 @@ func doCheckGenerate() { cachedir = flag.String("cachedir", "./build/cache", "directory for caching binaries.") tc = new(build.GoToolchain) ) - // Compute the origin hashes of all the files - var hashes map[string][32]byte - var err error - hashes, err = build.HashFolder(".", []string{"tests/testdata", "build/cache", ".git"}) - if err != nil { - log.Fatal("Error computing hashes", "err", err) - } // Run any go generate steps we might be missing var ( protocPath = downloadProtoc(*cachedir) protocGenGoPath = downloadProtocGenGo(*cachedir) ) - c := tc.Go("generate", "./...") pathList := []string{filepath.Join(protocPath, "bin"), protocGenGoPath, os.Getenv("PATH")} - c.Env = append(c.Env, "PATH="+strings.Join(pathList, string(os.PathListSeparator))) - build.MustRun(c) - // Check if generate file hashes have changed - generated, err := build.HashFolder(".", []string{"tests/testdata", "build/cache", ".git"}) - if err != nil { - log.Fatalf("Error re-computing hashes: %v", err) + excludes := []string{"tests/testdata", "build/cache", ".git"} + for i := range excludes { + excludes[i] = filepath.FromSlash(excludes[i]) } - updates := build.DiffHashes(hashes, generated) - for _, file := range updates { - log.Printf("File changed: %s", file) - } - if len(updates) != 0 { - log.Fatal("One or more generated files were updated by running 'go generate ./...'") + + for _, mod := range goModules { + // Compute the origin hashes of all the files + hashes, err := build.HashFolder(mod, excludes) + if err != nil { + log.Fatal("Error computing hashes", "err", err) + } + + c := tc.Go("generate", "./...") + c.Env = append(c.Env, "PATH="+strings.Join(pathList, string(os.PathListSeparator))) + c.Dir = mod + build.MustRun(c) + // Check if generate file hashes have changed + generated, err := build.HashFolder(mod, excludes) + if err != nil { + log.Fatalf("Error re-computing hashes: %v", err) + } + updates := build.DiffHashes(hashes, generated) + for _, file := range updates { + log.Printf("File changed: %s", file) + } + if len(updates) != 0 { + log.Fatal("One or more generated files were updated by running 'go generate ./...'") + } } fmt.Println("No stale files detected.") // Run go mod tidy check. - build.MustRun(tc.Go("mod", "tidy", "-diff")) + for _, mod := range goModules { + tidy := tc.Go("mod", "tidy", "-diff") + tidy.Dir = mod + build.MustRun(tidy) + } fmt.Println("No untidy module files detected.") } @@ -427,14 +538,30 @@ func doLint(cmdline []string) { cachedir = flag.String("cachedir", "./build/cache", "directory for caching golangci-lint binary.") ) flag.CommandLine.Parse(cmdline) - packages := []string{"./..."} - if len(flag.CommandLine.Args()) > 0 { - packages = flag.CommandLine.Args() - } linter := downloadLinter(*cachedir) - lflags := []string{"run", "--config", ".golangci.yml"} - build.MustRunCommandWithOutput(linter, append(lflags, packages...)...) + linter, err := filepath.Abs(linter) + if err != nil { + log.Fatal(err) + } + config, err := filepath.Abs(".golangci.yml") + if err != nil { + log.Fatal(err) + } + + lflags := []string{"run", "--config", config} + packages := flag.CommandLine.Args() + if len(packages) > 0 { + build.MustRunCommandWithOutput(linter, append(lflags, packages...)...) + } else { + // Run for all modules in workspace. + for _, mod := range goModules { + args := append(lflags, "./...") + lintcmd := exec.Command(linter, args...) + lintcmd.Dir = mod + build.MustRunWithOutput(lintcmd) + } + } fmt.Println("You have achieved perfection.") } @@ -590,6 +717,32 @@ func doArchive(cmdline []string) { } } +func doKeeperArchive(cmdline []string) { + var ( + signer = flag.String("signer", "", `Environment variable holding the signing key (e.g. LINUX_SIGNING_KEY)`) + signify = flag.String("signify", "", `Environment variable holding the signify key (e.g. LINUX_SIGNIFY_KEY)`) + upload = flag.String("upload", "", `Destination to upload the archives (usually "gethstore/builds")`) + ) + flag.CommandLine.Parse(cmdline) + + var ( + env = build.Env() + vsn = version.Archive(env.Commit) + keeper = "keeper-" + vsn + ".tar.gz" + ) + maybeSkipArchive(env) + files := []string{"COPYING"} + for _, target := range keeperTargets { + files = append(files, executablePath(fmt.Sprintf("keeper-%s", target.Name))) + } + if err := build.WriteArchive(keeper, files); err != nil { + log.Fatal(err) + } + if err := archiveUpload(keeper, *upload, *signer, *signify); err != nil { + log.Fatal(err) + } +} + func archiveBasename(arch string, archiveVersion string) string { platform := runtime.GOOS + "-" + arch if arch == "arm" { @@ -862,7 +1015,7 @@ func ppaUpload(workdir, ppa, sshUser string, files []string) { var idfile string if sshkey := getenvBase64("PPA_SSH_KEY"); len(sshkey) > 0 { idfile = filepath.Join(workdir, "sshkey") - if !build.FileExist(idfile) { + if !common.FileExist(idfile) { os.WriteFile(idfile, sshkey, 0600) } } diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 39ff5d83c6..0000000000 --- a/circle.yml +++ /dev/null @@ -1,32 +0,0 @@ -machine: - services: - - docker - -dependencies: - cache_directories: - - "~/.ethash" # Cache the ethash DAG generated by hive for consecutive builds - - "~/.docker" # Cache all docker images manually to avoid lengthy rebuilds - override: - # Restore all previously cached docker images - - mkdir -p ~/.docker - - for img in `ls ~/.docker`; do docker load -i ~/.docker/$img; done - - # Pull in and hive, restore cached ethash DAGs and do a dry run - - go get -u github.com/karalabe/hive - - (cd ~/.go_workspace/src/github.com/karalabe/hive && mkdir -p workspace/ethash/ ~/.ethash) - - (cd ~/.go_workspace/src/github.com/karalabe/hive && cp -r ~/.ethash/. workspace/ethash/) - - (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=NONE --test=. --sim=. --loglevel=6) - - # Cache all the docker images and the ethash DAGs - - for img in `docker images | grep -v "^" | tail -n +2 | awk '{print $1}'`; do docker save $img > ~/.docker/`echo $img | tr '/' ':'`.tar; done - - cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/ethash/. ~/.ethash - -test: - override: - # Build Geth and move into a known folder - - make geth - - cp ./build/bin/geth $HOME/geth - - # Run hive and move all generated logs into the public artifacts folder - - (cd ~/.go_workspace/src/github.com/karalabe/hive && hive --docker-noshell --client=go-ethereum:local --override=$HOME/geth --test=. --sim=.) - - cp -r ~/.go_workspace/src/github.com/karalabe/hive/workspace/logs/* $CIRCLE_ARTIFACTS diff --git a/cmd/devp2p/README.md b/cmd/devp2p/README.md index ad2985b4b0..b20d921dc4 100644 --- a/cmd/devp2p/README.md +++ b/cmd/devp2p/README.md @@ -121,7 +121,7 @@ with our test chain. The chain files are located in `./cmd/devp2p/internal/ethte --nat=none \ --networkid 3503995874084926 \ --verbosity 5 \ - --authrpc.jwtsecret 0x7365637265747365637265747365637265747365637265747365637265747365 + --authrpc.jwtsecret jwt.secret Note that the tests also require access to the engine API. The test suite can now be executed using the devp2p tool. @@ -130,7 +130,7 @@ The test suite can now be executed using the devp2p tool. --chain internal/ethtest/testdata \ --node enode://.... \ --engineapi http://127.0.0.1:8551 \ - --jwtsecret 0x7365637265747365637265747365637265747365637265747365637265747365 + --jwtsecret $(cat jwt.secret) Repeat the above process (re-initialising the node) in order to run the Eth Protocol test suite again. diff --git a/cmd/devp2p/internal/ethtest/mkchain.sh b/cmd/devp2p/internal/ethtest/mkchain.sh index b9253e8ca7..fab630d977 100644 --- a/cmd/devp2p/internal/ethtest/mkchain.sh +++ b/cmd/devp2p/internal/ethtest/mkchain.sh @@ -1,9 +1,10 @@ #!/bin/sh hivechain generate \ + --pos \ --fork-interval 6 \ --tx-interval 1 \ - --length 500 \ + --length 600 \ --outdir testdata \ - --lastfork cancun \ + --lastfork prague \ --outputs accounts,genesis,chain,headstate,txinfo,headblock,headfcu,newpayload,forkenv diff --git a/cmd/devp2p/internal/ethtest/protocol.go b/cmd/devp2p/internal/ethtest/protocol.go index a21d1ca7a1..af76082318 100644 --- a/cmd/devp2p/internal/ethtest/protocol.go +++ b/cmd/devp2p/internal/ethtest/protocol.go @@ -86,3 +86,9 @@ func protoOffset(proto Proto) uint64 { panic("unhandled protocol") } } + +// msgTypePtr is the constraint for protocol message types. +type msgTypePtr[U any] interface { + *U + Kind() byte +} diff --git a/cmd/devp2p/internal/ethtest/snap.go b/cmd/devp2p/internal/ethtest/snap.go index 9c1efa0e8e..f4fce0931f 100644 --- a/cmd/devp2p/internal/ethtest/snap.go +++ b/cmd/devp2p/internal/ethtest/snap.go @@ -86,9 +86,9 @@ func (s *Suite) TestSnapGetAccountRange(t *utesting.T) { root: root, startingHash: zero, limitHash: ffHash, - expAccounts: 86, + expAccounts: 67, expFirst: firstKey, - expLast: common.HexToHash("0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099"), + expLast: common.HexToHash("0x622e662246601dd04f996289ce8b85e86db7bb15bb17f86487ec9d543ddb6f9a"), desc: "In this test, we request the entire state range, but limit the response to 4000 bytes.", }, { @@ -96,9 +96,9 @@ func (s *Suite) TestSnapGetAccountRange(t *utesting.T) { root: root, startingHash: zero, limitHash: ffHash, - expAccounts: 65, + expAccounts: 49, expFirst: firstKey, - expLast: common.HexToHash("0x2e6fe1362b3e388184fd7bf08e99e74170b26361624ffd1c5f646da7067b58b6"), + expLast: common.HexToHash("0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099"), desc: "In this test, we request the entire state range, but limit the response to 3000 bytes.", }, { @@ -106,9 +106,9 @@ func (s *Suite) TestSnapGetAccountRange(t *utesting.T) { root: root, startingHash: zero, limitHash: ffHash, - expAccounts: 44, + expAccounts: 34, expFirst: firstKey, - expLast: common.HexToHash("0x1c3f74249a4892081ba0634a819aec9ed25f34c7653f5719b9098487e65ab595"), + expLast: common.HexToHash("0x2ef46ebd2073cecde499c2e8df028ad79a26d57bfaa812c4c6f7eb4c9617b913"), desc: "In this test, we request the entire state range, but limit the response to 2000 bytes.", }, { @@ -177,9 +177,9 @@ The server should return the first available account.`, root: root, startingHash: firstKey, limitHash: ffHash, - expAccounts: 86, + expAccounts: 67, expFirst: firstKey, - expLast: common.HexToHash("0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099"), + expLast: common.HexToHash("0x622e662246601dd04f996289ce8b85e86db7bb15bb17f86487ec9d543ddb6f9a"), desc: `In this test, startingHash is exactly the first available account key. The server should return the first available account of the state as the first item.`, }, @@ -188,9 +188,9 @@ The server should return the first available account of the state as the first i root: root, startingHash: hashAdd(firstKey, 1), limitHash: ffHash, - expAccounts: 86, + expAccounts: 67, expFirst: secondKey, - expLast: common.HexToHash("0x4615e5f5df5b25349a00ad313c6cd0436b6c08ee5826e33a018661997f85ebaa"), + expLast: common.HexToHash("0x66192e4c757fba1cdc776e6737008f42d50370d3cd801db3624274283bf7cd63"), desc: `In this test, startingHash is after the first available key. The server should return the second account of the state as the first item.`, }, @@ -226,9 +226,9 @@ server to return no data because genesis is older than 127 blocks.`, root: s.chain.RootAt(int(s.chain.Head().Number().Uint64()) - 127), startingHash: zero, limitHash: ffHash, - expAccounts: 84, + expAccounts: 66, expFirst: firstKey, - expLast: common.HexToHash("0x580aa878e2f92d113a12c0a3ce3c21972b03dbe80786858d49a72097e2c491a3"), + expLast: common.HexToHash("0x729953a43ed6c913df957172680a17e5735143ad767bda8f58ac84ec62fbec5e"), desc: `This test requests data at a state root that is 127 blocks old. We expect the server to have this state available.`, }, @@ -657,8 +657,8 @@ The server should reject the request.`, // It's a bit unfortunate these are hard-coded, but the result depends on // a lot of aspects of the state trie and can't be guessed in a simple // way. So you'll have to update this when the test chain is changed. - common.HexToHash("0x3e963a69401a70224cbfb8c0cc2249b019041a538675d71ccf80c9328d114e2e"), - common.HexToHash("0xd0670d09cdfbf3c6320eb3e92c47c57baa6c226551a2d488c05581091e6b1689"), + common.HexToHash("0x5bdc0d6057b35642a16d27223ea5454e5a17a400e28f7328971a5f2a87773b76"), + common.HexToHash("0x0a76c9812ca90ffed8ee4d191e683f93386b6e50cfe3679c0760d27510aa7fc5"), empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, empty, @@ -678,8 +678,8 @@ The server should reject the request.`, // be updated when the test chain is changed. expHashes: []common.Hash{ empty, - common.HexToHash("0xd0670d09cdfbf3c6320eb3e92c47c57baa6c226551a2d488c05581091e6b1689"), - common.HexToHash("0x3e963a69401a70224cbfb8c0cc2249b019041a538675d71ccf80c9328d114e2e"), + common.HexToHash("0x0a76c9812ca90ffed8ee4d191e683f93386b6e50cfe3679c0760d27510aa7fc5"), + common.HexToHash("0x5bdc0d6057b35642a16d27223ea5454e5a17a400e28f7328971a5f2a87773b76"), }, }, diff --git a/cmd/devp2p/internal/ethtest/suite.go b/cmd/devp2p/internal/ethtest/suite.go index 47d00761f3..c23360bf82 100644 --- a/cmd/devp2p/internal/ethtest/suite.go +++ b/cmd/devp2p/internal/ethtest/suite.go @@ -196,6 +196,7 @@ to check if the node disconnects after receiving multiple invalid requests.`) func (s *Suite) TestSimultaneousRequests(t *utesting.T) { t.Log(`This test requests blocks headers from the node, performing two requests concurrently, with different request IDs.`) + conn, err := s.dialAndPeer(nil) if err != nil { t.Fatalf("peering failed: %v", err) @@ -235,37 +236,36 @@ concurrently, with different request IDs.`) } // Wait for responses. - headers1 := new(eth.BlockHeadersPacket) - if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, &headers1); err != nil { - t.Fatalf("error reading block headers msg: %v", err) - } - if got, want := headers1.RequestId, req1.RequestId; got != want { - t.Fatalf("unexpected request id in response: got %d, want %d", got, want) - } - headers2 := new(eth.BlockHeadersPacket) - if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, &headers2); err != nil { - t.Fatalf("error reading block headers msg: %v", err) - } - if got, want := headers2.RequestId, req2.RequestId; got != want { - t.Fatalf("unexpected request id in response: got %d, want %d", got, want) + // Note they can arrive in either order. + resp, err := collectResponses(conn, 2, func(msg *eth.BlockHeadersPacket) uint64 { + if msg.RequestId != 111 && msg.RequestId != 222 { + t.Fatalf("response with unknown request ID: %v", msg.RequestId) + } + return msg.RequestId + }) + if err != nil { + t.Fatal(err) } - // Check received headers for accuracy. + // Check if headers match. + resp1 := resp[111] if expected, err := s.chain.GetHeaders(req1); err != nil { t.Fatalf("failed to get expected headers for request 1: %v", err) - } else if !headersMatch(expected, headers1.BlockHeadersRequest) { - t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers1) + } else if !headersMatch(expected, resp1.BlockHeadersRequest) { + t.Fatalf("header mismatch for request ID %v: \nexpected %v \ngot %v", 111, expected, resp1) } + resp2 := resp[222] if expected, err := s.chain.GetHeaders(req2); err != nil { t.Fatalf("failed to get expected headers for request 2: %v", err) - } else if !headersMatch(expected, headers2.BlockHeadersRequest) { - t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers2) + } else if !headersMatch(expected, resp2.BlockHeadersRequest) { + t.Fatalf("header mismatch for request ID %v: \nexpected %v \ngot %v", 222, expected, resp2) } } func (s *Suite) TestSameRequestID(t *utesting.T) { t.Log(`This test requests block headers, performing two concurrent requests with the same request ID. The node should handle the request by responding to both requests.`) + conn, err := s.dialAndPeer(nil) if err != nil { t.Fatalf("peering failed: %v", err) @@ -289,7 +289,7 @@ same request ID. The node should handle the request by responding to both reques Origin: eth.HashOrNumber{ Number: 33, }, - Amount: 2, + Amount: 3, }, } @@ -301,35 +301,52 @@ same request ID. The node should handle the request by responding to both reques t.Fatalf("failed to write to connection: %v", err) } - // Wait for the responses. - headers1 := new(eth.BlockHeadersPacket) - if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, &headers1); err != nil { - t.Fatalf("error reading from connection: %v", err) - } - if got, want := headers1.RequestId, request1.RequestId; got != want { - t.Fatalf("unexpected request id: got %d, want %d", got, want) - } - headers2 := new(eth.BlockHeadersPacket) - if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, &headers2); err != nil { - t.Fatalf("error reading from connection: %v", err) - } - if got, want := headers2.RequestId, request2.RequestId; got != want { - t.Fatalf("unexpected request id: got %d, want %d", got, want) + // Wait for the responses. They can arrive in either order, and we can't tell them + // apart by their request ID, so use the number of headers instead. + resp, err := collectResponses(conn, 2, func(msg *eth.BlockHeadersPacket) uint64 { + id := uint64(len(msg.BlockHeadersRequest)) + if id != 2 && id != 3 { + t.Fatalf("invalid number of headers in response: %d", id) + } + return id + }) + if err != nil { + t.Fatal(err) } // Check if headers match. + resp1 := resp[2] if expected, err := s.chain.GetHeaders(request1); err != nil { - t.Fatalf("failed to get expected block headers: %v", err) - } else if !headersMatch(expected, headers1.BlockHeadersRequest) { - t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers1) + t.Fatalf("failed to get expected headers for request 1: %v", err) + } else if !headersMatch(expected, resp1.BlockHeadersRequest) { + t.Fatalf("headers mismatch: \nexpected %v \ngot %v", expected, resp1) } + resp2 := resp[3] if expected, err := s.chain.GetHeaders(request2); err != nil { - t.Fatalf("failed to get expected block headers: %v", err) - } else if !headersMatch(expected, headers2.BlockHeadersRequest) { - t.Fatalf("header mismatch: \nexpected %v \ngot %v", expected, headers2) + t.Fatalf("failed to get expected headers for request 2: %v", err) + } else if !headersMatch(expected, resp2.BlockHeadersRequest) { + t.Fatalf("headers mismatch: \nexpected %v \ngot %v", expected, resp2) } } +// collectResponses waits for n messages of type T on the given connection. +// The messsages are collected according to the 'identity' function. +func collectResponses[T any, P msgTypePtr[T]](conn *Conn, n int, identity func(P) uint64) (map[uint64]P, error) { + resp := make(map[uint64]P, n) + for range n { + r := new(T) + if err := conn.ReadMsg(ethProto, eth.BlockHeadersMsg, r); err != nil { + return resp, fmt.Errorf("read error: %v", err) + } + id := identity(r) + if resp[id] != nil { + return resp, fmt.Errorf("duplicate response %v", r) + } + resp[id] = r + } + return resp, nil +} + func (s *Suite) TestZeroRequestID(t *utesting.T) { t.Log(`This test sends a GetBlockHeaders message with a request-id of zero, and expects a response.`) @@ -887,7 +904,7 @@ func (s *Suite) makeBlobTxs(count, blobs int, discriminator byte) (txs types.Tra from, nonce := s.chain.GetSender(5) for i := 0; i < count; i++ { // Make blob data, max of 2 blobs per tx. - blobdata := make([]byte, blobs%3) + blobdata := make([]byte, min(blobs, 2)) for i := range blobdata { blobdata[i] = discriminator blobs -= 1 @@ -1133,7 +1150,10 @@ func (s *Suite) testBadBlobTx(t *utesting.T, tx *types.Transaction, badTx *types // transmit the same tx but with correct sidecar from the good peer. var req *eth.GetPooledTransactionsPacket - req, err = readUntil[eth.GetPooledTransactionsPacket](context.Background(), conn) + ctx, cancel := context.WithTimeout(context.Background(), 12*time.Second) + defer cancel() + + req, err = readUntil[eth.GetPooledTransactionsPacket](ctx, conn) if err != nil { errc <- fmt.Errorf("reading pooled tx request failed: %v", err) return diff --git a/cmd/devp2p/internal/ethtest/testdata/chain.rlp b/cmd/devp2p/internal/ethtest/testdata/chain.rlp index 2964c02bb1..7d4f4b3efe 100644 Binary files a/cmd/devp2p/internal/ethtest/testdata/chain.rlp and b/cmd/devp2p/internal/ethtest/testdata/chain.rlp differ diff --git a/cmd/devp2p/internal/ethtest/testdata/forkenv.json b/cmd/devp2p/internal/ethtest/testdata/forkenv.json index 86c49e2b97..6679b73a2e 100644 --- a/cmd/devp2p/internal/ethtest/testdata/forkenv.json +++ b/cmd/devp2p/internal/ethtest/testdata/forkenv.json @@ -1,20 +1,27 @@ { - "HIVE_CANCUN_TIMESTAMP": "840", + "HIVE_CANCUN_BLOB_BASE_FEE_UPDATE_FRACTION": "3338477", + "HIVE_CANCUN_BLOB_MAX": "6", + "HIVE_CANCUN_BLOB_TARGET": "3", + "HIVE_CANCUN_TIMESTAMP": "60", "HIVE_CHAIN_ID": "3503995874084926", - "HIVE_FORK_ARROW_GLACIER": "60", - "HIVE_FORK_BERLIN": "48", - "HIVE_FORK_BYZANTIUM": "18", - "HIVE_FORK_CONSTANTINOPLE": "24", - "HIVE_FORK_GRAY_GLACIER": "66", + "HIVE_FORK_ARROW_GLACIER": "0", + "HIVE_FORK_BERLIN": "0", + "HIVE_FORK_BYZANTIUM": "0", + "HIVE_FORK_CONSTANTINOPLE": "0", + "HIVE_FORK_GRAY_GLACIER": "0", "HIVE_FORK_HOMESTEAD": "0", - "HIVE_FORK_ISTANBUL": "36", - "HIVE_FORK_LONDON": "54", - "HIVE_FORK_MUIR_GLACIER": "42", - "HIVE_FORK_PETERSBURG": "30", - "HIVE_FORK_SPURIOUS": "12", - "HIVE_FORK_TANGERINE": "6", - "HIVE_MERGE_BLOCK_ID": "72", + "HIVE_FORK_ISTANBUL": "0", + "HIVE_FORK_LONDON": "0", + "HIVE_FORK_MUIR_GLACIER": "0", + "HIVE_FORK_PETERSBURG": "0", + "HIVE_FORK_SPURIOUS": "0", + "HIVE_FORK_TANGERINE": "0", + "HIVE_MERGE_BLOCK_ID": "0", "HIVE_NETWORK_ID": "3503995874084926", - "HIVE_SHANGHAI_TIMESTAMP": "780", - "HIVE_TERMINAL_TOTAL_DIFFICULTY": "9454784" + "HIVE_PRAGUE_BLOB_BASE_FEE_UPDATE_FRACTION": "5007716", + "HIVE_PRAGUE_BLOB_MAX": "9", + "HIVE_PRAGUE_BLOB_TARGET": "6", + "HIVE_PRAGUE_TIMESTAMP": "120", + "HIVE_SHANGHAI_TIMESTAMP": "0", + "HIVE_TERMINAL_TOTAL_DIFFICULTY": "131072" } \ No newline at end of file diff --git a/cmd/devp2p/internal/ethtest/testdata/genesis.json b/cmd/devp2p/internal/ethtest/testdata/genesis.json index ace2f78815..c8ed44b885 100644 --- a/cmd/devp2p/internal/ethtest/testdata/genesis.json +++ b/cmd/devp2p/internal/ethtest/testdata/genesis.json @@ -2,28 +2,35 @@ "config": { "chainId": 3503995874084926, "homesteadBlock": 0, - "eip150Block": 6, - "eip155Block": 12, - "eip158Block": 12, - "byzantiumBlock": 18, - "constantinopleBlock": 24, - "petersburgBlock": 30, - "istanbulBlock": 36, - "muirGlacierBlock": 42, - "berlinBlock": 48, - "londonBlock": 54, - "arrowGlacierBlock": 60, - "grayGlacierBlock": 66, - "mergeNetsplitBlock": 72, - "shanghaiTime": 780, - "cancunTime": 840, - "terminalTotalDifficulty": 9454784, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "mergeNetsplitBlock": 0, + "shanghaiTime": 0, + "cancunTime": 60, + "pragueTime": 120, + "terminalTotalDifficulty": 131072, + "depositContractAddress": "0x0000000000000000000000000000000000000000", "ethash": {}, "blobSchedule": { "cancun": { "target": 3, "max": 6, "baseFeeUpdateFraction": 3338477 + }, + "prague": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 } } }, @@ -35,6 +42,18 @@ "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "coinbase": "0x0000000000000000000000000000000000000000", "alloc": { + "00000961ef480eb55e80d19ad83579a64c007002": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd", + "balance": "0x1" + }, + "0000bbddc7ce488642fb579f8b00f3a590007251": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", + "balance": "0x1" + }, + "0000f90827f1c53a10cb7a02335b175320002935": { + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500", + "balance": "0x1" + }, "000f3df6d732807ef1319fb7b8bb8522d0beac02": { "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "balance": "0x2a" @@ -81,6 +100,10 @@ "7435ed30a8b4aeb0877cef0c6e8cffe834eb865f": { "balance": "0xc097ce7bc90715b34b9f1000000000" }, + "7dcd17433742f4c0ca53122ab541d0ba67fc27df": { + "code": "0x3680600080376000206000548082558060010160005560005263656d697460206000a2", + "balance": "0x0" + }, "83c7e323d189f18725ac510004fdc2941f8c4a78": { "balance": "0xc097ce7bc90715b34b9f1000000000" }, @@ -112,7 +135,7 @@ "number": "0x0", "gasUsed": "0x0", "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "baseFeePerGas": null, + "baseFeePerGas": "0x3b9aca00", "excessBlobGas": null, "blobGasUsed": null -} +} \ No newline at end of file diff --git a/cmd/devp2p/internal/ethtest/testdata/headblock.json b/cmd/devp2p/internal/ethtest/testdata/headblock.json index e84e96b0f0..bb5244be18 100644 --- a/cmd/devp2p/internal/ethtest/testdata/headblock.json +++ b/cmd/devp2p/internal/ethtest/testdata/headblock.json @@ -1,16 +1,16 @@ { - "parentHash": "0x96a73007443980c5e0985dfbb45279aa496dadea16918ad42c65c0bf8122ec39", + "parentHash": "0x65151b101682b54cd08ba226f640c14c86176865ff9bfc57e0147dadaeac34bb", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", "miner": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xea4c1f4d9fa8664c22574c5b2f948a78c4b1a753cebc1861e7fb5b1aa21c5a94", - "transactionsRoot": "0xecda39025fc4c609ce778d75eed0aa53b65ce1e3d1373b34bad8578cc31e5b48", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xce423ebc60fc7764a43f09f1fe3ae61eef25e3eb8d09b1108f7e7eb77dfff5e6", + "transactionsRoot": "0x7ec1ae3989efa75d7bcc766e5e2443afa8a89a5fda42ebba90050e7e702980f7", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "difficulty": "0x0", - "number": "0x1f4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", - "timestamp": "0x1388", + "number": "0x258", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x1770", "extraData": "0x", "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": "0x0000000000000000", @@ -18,6 +18,7 @@ "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "blobGasUsed": "0x0", "excessBlobGas": "0x0", - "parentBeaconBlockRoot": "0xf653da50cdff4733f13f7a5e338290e883bdf04adf3f112709728063ea965d6c", - "hash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7" + "parentBeaconBlockRoot": "0xf5003fc8f92358e790a114bce93ce1d9c283c85e1787f8d7d56714d3489b49e6", + "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "hash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0" } \ No newline at end of file diff --git a/cmd/devp2p/internal/ethtest/testdata/headfcu.json b/cmd/devp2p/internal/ethtest/testdata/headfcu.json index 920212d0c0..9ab3a4de1a 100644 --- a/cmd/devp2p/internal/ethtest/testdata/headfcu.json +++ b/cmd/devp2p/internal/ethtest/testdata/headfcu.json @@ -1,12 +1,12 @@ { "jsonrpc": "2.0", - "id": "fcu500", + "id": "fcu600", "method": "engine_forkchoiceUpdatedV3", "params": [ { - "headBlockHash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7", - "safeBlockHash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7", - "finalizedBlockHash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7" + "headBlockHash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0", + "safeBlockHash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0", + "finalizedBlockHash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0" }, null ] diff --git a/cmd/devp2p/internal/ethtest/testdata/headstate.json b/cmd/devp2p/internal/ethtest/testdata/headstate.json index f7b076af69..72c7ebd509 100644 --- a/cmd/devp2p/internal/ethtest/testdata/headstate.json +++ b/cmd/devp2p/internal/ethtest/testdata/headstate.json @@ -1,20 +1,722 @@ { - "root": "ea4c1f4d9fa8664c22574c5b2f948a78c4b1a753cebc1861e7fb5b1aa21c5a94", + "root": "ce423ebc60fc7764a43f09f1fe3ae61eef25e3eb8d09b1108f7e7eb77dfff5e6", "accounts": { "0x0000000000000000000000000000000000000000": { - "balance": "233437500000029008737", + "balance": "30749363", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x0000000000000000000000000000000000000000", "key": "0x5380c7b7ae81a58eb98d9c78de4a1fd7fd9535fc953ed2be602daaa41767312a" }, - "0x000f3df6d732807ef1319fb7b8bb8522d0beac02": { + "0x00000961Ef480Eb55e80D19ad83579A64c007002": { + "balance": "1000000001", + "nonce": 0, + "root": "0x0ed2d94007a0eecee7c27c531d1249a18f6c48fe86c6d6e87c50b6943a5f015a", + "codeHash": "0x0345a365d2f4c5975b9f1599abe0a2ee76b7a3a731bc68781bd04c84e4858f50", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460cb5760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff146101f457600182026001905f5b5f82111560685781019083028483029004916001019190604d565b909390049250505036603814608857366101f457346101f4575f5260205ff35b34106101f457600154600101600155600354806003026004013381556001015f35815560010160203590553360601b5f5260385f601437604c5fa0600101600355005b6003546002548082038060101160df575060105b5f5b8181146101835782810160030260040181604c02815460601b8152601401816001015481526020019060020154807fffffffffffffffffffffffffffffffff00000000000000000000000000000000168252906010019060401c908160381c81600701538160301c81600601538160281c81600501538160201c81600401538160181c81600301538160101c81600201538160081c81600101535360010160e1565b910180921461019557906002556101a0565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff14156101cd57505f5b6001546002828201116101e25750505f6101e8565b01600290035b5f555f600155604c025ff35b5f5ffd", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000004": "7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "0x0000000000000000000000000000000000000000000000000000000000000005": "b917cfdc0d25b72d55cf94db328e1629b7f4fde2c30cdacf873b664416f76a0c", + "0x0000000000000000000000000000000000000000000000000000000000000006": "7f7cc50c9f72a3cb84be88144cde91250000000000000d800000000000000000" + }, + "address": "0x00000961ef480eb55e80d19ad83579a64c007002", + "key": "0xdf86c581c7d7b44eecbb92fd9e5867945ec1acdc0ea5bbabda21d17dddf06473" + }, + "0x0000BBdDc7CE488642fb579F8B00f3a590007251": { + "balance": "1", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x78c6cb5202685228bbcbfb992b1c4e116c7ec5ef11e25b8e92716cfc628ddd60", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe1460d35760115f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1461019a57600182026001905f5b5f82111560685781019083028483029004916001019190604d565b9093900492505050366060146088573661019a573461019a575f5260205ff35b341061019a57600154600101600155600354806004026004013381556001015f358155600101602035815560010160403590553360601b5f5260605f60143760745fa0600101600355005b6003546002548082038060021160e7575060025b5f5b8181146101295782810160040260040181607402815460601b815260140181600101548152602001816002015481526020019060030154905260010160e9565b910180921461013b5790600255610146565b90505f6002555f6003555b5f54807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff141561017357505f5b6001546001828201116101885750505f61018e565b01600190035b5f555f6001556074025ff35b5f5ffd", + "address": "0x0000bbddc7ce488642fb579f8b00f3a590007251", + "key": "0x0d6aea581b220579a2b99819299dd32c7c28a420018ecb0bde93af007ad89a31" + }, + "0x0000F90827F1C53a10cb7A02335B175320002935": { + "balance": "1", + "nonce": 0, + "root": "0xf6332d2b55fdf1c60c6e6a4f9605a08bc6ea545dd2753ba789d76c2669e3376d", + "codeHash": "0x6e49e66782037c0555897870e29fa5e552daf4719552131a0abce779daec0a5d", + "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604657602036036042575f35600143038111604257611fff81430311604257611fff9006545f5260205ff35b5f5ffd5b5f35611fff60014303065500", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000000b": "7167b82e4207928eb75fbe741b29d18fb5d469fa56c93941223667a07d183c44", + "0x000000000000000000000000000000000000000000000000000000000000000c": "23d7c4e274d71eee019119e9403d83ae181d9555d30a81aa0660c2103360f126", + "0x000000000000000000000000000000000000000000000000000000000000000d": "cbe5c6da730320128cc63a3c2454ede30738fa0d59a9e9de2e90f58b1938333a", + "0x000000000000000000000000000000000000000000000000000000000000000e": "ec7e5f7aada029114c5b556586e0e3c3ef3a39dde955f379ccea43ef93acabbc", + "0x000000000000000000000000000000000000000000000000000000000000000f": "7599aa2261eece5d6075f09401692a0ee37815ad63946cc80ab3ba29838c00f8", + "0x0000000000000000000000000000000000000000000000000000000000000010": "60576c148e7ac42f9d36ee36a7df5a89241609f624502b248b5cf710ed269a4c", + "0x0000000000000000000000000000000000000000000000000000000000000011": "8cd31f14889acd865b0ad0b2fd746586f29e87941166bf7087dc8bb429f01554", + "0x0000000000000000000000000000000000000000000000000000000000000012": "3e48b276f3b3209dda302780f9c8e4459d2c9378f4508c0fc4f9d26e6a5d173f", + "0x0000000000000000000000000000000000000000000000000000000000000013": "905f74a6377ead9037c78e9008bbb788c74c1fdb7f993b4820e24be5dde9c9af", + "0x0000000000000000000000000000000000000000000000000000000000000014": "35398f9b164bfdf8f4b4cde5181a9d96bb37947181332dc7977dc2360bee6300", + "0x0000000000000000000000000000000000000000000000000000000000000015": "4a4aef4730ba6155773a9e5c7e0c5f25a552d187687d59ad81b4a86c9f15a9fb", + "0x0000000000000000000000000000000000000000000000000000000000000016": "b3c7f4d24254129c2621485e664106ca2c2d08337672a2c8e484524b6e0dd0fb", + "0x0000000000000000000000000000000000000000000000000000000000000017": "25e8e33978b09de34a49b2595fd3dfe13d0f8c9a8939ca6c88376292459ec533", + "0x0000000000000000000000000000000000000000000000000000000000000018": "4f350577873216755df98391d69caf01ba646006d88459326e2f2bc2acbbf0e0", + "0x0000000000000000000000000000000000000000000000000000000000000019": "ec6593f4d6535e923dce8d47de08d98f8d751ea078f186072fe46b3b745d5274", + "0x000000000000000000000000000000000000000000000000000000000000001a": "c342e54f189bd6e3099871e6ecdb5f5b85a409299decd86a08e5564e42d22aa7", + "0x000000000000000000000000000000000000000000000000000000000000001b": "750dd92f162fd79de0f147a4a5a6928ea06463f04ce9ccd6f85d128f726d75c4", + "0x000000000000000000000000000000000000000000000000000000000000001c": "851dbf7f27a98cf2fc320a858b96e89bfe8af9551e4aa966cd6ed4d4b5d9dac8", + "0x000000000000000000000000000000000000000000000000000000000000001d": "95d530f6e64e5b60726d6f40f995fbcb099957cfaaf2765dc78684d4fccacb59", + "0x000000000000000000000000000000000000000000000000000000000000001e": "1da94a9b2bc22478c3c9e45591d3254ed48b2f15a68dcd86d272273bd362e1db", + "0x000000000000000000000000000000000000000000000000000000000000001f": "0776e32e33ee61a75147584501827f9a7cef40e1198d62791acf4d7f5c50a55a", + "0x0000000000000000000000000000000000000000000000000000000000000020": "39032e04806c95bf605cab0f493454b349e86b17808b4b019a6fc264c58e570b", + "0x0000000000000000000000000000000000000000000000000000000000000021": "7bfd33d91f0f065c4c0963ef3975dfacb13ebcd3b1d9433eeba5f26320bb453b", + "0x0000000000000000000000000000000000000000000000000000000000000022": "cbeea1d0322b931091bee7d7fd49ed48d09f35324c7837f3b51c1f9e017cdcc8", + "0x0000000000000000000000000000000000000000000000000000000000000023": "daecb35565efc8fe915c286637a2f664473681e90f9ab6e05d0aa02ecdcdc654", + "0x0000000000000000000000000000000000000000000000000000000000000024": "4accb52ae0491cfaed5866f5296d8d15233a16ffd73c91735040c58cebaf7ff9", + "0x0000000000000000000000000000000000000000000000000000000000000025": "a22225105655427813fb4e29887ef8ec1a18877bb441913fadce200903ba0f0f", + "0x0000000000000000000000000000000000000000000000000000000000000026": "6ad17c25de20d9f09aaff897681a87788d216791d9e33d2d4543b162f3c47423", + "0x0000000000000000000000000000000000000000000000000000000000000027": "5b65d43473b3132497d0fc75a2808f73a2808560785c6e7f55d2ac722047d291", + "0x0000000000000000000000000000000000000000000000000000000000000028": "ebf3316f9944a4d7686ca037353ab00ba9aba83839dbf6b81a1f17127bc97131", + "0x0000000000000000000000000000000000000000000000000000000000000029": "9a93da70b45233339e8a591567fec5e1fab43884f5b56bece2e795fb964942c3", + "0x000000000000000000000000000000000000000000000000000000000000002a": "4087ae9e71cbdae794c137d61684e08835fa8a6c13e9e5a001163eaccf6b842f", + "0x000000000000000000000000000000000000000000000000000000000000002b": "9eb1dcefdae7fc61fdacb218921236acad55350bda6c209931d89b65dcfd0eeb", + "0x000000000000000000000000000000000000000000000000000000000000002c": "c0fd1e13ad5b4c7102e278a96573f8cf66809bd6c3445f5c3650189596c0d680", + "0x000000000000000000000000000000000000000000000000000000000000002d": "84af2f9798e57abc0431d1f0156b45f6521c7720ff0215459af9fa0553eb47e5", + "0x000000000000000000000000000000000000000000000000000000000000002e": "cb33361cca9889678cb7c5fe9a4fe345d929cc71e8f6e53e5cd310820e01dff3", + "0x000000000000000000000000000000000000000000000000000000000000002f": "ef24d6293c96bd11abe059e96317856581f1736cf94786dbc0fc0d366df430af", + "0x0000000000000000000000000000000000000000000000000000000000000030": "95d87d14848a52aae340beecba232b70e909de98a3e2648fd44b66b73f7e12f8", + "0x0000000000000000000000000000000000000000000000000000000000000031": "b5e2e62689ca47b11879ba997cd532c410ab09f03719817fd33dc6923d990a03", + "0x0000000000000000000000000000000000000000000000000000000000000032": "56110ba58fe532a71688f5cb3ff7129f7e9636d4aaf69a4347f70299b6f21a22", + "0x0000000000000000000000000000000000000000000000000000000000000033": "2e693ca7593217b296154d482519dd780931e96b006b2deb05490fc2375c8c92", + "0x0000000000000000000000000000000000000000000000000000000000000034": "919d586bdedaf4fb38996e5a32eaa14f753a1babb1da62c6d0aa2035005b5d86", + "0x0000000000000000000000000000000000000000000000000000000000000035": "978425ebd54536bfd17945cf57726cd02fc25b083bc9332b7b4c8a94c37762bb", + "0x0000000000000000000000000000000000000000000000000000000000000036": "808ecd5038418740fc4b27954cdd2e4952569e8062b846b5cdd234b1eaaf7795", + "0x0000000000000000000000000000000000000000000000000000000000000037": "4313be4af809c236c319dbd5dad18e0d030f610e7e4cacef0ff8b26af563b046", + "0x0000000000000000000000000000000000000000000000000000000000000038": "cad24a57225330d06226b15cd3b5be7b0f2a42fef155e489994f7026f79924f4", + "0x0000000000000000000000000000000000000000000000000000000000000039": "16e634e48fc62762ce8fc1762c6bfd34e94b3533b98a5fb1bbd504b131a64a65", + "0x000000000000000000000000000000000000000000000000000000000000003a": "39f1c7f651e1970418fd8a5e0786c83e813744d55ea965e7902112bc02f190ec", + "0x000000000000000000000000000000000000000000000000000000000000003b": "ceccf9166834bac24869c590390335f72c85c59a1553be2d99db38b039bb4c99", + "0x000000000000000000000000000000000000000000000000000000000000003c": "b8c495461332ae67504ee899542ccf73e859f73c6682fad15415743f15b7f5e6", + "0x000000000000000000000000000000000000000000000000000000000000003d": "fe4445a66aeaa138c2045c340fffae7db7f7a49b7a31df8b8b5f5aa431c58546", + "0x000000000000000000000000000000000000000000000000000000000000003e": "0f13f717c99151d8b5b509af5cacb5313f1ebf813d7a6b37764cbe1ec0459beb", + "0x000000000000000000000000000000000000000000000000000000000000003f": "2e33aeb9f45e7cb955774b6b43df2c3a438c5aa03a69f90793f137ff5d2eb49e", + "0x0000000000000000000000000000000000000000000000000000000000000040": "f496b8d4d19037d646dcbc3796d2a28bf176488e2e238107feaa0b4b7f5ae6a5", + "0x0000000000000000000000000000000000000000000000000000000000000041": "49005c56e2c43c7d5d10026c97dce5b3b2e4a38eda72b6db3e544d2e92c12047", + "0x0000000000000000000000000000000000000000000000000000000000000042": "ae199d9dff48f9bc1202bd414078c175b977869bce215c79259cbed32e490b16", + "0x0000000000000000000000000000000000000000000000000000000000000043": "65ca2f730c7ef4ae37e81f916bfe2a89b86ee315d17796e0b8b5bb76c4127e", + "0x0000000000000000000000000000000000000000000000000000000000000044": "c091a79738ea695804fd7a370a3d24728d5d4523a047835b28fbe5790c914af0", + "0x0000000000000000000000000000000000000000000000000000000000000045": "c0dec6888ce6c75c575ce5ada6f3425cf1511b4d31b4f7ffeb63e93bf00ff243", + "0x0000000000000000000000000000000000000000000000000000000000000046": "fd1c5aae32a2ab886fbc6b5229bd30528f904fa67063d334e6428dfc94a9909b", + "0x0000000000000000000000000000000000000000000000000000000000000047": "537b75471b40aaa24670d4ed625d075165b59e4ab455236c14dedd7e99e65d34", + "0x0000000000000000000000000000000000000000000000000000000000000048": "509c406dedf930913cc53d51de88a6b34b0edf15d45c88deee154cdea0b35415", + "0x0000000000000000000000000000000000000000000000000000000000000049": "cd249ec42453922de5255c9b47ac76191e3cb60144ad0c4bd1b5e02d672c08a0", + "0x000000000000000000000000000000000000000000000000000000000000004a": "4b17336fdc9eccebc8c836ffcf41d077a956e9cf786521e9eb4d01db5de5a935", + "0x000000000000000000000000000000000000000000000000000000000000004b": "85784669b5e3b7ce03064984463c5c167f4c90bbc7731862bd5d6cdcbbe7dfaf", + "0x000000000000000000000000000000000000000000000000000000000000004c": "6d3b7ae474719d6929a8374bac361084a530941d9e9c8754bc8765a818704dc4", + "0x000000000000000000000000000000000000000000000000000000000000004d": "60ab9fa061b4a52ae93aac61a70a7049d5ace2d85ad81cd3ba18e5b6f9df5a90", + "0x000000000000000000000000000000000000000000000000000000000000004e": "8d76a11f766a753283cdebf3c0a4ada62f0a85333eadf13f5c94b5528b9a0bb8", + "0x000000000000000000000000000000000000000000000000000000000000004f": "70ed6c8dfbfd1a79453b1360fe0c9024d1c9a51b7e9ae491dc9f672c1495ee52", + "0x0000000000000000000000000000000000000000000000000000000000000050": "829bf1d587f5294d8ee978c07aa33af6df08dc44876e81c4f2d1d9403e6c0478", + "0x0000000000000000000000000000000000000000000000000000000000000051": "b57dc2887b5798442036ac860b372cb07b5858c460977c426b53bf780aee15ba", + "0x0000000000000000000000000000000000000000000000000000000000000052": "6793c6d579b24b7bfac5cfd619b7335aace2365f75cf5b0d1e1b5c367288b74b", + "0x0000000000000000000000000000000000000000000000000000000000000053": "ab38058baae4ce65fe734310ef852d1adb2eb0e5bce297e2dfb1f2aabb8155fe", + "0x0000000000000000000000000000000000000000000000000000000000000054": "c129c2d37fdd0defa0d0cdd7b27a95e5f17eb1beb11a8713bc4b398dff6f69a2", + "0x0000000000000000000000000000000000000000000000000000000000000055": "5e61412b6b77af36026fc83378b2aff64e52121621912d35061bf7db4e315657", + "0x0000000000000000000000000000000000000000000000000000000000000056": "06a3b3e77a4ecfa284cd0cbc5f563dafcebefcaa7e4610b0433f1da2353d65a5", + "0x0000000000000000000000000000000000000000000000000000000000000057": "096a5b9ce9899b40e70d721ead24b8da99a16bd9d115412a1e5d4ba2478ba276", + "0x0000000000000000000000000000000000000000000000000000000000000058": "a6b1b6fbde7fcc8c1c4b6b035835d839914b9d3ad21dedf946f5d91754d9a6c4", + "0x0000000000000000000000000000000000000000000000000000000000000059": "96d9997e171f41cd83e6829c097bd37f9c352553c0a1fb5a739d2766cd7b0772", + "0x000000000000000000000000000000000000000000000000000000000000005a": "70db0ab4ec61502d2a53b8faa0ffe5a45d7db6f562af25e6564d8d2669989d0a", + "0x000000000000000000000000000000000000000000000000000000000000005b": "a6aa03ee648578c9413c668ab9f6d2dc480a48bcf7b126dec17b85be35b28604", + "0x000000000000000000000000000000000000000000000000000000000000005c": "bec4f585aade8992655a98ecf32e5ad71245f864bb2c3987b0216bfcf2acb0c0", + "0x000000000000000000000000000000000000000000000000000000000000005d": "a75924e8dc804bc7d9588a41ae6545effa02c568f519abb7f109d76ae17442c0", + "0x000000000000000000000000000000000000000000000000000000000000005e": "c80ae577ac0e00ce2a417f069f0db47ca32ba3576ea6092273c623a035980fba", + "0x000000000000000000000000000000000000000000000000000000000000005f": "3e10fa0f7879c62f9eb6373a80bf6a0a2d4c16fee5ba96566d62488db5477e92", + "0x0000000000000000000000000000000000000000000000000000000000000060": "9ae8e852cab82414dd0762c67565523f30c9049a061c7c3b4a310cfcd4df9d2a", + "0x0000000000000000000000000000000000000000000000000000000000000061": "6c4fe4ae5fb8b2a347e58868bc6a741a6df75a83593b062869cacb7ce3a715af", + "0x0000000000000000000000000000000000000000000000000000000000000062": "6722daf402b94682af585921807783bb92e1957789399ed0e0be0e0faa5a8c87", + "0x0000000000000000000000000000000000000000000000000000000000000063": "651c869c9f62a753fa0c545a984f596d2068aa542234b109032b93a583442ffe", + "0x0000000000000000000000000000000000000000000000000000000000000064": "e93d89f5d6ab364e7c6597d99b6041f6c1d503a639f1265e8ffb1261f87fa2f3", + "0x0000000000000000000000000000000000000000000000000000000000000065": "0507a6937203ad4297bca7595e8e0d7715d59bb7296968aebd84c135b707c638", + "0x0000000000000000000000000000000000000000000000000000000000000066": "f08662ab38a7f4db3179eb425b28a2dd5d918c80b87740d1b88699ebe905a11b", + "0x0000000000000000000000000000000000000000000000000000000000000067": "122f9c89a20f0af63d4d5af9ac5e5ca3907ae256efa3d561f22b9288ad122f17", + "0x0000000000000000000000000000000000000000000000000000000000000068": "8cd5f4a012d4f51460556c04b7fc6f4a4d94d1203cb092d0297372a43fdf283d", + "0x0000000000000000000000000000000000000000000000000000000000000069": "eba87b6b36d970ede1071402e363515bfc524572febb086525b84c792093175f", + "0x000000000000000000000000000000000000000000000000000000000000006a": "1db257ebc3fdfbb6fe6fa8234fbc771becfee96128648eac4164773196acea99", + "0x000000000000000000000000000000000000000000000000000000000000006b": "2a5fd10344d681d2e72384382583b1a9fd82fd0125a1fc24b4296bf3e37cf096", + "0x000000000000000000000000000000000000000000000000000000000000006c": "647266d2cef5a6b13af790b1b0af42fae3962e80f0724115407e6ecf0b2a6556", + "0x000000000000000000000000000000000000000000000000000000000000006d": "52979d072bdf7bfb3fd707c0f83a4a3de1d1c8fb5380c240f858ed964aaa8106", + "0x000000000000000000000000000000000000000000000000000000000000006e": "7a86b91b59bbb2f833af91649b2cd1ba2b4e5f78e5775d78c03ab8b71045b3e3", + "0x000000000000000000000000000000000000000000000000000000000000006f": "4643bd6c3e1a9ac7a7ad650d12048b9e733e219b843f2b3d830f5da795852454", + "0x0000000000000000000000000000000000000000000000000000000000000070": "7c1fb25dc97d20bb97dce8d8343149b20a96180f46f4b771285546da9d3ef7d3", + "0x0000000000000000000000000000000000000000000000000000000000000071": "adf0cc4f267c585703d9e7403b046ab5ba320204592557eef982e4c409e3d2ea", + "0x0000000000000000000000000000000000000000000000000000000000000072": "2ee413006dcb6448fb5c37443102aae3575781369fa9cd34175c0f03e3ddb693", + "0x0000000000000000000000000000000000000000000000000000000000000073": "55487f68bbd481313212ae5cca520be32f0a54c44e77705e13518a9c8b1a54bf", + "0x0000000000000000000000000000000000000000000000000000000000000074": "d9fa2ad334f336af1b5f9fdb858c0ed6c956b7e0f9454c5e7ee8b64462725ec8", + "0x0000000000000000000000000000000000000000000000000000000000000075": "b7f7753236089ad38a8f5fc7d31811b521331e866eece20f7de934579ab95d1e", + "0x0000000000000000000000000000000000000000000000000000000000000076": "ed36126582b6287363b3cbc31b9c39d7afd4d97ee5e83c00b2cd5449c1d6848a", + "0x0000000000000000000000000000000000000000000000000000000000000077": "836c48482765990a0b394761a91ee93850aff87b82fac9b1def52375ed7535b3", + "0x0000000000000000000000000000000000000000000000000000000000000078": "f01e70ef5e688634e591415823fc7c898679659802e4db0de9ec3c3af735f664", + "0x0000000000000000000000000000000000000000000000000000000000000079": "c04cb16eda5544fcfa77e18ed2092981e834e71cabc2b61bd25153c830b660ff", + "0x000000000000000000000000000000000000000000000000000000000000007a": "41d260ba8d4501bbc92352b34daaaec17e3f3fc3652c9b92d87a587beaed96", + "0x000000000000000000000000000000000000000000000000000000000000007b": "d2331ab665bad7fa9a43bc09da232bb06c72bc79d817a9f1c5bb05f96b9646e6", + "0x000000000000000000000000000000000000000000000000000000000000007c": "43e6a0ed19de50761c59208a225a7f9bac091c3eb7dad46807998cf6ee69c7", + "0x000000000000000000000000000000000000000000000000000000000000007d": "f64f01561392db4d006de40b0c35b3b8b56204cbd89b734608d148d2ae629228", + "0x000000000000000000000000000000000000000000000000000000000000007e": "49e6318f4587a021ad50e32ccad223164e0cc1ba28e1be6ee01060d331ecebbf", + "0x000000000000000000000000000000000000000000000000000000000000007f": "51af93a015c8a1395fdf3030bfa74b3f7104037671ab930defa6eb75e222e1eb", + "0x0000000000000000000000000000000000000000000000000000000000000080": "7ca2f8c5a75e26ee5575e7d68fb5035c6a3ad57fb35b1308c19cf0c563e86b55", + "0x0000000000000000000000000000000000000000000000000000000000000081": "7614b81f123a279df0a712b8e9f0a9999add17fa9020ed9fabd1fd89315362cc", + "0x0000000000000000000000000000000000000000000000000000000000000082": "218dd8608e6cdb93545a3e1203979ab4ca55f0f5bccf76a533fdd191d19f708a", + "0x0000000000000000000000000000000000000000000000000000000000000083": "a5e002a44d498e7a40b8a36eeb8ce8101353c3d379a5955d5809fcaf559a2bfb", + "0x0000000000000000000000000000000000000000000000000000000000000084": "1f7613cc089d031344e77e764174fee74d4eb6f501f467664b12220179d10fac", + "0x0000000000000000000000000000000000000000000000000000000000000085": "ab82fa0386891a0f6590a93f3b0c6852f582a38757c1a32d1d37a8195830c9ef", + "0x0000000000000000000000000000000000000000000000000000000000000086": "b0d4b43954c092e02e74342616a87ee25e15dabb9ba4d94c0bd474a907dff210", + "0x0000000000000000000000000000000000000000000000000000000000000087": "f14886af3d36d40608acfeebf709b67d679146b86594eb7f3d717ec214cb423c", + "0x0000000000000000000000000000000000000000000000000000000000000088": "c310edfd4b8d1456b9d2f25ad392a0f409356115a0b6baa06c5055355e690380", + "0x0000000000000000000000000000000000000000000000000000000000000089": "eb26879fc8d9023ee720917ace6b9bfebe36c4b18c476581524c26ff6b1b1770", + "0x000000000000000000000000000000000000000000000000000000000000008a": "bc885f1dd76d6044edf950a00f65f8b7e09037b64694a8a5bf040a8f875df73d", + "0x000000000000000000000000000000000000000000000000000000000000008b": "3f8e6751bb589f71b4529f33b341be4bcbb64cc89a86ac00ba2ecd28b96843f4", + "0x000000000000000000000000000000000000000000000000000000000000008c": "53c40989ba0f74285db823aeb706fbdd2f34e53b65edf8edda6054f6fe0154f0", + "0x000000000000000000000000000000000000000000000000000000000000008d": "56aac6e61bbe149532c6f833c15bea8fd7739b35b114c63d0c81d1b6803a9324", + "0x000000000000000000000000000000000000000000000000000000000000008e": "20a194b00f602fcb1db01bb84014dda4654f7bbf59de521992100e4c90d95eae", + "0x000000000000000000000000000000000000000000000000000000000000008f": "6a7e2a65b2c12ddb337eef91aa0772eae0064f24028cbb5f8d4d7c0c8f1437f9", + "0x0000000000000000000000000000000000000000000000000000000000000090": "2f3f1707049c34f0ce4b2222d6cbe9f149d79a0e2c1ea6101058cefe33e9b3f6", + "0x0000000000000000000000000000000000000000000000000000000000000091": "b7332dcef7339e1aaf6fe2b41257738e00b916fbb030c919dafa065f36889886", + "0x0000000000000000000000000000000000000000000000000000000000000092": "03c384271631c83751232b695f032adf6fb4244c81cbebf3e6fdd030b61e384b", + "0x0000000000000000000000000000000000000000000000000000000000000093": "5d72bae0b85bb59e94d55b7f439c6c0a9a1a8a47fa242f5dc64a82b880260cfe", + "0x0000000000000000000000000000000000000000000000000000000000000094": "b3a80dd6748adaba8d2598da58441cc645b165d96de91b605122e82caff076d8", + "0x0000000000000000000000000000000000000000000000000000000000000095": "32305ca5493b007b7c591c7ea565ad705010ad747126202b191c78ffb49ea51e", + "0x0000000000000000000000000000000000000000000000000000000000000096": "11b82f7fbb7a781b00b4eb695a56aacd1a5477a2bc4e8167d4c08b95c4186e4c", + "0x0000000000000000000000000000000000000000000000000000000000000097": "7ad16d4c674b10a59ca3364904af33fa3713db2e963cf7c36da3f3172a917aaa", + "0x0000000000000000000000000000000000000000000000000000000000000098": "e756ee647aad508c521e5463abc774c9ad8d3ac6f25a52c4b6970a04f716331d", + "0x0000000000000000000000000000000000000000000000000000000000000099": "1a924af515c53c392afb3be5839f952f6495116f677ba7cc630c76d08fa12e24", + "0x000000000000000000000000000000000000000000000000000000000000009a": "0de1dee56d87848e4730dd05feae6c512a356a38bd52304e1e399e8d48be718b", + "0x000000000000000000000000000000000000000000000000000000000000009b": "de590f5a6aa2882e34cb6894bf54e16296d5abeb244c7df2c0b12ec627c41432", + "0x000000000000000000000000000000000000000000000000000000000000009c": "cf5949ad3562b8f632d82c9af77116a0b83b9b9806e86d0c2bce517c7be2e842", + "0x000000000000000000000000000000000000000000000000000000000000009d": "b158abf8e49c9fa6cf8103699f81039a82d085721e5cff677edec8c43bee073d", + "0x000000000000000000000000000000000000000000000000000000000000009e": "4c5f50016d24ab6a9b40d925d7b4be07d51679d2f5b12565958dfa80229031fa", + "0x000000000000000000000000000000000000000000000000000000000000009f": "dbbf71ab7420933453fd51ae3e6cdb95f05e1c25016e979fbe33deb794ea9ae2", + "0x00000000000000000000000000000000000000000000000000000000000000a0": "e2e850cb3176df3accc03247b8e9cdb15261ac3021c4911839aad275fe2a42ef", + "0x00000000000000000000000000000000000000000000000000000000000000a1": "5fd45fdf3f74bde3842258b46aec022feec7f5148302447a63b6e480d4444330", + "0x00000000000000000000000000000000000000000000000000000000000000a2": "639a8f45c9f9219f27cf4db4c33de2d346df8a09dcc770ac6044f60184330864", + "0x00000000000000000000000000000000000000000000000000000000000000a3": "45941317b4ff496cb5e8832d48f69c5f1d611cf609bf3d2933dba68dae211c49", + "0x00000000000000000000000000000000000000000000000000000000000000a4": "471066471af127a34b62c9f34c3fbfb26ba29d233f81d568f4d120d35d50ceaa", + "0x00000000000000000000000000000000000000000000000000000000000000a5": "e89e5d3756805d8458b5057f19b7d97faa7fa2351b2a08ddd75405c00af3a8c6", + "0x00000000000000000000000000000000000000000000000000000000000000a6": "8052bf3205c8803a64bb4cc52c4e86516db9734d9bf0ff47349a337e9bbe10e0", + "0x00000000000000000000000000000000000000000000000000000000000000a7": "dcf632311be8dfd6de736c05b4ae66e2aea72f7825fb23294bb8ccfeb218f486", + "0x00000000000000000000000000000000000000000000000000000000000000a8": "f4d88732713252e8ab1932ca55135b3819ef47a73a05002a338e5aa5617e7d9d", + "0x00000000000000000000000000000000000000000000000000000000000000a9": "5f5f3976768eaf850e525d41f05497af4731aa637d2b323dbc69154553943c50", + "0x00000000000000000000000000000000000000000000000000000000000000aa": "c1a9ccd5f651aa46a26433e521d6e7c4fcc6714f8fb9068ee4f1e0a8d043da0d", + "0x00000000000000000000000000000000000000000000000000000000000000ab": "9fb16206a35f8b4b9d8c30570c7010b5bc6a4149b5aa2ce42da9d60c92b5ea1d", + "0x00000000000000000000000000000000000000000000000000000000000000ac": "4d980e42bd8ab35744bf9b5aa58fbc8b71efd85b839b90e2e50584246a3831f8", + "0x00000000000000000000000000000000000000000000000000000000000000ad": "c9f402d074ac593ae2f09a8bb846b9e46963c305a8c33690c08ca0c8e0ac719f", + "0x00000000000000000000000000000000000000000000000000000000000000ae": "7c6e0e3b4dfc0728d41f7d5729a60d53758cafbab878bca3beed01bdc5ae9c56", + "0x00000000000000000000000000000000000000000000000000000000000000af": "36daac85c3d71809d96b04586cf5c50594ae2cafa74b9734491f6fb31b85142c", + "0x00000000000000000000000000000000000000000000000000000000000000b0": "edd306e502f0e098d70102017c0f33272d5934bbf766ef1c5ece71713d4f59c2", + "0x00000000000000000000000000000000000000000000000000000000000000b1": "1fdd1686c4e06bf2baf2287347ed95a45855aa4b546244e83e7aea4c6dd56a72", + "0x00000000000000000000000000000000000000000000000000000000000000b2": "a69441f08a1bef357d6f34fb74e4eeeaff0feb787f61e10879faf72609aeae24", + "0x00000000000000000000000000000000000000000000000000000000000000b3": "c37e2ca4253945c00e611fd26819875ef83d98dc20bb326a8e4ebbd804613214", + "0x00000000000000000000000000000000000000000000000000000000000000b4": "8564835e8d24f3fd01643847625fac3fa7bb13ba829c1a5ad7efd6ceda4f5bed", + "0x00000000000000000000000000000000000000000000000000000000000000b5": "c64398436144bb3196587e5ee9267e878400c5616f97cf97fd0921bae181bad4", + "0x00000000000000000000000000000000000000000000000000000000000000b6": "12d4a656b5b4d8d9c55515a7698a254fa74a397390a57167f785a2d3602539a6", + "0x00000000000000000000000000000000000000000000000000000000000000b7": "c858dea4bf702c29161d33ba7c02bfb4977169668843521b0df693d5eebcf5a3", + "0x00000000000000000000000000000000000000000000000000000000000000b8": "347ad864a477308c79cb4f766e8a6b62f4ece0a981cdfe49987e542acd89b5ac", + "0x00000000000000000000000000000000000000000000000000000000000000b9": "ac0c873a3d9942f92427ae37009ee280b326788fa803baba4dbbcc31736ff2ff", + "0x00000000000000000000000000000000000000000000000000000000000000ba": "5f67af973e604193cdcd68a80dea8ff0622ee1341330c1b8601502020617c2cd", + "0x00000000000000000000000000000000000000000000000000000000000000bb": "493bf6336f7b638f36a29952c86afbb58526152b62be20eb6433bee0474d62a8", + "0x00000000000000000000000000000000000000000000000000000000000000bc": "2febc2674bc628df6cde532fe9c598bfca92240c5f240d189aa372425c24487a", + "0x00000000000000000000000000000000000000000000000000000000000000bd": "341223f936840f7f6a33fd74e14e5ebe4300b215cfadf77a8f6e88bfed017dad", + "0x00000000000000000000000000000000000000000000000000000000000000be": "fcacae1b8715635bf3bbb10a375c44c799c2a882cab116306400381ff62e71f2", + "0x00000000000000000000000000000000000000000000000000000000000000bf": "ddb665db1612487f7e1e333fbb5f607b93bcfc618983de7dd61d76dac6f3d948", + "0x00000000000000000000000000000000000000000000000000000000000000c0": "cdeb0c3a06240f7f742c497bb142ac2477df943a878f8296b911b9f1169c1e46", + "0x00000000000000000000000000000000000000000000000000000000000000c1": "24b14515d27271ed944fd78cdea5855bbedf6cd84d65f925f8f06a426f7b1e4b", + "0x00000000000000000000000000000000000000000000000000000000000000c2": "d5f960e48e2767108920eba4e8e326c9fc3233c3a2fa349770f04debccc14826", + "0x00000000000000000000000000000000000000000000000000000000000000c3": "cbfad2a8bdfe5205c485383414e29d8e0a9c8b10812151d25bb51a74c95549a2", + "0x00000000000000000000000000000000000000000000000000000000000000c4": "078aa96db2936406a8d1d69a59f72bd60a908cbde5d2abb12166b41ff714977b", + "0x00000000000000000000000000000000000000000000000000000000000000c5": "c03fc9d4b6d49d1599717fbf75a9ad47496efb1ec6fafaa5b4bee2afae9bee30", + "0x00000000000000000000000000000000000000000000000000000000000000c6": "0fa887a20612f7ab9a00abfeb074c01ae4b509b4859c48c2e24abf27b7d7fed3", + "0x00000000000000000000000000000000000000000000000000000000000000c7": "bdc33ca00ea1641cf1ca2816913824999b73d47a92e7d5303c4104035ae78725", + "0x00000000000000000000000000000000000000000000000000000000000000c8": "44aa9401e0d5848c03c53c87cb883698f3a346340416803b666fce0eb7912595", + "0x00000000000000000000000000000000000000000000000000000000000000c9": "abf8b8c18e738be05befb8682083d8212b57c009c599b65535c4a7f47930bfa8", + "0x00000000000000000000000000000000000000000000000000000000000000ca": "c61c8872972b975d28191544f7200c3f3684a9e152c87f626b6c85aa56af4a22", + "0x00000000000000000000000000000000000000000000000000000000000000cb": "1e7e2004a340707d31625b7ac9ea03d7add6dddfa7c32922e6222147b86aa4b6", + "0x00000000000000000000000000000000000000000000000000000000000000cc": "13676db30bae04c5f3b7f190e44e72d1c1b1299567e9e3757603554f30ff45f5", + "0x00000000000000000000000000000000000000000000000000000000000000cd": "20836fb907f186aefcdcb5764e3d7c48fcd1b16bc98b967edd65b354e68a3e79", + "0x00000000000000000000000000000000000000000000000000000000000000ce": "5936f662e12c0f1b392611803d3cddbe33bb2d7605769956e334c560b372537a", + "0x00000000000000000000000000000000000000000000000000000000000000cf": "fa49b5f47466644348d75c491db8ff92813c96fb5b3f4a4deaa02bc92e3e134d", + "0x00000000000000000000000000000000000000000000000000000000000000d0": "6cedc591e85ed32d70655274734b636e3482105a5e9d416e62ef1dda2ddd4a9d", + "0x00000000000000000000000000000000000000000000000000000000000000d1": "53bfe21b477b2780bf2e1aa15b19710aa9bb5100cd7bb69c8cc3a881ae50ab54", + "0x00000000000000000000000000000000000000000000000000000000000000d2": "4c30c648a319319788200f7273f6de74e321f1796b01a2988f98840a11e307f1", + "0x00000000000000000000000000000000000000000000000000000000000000d3": "f490758a0266199a571a859efe170beefeb78de97d3a20328ac3d4bf07240fdb", + "0x00000000000000000000000000000000000000000000000000000000000000d4": "0a1e9c1d1ad91f4d574599fe8247974beb2ab68c78b43cdda303870ede057f49", + "0x00000000000000000000000000000000000000000000000000000000000000d5": "d89a67d59bfca6ef7942ef28cb121005dfd9c18b404a8dfb95e7c4d1b405a87e", + "0x00000000000000000000000000000000000000000000000000000000000000d6": "44e4a64750e4c9f6511df524c16e9cb23554a89325cf503b74f8f25f16253cec", + "0x00000000000000000000000000000000000000000000000000000000000000d7": "9a379148fa0512b767d90e2a9a20248c6c19441d7f9284b00f802de8d40c5404", + "0x00000000000000000000000000000000000000000000000000000000000000d8": "96ce02bc5a0630bbf7d4c1340ff68ba3cbc53a401d8ced01339937d2d764980e", + "0x00000000000000000000000000000000000000000000000000000000000000d9": "41eea349b7529f1465e872f4eeb3958da339bd18193b9055d1f77649b5b5a8b1", + "0x00000000000000000000000000000000000000000000000000000000000000da": "ecdbfed50e09e8bea9b23b0c056b9ef72bd724fd104590fdccfed99e26401a78", + "0x00000000000000000000000000000000000000000000000000000000000000db": "fa439516704748050ea45b059aad351048e40ae85f495fd0ec4e77c34a02325f", + "0x00000000000000000000000000000000000000000000000000000000000000dc": "8967b48c91a9a3ac039752dc1b0b5c091e38b28635f934949604b9ad0e2017e9", + "0x00000000000000000000000000000000000000000000000000000000000000dd": "4a6fe8bfb3d8209f060b20fd83362433e87e45b6059450ecd92207e5bb4bbdad", + "0x00000000000000000000000000000000000000000000000000000000000000de": "58f4f818948eb949af6ebbe9c9922a6742c45eb6c60cc272027488d0d0fb8207", + "0x00000000000000000000000000000000000000000000000000000000000000df": "75150cd02c717d33df03986668fca9287fa715ae9b3dc786e9a012689cbb4f2b", + "0x00000000000000000000000000000000000000000000000000000000000000e0": "4b087119094ef790b1981596fe9adfed930802ffbf33a9b5f91cf06b36aac5cf", + "0x00000000000000000000000000000000000000000000000000000000000000e1": "f7c7c5456af3ba05c94cd1d23c70ac90ea4b79b78e561045c649b08bfdaae321", + "0x00000000000000000000000000000000000000000000000000000000000000e2": "918ae7ac657fc84fc8cb10dcb3794f22ee74635bc3c48a09447f82525c8b4cff", + "0x00000000000000000000000000000000000000000000000000000000000000e3": "b77cf24f0c1fb354f7bf7c80e1804fdc2328774a1af50eb7959a46a8fe51a590", + "0x00000000000000000000000000000000000000000000000000000000000000e4": "b3317abdbcc0bdc256a422a5c333572f99ff8651f095922cdd5b995b44185a49", + "0x00000000000000000000000000000000000000000000000000000000000000e5": "3958180bd85edf4b17cf80881d40b68216a23a2dbadb92fff52757661070ec35", + "0x00000000000000000000000000000000000000000000000000000000000000e6": "b1503e5b89008f2ec7cf91492da840a6786f020d11cd33a8ebfd68ee824313ea", + "0x00000000000000000000000000000000000000000000000000000000000000e7": "74b7c334b7e246ba4cbdb9a91cf69bf72a3491ca4e39c2cda81e39c080bbe720", + "0x00000000000000000000000000000000000000000000000000000000000000e8": "5e06576f385d64e5475da19a55db8a1b49a905e54cdd00bc833f9a6e0d1821de", + "0x00000000000000000000000000000000000000000000000000000000000000e9": "cdf017d14aa10cc174c1f3f7d597eb085f52da7793e92fd8f84f0032009962df", + "0x00000000000000000000000000000000000000000000000000000000000000ea": "d85b3616680a40d04d64e6ee0d1b0dfbf1967634ca82b0a38be88513a556fce6", + "0x00000000000000000000000000000000000000000000000000000000000000eb": "aeb7dd5da8baa32aeb4a33f9d87914815fa0c941f5bc08e595d4e37bfdae7025", + "0x00000000000000000000000000000000000000000000000000000000000000ec": "d522a23cf0118178de9b0c94528f7161fa5f0e0c954ff141d86f7335fbed4276", + "0x00000000000000000000000000000000000000000000000000000000000000ed": "c24d834bba0307acaf2621819d979f535f972358a557d008cdd4374d6d7279e4", + "0x00000000000000000000000000000000000000000000000000000000000000ee": "bc7ccdf6cbccc29bfcb63055c8f06b26648f3b719434b29a74a477466fefaa5e", + "0x00000000000000000000000000000000000000000000000000000000000000ef": "84f81fe1c154c744c26786ae33b6ace4bc6e4e9318fd57b03a61e9d18ca64711", + "0x00000000000000000000000000000000000000000000000000000000000000f0": "ca2b42e197de583b704164d6db489ec43fe7394d38dd8a5752be70f52854ca58", + "0x00000000000000000000000000000000000000000000000000000000000000f1": "a09abb195168c21894826ccd65fa0c8549eb923a5b399c62cf9fd1011c465b69", + "0x00000000000000000000000000000000000000000000000000000000000000f2": "b4020e4b07dcf86bae80b8743a2ea666f6f3d45a5df2284109c25d7f51609ec5", + "0x00000000000000000000000000000000000000000000000000000000000000f3": "787fcaaf148ba19e63da9cd7d513303b2e8565baf64c4c28680996276e57c93c", + "0x00000000000000000000000000000000000000000000000000000000000000f4": "9d81061f02d7bf9a3a57e1b2b291bbe6100fdd34168fcc324a3e4c360168a058", + "0x00000000000000000000000000000000000000000000000000000000000000f5": "111ebb07018c6d7bf8df23b0454405dd991d7f8407d7c14f8bb86a0bd78032ac", + "0x00000000000000000000000000000000000000000000000000000000000000f6": "f0fff4c5758d8f5bc9e659c933b0267500c3dcd25916df0c0cd11f51a80057e4", + "0x00000000000000000000000000000000000000000000000000000000000000f7": "4063e7bd93501354cbef2184f7139559650a22eeca85d60bd62f4a468f2bd22c", + "0x00000000000000000000000000000000000000000000000000000000000000f8": "161049c951eaacfafd5b046be03ee813c9a9a6d3167fe4591f75673f0ff5097a", + "0x00000000000000000000000000000000000000000000000000000000000000f9": "f10eb78649d3c7dccd8a00576e460bed3eedf5e1e9b94e96cd2cdcf11c4171e7", + "0x00000000000000000000000000000000000000000000000000000000000000fa": "9d9c2b94a73067a8ba8736b77b159187bad6ce53b4372d3d0d0aa534aae1d7bd", + "0x00000000000000000000000000000000000000000000000000000000000000fb": "a4b169ebb5479f117266df73694d46f704685c3d756d411dcb5fc0b15f500f47", + "0x00000000000000000000000000000000000000000000000000000000000000fc": "205a14b20d2c13f174859295063f88da3779c22b3cd8cf8d3718cf014f8c0af9", + "0x00000000000000000000000000000000000000000000000000000000000000fd": "68ee7090901b0083e417d17e1e9eb637b50146077b32d5f3b63568a738220c98", + "0x00000000000000000000000000000000000000000000000000000000000000fe": "1d4e0daba7e6bdc87c5ecff530bca645bbe36a6a538e27b956c9c106607d982e", + "0x00000000000000000000000000000000000000000000000000000000000000ff": "adf3ad66db1c5384657a2b75a1753887c646c629bd10a8a50d15097b79c14cbc", + "0x0000000000000000000000000000000000000000000000000000000000000100": "9ae54ebf672230a7e3ae4ef423aacf24189f52e240c1356817cb32d767618063", + "0x0000000000000000000000000000000000000000000000000000000000000101": "ed093194e152b98e10d55a8db6403780d17346e9eff9c511712725e08c422381", + "0x0000000000000000000000000000000000000000000000000000000000000102": "cd35112597db3095f6c10b644aee930651c44a03d8c168581d8aff8d26050491", + "0x0000000000000000000000000000000000000000000000000000000000000103": "46728f520936c769482557b2d4d05386f030a3d9c03cca9d123940d3d3fc97be", + "0x0000000000000000000000000000000000000000000000000000000000000104": "65989a6ce9bd74150837c8f8feea080d86236e1706b2b1d9bb42ae329a212110", + "0x0000000000000000000000000000000000000000000000000000000000000105": "1244e39eddc59b8d38c3c9e609867b149bb1222e3087fcde4e60d1785f9ca6fb", + "0x0000000000000000000000000000000000000000000000000000000000000106": "9b11fa343fc18df51ad37fa94c9d6c17916786bbbab8bc10e3a3d1c0580e0b2f", + "0x0000000000000000000000000000000000000000000000000000000000000107": "6bd2bb001303e7dfb428c75ea4bd6dd7115d6ff61add2924cb23a0115c920884", + "0x0000000000000000000000000000000000000000000000000000000000000108": "db94bbffb05461e4f8a83c827cb5b0cc8e54ce71af9f4b57fd712c7bf245a67e", + "0x0000000000000000000000000000000000000000000000000000000000000109": "669d2fdcd20848e3f746c76753dac2763d798d43492e58e75eec82ef4fb156b3", + "0x000000000000000000000000000000000000000000000000000000000000010a": "8bc68b8a166d2b68a73be23ea20193dccd82a3bfedac661f969bdc32fcd454a4", + "0x000000000000000000000000000000000000000000000000000000000000010b": "f8160bbab91163c4b7120ab3c60606cc47ba1ec0e765daf1d68ca0dcf52d2787", + "0x000000000000000000000000000000000000000000000000000000000000010c": "3f4cebd4ebd414ba3710ad5eabfefa06fc5f007c62ef0900e07c263e1923889f", + "0x000000000000000000000000000000000000000000000000000000000000010d": "51a4821b633b80775e02a85aafd3a58ed2796e158c03aea46004e25ca138eaa1", + "0x000000000000000000000000000000000000000000000000000000000000010e": "6904e188fffed4cc41632df32452ec9bd4cafdee6f5d76c36e1b2efd33ad9079", + "0x000000000000000000000000000000000000000000000000000000000000010f": "f6354df3badf86b25e2f88f4630610c9c756a76eab5489bf84dc4b5faa5dfcad", + "0x0000000000000000000000000000000000000000000000000000000000000110": "a3f857458c4f8e850d17825dd663d51219737a227a157cb9f3eb21a7dabf3c12", + "0x0000000000000000000000000000000000000000000000000000000000000111": "a9e96ee23c11f8d5762340e128d2280d87ee788885951468baa9a384665b95f7", + "0x0000000000000000000000000000000000000000000000000000000000000112": "443c32584ab5e94cf1393eba7de764dcbf40a903572c0b1737a2198537886269", + "0x0000000000000000000000000000000000000000000000000000000000000113": "1910146905689fbbc61f374a7bde5325be084f307a5617b7bdb319691d7cbe7e", + "0x0000000000000000000000000000000000000000000000000000000000000114": "5d602bc5189b5a955faeb7842825c53c4cd335c0cac7756599e3a7d7a9b1e604", + "0x0000000000000000000000000000000000000000000000000000000000000115": "7cdd5d09a0af5e26bad74166fd6a4324185ee337b005e5df5f4f67f00155cce9", + "0x0000000000000000000000000000000000000000000000000000000000000116": "da06797d4ea9e2d242a7f1d77163e4cd0d18aa7e9ae04a2357c7a359c3a7897b", + "0x0000000000000000000000000000000000000000000000000000000000000117": "69c23b6cef19f994ec1120ebe41647daae8fc602ceeccb500bef3599ea8dc4d6", + "0x0000000000000000000000000000000000000000000000000000000000000118": "1be678ea3efa6308b7fb5b3102651a8493462715c6b09f6cd9697efd05fc7d0e", + "0x0000000000000000000000000000000000000000000000000000000000000119": "f776a4d1d5c352151872b684cb240fb3b7d163b655fd5939337a070a7c896d7a", + "0x000000000000000000000000000000000000000000000000000000000000011a": "9dc4808f611d1b29c89fe57085c64ec7815675f779d602734d45848babdaa5ce", + "0x000000000000000000000000000000000000000000000000000000000000011b": "e015df4bb2e84589a3bf64fa91b73091581910b42e0ee91f1d6cf25912d60027", + "0x000000000000000000000000000000000000000000000000000000000000011c": "9f3faf24dbf97542f5dcac91d35da491af51e24504e58f42c328ba2758b0b268", + "0x000000000000000000000000000000000000000000000000000000000000011d": "594c9091455bd0cd08631909cab257feeae3a05401a43544e423c759be125f77", + "0x000000000000000000000000000000000000000000000000000000000000011e": "1f1d279ca073fab2be1f425ff8c09696653b77632516524baee6171427d75532", + "0x000000000000000000000000000000000000000000000000000000000000011f": "c48ec13e43df85d25ae98c82d9ef4c2d1d09195aec3de87dd7b36f9cb530e234", + "0x0000000000000000000000000000000000000000000000000000000000000120": "082ba48558d19f6911b12db3e969c8f770871c5836cbd2a02d6686624c744c88", + "0x0000000000000000000000000000000000000000000000000000000000000121": "1e9ef85d67a81bd278cb21a68a068060358717f518aa9a31059b0ea52e9470f5", + "0x0000000000000000000000000000000000000000000000000000000000000122": "92ccd6105a6a3d6636516fc3de3d1d5b83476e27c6c15f0d1f0a4ac3cdb77f96", + "0x0000000000000000000000000000000000000000000000000000000000000123": "59eb05ad455dd8785b7a82a8ec0b14908b49b9b99b89438e48a64f2c35dbec5f", + "0x0000000000000000000000000000000000000000000000000000000000000124": "8aff95cd5730ce6970eca865968ba524b1e66c7688319793c6edaa11791b0a33", + "0x0000000000000000000000000000000000000000000000000000000000000125": "e9652de769d861b7ae1ff71d6086d0049ff01ee57126e7b37f8acb1009efdcb7", + "0x0000000000000000000000000000000000000000000000000000000000000126": "62defc14b1b4b19b963574f0ddbe0b887a8017d28661a9d889c55729a388a40b", + "0x0000000000000000000000000000000000000000000000000000000000000127": "98539ac0cea39c8cc5774cb783fa5993c03ab9e2dcc9e2e24ac18d9af67dacb6", + "0x0000000000000000000000000000000000000000000000000000000000000128": "84018a2df44823700329319d9aff27b73093f4284a45402e4a40958dde3ef298", + "0x0000000000000000000000000000000000000000000000000000000000000129": "e2c8b858ba858e6c7b73dbc23702f10a9a75117fbeaa447084be91921cfbe7f5", + "0x000000000000000000000000000000000000000000000000000000000000012a": "0a1092b8900b3db78271854ecef3b6b400f1fec980047d9ff07a130255a910f2", + "0x000000000000000000000000000000000000000000000000000000000000012b": "a1e26afee8565c8352f0dcc623e984f72d24e09e005aba99f916fdb7c3807ab7", + "0x000000000000000000000000000000000000000000000000000000000000012c": "dba21acb5043d419d3e972fad568d8e6179cffb0654e73c7f093a48877f38e9c", + "0x000000000000000000000000000000000000000000000000000000000000012d": "4d7b2d7c56da60a9b57c4210cdedba40311978ea1aebf519aac65867e16f6a3e", + "0x000000000000000000000000000000000000000000000000000000000000012e": "5ee998d96985103ae9e6f31a41ee0d44a4da62003a63b5ff4f29570aa42ddee4", + "0x000000000000000000000000000000000000000000000000000000000000012f": "81db24e85960807d0f347bacc0364a9327e64955fecca02ab5fcc55efdc4a37f", + "0x0000000000000000000000000000000000000000000000000000000000000130": "9cbca6aa8b06935a740ab85580674c5cd4b2a840d078c92e005294241a7eac81", + "0x0000000000000000000000000000000000000000000000000000000000000131": "5121438babb00581bb8862b84bfedfa4d586d59b08f7de67cad8988693061458", + "0x0000000000000000000000000000000000000000000000000000000000000132": "2c00478ccf60b7813adf88eae40d7f36cb2bb19d7d3a5e41904411d59f85b85a", + "0x0000000000000000000000000000000000000000000000000000000000000133": "bd2d25d7773172160974f1a8b6b790c629e44a011321c53a0cb08888b9cac459", + "0x0000000000000000000000000000000000000000000000000000000000000134": "a8a4ee8234dac48e460f619c77d02008ff818db6cf1a0a80de6a81af3e0d7e91", + "0x0000000000000000000000000000000000000000000000000000000000000135": "11ddcb0efb438a2965ba558170ed3ccb27ac43bc3f7028628edcb3406a1d4623", + "0x0000000000000000000000000000000000000000000000000000000000000136": "ccff97103894795edef27f3a29b05a2109a4f024d3c935233faff6be394b92f7", + "0x0000000000000000000000000000000000000000000000000000000000000137": "aac581c002035b4c80879f87a1418a3129921f493472482a52b09d0fb6233f04", + "0x0000000000000000000000000000000000000000000000000000000000000138": "7e3909c2f8ede6f928c0820363dbd9abb712eec9f7be844bfcf8d3d04a538bfe", + "0x0000000000000000000000000000000000000000000000000000000000000139": "bd1f3e51c77a927fc30973f8452ada7e030b8452273afd75dff18884af8a204c", + "0x000000000000000000000000000000000000000000000000000000000000013a": "f976366428e1f9e79b69a03a333c3ea2d57804cafad16ea0301def95480afa16", + "0x000000000000000000000000000000000000000000000000000000000000013b": "3752f226d6f4f227e0d59f153fcdefff90cc3aa9566c14b02bf86a5ba7e5f740", + "0x000000000000000000000000000000000000000000000000000000000000013c": "bd34ef105826797a46b3ccc8b4a82c61897bce87047aa90ca88d590887dcef52", + "0x000000000000000000000000000000000000000000000000000000000000013d": "a2689bec112dc66781dfbbfe0877f3b56c055872e331b6d45acd6e8d97e046e6", + "0x000000000000000000000000000000000000000000000000000000000000013e": "3f028560d99874cc15a76dd76b7da32cdb9548a9e262b5c986bc62ae920e643a", + "0x000000000000000000000000000000000000000000000000000000000000013f": "a0755b0908be2efd8534b105a279c0045087852b3c412f2d3a888988e4fa475c", + "0x0000000000000000000000000000000000000000000000000000000000000140": "dc88273a8339355e4c23b544329f1564ff0f17cda095b1ec2dff43d3dd0e39ed", + "0x0000000000000000000000000000000000000000000000000000000000000141": "ea4108c88374dcffd042b2fd53de46cc82aa3a0c1573c6228198529dd90ad350", + "0x0000000000000000000000000000000000000000000000000000000000000142": "89aa4d141def4c923b06aed9552126683bfb54e96f310d8fbc98bdef21e3b319", + "0x0000000000000000000000000000000000000000000000000000000000000143": "5e09d28a6f9e43be4a5f908f764b9c25db1fcb323d9af4d54a9a486721b6b766", + "0x0000000000000000000000000000000000000000000000000000000000000144": "a8e614e1553ea89015d1c2d2d90ef31794bacd4f661a9b8ca0e8f57cb8358a99", + "0x0000000000000000000000000000000000000000000000000000000000000145": "772516ae20b52f5521b3a703dd4fcecd98f348fa2f0523f85aa4b801d46b8a2d", + "0x0000000000000000000000000000000000000000000000000000000000000146": "40137062068c2bef8766bb8df571f0e0c341f3877dc1d7311c84177331165a5a", + "0x0000000000000000000000000000000000000000000000000000000000000147": "c10d42ae21c805f56d5f486087ab29e6c5f16d2743dceea53e68b4c4ec8c41de", + "0x0000000000000000000000000000000000000000000000000000000000000148": "f37ed9b3c15bebe2c65743e7013c97fa8b75f97e8791a353c033c16171a82fe8", + "0x0000000000000000000000000000000000000000000000000000000000000149": "8271d4efd4a54b038c0cc02e2a437d7cc3d96aed9148763fb2825fcc1ca58a1c", + "0x000000000000000000000000000000000000000000000000000000000000014a": "a9505142d5e8f2f3585f3d753c6cc615395b9694739c2aaebfdfbd52ea22d378", + "0x000000000000000000000000000000000000000000000000000000000000014b": "4d6b8d46d03208985e99ee7ca9d38e3ff54871672663c6a1cb4d8a558fe8b5fc", + "0x000000000000000000000000000000000000000000000000000000000000014c": "317d6cd8a8783099c05585ff4132c92fa56746ac04dc89d01f90a6087d95e3fa", + "0x000000000000000000000000000000000000000000000000000000000000014d": "1aa7fbd954a82016be127f3624a93bda8d45351191031f3671060abf2fbc7140", + "0x000000000000000000000000000000000000000000000000000000000000014e": "f0a0f1e9079642d9be82b1a2c786bf1c89f4e0bec03cbd6c1be96b92c47cbeeb", + "0x000000000000000000000000000000000000000000000000000000000000014f": "286ee500a7ccd24305014fc9ed773b472aa0e9de2005f98b0136bbba193e89f9", + "0x0000000000000000000000000000000000000000000000000000000000000150": "2f60754b89d3acfa2cd8e479e2b94e90c07bc5ca92f5e49b3d0280a30775893c", + "0x0000000000000000000000000000000000000000000000000000000000000151": "1d2172c03aa39bcb2ff80dc3a80b157ee311f01f1972c3ae61df2fbc08581df1", + "0x0000000000000000000000000000000000000000000000000000000000000152": "b5038ea078e022c5f7c97429a3f36c5b15ef525012266a78784315d5f5f8f742", + "0x0000000000000000000000000000000000000000000000000000000000000153": "b63287f903b3d2cd28cec281f1de235c85ed05ba3857e28cc86f9c29f39d57da", + "0x0000000000000000000000000000000000000000000000000000000000000154": "9c476efe697f7d3482e8a3a620811c6dc88ed3b98cdc752a53bb756d13a6dcb5", + "0x0000000000000000000000000000000000000000000000000000000000000155": "de9ba0e426dbd981f0ea6eb968d6f3a725b664f175d245e6e9e2478ff44afb72", + "0x0000000000000000000000000000000000000000000000000000000000000156": "36e28ee4cdd767038d87e898e8b59f777b31454f9960e87ab3fc258223c5b212", + "0x0000000000000000000000000000000000000000000000000000000000000157": "2955e6adbcf58ce3f34fc93da829c9c44a6641382ff92336f8cdedd1734669bd", + "0x0000000000000000000000000000000000000000000000000000000000000158": "4ef098ab7baa897a6c538545fe29382fbc85c59ac78a01b5428a0db58bb5bfca", + "0x0000000000000000000000000000000000000000000000000000000000000159": "ee27e318aea1e83eb7b252d701fc255f8a295bc048819b674977db2140507eaf", + "0x000000000000000000000000000000000000000000000000000000000000015a": "99c16f02cab4384eae354d510b84f49fb3cc77ac1a2deeaa87c7342894ce256b", + "0x000000000000000000000000000000000000000000000000000000000000015b": "38c75f8d455709c7dbb8ac586e04a2579d9e7d28a4d33a460588b70612a882e8", + "0x000000000000000000000000000000000000000000000000000000000000015c": "346083b60f44fd307e10d7e0f67b5da3d1230332adf26749cb5c80d00003300b", + "0x000000000000000000000000000000000000000000000000000000000000015d": "def08200cf595f64a706819f16a1c39b7409cbbc14fc29a87b50c95a3f9e0464", + "0x000000000000000000000000000000000000000000000000000000000000015e": "701b50b242d6e6062020d66c4134f678c49fc7887ba1f962f97863b7648626f2", + "0x000000000000000000000000000000000000000000000000000000000000015f": "3265fc38a6c5684461c72e9c03fe1ddd99a53cddb2d371d0fc1188a130d76e79", + "0x0000000000000000000000000000000000000000000000000000000000000160": "84bf2031465aeaaa042fc5f12c7cf61ce1cdb3225525bf961b115bffb477ba2d", + "0x0000000000000000000000000000000000000000000000000000000000000161": "95d03fc9c7ab7b1f91a38325076295ba7251541246ff6929d4c3b4d7af875705", + "0x0000000000000000000000000000000000000000000000000000000000000162": "d7e39656fea33b079d0fffa85665bda655e35ac8cd609b24db52fc10dd22030b", + "0x0000000000000000000000000000000000000000000000000000000000000163": "56f28aefa9c8a192e22bfd3ba9946ca3b8d1e96897d3599f8f7ce0af473662b6", + "0x0000000000000000000000000000000000000000000000000000000000000164": "a256e8a74e0d5f0db511d6df3d329492b15504f515278ff998d108a49902a8d6", + "0x0000000000000000000000000000000000000000000000000000000000000165": "fda145c2f89e067fcb82e98c5a201fb8f9949d578a1b87241e6f7c103fbda5d4", + "0x0000000000000000000000000000000000000000000000000000000000000166": "c60a413c6267e5f34ee8e27efcb89e2bbcdd4b839cb0c961f7dd37805181626f", + "0x0000000000000000000000000000000000000000000000000000000000000167": "9267c3d2e49d9a2fbb84a69db614d9fb33bae938ee4bd0fadcf5cc033562bd8c", + "0x0000000000000000000000000000000000000000000000000000000000000168": "f66d68a2b0dd9fbc45a5646cebcb99e8af641c8a372724264058493e141eaa46", + "0x0000000000000000000000000000000000000000000000000000000000000169": "cafa23b21dd847e0a6863e2d6a9e81749d2ae6174e340bf3ed6c27e030ed38fe", + "0x000000000000000000000000000000000000000000000000000000000000016a": "d6aca4fd2acf5ca563efa815897afcfaa175b8955931f699ae4018ac86eeea91", + "0x000000000000000000000000000000000000000000000000000000000000016b": "16b4cebad9f39a7db380791451d3a9dd9c35dbadc751254c41f94cae8280358e", + "0x000000000000000000000000000000000000000000000000000000000000016c": "505a6bf5ab0f40712af88078826c83c152e5ec99fd74ae718e47c0f1b6c7c0fb", + "0x000000000000000000000000000000000000000000000000000000000000016d": "0f15f04e28de513a6e468d22860d94e5389a07b5b630f8a8e7b84ed7bc0b8558", + "0x000000000000000000000000000000000000000000000000000000000000016e": "7371118bf9383f5e8b92bbb6cc9aaff94c06477228cde2abfffc48cabafc1bec", + "0x000000000000000000000000000000000000000000000000000000000000016f": "77d7c2eb0af7749896c1be40161508d650c019a8fdfdabab4b34b47f0caa5a80", + "0x0000000000000000000000000000000000000000000000000000000000000170": "c3c6a43b0a9fec6d3e9c232cd9048eb4b655f8c779ff7c510195e75d4c3cb3dc", + "0x0000000000000000000000000000000000000000000000000000000000000171": "024a6e084b404338002e6dd8b70331a3ad6d896cdedecd23db0c7db0cca13ea7", + "0x0000000000000000000000000000000000000000000000000000000000000172": "4ac493337944aac392f8ec72d0187775a98712347f2d3a8ce5e6dfade5fc88e1", + "0x0000000000000000000000000000000000000000000000000000000000000173": "53f13c2ada283dad19b4c6e1f5d01844ecdfce9b5e5cc064e025aafaa95c97fc", + "0x0000000000000000000000000000000000000000000000000000000000000174": "5aebb1a84a124ace93a6955bad2c1d3e26769ad5c4c8f7952bca62ffa6ecbb72", + "0x0000000000000000000000000000000000000000000000000000000000000175": "722cb497906813e0dac64a5e558aebc697f65a0929bdc4c9b763507b37d17442", + "0x0000000000000000000000000000000000000000000000000000000000000176": "86eef2cdfc7f44f813f99a5699adb200ac3e48a490a1e01656f2991f1655f387", + "0x0000000000000000000000000000000000000000000000000000000000000177": "f80b907a5268d198f59415e895a2dbd2d2f0ee499394f873bcaad64be35ba295", + "0x0000000000000000000000000000000000000000000000000000000000000178": "c4db6912f2653a9382b68bac827e5dd2eb40e3231f203a2f1f8eef0f72e6f02b", + "0x0000000000000000000000000000000000000000000000000000000000000179": "499ed1595f081f971a86fa5d465264ec4ebcf362ca75b566c64ed9e143779b92", + "0x000000000000000000000000000000000000000000000000000000000000017a": "b079707f805c9e021d3e353694af2c1295ff098e90f96b7e597f604df32d4f7d", + "0x000000000000000000000000000000000000000000000000000000000000017b": "07a887698ad470a92e0ea4b515f4e0c1eef4d02e005090f039ccad1f98dfa78e", + "0x000000000000000000000000000000000000000000000000000000000000017c": "37c51aeb36996d1204e1cc23f24fc8ce6a531230eac5fd95a0157afbae993408", + "0x000000000000000000000000000000000000000000000000000000000000017d": "fb7823c99d6a8cecf4576cccad394131869c27c19903241a4bac149e8a9df5cb", + "0x000000000000000000000000000000000000000000000000000000000000017e": "b43189b040f33d48780cb23517066fa7ef9be143f72926c776dd2a0deb74cdd8", + "0x000000000000000000000000000000000000000000000000000000000000017f": "36d98a00fa9cb5f2d23adaac16766bf86c534154016d362227b77a09e466ed03", + "0x0000000000000000000000000000000000000000000000000000000000000180": "864f50b8a89fc8049af6830206eeacfa26205d9ac2f1e9ef297c024532a57be4", + "0x0000000000000000000000000000000000000000000000000000000000000181": "a68dad1f5a2ca3fec7174293fb1eafeed1b3e1209dfc74ba1d4f67272530d1b9", + "0x0000000000000000000000000000000000000000000000000000000000000182": "b5d6be7351994263965ff5d6bec155497dfae4101d9fa6f7474f4346432cc94f", + "0x0000000000000000000000000000000000000000000000000000000000000183": "435041bdf7d03562f6cc28be67dd48e2a55cb6c36a8bde74217c78962fe35c04", + "0x0000000000000000000000000000000000000000000000000000000000000184": "74659e9bea0d8d39ee2966f14026731c00cfeac2addae8ab7440f3897752035a", + "0x0000000000000000000000000000000000000000000000000000000000000185": "8166e02057fbd66e2bdfdeb5e1b7348030fb8dcdf336c608186ecdf95a878d73", + "0x0000000000000000000000000000000000000000000000000000000000000186": "686342d6e14add1de361c209a4f097174472120c2649d4b1e3c0d69478c573a5", + "0x0000000000000000000000000000000000000000000000000000000000000187": "69ee2c164e201f10e82103b762fa299a98efcd3efb531d7f684cc93fe20877bc", + "0x0000000000000000000000000000000000000000000000000000000000000188": "977c2a14bc576911c691938eb8badf6a77843c4214b0613133fa356a23aa7f92", + "0x0000000000000000000000000000000000000000000000000000000000000189": "d9a295a0e39c94e3e9c9305b2e410aa89ee5380a8c343b901fc2ce60a19a431c", + "0x000000000000000000000000000000000000000000000000000000000000018a": "f2d8812d4f28578755d4229aef19bd2162c69cd9dbc684dd6a0b0b64c979bd73", + "0x000000000000000000000000000000000000000000000000000000000000018b": "c64105453f3f4a50ea7452760ca6066140fc6f2115e16065c397778756460d79", + "0x000000000000000000000000000000000000000000000000000000000000018c": "ff05bd7ed3a3f4e5abc2e5232c98d4343072bfd25121b241932703d33f875c0f", + "0x000000000000000000000000000000000000000000000000000000000000018d": "2fa9e1447264c03da65b930986c6c67078d887aa0b6252b49026c3bbc522ca59", + "0x000000000000000000000000000000000000000000000000000000000000018e": "10c9eb1115f231e7a50650aa52acc568532a80c7c1e0d695517fe4da1d493a8e", + "0x000000000000000000000000000000000000000000000000000000000000018f": "5abe00a7721db9dc1fbf458d49714c666ca2424e476099adfb77fd8dd54a0eab", + "0x0000000000000000000000000000000000000000000000000000000000000190": "ade4149b0375ad07777a88bf87a50426806e7e69c98719e63763ebf8585d39be", + "0x0000000000000000000000000000000000000000000000000000000000000191": "90544280b5a1c89044d0a9acf28015355e9f87f99cebb6e423a2429593805c3b", + "0x0000000000000000000000000000000000000000000000000000000000000192": "cbaec457a9bb83f627a46b321256873866c0a5c079315e1294328fc71b7d8529", + "0x0000000000000000000000000000000000000000000000000000000000000193": "888127ccf7a04b3ab6dc54a687036e7464c30e3fd813a0f4ddc69094cf250b90", + "0x0000000000000000000000000000000000000000000000000000000000000194": "08d7f2f015c06dee88d707cbc050021fd38afd6a253d3382a783e92ab30f22c8", + "0x0000000000000000000000000000000000000000000000000000000000000195": "729c0e22346bb677499d2b9af1da34dfaf7653ace58567673fc6894cf8d56289", + "0x0000000000000000000000000000000000000000000000000000000000000196": "d60f9025487642346d1ff6fcb21558a0b719524dda4fb773e50254be6ea5cb70", + "0x0000000000000000000000000000000000000000000000000000000000000197": "c2f378a6349f5ff2413494603a2bf9bf387182e0d7b2e042e0aa9bdde16b44e6", + "0x0000000000000000000000000000000000000000000000000000000000000198": "2332603e1b89c41adb97428017bd2297310b5deeca32af3d79c88a23090d5aaf", + "0x0000000000000000000000000000000000000000000000000000000000000199": "0b88f4a3ea4fe334e0f85983fc3ed8f0e5031f76642df83e9ffddff65637cf43", + "0x000000000000000000000000000000000000000000000000000000000000019a": "d5359ec7c8dbda34bbb1391a68ee130ee2fd94cdd86f2e6683e4ca680ef2ee43", + "0x000000000000000000000000000000000000000000000000000000000000019b": "e068d60356aae28f3154fa8f886f0f0067a7b74b524601c2f623610d258cbebb", + "0x000000000000000000000000000000000000000000000000000000000000019c": "650b963d47bb9f9b86c29b9d9e52c219bb70525460c04812bd6da741c0e4f90e", + "0x000000000000000000000000000000000000000000000000000000000000019d": "a36c2bf72d713f99a25528fb03aa69429831432f179f6c7c406918b542f76ea5", + "0x000000000000000000000000000000000000000000000000000000000000019e": "3987af76d0a00951e4513199ee41aec1071161b52151ce66934cda577c4336c6", + "0x000000000000000000000000000000000000000000000000000000000000019f": "7158030722716ed4b3153861925682677908d60a72f68d54c31732380dda9939", + "0x00000000000000000000000000000000000000000000000000000000000001a0": "fe58c2367f07005a8773b7faee91e02dbafcb140bc800a5145ee2e31dcca251e", + "0x00000000000000000000000000000000000000000000000000000000000001a1": "e75e1fff4381bbf11eaa336b11a4a79a82f0a39a8afeda3673bc6b98bf091f92", + "0x00000000000000000000000000000000000000000000000000000000000001a2": "7de3c0bd5e846119edcd858e4d51f0c0153974ea077bce8048eb3e7d191c3c65", + "0x00000000000000000000000000000000000000000000000000000000000001a3": "c6053e841c2e4bc75e4e959e1b74a9387b351bb4919ae295314e834c5d94e6ed", + "0x00000000000000000000000000000000000000000000000000000000000001a4": "404b549fee0787cefdf4065cb76e3a0e66aab2ad8c6a318e9adfe0bc4a73b85d", + "0x00000000000000000000000000000000000000000000000000000000000001a5": "1ef7fa7c852474808b71df44ef25db220e3dbbb3fd5e18cbb7445b0546b2dbb7", + "0x00000000000000000000000000000000000000000000000000000000000001a6": "c5e3d5218b2e1a652c2f2d9613df0b5e389b8695c73562332f4c3381d59faddc", + "0x00000000000000000000000000000000000000000000000000000000000001a7": "3bddbb879a8d46f692289da30f77e1ba669940bd42a1279d275b94c24dcaf9e0", + "0x00000000000000000000000000000000000000000000000000000000000001a8": "5ddb9e58b0ef297a051097bc988e136b1749d9f3445561b6b14a692fad23b8da", + "0x00000000000000000000000000000000000000000000000000000000000001a9": "36be5e83ae2b1baebbb956bc7c44f540745e5a78a59f3ca2aa088fb994fc62c8", + "0x00000000000000000000000000000000000000000000000000000000000001aa": "cd0da9da1e9b992dbbc4e98d488adea3b884852750ac79bde2b2ea2265a65d9f", + "0x00000000000000000000000000000000000000000000000000000000000001ab": "a5a646fb42670f9bb6782713ff7b2cdb24cd4bb3323b0586c5e2c03d03221d30", + "0x00000000000000000000000000000000000000000000000000000000000001ac": "ec2df5da5678a7b5ea6e5606f84879096c1b455ff0c9fe35679c9436c77953fd", + "0x00000000000000000000000000000000000000000000000000000000000001ad": "3b1fcf135ef30081e41bfa1d41b0fff91843274d326b76a81723c7cbcf81c7a5", + "0x00000000000000000000000000000000000000000000000000000000000001ae": "76c48fbe8881579636df3e68fe55621e99026e7d9810b74ff9cdb7557873d056", + "0x00000000000000000000000000000000000000000000000000000000000001af": "b0915a68a1ecb0bcafe6d483d3fddd6a93249d963db6e9650695570b2d494448", + "0x00000000000000000000000000000000000000000000000000000000000001b0": "fdda715666ca9712626e528f4570ffb24d48cdcc62e14571241d1a2f61576c46", + "0x00000000000000000000000000000000000000000000000000000000000001b1": "91bab78100c2b6909b533e246d772659957330f8ddfcf194087a8fb67bdfb6f7", + "0x00000000000000000000000000000000000000000000000000000000000001b2": "ad585c5a49c5db92630ed7c7b67fc367f3405060a0bff9de9dd64b996505a66d", + "0x00000000000000000000000000000000000000000000000000000000000001b3": "b8b4a3064cf8c569375764e5323ef7a03667dab6ea562bedcf67aeca7ad55e44", + "0x00000000000000000000000000000000000000000000000000000000000001b4": "53611bef1500f1568f35390b80eb6baf31ffaf9d8a4d34aab3932e5adffcecb5", + "0x00000000000000000000000000000000000000000000000000000000000001b5": "dd0f743e193c79a4a3ac080b01ed2ed15d9321300c002d70d74fb4c9b44564fb", + "0x00000000000000000000000000000000000000000000000000000000000001b6": "cfffe2d9251de471b21928c131be8ecb1b332ec4a9ffc226e64f041820caec47", + "0x00000000000000000000000000000000000000000000000000000000000001b7": "758647ab7f0d8935064c2c38ef6a2a34457df9c78297c2d42376ce18051a4a56", + "0x00000000000000000000000000000000000000000000000000000000000001b8": "1431bfb93a91538f50aebe4b46add424df29fddb8a479eb51c44539f7425d9c2", + "0x00000000000000000000000000000000000000000000000000000000000001b9": "f2d3d4be2e09a5499d838936b169c6ccf83a1dc510305e54e1e181243480bdcc", + "0x00000000000000000000000000000000000000000000000000000000000001ba": "9b8c6ecde0c9f7d3096db113472984400265c16b8f423527046f7c9cacec1c0d", + "0x00000000000000000000000000000000000000000000000000000000000001bb": "045aa374dc38d101b3846713180df1f69828e97bd630e2264149777bb19ece35", + "0x00000000000000000000000000000000000000000000000000000000000001bc": "e316b409f1472bfb043c4be4e9654a37e2a898850d9bdc815cb9ca1a44b29118", + "0x00000000000000000000000000000000000000000000000000000000000001bd": "5cf2998fd231bdc16bd2c20b02d58af1f81d846a058464ac2e74f75a0485a33b", + "0x00000000000000000000000000000000000000000000000000000000000001be": "576518015f61ddc9e28fcf964fa2a13490057c8f8ab669ad82dd2e6bfa19879b", + "0x00000000000000000000000000000000000000000000000000000000000001bf": "21d1d59bcf21cac072a2803938f6fd69d922d1e47a8b7049d8818266bfc27951", + "0x00000000000000000000000000000000000000000000000000000000000001c0": "e4e0607f25a8dcac8a8f7758373f3bbc1bc35176e239966d35a57925684b82fe", + "0x00000000000000000000000000000000000000000000000000000000000001c1": "8b744a371a22b4986eeceb8ee0f512ca44affb56ecd495cea9e6c66a490e1f9b", + "0x00000000000000000000000000000000000000000000000000000000000001c2": "ca1d7f951d628dd35b23cac8c21070a5740d64bba614089170c895a0ec8f57ef", + "0x00000000000000000000000000000000000000000000000000000000000001c3": "410876f7d8880a998a060adf663027422ab139d54e12e973c1bb8342844cb351", + "0x00000000000000000000000000000000000000000000000000000000000001c4": "b30c453a9fb88e026819b182903ff90738d44f4237cf66139fe010a93c83ffb4", + "0x00000000000000000000000000000000000000000000000000000000000001c5": "5588cd9a04aa1c7e5590c15bf201aa722f59c4aa952bedd1e0de2cd2026c016b", + "0x00000000000000000000000000000000000000000000000000000000000001c6": "ac273cc7933a2407ec16281e6c7e43bb9b24efd517f53122d265c0fd8e400e6b", + "0x00000000000000000000000000000000000000000000000000000000000001c7": "de0c3b47b2a8550abaebd952555b5a604916b2aa0c3516ac07f7cf9bf6d289b6", + "0x00000000000000000000000000000000000000000000000000000000000001c8": "305bd96c60a6435f5371739f23364940ac2ee253e9a6f8d3bd89a623112533e8", + "0x00000000000000000000000000000000000000000000000000000000000001c9": "322c4d0e57f585f032d5cbfff69c3adb7ac8084c95761a9bbad98b97f101327f", + "0x00000000000000000000000000000000000000000000000000000000000001ca": "721f94cdb4c6e847bfbc88d65c74a8eb476178d1fa868af25151fd17256aa5cb", + "0x00000000000000000000000000000000000000000000000000000000000001cb": "e98015589d78db8a32de341208e325d7613c6db8683c7d1376113589e15acf0f", + "0x00000000000000000000000000000000000000000000000000000000000001cc": "ca13a2bf7d0eb0db6335849b7706678ec18caf013540bf57873532d5bc5cced4", + "0x00000000000000000000000000000000000000000000000000000000000001cd": "4d93ae5d91ac6a55b6fe9e452210d4e60472cb09900262104063f91e1c4475fb", + "0x00000000000000000000000000000000000000000000000000000000000001ce": "4557b30a7674af7cbacde7748dff90a2d7b4b2a86f9d79d791e89d39f818a4b2", + "0x00000000000000000000000000000000000000000000000000000000000001cf": "07a8c620ead87a45afb4e0e815a54ca217e4054077635d1524710f1ce5ecea24", + "0x00000000000000000000000000000000000000000000000000000000000001d0": "87bca64e4e6c1a83cf43da1257fa59a376009b2c9f2f37487f85eb8013fb2f0f", + "0x00000000000000000000000000000000000000000000000000000000000001d1": "5984be6ef98b1e35c943bed4caf24066c34bea65dd09cf99762e7e3b6e41ae03", + "0x00000000000000000000000000000000000000000000000000000000000001d2": "223fd06ad6b3a95d0ca0b0fac2819ca9cc7abbcf53686cd3cc9ea9a7099aed2a", + "0x00000000000000000000000000000000000000000000000000000000000001d3": "bf9df0134a7722c090ee27e9061af8e32ba1f36de3561cf540aa19c1e0301694", + "0x00000000000000000000000000000000000000000000000000000000000001d4": "3426b1051fd2963cf74c091c9281236fec075e3b1a6207e0ea8bd590d234231f", + "0x00000000000000000000000000000000000000000000000000000000000001d5": "108535b032c23c831ea3f0e5e60b628b1653a8d4ff2a04f84ea0c28a5f7a334c", + "0x00000000000000000000000000000000000000000000000000000000000001d6": "c57d09bf4689a42694a8b98bb6ef2cb60c0af0446b6dbd1f55fb9d19743d0b6f", + "0x00000000000000000000000000000000000000000000000000000000000001d7": "62ec7b9a65be76bed69c2d1b89c7338fd99f11c52ce57d223d0978ad2623b666", + "0x00000000000000000000000000000000000000000000000000000000000001d8": "88fc2bd51129c6a76a5fc4d74e5bca399695ea9b272f65febb655c211ffecccf", + "0x00000000000000000000000000000000000000000000000000000000000001d9": "4a6fe7d7a0b3433c8c0017a34efcd408751e24ee224d865746e43ee5dbc6b72f", + "0x00000000000000000000000000000000000000000000000000000000000001da": "b4d421616ea7a4adc51abdc1eb68ae4517c83a7e65545ad5bd8570fea865bbe4", + "0x00000000000000000000000000000000000000000000000000000000000001db": "35ca0c82bbc6c2a282e04efd935ad91744a76f738b1a05f543f362089b077549", + "0x00000000000000000000000000000000000000000000000000000000000001dc": "a2e71dde107bc1f02f8f2303e84580a4061adb821347fd065dea806464488543", + "0x00000000000000000000000000000000000000000000000000000000000001dd": "8c2efd84e25c29636ce86228e1fa39045936581562d1d80d1273951d3a7e5b5b", + "0x00000000000000000000000000000000000000000000000000000000000001de": "ae195bb8f9a28f440a0a10bbf872db2c50aae4f08d49089e3b8783187b8b2d5b", + "0x00000000000000000000000000000000000000000000000000000000000001df": "d74fba51d365cdfe355295a9a9cb7470ab1ddb53070cc23dc84706d30a1c9d65", + "0x00000000000000000000000000000000000000000000000000000000000001e0": "586bfb94de868a094829593278f0059423d4b3a4fa381118368e866ac9ad174d", + "0x00000000000000000000000000000000000000000000000000000000000001e1": "ed9fa0da61fcefb49df7807a0e827069520dd2e1b7823c23b6c8316f261a1526", + "0x00000000000000000000000000000000000000000000000000000000000001e2": "2d4f68ab5cb1b7d5942ed325911da4de560c281bc4165f12e79b40896faf9240", + "0x00000000000000000000000000000000000000000000000000000000000001e3": "173ba1064b822d7fd886f79df09291855941c7e187348cb1be74b4f3853ac46a", + "0x00000000000000000000000000000000000000000000000000000000000001e4": "5fe23349b74796ea88667c124d31b7f83d1ea6c55888612d0546fcd8781469f0", + "0x00000000000000000000000000000000000000000000000000000000000001e5": "44b4ee4af4ea93cdc1f6d6a7600b78b1f18918e5adb36a95773fb69f0c95960b", + "0x00000000000000000000000000000000000000000000000000000000000001e6": "6e1a5f320d6c603aebe7b47c6f98bab7e6ca3f63648853117f90681ef82be343", + "0x00000000000000000000000000000000000000000000000000000000000001e7": "0e0736ecbc21d8283a34e648718dfde99dcf213778a19cbb385a528281994d02", + "0x00000000000000000000000000000000000000000000000000000000000001e8": "8d71815cf7e21c74cf91c9f2ff59fd941cbcf127084f929254498163c494f183", + "0x00000000000000000000000000000000000000000000000000000000000001e9": "bff2f568d9a26daaaedd8e26e46d3eecb122cfb8c091bc194d6326c88d058f1d", + "0x00000000000000000000000000000000000000000000000000000000000001ea": "509d2a2521abc4c30ba8b397d9e86976e6134a844bea08ebeac4a4b009bfdd32", + "0x00000000000000000000000000000000000000000000000000000000000001eb": "c73fe82ce95274c1aca827b1e2bcbdc56663f172a9a808e02fb03b594afd5494", + "0x00000000000000000000000000000000000000000000000000000000000001ec": "8e940db2d4e9688d0eac137008f26832b205e32c67877475cc0348c38be128ab", + "0x00000000000000000000000000000000000000000000000000000000000001ed": "c4686ab32da32550e9cc95adc86e731d96b3498f28c3454972b8647922a8c775", + "0x00000000000000000000000000000000000000000000000000000000000001ee": "2acc9875f08bf7c9185aea7dcce6c1163b303e620de25993fb494a866f831b9a", + "0x00000000000000000000000000000000000000000000000000000000000001ef": "e5e2de3cd1a2a8f6551e93be0ab3644c84c9653cae77d63caa4a10f5b805ffd4", + "0x00000000000000000000000000000000000000000000000000000000000001f0": "6413cdb135c067bf7c9894bc05cbef70350d5d2bcd089f661257b80a28d71a26", + "0x00000000000000000000000000000000000000000000000000000000000001f1": "e800f779e224dcc43b5c7bb57da2d643e20dbdb53e1cd60e41207b620a040b5c", + "0x00000000000000000000000000000000000000000000000000000000000001f2": "e3bd2dc0e6af6253299c175f22a860b34d75ee109faa0c7dc437c94c8e35643f", + "0x00000000000000000000000000000000000000000000000000000000000001f3": "44924c88d1ebadca339c20badf7e5e22ce7ec673cfcb7305d46487417a852cde", + "0x00000000000000000000000000000000000000000000000000000000000001f4": "7151d7993c13af657fb9afbcad9340ddb46fac82b873b64baf85f8f5780151df", + "0x00000000000000000000000000000000000000000000000000000000000001f5": "eb6625cb0981451d810c0172e25819ca3b6fc2035ea04542f3dee1dce7c516df", + "0x00000000000000000000000000000000000000000000000000000000000001f6": "efab54ac6e96aa6fc5d3270f7a928f03ab557ce9b7d2ed68f08825ca50c6307f", + "0x00000000000000000000000000000000000000000000000000000000000001f7": "f0591fc75f0711d3d9234011205cb9bd2c40a3477994d943e6d7a12c72e8d613", + "0x00000000000000000000000000000000000000000000000000000000000001f8": "df54b762c56706ef7861a0725b7fd4f01aaadcac614d3d3f39569cb8e621fd1a", + "0x00000000000000000000000000000000000000000000000000000000000001f9": "4effa3cb8383f0ece82c3391e95ce6a88be26f87bddcc62dfd99cd7a5a11dbfe", + "0x00000000000000000000000000000000000000000000000000000000000001fa": "2d903ece7c308b988d585304235cb0f3bacbafb64ec0b62da27c1f77aeb18d76", + "0x00000000000000000000000000000000000000000000000000000000000001fb": "5a1cd86c8a2bb05874d5fd341035e7228067175a1c757b91f442dc34922a1b", + "0x00000000000000000000000000000000000000000000000000000000000001fc": "9e7ffa6ebba334b9810de0937096a05f054a43eb03621ca8874411e5ddaf7543", + "0x00000000000000000000000000000000000000000000000000000000000001fd": "68b50078b3394b06d6ee3a3b12462a38eb85286023c07d90e290ba808b5da702", + "0x00000000000000000000000000000000000000000000000000000000000001fe": "bae08b3b1ac544135b3a06fbaafb931229a99d0e47434318580146086ce0dab3", + "0x00000000000000000000000000000000000000000000000000000000000001ff": "91711182ab4cdd63dfaac9e02b07f4d49016fe1ac744ff90843bd1f52f893761", + "0x0000000000000000000000000000000000000000000000000000000000000200": "fc6438ea7c3138aca8cf840a05aa7e627ecea40cec8d6166406f98449ba6182f", + "0x0000000000000000000000000000000000000000000000000000000000000201": "d7d6cfbe9f350fc0643592dbd7a2a98639f92b0183cee49ef6f5d99aba72b47a", + "0x0000000000000000000000000000000000000000000000000000000000000202": "e42d2c63e650101bc54d149c19d67b78ec05431cfc15134146790f1da71548b2", + "0x0000000000000000000000000000000000000000000000000000000000000203": "718c2451b8df916754650ca5d9a3fca98e0f9209d41cdafd30d3ee9343b12216", + "0x0000000000000000000000000000000000000000000000000000000000000204": "64f5dc426951c8d5c389bed1af605f9101235dbfaa4822f2ba83bbe9973be25b", + "0x0000000000000000000000000000000000000000000000000000000000000205": "1841a4c413f59d37b93421bc6d165288e0546f1261e25357feae9c96a66402e3", + "0x0000000000000000000000000000000000000000000000000000000000000206": "289f40c44da44e6d545900ecfab81d0d86b9756e74d6bfa2fb0095cf28a93cdd", + "0x0000000000000000000000000000000000000000000000000000000000000207": "b80db8759f920638458bd60e8f97e9a0773970c30941cf2744f4db475b5c53a8", + "0x0000000000000000000000000000000000000000000000000000000000000208": "4280ca715e955153245aa296395bd7f179a13606f4e909119b1d58b7b0457e34", + "0x0000000000000000000000000000000000000000000000000000000000000209": "56c95098c7c859b8b786bc2f776f739ba109a1d662beb8545294938b9ce5ef4f", + "0x000000000000000000000000000000000000000000000000000000000000020a": "ed614b855d979afefa3c40027ca4b6fff89a1467173e85302b48a478bfa7abad", + "0x000000000000000000000000000000000000000000000000000000000000020b": "f379747713313c3ef604ea0d5446066edf0b695213acfb86388ba46e6c926bae", + "0x000000000000000000000000000000000000000000000000000000000000020c": "71345ffec2ba388522c6703f19f24c5af1eb742a44d2ae6749276739d138912e", + "0x000000000000000000000000000000000000000000000000000000000000020d": "c73d56854a544ce56956bab6d4ffab7beca0ec861ff5cf5906aa2aec20682c75", + "0x000000000000000000000000000000000000000000000000000000000000020e": "d543d5b576ae572d9996cd3d05295368b201e3c618ae5da30fbec43cf24b52a3", + "0x000000000000000000000000000000000000000000000000000000000000020f": "dba4322406050555a1a8cfbae1c6fd627bee7757384059a41bfd5b6147543f53", + "0x0000000000000000000000000000000000000000000000000000000000000210": "9eadaf49e03a16c9c7cb8d2ea59c3285d7530750a462d6a9338e9a9e730b1055", + "0x0000000000000000000000000000000000000000000000000000000000000211": "eefa15b3aa7fbee117a78b61a365f6e38b6d8ae21482bc2eda241e637d43af8a", + "0x0000000000000000000000000000000000000000000000000000000000000212": "3c7d782eb5bbcdd254bbdb120e432c90d9b0510a3c7e64507ed2c82fc01a2a7a", + "0x0000000000000000000000000000000000000000000000000000000000000213": "56d781324e6bdab32f417adff9cc2b4c645f819184b323f47ec974574121b309", + "0x0000000000000000000000000000000000000000000000000000000000000214": "997c22b77767599b4d1f9f7d21ad9b34b1e13e5ba18986d4dee06d282e89e453", + "0x0000000000000000000000000000000000000000000000000000000000000215": "49223c27247cbb012c480dd78497ea761f0de37eab920e169067d710a6c697a6", + "0x0000000000000000000000000000000000000000000000000000000000000216": "09f9f3b73c653b5d3440ff550da397d5d6b4dd3e3297a2f2d3c5e67bb128afc9", + "0x0000000000000000000000000000000000000000000000000000000000000217": "6e277d1000baa83809de9f5f90fc8a3387d1ff660f9a7d7857ec4c3e66f70d57", + "0x0000000000000000000000000000000000000000000000000000000000000218": "eacee55ad16ffef8f34262dd2351947882b5c327565581fdaece63fe35c8044c", + "0x0000000000000000000000000000000000000000000000000000000000000219": "d13cb1082077f93cf162c8868d1e2ddfa3987c12f0b4d17de8f4e456ba9f646b", + "0x000000000000000000000000000000000000000000000000000000000000021a": "323fc2bb76f6f190369ed67f4eed60233e9ace45b6b77a8a545147f6e2a12826", + "0x000000000000000000000000000000000000000000000000000000000000021b": "1a26d12a9846cfa2af53cc33f21eadb49c2f39560b460bbb1d7c253025da7917", + "0x000000000000000000000000000000000000000000000000000000000000021c": "a68b828d73467b4edbb8f3a188d1d23b8de8113e1157ebe14ec188e8f266637e", + "0x000000000000000000000000000000000000000000000000000000000000021d": "46d5ce094294750e8d8c4508cea607a110ac887c6876460834bb7f944fb3cba0", + "0x000000000000000000000000000000000000000000000000000000000000021e": "8d3698f018ddc839a43997a360b3715b80f6f8fbf70836166601ecc42439b1df", + "0x000000000000000000000000000000000000000000000000000000000000021f": "bdaeadf6d9045a0a986c15262d81d49e1f12a3301035d7d7d03855f315498397", + "0x0000000000000000000000000000000000000000000000000000000000000220": "4466a1b8ce15a2b972b93d345e42e24d6c55e49e6e6b390daa111115737c8893", + "0x0000000000000000000000000000000000000000000000000000000000000221": "aac5449b0cee4d0ff7e6dc495061712400e5f908b5f5699bd489f8433c7f3ce6", + "0x0000000000000000000000000000000000000000000000000000000000000222": "bfc6905b39a1fd70f2d85dbd0ec084fc9bba34dd6bb89e4feae605de3472a46a", + "0x0000000000000000000000000000000000000000000000000000000000000223": "1320207357e4a928664d17895ca63c2e929115bf3078b13a0623a42b1361a27e", + "0x0000000000000000000000000000000000000000000000000000000000000224": "6988fc4983a5d91cb76203880fcb0be8d513013f9eda28c6db7c27d0e457f417", + "0x0000000000000000000000000000000000000000000000000000000000000225": "293913aa6fd6784e2dabfa7bdbf08dbcceac77ec746f2beaffe37f5c82ebd6e7", + "0x0000000000000000000000000000000000000000000000000000000000000226": "3c64be9f5fc05b3a06c21263201805872058b6dd89f5871f56126074937d7d69", + "0x0000000000000000000000000000000000000000000000000000000000000227": "9c0e5ad32b88aabd00d4e08f111128f36d2b3b9d00ec205b4deea450d7e20f52", + "0x0000000000000000000000000000000000000000000000000000000000000228": "ee8f988f3c18a72c2abea54699c856a15afdbaeae545924997985cb47210c6d7", + "0x0000000000000000000000000000000000000000000000000000000000000229": "90036a13de8b68ad7fa9658cb90a841951763c528de8a3891db006570d06760b", + "0x000000000000000000000000000000000000000000000000000000000000022a": "641e4d31a221b340b02dfbe9aa430eab15367721b41a224ad5aaf44d60bfb649", + "0x000000000000000000000000000000000000000000000000000000000000022b": "dfa68efde1f8c73371b729e119655153388ca5404df5f27cb8aef2d5dc49d472", + "0x000000000000000000000000000000000000000000000000000000000000022c": "e069e5bf125ec3bd85fc691a6e299363e03130bbbdcbb1d4c0e7ed74c44d19ae", + "0x000000000000000000000000000000000000000000000000000000000000022d": "7d4c7faff291a34dab9ad08cc22b38e3e0623fbd96e53041f1936aefea2d3d01", + "0x000000000000000000000000000000000000000000000000000000000000022e": "35fcbe1e362b97d634c17b08b78c253df56c0f4a52fdcc1da23c4c56871485aa", + "0x000000000000000000000000000000000000000000000000000000000000022f": "944867748f6677c888eeffa2f0ab037f72791f19d4957c1b015300f87e8f6946", + "0x0000000000000000000000000000000000000000000000000000000000000230": "e2a46fb9f878a562bb0392bec6634965964c742d80102bed78abf111455c1530", + "0x0000000000000000000000000000000000000000000000000000000000000231": "b229d60b67c1708d3994b81cb282f73ef6d2ae75438e401f4c8025562e2340fa", + "0x0000000000000000000000000000000000000000000000000000000000000232": "b3b6afe52f6d14dd44a71f1ff185ed96179409250f324659fa1d1abd1b232739", + "0x0000000000000000000000000000000000000000000000000000000000000233": "adafa5a8ecaf727c48b659ef4ab3204554e7cf7b27e69207926a5a62c24fcab6", + "0x0000000000000000000000000000000000000000000000000000000000000234": "dabd6ae95f5c2d68740f3001b8321ff60efcbd343b4c1d27e425b6e1d6dcbbef", + "0x0000000000000000000000000000000000000000000000000000000000000235": "bc4039fe1b1fe6767d379b48649f0208eedd6211fd09012c410e96231a70bd32", + "0x0000000000000000000000000000000000000000000000000000000000000236": "83db531e70791b6207c14af0b6321145a00614c977b70fd0668270988de4d5b6", + "0x0000000000000000000000000000000000000000000000000000000000000237": "d790766e32a204eba62eb8748875d63e58f290375cb77e1a8e06cee26be50aa0", + "0x0000000000000000000000000000000000000000000000000000000000000238": "5f7355f8b08daee6ee6be9e9522ecedee0db5282463952021b5eef1bf8fc6c7e", + "0x0000000000000000000000000000000000000000000000000000000000000239": "cd23cbad2ba375c546161adcaee6c4c81319c164b1ad8466811b7490b95e286b", + "0x000000000000000000000000000000000000000000000000000000000000023a": "f1357f71ed1cdbcf8c1a31552f1223403b9d85b44dd4ff2c9a3683ee440c95c8", + "0x000000000000000000000000000000000000000000000000000000000000023b": "b69086a5e21ff6ac0b0177b825eb4ac57307f19211d34d5d27f270d74ca07a17", + "0x000000000000000000000000000000000000000000000000000000000000023c": "d5c1878d16190ffce6abc0972a9250ab129a383fecf447dd5e1e5fe9c560e2b7", + "0x000000000000000000000000000000000000000000000000000000000000023d": "7adf3774b7bd3f89b0948e1ddbbf300835f06dcee2f437e09ee4473df6c8a07c", + "0x000000000000000000000000000000000000000000000000000000000000023e": "2dfc4f087156df89e8f26744590b923f3a81642defd298dd1a1db5bbce0b3d89", + "0x000000000000000000000000000000000000000000000000000000000000023f": "e58a461ab85b4e2208262ab6de81621a9fe3c96e4eadb9253e7baecdec571434", + "0x0000000000000000000000000000000000000000000000000000000000000240": "0bdeb401cf2ad8a1f33f3e6a71602b0720182bc5a290cbf92a20ad5a47b421df", + "0x0000000000000000000000000000000000000000000000000000000000000241": "29456e95da920f3dbc36b3dc0a926f2dec210b800550386ca672ed6110b169c6", + "0x0000000000000000000000000000000000000000000000000000000000000242": "ae6208b2d4c5f776a63eb1e4dc138b366387fe7ddecf72fd98130637bf65dfeb", + "0x0000000000000000000000000000000000000000000000000000000000000243": "bba5107c05a512e72c49b459b20a6ecdc1cfec225f866ef045c9a3693df05905", + "0x0000000000000000000000000000000000000000000000000000000000000244": "626d2bcb3645a3cab73403328051faad33be5e5f5f75ff38e195b77dfb0fba01", + "0x0000000000000000000000000000000000000000000000000000000000000245": "af6d014836a41c11af83a95a92d5324c0dd0e063a6feda19a05966c97cbeadf0", + "0x0000000000000000000000000000000000000000000000000000000000000246": "6268abdce6bb3bee101c9e848666f3522cf429cab4725f23a27a5eb9575ed2fe", + "0x0000000000000000000000000000000000000000000000000000000000000247": "5f5a1ffa3df60840b186c814fe10bee8d745a195f68174d5097067663eb692c8", + "0x0000000000000000000000000000000000000000000000000000000000000248": "b43bd5c412948cb43408ac47c85d080b9bcdcecc982ec14aa3a09dd531edbda6", + "0x0000000000000000000000000000000000000000000000000000000000000249": "fea440ef23de659e22508daedb4d4dd91a5bb39df9d3f039a24cde8ffa6527e4", + "0x000000000000000000000000000000000000000000000000000000000000024a": "5bda26af5e60d0a9bdccc94a59421b97f0d82cc828a117643b021ca4dbaa4372", + "0x000000000000000000000000000000000000000000000000000000000000024b": "bd1d9841873dd0a26419f9a183a78370dedd826f922adeff78afef05811f8f71", + "0x000000000000000000000000000000000000000000000000000000000000024c": "5f40f6bc01be52c0a6f0f800c4120e73ae430d2a0e2cc6cfd6958ef33aad54e6", + "0x000000000000000000000000000000000000000000000000000000000000024d": "5528f6ef151d9a9f71dae57e39b1cd2c5c6e5c7e0cd3a419afbee06e313d9f47", + "0x000000000000000000000000000000000000000000000000000000000000024e": "dff8f0703a0840e4d227f77f46348869d6c8b8c30b872137b26a9e2842914410", + "0x000000000000000000000000000000000000000000000000000000000000024f": "4ce9196d2fbc4bda9fcb9ab61e86167c9e1b547e873a7e5226f922b18db59953", + "0x0000000000000000000000000000000000000000000000000000000000000250": "5ba98af8b68bbf0d86879ec911858300293e7bbe347abc02548c5084ab5a0d3e", + "0x0000000000000000000000000000000000000000000000000000000000000251": "3d33f3036b1399cf00cc8966e85b8553b5d7d4127ad121f382df765661a6627a", + "0x0000000000000000000000000000000000000000000000000000000000000252": "3ed14e1e4d79669a7104b244f12d0dbbda1873230eddacca3ddf00d5e278be9b", + "0x0000000000000000000000000000000000000000000000000000000000000253": "93a7231507f57e163e3b2e48a47132fc1eff83375b041b46a35e61a090ded25e", + "0x0000000000000000000000000000000000000000000000000000000000000254": "42f57c5994becd0c778c625c4564b288f2ddd5523bf3505dcba11d4f31e317ea", + "0x0000000000000000000000000000000000000000000000000000000000000255": "05b8baa80ba3a0782ff6cade5129fb4e3cc8733de5d8da918d2338245ab76b6c", + "0x0000000000000000000000000000000000000000000000000000000000000256": "7d4219f429001b5f014e933f9a36aa865d09955de79a8292aac8a00e75ba0f03", + "0x0000000000000000000000000000000000000000000000000000000000000257": "65151b101682b54cd08ba226f640c14c86176865ff9bfc57e0147dadaeac34bb" + }, + "address": "0x0000f90827f1c53a10cb7a02335b175320002935", + "key": "0x6c9d57be05dd69371c4dd2e871bce6e9f4124236825bb612ee18a45e5675be51" + }, + "0x000F3df6D732807Ef1319fB7B8bB8522d0Beac02": { "balance": "42", "nonce": 0, - "root": "0xac3162a8b9dbb4318b84219f3140e7a9ec35126234120297dde10f51b25f6a26", + "root": "0x133a1f5d3770d41b04eba028628d43b91ab918068a4a77563f7b1a7a51200855", "codeHash": "0xf57acd40259872606d76197ef052f3d35588dadf919ee1f0e3cb9b62d3f4b02c", "code": "0x3373fffffffffffffffffffffffffffffffffffffffe14604d57602036146024575f5ffd5b5f35801560495762001fff810690815414603c575f5ffd5b62001fff01545f5260205ff35b5f5ffd5b62001fff42064281555f359062001fff015500", "storage": { + "0x000000000000000000000000000000000000000000000000000000000000003c": "3c", + "0x0000000000000000000000000000000000000000000000000000000000000046": "46", + "0x0000000000000000000000000000000000000000000000000000000000000050": "50", + "0x000000000000000000000000000000000000000000000000000000000000005a": "5a", + "0x0000000000000000000000000000000000000000000000000000000000000064": "64", + "0x000000000000000000000000000000000000000000000000000000000000006e": "6e", + "0x0000000000000000000000000000000000000000000000000000000000000078": "78", + "0x0000000000000000000000000000000000000000000000000000000000000082": "82", + "0x000000000000000000000000000000000000000000000000000000000000008c": "8c", + "0x0000000000000000000000000000000000000000000000000000000000000096": "96", + "0x00000000000000000000000000000000000000000000000000000000000000a0": "a0", + "0x00000000000000000000000000000000000000000000000000000000000000aa": "aa", + "0x00000000000000000000000000000000000000000000000000000000000000b4": "b4", + "0x00000000000000000000000000000000000000000000000000000000000000be": "be", + "0x00000000000000000000000000000000000000000000000000000000000000c8": "c8", + "0x00000000000000000000000000000000000000000000000000000000000000d2": "d2", + "0x00000000000000000000000000000000000000000000000000000000000000dc": "dc", + "0x00000000000000000000000000000000000000000000000000000000000000e6": "e6", + "0x00000000000000000000000000000000000000000000000000000000000000f0": "f0", + "0x00000000000000000000000000000000000000000000000000000000000000fa": "fa", + "0x0000000000000000000000000000000000000000000000000000000000000104": "0104", + "0x000000000000000000000000000000000000000000000000000000000000010e": "010e", + "0x0000000000000000000000000000000000000000000000000000000000000118": "0118", + "0x0000000000000000000000000000000000000000000000000000000000000122": "0122", + "0x000000000000000000000000000000000000000000000000000000000000012c": "012c", + "0x0000000000000000000000000000000000000000000000000000000000000136": "0136", + "0x0000000000000000000000000000000000000000000000000000000000000140": "0140", + "0x000000000000000000000000000000000000000000000000000000000000014a": "014a", + "0x0000000000000000000000000000000000000000000000000000000000000154": "0154", + "0x000000000000000000000000000000000000000000000000000000000000015e": "015e", + "0x0000000000000000000000000000000000000000000000000000000000000168": "0168", + "0x0000000000000000000000000000000000000000000000000000000000000172": "0172", + "0x000000000000000000000000000000000000000000000000000000000000017c": "017c", + "0x0000000000000000000000000000000000000000000000000000000000000186": "0186", + "0x0000000000000000000000000000000000000000000000000000000000000190": "0190", + "0x000000000000000000000000000000000000000000000000000000000000019a": "019a", + "0x00000000000000000000000000000000000000000000000000000000000001a4": "01a4", + "0x00000000000000000000000000000000000000000000000000000000000001ae": "01ae", + "0x00000000000000000000000000000000000000000000000000000000000001b8": "01b8", + "0x00000000000000000000000000000000000000000000000000000000000001c2": "01c2", + "0x00000000000000000000000000000000000000000000000000000000000001cc": "01cc", + "0x00000000000000000000000000000000000000000000000000000000000001d6": "01d6", + "0x00000000000000000000000000000000000000000000000000000000000001e0": "01e0", + "0x00000000000000000000000000000000000000000000000000000000000001ea": "01ea", + "0x00000000000000000000000000000000000000000000000000000000000001f4": "01f4", + "0x00000000000000000000000000000000000000000000000000000000000001fe": "01fe", + "0x0000000000000000000000000000000000000000000000000000000000000208": "0208", + "0x0000000000000000000000000000000000000000000000000000000000000212": "0212", + "0x000000000000000000000000000000000000000000000000000000000000021c": "021c", + "0x0000000000000000000000000000000000000000000000000000000000000226": "0226", + "0x0000000000000000000000000000000000000000000000000000000000000230": "0230", + "0x000000000000000000000000000000000000000000000000000000000000023a": "023a", + "0x0000000000000000000000000000000000000000000000000000000000000244": "0244", + "0x000000000000000000000000000000000000000000000000000000000000024e": "024e", + "0x0000000000000000000000000000000000000000000000000000000000000258": "0258", + "0x0000000000000000000000000000000000000000000000000000000000000262": "0262", + "0x000000000000000000000000000000000000000000000000000000000000026c": "026c", + "0x0000000000000000000000000000000000000000000000000000000000000276": "0276", + "0x0000000000000000000000000000000000000000000000000000000000000280": "0280", + "0x000000000000000000000000000000000000000000000000000000000000028a": "028a", + "0x0000000000000000000000000000000000000000000000000000000000000294": "0294", + "0x000000000000000000000000000000000000000000000000000000000000029e": "029e", + "0x00000000000000000000000000000000000000000000000000000000000002a8": "02a8", + "0x00000000000000000000000000000000000000000000000000000000000002b2": "02b2", + "0x00000000000000000000000000000000000000000000000000000000000002bc": "02bc", + "0x00000000000000000000000000000000000000000000000000000000000002c6": "02c6", + "0x00000000000000000000000000000000000000000000000000000000000002d0": "02d0", + "0x00000000000000000000000000000000000000000000000000000000000002da": "02da", + "0x00000000000000000000000000000000000000000000000000000000000002e4": "02e4", + "0x00000000000000000000000000000000000000000000000000000000000002ee": "02ee", + "0x00000000000000000000000000000000000000000000000000000000000002f8": "02f8", + "0x0000000000000000000000000000000000000000000000000000000000000302": "0302", + "0x000000000000000000000000000000000000000000000000000000000000030c": "030c", + "0x0000000000000000000000000000000000000000000000000000000000000316": "0316", + "0x0000000000000000000000000000000000000000000000000000000000000320": "0320", + "0x000000000000000000000000000000000000000000000000000000000000032a": "032a", + "0x0000000000000000000000000000000000000000000000000000000000000334": "0334", + "0x000000000000000000000000000000000000000000000000000000000000033e": "033e", "0x0000000000000000000000000000000000000000000000000000000000000348": "0348", "0x0000000000000000000000000000000000000000000000000000000000000352": "0352", "0x000000000000000000000000000000000000000000000000000000000000035c": "035c", @@ -432,3398 +1134,1469 @@ "0x0000000000000000000000000000000000000000000000000000000000001374": "1374", "0x000000000000000000000000000000000000000000000000000000000000137e": "137e", "0x0000000000000000000000000000000000000000000000000000000000001388": "1388", - "0x0000000000000000000000000000000000000000000000000000000000002347": "83472eda6eb475906aeeb7f09e757ba9f6663b9f6a5bf8611d6306f677f67ebd", - "0x0000000000000000000000000000000000000000000000000000000000002351": "2c809fbc7e3991c8ab560d1431fa8b6f25be4ab50977f0294dfeca9677866b6e", - "0x000000000000000000000000000000000000000000000000000000000000235b": "756e335a8778f6aadb2cc18c5bc68892da05a4d8b458eee5ce3335a024000c67", - "0x0000000000000000000000000000000000000000000000000000000000002365": "4b118bd31ed2c4eeb81dc9e3919e9989994333fe36f147c2930f12c53f0d3c78", - "0x000000000000000000000000000000000000000000000000000000000000236f": "d0122166752d729620d41114ff5a94d36e5d3e01b449c23844900c023d1650a5", - "0x0000000000000000000000000000000000000000000000000000000000002379": "60c606c4c44709ac87b367f42d2453744639fc5bee099a11f170de98408c8089", - "0x0000000000000000000000000000000000000000000000000000000000002383": "6ee04e1c27edad89a8e5a2253e4d9cca06e4f57d063ed4fe7cc1c478bb57eeca", - "0x000000000000000000000000000000000000000000000000000000000000238d": "36616354a17658eb3c3e8e5adda6253660e3744cb8b213006f04302b723749a8", - "0x0000000000000000000000000000000000000000000000000000000000002397": "c13802d4378dcb9c616f0c60ea0edd90e6c2dacf61f39ca06add0eaa67473b94", - "0x00000000000000000000000000000000000000000000000000000000000023a1": "8b345497936c51d077f414534be3f70472e4df101dee8820eaaff91a6624557b", - "0x00000000000000000000000000000000000000000000000000000000000023ab": "e958485d4b3e47b38014cc4eaeb75f13228072e7b362a56fc3ffe10155882629", - "0x00000000000000000000000000000000000000000000000000000000000023b5": "3346706b38a2331556153113383581bc6f66f209fdef502f9fc9b6daf6ea555e", - "0x00000000000000000000000000000000000000000000000000000000000023bf": "346910f7e777c596be32f0dcf46ccfda2efe8d6c5d3abbfe0f76dba7437f5dad", - "0x00000000000000000000000000000000000000000000000000000000000023c9": "e62a7bd9263534b752176d1ff1d428fcc370a3b176c4a6312b6016c2d5f8d546", - "0x00000000000000000000000000000000000000000000000000000000000023d3": "ffe267d11268388fd0426a627dedddeb075d68327df9172c0445cd2979ec7e4d", - "0x00000000000000000000000000000000000000000000000000000000000023dd": "23cc648c9cd82c08214882b7e28e026d6eb56920f90f64731bb09b6acf515427", - "0x00000000000000000000000000000000000000000000000000000000000023e7": "47c896f5986ec29f58ec60eec56ed176910779e9fc9cf45c3c090126aeb21acd", - "0x00000000000000000000000000000000000000000000000000000000000023f1": "6d19894928a3ab44077bb85dcb47e0865ce1c4c187bba26bad059aa774c03cfe", - "0x00000000000000000000000000000000000000000000000000000000000023fb": "efc50f4fc1430b6d5d043065201692a4a02252fef0699394631f5213a5667547", - "0x0000000000000000000000000000000000000000000000000000000000002405": "3cc9f65fc1f46927eb46fbf6d14bc94af078fe8ff982a984bdd117152cd1549f", - "0x000000000000000000000000000000000000000000000000000000000000240f": "63eb547e9325bc34fbbbdfda327a71dc929fd8ab6509795e56479e95dbd40a80", - "0x0000000000000000000000000000000000000000000000000000000000002419": "67317288cf707b0325748c7947e2dda5e8b41e45e62330d00d80e9be403e5c4c", - "0x0000000000000000000000000000000000000000000000000000000000002423": "7fc37e0d22626f96f345b05516c8a3676b9e1de01d354e5eb9524f6776966885", - "0x000000000000000000000000000000000000000000000000000000000000242d": "c8c5ffb6f192e9bda046ecd4ebb995af53c9dd6040f4ba8d8db9292c1310e43f", - "0x0000000000000000000000000000000000000000000000000000000000002437": "e40a9cfd9babe862d482ca0c07c0a4086641d16c066620cb048c6e673c5a4f91", - "0x0000000000000000000000000000000000000000000000000000000000002441": "e82e7cff48aea45fb3f7b199b0b173497bf4c5ea66ff840e2ec618d7eb3d7470", - "0x000000000000000000000000000000000000000000000000000000000000244b": "84ceda57767ea709da7ab17897a70da1868c9670931da38f2438519a5249534d", - "0x0000000000000000000000000000000000000000000000000000000000002455": "e9dcf640383969359c944cff24b75f71740627f596110ee8568fa09f9a06db1c", - "0x000000000000000000000000000000000000000000000000000000000000245f": "430ef678bb92f1af44dcd77af9c5b59fb87d0fc4a09901a54398ad5b7e19a8f4", - "0x0000000000000000000000000000000000000000000000000000000000002469": "f7af0b8b729cd17b7826259bc183b196dbd318bd7229d5e8085bf4849c0b12bf", - "0x0000000000000000000000000000000000000000000000000000000000002473": "e134e19217f1b4c7e11f193561056303a1f67b69dac96ff79a6d0aafa994f7cb", - "0x000000000000000000000000000000000000000000000000000000000000247d": "9cc58ab1a8cb0e983550e61f754aea1dd4f58ac6482a816dc50658de750de613", - "0x0000000000000000000000000000000000000000000000000000000000002487": "79c2b067779a94fd3756070885fc8eab5e45033bde69ab17c0173d553df02978", - "0x0000000000000000000000000000000000000000000000000000000000002491": "d908ef75d05b895600d3f9938cb5259612c71223b68d30469ff657d61c6b1611", - "0x000000000000000000000000000000000000000000000000000000000000249b": "e0d31906b7c46ac7f38478c0872d3c634f7113d54ef0b57ebfaf7f993959f5a3", - "0x00000000000000000000000000000000000000000000000000000000000024a5": "2318f5c5e6865200ad890e0a8db21c780a226bec0b2e29af1cb3a0d9b40196ae", - "0x00000000000000000000000000000000000000000000000000000000000024af": "523997f8d8fed954658f547954fdeceab818b411862647f2b61a3619f6a4d4bc", - "0x00000000000000000000000000000000000000000000000000000000000024b9": "be3396540ea36c6928cccdcfe6c669666edbbbcd4be5e703f59de0e3c2720da7", - "0x00000000000000000000000000000000000000000000000000000000000024c3": "2d3fcfd65d0a6881a2e8684d03c2aa27aee6176514d9f6d8ebb3b766f85e1039", - "0x00000000000000000000000000000000000000000000000000000000000024cd": "7ce0d5c253a7f910cca7416e949ac04fdaec20a518ab6fcbe4a63d8b439a5cfc", - "0x00000000000000000000000000000000000000000000000000000000000024d7": "4da13d835ea44926ee13f34ce8fcd4b9d3dc65be0a351115cf404234c7fbd256", - "0x00000000000000000000000000000000000000000000000000000000000024e1": "c5ee7483802009b45feabf4c5f701ec485f27bf7d2c4477b200ac53e210e9844", - "0x00000000000000000000000000000000000000000000000000000000000024eb": "0fc71295326a7ae8e0776c61be67f3ed8770311df88e186405b8d75bd0be552b", - "0x00000000000000000000000000000000000000000000000000000000000024f5": "7313b4315dd27586f940f8f2bf8af76825d8f24d2ae2c24d885dcb0cdd8d50f5", - "0x00000000000000000000000000000000000000000000000000000000000024ff": "2739473baa23a9bca4e8d0f4f221cfa48440b4b73e2bae7386c14caccc6c2059", - "0x0000000000000000000000000000000000000000000000000000000000002509": "d4da00e33a11ee18f67b25ad5ff574cddcdccaa30e6743e01a531336b16cbf8f", - "0x0000000000000000000000000000000000000000000000000000000000002513": "e651765d4860f0c46f191212c8193e7c82708e5d8bef1ed6f19bdde577f980cf", - "0x000000000000000000000000000000000000000000000000000000000000251d": "5b5b49487967b3b60bd859ba2fb13290c6eaf67e97e9f9f9dda935c08564b5f6", - "0x0000000000000000000000000000000000000000000000000000000000002527": "57b73780cc42a6a36676ce7008459d5ba206389dc9300f1aecbd77c4b90277fa", - "0x0000000000000000000000000000000000000000000000000000000000002531": "217e8514ea30f1431dc3cd006fe730df721f961cebb5d0b52069d1b4e1ae5d13", - "0x000000000000000000000000000000000000000000000000000000000000253b": "14b775119c252908bb10b13de9f8ae988302e1ea8b2e7a1b6d3c8ae24ba9396b", - "0x0000000000000000000000000000000000000000000000000000000000002545": "e736f0b3c5672f76332a38a6c1e66e5f39e0d01f1ddede2c24671f48e78daf63", - "0x000000000000000000000000000000000000000000000000000000000000254f": "7d112c85b58c64c576d34ea7a7c18287981885892fbf95110e62add156ca572e", - "0x0000000000000000000000000000000000000000000000000000000000002559": "28fbeedc649ed9d2a6feda6e5a2576949da6812235ebdfd030f8105d012f5074", - "0x0000000000000000000000000000000000000000000000000000000000002563": "6f7410cf59e390abe233de2a3e3fe022b63b78a92f6f4e3c54aced57b6c3daa6", - "0x000000000000000000000000000000000000000000000000000000000000256d": "d5edc3d8781deea3b577e772f51949a8866f2aa933149f622f05cde2ebba9adb", - "0x0000000000000000000000000000000000000000000000000000000000002577": "20308d99bc1e1b1b0717f32b9a3a869f4318f5f0eb4ed81fddd10696c9746c6b", - "0x0000000000000000000000000000000000000000000000000000000000002581": "91f7a302057a2e21d5e0ef4b8eea75dfb8b37f2c2db05c5a84517aaebc9d5131", - "0x000000000000000000000000000000000000000000000000000000000000258b": "743e5d0a5be47d489b121edb9f98dad7d0a85fc260909083656fabaf6d404774", - "0x0000000000000000000000000000000000000000000000000000000000002595": "cdcf99c6e2e7d0951f762e787bdbe0e2b3b320815c9d2be91e9cd0848653e839", - "0x000000000000000000000000000000000000000000000000000000000000259f": "cc9476183d27810e9738f382c7f2124976735ed89bbafc7dc19c99db8cfa9ad1", - "0x00000000000000000000000000000000000000000000000000000000000025a9": "f67e5fab2e7cacf5b89acd75ec53b0527d45435adddac6ee7523a345dcbcdceb", - "0x00000000000000000000000000000000000000000000000000000000000025b3": "e20f8ab522b2f0d12c068043852139965161851ad910b840db53604c8774a579", - "0x00000000000000000000000000000000000000000000000000000000000025bd": "f982160785861cb970559d980208dd00e6a2ec315f5857df175891b171438eeb", - "0x00000000000000000000000000000000000000000000000000000000000025c7": "230954c737211b72d5c7dcfe420bb07d5d72f2b4868c5976dd22c00d3df0c0b6", - "0x00000000000000000000000000000000000000000000000000000000000025d1": "b7743e65d6bbe09d5531f1bc98964f75943d8c13e27527ca6afd40ca069265d4", - "0x00000000000000000000000000000000000000000000000000000000000025db": "31ac943dc649c639fa6221400183ca827c07b812a6fbfc1795eb835aa280adf3", - "0x00000000000000000000000000000000000000000000000000000000000025e5": "ded49c937c48d466987a4130f4b6d04ef658029673c3afc99f70f33b552e178d", - "0x00000000000000000000000000000000000000000000000000000000000025ef": "a0effc449cab515020d2012897155a792bce529cbd8d5a4cf94d0bbf141afeb6", - "0x00000000000000000000000000000000000000000000000000000000000025f9": "1f36d9c66a0d437d8e49ffaeaa00f341e9630791b374e8bc0c16059c7445721f", - "0x0000000000000000000000000000000000000000000000000000000000002603": "34f89e6134f26e7110b47ffc942a847d8c03deeed1b33b9c041218c4e1a1a4e6", - "0x000000000000000000000000000000000000000000000000000000000000260d": "774404c430041ca4a58fdc281e99bf6fcb014973165370556d9e73fdec6d597b", - "0x0000000000000000000000000000000000000000000000000000000000002617": "d616971210c381584bf4846ab5837b53e062cbbb89d112c758b4bd00ce577f09", - "0x0000000000000000000000000000000000000000000000000000000000002621": "cdf6383634b0431468f6f5af19a2b7a087478b42489608c64555ea1ae0a7ee19", - "0x000000000000000000000000000000000000000000000000000000000000262b": "ec22e5df77320b4142c54fceaf2fe7ea30d1a72dc9c969a22acf66858d582b", - "0x0000000000000000000000000000000000000000000000000000000000002635": "cb32d77facfda4decff9e08df5a5810fa42585fdf96f0db9b63b196116fbb6af", - "0x000000000000000000000000000000000000000000000000000000000000263f": "6d76316f272f0212123d0b4b21d16835fe6f7a2b4d1960386d8a161da2b7c6a2", - "0x0000000000000000000000000000000000000000000000000000000000002649": "2de2da72ae329e359b655fc6311a707b06dc930126a27261b0e8ec803bdb5cbf", - "0x0000000000000000000000000000000000000000000000000000000000002653": "08bed4b39d14dc1e72e80f605573cde6145b12693204f9af18bbc94a82389500", - "0x000000000000000000000000000000000000000000000000000000000000265d": "e437f0465ac29b0e889ef4f577c939dd39363c08fcfc81ee61aa0b4f55805f69", - "0x0000000000000000000000000000000000000000000000000000000000002667": "89ca120183cc7085b6d4674d779fc4fbc9de520779bfbc3ebf65f9663cb88080", - "0x0000000000000000000000000000000000000000000000000000000000002671": "b15d5954c7b78ab09ede922684487c7a60368e82fdc7b5a0916842e58a44422b", - "0x000000000000000000000000000000000000000000000000000000000000267b": "ad13055a49d2b6a4ffc8b781998ff79086adad2fd6470a0563a43b740128c5f2", - "0x0000000000000000000000000000000000000000000000000000000000002685": "9e9909e4ed44f5539427ee3bc70ee8b630ccdaea4d0f1ed5337a067e8337119f", - "0x000000000000000000000000000000000000000000000000000000000000268f": "bf1f3aba184e08d4c650f05fe3d948bdda6c2d6982f277f2cd6b1a60cd4f3dac", - "0x0000000000000000000000000000000000000000000000000000000000002699": "bb70fe131f94783dba356c8d4d9d319247ef61c768134303f0db85ee3ef0496f", - "0x00000000000000000000000000000000000000000000000000000000000026a3": "6a81ebd3bde6cc54a2521aa72de29ef191e3b56d94953439a72cafdaa2996da0", - "0x00000000000000000000000000000000000000000000000000000000000026ad": "4c83e809a52ac52a587d94590c35c71b72742bd15915fca466a9aaec4f2dbfed", - "0x00000000000000000000000000000000000000000000000000000000000026b7": "268fc70790f00ad0759497585267fbdc92afba63ba01e211faae932f0639854a", - "0x00000000000000000000000000000000000000000000000000000000000026c1": "7e544f42df99d5666085b70bc57b3ca175be50b7a9643f26f464124df632d562", - "0x00000000000000000000000000000000000000000000000000000000000026cb": "d59cf5f55903ba577be835706b27d78a50cacb25271f35a5f57fcb88a3b576f3", - "0x00000000000000000000000000000000000000000000000000000000000026d5": "551cced461be11efdeaf8e47f3a91bb66d532af7294c4461c8009c5833bdbf57", - "0x00000000000000000000000000000000000000000000000000000000000026df": "c1e0e6907a57eefd12f1f95d28967146c836d72d281e7609de23d0a02351e978", - "0x00000000000000000000000000000000000000000000000000000000000026e9": "9d580c0ac3a7f00fdc3b135b758ae7c80ab135e907793fcf9621a3a3023ca205", - "0x00000000000000000000000000000000000000000000000000000000000026f3": "a7fd4dbac4bb62307ac7ad285ffa6a11ec679d950de2bd41839b8a846e239886", - "0x00000000000000000000000000000000000000000000000000000000000026fd": "6ba7b0ac30a04e11a3116b43700d91359e6b06a49058e543198d4b21e75fb165", - "0x0000000000000000000000000000000000000000000000000000000000002707": "8835104ed35ffd4db64660b9049e1c0328e502fd4f3744749e69183677b8474b", - "0x0000000000000000000000000000000000000000000000000000000000002711": "562f276b9f9ed46303e700c8863ad75fadff5fc8df27a90744ea04ad1fe8e801", - "0x000000000000000000000000000000000000000000000000000000000000271b": "d19f68026d22ae0f60215cfe4a160986c60378f554c763651d872ed82ad69ebb", - "0x0000000000000000000000000000000000000000000000000000000000002725": "f087a515b4b62d707991988eb912d082b85ecdd52effc9e8a1ddf15a74388860", - "0x000000000000000000000000000000000000000000000000000000000000272f": "f7e28b7daff5fad40ec1ef6a2b7e9066558126f62309a2ab0d0d775d892a06d6", - "0x0000000000000000000000000000000000000000000000000000000000002739": "77361844a8f4dd2451e6218d336378b837ba3fab921709708655e3f1ea91a435", - "0x0000000000000000000000000000000000000000000000000000000000002743": "e3cb33c7b05692a6f25470fbd63ab9c986970190729fab43191379da38bc0d8c", - "0x000000000000000000000000000000000000000000000000000000000000274d": "c893f9de119ec83fe37b178b5671d63448e9b5cde4de9a88cace3f52c2591194", - "0x0000000000000000000000000000000000000000000000000000000000002757": "39c96a6461782ac2efbcb5aaac2e133079b86fb29cb5ea69b0101bdad684ef0d", - "0x0000000000000000000000000000000000000000000000000000000000002761": "72a2724cdf77138638a109f691465e55d32759d3c044a6cb41ab091c574e3bdb", - "0x000000000000000000000000000000000000000000000000000000000000276b": "178ba15f24f0a8c33eed561d7927979c1215ddec20e1aef318db697ccfad0e03", - "0x0000000000000000000000000000000000000000000000000000000000002775": "f7b2c01b7c625588c9596972fdebae61db89f0d0f2b21286d4c0fa76683ff946", - "0x000000000000000000000000000000000000000000000000000000000000277f": "16e43284b041a4086ad1cbab9283d4ad3e8cc7c3a162f60b3df5538344ecdf54", - "0x0000000000000000000000000000000000000000000000000000000000002789": "0a98ea7f737e17706432eba283d50dde10891b49c3424d46918ed2b6af8ecf90", - "0x0000000000000000000000000000000000000000000000000000000000002793": "7637225dd61f90c3cb05fae157272985993b34d6c369bfe8372720339fe4ffd2", - "0x000000000000000000000000000000000000000000000000000000000000279d": "6a7d064bc053c0f437707df7c36b820cca4a2e9653dd1761941af4070f5273b6", - "0x00000000000000000000000000000000000000000000000000000000000027a7": "91c1e6eec8f7944fd6aafdce5477f45d4f6e29298c9ef628a59e441a5e071fae", - "0x00000000000000000000000000000000000000000000000000000000000027b1": "a1c227db9bbd2e49934bef01cbb506dd1e1c0671a81aabb1f90a90025980a3c3", - "0x00000000000000000000000000000000000000000000000000000000000027bb": "8fcfc1af10f3e8671505afadfd459287ae98be634083b5a35a400cc9186694cf", - "0x00000000000000000000000000000000000000000000000000000000000027c5": "cc1ea9c015bd3a6470669f85c5c13e42c1161fc79704143df347c4a621dff44f", - "0x00000000000000000000000000000000000000000000000000000000000027cf": "b0a22c625dd0c6534e29bccc9ebf94a550736e2c68140b9afe3ddc7216f797de", - "0x00000000000000000000000000000000000000000000000000000000000027d9": "92b8e6ca20622e5fd91a8f58d0d4faaf7be48a53ea262e963bcf26a1698f9df3", - "0x00000000000000000000000000000000000000000000000000000000000027e3": "f6253b8e2f31df6ca7a97086c3b4d49d9cbbbdfc5be731b0c3040a4381161c53", - "0x00000000000000000000000000000000000000000000000000000000000027ed": "ea8d762903bd24b80037d7ffe80019a086398608ead66208c18f0a5778620e67", - "0x00000000000000000000000000000000000000000000000000000000000027f7": "543382975e955588ba19809cfe126ea15dc43c0bfe6a43d861d7ad40eac2c2f4", - "0x0000000000000000000000000000000000000000000000000000000000002801": "095294f7fe3eb90cf23b3127d40842f61b85da2f48f71234fb94d957d865a8a2", - "0x000000000000000000000000000000000000000000000000000000000000280b": "144c2dd25fd12003ccd2678d69d30245b0222ce2d2bfead687931a7f6688482f", - "0x0000000000000000000000000000000000000000000000000000000000002815": "7295f7d57a3547b191f55951f548479cbb9a60b47ba38beb8d85c4ccf0e4ae4c", - "0x000000000000000000000000000000000000000000000000000000000000281f": "9e8e241e13f76a4e6d777a2dc64072de4737ac39272bb4987bcecbf60739ccf4", - "0x0000000000000000000000000000000000000000000000000000000000002829": "fc753bcea3e720490efded4853ef1a1924665883de46c21039ec43e371e96bb9", - "0x0000000000000000000000000000000000000000000000000000000000002833": "5f5204c264b5967682836ed773aee0ea209840fe628fd1c8d61702c416b427ca", - "0x000000000000000000000000000000000000000000000000000000000000283d": "5ba9a0326069e000b65b759236f46e54a0e052f379a876d242740c24f6c47aed", - "0x0000000000000000000000000000000000000000000000000000000000002847": "b40e9621d5634cd21f70274c345704af2e060c5befaeb2df109a78c7638167c2", - "0x0000000000000000000000000000000000000000000000000000000000002851": "70e26b74456e6fea452e04f8144be099b0af0e279febdff17dd4cdf9281e12a7", - "0x000000000000000000000000000000000000000000000000000000000000285b": "43d7158f48fb1f124b2962dff613c5b4b8ea415967f2b528af6e7ae280d658e5", - "0x0000000000000000000000000000000000000000000000000000000000002865": "b50b2b14efba477dddca9682df1eafc66a9811c9c5bd1ae796abbef27ba14eb4", - "0x000000000000000000000000000000000000000000000000000000000000286f": "c14936902147e9a121121f424ecd4d90313ce7fc603f3922cebb7d628ab2c8dd", - "0x0000000000000000000000000000000000000000000000000000000000002879": "86609ed192561602f181a9833573213eb7077ee69d65107fa94f657f33b144d2", - "0x0000000000000000000000000000000000000000000000000000000000002883": "0a71a6dbc360e176a0f665787ed3e092541c655024d0b136a04ceedf572c57c5", - "0x000000000000000000000000000000000000000000000000000000000000288d": "a4bcbab632ddd52cb85f039e48c111a521e8944b9bdbaf79dd7c80b20221e4d6", - "0x0000000000000000000000000000000000000000000000000000000000002897": "2bc468eab4fad397f9136f80179729b54caa2cb47c06b0695aab85cf9813620d", - "0x00000000000000000000000000000000000000000000000000000000000028a1": "fc7f9a432e6fd69aaf025f64a326ab7221311147dd99d558633579a4d8a0667b", - "0x00000000000000000000000000000000000000000000000000000000000028ab": "949613bd67fb0a68cf58a22e60e7b9b2ccbabb60d1d58c64c15e27a9dec2fb35", - "0x00000000000000000000000000000000000000000000000000000000000028b5": "289ddb1aee772ad60043ecf17a882c36a988101af91ac177954862e62012fc0e", - "0x00000000000000000000000000000000000000000000000000000000000028bf": "bfa48b05faa1a2ee14b3eaed0b75f0d265686b6ce3f2b7fa051b8dc98bc23d6a", - "0x00000000000000000000000000000000000000000000000000000000000028c9": "7bf49590a866893dc77444d89717942e09acc299eea972e8a7908e9d694a1150", - "0x00000000000000000000000000000000000000000000000000000000000028d3": "992f76aee242737eb21f14b65827f3ebc42524fb422b17f414f33c35a24092db", - "0x00000000000000000000000000000000000000000000000000000000000028dd": "da6e4f935d966e90dffc6ac0f6d137d9e9c97d65396627e5486d0089b94076fa", - "0x00000000000000000000000000000000000000000000000000000000000028e7": "65467514ed80f25b299dcf74fb74e21e9bb929832a349711cf327c2f8b60b57f", - "0x00000000000000000000000000000000000000000000000000000000000028f1": "cc2ac03d7a26ff16c990c5f67fa03dabda95641a988deec72ed2fe38c0f289d6", - "0x00000000000000000000000000000000000000000000000000000000000028fb": "096dbe9a0190c6badf79de3747abfd4d5eda3ab95b439922cae7ec0cfcd79290", - "0x0000000000000000000000000000000000000000000000000000000000002905": "0c659c769744094f60332ec247799d7ed5ae311d5738daa5dcead3f47ca7a8a2", - "0x000000000000000000000000000000000000000000000000000000000000290f": "9cb8a0d41ede6b951c29182422db215e22aedfa1a3549cd27b960a768f6ed522", - "0x0000000000000000000000000000000000000000000000000000000000002919": "2510f8256a020f4735e2be224e3bc3e8c14e56f7588315f069630fe24ce2fa26", - "0x0000000000000000000000000000000000000000000000000000000000002923": "2d3deb2385a2d230512707ece0bc6098ea788e3d5debb3911abe9a710dd332ea", - "0x000000000000000000000000000000000000000000000000000000000000292d": "1cec4b230f3bccfff7ca197c4a35cb5b95ff7785d064be3628235971b7aff27c", - "0x0000000000000000000000000000000000000000000000000000000000002937": "18e4a4238d43929180c7a626ae6f8c87a88d723b661549f2f76ff51726833598", - "0x0000000000000000000000000000000000000000000000000000000000002941": "700e1755641a437c8dc888df24a5d80f80f9eaa0d17ddab17db4eb364432a1f5", - "0x000000000000000000000000000000000000000000000000000000000000294b": "cad29ceb73b2f3c90d864a2c27a464b36b980458e2d8c4c7f32f70afad707312", - "0x0000000000000000000000000000000000000000000000000000000000002955": "a85e892063a7fd41d37142ae38037967eb047436c727fcf0bad813d316efe09f", - "0x000000000000000000000000000000000000000000000000000000000000295f": "040100f17208bcbd9456c62d98846859f7a5efa0e45a5b3a6f0b763b9c700fec", - "0x0000000000000000000000000000000000000000000000000000000000002969": "49d54a5147de1f5208c509b194af6d64b509398e4f255c20315131e921f7bd04", - "0x0000000000000000000000000000000000000000000000000000000000002973": "810ff6fcafb9373a4df3e91ab1ca64a2955c9e42ad8af964f829e38e0ea4ee20", - "0x000000000000000000000000000000000000000000000000000000000000297d": "9b72096b8b672ac6ff5362c56f5d06446d1693c5d2daa94a30755aa636320e78", - "0x0000000000000000000000000000000000000000000000000000000000002987": "f68bff777db51db5f29afc4afe38bd1bf5cdec29caa0dc52535b529e6d99b742", - "0x0000000000000000000000000000000000000000000000000000000000002991": "9566690bde717eec59f828a2dba90988fa268a98ed224f8bc02b77bce10443c4", - "0x000000000000000000000000000000000000000000000000000000000000299b": "d0e821fbd57a4d382edd638b5c1e6deefb81352d41aa97da52db13f330e03097", - "0x00000000000000000000000000000000000000000000000000000000000029a5": "43f9aa6fa63739abec56c4604874523ac6dabfcc08bb283195072aeb29d38dfe", - "0x00000000000000000000000000000000000000000000000000000000000029af": "54ebfa924e887a63d643a8277c3394317de0e02e63651b58b6eb0e90df8a20cd", - "0x00000000000000000000000000000000000000000000000000000000000029b9": "9e414c994ee35162d3b718c47f8435edc2c93394a378cb41037b671366791fc8", - "0x00000000000000000000000000000000000000000000000000000000000029c3": "4356f072bb235238abefb3330465814821097327842b6e0dc4a0ef95680c4d34", - "0x00000000000000000000000000000000000000000000000000000000000029cd": "215df775ab368f17ed3f42058861768a3fba25e8d832a00b88559ca5078b8fbc", - "0x00000000000000000000000000000000000000000000000000000000000029d7": "d17835a18d61605a04d2e50c4f023966a47036e5c59356a0463db90a76f06e3e", - "0x00000000000000000000000000000000000000000000000000000000000029e1": "875032d74e62dbfd73d4617754d36cd88088d1e5a7c5354bf3e0906c749e6637", - "0x00000000000000000000000000000000000000000000000000000000000029eb": "6f22ae25f70f4b03a2a2b17f370ace1f2b15d17fc7c2457824348a8f2a1eff9f", - "0x00000000000000000000000000000000000000000000000000000000000029f5": "f11fdf2cb985ce7472dc7c6b422c3a8bf2dfbbc6b86b15a1fa62cf9ebae8f6cf", - "0x00000000000000000000000000000000000000000000000000000000000029ff": "bbc97696e588f80fbe0316ad430fd4146a29c19b926248febe757cd9408deddc", - "0x0000000000000000000000000000000000000000000000000000000000002a09": "71dd15be02efd9f3d5d94d0ed9b5e60a205f439bb46abe6226879e857668881e", - "0x0000000000000000000000000000000000000000000000000000000000002a13": "b90e98bd91f1f7cc5c4456bb7a8868a2bb2cd3dda4b5dd6463b88728526dceea", - "0x0000000000000000000000000000000000000000000000000000000000002a1d": "4e80fd3123fda9b404a737c9210ccb0bacc95ef93ac40e06ce9f7511012426c4", - "0x0000000000000000000000000000000000000000000000000000000000002a27": "afb50d96b2543048dc93045b62357cc18b64d0e103756ce3ad0e04689dd88282", - "0x0000000000000000000000000000000000000000000000000000000000002a31": "d73341a1c9edd04a890f949ede6cc1e942ad62b63b6a60177f0f692f141a7e95", - "0x0000000000000000000000000000000000000000000000000000000000002a3b": "c26601e9613493118999d9268b401707e42496944ccdbfa91d5d7b791a6d18f1", - "0x0000000000000000000000000000000000000000000000000000000000002a45": "fb4619fb12e1b9c4b508797833eef7df65fcf255488660d502def2a7ddceef6d", - "0x0000000000000000000000000000000000000000000000000000000000002a4f": "d08b7458cd9d52905403f6f4e9dac15ad18bea1f834858bf48ecae36bf854f98", - "0x0000000000000000000000000000000000000000000000000000000000002a59": "df979da2784a3bb9e07c368094dc640aafc514502a62a58b464e50e5e50a34bd", - "0x0000000000000000000000000000000000000000000000000000000000002a63": "15855037d4712ce0019f0169dcd58b58493be8373d29decfa80b8df046e3d6ba", - "0x0000000000000000000000000000000000000000000000000000000000002a6d": "fd1462a68630956a33e4b65c8e171a08a131097bc7faf5d7f90b5503ab30b69c", - "0x0000000000000000000000000000000000000000000000000000000000002a77": "edad57fee633c4b696e519f84ad1765afbef5d2781b382acd9b8dfcf6cd6d572", - "0x0000000000000000000000000000000000000000000000000000000000002a81": "c2641ba296c2daa6edf09b63d0f1cfcefd51451fbbc283b6802cbd5392fb145c", - "0x0000000000000000000000000000000000000000000000000000000000002a8b": "5615d64e1d3a10972cdea4e4b106b4b6e832bc261129f9ab1d10a670383ae446", - "0x0000000000000000000000000000000000000000000000000000000000002a95": "0757c6141fad938002092ff251a64190b060d0e31c31b08fb56b0f993cc4ef0d", - "0x0000000000000000000000000000000000000000000000000000000000002a9f": "14ddc31bc9f9c877ae92ca1958e6f3affca7cc3064537d0bbe8ba4d2072c0961", - "0x0000000000000000000000000000000000000000000000000000000000002aa9": "490b0f08777ad4364f523f94dccb3f56f4aacb2fb4db1bb042a786ecfd248c79", - "0x0000000000000000000000000000000000000000000000000000000000002ab3": "4a37c0e55f539f2ecafa0ce71ee3d80bc9fe33fb841583073c9f524cc5a2615a", - "0x0000000000000000000000000000000000000000000000000000000000002abd": "133295fdf94e5e4570e27125807a77272f24622750bcf408be0360ba0dcc89f2", - "0x0000000000000000000000000000000000000000000000000000000000002ac7": "a73eb87c45c96b121f9ab081c095bff9a49cfe5a374f316e9a6a66096f532972", - "0x0000000000000000000000000000000000000000000000000000000000002ad1": "9040bc28f6e830ca50f459fc3dac39a6cd261ccc8cd1cca5429d59230c10f34c", - "0x0000000000000000000000000000000000000000000000000000000000002adb": "ec1d134c49cde6046ee295672a8f11663b6403fb71338181a89dc6bc92f7dea8", - "0x0000000000000000000000000000000000000000000000000000000000002ae5": "3130a4c80497c65a7ee6ac20f6888a95bd5b05636d6b4bd13d616dcb01591e16", - "0x0000000000000000000000000000000000000000000000000000000000002aef": "ccdfd5b42f2cbd29ab125769380fc1b18a9d272ac5d3508a6bbe4c82360ebcca", - "0x0000000000000000000000000000000000000000000000000000000000002af9": "74342c7f25ee7dd1ae6eb9cf4e5ce5bcab56c798aea36b554ccb31a660e123af", - "0x0000000000000000000000000000000000000000000000000000000000002b03": "f6f75f51a452481c30509e5de96edae82892a61f8c02c88d710dc782b5f01fc7", - "0x0000000000000000000000000000000000000000000000000000000000002b0d": "7ce6539cc82db9730b8c21b12d6773925ff7d1a46c9e8f6c986ada96351f36e9", - "0x0000000000000000000000000000000000000000000000000000000000002b17": "1983684da5e48936b761c5e5882bbeb5e42c3a7efe92989281367fa5ab25e918", - "0x0000000000000000000000000000000000000000000000000000000000002b21": "c564aa993f2b446325ee674146307601dd87eb7409266a97e695e4bb09dd8bf5", - "0x0000000000000000000000000000000000000000000000000000000000002b2b": "9ca2ff57d59decb7670d5f49bcca68fdaf494ba7dc06214d8e838bfcf7a2824e", - "0x0000000000000000000000000000000000000000000000000000000000002b35": "6d7b7476cecc036d470a691755f9988409059bd104579c0a2ded58f144236045", - "0x0000000000000000000000000000000000000000000000000000000000002b3f": "417504d79d00b85a29f58473a7ad643f88e9cdfe5da2ed25a5965411390fda4a", - "0x0000000000000000000000000000000000000000000000000000000000002b49": "e910eb040bf32e56e9447d63497799419957ed7df2572e89768b9139c6fa6a23", - "0x0000000000000000000000000000000000000000000000000000000000002b53": "8e462d3d5b17f0157bc100e785e1b8d2ad3262e6f27238fa7e9c62ba29e9c692", - "0x0000000000000000000000000000000000000000000000000000000000002b5d": "3e6f040dc96b2e05961c4e28df076fa654761f4b0e2e30f5e36b06f65d1893c1", - "0x0000000000000000000000000000000000000000000000000000000000002b67": "07e71d03691704a4bd83c728529642884fc1b1a8cfeb1ddcbf659c9b71367637", - "0x0000000000000000000000000000000000000000000000000000000000002b71": "f4d05f5986e4b92a845467d2ae6209ca9b7c6c63ff9cdef3df180660158163ef", - "0x0000000000000000000000000000000000000000000000000000000000002b7b": "5ca251408392b25af49419f1ecd9338d1f4b5afa536dc579ab54e1e3ee6914d4", - "0x0000000000000000000000000000000000000000000000000000000000002b85": "e98b64599520cf62e68ce0e2cdf03a21d3712c81fa74b5ade4885b7d8aec531b", - "0x0000000000000000000000000000000000000000000000000000000000002b8f": "d62ec5a2650450e26aac71a21d45ef795e57c231d28a18d077a01f761bc648fe", - "0x0000000000000000000000000000000000000000000000000000000000002b99": "4d3fb38cf24faf44f5b37f248553713af2aa9c3d99ddad4a534e49cd06bb8098", - "0x0000000000000000000000000000000000000000000000000000000000002ba3": "36e90abacae8fbe712658e705ac28fa9d00118ef55fe56ea893633680147148a", - "0x0000000000000000000000000000000000000000000000000000000000002bad": "164177f08412f7e294fae37457d238c4dd76775263e2c7c9f39e8a7ceca9028a", - "0x0000000000000000000000000000000000000000000000000000000000002bb7": "aa5a5586bf2f68df5c206dbe45a9498de0a9b5a2ee92235b740971819838a010", - "0x0000000000000000000000000000000000000000000000000000000000002bc1": "99d001850f513efdc613fb7c8ede12a943ff543c578a54bebbb16daecc56cec5", - "0x0000000000000000000000000000000000000000000000000000000000002bcb": "30a4501d58b23fc7eee5310f5262783b2dd36a94922d11e5e173ec763be8accb", - "0x0000000000000000000000000000000000000000000000000000000000002bd5": "a804188a0434260c0825a988483de064ae01d3e50cb111642c4cfb65bfc2dfb7", - "0x0000000000000000000000000000000000000000000000000000000000002bdf": "c554c79292c950bce95e9ef57136684fffb847188607705454909aa5790edc64", - "0x0000000000000000000000000000000000000000000000000000000000002be9": "c89e3673025beff5031d48a885098da23d716b743449fd5533a04f25bd2cd203", - "0x0000000000000000000000000000000000000000000000000000000000002bf3": "44c310142a326a3822abeb9161413f91010858432d27c9185c800c9c2d92aea6", - "0x0000000000000000000000000000000000000000000000000000000000002bfd": "ae3f497ee4bd619d651097d3e04f50caac1f6af55b31b4cbde4faf1c5ddc21e8", - "0x0000000000000000000000000000000000000000000000000000000000002c07": "3287d70a7b87db98964e828d5c45a4fa4cd7907be3538a5e990d7a3573ccb9c1", - "0x0000000000000000000000000000000000000000000000000000000000002c11": "b52bb578e25d833410fcca7aa6f35f79844537361a43192dce8dcbc72d15e09b", - "0x0000000000000000000000000000000000000000000000000000000000002c1b": "ff8f6f17c0f6d208d27dd8b9147586037086b70baf4f70c3629e73f8f053d34f", - "0x0000000000000000000000000000000000000000000000000000000000002c25": "70bccc358ad584aacb115076c8aded45961f41920ffedf69ffa0483e0e91fa52", - "0x0000000000000000000000000000000000000000000000000000000000002c2f": "e3881eba45a97335a6d450cc37e7f82b81d297c111569e38b6ba0c5fb0ae5d71", - "0x0000000000000000000000000000000000000000000000000000000000002c39": "2217beb48c71769d8bf9caaac2858237552fd68cd4ddefb66d04551e7beaa176", - "0x0000000000000000000000000000000000000000000000000000000000002c43": "06b56638d2545a02757e7f268b25a0cd3bce792fcb1e88da21b0cc21883b9720", - "0x0000000000000000000000000000000000000000000000000000000000002c4d": "ebdc8c9e2a85a1fb6582ca30616a685ec8ec25e9c020a65a85671e8b9dacc6eb", - "0x0000000000000000000000000000000000000000000000000000000000002c57": "738f3edb9d8d273aac79f95f3877fd885e1db732e86115fa3d0da18e6c89e9cf", - "0x0000000000000000000000000000000000000000000000000000000000002c61": "ae5ccfc8201288b0c5981cdb60e16bc832ac92edc51149bfe40ff4a935a0c13a", - "0x0000000000000000000000000000000000000000000000000000000000002c6b": "69a7a19c159c0534e50a98e460707c6c280e7e355fb97cf2b5e0fd56c45a0a97", - "0x0000000000000000000000000000000000000000000000000000000000002c75": "4d2a1e9207a1466593e5903c5481a579e38e247afe5e80bd41d629ac3342e6a4", - "0x0000000000000000000000000000000000000000000000000000000000002c7f": "d3e7d679c0d232629818cbb94251c24797ce36dd2a45dbe8c77a6a345231c3b3", - "0x0000000000000000000000000000000000000000000000000000000000002c89": "d1835b94166e1856dddb6eaa1cfdcc6979193f2ff4541ab274738bd48072899c", - "0x0000000000000000000000000000000000000000000000000000000000002c93": "1f12c89436a94d427a69bca5a080edc328bd2424896f3f37223186b440deb45e", - "0x0000000000000000000000000000000000000000000000000000000000002c9d": "ccb765890b7107fd98056a257381b6b1d10a83474bbf1bdf8e6b0b8eb9cef2a9", - "0x0000000000000000000000000000000000000000000000000000000000002ca7": "8bbf4e534dbf4580edc5a973194a725b7283f7b9fbb7d7d8deb386aaceebfa84", - "0x0000000000000000000000000000000000000000000000000000000000002cb1": "85a0516088f78d837352dcf12547ee3c598dda398e78a9f4d95acfbef19f5e19", - "0x0000000000000000000000000000000000000000000000000000000000002cbb": "0f669bc7780e2e5719f9c05872a112f6511e7f189a8649cda5d8dda88d6b8ac3", - "0x0000000000000000000000000000000000000000000000000000000000002cc5": "a7816288f9712fcab6a2b6fbd0b941b8f48c2acb635580ed80c27bed7e840a57", - "0x0000000000000000000000000000000000000000000000000000000000002ccf": "da5168c8c83ac67dfc2772af49d689f11974e960dee4c4351bac637db1a39e82", - "0x0000000000000000000000000000000000000000000000000000000000002cd9": "3f720ecec02446f1af948de4eb0f54775562f2d615726375c377114515ac545b", - "0x0000000000000000000000000000000000000000000000000000000000002ce3": "273830a0087f6cef0fdb42179aa1c6c8c19f7bc83c3dc7aa1a56e4e05ca473ea", - "0x0000000000000000000000000000000000000000000000000000000000002ced": "7044f700543fd542e87e7cdb94f0126b0f6ad9488d0874a8ac903a72bade34e9", - "0x0000000000000000000000000000000000000000000000000000000000002cf7": "f63a7ff76bb9713bea8d47831a1510d2c8971accd22a403d5bbfaaa3dc310616", - "0x0000000000000000000000000000000000000000000000000000000000002d01": "a68dbd9898dd1589501ca3220784c44d41852ad997a270e215539d461ec090f8", - "0x0000000000000000000000000000000000000000000000000000000000002d0b": "59e501ae3ba9e0c3adafdf0f696d2e6a358e1bec43cbe9b0258c2335dd8d764f", - "0x0000000000000000000000000000000000000000000000000000000000002d15": "4f19cff0003bdc03c2fee20db950f0efb323be170f0b09c491a20abcf26ecf43", - "0x0000000000000000000000000000000000000000000000000000000000002d1f": "52b1b89795a8fabd3c8594bd571b44fd72279979aaa1d49ea7105c787f8f5fa6", - "0x0000000000000000000000000000000000000000000000000000000000002d29": "7c1416bd4838b93bc87990c9dcca108675bafab950dd0faf111d9eddc4e54327", - "0x0000000000000000000000000000000000000000000000000000000000002d33": "ef87a35bb6e56e7d5a1f804c63c978bbd1c1516c4eb70edad2b8143169262c9f", - "0x0000000000000000000000000000000000000000000000000000000000002d3d": "e978f25d16f468c0a0b585994d1e912837f55e1cd8849e140f484a2702385ef2", - "0x0000000000000000000000000000000000000000000000000000000000002d47": "c3e85e9260b6fad139e3c42587cc2df7a9da07fadaacaf2381ca0d4a0c91c819", - "0x0000000000000000000000000000000000000000000000000000000000002d51": "bd2647c989abfd1d340fd05add92800064ad742cd82be8c2ec5cc7df20eb0351", - "0x0000000000000000000000000000000000000000000000000000000000002d5b": "99ac5ad7b62dd843abca85e485a6d4331e006ef9d391b0e89fb2eeccef1d29a2", - "0x0000000000000000000000000000000000000000000000000000000000002d65": "02a4349c3ee7403fe2f23cad9cf2fb6933b1ae37e34c9d414dc4f64516ea9f97", - "0x0000000000000000000000000000000000000000000000000000000000002d6f": "627b41fdbdf4a95381da5e5186123bf808c119b849dfdd3f515fa8d54c19c771", - "0x0000000000000000000000000000000000000000000000000000000000002d79": "c087b16d7caa58e1361a7b158159469975f55582a4ef760465703a40123226d7", - "0x0000000000000000000000000000000000000000000000000000000000002d83": "f7a477c0c27d4890e3fb56eb2dc0386e7409d1c59cab6c7f22b84de45b4c6867", - "0x0000000000000000000000000000000000000000000000000000000000002d8d": "1cb440b7d88e98ceb953bc46b003fde2150860be05e11b9a5abae2c814a71571", - "0x0000000000000000000000000000000000000000000000000000000000002d97": "72613e3e30445e37af38976f6bb3e3bf7debbcf70156eb37c5ac4e41834f9dd2", - "0x0000000000000000000000000000000000000000000000000000000000002da1": "e69e7568b9e70ee7e71ebad9548fc8afad5ff4435df5d55624b39df9e8826c91", - "0x0000000000000000000000000000000000000000000000000000000000002dab": "c3f1682f65ee45ce7019ee7059d65f8f1b0c0a8f68f94383410f7e6f46f26577", - "0x0000000000000000000000000000000000000000000000000000000000002db5": "93ee1e4480ed7935097467737e54c595a2a6424cf8eaed5eacc2bf23ce368192", - "0x0000000000000000000000000000000000000000000000000000000000002dbf": "b07f8855348b496166d3906437b8b76fdf7918f2e87858d8a78b1deece6e2558", - "0x0000000000000000000000000000000000000000000000000000000000002dc9": "ec60e51de32061c531b80d2c515bfa8f81600b9b50fc02beaf4dc01dd6e0c9ca", - "0x0000000000000000000000000000000000000000000000000000000000002dd3": "2fc9f34b3ed6b3cabd7b2b65b4a21381ad4419670eed745007f9efa8dd365ef1", - "0x0000000000000000000000000000000000000000000000000000000000002ddd": "f4af3b701f9b088d23f93bb6d5868370ed1cdcb19532ddd164ed3f411f3e5a95", - "0x0000000000000000000000000000000000000000000000000000000000002de7": "8272e509366a028b8d6bbae2a411eb3818b5be7dac69104a4e72317e55a9e697", - "0x0000000000000000000000000000000000000000000000000000000000002df1": "a194d76f417dafe27d02a6044a913c0b494fe893840b5b745386ae6078a44e9c", - "0x0000000000000000000000000000000000000000000000000000000000002dfb": "a255e59e9a27c16430219b18984594fc1edaf88fe47dd427911020fbc0d92507", - "0x0000000000000000000000000000000000000000000000000000000000002e05": "7996946b8891ebd0623c7887dd09f50a939f6f29dea4ca3c3630f50ec3c575cb", - "0x0000000000000000000000000000000000000000000000000000000000002e0f": "b04cbab069405f18839e6c6cf85cc19beeb9ee98c159510fcb67cb84652b7db9", - "0x0000000000000000000000000000000000000000000000000000000000002e19": "6f241a5e530d1e261ef0f5800d7ff252c33ce148865926e6231d4718f0b9eded", - "0x0000000000000000000000000000000000000000000000000000000000002e23": "fcfa9f1759f8db6a7e452af747a972cf3b1b493a216dbd32db21f7c2ce279cce", - "0x0000000000000000000000000000000000000000000000000000000000002e2d": "df880227742710ac4f31c0466a6da7c56ec54caccfdb8f58e5d3f72e40e800f3", - "0x0000000000000000000000000000000000000000000000000000000000002e37": "adfe28a0f8afc89c371dc7b724c78c2e3677904d03580c7141d32ba32f0ed46f", - "0x0000000000000000000000000000000000000000000000000000000000002e41": "b264d19d2daf7d5fcf8d2214eba0aacf72cabbc7a2617219e535242258d43a31", - "0x0000000000000000000000000000000000000000000000000000000000002e4b": "f2207420648dccc4f01992831e219c717076ff3c74fb88a96676bbcfe1e63f38", - "0x0000000000000000000000000000000000000000000000000000000000002e55": "41e8fae73b31870db8546eea6e11b792e0c9daf74d2fbb6471f4f6c6aaead362", - "0x0000000000000000000000000000000000000000000000000000000000002e5f": "4e7a5876c1ee2f1833267b5bd85ac35744a258cc3d7171a8a8cd5c87811078a2", - "0x0000000000000000000000000000000000000000000000000000000000002e69": "8d4a424d1a0ee910ccdfc38c7e7f421780c337232d061e3528e025d74b362315", - "0x0000000000000000000000000000000000000000000000000000000000002e73": "fa65829d54aba84896370599f041413d50f1acdc8a178211b2960827c1f85cbf", - "0x0000000000000000000000000000000000000000000000000000000000002e7d": "da5dfc12da14eafad2ac2a1456c241c4683c6e7e40a7c3569bc618cfc9d6dca3", - "0x0000000000000000000000000000000000000000000000000000000000002e87": "16243e7995312ffa3983c5858c6560b2abc637c481746003b6c2b58c62e9a547", - "0x0000000000000000000000000000000000000000000000000000000000002e91": "b75f0189b31abbbd88cd32c47ed311c93ec429f1253ee715a1b00d1ca6a1e094", - "0x0000000000000000000000000000000000000000000000000000000000002e9b": "d087eb94d6347da9322e3904add7ff7dd0fd72b924b917a8e10dae208251b49d", - "0x0000000000000000000000000000000000000000000000000000000000002ea5": "bc17244b8519292d8fbb455f6253e57ecc16b5803bd58f62b0d94da7f8b2a1d6", - "0x0000000000000000000000000000000000000000000000000000000000002eaf": "3ff8b39a3c6de6646124497b27e8d4e657d103c72f2001bdd4c554208a0566e3", - "0x0000000000000000000000000000000000000000000000000000000000002eb9": "4d0f765d2b6a01f0c787bbb13b1360c1624704883e2fd420ea36037fa7e3a563", - "0x0000000000000000000000000000000000000000000000000000000000002ec3": "f6f1dc891258163196785ce9516a14056cbe823b17eb9b90eeee7a299c1ce0e0", - "0x0000000000000000000000000000000000000000000000000000000000002ecd": "1dbf19b70c0298507d20fb338cc167d9b07b8747351785047e1a736b42d999d1", - "0x0000000000000000000000000000000000000000000000000000000000002ed7": "c3b71007b20abbe908fdb7ea11e3a3f0abff3b7c1ced865f82b07f100167de57", - "0x0000000000000000000000000000000000000000000000000000000000002ee1": "3f45edc424499d0d4bbc0fd5837d1790cb41c08f0269273fdf66d682429c25cc", - "0x0000000000000000000000000000000000000000000000000000000000002eeb": "cb8f5db9446c485eaae7edbc03e3afed72892fa7f11ad8eb7fa9dffbe3c220eb", - "0x0000000000000000000000000000000000000000000000000000000000002ef5": "3d151527b5ba165352a450bee69f0afc78cf2ea9645bb5d8f36fb04435f0b67c", - "0x0000000000000000000000000000000000000000000000000000000000002eff": "dd96b35b4ffabce80d377420a0b00b7fbf0eff6a910210155d22d9bd981be5d3", - "0x0000000000000000000000000000000000000000000000000000000000002f09": "ace0c30b543d3f92f37eaac45d6f8730fb15fcaaaad4097ea42218abe57cb9f4", - "0x0000000000000000000000000000000000000000000000000000000000002f13": "f6342dd31867c9bef6ffa06b6cf192db23d0891ed8fe610eb8d1aaa79726da01", - "0x0000000000000000000000000000000000000000000000000000000000002f1d": "a6589e823979c2c2ac55e034d547b0c63aa02109133575d9f159e8a7677f03cb", - "0x0000000000000000000000000000000000000000000000000000000000002f27": "9ce48bc641cc1d54ffdb409aab7da1304d5ee08042596b3542ca9737bb2b79a8", - "0x0000000000000000000000000000000000000000000000000000000000002f31": "a44be801bd978629775c00d70df6d70b76d0ba918595e81415a27d1e3d6fdee9", - "0x0000000000000000000000000000000000000000000000000000000000002f3b": "ce17f1e7af9f7ea8a99b2780d87b15d8b80a68fb29ea52f962b00fecfc6634e0", - "0x0000000000000000000000000000000000000000000000000000000000002f45": "4bd91febab8df3770c957560e6185e8af59d2a42078756c525cd7769eb943894", - "0x0000000000000000000000000000000000000000000000000000000000002f4f": "414c2a52de31de93a3c69531247b016ac578435243073acc516d4ea673c8dd80", - "0x0000000000000000000000000000000000000000000000000000000000002f59": "647fb60bdf2683bd46b63d6884745782364a5522282ed1dc67d9e17c4aaab17d", - "0x0000000000000000000000000000000000000000000000000000000000002f63": "fa681ffd0b0dd6f6775e99a681241b86a3a24446bc8a69cdae915701243e3855", - "0x0000000000000000000000000000000000000000000000000000000000002f6d": "106ca692777b30cb2aa23ca59f5591514b28196ee8e9b06aa2b4deaea30d9ef6", - "0x0000000000000000000000000000000000000000000000000000000000002f77": "494ac6d09377eb6a07ff759df61c2508e65e5671373d756c82e648bd9086d91a", - "0x0000000000000000000000000000000000000000000000000000000000002f81": "0ae4ccd2bffa603714cc453bfd92f769dce6c9731c03ac3e2083f35388e6c795", - "0x0000000000000000000000000000000000000000000000000000000000002f8b": "d860c999490d9836cc00326207393c78445b7fb90b12aa1d3607e3662b3d32cd", - "0x0000000000000000000000000000000000000000000000000000000000002f95": "9587384f876dfec24da857c0bcdb3ded17f3328f28a4d59aa35ca7c25c8102cf", - "0x0000000000000000000000000000000000000000000000000000000000002f9f": "4df8093d29bc0ec4e2a82be427771e77a206566194734a73c23477e1a9e451f8", - "0x0000000000000000000000000000000000000000000000000000000000002fa9": "c56640f78acbd1da07701c365369766f09a19800ba70276f1f1d3cd1cf6e0686", - "0x0000000000000000000000000000000000000000000000000000000000002fb3": "7173d4210aa525eece6b4b19b16bab23686ff9ac71bb9d16008bb114365e79f2", - "0x0000000000000000000000000000000000000000000000000000000000002fbd": "89698b41d7ac70e767976a9f72ae6a46701456bc5ad8d146c248548409c90015", - "0x0000000000000000000000000000000000000000000000000000000000002fc7": "5b605ab5048d9e4a51ca181ac3fa7001ef5d415cb20335b095c54a40c621dbff", - "0x0000000000000000000000000000000000000000000000000000000000002fd1": "9129a84b729e7f69a5522a7020db57e27bf8cbb6042e030106c0cbd185bf0ab8", - "0x0000000000000000000000000000000000000000000000000000000000002fdb": "31a63d6d54153ab35fc57068db205a3e68908be238658ca82d8bee9873f82159", - "0x0000000000000000000000000000000000000000000000000000000000002fe5": "828641bcea1bc6ee1329bc39dca0afddc11e6867f3da13d4bb5170c54158860d", - "0x0000000000000000000000000000000000000000000000000000000000002fef": "7e0752ddd86339f512ec1b647d3bf4b9b50c45e309ab9e70911da7716454b053", - "0x0000000000000000000000000000000000000000000000000000000000002ff9": "31d973051189456d5998e05b500da6552138644f8cdbe4ec63f96f21173cb6a1", - "0x0000000000000000000000000000000000000000000000000000000000003003": "e33e65b3d29c3b55b2d7b584c5d0540eb5c00c9f157287863b0b619339c302f0", - "0x000000000000000000000000000000000000000000000000000000000000300d": "78d55514bcef24b40c7eb0fbe55f922d4468c194f313898f28ba85d8534df82c", - "0x0000000000000000000000000000000000000000000000000000000000003017": "2e0f4be4d8adf8690fd64deddbc543f35c5b4f3c3a27b10a77b1fdb8d590f1ee", - "0x0000000000000000000000000000000000000000000000000000000000003021": "e1b83ea8c4329f421296387826c89100d82bdc2263ffd8eb9368806a55d9b83b", - "0x000000000000000000000000000000000000000000000000000000000000302b": "4ddad36d7262dd9201c5bdd58523f4724e3b740fddbed2185e32687fecacdf6b", - "0x0000000000000000000000000000000000000000000000000000000000003035": "156c0674e46cdec70505443c5269d42c7bb14ee6c00f86a23962f08906cbb846", - "0x000000000000000000000000000000000000000000000000000000000000303f": "dfc56ec6c218a08b471d757e0e7de8dddec9e82f401cb7d77df1f2a9ca54c607", - "0x0000000000000000000000000000000000000000000000000000000000003049": "395d660f77c4360705cdc0be895907ec183097f749fac18b6eaa0245c1009074", - "0x0000000000000000000000000000000000000000000000000000000000003053": "84c0060087da2c95dbd517d0f2dd4dfba70691a5952fe4048c310e88e9c06e4f", - "0x000000000000000000000000000000000000000000000000000000000000305d": "f4df943c52b1d5fb9c1f73294ca743577d83914ec26d6e339b272cdeb62de586", - "0x0000000000000000000000000000000000000000000000000000000000003067": "0bb47661741695863ef89d5c2b56666772f871be1cc1dccf695bd357e4bb26d6", - "0x0000000000000000000000000000000000000000000000000000000000003071": "4a1f7691f29900287c6931545884881143ecae44cb26fdd644892844fde65dac", - "0x000000000000000000000000000000000000000000000000000000000000307b": "9b133cc50cbc46d55ce2910eebaf8a09ab6d4e606062c94aac906da1646bc33f", - "0x0000000000000000000000000000000000000000000000000000000000003085": "473b076b542da72798f9de31c282cb1dcd76cba2a22adc7391670ffdbc910766", - "0x000000000000000000000000000000000000000000000000000000000000308f": "225dd472ef6b36a51de5c322a31a9f71c80f0f350432884526d9844bb2e676d3", - "0x0000000000000000000000000000000000000000000000000000000000003099": "31df97b2c9fc65b5520b89540a42050212e487f46fac67685868f1c3e652a9aa", - "0x00000000000000000000000000000000000000000000000000000000000030a3": "4416d885f34ad479409bb9e05e8846456a9be7e74655b9a4d7568a8d710aa06a", - "0x00000000000000000000000000000000000000000000000000000000000030ad": "ae627f8802a46c1357fa42a8290fd1366ea21b8ccec1cc624e42022647c53802", - "0x00000000000000000000000000000000000000000000000000000000000030b7": "8961e8b83d91487fc32b3d6af26b1d5e7b4010dd8d028fe165187cdfb04e151c", - "0x00000000000000000000000000000000000000000000000000000000000030c1": "c22e39f021605c6f3d967aef37f0bf40b09d776bac3edb4264d0dc07389b9845", - "0x00000000000000000000000000000000000000000000000000000000000030cb": "7cfa4c7066c690c12b9e8727551bef5fe05b750ac6637a5af632fce4ceb4e2ce", - "0x00000000000000000000000000000000000000000000000000000000000030d5": "943d79e4329b86f8e53e8058961955f2b0a205fc3edeea2aae54ba0c22b40c31", - "0x00000000000000000000000000000000000000000000000000000000000030df": "66598070dab784e48a153bf9c6c3e57d8ca92bed6592f0b9e9abe308a17aedf0", - "0x00000000000000000000000000000000000000000000000000000000000030e9": "ac8fe4eb91577288510a9bdae0d5a8c40b8225172379cd70988465d8b98cfa70", - "0x00000000000000000000000000000000000000000000000000000000000030f3": "2b0018a8548e5ce2a6b6b879f56e3236cc69d2efff80f48add54efd53681dfce", - "0x00000000000000000000000000000000000000000000000000000000000030fd": "823445936237e14452e253a6692290c1be2e1be529ddbeecc35c9f54f7ea9887", - "0x0000000000000000000000000000000000000000000000000000000000003107": "3051a0d0701d233836b2c802060d6ee629816c856a25a62dc73bb2f2fc93b918", - "0x0000000000000000000000000000000000000000000000000000000000003111": "44a50fda08d2f7ca96034186475a285a8a570f42891f72d256a52849cb188c85", - "0x000000000000000000000000000000000000000000000000000000000000311b": "6e60069a12990ef960c0ac825fd0d9eb44aec9eb419d0df0c25d7a1d16c282e7", - "0x0000000000000000000000000000000000000000000000000000000000003125": "581ddf7753c91af00c894f8d5ab22b4733cfeb4e75c763725ebf46fb889fa76a", - "0x000000000000000000000000000000000000000000000000000000000000312f": "9a1dfba8b68440fcc9e89b86e2e290367c5e5fb0833b34612d1f4cfc53189526", - "0x0000000000000000000000000000000000000000000000000000000000003139": "54a623060b74d56f3c0d6793e40a9269c56f90bcd19898855113e5f9e42abc2d", - "0x0000000000000000000000000000000000000000000000000000000000003143": "1cfeb8cd5d56e1d202b4ec2851f22e99d6ad89af8a4e001eb014b724d2d64924", - "0x000000000000000000000000000000000000000000000000000000000000314d": "ad223cbf591f71ffd29e2f1c676428643313e3a8e8a7d0b0e623181b3047be92", - "0x0000000000000000000000000000000000000000000000000000000000003157": "e13f31f026d42cad54958ad2941f133d8bd85ee159f364a633a79472f7843b67", - "0x0000000000000000000000000000000000000000000000000000000000003161": "b45099ae3bbe17f4417d7d42951bd4425bce65f1db69a354a64fead61b56306d", - "0x000000000000000000000000000000000000000000000000000000000000316b": "9d2b65379c5561a607df4dae8b36eca78818acec4455eb47cfa437a0b1941707", - "0x0000000000000000000000000000000000000000000000000000000000003175": "5855b3546d3becda6d5dd78c6440f879340a5734a18b06340576a3ce6a48d9a0", - "0x000000000000000000000000000000000000000000000000000000000000317f": "d6a61c76ae029bb5bca86d68422c55e8241d9fd9b616556b375c91fb7224b79e", - "0x0000000000000000000000000000000000000000000000000000000000003189": "96ac5006561083735919ae3cc8d0762a9cba2bdefd4a73b8e69f447f689fba31", - "0x0000000000000000000000000000000000000000000000000000000000003193": "4ced18f55676b924d39aa7bcd7170bac6ff4fbf00f6a800d1489924c2a091412", - "0x000000000000000000000000000000000000000000000000000000000000319d": "c95a6a7efdbefa710a525085bcb57ea2bf2d4ae9ebfcee4be3777cfcc3e534ea", - "0x00000000000000000000000000000000000000000000000000000000000031a7": "2b2917b5b755eb6af226e16781382bd22a907c9c7411c34a248af2b5a0439079", - "0x00000000000000000000000000000000000000000000000000000000000031b1": "18d5804f2e9ad3f891ecf05e0bfc2142c2a9f7b4de03aebd1cf18067a1ec6490", - "0x00000000000000000000000000000000000000000000000000000000000031bb": "b47682f0ce3783700cbe5ffbb95d22c943cc74af12b9c79908c5a43f10677478", - "0x00000000000000000000000000000000000000000000000000000000000031c5": "e4b60e5cfb31d238ec412b0d0e3ad9e1eb00e029c2ded4fea89288f900f7db0e", - "0x00000000000000000000000000000000000000000000000000000000000031cf": "fc0ea3604298899c10287bba84c02b9ec5d6289c1493e9fc8d58920e4eaef659", - "0x00000000000000000000000000000000000000000000000000000000000031d9": "4c3301a70611b34e423cf713bda7f6f75bd2070f909681d3e54e3a9a6d202e5a", - "0x00000000000000000000000000000000000000000000000000000000000031e3": "84a5b4e32a62bf3298d846e64b3896dffbbcc1fafb236df3a047b5223577d07b", - "0x00000000000000000000000000000000000000000000000000000000000031ed": "ff70b97d34af8e2ae984ada7bc6f21ed294d9b392a903ad8bbb1be8b44083612", - "0x00000000000000000000000000000000000000000000000000000000000031f7": "73e186de72ef30e4be4aeebe3eaec84222f8a325d2d07cd0bd1a49f3939915ce", - "0x0000000000000000000000000000000000000000000000000000000000003201": "ed185ec518c0459392b274a3d10554e452577d33ecb72910f613941873e61215", - "0x000000000000000000000000000000000000000000000000000000000000320b": "5cfbad3e509733bce64e0f6492b3886300758c47a38e9edec4b279074c7966d4", - "0x0000000000000000000000000000000000000000000000000000000000003215": "867a7ab4c504e836dd175bd6a00e8489f36edaeda95db9ce4acbf9fb8df28926", - "0x000000000000000000000000000000000000000000000000000000000000321f": "0d01993fd605f101c950c68b4cc2b8096ef7d0009395dec6129f86f195eb2217", - "0x0000000000000000000000000000000000000000000000000000000000003229": "8e14fd675e72f78bca934e1ffad52b46fd26913063e7e937bce3fa11aed29075", - "0x0000000000000000000000000000000000000000000000000000000000003233": "4ec1847e4361c22cdecc67633e244b9e6d04ec103f4019137f9ba1ecc90198f4", - "0x000000000000000000000000000000000000000000000000000000000000323d": "ec69e9bbb0184bf0889df50ec7579fa4029651658d639af456a1f6a7543930ef", - "0x0000000000000000000000000000000000000000000000000000000000003247": "efdd626048ad0aa6fcf806c7c2ad7b9ae138136f10a3c2001dc5b6c920db1554", - "0x0000000000000000000000000000000000000000000000000000000000003251": "551de1e4cafd706535d77625558f8d3898173273b4353143e5e1c7e859848d6b", - "0x000000000000000000000000000000000000000000000000000000000000325b": "137efe559a31d9c5468259102cd8634bba72b0d7a0c7d5bcfc449c5f4bdb997a", - "0x0000000000000000000000000000000000000000000000000000000000003265": "fb0a1b66acf5f6bc2393564580d74637945891687e61535aae345dca0b0f5e78", - "0x000000000000000000000000000000000000000000000000000000000000326f": "96eea2615f9111ee8386319943898f15c50c0120b8f3263fab029123c5fff80c", - "0x0000000000000000000000000000000000000000000000000000000000003279": "68725bebed18cd052386fd6af9b398438c01356223c5cc15f49093b92b673eff", - "0x0000000000000000000000000000000000000000000000000000000000003283": "e2f1e4557ed105cf3bd8bc51ebaa4446f554dcb38c005619bd9f203f4494f5dd", - "0x000000000000000000000000000000000000000000000000000000000000328d": "48ef06d84d5ad34fe56ce62e095a34ea4a903bf597a8640868706af7b4de7288", - "0x0000000000000000000000000000000000000000000000000000000000003297": "5c57714b2a85d0d9331ce1ee539a231b33406ec19adcf1d8f4c88ab8c1f4fbae", - "0x00000000000000000000000000000000000000000000000000000000000032a1": "204299e7aa8dfe5328a0b863b20b6b4cea53a469d6dc8d4b31c7873848a93f33", - "0x00000000000000000000000000000000000000000000000000000000000032ab": "b74eea6df3ce54ee9f069bebb188f4023673f8230081811ab78ce1c9719879e5", - "0x00000000000000000000000000000000000000000000000000000000000032b5": "af5624a3927117b6f1055893330bdf07a64e96041241d3731b9315b5cd6d14d7", - "0x00000000000000000000000000000000000000000000000000000000000032bf": "c657b0e79c166b6fdb87c67c7fe2b085f52d12c6843b7d6090e8f230d8306cda", - "0x00000000000000000000000000000000000000000000000000000000000032c9": "a0e08ceff3f3c426ab2c30881eff2c2fc1edf04b28e1fb38e622648224ffbc6b", - "0x00000000000000000000000000000000000000000000000000000000000032d3": "c9792da588df98731dfcbf54a6264082e791540265acc2b3ccca5cbd5c0c16de", - "0x00000000000000000000000000000000000000000000000000000000000032dd": "c74f4bb0f324f42c06e7aeacb9446cd5ea500c3b014d5888d467610eafb69297", - "0x00000000000000000000000000000000000000000000000000000000000032e7": "1acd960a8e1dc68da5b1db467e80301438300e720a450ab371483252529a409b", - "0x00000000000000000000000000000000000000000000000000000000000032f1": "6cef279ba63cbac953676e889e4fe1b040994f044078196a6ec4e6d868b79aa1", - "0x00000000000000000000000000000000000000000000000000000000000032fb": "60eb986cb497a0642b684852f009a1da143adb3128764b772daf51f6efaae90a", - "0x0000000000000000000000000000000000000000000000000000000000003305": "c50024557485d98123c9d0e728db4fc392091f366e1639e752dd677901681acc", - "0x000000000000000000000000000000000000000000000000000000000000330f": "b860632e22f3e4feb0fdf969b4241442eae0ccf08f345a1cc4bb62076a92d93f", - "0x0000000000000000000000000000000000000000000000000000000000003319": "21085bf2d264529bd68f206abc87ac741a2b796919eeee6292ed043e36d23edb", - "0x0000000000000000000000000000000000000000000000000000000000003323": "80052afb1f39f11c67be59aef7fe6551a74f6b7d155a73e3d91b3a18392120a7", - "0x000000000000000000000000000000000000000000000000000000000000332d": "a3b0793132ed37459f24d6376ecfa8827c4b1d42afcd0a8c60f9066f230d7675", - "0x0000000000000000000000000000000000000000000000000000000000003337": "e69d353f4bc38681b4be8cd5bbce5eb4e819399688b0b6225b95384b08dcc8b0", - "0x0000000000000000000000000000000000000000000000000000000000003341": "221e784d42a121cd1d13d111128fcae99330408511609ca8b987cc6eecafefc4", - "0x000000000000000000000000000000000000000000000000000000000000334b": "dcd669ebef3fb5bebc952ce1c87ae4033b13f37d99cf887022428d024f3a3d2e", - "0x0000000000000000000000000000000000000000000000000000000000003355": "4dd1eb9319d86a31fd56007317e059808f7a76eead67aecc1f80597344975f46", - "0x000000000000000000000000000000000000000000000000000000000000335f": "5e1834c653d853d146db4ab6d17509579497c5f4c2f9004598bcd83172f07a5f", - "0x0000000000000000000000000000000000000000000000000000000000003369": "9f78a30e124d21168645b9196d752a63166a1cf7bbbb9342d0b8fee3363ca8de", - "0x0000000000000000000000000000000000000000000000000000000000003373": "1f7c1081e4c48cef7d3cb5fd64b05135775f533ae4dabb934ed198c7e97e7dd8", - "0x000000000000000000000000000000000000000000000000000000000000337d": "4d40a7ec354a68cf405cc57404d76de768ad71446e8951da553c91b06c7c2d51", - "0x0000000000000000000000000000000000000000000000000000000000003387": "f653da50cdff4733f13f7a5e338290e883bdf04adf3f112709728063ea965d6c" + "0x0000000000000000000000000000000000000000000000000000000000001392": "1392", + "0x000000000000000000000000000000000000000000000000000000000000139c": "139c", + "0x00000000000000000000000000000000000000000000000000000000000013a6": "13a6", + "0x00000000000000000000000000000000000000000000000000000000000013b0": "13b0", + "0x00000000000000000000000000000000000000000000000000000000000013ba": "13ba", + "0x00000000000000000000000000000000000000000000000000000000000013c4": "13c4", + "0x00000000000000000000000000000000000000000000000000000000000013ce": "13ce", + "0x00000000000000000000000000000000000000000000000000000000000013d8": "13d8", + "0x00000000000000000000000000000000000000000000000000000000000013e2": "13e2", + "0x00000000000000000000000000000000000000000000000000000000000013ec": "13ec", + "0x00000000000000000000000000000000000000000000000000000000000013f6": "13f6", + "0x0000000000000000000000000000000000000000000000000000000000001400": "1400", + "0x000000000000000000000000000000000000000000000000000000000000140a": "140a", + "0x0000000000000000000000000000000000000000000000000000000000001414": "1414", + "0x000000000000000000000000000000000000000000000000000000000000141e": "141e", + "0x0000000000000000000000000000000000000000000000000000000000001428": "1428", + "0x0000000000000000000000000000000000000000000000000000000000001432": "1432", + "0x000000000000000000000000000000000000000000000000000000000000143c": "143c", + "0x0000000000000000000000000000000000000000000000000000000000001446": "1446", + "0x0000000000000000000000000000000000000000000000000000000000001450": "1450", + "0x000000000000000000000000000000000000000000000000000000000000145a": "145a", + "0x0000000000000000000000000000000000000000000000000000000000001464": "1464", + "0x000000000000000000000000000000000000000000000000000000000000146e": "146e", + "0x0000000000000000000000000000000000000000000000000000000000001478": "1478", + "0x0000000000000000000000000000000000000000000000000000000000001482": "1482", + "0x000000000000000000000000000000000000000000000000000000000000148c": "148c", + "0x0000000000000000000000000000000000000000000000000000000000001496": "1496", + "0x00000000000000000000000000000000000000000000000000000000000014a0": "14a0", + "0x00000000000000000000000000000000000000000000000000000000000014aa": "14aa", + "0x00000000000000000000000000000000000000000000000000000000000014b4": "14b4", + "0x00000000000000000000000000000000000000000000000000000000000014be": "14be", + "0x00000000000000000000000000000000000000000000000000000000000014c8": "14c8", + "0x00000000000000000000000000000000000000000000000000000000000014d2": "14d2", + "0x00000000000000000000000000000000000000000000000000000000000014dc": "14dc", + "0x00000000000000000000000000000000000000000000000000000000000014e6": "14e6", + "0x00000000000000000000000000000000000000000000000000000000000014f0": "14f0", + "0x00000000000000000000000000000000000000000000000000000000000014fa": "14fa", + "0x0000000000000000000000000000000000000000000000000000000000001504": "1504", + "0x000000000000000000000000000000000000000000000000000000000000150e": "150e", + "0x0000000000000000000000000000000000000000000000000000000000001518": "1518", + "0x0000000000000000000000000000000000000000000000000000000000001522": "1522", + "0x000000000000000000000000000000000000000000000000000000000000152c": "152c", + "0x0000000000000000000000000000000000000000000000000000000000001536": "1536", + "0x0000000000000000000000000000000000000000000000000000000000001540": "1540", + "0x000000000000000000000000000000000000000000000000000000000000154a": "154a", + "0x0000000000000000000000000000000000000000000000000000000000001554": "1554", + "0x000000000000000000000000000000000000000000000000000000000000155e": "155e", + "0x0000000000000000000000000000000000000000000000000000000000001568": "1568", + "0x0000000000000000000000000000000000000000000000000000000000001572": "1572", + "0x000000000000000000000000000000000000000000000000000000000000157c": "157c", + "0x0000000000000000000000000000000000000000000000000000000000001586": "1586", + "0x0000000000000000000000000000000000000000000000000000000000001590": "1590", + "0x000000000000000000000000000000000000000000000000000000000000159a": "159a", + "0x00000000000000000000000000000000000000000000000000000000000015a4": "15a4", + "0x00000000000000000000000000000000000000000000000000000000000015ae": "15ae", + "0x00000000000000000000000000000000000000000000000000000000000015b8": "15b8", + "0x00000000000000000000000000000000000000000000000000000000000015c2": "15c2", + "0x00000000000000000000000000000000000000000000000000000000000015cc": "15cc", + "0x00000000000000000000000000000000000000000000000000000000000015d6": "15d6", + "0x00000000000000000000000000000000000000000000000000000000000015e0": "15e0", + "0x00000000000000000000000000000000000000000000000000000000000015ea": "15ea", + "0x00000000000000000000000000000000000000000000000000000000000015f4": "15f4", + "0x00000000000000000000000000000000000000000000000000000000000015fe": "15fe", + "0x0000000000000000000000000000000000000000000000000000000000001608": "1608", + "0x0000000000000000000000000000000000000000000000000000000000001612": "1612", + "0x000000000000000000000000000000000000000000000000000000000000161c": "161c", + "0x0000000000000000000000000000000000000000000000000000000000001626": "1626", + "0x0000000000000000000000000000000000000000000000000000000000001630": "1630", + "0x000000000000000000000000000000000000000000000000000000000000163a": "163a", + "0x0000000000000000000000000000000000000000000000000000000000001644": "1644", + "0x000000000000000000000000000000000000000000000000000000000000164e": "164e", + "0x0000000000000000000000000000000000000000000000000000000000001658": "1658", + "0x0000000000000000000000000000000000000000000000000000000000001662": "1662", + "0x000000000000000000000000000000000000000000000000000000000000166c": "166c", + "0x0000000000000000000000000000000000000000000000000000000000001676": "1676", + "0x0000000000000000000000000000000000000000000000000000000000001680": "1680", + "0x000000000000000000000000000000000000000000000000000000000000168a": "168a", + "0x0000000000000000000000000000000000000000000000000000000000001694": "1694", + "0x000000000000000000000000000000000000000000000000000000000000169e": "169e", + "0x00000000000000000000000000000000000000000000000000000000000016a8": "16a8", + "0x00000000000000000000000000000000000000000000000000000000000016b2": "16b2", + "0x00000000000000000000000000000000000000000000000000000000000016bc": "16bc", + "0x00000000000000000000000000000000000000000000000000000000000016c6": "16c6", + "0x00000000000000000000000000000000000000000000000000000000000016d0": "16d0", + "0x00000000000000000000000000000000000000000000000000000000000016da": "16da", + "0x00000000000000000000000000000000000000000000000000000000000016e4": "16e4", + "0x00000000000000000000000000000000000000000000000000000000000016ee": "16ee", + "0x00000000000000000000000000000000000000000000000000000000000016f8": "16f8", + "0x0000000000000000000000000000000000000000000000000000000000001702": "1702", + "0x000000000000000000000000000000000000000000000000000000000000170c": "170c", + "0x0000000000000000000000000000000000000000000000000000000000001716": "1716", + "0x0000000000000000000000000000000000000000000000000000000000001720": "1720", + "0x000000000000000000000000000000000000000000000000000000000000172a": "172a", + "0x0000000000000000000000000000000000000000000000000000000000001734": "1734", + "0x000000000000000000000000000000000000000000000000000000000000173e": "173e", + "0x0000000000000000000000000000000000000000000000000000000000001748": "1748", + "0x0000000000000000000000000000000000000000000000000000000000001752": "1752", + "0x000000000000000000000000000000000000000000000000000000000000175c": "175c", + "0x0000000000000000000000000000000000000000000000000000000000001766": "1766", + "0x0000000000000000000000000000000000000000000000000000000000001770": "1770", + "0x000000000000000000000000000000000000000000000000000000000000203b": "83472eda6eb475906aeeb7f09e757ba9f6663b9f6a5bf8611d6306f677f67ebd", + "0x0000000000000000000000000000000000000000000000000000000000002045": "2c809fbc7e3991c8ab560d1431fa8b6f25be4ab50977f0294dfeca9677866b6e", + "0x000000000000000000000000000000000000000000000000000000000000204f": "756e335a8778f6aadb2cc18c5bc68892da05a4d8b458eee5ce3335a024000c67", + "0x0000000000000000000000000000000000000000000000000000000000002059": "4b118bd31ed2c4eeb81dc9e3919e9989994333fe36f147c2930f12c53f0d3c78", + "0x0000000000000000000000000000000000000000000000000000000000002063": "d0122166752d729620d41114ff5a94d36e5d3e01b449c23844900c023d1650a5", + "0x000000000000000000000000000000000000000000000000000000000000206d": "60c606c4c44709ac87b367f42d2453744639fc5bee099a11f170de98408c8089", + "0x0000000000000000000000000000000000000000000000000000000000002077": "6ee04e1c27edad89a8e5a2253e4d9cca06e4f57d063ed4fe7cc1c478bb57eeca", + "0x0000000000000000000000000000000000000000000000000000000000002081": "36616354a17658eb3c3e8e5adda6253660e3744cb8b213006f04302b723749a8", + "0x000000000000000000000000000000000000000000000000000000000000208b": "c13802d4378dcb9c616f0c60ea0edd90e6c2dacf61f39ca06add0eaa67473b94", + "0x0000000000000000000000000000000000000000000000000000000000002095": "8b345497936c51d077f414534be3f70472e4df101dee8820eaaff91a6624557b", + "0x000000000000000000000000000000000000000000000000000000000000209f": "e958485d4b3e47b38014cc4eaeb75f13228072e7b362a56fc3ffe10155882629", + "0x00000000000000000000000000000000000000000000000000000000000020a9": "3346706b38a2331556153113383581bc6f66f209fdef502f9fc9b6daf6ea555e", + "0x00000000000000000000000000000000000000000000000000000000000020b3": "346910f7e777c596be32f0dcf46ccfda2efe8d6c5d3abbfe0f76dba7437f5dad", + "0x00000000000000000000000000000000000000000000000000000000000020bd": "e62a7bd9263534b752176d1ff1d428fcc370a3b176c4a6312b6016c2d5f8d546", + "0x00000000000000000000000000000000000000000000000000000000000020c7": "ffe267d11268388fd0426a627dedddeb075d68327df9172c0445cd2979ec7e4d", + "0x00000000000000000000000000000000000000000000000000000000000020d1": "23cc648c9cd82c08214882b7e28e026d6eb56920f90f64731bb09b6acf515427", + "0x00000000000000000000000000000000000000000000000000000000000020db": "47c896f5986ec29f58ec60eec56ed176910779e9fc9cf45c3c090126aeb21acd", + "0x00000000000000000000000000000000000000000000000000000000000020e5": "6d19894928a3ab44077bb85dcb47e0865ce1c4c187bba26bad059aa774c03cfe", + "0x00000000000000000000000000000000000000000000000000000000000020ef": "efc50f4fc1430b6d5d043065201692a4a02252fef0699394631f5213a5667547", + "0x00000000000000000000000000000000000000000000000000000000000020f9": "3cc9f65fc1f46927eb46fbf6d14bc94af078fe8ff982a984bdd117152cd1549f", + "0x0000000000000000000000000000000000000000000000000000000000002103": "63eb547e9325bc34fbbbdfda327a71dc929fd8ab6509795e56479e95dbd40a80", + "0x000000000000000000000000000000000000000000000000000000000000210d": "67317288cf707b0325748c7947e2dda5e8b41e45e62330d00d80e9be403e5c4c", + "0x0000000000000000000000000000000000000000000000000000000000002117": "7fc37e0d22626f96f345b05516c8a3676b9e1de01d354e5eb9524f6776966885", + "0x0000000000000000000000000000000000000000000000000000000000002121": "c8c5ffb6f192e9bda046ecd4ebb995af53c9dd6040f4ba8d8db9292c1310e43f", + "0x000000000000000000000000000000000000000000000000000000000000212b": "e40a9cfd9babe862d482ca0c07c0a4086641d16c066620cb048c6e673c5a4f91", + "0x0000000000000000000000000000000000000000000000000000000000002135": "e82e7cff48aea45fb3f7b199b0b173497bf4c5ea66ff840e2ec618d7eb3d7470", + "0x000000000000000000000000000000000000000000000000000000000000213f": "84ceda57767ea709da7ab17897a70da1868c9670931da38f2438519a5249534d", + "0x0000000000000000000000000000000000000000000000000000000000002149": "e9dcf640383969359c944cff24b75f71740627f596110ee8568fa09f9a06db1c", + "0x0000000000000000000000000000000000000000000000000000000000002153": "430ef678bb92f1af44dcd77af9c5b59fb87d0fc4a09901a54398ad5b7e19a8f4", + "0x000000000000000000000000000000000000000000000000000000000000215d": "f7af0b8b729cd17b7826259bc183b196dbd318bd7229d5e8085bf4849c0b12bf", + "0x0000000000000000000000000000000000000000000000000000000000002167": "e134e19217f1b4c7e11f193561056303a1f67b69dac96ff79a6d0aafa994f7cb", + "0x0000000000000000000000000000000000000000000000000000000000002171": "9cc58ab1a8cb0e983550e61f754aea1dd4f58ac6482a816dc50658de750de613", + "0x000000000000000000000000000000000000000000000000000000000000217b": "79c2b067779a94fd3756070885fc8eab5e45033bde69ab17c0173d553df02978", + "0x0000000000000000000000000000000000000000000000000000000000002185": "d908ef75d05b895600d3f9938cb5259612c71223b68d30469ff657d61c6b1611", + "0x000000000000000000000000000000000000000000000000000000000000218f": "e0d31906b7c46ac7f38478c0872d3c634f7113d54ef0b57ebfaf7f993959f5a3", + "0x0000000000000000000000000000000000000000000000000000000000002199": "2318f5c5e6865200ad890e0a8db21c780a226bec0b2e29af1cb3a0d9b40196ae", + "0x00000000000000000000000000000000000000000000000000000000000021a3": "523997f8d8fed954658f547954fdeceab818b411862647f2b61a3619f6a4d4bc", + "0x00000000000000000000000000000000000000000000000000000000000021ad": "be3396540ea36c6928cccdcfe6c669666edbbbcd4be5e703f59de0e3c2720da7", + "0x00000000000000000000000000000000000000000000000000000000000021b7": "2d3fcfd65d0a6881a2e8684d03c2aa27aee6176514d9f6d8ebb3b766f85e1039", + "0x00000000000000000000000000000000000000000000000000000000000021c1": "7ce0d5c253a7f910cca7416e949ac04fdaec20a518ab6fcbe4a63d8b439a5cfc", + "0x00000000000000000000000000000000000000000000000000000000000021cb": "4da13d835ea44926ee13f34ce8fcd4b9d3dc65be0a351115cf404234c7fbd256", + "0x00000000000000000000000000000000000000000000000000000000000021d5": "c5ee7483802009b45feabf4c5f701ec485f27bf7d2c4477b200ac53e210e9844", + "0x00000000000000000000000000000000000000000000000000000000000021df": "0fc71295326a7ae8e0776c61be67f3ed8770311df88e186405b8d75bd0be552b", + "0x00000000000000000000000000000000000000000000000000000000000021e9": "7313b4315dd27586f940f8f2bf8af76825d8f24d2ae2c24d885dcb0cdd8d50f5", + "0x00000000000000000000000000000000000000000000000000000000000021f3": "2739473baa23a9bca4e8d0f4f221cfa48440b4b73e2bae7386c14caccc6c2059", + "0x00000000000000000000000000000000000000000000000000000000000021fd": "d4da00e33a11ee18f67b25ad5ff574cddcdccaa30e6743e01a531336b16cbf8f", + "0x0000000000000000000000000000000000000000000000000000000000002207": "e651765d4860f0c46f191212c8193e7c82708e5d8bef1ed6f19bdde577f980cf", + "0x0000000000000000000000000000000000000000000000000000000000002211": "5b5b49487967b3b60bd859ba2fb13290c6eaf67e97e9f9f9dda935c08564b5f6", + "0x000000000000000000000000000000000000000000000000000000000000221b": "57b73780cc42a6a36676ce7008459d5ba206389dc9300f1aecbd77c4b90277fa", + "0x0000000000000000000000000000000000000000000000000000000000002225": "217e8514ea30f1431dc3cd006fe730df721f961cebb5d0b52069d1b4e1ae5d13", + "0x000000000000000000000000000000000000000000000000000000000000222f": "14b775119c252908bb10b13de9f8ae988302e1ea8b2e7a1b6d3c8ae24ba9396b", + "0x0000000000000000000000000000000000000000000000000000000000002239": "e736f0b3c5672f76332a38a6c1e66e5f39e0d01f1ddede2c24671f48e78daf63", + "0x0000000000000000000000000000000000000000000000000000000000002243": "7d112c85b58c64c576d34ea7a7c18287981885892fbf95110e62add156ca572e", + "0x000000000000000000000000000000000000000000000000000000000000224d": "28fbeedc649ed9d2a6feda6e5a2576949da6812235ebdfd030f8105d012f5074", + "0x0000000000000000000000000000000000000000000000000000000000002257": "6f7410cf59e390abe233de2a3e3fe022b63b78a92f6f4e3c54aced57b6c3daa6", + "0x0000000000000000000000000000000000000000000000000000000000002261": "d5edc3d8781deea3b577e772f51949a8866f2aa933149f622f05cde2ebba9adb", + "0x000000000000000000000000000000000000000000000000000000000000226b": "20308d99bc1e1b1b0717f32b9a3a869f4318f5f0eb4ed81fddd10696c9746c6b", + "0x0000000000000000000000000000000000000000000000000000000000002275": "91f7a302057a2e21d5e0ef4b8eea75dfb8b37f2c2db05c5a84517aaebc9d5131", + "0x000000000000000000000000000000000000000000000000000000000000227f": "743e5d0a5be47d489b121edb9f98dad7d0a85fc260909083656fabaf6d404774", + "0x0000000000000000000000000000000000000000000000000000000000002289": "cdcf99c6e2e7d0951f762e787bdbe0e2b3b320815c9d2be91e9cd0848653e839", + "0x0000000000000000000000000000000000000000000000000000000000002293": "cc9476183d27810e9738f382c7f2124976735ed89bbafc7dc19c99db8cfa9ad1", + "0x000000000000000000000000000000000000000000000000000000000000229d": "f67e5fab2e7cacf5b89acd75ec53b0527d45435adddac6ee7523a345dcbcdceb", + "0x00000000000000000000000000000000000000000000000000000000000022a7": "e20f8ab522b2f0d12c068043852139965161851ad910b840db53604c8774a579", + "0x00000000000000000000000000000000000000000000000000000000000022b1": "f982160785861cb970559d980208dd00e6a2ec315f5857df175891b171438eeb", + "0x00000000000000000000000000000000000000000000000000000000000022bb": "230954c737211b72d5c7dcfe420bb07d5d72f2b4868c5976dd22c00d3df0c0b6", + "0x00000000000000000000000000000000000000000000000000000000000022c5": "b7743e65d6bbe09d5531f1bc98964f75943d8c13e27527ca6afd40ca069265d4", + "0x00000000000000000000000000000000000000000000000000000000000022cf": "31ac943dc649c639fa6221400183ca827c07b812a6fbfc1795eb835aa280adf3", + "0x00000000000000000000000000000000000000000000000000000000000022d9": "ded49c937c48d466987a4130f4b6d04ef658029673c3afc99f70f33b552e178d", + "0x00000000000000000000000000000000000000000000000000000000000022e3": "a0effc449cab515020d2012897155a792bce529cbd8d5a4cf94d0bbf141afeb6", + "0x00000000000000000000000000000000000000000000000000000000000022ed": "1f36d9c66a0d437d8e49ffaeaa00f341e9630791b374e8bc0c16059c7445721f", + "0x00000000000000000000000000000000000000000000000000000000000022f7": "34f89e6134f26e7110b47ffc942a847d8c03deeed1b33b9c041218c4e1a1a4e6", + "0x0000000000000000000000000000000000000000000000000000000000002301": "774404c430041ca4a58fdc281e99bf6fcb014973165370556d9e73fdec6d597b", + "0x000000000000000000000000000000000000000000000000000000000000230b": "d616971210c381584bf4846ab5837b53e062cbbb89d112c758b4bd00ce577f09", + "0x0000000000000000000000000000000000000000000000000000000000002315": "cdf6383634b0431468f6f5af19a2b7a087478b42489608c64555ea1ae0a7ee19", + "0x000000000000000000000000000000000000000000000000000000000000231f": "ec22e5df77320b4142c54fceaf2fe7ea30d1a72dc9c969a22acf66858d582b", + "0x0000000000000000000000000000000000000000000000000000000000002329": "cb32d77facfda4decff9e08df5a5810fa42585fdf96f0db9b63b196116fbb6af", + "0x0000000000000000000000000000000000000000000000000000000000002333": "6d76316f272f0212123d0b4b21d16835fe6f7a2b4d1960386d8a161da2b7c6a2", + "0x000000000000000000000000000000000000000000000000000000000000233d": "2de2da72ae329e359b655fc6311a707b06dc930126a27261b0e8ec803bdb5cbf", + "0x0000000000000000000000000000000000000000000000000000000000002347": "08bed4b39d14dc1e72e80f605573cde6145b12693204f9af18bbc94a82389500", + "0x0000000000000000000000000000000000000000000000000000000000002351": "e437f0465ac29b0e889ef4f577c939dd39363c08fcfc81ee61aa0b4f55805f69", + "0x000000000000000000000000000000000000000000000000000000000000235b": "89ca120183cc7085b6d4674d779fc4fbc9de520779bfbc3ebf65f9663cb88080", + "0x0000000000000000000000000000000000000000000000000000000000002365": "b15d5954c7b78ab09ede922684487c7a60368e82fdc7b5a0916842e58a44422b", + "0x000000000000000000000000000000000000000000000000000000000000236f": "ad13055a49d2b6a4ffc8b781998ff79086adad2fd6470a0563a43b740128c5f2", + "0x0000000000000000000000000000000000000000000000000000000000002379": "9e9909e4ed44f5539427ee3bc70ee8b630ccdaea4d0f1ed5337a067e8337119f", + "0x0000000000000000000000000000000000000000000000000000000000002383": "bf1f3aba184e08d4c650f05fe3d948bdda6c2d6982f277f2cd6b1a60cd4f3dac", + "0x000000000000000000000000000000000000000000000000000000000000238d": "bb70fe131f94783dba356c8d4d9d319247ef61c768134303f0db85ee3ef0496f", + "0x0000000000000000000000000000000000000000000000000000000000002397": "6a81ebd3bde6cc54a2521aa72de29ef191e3b56d94953439a72cafdaa2996da0", + "0x00000000000000000000000000000000000000000000000000000000000023a1": "4c83e809a52ac52a587d94590c35c71b72742bd15915fca466a9aaec4f2dbfed", + "0x00000000000000000000000000000000000000000000000000000000000023ab": "268fc70790f00ad0759497585267fbdc92afba63ba01e211faae932f0639854a", + "0x00000000000000000000000000000000000000000000000000000000000023b5": "7e544f42df99d5666085b70bc57b3ca175be50b7a9643f26f464124df632d562", + "0x00000000000000000000000000000000000000000000000000000000000023bf": "d59cf5f55903ba577be835706b27d78a50cacb25271f35a5f57fcb88a3b576f3", + "0x00000000000000000000000000000000000000000000000000000000000023c9": "551cced461be11efdeaf8e47f3a91bb66d532af7294c4461c8009c5833bdbf57", + "0x00000000000000000000000000000000000000000000000000000000000023d3": "c1e0e6907a57eefd12f1f95d28967146c836d72d281e7609de23d0a02351e978", + "0x00000000000000000000000000000000000000000000000000000000000023dd": "9d580c0ac3a7f00fdc3b135b758ae7c80ab135e907793fcf9621a3a3023ca205", + "0x00000000000000000000000000000000000000000000000000000000000023e7": "a7fd4dbac4bb62307ac7ad285ffa6a11ec679d950de2bd41839b8a846e239886", + "0x00000000000000000000000000000000000000000000000000000000000023f1": "6ba7b0ac30a04e11a3116b43700d91359e6b06a49058e543198d4b21e75fb165", + "0x00000000000000000000000000000000000000000000000000000000000023fb": "8835104ed35ffd4db64660b9049e1c0328e502fd4f3744749e69183677b8474b", + "0x0000000000000000000000000000000000000000000000000000000000002405": "562f276b9f9ed46303e700c8863ad75fadff5fc8df27a90744ea04ad1fe8e801", + "0x000000000000000000000000000000000000000000000000000000000000240f": "d19f68026d22ae0f60215cfe4a160986c60378f554c763651d872ed82ad69ebb", + "0x0000000000000000000000000000000000000000000000000000000000002419": "f087a515b4b62d707991988eb912d082b85ecdd52effc9e8a1ddf15a74388860", + "0x0000000000000000000000000000000000000000000000000000000000002423": "f7e28b7daff5fad40ec1ef6a2b7e9066558126f62309a2ab0d0d775d892a06d6", + "0x000000000000000000000000000000000000000000000000000000000000242d": "77361844a8f4dd2451e6218d336378b837ba3fab921709708655e3f1ea91a435", + "0x0000000000000000000000000000000000000000000000000000000000002437": "e3cb33c7b05692a6f25470fbd63ab9c986970190729fab43191379da38bc0d8c", + "0x0000000000000000000000000000000000000000000000000000000000002441": "c893f9de119ec83fe37b178b5671d63448e9b5cde4de9a88cace3f52c2591194", + "0x000000000000000000000000000000000000000000000000000000000000244b": "39c96a6461782ac2efbcb5aaac2e133079b86fb29cb5ea69b0101bdad684ef0d", + "0x0000000000000000000000000000000000000000000000000000000000002455": "72a2724cdf77138638a109f691465e55d32759d3c044a6cb41ab091c574e3bdb", + "0x000000000000000000000000000000000000000000000000000000000000245f": "178ba15f24f0a8c33eed561d7927979c1215ddec20e1aef318db697ccfad0e03", + "0x0000000000000000000000000000000000000000000000000000000000002469": "f7b2c01b7c625588c9596972fdebae61db89f0d0f2b21286d4c0fa76683ff946", + "0x0000000000000000000000000000000000000000000000000000000000002473": "16e43284b041a4086ad1cbab9283d4ad3e8cc7c3a162f60b3df5538344ecdf54", + "0x000000000000000000000000000000000000000000000000000000000000247d": "0a98ea7f737e17706432eba283d50dde10891b49c3424d46918ed2b6af8ecf90", + "0x0000000000000000000000000000000000000000000000000000000000002487": "7637225dd61f90c3cb05fae157272985993b34d6c369bfe8372720339fe4ffd2", + "0x0000000000000000000000000000000000000000000000000000000000002491": "6a7d064bc053c0f437707df7c36b820cca4a2e9653dd1761941af4070f5273b6", + "0x000000000000000000000000000000000000000000000000000000000000249b": "91c1e6eec8f7944fd6aafdce5477f45d4f6e29298c9ef628a59e441a5e071fae", + "0x00000000000000000000000000000000000000000000000000000000000024a5": "a1c227db9bbd2e49934bef01cbb506dd1e1c0671a81aabb1f90a90025980a3c3", + "0x00000000000000000000000000000000000000000000000000000000000024af": "8fcfc1af10f3e8671505afadfd459287ae98be634083b5a35a400cc9186694cf", + "0x00000000000000000000000000000000000000000000000000000000000024b9": "cc1ea9c015bd3a6470669f85c5c13e42c1161fc79704143df347c4a621dff44f", + "0x00000000000000000000000000000000000000000000000000000000000024c3": "b0a22c625dd0c6534e29bccc9ebf94a550736e2c68140b9afe3ddc7216f797de", + "0x00000000000000000000000000000000000000000000000000000000000024cd": "92b8e6ca20622e5fd91a8f58d0d4faaf7be48a53ea262e963bcf26a1698f9df3", + "0x00000000000000000000000000000000000000000000000000000000000024d7": "f6253b8e2f31df6ca7a97086c3b4d49d9cbbbdfc5be731b0c3040a4381161c53", + "0x00000000000000000000000000000000000000000000000000000000000024e1": "ea8d762903bd24b80037d7ffe80019a086398608ead66208c18f0a5778620e67", + "0x00000000000000000000000000000000000000000000000000000000000024eb": "543382975e955588ba19809cfe126ea15dc43c0bfe6a43d861d7ad40eac2c2f4", + "0x00000000000000000000000000000000000000000000000000000000000024f5": "095294f7fe3eb90cf23b3127d40842f61b85da2f48f71234fb94d957d865a8a2", + "0x00000000000000000000000000000000000000000000000000000000000024ff": "144c2dd25fd12003ccd2678d69d30245b0222ce2d2bfead687931a7f6688482f", + "0x0000000000000000000000000000000000000000000000000000000000002509": "7295f7d57a3547b191f55951f548479cbb9a60b47ba38beb8d85c4ccf0e4ae4c", + "0x0000000000000000000000000000000000000000000000000000000000002513": "9e8e241e13f76a4e6d777a2dc64072de4737ac39272bb4987bcecbf60739ccf4", + "0x000000000000000000000000000000000000000000000000000000000000251d": "fc753bcea3e720490efded4853ef1a1924665883de46c21039ec43e371e96bb9", + "0x0000000000000000000000000000000000000000000000000000000000002527": "5f5204c264b5967682836ed773aee0ea209840fe628fd1c8d61702c416b427ca", + "0x0000000000000000000000000000000000000000000000000000000000002531": "5ba9a0326069e000b65b759236f46e54a0e052f379a876d242740c24f6c47aed", + "0x000000000000000000000000000000000000000000000000000000000000253b": "b40e9621d5634cd21f70274c345704af2e060c5befaeb2df109a78c7638167c2", + "0x0000000000000000000000000000000000000000000000000000000000002545": "70e26b74456e6fea452e04f8144be099b0af0e279febdff17dd4cdf9281e12a7", + "0x000000000000000000000000000000000000000000000000000000000000254f": "43d7158f48fb1f124b2962dff613c5b4b8ea415967f2b528af6e7ae280d658e5", + "0x0000000000000000000000000000000000000000000000000000000000002559": "b50b2b14efba477dddca9682df1eafc66a9811c9c5bd1ae796abbef27ba14eb4", + "0x0000000000000000000000000000000000000000000000000000000000002563": "c14936902147e9a121121f424ecd4d90313ce7fc603f3922cebb7d628ab2c8dd", + "0x000000000000000000000000000000000000000000000000000000000000256d": "86609ed192561602f181a9833573213eb7077ee69d65107fa94f657f33b144d2", + "0x0000000000000000000000000000000000000000000000000000000000002577": "0a71a6dbc360e176a0f665787ed3e092541c655024d0b136a04ceedf572c57c5", + "0x0000000000000000000000000000000000000000000000000000000000002581": "a4bcbab632ddd52cb85f039e48c111a521e8944b9bdbaf79dd7c80b20221e4d6", + "0x000000000000000000000000000000000000000000000000000000000000258b": "2bc468eab4fad397f9136f80179729b54caa2cb47c06b0695aab85cf9813620d", + "0x0000000000000000000000000000000000000000000000000000000000002595": "fc7f9a432e6fd69aaf025f64a326ab7221311147dd99d558633579a4d8a0667b", + "0x000000000000000000000000000000000000000000000000000000000000259f": "949613bd67fb0a68cf58a22e60e7b9b2ccbabb60d1d58c64c15e27a9dec2fb35", + "0x00000000000000000000000000000000000000000000000000000000000025a9": "289ddb1aee772ad60043ecf17a882c36a988101af91ac177954862e62012fc0e", + "0x00000000000000000000000000000000000000000000000000000000000025b3": "bfa48b05faa1a2ee14b3eaed0b75f0d265686b6ce3f2b7fa051b8dc98bc23d6a", + "0x00000000000000000000000000000000000000000000000000000000000025bd": "7bf49590a866893dc77444d89717942e09acc299eea972e8a7908e9d694a1150", + "0x00000000000000000000000000000000000000000000000000000000000025c7": "992f76aee242737eb21f14b65827f3ebc42524fb422b17f414f33c35a24092db", + "0x00000000000000000000000000000000000000000000000000000000000025d1": "da6e4f935d966e90dffc6ac0f6d137d9e9c97d65396627e5486d0089b94076fa", + "0x00000000000000000000000000000000000000000000000000000000000025db": "65467514ed80f25b299dcf74fb74e21e9bb929832a349711cf327c2f8b60b57f", + "0x00000000000000000000000000000000000000000000000000000000000025e5": "cc2ac03d7a26ff16c990c5f67fa03dabda95641a988deec72ed2fe38c0f289d6", + "0x00000000000000000000000000000000000000000000000000000000000025ef": "096dbe9a0190c6badf79de3747abfd4d5eda3ab95b439922cae7ec0cfcd79290", + "0x00000000000000000000000000000000000000000000000000000000000025f9": "0c659c769744094f60332ec247799d7ed5ae311d5738daa5dcead3f47ca7a8a2", + "0x0000000000000000000000000000000000000000000000000000000000002603": "9cb8a0d41ede6b951c29182422db215e22aedfa1a3549cd27b960a768f6ed522", + "0x000000000000000000000000000000000000000000000000000000000000260d": "2510f8256a020f4735e2be224e3bc3e8c14e56f7588315f069630fe24ce2fa26", + "0x0000000000000000000000000000000000000000000000000000000000002617": "2d3deb2385a2d230512707ece0bc6098ea788e3d5debb3911abe9a710dd332ea", + "0x0000000000000000000000000000000000000000000000000000000000002621": "1cec4b230f3bccfff7ca197c4a35cb5b95ff7785d064be3628235971b7aff27c", + "0x000000000000000000000000000000000000000000000000000000000000262b": "18e4a4238d43929180c7a626ae6f8c87a88d723b661549f2f76ff51726833598", + "0x0000000000000000000000000000000000000000000000000000000000002635": "700e1755641a437c8dc888df24a5d80f80f9eaa0d17ddab17db4eb364432a1f5", + "0x000000000000000000000000000000000000000000000000000000000000263f": "cad29ceb73b2f3c90d864a2c27a464b36b980458e2d8c4c7f32f70afad707312", + "0x0000000000000000000000000000000000000000000000000000000000002649": "a85e892063a7fd41d37142ae38037967eb047436c727fcf0bad813d316efe09f", + "0x0000000000000000000000000000000000000000000000000000000000002653": "040100f17208bcbd9456c62d98846859f7a5efa0e45a5b3a6f0b763b9c700fec", + "0x000000000000000000000000000000000000000000000000000000000000265d": "49d54a5147de1f5208c509b194af6d64b509398e4f255c20315131e921f7bd04", + "0x0000000000000000000000000000000000000000000000000000000000002667": "810ff6fcafb9373a4df3e91ab1ca64a2955c9e42ad8af964f829e38e0ea4ee20", + "0x0000000000000000000000000000000000000000000000000000000000002671": "9b72096b8b672ac6ff5362c56f5d06446d1693c5d2daa94a30755aa636320e78", + "0x000000000000000000000000000000000000000000000000000000000000267b": "f68bff777db51db5f29afc4afe38bd1bf5cdec29caa0dc52535b529e6d99b742", + "0x0000000000000000000000000000000000000000000000000000000000002685": "9566690bde717eec59f828a2dba90988fa268a98ed224f8bc02b77bce10443c4", + "0x000000000000000000000000000000000000000000000000000000000000268f": "d0e821fbd57a4d382edd638b5c1e6deefb81352d41aa97da52db13f330e03097", + "0x0000000000000000000000000000000000000000000000000000000000002699": "43f9aa6fa63739abec56c4604874523ac6dabfcc08bb283195072aeb29d38dfe", + "0x00000000000000000000000000000000000000000000000000000000000026a3": "54ebfa924e887a63d643a8277c3394317de0e02e63651b58b6eb0e90df8a20cd", + "0x00000000000000000000000000000000000000000000000000000000000026ad": "9e414c994ee35162d3b718c47f8435edc2c93394a378cb41037b671366791fc8", + "0x00000000000000000000000000000000000000000000000000000000000026b7": "4356f072bb235238abefb3330465814821097327842b6e0dc4a0ef95680c4d34", + "0x00000000000000000000000000000000000000000000000000000000000026c1": "215df775ab368f17ed3f42058861768a3fba25e8d832a00b88559ca5078b8fbc", + "0x00000000000000000000000000000000000000000000000000000000000026cb": "d17835a18d61605a04d2e50c4f023966a47036e5c59356a0463db90a76f06e3e", + "0x00000000000000000000000000000000000000000000000000000000000026d5": "875032d74e62dbfd73d4617754d36cd88088d1e5a7c5354bf3e0906c749e6637", + "0x00000000000000000000000000000000000000000000000000000000000026df": "6f22ae25f70f4b03a2a2b17f370ace1f2b15d17fc7c2457824348a8f2a1eff9f", + "0x00000000000000000000000000000000000000000000000000000000000026e9": "f11fdf2cb985ce7472dc7c6b422c3a8bf2dfbbc6b86b15a1fa62cf9ebae8f6cf", + "0x00000000000000000000000000000000000000000000000000000000000026f3": "bbc97696e588f80fbe0316ad430fd4146a29c19b926248febe757cd9408deddc", + "0x00000000000000000000000000000000000000000000000000000000000026fd": "71dd15be02efd9f3d5d94d0ed9b5e60a205f439bb46abe6226879e857668881e", + "0x0000000000000000000000000000000000000000000000000000000000002707": "b90e98bd91f1f7cc5c4456bb7a8868a2bb2cd3dda4b5dd6463b88728526dceea", + "0x0000000000000000000000000000000000000000000000000000000000002711": "4e80fd3123fda9b404a737c9210ccb0bacc95ef93ac40e06ce9f7511012426c4", + "0x000000000000000000000000000000000000000000000000000000000000271b": "afb50d96b2543048dc93045b62357cc18b64d0e103756ce3ad0e04689dd88282", + "0x0000000000000000000000000000000000000000000000000000000000002725": "d73341a1c9edd04a890f949ede6cc1e942ad62b63b6a60177f0f692f141a7e95", + "0x000000000000000000000000000000000000000000000000000000000000272f": "c26601e9613493118999d9268b401707e42496944ccdbfa91d5d7b791a6d18f1", + "0x0000000000000000000000000000000000000000000000000000000000002739": "fb4619fb12e1b9c4b508797833eef7df65fcf255488660d502def2a7ddceef6d", + "0x0000000000000000000000000000000000000000000000000000000000002743": "d08b7458cd9d52905403f6f4e9dac15ad18bea1f834858bf48ecae36bf854f98", + "0x000000000000000000000000000000000000000000000000000000000000274d": "df979da2784a3bb9e07c368094dc640aafc514502a62a58b464e50e5e50a34bd", + "0x0000000000000000000000000000000000000000000000000000000000002757": "15855037d4712ce0019f0169dcd58b58493be8373d29decfa80b8df046e3d6ba", + "0x0000000000000000000000000000000000000000000000000000000000002761": "fd1462a68630956a33e4b65c8e171a08a131097bc7faf5d7f90b5503ab30b69c", + "0x000000000000000000000000000000000000000000000000000000000000276b": "edad57fee633c4b696e519f84ad1765afbef5d2781b382acd9b8dfcf6cd6d572", + "0x0000000000000000000000000000000000000000000000000000000000002775": "c2641ba296c2daa6edf09b63d0f1cfcefd51451fbbc283b6802cbd5392fb145c", + "0x000000000000000000000000000000000000000000000000000000000000277f": "5615d64e1d3a10972cdea4e4b106b4b6e832bc261129f9ab1d10a670383ae446", + "0x0000000000000000000000000000000000000000000000000000000000002789": "0757c6141fad938002092ff251a64190b060d0e31c31b08fb56b0f993cc4ef0d", + "0x0000000000000000000000000000000000000000000000000000000000002793": "14ddc31bc9f9c877ae92ca1958e6f3affca7cc3064537d0bbe8ba4d2072c0961", + "0x000000000000000000000000000000000000000000000000000000000000279d": "490b0f08777ad4364f523f94dccb3f56f4aacb2fb4db1bb042a786ecfd248c79", + "0x00000000000000000000000000000000000000000000000000000000000027a7": "4a37c0e55f539f2ecafa0ce71ee3d80bc9fe33fb841583073c9f524cc5a2615a", + "0x00000000000000000000000000000000000000000000000000000000000027b1": "133295fdf94e5e4570e27125807a77272f24622750bcf408be0360ba0dcc89f2", + "0x00000000000000000000000000000000000000000000000000000000000027bb": "a73eb87c45c96b121f9ab081c095bff9a49cfe5a374f316e9a6a66096f532972", + "0x00000000000000000000000000000000000000000000000000000000000027c5": "9040bc28f6e830ca50f459fc3dac39a6cd261ccc8cd1cca5429d59230c10f34c", + "0x00000000000000000000000000000000000000000000000000000000000027cf": "ec1d134c49cde6046ee295672a8f11663b6403fb71338181a89dc6bc92f7dea8", + "0x00000000000000000000000000000000000000000000000000000000000027d9": "3130a4c80497c65a7ee6ac20f6888a95bd5b05636d6b4bd13d616dcb01591e16", + "0x00000000000000000000000000000000000000000000000000000000000027e3": "ccdfd5b42f2cbd29ab125769380fc1b18a9d272ac5d3508a6bbe4c82360ebcca", + "0x00000000000000000000000000000000000000000000000000000000000027ed": "74342c7f25ee7dd1ae6eb9cf4e5ce5bcab56c798aea36b554ccb31a660e123af", + "0x00000000000000000000000000000000000000000000000000000000000027f7": "f6f75f51a452481c30509e5de96edae82892a61f8c02c88d710dc782b5f01fc7", + "0x0000000000000000000000000000000000000000000000000000000000002801": "7ce6539cc82db9730b8c21b12d6773925ff7d1a46c9e8f6c986ada96351f36e9", + "0x000000000000000000000000000000000000000000000000000000000000280b": "1983684da5e48936b761c5e5882bbeb5e42c3a7efe92989281367fa5ab25e918", + "0x0000000000000000000000000000000000000000000000000000000000002815": "c564aa993f2b446325ee674146307601dd87eb7409266a97e695e4bb09dd8bf5", + "0x000000000000000000000000000000000000000000000000000000000000281f": "9ca2ff57d59decb7670d5f49bcca68fdaf494ba7dc06214d8e838bfcf7a2824e", + "0x0000000000000000000000000000000000000000000000000000000000002829": "6d7b7476cecc036d470a691755f9988409059bd104579c0a2ded58f144236045", + "0x0000000000000000000000000000000000000000000000000000000000002833": "417504d79d00b85a29f58473a7ad643f88e9cdfe5da2ed25a5965411390fda4a", + "0x000000000000000000000000000000000000000000000000000000000000283d": "e910eb040bf32e56e9447d63497799419957ed7df2572e89768b9139c6fa6a23", + "0x0000000000000000000000000000000000000000000000000000000000002847": "8e462d3d5b17f0157bc100e785e1b8d2ad3262e6f27238fa7e9c62ba29e9c692", + "0x0000000000000000000000000000000000000000000000000000000000002851": "3e6f040dc96b2e05961c4e28df076fa654761f4b0e2e30f5e36b06f65d1893c1", + "0x000000000000000000000000000000000000000000000000000000000000285b": "07e71d03691704a4bd83c728529642884fc1b1a8cfeb1ddcbf659c9b71367637", + "0x0000000000000000000000000000000000000000000000000000000000002865": "f4d05f5986e4b92a845467d2ae6209ca9b7c6c63ff9cdef3df180660158163ef", + "0x000000000000000000000000000000000000000000000000000000000000286f": "5ca251408392b25af49419f1ecd9338d1f4b5afa536dc579ab54e1e3ee6914d4", + "0x0000000000000000000000000000000000000000000000000000000000002879": "e98b64599520cf62e68ce0e2cdf03a21d3712c81fa74b5ade4885b7d8aec531b", + "0x0000000000000000000000000000000000000000000000000000000000002883": "d62ec5a2650450e26aac71a21d45ef795e57c231d28a18d077a01f761bc648fe", + "0x000000000000000000000000000000000000000000000000000000000000288d": "4d3fb38cf24faf44f5b37f248553713af2aa9c3d99ddad4a534e49cd06bb8098", + "0x0000000000000000000000000000000000000000000000000000000000002897": "36e90abacae8fbe712658e705ac28fa9d00118ef55fe56ea893633680147148a", + "0x00000000000000000000000000000000000000000000000000000000000028a1": "164177f08412f7e294fae37457d238c4dd76775263e2c7c9f39e8a7ceca9028a", + "0x00000000000000000000000000000000000000000000000000000000000028ab": "aa5a5586bf2f68df5c206dbe45a9498de0a9b5a2ee92235b740971819838a010", + "0x00000000000000000000000000000000000000000000000000000000000028b5": "99d001850f513efdc613fb7c8ede12a943ff543c578a54bebbb16daecc56cec5", + "0x00000000000000000000000000000000000000000000000000000000000028bf": "30a4501d58b23fc7eee5310f5262783b2dd36a94922d11e5e173ec763be8accb", + "0x00000000000000000000000000000000000000000000000000000000000028c9": "a804188a0434260c0825a988483de064ae01d3e50cb111642c4cfb65bfc2dfb7", + "0x00000000000000000000000000000000000000000000000000000000000028d3": "c554c79292c950bce95e9ef57136684fffb847188607705454909aa5790edc64", + "0x00000000000000000000000000000000000000000000000000000000000028dd": "c89e3673025beff5031d48a885098da23d716b743449fd5533a04f25bd2cd203", + "0x00000000000000000000000000000000000000000000000000000000000028e7": "44c310142a326a3822abeb9161413f91010858432d27c9185c800c9c2d92aea6", + "0x00000000000000000000000000000000000000000000000000000000000028f1": "ae3f497ee4bd619d651097d3e04f50caac1f6af55b31b4cbde4faf1c5ddc21e8", + "0x00000000000000000000000000000000000000000000000000000000000028fb": "3287d70a7b87db98964e828d5c45a4fa4cd7907be3538a5e990d7a3573ccb9c1", + "0x0000000000000000000000000000000000000000000000000000000000002905": "b52bb578e25d833410fcca7aa6f35f79844537361a43192dce8dcbc72d15e09b", + "0x000000000000000000000000000000000000000000000000000000000000290f": "ff8f6f17c0f6d208d27dd8b9147586037086b70baf4f70c3629e73f8f053d34f", + "0x0000000000000000000000000000000000000000000000000000000000002919": "70bccc358ad584aacb115076c8aded45961f41920ffedf69ffa0483e0e91fa52", + "0x0000000000000000000000000000000000000000000000000000000000002923": "e3881eba45a97335a6d450cc37e7f82b81d297c111569e38b6ba0c5fb0ae5d71", + "0x000000000000000000000000000000000000000000000000000000000000292d": "2217beb48c71769d8bf9caaac2858237552fd68cd4ddefb66d04551e7beaa176", + "0x0000000000000000000000000000000000000000000000000000000000002937": "06b56638d2545a02757e7f268b25a0cd3bce792fcb1e88da21b0cc21883b9720", + "0x0000000000000000000000000000000000000000000000000000000000002941": "ebdc8c9e2a85a1fb6582ca30616a685ec8ec25e9c020a65a85671e8b9dacc6eb", + "0x000000000000000000000000000000000000000000000000000000000000294b": "738f3edb9d8d273aac79f95f3877fd885e1db732e86115fa3d0da18e6c89e9cf", + "0x0000000000000000000000000000000000000000000000000000000000002955": "ae5ccfc8201288b0c5981cdb60e16bc832ac92edc51149bfe40ff4a935a0c13a", + "0x000000000000000000000000000000000000000000000000000000000000295f": "69a7a19c159c0534e50a98e460707c6c280e7e355fb97cf2b5e0fd56c45a0a97", + "0x0000000000000000000000000000000000000000000000000000000000002969": "4d2a1e9207a1466593e5903c5481a579e38e247afe5e80bd41d629ac3342e6a4", + "0x0000000000000000000000000000000000000000000000000000000000002973": "d3e7d679c0d232629818cbb94251c24797ce36dd2a45dbe8c77a6a345231c3b3", + "0x000000000000000000000000000000000000000000000000000000000000297d": "d1835b94166e1856dddb6eaa1cfdcc6979193f2ff4541ab274738bd48072899c", + "0x0000000000000000000000000000000000000000000000000000000000002987": "1f12c89436a94d427a69bca5a080edc328bd2424896f3f37223186b440deb45e", + "0x0000000000000000000000000000000000000000000000000000000000002991": "ccb765890b7107fd98056a257381b6b1d10a83474bbf1bdf8e6b0b8eb9cef2a9", + "0x000000000000000000000000000000000000000000000000000000000000299b": "8bbf4e534dbf4580edc5a973194a725b7283f7b9fbb7d7d8deb386aaceebfa84", + "0x00000000000000000000000000000000000000000000000000000000000029a5": "85a0516088f78d837352dcf12547ee3c598dda398e78a9f4d95acfbef19f5e19", + "0x00000000000000000000000000000000000000000000000000000000000029af": "0f669bc7780e2e5719f9c05872a112f6511e7f189a8649cda5d8dda88d6b8ac3", + "0x00000000000000000000000000000000000000000000000000000000000029b9": "a7816288f9712fcab6a2b6fbd0b941b8f48c2acb635580ed80c27bed7e840a57", + "0x00000000000000000000000000000000000000000000000000000000000029c3": "da5168c8c83ac67dfc2772af49d689f11974e960dee4c4351bac637db1a39e82", + "0x00000000000000000000000000000000000000000000000000000000000029cd": "3f720ecec02446f1af948de4eb0f54775562f2d615726375c377114515ac545b", + "0x00000000000000000000000000000000000000000000000000000000000029d7": "273830a0087f6cef0fdb42179aa1c6c8c19f7bc83c3dc7aa1a56e4e05ca473ea", + "0x00000000000000000000000000000000000000000000000000000000000029e1": "7044f700543fd542e87e7cdb94f0126b0f6ad9488d0874a8ac903a72bade34e9", + "0x00000000000000000000000000000000000000000000000000000000000029eb": "f63a7ff76bb9713bea8d47831a1510d2c8971accd22a403d5bbfaaa3dc310616", + "0x00000000000000000000000000000000000000000000000000000000000029f5": "a68dbd9898dd1589501ca3220784c44d41852ad997a270e215539d461ec090f8", + "0x00000000000000000000000000000000000000000000000000000000000029ff": "59e501ae3ba9e0c3adafdf0f696d2e6a358e1bec43cbe9b0258c2335dd8d764f", + "0x0000000000000000000000000000000000000000000000000000000000002a09": "4f19cff0003bdc03c2fee20db950f0efb323be170f0b09c491a20abcf26ecf43", + "0x0000000000000000000000000000000000000000000000000000000000002a13": "52b1b89795a8fabd3c8594bd571b44fd72279979aaa1d49ea7105c787f8f5fa6", + "0x0000000000000000000000000000000000000000000000000000000000002a1d": "7c1416bd4838b93bc87990c9dcca108675bafab950dd0faf111d9eddc4e54327", + "0x0000000000000000000000000000000000000000000000000000000000002a27": "ef87a35bb6e56e7d5a1f804c63c978bbd1c1516c4eb70edad2b8143169262c9f", + "0x0000000000000000000000000000000000000000000000000000000000002a31": "e978f25d16f468c0a0b585994d1e912837f55e1cd8849e140f484a2702385ef2", + "0x0000000000000000000000000000000000000000000000000000000000002a3b": "c3e85e9260b6fad139e3c42587cc2df7a9da07fadaacaf2381ca0d4a0c91c819", + "0x0000000000000000000000000000000000000000000000000000000000002a45": "bd2647c989abfd1d340fd05add92800064ad742cd82be8c2ec5cc7df20eb0351", + "0x0000000000000000000000000000000000000000000000000000000000002a4f": "99ac5ad7b62dd843abca85e485a6d4331e006ef9d391b0e89fb2eeccef1d29a2", + "0x0000000000000000000000000000000000000000000000000000000000002a59": "02a4349c3ee7403fe2f23cad9cf2fb6933b1ae37e34c9d414dc4f64516ea9f97", + "0x0000000000000000000000000000000000000000000000000000000000002a63": "627b41fdbdf4a95381da5e5186123bf808c119b849dfdd3f515fa8d54c19c771", + "0x0000000000000000000000000000000000000000000000000000000000002a6d": "c087b16d7caa58e1361a7b158159469975f55582a4ef760465703a40123226d7", + "0x0000000000000000000000000000000000000000000000000000000000002a77": "f7a477c0c27d4890e3fb56eb2dc0386e7409d1c59cab6c7f22b84de45b4c6867", + "0x0000000000000000000000000000000000000000000000000000000000002a81": "1cb440b7d88e98ceb953bc46b003fde2150860be05e11b9a5abae2c814a71571", + "0x0000000000000000000000000000000000000000000000000000000000002a8b": "72613e3e30445e37af38976f6bb3e3bf7debbcf70156eb37c5ac4e41834f9dd2", + "0x0000000000000000000000000000000000000000000000000000000000002a95": "e69e7568b9e70ee7e71ebad9548fc8afad5ff4435df5d55624b39df9e8826c91", + "0x0000000000000000000000000000000000000000000000000000000000002a9f": "c3f1682f65ee45ce7019ee7059d65f8f1b0c0a8f68f94383410f7e6f46f26577", + "0x0000000000000000000000000000000000000000000000000000000000002aa9": "93ee1e4480ed7935097467737e54c595a2a6424cf8eaed5eacc2bf23ce368192", + "0x0000000000000000000000000000000000000000000000000000000000002ab3": "b07f8855348b496166d3906437b8b76fdf7918f2e87858d8a78b1deece6e2558", + "0x0000000000000000000000000000000000000000000000000000000000002abd": "ec60e51de32061c531b80d2c515bfa8f81600b9b50fc02beaf4dc01dd6e0c9ca", + "0x0000000000000000000000000000000000000000000000000000000000002ac7": "2fc9f34b3ed6b3cabd7b2b65b4a21381ad4419670eed745007f9efa8dd365ef1", + "0x0000000000000000000000000000000000000000000000000000000000002ad1": "f4af3b701f9b088d23f93bb6d5868370ed1cdcb19532ddd164ed3f411f3e5a95", + "0x0000000000000000000000000000000000000000000000000000000000002adb": "8272e509366a028b8d6bbae2a411eb3818b5be7dac69104a4e72317e55a9e697", + "0x0000000000000000000000000000000000000000000000000000000000002ae5": "a194d76f417dafe27d02a6044a913c0b494fe893840b5b745386ae6078a44e9c", + "0x0000000000000000000000000000000000000000000000000000000000002aef": "a255e59e9a27c16430219b18984594fc1edaf88fe47dd427911020fbc0d92507", + "0x0000000000000000000000000000000000000000000000000000000000002af9": "7996946b8891ebd0623c7887dd09f50a939f6f29dea4ca3c3630f50ec3c575cb", + "0x0000000000000000000000000000000000000000000000000000000000002b03": "b04cbab069405f18839e6c6cf85cc19beeb9ee98c159510fcb67cb84652b7db9", + "0x0000000000000000000000000000000000000000000000000000000000002b0d": "6f241a5e530d1e261ef0f5800d7ff252c33ce148865926e6231d4718f0b9eded", + "0x0000000000000000000000000000000000000000000000000000000000002b17": "fcfa9f1759f8db6a7e452af747a972cf3b1b493a216dbd32db21f7c2ce279cce", + "0x0000000000000000000000000000000000000000000000000000000000002b21": "df880227742710ac4f31c0466a6da7c56ec54caccfdb8f58e5d3f72e40e800f3", + "0x0000000000000000000000000000000000000000000000000000000000002b2b": "adfe28a0f8afc89c371dc7b724c78c2e3677904d03580c7141d32ba32f0ed46f", + "0x0000000000000000000000000000000000000000000000000000000000002b35": "b264d19d2daf7d5fcf8d2214eba0aacf72cabbc7a2617219e535242258d43a31", + "0x0000000000000000000000000000000000000000000000000000000000002b3f": "f2207420648dccc4f01992831e219c717076ff3c74fb88a96676bbcfe1e63f38", + "0x0000000000000000000000000000000000000000000000000000000000002b49": "41e8fae73b31870db8546eea6e11b792e0c9daf74d2fbb6471f4f6c6aaead362", + "0x0000000000000000000000000000000000000000000000000000000000002b53": "4e7a5876c1ee2f1833267b5bd85ac35744a258cc3d7171a8a8cd5c87811078a2", + "0x0000000000000000000000000000000000000000000000000000000000002b5d": "8d4a424d1a0ee910ccdfc38c7e7f421780c337232d061e3528e025d74b362315", + "0x0000000000000000000000000000000000000000000000000000000000002b67": "fa65829d54aba84896370599f041413d50f1acdc8a178211b2960827c1f85cbf", + "0x0000000000000000000000000000000000000000000000000000000000002b71": "da5dfc12da14eafad2ac2a1456c241c4683c6e7e40a7c3569bc618cfc9d6dca3", + "0x0000000000000000000000000000000000000000000000000000000000002b7b": "16243e7995312ffa3983c5858c6560b2abc637c481746003b6c2b58c62e9a547", + "0x0000000000000000000000000000000000000000000000000000000000002b85": "b75f0189b31abbbd88cd32c47ed311c93ec429f1253ee715a1b00d1ca6a1e094", + "0x0000000000000000000000000000000000000000000000000000000000002b8f": "d087eb94d6347da9322e3904add7ff7dd0fd72b924b917a8e10dae208251b49d", + "0x0000000000000000000000000000000000000000000000000000000000002b99": "bc17244b8519292d8fbb455f6253e57ecc16b5803bd58f62b0d94da7f8b2a1d6", + "0x0000000000000000000000000000000000000000000000000000000000002ba3": "3ff8b39a3c6de6646124497b27e8d4e657d103c72f2001bdd4c554208a0566e3", + "0x0000000000000000000000000000000000000000000000000000000000002bad": "4d0f765d2b6a01f0c787bbb13b1360c1624704883e2fd420ea36037fa7e3a563", + "0x0000000000000000000000000000000000000000000000000000000000002bb7": "f6f1dc891258163196785ce9516a14056cbe823b17eb9b90eeee7a299c1ce0e0", + "0x0000000000000000000000000000000000000000000000000000000000002bc1": "1dbf19b70c0298507d20fb338cc167d9b07b8747351785047e1a736b42d999d1", + "0x0000000000000000000000000000000000000000000000000000000000002bcb": "c3b71007b20abbe908fdb7ea11e3a3f0abff3b7c1ced865f82b07f100167de57", + "0x0000000000000000000000000000000000000000000000000000000000002bd5": "3f45edc424499d0d4bbc0fd5837d1790cb41c08f0269273fdf66d682429c25cc", + "0x0000000000000000000000000000000000000000000000000000000000002bdf": "cb8f5db9446c485eaae7edbc03e3afed72892fa7f11ad8eb7fa9dffbe3c220eb", + "0x0000000000000000000000000000000000000000000000000000000000002be9": "3d151527b5ba165352a450bee69f0afc78cf2ea9645bb5d8f36fb04435f0b67c", + "0x0000000000000000000000000000000000000000000000000000000000002bf3": "dd96b35b4ffabce80d377420a0b00b7fbf0eff6a910210155d22d9bd981be5d3", + "0x0000000000000000000000000000000000000000000000000000000000002bfd": "ace0c30b543d3f92f37eaac45d6f8730fb15fcaaaad4097ea42218abe57cb9f4", + "0x0000000000000000000000000000000000000000000000000000000000002c07": "f6342dd31867c9bef6ffa06b6cf192db23d0891ed8fe610eb8d1aaa79726da01", + "0x0000000000000000000000000000000000000000000000000000000000002c11": "a6589e823979c2c2ac55e034d547b0c63aa02109133575d9f159e8a7677f03cb", + "0x0000000000000000000000000000000000000000000000000000000000002c1b": "9ce48bc641cc1d54ffdb409aab7da1304d5ee08042596b3542ca9737bb2b79a8", + "0x0000000000000000000000000000000000000000000000000000000000002c25": "a44be801bd978629775c00d70df6d70b76d0ba918595e81415a27d1e3d6fdee9", + "0x0000000000000000000000000000000000000000000000000000000000002c2f": "ce17f1e7af9f7ea8a99b2780d87b15d8b80a68fb29ea52f962b00fecfc6634e0", + "0x0000000000000000000000000000000000000000000000000000000000002c39": "4bd91febab8df3770c957560e6185e8af59d2a42078756c525cd7769eb943894", + "0x0000000000000000000000000000000000000000000000000000000000002c43": "414c2a52de31de93a3c69531247b016ac578435243073acc516d4ea673c8dd80", + "0x0000000000000000000000000000000000000000000000000000000000002c4d": "647fb60bdf2683bd46b63d6884745782364a5522282ed1dc67d9e17c4aaab17d", + "0x0000000000000000000000000000000000000000000000000000000000002c57": "fa681ffd0b0dd6f6775e99a681241b86a3a24446bc8a69cdae915701243e3855", + "0x0000000000000000000000000000000000000000000000000000000000002c61": "106ca692777b30cb2aa23ca59f5591514b28196ee8e9b06aa2b4deaea30d9ef6", + "0x0000000000000000000000000000000000000000000000000000000000002c6b": "494ac6d09377eb6a07ff759df61c2508e65e5671373d756c82e648bd9086d91a", + "0x0000000000000000000000000000000000000000000000000000000000002c75": "0ae4ccd2bffa603714cc453bfd92f769dce6c9731c03ac3e2083f35388e6c795", + "0x0000000000000000000000000000000000000000000000000000000000002c7f": "d860c999490d9836cc00326207393c78445b7fb90b12aa1d3607e3662b3d32cd", + "0x0000000000000000000000000000000000000000000000000000000000002c89": "9587384f876dfec24da857c0bcdb3ded17f3328f28a4d59aa35ca7c25c8102cf", + "0x0000000000000000000000000000000000000000000000000000000000002c93": "4df8093d29bc0ec4e2a82be427771e77a206566194734a73c23477e1a9e451f8", + "0x0000000000000000000000000000000000000000000000000000000000002c9d": "c56640f78acbd1da07701c365369766f09a19800ba70276f1f1d3cd1cf6e0686", + "0x0000000000000000000000000000000000000000000000000000000000002ca7": "7173d4210aa525eece6b4b19b16bab23686ff9ac71bb9d16008bb114365e79f2", + "0x0000000000000000000000000000000000000000000000000000000000002cb1": "89698b41d7ac70e767976a9f72ae6a46701456bc5ad8d146c248548409c90015", + "0x0000000000000000000000000000000000000000000000000000000000002cbb": "5b605ab5048d9e4a51ca181ac3fa7001ef5d415cb20335b095c54a40c621dbff", + "0x0000000000000000000000000000000000000000000000000000000000002cc5": "9129a84b729e7f69a5522a7020db57e27bf8cbb6042e030106c0cbd185bf0ab8", + "0x0000000000000000000000000000000000000000000000000000000000002ccf": "31a63d6d54153ab35fc57068db205a3e68908be238658ca82d8bee9873f82159", + "0x0000000000000000000000000000000000000000000000000000000000002cd9": "828641bcea1bc6ee1329bc39dca0afddc11e6867f3da13d4bb5170c54158860d", + "0x0000000000000000000000000000000000000000000000000000000000002ce3": "7e0752ddd86339f512ec1b647d3bf4b9b50c45e309ab9e70911da7716454b053", + "0x0000000000000000000000000000000000000000000000000000000000002ced": "31d973051189456d5998e05b500da6552138644f8cdbe4ec63f96f21173cb6a1", + "0x0000000000000000000000000000000000000000000000000000000000002cf7": "e33e65b3d29c3b55b2d7b584c5d0540eb5c00c9f157287863b0b619339c302f0", + "0x0000000000000000000000000000000000000000000000000000000000002d01": "78d55514bcef24b40c7eb0fbe55f922d4468c194f313898f28ba85d8534df82c", + "0x0000000000000000000000000000000000000000000000000000000000002d0b": "2e0f4be4d8adf8690fd64deddbc543f35c5b4f3c3a27b10a77b1fdb8d590f1ee", + "0x0000000000000000000000000000000000000000000000000000000000002d15": "e1b83ea8c4329f421296387826c89100d82bdc2263ffd8eb9368806a55d9b83b", + "0x0000000000000000000000000000000000000000000000000000000000002d1f": "4ddad36d7262dd9201c5bdd58523f4724e3b740fddbed2185e32687fecacdf6b", + "0x0000000000000000000000000000000000000000000000000000000000002d29": "156c0674e46cdec70505443c5269d42c7bb14ee6c00f86a23962f08906cbb846", + "0x0000000000000000000000000000000000000000000000000000000000002d33": "dfc56ec6c218a08b471d757e0e7de8dddec9e82f401cb7d77df1f2a9ca54c607", + "0x0000000000000000000000000000000000000000000000000000000000002d3d": "395d660f77c4360705cdc0be895907ec183097f749fac18b6eaa0245c1009074", + "0x0000000000000000000000000000000000000000000000000000000000002d47": "84c0060087da2c95dbd517d0f2dd4dfba70691a5952fe4048c310e88e9c06e4f", + "0x0000000000000000000000000000000000000000000000000000000000002d51": "f4df943c52b1d5fb9c1f73294ca743577d83914ec26d6e339b272cdeb62de586", + "0x0000000000000000000000000000000000000000000000000000000000002d5b": "0bb47661741695863ef89d5c2b56666772f871be1cc1dccf695bd357e4bb26d6", + "0x0000000000000000000000000000000000000000000000000000000000002d65": "4a1f7691f29900287c6931545884881143ecae44cb26fdd644892844fde65dac", + "0x0000000000000000000000000000000000000000000000000000000000002d6f": "9b133cc50cbc46d55ce2910eebaf8a09ab6d4e606062c94aac906da1646bc33f", + "0x0000000000000000000000000000000000000000000000000000000000002d79": "473b076b542da72798f9de31c282cb1dcd76cba2a22adc7391670ffdbc910766", + "0x0000000000000000000000000000000000000000000000000000000000002d83": "225dd472ef6b36a51de5c322a31a9f71c80f0f350432884526d9844bb2e676d3", + "0x0000000000000000000000000000000000000000000000000000000000002d8d": "31df97b2c9fc65b5520b89540a42050212e487f46fac67685868f1c3e652a9aa", + "0x0000000000000000000000000000000000000000000000000000000000002d97": "4416d885f34ad479409bb9e05e8846456a9be7e74655b9a4d7568a8d710aa06a", + "0x0000000000000000000000000000000000000000000000000000000000002da1": "ae627f8802a46c1357fa42a8290fd1366ea21b8ccec1cc624e42022647c53802", + "0x0000000000000000000000000000000000000000000000000000000000002dab": "8961e8b83d91487fc32b3d6af26b1d5e7b4010dd8d028fe165187cdfb04e151c", + "0x0000000000000000000000000000000000000000000000000000000000002db5": "c22e39f021605c6f3d967aef37f0bf40b09d776bac3edb4264d0dc07389b9845", + "0x0000000000000000000000000000000000000000000000000000000000002dbf": "7cfa4c7066c690c12b9e8727551bef5fe05b750ac6637a5af632fce4ceb4e2ce", + "0x0000000000000000000000000000000000000000000000000000000000002dc9": "943d79e4329b86f8e53e8058961955f2b0a205fc3edeea2aae54ba0c22b40c31", + "0x0000000000000000000000000000000000000000000000000000000000002dd3": "66598070dab784e48a153bf9c6c3e57d8ca92bed6592f0b9e9abe308a17aedf0", + "0x0000000000000000000000000000000000000000000000000000000000002ddd": "ac8fe4eb91577288510a9bdae0d5a8c40b8225172379cd70988465d8b98cfa70", + "0x0000000000000000000000000000000000000000000000000000000000002de7": "2b0018a8548e5ce2a6b6b879f56e3236cc69d2efff80f48add54efd53681dfce", + "0x0000000000000000000000000000000000000000000000000000000000002df1": "823445936237e14452e253a6692290c1be2e1be529ddbeecc35c9f54f7ea9887", + "0x0000000000000000000000000000000000000000000000000000000000002dfb": "3051a0d0701d233836b2c802060d6ee629816c856a25a62dc73bb2f2fc93b918", + "0x0000000000000000000000000000000000000000000000000000000000002e05": "44a50fda08d2f7ca96034186475a285a8a570f42891f72d256a52849cb188c85", + "0x0000000000000000000000000000000000000000000000000000000000002e0f": "6e60069a12990ef960c0ac825fd0d9eb44aec9eb419d0df0c25d7a1d16c282e7", + "0x0000000000000000000000000000000000000000000000000000000000002e19": "581ddf7753c91af00c894f8d5ab22b4733cfeb4e75c763725ebf46fb889fa76a", + "0x0000000000000000000000000000000000000000000000000000000000002e23": "9a1dfba8b68440fcc9e89b86e2e290367c5e5fb0833b34612d1f4cfc53189526", + "0x0000000000000000000000000000000000000000000000000000000000002e2d": "54a623060b74d56f3c0d6793e40a9269c56f90bcd19898855113e5f9e42abc2d", + "0x0000000000000000000000000000000000000000000000000000000000002e37": "1cfeb8cd5d56e1d202b4ec2851f22e99d6ad89af8a4e001eb014b724d2d64924", + "0x0000000000000000000000000000000000000000000000000000000000002e41": "ad223cbf591f71ffd29e2f1c676428643313e3a8e8a7d0b0e623181b3047be92", + "0x0000000000000000000000000000000000000000000000000000000000002e4b": "e13f31f026d42cad54958ad2941f133d8bd85ee159f364a633a79472f7843b67", + "0x0000000000000000000000000000000000000000000000000000000000002e55": "b45099ae3bbe17f4417d7d42951bd4425bce65f1db69a354a64fead61b56306d", + "0x0000000000000000000000000000000000000000000000000000000000002e5f": "9d2b65379c5561a607df4dae8b36eca78818acec4455eb47cfa437a0b1941707", + "0x0000000000000000000000000000000000000000000000000000000000002e69": "5855b3546d3becda6d5dd78c6440f879340a5734a18b06340576a3ce6a48d9a0", + "0x0000000000000000000000000000000000000000000000000000000000002e73": "d6a61c76ae029bb5bca86d68422c55e8241d9fd9b616556b375c91fb7224b79e", + "0x0000000000000000000000000000000000000000000000000000000000002e7d": "96ac5006561083735919ae3cc8d0762a9cba2bdefd4a73b8e69f447f689fba31", + "0x0000000000000000000000000000000000000000000000000000000000002e87": "4ced18f55676b924d39aa7bcd7170bac6ff4fbf00f6a800d1489924c2a091412", + "0x0000000000000000000000000000000000000000000000000000000000002e91": "c95a6a7efdbefa710a525085bcb57ea2bf2d4ae9ebfcee4be3777cfcc3e534ea", + "0x0000000000000000000000000000000000000000000000000000000000002e9b": "2b2917b5b755eb6af226e16781382bd22a907c9c7411c34a248af2b5a0439079", + "0x0000000000000000000000000000000000000000000000000000000000002ea5": "18d5804f2e9ad3f891ecf05e0bfc2142c2a9f7b4de03aebd1cf18067a1ec6490", + "0x0000000000000000000000000000000000000000000000000000000000002eaf": "b47682f0ce3783700cbe5ffbb95d22c943cc74af12b9c79908c5a43f10677478", + "0x0000000000000000000000000000000000000000000000000000000000002eb9": "e4b60e5cfb31d238ec412b0d0e3ad9e1eb00e029c2ded4fea89288f900f7db0e", + "0x0000000000000000000000000000000000000000000000000000000000002ec3": "fc0ea3604298899c10287bba84c02b9ec5d6289c1493e9fc8d58920e4eaef659", + "0x0000000000000000000000000000000000000000000000000000000000002ecd": "4c3301a70611b34e423cf713bda7f6f75bd2070f909681d3e54e3a9a6d202e5a", + "0x0000000000000000000000000000000000000000000000000000000000002ed7": "84a5b4e32a62bf3298d846e64b3896dffbbcc1fafb236df3a047b5223577d07b", + "0x0000000000000000000000000000000000000000000000000000000000002ee1": "ff70b97d34af8e2ae984ada7bc6f21ed294d9b392a903ad8bbb1be8b44083612", + "0x0000000000000000000000000000000000000000000000000000000000002eeb": "73e186de72ef30e4be4aeebe3eaec84222f8a325d2d07cd0bd1a49f3939915ce", + "0x0000000000000000000000000000000000000000000000000000000000002ef5": "ed185ec518c0459392b274a3d10554e452577d33ecb72910f613941873e61215", + "0x0000000000000000000000000000000000000000000000000000000000002eff": "5cfbad3e509733bce64e0f6492b3886300758c47a38e9edec4b279074c7966d4", + "0x0000000000000000000000000000000000000000000000000000000000002f09": "867a7ab4c504e836dd175bd6a00e8489f36edaeda95db9ce4acbf9fb8df28926", + "0x0000000000000000000000000000000000000000000000000000000000002f13": "0d01993fd605f101c950c68b4cc2b8096ef7d0009395dec6129f86f195eb2217", + "0x0000000000000000000000000000000000000000000000000000000000002f1d": "8e14fd675e72f78bca934e1ffad52b46fd26913063e7e937bce3fa11aed29075", + "0x0000000000000000000000000000000000000000000000000000000000002f27": "4ec1847e4361c22cdecc67633e244b9e6d04ec103f4019137f9ba1ecc90198f4", + "0x0000000000000000000000000000000000000000000000000000000000002f31": "ec69e9bbb0184bf0889df50ec7579fa4029651658d639af456a1f6a7543930ef", + "0x0000000000000000000000000000000000000000000000000000000000002f3b": "efdd626048ad0aa6fcf806c7c2ad7b9ae138136f10a3c2001dc5b6c920db1554", + "0x0000000000000000000000000000000000000000000000000000000000002f45": "551de1e4cafd706535d77625558f8d3898173273b4353143e5e1c7e859848d6b", + "0x0000000000000000000000000000000000000000000000000000000000002f4f": "137efe559a31d9c5468259102cd8634bba72b0d7a0c7d5bcfc449c5f4bdb997a", + "0x0000000000000000000000000000000000000000000000000000000000002f59": "fb0a1b66acf5f6bc2393564580d74637945891687e61535aae345dca0b0f5e78", + "0x0000000000000000000000000000000000000000000000000000000000002f63": "96eea2615f9111ee8386319943898f15c50c0120b8f3263fab029123c5fff80c", + "0x0000000000000000000000000000000000000000000000000000000000002f6d": "68725bebed18cd052386fd6af9b398438c01356223c5cc15f49093b92b673eff", + "0x0000000000000000000000000000000000000000000000000000000000002f77": "e2f1e4557ed105cf3bd8bc51ebaa4446f554dcb38c005619bd9f203f4494f5dd", + "0x0000000000000000000000000000000000000000000000000000000000002f81": "48ef06d84d5ad34fe56ce62e095a34ea4a903bf597a8640868706af7b4de7288", + "0x0000000000000000000000000000000000000000000000000000000000002f8b": "5c57714b2a85d0d9331ce1ee539a231b33406ec19adcf1d8f4c88ab8c1f4fbae", + "0x0000000000000000000000000000000000000000000000000000000000002f95": "204299e7aa8dfe5328a0b863b20b6b4cea53a469d6dc8d4b31c7873848a93f33", + "0x0000000000000000000000000000000000000000000000000000000000002f9f": "b74eea6df3ce54ee9f069bebb188f4023673f8230081811ab78ce1c9719879e5", + "0x0000000000000000000000000000000000000000000000000000000000002fa9": "af5624a3927117b6f1055893330bdf07a64e96041241d3731b9315b5cd6d14d7", + "0x0000000000000000000000000000000000000000000000000000000000002fb3": "c657b0e79c166b6fdb87c67c7fe2b085f52d12c6843b7d6090e8f230d8306cda", + "0x0000000000000000000000000000000000000000000000000000000000002fbd": "a0e08ceff3f3c426ab2c30881eff2c2fc1edf04b28e1fb38e622648224ffbc6b", + "0x0000000000000000000000000000000000000000000000000000000000002fc7": "c9792da588df98731dfcbf54a6264082e791540265acc2b3ccca5cbd5c0c16de", + "0x0000000000000000000000000000000000000000000000000000000000002fd1": "c74f4bb0f324f42c06e7aeacb9446cd5ea500c3b014d5888d467610eafb69297", + "0x0000000000000000000000000000000000000000000000000000000000002fdb": "1acd960a8e1dc68da5b1db467e80301438300e720a450ab371483252529a409b", + "0x0000000000000000000000000000000000000000000000000000000000002fe5": "6cef279ba63cbac953676e889e4fe1b040994f044078196a6ec4e6d868b79aa1", + "0x0000000000000000000000000000000000000000000000000000000000002fef": "60eb986cb497a0642b684852f009a1da143adb3128764b772daf51f6efaae90a", + "0x0000000000000000000000000000000000000000000000000000000000002ff9": "c50024557485d98123c9d0e728db4fc392091f366e1639e752dd677901681acc", + "0x0000000000000000000000000000000000000000000000000000000000003003": "b860632e22f3e4feb0fdf969b4241442eae0ccf08f345a1cc4bb62076a92d93f", + "0x000000000000000000000000000000000000000000000000000000000000300d": "21085bf2d264529bd68f206abc87ac741a2b796919eeee6292ed043e36d23edb", + "0x0000000000000000000000000000000000000000000000000000000000003017": "80052afb1f39f11c67be59aef7fe6551a74f6b7d155a73e3d91b3a18392120a7", + "0x0000000000000000000000000000000000000000000000000000000000003021": "a3b0793132ed37459f24d6376ecfa8827c4b1d42afcd0a8c60f9066f230d7675", + "0x000000000000000000000000000000000000000000000000000000000000302b": "e69d353f4bc38681b4be8cd5bbce5eb4e819399688b0b6225b95384b08dcc8b0", + "0x0000000000000000000000000000000000000000000000000000000000003035": "221e784d42a121cd1d13d111128fcae99330408511609ca8b987cc6eecafefc4", + "0x000000000000000000000000000000000000000000000000000000000000303f": "dcd669ebef3fb5bebc952ce1c87ae4033b13f37d99cf887022428d024f3a3d2e", + "0x0000000000000000000000000000000000000000000000000000000000003049": "4dd1eb9319d86a31fd56007317e059808f7a76eead67aecc1f80597344975f46", + "0x0000000000000000000000000000000000000000000000000000000000003053": "5e1834c653d853d146db4ab6d17509579497c5f4c2f9004598bcd83172f07a5f", + "0x000000000000000000000000000000000000000000000000000000000000305d": "9f78a30e124d21168645b9196d752a63166a1cf7bbbb9342d0b8fee3363ca8de", + "0x0000000000000000000000000000000000000000000000000000000000003067": "1f7c1081e4c48cef7d3cb5fd64b05135775f533ae4dabb934ed198c7e97e7dd8", + "0x0000000000000000000000000000000000000000000000000000000000003071": "4d40a7ec354a68cf405cc57404d76de768ad71446e8951da553c91b06c7c2d51", + "0x000000000000000000000000000000000000000000000000000000000000307b": "f653da50cdff4733f13f7a5e338290e883bdf04adf3f112709728063ea965d6c", + "0x0000000000000000000000000000000000000000000000000000000000003085": "259ab95f666ac488c7d45e2a64d6f6c2bb8dc740b23d3e94a04617a0a3fbe0eb", + "0x000000000000000000000000000000000000000000000000000000000000308f": "c4b808157fad1819c40973c2712d24ce49df04f8ad955ad0373625dcbcc5aa7b", + "0x0000000000000000000000000000000000000000000000000000000000003099": "e7c5536cfd18a67450339a94845bc86835cab1386e7f8b3eff0b4e23e706c23e", + "0x00000000000000000000000000000000000000000000000000000000000030a3": "8f5d7fbf3369ffcc9cc71dc871a54df7fd2f391054043e91f4afd27937ad2571", + "0x00000000000000000000000000000000000000000000000000000000000030ad": "77b7c55aa160a8bb8011b7132e25c90653a099d1e2925643721c979dde14c1c2", + "0x00000000000000000000000000000000000000000000000000000000000030b7": "9cd67bbefa6a7a9ae1eab06e461086b6bad850bfb0bda838ea83dc58d0c20feb", + "0x00000000000000000000000000000000000000000000000000000000000030c1": "060aba9d44a5513488273214452bed1c1e85dc18695bf28a44d98dd24d20cee5", + "0x00000000000000000000000000000000000000000000000000000000000030cb": "d5fc23888bb73b0a9c6bf06b969040c7be41d5bfcbaf51388390fe09abbfe03f", + "0x00000000000000000000000000000000000000000000000000000000000030d5": "7e0f61114c9e1271a083af0112a3d8e75c1945bdbf4436b2d06604cdd3e48ed4", + "0x00000000000000000000000000000000000000000000000000000000000030df": "8a6f4493c846bfcfb55e3813f2be3ce8a97c822d88bbf56ebe6070da480dca20", + "0x00000000000000000000000000000000000000000000000000000000000030e9": "83e6fd189fd00cd332b6a76e3806367f086beb3e0fd0060c0a3574d10cf86c8a", + "0x00000000000000000000000000000000000000000000000000000000000030f3": "775e887c6cb79392692d17fc58f861a98e70d013afd252b2a644073fa185034c", + "0x00000000000000000000000000000000000000000000000000000000000030fd": "d6f95bc3e63325669aa3b41a80caaaa350031821fc65f792cec135bbfca7b9a9", + "0x0000000000000000000000000000000000000000000000000000000000003107": "cbaab7c932a6465b5c3ff1d248ca02300484a6e6e9b6140983daeb58eb16a434", + "0x0000000000000000000000000000000000000000000000000000000000003111": "a0d5f4fbf6dcc49bee52b3f185c619817e08a3dff2bfd11cfae07557bf3e5727", + "0x000000000000000000000000000000000000000000000000000000000000311b": "7bcd5ed57e123ed0d2a16b433c4e584231867efef22b4903b0de3dba6c0249ff", + "0x0000000000000000000000000000000000000000000000000000000000003125": "24054b31c796a86751c71d8f0113d6f56397bc46dec675697960c4ee6d1370d7", + "0x000000000000000000000000000000000000000000000000000000000000312f": "6a3a65f6fcf34e82edbc10f8ce17c7aac559454d22b5f8b865b0b26182a791b2", + "0x0000000000000000000000000000000000000000000000000000000000003139": "43a4a75cdb8ddebc28bf09b4ae12d71dc0765defafcd384de22c3711726a5d80", + "0x0000000000000000000000000000000000000000000000000000000000003143": "0d9b141fe39d89d2bedec5f3d98f0533f43a4d7c407d4df1e3faa9a386875fb0", + "0x000000000000000000000000000000000000000000000000000000000000314d": "06747e12a0ff61f487ca91cc386c696148d6e20a1ece40d5a3528a3899f0536d", + "0x0000000000000000000000000000000000000000000000000000000000003157": "7886c0928a9559d88002185e1f2474adc78ea9c997a343656449cbb6ec97d65b", + "0x0000000000000000000000000000000000000000000000000000000000003161": "c00472c88e5c05094693f81159e3b89cc45cac9dde868c41e1e418f6f09c8fbc", + "0x000000000000000000000000000000000000000000000000000000000000316b": "c8d220c2229f22cc81c69ebdd7e54d6964acbe0d550eacc6a83eb488c4d5bda8", + "0x0000000000000000000000000000000000000000000000000000000000003175": "26f2e58f0750c1fe9056a9a6392d3ef6af4c7ffc78033e2c42e9fdf96ca15361", + "0x000000000000000000000000000000000000000000000000000000000000317f": "8aae197b8ccf12c586225a94624141507808c6ab7ee29e9ee6e324d01557fd5e", + "0x0000000000000000000000000000000000000000000000000000000000003189": "946d6d60fe20c81d1cf507d2a9567fc06ea539ac3a542d283373ccee3f82212d", + "0x0000000000000000000000000000000000000000000000000000000000003193": "c43169ff521bf0728a5e972911abeacd2f597eff89b961f3132b2f91ce04dc20", + "0x000000000000000000000000000000000000000000000000000000000000319d": "427e24cb2c8355bd1f18d20aa668805a4e4acfa1411ef2ec980839670499c0a7", + "0x00000000000000000000000000000000000000000000000000000000000031a7": "b96ddc711361deb1db8cbe6a3bf2bfa883bce23e2f2260c3a0f3c6758f3fcabb", + "0x00000000000000000000000000000000000000000000000000000000000031b1": "c92246b2394e70d0d0d5c3fd1a5f6c585293d1ee7589b5c8bb37e997e0985b82", + "0x00000000000000000000000000000000000000000000000000000000000031bb": "487f419b494cf102fa1813eb824fe3809d34806cc2548e6a41a9e3f755f6c131", + "0x00000000000000000000000000000000000000000000000000000000000031c5": "4ae0132498c0baaa78d768792661893e0455eea248e8e334e9aabcbec8909a0c", + "0x00000000000000000000000000000000000000000000000000000000000031cf": "b3c4c107e197af6bc4e5542501108ae40e405c8065c54c4f75784b217cddf40a", + "0x00000000000000000000000000000000000000000000000000000000000031d9": "5bb5995473e555f6b3a3649155d6c305866a8266f3a8e6d549fbb4b5c6a785a4", + "0x00000000000000000000000000000000000000000000000000000000000031e3": "034986be3995c99d86ded5f0984cb1c60f4d01157905782157f447054303e1c6", + "0x00000000000000000000000000000000000000000000000000000000000031ed": "ea092ecb252e475b5493c71739404f66771dfe92e90554924e7c979b1ac68c1f", + "0x00000000000000000000000000000000000000000000000000000000000031f7": "70403edcf814de8d55741ccb378648ba8de7893d6affa4ba0e5549d0de6bcb2b", + "0x0000000000000000000000000000000000000000000000000000000000003201": "b8b758a473ba28008dfe949d230cd8a73b4340bc0687cfe8b0326eded2558ba1", + "0x000000000000000000000000000000000000000000000000000000000000320b": "76daa53b1c8d26a50bd4e4eca2703ba4bcad8248f6ad3227ed0af745d19d8ae4", + "0x0000000000000000000000000000000000000000000000000000000000003215": "2143743a63aa6ab5a7a6586dc404e48493f59fcb7021c079cd5e7efbe4a9fc62", + "0x000000000000000000000000000000000000000000000000000000000000321f": "6919ec8682908f8de7753ac9fb4e8fb1b6c0b6cc2d2d1a7df12eef58d8c6c841", + "0x0000000000000000000000000000000000000000000000000000000000003229": "3c61846fc931a63f5fc1fb0dec6dfa5bee9c19104acc5a1dbd0fdfe331827dca", + "0x0000000000000000000000000000000000000000000000000000000000003233": "65e7c42e7c1674ca5d52dacbd9fdc6fad75a0cd87294e8641c56aaf12092774c", + "0x000000000000000000000000000000000000000000000000000000000000323d": "d17d5eec3cbd76848cac5f8fb453911fcf5d896670703252da7925f33f6597ca", + "0x0000000000000000000000000000000000000000000000000000000000003247": "aa5ae82882c7a2a53ab35d0499ae76069be55e70153ee47d3c712f48f24be400", + "0x0000000000000000000000000000000000000000000000000000000000003251": "5cd2ace5b0d5e6867c6d71e22516a625f6c5ab69e7067998cb789a2867c96b8e", + "0x000000000000000000000000000000000000000000000000000000000000325b": "c5ff6ef86066abbe0d48a2de1a1a2c4a5e9c695a1be00ada4e3ab8402b15b476", + "0x0000000000000000000000000000000000000000000000000000000000003265": "1b68873106bbf102095733021e2f7f49c4822f297c0930460d6358864868e09d", + "0x000000000000000000000000000000000000000000000000000000000000326f": "c55e7bb8bdeeaaae3b84adac51bddd9ba7a8c23b66e1a73325fef138edbe1fcc", + "0x0000000000000000000000000000000000000000000000000000000000003279": "b9b10d869f9b60ca46c5484073a0bb44fe92a031955f3555ed291fe0ffd8328a", + "0x0000000000000000000000000000000000000000000000000000000000003283": "ba29f52ef7aa5b2c71b61919ff7890c9c8d37234ba7fde07a58301b90296e3b2", + "0x000000000000000000000000000000000000000000000000000000000000328d": "990f0ab0ebf53ff997b27d831eb969965736cabf07d38003adb40a66d0a758bd", + "0x0000000000000000000000000000000000000000000000000000000000003297": "bda84af9ce3c88c3243669481454971f19d18b777e3a15ab7d87a7559d77ed43", + "0x00000000000000000000000000000000000000000000000000000000000032a1": "2c5d55a9ee442f1a84215cfcc70e2fe9ca0504b238c4b121587b015a43a8feed", + "0x00000000000000000000000000000000000000000000000000000000000032ab": "02e3afb0a7cbd95fb5926b8e9ca36f742f6a9981ed37f1a6dec56be6bf1081bc", + "0x00000000000000000000000000000000000000000000000000000000000032b5": "ead6fe3098cd7db5dbe406cbf0977458fe24bdba875ac5964f42607c7756ece3", + "0x00000000000000000000000000000000000000000000000000000000000032bf": "f10709ee045c777c61651e6ccf2b40b539f12fdb42642af7eaeb020ed05b1a15", + "0x00000000000000000000000000000000000000000000000000000000000032c9": "d60510beb7cc6faff2dbdf5571982f0fe16806f7099f5b96be88b34c884ad75d", + "0x00000000000000000000000000000000000000000000000000000000000032d3": "52d158762abaf754f45eedfacbdfe8d5d4cea5ecbca4315e9c42c14e22021a10", + "0x00000000000000000000000000000000000000000000000000000000000032dd": "542256a140e92ed9eb4280c21acc962f287cb81fdb913adad4ca43b89d3a7920", + "0x00000000000000000000000000000000000000000000000000000000000032e7": "79b058ec1c5cbe0920b5952501060f137989ac99cce216800bd06649890c3be1", + "0x00000000000000000000000000000000000000000000000000000000000032f1": "f4c5320c831d84242a9194e38951a279654456e3eb90f3712c14fdac4d326723", + "0x00000000000000000000000000000000000000000000000000000000000032fb": "c00307f2fde3105322eab259007d6fdfda80cef1b9472584e82bb321d1827305", + "0x0000000000000000000000000000000000000000000000000000000000003305": "f64129691e90ca381d267b0e80bcd562d68049c21d623c8ac7284edf560bf253", + "0x000000000000000000000000000000000000000000000000000000000000330f": "730279e1ea668c639d5c41d5d4cbb1b7f474dc359bc977017be59d5c4da6c2e4", + "0x0000000000000000000000000000000000000000000000000000000000003319": "09d9cafda4e28b50bba8823b4bf20a39646b273df60467b5cba6bcd04a9e417d", + "0x0000000000000000000000000000000000000000000000000000000000003323": "b0424ee936aae94e0394ede6947b15427dc1664a14d82a17969162ec6e838ec3", + "0x000000000000000000000000000000000000000000000000000000000000332d": "bbe5b3daa5def4caff6e3e2ccaa0d77694cb0886d68b6844888838d720c8a1ad", + "0x0000000000000000000000000000000000000000000000000000000000003337": "29cf1633458442d2d60c8597fd7e8e3032c77f715695390f6c6c79a56a1f6c41", + "0x0000000000000000000000000000000000000000000000000000000000003341": "af082fe588954fe25630edd8bb48a91725372f8615834cfa45e1994b2fe75b84", + "0x000000000000000000000000000000000000000000000000000000000000334b": "1d2385a885bc5bbab703e39a21c87909b765fee7808ceb7d64f6e0e1dcdbeada", + "0x0000000000000000000000000000000000000000000000000000000000003355": "9f7e031c508d86e139947f5b167bce022363da48a40dc260d10b7056ac51cf31", + "0x000000000000000000000000000000000000000000000000000000000000335f": "ae2de0af5de73a96ed6b567a73e6a11b603d6cd010885f5c0311faafa922f2cf", + "0x0000000000000000000000000000000000000000000000000000000000003369": "25b6a571ef6a73ada1798c7c6f5c6bfafe256c766329fec4f10bf8bad197ef43", + "0x0000000000000000000000000000000000000000000000000000000000003373": "a13ee26b6abfa659eab111d6d431ab808f24de841d7946e3972c71f886cf3b7e", + "0x000000000000000000000000000000000000000000000000000000000000337d": "7472248ce56a1577d4471f3da8cf5cde06f8950286675ca5a1194796a28a4005", + "0x0000000000000000000000000000000000000000000000000000000000003387": "b152754c5a5cc6999ca01b88a6d422090559b16c7ead087411458740c57a128a", + "0x0000000000000000000000000000000000000000000000000000000000003391": "651093fcc06254ac1de6075cba7da2cd7406b6a90a0f1425a26c7496f2f60dab", + "0x000000000000000000000000000000000000000000000000000000000000339b": "b93351b11b6a73ecb4818697b1ee7cea2eaf192a56caf8df1454b9bc7510f722", + "0x00000000000000000000000000000000000000000000000000000000000033a5": "7f4e75a6d4ab8d9dbe0728bda7f7ebf8bdc1942aecc5912f25573fdb9bafe803", + "0x00000000000000000000000000000000000000000000000000000000000033af": "767177cd603c7e3eb94583c38141b0d701b15631173ffb7a35beb5a7515c7fff", + "0x00000000000000000000000000000000000000000000000000000000000033b9": "b7cbac00a090b3cf081c92da779bab61f22c7f83e8b9c5dce4e91c8c1d208b7c", + "0x00000000000000000000000000000000000000000000000000000000000033c3": "38a90f286b0a1fe34e7d3b9ff797c39789970041d2818e5adc11b91e0579537c", + "0x00000000000000000000000000000000000000000000000000000000000033cd": "c19bcd1a95bf2edb1eaa8cf59fb23d053422845e57f4a41a2832500d1f415f5a", + "0x00000000000000000000000000000000000000000000000000000000000033d7": "1beb8053a04c4c9a4a885576977da294a141c196be9e4af9fd21d7801196559f", + "0x00000000000000000000000000000000000000000000000000000000000033e1": "6514900951391e916e7d78ae0340e1fa0cd5b3e4c1319438aa4db66177eba45c", + "0x00000000000000000000000000000000000000000000000000000000000033eb": "96836b3cb8f807083b6a006ae323d1e829d82357fedc171e8d20dacfe39755a9", + "0x00000000000000000000000000000000000000000000000000000000000033f5": "b4e2322123051b7ae894776aba06808205c6bf96a70e56b0c628a51408e5c28e", + "0x00000000000000000000000000000000000000000000000000000000000033ff": "db00a732067d4f7ab43e113731f05922c7acc4c9d937dcf77cca57ed319b3290", + "0x0000000000000000000000000000000000000000000000000000000000003409": "085cd56145b890e872ccab3784b1ec282a8adf95bb90f918fb400c03ca25b188", + "0x0000000000000000000000000000000000000000000000000000000000003413": "43fc6f30f79ff0be21aab95d8db8fa7b819fa91382063a80f286051f9f2d9aa9", + "0x000000000000000000000000000000000000000000000000000000000000341d": "bb26c41420c8eccc97109bec0db605657b7ad911842ea5c892af203f5dc72b0a", + "0x0000000000000000000000000000000000000000000000000000000000003427": "79e7d775b35bea6224afd7e2f838079f88413410f667f16dcaf54f2124a68de7", + "0x0000000000000000000000000000000000000000000000000000000000003431": "5f4be0643a56b90ece82db7ff08963e8d9796840afd11d6a1d0d39b4498fa26e", + "0x000000000000000000000000000000000000000000000000000000000000343b": "15b308f32252d593d6f48353f3217f10c391d03cff6eb9742f3bccbe6d1d6145", + "0x0000000000000000000000000000000000000000000000000000000000003445": "959068ffcb9b2830276c8aba06e7272d43aa3aa1b7220b9357ccf0f57c3c004d", + "0x000000000000000000000000000000000000000000000000000000000000344f": "e75e86a54290b92d8664fb2f08a2f88c05b4d97d79fe482da765f8386c614f", + "0x0000000000000000000000000000000000000000000000000000000000003459": "2b736a8b6f16cc86e1adc0f2970e29ca45ed79734255a30ecf92a40549d7bd56", + "0x0000000000000000000000000000000000000000000000000000000000003463": "c46c8a987f02fc5b5185de4713c08a87ff4de7c745df1d52326418c60ab262b2", + "0x000000000000000000000000000000000000000000000000000000000000346d": "4c5566cbcba6320f9081048390d01c905f9bc09b731d3e7f6d41a463755a8b58", + "0x0000000000000000000000000000000000000000000000000000000000003477": "da6fa07274e44043f94ee45fa0ceb22272d43aa0af21c6c9cc97edc786407138", + "0x0000000000000000000000000000000000000000000000000000000000003481": "874290457e263452e8d382faa3fbe492ccdb28cee1c8a5ff61c039977c20c053", + "0x000000000000000000000000000000000000000000000000000000000000348b": "0ffe5e304347d11e92a03004fd66c66fb058267e5c835b2ff6f4dade1ed6159e", + "0x0000000000000000000000000000000000000000000000000000000000003495": "9ae315e6ecd4a85e734e737190ea4501b8d0f5d0885ccaa267509bddb290bd07", + "0x000000000000000000000000000000000000000000000000000000000000349f": "b9808a96196fba3329eb714aa00743098723d9850510689ad18fd6952b655882", + "0x00000000000000000000000000000000000000000000000000000000000034a9": "3cacbae26791d03a0ba1bec3ba0599219257c88708b022bbddb7e7673ef818e1", + "0x00000000000000000000000000000000000000000000000000000000000034b3": "97874b014835a49286b4ea56d5a282b34220b0950c69558ef0e38877061c88d9", + "0x00000000000000000000000000000000000000000000000000000000000034bd": "30671eff1dd3e3e79d6269eacaca22ff3b4d4fd320a192c10d9cfa56d5553c3a", + "0x00000000000000000000000000000000000000000000000000000000000034c7": "d8d54c092190a712f5ac8e0a4b7e10b349220075f76775f9e4c4d4890954999a", + "0x00000000000000000000000000000000000000000000000000000000000034d1": "b3e8460e8c6dccf295d6a48d8335d66e44d66ce1a1a422340fa5851b4eee9d88", + "0x00000000000000000000000000000000000000000000000000000000000034db": "6c0b1e570cc4d4a7db18835084f04878f61c4c184bb120ade6d0079cdddc0f03", + "0x00000000000000000000000000000000000000000000000000000000000034e5": "22590be535e87808bcbfed1999053f2a159b4ec2d830ee2983ebd95b2c7cb7e9", + "0x00000000000000000000000000000000000000000000000000000000000034ef": "5c147544dcb51e46004d656f863d8c78c08d7801fa1142e9c81e231ceab7f91c", + "0x00000000000000000000000000000000000000000000000000000000000034f9": "9579f88762d50f0b88eb438cc616ce1a2fce24a0655bfa18c17600f37bcd84a9", + "0x0000000000000000000000000000000000000000000000000000000000003503": "be71754b5029b99b3f84d2f972f2f3364e404e211f30737d6e19fe2ed70bd3a1", + "0x000000000000000000000000000000000000000000000000000000000000350d": "72ac7ccbdef2d82e39f5ea95cccfdb59f5d1c4a9a83e7e32a275dd2cf71db91b", + "0x0000000000000000000000000000000000000000000000000000000000003517": "2f72d33db4de041ba2707492686a6f045671d2b63383cc70a770a94f39244793", + "0x0000000000000000000000000000000000000000000000000000000000003521": "400bbdb9ea1f1982431a31e5d0830c0affe0fbd940c7083bdc1d774e0f6cd9cd", + "0x000000000000000000000000000000000000000000000000000000000000352b": "e010c49cc710b1249238f6dbda9f74d529142c897b1b786eee0e01a41751ccd0", + "0x0000000000000000000000000000000000000000000000000000000000003535": "4130c014364b543cbea200a882ca0e2ee707740042e3b252f079f4774e906e72", + "0x000000000000000000000000000000000000000000000000000000000000353f": "506cb52170cb9a25fec6c4454c306efa32f9368e4a71b333a1b211ad18a45d1b", + "0x0000000000000000000000000000000000000000000000000000000000003549": "adfba1e3ff9978ca95fd32570e09cb9ff7d6c8874aa044e0aaaaa2771443405a", + "0x0000000000000000000000000000000000000000000000000000000000003553": "2f527ed6b4ddae83034b3cd789d451f3b7131bd8f196126cb60f0754cf15fca3", + "0x000000000000000000000000000000000000000000000000000000000000355d": "a72fcd0c929130353532dc56f8c43a7e4ba9748f56fa2f3cb39bff62b4ce04bf", + "0x0000000000000000000000000000000000000000000000000000000000003567": "295fe8a5ddc346bf5e6f66db4e8961178d57e41915af94f89da7d40ece7b8f70", + "0x0000000000000000000000000000000000000000000000000000000000003571": "673fd177d3d2b3486f6250e98100855417df12d7a090b7ed709bba223e03276e", + "0x000000000000000000000000000000000000000000000000000000000000357b": "c5ea3d95ee2c22d741f6c48ac6d87e445e826cc8f6d25a1b2c12f3d9a447a353", + "0x0000000000000000000000000000000000000000000000000000000000003585": "4085071556a9ec9d229d1d9b802b3e89cdd093f9f9139ea42eb5abe892541ff8", + "0x000000000000000000000000000000000000000000000000000000000000358f": "220bddb698fba55c2a96db728cf5caffae495e6903a27d57e74e61991634a7e3", + "0x0000000000000000000000000000000000000000000000000000000000003599": "1f6b1570460ec8766ca6e568bd30d50175e71cc8ae45039bfbd2e82ca991041f", + "0x00000000000000000000000000000000000000000000000000000000000035a3": "d323f7e63c7ee0244d6795f2d05907b6d0361e6e8b5757cdcff96f2ade53e181", + "0x00000000000000000000000000000000000000000000000000000000000035ad": "c7709a90d90185b34b5d069558a1a0e23279c82cb5b9c80b9a054a1747a100b2", + "0x00000000000000000000000000000000000000000000000000000000000035b7": "f41d4fd21005f25600285ed8c8119a41a59af6c0c295cb06a26a29f87ff25aba", + "0x00000000000000000000000000000000000000000000000000000000000035c1": "925086e21edd2723f3b5556821ac5a4bdc2ff1f673ac084cbac931be2ba37290", + "0x00000000000000000000000000000000000000000000000000000000000035cb": "2662096fc52fdc578d134fceb1b462236b7003d5f2228536b1b3e9642a49e0d3", + "0x00000000000000000000000000000000000000000000000000000000000035d5": "13bc04c697ce8353ef9332bf77b0a9dfaa3b46750477b2d6c3ec0320b667fa44", + "0x00000000000000000000000000000000000000000000000000000000000035df": "5c9c995de8502ece5f040c187feb066888f95c5c18f19e26d22fd33c214f1797", + "0x00000000000000000000000000000000000000000000000000000000000035e9": "80e9466bece8ddfabc70825bcec4e24aa55e1acf4ede6dc91e58bbd507b89106", + "0x00000000000000000000000000000000000000000000000000000000000035f3": "b60ebee302c2151ccc37af32e3613b07defd9503e344434d344ba3f8331954fa", + "0x00000000000000000000000000000000000000000000000000000000000035fd": "11c42898638189fe88536cc1845ddf768fc26b99b993c356b1f5dcc14dcadccb", + "0x0000000000000000000000000000000000000000000000000000000000003607": "b623473143c27ada98b34a5cfcbabf6b70860e562953e346a03770e4237b16c8", + "0x0000000000000000000000000000000000000000000000000000000000003611": "eb4739b0ae9d202f1529006ae74d98da58dbec8dfad38902ca920e6923beb35b", + "0x000000000000000000000000000000000000000000000000000000000000361b": "506e559f06fc9dbf1609acbdc09d2ae31dc353794a5f742e2645791d3b9b92b2", + "0x0000000000000000000000000000000000000000000000000000000000003625": "3cf622b6ae96fd95cb12ce270854ed7ae4f651268000e01e37574dfc0f33ce6f", + "0x000000000000000000000000000000000000000000000000000000000000362f": "eeef194c98225e4ce5119ad6bf465ff5b4a542475152471fbe5bb408035137b5", + "0x0000000000000000000000000000000000000000000000000000000000003639": "d8d4edf4122ac50f05b76868187eefbe56393c634490733ab80b12adf4fee4ff", + "0x0000000000000000000000000000000000000000000000000000000000003643": "05efbc961556af4359a25fa1bb0ade5e3dd4b058ef14e80b0aaeee81da998c26", + "0x000000000000000000000000000000000000000000000000000000000000364d": "65490c264abcd05d08f11c260d49dc0f2c55f3459f2f902400cc3751ae16115d", + "0x0000000000000000000000000000000000000000000000000000000000003657": "a662fe4e7f5b359da22861957ebabef233d14df689a0a378333f9caaae8ddcc1", + "0x0000000000000000000000000000000000000000000000000000000000003661": "4e99f494a9bb40f134a5ef00de1bcdf3f971b37c873330d5aeb3d49efbcb4c00", + "0x000000000000000000000000000000000000000000000000000000000000366b": "67e21c966ca98e58bd6989dff5e94d2bd4e74bd63e0c1419a6d1af34e7cf6a20", + "0x0000000000000000000000000000000000000000000000000000000000003675": "e359cbd3a9dff480adcd4cd1aae545e0a0043a076ab291d897dee9316e8a6286", + "0x000000000000000000000000000000000000000000000000000000000000367f": "a35fac8a05400bf2a27ce6d8720f3c0bcaf373aede26d8b2b858ebfae843a327", + "0x0000000000000000000000000000000000000000000000000000000000003689": "5b5c8208e8820c4e2730cf589ab50d61729dfd14468f06ec0ec9f7941a64f0db", + "0x0000000000000000000000000000000000000000000000000000000000003693": "fdc9e6eb33d8f37b2d9599ab0c98fbbb7cada3861352e1244d31d2ec5d4acf49", + "0x000000000000000000000000000000000000000000000000000000000000369d": "380c81a5a4ff1291139f4d753060a10393993331c5c422be8f84788bd29709ef", + "0x00000000000000000000000000000000000000000000000000000000000036a7": "84f551d9aedb25cafb6326fd75774b6bd3a7e13666cdf07ed4f43989915856f4", + "0x00000000000000000000000000000000000000000000000000000000000036b1": "724715f1a28b0b873df27b080122f16d318ae96da7d3adc1ca1e06ed62fa7c19", + "0x00000000000000000000000000000000000000000000000000000000000036bb": "a3fa3c1b9234dd7e0e566d7f8b57a65f8c4b39d7a0a2346e822afd34a6852a80", + "0x00000000000000000000000000000000000000000000000000000000000036c5": "f48ee127fa2d3b4a69eff4f11cc838cf34b88ea4eb595db690e2f098af6dc64e", + "0x00000000000000000000000000000000000000000000000000000000000036cf": "0c047872d9588bf22e89ea7ec207e8be8486d0bfa775d147ea49b25a9847b3c6", + "0x00000000000000000000000000000000000000000000000000000000000036d9": "855d87626620858c83ac8ac407d521c183da8a43964f92d9b9285389f90a6d02", + "0x00000000000000000000000000000000000000000000000000000000000036e3": "7101dac063e1ce1cb178112d72d1b8abbd9615086ef636f6655d652e70f2aa64", + "0x00000000000000000000000000000000000000000000000000000000000036ed": "506d8aa3d5c8509b51930509c98cf6f5badc86968812fe7ab2d4762d9352f4e3", + "0x00000000000000000000000000000000000000000000000000000000000036f7": "95ea210881696a1062dddaf3b2b082b5c4bf40e8232113d7b86da72999b1d2ba", + "0x0000000000000000000000000000000000000000000000000000000000003701": "0c83a90f2b9a311c3cd7c7643087802a075de0891995be8c92a6b6e1891778dc", + "0x000000000000000000000000000000000000000000000000000000000000370b": "aa9ef93934d889062636008fcf4837d7b8d272bbd14e81b50b2248a4911d7c67", + "0x0000000000000000000000000000000000000000000000000000000000003715": "f0c8a0bbba4bed135f2022b60bc785bd514b1c5b7f3db99c37124f5bcd403c", + "0x000000000000000000000000000000000000000000000000000000000000371f": "08e29d129649f398887792f5fa5eff38572306a1efb3604008b74eca49c40774", + "0x0000000000000000000000000000000000000000000000000000000000003729": "64fa01a0000ef58c90fac82ae28c33b45f947097be7cf43737d60e6568486204", + "0x0000000000000000000000000000000000000000000000000000000000003733": "18104f198e6c84cec4875b8b6d2734b6b9b8ce4bbbe158adfa81bfdb239595e2", + "0x000000000000000000000000000000000000000000000000000000000000373d": "64f9ed7df2e19a503f0b6f5b79e4d7b512c66623c28887e7f8968750f081f06a", + "0x0000000000000000000000000000000000000000000000000000000000003747": "020d16dfaa507ca4120cf799ddb20a8998f07a68b2dec691dc61a14e5c929b17", + "0x0000000000000000000000000000000000000000000000000000000000003751": "792b0101e0c969be7fda601c282846dbf3f1216b265d7086b3b1acd49882cce5", + "0x000000000000000000000000000000000000000000000000000000000000375b": "c331bb6e00dfa4489c3cbe3840bd49c936bb3eb6ef0424f076e2b2a3215545ad", + "0x0000000000000000000000000000000000000000000000000000000000003765": "bf47e8a69bb557bccb9c04b516f1c68adaf982a10fdaada6bea4bb12cb40d818", + "0x000000000000000000000000000000000000000000000000000000000000376f": "f5003fc8f92358e790a114bce93ce1d9c283c85e1787f8d7d56714d3489b49e6" }, + "address": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02", "key": "0x37d65eaa92c6bc4c13a5ec45527f0c18ea8932588728769ec7aecfe6d9f32e42" }, - "0x00f691ca9e1403d01344ebbaca0201380cacc99c": { + "0x00F691CA9E1403D01344eBbaCa0201380caCC99C": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "codeHash": "0x414f775e04d169c219a5acda8227220896061f1edcf83d93e9ef0e036e6b07eb", + "code": "0xb8e894a6dd5121be9d2a29c2e1cf16ab2c760e3243306ce88e771a7860df9e85b1e225b71c59213e32f4bb29d456e874b9c97a51f77a8f958e9e475745869be7bb253242668f210ab37ea93841fe0d17a46e78879caed1b4f17f085c8a9963a6830bab64ca008c825ce6fee9d16d63427d5148d6bfa8237fc8acd3ea124b12c65cada8413107c6f4009d62c1355b55832bd0688b7023e5888115d596c1cc5e94da5898a2ce83fbb79921776bda0d9000fbb2244c87f580711e4e2863ca14b405b8c1b99a0a643c89a0443cb185772b972869cfa5fa581f8dc3f977b3df54a682e345b295cb7c8e9f4fa00470e4a0eeeb15892acde8fee168a1403d820087e73d", + "address": "0x00f691ca9e1403d01344ebbaca0201380cacc99c", "key": "0x7c48e400de1f24b4de94c59068fcd91a028576d13a22f900a7fcbd8f4845bcf4" }, - "0x0300100f529a704d19736a8714837adbc934db7f": { + "0x0175C17De53473bbf136e6aF7086B8700B43CF38": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x0175c17de53473bbf136e6af7086b8700b43cf38", + "key": "0xf045ac5237b17e93661fe75054f95cc76df4c3b668f0e4a1d8f5daebc12a85c5" + }, + "0x022916D4E98bF4d48884Ad1cB9c4aA58CbfDc970": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x022916d4e98bf4d48884ad1cb9c4aa58cbfdc970", + "key": "0xf80cab3980ad7df8c2fc9d0f457c7fa62e4a5a2e0e0057ad96302ecc3d1e6cd3" + }, + "0x0242186831F57A6FC1177d96F18B31E8bF67E7AE": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x0242186831f57a6fc1177d96f18b31e8bf67e7ae", + "key": "0x022c043e6e7e719985ea4071080e6532d25dc102f3fffa2d96db43eeae4e8dc6" + }, + "0x0300100F529a704d19736A8714837adbc934db7F": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x730f4b9a001161056466356bac602cec9aea791a93eee35887c5b445c1ba84d2", + "code": "0xa3460b9064575a01ae448ac16880d3d6297c3b1b3ed6401e5e55576437da869cb8268a6811e35185c888408dbd03c24dd26f48c3ed147cffb085165a9b915e99d9c7c9af5ae3bd9d3c51ae123d91d0a46beaa95906b5f109f17d5f466c68dbf5e7484af6bbc8157ed372968cb5ffae804c38bcbc5773bb07433d44bbcc6ebbf0599ef2d67d4a71e24d4f29210ed925ef54d64da410ce44512c56a7a472cfb0df80db63b10209d83bee8914a5717573d21b5817ca696e60bfa859102ac5a737f7e23d3626096a70b8a02737a3c2f960e5732ebae39d6a014de867a32a96f9bd4df5d6daae740c69c53563f540b21d345f00222698cc33e6e7a4196bed610744c1", + "address": "0x0300100f529a704d19736a8714837adbc934db7f", "key": "0x97b25febb46f44607c87a3498088c605086df207c7ddcd8ee718836a516a9153" }, - "0x043a718774c572bd8a25adbeb1bfcd5c0256ae11": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4c310e1f5d2f2e03562c4a5c473ae044b9ee19411f07097ced41e85bd99c3364" - }, - "0x046dc70a4eba21473beb6d9460d880b8cfd66613": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4fd7c8d583447b937576211163a542d945ac8c0a6e22d0c42ac54e2cbaff9281" - }, - "0x04b85539570fb9501f65453dbfad410a467becdd": { + "0x075dB7AB5778cd5491d3ED7Ab64c1Ec0818148F3": { "balance": "0", "nonce": 1, - "root": "0x9e53f0a2ddb430d27f6fffa0a68b5f75db1d68e24113dcca6e33918cdae80846", + "root": "0xd3f27d2eba503b1af71052fe41fe4073a680ebe483f428d3caf50e94dfff12ab", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000019": "19", - "0x000000000000000000000000000000000000000000000000000000000000001a": "1a", - "0x000000000000000000000000000000000000000000000000000000000000001b": "1b" + "0x000000000000000000000000000000000000000000000000000000000000019f": "019f", + "0x00000000000000000000000000000000000000000000000000000000000001a0": "01a0", + "0x00000000000000000000000000000000000000000000000000000000000001a1": "01a1" }, - "key": "0xd84f7711be2f8eca69c742153230995afb483855b7c555b08da330139cdb9579" - }, - "0x04b8d34e20e604cadb04b9db8f6778c35f45a2d2": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe99460a483f3369006e3edeb356b3653699f246ec71f30568617ebc702058f59" - }, - "0x04d6c0c946716aac894fc1653383543a91faab60": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x98bb9ba48fda7bb8091271ab0e53d7e0022fb1f1fa8fa00814e193c7d4b91eb3" - }, - "0x050c9c302e904c7786b69caa9dd5b27a6e571b72": { - "balance": "0", - "nonce": 1, - "root": "0x818eaf5adb56c6728889ba66b6980cd66b41199f0007cdd905ae739405e3c630", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000077": "77", - "0x0000000000000000000000000000000000000000000000000000000000000078": "78", - "0x0000000000000000000000000000000000000000000000000000000000000079": "79" - }, - "key": "0xc3ac56e9e7f2f2c2c089e966d1b83414951586c3afeb86300531dfa350e38929" - }, - "0x06f647b157b8557a12979ba04cf5ba222b9747cf": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xaf38e0e6a4a4005507b5d3e9470e8ccc0273b74b6971f768cbdf85abeab8a95b" - }, - "0x075198bfe61765d35f990debe90959d438a943ce": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x1d38ada74301c31f3fd7d92dd5ce52dc37ae633e82ac29c4ef18dfc141298e26" - }, - "0x075db7ab5778cd5491d3ed7ab64c1ec0818148f3": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x075db7ab5778cd5491d3ed7ab64c1ec0818148f3", "key": "0xf84223f460140ad56af9836cfa6c1c58c1397abf599c214689bc881066020ff7" }, - "0x08037e79bb41c0f1eda6751f0dabb5293ca2d5bf": { - "balance": "1", - "nonce": 0, + "0x0767637af7aeA66d876BAC94769Da962Bb4D93F6": { + "balance": "0", + "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xcd07379b0120ad9a9c7fa47e77190be321ab107670f3115fec485bebb467307d" + "address": "0x0767637af7aea66d876bac94769da962bb4d93f6", + "key": "0x500b6c47c37153a6d5f95cb6503d4d6677f1b875ab80b7d12a3e15db75573930" }, - "0x087d80f7f182dd44f184aa86ca34488853ebcc04": { - "balance": "100000000000", - "nonce": 0, + "0x08B229256Ba635C4500B5bCd23C8df2E06FD2666": { + "balance": "0", + "nonce": 1, + "root": "0x533722a718cdf4f4cd17633807044d1e14f967b005430f7aee50ae9a4844c16d", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000020d": "020d", + "0x000000000000000000000000000000000000000000000000000000000000020e": "020e", + "0x000000000000000000000000000000000000000000000000000000000000020f": "020f" + }, + "address": "0x08b229256ba635c4500b5bcd23c8df2e06fd2666", + "key": "0x2aae99477bd369e3478c1f1df2c669e8960d4583ded8d183f9578e36b301544e" + }, + "0x0E4aea2BBB2Ae557728f2661Ee3639360f1d787A": { + "balance": "0", + "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x867bc89cf8d5b39f1712fbc77414bbd93012af454c226dcee0fb34ccc0017498" - }, - "0x08d3b23dbfe8ef7965a8b5e4d9c21feddbc11491": { - "balance": "0", - "nonce": 1, - "root": "0x9a4a33f978d84e0aceb3ac3670c2e2df6c8ae27c189a96ed00b806d10ed7b4ee", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001c6": "01c6", - "0x00000000000000000000000000000000000000000000000000000000000001c7": "01c7", - "0x00000000000000000000000000000000000000000000000000000000000001c8": "01c8" - }, - "key": "0x792cc9f20a61c16646d5b6136693e7789549adb7d8e35503d0004130ea6528b0" - }, - "0x09b9c1875399cd724b1017f155a193713cb23732": { - "balance": "0", - "nonce": 1, - "root": "0x47fa48e25d3669a9bb190c59938f4be49de2d083696eb939c3b4072ec67e43b1", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000005e": "5e", - "0x000000000000000000000000000000000000000000000000000000000000005f": "5f", - "0x0000000000000000000000000000000000000000000000000000000000000060": "60" - }, - "key": "0x23ddaac09188c12e5d88009afa4a34041175c5531f45be53f1560a1cbfec4e8a" - }, - "0x0a3aaee7ccfb1a64f6d7bcd46657c27cb1f4569a": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc7fc033fe9f00d24cb9c479ddc0598e592737c305263d088001d7419d16feffa" - }, - "0x0badc617ca1bcb1cb1d5272f64b168cbf0e8f86f": { - "balance": "0", - "nonce": 1, - "root": "0xca39f5f4ee3c6b33efe7bc485439f97f9dc62f65852c7a1cdf54fab1e3b70429", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000002d": "2d", - "0x000000000000000000000000000000000000000000000000000000000000002e": "2e", - "0x000000000000000000000000000000000000000000000000000000000000002f": "2f" - }, - "key": "0xc250f30c01f4b7910c2eb8cdcd697cf493f6417bb2ed61d637d625a85a400912" - }, - "0x0c2c51a0990aee1d73c1228de158688341557508": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x28f25652ec67d8df6a2e33730e5d0983443e3f759792a0128c06756e8eb6c37f" - }, - "0x0d336bc3778662a1252d29a6f7216055f7a582bf": { - "balance": "0", - "nonce": 1, - "root": "0xa5a91cf9e815fb55df14b3ee8c1325a988cb3b6dd34796c901385c3cc2992073", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000013f": "013f", - "0x0000000000000000000000000000000000000000000000000000000000000140": "0140", - "0x0000000000000000000000000000000000000000000000000000000000000141": "0141" - }, - "key": "0x86a73e3c668eb065ecac3402c6dc912e8eb886788ea147c770f119dcd30780c6" - }, - "0x0e4aea2bbb2ae557728f2661ee3639360f1d787a": { - "balance": "0", - "nonce": 1, - "root": "0x74ed78eb16016d7ff3a173ab1bbcee9daa8e358a9d6c9be5e84ba6f4a34cf96a", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000d1": "d1", - "0x00000000000000000000000000000000000000000000000000000000000000d2": "d2", - "0x00000000000000000000000000000000000000000000000000000000000000d3": "d3" - }, + "address": "0x0e4aea2bbb2ae557728f2661ee3639360f1d787a", "key": "0x517bd5fbe28e4368b0b9fcba13d5e81fb51babdf4ed63bd83885235ee67a8fa0" }, - "0x0ef32dec5f88a96c2eb042126e8ab982406e0267": { + "0x0c2c51a0990AeE1d73C1228de158688341557508": { + "balance": "1000000000000000000000000400000000012", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", + "key": "0x28f25652ec67d8df6a2e33730e5d0983443e3f759792a0128c06756e8eb6c37f" + }, + "0x0eD465f2D38113203793802EaFcFe2a302F5141F": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x181abdd5e212171007e085fdc284a84d42d5bfc160960d881ccb6a10005ff089" + "address": "0x0ed465f2d38113203793802eafcfe2a302f5141f", + "key": "0xcae77150ac0c4c8a134fd8b7c02b6e053e99a44f91db924f3033dff62033de25" }, - "0x0ef96a52f4510f82b049ba991c401a8f5eb823e5": { + "0x0eE3aB1371c93E7c0c281cC0c2107cDebc8B1930": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x247cc3b27208cdf8036ec9c5aa16ae2aa005255b13aaf0e79824fc6d69e2df61", + "code": "0x60003515156036577f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f75736572206572726f7200000000000000000000000000000000000000000000604452604e6000fd", + "address": "0x0ee3ab1371c93e7c0c281cc0c2107cdebc8b1930", + "key": "0x9afc282e9868fb95921af24218a3612a16ad8e7329530b5be184a6507bbddecc" + }, + "0x112e887C13720ea0Ea8Ab3c2eE9639155Ff06e50": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x59312f89c13e9e24c1cb8b103aa39a9b2800348d97a92c2c9e2a78fa02b70025" + "address": "0x112e887c13720ea0ea8ab3c2ee9639155ff06e50", + "key": "0x171124648329d6a061328d1189b14f64e3da43648255489dbc67168331936bc6" }, - "0x0f228c3ba41142e702ee7306859026c99d3d2df5": { + "0x1218Cf397301c287Cfd4a2Bdbd922A3432457388": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xedd9b1f966f1dfe50234523b479a45e95a1a8ec4a057ba5bfa7b69a13768197c" + "codeHash": "0x097d31b10fc018fa01b350d82033872d007057b464560cdc1afd34fcddb14501", + "code": "0x3568ac4853d98daec689c5f2aa7d3141dd0256607e02057f4de3da3f333907ff9b41fe675cf46e85813b95622c1329ddda8c317b528ee44b3cbf5c27b8b8f7e5759c070bd3698aa0ecb5628e2a94ee9c0fc87c120f625d01a781262556e517bada8419d7f831676b15592f36811aed673124b0b8123e5c73e1ea68245a6ccf6457969cb441519f4b2cd9b0a57d7e95a7eb2c5e3f719cad38e8c60697bef8a3c2e153613a7c973b978a2b720f5225dbf4b83bda7128b3fd13e56307208ddfe0c77c2ebe6bc91f70109fbacaade46e1cb5258e806c9970c9d5085c13d5e23751de34ee70246abe44a6ef3f9dc451e68ce7669b7393fc4538f9fc58aec8dbf5b825", + "address": "0x1218cf397301c287cfd4a2bdbd922a3432457388", + "key": "0x887e6e4c23e7a93a0c66f56b8ac9b5399d205063604ff2f093c5b2d30af481e3" }, - "0x0fdcca8fde6d69ecbc9bfadb056ecf62d1966370": { + "0x132432ce1CE64304f1D145eBa1772F6edd6Cdd17": { "balance": "0", "nonce": 1, - "root": "0x493f90435402df0907019bffc6dd25a17ce4acd6eb6077ef94c1626f0d77c9f0", + "root": "0xa8cbc3846808271a2bf0580ee9da43b36853292ce79dbe0bc785c62337eaec86", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000f9": "f9", - "0x00000000000000000000000000000000000000000000000000000000000000fa": "fa", - "0x00000000000000000000000000000000000000000000000000000000000000fb": "fb" + "0x000000000000000000000000000000000000000000000000000000000000006b": "6b", + "0x000000000000000000000000000000000000000000000000000000000000006c": "6c", + "0x000000000000000000000000000000000000000000000000000000000000006d": "6d" }, - "key": "0xfb5a31c5cfd33dce2c80a30c5efc28e5f4025624adcc2205a2504a78c57bdd1c" - }, - "0x0fe037febcc3adf9185b4e2ad4ea43c125f05049": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb7d9d175039df1ba52c734547844f8805252893c029f7dbba9a63f8bce3ee306" - }, - "0x0fed138ec52bab88db6c068df9125936c7c3e11b": { - "balance": "0", - "nonce": 1, - "root": "0x66eb16071ba379bf0c632fcb52f9175a656bef62adf0bef5349a7f5a6aad5d88", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000176": "0176", - "0x0000000000000000000000000000000000000000000000000000000000000177": "0177", - "0x0000000000000000000000000000000000000000000000000000000000000178": "0178" - }, - "key": "0x255ec86eac03ba59f6dfcaa02128adbb22c561ae0c49e9e62e4fff363750626e" - }, - "0x102efa1f2e0ad16ada57759b815245b8f8d27ce4": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x9d42947ac5e61285567f65d4b400d90343dbd3192534c4c1f9d941c04f48f17c" - }, - "0x1037044fabf0421617c47c74681d7cc9c59f136c": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x2290ea88cc63f09ab5e8c989a67e2e06613311801e39c84aae3badd8bb38409c" - }, - "0x1042d41ee3def49e70df4e6c2be307b8015111e5": { - "balance": "0", - "nonce": 1, - "root": "0xdf3c1bfab8f7e70a8edf94792f91e4b6b2c2aa61caf687e4f6cb689d180adb80", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000095": "95", - "0x0000000000000000000000000000000000000000000000000000000000000096": "96", - "0x0000000000000000000000000000000000000000000000000000000000000097": "97" - }, - "key": "0xc0ce77c6a355e57b89cca643e70450612c0744c9f0f8bf7dee51d6633dc850b1" - }, - "0x104eb07eb9517a895828ab01a3595d3b94c766d5": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfab4c6889992a3f4e96b005dfd851021e9e1ec2631a7ccd2a001433e35077968" - }, - "0x1219c38638722b91f3a909f930d3acc16e309804": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd63070208c85e91c4c8c942cf52c416f0f3004c392a15f579350168f178dba2e" - }, - "0x132432ce1ce64304f1d145eba1772f6edd6cdd17": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x132432ce1ce64304f1d145eba1772f6edd6cdd17", "key": "0x729953a43ed6c913df957172680a17e5735143ad767bda8f58ac84ec62fbec5e" }, - "0x13dd437fc2ed1cd5d943ac1dd163524c815d305c": { - "balance": "100000000000", - "nonce": 0, + "0x13f3F31335881a7402955Dc3Bf0b4A62936b44aa": { + "balance": "0", + "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x99e56541f21039c9b7c63655333841a3415de0d27b79d18ade9ec7ecde7a1139" + "address": "0x13f3f31335881a7402955dc3bf0b4a62936b44aa", + "key": "0x6742b9f65e686fd1b9da73a3a29541cbb07afaaf51b5b5be682b462131709388" }, - "0x14e46043e63d0e3cdcf2530519f4cfaf35058cb2": { - "balance": "1000000000000000000000000000000000000", + "0x14e46043e63D0E3cdcf2530519f4cFAf35058Cb2": { + "balance": "1000000000000000000000000100000000009", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x14e46043e63d0e3cdcf2530519f4cfaf35058cb2", "key": "0x9feaf0bd45df0fbf327c964c243b2fbc2f0a3cb48fedfeea1ae87ac1e66bc02f" }, - "0x1534b43c6dfa3695446aaf2aa07d123132cceceb": { + "0x1534b43C6Dfa3695446AaF2aa07d123132Cceceb": { "balance": "0", "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "root": "0x2eadda3a2ead59e184a6b073cdd8fbe4538eac19175e79833c3efb263ff9d09b", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x00000000000000000000000000000000000000000000000000000000000000d9": "d9", + "0x00000000000000000000000000000000000000000000000000000000000000da": "da", + "0x00000000000000000000000000000000000000000000000000000000000000db": "db" + }, + "address": "0x1534b43c6dfa3695446aaf2aa07d123132cceceb", "key": "0x2a248c1755e977920284c8054fceeb20530dc07cd8bbe876f3ce02000818cc3a" }, - "0x15af6900147a8730b5ce3e1db6333f33f64ebb2c": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5264e880ecf7b80afda6cc2a151bac470601ff8e376af91aaf913a36a30c4009" - }, - "0x16032a66fc011dab75416d2449fe1a3d5f4319d8": { + "0x15B9118f5f6a91cC127c4AbcDDDa1FA08D6d41C2": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe3c79e424fd3a7e5bf8e0426383abd518604272fda87ecd94e1633d36f55bbb6" + "address": "0x15b9118f5f6a91cc127c4abcddda1fa08d6d41c2", + "key": "0xcb10ab6f495ae291b320182d2316da52c2b5a4bdfe13d7071d1c948461abbe49" }, - "0x16c57edf7fa9d9525378b0b81bf8a3ced0620c1c": { - "balance": "1000000000000000000000000000000000000", + "0x16c57eDF7Fa9D9525378B0b81Bf8A3cEd0620C1c": { + "balance": "1000000000000000000000000000000000011", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x16c57edf7fa9d9525378b0b81bf8a3ced0620c1c", "key": "0xda81833ff053aff243d305449775c3fb1bd7f62c4a3c95dc9fb91b85e032faee" }, - "0x17333b15b4a5afd16cac55a104b554fc63cc8731": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4ceaf2371fcfb54a4d8bc1c804d90b06b3c32c9f17112b57c29b30a25cf8ca12" - }, - "0x17b917f9d79d922b33e41582984712e32b3ad366": { - "balance": "0", - "nonce": 1, - "root": "0x944f095afbd1383e5d0f91ef02895d398f4f76fdb6d86adf4765f25bdc304f5f", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000081": "81", - "0x0000000000000000000000000000000000000000000000000000000000000082": "82", - "0x0000000000000000000000000000000000000000000000000000000000000083": "83" - }, - "key": "0x13cfc46f6bdb7a1c30448d41880d061c3b8d36c55a29f1c0c8d95a8e882b8c25" - }, - "0x18291b5f568e45ef0f16709b20c810e08750791f": { + "0x17e7EedCe4Ac02ef114a7eD9fE6E2F33Feba1667": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "codeHash": "0x975f732458c1f6c2dd22b866b031cc509c6d4f788b1f020e351c1cdba48dacca", + "code": "0x366002146022577177726f6e672d63616c6c6461746173697a656000526012600efd5b60003560f01c61ff01146047576d77726f6e672d63616c6c64617461600052600e6012fd5b61ffee6000526002601ef3", + "address": "0x17e7eedce4ac02ef114a7ed9fe6e2f33feba1667", + "key": "0x69bf6d72df9e6b88306eb4e4624996e919f0433ba63520aa9a1d3f9888e09b1f" + }, + "0x18291b5F568E45eF0f16709B20c810E08750791f": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x94d95e732733c801cf6c47d1092559b355b731663edf264cd56f1f8bf9643dde", + "code": "0x53e446b02877d67323538930ac023539909d7ae9c37d47c9041a36b516d7a895b9082031afe800ff4145d688a9aceb89c2035073c366644d7c1fa9b891d3a351f13c26c3380332c756c2535bb8be8673c2d150e01b15e31f73fa100e1f4968f5f1b5f43cfd58433d8089d74d4b0d048639a18b3e74e203da03a300c559157a05ac7a8c487ac9ae6a81f1a5f24686cb5abcc471ed89182a27eb411609d783592905ad14573d4f19affa497b220c03fe2d7d204eecd50d03e42c775d0bdb013b9951aa4fa60f2ae98ad35a8d9cb8bb757547523cdbf7ebaea966a3a6a229e3bbecb59ab80f5598cb65e185f83739c5b8a9f7ed18c2d44c1cfa8eb3fe5e47e30e9e", + "address": "0x18291b5f568e45ef0f16709b20c810e08750791f", "key": "0x315ccc15883d06b4e743f8252c999bf1ee994583ff6114d89c0f3ddee828302b" }, - "0x189f40034be7a199f1fa9891668ee3ab6049f82d": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6225e8f52719d564e8217b5f5260b1d1aac2bcb959e54bc60c5f479116c321b8" - }, - "0x18ac3e7343f016890c510e93f935261169d9e3f5": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xeba984db32038d7f4d71859a9a2fc6e19dde2e23f34b7cedf0c4bf228c319f17" - }, - "0x19041ad672875015bc4041c24b581eafc0869aab": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfc8d513d1615c763865b984ea9c381032c14a983f80e5b2bd90b20b518329ed7" - }, - "0x19129f84d987b13468846f822882dba0c50ca07d": { + "0x19129f84D987b13468846f822882DBa0C50cA07D": { "balance": "0", "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "root": "0x5804411a83500245d7b0f6826a301fe8e9314c1a4407b78022cd212295dc60c0", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000105": "0105", + "0x0000000000000000000000000000000000000000000000000000000000000106": "0106", + "0x0000000000000000000000000000000000000000000000000000000000000107": "0107" + }, + "address": "0x19129f84d987b13468846f822882dba0c50ca07d", "key": "0x2b8d12301a8af18405b3c826b6edcc60e8e034810f00716ca48bebb84c4ce7ab" }, - "0x194e49be24c1a94159f127aa9257ded12a0027db": { + "0x194E49Be24C1a94159F127aA9257DeD12A0027db": { "balance": "0", "nonce": 1, - "root": "0xe0a3d3b839fca0f54745d0c50a048e424c9259f063b7416410a4422eeb7f837e", + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000180": "0180", - "0x0000000000000000000000000000000000000000000000000000000000000181": "0181", - "0x0000000000000000000000000000000000000000000000000000000000000182": "0182" - }, + "address": "0x194e49be24c1a94159f127aa9257ded12a0027db", "key": "0xd57eafe6d4c5b91fe7114e199318ab640e55d67a1e9e3c7833253808b7dca75f" }, - "0x19581e27de7ced00ff1ce50b2047e7a567c76b1c": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7bac5af423cb5e417fa6c103c7cb9777e80660ce3735ca830c238b0d41610186" - }, - "0x196d4a4c50eb47562596429fdecb4e3ac6b2a5fd": { + "0x196d4a4c50EB47562596429fDeCB4e3ac6b2a5fD": { "balance": "0", "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "root": "0x5a25afca240ed3f1756a12b178c2875f75a1ebd4e7942a550856d04b61d424b1", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000013": "13", + "0x0000000000000000000000000000000000000000000000000000000000000014": "14", + "0x0000000000000000000000000000000000000000000000000000000000000015": "15" + }, + "address": "0x196d4a4c50eb47562596429fdecb4e3ac6b2a5fd", "key": "0x4e258aa445a0e2a8704cbc57bbe32b859a502cd6f99190162236300fabd86c4a" }, - "0x1a0eae9b9214d9269a4cff4982c45a67f4ca63aa": { + "0x1B6eC89d00555BeBF7DEBE884b5A1b1FB5ef79B1": { "balance": "0", "nonce": 1, - "root": "0x5622801b1011de8403e44308bbf89a5809b7ad6586268cd72164523587f9b0e4", + "root": "0x29a3676b5776327effe8a01b0b824a04133fb3944d215d371d27817c7c7d0050", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x000000000000000000000000000000000000000000000000000000000000007c": "7c", - "0x000000000000000000000000000000000000000000000000000000000000007d": "7d", - "0x000000000000000000000000000000000000000000000000000000000000007e": "7e" + "0x00000000000000000000000000000000000000000000000000000000000000ce": "ce", + "0x00000000000000000000000000000000000000000000000000000000000000cf": "cf", + "0x00000000000000000000000000000000000000000000000000000000000000d0": "d0" }, - "key": "0x6a2c8498657ae4f0f7b1a02492c554f7f8a077e454550727890188f7423ba014" + "address": "0x1b6ec89d00555bebf7debe884b5a1b1fb5ef79b1", + "key": "0x622e662246601dd04f996289ce8b85e86db7bb15bb17f86487ec9d543ddb6f9a" }, - "0x1ae59138ad95812304b117ee7b0d502bcb885af5": { + "0x1E8CE8258Fb47F55Bf2C1473aCb89a10074B9D0E": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf164775805f47d8970d3282188009d4d7a2da1574fe97e5d7bc9836a2eed1d5b" - }, - "0x1b16b1df538ba12dc3f97edbb85caa7050d46c14": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x8ee17a1ec4bae15d8650323b996c55d5fa11a14ceec17ff1d77d725183904914" - }, - "0x1c123d5c0d6c5a22ef480dce944631369fc6ce28": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa9fd2e3a6de5a9da5badd719bd6e048acefa6d29399d8a99e19fd9626805b60b" - }, - "0x1c972398125398a3665f212930758ae9518a8c94": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5d97d758e8800d37b6d452a1b1812d0afedba11f3411a17a8d51ee13a38d73f0" - }, - "0x1e345d32d0864f75b16bde837543aa44fac35935": { - "balance": "0", - "nonce": 1, - "root": "0xd91acf305934a60c960a93fb00f927ec79308b8a919d2449faede722c2324cb3", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000153": "0153", - "0x0000000000000000000000000000000000000000000000000000000000000154": "0154", - "0x0000000000000000000000000000000000000000000000000000000000000155": "0155" - }, - "key": "0x961508ac3c93b30ee9a5a34a862c9fe1659e570546ac6c2e35da20f6d2bb5393" - }, - "0x1e8ce8258fb47f55bf2c1473acb89a10074b9d0e": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "codeHash": "0xd5daa3aec1f142e2b2059b675d676ccb42129d27d96f8e901df2dac6104b38e2", + "code": "0xf548adfdedfd2f8b2416994318306c690dadb026395430e32e9a141187933c8602d9f8353bca53bc9b195aa186ab6d98b49a9120c00257ee2c7d860c26f864ea7352bc45c8aa6995480780fe15a07c4daa795263b5e7a9d04d9ed979c93ca85e57023ef7fe58b878582140ea36f22723905ad724896eaf74090fba76c229bd2269bc8c08a6b955aec2072ca430bac7123bc3539264a736d1a23621b0f0c62f3166eeecffab615cf4c69d47d3aa51576e95b697767264fa754ea36f4e363ea19359149054a4189e9e52234a041160d0a984f6bcb43e7a9da69cfb168d147633650425d4cac564eade3739b18cff91bb2bc855f9c26bed98f6e089d895e00c3d5f", + "address": "0x1e8ce8258fb47f55bf2c1473acb89a10074b9d0e", "key": "0xfb2ab315988de92dcf6ba848e756676265b56e4b84778a2c955fb2b3c848c51c" }, - "0x1f4924b14f34e24159387c0a4cdbaa32f3ddb0cf": { - "balance": "1000000000000000000000000000000000000", + "0x1F12d422bFb4444EdA416C805B0eBC9C9C5219b9": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x2163e5f7425a961dedf4ab14d04cb5da552f71e6753f2ee5d0f757fa80557a72", + "code": "0x6d51b3e2fee37bb096ac27bcd2f51406f41ca898c8655c777eb566221b5c30ef0caf086fb5eddf1b4d11c4f0b807d5031fcc6c85a4bde491a90c50edc223e345203d2d2bdae77b6c59cc38f69817e60d54c7ca8eeca5cbd2727e9f9fb7a596a5ef8f912c2063a9c1079545513398425889f237200dbe31f704b550eedddec1553cb8dbdb71abce785b0d3ada500497411f9a35029bc9f0128fe99dbe40b831ed7092736705691e7fcb646542760fd0f452b1b0698662a4e52aa598cf52e0872bb29f850db3636ac0c738910696357ccf04bdcf9eecb591427ec2a19c4d0307382a9415d08c0c16e17c81d1ddd07c87b75cf5938c1315af07b6f3e822070a8512", + "address": "0x1f12d422bfb4444eda416c805b0ebc9c9c5219b9", + "key": "0x5e30d12ba0a17b9e1add523ccad77978516b91d2637cfa79061c848fd42dc002" + }, + "0x1F4924B14F34e24159387C0A4CdBaa32f3DDb0cF": { + "balance": "1000000000000000000000000200000000003", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x1f4924b14f34e24159387c0a4cdbaa32f3ddb0cf", "key": "0x7963685967117ffb6fd019663dc9e782ebb1234a38501bffc2eb5380f8dc303b" }, - "0x1f5746736c7741ae3e8fa0c6e947cade81559a86": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4e5bab4ebd077c3bbd8239995455989ea2e95427ddeed47d0618d9773332bb05" - }, - "0x1f5bde34b4afc686f136c7a3cb6ec376f7357759": { - "balance": "1000000000000000000000000000000000000", + "0x1F5BDe34B4afC686f136c7a3CB6EC376F7357759": { + "balance": "1000000000000000000000000100000000010", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x1f5bde34b4afc686f136c7a3cb6ec376f7357759", "key": "0xc3791fc487a84f3731eb5a8129a7e26f357089971657813b48a821f5582514b3" }, - "0x2143e52a9d8ad4c55c8fdda755f4889e3e3e7721": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd9fa858992bc92386a7cebcd748eedd602bf432cb4b31607566bc92b85179624" - }, - "0x2144780b7d04d82239c6570f84ab66376b63dfc9": { + "0x1F94C5D92A7cDA91E46258db39cd2080934cf401": { "balance": "0", "nonce": 1, - "root": "0x59936c15c454933ebc4989afa77e350f7640301b07341aead5f1b2668eeb1dad", + "root": "0x2ac8ab8e205b5f066caaf29772e71b8acc033fb2dd00aef81d58d5c6cf41393f", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000db": "db", - "0x00000000000000000000000000000000000000000000000000000000000000dc": "dc", - "0x00000000000000000000000000000000000000000000000000000000000000dd": "dd" + "0x00000000000000000000000000000000000000000000000000000000000000a2": "a2", + "0x00000000000000000000000000000000000000000000000000000000000000a3": "a3", + "0x00000000000000000000000000000000000000000000000000000000000000a4": "a4" }, - "key": "0xd37b6f5e5f0fa6a1b3fd15c9b3cf0fb595ba245ab912ad8059e672fa55f061b8" + "address": "0x1f94c5d92a7cda91e46258db39cd2080934cf401", + "key": "0xade3931ebf0e80c7ff1ef57f79e1a3bee133066fbc2f65c98bde9b9751c59fd5" }, - "0x22694f8f2d0c62f63a25bd0057a80b89084c3b47": { + "0x1aE59138Ad95812304b117eE7B0d502bCB885af5": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x2369a492b6cddcc0218617a060b40df0e7dda26abe48ba4e4108c532d3f2b84f" + "codeHash": "0x91229856266a08d68e2ba7fbe841ea0367eee39a9abbdf7fffa2e1fca5bf530a", + "code": "0x1a3539311f056efda55cfb638b48ceb0b16c46de7fdcfeece7c16dd10edb530a980802d84c4907cfb351be0c47b17b29e497879c00ff4207f841b525e59a4adb4dfcef122f40141197bd2add22dde2be0b18caf178af0e36baf2dbaca781064eb0aef7f62d67906ac495f365239649f69c785963deec1dc59e987ee4ff2c0aac26dc59d1574bbfa08847573f46e3a6a81f6dd471c94e177fd7e9d751b032632fafdc38a2d8170640ae476d556f5391a670c7dcea12fef53e3782b397413b8073ab5c193bc1e7e460f2a67a20e95e8eb487cb5c6e73e0a81f056b2ad06bca644804c56e6a6ea052548b58611dab35b25575fbe01e39f14d213e55204b97fe495f", + "address": "0x1ae59138ad95812304b117ee7b0d502bcb885af5", + "key": "0xf164775805f47d8970d3282188009d4d7a2da1574fe97e5d7bc9836a2eed1d5b" }, - "0x22b3f17adeb5f2ec22135d275fcc6e29f4989401": { + "0x1c991868B648141eFE0a1797d2E684f0E9D85f5D": { "balance": "0", "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa3abdaefbb886078dc6c5c72e4bc8d12e117dbbd588236c3fa7e0c69420eb24a" - }, - "0x23262ad5ae496588bd793910b55ccf178fbd73f9": { - "balance": "0", - "nonce": 1, - "root": "0x3437803101a8040aca273fb734d7965a87f823ff1ef78c7edcaad358eb98dee3", + "root": "0xd5b837548792630f18e5e5860cb7c2e09d50f3e0bf633031a5266dc813e51722", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000171": "0171", - "0x0000000000000000000000000000000000000000000000000000000000000172": "0172", - "0x0000000000000000000000000000000000000000000000000000000000000173": "0173" + "0x00000000000000000000000000000000000000000000000000000000000000fa": "fa", + "0x00000000000000000000000000000000000000000000000000000000000000fb": "fb", + "0x00000000000000000000000000000000000000000000000000000000000000fc": "fc" }, - "key": "0xd8489fd0ce5e1806b24d1a7ce0e4ba8f0856b87696456539fcbb625a9bed2ccc" + "address": "0x1c991868b648141efe0a1797d2e684f0e9d85f5d", + "key": "0xdaa5ac389919fe4309e82b1ec0173c579a91909e43606c075fffcd175d449bb1" }, - "0x23b17315554bd2928c1f86dd526f7ee065a9607d": { + "0x23946FCc6A6FC157F5fA71766920C05B3ca332A9": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x9b8e6ae27d3f687d8da6c6cd00910988ee2f132e69a9039495349f53e5d420d4", + "code": "0x2200b384d5b1adb897ca35499aac189a6bc95554ae7cd569cff630ab95ab2408ec2ece864d596b2df3fda60d8ff3647904c8787bbcdca061ac2c3ced7ec882414e891f8214eefddacb67949285b4d8381359bda85deba8c8d1cd531fac277446250aa56d419d6944c75ef323c37456f10c8deae91a088f5266af04395bfb6f9f1d83040a41828888b050efc081f5d66c96d76f2436e80f14429fe3ba7679228b5d30ee1cebf81682922812857932b35925ce3b0005995d8dcc5cdc3ade024209b45d823cb873a82c40322caac58ec73ecb33fe985c8d73b5edc8c5bd10a32dacbd709dd7349a1e346060645a803266120e2ad65cd1489f355739a06ccb96006a", + "address": "0x23946fcc6a6fc157f5fa71766920c05b3ca332a9", + "key": "0xfb1f3c0b3adbfacce7162c4512f5e01da2e45f783d1d098d59478ba98579a943" + }, + "0x23E7eCFEbfe3a69F17F90fE6AFF700c395C502A4": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x23e7ecfebfe3a69f17f90fe6aff700c395c502a4", + "key": "0xed63eed77538b7d6aec65f20d6538407bb521bcc2049f5227f0ba7125f7e5246" + }, + "0x23b17315554BD2928C1f86dD526F7ee065a9607d": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x9a29a4ee31aaa09c1644e1fbb4f6daf087496185098474a6caf2128201e2ef26", + "code": "0x9e91c95f108ead30341468db9696e39ed81de6a68bc8c6702bcb66393fce6e75f7459e621ec1fc60fd62c436d4281de72cb9f48787dc9c8288a3050292b090046d00efa09a7071d855bc5fb7d93921fbf02f2c4e3992802f2a9b08050cf48ea83ba015d6b845e102ce2f76836007be82508e3543856f2a3c2ff4b56eb46d920eeaa72e3626d79eea854e214b64a34b95d0c9348f5b8df0b074d774f7dba83c65641a7e47c832ef1f4ef72e654761ca2c0b592dc5a9de41ec09261efc0afea2bed4c27e5d2ce7b7345f78d7f5ddc8b90697d63512e00b9f949b158a467d0bfffc759e22076818c4256545c2158d054d4904983321e7c2bbb6fe78c5cb62872764", + "address": "0x23b17315554bd2928c1f86dd526f7ee065a9607d", "key": "0x12e394ad62e51261b4b95c431496e46a39055d7ada7dbf243f938b6d79054630" }, - "0x23c86a8aded0ad81f8111bb07e6ec0ffb00ce5bf": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd72e318c1cea7baf503950c9b1bd67cf7caf2f663061fcde48d379047a38d075" - }, - "0x23e6931c964e77b02506b08ebf115bad0e1eca66": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x174f1a19ff1d9ef72d0988653f31074cb59e2cf37cd9d2992c7b0dd3d77d84f9" - }, - "0x24255ef5d941493b9978f3aabb0ed07d084ade19": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7583557e4e3918c95965fb610dc1424976c0eee606151b6dfc13640e69e5cb15" - }, - "0x245843abef9e72e7efac30138a994bf6301e7e1d": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfe6e594c507ec0ac14917f7a8032f83cd0c3c58b461d459b822190290852c0e1" - }, - "0x25261a7e8395b6e798e9b411c962fccc0fb31e38": { + "0x25261A7e8395b6e798e9B411C962fcCc0Fb31E38": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "codeHash": "0xda6d4548d8504c1c6b93b3f8afa6a43ec3f393b4538817077e5c0d8a16ba37ae", + "code": "0x7789c5fe6d71025d8baaa82349a48bdecdf7d33796c5b62fb2e2709eecea43508c8f1d83c32f3a2c534b56bae7b22603ef0e0c3b7e11b1eef2bafb0da977e3dc1ced5e204c93c1fdad1d04ee5664dbf790f8db86241883cdde350ce907ad86ca1f61127137b2b334cc768fbb1f2c09bd3ffa8b4efe78fbac6f501d1ec08449daef188faeece6fe5db45dc7f5d168733c0c348bd006890ac720106e2aa22f60bc305ece2ab3243c04f78c036bbbc0c561f9d54db01bbb3dc7946b4979b6a40dbd68404147fdbb906e3359f7733cbd4345edc2b456718e75029e6a1f6ba819c54467dd4e7709cbc529012d23fcd661c8cc3327ec3cefbc12e02677a50c121eecc2", + "address": "0x25261a7e8395b6e798e9b411c962fccc0fb31e38", "key": "0x1017b10a7cc3732d729fe1f71ced25e5b7bc73dc62ca61309a8c7e5ac0af2f72" }, - "0x2553ec67bc75f75d7de13db86b14290f0f76e342": { + "0x255F219878846c5893F664CFb2A35a381ec8C149": { "balance": "0", "nonce": 1, - "root": "0x8078f3259d8199b7ca39d51e35d5b58d71ff148606731060386d323c5d19182c", + "root": "0x5bec588324e6249140515272adc6b1f5b34ae0a4782db0a55a7481bbce20b6e8", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000185": "0185", - "0x0000000000000000000000000000000000000000000000000000000000000186": "0186", - "0x0000000000000000000000000000000000000000000000000000000000000187": "0187" + "0x0000000000000000000000000000000000000000000000000000000000000244": "0244", + "0x0000000000000000000000000000000000000000000000000000000000000245": "0245", + "0x0000000000000000000000000000000000000000000000000000000000000246": "0246" }, - "key": "0x0f30822f90f33f1d1ba6d1521a00935630d2c81ab12fa03d4a0f4915033134f3" + "address": "0x255f219878846c5893f664cfb2a35a381ec8c149", + "key": "0x8adecfc09eaee180c4a23258a373d4f4c472a03eed1be91814ca315fdba5902b" }, - "0x2604439a795970de2047e339293a450c0565f625": { + "0x26e92A8D6eDBD0b9cED1dd80a920Ad0b796fCf93": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x8678559b30b321b0f0420a4a3e8cecfde90c6e56766b78c1723062c93c1f041f" + "address": "0x26e92a8d6edbd0b9ced1dd80a920ad0b796fcf93", + "key": "0xa28e6adde4090652685168a269cb1141e28b0849487175237b9b32064788c2f9" }, - "0x26704bf05b1da795939788ef05c8804dcf4b9009": { + "0x2C0cd3C60f41d56ED7664dbce39630395614Bf4b": { "balance": "0", "nonce": 1, - "root": "0xd60ee4ad5abbe759622fca5c536109b11e85aa2b48c0be2aebf01df597e74dba", + "root": "0xa3e3987c498c56b398b12cf368a76f2d184dd1d77b4896f4626909e35a7536d2", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x000000000000000000000000000000000000000000000000000000000000015d": "015d", - "0x000000000000000000000000000000000000000000000000000000000000015e": "015e", - "0x000000000000000000000000000000000000000000000000000000000000015f": "015f" + "0x00000000000000000000000000000000000000000000000000000000000000c3": "c3", + "0x00000000000000000000000000000000000000000000000000000000000000c4": "c4", + "0x00000000000000000000000000000000000000000000000000000000000000c5": "c5" }, - "key": "0xd1691564c6a5ab1391f0495634e749b9782de33756b6a058f4a9536c1b37bca6" - }, - "0x2727d12b98783b2c3641b5672bcfcdf007971d28": { - "balance": "0", - "nonce": 1, - "root": "0x59739ba3b156eb78f8bbb14bbf3dacdebfde95140f586db66f72e3117b94bb67", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000112": "0112", - "0x0000000000000000000000000000000000000000000000000000000000000113": "0113", - "0x0000000000000000000000000000000000000000000000000000000000000114": "0114" - }, - "key": "0x88bf4121c2d189670cb4d0a16e68bdf06246034fd0a59d0d46fb5cec0209831e" - }, - "0x2795044ce0f83f718bc79c5f2add1e52521978df": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xee9186a01e5e1122b61223b0e6acc6a069c9dcdb7307b0a296421272275f821b" - }, - "0x27952171c7fcdf0ddc765ab4f4e1c537cb29e5e5": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x0a93a7231976ad485379a3b66c2d8983ba0b2ca87abaf0ca44836b2a06a2b102" - }, - "0x27abdeddfe8503496adeb623466caa47da5f63ab": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x482814ea8f103c39dcf6ba7e75df37145bde813964d82e81e5d7e3747b95303d" - }, - "0x281c93990bac2c69cf372c9a3b66c406c86cca82": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x81c0c51e15c9679ef12d02729c09db84220ba007efe7ced37a57132f6f0e83c9" - }, - "0x2847213288f0988543a76512fab09684131809d9": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe1b86a365b0f1583a07fc014602efc3f7dedfa90c66e738e9850719d34ac194e" - }, - "0x28969cdfa74a12c82f3bad960b0b000aca2ac329": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x96d7104053877823b058fd9248e0bba2a540328e52ffad9bb18805e89ff579dc" - }, - "0x2a0ab732b4e9d85ef7dc25303b64ab527c25a4d7": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5e88e876a3af177e6daafe173b67f186a53f1771a663747f26b278c5acb4c219" - }, - "0x2aac4746638ae1457010747a5b0fd2380a388f4f": { - "balance": "0", - "nonce": 1, - "root": "0x5a82aff126ffebff76002b1e4de03c40ba494b81cb3fbc528f23e4be35a9afe6", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000004b": "4b", - "0x000000000000000000000000000000000000000000000000000000000000004c": "4c", - "0x000000000000000000000000000000000000000000000000000000000000004d": "4d" - }, - "key": "0x96c43ef9dce3410b78df97be69e7ccef8ed40d6e5bfe6582ea4cd7d577aa4569" - }, - "0x2bb3295506aa5a21b58f1fd40f3b0f16d6d06bbc": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x303f57a0355c50bf1a0e1cf0fa8f9bdbc8d443b70f2ad93ac1c6b9c1d1fe29a2" - }, - "0x2c0cd3c60f41d56ed7664dbce39630395614bf4b": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x2c0cd3c60f41d56ed7664dbce39630395614bf4b", "key": "0x92d0f0954f4ec68bd32163a2bd7bc69f933c7cdbfc6f3d2457e065f841666b1c" }, - "0x2c1287779024c3a2f0924b54816d79b7e378907d": { - "balance": "0", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x09d6e6745d272389182a510994e2b54d14b731fac96b9c9ef434bc1924315371" - }, - "0x2c582db705c5721bb3ba59f4ec8e44fb4ef6b920": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe02ec497b66cb57679eb01de1bed2ad385a3d18130441a9d337bd14897e85d39" - }, - "0x2d389075be5be9f2246ad654ce152cf05990b209": { - "balance": "1000000000000000000000000000000000000", + "0x2D389075BE5be9F2246Ad654cE152cF05990b209": { + "balance": "1000000000000000000000000300000000006", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x2d389075be5be9f2246ad654ce152cf05990b209", "key": "0xa9233a729f0468c9c309c48b82934c99ba1fd18447947b3bc0621adb7a5fc643" }, - "0x2d711642b726b04401627ca9fbac32f5c8530fb1": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfe2149c5c256a5eb2578c013d33e3af6a87a514965c7ddf4a8131e2d978f09f9" - }, - "0x2e350f8e7f890a9301f33edbf55f38e67e02d72b": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf33a7b66489679fa665dbfb4e6dd4b673495f853850eedc81d5f28bd2f4bd3b5" - }, - "0x2e5f413fd8d378ed081a76e1468dad8cbf6e9ed5": { + "0x2b6D216387cc86BF46FA7202C36C4f40BF1d7A22": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe69f40f00148bf0d4dfa28b3f3f5a0297790555eca01a00e49517c6645096a6c" + "codeHash": "0xd0db10813ed93d8d4216b55bb44f28dbd8979334d17f96e96230067c22aa3d7d", + "code": "0x366a7b92acda364086cc991f618bf9f10b629ec0f7ae94543f96b691b69ec9922cc30221e0553428287371236269b4e2f6f11f95f33fb976fdb79b586bb6c342c0c96d13f150a4b457c3bd96e92c2a5ab695d3246c81b0c07a0503c31ecba4728bd72d705e704e96ab1fa5baf1ac8053f4ec008dca8cf0376ca60a5648fa9532aaef4f4d920c99352d192889a8613287b33396c3d6a14178bd3f0455af509e256c40122c67bd2f0cbd1c3fa8ee6656e600ea58ee13b4077687b98c5c145bddbefd91b674668e771a29edc7bd49406822c49336f642d316b2b9ba0c0ff145fb18c23152f459c8033d1c6b84df917f2b2519e4be6bb34595e1cf96f7c07f456725", + "address": "0x2b6d216387cc86bf46fa7202c36c4f40bf1d7a22", + "key": "0x3e442de3aafac6a255389001775f311d0fead71621ec597e7ea7f91bcba73e49" }, - "0x2eb6db4e06119ab31a3acf4f406ccbaa85e39c66": { + "0x2b8E14ACde4DC8f4dd1A6FC249a48323431c69DF": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xaeaf19d38b69be4fb41cc89e4888708daa6b9b1c3f519fa28fe9a0da70cd8697" + "codeHash": "0x9f9a33401f113dceb7f8594ad6699ba7ef06665b11fe19c87f37e1c58d2eccc6", + "code": "0x66f4851715b29678b0cca267bfde816a0838d4b72ddc17590aadfd30fc1f1d13a6d5a907f2fd275a22b20a64111d18d562bc2b61aa65b44f5c83c1d6aac7d2e45db2aa293c68d8b2d991211b8aae5b6920d37ca709b36adc4d30eab3b5df163fef8374c201f52e9cadf0358fa9fe81d3b5dc6cfd55611ff392a0f6af5d359a1bff5cc1e3a6fb7e9faa08d225cdd564eed6d3c066f453d24f62b227f5b7a98674b0e5ed5015336e10965b0014527cad85307e5d111ca7afc3b5a60ce0021cc0a88dc3ccc90a5a484fa2a729ed5b473614aaeab270aa88d72534a542e99667eddc42fb786c069f6c2379a23a093b7909d15b477e8db52dacfeaae781f4c468708a", + "address": "0x2b8e14acde4dc8f4dd1a6fc249a48323431c69df", + "key": "0x448717f258267a130bd10b361c293b918047608106b21f4bdaff520b90586d4e" }, - "0x2f01c1c8c735a9a1b89898d3f14bbf61c91bf0fd": { + "0x2be6F9Ec5d4a0E79953570f06554FbFf9473B11E": { "balance": "0", "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd2f394b4549b085fb9b9a8b313a874ea660808a4323ab2598ee15ddd1eb7e897" - }, - "0x2fb64110da9389ce8567938a78f21b79222332f9": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x415ded122ff7b6fe5862f5c443ea0375e372862b9001c5fe527d276a3a420280" - }, - "0x2fc7b26c1fd501c57e57db3e876dc6ae7af6979b": { - "balance": "0", - "nonce": 1, - "root": "0x3d20fedd270b3771706fe00a580a155439be57e8d550762def10906e83ed58bb", + "root": "0x9e2e9c13c28b856f12884ebd17a330603ac2294d472aa7b0caab80761af0ae9d", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x000000000000000000000000000000000000000000000000000000000000009f": "9f", - "0x00000000000000000000000000000000000000000000000000000000000000a0": "a0", - "0x00000000000000000000000000000000000000000000000000000000000000a1": "a1" + "0x0000000000000000000000000000000000000000000000000000000000000076": "76", + "0x0000000000000000000000000000000000000000000000000000000000000077": "77", + "0x0000000000000000000000000000000000000000000000000000000000000078": "78" }, + "address": "0x2be6f9ec5d4a0e79953570f06554fbff9473b11e", + "key": "0xc5a247c452045b83598d9bdb0bfc185eadffbc577e2f8bbafaa5339d2adac545" + }, + "0x2c1287779024c3a2F0924b54816D79b7e378907d": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xbe1fa08bc91e8829cee159efe23236d54f009cb119f2685588cb4d78945236ea", + "code": "0x52d75039926638d3c558b2bdefb945d5be8dae29dedd1c313212a4d472d9fde5edc95719e9a3b28dd8e80877cb5880a9be7de1a13fc8b05e7999683b6b567643ee60d0579bcffd98e668647d59fec1ff86a7fb340ce572e844f234ae73a6918f83ec6a1f0257b830b5e016457c9cf1435391bf56cc98f369a58a54fe937724651a1e6821cde7d0159c0d293177871e09677b4e42307c7db3ba94f8648a5a050f3eec716f11ba9e820c81ca75eb978ffb45831ef8b7a53e5e422c26008e1ca6d5c5069e24aaadb2addc3e52e868fcf3f4f8acf5a87e24300992fd4540c2a87eedb805995a7ec585a251200611a61d179cfd7fb105e1ab17dc415a7336783786f7", + "address": "0x2c1287779024c3a2f0924b54816d79b7e378907d", + "key": "0x09d6e6745d272389182a510994e2b54d14b731fac96b9c9ef434bc1924315371" + }, + "0x2fc7B26C1FD501C57E57dB3E876Dc6Ae7AF6979B": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x2fc7b26c1fd501c57e57db3e876dc6ae7af6979b", "key": "0xb9cddc73dfdacd009e55f27bdfd1cd37eef022ded5ce686ab0ffe890e6bf311e" }, - "0x30a5bfa58e128af9e5a4955725d8ad26d4d574a5": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe1eb1e18ae510d0066d60db5c2752e8c33604d4da24c38d2bda07c0cb6ad19e4" - }, - "0x30c72b4fb390ff1d387821e210f3ab04fbe86d13": { + "0x33aFD8244c9C1a37F5bDDb3254Cd08779a196458": { "balance": "0", "nonce": 1, - "root": "0xdf97f94bc47471870606f626fb7a0b42eed2d45fcc84dc1200ce62f7831da990", + "root": "0x18bb17163a640c960d76901ccac104f3b60f46c150c29584868b14229b97966f", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000d6": "d6", - "0x00000000000000000000000000000000000000000000000000000000000000d7": "d7", - "0x00000000000000000000000000000000000000000000000000000000000000d8": "d8" + "0x00000000000000000000000000000000000000000000000000000000000001b5": "01b5", + "0x00000000000000000000000000000000000000000000000000000000000001b6": "01b6", + "0x00000000000000000000000000000000000000000000000000000000000001b7": "01b7" }, - "key": "0x005e94bf632e80cde11add7d3447cd4ca93a5f2205d9874261484ae180718bd6" - }, - "0x311df588ca5f412f970891e4cc3ac23648968ca2": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x974a4800ec4c0e998f581c6ee8c3972530989e97a179c6b2d40b8710c036e7b1" - }, - "0x312e8fca5ac7dfc591031831bff6fede6ecf12a8": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x64bfba8a4688bdee41c4b998e101567b8b56fea53d30ab85393f2d5b70c5da90" - }, - "0x32c417b98c3d9bdd37550c0070310526347b4648": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x80cd4a7b601d4ba0cb09e527a246c2b5dd25b6dbf862ac4e87c6b189bfce82d7" - }, - "0x33afd8244c9c1a37f5bddb3254cd08779a196458": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x33afd8244c9c1a37f5bddb3254cd08779a196458", "key": "0x210ce6d692a21d75de3764b6c0356c63a51550ebec2c01f56c154c24b1cf8888" }, - "0x33fc6e8ad066231eb5527d1a39214c1eb390985d": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x87e33f70e1dd3c6ff68e3b71757d697fbeb20daae7a3cc8a7b1b3aa894592c50" - }, - "0x360671abc40afd33ae0091e87e589fc320bf9e3d": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x12c1bb3dddf0f06f62d70ed5b7f7db7d89b591b3f23a838062631c4809c37196" - }, - "0x3632d1763078069ca77b90e27061147a3b17ddc3": { + "0x36fedBB5CdA6a9924e5da9Ce388b3418E0cFae06": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x0463e52cda557221b0b66bd7285b043071df4c2ab146260f4e010970f3a0cccf" + "address": "0x36fedbb5cda6a9924e5da9ce388b3418e0cfae06", + "key": "0xd9cf358f42d8836e892ab02529c9659d6fae5ea088bd936be43e28d85af28fbe" }, - "0x368b766f1e4d7bf437d2a709577a5210a99002b6": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4845aac9f26fcd628b39b83d1ccb5c554450b9666b66f83aa93a1523f4db0ab6" - }, - "0x36a9e7f1c95b82ffb99743e0c5c4ce95d83c9a43": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xcac96145454c46255fccca35343d9505164dabe319c17d81fda93cf1171e4c6e" - }, - "0x38d0bd409abe8d78f9f0e0a03671e44e81c41c27": { + "0x38D0Bd409aBe8d78F9F0E0a03671e44e81c41C27": { "balance": "0", "nonce": 1, - "root": "0x23a888c0a464ce461651fc1be2cfa0cb6ba4d1b125abe5b447eeadf9c5adf1f1", + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000167": "0167", - "0x0000000000000000000000000000000000000000000000000000000000000168": "0168", - "0x0000000000000000000000000000000000000000000000000000000000000169": "0169" - }, + "address": "0x38d0bd409abe8d78f9f0e0a03671e44e81c41c27", "key": "0xb58e67c536550fdf7140c8333ca62128df469a7270b16d528bc778909e0ac9a5" }, - "0x3ae75c08b4c907eb63a8960c45b86e1e9ab6123c": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, + "0x3A2C11526F95C05A5de3614E9c40666798C5F9b9": { + "balance": "0", + "nonce": 1, + "root": "0x838d9383f5c87eea967abf79c12ce654a2472b04b35c0dacda9d7d4c992e3993", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000168": "0168", + "0x0000000000000000000000000000000000000000000000000000000000000169": "0169", + "0x000000000000000000000000000000000000000000000000000000000000016a": "016a" + }, + "address": "0x3a2c11526f95c05a5de3614e9c40666798c5f9b9", + "key": "0xec873ed51fb0822893b43c0fd08bd25d1c226a97f7ba073cd03b8fdbe380ed19" + }, + "0x3C48a562A0361236F28a17AAC65B9130a0316B71": { + "balance": "0", + "nonce": 1, + "root": "0xd8419536b78c13ef996838648ee38f89388fe1ffdca0b92bbbd78187a54c3f49", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000034": "34", + "0x0000000000000000000000000000000000000000000000000000000000000035": "35", + "0x0000000000000000000000000000000000000000000000000000000000000036": "36" + }, + "address": "0x3c48a562a0361236f28a17aac65b9130a0316b71", + "key": "0x8ff8a4884137e983c0298ad24228193292b5f523869dc16eeb916cae8b09239c" + }, + "0x3Ee253436Fc50e5a136eE01489a318afe2bbD572": { + "balance": "0", + "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x878040f46b1b4a065e6b82abd35421eb69eededc0c9598b82e3587ae47c8a651" - }, - "0x3bcc2d6d48ffeade5ac5af3ee7acd7875082e50a": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb5bca5e9ccef948c2431372315acc3b96e098d0e962b0c99d634a0475b670dc3" - }, - "0x3c204ccddfebae334988367b5cf372387dc49ebd": { - "balance": "0", - "nonce": 1, - "root": "0xc7bf2b34294065afb9a2c15f906cba1f7a1a9f0da34ea9c46603b52cae9028ec", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000194": "0194", - "0x0000000000000000000000000000000000000000000000000000000000000195": "0195", - "0x0000000000000000000000000000000000000000000000000000000000000196": "0196" - }, - "key": "0x5ec55391e89ac4c3cf9e61801cd13609e8757ab6ed08687237b789f666ea781b" - }, - "0x3c2572436de9a5f3c450071e391c8a9410ba517d": { - "balance": "0", - "nonce": 1, - "root": "0xbfba1bc2ac42655f5a97450be62b9430822232f1ce4998eaf5239b0c243b2b84", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000090": "90", - "0x0000000000000000000000000000000000000000000000000000000000000091": "91", - "0x0000000000000000000000000000000000000000000000000000000000000092": "92" - }, - "key": "0x606059a65065e5f41347f38754e6ddb99b2d709fbff259343d399a4f9832b48f" - }, - "0x3c5c4713708c72b519144ba8e595a8865505000d": { - "balance": "0", - "nonce": 1, - "root": "0x52d6d2913ae44bca11b5a116021db97c91a13e385ed48ba06628e74201231dba", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001c1": "01c1", - "0x00000000000000000000000000000000000000000000000000000000000001c2": "01c2", - "0x00000000000000000000000000000000000000000000000000000000000001c3": "01c3" - }, - "key": "0x37ddfcbcb4b2498578f90e0fcfef9965dcde4d4dfabe2f2836d2257faa169947" - }, - "0x3cf2e7052ebd484a8d6fbca579ddb3cf920de9d3": { - "balance": "0", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa95c88d7dc0f2373287c3b2407ba8e7419063833c424b06d8bb3b29181bb632e" - }, - "0x3ee253436fc50e5a136ee01489a318afe2bbd572": { - "balance": "0", - "nonce": 1, - "root": "0xc57604a461c94ecdac12dbb706a52b32913d72253baffb8906e742724ae12449", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001b2": "01b2", - "0x00000000000000000000000000000000000000000000000000000000000001b3": "01b3", - "0x00000000000000000000000000000000000000000000000000000000000001b4": "01b4" - }, + "address": "0x3ee253436fc50e5a136ee01489a318afe2bbd572", "key": "0xaf7c37d08a73483eff9ef5054477fb5d836a184aa07c3edb4409b9eb22dd56ca" }, - "0x3f31becc97226d3c17bf574dd86f39735fe0f0c1": { - "balance": "100000000000", + "0x3aDfbF5A4B4493AB10b6d695E5a6f7f91F768098": { + "balance": "0", + "nonce": 1, + "root": "0x98d78678d41a3fbfda98fdf2709727e38bb15bf11287e7204299ef5a125acf8f", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000022e": "022e", + "0x000000000000000000000000000000000000000000000000000000000000022f": "022f", + "0x0000000000000000000000000000000000000000000000000000000000000230": "0230" + }, + "address": "0x3adfbf5a4b4493ab10b6d695e5a6f7f91f768098", + "key": "0x83d7634225a59c664f323c88bcfaff1cf73421ed036ccd2dbe44571312128db7" + }, + "0x3aE75c08b4c907EB63a8960c45B86E1e9ab6123c": { + "balance": "1000000000000000000000000100000000012", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb40cc623b26a22203675787ca05b3be2c2af34b6b565bab95d43e7057e458684" + "address": "0x3ae75c08b4c907eb63a8960c45b86e1e9ab6123c", + "key": "0x878040f46b1b4a065e6b82abd35421eb69eededc0c9598b82e3587ae47c8a651" }, - "0x3f79bb7b435b05321651daefd374cdc681dc06fa": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "0x4055CAe5c7d838cda10D40f9d07106C7f5f3be1c": { + "balance": "0", + "nonce": 1, + "root": "0xf8f4ccb01824f447885742bd7fbc7505e7f1d0252fba74fe7068be964e8a35ee", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x8c7bfaa19ea367dec5272872114c46802724a27d9b67ea3eed85431df664664e" + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000006": "06", + "0x0000000000000000000000000000000000000000000000000000000000000007": "07", + "0x0000000000000000000000000000000000000000000000000000000000000008": "08" + }, + "address": "0x4055cae5c7d838cda10d40f9d07106c7f5f3be1c", + "key": "0x6b9ff41fb13fc66c4e1c4f85d59c52608698715472b7cce609bdbf75976a438b" }, - "0x3fba9ae304c21d19f50c23db133073f4f9665fc1": { + "0x417fE11f58B6A2d089826B60722fBeD1D2Db96dD": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x0b564e4a0203cbcec8301709a7449e2e7371910778df64c89f48507390f2d129" - }, - "0x402f57de890877def439a753fcc0c37ac7808ef5": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5c20f6ee05edbb60beeab752d87412b2f6e12c8feefa2079e6bd989f814ed4da" - }, - "0x40b7ab67fb92dbcb4ff4e39e1155cad2fa066523": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd352b05571154d9a2061143fe6df190a740a2d321c59eb94a54acb7f3054e489" - }, - "0x414a21e525a759e3ffeb22556be6348a92d5a13e": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x15293aec87177f6c88f58bc51274ba75f1331f5cb94f0c973b1deab8b3524dfe" - }, - "0x417fe11f58b6a2d089826b60722fbed1d2db96dd": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "codeHash": "0x35e6505af3b8e9a18eefffd4dafa37f401469b1932fa2011ce72a78ea72721ab", + "code": "0x36156009575f355f555b305f525f5460205260405ff3", + "address": "0x417fe11f58b6a2d089826b60722fbed1d2db96dd", "key": "0xd5e252ab2fba10107258010f154445cf7dffc42b7d8c5476de9a7adb533d73f1" }, - "0x41b45640640c98c953feef23468e0d275515f82f": { + "0x426Fcdc383c8bEcb38926EC0569Ec4a810105faB": { "balance": "0", "nonce": 1, - "root": "0x82b326641825378faa11c641c916f2e22c01080f487de0463e30d5e32b960f97", + "root": "0x42e40009dbade0eeca64fbd7faef8c68145ca05516d238892f9caa271801f955", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x000000000000000000000000000000000000000000000000000000000000013a": "013a", - "0x000000000000000000000000000000000000000000000000000000000000013b": "013b", - "0x000000000000000000000000000000000000000000000000000000000000013c": "013c" + "0x0000000000000000000000000000000000000000000000000000000000000173": "0173", + "0x0000000000000000000000000000000000000000000000000000000000000174": "0174", + "0x0000000000000000000000000000000000000000000000000000000000000175": "0175" }, - "key": "0xc2406cbd93e511ef493ac81ebe2b6a3fbecd05a3ba52d82a23a88eeb9d8604f0" - }, - "0x426fcdc383c8becb38926ec0569ec4a810105fab": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x426fcdc383c8becb38926ec0569ec4a810105fab", "key": "0x6bd9fb206b22c76b4f9630248940855b842c684db89adff0eb9371846ea625a9" }, - "0x4340ee1b812acb40a1eb561c019c327b243b92df": { - "balance": "1000000000000000000000000000000000000", + "0x4340Ee1b812ACB40a1eb561C019c327b243b92Df": { + "balance": "1000000000000000000000000300000000003", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x4340ee1b812acb40a1eb561c019c327b243b92df", "key": "0xa13bfef92e05edee891599aa5e447ff2baa1708d9a6473a04ef66ab94f2a11e4" }, - "0x44bd7ae60f478fae1061e11a7739f4b94d1daf91": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb66092bc3624d84ff94ee42b097e846baf6142197d2c31245734d56a275c8eb9" - }, - "0x452705f08c621987b14d5f729ca81829041f6373": { + "0x4392115B81B6B7CbFf42Cd14752B9e565f316A17": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xac7183ebb421005a660509b070d3d47fc4e134cb7379c31dc35dc03ebd02e1cf" + "address": "0x4392115b81b6b7cbff42cd14752b9e565f316a17", + "key": "0x22a1c10e01e8ea21a3cb7e91945d881902b50c6adf4c0ea05d84031843e2926d" }, - "0x45dcb3e20af2d8ba583d774404ee8fedcd97672b": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x465311df0bf146d43750ed7d11b0451b5f6d5bfc69b8a216ef2f1c79c93cd848" - }, - "0x45f83d17e10b34fca01eb8f4454dac34a777d940": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6dc09fdec00aa9a30dd8db984406a33e3ca15e35222a74773071207a5e56d2c2" - }, - "0x469542b3ece7ae501372a11c673d7627294a85ca": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6dbe5551f50400859d14228606bf221beff07238bfa3866454304abb572f9512" - }, - "0x469dacecdef1d68cb354c4a5c015df7cb6d655bf": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x8b76305d3f00d33f77bd41496b4144fd3d113a2ec032983bd5830a8b73f61cf0" - }, - "0x46b61db0aac95a332cecadad86e52531e578cf1f": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5677600b2af87d21fdab2ac8ed39bd1be2f790c04600de0400c1989040d9879c" - }, - "0x478508483cbb05defd7dcdac355dadf06282a6f2": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5fc13d7452287b5a8e3c3be9e4f9057b5c2dd82aeaff4ed892c96fc944ec31e7" - }, - "0x47ce7195b6d53aaa737ff17d57db20d0d4874ef1": { + "0x452b949F5F7A7D6AC67548ec72e0094da846ea4b": { "balance": "0", "nonce": 1, - "root": "0x3d0e2ba537f35941068709450f25fee45aaf4dc6ae2ed22ad12e0743ac7c54a7", + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x59e905c6f4910756e1c3d7a42a7f0112d5bbfbffc659d314844a4acc0887b80b", + "code": "0xd999b6a905cb253021254361eb51ac2428d229184f9dd8342bc05b348b9500fb36ade7bb9eee45f234519bd60a6fcadd441f23ab0372b0e186bc601b6ef1620fb65a1d54c4d5bc403446d3ef51b4c9b82eef10b13a26d6879a440e0632bbcc7cbb77812a8fa7fa6a572953fea9126358f3aec9cde938b0c1788d783c38ffd2cb5223396cf9abeb9b7dc4cfbacea4c512b02b65d83cdfbd6fd2dce335ed44bc52e9273958f1f266f4f9bc99c85e71ee2d69a5da24fcfd4d7f1afcc533bd57dec460ac682b9a49392840ac8f0ca7e6ca743398112599febf8b36c5b1bc3b8722e72fd80a925745c8e06fa027189d551200638c1edbf79c0b3fef833bbdd2036cad", + "address": "0x452b949f5f7a7d6ac67548ec72e0094da846ea4b", + "key": "0x2ef46ebd2073cecde499c2e8df028ad79a26d57bfaa812c4c6f7eb4c9617b913" + }, + "0x46BEEa1D87bA969470C758f1540e78e8C2A15C89": { + "balance": "0", + "nonce": 1, + "root": "0x42839850cb45ac89303f87b0f4163a6f349a021dfce0397819b4008210e70556", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000108": "0108", - "0x0000000000000000000000000000000000000000000000000000000000000109": "0109", - "0x000000000000000000000000000000000000000000000000000000000000010a": "010a" + "0x00000000000000000000000000000000000000000000000000000000000000e4": "e4", + "0x00000000000000000000000000000000000000000000000000000000000000e5": "e5", + "0x00000000000000000000000000000000000000000000000000000000000000e6": "e6" }, - "key": "0x0579e46a5ed8a88504ac7d579b12eb346fbe4fd7e281bdd226b891f8abed4789" + "address": "0x46beea1d87ba969470c758f1540e78e8c2a15c89", + "key": "0xae3a22c9b1610c3a9f8e0f71e2f5daa824be2a1e2de6b40da984e4e8bdb2df8d" }, - "0x47dc540c94ceb704a23875c11273e16bb0b8a87a": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x025f478d53bf78add6fa3708d9e061d59bfe14b21329b2a4cf1156d4f81b3d2d" - }, - "0x47e642c9a2f80499964cfda089e0b1f52ed0f57d": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x05f6de281d8c2b5d98e8e01cd529bd76416b248caf11e0552047c5f1d516aab6" - }, - "0x4816ce9dd68c07ab1e12b5ddc4dbef38792751c5": { + "0x46bFe8155134dcD7bB9baDEf1B2EF25AE86435C8": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x46bfe8155134dcd7bb9badef1b2ef25ae86435c8", + "key": "0x59f49281260efa7511a50c95aebc610a48a19aeaa54f041e1373b81b698989d3" + }, + "0x47e37FB6Ade990175D502C02DA3Dc3607b9D0080": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x30cddb925e3f4db7ec9bb0259a1726f79627a71b97dfdbf8827cce2ff258fc64", + "code": "0xd6866844f1a8c30f9968e80fa46697288da4b41c675b67a51469639e5afc24352ad561dc52a39ba65c35d8ffc50780b2be420e6593582aa43068d94afe08aa0ba82effcee24f9d07d1b8ac005bd5c8627d3d8c14e389a86d3b62ee3d5f63ab8910f3a17841c6d818ccbb16e4596978865bb77ba586b583c9de26b166e55de864aaded8c7cb956d25d285cba29213c176ec5fc32f3996cb04804f6c9dc496ea728ec4d803bc2cd2bec8ceaf2e5a0dec14ca32ca78fa74656eb25549e85d5772b1a241f58d1f790a3686289a7a511e6884e534f73cfe21a83706dadf334c70edd8a42755a2e6766ad8a3c8e0dc6925c5b384a166afae805bfb4a3c3233012e5345", + "address": "0x47e37fb6ade990175d502c02da3dc3607b9d0080", + "key": "0x7842c57cd7a74b4a6b925c5db7c5953f7c65969fedc3f81c087d6ddf9322e6de" + }, + "0x4816Ce9Dd68c07aB1e12b5dDC4dBEF38792751C5": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x68fe999031d902f2cc91d087a2598dbc4461ac613484a5e190363612bbb7b26a", + "code": "0xfcb16150feea765524e9631cb7d1c8fad9ef75bffc2b9555ecc778186e5f140839772aaac033ecb199d13e70c3b4f8460b29cb5c3706d73d2ca45ca99b4ca34eff4638b33a6cbf8dc1ce4956e292e68da624d971bbf286cb7b35f308cea1c92b25449fa2e7137906e514f13986232d0f39f369be718e81f160ca187154669ae03a9dbf973d57393fa007fb8bd8b707e68131e5350075a7173b126035e7d5ef0800865105d845ec42a1bb319d16dde04301a355a4a41c6bd516f7937fbef9e4a44afe6e90eec383b191ec32dadb5b4f777a12a1e05ead60984ca62aa5eb8c24a5cf02837130190a95dcc836111e3f8751322ffcf187e84483660b9878a189eb2f", + "address": "0x4816ce9dd68c07ab1e12b5ddc4dbef38792751c5", "key": "0x93843d6fa1fe5709a3035573f61cc06832f0377544d16d3a0725e78a0fa0267c" }, - "0x48701721ec0115f04bc7404058f6c0f386946e09": { - "balance": "100000000000", - "nonce": 0, + "0x49790702079905E7fF97976DB38b586cbC8d8f8F": { + "balance": "0", + "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x12be3bf1f9b1dab5f908ca964115bee3bcff5371f84ede45bc60591b21117c51" + "codeHash": "0x9231a45606b88ef38e96170f698ef8b8598e49b17187c2e70bc225e6a310cc36", + "code": "0xe5f0063c1029cda3916753b401644c6cf5a2638073f3d047231d47d090ece5034da2fdba370917407bf27824b5e855154d59c9cf9fb85539d72027a97766a6847cddfe6ee35b633c2515d8bb92b0535385c25ce39e902fe4b910ed87a58a3b60cd3081b24d2bafaebfca188b94ec88c4e89cff1900493426655481a8976b4844bcc8f9a3b8acb6eaeffd4381f3d6cf8b3246ec37986171ade75dabece51a6f930482edbcb3ac47f314e74e8a59cbb23c7d36fd54f30d440cd1e2368bac348c0234d70136299f76a744ea8afda8ebddfe1632bb03a70f19f9a17b6d3d3ba5575326dae0c1fa21b43457f9f70b55c25fa5dbad768871d3a55b8d7fdbbe10bdd96f", + "address": "0x49790702079905e7ff97976db38b586cbc8d8f8f", + "key": "0x13fb7f6b6fcbfc3892b99fb37dfd04ecf3c8d56f2d14add9517b76ea9555c1a3" }, - "0x494d799e953876ac6022c3f7da5e0f3c04b549be": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "0x4A5F072863f868E00D0039807EE1d00F783335A0": { + "balance": "0", + "nonce": 1, + "root": "0x4ba055b3d6ea2c0c46b8cb5ee08f6999487ff7d49e3e4fe566ae049608f647aa", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x04d9aa4f67f8b24d70a0ffd757e82456d9184113106b7d9e8eb6c3e8a8df27ee" + "storage": { + "0x00000000000000000000000000000000000000000000000000000000000001aa": "01aa", + "0x00000000000000000000000000000000000000000000000000000000000001ab": "01ab", + "0x00000000000000000000000000000000000000000000000000000000000001ac": "01ac" + }, + "address": "0x4a5f072863f868e00d0039807ee1d00f783335a0", + "key": "0x8fa1ad571a8b9c6e679630b6e0d38d678311338dc0362f9303d10585aaf26d88" }, - "0x4a0f1452281bcec5bd90c3dce6162a5995bfe9df": { - "balance": "1000000000000000000000000000000000000", + "0x4BE1C90eB0389A67A16a0d3027AFbE68eB26Fa40": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1cb937eefd555a5cd91fcc756cc135b04866df6c4e79b7fadf8ee10c0e8c45a3", + "code": "0x6bf91e8d24ef545af6a807b0be29a4dd23c0aa47cf86b2cc206ca5ea23e055b2508079f55449251bb3bbdddb22a48768402fe704ba650632035ff2d1f076fe8ed4dd338702652a43f9ac2b2bb0a6113f819db6a79f2161642d6d00325b6004b409c221adb84d5771ff4acef6600bf4bcaae01c6e3b391a7a61d09dd98b033b4d5a720867e9fea2afb6fbd35e6fcef36c6937fcecdcc9d43dcf109be0eaf9b0f76f25c0a5b9213781766d43fd87d9b3c49063e227d41ca646f0041bc234e3f0b821cc2999d14cb884f78fd8d378149fefb96229f402ad786759cb00743d06a86d4128452ee0fadc2e40ee2c2df6066f44872006f24784df32eee9df0d59afcb65", + "address": "0x4be1c90eb0389a67a16a0d3027afbe68eb26fa40", + "key": "0xccf7b06a67d8943c3e6f1af42977144fdcd4e35c5935804dccfab975d22fafbb" + }, + "0x4Ba8273797F206A13B4d13239A9C7692951Ba5Dd": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x6bd773abf6bc040838521c9de345cfedbce33617c4c7dc7e28ff79ee67576911", + "code": "0x7c263fa0a5ccb147804e1651fd02a4a91952936ded9df2b9563f58d3237deb6a2d4d9a6ec39bf84ae0d7d0d9e45117cf3fa3d0fbb6e82c52a370dde3249feff83cde3efd24a4795570409a9e1b6dbf5422dfd717e5210b527266f77c827cdf45d903a9ee0bc20272238d57d8e5255e7e6042b6f02f15379507de7f4fd2d73e2efb5e2c639adf6f19556e762eea9953bf8c1f92c6a39651186429f581ab8068491845cf6ae7e4ea2bf7813e2b8bc2c114d32bd93817b2f113543c4e0ebc1f38d29c098d85f6b83561069bae1c5511a0bbd59215ff2718b423e828420534b07ce255f7fb2960e0b7d7b8eaaaeb07b847a0fcd209d4e050e30df0ea578f57d3dabd", + "address": "0x4ba8273797f206a13b4d13239a9c7692951ba5dd", + "key": "0x48c2282032e9f2a065de95c075888d04a8dede9499b3c4837179b81d6992c572" + }, + "0x4FdE47c424dddFb38606FEdaE5b6522D8aC6C3e3": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x314204915e2b98401a3ade8178f328eb28e28be295588c447b09b5ac4a782140", + "code": "0x825cb36b0f2510a04cf6a63d38fd27bab6d05658e3c7b75a8e0bc0433c0ad1d83254a08c6b1f2452e29dd01c1d0c85218d57ed34adaa4d9e3b5080f944b9bd85a0b82392ca930f909da3e8f1e1b75001281d70a8e3841b3b4dbad931d5554bd4fbca97ca5841cc7bc1e64c05a3e88ed0241af42ee1c0e65d806d2bfb6bb7fcde939a97a2cdf42f5b2accc7a97b393a7e41066fe584741a52b411280ec3e57603acafcf2c60bf92bccb8c65f5ccffb377b9ab5ab1e8283e2807c12a0c2ffc1ebeb63423a192f69a0ae0d422d5ecafd6a0773a3869d94cfcc860a907e75f293a84a569f999e0f44f33e77ec9059a51b9940e65c0f955f48a7dfe61f7c752a08a8e", + "address": "0x4fde47c424dddfb38606fedae5b6522d8ac6c3e3", + "key": "0xfb620e9421928a795a331d223b11ab476c45372f2c7c3dffc9b13f0e1812b05c" + }, + "0x4a0f1452281bCec5bd90c3dce6162a5995bfe9df": { + "balance": "1000000000000000000000000200000000010", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x4a0f1452281bcec5bd90c3dce6162a5995bfe9df", "key": "0x5c1d92594d6377fe6423257781b382f94dffcde4fadbf571aa328f6eb18f8fcd" }, - "0x4a64a107f0cb32536e5bce6c98c393db21cca7f4": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf16522fc36907ee1e9948240b0c1d1d105a75cc63b71006f16c20d79ad469bd7" - }, - "0x4ae81572f06e1b88fd5ced7a1a000945432e83e1": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x2116ab29b4cb8547af547fe472b7ce30713f234ed49cb1801ea6d3cf9c796d57" - }, - "0x4b227777d4dd1fc61c6f884f48641d02b4d121d3": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x246cc8a2b79a30ec71390d829d0cb37cce1b953e89cb14deae4945526714a71c" - }, - "0x4ba91e785d2361ddb198bcd71d6038305021a9b8": { + "0x4bA91E785d2361ddB198Bcd71D6038305021A9b8": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "codeHash": "0xd65f73004752376a8f043ec68c2c964e98926865f14775678b2aa84947a74e7b", + "code": "0x84420f67222b5641972786145b747b9f6b269166fdbd701129dc55eaa77148fe96259bc7ece823714bb3a8cdbaf7f384e05c267f2e16021d51fba05ac06151898b94fcf86dae9dd6026b2b824fa932e75c4b81a1e20209dc376bd215d0be1a551346e0df37ec385cdcfef5b73b13f4fa1b55be0c86f81fb5b3701ef64fc4df00f5349d815f3ca9782afe723f3eacee30c3464fc05e12638977843bb2183a16ade78ea91a221fb67f10aba14ba22dc39f780130b5cf7d2295f57a7414e295968ba005de1f4b235134f6a66019013c8498d7fe5d9c4a258bb57fe1485c0d4f3e3abd13a6863b607a386edab49cda39c0a4d9199a0f276cecc8aaa8f8c5a83f8170", + "address": "0x4ba91e785d2361ddb198bcd71d6038305021a9b8", "key": "0x99ce1680f73f2adfa8e6bed135baa3360e3d17f185521918f9341fc236526321" }, - "0x4bfa260a661d68110a7a0a45264d2d43af9727de": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6f358b4e903d31fdd5c05cddaa174296bb30b6b2f72f1ff6410e6c1069198989" - }, - "0x4dde844b71bcdf95512fb4dc94e84fb67b512ed8": { - "balance": "1000000000000000000000000000000000000", + "0x4ddE844b71bcdf95512Fb4Dc94e84FB67b512eD8": { + "balance": "1000000000000000000000000000000000011", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x4dde844b71bcdf95512fb4dc94e84fb67b512ed8", "key": "0x5602444769b5fd1ddfca48e3c38f2ecad326fe2433f22b90f6566a38496bd426" }, - "0x4f362f9093bb8e7012f466224ff1237c0746d8c8": { - "balance": "100000000000", - "nonce": 0, + "0x514772fb7F9ED5E54Ea9fdC34aA4dfC7bE594494": { + "balance": "0", + "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xcb6f450b4720c6b36d3a12271e35ace27f1d527d46b073771541ad39cc59398d" + "codeHash": "0x899281cb5d4cbae8408193bbbaa6701ab3d6dc4c07df2c4212f3f64b31f00416", + "code": "0x6654c25418c9c9cdb53e9c7e15d751e46e03faf5fe299ca4ef6817467fb3bbbb02f99646d718504e95233737033d5f11cacb283e1a9b2d1ad1d2dcef08c6a40afbe158bb61721b4374c6cbf06c87d78138667de83e1f69f30893bb437dff0373ddcda9846e422308a606a70526455845f80d0b22327f98d8eaafcc7c9b60f26b3d112fe2cfc19c13b28ff9f53ecf385f288fca3c9a800e2826903f86442b3c692e2d51fab4d9c1610962d39452e3dbc097fb8114b50951fac0449fa7df26914402f56c3256756e82795f0244ca0a1b4c6ee21854c0a86342ad6bb8f8a2eb8a4067bc00cb24423cdb75e37549e0e845bf4e9d27038e3fbbeb29e8e99a1aa5c461", + "address": "0x514772fb7f9ed5e54ea9fdc34aa4dfc7be594494", + "key": "0xf02f9c16ca8e4ca4daf37afe833d6f9b50b934fcb50954792900ce943d6b5fc8" }, - "0x4f3e7da249f34e3cc8b261a7dc5b2d8e1cd85b78": { + "0x5259FD366E381590eD3d01cF2181726498eFdaA2": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4d79fea6c7fef10cb0b5a8b3d85b66836a131bec0b04d891864e6fdb9794af75" + "address": "0x5259fd366e381590ed3d01cf2181726498efdaa2", + "key": "0xb4ac940399ad74961d86385549af09654ff2fd37b19860ac2197cf0ede38fcbc" }, - "0x4fb733bedb74fec8d65bedf056b935189a289e92": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa02abeb418f26179beafd96457bda8c690c6b1f3fbabac392d0920863edddbc6" - }, - "0x4fffb6fbd0372228cb5e4d1f033a29f30cb668c8": { + "0x52859c77dc11a2983F1eD3F9284f215c94FF354C": { "balance": "0", "nonce": 1, - "root": "0xcd3e75299e967d5f88d306be905a134343b224d3fd5a861b1a690de0e2dfe1ba", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000b3": "b3", - "0x00000000000000000000000000000000000000000000000000000000000000b4": "b4", - "0x00000000000000000000000000000000000000000000000000000000000000b5": "b5" - }, - "key": "0xf19ee923ed66b7b9264c2644aa20e5268a251b4914ca81b1dffee96ecb074cb1" - }, - "0x50996999ff63a9a1a07da880af8f8c745a7fe72c": { - "balance": "1", - "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x0e57ffa6cc6cbd96c1400150417dd9b30d958c58f63c36230a90a02b076f78b5" + "codeHash": "0x38ec67839d530b6a89731615d891c92067632d4439c68e5ac4a823d0a6e4f567", + "code": "0x117de450db9ef19cde82383de3b55cb0a7965580517c7121000ae2f172c97cbc9e45afa898d1218177bd2c70d157dabd7c7e29f662fd9efaedfcbb325862d874ac7511a01df823fb51359303411b7e2f723cd4e10f128e3084b8ebbea214c26304bb3b4207ce82295d38e8bff9678c7ffab2d11ac7c8ae0afa11bb2d6b2ff7fc6a4cd983fbfa662ee9a9fcdd19aa030fb27b315fada4a7adf24555d0223dc4871c8533394fc1a3f2824e39d8ef04b7ac42ed1afab3eb82c41e5654726710177000cc4898feff114e317ec8cc5776eedd027135f826cc0a15a25d1f713a60e56f0d1052827618a31385863032e24ca36ed2081d363c7d531b6429ccd7f7fafb7b", + "address": "0x52859c77dc11a2983f1ed3f9284f215c94ff354c", + "key": "0xb8da07edfd4449f2c95df40fc5095b3e75a702fcbaac7b5f9dce232800cfac3e" }, - "0x5123198d8a827fe0c788c409e7d2068afde64339": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa15773c9bfabef49e9825460ed95bf67b22b67d7806c840e0eb546d73c424768" - }, - "0x526e1ff4cddb5033849a114c54eb71a176f6440c": { - "balance": "0", - "nonce": 1, - "root": "0x834718111121e2058fdb90a51f448028071857e11fbd55d43256174df56af01a", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000c7": "c7", - "0x00000000000000000000000000000000000000000000000000000000000000c8": "c8", - "0x00000000000000000000000000000000000000000000000000000000000000c9": "c9" - }, - "key": "0xb3a33a7f35ca5d08552516f58e9f76219716f9930a3a11ce9ae5db3e7a81445d" - }, - "0x5371ac01baa0b8aa9cbfcd36a49e0b5f7fb7109d": { - "balance": "0", - "nonce": 1, - "root": "0x385b84d27059a3c78e7ea63a691eeb9c5376f77af11336762f8c18882ff7471a", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000028": "28", - "0x0000000000000000000000000000000000000000000000000000000000000029": "29", - "0x000000000000000000000000000000000000000000000000000000000000002a": "2a" - }, - "key": "0x7a08bb8417e6b18da3ba926568f1022c15553b2b0f1a32f2fd9e5a605469e54f" - }, - "0x54314225e5efd5b8283d6ec2f7a03d5a92106374": { + "0x549ABF1AE8db6dE0D131A7B2b094C813EC1c6731": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xcade985c7fb6d371d0c7f7cb40178e7873d623eadcc37545798ec33a04bb2173" - }, - "0x549abf1ae8db6de0d131a7b2b094c813ec1c6731": { - "balance": "0", - "nonce": 1, - "root": "0x73bffc68a947fa19b7becd45661d22c870fac8dbf2b25703e1bdab5367f29543", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000086": "86", - "0x0000000000000000000000000000000000000000000000000000000000000087": "87", - "0x0000000000000000000000000000000000000000000000000000000000000088": "88" - }, + "address": "0x549abf1ae8db6de0d131a7b2b094c813ec1c6731", "key": "0x910fb8b22867289cb57531ad39070ef8dbdbbe7aee941886a0e9f572b63ae9ee" }, - "0x5502b2da1a3a08ad258aa08c0c6e0312cf047e64": { - "balance": "0", - "nonce": 1, - "root": "0xf73591e791af4c7c5fa039c33dd9d169cab14b1d9b0ca78bcc4e740d553b1acf", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000f4": "f4", - "0x00000000000000000000000000000000000000000000000000000000000000f5": "f5", - "0x00000000000000000000000000000000000000000000000000000000000000f6": "f6" - }, - "key": "0x1d6ee979097e29141ad6b97ae19bb592420652b7000003c55eb52d5225c3307d" - }, - "0x553f68e60e9f8ea74c831449525dc1bc4f6fc58e": { - "balance": "0", - "nonce": 1, - "root": "0x14f9f4b9445c7547d5a4671a38b0b12bbc0e7198c3b2934b82b695c8630d4972", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000126": "0126", - "0x0000000000000000000000000000000000000000000000000000000000000127": "0127", - "0x0000000000000000000000000000000000000000000000000000000000000128": "0128" - }, - "key": "0x6ad3ba011e031431dc057c808b85346d58001b85b32a4b5c90ccccea0f82e170" - }, - "0x56270eccd88bcd5ad8d2b08f82d96cd8dace4eb3": { - "balance": "0", - "nonce": 1, - "root": "0xb0700fe13dbaf94be50bcbec13a7b53e6cba034b29a3daba98fa861f5897213f", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000063": "63", - "0x0000000000000000000000000000000000000000000000000000000000000064": "64", - "0x0000000000000000000000000000000000000000000000000000000000000065": "65" - }, - "key": "0xcd6b3739d4dbce17dafc156790f2a3936eb75ce95e9bba039dd76661f40ea309" - }, - "0x56d3f289b889e65c4268a1b56b3da2d3860d0afb": { - "balance": "0", - "nonce": 0, - "root": "0x207f6c3e450546b0d1f3bc6a6faf5bfa0bff80396c55d567b834cf0e7c760347", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000000a": "0a", - "0x000000000000000000000000000000000000000000000000000000000000000b": "0b", - "0x000000000000000000000000000000000000000000000000000000000000000c": "0c" - }, - "key": "0xdc9ea08bdea052acab7c990edbb85551f2af3e1f1a236356ab345ac5bcc84562" - }, - "0x56dc3a6c5ca1e1b773e5fdfc8a92e9a42feaa6e9": { + "0x591317752B32E45c9d44D925a4bCb4898f6b51Fb": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xdbd66b6a89e01c76ae5f8cb0dcd8a24e787f58f015c9b08972bfabefa2eae0d5" - }, - "0x579ab019e6b461188300c7fb202448d34669e5ff": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x18f4256a59e1b2e01e96ac465e1d14a45d789ce49728f42082289fc25cf32b8d" - }, - "0x5820871100e656b0d84b950f0a557e37419bf17d": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4615e5f5df5b25349a00ad313c6cd0436b6c08ee5826e33a018661997f85ebaa" - }, - "0x58d77a134c11f45f9573d5c105fa6c8ae9b4237a": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd9f987fec216556304eba05bcdae47bb736eea5a4183eb3e2c3a5045734ae8c7" - }, - "0x591317752b32e45c9d44d925a4bcb4898f6b51fb": { - "balance": "0", - "nonce": 1, - "root": "0x89bde89df7f2d83344a503944bb347b847f208df837228bb2cdfd6c3228ca3df", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000011c": "011c", - "0x000000000000000000000000000000000000000000000000000000000000011d": "011d", - "0x000000000000000000000000000000000000000000000000000000000000011e": "011e" - }, + "address": "0x591317752b32e45c9d44d925a4bcb4898f6b51fb", "key": "0x88a5635dabc83e4e021167be484b62cbed0ecdaa9ac282dab2cd9405e97ed602" }, - "0x5a6e7a4754af8e7f47fc9493040d853e7b01e39d": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x3e57e37bc3f588c244ffe4da1f48a360fa540b77c92f0c76919ec4ee22b63599" - }, - "0x5b35d3e1ac7a2c61d247046d38773decf4f2839a": { + "0x5C04401B6F6a5e318c7B6f3106A6217d20008427": { "balance": "0", "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x55cab9586acb40e66f66147ff3a059cfcbbad785dddd5c0cc31cb43edf98a5d5" - }, - "0x5c019738b38feae2a8944bd644f7acd5e6f40e5c": { - "balance": "0", - "nonce": 1, - "root": "0xea83389383152270104093ed5dfe34ba403c75308133aa1be8f51ad804b3e9ee", + "root": "0xfa8419ae99f4a7adefcfee0f90051b152ab94b0f2c5e8f40afa685eaedd48d0e", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000103": "0103", - "0x0000000000000000000000000000000000000000000000000000000000000104": "0104", - "0x0000000000000000000000000000000000000000000000000000000000000105": "0105" + "0x00000000000000000000000000000000000000000000000000000000000000ad": "ad", + "0x00000000000000000000000000000000000000000000000000000000000000ae": "ae", + "0x00000000000000000000000000000000000000000000000000000000000000af": "af" }, - "key": "0xbccd85b63dba6300f84c561c5f52ce08a240564421e382e6f550ce0c12f2f632" - }, - "0x5c04401b6f6a5e318c7b6f3106a6217d20008427": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x5c04401b6f6a5e318c7b6f3106a6217d20008427", "key": "0x6c37093a34016ae687da7aabb18e42009b71edff70a94733c904aea51a4853c1" }, - "0x5c23d95614dce3317e7be72de3c81479c3172a8a": { + "0x5c019738b38feAE2a8944BD644f7AcD5E6f40e5c": { "balance": "0", "nonce": 1, - "root": "0x4f446329b5ee3d13d4f6b5e5f210ddc2d90fedba384b950e36a1d19af95c5cb1", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000000f": "0f", - "0x0000000000000000000000000000000000000000000000000000000000000010": "10", - "0x0000000000000000000000000000000000000000000000000000000000000011": "11" - }, - "key": "0x34a715e08b77afd68cde30b62e222542f3db90758370400c94d0563959a1d1a0" - }, - "0x5c62e091b8c0565f1bafad0dad5934276143ae2c": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x1bf7626cec5330a127e439e68e6ee1a1537e73b2de1aa6d6f7e06bc0f1e9d763" - }, - "0x5d6bc8f87dd221a9f8c4144a256391979ff6426b": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xcc74930e1ee0e71a8081f247ec47442a3e5d00897966754a5b3ee8beb2c1160c" - }, - "0x5df7504bc193ee4c3deadede1459eccca172e87c": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4f458f480644b18c0e8207f405b82da7f75c7b3b5a34fe6771a0ecf644677f33" - }, - "0x5ee0dd4d4840229fab4a86438efbcaf1b9571af9": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x3848b7da914222540b71e398081d04e3849d2ee0d328168a3cc173a1cd4e783b" - }, - "0x5f4755a4bd689dc90425fb2fdb64a4b191a7264d": { - "balance": "0", - "nonce": 1, - "root": "0xaf867e6cbae810caa924b8b6ac3d8c0891831491a6906dd0be7ad324dcd1533d", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000016c": "016c", - "0x000000000000000000000000000000000000000000000000000000000000016d": "016d", - "0x000000000000000000000000000000000000000000000000000000000000016e": "016e" - }, - "key": "0x1c3f74249a4892081ba0634a819aec9ed25f34c7653f5719b9098487e65ab595" - }, - "0x5f552da00dfb4d3749d9e62dcee3c918855a86a0": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd52564daf6d32a6ae29470732726859261f5a7409b4858101bd233ed5cc2f662" - }, - "0x5f553e0d115af809cfc1396b4823378b2c7cced5": { - "balance": "0", - "nonce": 1, - "root": "0xcc48f8d1c0dd6ec8ab7bbd792d94f6a74c8876b41bc859cee2228e8dad8207a4", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000ae": "ae", - "0x00000000000000000000000000000000000000000000000000000000000000af": "af", - "0x00000000000000000000000000000000000000000000000000000000000000b0": "b0" - }, - "key": "0xe3c2e12be28e2e36dc852e76dd32e091954f99f2a6480853cd7b9e01ec6cd889" - }, - "0x6096d8459f8e424f514468098e6a0f2a871c815d": { - "balance": "0", - "nonce": 1, - "root": "0xa20e6a21244af8ffccd5442297ad9b7a76ac72d7d8ac9e16f12fcc50e90b734e", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000018f": "018f", - "0x0000000000000000000000000000000000000000000000000000000000000190": "0190", - "0x0000000000000000000000000000000000000000000000000000000000000191": "0191" - }, - "key": "0x67cc0bf5341efbb7c8e1bdbf83d812b72170e6edec0263eeebdea6f107bbef0d" - }, - "0x60d0debc5c81432ee294b9a06dcf58964224bbc2": { - "balance": "0", - "nonce": 1, - "root": "0x5446b818f4c669669cd3314726ff134cf18c58a9a536df13c700610705a8b7c8", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000041": "41", - "0x0000000000000000000000000000000000000000000000000000000000000042": "42", - "0x0000000000000000000000000000000000000000000000000000000000000043": "43" - }, - "key": "0x395b92f75f8e06b5378a84ba03379f025d785d8b626b2b6a1c84b718244b9a91" - }, - "0x61774970e93c00a3e206a26c64707d3e33f89972": { - "balance": "0", - "nonce": 1, - "root": "0x869acb929f591c54cb85842a51f296635e7d895798c547a293afe43e7bf7f417", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000006d": "6d", - "0x000000000000000000000000000000000000000000000000000000000000006e": "6e", - "0x000000000000000000000000000000000000000000000000000000000000006f": "6f" - }, - "key": "0x07b49045c401bcc408f983d91a199c908cdf0d646049b5b83629a70b0117e295" - }, - "0x6269e930eee66e89863db1ff8e4744d65e1fb6bf": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x419809ad1512ed1ab3fb570f98ceb2f1d1b5dea39578583cd2b03e9378bbe418" - }, - "0x62b67e1f685b7fef51102005dddd27774be3fee3": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf462aaa112b195c148974ff796a81c0e7f9a972d04e60c178ac109102d593a88" - }, - "0x6325c46e45d96f775754b39a17d733c4920d0038": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7c463797c90e9ba42b45ae061ffaa6bbd0dad48bb4998f761e81859f2a904a49" - }, - "0x63eb2d6ec7c526fd386631f71824bad098f39813": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfdaf2549ea901a469b3e91cd1c4290fab376ef687547046751e10b7b461ff297" - }, - "0x6510225e743d73828aa4f73a3133818490bd8820": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe6d72f72fd2fc8af227f75ab3ab199f12dfb939bdcff5f0acdac06a90084def8" - }, - "0x653b3bb3e18ef84d5b1e8ff9884aecf1950c7a1c": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc2c26fbc0b7893d872fa528d6c235caab9164feb5b54c48381ff3d82c8244e77" - }, - "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x00aa781aff39a8284ef43790e3a511b2caa50803613c5096bc782e8de08fa4c5" - }, - "0x65c74c15a686187bb6bbf9958f494fc6b8006803": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x570210539713235b442bbbad50c58bee81b70efd2dad78f99e41a6c462faeb43" - }, - "0x662fb906c0fb671022f9914d6bba12250ea6adfb": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb58e22a9ece8f9b3fdbaa7d17fe5fc92345df11d6863db4159647d64a34ff10b" - }, - "0x66378d2edcc2176820e951f080dd6e9e15a0e695": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa02c8b02efb52fad3056fc96029467937c38c96d922250f6d2c0f77b923c85aa" - }, - "0x670dc376ecca46823e13bab90acab2004fb1706c": { - "balance": "0", - "nonce": 1, - "root": "0xae440143d21e24a931b6756f6b3d50d337eaf0db3e6c34e36ab46fe2d99ef83e", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000199": "0199", - "0x000000000000000000000000000000000000000000000000000000000000019a": "019a", - "0x000000000000000000000000000000000000000000000000000000000000019b": "019b" - }, - "key": "0xdcda5b5203c2257997a574bdf85b2bea6d04829e8d7e048a709badc0fb99288c" - }, - "0x6741149452787eb4384ebbd8456643f246217034": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x37e51740ad994839549a56ef8606d71ace79adc5f55c988958d1c450eea5ac2d" - }, - "0x684888c0ebb17f374298b65ee2807526c066094c": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb062c716d86a832649bccd53e9b11c77fc8a2a00ef0cc0dd2f561688a69d54f7" - }, - "0x6922e93e3827642ce4b883c756b31abf80036649": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x3be526914a7d688e00adca06a0c47c580cb7aa934115ca26006a1ed5455dd2ce" - }, - "0x6a632187a3abf9bebb66d43368fccd612f631cbc": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x9de451c4f48bdb56c6df198ff8e1f5e349a84a4dc11de924707718e6ac897aa6" - }, - "0x6b23c0d5f35d1b11f9b683f0b0a617355deb1127": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x099d5081762b8b265e8ba4cd8e43f08be4715d903a0b1d96b3d9c4e811cbfb33" - }, - "0x6b2884fef44bd4288621a2cda9f88ca07b480861": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe6c5edf6a0fbdcff100e5ceafb63cba9aea355ba397a93fdb42a1a67b91375f8" - }, - "0x6c49c19c40a44bbf1cf9d2d8741ec1126e815fc6": { - "balance": "0", - "nonce": 1, - "root": "0xe00c49a65849d05cbf27a4d7788a68bc7b6013ae33411d40bc89282fc064f33d", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001ad": "01ad", - "0x00000000000000000000000000000000000000000000000000000000000001ae": "01ae", - "0x00000000000000000000000000000000000000000000000000000000000001af": "01af" - }, - "key": "0x0304d8eaccf0b942c468074250cbcb625ec5c4688b6b5d17d2a9bdd8dd565d5a" - }, - "0x6ca60a92cbf88c7f527978dc183a22e774755551": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x52d034ca6ebd21c7ba62a2ad3b6359aa4a1cdc88bdaa64bb2271d898777293ab" - }, - "0x6cc0ab95752bf25ec58c91b1d603c5eb41b8fbd7": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xaa0ac2f707a3dc131374839d4ee969eeb1cb55adea878f56e7b5b83d187d925c" - }, - "0x6d09a879576c0d941bea7833fb2285051b10d511": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xaa0ffaa57269b865dccce764bf412de1dff3e7bba22ce319ef09e5907317b3e7" - }, - "0x6d8b8f27857e10b21c0ff227110d7533cea03d0e": { - "balance": "0", - "nonce": 1, - "root": "0xd3d9839f87c29fb007fd9928d38bbf84ef089f0cd640c838f4a42631e828c667", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000117": "0117", - "0x0000000000000000000000000000000000000000000000000000000000000118": "0118", - "0x0000000000000000000000000000000000000000000000000000000000000119": "0119" - }, - "key": "0xfdbb8ddca8cecfe275da1ea1c36e494536f581d64ddf0c4f2e6dae9c7d891427" - }, - "0x6e09a59a69b41abca97268b05595c074ad157872": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7a3870cc1ed4fc29e9ab4dd3218dbb239dd32c9bf05bff03e325b7ba68486c47" - }, - "0x6e3d512a9328fa42c7ca1e20064071f88958ed93": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc1a6a0bf60ee7b3228ecf6cb7c9e5491fbf62642a3650d73314e976d9eb9a966" - }, - "0x6e3faf1e27d45fca70234ae8f6f0a734622cff8a": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x97f72ff641eb40ee1f1163544931635acb7550a0d44bfb9f4cc3aeae829b6d7d" - }, - "0x6f80f6a318ea88bf0115d693f564139a5fb488f6": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe73b3367629c8cb991f244ac073c0863ad1d8d88c2e180dd582cefda2de4415e" - }, - "0x7021bf21ecdbefcb33d09e4b812a47b273aa1d5c": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb9400acf38453fd206bc18f67ba04f55b807b20e4efc2157909d91d3a9f7bed2" - }, - "0x706be462488699e89b722822dcec9822ad7d05a7": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x78948842ff476b87544c189ce744d4d924ffd0907107a0dbaa4b71d0514f2225" - }, - "0x717f8aa2b982bee0e29f573d31df288663e1ce16": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc3c8e2dc64e67baa83b844263fe31bfe24de17bb72bfed790ab345b97b007816" - }, - "0x7212449475dcc75d408ad62a9acc121d94288f6d": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe333845edc60ed469a894c43ed8c06ec807dafd079b3c948077da56e18436290" - }, - "0x72dfcfb0c470ac255cde83fb8fe38de8a128188e": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x2fe5767f605b7b821675b223a22e4e5055154f75e7f3041fdffaa02e4787fab8" - }, - "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f": { - "balance": "999999999999999999999518871495454239", - "nonce": 402, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4363d332a0d4df8582a84932729892387c623fe1ec42e2cfcbe85c183ed98e0e" - }, - "0x75b9236dfe7d0e12eb21b6d175276a7c5d4e851d": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc54ffffcbaa5b566a7cf37386c4ce5a338d558612343caaa99788343d516aa5f" - }, - "0x77adfc95029e73b173f60e556f915b0cd8850848": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x0993fd5b750fe4414f93c7880b89744abb96f7af1171ed5f47026bdf01df1874" - }, - "0x788adf954fc28a524008ea1f2d0e87ae8893afdc": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x903f24b3d3d45bc50c082b2e71c7339c7060f633f868db2065ef611885abe37e" - }, - "0x7a19252e8c9b457eb07f52d0ddbe16820b5b7830": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xab7bdc41a80ae9c8fcb9426ba716d8d47e523f94ffb4b9823512d259c9eca8cd" - }, - "0x7ace431cb61584cb9b8dc7ec08cf38ac0a2d6496": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x71dee9adfef0940a36336903bd6830964865180b98c0506f9bf7ba8f2740fbf9" - }, - "0x7c5bd2d144fdde498406edcb9fe60ce65b0dfa5f": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfcc08928955d4e5e17e17e46d5adbb8011e0a8a74cabbdd3e138c367e89a4428" - }, - "0x7cb7c4547cf2653590d7a9ace60cc623d25148ad": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x55d0609468d8d4147a942e88cfc5f667daff850788d821889fbb03298924767c" - }, - "0x7d80ad47bf8699f49853640b12ee55b1f51691f1": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x65cf42efacdee07ed87a1c2de0752a4e3b959f33f9f9f8c77424ba759e01fcf2" - }, - "0x7da59d0dfbe21f43e842e8afb43e12a6445bbac0": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7c3e44534b1398abc786e4591364c329e976dbde3b3ed3a4d55589de84bcb9a6" - }, - "0x7dcef881c305fb208500cc9509db689047ed0967": { - "balance": "0", - "nonce": 1, - "root": "0x6d2b8a074c78a0e5a8095d7a010d4961c639c541cf56fbb7049480cc8f199765", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001bc": "01bc", - "0x00000000000000000000000000000000000000000000000000000000000001bd": "01bd", - "0x00000000000000000000000000000000000000000000000000000000000001be": "01be" - }, - "key": "0x68fc814efedf52ac8032da358ddcb61eab4138cb56b536884b86e229c995689c" - }, - "0x7f2dce06acdeea2633ff324e5cb502ee2a42d979": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe04fdefc4f2eefd22721d5944411b282d0fcb1f9ac218f54793a35bca8199c25" - }, - "0x7f774bb46e7e342a2d9d0514b27cee622012f741": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x720f25b62fc39426f70eb219c9dd481c1621821c8c0fa5367a1df6e59e3edf59" - }, - "0x7fd02a3bb5d5926d4981efbf63b66de2a7b1aa63": { - "balance": "0", - "nonce": 1, - "root": "0x7bf542bdaff5bfe3d33c26a88777773b5e525461093c36acb0dab591a319e509", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000032": "32", - "0x0000000000000000000000000000000000000000000000000000000000000033": "33", - "0x0000000000000000000000000000000000000000000000000000000000000034": "34" - }, - "key": "0xfc3d2e27841c0913d10aa11fc4af4793bf376efe3d90ce8360aa392d0ecefa24" - }, - "0x8074971c7d405ba1e70af34f5af7d564ddc495df": { - "balance": "0", - "nonce": 1, - "root": "0x60fc69100d8e632667c80b94d434008823ed75416b71cbd112b4d0b02f563027", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000a4": "a4", - "0x00000000000000000000000000000000000000000000000000000000000000a5": "a5", - "0x00000000000000000000000000000000000000000000000000000000000000a6": "a6" - }, - "key": "0x0e0e4646090b881949ec9991e48dec768ccd1980896aefd0d51fd56fd5689790" - }, - "0x8120ff763f8283e574fc767702056b57fcc89003": { - "balance": "0", - "nonce": 1, - "root": "0xa2e7084ba9cec179519c7e8950c66ad3cba8586a60cff9f4d60c188dd621522a", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000037": "37", - "0x0000000000000000000000000000000000000000000000000000000000000038": "38", - "0x0000000000000000000000000000000000000000000000000000000000000039": "39" - }, - "key": "0x48e291f8a256ab15da8401c8cae555d5417a992dff3848926fa5b71655740059" - }, - "0x8176caac8654abc74a905b137a37ecf7be2a9e95": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc4bab059ee8f7b36c82ada44d22129671d8f47f254ca6a48fded94a8ff591c88" - }, - "0x81bda6e29da8c3e4806b64dfa1cd32cd9c8fa70e": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd5e5e7be8a61bb5bfa271dfc265aa9744dea85de957b6cffff0ecb403f9697db" - }, - "0x828a91cb304a669deff703bb8506a19eba28e250": { - "balance": "0", - "nonce": 1, - "root": "0x936ac6251848da69a191cc91174e4b7583a12a43d896e243841ea98b65f264ad", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000017b": "017b", - "0x000000000000000000000000000000000000000000000000000000000000017c": "017c", - "0x000000000000000000000000000000000000000000000000000000000000017d": "017d" - }, - "key": "0xea810ea64a420acfa917346a4a02580a50483890cba1d8d1d158d11f1c59ed02" - }, - "0x82c291ed50c5f02d7e15e655c6353c9278e1bbec": { - "balance": "0", - "nonce": 1, - "root": "0x12de4544640fc8a027e1a912d776b90675bebfd50710c2876b2a24ec9eced367", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000cc": "cc", - "0x00000000000000000000000000000000000000000000000000000000000000cd": "cd", - "0x00000000000000000000000000000000000000000000000000000000000000ce": "ce" - }, - "key": "0xa9970b3744a0e46b248aaf080a001441d24175b5534ad80755661d271b976d67" - }, - "0x83c7e323d189f18725ac510004fdc2941f8c4a78": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb17ea61d092bd5d77edd9d5214e9483607689cdcc35a30f7ea49071b3be88c64" - }, - "0x847f88846c35337cbf57e37ffc18316a99ac2f14": { - "balance": "0", - "nonce": 1, - "root": "0x310a2ac83d7e3e4d333102b1f7153bb0416b38427eb2e335dc6632d779a8b4af", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000bd": "bd", - "0x00000000000000000000000000000000000000000000000000000000000000be": "be", - "0x00000000000000000000000000000000000000000000000000000000000000bf": "bf" - }, - "key": "0xbea55c1dc9f4a9fb50cbedc70448a4e162792b9502bb28b936c7e0a2fd7fe41d" - }, - "0x84873854dba02cf6a765a6277a311301b2656a7f": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x3197690074092fe51694bdb96aaab9ae94dac87f129785e498ab171a363d3b40" - }, - "0x84e75c28348fb86acea1a93a39426d7d60f4cc46": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5162f18d40405c59ef279ad71d87fbec2bbfedc57139d56986fbf47daf8bcbf2" - }, - "0x85f97e04d754c81dac21f0ce857adc81170d08c6": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x2baa718b760c0cbd0ec40a3c6df7f2948b40ba096e6e4b116b636f0cca023bde" - }, - "0x8642821710100a9a3ab10cd4223278a713318096": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4fbc5fc8df4f0a578c3be3549f1cb3ef135cbcdf75f620c7a1d412462e9b3b94" - }, - "0x8749e96779cd1b9fa62b2a19870d9efc28acae09": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa3d8baf7ae7c96b1020753d12154e28cc7206402037c28c49c332a08cf7c4b51" - }, - "0x87610688d55c08238eacf52864b5a5920a00b764": { - "balance": "0", - "nonce": 1, - "root": "0x2da86eb3d4ffdd895170bc7ef02b69a116fe21ac2ce45a3ed8e0bb8af17cf92b", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000fe": "fe", - "0x00000000000000000000000000000000000000000000000000000000000000ff": "ff", - "0x0000000000000000000000000000000000000000000000000000000000000100": "0100" - }, - "key": "0x80a2c1f38f8e2721079a0de39f187adedcb81b2ab5ae718ec1b8d64e4aa6930e" - }, - "0x878dedd9474cfa24d91bccc8b771e180cf01ac40": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7e1ef9f8d2fa6d4f8e6717c3dcccff352ea9b8b46b57f6106cdbeed109441799" - }, - "0x882e7e5d12617c267a72948e716f231fa79e6d51": { - "balance": "0", - "nonce": 0, - "root": "0x491b2cfba976b2e78bd9be3bc15c9964927205fc34c9954a4d61bbe8170ba533", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000005": "05", - "0x0000000000000000000000000000000000000000000000000000000000000006": "06", - "0x0000000000000000000000000000000000000000000000000000000000000007": "07" - }, - "key": "0xd2501ae11a14bf0c2283a24b7e77c846c00a63e71908c6a5e1caff201bad0762" - }, - "0x88654f0e7be1751967bba901ed70257a3cb79940": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x30ce5b7591126d5464dfb4fc576a970b1368475ce097e244132b06d8cc8ccffe" - }, - "0x892f60b39450a0e770f00a836761c8e964fd7467": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x74614a0c4ba7d7c70b162dad186b6cc77984ab4070534ad9757e04a5b776dcc8" - }, - "0x8a5edab282632443219e051e4ade2d1d5bbc671c": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc251a3acb75a90ff0cdca31da1408a27ef7dcaa42f18e648f2be1a28b35eac32" - }, - "0x8a817bc42b2e2146dc4ca4dc686db0a4051d2944": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x17984cc4b4aac0492699d37662b53ec2acf8cbe540c968b817061e4ed27026d0" - }, - "0x8a8950f7623663222542c9469c73be3c4c81bbdf": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xaef83ad0ab332330a20e88cd3b5a4bcf6ac6c175ee780ed4183d11340df17833" - }, - "0x8ba7e4a56d8d4a4a2fd7d0c8b9e6f032dc76cefb": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x72e962dfe7e2828809f5906996dedeba50950140555b193fceb94f12fd6f0a22" - }, - "0x8bebc8ba651aee624937e7d897853ac30c95a067": { - "balance": "1", - "nonce": 1, - "root": "0xbe3d75a1729be157e79c3b77f00206db4d54e3ea14375a015451c88ec067c790", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000001": "01", - "0x0000000000000000000000000000000000000000000000000000000000000002": "02", - "0x0000000000000000000000000000000000000000000000000000000000000003": "03" - }, - "key": "0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099" - }, - "0x8cf42eb93b1426f22a30bd22539503bdf838830c": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x0267c643f67b47cac9efacf6fcf0e4f4e1b273a727ded155db60eb9907939eb6" - }, - "0x8d33f520a3c4cef80d2453aef81b612bfe1cb44c": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb8d9b988ed60dbf5dca3e9d169343ca667498605f34fb6c30b45b2ed0f996f1a" - }, - "0x8d36bbb3d6fbf24f38ba020d9ceeef5d4562f5f2": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc13c19f53ce8b6411d6cdaafd8480dfa462ffdf39e2eb68df90181a128d88992" - }, - "0x8fa24283a8c1cc8a0f76ac69362139a173592567": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xefaff7acc3ad3417517b21a92187d2e63d7a77bc284290ed406d1bc07ab3d885" - }, - "0x8fb778e47caf2df14eca7a389955ca74ac8f4924": { - "balance": "0", - "nonce": 1, - "root": "0xae2e7f1c933c6ca84ce8be811ef411dee773fb69508056d72448048ea1db5c47", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001ee": "01ee", - "0x00000000000000000000000000000000000000000000000000000000000001ef": "01ef", - "0x00000000000000000000000000000000000000000000000000000000000001f0": "01f0" - }, - "key": "0x4973f6aa8cf5b1190fc95379aa01cff99570ee6b670725880217237fb49e4b24" - }, - "0x90fd8e600ae1a7c69fa6ef2c537b533ca77366e8": { - "balance": "0", - "nonce": 1, - "root": "0xee9821621aa5ec9ab7d5878b2a995228adcdcacb710df522d2f91b434d3bdc79", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000c2": "c2", - "0x00000000000000000000000000000000000000000000000000000000000000c3": "c3", - "0x00000000000000000000000000000000000000000000000000000000000000c4": "c4" - }, - "key": "0xbfaac98225451c56b2f9aec858cffc1eb253909615f3d9617627c793b938694f" - }, - "0x913f841dfc8703ae76a4e1b8b84cd67aab15f17a": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xcb54add475a18ea02ab1adf9e2e73da7f23ecd3e92c4fa8ca4e8f588258cb5d3" - }, - "0x923f800cf288500f8e53f04e4698c9b885dcf030": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb91824b28183c95881ada12404d5ee8af8123689a98054d41aaf4dd5bec50e90" - }, - "0x9344b07175800259691961298ca11c824e65032d": { - "balance": "0", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0x8e0388ecf64cfa76b3a6af159f77451519a7f9bb862e4cce24175c791fdcb0df", - "code": "0x60004381526020014681526020014181526020014881526020014481526020013281526020013481526020016000f3", - "key": "0x2e6fe1362b3e388184fd7bf08e99e74170b26361624ffd1c5f646da7067b58b6" - }, - "0x93747f73c18356c6b202f527f552436a0e06116a": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x73cd1b7cd355f3f77c570a01100a616757408bb7abb78fe9ee1262b99688fcc4" - }, - "0x9380b994c5738f68312f0e517902da81f63cdcfa": { - "balance": "0", - "nonce": 1, - "root": "0x51b829f0f2c3de9cfbd94e47828a89940c329a49cd59540ca3c6d751a8d214d6", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000135": "0135", - "0x0000000000000000000000000000000000000000000000000000000000000136": "0136", - "0x0000000000000000000000000000000000000000000000000000000000000137": "0137" - }, - "key": "0x50d83ef5194d06752cd5594b57e809b135f24eedd124a51137feaaf049bc2efd" - }, - "0x94d068bff1af651dd9d9c2e75adfb7eec6f66be7": { - "balance": "0", - "nonce": 1, - "root": "0x0754035aa4073381a211342b507de8e775c97c961096e6e2275df0bfcbb3a01c", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000059": "59", - "0x000000000000000000000000000000000000000000000000000000000000005a": "5a", - "0x000000000000000000000000000000000000000000000000000000000000005b": "5b" - }, - "key": "0x0cd2a7c53c76f228ed3aa7a29644b1915fde9ec22e0433808bf5467d914e7c7a" - }, - "0x956062137518b270d730d4753000896de17c100a": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5aa3b4a2ebdd402721c3953b724f4fe90900250bb4ef89ce417ec440da318cd6" - }, - "0x96a1cabb97e1434a6e23e684dd4572e044c243ea": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe7c6828e1fe8c586b263a81aafc9587d313c609c6db8665a42ae1267cd9ade59" - }, - "0x984c16459ded76438d98ce9b608f175c28a910a0": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4b9f335ce0bdffdd77fdb9830961c5bc7090ae94703d0392d3f0ff10e6a4fbab" - }, - "0x99a1c0703485b331fa0302d6077b583082e242ea": { - "balance": "0", - "nonce": 1, - "root": "0x2cf292c1e382bdd0e72e126701d7b02484e6e272f4c0d814f5a6fae233fc7935", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000121": "0121", - "0x0000000000000000000000000000000000000000000000000000000000000122": "0122", - "0x0000000000000000000000000000000000000000000000000000000000000123": "0123" - }, - "key": "0x734ee4981754a3f1403c4e8887d35addfb31717d93de3e00ede78368c230861e" - }, - "0x99d40a710cb552eaaee1599d4040055859b1610d": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x946bfb429d90f1b39bb47ada75376a8d90a5778068027d4b8b8514ac13f53eca" - }, - "0x9a7b7b3a5d50781b4f4768cd7ce223168f6b449b": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd16e029e8c67c3f330cddaa86f82d31f523028404dfccd16d288645d718eb9da" - }, - "0x9ae62b6d840756c238b5ce936b910bb99d565047": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x8989651e80c20af78b37fdb693d74ecafc9239426ff1315e1fb7b674dcdbdb75" - }, - "0x9b3cf956056937dfb6f9e3dc02e3979a4e421c0a": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb1b2c1c59637202bb0e0d21255e44e0df719fe990be05f213b1b813e3d8179d7" - }, - "0x9bb981f592bc1f9c31db67f30bbf1ff44b649886": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x1ee7e0292fba90d9733f619f976a2655c484adb30135ef0c5153b5a2f32169df" - }, - "0x9bfb328671c108c9ba4d45734d9f4462d8c9a9cb": { - "balance": "0", - "nonce": 1, - "root": "0xc15b43e5f4853ec8da53ebde03de87b94afce42a9c02f648ad8bdb224604c4ad", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001da": "01da", - "0x00000000000000000000000000000000000000000000000000000000000001db": "01db", - "0x00000000000000000000000000000000000000000000000000000000000001dc": "01dc" - }, - "key": "0xa683478d0c949580d5738b490fac8129275bb6e921dfe5eae37292be3ee281b9" - }, - "0x9defb0a9e163278be0e05aa01b312ec78cfa3726": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb31919583a759b75e83c14d00d0a89bb36adc452f73cee2933a346ccebaa8e31" - }, - "0x9e59004e909ff011e5882332e421b6772e68ed10": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x3897cb9b6f68765022f3c74f84a9f2833132858f661f4bc91ccd7a98f4e5b1ee" - }, - "0x9f50ec6c8a595869d71ce8c3b1c17c02599a5cc3": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x2705244734f69af78e16c74784e1dc921cb8b6a98fe76f577cc441c831e973bf" - }, - "0xa0794cd73f564baeeda23fa4ce635a3f8ae39621": { - "balance": "0", - "nonce": 1, - "root": "0xfb79021e7fa54b9bd2df64f6db57897d52ae85f7c195af518de48200a1325e2c", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000ef": "ef", - "0x00000000000000000000000000000000000000000000000000000000000000f0": "f0", - "0x00000000000000000000000000000000000000000000000000000000000000f1": "f1" - }, - "key": "0x60535eeb3ffb721c1688b879368c61a54e13f8881bdef6bd4a17b8b92e050e06" - }, - "0xa12b147dd542518f44f821a4d436066c64932b0d": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xae88076d02b19c4d09cb13fca14303687417b632444f3e30fc4880c225867be3" - }, - "0xa179dbdd51c56d0988551f92535797bcf47ca0e7": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6d1da4cf1127d654ed731a93105f481b315ecfc2f62b1ccb5f6d2717d6a40f9b" - }, - "0xa1fce4363854ff888cff4b8e7875d600c2682390": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xad99b5bc38016547d5859f96be59bf18f994314116454def33ebfe9a892c508a" - }, - "0xa225fe6df11a4f364234dd6a785a17cd38309acb": { - "balance": "0", - "nonce": 1, - "root": "0xc1686045288a5952ad57de0e971bd25007723c9f749f49f391e715c27bf526c8", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000072": "72", - "0x0000000000000000000000000000000000000000000000000000000000000073": "73", - "0x0000000000000000000000000000000000000000000000000000000000000074": "74" - }, - "key": "0x4e0ab2902f57bf2a250c0f87f088acc325d55f2320f2e33abd8e50ba273c9244" - }, - "0xa25513c7e0f6eaa80a3337ee18081b9e2ed09e00": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfb9474d0e5538fcd99e8d8d024db335b4e057f4bcd359e85d78f4a5226b33272" - }, - "0xa5ab782c805e8bfbe34cb65742a0471cf5a53a97": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6188c4510d25576535a642b15b1dbdb8922fe572b099f504390f923c19799777" - }, - "0xa64f449891f282b87e566036f981023dba4ed477": { - "balance": "0", - "nonce": 1, - "root": "0x61176dbc05a8537d8de85f82a03b8e1049cea7ad0a9f0e5b60ee15fca6fe0d42", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000012b": "012b", - "0x000000000000000000000000000000000000000000000000000000000000012c": "012c", - "0x000000000000000000000000000000000000000000000000000000000000012d": "012d" - }, - "key": "0x7c1edabb98857d64572f03c64ac803e4a14b1698fccffffd51675d99ee3ba217" - }, - "0xa6515a495ec7723416665ebb54fc002bf1e9a873": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xbbdc59572cc62c338fb6e027ab00c57cdeed233c8732680a56a5747141d20c7c" - }, - "0xa6a54695341f038ad15e9e32f1096f5201236512": { - "balance": "0", - "nonce": 1, - "root": "0xe2a72f5bfbeba70fc9ab506237ba27c096a4e96c3968cabf5b1b2fb54431b5cf", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000023": "23", - "0x0000000000000000000000000000000000000000000000000000000000000024": "24", - "0x0000000000000000000000000000000000000000000000000000000000000025": "25" - }, - "key": "0xa87387b50b481431c6ccdb9ae99a54d4dcdd4a3eff75d7b17b4818f7bbfc21e9" - }, - "0xa8100ae6aa1940d0b663bb31cd466142ebbdbd51": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x02547b56492bfe767f3d18be2aab96441c449cd945770ef7ef8555acc505b2e4" - }, - "0xa8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x913e2a02a28d71d595d7216a12311f6921a4caf40aeabf0f28edf937f1df72b4" - }, - "0xa92bb60b61e305ddd888015189d6591b0eab0233": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xdd1589b1fe1d9b4ca947f98ff324de7887af299d5490ed92ae40e95eec944118" - }, - "0xa956ca63bf28e7da621475d6b077da1ab9812b3a": { - "balance": "0", - "nonce": 1, - "root": "0xa090b66fbca46cb71abd1daa8d419d2c6e291094f52872978dfcb1c31ad7a900", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001e4": "01e4", - "0x00000000000000000000000000000000000000000000000000000000000001e5": "01e5", - "0x00000000000000000000000000000000000000000000000000000000000001e6": "01e6" - }, - "key": "0xaad7b91d085a94c11a2f7e77dc95cfcfc5daf4f509ca4e0c0e493b86c6cbff78" - }, - "0xaa0d6dfdb7588017c80ea088768a5f3d0cdeacdb": { - "balance": "0", - "nonce": 1, - "root": "0x89ecb0ceeea20ccd7d1b18cf1d35b7a2fd7b76ddc8d627f43304ed8b31b01248", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000144": "0144", - "0x0000000000000000000000000000000000000000000000000000000000000145": "0145", - "0x0000000000000000000000000000000000000000000000000000000000000146": "0146" - }, - "key": "0xb990eaca858ea15fda296f3f47baa2939e8aa8bbccc12ca0c3746d9b5d5fb2ae" - }, - "0xaa53ff4bb2334faf9f4447197ef69c39c0bb1379": { - "balance": "0", - "nonce": 1, - "root": "0xe547c0050253075b1be4210608bc639cffe70110194c316481235e738be961e7", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000ea": "ea", - "0x00000000000000000000000000000000000000000000000000000000000000eb": "eb", - "0x00000000000000000000000000000000000000000000000000000000000000ec": "ec" - }, - "key": "0xed263a22f0e8be37bcc1873e589c54fe37fdde92902dc75d656997a7158a9d8c" - }, - "0xaa7225e7d5b0a2552bbb58880b3ec00c286995b8": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5a4a3feecfc77b402e938e28df0c4cbb874771cb3c5a92524f303cffb82a2862" - }, - "0xab12a5f97f03edbff03eded9d1a2a1179d2fc69e": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xba1d0afdfee510e8852f24dff964afd824bf36d458cf5f5d45f02f04b7c0b35d" - }, - "0xab557835ab3e5c43bf34ac9b2ab730c5e0bc9967": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc9ea69dc9e84712b1349c9b271956cc0cb9473106be92d7a937b29e78e7e970e" - }, - "0xab9025d4a9f93c65cd4fe978d38526860af0aa62": { - "balance": "0", - "nonce": 1, - "root": "0x4ce79cd9645650f0a00effa86f6fea733cecea9ea26964828ff25cf0577bc974", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000009a": "9a", - "0x000000000000000000000000000000000000000000000000000000000000009b": "9b", - "0x000000000000000000000000000000000000000000000000000000000000009c": "9c" - }, - "key": "0x17350c7adae7f08d7bbb8befcc97234462831638443cd6dfea186cbf5a08b7c7" - }, - "0xabd693b23d55dec7d0d0cba2ecbc9298dc4edf02": { - "balance": "0", - "nonce": 1, - "root": "0xafd54e81f3e415407f0812a678856f1b4068ed64a08b3f3bf5b2190fcfb2322d", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001b7": "01b7", - "0x00000000000000000000000000000000000000000000000000000000000001b8": "01b8", - "0x00000000000000000000000000000000000000000000000000000000000001b9": "01b9" - }, - "key": "0xbe7d987a9265c0e44e9c5736fb2eb38c41973ce96e5e8e6c3c713f9d50a079ff" - }, - "0xabe2b033c497e091c1e494c98c178e8aa06bcb00": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x2374954008440ca3d17b1472d34cc52a6493a94fb490d5fb427184d7d5fd1cbf" - }, - "0xac4d51af4cb7bab4743fa57bc80b144d7a091268": { - "balance": "0", - "nonce": 1, - "root": "0xfb00729a5f4f9a2436b999aa7159497a9cd88d155770f873a818b55052c5f067", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000149": "0149", - "0x000000000000000000000000000000000000000000000000000000000000014a": "014a", - "0x000000000000000000000000000000000000000000000000000000000000014b": "014b" - }, - "key": "0xe42a85d04a1d0d9fe0703020ef98fa89ecdeb241a48de2db73f2feeaa2e49b0f" - }, - "0xac7d8d5f6be7d251ec843ddbc09095150df59965": { - "balance": "0", - "nonce": 1, - "root": "0xa9580109be2f7d35b5360050c2ced74e5d4dea2f82d46e8d266ed89157636004", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000046": "46", - "0x0000000000000000000000000000000000000000000000000000000000000047": "47", - "0x0000000000000000000000000000000000000000000000000000000000000048": "48" - }, - "key": "0x943f42ad91e8019f75695946d491bb95729f0dfc5dbbb953a7239ac73f208943" - }, - "0xac9e61d54eb6967e212c06aab15408292f8558c4": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf2b9bc1163840284f3eb15c539972edad583cda91946f344f4cb57be15af9c8f" - }, - "0xaceac762ff518b4cf93a6eebbc55987e7b79b2ce": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x1960414a11f8896c7fc4243aba7ed8179b0bc6979b7c25da7557b17f5dee7bf7" - }, - "0xacfa6b0e008d0208f16026b4d17a4c070e8f9f8d": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x58e416a0dd96454bd2b1fe3138c3642f5dee52e011305c5c3416d97bc8ba5cf0" - }, - "0xad108e31c9632ad9e20614b3ca40644d32948dbb": { - "balance": "0", - "nonce": 1, - "root": "0x2625f8a23d24a5dff6a79f632b1020593362a6ac622fa5237460bc67b0aa0ed3", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001a3": "01a3", - "0x00000000000000000000000000000000000000000000000000000000000001a4": "01a4", - "0x00000000000000000000000000000000000000000000000000000000000001a5": "01a5" - }, - "key": "0xdce547cc70c79575ef72c061502d6066db1cbce200bd904d5d2b20d4f1cb5963" - }, - "0xae3f4619b0413d70d3004b9131c3752153074e45": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb1b2fd7758f73e25a2f9e72edde82995b2b32ab798bcffd2c7143f2fc8196fd8" - }, - "0xae58b7e08e266680e93e46639a2a7e89fde78a6f": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe09e5f27b8a7bf61805df6e5fefc24eb6894281550c2d06250adecfe1e6581d7" - }, - "0xaf17b30f5ab8e6a4d7a563bdb0194f3e0bd50209": { - "balance": "0", - "nonce": 1, - "root": "0x2434bfc643ec364116cd71519a397662b20c52d1adcff0b830e80a738e19f30e", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000b8": "b8", - "0x00000000000000000000000000000000000000000000000000000000000000b9": "b9", - "0x00000000000000000000000000000000000000000000000000000000000000ba": "ba" - }, - "key": "0x26ce7d83dfb0ab0e7f15c42aeb9e8c0c5dba538b07c8e64b35fb64a37267dd96" - }, - "0xaf193a8cdcd0e3fb39e71147e59efa5cad40763d": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x1a28912018f78f7e754df6b9fcec33bea25e5a232224db622e0c3343cf079eff" - }, - "0xaf2c6f1512d1cabedeaf129e0643863c57419732": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xad6a4a6ebd5166c9b5cc8cfbaec176cced40fa88c73d83c67f0c3ed426121ebc" - }, - "0xb0b2988b6bbe724bacda5e9e524736de0bc7dae4": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x053df2c3b574026812b154a99b13b626220af85cd01bb1693b1d42591054bce6" - }, - "0xb0ee91ba61e8a3914a7eab120786e9e61bfe4faf": { - "balance": "0", - "nonce": 1, - "root": "0xa14913d548ac1d3f9962a21a569fe52f1436b6d2f5ea4e36de13ea855ede54e0", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000068": "68", - "0x0000000000000000000000000000000000000000000000000000000000000069": "69", - "0x000000000000000000000000000000000000000000000000000000000000006a": "6a" - }, - "key": "0x4bd8ef9873a5e85d4805dbcb0dbf6810e558ea175167549ef80545a9cafbb0e1" - }, - "0xb12dc850a3b0a3b79fc2255e175241ce20489fe4": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4ccd31891378d2025ef58980481608f11f5b35a988e877652e7cbb0a6127287c" - }, - "0xb47f70b774d780c3ec5ac411f2f9198293b9df7a": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xdef989cb85107747de11222bd7418411f8f3264855e1939ef6bef9447e42076d" - }, - "0xb4bc136e1fb4ea0b3340d06b158277c4a8537a13": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb7c2ef96238f635f86f9950700e36368efaaa70e764865dddc43ff6e96f6b346" - }, - "0xb519be874447e0f0a38ee8ec84ecd2198a9fac77": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x92b13a73440c6421da22e848d23f9af80610085ab05662437d850c97a012d8d3" - }, - "0xb55a3d332d267493105927b892545d2cd4c83bd6": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc781c7c3babeb06adfe8f09ecb61dbe0eb671e41f3a1163faac82fdfa2bc83e8" - }, - "0xb609bc528052bd9669595a35f6eb6a4d7a30ac3d": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe6388bfcbbd6000e90a10633c72c43b0b0fed7cf38eab785a71e6f0c5b80a26a" - }, - "0xb68176634dde4d9402ecb148265db047d17cb4ab": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf4a1c4554b186a354b3e0c467eef03df9907cd5a5d96086c1a542b9e5160ca78" - }, - "0xb70654fead634e1ede4518ef34872c9d4f083a53": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7f9726a7b2f5f3a501b2d7b18ec726f25f22c86348fae0f459d882ec5fd7d0c7" - }, - "0xb71de80778f2783383f5d5a3028af84eab2f18a4": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x64d0de66ea29cbcf7f237dae1c5f883fa6ff0ba52b90f696bb0348224dbc82ce" - }, - "0xb787c848479278cfdb56950cda545cd45881722d": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x1098f06082dc467088ecedb143f9464ebb02f19dc10bd7491b03ba68d751ce45" - }, - "0xb911abeead298d03c21c6c5ff397cd80eb375d73": { - "balance": "0", - "nonce": 1, - "root": "0x54abcdbc8b04bc9b70e9bd46cb9db9b8eb08cfd4addba4c941dacc34dd28648e", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000054": "54", - "0x0000000000000000000000000000000000000000000000000000000000000055": "55", - "0x0000000000000000000000000000000000000000000000000000000000000056": "56" - }, - "key": "0x873429def7829ff8227e4ef554591291907892fc8f3a1a0667dada3dc2a3eb84" - }, - "0xb917b7f3d49770d3d2f0ad2f497e5bfe0f25dc5f": { - "balance": "0", - "nonce": 1, - "root": "0x11d4eec7df52cd54e74690a487884e56371976c2b8c49ffc4c8f34831166bf4e", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000162": "0162", - "0x0000000000000000000000000000000000000000000000000000000000000163": "0163", - "0x0000000000000000000000000000000000000000000000000000000000000164": "0164" - }, - "key": "0x65e6b6521e4f1f97e80710581f42063392c9b33e0aeea4081a102a32238992ea" - }, - "0xb9b85616fc8ed95979a5e31b8968847e7518b165": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6a5e43139d88da6cfba857e458ae0b5359c3fde36e362b6e5f782a90ce351f14" - }, - "0xbac9d93678c9b032c393a23e4c013e37641ad850": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x8a8266874b43f78d4097f27b2842132faed7e7e430469eec7354541eb97c3ea0" - }, - "0xbbeebd879e1dff6918546dc0c179fdde505f2a21": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x170c927130fe8f1db3ae682c22b57f33f54eb987a7902ec251fe5dba358a2b25" - }, - "0xbbf3f11cb5b43e700273a78d12de55e4a7eab741": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe74ac72f03e8c514c2c75f3c4f54ba31e920374ea7744ef1c33937e64c7d54f1" - }, - "0xbc5959f43bc6e47175374b6716e53c9a7d72c594": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfd3a8bacd3b2061cbe54f8d38cf13c5c87a92816937683652886dee936dfae10" - }, - "0xbceef655b5a034911f1c3718ce056531b45ef03b": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6c05d8abc81143ce7c7568c98aadfe6561635c049c07b2b4bce3019cef328cb9" - }, - "0xbd079b0337a29cccd2ec95b395ef5c01e992b6a5": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf0877d51b7712e08f2a3c96cddf50ff61b8b90f80b8b9817ea613a8a157b0c45" - }, - "0xbe3eea9a483308cb3134ce068e77b56e7c25af19": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7026c939a9158beedff127a64f07a98b328c3d1770690437afdb21c34560fc57" - }, - "0xc04b5bb1a5b2eb3e9cd4805420dba5a9d133da5b": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x72d91596112f9d7e61d09ffa7575f3587ad9636172ae09641882761cc369ecc0" - }, - "0xc18d2be47547904f88a4f46cee75f8f4a94e1807": { - "balance": "0", - "nonce": 1, - "root": "0x9c32ffd5059115bba9aed9174f5ab8b4352e3f51a85dde33000f703c9b9fe7c2", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000018a": "018a", - "0x000000000000000000000000000000000000000000000000000000000000018b": "018b", - "0x000000000000000000000000000000000000000000000000000000000000018c": "018c" - }, - "key": "0xa601eb611972ca80636bc39087a1dae7be5a189b94bda392f84d6ce0d3c866b9" - }, - "0xc19a797fa1fd590cd2e5b42d1cf5f246e29b9168": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x99dba7e9230d5151cc37ff592fa1592f27c7c81d203760dfaf62ddc9f3a6b8fd" - }, - "0xc305dd6cfc073cfe5e194fc817536c419410a27d": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x016d92531f4754834b0502de5b0342ceff21cde5bef386a83d2292f4445782c2" - }, - "0xc337ded6f56c07205fb7b391654d7d463c9e0c72": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7c608293e741d1eb5ae6916c249a87b6540cf0c2369e96d293b1a7b5b9bd8b31" - }, - "0xc57aa6a4279377063b17c554d3e33a3490e67a9a": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc192ea2d2bb89e9bb7f17f3a282ebe8d1dd672355b5555f516b99b91799b01f6" - }, - "0xc5eaec262d853fbdaccca406cdcada6fa6dd0944": { - "balance": "0", - "nonce": 1, - "root": "0x471bf8988ad0d7602d6bd5493c08733096c116ac788b76f22a682bc4558e3aa7", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000158": "0158", - "0x0000000000000000000000000000000000000000000000000000000000000159": "0159", - "0x000000000000000000000000000000000000000000000000000000000000015a": "015a" - }, - "key": "0x580aa878e2f92d113a12c0a3ce3c21972b03dbe80786858d49a72097e2c491a3" - }, - "0xc7a0a19ea8fc63cc6021af2e11ac0584d75c97b7": { - "balance": "0", - "nonce": 1, - "root": "0xe2a164e2c30cf30391c88ff32a0e202194b08f2a61a9cd2927ea5ed6dfbf1056", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000e5": "e5", - "0x00000000000000000000000000000000000000000000000000000000000000e6": "e6", - "0x00000000000000000000000000000000000000000000000000000000000000e7": "e7" - }, - "key": "0x86d03d0f6bed220d046a4712ec4f451583b276df1aed33f96495d22569dc3485" - }, - "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x8e11480987056c309d7064ebbd887f086d815353cdbaadb796891ed25f8dcf61" - }, - "0xc7d4ef05550c226c50cf0d4231ba1566d03fa98d": { - "balance": "0", - "nonce": 1, - "root": "0x3a2985c6ada67e5604b99fa2fc1a302abd0dc241ee7f14c428fa67d476868bb6", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000010d": "010d", - "0x000000000000000000000000000000000000000000000000000000000000010e": "010e", - "0x000000000000000000000000000000000000000000000000000000000000010f": "010f" - }, - "key": "0x5a356862c79afffd6a01af752d950e11490146e4d86dfb8ab1531e9aef4945a1" - }, - "0xca358758f6d27e6cf45272937977a748fd88391d": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xbccd3d2f920dfb8d70a38c9ccd5ed68c2ef6e3372199381767ce222f13f36c87" - }, - "0xca87240ef598bd6e4b8f67b3761af07d5f575514": { - "balance": "0", - "nonce": 1, - "root": "0x11f5d399ca8fb7a9af5ad481be60cf61d45493cd20206c9d0a237ce7d7571e5f", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001f3": "01f3", - "0x00000000000000000000000000000000000000000000000000000000000001f4": "01f4", - "0x00000000000000000000000000000000000000000000000000000000000001f5": "01f5" - }, - "key": "0x4b238e08b80378d0815e109f350a08e5d41ec4094df2cfce7bc8b9e3115bda70" - }, - "0xcb925b74da97bdff2130523c2a788d4beff7b3c3": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe0c5acf66bda927704953fdf7fb4b99e116857121c069eca7fb9bd8acfc25434" - }, - "0xcccc369c5141675a9e9b1925164f30cdd60992dc": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfe2511e8a33ac9973b773aaedcb4daa73ae82481fe5a1bf78b41281924260cf5" - }, - "0xce24f30695b735e48b67467d76f5185ee3c7a0c5": { - "balance": "0", - "nonce": 1, - "root": "0x5442e0279d3f1149de4ce8d9e2d3f01d1854755038ac1a0fae5c48749bf71f20", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001e9": "01e9", - "0x00000000000000000000000000000000000000000000000000000000000001ea": "01ea", - "0x00000000000000000000000000000000000000000000000000000000000001eb": "01eb" - }, - "key": "0x47450e5beefbd5e3a3f80cbbac474bb3db98d5e609aa8d15485c3f0d733dea3a" - }, - "0xd048d242574c45095c72eaf58d2808778117afcb": { - "balance": "0", - "nonce": 1, - "root": "0x7217cb747054306f826e78aa3fc68fe4441299a337ecea1d62582f2da8a7f336", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001a8": "01a8", - "0x00000000000000000000000000000000000000000000000000000000000001a9": "01a9", - "0x00000000000000000000000000000000000000000000000000000000000001aa": "01aa" - }, - "key": "0xa9656c0192bb27f0ef3f93ecc6cc990dd146da97ac11f3d8d0899fba68d5749a" - }, - "0xd0752b60adb148ca0b3b4d2591874e2dabd34637": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x625e5c85d5f4b6385574b572709d0f704b097527a251b7c658c0c4441aef2af6" - }, - "0xd089c853b406be547d8e331d31cbd5c4d472a349": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x389093badcaa24c3a8cbb4461f262fba44c4f178a162664087924e85f3d55710" - }, - "0xd0918e2e24c5ddc0557a61ca11e055d2ac210fe5": { - "balance": "0", - "nonce": 1, - "root": "0x25b42ec5480843a0328c63bc50eff8595d90f1d1b0afcab2f4a19b888c794f37", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000a9": "a9", - "0x00000000000000000000000000000000000000000000000000000000000000aa": "aa", - "0x00000000000000000000000000000000000000000000000000000000000000ab": "ab" - }, - "key": "0xbaae09901e990935de19456ac6a6c8bc1e339d0b80ca129b8622d989b5c79120" - }, - "0xd10b36aa74a59bcf4a88185837f658afaf3646ef": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x9fe8b6e43098a4df56e206d479c06480801485dfd8ec3da4ccc3cebf5fba89a1" - }, - "0xd1211001882d2ce16a8553e449b6c8b7f71e6183": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x61088707d2910974000e63c2d1a376f4480ba19dde19c4e6a757aeb3d62d5439" - }, - "0xd1347bfa3d09ec56b821e17c905605cd5225069f": { - "balance": "0", - "nonce": 1, - "root": "0x287acc7869421fb9f49a3549b902fb01b7accc032243bd7e1accd8965d95d915", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000019e": "019e", - "0x000000000000000000000000000000000000000000000000000000000000019f": "019f", - "0x00000000000000000000000000000000000000000000000000000000000001a0": "01a0" - }, - "key": "0x5b90bb05df9514b2d8e3a8feb3d6c8c22526b02398f289b42111426edc4fe6cf" - }, - "0xd20b702303d7d7c8afe50344d66a8a711bae1425": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4d67d989fdb264fa4b2524d306f7b3f70ddce0b723411581d1740407da325462" - }, - "0xd282cf9c585bb4f6ce71e16b6453b26aa8d34a53": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x0e27113c09de0a0cb0ff268c677aba17d39a3190fe15aec0ff7f54184955cba4" - }, - "0xd2e2adf7177b7a8afddbc12d1634cf23ea1a7102": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x79afb7a5ffe6ccd537f9adff8287b78f75c37d97ea8a4dd504a08bc09926c3fa" - }, - "0xd39b94587711196640659ec81855bcf397e419ff": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa9de128e7d4347403eb97f45e969cd1882dfe22c1abe8857aab3af6d0f9e9b92" - }, - "0xd48171b7166f5e467abcba12698df579328e637d": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x188111c233bf6516bb9da8b5c4c31809a42e8604cd0158d933435cfd8e06e413" - }, - "0xd4f09e5c5af99a24c7e304ca7997d26cb0090169": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe1068e9986da7636501d8893f67aa94f5d73df849feab36505fd990e2d6240e9" - }, - "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe5302e42ca6111d3515cbbb2225265077da41d997f069a6c492fa3fcb0fdf284" - }, - "0xd854d6dd2b74dc45c9b883677584c3ac7854e01a": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x9a1896e612ca43ecb7601990af0c3bc135b9012c50d132769dfb75d0038cc3be" - }, - "0xd8c50d6282a1ba47f0a23430d177bbfbb72e2b84": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xfc4870c3cd21d694424c88f0f31f75b2426e1530fdea26a14031ccf9baed84c4" - }, - "0xd917458e88a37b9ae35f72d4cc315ef2020b2418": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x4c2765139cace1d217e238cc7ccfbb751ef200e0eae7ec244e77f37e92dfaee5" - }, - "0xdbe726e81a7221a385e007ef9e834a975a4b528c": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x5fcd9b6fce3394ad1d44733056b3e5f6306240974a16f9de8e96ebdd14ae06b1" - }, - "0xdc60d4434411b2608150f68c4c1b818b6208acc2": { - "balance": "0", - "nonce": 1, - "root": "0x27e9b6a54cf0fb188499c508bd96d450946cd6ba1cf76cf5343b5c74450f6690", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001df": "01df", - "0x00000000000000000000000000000000000000000000000000000000000001e0": "01e0", - "0x00000000000000000000000000000000000000000000000000000000000001e1": "01e1" - }, - "key": "0x8510660ad5e3d35a30d4fb7c2615c040f9f698faae2ac48022e366deaeecbe77" - }, - "0xdd1e2826c0124a6d4f7397a5a71f633928926c06": { - "balance": "1", - "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf0a51b55aadfa3cafdd214b0676816e574931a683f51218207c625375884e785" + "address": "0x5c019738b38feae2a8944bd644f7acd5e6f40e5c", + "key": "0xbccd85b63dba6300f84c561c5f52ce08a240564421e382e6f550ce0c12f2f632" }, - "0xdd9ee108e8d5d2e8937e9fd029ec3a6640708af0": { + "0x5ddf897368f755b65a47c325558C5D1B6101D6AE": { "balance": "0", "nonce": 1, "root": "0x8289b558865f2ca1f54c98b5ff5df95f07c24ec605e247b58c7798605dcd794f", @@ -3833,89 +2606,647 @@ "0x00000000000000000000000000000000000000000000000000000000000001cc": "01cc", "0x00000000000000000000000000000000000000000000000000000000000001cd": "01cd" }, - "key": "0x2a39afbe88f572c23c90da2d059af3de125f1da5c3753c530dc5619a4857119f" + "address": "0x5ddf897368f755b65a47c325558c5d1b6101d6ae", + "key": "0x411fbb986eebf586de3c9c5e658d280361302fb01b9c78a4ad377a1d22f48c30" }, - "0xde5a6f78116eca62d7fc5ce159d23ae6b889b365": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xbb861b82d884a70666afeb78bbf30cab7fdccf838f4d5ce5f4e5ca1be6be61b1" - }, - "0xde7d1b721a1e0632b7cf04edf5032c8ecffa9f9a": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x9966a8b4cd856b175855258fa7e412ffef06d9e92b519050fa7ac06d8952ac84" - }, - "0xdfe052578c96df94fa617102199e66110181ed2c": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x54c12444ede3e2567dd7f4d9a06d4db8c6ab800d5b3863f8ff22a0db6d09bf24" - }, - "0xe3a71b4caf54df7d2480743c5a6770a1a5a9bcda": { + "0x5e028FC1Db7DEA67e88450a41E8a8C171a2D98af": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe4d9c31cc9b4a9050bbbf77cc08ac26d134253dcb6fd994275c5c3468f5b7810" + "address": "0x5e028fc1db7dea67e88450a41e8a8c171a2d98af", + "key": "0x093469a66063567a18434eb090355fdf9a1cda7b36496375c8ad5352490f37db" }, - "0xe3b98a4da31a127d4bde6e43033f66ba274cab0e": { - "balance": "100000000000", + "0x5f552da00dFB4d3749D9e62dCeE3c918855A86A0": { + "balance": "1000000000000000000000000200000000009", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x70aae390a762a4347a4d167a2431874554edf1d77579213e55fea3ec39a1257c" + "address": "0x5f552da00dfb4d3749d9e62dcee3c918855a86a0", + "key": "0xd52564daf6d32a6ae29470732726859261f5a7409b4858101bd233ed5cc2f662" }, - "0xe439e4ea04e52cf38d0925f0722d341097378b88": { + "0x6122a0F0099Cf6829a1A798C7d8194F3F1c767C6": { "balance": "0", "nonce": 1, - "root": "0x6c00e091dae3d4226facd6be802c865d5db0f524754d22666406138b54fab0e6", + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1cdd99d5886db6ad2fa95eae0e3dbbe46bfd4d76dd9fc071924bfbdfb5092df1", + "code": "0x5ebf747c75d0738c34413ae2d381abbe56223451ec9a8182acbb3c1b4cd303c36b426b81e25bfdca83dacfd6d1498cc9b779efa0e16c484b0a45c63e2a8ac0eb41338e7384edaf5f4b58e81789655568fca10ff473e1ae582e94707ba3b4af90ef1ae8d7b697e2fe5c14ab2301c3ae5fc2eb455e13fec873d608e25c13013abe76d086a43441006cc18880195fbac37baa9f0b926a479db4db18e84f5b93b3bdc27bef70534a73a3458fa13111419bdb863ccef9e14b21600ede3c5d6199ba547b426c558c84faa8521ed0fec4740eb270d0d68f28ebd25a3f457810c19e5e1d6c8fbe6ccd59976251666e62bf63684699437b1318f66f299d463a2a35e6cafc", + "address": "0x6122a0f0099cf6829a1a798c7d8194f3f1c767c6", + "key": "0x0e733ffe8353481b1a9ff5640302b8aea65c7d1863b432df95ccb2be96afa76b" + }, + "0x61774970e93c00A3E206a26c64707D3E33F89972": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x61774970e93c00a3e206a26c64707d3e33f89972", + "key": "0x07b49045c401bcc408f983d91a199c908cdf0d646049b5b83629a70b0117e295" + }, + "0x62b519210D1152d05522eCD2786a0894Ef96711a": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x53e60f54205478067bd7871cc267787db82640762b903ae292cc4f7b1e034b2f", + "code": "0xd9dfa62431de8be2dbd2a3e48181600f1d9a369e648c27560dba1fbb3ad2b73f114d5534ea633c2a4fc65ce2157734e1ac5b006861db9b2fb713da83945f9b1644e6cc9ec0025107fead21d06dc3a721589436afc2b981a277584ae87017150697b8d5f3ffb17ab53746c00a9a5934cdc979817ec37b75a47e7116ebc0dc98bb39e54ab7b21fcfb47de39aee65760cb929603027794f0bcd7af8e3aad7c10b9511a5f8a2a2bf42740ed0a334377de2c3084e93c4f4d0a6c75576781b77d09917724e042275b7684cb97d5450ac014448187dcc8ad8eca739641820e932cead43c37c803fa400daf840edddd3bfd7134b4feb4e68c807934df6e79be380372de7", + "address": "0x62b519210d1152d05522ecd2786a0894ef96711a", + "key": "0x2439cfa77d7473700a4a2e1f646172781c057ed8562f05dd5d4262b33fd7861a" + }, + "0x6325c46e45d96F775754B39A17D733C4920d0038": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x005277275713c3dca04ab6c7e47c80280f192d40dbc42d4798ae13efafb012aa", + "code": "0x66ce4e8e12a5403828e3fb3176b429cb926ef9dc29fd04c1b3c13ed2787d98d63eae4e449535fef8fff684d6f73d890e306ee348ada8a418981c28d496bb7be350dfc491ab5c757ee78cfa27228f3a47882447741e862da671b4cb5afd51d95370d52b43b3e1f9a31ab6163a901e55133bd37da50c470c7ad07e6be9a4e139f4309f8175bdcf9b0c39a91eee31067537b925ed2b384eabdf80116866cc3ab80ddb57df9c1c4f68e2fa98244b87e0d27e04c99093c63e7983b367307c46863d3f3fc3eafd6666b4115f284754aee9ae5ecd0e309cfccdd979fc5507fff0213446ac2be92b45f4e420d0da2f410ca74328fa136fa304300cb98f3bfe380f244449", + "address": "0x6325c46e45d96f775754b39a17d733c4920d0038", + "key": "0x7c463797c90e9ba42b45ae061ffaa6bbd0dad48bb4998f761e81859f2a904a49" + }, + "0x63EB2d6EC7c526Fd386631f71824baD098f39813": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1168db50d8c2d04754fa4490bbedbb9da7d8abaee13dbb166226184e43a2c230", + "code": "0x50f395cf935269ec6c0da54860a5c40e4a834461db1470816d90e1e42a72199933adcd84fdc27d3e867d7b3e99f37edf5e90974dafbd1ff1ab87448df87b1e8832c9847d10682bcdcec3f220294c4be920f5b07e4c9bd319b015ed2172b56db476f70a4b50e1ae7567d0cc5ac047a75e39b034ce3beb11fbcef92f4b009d5ac5d98acec5291ba9332e4780f7cbe1ffb2dd12ac35ed0a419e68c5bb25a3f36736406423470b595ffad93ccf38676da45f48a17fcf63343e5bfb15c88f71795d1135c961d63bca6edaaef30eb43d3e98ae2b23003091278d643f0b7d548887f0c1bbb0e6314a05b0c3773a37fe72e4dab42b2fabbc8cab6968d2bbb4760eccbeb9", + "address": "0x63eb2d6ec7c526fd386631f71824bad098f39813", + "key": "0xfdaf2549ea901a469b3e91cd1c4290fab376ef687547046751e10b7b461ff297" + }, + "0x654aa64f5FbEFb84c270eC74211B81cA8C44A72e": { + "balance": "1000000000000000000000000400000000008", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", + "key": "0x00aa781aff39a8284ef43790e3a511b2caa50803613c5096bc782e8de08fa4c5" + }, + "0x667Bb3a03733d43Ec28d2178c39DC8d8D62e48C2": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xb7c056307dcfe4d5bf2de7d5ad1bde4bfcd7aaa0b8f809a5f281bf5c0ffc5ef3", + "code": "0x8287407dd86f9cd15823a62f56cae15d1cdb1d9dd2cfac15669fd1037cbd633fba04c9fd01e5135b6259852aa7338be61049b7b5f6b9bf8cbd858ccf50532c262f2120a9890bd4e58b07c28e03ff53234c375f6e9b60ef12bd3dd7fb6234e9bc2b664fbfedceaa9e368d36426d56ced624f761197dd7b96937cddcd7d4a8ca8d775b7a133f8641b4824710333c2c435f2413ef48954449113b6ed0576502adb9825fb6258ed58db931ef4a50b617f3b78cc886f5d1e09c7deb5b845bffeed38bb03cda5378747d2b3f6b4d23edbf03f046cbf5e0ec8cf1df19f2b28601c8cd810b1b62f1989f657b839db886f8749798d4c830427984730946a0d3525032d7c6", + "address": "0x667bb3a03733d43ec28d2178c39dc8d8d62e48c2", + "key": "0x184b9df2b6cae0dae7687488d9f738d1038720fb1c84aa74b880cea89d89ccdf" + }, + "0x670DC376eCcA46823e13bAb90acAB2004fB1706C": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x670dc376ecca46823e13bab90acab2004fb1706c", + "key": "0xdcda5b5203c2257997a574bdf85b2bea6d04829e8d7e048a709badc0fb99288c" + }, + "0x6741149452787eB4384ebbD8456643F246217034": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xa0750f0af31158ef75bf1585ac49a9f036c3d1c824bc9cf85348eea1cd44c4e7", + "code": "0x2bdf3b387a25238ca107528ef613f0cda5e5fdc55d2a862a6772bc33c52e9bfa806416b7717fcc15b81108defcfbf29e72f55b2197fecde6e539ebee057989a401c50f6fac5dab042d56d6672b634cb37b505c5aae3d7ba4611136701b0571deb7b30a37f76c4fb5cd36b8aa4d39c72a853a8d4c2fa5b557a49cb235c2e1dafff37f59c4a66e94d1fca74ea62b6b8408510c029e65fdcd1df49d986c1b36dc7926564a9842445dc74d9f07ed82bf6b114b8b1d9caab12e4ffe452622666b49365b356955612a215e910dad02f366f8b9b52d08b78752c97e0f89f9efd40bcbdd49d68b6163ca37cddbba727f9683532a5f96ca0a6046c4d911e9c07656aba166", + "address": "0x6741149452787eb4384ebbd8456643f246217034", + "key": "0x37e51740ad994839549a56ef8606d71ace79adc5f55c988958d1c450eea5ac2d" + }, + "0x67b7C7F0A33D823099897812498d27F02641211C": { + "balance": "0", + "nonce": 1, + "root": "0xa76e1579c7dc21902a22df113429d0ce1741c95e74724cb3380542329025d9f5", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x000000000000000000000000000000000000000000000000000000000000008b": "8b", - "0x000000000000000000000000000000000000000000000000000000000000008c": "8c", - "0x000000000000000000000000000000000000000000000000000000000000008d": "8d" + "0x0000000000000000000000000000000000000000000000000000000000000152": "0152", + "0x0000000000000000000000000000000000000000000000000000000000000153": "0153", + "0x0000000000000000000000000000000000000000000000000000000000000154": "0154" }, - "key": "0x38152bce526b7e1c2bedfc9d297250fcead02818be7806638564377af145103b" + "address": "0x67b7c7f0a33d823099897812498d27f02641211c", + "key": "0x32e29e5de456ade7b4d54018ccdb635ed75ef0f69d5012a5bc7940db8ad41c5a" }, - "0xe43ce33cdb88a2efe8a3d652bfb252fd91a950a7": { + "0x6e538D4e5B09ef72527C5f360A9eed7BdC78c013": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xc157e0d637d64b90e2c59bc8bed2acd75696ea1ac6b633661c12ce8f2bce0d62" + "address": "0x6e538d4e5b09ef72527c5f360a9eed7bdc78c013", + "key": "0x8a9059b202d794382c3d775abd293c1e8a931a9e452cd405bce318655011be46" }, - "0xe52c0f008957444c48eba77467eaf2b7c127e3c5": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb888c9946a84be90a9e77539b5ac68a3c459761950a460f3e671b708bb39c41f" - }, - "0xe5ec19296e6d1518a6a38c1dbc7ad024b8a1a248": { - "balance": "100000000000", + "0x717f8AA2b982BeE0e29f573D31Df288663e1Ce16": { + "balance": "1000000000000000000000000400000000004", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x519abb269c3c5710f1979ca84192e020ba5c838bdd267b2d07436a187f171232" + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", + "key": "0xc3c8e2dc64e67baa83b844263fe31bfe24de17bb72bfed790ab345b97b007816" }, - "0xe6dddbffde545e58030d4b8ca9e00cfb68975b5d": { + "0x71e7DffB120141296fC9cD4B605D2C3e91532320": { "balance": "0", "nonce": 1, - "root": "0x2afe93e1b0f26e588d2809127e4360ad7e28cf552498b2bc4847d6bcda738cdb", + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x71e7dffb120141296fc9cd4b605d2c3e91532320", + "key": "0x9c30e371e95f1eee489bdfa184e03da347fc67634e0563059d2ff4deb72ecfcd" + }, + "0x72488f954A3eB61484471640cBAEaF78CE76d3C0": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x29d4a41b515bc92289080c82736daf9be34e98756523c594c9fcbca9cb623601", + "code": "0x0d62091370673e8ccd6112f88e6cf83a7e262bdd01fbb39f2ad26dc1950ace20478420247b5400ed2ef8c9e82b364bd8588bb9b0f3d359f4eb07c15c2f2ace704689d4ccce42c0f0a53795099e826dae48c5e1990d368d17ddbf2a2a73c395a4d771cacdd43debfb6108ecc2af178721126880a13fe3c1a3eb78b982ac4bb9062ab704a4764a354b72c71784596f1ee2535c2159415177c6759c4aac4c0d6a35c035b7fd4ca3fb9e95fbb0270d7dcc45400ea942e0f1f7c81eab928d513d29259a4083a76373c129b3fc4a15974f8c405a4ae2d36a6502465cdefa34133101b918895f212d9030d8444c7d68dbfba2c3cbe3d4e7953a2b544ff4d6facabbee32", + "address": "0x72488f954a3eb61484471640cbaeaf78ce76d3c0", + "key": "0xacb2843c9c612c1164efb43e55701927b28291c14b6a950c9f658d687cf238f6" + }, + "0x73AACD67E1d72534a3D83D38b88026bE46ff2928": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1e68027de7f5bb2a9c63f83cc6107bfe71694dc9d086d845e1e3b1e97dacf2c5", + "code": "0xa81c3a5a553fab8c561679d85bb19e6a7eb0218b4839501a326c84cd4158b2d51161d849492e842dca32edceeb2630bc6d621f9dea3fdc78ca65f82bb844f4b139366d2e14b42d797be5fb2272e93ead41cec826548512dfa09eaadf5ba4c2a4a171e6dff2e291b2403638b36fa1900bfb6d28056b9cc28339adf04ff3e24b88f13a4de10a82cea8926787ad7534bdd0eeb85aaf1d4813cb0c9cf7e399b7ef0bc1e4ab78a93992ee6fa5897690163464c8f8afa9af264f2d83bf6e5bb209a73a84ff3eb04bac0a2190b4fb9ac6d0dbbdf1bb431847b8b7ccd4a0ae0968e179db7130ab3fdec6ebe33fbecf2e3fe7b06f5b02e4c74c7e44e42655d673012f1254", + "address": "0x73aacd67e1d72534a3d83d38b88026be46ff2928", + "key": "0x9dcac55a8e43a847f19e26fedaddad4c4b70f05633da984b95bc232a1289470b" + }, + "0x7419f9024b102E628c6d8Ae2178fc11edA4091cA": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x7419f9024b102e628c6d8ae2178fc11eda4091ca", + "key": "0xedad8de5342a46c07726160a648709be199da56fdbc92ea23f5bc51a32abd680" + }, + "0x7435ed30A8b4AEb0877CEf0c6E8cFFe834eb865f": { + "balance": "999999999999999999999504116057851184", + "nonce": 548, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "key": "0x4363d332a0d4df8582a84932729892387c623fe1ec42e2cfcbe85c183ed98e0e" + }, + "0x75F2A26625f08390f5b66C5238571de790b4D7cD": { + "balance": "0", + "nonce": 1, + "root": "0xe0a82b671528878859d9895420b108b58cd0a4b529f64b68aba04b144fd8391c", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000130": "0130", - "0x0000000000000000000000000000000000000000000000000000000000000131": "0131", - "0x0000000000000000000000000000000000000000000000000000000000000132": "0132" + "0x0000000000000000000000000000000000000000000000000000000000000223": "0223", + "0x0000000000000000000000000000000000000000000000000000000000000224": "0224", + "0x0000000000000000000000000000000000000000000000000000000000000225": "0225" }, - "key": "0xa0f5dc2d18608f8e522ffffd86828e3d792b36d924d5505c614383ddff9be2eb" + "address": "0x75f2a26625f08390f5b66c5238571de790b4d7cd", + "key": "0x0530f0a872be8e03883d9dcdf34c6243c8b077f5e1454dcba0b00ac41b1c4007" }, - "0xe75db02929f3d5d7c28ecdb064ece929602c06bd": { + "0x75b9236DFE7D0E12Eb21B6d175276A7c5D4e851D": { + "balance": "0", + "nonce": 1, + "root": "0xb3f69d1bc520e1e6cb0c45736136f623265d1c97a183709d9171fb81e888d0b2", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000055": "55", + "0x0000000000000000000000000000000000000000000000000000000000000056": "56", + "0x0000000000000000000000000000000000000000000000000000000000000057": "57" + }, + "address": "0x75b9236dfe7d0e12eb21b6d175276a7c5d4e851d", + "key": "0xc54ffffcbaa5b566a7cf37386c4ce5a338d558612343caaa99788343d516aa5f" + }, + "0x77EA772798792AE8A7A5Db1444c5a08422E61D70": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1d0c729cea26d0141bd5dbd789a82c2bf58858a1b7dd4afc84996e5664a9a4d6", + "code": "0xa29f2962b8badecbf4d3036e28fcd7dcf22db126f130193790f7698ee4d3dd84c8d233a0ebef7c9a17d2b0b17eea62cca39002a128ccf419119b4a1a1f1e7428a4e0f4432e44d027a7b3f953940f096bca7a9bd910297cad2ba7c703c2b799d3fc111d09a6e2f0958402cbe16a5aef32c9d8ddb9a4df7271140de57bfed6525aac375bcb880242328180c23d4a918023a12a7caf7cf12b8c4074e4a3f39900a0b4e18992ad424cdedc46668609f2bafcf665a8d99577618d5923c69264d9cf5f84a4048ee77615560f9afb39551a46e123dd0dd6c928af241dc565271d0325697fecc9f0b925868a8c62ee842da0498074146a036d84a1041d9b5286786bbbf3", + "address": "0x77ea772798792ae8a7a5db1444c5a08422e61d70", + "key": "0xea65665779db5aff91565df8d1183c21fef505ef0568218063195936d02da2dd" + }, + "0x789f8Bd19f7Dd88DE4C94662B7680AB685553728": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x789f8bd19f7dd88de4c94662b7680ab685553728", + "key": "0xeb4aae143f2a12481bedc1d5283378b5cdb0d04e0726fdb5735008d766a0a726" + }, + "0x7A19252e8C9b457Eb07f52D0dDBe16820B5b7830": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xd9733b05a801246c9a6b8f04fb365284d2e15776e63ec367591211b31bac3d12", + "code": "0xff91e8593b941cc006a9af6dd29cf00c1d93d745cd30e13d28db6ad34229c727c0f9ae4ecbfaa81a3f2a4c9bb264c28cac2ae8853111c19109e83d6c1292e7a5db185bc3aea90f5e30861a799d320e0bb6de11723a5674bbbfb6409c8f47b8822023c3bd05b942cf6cbd5cd645de4d3fea19926fd4838b16303d2ed62750847284ea7badd9e8d390707dc2872182ac68c8c7a984bb7d1aac16736628a499083edb0e2bdd19b7b49c93d2d0d8a27fc83f2071eeb7608d02782d79ee059eccc097f09b457c15826396efb730bf67656e5debac76c904fafa6861ed5765cea4df444069a8200c657d770aa801936fc60d04a47893a564a93a09e064b483165beec1", + "address": "0x7a19252e8c9b457eb07f52d0ddbe16820b5b7830", + "key": "0xab7bdc41a80ae9c8fcb9426ba716d8d47e523f94ffb4b9823512d259c9eca8cd" + }, + "0x7BBcF9B49875acdBaa5857fD596CAF6dF405939c": { + "balance": "0", + "nonce": 1, + "root": "0x8dd6737b0207a31db75fbbc29063d72290aafa75f4164d85f3f4b6fbbba2fc74", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000024f": "024f", + "0x0000000000000000000000000000000000000000000000000000000000000250": "0250", + "0x0000000000000000000000000000000000000000000000000000000000000251": "0251" + }, + "address": "0x7bbcf9b49875acdbaa5857fd596caf6df405939c", + "key": "0xd82835359d9c4b09cad79be31a60ead5e421589b8cb2bfdd6e173d680176bf7e" + }, + "0x7DB168B2537EcaAc90f67C14401fa36fD8980252": { + "balance": "0", + "nonce": 1, + "root": "0xc5913c221e08d61a0acf3d91886ae1dd3d00f640857b9abba5bb23639b95c015", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000218": "0218", + "0x0000000000000000000000000000000000000000000000000000000000000219": "0219", + "0x000000000000000000000000000000000000000000000000000000000000021a": "021a" + }, + "address": "0x7db168b2537ecaac90f67c14401fa36fd8980252", + "key": "0x33f31989117f50a30bbd8bde69d2efcc6ea606102f7b3841a65a69fdb909f041" + }, + "0x7Dcd17433742F4c0Ca53122aB541D0Ba67fC27Df": { + "balance": "486", + "nonce": 0, + "root": "0x735b3acfeefa3610e61d87c6927b5d712cedaa9fd722002c537b13d8619fe39c", + "codeHash": "0xa3216dd3ef46a63d518ef54e482cecac68a077f70fca0e5fb900be63f41d54a2", + "code": "0x3680600080376000206000548082558060010160005560005263656d697460206000a2", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "d8", + "0x00f7ca033c24d91f8fc39cbf0edc8a43192507f93d7316f311b05eeb85921eed": "1d", + "0x02bd9d62880450596e11c3417f2644a81f7cc233a05394bbbfb58428ed53f413": "22", + "0x039a54e14fa9769f840074356dec3dbd47c3588fe71fe942fb7aec5edfd0a096": "82", + "0x0678ff21f84e5213aa8d1d173b3517f8e6c3d1523959c101c75a31daa70ab942": "65", + "0x075a739ccce514f063220aa4bb66f08a7966189b0f24a2c5ad4692133d7aa6cb": "bc", + "0x09b79212fdf6dfcd322d6aabd5ba752b962d7e575cf299112bead28ab955f4c8": "bf", + "0x0a2bc3fd72bd3f8bb7f1de9a7dc9e928a7c6a831237124e65c60c25f8348af19": "47", + "0x0a5a37a1db2e0068ee9791dbe377a74c4f7bc36bc27af57ca7e49059127e8eb0": "b5", + "0x0c8e91bcf03d65aedba99f4f76d3ff8cd007668948ce12daf4dded4761c7b19d": "8f", + "0x0d968817f6ab6815faa1501ac1eafc810f4bc9b7423abc4f1bd5e65e791b4e0b": "18", + "0x0dcf6219856f226889a2440b388d8e15f5df0eb64a7b443f3a7a5dca7b87b0f2": "26", + "0x0f624930606bfcd2386d583abca6ab10227d71fc1633fea53f94bd146c152b8f": "2a", + "0x11f0a8ac2adda075c95bbf6be534e3254dafa759f62cbcf0e91bc6f0335e70aa": "0e", + "0x142951613bf93db71eba96bb48c57a42168fcfded6491e1229ea2b8570f77e7f": "c5", + "0x14ec3dfb63100132cf23ef71b80689146033fc6ceb9f8c0f0a65ef93cd18c2c7": "d0", + "0x165e0e0cc13ca53c5af4860637550364c5c90a512906490ace14efb534873741": "27", + "0x16bee816935475cd45501fc5fd01bf913f8ef54330a43d80ef73101a4c728b34": "2b", + "0x17f29f600f5128013ce183ac10efc609231aff556df37c8f5d6802c1240c22f4": "af", + "0x187c8bbc8cd3f478b5688bc03cf5eda82ee75aa605e946b39ed1898f0cc0e00f": "88", + "0x18fbf0ae0e2133584c461cbd43169854c7c7e818e8b5779892da244f24d27b56": "52", + "0x19fbac480a243f8c051e10225cec11bcb7fb274fac8792ca7e36bab8e39d312c": "91", + "0x1bf804b21bbd284f3f59e4862747fabb1d91cd202d99df811fbcd650c8916ef1": "58", + "0x1bf8eef1506aea16c94dd534ab271dfdae26648de569b3bf6fc8bf4c76bd1a99": "8c", + "0x1f1860251182573015d583a718463a52050e45d795ec0f94d112206c3fd62e45": "8d", + "0x1f6ebf3e4d9c96ec86b866137bbec9bbb56d188e7126babfccc6394fdcc6a3d4": "63", + "0x1fac03facd67f44699ff86330a7f959ed3745add76d323f4832bc17c35be45c9": "9f", + "0x205bcc2489f954a3af7a16da4d6042a75fcd6eb69b848c52b3448acb24b23580": "43", + "0x231eb803c34ec183e74b466c105b5518b554ce215bbc31bfa52c384138b8479a": "ab", + "0x23c2e06f633f91e89e0d95cf87dce47fe1cb2b95434ff45773f1fd560ad2dcf6": "42", + "0x24a4daf5b3cac3bf3066902cda09da0fc862e0a6723c47981ed601782ad69079": "1a", + "0x250ca62bfd18dde43e70bab089d01d591ce6ab28978434258ae1017c72f12b0a": "96", + "0x27edda711baed4a613c44d8ac8678531c9938eea106e7c5649e438f3d24b8fe3": "ae", + "0x2aee290f6f3f6c60a6985d0150eab487f9de1c47962a779be7343cc0cff270f9": "a1", + "0x2daaea9286d7edb7568e0803a61bfdb1e1506156d27e93bdf1942564850646c6": "2e", + "0x2dd51e8325001014c6845bc5ad51b134ab237f95ab18da55cabc4275b029bf3f": "5b", + "0x2df4cc92987ab73b08a3474750456382a0add51fa25f928480762f3d993f2984": "31", + "0x2ecc9be98f9a8adac6e6acc5f160b0d15439b3856f0dee2a3005db79076252a1": "98", + "0x30335bc132be5a5f3bf464e0eed03a3c74f180cb9906552e187e4c04f024b804": "c4", + "0x321c62425869f150c2cb7f489691c3e5cd49f7cd62d07ecbb7477c4148aaaa0b": "5f", + "0x32984cfbb954e0815427570f4ceaef21a3691026950e5ad80401232f687620e7": "44", + "0x35f96bc70aa62a539fa99d9153b0f8aaa4594abf70cc8a8d9018e04e39a17982": "0c", + "0x38570ba11cfca6a25bea615c7ec09ae671516245a92a5f8fc61d2e82529454e8": "6d", + "0x39410f5a8f450e0b7fe63aa93e214a7c5cbe78786c815ebc926f1e8a2a14f4bb": "b8", + "0x3982f6a73961b17f67a84959ebc42a5a3ebdd1faa925399f3f276cc2de65f2fb": "4c", + "0x3a970a6d07c991261dcb566f26d21a76c578d05d1565c47dbc1fc071934c8c43": "ac", + "0x3c8110e03f1b54de6085ff899d0dccd87806b788d1ef3fddbca1de4c356266e7": "46", + "0x3eb32abcff52bfdf0887e9aebaeeaee4a61b76f2fbc9a183c2afc8552d46c3f6": "6f", + "0x3f410a22d042d915c50f9269337a2bc7155f86d79bbff1721d83f44153635ac2": "87", + "0x40325cfcd159fa7bf89d8c252b6ff47cbc17aafff5e7feb92014d00285484cfd": "7e", + "0x40c619388e6393f420e805451bd48b10c670de7d51e916a3ffe5ac3c96b81938": "55", + "0x412379b7f583981ea6e84408cba75ced69039e07ce9cdaa32a8a9dac997aaafb": "17", + "0x41565ae6f06f2555139f444c467d6b709b45180aa0c6b15bb5b1388d55ef952c": "19", + "0x415feb809041baabc4d9246223e40f1083963cbe1ef6dedb8b153e49d02ee7ce": "09", + "0x41b546f355dc0dd009ac5da8bfd17c8e197595c1c1f21aabbb1f3b18343a0718": "a5", + "0x427b8ffdff6454ea85c8251407144400ed4e693ffb6a74f319e0238c0e72afad": "57", + "0x4323bceecd4ef7216d5b57b9dd12ecf03842ed56d87fe43d0959436f408f44c4": "49", + "0x4348597bdcdee80c8e110d94f771eb7edce9c8691b2f90b71c0d11f729f086c9": "5e", + "0x434e2bcc5f4148668dd618144aac33ef5d463b292b3baad302a60aeb6be03b86": "90", + "0x44dc9099d91b074b843002013672df4de9f691cf60546fa74eccafa9044a75a2": "54", + "0x4632fe8e9579f33e2e42e68811d49a09ad1af1f01a68e7ae742f765e8e797ff8": "3f", + "0x46765aab85a7ee88496ecde24f93cd5ce361b5a9fb43a2641d77bfbc97928010": "41", + "0x468eae0ffdb87a4dc081a86c494969801637f690e1e1da15fb4a9d2c78272da8": "25", + "0x47cd31a1b89686fa610642222d2da6119e54ee8ca761bd01a649e3759e47746c": "28", + "0x48ca1081e747a7f831228b894dd5fc401d64c6496a2b9e578dd3c59b8f0df2cc": "d6", + "0x490b9d550a200295b38f2456a42525d3a43c345d2fa1431e770fea9656b26723": "81", + "0x492ae6c575840126917090c30d003aec0892cd6250f877b99f33b72133b94f23": "a4", + "0x4b3120af8064823e074758c51cd6cd0954587c0d94b5b37b336261fc7aa2ddb3": "15", + "0x4b85d3d5e4e06787a4e7e6d00f4e2f6d7e0358d9e511177ab584553d4ca06038": "8b", + "0x4b916e15bdb0f5b4bccaa3447694db53cc34095b5bc26299c14a9f573bd6c758": "7c", + "0x4c3dffb6198347c61671fa1fafd5d80f384ab67a494f5c7bc7428bcb6ca5a445": "4b", + "0x4d4855c520c09f3435e2cb46ceb4d2a12df59c127a1f2e871e7e9e8203fd6ce1": "6c", + "0x4edb05f465bc71ee02c59ac9b5b50ddd974960ea2bd7e8cf7ae91c38c0b5789c": "61", + "0x50495437ee69f7b12c5d6eb55cdcd8f5ce12a2eac21a2a42a7549e9f5289b1fb": "20", + "0x506c0723b5e537632209d4a824a6073d5eccadb36b9b8717b2ecc9e2d5cacda2": "aa", + "0x51524a498a88953303410a83d67c2b8c69ddafeb99b570accaaed774fbc8583e": "b0", + "0x5423899586eb1d932cb9da03e478e1dd5d4cbbcb66d24262c7d67e543185c2ef": "84", + "0x5571137d48f7d081e62051a6bbca9d1e25c93ac6f84b7a3bc146f126ac80928d": "d4", + "0x562f817652b4478bc1e434240cd21e00774a5a1210833cbf0225273e2b98bae2": "2c", + "0x59b1019e8b01471b1dd478e65c30667d2d1780ed0c8bf5fc784b1413789b2f82": "24", + "0x5b300d53be5798f53b472dadb8966674169ff3e8d08eccb3f065bd827abd7b77": "33", + "0x5d7c0426d6595c1819b962730e5d2a44644703ebd960ec3ac51297ad937692f4": "4a", + "0x611f5b5e5ee263412fed40f169d0727f4e6e1a2bc94caf668d2bcf22cddca8c1": "3b", + "0x628887ea9304aeb7f3934543b9d14ab4e7e5cd422ba572d39d6ee10c33045345": "5c", + "0x63cde520fb894276a981d2c9099bef9beb949121c1be98f3abe1b721d880899f": "02", + "0x6551251b96ca27f3af8a2c500d6dd1ea5b9ab7002b3d923b66db0493f4a7123e": "0f", + "0x677a6b432bd3361f469c2e051c8e09ea92ed0d049eb563118ff8c680fc93a2a7": "92", + "0x69626497767f58c222726a6a3c65050bcfdbb9346f9e5d146ef02bf59275b3d2": "d3", + "0x6a99e5276c6ea0c0894cfaf376fbbfdc736b359e1560a77365c14fcdf6cbbf53": "3a", + "0x6c172610999b0729fbb6bb1ba27e7a0009f1b584ad6f8307d3dcc7d24a180874": "c2", + "0x6df5983ddc40ef2c7ffa2c79bf9402568f2ee0ec7b675ca15aaa20b536d2a5f2": "7a", + "0x6e2466f20ef20cb42d216dbf4a0d934199213e9b8d75bedc9c2d3e038a587474": "1f", + "0x6f9ff000b2dc3a554bbbb882ebc7726b700eb7afea141ab16e00a057f314d0db": "a2", + "0x701960547b78067b00883157f5e9fca3bbea742385129f0db7e1e69ce445dfef": "d5", + "0x72be914df22404e1ed45a8224b52201a77605d52065746a00af5f60980fa4c99": "34", + "0x73286395f2a86bb5537d9b45ca7c681044645f31475a11d49285d6a0f028b8f0": "08", + "0x73b2b230124967b31546c7e2fedbc5ab108a537ef6d645621fe74fcdc0644b28": "3d", + "0x75eb384e56c3a3a30a408622e6f0595d30705efaff129c133effc43c3b946de0": "9d", + "0x761bf5fb1730fee0e499bb1806b9ae14394e673ab9c1dc12e95b9d3f1647cecd": "21", + "0x782a285a3a645a32202a71e713e4a813bbaef9f50ce10e4caa0122c110d86bf6": "50", + "0x7975cc1088361453b019ff19e2177b264cfea56f4c09b1a8a086f6c405dd516c": "80", + "0x7a536b71187079aaf5462b7d483063e3d25cea8e3a6790ebdbb284666fe81068": "ce", + "0x7a63090121e41c76eee07564883abe3bd839fb20a0d2513bc9bc524f6c16f88a": "74", + "0x7a9cae3647128ba14914f547c5f27444cd7325bbc37e5038abc31eea45003034": "2d", + "0x7b95105ef96b105a85277c69993f6f56602d912fe712ddf6156cdfcd8c490607": "94", + "0x7c24a68c92e3b68daa153ae82eff9be1ebbab973384e0f4b256f158f93c5d525": "1e", + "0x7eae9da1da48fe866f64de7ac5c70c8e43644867b917aa8461f84915396d3598": "a0", + "0x81260b78e72018d5773b6ba1df006b09a387fd733e59ad152c119d9848ecf1f9": "66", + "0x81607ef8d6fd479d2d0f55ec50762ee5fc35883ee5600525ce1e9ef3398d5aa5": "4d", + "0x82a4bb68f7522b711c9f22b00f9c5e050f52cb2bc5f0f50eadcb12a5f1c30839": "93", + "0x8405cb4703a08e5160e343c37d42df5f045091f6b22664b0ec3f587df18d2d82": "b3", + "0x8460e232c64e6cd9f816c02d855c892755984ebbb91592e683cda80aaba4ba22": "12", + "0x85c0042b81b23b846d1e4881b0131b4bbff774dd9bdece2e74fa92ebdb053c34": "40", + "0x85ca3ddf1ae9fb0aeadecd8109961dc5d5eaff16ef7adc672149a7826c69da97": "39", + "0x87dfa85154edde1626e3a09196eab4b60f71887ec7b50ccbbe7ec76c0be6bdff": "1b", + "0x87fc0239418406958902bcd8e059f9ddc08fb2683a4be0cfd47b1eb97418be1e": "3c", + "0x881a8434f98b103a2ee48727304618ca54234f1474c44bef70c21accc4dbc0a7": "01", + "0x88edc52ba848622b1d92e73d2c311c1c83420986c621546fbadac23c3428c570": "ca", + "0x89c17d9392b73a55738ba19aae192f2f9c5612dc8bd803ca23b9c2fb9c309e56": "0d", + "0x8a38792846734575025e5114061b62006064b0636caf6733294eb26895bda2ac": "4f", + "0x8a76d1e2fd58cc0018aa306e83990d74d16ba9aeab4794595fc72551f0465476": "70", + "0x9038344c39b01167bfa8e99a6425d34bca24c27ceb191e8eba70ab5a8f719ce5": "11", + "0x905cfe802dc4c667312ea08fdbe97798b88cfb11049ade2b18ad9001e8b6dd7c": "14", + "0x9138868b39f601dde19efa6e9a154230a51805e9a6cabaf28fed5163aea58328": "5a", + "0x9225354562a563158ba2ce0e86cfeed7fde0ed27c77342aaea09551b9c00ea19": "a7", + "0x927e4ce70caf344a9e108ea8803cd49216852109c3e4922dfed2680e9f24361d": "86", + "0x92da59b68bfd8a9c1cb1ca6a302ee966f829f2727a36823b0dc7fddf7790a108": "8e", + "0x945c01f307d13fcdab0a2a3a4c4bd5ebb69a00c3dd59896a959664e01ce10695": "83", + "0x94605c950838b2b0b1ce76f58acfb91a94c2aba787d02add7187360989745a4e": "6b", + "0x951b3b37c2a87b5a67918e750832a50c5565298a35390bad3ffffadb2f7b4afe": "77", + "0x9575996f3ad6e9709d7122224335451a59395327d297fd7967004e8dc1391308": "72", + "0x96c0d209b0a5b8b06947cc4c7ca723df55c5b972711b6c08ec7b9c393fa6e8ea": "b4", + "0x970a64830f255bfc38886621b37a7f1a7284bad6c4a04b6a2442ad212e19a6a2": "37", + "0x989e02934facff928d8e788f174ab7d48838c62b07d420a8527cb7eaabdbe91b": "b6", + "0x9ebbf91a66183d0d37b03faf46daf8fe238c1aa2b24e6663dc14e50557d432c7": "67", + "0x9f5941a130f6c2ff98ec21bb2517998dc5c8512230dcb37ede3cb8a4694175ab": "c0", + "0xa0634d80c0a702c2b06dfe60ace0d8f788b99406f1d2ac44ad3a26faa3fc1464": "1c", + "0xa0c2e429d47e77e9b7c98c1aa4aefb731206f41b64a6587678905a86d14a7d75": "d2", + "0xa22721490cd06a0e77bc2b085bb4d57e7e5e0b459a2afc65ec4697d51926e1b8": "59", + "0xa344ff63ecb6c6cbbd711b06a84844147910ef79a57679958664abf4af9938d3": "c6", + "0xa3e65c2aeaf352e79173be13e572f691d8d75ea1064610b8418246d95bcc421c": "79", + "0xa41cb4f2ab2731a8889754ae1a340c666cb8107b497b922073df80a9b255e31b": "06", + "0xa6602e59691514abf1ee46e71c1f4c7411eddb76e687f8f4aaa1ebf305b97f6c": "b1", + "0xa6d01173df2aa437fb0118d181e64a8f8e05713fc01c42fbfd2250516639ae95": "07", + "0xa791ce367786fdc4c5216c8b94dfe1076746e058166dabda25b5e6a3266ce857": "76", + "0xa90642da2f095eb8128f01811cb553162395cfcecbe5b077f12c62a1effa7c82": "99", + "0xa99b8fb9a23a3a24ef3330a371d081c4158ea1b75c9af3c2bda5440857bc8237": "c9", + "0xab15322a52f3de5dda0553d7abbf171524cabb9c97dacea8806c750361d472df": "be", + "0xab5140d25dce39c42d511dba633cde87b45465d48aa4ec211b27de998abbadfc": "cb", + "0xac748acc1af284e25d06434a8c1bbbf75bb8154a06f53f75d4f36edb656a49ba": "5d", + "0xaf1c2654b2e98e9ffbb02f14d88617a245a9a1679162be29776a4836185dc2fa": "62", + "0xaf1f0d50933e49dd24b61a24c670809a5b875e3b746862636288dead8579dc4e": "2f", + "0xafc44d58dec637206e79248a528189c68365e20afc23410475deb5e5dc69c82a": "89", + "0xb2416e7ca12669406e6cd5154ad5177841b7d0cddeb2760249c28e1aa151f970": "0a", + "0xb296a1364260e1c8d47bcf2239f26b6b909a0a7687250af4af545eff0ea95ed7": "c1", + "0xb36949b816cb2ec4ab90f345d0bed84f55b8fcbeffd22198724c45d8a30b20a6": "51", + "0xb3750ecb88b6e11e5f686cbacb3d24e61396cef4a1525b30d5a30edc4b3fdec0": "69", + "0xb50dcc47e811f76cc69369cb397936a5c70520a51f33b84f1b54591da145e823": "b9", + "0xb5e95d5da3e73f937bfbc9b4990bfdbd865c6d3a3b50478657e20b507fac7541": "75", + "0xb8d28e7b703baf999848ecbba44026cb6479b3f0466037bcf2221ffc3f8549f9": "03", + "0xb9a419e057752857f289694284890ff1fcbfbe5d736b5e52bb8568e077f49883": "cd", + "0xb9f03edd278ccfc90e45785c1fea3f972618a32899f836dd4fe0e63eaf8c7c40": "30", + "0xbae4f13d358194452066fc1305964decaafbc9c56a2fd16936d25d9521a57a19": "b2", + "0xbdfd2b337ff30e9e15c09313bf796d3c75177943e0aa0445f479fbd2dd5c1d6e": "3e", + "0xbefb4ff6aefe6c4d85158d11057517eb9cb1e1cae3e9d2d9c90ff40b2cceb546": "6e", + "0xc452b6d808f45af81c3310dcf94a1704359eafc34709c45b0c7b95adf4cd02af": "9c", + "0xc4f8d20ccba0b50d46d9c87f28cebf8c165fced694a2b34412a4b6153b987a17": "78", + "0xc558392238c2d11cdd04a6ae37065f3541a22140500f92c0d8006ff95e8df595": "cf", + "0xc668aa05d66c2f88a95db12354386f3b6a1722a98aade506e117201f2fd0511f": "c8", + "0xc6bea923a54f8cf570edfddbda896a2ebf7b53d33b1dac8914ed024ff0621f18": "bd", + "0xc8bbb420578d2d80897ca392a55fce5e4834f1d641472c0fd6a9698b7a8e7866": "a8", + "0xca27d6fc8e6016df20a295f26b57b2f6ac7a8cec98224571f416ea88c0ee7b97": "a9", + "0xcb35fbd0ebf79655e6882326c19855ff90befcd2e589418566ec2e3a1efd65d8": "85", + "0xcb55d89f2ee070d017b426876d6072d91c2a7311ade9a1bed2f8200127ec380e": "04", + "0xcd78e90ed1705eeff092f3df07b16a382082e9c388030ec3188daefa57a731dd": "7d", + "0xce285eb20810f2d026bc0b62faf3735df2193835ffd85df244ecc2df24f43b00": "c3", + "0xce87527a0ad3ddb4d0d57d8077e84d48a6f3810f2a5672143d3b6969b0f86d6e": "97", + "0xcea8a961664f986542ebbc496878d052736682831cd7847bc769ae16e9eefb65": "9a", + "0xd0e6005ee39e02d654cc2db358df9659d8265e24d7362df88a7df9200438f6ba": "45", + "0xd1a0570d06c0cc4198b4475cb892ec41ca3239ff670666bcd97faeb62c1db6bb": "ad", + "0xd2dcfcdea157f70f8422558eb02bdc6a503cf24126f8f2dc2b52a644f5f02271": "68", + "0xd314fafd686fcd729a24ff511ae5e19248bd6ac6de8c28c79918df72de20e63e": "73", + "0xd34d30c2584168001b907965762f784cb4337381aa8090ae36bc66bd515849b5": "48", + "0xd5eb8e9a486b23e10cf0092ca8690e7bd6d6c90932960cdfa5da36d1e1f20423": "71", + "0xd73688caabee79f6ecf3a0b092d26e639b7e486e45c00031db80d3d7abe8c683": "7f", + "0xd75c9abb1414054ca164bba2f8c09917fb90c24789feaa311ee34a0b3f4a82f0": "23", + "0xdbc7a073eb54d33d8e6dec5b0b635a874204bda1c23234ff0cca057ff8ed77f5": "29", + "0xe067f85eba81feba79bf640415c11ab4448d5cc4a41652fc0a200be4d2661786": "7b", + "0xe0fa1a4e967a01f4a84aa6715b0977cc111d3cc0834c5d04f0f1d87e0d561a71": "d1", + "0xe207f028cce1624a1fc76c56f1794c2704a692c1f214685291d618e40733ff1b": "4e", + "0xe2a0b166c03b200234eacf5eaf9ea11746c9bfd00e72f55d8cab76e0eca7195a": "8a", + "0xe3cb3b98042d005e52e8bbbf49b25e11be63ec7c63ae5a5043e44c545fce633e": "9b", + "0xe4c7ff156c2f31d046217715d0f193c8a6b3a7af6341d6abe0e28c49d1210638": "a3", + "0xe5f4774cc356a99594f072de9e8113739c65fb51b5d0fef3f40627cac02dd963": "9e", + "0xe6a5227fabefc934ddc0a3142a50747ad1157ad0829ec0bbc389d5e22e3282c2": "36", + "0xe70ed54757ba10a0b95454f6483d3d2e11613828f13d57d50b8a3a98e2c8df1c": "53", + "0xe7d55978188f31ab090b1f10d8d401a66356b11ca8c296384a0a51e36e6ec11f": "16", + "0xe865c3418b47b88e94c28956b326a799298fb44c62a7a6bb55fd991f7c0442ca": "b7", + "0xe891146f52235abb9f53919fc0e41a678d5a8a807a2247177d67539a2bcc3d1a": "ba", + "0xe8a78860d5ffde377f4eb0849fe59ed491d4a12fd51edebc2bceab3549d83463": "56", + "0xe94d0b2545ec05c3ce3431c4d45c3b62fcab156563e8308fae1ebd27a2810c1a": "0b", + "0xec200bf1cc6a2c5d58960dc3476cc4794ba1a9fca2ac3d09b63e7811b7299c3d": "bb", + "0xee0b894f33a9643c94e4e2237077260f4191c5bf6bb3c17a2212b86af6f67df4": "d7", + "0xee181b97fd68754f6245c655a0a0686e8d12aa4eac5f1d059e7e3b8d6a924073": "60", + "0xefcb86facadbec33b8779888975eacca8f44a9073a845521617f1fb30e1ac818": "10", + "0xf0ca8a88096a033508993a424f4e40ee1d800f62390dfe4ed5dd74a0f6785e25": "64", + "0xf26b2f780c4b92b3f15f1d6e90f7d5a176b58eefea6f0d9cf2f8a0d1f86a139f": "c7", + "0xf77c749ecb156f605e2334b14caea388100bed09b4c16579c952a96e90355629": "05", + "0xf8b0a158a81e46d2f46d268e7726acaf7c33fc321c36f6157f07abbf7fa49e5b": "35", + "0xf9b648439e7b876f9aa1b178fc6381f44bcaee23754d8da33b2d44e78cf47bb1": "6a", + "0xfa29cff134420b6526f434ab690a9c3a140aa27b8479ae3d8d83b6c799acbc23": "13", + "0xfaca663a6ed04f52c0e7a8981cb438545f614a2cf84f9077659d0fce0045cda7": "32", + "0xfb2772a3127ac292efa3da20fad64d950bf973fb209892fdf834766aa8cdc3ba": "95", + "0xfc6dfdea8f35e8af49faf38c0164a3deacd65c3927eeece6023868f32fd382a7": "cc", + "0xfd6fc192aa03eedb6505372aa1dcda93dd186fb3eded0bcafdaa4f2829fe43b5": "a6", + "0xff5c526fc525d03cecce39f4ec167af09f80525e2d44e60ee4df33a357b24ed2": "38" + }, + "address": "0x7dcd17433742f4c0ca53122ab541d0ba67fc27df", + "key": "0xbf1f52c702c40589735c4b038bd94e04268a58c35afad63bb16c071d62d2e23d" + }, + "0x830544a6A94aa496947fB7e0182d64FC90192AFc": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x830544a6a94aa496947fb7e0182d64fc90192afc", + "key": "0xf1b58012b0f270cdd9c1add82f593179cef3f8360950aa5d1fe5de28677e73a2" + }, + "0x838CD8572D61ec23308cfb4f1f243B796a7f310B": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x30bfd822c5b2b88f07fc3988e7e78f96e22799091c6d1ba6e7cd6664669dddbd", + "code": "0xdbacf0626d1d814fd5d504189e5d5800cfd88bcf349ba6ba602b922e791aad56ccfe5d2425df2e3cbe8d7f0532b0a6b9f9be4a330be5d04c4d5f0c47290ef43ed67c34e8612c0557ad77818f63b0e965e2a918f477c43c5c407335625c16a68dfc647ae7caefab63c0c1f704d0ea4ba636fcfdf39fd0af454789b76cbc52f42e66b0a0b12995e6441f9cb2914565120c2e684eba0fba8b96acd03665e0cd074866e8088a238d9e0c32ad5efd7ee9df89e732a9c593a90146e4811d165f76da25de0705a5a4491cc4250dfb52b96473113e661025e4c03285e60a4cabadf93d8d256808232eb07d2271c0909d50bea3c5ea7ccbf9eef8f2443bdaee0dcef83c94", + "address": "0x838cd8572d61ec23308cfb4f1f243b796a7f310b", + "key": "0xd6167bc4042666c07f4e56f51aabd2c4362fa4f6c83ca79a912bdf0a8e779475" + }, + "0x83C7e323d189f18725ac510004fdC2941F8C4A78": { + "balance": "1000000000000000000000000100000000008", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x83c7e323d189f18725ac510004fdc2941f8c4a78", + "key": "0xb17ea61d092bd5d77edd9d5214e9483607689cdcc35a30f7ea49071b3be88c64" + }, + "0x84E75c28348fB86AceA1A93a39426d7D60f4CC46": { + "balance": "1000000000000000000000000300000000009", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x84e75c28348fb86acea1a93a39426d7d60f4cc46", + "key": "0x5162f18d40405c59ef279ad71d87fbec2bbfedc57139d56986fbf47daf8bcbf2" + }, + "0x882e7e5d12617C267a72948e716f231Fa79e6d51": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x882e7e5d12617c267a72948e716f231fa79e6d51", + "key": "0xd2501ae11a14bf0c2283a24b7e77c846c00a63e71908c6a5e1caff201bad0762" + }, + "0x894a5b01c2d125723dC24027397b84fc2C12f98e": { + "balance": "0", + "nonce": 1, + "root": "0x74e31aae08ca993c66e057308da6ff98cfa7397ef38e32b8c80bc3d0b2feed44", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000239": "0239", + "0x000000000000000000000000000000000000000000000000000000000000023a": "023a", + "0x000000000000000000000000000000000000000000000000000000000000023b": "023b" + }, + "address": "0x894a5b01c2d125723dc24027397b84fc2c12f98e", + "key": "0xa0e89baa990383f786b92798b476b4168593965a50467398bc287826e453357f" + }, + "0x89755Db2D43ED07322030C44268CFa774A05213F": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x8bea63d78653a516d0f413b043e750eeb449d8f5945d8b4c99a31a180ebdbd92", + "code": "0x3cf37595cd499be52965dd5cca4dc7fd8080976ba95b4d20907743b4d3ecf9ffd77d0f489ce296cd5f8054a5bea29f38d5248debcffc93c173d3e97af0f5880eb9106f1081d00798476dd8912565c23630e501584be091d1b1a61107e4b43f0c7f6764beb2e7bda5d37196dccaaf19eedcfd75069c8ae61ff739b58f0245c006f6e0480bfd242c1f13584a18b56f00f714e95b7578def5b6fe8aa6fe2c7565cb880cf1e5ea91773c5662a51b8b5d0bcb364561c2a7d5f3dd16bb1e539e17a963c6bed01c788e26af9ba38008dbb606bf52075609b11bbf1ff2f92d9630a74dad5f42225f39926a4b2bfb3ebbfb8ad78d7118cb50f042eeb7c25d212650a9a4af", + "address": "0x89755db2d43ed07322030c44268cfa774a05213f", + "key": "0xaa0ee8e4dced0932f418b0f072a87b286e6fbff9a0fa8b8914bb99c64cf7f019" + }, + "0x89b589f62abaEEC1C5BeBB68E788Dfae838470A2": { + "balance": "0", + "nonce": 1, + "root": "0xc7bf2b34294065afb9a2c15f906cba1f7a1a9f0da34ea9c46603b52cae9028ec", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000194": "0194", + "0x0000000000000000000000000000000000000000000000000000000000000195": "0195", + "0x0000000000000000000000000000000000000000000000000000000000000196": "0196" + }, + "address": "0x89b589f62abaeec1c5bebb68e788dfae838470a2", + "key": "0x2befff860dbde3744ff8ebca534b22fa4b34a87bf632b578ff4eb0685a0ab872" + }, + "0x8A2DC10DdfaE949F0810dc849F6195a74b290501": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x481f79f5082e69b26df9c2cd4e19599929555456c22e17e22f049e28eefb707b", + "code": "0xc2ced89aea6870645fec84643e7d808703ca38865c8c677d069f1a9aa44744d5d4ce3a3d4d5bbdf364c0d3c4eb9dfd5cd27b08e454db6df196e94ce85c8c64c6e513bcea0dcfdc2f60988fa782e2f91b05213e66c317b74d8828ed1b7b2d6f8140dd0cfefe152c0a4af45294b873b56135d6096f0d51077644850563ebdd18d5c5f542e7eba9a41bae99afbaf85429bd619c0a3f8e6a3abf870af45cfcb8fc3f9aac8525636c18ba20aa23afd65d3d23be8a3f9d95e71cd44833411e5e7afcb8ef888a6857569f16b358b116a33788c292ca4551ca7517600ee16822e6277fdd92676c0b232be4b423ebe93ca4f745d6c40b234da106081418f7687d28b0a21b", + "address": "0x8a2dc10ddfae949f0810dc849f6195a74b290501", + "key": "0xd66cce0c10db7db9dd3380c4eb64b6e3e150b592552454222c6fda7e17ae4610" + }, + "0x8BEbc8Ba651AEE624937E7d897853AC30C95a067": { + "balance": "1", + "nonce": 1, + "root": "0xbe3d75a1729be157e79c3b77f00206db4d54e3ea14375a015451c88ec067c790", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "01", + "0x0000000000000000000000000000000000000000000000000000000000000002": "02", + "0x0000000000000000000000000000000000000000000000000000000000000003": "03" + }, + "address": "0x8bebc8ba651aee624937e7d897853ac30c95a067", + "key": "0x445cb5c1278fdce2f9cbdb681bdd76c52f8e50e41dbd9e220242a69ba99ac099" + }, + "0x8Cb56A21fa72164941Cb0dbf29aeB768717854D6": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x0c8bff548799dd135f3cb3e056bf566181e9108be2994a07f4d4794cedb7e552", + "code": "0x5bba6c3fee0b8124daca6363e92ecaf12fc7e679b7fa7011ec71097aa99d7c72ac4a0eaf77f84b961843673f6a295658373799f9f55eb8ad7739eeb7e7bb806b582a010d0a424aedb0a6e3b9b8c4d8ab900ba6a6eaaaee7fe1ca909c2a57c9362474d855c356a0fe098517bf1b7facee1d1f874bc27250eccd0f1415584ff2746ff3aaf1ca46bc5ca71f78d7eb78c5a5a10473d97581fc61b8f8d9e4738631cc2b47fd924568f9fb3e1cb8fb8c820469b32885a74104faa8542215bc59fe949d2fb0756fccf098e4766a8684e0acf250cbde9ac42fd27538d731ee65f3e37c574579d5daf3f336107fec35c60afae2c2eaaac8e901664ce44148f4fa015b29be", + "address": "0x8cb56a21fa72164941cb0dbf29aeb768717854d6", + "key": "0xa883489fab16a412983ab7d7bbaacb91c62548282def2f7b64ce8c475d619dfa" + }, + "0x8b1B7E36D89a957b4f8935113702804cfc65cFC4": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x89094b9a1487e37689f7f10ab8ff11eaeffc224fe768c9959e37559da47ad5fd", + "code": "0xba70091b59edd96ce7f20e2d9e4d1a8ff78ed58cf842ef9d3c4945ad51bac5a84463531b582656b98d060e631b75e28c2993b7cc42d2faedbefd233392cd85febfcfc796f25e532dc8d3e923c03fc20e0aee82035abb3854bdecaf0c14f777f5fdbe17e4b45e906c090608f319c93802261400cfc4bccf7a0240a7a87faf0787bfd682e324f5d3e09c19c4aca68dd3ebef5b70719e211c0cab7f523b82e023a5f8fc1612348518ed777bc0250e14254f3b6b88ed58bcd55709a312a4d201e704d7bace496d479a6b3b5ac73c7fb8b832ab5cd6dc13d81d0ff67a6e79f594c43313913426d545a8000c0ac5d0c18679db9c0933e838942bfeadc26a52312d2b5c", + "address": "0x8b1b7e36d89a957b4f8935113702804cfc65cfc4", + "key": "0x1a2fc8f747f8fd4e384ec9dc259383cd532f5c476383c3dd176a436b93b37299" + }, + "0x8cea358A7a343ac1142AAab4690DEE0572d28bc1": { + "balance": "0", + "nonce": 1, + "root": "0xd40c66b99a645b9b203a05d314f80d49242d015fc1dc68bba7a83fa42822987d", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000017e": "017e", + "0x000000000000000000000000000000000000000000000000000000000000017f": "017f", + "0x0000000000000000000000000000000000000000000000000000000000000180": "0180" + }, + "address": "0x8cea358a7a343ac1142aaab4690dee0572d28bc1", + "key": "0x4e92c4f7b78ccc124d89bec7c7571034a98595ab1cb7a80092c2545d22cc694e" + }, + "0x9025d2F24A1a23CB2B093823e52e1f90DAC60a95": { + "balance": "0", + "nonce": 1, + "root": "0x5a937f34e712fd3198d9708e641383e8e45367b8fd1732b5d8a9f88835045af2", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000004a": "4a", + "0x000000000000000000000000000000000000000000000000000000000000004b": "4b", + "0x000000000000000000000000000000000000000000000000000000000000004c": "4c" + }, + "address": "0x9025d2f24a1a23cb2b093823e52e1f90dac60a95", + "key": "0x6e9e5296c3f88a6ee0f51246dc1237dec2b78db9938cd04f404f44bc0b70a479" + }, + "0x9344b07175800259691961298cA11c824e65032d": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x8e0388ecf64cfa76b3a6af159f77451519a7f9bb862e4cce24175c791fdcb0df", + "code": "0x60004381526020014681526020014181526020014881526020014481526020013281526020013481526020016000f3", + "address": "0x9344b07175800259691961298ca11c824e65032d", + "key": "0x2e6fe1362b3e388184fd7bf08e99e74170b26361624ffd1c5f646da7067b58b6" + }, + "0x9379ed0f7e4f0da2814dc50bbf895F239Be0e367": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x9379ed0f7e4f0da2814dc50bbf895f239be0e367", + "key": "0x89cbf9be493866f796305912943ca6b0991e8ad18a2f5b4a2847c72aaa021fff" + }, + "0x9380b994c5738F68312f0E517902da81f63cDCfa": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x9380b994c5738f68312f0e517902da81f63cdcfa", + "key": "0x50d83ef5194d06752cd5594b57e809b135f24eedd124a51137feaaf049bc2efd" + }, + "0x9539d142fbbdEa1A80522fEdfA5A8619b4fa1861": { "balance": "0", "nonce": 1, "root": "0x9eda8eb6ca03d7c4afe47279acc90a45d1b2ca6a11afd95206f8868d20520d06", @@ -3925,280 +3256,651 @@ "0x000000000000000000000000000000000000000000000000000000000000001f": "1f", "0x0000000000000000000000000000000000000000000000000000000000000020": "20" }, - "key": "0x600a7a5f41a67f6f759dcb664198f1c5d9b657fb51a870ce9e234e686dff008e" + "address": "0x9539d142fbbdea1a80522fedfa5a8619b4fa1861", + "key": "0x9a57b0a587fc060d23e9d43445f3f75c10c91121e850e44ef1fd11e47afd5ba7" }, - "0xe7b2ceb8674516c4aeb43979808b237656ab3b6b": { + "0x98618Af6804CBB0B95A2625850bdC390f3Df5792": { "balance": "0", "nonce": 1, - "root": "0xcd31ed5d5da79990afed0d993cb725c4e34dd97544b03466ed34212e42c28d68", + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1a78f610af853b8d5ead50bd031651dd1270a5b813d8b8bbe12be891d693bf48", + "code": "0xb2b734aa38ff5be8e3809aef093ad60f972a796d6f60e255580de9e9a1a5fb18bef76e95677125529feb51c7954bfde7834b036aab1e14449b02160892e908d960d9a2c4081113d70e03e5593f31ca97a5eb6efbf19cffdc881e02b429b9e44484284a16ccabc0709ac21718bc53daf6afa43ecd0fd1b02c884ad060803854db405765d7ae389012e16cc1e5275b26952f443a9ee40870dbc2cae0484b4929c8e1c54a86e002b6bdd7a5b8085479a79193c73096027f68ab35c38dc9cfed12090e9838fe1d2e639a62395f7e52a2d745fd5b0f7011b24ef0e937458897583a0c22872262be58395faccd44f164ce49ff825546056a0badb18b18b061da4f1238", + "address": "0x98618af6804cbb0b95a2625850bdc390f3df5792", + "key": "0x8e1a4d37ee935603b4bef1a0603bffd5f07b0c6a9b18ea4bb831d4fa6bc4e80d" + }, + "0x98f1772522fB7635C01709D834Df35F151Fd08eF": { + "balance": "0", + "nonce": 1, + "root": "0x2434bfc643ec364116cd71519a397662b20c52d1adcff0b830e80a738e19f30e", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x000000000000000000000000000000000000000000000000000000000000014e": "014e", - "0x000000000000000000000000000000000000000000000000000000000000014f": "014f", - "0x0000000000000000000000000000000000000000000000000000000000000150": "0150" + "0x00000000000000000000000000000000000000000000000000000000000000b8": "b8", + "0x00000000000000000000000000000000000000000000000000000000000000b9": "b9", + "0x00000000000000000000000000000000000000000000000000000000000000ba": "ba" }, - "key": "0x75d231f57a1a9751f58769d5691f4807ab31ac0e802b1a1f6bfc77f5dff0adbf" + "address": "0x98f1772522fb7635c01709d834df35f151fd08ef", + "key": "0x1b6dc4d3b5ec40115001f1d0225ddacec642f618d497090db5f88565b8be234c" }, - "0xe7d13f7aa2a838d24c59b40186a0aca1e21cffcc": { - "balance": "1000000000000000000000000000000000000", + "0x99D40A710cb552EAaee1599d4040055859b1610d": { + "balance": "0", + "nonce": 1, + "root": "0x9b3243375d54294b7f3e11b027fdfb57c63136fe58b679c0a227e2f55ad7c072", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000147": "0147", + "0x0000000000000000000000000000000000000000000000000000000000000148": "0148", + "0x0000000000000000000000000000000000000000000000000000000000000149": "0149" + }, + "address": "0x99d40a710cb552eaaee1599d4040055859b1610d", + "key": "0x946bfb429d90f1b39bb47ada75376a8d90a5778068027d4b8b8514ac13f53eca" + }, + "0x9DDDb8668AF4D3DC4746b64973d7961Cb7Ca83Fd": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x9dddb8668af4d3dc4746b64973d7961cb7ca83fd", + "key": "0xf251e6fdb71031f2b1cfc0e2189460c6b88783c30f5d8e84aa0bf5262b7064a5" + }, + "0x9Ef0201350e14E23DEFbace3Df6C0582F1B7eAA0": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0x9ef0201350e14e23defbace3df6c0582f1b7eaa0", + "key": "0x136a96313f35a3d9f3439a676c0780ca086c2638a6b92272afcc6e296b89935e" + }, + "0x9b3cf956056937Dfb6F9E3dc02e3979A4E421c0A": { + "balance": "0", + "nonce": 1, + "root": "0xce2f545355cdd2106ac32f9929d2a421f2b50fa224d450fdbd6ce592eeec1222", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000003f": "3f", + "0x0000000000000000000000000000000000000000000000000000000000000040": "40", + "0x0000000000000000000000000000000000000000000000000000000000000041": "41" + }, + "address": "0x9b3cf956056937dfb6f9e3dc02e3979a4e421c0a", + "key": "0xb1b2c1c59637202bb0e0d21255e44e0df719fe990be05f213b1b813e3d8179d7" + }, + "0x9bB981F592bC1f9c31dB67F30Bbf1FF44b649886": { + "balance": "0", + "nonce": 1, + "root": "0xd60ee4ad5abbe759622fca5c536109b11e85aa2b48c0be2aebf01df597e74dba", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000015d": "015d", + "0x000000000000000000000000000000000000000000000000000000000000015e": "015e", + "0x000000000000000000000000000000000000000000000000000000000000015f": "015f" + }, + "address": "0x9bb981f592bc1f9c31db67f30bbf1ff44b649886", + "key": "0x1ee7e0292fba90d9733f619f976a2655c484adb30135ef0c5153b5a2f32169df" + }, + "0x9c06979A58c4E331F355883d1e893D13e3b7F341": { + "balance": "0", + "nonce": 1, + "root": "0x209641d47d9d587d8c732197fc36a51c1d24948f632742d213d0cb8763c7edf7", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x00000000000000000000000000000000000000000000000000000000000001ec": "01ec", + "0x00000000000000000000000000000000000000000000000000000000000001ed": "01ed", + "0x00000000000000000000000000000000000000000000000000000000000001ee": "01ee" + }, + "address": "0x9c06979a58c4e331f355883d1e893d13e3b7f341", + "key": "0xa619a597342a62e6b3fbe3ab3d7933a82020342dd0f1520abfa4623d9bbbbb90" + }, + "0x9e59004e909fF011E5882332E421b6772E68ED10": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x2f69e37f59a31ef79d90459fccee2d365e354ad304c05e646cbf6b4a9f085eab", + "code": "0xb4c4e2b6245313ebc2e84fd30cd4004aef84bd2a40151a93462f49c26e7506fb2d24f5b2a624144cca8966ee8ebaaedd1ac3debcaece0f685b099077dfb2d70a0e75755c41adbb4f27053405d1410dcc6f39998c05961a8623aa6cb33b0be66f8195e934be8e1e1e67e36670679242f3eb3fe013d19203686902c1dc42dff3e49866e7eef0c92f888b29f2bed58ab872a91939249d76586c0b7412b6b577479e1d87c3377c62b76e969d2b0db015e24647df9fee4d414b11c6817618df8537f3098e5c8946c3f55aae04af8fe9c4589802eae2b11667f4dfa6883e23815c01edd65ecf137cd4f3b2d832c2d1201b08f864662ac72ecf52eb255eb7d0df1a1db6", + "address": "0x9e59004e909ff011e5882332e421b6772e68ed10", + "key": "0x3897cb9b6f68765022f3c74f84a9f2833132858f661f4bc91ccd7a98f4e5b1ee" + }, + "0xA355a21C36De6b7218d21e119b60676b176704fc": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x733cb31bbb18e7b961481250f0ba1360594dc64d3e718fe7de2ec90d34c6098e", + "code": "0x1e294673971cfca694eb2b530effc46ed1a0e6951dc278025e8cc33a1b7920173741728d05b0ba6fc6794269449728dd17f14bc1b31e69610ecc42912ff0f4d20e2fb4e3c2ec2260f93ea3216765fbac4298665bf7377032a021f529b2e2d5222a16a5eea9d64b50e6e0c5b94e99bd7223c40366b3c0a4ea4fe6ffa3e3a0e6e1ed85464681cf13f1b75d78e7f27dcf6f81bcb07a6f89e5530327fe310424559eaa4c866d26f9e82356895b445c2e5df46dc3b43ac6c8b2c240632dc8221f3a766c72695df125cf92f136bb13fddea02c359a434c7ac841202aefd428779c63f889b65a10a48c13fa4f1a7fd615279159853638195bb5622212415f85f7b734e0", + "address": "0xa355a21c36de6b7218d21e119b60676b176704fc", + "key": "0x958facc25352ac71b19beae99e016548fa24d959f5e766b4f9348cd15b65d565" + }, + "0xA6a54695341F038ad15e9e32f1096f5201236512": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xa6a54695341f038ad15e9e32f1096f5201236512", + "key": "0xa87387b50b481431c6ccdb9ae99a54d4dcdd4a3eff75d7b17b4818f7bbfc21e9" + }, + "0xAE6883d7bEE5Ac3a2B1B2687C64309d3a168fBE9": { + "balance": "0", + "nonce": 1, + "root": "0xaff437d2f3b4a919f175d26053aae80fd53ae4901a9007925d621faa5d3024e8", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000202": "0202", + "0x0000000000000000000000000000000000000000000000000000000000000203": "0203", + "0x0000000000000000000000000000000000000000000000000000000000000204": "0204" + }, + "address": "0xae6883d7bee5ac3a2b1b2687c64309d3a168fbe9", + "key": "0x0e85ef0d4474e7938384fefcd97e2f3603fb0fa1d3efb98eddfa5ffff6679cc4" + }, + "0xB565fF21AF37E44a5E8BC217D6B43C86419CF0F9": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xb565ff21af37e44a5e8bc217d6b43c86419cf0f9", + "key": "0x66192e4c757fba1cdc776e6737008f42d50370d3cd801db3624274283bf7cd63" + }, + "0xBAC9D93678C9B032c393a23e4c013E37641AD850": { + "balance": "0", + "nonce": 1, + "root": "0xfb79021e7fa54b9bd2df64f6db57897d52ae85f7c195af518de48200a1325e2c", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x00000000000000000000000000000000000000000000000000000000000000ef": "ef", + "0x00000000000000000000000000000000000000000000000000000000000000f0": "f0", + "0x00000000000000000000000000000000000000000000000000000000000000f1": "f1" + }, + "address": "0xbac9d93678c9b032c393a23e4c013e37641ad850", + "key": "0x8a8266874b43f78d4097f27b2842132faed7e7e430469eec7354541eb97c3ea0" + }, + "0xBd079b0337A29cCCD2EC95b395Ef5c01E992b6a5": { + "balance": "0", + "nonce": 1, + "root": "0xe478b9c7df7d530ab039ef863b6ee52df4c726c17ac895122343b51c45d5f18e", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000029": "29", + "0x000000000000000000000000000000000000000000000000000000000000002a": "2a", + "0x000000000000000000000000000000000000000000000000000000000000002b": "2b" + }, + "address": "0xbd079b0337a29cccd2ec95b395ef5c01e992b6a5", + "key": "0xf0877d51b7712e08f2a3c96cddf50ff61b8b90f80b8b9817ea613a8a157b0c45" + }, + "0xC7B99a164Efd027a93f147376Cc7DA7C67c6bbE0": { + "balance": "1000000000000000000000000500000000007", "nonce": 0, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", + "key": "0x8e11480987056c309d7064ebbd887f086d815353cdbaadb796891ed25f8dcf61" + }, + "0xD089C853b406be547d8e331D31CbD5C4D472A349": { + "balance": "0", + "nonce": 1, + "root": "0xa33259a022cf713371b64cf9305a032e8bf31d4245fe00f5dca4aaa19967abb4", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000097": "97", + "0x0000000000000000000000000000000000000000000000000000000000000098": "98", + "0x0000000000000000000000000000000000000000000000000000000000000099": "99" + }, + "address": "0xd089c853b406be547d8e331d31cbd5c4d472a349", + "key": "0x389093badcaa24c3a8cbb4461f262fba44c4f178a162664087924e85f3d55710" + }, + "0xD68D1A62f58c6B8cceF66B50228Bb9163784F355": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xd68d1a62f58c6b8ccef66b50228bb9163784f355", + "key": "0xf7eaa0ae3d9e339e65e019d913513f53f3175e0b35c21f171cc04e6bb06e8c13" + }, + "0xD917458e88a37B9aE35F72d4CC315ef2020b2418": { + "balance": "0", + "nonce": 1, + "root": "0x1b9e47810d5392418d38571a39fa5984e48e0f03b932d8b98f6aa771ccad65f2", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000131": "0131", + "0x0000000000000000000000000000000000000000000000000000000000000132": "0132", + "0x0000000000000000000000000000000000000000000000000000000000000133": "0133" + }, + "address": "0xd917458e88a37b9ae35f72d4cc315ef2020b2418", + "key": "0x4c2765139cace1d217e238cc7ccfbb751ef200e0eae7ec244e77f37e92dfaee5" + }, + "0xD9D4095509b1ea9aDde0E42D4eed8A4bC01ce4F9": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xbbcdc1260a8c1207ed4df8f6aa53d86b13407470023e3d529bb2d34ee71739ef", + "code": "0x505a94e92091157a2b6c32cdb529e4e0fff70a56f15fdc98e76e3995f7d83843d5db31e9e7c32143fe3af51e3315d4786b187de82f0dfa39162c39200bde0914635ba9e622461ba1e5f620ca05d0e3903d2be7dd66af8da9796c6b26acd3b499fe480de640588828f4a109d5f0bce8c49ea257ed6d39a78cefb2cb82699ced8d0b68115d5c2b6ccaf79db212002dcc3d52944fdf04f672a09f6629e434f2646687ab7a5a3e42e9ce80c9bfd4beffdff114c758e71396b4ddbbdcc38c72c3a00cbf662de3bbc8b6d7b5786261d3e6f5e282baa7fdbd39fa16fa0c27c43972cc6e10e1d521b80b6a244f273da5d76441c35c86907c122c4d9bb88ab0ae851ea3f4", + "address": "0xd9d4095509b1ea9adde0e42d4eed8a4bc01ce4f9", + "key": "0x38978834c603c45c873fa267fe1b541694e9e55e9c59abd0c22489cd9eaef823" + }, + "0xDB25388D92FA7D824178bc472C0a5FD84A69d18D": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xdb25388d92fa7d824178bc472c0a5fd84a69d18d", + "key": "0x9a36e49d6fa789abc112272965ccb529476471bc9584caf51bbf38cf818ecf57" + }, + "0xDD9ee108e8d5D2E8937E9FD029eC3A6640708af0": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xdd9ee108e8d5d2e8937e9fd029ec3a6640708af0", + "key": "0x2a39afbe88f572c23c90da2d059af3de125f1da5c3753c530dc5619a4857119f" + }, + "0xDE1c2fC2e4Ee50F61a0Ee3758Bb67Bc468467F03": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x6ce8bcf63e7a26264045680ee93464c00c1029a197aacc749391b7a840cc8697", + "code": "0x24259e866b89e445290f514548cfa7341e867e1c75b75575d8008246d6bf88796e0cbff4014bd643fbb0707f5e2c1ad686153dae9f96a33de90a5cb2c73f01934107dbec03e25a3a7041ae16c199ebe0c15cdfc958612c5bc8a87d743449bee7e7b26963c6a46bc669ee69f5ec3ddaa2b4dba8fb6c66bbf247f3096d559f5641849d57e96537ad7e37a5709b12dd8ea54383e2864ba1d0d83e2ffbde7f8a5fb5f6ddcb15ef525982aac03ef65faf2cb3fcdd8eb6b2a2b58c6bc2acd57989ebb44362cdde8131eaf20d98617619b09146ce4f5f53fe563db99ef97b050183da81c5072f4eee335da8bb992dd71959a7534cd43bcc582c57ed9631abb2f4d7bcc4", + "address": "0xde1c2fc2e4ee50f61a0ee3758bb67bc468467f03", + "key": "0x0243011ec33679195dffcf94a02eed0e26b589f14af470e55e798647b537c46f" + }, + "0xDeF9100B4510C563B2532EDDfC5dCDc82bb541f2": { + "balance": "0", + "nonce": 1, + "root": "0xd45ccd3dd6bb0efbcc59566edbba5873ffadaa694d76582ad5b876b88f39b461", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000008c": "8c", + "0x000000000000000000000000000000000000000000000000000000000000008d": "8d", + "0x000000000000000000000000000000000000000000000000000000000000008e": "8e" + }, + "address": "0xdef9100b4510c563b2532eddfc5dcdc82bb541f2", + "key": "0x9b6e7bfcd9347b45c94947acb6ddd3df4d228807ea09100b7a60b8c1b2aede5a" + }, + "0xE06751015cf69396708198F9Fd3fAC98367847ae": { + "balance": "0", + "nonce": 1, + "root": "0xd39ad83d4fc3df3ce208b6c0779e4d1c0138867bdd0a6ba4e49ccb45419e540d", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000013c": "013c", + "0x000000000000000000000000000000000000000000000000000000000000013d": "013d", + "0x000000000000000000000000000000000000000000000000000000000000013e": "013e" + }, + "address": "0xe06751015cf69396708198f9fd3fac98367847ae", + "key": "0x0610ba7a05912ec56deae88974bcc177dbce70b079adc9db6212f83a093a91c2" + }, + "0xE153E75b139632f5d13F19d5C66579D5d6813259": { + "balance": "0", + "nonce": 1, + "root": "0xff687feaf8718db6ab0fc7f8d1e2cfd9ef45928488fc3d578477cdfdcc51dd09", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x00000000000000000000000000000000000000000000000000000000000001f7": "01f7", + "0x00000000000000000000000000000000000000000000000000000000000001f8": "01f8", + "0x00000000000000000000000000000000000000000000000000000000000001f9": "01f9" + }, + "address": "0xe153e75b139632f5d13f19d5c66579d5d6813259", + "key": "0x59aef4df4fe449a1f7048fe2bcb680f4591eae75f45efe3dfca5febfe54d38d8" + }, + "0xE3A71B4CAf54dF7d2480743C5A6770A1a5a9BcDa": { + "balance": "0", + "nonce": 1, + "root": "0xd9302d64a423861c7b3ffa4e25dd32c407f472bda0e75c4da719b77a4c9d7424", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x000000000000000000000000000000000000000000000000000000000000011b": "011b", + "0x000000000000000000000000000000000000000000000000000000000000011c": "011c", + "0x000000000000000000000000000000000000000000000000000000000000011d": "011d" + }, + "address": "0xe3a71b4caf54df7d2480743c5a6770a1a5a9bcda", + "key": "0xe4d9c31cc9b4a9050bbbf77cc08ac26d134253dcb6fd994275c5c3468f5b7810" + }, + "0xE43cE33cdB88A2EFE8A3d652bfB252fd91A950a7": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x037e70d89f4b730aac959986dbbfe0af1a286ddb31e1de05bcee64135e5c17cb", + "code": "0xeef53c6ca945792f947138460881b8ce441c90705cebd2ac63082b1a9dbb6d1ef15659e3492137bbe7b2a548a5ff636574ffc69b4cd7e9919fa8f0121846b7587f8a4e01196c8d8e8d7fab5763f17afdd953e7fd375125594fe15f4147baa966b31f12b3ea8a692474f7a878f34a0093e7342405a33cd6974e35402ae55fdcccdf0fed250aa631da36a99e614c87fd768ef2946f5a4a62890303785aab8ccc70c9aadf72d8055a8681a6e3890308b25746e822fb40031daa81d0d225a722d0fbb0a0135deb29f445269723c8cde0b5434bcd83acff45693494d6a48dfe22d505d01e0763a645edda4d609886f87b822dc86d428442ef174eb0085b4a201be63d", + "address": "0xe43ce33cdb88a2efe8a3d652bfb252fd91a950a7", + "key": "0xc157e0d637d64b90e2c59bc8bed2acd75696ea1ac6b633661c12ce8f2bce0d62" + }, + "0xE52C0F008957444c48Eba77467eaf2b7C127e3C5": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1973f7c92cddb2e8e1b1a679e0ccc4228c832fa0881e126e99d8c153768fe417", + "code": "0x23aec33011cec136936404546e8d71610b1ea813717b1b6bf3b77b689326a34bff8631e720139e221f6f7436289600a293ec800074eefb6074c9c4d3d71451d44f3b95b4e5f87ebaefd8697e1beeac39c49315154dac40afc4471c173e106006158cf96e390593ec3d9db70f55562909ef65f4603e50b9bf4a3df75ee2795f3069934b3c578097dd99f0cb0d2c04136fd8095c48557144cc40a978589e45b612072a01774dff6b43d7101e6ad7d329fe9af3407ec1356a898458310d3114a95c20874b0c906c478f1952ec7ffbf9ccb55019a08fb7b7fe98adcb0bbcfe4c582b3173396d1c155446a89455c4997640738bf81f11b8e7aa00d59a627e170c021f", + "address": "0xe52c0f008957444c48eba77467eaf2b7c127e3c5", + "key": "0xb888c9946a84be90a9e77539b5ac68a3c459761950a460f3e671b708bb39c41f" + }, + "0xE7d13f7Aa2A838D24c59b40186a0aCa1e21CffCC": { + "balance": "1000000000000000000000000300000000004", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xe7d13f7aa2a838d24c59b40186a0aca1e21cffcc", "key": "0xec3e92967d10ac66eff64a5697258b8acf87e661962b2938a0edcd78788f360d" }, - "0xe82c38488eded9fb72a5ed9e039404c537f20b13": { + "0xED61c537F1B4f454c46B2352069Fa6b42623C110": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7a2464bc24d90557940e93a3b73308ea354ed7d988be720c545974a17959f93f" + "address": "0xed61c537f1b4f454c46b2352069fa6b42623c110", + "key": "0xfbf3a1231e6625c304d124d07affe93eb8815d22b5fd75d546c09dc1cfda9e67" }, - "0xe920ab4e34595482e98b2c0d16be164c49190546": { + "0xF9062429a0c38F2886bbc72EC59Eb41041caE478": { "balance": "0", "nonce": 1, "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd623b1845175b206c127c08046281c013e4a3316402a771f1b3b77a9831143f5" + "address": "0xf9062429a0c38f2886bbc72ec59eb41041cae478", + "key": "0x3de2ace05e9ea0f0318554327d9809e6706eadd51f104b1235f40712070503e5" }, - "0xe99c76a6c3b831a926ab623476d2ec14560c09b4": { + "0xFb7b49bc3178263F3a205349c0E8060F44584500": { "balance": "0", "nonce": 1, - "root": "0x0fd8e99b1b4ab4eb8c6c2218221ae6978cc67433341ed8a1ad6185d34fa82c61", + "root": "0x5b8cce34b1c8ca497abd9d4baa011f924fabb467a2d6617c9cfd83a2c32a1aee", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000014": "14", - "0x0000000000000000000000000000000000000000000000000000000000000015": "15", - "0x0000000000000000000000000000000000000000000000000000000000000016": "16" + "0x0000000000000000000000000000000000000000000000000000000000000189": "0189", + "0x000000000000000000000000000000000000000000000000000000000000018a": "018a", + "0x000000000000000000000000000000000000000000000000000000000000018b": "018b" }, - "key": "0x6641e3ed1f264cf275b53bb7012dabecf4c1fca700e3db989e314c24cc167074" - }, - "0xe9b17e54dba3344a23160cb2b64f88024648c53e": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xb4f179efc346197df9c3a1cb3e95ea743ddde97c27b31ad472d352dba09ee1f5" - }, - "0xebe708edc62858621542b7354bb478228eb95577": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7bff1b6b56891e66584ced453d09450c2fed9453b1644e8509bef9f9dd081bbb" - }, - "0xebf37af41b6d7913aed3b9cc650d1e8f58a3d785": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x209b102e507b8dfc6acfe2cf55f4133b9209357af679a6d507e6ee87112bfe10" - }, - "0xeda8645ba6948855e3b3cd596bbb07596d59c603": { - "balance": "1000000000000000000000000000000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xabd8afe9fbf5eaa36c506d7c8a2d48a35d013472f8182816be9c833be35e50da" - }, - "0xef6cbd2161eaea7943ce8693b9824d23d1793ffb": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xce732a5e3b88ae26790aeb390a2bc02c449fdf57665c6d2c2b0dbce338c4377e" - }, - "0xf031efa58744e97a34555ca98621d4e8a52ceb5f": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x00748bacab20da9ae19dd26a33bd10bbf825e28b3de84fc8fe1d15a21645067f" - }, - "0xf068ae4089a66c79afe47d6e513f718838d8f73f": { - "balance": "0", - "nonce": 1, - "root": "0x72c89221daedccdd3fbba66c1b081b3634ce89d5a069be97ff7832778f7b023a", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000003c": "3c", - "0x000000000000000000000000000000000000000000000000000000000000003d": "3d", - "0x000000000000000000000000000000000000000000000000000000000000003e": "3e" - }, - "key": "0x37310559ceaade42e45b3e3f05925aadca9e60aeeb9dd60d824875d9e9e71e26" - }, - "0xf0a279d2276de583ebcd7f69a6532f13349ad656": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x11eb0304c1baa92e67239f6947cb93e485a7db05e2b477e1167a8960458fa8cc" - }, - "0xf0a5f15ef71424b5d543394ec46c46bfd2817747": { - "balance": "0", - "nonce": 1, - "root": "0xbefe55b606a865c3898ec2093bd160b37c3976011516f43736cac2a9a7ecd4ca", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000000e0": "e0", - "0x00000000000000000000000000000000000000000000000000000000000000e1": "e1", - "0x00000000000000000000000000000000000000000000000000000000000000e2": "e2" - }, - "key": "0xdbea1fd70fe1c93dfef412ce5d8565d87d6843aac044d3a015fc3db4d20a351b" - }, - "0xf14d90dc2815f1fc7536fc66ca8f73562feeedd1": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xabdc44a9bc7ccf1ce76b942d25cd9d731425cd04989597d7a2e36423e2dac7ee" - }, - "0xf16ba6fa61da3398815be2a6c0f7cb1351982dbc": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x728325587fa336e318b54298e1701d246c4f90d6094eb95635d8a47f080f4603" - }, - "0xf1fc98c0060f0d12ae263986be65770e2ae42eae": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xca7ad42d3c4fe14ddb81bf27d4679725a1f6c3f23b688681bb6f24262d63212f" - }, - "0xf4f97c88c409dcf3789b5b518da3f7d266c48806": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x84c7ee50e102d0abf5750e781c1635d60346f20ab0d5e5f9830db1a592c658ff" - }, - "0xf5347043ae5fca9412ca2c72aee17a1d3ba37691": { - "balance": "0", - "nonce": 1, - "root": "0xf390264acaf1433c0ea670b2c094a30076641469524ae24f5fddc44e99c5b032", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x000000000000000000000000000000000000000000000000000000000000004f": "4f", - "0x0000000000000000000000000000000000000000000000000000000000000050": "50", - "0x0000000000000000000000000000000000000000000000000000000000000051": "51" - }, - "key": "0xa5541b637a896d30688a80b7affda987d9597aac7ccd9799c15999a1d7d094e2" - }, - "0xf57fd44ccea35d9c530ef23f3e55de2f6e5415bf": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x6d4162ce16817e46fa2ddc5e70cee790b80abc3d6f7778cfbaed327c5d2af36c" - }, - "0xf6152f2ad8a93dc0f8f825f2a8d162d6da46e81f": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x7e839d9fd8a767e90a8b2f48a571f111dd2451bc5910cf2bf3ae79963e47e34d" - }, - "0xf61ac2a10b7981a12822e3e48671ebd969bce9c2": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xbfe5dee42bddd2860a8ebbcdd09f9c52a588ba38659cf5e74b07d20f396e04d4" - }, - "0xf7eaadcf76ffcf006a86deb2f17d0b8fe0b211a8": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x1dff76635b74ddba16bba3054cc568eed2571ea6becaabd0592b980463f157e2" - }, - "0xf83af0ceb5f72a5725ffb7e5a6963647be7d8847": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x662d147a16d7c23a2ba6d3940133e65044a90985e26207501bfca9ae47a2468c" - }, - "0xf8d20e598df20877e4d826246fc31ffb4615cbc0": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xa248850a2e0d6fe62259d33fc498203389fa754c3bd098163e86946888e455bd" - }, - "0xf91193b7442e274125c63003ee53f4ce5836f424": { - "balance": "0", - "nonce": 1, - "root": "0xb25f9e4f6f913a4a1e8debf7d4752bfa521d147bb67c69d5855301e76dd80633", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001d5": "01d5", - "0x00000000000000000000000000000000000000000000000000000000000001d6": "01d6", - "0x00000000000000000000000000000000000000000000000000000000000001d7": "01d7" - }, - "key": "0xbfe731f071443795cef55325f32e6e03c8c0d0398671548dfd5bc96b5a6555c0" - }, - "0xf997ed224012b1323eb2a6a0c0044a956c6b8070": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xbcebc35bfc663ecd6d4410ee2363e5b7741ee953c7d3359aa585095e503d20c8" - }, - "0xfb7b49bc3178263f3a205349c0e8060f44584500": { - "balance": "0", - "nonce": 1, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xfb7b49bc3178263f3a205349c0e8060f44584500", "key": "0xa03fe040e4264070290e95ffe06bf9da0006556091f17c5df5abaa041de0c2f7" }, - "0xfb95aa98d6e6c5827a57ec17b978d647fcc01d98": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xf63360f8bb23f88b0a564f9e07631c38c73b4074ba4192d6131336ef02ee9cf2" - }, - "0xfcc8d4cd5a42cca8ac9f9437a6d0ac09f1d08785": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xd3443fa37ee617edc09a9c930be4873c21af2c47c99601d5e20483ce6d01960a" - }, - "0xfd5e6e8c850fafa2ba2293c851479308c0f0c9e7": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0x1c248f110218eaae2feb51bc82e9dcc2844bf93b88172c52afcb86383d262323" - }, - "0xfde502858306c235a3121e42326b53228b7ef469": { - "balance": "1", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe3d7213321be060ae2e1ff70871131ab3e4c9f4214a17fe9441453745c29365b" - }, - "0xfe1dcd3abfcd6b1655a026e60a05d03a7f71e4b6": { - "balance": "100000000000", - "nonce": 0, - "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", - "key": "0xe31747e6542bf4351087edfbeb23e225e4217b5fa25d385f33cd024df0c9ae12" - }, - "0xfe96089d9b79f2d10f3e8b0fb9629aeb6cc7cde6": { + "0xa6515a495Ec7723416665EBb54fC002BF1e9A873": { "balance": "0", "nonce": 1, - "root": "0xcf2123d110997f426821d3e541334e43fdd6b5286c3c33252c24b5f8aafc7aa2", + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x4a027c1ef8411fa885c9fe4e5a504ec57076b475c72c4b0d150b8d97906de706", + "code": "0x91d04e206f89145185d7c0a82618aa78fe710bc8a1b4b414b377926cf5e3a66be28502ad67d33d7274b03e765dd18f1a1ab4ba1c827c6d3e7a0d3ca492e6b46315531e88bae16d971c335931052549d408d7d05a38b4dacc091f6db9dbbb6ddc38d21990164d4d7df1f1c3adadd435da81121ed3ccf04d07098021ef81b4663045d505cb6581b7f15e33d93b5bbad62cb60fb8a720b633d8cb1906954b0943f218fe2baba04b04b843cd138489dc125d2854aec75ebb8a449c914ba035cd57fe923334cd90d34656991c6938c9e0b8aa7a8fca68f889521f05af1a847e16ec0dd52427a773bf62425ab36cd77fb888038dcf97aeef30aa680c9fcd289221ae32", + "address": "0xa6515a495ec7723416665ebb54fc002bf1e9a873", + "key": "0xbbdc59572cc62c338fb6e027ab00c57cdeed233c8732680a56a5747141d20c7c" + }, + "0xa956ca63bf28E7dA621475D6b077dA1AB9812b3A": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xa956ca63bf28e7da621475d6b077da1ab9812b3a", + "key": "0xaad7b91d085a94c11a2f7e77dc95cfcfc5daf4f509ca4e0c0e493b86c6cbff78" + }, + "0xaD9Dad8a45e691B45a09e2CE5a88594A08f4744A": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xad9dad8a45e691b45a09e2ce5a88594a08f4744a", + "key": "0x90c9be68ba7502086f74ff43be0a2f2dff9baa9073fbccf73690addc0d93ee20" + }, + "0xaF17b30f5Ab8e6a4D7A563bDB0194F3E0bD50209": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xaf17b30f5ab8e6a4d7a563bdb0194f3e0bd50209", + "key": "0x26ce7d83dfb0ab0e7f15c42aeb9e8c0c5dba538b07c8e64b35fb64a37267dd96" + }, + "0xaa53Ff4bb2334Faf9f4447197ef69c39c0BB1379": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xaa53ff4bb2334faf9f4447197ef69c39c0bb1379", + "key": "0xed263a22f0e8be37bcc1873e589c54fe37fdde92902dc75d656997a7158a9d8c" + }, + "0xaaAF6A159065e1df8848bAD2123ce201f914651f": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xaaaf6a159065e1df8848bad2123ce201f914651f", + "key": "0x77f9408520acfbb12b62b72ca755db32798673aa3f13a27d4d72b5e5d9dc394d" + }, + "0xb42f46FA28a45E5d7ED2C6FBcf264be09A84b35d": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xf4015a92c21a43971b9daccd6b117d4bda8d0352cb2dffa3d2c0efa501043c1a", + "code": "0xa64ecc77bab92b6155b22af00b12afb654597705e4fcedbdecf5dc7272cb0f1f27a10e596b57a3dae1dab1396485571e7fc51fd56683e8c6f8517abac4c25fbeff399588cfa8d511a211e40c93169611693b7927d66122c83d455700805304135dd20ad87799fcce6db776139c19c898b9fa778865daa59dbe0bcba6f687140a6f8d38651f1dcccb2ffd8cee889c99e454fc3ecb2116512ff23076dc2d265910b2ab2ee89b347143724a865a498c0e338ae104e581dbd5f935efa1f13c842808eed4ee5aa0ba661a4be59fe47e33a2878d27cbc9c92c7053456f79d7567252f05d4e160575fee9c3345b17a5540abdd97c833048d80099370b0a86e8fdb4ca4b", + "address": "0xb42f46fa28a45e5d7ed2c6fbcf264be09a84b35d", + "key": "0x8eaa3c641bf0bced203401b48cad74dc2e5b5eadab6b21a275a0c90a226ced77" + }, + "0xb5435eFdaf27d2d95A4074d8a202Fe8605e93bc6": { + "balance": "0", + "nonce": 1, + "root": "0x50c6f81d76e16573b6164ad984d3383e480986fb380b3b49aeb5ded831297fe2", "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", "storage": { - "0x00000000000000000000000000000000000000000000000000000000000001d0": "01d0", - "0x00000000000000000000000000000000000000000000000000000000000001d1": "01d1", - "0x00000000000000000000000000000000000000000000000000000000000001d2": "01d2" + "0x0000000000000000000000000000000000000000000000000000000000000060": "60", + "0x0000000000000000000000000000000000000000000000000000000000000061": "61", + "0x0000000000000000000000000000000000000000000000000000000000000062": "62" }, - "key": "0xbf632670b6fa18a8ad174a36180202bfef9a92c2eeda55412460491ae0f6a969" + "address": "0xb5435efdaf27d2d95a4074d8a202fe8605e93bc6", + "key": "0x7d3eeccfd59fb913b7c1da576a38811506589cb0c082898306ac97727104a41d" + }, + "0xb609BC528052Bd9669595a35f6eB6A4d7A30AC3D": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1df52e345118c81b3e417faae2407169b7143b97665088704492ebe68918af5b", + "code": "0xb6c77d91e1853c9460797543e6950962a973fa1ff748bd1983124d001970f0fe86752f6f10cf905e418968184a6649df48e5bb4b03fe0c6c30d4a92846800ae5120d6850bf2577eddbd2ee4d37824e28eb8583bd541f524a671400c5a7a4d0d343101321f77bc643f5acb4f9e125b12553e936073cee8dc5591c518fbdd9b31bfd12ab6661c66aa507572bb762941842d549de49dae1e273c6eff4353793382663751fa9514f6f7fc44151fc96fb391df328691d6b6a3752c0e99a8013ceca8537ce7393bde93f10df15acd9635be2b3c297dc27a2b26e7c8a093e1e7b56ff6c46d267957117ed5d4464f4be9f8d0298d446fb30aa03ae79a281755983f162ef", + "address": "0xb609bc528052bd9669595a35f6eb6a4d7a30ac3d", + "key": "0xe6388bfcbbd6000e90a10633c72c43b0b0fed7cf38eab785a71e6f0c5b80a26a" + }, + "0xb911ABEEaD298d03C21c6C5fF397Cd80EB375D73": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xb911abeead298d03c21c6c5ff397cd80eb375d73", + "key": "0x873429def7829ff8227e4ef554591291907892fc8f3a1a0667dada3dc2a3eb84" + }, + "0xbA015A43CbAD870109287840657E509A8341430a": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x1d14dc1aad6545eccef12200b1d83eeccb7348e9efd37e3746547dc73319afcf", + "code": "0x6e114c97b74d78d3fc0453a7d40bb97c3b4da8bb89f0980f5e4234e1f334ec84d4fbf7701c97d78140335cb7a734885ddc620514a15e05dbfac5539c2e57005b4b399fdd2bd107baa82b219995c39b6fc0ea647f084bf576820030b40ec5eb1cc5a384a96c46160234a4c0a6841ffd094db428a8c4daf7fd60b8b3a2ec664beb2e4a5db9f6476a273a6466f6797062bb465d865a212e1a73b871f554b9505f849b837c8b3dd4ff54aa4bc7a8e72175cdf3090b5f77b8bbf2a981c389876ba34efc97c68684fd6376bbc41389aefdca942921a4974c57e664af0fefd08944deed5a7db4128d556fcc54111e0c2d693821e2cc01fc3dcce8e3a8e72c6393e2e68c", + "address": "0xba015a43cbad870109287840657e509a8341430a", + "key": "0xe49c3e4a107c2ab2bb5eb9f7830765501c0d2ba62d3bbdd3893ad2c6c7988e1a" + }, + "0xbA28562EAec75C2a24AddcdcB48b652a1D3d796a": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xba28562eaec75c2a24addcdcb48b652a1d3d796a", + "key": "0xf4f027863d66e0e04cac2d1b0bab3ce723d96b75cba02adfd94ec1aaac5f2e4f" + }, + "0xbE2b071590A1AEdbAe740BdA19589961eA8b90cb": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xbe2b071590a1aedbae740bda19589961ea8b90cb", + "key": "0x913a945d006f413415a63ff0e57fd2fad9ffbfe8857259722a0151b119f95e8e" + }, + "0xc672A4A5736BF99939A58C779E8574426ec2cb51": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x75de76446047b5ca099fe7a60a63ca86f78a280755e4b047d9e0f6ab5a3c8768", + "code": "0x03a2399dbeda27cb7b00f2bfdc46f625dc0d6ae1d1ae296eec64981420d7379f0f3712e63236af36733b72c796625945c9773de445465c4fc67079d0b2e58274ef975306a7f41285be2b1dbd58511cc28e1ba38da8aa9340702e3ef450eb792d74a58ce557b85901a0b85724f38fce3ea8b9f9a3989c57d19c477401a276956ceab7b9199383d8854ef3a3f8fee3f1e19d8bfc85e865c3273d04fc662b1ce3bdc3aa7b16422e3d10217b011900f49bacef88cb7c2a404a290e330e33c4bcfaeea29fc3afaacd35a28d15a491bc01bca5199d6323fa7cbb82b966837ee0fcb0c3a879e17a65faef645fad8f5e188dd2ff408303922ad6e8d1183345917dabbe25", + "address": "0xc672a4a5736bf99939a58c779e8574426ec2cb51", + "key": "0xb7ff380fe56a4b74a8253a904b912204c0421a68d57b0c2251eac54ee7d1edf3" + }, + "0xcCF0b963A645abe7b67Aa6E95AEA73FF9E0576CC": { + "balance": "0", + "nonce": 1, + "root": "0x54d96c4ece0ea7b8fb4020944003566809100c43a61883d7edaf155e10e9c7cc", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x00000000000000000000000000000000000000000000000000000000000001e1": "01e1", + "0x00000000000000000000000000000000000000000000000000000000000001e2": "01e2", + "0x00000000000000000000000000000000000000000000000000000000000001e3": "01e3" + }, + "address": "0xccf0b963a645abe7b67aa6e95aea73ff9e0576cc", + "key": "0x2c5f586f46056bc6b891f7ed71cbe787e6f4839646e44d67e5c0bd737ff7154b" + }, + "0xd48171b7166F5E467AbCbA12698dF579328e637D": { + "balance": "0", + "nonce": 1, + "root": "0x944f095afbd1383e5d0f91ef02895d398f4f76fdb6d86adf4765f25bdc304f5f", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000081": "81", + "0x0000000000000000000000000000000000000000000000000000000000000082": "82", + "0x0000000000000000000000000000000000000000000000000000000000000083": "83" + }, + "address": "0xd48171b7166f5e467abcba12698df579328e637d", + "key": "0x188111c233bf6516bb9da8b5c4c31809a42e8604cd0158d933435cfd8e06e413" + }, + "0xd778467Da3D250d74009a0b24A77ec73fE459164": { + "balance": "0", + "nonce": 1, + "root": "0xf120c3cc3618eef211a028a99d9f010cc498a79097042dff780391ec3563ad51", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x00000000000000000000000000000000000000000000000000000000000001d6": "01d6", + "0x00000000000000000000000000000000000000000000000000000000000001d7": "01d7", + "0x00000000000000000000000000000000000000000000000000000000000001d8": "01d8" + }, + "address": "0xd778467da3d250d74009a0b24a77ec73fe459164", + "key": "0x6862961bf74f98147405d296a8f9d9147a02013a4bebb049a171715de1a58963" + }, + "0xd803681E487E6AC18053aFc5a6cD813c86Ec3E4D": { + "balance": "1000000000000000000000000500000000007", + "nonce": 0, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", + "key": "0xe5302e42ca6111d3515cbbb2225265077da41d997f069a6c492fa3fcb0fdf284" + }, + "0xd9c035E32F69DaB32F382F4ECA08ac316CB4fa4d": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x91490c55fe9d257ab92ee7c14d7614e4ce7bac6f9bb136427a3c67df010b8761", + "code": "0x941a419570a1ac7361c777110e70919980aa20af68c061451b272502d1c7bf877d3fa8f5cca21f050296be6b1a18825e0663c16cf7abb5263fd97a7042f1a7019aead984481533ddc3e1804cd415af4859e5a9209b3e78027e9504b13edc4bf9726c0239d8143fcc34d30ac6ef3f6e3a51e31b0bb7a03ff559c40434071fd48d080207eb7481f12bdcb87a64d5eef86a69742a6e85ca5bc6cbd6493c6f955c00563116b304f60034ae594a61486cd49541585ff56c84c5873e3fccb3f79c188f93526f8eb108615ff025803e1a91a242013880017345c667ca5624ba4a4111579881b6eeebb8651e1bf8e3463186d9b28eb3683206809622f3c6655c5386ebe1", + "address": "0xd9c035e32f69dab32f382f4eca08ac316cb4fa4d", + "key": "0x52ee830cbf07cbdfef612efc7475e16c6988d86442e32f31308d7c52d509a394" + }, + "0xdeD53dD3E21f2A1F750807aFeF8c31053485bb28": { + "balance": "0", + "nonce": 1, + "root": "0x86d6eca3c02c7902d9cb8308a979bb0328be4246d716a06a40304ae5fc4e8e74", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000110": "0110", + "0x0000000000000000000000000000000000000000000000000000000000000111": "0111", + "0x0000000000000000000000000000000000000000000000000000000000000112": "0112" + }, + "address": "0xded53dd3e21f2a1f750807afef8c31053485bb28", + "key": "0x323982bb110cddfe49cc86eea33d47fa410394e47cd185814cf8e3d7573b216a" + }, + "0xe2FF4E7E4A28D327B030800BB65149d843D82d2D": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xd4b553aed9df4bb81dfec99c249dbb99fb7beaef39f870cded5fe5719a809f7a", + "code": "0x0dda8da39b09c5d12be3408433542bcb85e79c16e9fa698274be0a5f5c0de0fb9155f2118833bf042b9dc03ff0b395208526fb6aae0ce96bd5b48743c48f179e14f494c65b48b2269e6f5785daed2174329ff45233af29f1ab57a83ec298b66135158e6a4d60ba7fad6584323785917414cc012686456fc0f2439c277bd05cfc9c989adbdafe30987e6fdc03d7338cb0c4591d695fc239ac5a81ff2f8e808e27ae2e9d1466e10fd686cfb1a2f8b60d75f9fd753466b824829dac49112d9496996c44c6278aa5f1fb3b169e5ac7fc49bdcfc3e1806375d1855254212e157be3bf1325408048277dccf4ad3c883277c32a60bc62de3dc708503358ea4b20f98206", + "address": "0xe2ff4e7e4a28d327b030800bb65149d843d82d2d", + "key": "0x911077c76a4a16f33df9c81d27b2ca80256a7141e83339fc2f18948313012e2f" + }, + "0xe7B2CEB8674516c4aEb43979808b237656aB3B6B": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xe7b2ceb8674516c4aeb43979808b237656ab3b6b", + "key": "0x75d231f57a1a9751f58769d5691f4807ab31ac0e802b1a1f6bfc77f5dff0adbf" + }, + "0xe920AB4e34595482e98B2C0d16Be164c49190546": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xf91b587fa3d345550ae9b246a788e2f668bf8df9071d8b4e3f07594a52791925", + "code": "0xddf72b2f62b0846ca7da60f0df0f94cdb28e603ef5291f65615841a7468c44c0710244b60ba7c1bd35ceda568c1c62624e99f11696da5612c84c7901031a9ece682e02e2fdab880917c319130d538d88dd4ea8d4b55431d219c9fc1fda9de93cc441712b999ae1b5f312a9513edfd8374c171ed2e13f457312b48a6118e30c586c90643f346afd56f022a6ddf0199dca4d55558c4e0c6b438b89dc77236b62238e8fc62d2064391f7b9dfc498260918dda58b2fadba062c23c105952e10f766b5a9adcc69eddff3413d21062a8f00e1b55efcbb4b88e08038f348ea9bf741c6d8060c339d013a28259483a9bbf8245b3f2c21722b238902c8756e3fa46291ecb", + "address": "0xe920ab4e34595482e98b2c0d16be164c49190546", + "key": "0xd623b1845175b206c127c08046281c013e4a3316402a771f1b3b77a9831143f5" + }, + "0xedA8645bA6948855E3B3cD596bbB07596d59c603": { + "balance": "1000000000000000000000000200000000000", + "nonce": 1, + "root": "0xdd43fc82ac338ab2ee3c6203da0c8f16e893e6c37720b37ce8676f0e7c68bb05", + "codeHash": "0x3eea9094c21233d71a12df13d1f911a5f47d133c4c828a74089984eaeecf2640", + "code": "0xef0100417fe11f58b6a2d089826b60722fbed1d2db96dd", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "696e766f6b656400000000000000000000000000000000000000000000000000" + }, + "address": "0xeda8645ba6948855e3b3cd596bbb07596d59c603", + "key": "0xabd8afe9fbf5eaa36c506d7c8a2d48a35d013472f8182816be9c833be35e50da" + }, + "0xf068AE4089A66C79Afe47D6E513F718838D8f73F": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xf068ae4089a66c79afe47d6e513f718838d8f73f", + "key": "0x37310559ceaade42e45b3e3f05925aadca9e60aeeb9dd60d824875d9e9e71e26" + }, + "0xf11Da605c7cE2BB45FDD1117c7A7744F505eFEa4": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xf11da605c7ce2bb45fdd1117c7a7744f505efea4", + "key": "0x4490d5539df3636dbe295411ff92b662bb12ea3656f46fedbf5625af73882277" + }, + "0xf820E25fAA00515571CFFa390f2fa3E96B0b5c6a": { + "balance": "0", + "nonce": 1, + "root": "0xc7839c3366ccfac78f919d8471358021b5b7d493e6532c52efe048ff2da0af0c", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x00000000000000000000000000000000000000000000000000000000000001c0": "01c0", + "0x00000000000000000000000000000000000000000000000000000000000001c1": "01c1", + "0x00000000000000000000000000000000000000000000000000000000000001c2": "01c2" + }, + "address": "0xf820e25faa00515571cffa390f2fa3e96b0b5c6a", + "key": "0x7e1eec4a63dcc09bf241883e29bb53e7c377c1c0891a1b0189bcd411b20c0738" + }, + "0xfAbE26BC448a25eC56FF9360b19B66d56BaDFf51": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x605a56872757b687e70b0a8c3c3bab8566722172023e2c89b8be7ca0601ddf87", + "code": "0xc189f84ce68d330a8fdf55d40ed2705c7b14e02dd92ac2ee8966971c2fb56ec7ead8f6c0653ac108e89227cbe7425f3b89d61d55b92d8aa75cefaf308a8fbf7e8622f55c65610f385e1d95c8f07ca152f97aa824081a0afcd103f33f6b8ca72a33871796b7313fc5499b1f5322d50f5058acefe7776b255179bf9ae1e55602027173dcd6a2b7fe9242f4c2bd4b2c88cf749fb25984608228bc83697bfa7eb5b471185a1ea5a896559cd0665d0979f85c835265f180e74502f783bd7a192bf63fece6665d217127474d08619b555ba7cf850c9566e44f26045fd57ee3fafe0590e674d6359c3bd263fc88d21d87228700bd819a703993ffdb575906e5517cd01d", + "address": "0xfabe26bc448a25ec56ff9360b19b66d56badff51", + "key": "0x7b5d2a2cc2dee3a5ba257d9324d8772b209ed8ebc559c73dadd32af002df621e" + }, + "0xfCE0CADC18035c4a6FE8279165277788826591fB": { + "balance": "0", + "nonce": 1, + "root": "0x14f9f4b9445c7547d5a4671a38b0b12bbc0e7198c3b2934b82b695c8630d4972", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000126": "0126", + "0x0000000000000000000000000000000000000000000000000000000000000127": "0127", + "0x0000000000000000000000000000000000000000000000000000000000000128": "0128" + }, + "address": "0xfce0cadc18035c4a6fe8279165277788826591fb", + "key": "0x68bda3bd48de9803b2a21ffd518bc8aa99a56d7eb40cc8db1a6bf803b8693be5" + }, + "0xfcb2A3a61D3De12F554db60494f13e9477F31a2f": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0x302c2cdce1f556b5053afca77878c358d2492d7745f5cbbf9db5761df20db001", + "code": "0x50ba73278bbf571a271f39357d381d2f5f97b7d5b6a23b684b7751eddba38718b712f55a8405e8766b7610a3b707f0ea903b826c8623fa2624da135a56a422ebb8b9c4837d54a5d26c8f7e03d3b9cd37367cb9ba2a74a2e4e571a0b453433473fcbc0922eb3255790a824facc22abbf7bf018597c0700c13a6df4a019b75b3ae9ffad69f84083f437fc88821853a0555fc46dd72c6c7dcb209f949f252909fdcefff4d220e7779831f23f8b0cb0449a9525f4c42705a5e35acfb5cc1016cf81b8e7bd63088de20dd86bdf2b9ba56bd140f59161a5d05abb70bf55a82cda068e494152e7cadd4eba05f59e9c2118d2ed4e1d9e020bb8d2b37c15f90576f810742", + "address": "0xfcb2a3a61d3de12f554db60494f13e9477f31a2f", + "key": "0x678bb0d1fd0696bae4b7e06994861242bfbfe332bc030c15ab9d33c26eeab13c" + }, + "0xfdB19A177ED1B386d141e392B7A27467469fAbB2": { + "balance": "0", + "nonce": 1, + "root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "address": "0xfdb19a177ed1b386d141e392b7a27467469fabb2", + "key": "0x7cf2a82cb777b7aa435dcddab99299165f8e46c83c1f9bd50206e428074143be" } } } \ No newline at end of file diff --git a/cmd/devp2p/internal/ethtest/testdata/newpayload.json b/cmd/devp2p/internal/ethtest/testdata/newpayload.json index 7f8c99afa9..0e18cd8525 100644 --- a/cmd/devp2p/internal/ethtest/testdata/newpayload.json +++ b/cmd/devp2p/internal/ethtest/testdata/newpayload.json @@ -1,284 +1,25 @@ [ { "jsonrpc": "2.0", - "id": "np72", - "method": "engine_newPayloadV1", - "params": [ - { - "parentHash": "0x9e8a444b740df016941ecc815fe9eebeaa04a047db6569855573a52a8cb78cdd", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x74035b613e4ea1072fd029f35d0fa5b26fbfaa54cabebcec88b9ee07cca321ae", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x48", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", - "timestamp": "0x2d0", - "extraData": "0x", - "baseFeePerGas": "0x568d2f9", - "blockHash": "0xf0a50b18d597552b6ad8a711f4ac1f7ab225d59daa74137f689256a16a0ff809", - "transactions": [ - "0xf86a39840568d2fa8252089444bd7ae60f478fae1061e11a7739f4b94d1daf9101808718e5bb3abd10a0a050fc2310f542cf90b3376f54d296158f5be7ad852db200f9956e3210c0f8125ca04f880fe872915a7843c37147a69758eff0a93cfaf8ce54f36502190e54b6e5c7" - ], - "withdrawals": null, - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np73", - "method": "engine_newPayloadV1", - "params": [ - { - "parentHash": "0xf0a50b18d597552b6ad8a711f4ac1f7ab225d59daa74137f689256a16a0ff809", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x18b68edcdfc835d5db51310e7960eaf0c0afcc5a6611282d2085f3282b2f9e3f", - "receiptsRoot": "0xabc882591cb5b81b276a4e5cd873e1be7e1b4a69f630d2127f06d63c8db5acb2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x49", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146e8", - "timestamp": "0x2da", - "extraData": "0x", - "baseFeePerGas": "0x4bbd14a", - "blockHash": "0x662ab680f6b14375e7642874a16a514d1ecffc9921a9d8e143b5ade129ad554b", - "transactions": [ - "0xf8853a8404bbd14b830146e88080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a027748abc264040530bca00d1cc86b199586c1fe26955cd5e250b97e2b9ca3128a050a822d9df3b63e6911766d4ae8c722f5afee7a6c06a7b5eb73772a5b137ca36" - ], - "withdrawals": null, - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np74", - "method": "engine_newPayloadV1", - "params": [ - { - "parentHash": "0x662ab680f6b14375e7642874a16a514d1ecffc9921a9d8e143b5ade129ad554b", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6fb7295e0a62bff03ddeba56ba643cd817fab6bc8df11309f8e8a3dbcf7d502e", - "receiptsRoot": "0x7b9d8080a095524251324dc00e77d3ecf4c249c48eebed2e4a5acedc678c70b4", - "logsBloom": "0x000800000000000000000000000000000900000000000000000000000000c0080000000000000010000000020000000000000004100000000480008020100000000000000000000000000000001000200000000000000010000010000000000000000000000000000000000000000000000000000000000200000000000000800001000000000000000000000000000000000004000000000000000800000000008000000000000001000000000002000000000000000000000000000000080000000000000000200404000000000000000000000000000000000000000000000000080100000000000000000000000000000000000000000000000000000000", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x4a", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc61", - "timestamp": "0x2e4", - "extraData": "0x", - "baseFeePerGas": "0x424ad37", - "blockHash": "0x9981d4e953d402b0b1554ef62ebbeb7760790a5e53191c9753329b6a3eab3d13", - "transactions": [ - "0xf87c3b840424ad3883011f548080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a050e3677064fe82b08a8fae8cea250fbaf00dbca1b6921cffd311ca17c7979865a051e738138eab4b31f1ba163b8ed2cfd778af98eff583cd5a26fcd9bd673fe027" - ], - "withdrawals": null, - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np75", - "method": "engine_newPayloadV1", - "params": [ - { - "parentHash": "0x9981d4e953d402b0b1554ef62ebbeb7760790a5e53191c9753329b6a3eab3d13", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x65038690e44bf1ee49d47beb6efc7cc84d7f01d2ba645768e3a584a50979b36d", - "receiptsRoot": "0xf5419129ce2f36d1b2206d4723f3e499691ad9aee741223426cda1b22e601a19", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x4b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36c", - "timestamp": "0x2ee", - "extraData": "0x", - "baseFeePerGas": "0x3a051bc", - "blockHash": "0xc5e8361f3f3ba7bfbed66940c015f351d498ed34d48f8de6e020ffffbcbbec61", - "transactions": [ - "0xf8673c8403a051bd83020888808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0dd01417c1ac62f9e593b07848f93c1f5ab729e73a493e22141f6e1c6e8a4f94fa00b9e979c6bae8ab4a90b7b2ba61d590d800e5411bc12be320efc3fb7310506e3" - ], - "withdrawals": null, - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np76", - "method": "engine_newPayloadV1", - "params": [ - { - "parentHash": "0xc5e8361f3f3ba7bfbed66940c015f351d498ed34d48f8de6e020ffffbcbbec61", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3b8d5706f2e3d66bb968de876e2683d75dce76d04118bc0184d6af44fb10196f", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x4c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", - "timestamp": "0x2f8", - "extraData": "0x", - "baseFeePerGas": "0x32ca5cf", - "blockHash": "0xcb51fdebc936f135546a0ff78a7ce246aee0a5c73b41b7accdc547825bb97766", - "transactions": [ - "0x02f86d870c72dd9d5e883e3d0184032ca5d08252089472dfcfb0c470ac255cde83fb8fe38de8a128188e0180c080a0116da1fc19daf120ddc2cc3fa0a834f9c176028e65d5f5d4c86834a0b4fe2a36a017001c3ad456650dd1b28c12f41c94f50b4571da5b62e9f2a95dff4c8c3f61fd" - ], - "withdrawals": null, - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np77", - "method": "engine_newPayloadV1", - "params": [ - { - "parentHash": "0xcb51fdebc936f135546a0ff78a7ce246aee0a5c73b41b7accdc547825bb97766", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3b8d17721b733ce2b6e7607a69fb6bf678dbabcb708f64cb5d211915b3238090", - "receiptsRoot": "0xabc882591cb5b81b276a4e5cd873e1be7e1b4a69f630d2127f06d63c8db5acb2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x4d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146e8", - "timestamp": "0x302", - "extraData": "0x", - "baseFeePerGas": "0x2c71f92", - "blockHash": "0x49b74bc0dea88f3125f95f1eb9c0503e90440f7f23b362c4f66269a14a2dcc3e", - "transactions": [ - "0xf8853e8402c71f93830146e88080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a00cb7fb1bba811ea1948e035550c66840f0491d29d0ae9a6e4726e77a57ca8058a041523fc7133a6473784720a68d7f7f1d54d8a5a1f868640783a0284fb22f4309" - ], - "withdrawals": null, - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np78", + "id": "np0", "method": "engine_newPayloadV2", "params": [ { - "parentHash": "0x49b74bc0dea88f3125f95f1eb9c0503e90440f7f23b362c4f66269a14a2dcc3e", + "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf21b9b380d6c5833270617a17ea187e1f85a6556f1c1dfaf6bcb0700c88abe24", - "receiptsRoot": "0xb08f0ccb7116304320035e77c514c9234f2d5a916d68de82ba20f0a24ab6d9e4", - "logsBloom": "0x00000000000000400000000000200000000000000000000000000000000000000000200010000000000000000000000000000040000400000010000000000020000000000000000000000000000000000000000000000000000000900000000000800000000800000010000008000000000000000000000102000000000000100000080000000100000000000000000000000000000008000000000000008000800800000000000000000000400000000008200000000200200000000000000000000000000000200000000000000000000000000000000000000000000000000000000011000000000000800000000000000000000000000000000000000008", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x4e", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", - "timestamp": "0x30c", - "extraData": "0x", - "baseFeePerGas": "0x26e6e24", - "blockHash": "0x157062b78da942ff0b0e892142e8230ffdf9330f60c5f82c2d66291a6472fd7c", - "transactions": [ - "0xf87c3f84026e6e2583011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0fa1ba7a3639ec15944466d72a2e972d5eda143fc54f07aa47ecd56769ba5fbf8a041018f9af7a55685cbfa25d35f353e4bccef32a5e0bcdb373191d34cfed9a8db" - ], - "withdrawals": [], - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np79", - "method": "engine_newPayloadV2", - "params": [ - { - "parentHash": "0x157062b78da942ff0b0e892142e8230ffdf9330f60c5f82c2d66291a6472fd7c", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8bb2c279cf46bd7eb856cc00fdce9bb396b21f65da47fdf0f13b41e0c0e0aa7f", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x4f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", - "timestamp": "0x316", - "extraData": "0x", - "baseFeePerGas": "0x220c283", - "blockHash": "0x39a05d1b50f4334060d2b37724df159784c5cbfe1a679f3b99d9f725aed4d619", - "transactions": [ - "0xf86740840220c2848302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0bcd36ef6498fd3ce093febc53b3e35004a9d9200816306515f5ffad98140426fa00656b7e75310845c1d2e47495ed7765d687f0a943a604644d9cf7b97b01f300f" - ], - "withdrawals": [], - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np80", - "method": "engine_newPayloadV2", - "params": [ - { - "parentHash": "0x39a05d1b50f4334060d2b37724df159784c5cbfe1a679f3b99d9f725aed4d619", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x62b57c9d164c28bc924ec89b1fe49adc736ee45e171f759f697899a766e3f7a4", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", - "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x50", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", - "timestamp": "0x320", - "extraData": "0x", - "baseFeePerGas": "0x1dce188", - "blockHash": "0xa7806a3f4d0f3d523bf65b89164372b524c897688d22d2ef2e218f7abb9cbddb", - "transactions": [ - "0xf869418401dce189825208945c62e091b8c0565f1bafad0dad5934276143ae2c01808718e5bb3abd10a0a0b82a5be85322581d1e611c5871123983563adb99e97980574d63257ab98807d59fdd49901bf0b0077d71c9922c4bd8449a78e2918c6d183a6653be9aaa334148" - ], - "withdrawals": [], - "blobGasUsed": null, - "excessBlobGas": null - } - ] - }, - { - "jsonrpc": "2.0", - "id": "np81", - "method": "engine_newPayloadV2", - "params": [ - { - "parentHash": "0xa7806a3f4d0f3d523bf65b89164372b524c897688d22d2ef2e218f7abb9cbddb", - "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1820989c0844509c8b60af1baa9030bdcc357bc9462b8612493af9d17c76eb3d", + "stateRoot": "0xe5d8b049a78427be8c23ebd6811ed436b3a36cc117954b496848b90f0c654844", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x51", - "gasLimit": "0x47e7c40", + "blockNumber": "0x0", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x32a", - "extraData": "0x", - "baseFeePerGas": "0x1a14dd8", - "blockHash": "0x7ec45b0f5667acb560d6e0fee704bb74f7738deb2711e5f380e4a9b2528d29c1", + "timestamp": "0x0", + "extraData": "0x68697665636861696e", + "baseFeePerGas": "0x3b9aca00", + "blockHash": "0xe5850a454eb99a0b5a4393fc9b4b3e02f8daf8079f828f76c307936006d70b1e", "transactions": [], - "withdrawals": [ - { - "index": "0x0", - "validatorIndex": "0x5", - "address": "0x4ae81572f06e1b88fd5ced7a1a000945432e83e1", - "amount": "0x64" - } - ], + "withdrawals": [], "blobGasUsed": null, "excessBlobGas": null } @@ -286,25 +27,25 @@ }, { "jsonrpc": "2.0", - "id": "np82", + "id": "np1", "method": "engine_newPayloadV2", "params": [ { - "parentHash": "0x7ec45b0f5667acb560d6e0fee704bb74f7738deb2711e5f380e4a9b2528d29c1", + "parentHash": "0xe5850a454eb99a0b5a4393fc9b4b3e02f8daf8079f828f76c307936006d70b1e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8145365a52eb3a4b608966d28a8ed05598c13af426c7ab24f28f2bdc7a00b12b", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x950aea7b35a0d9e8f81dfdc3387fa12aa4d4f8a043f3341de7e9002933ca280f", + "receiptsRoot": "0x97a526b2e32116d208b71a92e95e23a6734f413a15a057d122b5983acf25f8bc", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x52", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x334", + "blockNumber": "0x1", + "gasLimit": "0x23f3e20", + "gasUsed": "0xf777", + "timestamp": "0xa", "extraData": "0x", - "baseFeePerGas": "0x16d241d", - "blockHash": "0x8dbcafaa0e32cd9f71f1d5b0f22f549aee0fddce3bda577ac200e24c7dc8ba62", + "baseFeePerGas": "0x342770c0", + "blockHash": "0xbdd7b3e2623f0903d9b0f4c50c161837fc61ee01feac041001f5c5dc75337423", "transactions": [ - "0xf8854284016d241e830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a061c5ecaf5f73e89370f5b35c31bce60d04c7417cc70cc897beae6429cb6d3880a02271644378271ec296459da5181507d52bdbd4489600690c32998cdb4b032042" + "0xf8938084342770c1830131348080b83c600d380380600d6000396000f360004381526020014681526020014181526020014881526020014481526020013281526020013481526020016000f38718e5bb3abd109fa04bbfb315c19415b5e39df54c30c5a0c8d5e8100fc5e245e67623ff20dd8390279f0a29f1401eec72972b601f590b17c904db69e9ccf3e10384e4da572788269b" ], "withdrawals": [], "blobGasUsed": null, @@ -314,25 +55,25 @@ }, { "jsonrpc": "2.0", - "id": "np83", + "id": "np2", "method": "engine_newPayloadV2", "params": [ { - "parentHash": "0x8dbcafaa0e32cd9f71f1d5b0f22f549aee0fddce3bda577ac200e24c7dc8ba62", + "parentHash": "0xbdd7b3e2623f0903d9b0f4c50c161837fc61ee01feac041001f5c5dc75337423", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x07cc0bca2e8f3b243635dc6f988372dd2427b6090f1035d06f2eff2e99315170", - "receiptsRoot": "0xace7ae7e3c226cecca4b33082b19cd1023960138a576ef77fddadcc223b4250a", - "logsBloom": "0x40000010010000000000000100000c00000001000000000000000000000000000000000200000000000042000000000000001000000000000000000000000000000000000000000000000820040000800000000000004000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000001000800000001000000000000000000000000000000000000000004000004000000000000000410000000000000000000000040000000000000000004000000000000000000000000000400001000000000000000000400000000000000000000200080000000000000000000000010000000040000", + "stateRoot": "0xe155278d003025157bb43b08603da00313c14aa9f10710e72b72d69284382afb", + "receiptsRoot": "0xe078709b25bc275a65cecf4c9c5e192aa3c2cbd051b6a35279c391a3ee4d597c", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x53", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", - "timestamp": "0x33e", + "blockNumber": "0x2", + "gasLimit": "0x23f3e20", + "gasUsed": "0x115c7", + "timestamp": "0x14", "extraData": "0x", - "baseFeePerGas": "0x13f998a", - "blockHash": "0x686c223412a42d17a7fe0fe2a8b15d6181afa366cccd26a0b35a7581c0686721", + "baseFeePerGas": "0x2da81e94", + "blockHash": "0xfacb55d35b1efa3f38d8c066ad6684b329755ad2d34f7029ae5c7c6bbc8a6ae8", "transactions": [ - "0xf87c4384013f998b83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a01001f6f02c9dac33915eb5d0fe81d88599a29341d84ee6f46b1ef05d270a0c1fa05ea1dbc664d9f4a83b4743bc40579e6b727ff8b5e78c4249bd59aa47c33d770f" + "0xf8b801842da81e9583014f7e8080b860600d380380600d6000396000f3366002146022577177726f6e672d63616c6c6461746173697a656000526012600efd5b60003560f01c61ff01146047576d77726f6e672d63616c6c64617461600052600e6012fd5b61ffee6000526002601ef38718e5bb3abd10a0a045dc6b6d59b0f906744f1d09ea500ceae82dad075a9b0868b7760966ff604870a0464b4a826cb475452d2587b8a67f0e48c98b55adef2558cd5eaf60c181a32afb" ], "withdrawals": [], "blobGasUsed": null, @@ -342,25 +83,109 @@ }, { "jsonrpc": "2.0", - "id": "np84", + "id": "np3", + "method": "engine_newPayloadV2", + "params": [ + { + "parentHash": "0xfacb55d35b1efa3f38d8c066ad6684b329755ad2d34f7029ae5c7c6bbc8a6ae8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x59e18bf6f9ab05be8ef42c5b91d750b0eda247201beeaa583004724130cba9ac", + "receiptsRoot": "0x75908b9afeb91eecae34b9a2cfbeda7fd4c66398fea481c89a7564e41d5da0cd", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x3", + "gasLimit": "0x23f3e20", + "gasUsed": "0x143eb", + "timestamp": "0x1e", + "extraData": "0x", + "baseFeePerGas": "0x27f89dc5", + "blockHash": "0x30c554999f56478175c7d58b6911819608ec37e738e3b1de824e55094462ceb4", + "transactions": [ + "0xf8f3028427f89dc683017d968080b89b600d380380600d6000396000f360003515156036577f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b7f08c379a0000000000000000000000000000000000000000000000000000000006000526020600452600a6024527f75736572206572726f7200000000000000000000000000000000000000000000604452604e6000fd8718e5bb3abd109fa03c13b52b90355f3392f8134624087ca1d80e35900c8f3515e662869feaacea04a05f800daf0a81d4993f977e2b5bb3db8f30888d28ac7e4b3077c79c9028d1ae0e" + ], + "withdrawals": [], + "blobGasUsed": null, + "excessBlobGas": null + } + ] + }, + { + "jsonrpc": "2.0", + "id": "np4", + "method": "engine_newPayloadV2", + "params": [ + { + "parentHash": "0x30c554999f56478175c7d58b6911819608ec37e738e3b1de824e55094462ceb4", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x524c3a9d48961688fd669794a18e3dd8c62b75fab78b9c56f008fac18d8b8d7c", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x4", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x28", + "extraData": "0x", + "baseFeePerGas": "0x22ff2a8b", + "blockHash": "0xd31109a0dbafd1f1cc8c766e26e0d2c604624ff2b66bcc95baf784d3d7e21aef", + "transactions": [ + "0xf885038422ff2a8c8301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa0bdd3c5894ecd41fe69173487fc04062b827ef70887a998a96854288770eca1f0a03777f418485bf99684eea6842c59e2eeaf6db201f1fcc6d9886cb18fb802c6df" + ], + "withdrawals": [], + "blobGasUsed": null, + "excessBlobGas": null + } + ] + }, + { + "jsonrpc": "2.0", + "id": "np5", + "method": "engine_newPayloadV2", + "params": [ + { + "parentHash": "0xd31109a0dbafd1f1cc8c766e26e0d2c604624ff2b66bcc95baf784d3d7e21aef", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x3616ac845c5539addfdc3c8495c3e5cf92ca55638127a25107dde16fef02139a", + "receiptsRoot": "0x399a62e49d637d071f11c70ab4fd9aca6de920b3fddb2b1c9739e107d60d683f", + "logsBloom": "0x00000000000000000000000000000000000000000008000000000000040420000000008000000000000000000000000000000000000000000000008200000000000000000000000000000000000000000000080000010000000000000000800000002000000000000000000000000000000000000000000000000004000080000000000000400000000000000000000000000000000000000000000000040000000004020000000800000000000000000000000000010000000000000010000000042000000080000006000000000000000000000000000000000000000000000200000200000000100200000000000000200000020000100000000000000080", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x5", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x32", + "extraData": "0x", + "baseFeePerGas": "0x1ea58e20", + "blockHash": "0xfe55c597a9aa81a0233ae2e1aab26b32a2cd890978bbef31b3a3517217d587de", + "transactions": [ + "0xf87c04841ea58e2183011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa060f7133945281b66a86cbcfe120e0801afbfc9abfdec1597397233c44a758b77a0592c06634ac4f7e82d40f52c2dd92686f47b45382d0256f87f386ae5f3b09d20" + ], + "withdrawals": [], + "blobGasUsed": null, + "excessBlobGas": null + } + ] + }, + { + "jsonrpc": "2.0", + "id": "np6", "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0x686c223412a42d17a7fe0fe2a8b15d6181afa366cccd26a0b35a7581c0686721", + "parentHash": "0xfe55c597a9aa81a0233ae2e1aab26b32a2cd890978bbef31b3a3517217d587de", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe1a71059650ccefaf7d0a407c43a87ccc9fe63a6369a46509074658f714c54ad", + "stateRoot": "0x89a905393431866fe45f07895e3045eee539820dbdcd9bad7e9a75afa410de6e", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x54", - "gasLimit": "0x47e7c40", + "blockNumber": "0x6", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x348", + "timestamp": "0x3c", "extraData": "0x", - "baseFeePerGas": "0x117b7e1", - "blockHash": "0x8a76d39e76bdf6ccf937b5253ae5c1db1bdc80ca64a71edccd41ba0c35b17b84", + "baseFeePerGas": "0x1ad438f2", + "blockHash": "0x55e4cf7027d011ce8517b43ce6dbacad82fe7b48b89f1b1053a1d02013be10fd", "transactions": [ - "0xf86744840117b7e28302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0b4a7e6c791f457a428f870b8df8ee0148acac74050aeea658c3dad552a7e8140a0793951ba22a6f628dd86ec8964b09c74e0f77306a28dd276dfe42f40ee76c73c" + "0xf86705841ad438f38302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa04618d35cd148b289eba951b1b67fba60ed0c71ec6aa072f01843f0cbb0a6f8e7a01d7d73fba778e165db04d8502f224ea7a2bcb7482c506a036c831cebed70f2ed" ], "withdrawals": [], "blobGasUsed": "0x0", @@ -372,25 +197,25 @@ }, { "jsonrpc": "2.0", - "id": "np85", + "id": "np7", "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0x8a76d39e76bdf6ccf937b5253ae5c1db1bdc80ca64a71edccd41ba0c35b17b84", + "parentHash": "0x55e4cf7027d011ce8517b43ce6dbacad82fe7b48b89f1b1053a1d02013be10fd", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x198575d6df4370febe3a96865e4a2280a5caa2f7bd55058b27ea5f3082db8d99", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x0d0e92ffa93004447ae8c651e98a8370ea156e4fffeef500a1be099fa982fad1", + "receiptsRoot": "0xab3d679c59ae2bd60b09801e3dcaa843b6231d88f744e2d4fb89607f4232b7ab", + "logsBloom": "0x00000100000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x55", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", - "timestamp": "0x352", + "blockNumber": "0x7", + "gasLimit": "0x23f3e20", + "gasUsed": "0xbfac", + "timestamp": "0x46", "extraData": "0x", - "baseFeePerGas": "0xf4dd4f", - "blockHash": "0xc0d03736d9e3c2d4e14115f9702497daf53b39875122e51932f4b9b752ba7059", + "baseFeePerGas": "0x177f2512", + "blockHash": "0x1b9b663eca7124419b9131f1045a0edbc4154e026f4fc7de8311d459246f2eff", "transactions": [ - "0x02f86c870c72dd9d5e883e450183f4dd5082520894a25513c7e0f6eaa80a3337ee18081b9e2ed09e000180c080a0e8ac7cb5028b3e20e8fc1ec90520dab2be89c8f50f4a14e315f6aa2229d33ce8a07c2504ac2e5b2fe4d430db81a923f6cc2d73b8fd71281d9f4e75ee9fc18759b9" + "0x02f8d6870c72dd9d5e883e060184177f2513830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c7e2e8b49f93a4f1f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a03569f740e521d8bb11c5b72660dc96272ad66bfd811ed918c3a9e02acd4ade8f01a09946d8fc8ffcee7840c0fe223ea25f630d1e734432787ecd0b5107f773253849a03ee58d6d70214319409499d220ec1555ad458e9c312b660c79afe19cb68a89e5" ], "withdrawals": [], "blobGasUsed": "0x0", @@ -402,32 +227,27 @@ }, { "jsonrpc": "2.0", - "id": "np86", + "id": "np8", "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0xc0d03736d9e3c2d4e14115f9702497daf53b39875122e51932f4b9b752ba7059", + "parentHash": "0x1b9b663eca7124419b9131f1045a0edbc4154e026f4fc7de8311d459246f2eff", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x90c402a8569aae0c095540a9762aefac4f43df4e97fc7a24df1d4051c555bc2c", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd47e264283e68d12bba8070826a2f72b06e3bd92527a56d74214a406fa4624b3", + "receiptsRoot": "0x59df46f0e6bac1dc285d10ccd74b357af596460248be25ef75fc47c7fac1a39c", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000001000000000000000000000000000000000000004000000000000200000000000000000000000200002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x56", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", - "timestamp": "0x35c", + "blockNumber": "0x8", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x50", "extraData": "0x", - "baseFeePerGas": "0xd64603", - "blockHash": "0xa7323a02aa9acf63f26368292292d4bcb9dc7ef33296bbd98f423b24db3408bd", - "transactions": [], - "withdrawals": [ - { - "index": "0x1", - "validatorIndex": "0x5", - "address": "0xde5a6f78116eca62d7fc5ce159d23ae6b889b365", - "amount": "0x64" - } + "baseFeePerGas": "0x14913581", + "blockHash": "0x61322084e9721face5911ca9988aa668185e1e2786057fcb069cb29c8190bf61", + "transactions": [ + "0x01f8d5870c72dd9d5e883e078414913582830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c92c0a3cd8b571ac5656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0881a8434f98b103a2ee48727304618ca54234f1474c44bef70c21accc4dbc0a780a0a6d4adfb0a6bbc11fffb1025bdc8e0216316178f3b9bb7275f0d71a6df68067da0454a6e70c9e349890bdd5c9bf42ad3d4809d8bd246fda129dcacabad1d43c228" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, @@ -437,55 +257,57 @@ }, { "jsonrpc": "2.0", - "id": "np87", + "id": "np9", "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0xa7323a02aa9acf63f26368292292d4bcb9dc7ef33296bbd98f423b24db3408bd", + "parentHash": "0x61322084e9721face5911ca9988aa668185e1e2786057fcb069cb29c8190bf61", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7e1765cf5abdf835814ee20c9e401b0e99e2b31f2ad8ea14c62ef732c6e63d2d", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x498a464dec3c6e5290fa555c92cb8a865b30cdce6682e1ab1871c6a36e0b3e2b", + "receiptsRoot": "0x7427faac1fbc3e399bb731da9429aa768a3c2c054e1ec11c64625942bb2ba0c3", + "logsBloom": "0x00000000000000004000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x57", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x366", + "blockNumber": "0x9", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x5a", "extraData": "0x", - "baseFeePerGas": "0xbb7d43", - "blockHash": "0xbbd89c9c2805888d9d1397d066495db1ce1c570e23b5b6f853dc0ff698575a04", + "baseFeePerGas": "0x1200de71", + "blockHash": "0x3af964bbb4a63a63e6110faa9b27c25ae5c1e22d9273a2b60f43c71b6b4bf31d", "transactions": [ - "0xf8844683bb7d44830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a052c928a2062b214d44b9a641faf87e439fbc5a07f571021f0f3c8fd2a2087a57a0650c77ab1cd522a7d3a435058f53636b6ae86d19fd4f691bf61c13fd8b7de69a" + "0x03f8fc870c72dd9d5e883e0801841200de72830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038ca66c701845710c6c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a063cde520fb894276a981d2c9099bef9beb949121c1be98f3abe1b721d880899f83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a00fb516e328b806289d882c3ea936d603a2231af896649eb0e49d805152f5f2d4a043e7d256698deeceedcaa310c055ff85b3d7805e7fad3b540ab7de9463011738" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], "0x4b118bd31ed2c4eeb81dc9e3919e9989994333fe36f147c2930f12c53f0d3c78" ] }, { "jsonrpc": "2.0", - "id": "np88", + "id": "np10", "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0xbbd89c9c2805888d9d1397d066495db1ce1c570e23b5b6f853dc0ff698575a04", + "parentHash": "0x3af964bbb4a63a63e6110faa9b27c25ae5c1e22d9273a2b60f43c71b6b4bf31d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3ec8183c28814317cb7a7b86633041db40de94b45a47dab5614b21087c308648", - "receiptsRoot": "0xe2e7a47b1c0009f35c3a46c96e604a459822fe9f02929afa823f2c514f1fbd39", - "logsBloom": "0x00000000000000000000000000000002000000000000000000000000000000000000000800000000000000000000000200000000008000000000000000000000000000000800000000000000800000000000000000000002000000000100000000000000000000000000000000000000001000000000400000000000000000000000000000000001000000000000000000000000000000000000000000000020000000000000400000000000000100000000000100000000000000000000100200000000000000000000000000000010400000000000000050080004000000400000000010000000800030001000000000000000004000000000000000000a00", + "stateRoot": "0x5561c28bf67d2f12f3b0df3d4865cc661247a904e0f64fa82cd8e8ef80610691", + "receiptsRoot": "0x4478e3b373311a23ee4d53203c0bd7e990e5e81cd616e690fdc8eb2a784e5020", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000100000000001000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x58", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", - "timestamp": "0x370", + "blockNumber": "0xa", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x64", "extraData": "0x", - "baseFeePerGas": "0xa41aed", - "blockHash": "0xe67371f91330dd937081250eeda098394453c2ced0b6ffd31a67f8d95261d849", + "baseFeePerGas": "0xfc25878", + "blockHash": "0x7530fb1515a8ec5b024a700bf0220783269b1e2edc3d215207c96bf5c5539632", "transactions": [ - "0xf87b4783a41aee83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa09799e22509fcf203235570e7ba0df80bad6124b89b812146b50bca27f03161a9a0118a4f264815d7cf1a069009bff736f04369e19e364bd1a409a4c4865ec7d81f" + "0xf87709840fc25879830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c06072144caa6635a656d69748718e5bb3abd10a0a05f933238929883d03102abfa12902de040aa3990210570fedfc48c6820fb9a8aa04edb8bdf127341d132c798f7203e62b37bd27dcf361732fe918792e21066b3aa" ], "withdrawals": [], "blobGasUsed": "0x0", @@ -497,25 +319,25 @@ }, { "jsonrpc": "2.0", - "id": "np89", + "id": "np11", "method": "engine_newPayloadV3", "params": [ { - "parentHash": "0xe67371f91330dd937081250eeda098394453c2ced0b6ffd31a67f8d95261d849", + "parentHash": "0x7530fb1515a8ec5b024a700bf0220783269b1e2edc3d215207c96bf5c5539632", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x07118ca8999c49a924f92b54d21cecad7cbcc27401d16181bbcdee05b613399c", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x5b2457ac13c8edf5deedd62c51bfca391a8a4b99d7901ff251c56658f74bbae9", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x59", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", - "timestamp": "0x37a", + "blockNumber": "0xb", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x6e", "extraData": "0x", - "baseFeePerGas": "0x8fa090", - "blockHash": "0x395eda9767326b57bbab88abee96eea91286c412a7297bedc3f1956f56db8b18", + "baseFeePerGas": "0xdcb6245", + "blockHash": "0x7167b82e4207928eb75fbe741b29d18fb5d469fa56c93941223667a07d183c44", "transactions": [ - "0xf86648838fa0918302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0fd5a86a96cbf94d2bba5c7fb6efd2bf501dd30c8b37e896ae360b40ab693272aa0331e570a5b3ce2cef67731c331bba3e6de2ede8145dd0719ce6dfcca587c64ba" + "0x02f86d870c72dd9d5e883e0a01840dcb6246825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c0180c080a084acd22563552cb084358e49c7d881c7fd44d2bb47becbf7d45db91a89d256a0a0693e415095b70f8b616169aba614e663b0dcbad5b55b427407c8e11a70b4dc85" ], "withdrawals": [], "blobGasUsed": "0x0", @@ -527,59 +349,853 @@ }, { "jsonrpc": "2.0", - "id": "np90", - "method": "engine_newPayloadV3", + "id": "np12", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x395eda9767326b57bbab88abee96eea91286c412a7297bedc3f1956f56db8b18", + "parentHash": "0x7167b82e4207928eb75fbe741b29d18fb5d469fa56c93941223667a07d183c44", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0d9d080dde44cc511dc9dc457b9839409e1b3a186e6b9a5ae642b5354acc6cc4", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xd3dd7c33bb46023c18a65ed23544cd1fa6cb94f44ed609ef6c2f7a8d66ed4f54", + "receiptsRoot": "0xa073f3de39b2256f0a223d83925e01b3ba1924797d00c334d406fa19adc17631", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x5a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", - "timestamp": "0x384", + "blockNumber": "0xc", + "gasLimit": "0x23f3e20", + "gasUsed": "0x21b95", + "timestamp": "0x78", "extraData": "0x", - "baseFeePerGas": "0x7dbb15", - "blockHash": "0x919c92e04181d139a4860cce64252ab9c14a5be9fa6adfc76b4b27f804fce2b9", + "baseFeePerGas": "0xc1273e2", + "blockHash": "0x23d7c4e274d71eee019119e9403d83ae181d9555d30a81aa0660c2103360f126", "transactions": [ - "0xf86949837dbb1682520894bbeebd879e1dff6918546dc0c179fdde505f2a2101808718e5bb3abd10a0a002f0119acaae03520f87748a1a855d0ef7ac4d5d1961d8f72f42734b5316a849a0182ad3a9efddba6be75007e91afe800869a18a36a11feee4743dde2ab6cc54d9" + "0xf87a0b840c1273e383011c328080a3600d380380600d6000396000f336156009575f355f555b305f525f5460205260405ff38718e5bb3abd109fa0d5560e311f2a2d1711dac8694b2a896df37d88199089c31f35080e3386eccbeaa0731d81520db66c0bd7fe2bb6f5afdf77615352197b3d909147d4fc390d87ef62", + "0x04f8d2870c72dd9d5e883e0c01840c1273e382b3b09400000000000000000000000000000000000000008080c0f863f861870c72dd9d5e883e94417fe11f58b6a2d089826b60722fbed1d2db96dd8080a039590402b13d3414ae54091a9923801c47a76664357c75650a8b84a185a1ba9aa012a807778ca1bc0a9132371ebd97e4b90b58842e8ca19c88ec19dec719b08c7601a042ed44bc123804a06c01dc4363881012c1d6fbf3ab10930af1ff17e7ea05e4c8a01aba6b1d0e03da9aa244f7f5148c7795db17a3864db721bbba1816f28c4accf3", + "0xf8720d840c1273e38301117094eda8645ba6948855e3b3cd596bbb07596d59c6038087696e766f6b65648718e5bb3abd109fa02ee2b3da4dcd45d653a95a338bc9e574509c9d2c5b9367faa2e6bc8c9a8553c4a0191fa50fa1a1b10764d71be4f17bc39286bba27c79ed50eda88a5f197e281886" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6ee04e1c27edad89a8e5a2253e4d9cca06e4f57d063ed4fe7cc1c478bb57eeca" + "0x6ee04e1c27edad89a8e5a2253e4d9cca06e4f57d063ed4fe7cc1c478bb57eeca", + [] ] }, { "jsonrpc": "2.0", - "id": "np91", - "method": "engine_newPayloadV3", + "id": "np13", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x919c92e04181d139a4860cce64252ab9c14a5be9fa6adfc76b4b27f804fce2b9", + "parentHash": "0x23d7c4e274d71eee019119e9403d83ae181d9555d30a81aa0660c2103360f126", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa5aea2e2c617a5a3a341e01c72fbf960e809dd589b4a988a04d50f6fb666b6c8", + "stateRoot": "0x886aac3e90114014faccd1d17dc60c5693a41594a48a31dc2c5049c9790ae96d", + "receiptsRoot": "0xe4c268cbbfa69cbaf9df3ba67fbc172a06bcbc45b5328a21232249c3fa7cd65d", + "logsBloom": "0x00000000008000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0xd", + "gasLimit": "0x23f3e20", + "gasUsed": "0x21259", + "timestamp": "0x82", + "extraData": "0x", + "baseFeePerGas": "0xa92fa1e", + "blockHash": "0xcbe5c6da730320128cc63a3c2454ede30738fa0d59a9e9de2e90f58b1938333a", + "transactions": [ + "0x02f8ab870c72dd9d5e883e0e02840a92fa1f830249f09400000961ef480eb55e80d19ad83579a64c007002843b9aca00b838b917cfdc0d25b72d55cf94db328e1629b7f4fde2c30cdacf873b664416f76a0c7f7cc50c9f72a3cb84be88144cde91250000000000000d80c080a0cb1c18b2bec62be2b64921b9d3ba10e7803970317a6b472986f52e5b6b5e6e08a043a8be395aef9cb8873067302ca16e2009f572c46a3594e253107e18dc26f892" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x36616354a17658eb3c3e8e5adda6253660e3744cb8b213006f04302b723749a8", + [ + "AXQ17TCotK6wh3zvDG6M/+g064ZfuRfP3A0lty1Vz5TbMo4WKbf0/eLDDNrPhztmRBb3agx/fMUMn3Kjy4S+iBRM3pElgA0AAAAAAAA=" + ] + ] + }, + { + "jsonrpc": "2.0", + "id": "np14", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xcbe5c6da730320128cc63a3c2454ede30738fa0d59a9e9de2e90f58b1938333a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x273a92dcd7e5b69db9a05c78121c8a932bb3bfd03e53b49fc7cb0bc8133bd63d", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0xe", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x8c", + "extraData": "0x", + "baseFeePerGas": "0x9430ac8", + "blockHash": "0xec7e5f7aada029114c5b556586e0e3c3ef3a39dde955f379ccea43ef93acabbc", + "transactions": [ + "0x01f86c870c72dd9d5e883e0f8409430ac98252089484e75c28348fb86acea1a93a39426d7d60f4cc460180c080a01861188078feab73f7703fe6588d303f43c3439f1f9b99e71fd094140e486cafa05eeb3113857b44050ab6cabcb24b8ee60528806a15592a7a97479c380a12d8c0" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc13802d4378dcb9c616f0c60ea0edd90e6c2dacf61f39ca06add0eaa67473b94", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np15", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xec7e5f7aada029114c5b556586e0e3c3ef3a39dde955f379ccea43ef93acabbc", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7e6fd4b6f397fe383c121c08a5b9b6d3ea854313afcbeec3060ee88b5b2f782d", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0xf", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x96", + "extraData": "0x", + "baseFeePerGas": "0x81afdf7", + "blockHash": "0x7599aa2261eece5d6075f09401692a0ee37815ad63946cc80ab3ba29838c00f8", + "transactions": [ + "0xf86a1084081afdf8825208940c2c51a0990aee1d73c1228de15868834155750801808718e5bb3abd10a0a057f5046223be25b7a2749c5f8b63468d67191af95b146876ed91d962e1323a97a04041fb4e18f34572224c21f024e7f744d1fc259c3e6335016f484af0231b9fae" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x8b345497936c51d077f414534be3f70472e4df101dee8820eaaff91a6624557b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np16", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x7599aa2261eece5d6075f09401692a0ee37815ad63946cc80ab3ba29838c00f8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xfc9e1c12454ca1c0629272b15771d8fd75dc9c071784eb7674454da05238fc92", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x5b", - "gasLimit": "0x47e7c40", + "blockNumber": "0x10", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x38e", + "timestamp": "0xa0", "extraData": "0x", - "baseFeePerGas": "0x6e05f1", - "blockHash": "0x17a574ee7489840acc4a8aecd1d7b540ba9b033b7236c13d0b0a5403ff07f7f3", + "baseFeePerGas": "0x717e832", + "blockHash": "0x60576c148e7ac42f9d36ee36a7df5a89241609f624502b248b5cf710ed269a4c", + "transactions": [], + "withdrawals": [ + { + "index": "0x0", + "validatorIndex": "0x5", + "address": "0x5f552da00dfb4d3749d9e62dcee3c918855a86a0", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xe958485d4b3e47b38014cc4eaeb75f13228072e7b362a56fc3ffe10155882629", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np17", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x60576c148e7ac42f9d36ee36a7df5a89241609f624502b248b5cf710ed269a4c", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x9d25087eccbadc71b6dcb4f1b429c3e1e1bd74e1adaadc358dbe96706df3dce9", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x11", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0xaa", + "extraData": "0x", + "baseFeePerGas": "0x634eb2c", + "blockHash": "0x8cd31f14889acd865b0ad0b2fd746586f29e87941166bf7087dc8bb429f01554", + "transactions": [ + "0xf88511840634eb2d8301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a06eec2c18bcf77ec57bab296d887982308ce7ee01c04883b1c667d2b3f99844e0a07f927348927013d0def756a6aaeb1626cbbb82978b0238c1bede7cca96c16f8d" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x3346706b38a2331556153113383581bc6f66f209fdef502f9fc9b6daf6ea555e", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np18", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x8cd31f14889acd865b0ad0b2fd746586f29e87941166bf7087dc8bb429f01554", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x2830ff653bec149b7a571e05ee9416397aeb6f859701a4aff1e6ae20c63e3386", + "receiptsRoot": "0x271e2e5c8c30a31dfe415c355346b4698b7b3ab4fc4ecbf5602fbc12e20eae8a", + "logsBloom": "0x00000000000000000000000000000000008000800400000000000082000000200000000000000000000000000000000000000100000000400000100040000000000000000000000000000004000002000000010000000000000000000200000000000000000000000100000100000000000000000000000000000000000000040004000000000000000400000000000000000000001000000008000000000000000000000000000004000000000000000020000000000040000000000000000000000000000020040000000000000000000000000100000000000000000000000000000084000200000800000000000000000000000000004000000000200000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x12", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0xb4", + "extraData": "0x", + "baseFeePerGas": "0x56f6b1e", + "blockHash": "0x3e48b276f3b3209dda302780f9c8e4459d2c9378f4508c0fc4f9d26e6a5d173f", + "transactions": [ + "0xf87c1284056f6b1f83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0f902fd4698ffef3b8ddc1c375497f85fe2b56388afcb636bc563116f9e87b16ea07c32cfaac5a1ca683d7f0904ad62b5ebee224cc953d113856124601436367415" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x346910f7e777c596be32f0dcf46ccfda2efe8d6c5d3abbfe0f76dba7437f5dad", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np19", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x3e48b276f3b3209dda302780f9c8e4459d2c9378f4508c0fc4f9d26e6a5d173f", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x5e0abc8d3e6a776260485305d8dd0c8ef63d7b25394d96c104b5c9ff579bf51e", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x13", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0xbe", + "extraData": "0x", + "baseFeePerGas": "0x4c2165b", + "blockHash": "0x905f74a6377ead9037c78e9008bbb788c74c1fdb7f993b4820e24be5dde9c9af", + "transactions": [ + "0xf867138404c2165c8302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa032f1d63abf50a1b102ee291e13581a0d6ce2eddf511d01a3ebeec5ce97cd839ca02dfb6796f006554686a474dee866c9ddade4b3ee3398f1d5fed3a865c098fa9a" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xe62a7bd9263534b752176d1ff1d428fcc370a3b176c4a6312b6016c2d5f8d546", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np20", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x905f74a6377ead9037c78e9008bbb788c74c1fdb7f993b4820e24be5dde9c9af", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xc97170cf07d54c88244ab7495de7b219a0c5e53de8a00fedb6a1698d05c072e4", + "receiptsRoot": "0x3e5b0c08f66fb3479a54ec93bdafda95f7988f6c27dc427c3a8c0ef1e491e9f2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x14", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0xc8", + "extraData": "0x", + "baseFeePerGas": "0x42acb03", + "blockHash": "0x35398f9b164bfdf8f4b4cde5181a9d96bb37947181332dc7977dc2360bee6300", + "transactions": [ + "0x02f8d6870c72dd9d5e883e140184042acb04830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c7346f7df2f4852bf656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0cb55d89f2ee070d017b426876d6072d91c2a7311ade9a1bed2f8200127ec380e80a08897d5c6dc27a43adfcf912ec9c7ec1bc94763ecf00a0e0f7bb5d48a81c6de74a05708b993e4e74cbfdb940a5bf5a2a09d5a9840e94bfe40662a097bd324614372" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xffe267d11268388fd0426a627dedddeb075d68327df9172c0445cd2979ec7e4d", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np21", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x35398f9b164bfdf8f4b4cde5181a9d96bb37947181332dc7977dc2360bee6300", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x5552828e6c3bbf0c5a79f916e732ef9b622a20bd65a36765220a2ef3eace5ee1", + "receiptsRoot": "0x9e8e0dcc70def6a3ae4631d1a635ce268a142352191bd2736faa4ea3e1ddb5b1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000800000000000000000000000000000000000000000000000004000000000000200000008000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x15", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0xd2", + "extraData": "0x", + "baseFeePerGas": "0x3a5cf93", + "blockHash": "0x4a4aef4730ba6155773a9e5c7e0c5f25a552d187687d59ad81b4a86c9f15a9fb", + "transactions": [ + "0x01f8d5870c72dd9d5e883e158403a5cf94830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c470b103921f87d93656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0f77c749ecb156f605e2334b14caea388100bed09b4c16579c952a96e9035562901a04025efe7ff5d26258dc328878721531502592da19dfa528c3fe3e4af4ae32648a02425bd922df542ec69f5e1175f7dd0193e9610d715978a5e8ba70ec06cdd6e28" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x23cc648c9cd82c08214882b7e28e026d6eb56920f90f64731bb09b6acf515427", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np22", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4a4aef4730ba6155773a9e5c7e0c5f25a552d187687d59ad81b4a86c9f15a9fb", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xfc375dd0b2d82dba534d316a0ddc2fd9cce0f131e0cb2520059a96ebd4110f57", + "receiptsRoot": "0xa6d78192909ccc0689aa6ab6ad1383a53f32ab9f1941734dd79ec970c9bb581f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000008000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x16", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0xdc", + "extraData": "0x", + "baseFeePerGas": "0x33167db", + "blockHash": "0xb3c7f4d24254129c2621485e664106ca2c2d08337672a2c8e484524b6e0dd0fb", + "transactions": [ + "0x03f8fc870c72dd9d5e883e160184033167dc830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c3e08783bf128a680656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a41cb4f2ab2731a8889754ae1a340c666cb8107b497b922073df80a9b255e31b83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0a585e353498ce5174d60739a0b63435439e46487cdbb28b9735d3f2f75ce517da059f052093e5d64f3343fb0b5100e76c3a990fa831d8002117638b02f4072f942" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x47c896f5986ec29f58ec60eec56ed176910779e9fc9cf45c3c090126aeb21acd", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np23", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xb3c7f4d24254129c2621485e664106ca2c2d08337672a2c8e484524b6e0dd0fb", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xea3988f3c858eef128aa58daea75b61e4bf315f4dcca44bd49b3f7038efe7c9c", + "receiptsRoot": "0x489544b1af9649410f1f0b2edd686f702467f24446ecc3926b905d196f153cff", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x17", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0xe6", + "extraData": "0x", + "baseFeePerGas": "0x2cb82da", + "blockHash": "0x25e8e33978b09de34a49b2595fd3dfe13d0f8c9a8939ca6c88376292459ec533", + "transactions": [ + "0xf877178402cb82db830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028caaccee2fba6608ff656d69748718e5bb3abd10a0a02f5170b3be2a8b1ea396ce6d7e8328e9fc89e1feeedff915163a421f253066eba04ea5e11797ab87ab71e2affaad4f4d53addaf82345c93a050892af864870dd6f" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x6d19894928a3ab44077bb85dcb47e0865ce1c4c187bba26bad059aa774c03cfe", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np24", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x25e8e33978b09de34a49b2595fd3dfe13d0f8c9a8939ca6c88376292459ec533", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x94a104a2cc89c456366487a7ff541dd38b14800da5d7e74652cab2b633402a0a", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x18", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0xf0", + "extraData": "0x", + "baseFeePerGas": "0x2724ef3", + "blockHash": "0x4f350577873216755df98391d69caf01ba646006d88459326e2f2bc2acbbf0e0", + "transactions": [ + "0x02f86d870c72dd9d5e883e18018402724ef48252089414e46043e63d0e3cdcf2530519f4cfaf35058cb20180c001a08abdb3bb1c920c0a75c8e979079e8bfbd407843ba5aefa8ef97a88bd27329e84a006a953cb7369e2810022fd66d14fdeb5ddedf70d062975d966aa0e28bf690ad0" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xefc50f4fc1430b6d5d043065201692a4a02252fef0699394631f5213a5667547", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np25", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4f350577873216755df98391d69caf01ba646006d88459326e2f2bc2acbbf0e0", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xe6b25116fe80c641f9ae002e38ee0885699983cff8f25515795c4d7187af561a", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x19", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0xfa", + "extraData": "0x", + "baseFeePerGas": "0x2241b69", + "blockHash": "0xec6593f4d6535e923dce8d47de08d98f8d751ea078f186072fe46b3b745d5274", + "transactions": [ + "0x01f86c870c72dd9d5e883e198402241b6a825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df0180c080a0aa91f4ab09c290fb090ca2638cc97bc7af972b422ffa74f075e04865199b1456a06d7240f6be85ef4696869d78189e1d2b5d2441c4caf770b203f2ed4abf7da308" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x3cc9f65fc1f46927eb46fbf6d14bc94af078fe8ff982a984bdd117152cd1549f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np26", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xec6593f4d6535e923dce8d47de08d98f8d751ea078f186072fe46b3b745d5274", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x2169a20d6e248e2c5322a5b01f73acd038baf8efc185daba156bb17af84cd8b8", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1a", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x104", + "extraData": "0x", + "baseFeePerGas": "0x1dfab87", + "blockHash": "0xc342e54f189bd6e3099871e6ecdb5f5b85a409299decd86a08e5564e42d22aa7", + "transactions": [ + "0xf86a1a8401dfab88825208941f5bde34b4afc686f136c7a3cb6ec376f735775901808718e5bb3abd10a0a0bf906d9eaec05fd44a6c7c2d0b7f30d6de811ddef24d96db9e48497ff60a1484a074f6f7bf0aff7038f7769b4e1a5d35b76f72dac84e043b87ca0d90e2271b0783" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x63eb547e9325bc34fbbbdfda327a71dc929fd8ab6509795e56479e95dbd40a80", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np27", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xc342e54f189bd6e3099871e6ecdb5f5b85a409299decd86a08e5564e42d22aa7", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xf764dd8c400bd0cf0de446a478e786a16d8b6b6c772ec44f55aa63335254ef26", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1b", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x10e", + "extraData": "0x", + "baseFeePerGas": "0x1a3c730", + "blockHash": "0x750dd92f162fd79de0f147a4a5a6928ea06463f04ce9ccd6f85d128f726d75c4", + "transactions": [], + "withdrawals": [ + { + "index": "0x1", + "validatorIndex": "0x5", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x67317288cf707b0325748c7947e2dda5e8b41e45e62330d00d80e9be403e5c4c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np28", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x750dd92f162fd79de0f147a4a5a6928ea06463f04ce9ccd6f85d128f726d75c4", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd3cc1a6a6b477ad90f576880cd467fa97802149e48ba2976e6be835d077a8e6a", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1c", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x118", + "extraData": "0x", + "baseFeePerGas": "0x16f4e4a", + "blockHash": "0x851dbf7f27a98cf2fc320a858b96e89bfe8af9551e4aa966cd6ed4d4b5d9dac8", + "transactions": [ + "0xf8851b84016f4e4b8301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa01e147627a8b655495ffe95ecc114eeaf910bc89166f4ad45f626774a79c7b195a04c7dac20ac839c4dcaae197402b54589cff504b8dd6e8d084f90651d45193227" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x7fc37e0d22626f96f345b05516c8a3676b9e1de01d354e5eb9524f6776966885", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np29", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x851dbf7f27a98cf2fc320a858b96e89bfe8af9551e4aa966cd6ed4d4b5d9dac8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd2c58f66ca2ceae3eac008458fb5396d2e3c8e80e416d66037472875a4e07997", + "receiptsRoot": "0xd072fe68030b122d6d943712a735f4d9b12048b038b38ce8ca90d3da4f3d4f71", + "logsBloom": "0x00000009000000000020000000000000000000000000000000000000000000000000000000000000000008000000000000100000000000000000000800000200000010000000600000000000000800000000000020000000000002000000000400000000000010000000000000000000000000000000000000000000000200020000000000000000000004000000000000000020000001000000000000000000000000000000008000400080000000000600000100000000000000000000000000000000000000001000000000000000000001000000000000000000000000000000000000008000000020000008000000080000000000000000000040000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1d", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x122", + "extraData": "0x", + "baseFeePerGas": "0x141a677", + "blockHash": "0x95d530f6e64e5b60726d6f40f995fbcb099957cfaaf2765dc78684d4fccacb59", + "transactions": [ + "0xf87c1c840141a67883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a09d0cb094f38fc156df1e73cb965c52438c56eb5b3ff00a3128990667b4f8f77aa02a614f5723d63cb69b28b7faa6ab8c55807c9a3a9239d81599e48ce025f6c344" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc8c5ffb6f192e9bda046ecd4ebb995af53c9dd6040f4ba8d8db9292c1310e43f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np30", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x95d530f6e64e5b60726d6f40f995fbcb099957cfaaf2765dc78684d4fccacb59", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x69347f83eaca294d85b8085c403c1e6552b39f9074d8b0907ee4ca2f1052c46b", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x12c", + "extraData": "0x", + "baseFeePerGas": "0x11994f1", + "blockHash": "0x1da94a9b2bc22478c3c9e45591d3254ed48b2f15a68dcd86d272273bd362e1db", + "transactions": [ + "0xf8671d84011994f28302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0ea4b870e45a695e7e157f7af87905291f11956ae897a1806c4a3f7b4a3d06c37a0468b5ac7b003d53b820006ee1c1219d7c451aa2780c04d21f7566abb1fc54479" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xe40a9cfd9babe862d482ca0c07c0a4086641d16c066620cb048c6e673c5a4f91", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np31", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x1da94a9b2bc22478c3c9e45591d3254ed48b2f15a68dcd86d272273bd362e1db", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x04bfc46ce455b63d4618f74e4d8ecd958040f43843e6ad303245ade19058a95c", + "receiptsRoot": "0xfd4c826f3e7c6c8ac7c8e9205e3b6dbf4c97cf66bd1585ee4db643939a15a009", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1f", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x136", + "extraData": "0x", + "baseFeePerGas": "0xf69b87", + "blockHash": "0x0776e32e33ee61a75147584501827f9a7cef40e1198d62791acf4d7f5c50a55a", + "transactions": [ + "0x02f8d5870c72dd9d5e883e1e0183f69b88830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cfc9e175c02d62655656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a073286395f2a86bb5537d9b45ca7c681044645f31475a11d49285d6a0f028b8f001a0348a5f9cc0dfd726dc9c9720e8e8b111b768604032a87de10a6ea140b1abd3dfa04ae302c53544f8f00dda9b71b791c5d6450e26ea5baf697afbcd46eff9355334" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xe82e7cff48aea45fb3f7b199b0b173497bf4c5ea66ff840e2ec618d7eb3d7470", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np32", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x0776e32e33ee61a75147584501827f9a7cef40e1198d62791acf4d7f5c50a55a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xbf2c2c34b76a1bc162355b87de7cb815153c0a91a56f92d842c512a5fa61bdb2", + "receiptsRoot": "0x11a9a367c2a5ce735e23968b85f4f00c7f50f20f0b2901cc9c5b4b33b4959682", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000040000000000000000000000000000000000000000000000000000002004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x20", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x140", + "extraData": "0x", + "baseFeePerGas": "0xd7ddce", + "blockHash": "0x39032e04806c95bf605cab0f493454b349e86b17808b4b019a6fc264c58e570b", + "transactions": [ + "0x01f8d4870c72dd9d5e883e1f83d7ddcf830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cb524830fb1b95fef656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0415feb809041baabc4d9246223e40f1083963cbe1ef6dedb8b153e49d02ee7ce01a03a3dcce3ef39b2151f4c787cf3ad601d1b71e4659213f948f1661d8f0525c92ea055a309950e20ba06ac5d3e0e89805c14816e63153a7d3ef677407ecdd00e3c5b" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x84ceda57767ea709da7ab17897a70da1868c9670931da38f2438519a5249534d", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np33", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x39032e04806c95bf605cab0f493454b349e86b17808b4b019a6fc264c58e570b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x052055733a53c0f7febb45a9d8a41a2a3dd29ca97278c35849050cf6e4fad0f1", + "receiptsRoot": "0xaba497cc3d5037548e60d91b85c707f2444349ae159036631f95fdd7869f1f8c", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000800000000000000000008000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x21", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x14a", + "extraData": "0x", + "baseFeePerGas": "0xbcf517", + "blockHash": "0x7bfd33d91f0f065c4c0963ef3975dfacb13ebcd3b1d9433eeba5f26320bb453b", + "transactions": [ + "0x03f8fb870c72dd9d5e883e200183bcf518830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cbf21e84fccd0c2c0656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0b2416e7ca12669406e6cd5154ad5177841b7d0cddeb2760249c28e1aa151f97083020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0dbce1c078f5374f0da355497abc98d8233dd702e63355fc66d4b77f8aa645c0da02535209ac89839a34994622ac2b9f2fc0b1f45fb08f43a5579093585c9c62caa" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xe9dcf640383969359c944cff24b75f71740627f596110ee8568fa09f9a06db1c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np34", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x7bfd33d91f0f065c4c0963ef3975dfacb13ebcd3b1d9433eeba5f26320bb453b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x56312b12ec96358f46f673850692a02c7769fcc0af7e86e2cc6a31db672bfd34", + "receiptsRoot": "0x13bd42f63e98963d548495d33334a05c830e7aeb166aa5f1116b6601446a4685", + "logsBloom": "0x00000000000000000000000000000000000000000200000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x22", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x154", + "extraData": "0x", + "baseFeePerGas": "0xa56718", + "blockHash": "0xcbeea1d0322b931091bee7d7fd49ed48d09f35324c7837f3b51c1f9e017cdcc8", + "transactions": [ + "0xf8762183a56719830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cfd7bf8757ddb24d9656d69748718e5bb3abd10a0a06c07e8d0a7d3ba1f3a8dcb209e990148ed6a7f44e8263d932e6ee30b2ab5310ca05a5eca8431b6406a0910fd5dbfbce72e4b3cc8514cdfbe3b46b10efc533eba64" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x430ef678bb92f1af44dcd77af9c5b59fb87d0fc4a09901a54398ad5b7e19a8f4", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np35", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xcbeea1d0322b931091bee7d7fd49ed48d09f35324c7837f3b51c1f9e017cdcc8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x2ca02337777db57a1ab0266b72eeeb951770529e1e9cdc2e150b2b9f0a1a8365", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x23", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x15e", + "extraData": "0x", + "baseFeePerGas": "0x90c82f", + "blockHash": "0xdaecb35565efc8fe915c286637a2f664473681e90f9ab6e05d0aa02ecdcdc654", + "transactions": [ + "0x02f86c870c72dd9d5e883e22018390c8308252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c080a03c1d323db1f685c6ffd338c17c010fd81c6fd4e142a985fbe8ddabc7f4cb8737a02d8d268af499407f139c60e3ef6e5c2b465ef86bd9912313529427ecd20cff02" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xf7af0b8b729cd17b7826259bc183b196dbd318bd7229d5e8085bf4849c0b12bf", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np36", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xdaecb35565efc8fe915c286637a2f664473681e90f9ab6e05d0aa02ecdcdc654", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xed1385e367caa8d8f469626720d381eeb15cf18bb5b2d28a9fc1fb01d2a2521f", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x24", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x168", + "extraData": "0x", + "baseFeePerGas": "0x7eb453", + "blockHash": "0x4accb52ae0491cfaed5866f5296d8d15233a16ffd73c91735040c58cebaf7ff9", + "transactions": [ + "0x01f86b870c72dd9d5e883e23837eb454825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c0180c001a04f07315aebd92596d180363d42cb97af8cf0aa76441216f3548929b70dabeca4a03023bffff6c77cf2bebcd9139c9a938504c68bd739bd046002281a4331f1fc90" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xe134e19217f1b4c7e11f193561056303a1f67b69dac96ff79a6d0aafa994f7cb", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np37", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4accb52ae0491cfaed5866f5296d8d15233a16ffd73c91735040c58cebaf7ff9", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1d19c3aacd2f657d1835d032863abbcfda8db6bba9368c64e3def4e716a05599", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x25", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x172", + "extraData": "0x", + "baseFeePerGas": "0x6ee24e", + "blockHash": "0xa22225105655427813fb4e29887ef8ec1a18877bb441913fadce200903ba0f0f", + "transactions": [ + "0xf86924836ee24f82520894c7b99a164efd027a93f147376cc7da7c67c6bbe001808718e5bb3abd10a0a0ad08245b8162c9482e8c5a0dc7a50bbd4fbcf27bcf60eb2af5f73dc82db728eda048a4a5bbaedea5004b9be5f15e7babac229a7af181cc7146d3a998a7e8e0e481" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x9cc58ab1a8cb0e983550e61f754aea1dd4f58ac6482a816dc50658de750de613", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np38", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xa22225105655427813fb4e29887ef8ec1a18877bb441913fadce200903ba0f0f", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xaf9f3d14eb60e28d448c5c1177b6d23047481feae580fc5396e5165bfd370d45", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x26", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x17c", + "extraData": "0x", + "baseFeePerGas": "0x6109f9", + "blockHash": "0x6ad17c25de20d9f09aaff897681a87788d216791d9e33d2d4543b162f3c47423", "transactions": [], "withdrawals": [ { "index": "0x2", "validatorIndex": "0x5", - "address": "0x245843abef9e72e7efac30138a994bf6301e7e1d", + "address": "0xe7d13f7aa2a838d24c59b40186a0aca1e21cffcc", "amount": "0x64" } ], @@ -587,154 +1203,347 @@ "excessBlobGas": "0x0" }, [], - "0x36616354a17658eb3c3e8e5adda6253660e3744cb8b213006f04302b723749a8" + "0x79c2b067779a94fd3756070885fc8eab5e45033bde69ab17c0173d553df02978", + [] ] }, { "jsonrpc": "2.0", - "id": "np92", - "method": "engine_newPayloadV3", + "id": "np39", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x17a574ee7489840acc4a8aecd1d7b540ba9b033b7236c13d0b0a5403ff07f7f3", + "parentHash": "0x6ad17c25de20d9f09aaff897681a87788d216791d9e33d2d4543b162f3c47423", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd1e927e1a7106591aa46d3e327e9e7d493248786b4c6284bd138d329c6cb1fbb", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x69e1439c4d3d65155cc6997a6a8d9d64e23af139997f29f366c9fcbb4c94740d", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x5c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x398", + "blockNumber": "0x27", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x186", "extraData": "0x", - "baseFeePerGas": "0x604533", - "blockHash": "0x7848fe02daea45d47101fbe84b6d94576452c2d0cb9261bc346343b5b2df844f", + "baseFeePerGas": "0x54e8ba", + "blockHash": "0x5b65d43473b3132497d0fc75a2808f73a2808560785c6e7f55d2ac722047d291", "transactions": [ - "0xf8844a83604534830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0667955bfddc6500ad6a0a298d08a0fdeb453d483be41f7496f557039c99d5b8ea06ad5f6871f3d78ea543484d51590454f8a65b5b1b89f58992ff94a02a30c0c93" + "0xf884258354e8bb8301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa02a4cf21d43634cc09828755f9c853bd5019954d8139024fdb4edea7a37de03c1a01c6e3fe600e47ecd9c019960d38fc878cdce4937f178cac03d95fb0b257cac7e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc13802d4378dcb9c616f0c60ea0edd90e6c2dacf61f39ca06add0eaa67473b94" + "0xd908ef75d05b895600d3f9938cb5259612c71223b68d30469ff657d61c6b1611", + [] ] }, { "jsonrpc": "2.0", - "id": "np93", - "method": "engine_newPayloadV3", + "id": "np40", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x7848fe02daea45d47101fbe84b6d94576452c2d0cb9261bc346343b5b2df844f", + "parentHash": "0x5b65d43473b3132497d0fc75a2808f73a2808560785c6e7f55d2ac722047d291", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8d4e68f0a1ad7578b1627d665263c04856efa4eb4938014a8c794547d597f89b", - "receiptsRoot": "0xa37a62134a71ef21b16f2eee431b806a4d13c0a80a11ddeb5cbb18e3707aecdf", - "logsBloom": "0x00000000000000000000000002000000000021000000000000000000240000000000000000000000000004000000010000000000000000000000000000000000000008000000000000000000000000000020000000000000000400000400000000000400000000000000000000000000000000000080000004000000000000000000000000000800000000000000000000000000000000000000000000002000000080000002010000420000000000000000000000000040402002000200000000000000000000000000008000000000000000000000000100000000000000000000000000000000000084000000000080000000000000000000040000000000", + "stateRoot": "0x9ec651a3159991b6da7dfe19c6636291d50bafd2eff0a1673ad0235689da7367", + "receiptsRoot": "0x7e2b4724f582d1d4cb18b0c68b1651b6a1114918e60a553ace9bebd0b0778b72", + "logsBloom": "0x00000000000000000000000000000000000000000000000400000000004000000000000000000000800000000000020000000000021000000000000000000000000080000000010000000000000000002000000000000000000020000000000000000000000000200004000000000000400000000000000000000000000014000000000000000000000000000000000000000000000000000000000000200200000000800400000000000000000000020000000000000000000000000000000000800000000000000000080000000000040000400001080000000040002000000000000000000000000200010000000008000000000000000000000000100080", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x5d", - "gasLimit": "0x47e7c40", + "blockNumber": "0x28", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x3a2", + "timestamp": "0x190", "extraData": "0x", - "baseFeePerGas": "0x544364", - "blockHash": "0x6c5d29870c54d8c4e318523a7ea7fb9756b6633bbdf70dcb1e4659ff3564615b", + "baseFeePerGas": "0x4a5ae3", + "blockHash": "0xebf3316f9944a4d7686ca037353ab00ba9aba83839dbf6b81a1f17127bc97131", "transactions": [ - "0xf87b4b8354436583011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a09662003f67b0c146ecaa0c074b010d1f27d0803dc1809fd4f6ea80a5f09c34aea0100a5c0fbfdbee733f1baecb893a33ce2d42316303a5ddf1515645dfbb40d103" + "0xf87b26834a5ae483011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0c5d1f9d80dc521f85c9024ee685ec13c3a8cfa793d6bfcbcd47fd4244a0b4d7aa06995f77a29ec57b0005cd8044a79b8060fa046e6264f89617f4e3bdd57ae8f7f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x8b345497936c51d077f414534be3f70472e4df101dee8820eaaff91a6624557b" + "0xe0d31906b7c46ac7f38478c0872d3c634f7113d54ef0b57ebfaf7f993959f5a3", + [] ] }, { "jsonrpc": "2.0", - "id": "np94", - "method": "engine_newPayloadV3", + "id": "np41", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6c5d29870c54d8c4e318523a7ea7fb9756b6633bbdf70dcb1e4659ff3564615b", + "parentHash": "0xebf3316f9944a4d7686ca037353ab00ba9aba83839dbf6b81a1f17127bc97131", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbd07ab096fc1b3e50229bcff0fc5fca9e9f7d368e77fe43a71e468b7b0adb133", + "stateRoot": "0x6674d2364f011c039d71388ad814a8cc5b67b9373f0b04ea381257c780084826", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x5e", - "gasLimit": "0x47e7c40", + "blockNumber": "0x29", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x3ac", + "timestamp": "0x19a", "extraData": "0x", - "baseFeePerGas": "0x49bf97", - "blockHash": "0xe7b8c1ca432a521b1e7f0cf3cb63be25da67e3364cc0b02b0a28e06ba8deed80", + "baseFeePerGas": "0x4117af", + "blockHash": "0x9a93da70b45233339e8a591567fec5e1fab43884f5b56bece2e795fb964942c3", "transactions": [ - "0xf8664c8349bf988302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa03b3113a7b1919311fbc03ee25c4829b60f07341c72107de061da06eef7ec0856a01bc4eeb29301e1610984ee042f8236863ad78402d3d55c69a6922d67238dde75" + "0xf86627834117b08302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a05c7eb02efd38c05171b4af43db20a721c7f54087fbadabf662f1be055813d644a075cf5658966cc283f17b61be68dafe570cd75814c67977c33389d645fc37dbe4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe958485d4b3e47b38014cc4eaeb75f13228072e7b362a56fc3ffe10155882629" + "0x2318f5c5e6865200ad890e0a8db21c780a226bec0b2e29af1cb3a0d9b40196ae", + [] ] }, { "jsonrpc": "2.0", - "id": "np95", - "method": "engine_newPayloadV3", + "id": "np42", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe7b8c1ca432a521b1e7f0cf3cb63be25da67e3364cc0b02b0a28e06ba8deed80", + "parentHash": "0x9a93da70b45233339e8a591567fec5e1fab43884f5b56bece2e795fb964942c3", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4a154c665e5b68adadf9455bd905da607f0279b5d2b4bfb0c1a3db5b6a908d4d", + "stateRoot": "0x35ab337c3fe3a3d6a7e5253bc5c51f9e6c257f8251fd43344e1a48d58f525a9d", + "receiptsRoot": "0x722bce83ca7ab873dd94d9f22d3df08cca281d5eec34fba8690b529983de0c5c", + "logsBloom": "0x00000000000000000000000000000000000000000000000100000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x2a", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1a4", + "extraData": "0x", + "baseFeePerGas": "0x3901f3", + "blockHash": "0x4087ae9e71cbdae794c137d61684e08835fa8a6c13e9e5a001163eaccf6b842f", + "transactions": [ + "0x02f8d5870c72dd9d5e883e2801833901f4830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c29db68258899c2fe656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a035f96bc70aa62a539fa99d9153b0f8aaa4594abf70cc8a8d9018e04e39a1798201a016ee4f37bff1c0a3c97047b92910aaaee0e6b82ec659d142ff905846a2c71e93a071ec71aa535ac3a0bb492e70cb4394ad0212af2b7c3000a45e29bd59a281097e" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x523997f8d8fed954658f547954fdeceab818b411862647f2b61a3619f6a4d4bc", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np43", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4087ae9e71cbdae794c137d61684e08835fa8a6c13e9e5a001163eaccf6b842f", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1e43cd66bda4a9c2aa6935b12ecf1051525c9f072c175f247c8d5d94b02cf2c9", + "receiptsRoot": "0x28e6deb0dbc0cb34fb9f35a37cac83443c3a4ff2c1b3266bd55c0a9ebeeff704", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000200000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000008000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x2b", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1ae", + "extraData": "0x", + "baseFeePerGas": "0x31e6ba", + "blockHash": "0x9eb1dcefdae7fc61fdacb218921236acad55350bda6c209931d89b65dcfd0eeb", + "transactions": [ + "0x01f8d4870c72dd9d5e883e298331e6bb830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ceec855297bb026a7656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a089c17d9392b73a55738ba19aae192f2f9c5612dc8bd803ca23b9c2fb9c309e5680a07de4f993b57649b9621caacf9230b83e142e5f8dcc05fe53f31d7535a99bc4b8a04db26984ed0c47d7b7077db4468503112cd850621902f1321db6de4951171933" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xbe3396540ea36c6928cccdcfe6c669666edbbbcd4be5e703f59de0e3c2720da7", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np44", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x9eb1dcefdae7fc61fdacb218921236acad55350bda6c209931d89b65dcfd0eeb", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x523c5a14c0fc2ea830dfb85907766c4d902eeb56315cc1802aa94c92c906abb1", + "receiptsRoot": "0xc121a079255bfaefd387d136353ea50d122f14486efe1e24d992102de7da41c1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000400000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x2c", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1b8", + "extraData": "0x", + "baseFeePerGas": "0x2bae48", + "blockHash": "0xc0fd1e13ad5b4c7102e278a96573f8cf66809bd6c3445f5c3650189596c0d680", + "transactions": [ + "0x03f8fb870c72dd9d5e883e2a01832bae49830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c2276cc05d723a1e7656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a011f0a8ac2adda075c95bbf6be534e3254dafa759f62cbcf0e91bc6f0335e70aa83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a08dba995d002055ec395867b0cdc2d2986ad057cf63108390ab1d9b4ef1cd6fd0a07f800af40435fc91931b25c9c3c3015fb09c5436c0939d66534ee8dddfc40236" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x2d3fcfd65d0a6881a2e8684d03c2aa27aee6176514d9f6d8ebb3b766f85e1039", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np45", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xc0fd1e13ad5b4c7102e278a96573f8cf66809bd6c3445f5c3650189596c0d680", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xdfa9d2b7cda13e260da200f697f2387095f8318b19915c94ad7633cf6f4759fc", + "receiptsRoot": "0xea990763b2324d2121505b0b74be5126cd1a040b1a13d3d0e4d04db99f66df01", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000020000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x2d", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x1c2", + "extraData": "0x", + "baseFeePerGas": "0x263c58", + "blockHash": "0x84af2f9798e57abc0431d1f0156b45f6521c7720ff0215459af9fa0553eb47e5", + "transactions": [ + "0xf8762b83263c59830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c580abd8a903ed7d3656d69748718e5bb3abd10a0a07c3c3d9aa157f22797519c2adcb77137a16f0a978442ad7213b31129e399269ca053840caea2b9c28f05566f931ec7cda3061b26cb4cea9f805af8353f89cf776b" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x7ce0d5c253a7f910cca7416e949ac04fdaec20a518ab6fcbe4a63d8b439a5cfc", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np46", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x84af2f9798e57abc0431d1f0156b45f6521c7720ff0215459af9fa0553eb47e5", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xca5cbb3c9dd01d9af5180eae51d6d8f564132488f10c5d85f2aad41f76c62563", "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x5f", - "gasLimit": "0x47e7c40", + "blockNumber": "0x2e", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", - "timestamp": "0x3b6", + "timestamp": "0x1cc", "extraData": "0x", - "baseFeePerGas": "0x408f22", - "blockHash": "0xaa62b2faefe50fe1562f3fb5bf96a765ca7c92164465e226fc9a8ba75cabc387", + "baseFeePerGas": "0x217809", + "blockHash": "0xcb33361cca9889678cb7c5fe9a4fe345d929cc71e8f6e53e5cd310820e01dff3", "transactions": [ - "0x02f86c870c72dd9d5e883e4d0183408f2382520894d2e2adf7177b7a8afddbc12d1634cf23ea1a71020180c001a08556dcfea479b34675db3fe08e29486fe719c2b22f6b0c1741ecbbdce4575cc6a01cd48009ccafd6b9f1290bbe2ceea268f94101d1d322c787018423ebcbc87ab4" + "0x02f86c870c72dd9d5e883e2c018321780a8252089483c7e323d189f18725ac510004fdc2941f8c4a780180c001a097d5d861629fb7c4c15662cb0459b76abc9217b963ffa402806e8a13235e6c3ca006f42c3ec85ac47fc5eae74bbfb58c55d113ca213b6d8a31b9b284f4c53606ee" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x3346706b38a2331556153113383581bc6f66f209fdef502f9fc9b6daf6ea555e" + "0x4da13d835ea44926ee13f34ce8fcd4b9d3dc65be0a351115cf404234c7fbd256", + [] ] }, { "jsonrpc": "2.0", - "id": "np96", - "method": "engine_newPayloadV3", + "id": "np47", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xaa62b2faefe50fe1562f3fb5bf96a765ca7c92164465e226fc9a8ba75cabc387", + "parentHash": "0xcb33361cca9889678cb7c5fe9a4fe345d929cc71e8f6e53e5cd310820e01dff3", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3b2adb11488a7634a20bc6f81bcc0211993fe790f75eeb1f4889a98d1bdbcb37", + "stateRoot": "0x539e0d194f8e6bfb6c425d7f8753df0d75fb12220efdaaa621e7ef7c97327a38", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x2f", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1d6", + "extraData": "0x", + "baseFeePerGas": "0x1d4a3a", + "blockHash": "0xef24d6293c96bd11abe059e96317856581f1736cf94786dbc0fc0d366df430af", + "transactions": [ + "0x01f86b870c72dd9d5e883e2d831d4a3b825208941f5bde34b4afc686f136c7a3cb6ec376f73577590180c080a0868fba18eb3230967166a7edbdc2504c2d1efd0d49f778d4a60e8b0db2587028a016086a90bb652179a93788f55823d5d8d8ca3fcf22e7e36dbf6c45eec6bdae67" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc5ee7483802009b45feabf4c5f701ec485f27bf7d2c4477b200ac53e210e9844", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np48", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xef24d6293c96bd11abe059e96317856581f1736cf94786dbc0fc0d366df430af", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x48b9e8211c2ddabfb64514a6e5dc2f63fabe2bad8a06e9a8b553c43a60b13718", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x30", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1e0", + "extraData": "0x", + "baseFeePerGas": "0x19a1ff", + "blockHash": "0x95d87d14848a52aae340beecba232b70e909de98a3e2648fd44b66b73f7e12f8", + "transactions": [ + "0xf8692e8319a2008252089483c7e323d189f18725ac510004fdc2941f8c4a7801808718e5bb3abd10a0a0847f750f8cd8a5d53ccb55b2b59b1c8aed393e7eef8cb47abdefe512f4b21548a04b7305134a0b0043633b2f39f5d80333a8355e51d412735d78de08afa3f4b410" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x0fc71295326a7ae8e0776c61be67f3ed8770311df88e186405b8d75bd0be552b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np49", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x95d87d14848a52aae340beecba232b70e909de98a3e2648fd44b66b73f7e12f8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xf439de1a0caaaebf3494a15de8803730dc41ac7ccd216cff2a4dcb7230581d44", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x60", - "gasLimit": "0x47e7c40", + "blockNumber": "0x31", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x3c0", + "timestamp": "0x1ea", "extraData": "0x", - "baseFeePerGas": "0x387e65", - "blockHash": "0x6a6df67e09c4411bb89664cbc78f78237bb6a2fc299bc6a682cca406feb8dd4d", + "baseFeePerGas": "0x166eaa", + "blockHash": "0xb5e2e62689ca47b11879ba997cd532c410ab09f03719817fd33dc6923d990a03", "transactions": [], "withdrawals": [ { "index": "0x3", "validatorIndex": "0x5", - "address": "0x8d33f520a3c4cef80d2453aef81b612bfe1cb44c", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", "amount": "0x64" } ], @@ -742,154 +1551,347 @@ "excessBlobGas": "0x0" }, [], - "0x346910f7e777c596be32f0dcf46ccfda2efe8d6c5d3abbfe0f76dba7437f5dad" + "0x7313b4315dd27586f940f8f2bf8af76825d8f24d2ae2c24d885dcb0cdd8d50f5", + [] ] }, { "jsonrpc": "2.0", - "id": "np97", - "method": "engine_newPayloadV3", + "id": "np50", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6a6df67e09c4411bb89664cbc78f78237bb6a2fc299bc6a682cca406feb8dd4d", + "parentHash": "0xb5e2e62689ca47b11879ba997cd532c410ab09f03719817fd33dc6923d990a03", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd67c810501ca4f4ee4262e86dcaf793ca75637249bf157dee4800274372f236f", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x253153c88c427fd59bb0022d9ee7e77c1c82ad3df936e4adcddbac5606b68ddf", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x61", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x3ca", + "blockNumber": "0x32", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x1f4", "extraData": "0x", - "baseFeePerGas": "0x316e99", - "blockHash": "0xfec8ebc1c3d312ec3537d860b406110aeac3980763165d0026ecab156a377bdf", + "baseFeePerGas": "0x13a0d5", + "blockHash": "0x56110ba58fe532a71688f5cb3ff7129f7e9636d4aaf69a4347f70299b6f21a22", "transactions": [ - "0xf8844e83316e9a830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a036b2adb5bbd4d43198587067bf0b669e00862b0807adb947ee4c9869d79f9d8ca063e0b200645435853dceed29fd3b4c55d94b868a0aa6513ca6bd730705f2c9ef" + "0xf8842f8313a0d68301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a06084bb9d0485fb800f9fe54ad691985f8b129c9a041f731d464e6a69a62ba9c1a01b4e93d85984bd5c0dac90720de54f0482ac2cd9c9177650ebb85a4c29833c53" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe62a7bd9263534b752176d1ff1d428fcc370a3b176c4a6312b6016c2d5f8d546" + "0x2739473baa23a9bca4e8d0f4f221cfa48440b4b73e2bae7386c14caccc6c2059", + [] ] }, { "jsonrpc": "2.0", - "id": "np98", - "method": "engine_newPayloadV3", + "id": "np51", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfec8ebc1c3d312ec3537d860b406110aeac3980763165d0026ecab156a377bdf", + "parentHash": "0x56110ba58fe532a71688f5cb3ff7129f7e9636d4aaf69a4347f70299b6f21a22", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xae82dda9df38bcc8d99e311b63ae055591953577b6b560840658eca24ecacee9", - "receiptsRoot": "0x675ab823f90b9bdd3d04afb108bc1a1dcd77654a0de4c8a539e355b6d24f29f4", - "logsBloom": "0x10000000000000000010000000000020000000000008000000000000000000000000000000000000000000020000000000000000000000000000040000010000000000000000000000000000000000000000000000008000000000000000000000000080000110000000000800000002000000800040800000000040000000000000004000000000001000000000000000000000000000000000008000000000000000000000000000000020010080001000000000000000000000000004008000004000008000000000000000040000000400000000000001000000000000000000000008000000000000000000000200000000000000000000000000000000", + "stateRoot": "0xc8862c70a77a3de6bbc1d10421e0125c3e711c9bd6d4f9357e1ebdcf97757185", + "receiptsRoot": "0x3a82faa3f7e8c825464303587a1e69b4bad3780148937c8746f832aebb601f7f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000020000004000000000000020000000000004400000000000000000080000000000000000000000000000000000800000000000000000000400000002000801000000000000000000001200000000000000000000000000000000000000000000000000000000000000002000000000000000200000000000000000000400000000000000000000000001000000000000000000000200000000040000000800000004000004800000000000000000000000000000008000000000004000000000000000000000000000000000000020000048800000000000002000000000000000000000800820", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x62", - "gasLimit": "0x47e7c40", + "blockNumber": "0x33", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x3d4", + "timestamp": "0x1fe", "extraData": "0x", - "baseFeePerGas": "0x2b4449", - "blockHash": "0x3124d842afa1334bb72f0a8f058d7d3ad489d6c6bd684f81d3ecdf71d287f517", + "baseFeePerGas": "0x113041", + "blockHash": "0x2e693ca7593217b296154d482519dd780931e96b006b2deb05490fc2375c8c92", "transactions": [ - "0xf87b4f832b444a83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0824522ae97a912dd75a883798f4f296d960f6a7be8510e2a4a121d85f496da16a008cade93390e31f7b0e6615b4defe3bd4225b7a4d97a7835c02ad0b4d004fb5b" + "0xf87b308311304283011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0ebf28cffb555f6149bccfa9a4e6e960534d962c25699da92f3467dcadd4f65a1a02e18b53fd5d4b16988e165ab3396984f33958aec50064099cba0056107c6c647" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xffe267d11268388fd0426a627dedddeb075d68327df9172c0445cd2979ec7e4d" + "0xd4da00e33a11ee18f67b25ad5ff574cddcdccaa30e6743e01a531336b16cbf8f", + [] ] }, { "jsonrpc": "2.0", - "id": "np99", - "method": "engine_newPayloadV3", + "id": "np52", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3124d842afa1334bb72f0a8f058d7d3ad489d6c6bd684f81d3ecdf71d287f517", + "parentHash": "0x2e693ca7593217b296154d482519dd780931e96b006b2deb05490fc2375c8c92", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x588419f24b32499745bbae81eb1a303d563c31b2743c8621d39b820c2affb3cb", + "stateRoot": "0x21ce67a7cbd6ace7dc42fb2e8c98a63ca87ddb33a0ad3a31b16ffc2bec255c65", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x63", - "gasLimit": "0x47e7c40", + "blockNumber": "0x34", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x3de", + "timestamp": "0x208", "extraData": "0x", - "baseFeePerGas": "0x25de20", - "blockHash": "0x53d785a42c58a40edbc18e6bee93d4072a4281c744f697f9b5cae1d0b3bf2962", + "baseFeePerGas": "0xf0c1c", + "blockHash": "0x919d586bdedaf4fb38996e5a32eaa14f753a1babb1da62c6d0aa2035005b5d86", "transactions": [ - "0xf866508325de218302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0744b7f5fb26cc6dd16b1849d0c04236e3b4e993f37e5b91de6e55f5f899450baa0456225c91372bddd4e3a1dde449e59ad62d63f0c850f9b869870ea2621494fd7" + "0xf86631830f0c1d8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a03ea49161c9b977393c9d765e2286c1142f8529323b7ef0e6b68dda28f1239603a032b36762398e02c8368d0fe69ec76b5fba945c136a7e06304a58cf2b1b62729a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x23cc648c9cd82c08214882b7e28e026d6eb56920f90f64731bb09b6acf515427" + "0xe651765d4860f0c46f191212c8193e7c82708e5d8bef1ed6f19bdde577f980cf", + [] ] }, { "jsonrpc": "2.0", - "id": "np100", - "method": "engine_newPayloadV3", + "id": "np53", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x53d785a42c58a40edbc18e6bee93d4072a4281c744f697f9b5cae1d0b3bf2962", + "parentHash": "0x919d586bdedaf4fb38996e5a32eaa14f753a1babb1da62c6d0aa2035005b5d86", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xfee7a27147c7984caec35dc4cee4f3a38fee046e5d8f17ce7ec82b982decd9aa", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xda4cd278427ad08c2147716f414b9daab40231ade9fcb1d42baebb8e4ba56d46", + "receiptsRoot": "0x46c9ff6a21405f72ad433e6b8aa71b50f3fb0a5c7fbeb964cb561cfa5fd3cf7e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000001000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000020000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x35", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x212", + "extraData": "0x", + "baseFeePerGas": "0xd2da8", + "blockHash": "0x978425ebd54536bfd17945cf57726cd02fc25b083bc9332b7b4c8a94c37762bb", + "transactions": [ + "0x02f8d5870c72dd9d5e883e3201830d2da9830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cac2ee5432174b752656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0efcb86facadbec33b8779888975eacca8f44a9073a845521617f1fb30e1ac81801a05fae983b0fa627652888859db16b05d933c27604a4c193629f58fac19ee73d12a05419fe7056d1fdb665bca996c17944711f339966334a962f767133687b832fa7" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x5b5b49487967b3b60bd859ba2fb13290c6eaf67e97e9f9f9dda935c08564b5f6", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np54", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x978425ebd54536bfd17945cf57726cd02fc25b083bc9332b7b4c8a94c37762bb", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0810e4cc0f16ec17edf78a400c8efee493c863c7ef2ed760356855e7298e4fea", + "receiptsRoot": "0xa7bb91000287f7c0128087719cc6ddcd616ab350484fb520e76b6e581d5ebd25", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000002000000000000000000000004000000000000200000000000000000000000000002000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x36", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x21c", + "extraData": "0x", + "baseFeePerGas": "0xb891d", + "blockHash": "0x808ecd5038418740fc4b27954cdd2e4952569e8062b846b5cdd234b1eaaf7795", + "transactions": [ + "0x01f8d4870c72dd9d5e883e33830b891e830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c5201fc7d087c0d9b656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a09038344c39b01167bfa8e99a6425d34bca24c27ceb191e8eba70ab5a8f719ce501a01810fe081a9df9de52cf2baaed3f136cdd16ed6fb3c860aa71f41ba7096ad1c5a06c9e05751e206ff38b9e192289b24bf8962d77448351b1f35dc5b431ebdc0636" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x57b73780cc42a6a36676ce7008459d5ba206389dc9300f1aecbd77c4b90277fa", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np55", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x808ecd5038418740fc4b27954cdd2e4952569e8062b846b5cdd234b1eaaf7795", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xe24e18212ede77b435698b2c3edcd891f73d208151d14021bdb894c4f944f6e5", + "receiptsRoot": "0x2798a949b707f2f5df2e046ea3e8bb201e9d6f7b10018f2d35c5ec9fa80c8885", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000004000000200000000000000000000000000002000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x37", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x226", + "extraData": "0x", + "baseFeePerGas": "0xa18fe", + "blockHash": "0x4313be4af809c236c319dbd5dad18e0d030f610e7e4cacef0ff8b26af563b046", + "transactions": [ + "0x03f8fb870c72dd9d5e883e3401830a18ff830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038ce62b8536019651e7656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a08460e232c64e6cd9f816c02d855c892755984ebbb91592e683cda80aaba4ba2283020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a099dc58693b7dfd97272436ef8a2bab266caec51f233baa1108f5885449eb4f2ca06c0d1d946a7c787695511505281cce9c65b4e6ab824ea52b608399c8013460c5" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x217e8514ea30f1431dc3cd006fe730df721f961cebb5d0b52069d1b4e1ae5d13", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np56", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4313be4af809c236c319dbd5dad18e0d030f610e7e4cacef0ff8b26af563b046", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x8e5be0f31660f917fc9ef594f2952008faf8b5b7d86ebde604cc2d12ca6934e7", + "receiptsRoot": "0x8a60bb1e24339f5115c680df6608b457500fc8f3313d738aacab165a72e6e978", + "logsBloom": "0x00000040000000000000000000000000000000000040000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x38", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x230", + "extraData": "0x", + "baseFeePerGas": "0x8d6c2", + "blockHash": "0xcad24a57225330d06226b15cd3b5be7b0f2a42fef155e489994f7026f79924f4", + "transactions": [ + "0xf876358308d6c3830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c74fb911b03a9f447656d69748718e5bb3abd109fa09b1980b11de8f043e965487b78594b788c64434b74d434201051bbfc4f2472c6a068aa5f4cb9982931e79579100e0fd5ac4c0a6ee46a7a09dee7fe150f900dee95" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x14b775119c252908bb10b13de9f8ae988302e1ea8b2e7a1b6d3c8ae24ba9396b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np57", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xcad24a57225330d06226b15cd3b5be7b0f2a42fef155e489994f7026f79924f4", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xabe5b798fd9af1679cb95f39a37df8944585ad8cebc7b8ea81a2b372d9d55e12", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x64", - "gasLimit": "0x47e7c40", + "blockNumber": "0x39", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", - "timestamp": "0x3e8", + "timestamp": "0x23a", "extraData": "0x", - "baseFeePerGas": "0x212635", - "blockHash": "0x96d2a59527aa149efe64eef6b2fbf4722c9c833aba48e0c7cb0cb4033fa1af5e", + "baseFeePerGas": "0x7bca9", + "blockHash": "0x16e634e48fc62762ce8fc1762c6bfd34e94b3533b98a5fb1bbd504b131a64a65", "transactions": [ - "0xf86951832126368252089418ac3e7343f016890c510e93f935261169d9e3f501808718e5bb3abd10a0a099aba91f70df4d53679a578ed17e955f944dc96c7c449506b577ac1288dac6d4a0582c7577f2343dd5a7c7892e723e98122227fca8486debd9a43cd86f65d4448a" + "0x02f86c870c72dd9d5e883e36018307bcaa8252089484e75c28348fb86acea1a93a39426d7d60f4cc460180c080a0e3cd72920d622e7c8f3317d1f8a8387e25524d15f7e5fa54b2376f750236cf4ca013736138281feef80a6a77396ab234e03d09b82ca141d8b26fa24af15063d135" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x47c896f5986ec29f58ec60eec56ed176910779e9fc9cf45c3c090126aeb21acd" + "0xe736f0b3c5672f76332a38a6c1e66e5f39e0d01f1ddede2c24671f48e78daf63", + [] ] }, { "jsonrpc": "2.0", - "id": "np101", - "method": "engine_newPayloadV3", + "id": "np58", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x96d2a59527aa149efe64eef6b2fbf4722c9c833aba48e0c7cb0cb4033fa1af5e", + "parentHash": "0x16e634e48fc62762ce8fc1762c6bfd34e94b3533b98a5fb1bbd504b131a64a65", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb1600603ea31446c716fece48a379fb946eab40182133a8032914e868bb4929e", + "stateRoot": "0x2fd54e41658c7a7134d46b16e8152a342d2e2993f81d8ab2dc0f25448e248b9e", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x3a", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x244", + "extraData": "0x", + "baseFeePerGas": "0x6c55b", + "blockHash": "0x39f1c7f651e1970418fd8a5e0786c83e813744d55ea965e7902112bc02f190ec", + "transactions": [ + "0x01f86b870c72dd9d5e883e378306c55c825208945f552da00dfb4d3749d9e62dcee3c918855a86a00180c080a018d4576c526d8b56ab73d3ec9929d86808d13d3e3c88a45a5ae82c590d492c7ea00cbd53212b5b966bc6af503f738b7f9ec274225664c2d75e15f6a701a24ba9f1" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x7d112c85b58c64c576d34ea7a7c18287981885892fbf95110e62add156ca572e", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np59", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x39f1c7f651e1970418fd8a5e0786c83e813744d55ea965e7902112bc02f190ec", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xfbe509b0b3251cebdcd95315fbbcb61f913a524602d35c03b5f270b667108f3a", + "receiptsRoot": "0x642cd2bcdba228efb3996bf53981250d3608289522b80754c4e3c085c93c806f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x3b", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x24e", + "extraData": "0x", + "baseFeePerGas": "0x5ecee", + "blockHash": "0xceccf9166834bac24869c590390335f72c85c59a1553be2d99db38b039bb4c99", + "transactions": [ + "0xf869388305ecef82520894eda8645ba6948855e3b3cd596bbb07596d59c60301808718e5bb3abd10a0a03ec04936103192dfdb6ba9599584104a1a1af9d46f81c4ccefda71f2637632dba00c983e0ddaec1491cde1f892944cd420020d6a4ffab6a8206404c2f4e562f6bd" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x28fbeedc649ed9d2a6feda6e5a2576949da6812235ebdfd030f8105d012f5074", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np60", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xceccf9166834bac24869c590390335f72c85c59a1553be2d99db38b039bb4c99", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x5b7a9350c65fcf4bc55005baa15c44063e165fb4ac7c1f53f13fbf9363b608da", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x65", - "gasLimit": "0x47e7c40", + "blockNumber": "0x3c", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x3f2", + "timestamp": "0x258", "extraData": "0x", - "baseFeePerGas": "0x1d0206", - "blockHash": "0xf2750d7772a6dcdcad79562ddf2dee24c1c2b7862905024a8468adfb62f8ef14", + "baseFeePerGas": "0x52f87", + "blockHash": "0xb8c495461332ae67504ee899542ccf73e859f73c6682fad15415743f15b7f5e6", "transactions": [], "withdrawals": [ { "index": "0x4", "validatorIndex": "0x5", - "address": "0x3f79bb7b435b05321651daefd374cdc681dc06fa", + "address": "0xe7d13f7aa2a838d24c59b40186a0aca1e21cffcc", "amount": "0x64" } ], @@ -897,154 +1899,347 @@ "excessBlobGas": "0x0" }, [], - "0x6d19894928a3ab44077bb85dcb47e0865ce1c4c187bba26bad059aa774c03cfe" + "0x6f7410cf59e390abe233de2a3e3fe022b63b78a92f6f4e3c54aced57b6c3daa6", + [] ] }, { "jsonrpc": "2.0", - "id": "np102", - "method": "engine_newPayloadV3", + "id": "np61", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf2750d7772a6dcdcad79562ddf2dee24c1c2b7862905024a8468adfb62f8ef14", + "parentHash": "0xb8c495461332ae67504ee899542ccf73e859f73c6682fad15415743f15b7f5e6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd3908889240ecc36175f7ac23e9596230ea200b98ee9c9ca078154288b69c637", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xeef64cf4a7bb430d2200064c49eb11996795bdbb68fc4af5398a582c4be86ff1", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x66", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x3fc", + "blockNumber": "0x3d", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x262", "extraData": "0x", - "baseFeePerGas": "0x1961c6", - "blockHash": "0x57054aa8d635c98b3b71d24e11e22e9235bc384995b7b7b4acd5ca271d0898b4", + "baseFeePerGas": "0x48997", + "blockHash": "0xfe4445a66aeaa138c2045c340fffae7db7f7a49b7a31df8b8b5f5aa431c58546", "transactions": [ - "0xf88452831961c7830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0c43b4e8ddaecaadfc1fd4b35659ced2bbaa2ab24b1cff975685cd35f486a723fa056a91d2ff05b4eae02ee1d87442ec57759e66ec13bfd3ea2655cf4f04b6e863d" + "0xf88439830489988301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa038216928b5f6a70e1cf134bb6c9a951de7c2817fc38b3f86949550175a859fb0a043f7d04317166f2d72e9cfd988bcf737ffc95a343c9733f11b288021f523a5ac" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xefc50f4fc1430b6d5d043065201692a4a02252fef0699394631f5213a5667547" + "0xd5edc3d8781deea3b577e772f51949a8866f2aa933149f622f05cde2ebba9adb", + [] ] }, { "jsonrpc": "2.0", - "id": "np103", - "method": "engine_newPayloadV3", + "id": "np62", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x57054aa8d635c98b3b71d24e11e22e9235bc384995b7b7b4acd5ca271d0898b4", + "parentHash": "0xfe4445a66aeaa138c2045c340fffae7db7f7a49b7a31df8b8b5f5aa431c58546", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd66957c43447a6edfb6b9bc9c4e985f28c24e6ce3253c68e5937c31c5d376f94", - "receiptsRoot": "0xd99d12e61c8e9be69f1eb49cea2f72664c7e569463415b064954bf5e0dbc6a01", - "logsBloom": "0x00000000000000000000100000000000200000000000000000200000000000000000000000040000000000200000000000000000000000000200000000000000000018000000000000000000010000000000000000000000000000000000100000000000000000000000000000000000000000000000000000800200000000021000000000002000000000002088400000000000000000000000000000000000000000000000000000000010000000000800000080000000000000000000000008000000000000000020000100001000000000080000002000400000000400000000000000002200000000000000000000000000000000000000000020000000", + "stateRoot": "0x0e3c5c9b3160c6b8d8951ca6b10c478d32c9d7bfd6e62c363054554fd9ddb9a9", + "receiptsRoot": "0x0c764fac3f63a25bae530d64f6553466d7a33565bbfc2aeb58e88cd53d2f1e3f", + "logsBloom": "0x10000000000000000000000000000000000000000000000000000000000000000000020000000040000000000000000000000000000000000000001200004000000000000000000000000000010000000000000000000000040080000000001000000200000000000000000000000000000000000000000001000000000002000000000000000000000000200000000000000000000000000000000000000000040000000000000000000000202000020000000000001000000020000000800000100000000000008001000000000010000000002000010000000000000000000000000000040000010000000000000020000000000000000006000040000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x67", - "gasLimit": "0x47e7c40", + "blockNumber": "0x3e", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x406", + "timestamp": "0x26c", "extraData": "0x", - "baseFeePerGas": "0x16375b", - "blockHash": "0xf4f1f726bcb9a3db29481be3a2e00c6ab4bf594ae85927414540ec9ede649d4d", + "baseFeePerGas": "0x3f935", + "blockHash": "0x0f13f717c99151d8b5b509af5cacb5313f1ebf813d7a6b37764cbe1ec0459beb", "transactions": [ - "0xf87b538316375c83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0e59d36f30ed2dfc5eb71433457547f63bf4ad98e0a2181c4373a5e7ddf04d17ea06dce4f88f48f6fd93c2c834537a8baef27bb2965b9e2ce68dc437adb3d657d28" + "0xf87b3a8303f93683011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0b2beb8e7391a9ac3ede139938af3c58f6916107ba6daf327a8964b4f6d273a8fa05561b70ac9189628fd0beaa4547deec02c2fa58766fcde758de4bb2ac93e2d35" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x3cc9f65fc1f46927eb46fbf6d14bc94af078fe8ff982a984bdd117152cd1549f" + "0x20308d99bc1e1b1b0717f32b9a3a869f4318f5f0eb4ed81fddd10696c9746c6b", + [] ] }, { "jsonrpc": "2.0", - "id": "np104", - "method": "engine_newPayloadV3", + "id": "np63", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf4f1f726bcb9a3db29481be3a2e00c6ab4bf594ae85927414540ec9ede649d4d", + "parentHash": "0x0f13f717c99151d8b5b509af5cacb5313f1ebf813d7a6b37764cbe1ec0459beb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe06685d528d0c69051bcf8a6776d6c96c1f1c203da29851979c037be2faac486", + "stateRoot": "0x365f7c27afe4331fd7832a76194f6da1222367f343ab73aabd703d7cb320beae", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x68", - "gasLimit": "0x47e7c40", + "blockNumber": "0x3f", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x410", + "timestamp": "0x276", "extraData": "0x", - "baseFeePerGas": "0x1371a8", - "blockHash": "0xc8fe6583a2370fa9bda247532a8fb7845fceea9b54c9e81cda787947bb0ad41d", + "baseFeePerGas": "0x37a7e", + "blockHash": "0x2e33aeb9f45e7cb955774b6b43df2c3a438c5aa03a69f90793f137ff5d2eb49e", "transactions": [ - "0xf86654831371a98302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0a427e65413948a8a1cf63c15214525d05bffca4667149c6a4019513defe57e6ba02819aa7d6a404a7f0194ef3ba7ec45b876f4226b278ebbcfa4012a90a1af3905" + "0xf8663b83037a7f8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0330d4dff22fc1215cb9dd37e6c0e4f5f5b8b343901decd1dc090217a1a30780fa0634cd91aecc44473bde30fc756a8d35b9ba50c8f70e199469cd4c48666724b23" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x63eb547e9325bc34fbbbdfda327a71dc929fd8ab6509795e56479e95dbd40a80" + "0x91f7a302057a2e21d5e0ef4b8eea75dfb8b37f2c2db05c5a84517aaebc9d5131", + [] ] }, { "jsonrpc": "2.0", - "id": "np105", - "method": "engine_newPayloadV3", + "id": "np64", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc8fe6583a2370fa9bda247532a8fb7845fceea9b54c9e81cda787947bb0ad41d", + "parentHash": "0x2e33aeb9f45e7cb955774b6b43df2c3a438c5aa03a69f90793f137ff5d2eb49e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x32d5d07d12d91b8b4392872b740f46492fea678e9f5dc334c21101767bd54833", + "stateRoot": "0xaa1f9542e99b8fc7584926efd625552d9a0b49ac0737ef2ef01f2a328c0b3d07", + "receiptsRoot": "0xc9510b4222f446bd32f7fc5db4f3d25c48644389a56e3f38da4bd0e8e85ea5db", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000009000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x40", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x280", + "extraData": "0x", + "baseFeePerGas": "0x30be4", + "blockHash": "0xf496b8d4d19037d646dcbc3796d2a28bf176488e2e238107feaa0b4b7f5ae6a5", + "transactions": [ + "0x02f8d5870c72dd9d5e883e3c0183030be5830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c6c744aeee3965d5c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0905cfe802dc4c667312ea08fdbe97798b88cfb11049ade2b18ad9001e8b6dd7c01a08108fba0b09bd2524b990bfdb8859c61415ce9fc89c5a74c6646c006d48cf063a07e42d23500741f1c090ef29678d3ee14ebab252ee22b7b2739b7f247d6f77726" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x743e5d0a5be47d489b121edb9f98dad7d0a85fc260909083656fabaf6d404774", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np65", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xf496b8d4d19037d646dcbc3796d2a28bf176488e2e238107feaa0b4b7f5ae6a5", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x6a74cc114b3893db5aae2f6053f8dc07aa202d92809edeaa5c992d6ec64de2d4", + "receiptsRoot": "0x642c1186627a30db8aca0880b5a4e4898347733004fcba0261730af52e7f84e9", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x41", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x28a", + "extraData": "0x", + "baseFeePerGas": "0x2aaad", + "blockHash": "0x49005c56e2c43c7d5d10026c97dce5b3b2e4a38eda72b6db3e544d2e92c12047", + "transactions": [ + "0x01f8d4870c72dd9d5e883e3d8302aaae830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c3f2b9739dd517491656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a04b3120af8064823e074758c51cd6cd0954587c0d94b5b37b336261fc7aa2ddb380a01e0726157040be97d0fc732cfe43a33f37d3c7023ef5506a6ddc70c382a86568a059b0b6972511633af465bd1361ab7150667deb1069d0d257f6f2f2a7ab02235b" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xcdcf99c6e2e7d0951f762e787bdbe0e2b3b320815c9d2be91e9cd0848653e839", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np66", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x49005c56e2c43c7d5d10026c97dce5b3b2e4a38eda72b6db3e544d2e92c12047", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x14b3123c5e05edc308b317830c11696e3a852faacddfd3c797313e76f3e8d4ac", + "receiptsRoot": "0x336f42e12ba106c40aa9562f2451020ac99cd3f09668f3c93d60e7867939b8bb", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000008000400000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x42", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x294", + "extraData": "0x", + "baseFeePerGas": "0x25594", + "blockHash": "0xae199d9dff48f9bc1202bd414078c175b977869bce215c79259cbed32e490b16", + "transactions": [ + "0x03f8fb870c72dd9d5e883e3e0183025595830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c4f2fdd3d218cddc4656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0e7d55978188f31ab090b1f10d8d401a66356b11ca8c296384a0a51e36e6ec11f83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0ba7c04326cf6a555be5bd9f31cb2fba1eb9a9f3e33e2946aac1f9fc22b568383a04a0b8e9efdb25fa0cb8a181b58efb746c78f2ddff7e871de4eb252238150a672" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xcc9476183d27810e9738f382c7f2124976735ed89bbafc7dc19c99db8cfa9ad1", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np67", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xae199d9dff48f9bc1202bd414078c175b977869bce215c79259cbed32e490b16", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xe2923af53ace216a2f3756f07e02eec3fe11417e1444f7f7f3ee962730052b0c", + "receiptsRoot": "0x0c1845ba8a6c851d9de17fa0df7f08367b9b3a8b47d536aaca24ca3551c9e1cb", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000009000000000000000000000000000100000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x43", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x29e", + "extraData": "0x", + "baseFeePerGas": "0x20b17", + "blockHash": "0x0065ca2f730c7ef4ae37e81f916bfe2a89b86ee315d17796e0b8b5bb76c4127e", + "transactions": [ + "0xf8763f83020b18830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c830865895079ba54656d69748718e5bb3abd109fa030af21395f8f337afa3ec46a10e083ab868ec41ded089861c9bb7031f6996fc0a01f6cb2daa409d5eabfe1e2f78a94ae403fd8f790b25817a007d999b0bbb9b4d5" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xf67e5fab2e7cacf5b89acd75ec53b0527d45435adddac6ee7523a345dcbcdceb", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np68", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x0065ca2f730c7ef4ae37e81f916bfe2a89b86ee315d17796e0b8b5bb76c4127e", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x79b6da8621db4d382ab7daf4b067e987df60959df8352369ab182b7e5edb388b", "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x69", - "gasLimit": "0x47e7c40", + "blockNumber": "0x44", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", - "timestamp": "0x41a", + "timestamp": "0x2a8", "extraData": "0x", - "baseFeePerGas": "0x11056d", - "blockHash": "0xb30b266de816c61ef16e4abfc94fbed8b4032710f4275407df2bf716a1f0bbd7", + "baseFeePerGas": "0x1c9e1", + "blockHash": "0xc091a79738ea695804fd7a370a3d24728d5d4523a047835b28fbe5790c914af0", "transactions": [ - "0x02f86c870c72dd9d5e883e55018311056e82520894de7d1b721a1e0632b7cf04edf5032c8ecffa9f9a0180c080a02a6c70afb68bff0d4e452f17042700e1ea43c10fc75e55d842344c1eb55e2e97a027c64f6f48cfa60dc47bfb2063f9f742a0a4f284d6b65cb394871caca2928cde" + "0x02f86c870c72dd9d5e883e40018301c9e2825208945f552da00dfb4d3749d9e62dcee3c918855a86a00180c001a00929204cf592a006c27998253c5071e583e2c920514e7d5c1e34a49e37453f38a05dbbbc9782cc4d74b300914cb993d12bd127c2122e7fe1b7cca30c65f7c6edcb" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x67317288cf707b0325748c7947e2dda5e8b41e45e62330d00d80e9be403e5c4c" + "0xe20f8ab522b2f0d12c068043852139965161851ad910b840db53604c8774a579", + [] ] }, { "jsonrpc": "2.0", - "id": "np106", - "method": "engine_newPayloadV3", + "id": "np69", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb30b266de816c61ef16e4abfc94fbed8b4032710f4275407df2bf716a1f0bbd7", + "parentHash": "0xc091a79738ea695804fd7a370a3d24728d5d4523a047835b28fbe5790c914af0", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf89d6d5f7a16d98062e1ef668ee9a1819b0634bd768ece2fc2b687f8968dc373", + "stateRoot": "0xa7486d74361a7d787a9e90106c8a08d8a235890e58111e07ec69684b9758ab09", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x45", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x2b2", + "extraData": "0x", + "baseFeePerGas": "0x190b6", + "blockHash": "0xc0dec6888ce6c75c575ce5ada6f3425cf1511b4d31b4f7ffeb63e93bf00ff243", + "transactions": [ + "0x01f86b870c72dd9d5e883e41830190b7825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c0180c080a040e500b278d2f1bc4f1712d23db7301b0c51eb5fcee5c0e6c2fffe2eeb2c5297a050aa2d6a1dfe6d17354f121168b2a9e2e4e9a486ad2b6ce20c10167c33b1f0ab" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xf982160785861cb970559d980208dd00e6a2ec315f5857df175891b171438eeb", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np70", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xc0dec6888ce6c75c575ce5ada6f3425cf1511b4d31b4f7ffeb63e93bf00ff243", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0780d1da5793aa323fc66a9089541cb12ae3cb7510f9f3685a3941195276d2ad", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x46", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x2bc", + "extraData": "0x", + "baseFeePerGas": "0x15eae", + "blockHash": "0xfd1c5aae32a2ab886fbc6b5229bd30528f904fa67063d334e6428dfc94a9909b", + "transactions": [ + "0xf8694283015eaf825208942d389075be5be9f2246ad654ce152cf05990b20901808718e5bb3abd109fa0cc54eb0962f6ee85e270409d8e16dcd4a85b55c027c40fede1eb337b6b22b113a06eb534ff3e0ad65677e8d47cbeef950d10ff14edcbbeedae7163c139e20a4289" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x230954c737211b72d5c7dcfe420bb07d5d72f2b4868c5976dd22c00d3df0c0b6", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np71", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xfd1c5aae32a2ab886fbc6b5229bd30528f904fa67063d334e6428dfc94a9909b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x67d9e95841df8e76fc7449398d692c9e22aa5a9cc46062f0f9ce86e86c6be65b", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x6a", - "gasLimit": "0x47e7c40", + "blockNumber": "0x47", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x424", + "timestamp": "0x2c6", "extraData": "0x", - "baseFeePerGas": "0xee50e", - "blockHash": "0x35221530b572a05628d99d8ca9434287c581e30473f83d612cbbfb7f394c587b", + "baseFeePerGas": "0x132e5", + "blockHash": "0x537b75471b40aaa24670d4ed625d075165b59e4ab455236c14dedd7e99e65d34", "transactions": [], "withdrawals": [ { "index": "0x5", "validatorIndex": "0x5", - "address": "0x189f40034be7a199f1fa9891668ee3ab6049f82d", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", "amount": "0x64" } ], @@ -1052,154 +2247,347 @@ "excessBlobGas": "0x0" }, [], - "0x7fc37e0d22626f96f345b05516c8a3676b9e1de01d354e5eb9524f6776966885" + "0xb7743e65d6bbe09d5531f1bc98964f75943d8c13e27527ca6afd40ca069265d4", + [] ] }, { "jsonrpc": "2.0", - "id": "np107", - "method": "engine_newPayloadV3", + "id": "np72", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x35221530b572a05628d99d8ca9434287c581e30473f83d612cbbfb7f394c587b", + "parentHash": "0x537b75471b40aaa24670d4ed625d075165b59e4ab455236c14dedd7e99e65d34", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xaf4107a57da519d24d0c0e3ae6a5c81f3958ddc49e3f1c2792154b47d58d79a1", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x1e288bfa95da0801a29d41c58b606e07c2741f55b9de3176b9f1304a270bd043", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x6b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x42e", + "blockNumber": "0x48", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x2d0", "extraData": "0x", - "baseFeePerGas": "0xd086d", - "blockHash": "0xe3981baf40fc5dac54055fab95177a854a37ff2627208247697d5627b8ae3c35", + "baseFeePerGas": "0x10c89", + "blockHash": "0x509c406dedf930913cc53d51de88a6b34b0edf15d45c88deee154cdea0b35415", "transactions": [ - "0xf88456830d086e830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a04c088a3642c3cfad977a0927e6d694bd26be96246f127f03d37fe2b494b99da2a00ef5b6e7aca1ac95ef964978a7ec4bb66688fbb7abace43f90f0c344196379e5" + "0xf8844383010c8a8301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a00f95d60b8058eb4ed470df1649e1d49a6bdd13b4d4550cf9190ad46deb6e385ca06a35861fbdd443bdaf5b29b45009d23e10095e81e6bc5ae57d56ac18bdad4f8d" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc8c5ffb6f192e9bda046ecd4ebb995af53c9dd6040f4ba8d8db9292c1310e43f" + "0x31ac943dc649c639fa6221400183ca827c07b812a6fbfc1795eb835aa280adf3", + [] ] }, { "jsonrpc": "2.0", - "id": "np108", - "method": "engine_newPayloadV3", + "id": "np73", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe3981baf40fc5dac54055fab95177a854a37ff2627208247697d5627b8ae3c35", + "parentHash": "0x509c406dedf930913cc53d51de88a6b34b0edf15d45c88deee154cdea0b35415", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9afc46d870489ac06cac1ea0b65c417d8e0086f0fb828dd92dca30da737c827b", - "receiptsRoot": "0x9b9c6d15a59d6b1c222cc63abe6aa28d734463877a3c34d4b3d9e80b768b77aa", - "logsBloom": "0x00000000000000000000000000000080000000000002000000000002000000000000004000000000000000000000010000000000000000000000000000000000000400000000000000100000000000000000200000000000000000000200000000000000000008000010000000000000000080000000000200000008000400000000000000000400000000000000000008000000001000000001000000000000000000000000008000000200000000000000000008400000000000000000000000001000000000000000000000001000010000000020000000040000000000000000000000000000000200080000000000000000000000040000000200000400", + "stateRoot": "0xe629e14f080a5b136f2692b4d69c567f5434c457903057b1b6f5ee7f48f1683e", + "receiptsRoot": "0xbacbf940adc4821ad97f4693540bbfd97f5e03fafb76a803ca8a9d0f48eaad59", + "logsBloom": "0x00000000000000002000200000000004000000000210000000300000000010000000000004000000000040000000000000000004000000000000000000000000000000000000040000000000000000000000000000000000000000000000000800000000000000000020000800000000000000000040000000200000000000000000000000000000000000000000001100000000002000000000000000000000000000000200000000000000000000000000000010000000000000000100000000000000400000010000200000000000800000000000000000000000400000000000080400000000000040000000000800010000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x6c", - "gasLimit": "0x47e7c40", + "blockNumber": "0x49", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x438", + "timestamp": "0x2da", "extraData": "0x", - "baseFeePerGas": "0xb684d", - "blockHash": "0x54fcc3af800dbeae5c45ac8acba05313bd8d4c1bb06502702a14a225259367aa", + "baseFeePerGas": "0xeb29", + "blockHash": "0xcd249ec42453922de5255c9b47ac76191e3cb60144ad0c4bd1b5e02d672c08a0", "transactions": [ - "0xf87b57830b684e83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a06789a9252207970001fd703c22b2b7e5c0388bf018bc070a0469129f80cc5d63a048de0e437b02a8dd3a783892ad1691a1062cd73ddd35c481d9632f5158650317" + "0xf87a4482eb2a83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0844a9661b1056386289b482f1ad2b05fae312ad19ce2e3a3d06ab9028ec70a33a022f2d8348abde63af504b925a8ba1d258a2208d2aa056b8b73cbdaad67c55f5d" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe40a9cfd9babe862d482ca0c07c0a4086641d16c066620cb048c6e673c5a4f91" + "0xded49c937c48d466987a4130f4b6d04ef658029673c3afc99f70f33b552e178d", + [] ] }, { "jsonrpc": "2.0", - "id": "np109", - "method": "engine_newPayloadV3", + "id": "np74", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x54fcc3af800dbeae5c45ac8acba05313bd8d4c1bb06502702a14a225259367aa", + "parentHash": "0xcd249ec42453922de5255c9b47ac76191e3cb60144ad0c4bd1b5e02d672c08a0", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x02324f55d0548cb8743857fe938f91e6f15bfbe94654aadde56c59f83083980a", + "stateRoot": "0x585fadd5c479efb4ac957ebc42b3af0672543a6486bac7218af2a8d20a438172", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x6d", - "gasLimit": "0x47e7c40", + "blockNumber": "0x4a", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x442", + "timestamp": "0x2e4", "extraData": "0x", - "baseFeePerGas": "0x9fbe4", - "blockHash": "0x62bb35defc0aac7bfbe789de02062f7ac622e9e354cfea5dceeccb792a61bae3", + "baseFeePerGas": "0xcdde", + "blockHash": "0x4b17336fdc9eccebc8c836ffcf41d077a956e9cf786521e9eb4d01db5de5a935", "transactions": [ - "0xf866588309fbe58302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa07e3ef87807ccd797a0020fade1b7d65a7b190fbe40a6f8bdc35cd6a3a6fbed73a0283ad99e27eb389ca3b389bce3c29b3c711b74b6ecd05b290c7be33389830fab" + "0xf8654582cddf8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0903ed0f6e8c13e03dd6873a3dd66d60f595f047b94c3320eb409a6ea4a039b0fa05c8a6d80d1ef19f554c6c5b8dc2093fb9665369c706ff7afb53d7c8b4886743a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe82e7cff48aea45fb3f7b199b0b173497bf4c5ea66ff840e2ec618d7eb3d7470" + "0xa0effc449cab515020d2012897155a792bce529cbd8d5a4cf94d0bbf141afeb6", + [] ] }, { "jsonrpc": "2.0", - "id": "np110", - "method": "engine_newPayloadV3", + "id": "np75", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x62bb35defc0aac7bfbe789de02062f7ac622e9e354cfea5dceeccb792a61bae3", + "parentHash": "0x4b17336fdc9eccebc8c836ffcf41d077a956e9cf786521e9eb4d01db5de5a935", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9932915761c4c894fc50819df189e875d3b025a7c045406fe415abe61d0e3086", + "stateRoot": "0xaad034b9aed035a65c6f0a7bcd8327867b8afc96c350c9c71cab19e4e9c2f309", + "receiptsRoot": "0x5261381ed0a36b358279ebe50c64a85c106a8166fade9b69010f342eb757bea1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000008000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x4b", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x2ee", + "extraData": "0x", + "baseFeePerGas": "0xb44d", + "blockHash": "0x85784669b5e3b7ce03064984463c5c167f4c90bbc7731862bd5d6cdcbbe7dfaf", + "transactions": [ + "0x02f8d4870c72dd9d5e883e460182b44e830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c324bbfff4e8882f2656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a00d968817f6ab6815faa1501ac1eafc810f4bc9b7423abc4f1bd5e65e791b4e0b01a0cf115f14e366d52ac5a9b1faff8e03b73051d51a3deef72e84a21d76a6894971a0764be216a65078c1f43363c76dbe88be7be58367d618682445d8c44a819f6b6a" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x1f36d9c66a0d437d8e49ffaeaa00f341e9630791b374e8bc0c16059c7445721f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np76", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x85784669b5e3b7ce03064984463c5c167f4c90bbc7731862bd5d6cdcbbe7dfaf", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x10f5f1733d662117fa95692a2c2b9867cdb9f1f04b83ae8bc6a75df18429ec4b", + "receiptsRoot": "0x8c6369cb0d38a3b914a4021483e92520156bcf6d81d9d294540fe99ec3c1c0eb", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000080000000000000000000000000000000000000004000000000000200000000000000000000000400002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x4c", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x2f8", + "extraData": "0x", + "baseFeePerGas": "0x9dd4", + "blockHash": "0x6d3b7ae474719d6929a8374bac361084a530941d9e9c8754bc8765a818704dc4", + "transactions": [ + "0x01f8d3870c72dd9d5e883e47829dd5830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c3acdabed71e665d0656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a041565ae6f06f2555139f444c467d6b709b45180aa0c6b15bb5b1388d55ef952c80a0252e9727a43663fd5aa98761487ebeb15b95d7db033235f7d351eb9acb475979a01f3d1b12b2c37a769a0c272fe6e9a7ef01d133dbd50b57cead6d7b7507facc0f" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x34f89e6134f26e7110b47ffc942a847d8c03deeed1b33b9c041218c4e1a1a4e6", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np77", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x6d3b7ae474719d6929a8374bac361084a530941d9e9c8754bc8765a818704dc4", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7206ee5e84555ed8f4ba8d272e1dccfe1925624632761455bcfdc0e67c5e823f", + "receiptsRoot": "0x6982e94426d405c8d3de49f7b6ce870c10701f30c45ecd2af43f133599b6f8bf", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000080000000000022000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x4d", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x302", + "extraData": "0x", + "baseFeePerGas": "0x8a28", + "blockHash": "0x60ab9fa061b4a52ae93aac61a70a7049d5ace2d85ad81cd3ba18e5b6f9df5a90", + "transactions": [ + "0x03f8fa870c72dd9d5e883e4801828a29830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c3bcdbc5784078a41656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a024a4daf5b3cac3bf3066902cda09da0fc862e0a6723c47981ed601782ad6907983020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0be16a650dcd81359ba2d9f87a008c438a386e541e9a4ba6ed80dfedacea76e12a03d50205907b0ab60580851df05efbb4abc9d8019111bdabb3223a48d33b0048e" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x774404c430041ca4a58fdc281e99bf6fcb014973165370556d9e73fdec6d597b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np78", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x60ab9fa061b4a52ae93aac61a70a7049d5ace2d85ad81cd3ba18e5b6f9df5a90", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xdd742a8891473ccbb5ccc2120e977e1408c391722034f2f2484307282b7e767a", + "receiptsRoot": "0x42fd4760a510b52f9c950b84b193545e86594957ee0531c97075c8d30a2cabda", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200004000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000020000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x4e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x30c", + "extraData": "0x", + "baseFeePerGas": "0x78f0", + "blockHash": "0x8d76a11f766a753283cdebf3c0a4ada62f0a85333eadf13f5c94b5528b9a0bb8", + "transactions": [ + "0xf875498278f1830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c2d5a0323bb16361f656d69748718e5bb3abd109fa04bebaf0a20678a2de1d3fb9bf40b4ab012b3cd73349d89900b4e5f6d58432fd1a024734d16fda50818adff08a6379f83c3cad54ccf6ef14788cc620042b50439de" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xd616971210c381584bf4846ab5837b53e062cbbb89d112c758b4bd00ce577f09", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np79", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x8d76a11f766a753283cdebf3c0a4ada62f0a85333eadf13f5c94b5528b9a0bb8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x9c475f68fef47ca76bf7002bb05160c1ed7573f0dfcec725e4a664eabccfc1ce", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x4f", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x316", + "extraData": "0x", + "baseFeePerGas": "0x69dd", + "blockHash": "0x70ed6c8dfbfd1a79453b1360fe0c9024d1c9a51b7e9ae491dc9f672c1495ee52", + "transactions": [ + "0x02f86b870c72dd9d5e883e4a018269de825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c0180c080a0cec492241954a9cc71f9b7dcacfb8f26b2c3e393964b9ee7fcc1ccaaf04a4969a048fbd9b31f2ac94df51147ab5444d3d866e8c34df7e4a832555861dea6d5c5cd" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xcdf6383634b0431468f6f5af19a2b7a087478b42489608c64555ea1ae0a7ee19", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np80", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x70ed6c8dfbfd1a79453b1360fe0c9024d1c9a51b7e9ae491dc9f672c1495ee52", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xb3b9f2c0207a37013276417dcb6f68feadd4c581a6584b6d7c8ec57027966809", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x50", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x320", + "extraData": "0x", + "baseFeePerGas": "0x5ca6", + "blockHash": "0x829bf1d587f5294d8ee978c07aa33af6df08dc44876e81c4f2d1d9403e6c0478", + "transactions": [ + "0x01f86a870c72dd9d5e883e4b825ca78252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c080a0173d73de31dce0e30697770fa0adace02cdddce31c863f96b48ebd5644f39dc5a04dcb29a3c6f29163bd885c9954afd430aa16fbdd6c33ded3705b13730c6e9c21" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x00ec22e5df77320b4142c54fceaf2fe7ea30d1a72dc9c969a22acf66858d582b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np81", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x829bf1d587f5294d8ee978c07aa33af6df08dc44876e81c4f2d1d9403e6c0478", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xe2f7eedb26752b56cc96454638b9be27c25f16a24dfc7076701a4bb9cc93d79b", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x6e", - "gasLimit": "0x47e7c40", + "blockNumber": "0x51", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", - "timestamp": "0x44c", + "timestamp": "0x32a", "extraData": "0x", - "baseFeePerGas": "0x8bd6c", - "blockHash": "0x2c4731fbb4f4adae94723c078548c510649e8973dfdb229fd6031b1b06eb75c0", + "baseFeePerGas": "0x5115", + "blockHash": "0xb57dc2887b5798442036ac860b372cb07b5858c460977c426b53bf780aee15ba", "transactions": [ - "0xf869598308bd6d825208941b16b1df538ba12dc3f97edbb85caa7050d46c1401808718e5bb3abd109fa0abbde17fddcc6495e854f86ae50052db04671ae3b6f502d45ba1363ae68ee62ca03aa20e294b56797a930e48eda73a4b036b0d9389893806f65af26b05f303100f" + "0xf8684c825116825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c01808718e5bb3abd10a0a0eec30a6c02d46baadfef66f942f70140f3b78f905d3af1147f1501bec20ef862a014e5e443a94dff326c43d830e21df8c9025ea9d8198f59be1e991d06aa1ada9a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x84ceda57767ea709da7ab17897a70da1868c9670931da38f2438519a5249534d" + "0xcb32d77facfda4decff9e08df5a5810fa42585fdf96f0db9b63b196116fbb6af", + [] ] }, { "jsonrpc": "2.0", - "id": "np111", - "method": "engine_newPayloadV3", + "id": "np82", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2c4731fbb4f4adae94723c078548c510649e8973dfdb229fd6031b1b06eb75c0", + "parentHash": "0xb57dc2887b5798442036ac860b372cb07b5858c460977c426b53bf780aee15ba", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2849b35fb3ec8146f637be768e3eaefda559928f8bb35753584d5b326a400ff5", + "stateRoot": "0x6d4e3e96904866f611e25ff2555e0edf6c4a78ef22ea78dc0d256ca8205485ca", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x6f", - "gasLimit": "0x47e7c40", + "blockNumber": "0x52", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x456", + "timestamp": "0x334", "extraData": "0x", - "baseFeePerGas": "0x7a5e7", - "blockHash": "0x76b385d3f8a4b6e66ea8c246ed7c6275ad164d028ec5a986f9524bfe7437dcc7", + "baseFeePerGas": "0x46f6", + "blockHash": "0x6793c6d579b24b7bfac5cfd619b7335aace2365f75cf5b0d1e1b5c367288b74b", "transactions": [], "withdrawals": [ { "index": "0x6", "validatorIndex": "0x5", - "address": "0x65c74c15a686187bb6bbf9958f494fc6b8006803", + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", "amount": "0x64" } ], @@ -1207,154 +2595,347 @@ "excessBlobGas": "0x0" }, [], - "0xe9dcf640383969359c944cff24b75f71740627f596110ee8568fa09f9a06db1c" + "0x6d76316f272f0212123d0b4b21d16835fe6f7a2b4d1960386d8a161da2b7c6a2", + [] ] }, { "jsonrpc": "2.0", - "id": "np112", - "method": "engine_newPayloadV3", + "id": "np83", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x76b385d3f8a4b6e66ea8c246ed7c6275ad164d028ec5a986f9524bfe7437dcc7", + "parentHash": "0x6793c6d579b24b7bfac5cfd619b7335aace2365f75cf5b0d1e1b5c367288b74b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2f24b6182543c677e7d1cab81bc020033c64e034571a20ecd632e252c8f202b3", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xc79924280afff05363b95785cda5387e9e82ddae8266c1e34e9c8f5a4e2bfe5e", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x70", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x460", + "blockNumber": "0x53", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x33e", "extraData": "0x", - "baseFeePerGas": "0x6b12b", - "blockHash": "0x33385ec44cfd01ba27c927a3ebe607a27e55fd8e89965af09b991a7cdc127dbc", + "baseFeePerGas": "0x3e18", + "blockHash": "0xab38058baae4ce65fe734310ef852d1adb2eb0e5bce297e2dfb1f2aabb8155fe", "transactions": [ - "0xf8845a8306b12c830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0bf8a8863f63a16d43652b12e54dc61bd71c8ab86d88aebb756c6e420fca56a1aa01f62e0032c57f1629ee82b4fefb8d6c59a85c5c2889b1671ce0713581e773b6e" + "0xf8834d823e198301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0ae704e1b38122ca02493c828a10c293237b1088376a32c71c0402cc4ccee0ea9a039f2324696ba0be7a7730d4f922ae10586c25d92b6525e0f1ec332de4fbf3b36" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x430ef678bb92f1af44dcd77af9c5b59fb87d0fc4a09901a54398ad5b7e19a8f4" + "0x2de2da72ae329e359b655fc6311a707b06dc930126a27261b0e8ec803bdb5cbf", + [] ] }, { "jsonrpc": "2.0", - "id": "np113", - "method": "engine_newPayloadV3", + "id": "np84", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x33385ec44cfd01ba27c927a3ebe607a27e55fd8e89965af09b991a7cdc127dbc", + "parentHash": "0xab38058baae4ce65fe734310ef852d1adb2eb0e5bce297e2dfb1f2aabb8155fe", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6d6c9c24ef7d93db6ba57324fb6f3604b09611301e12d250162c2b2b50871625", - "receiptsRoot": "0x257c29f688aaf63db2244378182225d104d84cfbd188c82b92323623d11574e9", - "logsBloom": "0x00000000000000000000080040000000000000000000000000008000000000000000000000000000000000000001000000000000000000000040000000040010000100000000000000400000000000000000020000000000000000800000000400000000000000000000000040000000000002000100400000000000000200000000000000000000000008000000010000000000000800000000000000000000000080000000000000000000000000000000080400000000000000000000400000000000010000000004000000000000000000000010020000000000000000000000000000000100000000040000000000000000000000200000001800000000", + "stateRoot": "0xce9a3b040049312688b963ff49410e9dfff53349b9abd1a3f93d4e67b2f2408d", + "receiptsRoot": "0x192362bc21457de45deb735ce9f1cd26e7ee37928db9cdc4d40436d2134140f7", + "logsBloom": "0x00000000008002000000004000000000000000800000800000400800000000040040000000000000000800000000000000000000000040000008002000000000000000000000000000000000000000000000000000000020000000000000000004000000000000000000000008400000000000000000000000010001000000000000000000000000000000800000000000020000000200000000000000020000000000000000000000000000000000000000000020000000000000000000000000000000040000800000000000000200000020008000002000000000002000000000000000000000000000000000000000200008000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x71", - "gasLimit": "0x47e7c40", + "blockNumber": "0x54", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x46a", + "timestamp": "0x348", "extraData": "0x", - "baseFeePerGas": "0x5db80", - "blockHash": "0x66ad7aaacf3efede70dda0c82629af2046e67b96713cf3cf02a9a2613ca25b6f", + "baseFeePerGas": "0x3661", + "blockHash": "0xc129c2d37fdd0defa0d0cdd7b27a95e5f17eb1beb11a8713bc4b398dff6f69a2", "transactions": [ - "0xf87b5b8305db8183011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0f893fcd21c2a882bc3968ea3c41dd37a8dbfbf07a34a8694a49fdd8081996e25a0502578b516e04b1939fdad45fd0688e636d57f59826a8e252b63f496b919d91c" + "0xf87a4e82366283011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0fe30fa3e184a6907501b49905902316be2f564d4196be62497233bc1610dedd2a016312759531406df473240de2509a119c62c1833808a0a2b246c6d62af9a249c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf7af0b8b729cd17b7826259bc183b196dbd318bd7229d5e8085bf4849c0b12bf" + "0x08bed4b39d14dc1e72e80f605573cde6145b12693204f9af18bbc94a82389500", + [] ] }, { "jsonrpc": "2.0", - "id": "np114", - "method": "engine_newPayloadV3", + "id": "np85", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x66ad7aaacf3efede70dda0c82629af2046e67b96713cf3cf02a9a2613ca25b6f", + "parentHash": "0xc129c2d37fdd0defa0d0cdd7b27a95e5f17eb1beb11a8713bc4b398dff6f69a2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x61c50266ae62e14edea48c9238f79f6369fd44e7f3d6519c7139aa1e87ee13ba", + "stateRoot": "0xb8adf9d72b4060e71a58b8c69a089dc07fccd0f8a6bae96f83f05273a65283ae", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x72", - "gasLimit": "0x47e7c40", + "blockNumber": "0x55", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x474", + "timestamp": "0x352", "extraData": "0x", - "baseFeePerGas": "0x52063", - "blockHash": "0x00fd70a53be9c85c986d3dd87f46e079e4ce4a4a3dd95c1e497457c50bacbe2d", + "baseFeePerGas": "0x2f9b", + "blockHash": "0x5e61412b6b77af36026fc83378b2aff64e52121621912d35061bf7db4e315657", "transactions": [ - "0xf8665c830520648302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0961de3e3657fdc49c722cc23de35eaf41de51c3aab3ca9a09b3d358fc19195aca060ee48b2fad3f3798111a93038fcb5c9c9791daf3c6acbaf70134fd182b5c663" + "0xf8654f822f9c8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0682574928d1ae7cc05750ebf529d96ab94d0b2721e0c40e628dc2d79acd3f5b9a06f0f8ed0215494365e2529f8b460b27d24de18f27bf35d38096f7c1d76b80227" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe134e19217f1b4c7e11f193561056303a1f67b69dac96ff79a6d0aafa994f7cb" + "0xe437f0465ac29b0e889ef4f577c939dd39363c08fcfc81ee61aa0b4f55805f69", + [] ] }, { "jsonrpc": "2.0", - "id": "np115", - "method": "engine_newPayloadV3", + "id": "np86", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x00fd70a53be9c85c986d3dd87f46e079e4ce4a4a3dd95c1e497457c50bacbe2d", + "parentHash": "0x5e61412b6b77af36026fc83378b2aff64e52121621912d35061bf7db4e315657", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2bebf2f158ec1b8c7be21ef7c47c63fa5a3eb2292f409f365b40fa41bacb351e", + "stateRoot": "0xa08f4f70e62edae94e6d64a375443d46c1d54439b3e4b8c4f9b40882951c21ba", + "receiptsRoot": "0x2975f936074e89e49d796dc3b56be7f803c99492e85fab5560e6930cb537658f", + "logsBloom": "0x00000000000000000000000040200000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x56", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x35c", + "extraData": "0x", + "baseFeePerGas": "0x29b2", + "blockHash": "0x06a3b3e77a4ecfa284cd0cbc5f563dafcebefcaa7e4610b0433f1da2353d65a5", + "transactions": [ + "0x02f8d4870c72dd9d5e883e50018229b3830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cf283ffec056e262f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a0634d80c0a702c2b06dfe60ace0d8f788b99406f1d2ac44ad3a26faa3fc146480a021f7ebe5983412cc2643a7a86426e7a1c3acf25fa8ae945515d1c18bcbc04d41a05acfac3d64f7915ab60faddf75f5bd069d60c790c1d53a987d0599c5a7c499d3" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x89ca120183cc7085b6d4674d779fc4fbc9de520779bfbc3ebf65f9663cb88080", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np87", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x06a3b3e77a4ecfa284cd0cbc5f563dafcebefcaa7e4610b0433f1da2353d65a5", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xf28efb86161fd054eaeeb8012454fd6fcabbf1d1a00393e0115d80eab410d30d", + "receiptsRoot": "0x7d22b3980b29df178aadcc46b209a79b386bf81e22e12abda09b5f28bd65ceee", + "logsBloom": "0x00000000000000000000000000000100000000000000000000000000800008000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x57", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x366", + "extraData": "0x", + "baseFeePerGas": "0x2480", + "blockHash": "0x096a5b9ce9899b40e70d721ead24b8da99a16bd9d115412a1e5d4ba2478ba276", + "transactions": [ + "0x01f8d3870c72dd9d5e883e51822481830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c8e5b86c510108d5c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a000f7ca033c24d91f8fc39cbf0edc8a43192507f93d7316f311b05eeb85921eed01a09e097f570d76bf39617cd5dd44154c9e0fcf81f3e7f5b83e92764c27d565bf9aa053c086d715941f75c5c0878067815b8cc96734268162abe11b47f3a06e3adc05" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xb15d5954c7b78ab09ede922684487c7a60368e82fdc7b5a0916842e58a44422b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np88", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x096a5b9ce9899b40e70d721ead24b8da99a16bd9d115412a1e5d4ba2478ba276", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x35b9213f895371cbb4392162da8a7500f5a47cb89e3fa982a508bad473c26271", + "receiptsRoot": "0x945052b14f54239fd074dc767b331c1081ed1b6e0f16b7b26adc4ff42a85542e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000010000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x58", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x370", + "extraData": "0x", + "baseFeePerGas": "0x1ff4", + "blockHash": "0xa6b1b6fbde7fcc8c1c4b6b035835d839914b9d3ad21dedf946f5d91754d9a6c4", + "transactions": [ + "0x03f8fa870c72dd9d5e883e5201821ff5830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cdc2a7ef24edc33ac656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a07c24a68c92e3b68daa153ae82eff9be1ebbab973384e0f4b256f158f93c5d52583020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a017e7abc42245a61de024c71dc03c28e284e819dd4c65cbc300aa4ae44f419d08a07ae5e68345b3710abb71dcb5b4661750bb74db92fbde39954ca440883ba1dc0e" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xad13055a49d2b6a4ffc8b781998ff79086adad2fd6470a0563a43b740128c5f2", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np89", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xa6b1b6fbde7fcc8c1c4b6b035835d839914b9d3ad21dedf946f5d91754d9a6c4", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1bf7f56cd090ccc023f7e630f15afc802cc285fc6c1b6b58d5c7758dd7cc3da4", + "receiptsRoot": "0x627165c3f8e25a917da5a29d58d0e712ff1762956a221a0560878d7c29865dc9", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000008000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x59", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x37a", + "extraData": "0x", + "baseFeePerGas": "0x1bf9", + "blockHash": "0x96d9997e171f41cd83e6829c097bd37f9c352553c0a1fb5a739d2766cd7b0772", + "transactions": [ + "0xf87553821bfa830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cd458dc07963e0c5c656d69748718e5bb3abd109fa03486504c2c493dc7c0df1daaa1f22b3253fb838145724f7a687fe81661704de9a00dab1a6db8a4c04cb34fb6a8861624fe5dbe210257e3ef723042bf7fb42d8d12" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x9e9909e4ed44f5539427ee3bc70ee8b630ccdaea4d0f1ed5337a067e8337119f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np90", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x96d9997e171f41cd83e6829c097bd37f9c352553c0a1fb5a739d2766cd7b0772", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xa5e05aa6d25b0f8d77edc2c17afd1a35927ebd5f0219255768f83a6bca6c2774", "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x73", - "gasLimit": "0x47e7c40", + "blockNumber": "0x5a", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", - "timestamp": "0x47e", + "timestamp": "0x384", "extraData": "0x", - "baseFeePerGas": "0x47cdc", - "blockHash": "0xbb9f244470573774df6fca785d3e11e6bd1b896213cacd43cdfcb131f806ca4c", + "baseFeePerGas": "0x187d", + "blockHash": "0x70db0ab4ec61502d2a53b8faa0ffe5a45d7db6f562af25e6564d8d2669989d0a", "transactions": [ - "0x02f86c870c72dd9d5e883e5d0183047cdd82520894043a718774c572bd8a25adbeb1bfcd5c0256ae110180c001a02ae4b3f6fa0e08145814f9e8da8305b9ca422e0da5508a7ae82e21f17d8c1196a077a6ea7a39bbfe93f6b43a48be83fa6f9363775a5bdb956c8d36d567216ea648" + "0x02f86b870c72dd9d5e883e540182187e825208944dde844b71bcdf95512fb4dc94e84fb67b512ed80180c080a071641b0db3191ff7b3372c8d63f3e392f1ec323473550c359736914d5ae435cba0021fe07df29b5ef1cc0ca885184047b173929624a0a7faf0cf3437ab9a5e7320" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9cc58ab1a8cb0e983550e61f754aea1dd4f58ac6482a816dc50658de750de613" + "0xbf1f3aba184e08d4c650f05fe3d948bdda6c2d6982f277f2cd6b1a60cd4f3dac", + [] ] }, { "jsonrpc": "2.0", - "id": "np116", - "method": "engine_newPayloadV3", + "id": "np91", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xbb9f244470573774df6fca785d3e11e6bd1b896213cacd43cdfcb131f806ca4c", + "parentHash": "0x70db0ab4ec61502d2a53b8faa0ffe5a45d7db6f562af25e6564d8d2669989d0a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3b359e20c5966cdcbb7b0298480621892d43f8efa58488b3548d84cf2ee514c1", + "stateRoot": "0x6b0ad802144e4563427f6909d3dc126246c0b8649117b1a8fffb6a548c2bb6eb", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x5b", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x38e", + "extraData": "0x", + "baseFeePerGas": "0x156f", + "blockHash": "0xa6aa03ee648578c9413c668ab9f6d2dc480a48bcf7b126dec17b85be35b28604", + "transactions": [ + "0x01f86a870c72dd9d5e883e5582157082520894d803681e487e6ac18053afc5a6cd813c86ec3e4d0180c080a09d31e711219a13ab4928d1b1741ce55a3e4b6ba173deb752a85e2b12661a7c0ba075180a720633d4411a4b1b7bdea101501ec6b4d1c50c411aefd8ee921afded20" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xbb70fe131f94783dba356c8d4d9d319247ef61c768134303f0db85ee3ef0496f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np92", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xa6aa03ee648578c9413c668ab9f6d2dc480a48bcf7b126dec17b85be35b28604", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd53027d41e55fa10d6a7a51bcfd3a6f904c3360fe366d2ff3050afd2a5838e1d", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x5c", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x398", + "extraData": "0x", + "baseFeePerGas": "0x12c2", + "blockHash": "0xbec4f585aade8992655a98ecf32e5ad71245f864bb2c3987b0216bfcf2acb0c0", + "transactions": [ + "0xf868568212c38252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c01808718e5bb3abd10a0a0b6faa7b0b72e8d5d945d970a2a587026d18039ca5c2a36cc85a81f4a6463c054a077e7921998baebfe50319cab574a14c1d851440c69a2f0772327629f19811e72" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x6a81ebd3bde6cc54a2521aa72de29ef191e3b56d94953439a72cafdaa2996da0", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np93", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xbec4f585aade8992655a98ecf32e5ad71245f864bb2c3987b0216bfcf2acb0c0", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x9b12ffe7615b8381a3d361af306212c07f0a006162f1b0bdc7a3305964072a70", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x74", - "gasLimit": "0x47e7c40", + "blockNumber": "0x5d", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x488", + "timestamp": "0x3a2", "extraData": "0x", - "baseFeePerGas": "0x3ed55", - "blockHash": "0x6d18b9bca4ee00bd7dc6ec4eb269cd4ba0aceb83a12520e5b825b827cb875fd9", + "baseFeePerGas": "0x106b", + "blockHash": "0xa75924e8dc804bc7d9588a41ae6545effa02c568f519abb7f109d76ae17442c0", "transactions": [], "withdrawals": [ { "index": "0x7", "validatorIndex": "0x5", - "address": "0xe3b98a4da31a127d4bde6e43033f66ba274cab0e", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "amount": "0x64" } ], @@ -1362,154 +2943,347 @@ "excessBlobGas": "0x0" }, [], - "0x79c2b067779a94fd3756070885fc8eab5e45033bde69ab17c0173d553df02978" + "0x4c83e809a52ac52a587d94590c35c71b72742bd15915fca466a9aaec4f2dbfed", + [] ] }, { "jsonrpc": "2.0", - "id": "np117", - "method": "engine_newPayloadV3", + "id": "np94", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6d18b9bca4ee00bd7dc6ec4eb269cd4ba0aceb83a12520e5b825b827cb875fd9", + "parentHash": "0xa75924e8dc804bc7d9588a41ae6545effa02c568f519abb7f109d76ae17442c0", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9776b87f7c94469bd3f80d7d9b639dace4981230bbb7c14df9326aafe66f3da4", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x205f42eb8c6ea2b8f12b340c6a6267c591bd4226f937c79de0611ca85f4dbdfe", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x75", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x492", + "blockNumber": "0x5e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x3ac", "extraData": "0x", - "baseFeePerGas": "0x36fab", - "blockHash": "0xcef84ea2c6fac4a2af80a594bbe5a40bf5f5285efe67fab7ceb858844c593ae9", + "baseFeePerGas": "0xe5e", + "blockHash": "0xc80ae577ac0e00ce2a417f069f0db47ca32ba3576ea6092273c623a035980fba", "transactions": [ - "0xf8845e83036fac830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a08315d9fb30662071b05a4e38240e4b85b8e240c0c3e190f27ada50678236c6e7a00ee07dc873780f17ac9d0c7b3d434f89be92231cfca042ca5f23d3f3d7346861" + "0xf88357820e5f8301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0796daf4b6f92e4c939847cdf656db14c7789b58313aec2713c29efae499e15a6a04fb5264cd95b8a06582bdbf1bb93b25e642a25be12f938005b348f02f186d161" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd908ef75d05b895600d3f9938cb5259612c71223b68d30469ff657d61c6b1611" + "0x268fc70790f00ad0759497585267fbdc92afba63ba01e211faae932f0639854a", + [] ] }, { "jsonrpc": "2.0", - "id": "np118", - "method": "engine_newPayloadV3", + "id": "np95", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcef84ea2c6fac4a2af80a594bbe5a40bf5f5285efe67fab7ceb858844c593ae9", + "parentHash": "0xc80ae577ac0e00ce2a417f069f0db47ca32ba3576ea6092273c623a035980fba", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xcd5cc668a3b28217e9fd05ddaea82d453a6a7394770a888b7d88013a4c9bcb22", - "receiptsRoot": "0xe35b2accd70b81901c8d0c931a12687e493a489ed7b82d78ade199815c466d5f", - "logsBloom": "0x0000000000000000000000000000000000000a00000000000000000000000000000000000000000000018000000000000000000000000000008000000000000048000000000000004000000000000000000008000000000000000000000020000000000000000002201010000000000000000400000000200000000000000000000000000000000000000000200000000000a200000001000000000000000000000000200000000000000000000400040000000000000000000000800000000000000000001800000000000802000000000000000000000080000000000000000000000000000000000000000000000000400000010800000000000000000000", + "stateRoot": "0x48b892bb8b406d4ac3fb597fa6c9ffca4acd27fb4f2704ecf6bd764d79da23eb", + "receiptsRoot": "0x9486adf3b9ae8b48318e66420a28ade75a4e8db57e410418b81478f7996b8f23", + "logsBloom": "0x00000000000000000010000000000000000100000000000000000104000000000000000000000100000000000000000010000000000000000080000000080000000000000000080000000000000000200000000000000000000000000000000000000002000000000800000000000000140000000000048004000001020000020000008000000000000000300000004000000000000000001000000000000000000000000000000000000000000000000000000400000000400000000000000000000100000000000000000000080000008008000000000000000000000000000800000000000000000000000000000000000000000000200000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x76", - "gasLimit": "0x47e7c40", + "blockNumber": "0x5f", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x49c", + "timestamp": "0x3b6", "extraData": "0x", - "baseFeePerGas": "0x301f5", - "blockHash": "0x7b65cb3becfab6b30f0d643095b11c6853a33ca064a272f1326adb74e876e305", + "baseFeePerGas": "0xc95", + "blockHash": "0x3e10fa0f7879c62f9eb6373a80bf6a0a2d4c16fee5ba96566d62488db5477e92", "transactions": [ - "0xf87b5f830301f683011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0a3952a3372b48d4ef804b20a0ff5bbd5440156de3b71d37024356a3c1c5205d8a02ff03cae2dc449ca7ed7d25c91f99b17f0bafcdaf0ecc6e20bdeb80895c83e82" + "0xf87a58820c9683011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0e6fff4260c9471cfb777098433e0fb364640acb16343288999acf14c0b88809ea00b968782ab0888217477cafea77f3b57db4d431452cb8ea7e6978ae773cf2985" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe0d31906b7c46ac7f38478c0872d3c634f7113d54ef0b57ebfaf7f993959f5a3" + "0x7e544f42df99d5666085b70bc57b3ca175be50b7a9643f26f464124df632d562", + [] ] }, { "jsonrpc": "2.0", - "id": "np119", - "method": "engine_newPayloadV3", + "id": "np96", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x7b65cb3becfab6b30f0d643095b11c6853a33ca064a272f1326adb74e876e305", + "parentHash": "0x3e10fa0f7879c62f9eb6373a80bf6a0a2d4c16fee5ba96566d62488db5477e92", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xdd592cc191ae4ba2be51a47d5056c2f0ba8799c74445ea3f294e0fc95a973f16", + "stateRoot": "0xdcbc6fa752481c6726f4fb3c12bb4139441dc502d855073c856fe72f2e2b9700", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x77", - "gasLimit": "0x47e7c40", + "blockNumber": "0x60", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x4a6", + "timestamp": "0x3c0", "extraData": "0x", - "baseFeePerGas": "0x2a1e1", - "blockHash": "0x5d089bec3bbf3a0c83c7796afaa1ae4d21df034a3e33a6acb80e700e19bcaab0", + "baseFeePerGas": "0xb04", + "blockHash": "0x9ae8e852cab82414dd0762c67565523f30c9049a061c7c3b4a310cfcd4df9d2a", "transactions": [ - "0xf866608302a1e28302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0fd1714b8a15fa8a4e3ffe824632ec26f1daa6ce681e92845d1c1dfe60f032b4ea074bd5a60859bd735bbc70c9531a3ff48421f5c3b87e144406ee37ef78b8fda37" + "0xf86559820b058302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0db909926540f1032894a4db02a37d05c8edff1f5541159e8ed3a1cb143c1928ea07ffeb1ba41fd78f66ba04956b0b9cc7f834d6b5961f3afc8a6bae5525739ef5e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2318f5c5e6865200ad890e0a8db21c780a226bec0b2e29af1cb3a0d9b40196ae" + "0xd59cf5f55903ba577be835706b27d78a50cacb25271f35a5f57fcb88a3b576f3", + [] ] }, { "jsonrpc": "2.0", - "id": "np120", - "method": "engine_newPayloadV3", + "id": "np97", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5d089bec3bbf3a0c83c7796afaa1ae4d21df034a3e33a6acb80e700e19bcaab0", + "parentHash": "0x9ae8e852cab82414dd0762c67565523f30c9049a061c7c3b4a310cfcd4df9d2a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4b5122bd4713cd58711f405c4bd9a0e924347ffce532693cce1dd51f36094676", + "stateRoot": "0xc94ba29902b69aa858c2583ca321e2c1e63e6f4dd190a4040362c54969113191", + "receiptsRoot": "0xf596f1ec769d7d49f408b6aa2d8146e77550c7576de2779aeba070e5bc9c370c", + "logsBloom": "0x00000000000000000040000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000109000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x61", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x3ca", + "extraData": "0x", + "baseFeePerGas": "0x9a6", + "blockHash": "0x6c4fe4ae5fb8b2a347e58868bc6a741a6df75a83593b062869cacb7ce3a715af", + "transactions": [ + "0x02f8d4870c72dd9d5e883e5a018209a7830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c50edc262344620eb656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a050495437ee69f7b12c5d6eb55cdcd8f5ce12a2eac21a2a42a7549e9f5289b1fb80a0d1a42fdd58ea301bc622518a5df023b6c47ce337d27c4b6085207d4dbde3dfd7a03a891e16fee217f1f98c0d535690b2ebfce973836172d6aaa77a80ecb8d24049" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x551cced461be11efdeaf8e47f3a91bb66d532af7294c4461c8009c5833bdbf57", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np98", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x6c4fe4ae5fb8b2a347e58868bc6a741a6df75a83593b062869cacb7ce3a715af", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x872601fe4846f89a9affffdd232712819a15245cbb7dc617ae9b16d2a3741c27", + "receiptsRoot": "0xa29fa19bf70f4fc573b33c765b9603c1f39820fb7c365f971cf8425b8a5172da", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020009000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x62", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x3d4", + "extraData": "0x", + "baseFeePerGas": "0x873", + "blockHash": "0x6722daf402b94682af585921807783bb92e1957789399ed0e0be0e0faa5a8c87", + "transactions": [ + "0x01f8d3870c72dd9d5e883e5b820874830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c899b80c8dc11d5c2656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0761bf5fb1730fee0e499bb1806b9ae14394e673ab9c1dc12e95b9d3f1647cecd80a0bbb21740cb875793183087033bbe574233d7f0a3ab8b89d4cdc2a2603ccf603ba048c6ff73f3ee02a1d69feb70cf642978368e40861e768cfa7ecd229fddfe54c5" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc1e0e6907a57eefd12f1f95d28967146c836d72d281e7609de23d0a02351e978", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np99", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x6722daf402b94682af585921807783bb92e1957789399ed0e0be0e0faa5a8c87", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x2239cee6ef71575c8197ff42e2a28e8b2e561b59874f19934636da3c8e3510ad", + "receiptsRoot": "0x006004762186f9eb89941184c170358002854d9fc3990ce1ee068b72f42b6a01", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000004000000000000010000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x63", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x3de", + "extraData": "0x", + "baseFeePerGas": "0x766", + "blockHash": "0x651c869c9f62a753fa0c545a984f596d2068aa542234b109032b93a583442ffe", + "transactions": [ + "0x03f8fa870c72dd9d5e883e5c01820767830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c913746d244054c52656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a002bd9d62880450596e11c3417f2644a81f7cc233a05394bbbfb58428ed53f41383020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a03adcb0eae8331808d9e643d067c542b39ec1496eecc687b299eff56aeea0601fa05fec7e1a65b7d0d89524440cbcc569eef8433d1c3976497daddccffdbc32a21e" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x9d580c0ac3a7f00fdc3b135b758ae7c80ab135e907793fcf9621a3a3023ca205", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np100", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x651c869c9f62a753fa0c545a984f596d2068aa542234b109032b93a583442ffe", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x29db53323cdcc44b58a5f4b48dcd02b2a7c0014d7044387f711b6b2b48b00ac9", + "receiptsRoot": "0x2733fb23cff5be65a62478606a44d8c502792b0c48a42dc70cfa0b80ef758dbc", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000002000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000012000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x64", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x3e8", + "extraData": "0x", + "baseFeePerGas": "0x67a", + "blockHash": "0xe93d89f5d6ab364e7c6597d99b6041f6c1d503a639f1265e8ffb1261f87fa2f3", + "transactions": [ + "0xf8755d82067b830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c019f76127757f5d2656d69748718e5bb3abd109fa0218afd167510eac77bba6b2fdaa59d3580fd0a70719e57e0e40cda7712a36f8ca041221634bbbf80f4bbd0087fff1a6753631a32e4c2c5684e5191eb8b3d613c2c" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xa7fd4dbac4bb62307ac7ad285ffa6a11ec679d950de2bd41839b8a846e239886", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np101", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xe93d89f5d6ab364e7c6597d99b6041f6c1d503a639f1265e8ffb1261f87fa2f3", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x6d1ac14be0fb955ef6d906d373d29690e9609bdbd24b0c4f9d8bbdc2570c4e1d", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x3f2", + "extraData": "0x", + "baseFeePerGas": "0x5ac", + "blockHash": "0x0507a6937203ad4297bca7595e8e0d7715d59bb7296968aebd84c135b707c638", + "transactions": [ + "0x02f86b870c72dd9d5e883e5e018205ad825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df0180c080a031b61d05b2b5a5d3618cb2d89d8569ef1f539a16677e2aa8a7396aa684614c77a05e846fbccb38e529992125ba3fb8c49f6abec967dce763660761198fc7813dfa" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x6ba7b0ac30a04e11a3116b43700d91359e6b06a49058e543198d4b21e75fb165", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np102", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x0507a6937203ad4297bca7595e8e0d7715d59bb7296968aebd84c135b707c638", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7065f9b94923ab593d8472a940eca2f1c4bf224de039f252e5f9e020b5f78b70", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x66", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x3fc", + "extraData": "0x", + "baseFeePerGas": "0x4f7", + "blockHash": "0xf08662ab38a7f4db3179eb425b28a2dd5d918c80b87740d1b88699ebe905a11b", + "transactions": [ + "0x01f86a870c72dd9d5e883e5f8204f8825208945f552da00dfb4d3749d9e62dcee3c918855a86a00180c080a0d257f99d3499a621786e5a89bf766d9231746493e9b7b3956d9f0b370ac1be56a03a2a2c61d628a2c65befe9279bc9debf8df4697734f7403086fad1f5fa5299ea" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x8835104ed35ffd4db64660b9049e1c0328e502fd4f3744749e69183677b8474b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np103", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xf08662ab38a7f4db3179eb425b28a2dd5d918c80b87740d1b88699ebe905a11b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xcfb338887a35752ca4cfc6134cf589ab41cbadecae007a26d188901e182c7e1e", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x78", - "gasLimit": "0x47e7c40", + "blockNumber": "0x67", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", - "timestamp": "0x4b0", + "timestamp": "0x406", "extraData": "0x", - "baseFeePerGas": "0x24dea", - "blockHash": "0x02c9511703f78db34f67541d80704165d8a698726ef2cbcfbdc257bcf51594dd", + "baseFeePerGas": "0x459", + "blockHash": "0x122f9c89a20f0af63d4d5af9ac5e5ca3907ae256efa3d561f22b9288ad122f17", "transactions": [ - "0xf8696183024deb825208942d711642b726b04401627ca9fbac32f5c8530fb101808718e5bb3abd109fa0b4d70622cd8182ff705beb3dfa5ffa4b8c9e4b6ad5ad00a14613e28b076443f6a0676eb97410d3d70cfa78513f5ac156b9797abbecc7a8c69df814135947dc7d42" + "0xf8686082045a825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df01808718e5bb3abd109fa0a39701c019e6e29a937a0efe26e4a5e34b00a2c12c2812953967794bbb2c14dea0649354ae5e34e4b7b850e1330099b68dfce37805f773db51cae112bf38afeeea" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x523997f8d8fed954658f547954fdeceab818b411862647f2b61a3619f6a4d4bc" + "0x562f276b9f9ed46303e700c8863ad75fadff5fc8df27a90744ea04ad1fe8e801", + [] ] }, { "jsonrpc": "2.0", - "id": "np121", - "method": "engine_newPayloadV3", + "id": "np104", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x02c9511703f78db34f67541d80704165d8a698726ef2cbcfbdc257bcf51594dd", + "parentHash": "0x122f9c89a20f0af63d4d5af9ac5e5ca3907ae256efa3d561f22b9288ad122f17", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x18484e0a8e7bcccf7fbf4f6c7e1eff4b4a8c5b5e0ba7c2f2b27da315a0a06f97", + "stateRoot": "0xf127a71e9abb554f65e7c0aaef0ab838d638b850e63d8270cec55904dc7106dc", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x79", - "gasLimit": "0x47e7c40", + "blockNumber": "0x68", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x4ba", + "timestamp": "0x410", "extraData": "0x", - "baseFeePerGas": "0x20438", - "blockHash": "0x1edbbce4143b5cb30e707564f7ada75afe632e72b13d7de14224e3ed0044a403", + "baseFeePerGas": "0x3cf", + "blockHash": "0x8cd5f4a012d4f51460556c04b7fc6f4a4d94d1203cb092d0297372a43fdf283d", "transactions": [], "withdrawals": [ { "index": "0x8", "validatorIndex": "0x5", - "address": "0xa1fce4363854ff888cff4b8e7875d600c2682390", + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", "amount": "0x64" } ], @@ -1517,154 +3291,347 @@ "excessBlobGas": "0x0" }, [], - "0xbe3396540ea36c6928cccdcfe6c669666edbbbcd4be5e703f59de0e3c2720da7" + "0xd19f68026d22ae0f60215cfe4a160986c60378f554c763651d872ed82ad69ebb", + [] ] }, { "jsonrpc": "2.0", - "id": "np122", - "method": "engine_newPayloadV3", + "id": "np105", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1edbbce4143b5cb30e707564f7ada75afe632e72b13d7de14224e3ed0044a403", + "parentHash": "0x8cd5f4a012d4f51460556c04b7fc6f4a4d94d1203cb092d0297372a43fdf283d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6c921d64a95659dd6c62a919f2df9da2fda7cb8ec519aeb3b50ffb4e635dc561", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xa318a4d8ad3b1a05833ee60497927b12a615d115db0812903b6b3b0117aec6d0", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x7a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x4c4", + "blockNumber": "0x69", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x41a", "extraData": "0x", - "baseFeePerGas": "0x1c3b1", - "blockHash": "0x38e1ce2b062e29a9dbe5f29a5fc2b3c47bf2eed39c98d2b2689a2e01650e97ca", + "baseFeePerGas": "0x356", + "blockHash": "0xeba87b6b36d970ede1071402e363515bfc524572febb086525b84c792093175f", "transactions": [ - "0xf884628301c3b2830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0f48d056f98b681d69f84fcde715c63b1669b11563164d7c17e03e5d3a4641a0fa010fce327ee99c5206995065cbb134d5458143a34cbc64b326476aeef47ae482a" + "0xf883618203578301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa0a10fa7164cced8d2a3bd2f586c3bccaa86bec0337decd61d6196e028e4030c73a04f09a1f0824fc63829428889a95b7030d8dd809b9e56aea441a09a1a95802bef" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2d3fcfd65d0a6881a2e8684d03c2aa27aee6176514d9f6d8ebb3b766f85e1039" + "0xf087a515b4b62d707991988eb912d082b85ecdd52effc9e8a1ddf15a74388860", + [] ] }, { "jsonrpc": "2.0", - "id": "np123", - "method": "engine_newPayloadV3", + "id": "np106", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x38e1ce2b062e29a9dbe5f29a5fc2b3c47bf2eed39c98d2b2689a2e01650e97ca", + "parentHash": "0xeba87b6b36d970ede1071402e363515bfc524572febb086525b84c792093175f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x09df4733053f80da4904bce8d847883472e20bc3b1378eb1579e2e3df44d3948", - "receiptsRoot": "0x03ecb1b96e21ef88b48a9f1a85a170bdb0406e26918c7b14b9602e6f9a7e6937", - "logsBloom": "0x00000004000000000000002000000000000000004000000000000000000000000000400000400000000000000000010000080000000024404000000000000000000000000000000800000000020000000001000100000080000000000000000000000000000800000000000000000000000014000000000000000000000000001000000000000002000000100000000000000000000000000000040000000000000000000000000000040000020000000000000000200000000000000000000000000000000000000000000480010000000000000000000000040000000000000000000000000008000000000000000020000000000000000000000000000000", + "stateRoot": "0x905e296705351182cef7897c05522e78c9372cdcbd6a731907faee6f63d20b06", + "receiptsRoot": "0x9eeaf7ef73497823223378406a8d225dfe5b60042fce8770c0c2a7c2c5714936", + "logsBloom": "0x100000000000000000000000000000000000000000000000000004200000000000000000000000000000000020080000000400000000000000000000001000000000000800002000000000000000000200000000000000040000000000000004000000000000000000000001800000000000000000080a0000000000000000000800100000000080000000800000000040000000000004000000000000000000000000000000040000000000000000000000000000000000000000000000000000000020000000000000400000000020000000020000000000000800080020001000000000000000000000000000000040000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x7b", - "gasLimit": "0x47e7c40", + "blockNumber": "0x6a", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x4ce", + "timestamp": "0x424", "extraData": "0x", - "baseFeePerGas": "0x18b5b", - "blockHash": "0xda82bddbddc44bf3ce23eb1f6f94ae987861720b6b180176080919015b1e4e90", + "baseFeePerGas": "0x2ec", + "blockHash": "0x1db257ebc3fdfbb6fe6fa8234fbc771becfee96128648eac4164773196acea99", "transactions": [ - "0xf87b6383018b5c83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0b223787310f8ba4f9271d98c8bfc4f7e926ced7773cab6b5c856fb4c43b6dad5a07d0edf043f5b767ffd513479a43cbdc3dcbd18f254e3eb11043d4d7aa4dd7445" + "0xf87a628202ed83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0d24465c4877d28eae24a14ca982e561a5163c6bbe358b1c2f73ff936d50eaeb3a02eaa4e9b5434329a62f7bf3d254bb96eb7dd0b155f2cdb75f6ea37a3518c09f7" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7ce0d5c253a7f910cca7416e949ac04fdaec20a518ab6fcbe4a63d8b439a5cfc" + "0xf7e28b7daff5fad40ec1ef6a2b7e9066558126f62309a2ab0d0d775d892a06d6", + [] ] }, { "jsonrpc": "2.0", - "id": "np124", - "method": "engine_newPayloadV3", + "id": "np107", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xda82bddbddc44bf3ce23eb1f6f94ae987861720b6b180176080919015b1e4e90", + "parentHash": "0x1db257ebc3fdfbb6fe6fa8234fbc771becfee96128648eac4164773196acea99", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x15da947afcb1ba68f9fe2328e500881a302de649bd7d37f6e969bf7ec1aca37d", + "stateRoot": "0xb5b20b658b75ed622731629e45c6e98dcaaa3c55f1478d74482795b701eb20d0", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x7c", - "gasLimit": "0x47e7c40", + "blockNumber": "0x6b", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x4d8", + "timestamp": "0x42e", "extraData": "0x", - "baseFeePerGas": "0x15a06", - "blockHash": "0x8948407592d9c816f63c7194fa010c12115bee74e86c3b7d9e6ca30589830f21", + "baseFeePerGas": "0x28f", + "blockHash": "0x2a5fd10344d681d2e72384382583b1a9fd82fd0125a1fc24b4296bf3e37cf096", "transactions": [ - "0xf8666483015a078302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa037c41575c8abba9465870babe53a436d036974edf6a9de15d40fff1b4cca7552a07e815124c036ad7c603e7faa56d1d9e517d60cee33c1e47122a303e42d59b6fa" + "0xf865638202908302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0492cbed3575864725f568fc42711408ac80668d1afe3dcbce06a138f7b62bb35a0141638d9e8d058ac06a1e817e6c1f66d4a226de5d3047e043fb234b6b89d7e16" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4da13d835ea44926ee13f34ce8fcd4b9d3dc65be0a351115cf404234c7fbd256" + "0x77361844a8f4dd2451e6218d336378b837ba3fab921709708655e3f1ea91a435", + [] ] }, { "jsonrpc": "2.0", - "id": "np125", - "method": "engine_newPayloadV3", + "id": "np108", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8948407592d9c816f63c7194fa010c12115bee74e86c3b7d9e6ca30589830f21", + "parentHash": "0x2a5fd10344d681d2e72384382583b1a9fd82fd0125a1fc24b4296bf3e37cf096", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa085ae940536d1e745cf78acd4001cb88fbc1e939151193c4e792cb659fe1aa0", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0xbd4789f74fae185b96efda6c2ef419fe9ab9d33f89de1c3389d1c6e64672d663", + "receiptsRoot": "0x95393692a67eeda3b9cba04610c3dbf9c1a2fcef878680e3365e0a5e13995226", + "logsBloom": "0x00000000000000000000000000000000000000000000000000008000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x6c", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x438", + "extraData": "0x", + "baseFeePerGas": "0x23e", + "blockHash": "0x647266d2cef5a6b13af790b1b0af42fae3962e80f0724115407e6ecf0b2a6556", + "transactions": [ + "0x02f8d4870c72dd9d5e883e640182023f830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c9a87cc3076dc0da4656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a059b1019e8b01471b1dd478e65c30667d2d1780ed0c8bf5fc784b1413789b2f8201a0c50123161c011aa5c434f47412e85e3d23f83f8eb7f5e653b5e1014cd13528eaa0148a25184ec141ed7f9215254f4f4806f78da682c3d3f66aa3e3c1094f4db467" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xe3cb33c7b05692a6f25470fbd63ab9c986970190729fab43191379da38bc0d8c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np109", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x647266d2cef5a6b13af790b1b0af42fae3962e80f0724115407e6ecf0b2a6556", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0366e1c148753cbcf3400abb05da7ae31165163d45dad1c2f33f08f6b4ce4821", + "receiptsRoot": "0xd0d0683682a7dfeecf539831e169a2293fa3304248cecf6d40a759e36658877c", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000009000000000001000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x6d", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca90", + "timestamp": "0x442", + "extraData": "0x", + "baseFeePerGas": "0x1f7", + "blockHash": "0x52979d072bdf7bfb3fd707c0f83a4a3de1d1c8fb5380c240f858ed964aaa8106", + "transactions": [ + "0x01f8d3870c72dd9d5e883e658201f8830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c9ede968e005a23ff656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0468eae0ffdb87a4dc081a86c494969801637f690e1e1da15fb4a9d2c78272da801a0149abcc3167c411f429a2c9caa64e6ac3e56ae1085a23fcf6494e2ed5d384ef5a00e307ed91455775838666610589af7d05d007f7d0213d0dc50da7800f8501c95" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc893f9de119ec83fe37b178b5671d63448e9b5cde4de9a88cace3f52c2591194", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np110", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x52979d072bdf7bfb3fd707c0f83a4a3de1d1c8fb5380c240f858ed964aaa8106", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x34fed49a40f6a9d0ca498e700a05451505ba89367e63f7a46f1706e58117ac10", + "receiptsRoot": "0xf648e46bd37c97cd795ddfab278e6559906de048035d1506cd5d09af3b35e60e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000400000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x6e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x44c", + "extraData": "0x", + "baseFeePerGas": "0x1b9", + "blockHash": "0x7a86b91b59bbb2f833af91649b2cd1ba2b4e5f78e5775d78c03ab8b71045b3e3", + "transactions": [ + "0x03f8fa870c72dd9d5e883e66018201ba830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cfd87400839d77a68656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a00dcf6219856f226889a2440b388d8e15f5df0eb64a7b443f3a7a5dca7b87b0f283020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0931bd1e023b91d40d304e3f93356dc9a0458e42baff3b7902c8e37905ff2e12da0578219fac1e70b8e8df918fb511dd7d9c8ab126c302cd77d7777764febc9e3aa" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x39c96a6461782ac2efbcb5aaac2e133079b86fb29cb5ea69b0101bdad684ef0d", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np111", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x7a86b91b59bbb2f833af91649b2cd1ba2b4e5f78e5775d78c03ab8b71045b3e3", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xabb3c52d564e6e1e1c5d9bf01b6f4d60d32aed3d80a781c1467683529ad75882", + "receiptsRoot": "0x5034e9ebd4c3eb2a30e153892377f3cbc49ab2ad49da8eb85600997255c146bf", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000080000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x6f", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x456", + "extraData": "0x", + "baseFeePerGas": "0x183", + "blockHash": "0x4643bd6c3e1a9ac7a7ad650d12048b9e733e219b843f2b3d830f5da795852454", + "transactions": [ + "0xf87567820184830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ccf12b9aa38445e4b656d69748718e5bb3abd109fa07920da58c7a8bb3d1a93ae181aaba1994d54bfa9936c6847f452085ca4aab987a05f66b99150ed42111c97dc597bedc8b99a15de0e3fd079231d229d6f344da46e" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x72a2724cdf77138638a109f691465e55d32759d3c044a6cb41ab091c574e3bdb", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np112", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4643bd6c3e1a9ac7a7ad650d12048b9e733e219b843f2b3d830f5da795852454", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xcff80202fad319bbd221a272bf547ee59fc92bf289e20f3162b61a9fefd661af", + "receiptsRoot": "0x005fb2a0d0c8a6f3490f9594e6458703eea515262f1b69a1103492b61e8d0ee2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x7d", - "gasLimit": "0x47e7c40", + "blockNumber": "0x70", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", - "timestamp": "0x4e2", + "timestamp": "0x460", "extraData": "0x", - "baseFeePerGas": "0x12ee9", - "blockHash": "0x5f66e4813f2b86dc401a90a05aafd8a2c38f6f1241e8a947bf54d679014a06a5", + "baseFeePerGas": "0x153", + "blockHash": "0x7c1fb25dc97d20bb97dce8d8343149b20a96180f46f4b771285546da9d3ef7d3", "transactions": [ - "0x02f86c870c72dd9d5e883e650183012eea82520894d10b36aa74a59bcf4a88185837f658afaf3646ef0180c080a0882e961b849dc71672ce1014a55792da7aa8a43b07175d2b7452302c5b3cac2aa041356d00a158aa670c1a280b28b3bc8bb9d194a159c05812fa0a545f5b4bc57b" + "0x02f86b870c72dd9d5e883e680182015482520894eda8645ba6948855e3b3cd596bbb07596d59c6030180c001a0ec462cecc7c71106b7cc36137de204cc166a0c8903553bb54445d254c9fc0e59a07b804ce9fa8f68064c993b5da7db54cd8bed544975610c8a5f64e7bd6ecdabaa" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc5ee7483802009b45feabf4c5f701ec485f27bf7d2c4477b200ac53e210e9844" + "0x178ba15f24f0a8c33eed561d7927979c1215ddec20e1aef318db697ccfad0e03", + [] ] }, { "jsonrpc": "2.0", - "id": "np126", - "method": "engine_newPayloadV3", + "id": "np113", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5f66e4813f2b86dc401a90a05aafd8a2c38f6f1241e8a947bf54d679014a06a5", + "parentHash": "0x7c1fb25dc97d20bb97dce8d8343149b20a96180f46f4b771285546da9d3ef7d3", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xfb39354666f43e8f8b88f105333d6f595054b2e1b0019f89bf5dbddf7ec9a0ab", + "stateRoot": "0xc6eeb56e5484926bcf28f23f4c7a45270aa94a09b4d15ce8d3def1eacbe41ca4", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x71", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x46a", + "extraData": "0x", + "baseFeePerGas": "0x129", + "blockHash": "0xadf0cc4f267c585703d9e7403b046ab5ba320204592557eef982e4c409e3d2ea", + "transactions": [ + "0x01f86a870c72dd9d5e883e6982012a82520894717f8aa2b982bee0e29f573d31df288663e1ce160180c080a0ce04f690427d24c279459d884ed669546ce90f5f2df71b823876a7419259a73aa00609df091f125957bd4d9be5cf19f3470fe71e4be5b4db9f96a0daf31e8f5a57" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xf7b2c01b7c625588c9596972fdebae61db89f0d0f2b21286d4c0fa76683ff946", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np114", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xadf0cc4f267c585703d9e7403b046ab5ba320204592557eef982e4c409e3d2ea", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xa8849ca5ed7a18269196963d71e4ce3c8a376e81a85107104f467e1c77a9ddd6", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x72", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x474", + "extraData": "0x", + "baseFeePerGas": "0x104", + "blockHash": "0x2ee413006dcb6448fb5c37443102aae3575781369fa9cd34175c0f03e3ddb693", + "transactions": [ + "0xf8686a8201058252089484e75c28348fb86acea1a93a39426d7d60f4cc4601808718e5bb3abd10a0a0c3dc13e38f7bff80b68a31cc9e53f620161dd450f4c696236468eef7c7ba2faea01fb1bc7aa82335170e77594acf9aed68211234bde4bd9d174314178ef74dd94b" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x16e43284b041a4086ad1cbab9283d4ad3e8cc7c3a162f60b3df5538344ecdf54", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np115", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x2ee413006dcb6448fb5c37443102aae3575781369fa9cd34175c0f03e3ddb693", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x8a1ec9a0c964fbaf4b7f1767faad0ea0e1cc88801706c08e97c1b76933e8177b", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x7e", - "gasLimit": "0x47e7c40", + "blockNumber": "0x73", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x4ec", + "timestamp": "0x47e", "extraData": "0x", - "baseFeePerGas": "0x10912", - "blockHash": "0x1b452f327c51d7a41d706af9b74ac14ff50b74dcef77fdb94333a8f5c86436a8", + "baseFeePerGas": "0xe4", + "blockHash": "0x55487f68bbd481313212ae5cca520be32f0a54c44e77705e13518a9c8b1a54bf", "transactions": [], "withdrawals": [ { "index": "0x9", "validatorIndex": "0x5", - "address": "0x7ace431cb61584cb9b8dc7ec08cf38ac0a2d6496", + "address": "0xe7d13f7aa2a838d24c59b40186a0aca1e21cffcc", "amount": "0x64" } ], @@ -1672,154 +3639,347 @@ "excessBlobGas": "0x0" }, [], - "0x0fc71295326a7ae8e0776c61be67f3ed8770311df88e186405b8d75bd0be552b" + "0x0a98ea7f737e17706432eba283d50dde10891b49c3424d46918ed2b6af8ecf90", + [] ] }, { "jsonrpc": "2.0", - "id": "np127", - "method": "engine_newPayloadV3", + "id": "np116", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1b452f327c51d7a41d706af9b74ac14ff50b74dcef77fdb94333a8f5c86436a8", + "parentHash": "0x55487f68bbd481313212ae5cca520be32f0a54c44e77705e13518a9c8b1a54bf", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb042b6a0d783d5e3757a9799dbc66d75515d0a511e5157650048a883a48d7c75", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xa53943d22ce3fda978418903209e780b9878ead66bed439adf09e733ceffcb0e", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x7f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x4f6", + "blockNumber": "0x74", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x488", "extraData": "0x", - "baseFeePerGas": "0xe7f0", - "blockHash": "0x4831cdabfa81a5a7c4a8bb9fee309515e2d60dd5e754dfef4456794385771161", + "baseFeePerGas": "0xc8", + "blockHash": "0xd9fa2ad334f336af1b5f9fdb858c0ed6c956b7e0f9454c5e7ee8b64462725ec8", "transactions": [ - "0xf8836682e7f1830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0e5232243797a918b702f03aa9ccf4e944ff52293e7f5b7b1cb6874047f064ed6a02ae2cefc3e4fdb15fb4172d6fe04c7d54a312d077dcd15f91bf5f7047c10d079" + "0xf8826b81c98301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0844fce1ef5552ade29ffc13373e10f0c4b17c330e87863ce986fcd67a6f24e74a06ac11975e7515b69b03f90faf6f3206817931f607dd61040f8644241de4be8f0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7313b4315dd27586f940f8f2bf8af76825d8f24d2ae2c24d885dcb0cdd8d50f5" + "0x7637225dd61f90c3cb05fae157272985993b34d6c369bfe8372720339fe4ffd2", + [] ] }, { "jsonrpc": "2.0", - "id": "np128", - "method": "engine_newPayloadV3", + "id": "np117", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4831cdabfa81a5a7c4a8bb9fee309515e2d60dd5e754dfef4456794385771161", + "parentHash": "0xd9fa2ad334f336af1b5f9fdb858c0ed6c956b7e0f9454c5e7ee8b64462725ec8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0400502ad286f8ca3e6e362d38ec9f2119eddc480e9af1ec646bc48e5451a379", - "receiptsRoot": "0xdcfb036965921ecaf598a6a02e3fb77784da94be9ed9aeee279d085a20342e47", - "logsBloom": "0x00000002000041000000000200000200400000000000000008000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00080000000000000000000000000000000000000000000400000000000000008000000000000000000000014800000000000000000000000000000000000000000000000000000000000080000000000008000000000000000000000000000008000000000000000000000100000000000000000200000000000000000000000000000000000000030000800000000000000000000001000000002000000000000000020000400005002000004000000000000000000000", + "stateRoot": "0x7ebb65f88baf475ec0280941de0ec9b32ff0ecf1d4773ee5a2f2a736d14dfbf4", + "receiptsRoot": "0x6ac819d6516dcb344dca13b617ccde929eba52bdfff5b57fbc3449fa71daa72d", + "logsBloom": "0x00000000000000000020000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000100000000000010000000000000000000000000000000000000200000000000000000000000000000000000000000000004000000000002000040000000080200000000000000000000000000020000000040040410000000000000008000044000010000400000000000008000000000000200000000000000000000000000000000000000000000000008000000000000000000000000000000002000020000800084000000000080000000000400000000000000000080000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x80", - "gasLimit": "0x47e7c40", + "blockNumber": "0x75", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x500", + "timestamp": "0x492", "extraData": "0x", - "baseFeePerGas": "0xcb03", - "blockHash": "0xfadcdb29ddbfaed75902beaecb3b9e859bf4faefe78591baf8ac9c99faec09d2", + "baseFeePerGas": "0xb0", + "blockHash": "0xb7f7753236089ad38a8f5fc7d31811b521331e866eece20f7de934579ab95d1e", "transactions": [ - "0xf87a6782cb0483011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa07e94803268c610035c580891ef0c6edd5c21babd8a2bb54d22373e982db9bf46a0375bc266e5e65f0a899b2299ddddbdc0e0d7d40c21e6d254d664abd7d0698076" + "0xf8796c81b183011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0c174c4d0bb9963d480b8254de1b9147a6357c2f19e6ac8a71bcd11a7a2ab12dda0732a1860cec66350374c2cbac1a9f0e8b6386317aaf8597aa6c4bbab4991cfd5" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2739473baa23a9bca4e8d0f4f221cfa48440b4b73e2bae7386c14caccc6c2059" + "0x6a7d064bc053c0f437707df7c36b820cca4a2e9653dd1761941af4070f5273b6", + [] ] }, { "jsonrpc": "2.0", - "id": "np129", - "method": "engine_newPayloadV3", + "id": "np118", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfadcdb29ddbfaed75902beaecb3b9e859bf4faefe78591baf8ac9c99faec09d2", + "parentHash": "0xb7f7753236089ad38a8f5fc7d31811b521331e866eece20f7de934579ab95d1e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1f1fc8702bf538caf0df25f854999a44a7583b4339011bc24dadcee848e3daf5", + "stateRoot": "0xd65821d8f18e362704ebbc137324dcab618207ce58d8c92ef32990f4dff7761d", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x81", - "gasLimit": "0x47e7c40", + "blockNumber": "0x76", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x50a", + "timestamp": "0x49c", "extraData": "0x", - "baseFeePerGas": "0xb1ae", - "blockHash": "0x5bc61ce8add484ead933542e385d4592d82aac6d47b46dcb2451390b884b8c3d", + "baseFeePerGas": "0x9b", + "blockHash": "0xed36126582b6287363b3cbc31b9c39d7afd4d97ee5e83c00b2cd5449c1d6848a", "transactions": [ - "0xf8656882b1af8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a064097d6048ea289fa6b8a002f4a7d53d8381ee46bf0dadd3ac1befa477cef309a0300f780844db5eaa99ff65752886da8b671329d7c12db4e65dd7f525abe9b1d8" + "0xf8646d819c8302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0dfde1f4a31f0020dc87c2572131bf5d96b9e3a756a0c530eaf1af42c329c7576a02514150fb58cb64b06c460e7af51ded20ced9595d9de56ad88ec982cc5c4794d" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd4da00e33a11ee18f67b25ad5ff574cddcdccaa30e6743e01a531336b16cbf8f" + "0x91c1e6eec8f7944fd6aafdce5477f45d4f6e29298c9ef628a59e441a5e071fae", + [] ] }, { "jsonrpc": "2.0", - "id": "np130", - "method": "engine_newPayloadV3", + "id": "np119", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5bc61ce8add484ead933542e385d4592d82aac6d47b46dcb2451390b884b8c3d", + "parentHash": "0xed36126582b6287363b3cbc31b9c39d7afd4d97ee5e83c00b2cd5449c1d6848a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb04a7bb7f21e64f23bd415ee3ad1dc8a191975c86e0f0d43a92a4204a32ac090", + "stateRoot": "0xbfe4a4ed5d8c5dd809c20601719a5c989a00b8496c2dde4f63dff40ec1ee67ee", + "receiptsRoot": "0xbb4b35695bf1d4da91a2959a4e1beeaf0e94f784016e3abab46fcb118b19c33b", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000008000004000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x77", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x4a6", + "extraData": "0x", + "baseFeePerGas": "0x88", + "blockHash": "0x836c48482765990a0b394761a91ee93850aff87b82fac9b1def52375ed7535b3", + "transactions": [ + "0x02f8d3870c72dd9d5e883e6e018189830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ce5868624950d7b3f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a047cd31a1b89686fa610642222d2da6119e54ee8ca761bd01a649e3759e47746c80a0122f8ed1a3241a3f8428a9e8e34cf6da7ffcc6ae4ac12b7935aad14f1831d7faa0658f5be0960c1ceb873dee434e22a2c80cc97879133d1838673fc8579525d6fa" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xa1c227db9bbd2e49934bef01cbb506dd1e1c0671a81aabb1f90a90025980a3c3", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np120", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x836c48482765990a0b394761a91ee93850aff87b82fac9b1def52375ed7535b3", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0e82742b466bce6844a7e2805cca31bbe264af1734e9ea8bb532725d43b1237a", + "receiptsRoot": "0x3c2584b43ed6850bacfb2a0d19311ff17baaa0c01436e7a981abc5f0db79f8a6", + "logsBloom": "0x00800400000000000000000000000000000000000000000000040000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x78", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x4b0", + "extraData": "0x", + "baseFeePerGas": "0x78", + "blockHash": "0xf01e70ef5e688634e591415823fc7c898679659802e4db0de9ec3c3af735f664", + "transactions": [ + "0x01f8d1870c72dd9d5e883e6f79830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c3549372440f3505b656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0dbc7a073eb54d33d8e6dec5b0b635a874204bda1c23234ff0cca057ff8ed77f501a056996168cd85e8e5d689565d346c2e139aeef2bf6f1c65cc759b48fdd955968da07ff97b195809ea3b42ceeadcff6d101822cdaf6d1be0cb56fe2b0ef00b5b717a" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x8fcfc1af10f3e8671505afadfd459287ae98be634083b5a35a400cc9186694cf", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np121", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xf01e70ef5e688634e591415823fc7c898679659802e4db0de9ec3c3af735f664", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xae1f69500c8994278c41c0e159106e6f4b688be296fb115bfe6af77cf4d9e6fc", + "receiptsRoot": "0xf7b10686a974aa90247a5f4acaae577e16e0fafd0eed9eb02ebf8186c979cb7a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x79", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x4ba", + "extraData": "0x", + "baseFeePerGas": "0x6a", + "blockHash": "0xc04cb16eda5544fcfa77e18ed2092981e834e71cabc2b61bd25153c830b660ff", + "transactions": [ + "0x03f8f8870c72dd9d5e883e70016b830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c377bce5421c11bab656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a00f624930606bfcd2386d583abca6ab10227d71fc1633fea53f94bd146c152b8f83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a047e6cb09a7296ded3a00c5eb72eef7de21f83e5b4f1b5ddfe76bab19eec5bce9a02a0222118f9eb3daa5d7ea174cfe5ca3850889b08f71627e157e79c0c94c2f3d" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xcc1ea9c015bd3a6470669f85c5c13e42c1161fc79704143df347c4a621dff44f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np122", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xc04cb16eda5544fcfa77e18ed2092981e834e71cabc2b61bd25153c830b660ff", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1480fa2896359aa3cdc46abf7f813a7f4586ca63acc3ed60ad6c0e904bf82e47", + "receiptsRoot": "0xad3ae0362ab95a18b4cbd7d4aae22aa7043fc237ac9a9532d25781124f99d82a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000100800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000200000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x7a", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x4c4", + "extraData": "0x", + "baseFeePerGas": "0x5d", + "blockHash": "0x0041d260ba8d4501bbc92352b34daaaec17e3f3fc3652c9b92d87a587beaed96", + "transactions": [ + "0xf873715e830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c1e6612d36269933d656d69748718e5bb3abd10a0a0b4f6ac5bba5f751656d27aa834bd607a421be4b25fb9bd6d44c0d042590a59d5a0430846ae13aceaa6491aa630da433990c9e6f773ec33ec179917b9f18cc6e323" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xb0a22c625dd0c6534e29bccc9ebf94a550736e2c68140b9afe3ddc7216f797de", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np123", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x0041d260ba8d4501bbc92352b34daaaec17e3f3fc3652c9b92d87a587beaed96", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x05ec31cba0fd8b2ab3bccce33dedfdd7182dfb153dd7538793e27e630d026b93", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x7b", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x4ce", + "extraData": "0x", + "baseFeePerGas": "0x52", + "blockHash": "0xd2331ab665bad7fa9a43bc09da232bb06c72bc79d817a9f1c5bb05f96b9646e6", + "transactions": [ + "0x02f869870c72dd9d5e883e720153825208947435ed30a8b4aeb0877cef0c6e8cffe834eb865f0180c001a0ca6f290bc58c596ecf60c042d784bf6614046f417274749abb60a6c8dee20e60a028dc9de376bab6b0f4857ed3f07119ff61152305bc467e07e221f0950992a4c4" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x92b8e6ca20622e5fd91a8f58d0d4faaf7be48a53ea262e963bcf26a1698f9df3", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np124", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xd2331ab665bad7fa9a43bc09da232bb06c72bc79d817a9f1c5bb05f96b9646e6", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xdb068a648f8027eddd24cf90e37cff5d4b734d68270d9736ebcf79408bab0be3", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x7c", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x4d8", + "extraData": "0x", + "baseFeePerGas": "0x48", + "blockHash": "0x0043e6a0ed19de50761c59208a225a7f9bac091c3eb7dad46807998cf6ee69c7", + "transactions": [ + "0x01f868870c72dd9d5e883e7349825208940c2c51a0990aee1d73c1228de1586883415575080180c080a032a2fdfc6e8af7f2aa9e598c6030dcf3bd5bfb3b3e6dbc380ade9a4f6e24ea46a05c9e963837afa3b15e63566bfd577f10a2c35d5877c66fc85cee42ec7cca9f5c" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xf6253b8e2f31df6ca7a97086c3b4d49d9cbbbdfc5be731b0c3040a4381161c53", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np125", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x0043e6a0ed19de50761c59208a225a7f9bac091c3eb7dad46807998cf6ee69c7", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xa32b1b718a1517a2dbb796c8428a8949d51c845cb5bc68ddc5829aca9cd184b5", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x82", - "gasLimit": "0x47e7c40", + "blockNumber": "0x7d", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", - "timestamp": "0x514", + "timestamp": "0x4e2", "extraData": "0x", - "baseFeePerGas": "0x9b8b", - "blockHash": "0x30fcf7ed7c580b55b92289383259c5c1d380d54c1f527bfdc8b062af1e898b8f", + "baseFeePerGas": "0x40", + "blockHash": "0xf64f01561392db4d006de40b0c35b3b8b56204cbd89b734608d148d2ae629228", "transactions": [ - "0xf86869829b8c82520894a5ab782c805e8bfbe34cb65742a0471cf5a53a9701808718e5bb3abd10a0a078e180a6afd88ae67d063c032ffa7e1ee629ec053306ce2c0eb305b2fb98245ea07563e1d27126c9294391a71da19044cb964fd6c093e8bc2a606b6cb5a0a604ac" + "0xf86674418252089414e46043e63d0e3cdcf2530519f4cfaf35058cb201808718e5bb3abd10a0a04492dad8443375d9959f8fc24313113adbe78f4d8675ea6028d50fc459f3c34fa06222bd09536c90124b7a82a43c817c38a34ee8bed6af3fa4b293ae4aa31a189a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe651765d4860f0c46f191212c8193e7c82708e5d8bef1ed6f19bdde577f980cf" + "0xea8d762903bd24b80037d7ffe80019a086398608ead66208c18f0a5778620e67", + [] ] }, { "jsonrpc": "2.0", - "id": "np131", - "method": "engine_newPayloadV3", + "id": "np126", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x30fcf7ed7c580b55b92289383259c5c1d380d54c1f527bfdc8b062af1e898b8f", + "parentHash": "0xf64f01561392db4d006de40b0c35b3b8b56204cbd89b734608d148d2ae629228", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xfd2a1032389a1b7c6221d287a69e56a32d8a618396b8ef829601a9bcb3e91cce", + "stateRoot": "0xc7a87b275cac7243486e8f78dcd2dc1dd561d74319222ca75f00b2c4a1dff6bf", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x83", - "gasLimit": "0x47e7c40", + "blockNumber": "0x7e", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x51e", + "timestamp": "0x4ec", "extraData": "0x", - "baseFeePerGas": "0x881d", - "blockHash": "0x8b3a8443b32d2085952d89ca1b1ecb7574b37483cb38e71b150c00d001fea498", + "baseFeePerGas": "0x39", + "blockHash": "0x49e6318f4587a021ad50e32ccad223164e0cc1ba28e1be6ee01060d331ecebbf", "transactions": [], "withdrawals": [ { "index": "0xa", "validatorIndex": "0x5", - "address": "0x5ee0dd4d4840229fab4a86438efbcaf1b9571af9", + "address": "0x4340ee1b812acb40a1eb561c019c327b243b92df", "amount": "0x64" } ], @@ -1827,1549 +3987,1739 @@ "excessBlobGas": "0x0" }, [], - "0x5b5b49487967b3b60bd859ba2fb13290c6eaf67e97e9f9f9dda935c08564b5f6" + "0x543382975e955588ba19809cfe126ea15dc43c0bfe6a43d861d7ad40eac2c2f4", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np127", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x49e6318f4587a021ad50e32ccad223164e0cc1ba28e1be6ee01060d331ecebbf", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x96e7a8269c8e48ac7a7b445f1b438f88c1534d0bb86c21c7dd52885ec1481b8b", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x7f", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x4f6", + "extraData": "0x", + "baseFeePerGas": "0x32", + "blockHash": "0x51af93a015c8a1395fdf3030bfa74b3f7104037671ab930defa6eb75e222e1eb", + "transactions": [ + "0xf88175338301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa052d500007cddc18002c2672c0dbc1990811460048d361419dffade1ce101b832a04f6108a2fa5a99ffc810d8593e6c3995ada16e5a1ca772a67d9ac158256758e6" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x095294f7fe3eb90cf23b3127d40842f61b85da2f48f71234fb94d957d865a8a2", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np128", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x51af93a015c8a1395fdf3030bfa74b3f7104037671ab930defa6eb75e222e1eb", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x8310dc68223b2c72b24ce65dd25aaf65b275894ca69f2c7681680a7598571444", + "receiptsRoot": "0xefd8b8e464ca380008383fda4fac3a7a461e5f0474d252d603f316debd45de9c", + "logsBloom": "0x00000002000041000000000200000200400000000000000008000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c00080000000000000000000000000000000000000000000400000000000000008000000000000000000000000800000000000000000000000000000000000000000000000000000000000080000000000008000000000000000000000000000008000002000000000000000100000000000000000200000000000100000000000000000000000000030000800000000000000000000041000000002000000000000000020000400005002000004000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x80", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x500", + "extraData": "0x", + "baseFeePerGas": "0x2c", + "blockHash": "0x7ca2f8c5a75e26ee5575e7d68fb5035c6a3ad57fb35b1308c19cf0c563e86b55", + "transactions": [ + "0xf878762d83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0f681d83827bf4634bd4e1ecd3026953b8b2ebd0014c6db725491f9d6989e1e14a03b3335cf3f7999c19274f41fa482fb6363d4e18626accccadb347e5817b22481" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x144c2dd25fd12003ccd2678d69d30245b0222ce2d2bfead687931a7f6688482f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np129", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x7ca2f8c5a75e26ee5575e7d68fb5035c6a3ad57fb35b1308c19cf0c563e86b55", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xbcab9d02dcbf723c5d60536871e651f6ffe620546c5721cd6439f72fc9121935", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x81", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x50a", + "extraData": "0x", + "baseFeePerGas": "0x27", + "blockHash": "0x7614b81f123a279df0a712b8e9f0a9999add17fa9020ed9fabd1fd89315362cc", + "transactions": [ + "0xf86377288302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0c146142efd1561230a2d2ef6ecec9cf9be6271a10fd51ecf2e7ce09758037be9a069a11d8bac3df89cda3e144201a06f7fcf7e0cd170306e3d6cf0e51116efea64" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x7295f7d57a3547b191f55951f548479cbb9a60b47ba38beb8d85c4ccf0e4ae4c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np130", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x7614b81f123a279df0a712b8e9f0a9999add17fa9020ed9fabd1fd89315362cc", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x9c8f0ef089a58523152c15c140a1c89aeca3a7876045f93097574e1099f4583e", + "receiptsRoot": "0x0e199ed3c170c92dca3cd1aa9248fe6a9f6bcd95c64d18da5e54bdfc3b422717", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004800000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x82", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x514", + "extraData": "0x", + "baseFeePerGas": "0x23", + "blockHash": "0x218dd8608e6cdb93545a3e1203979ab4ca55f0f5bccf76a533fdd191d19f708a", + "transactions": [ + "0x02f8d2870c72dd9d5e883e780124830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c99ca04a4bf313cdd656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0562f817652b4478bc1e434240cd21e00774a5a1210833cbf0225273e2b98bae280a01f430a7342e607007f513ba0696d28e052c0a2ef944fa28aeaa4037034009210a0309576f12525f004074368b7f8248c46cb033b311c4d898f9c8fcfcb12c03e85" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x9e8e241e13f76a4e6d777a2dc64072de4737ac39272bb4987bcecbf60739ccf4", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np131", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x218dd8608e6cdb93545a3e1203979ab4ca55f0f5bccf76a533fdd191d19f708a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd4398f2e95d2b42f66c099f5f54bf784ba5e513926c56ffc18f72e9243c9256c", + "receiptsRoot": "0xd2739a1d0afc6cfbfb2a3cc7da84309cc3b60aef32cf4654c2d836a711bdbab0", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000001000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x83", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x51e", + "extraData": "0x", + "baseFeePerGas": "0x1f", + "blockHash": "0xa5e002a44d498e7a40b8a36eeb8ce8101353c3d379a5955d5809fcaf559a2bfb", + "transactions": [ + "0x01f8d1870c72dd9d5e883e7920830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cb3ce3e52ced1e406656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a07a9cae3647128ba14914f547c5f27444cd7325bbc37e5038abc31eea4500303480a0d3dd236e2e105b7bee61b1b48f944948afdcd12dfecb955bb752af7b8c046adda055eb47d4d846ad6954754a8bd9e8c224a2052202008ebdbbbb4fa7f339273c8d" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xfc753bcea3e720490efded4853ef1a1924665883de46c21039ec43e371e96bb9", + [] ] }, { "jsonrpc": "2.0", "id": "np132", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8b3a8443b32d2085952d89ca1b1ecb7574b37483cb38e71b150c00d001fea498", + "parentHash": "0xa5e002a44d498e7a40b8a36eeb8ce8101353c3d379a5955d5809fcaf559a2bfb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x91120613028234db2b47071a122f6ff291d837abe46f1f79830276fd23934c56", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xc2deaea2a4f5283a91fd7da8b0a078c1dee45e03e52373016e7880b32185601f", + "receiptsRoot": "0x24fd8bb66bc1411f5e1df9829f471db8c66dd4e59df98c2c7f016fdf1b95162c", + "logsBloom": "0x00000000000000000000000000000000000000000080000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000002000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x84", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x528", "extraData": "0x", - "baseFeePerGas": "0x771a", - "blockHash": "0xc9a9cc06b8a5d6edad0116a50740cb23d1cb130f6c3052bae9f69a20abf639c3", + "baseFeePerGas": "0x1c", + "blockHash": "0x1f7613cc089d031344e77e764174fee74d4eb6f501f467664b12220179d10fac", "transactions": [ - "0xf8836a82771b830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0a295fe01d21a6f8ffd36f8415e00da318f965a12155808a0d3b51c2c1914cf65a055022813f479686f077e227f3b00dc983081ad361dd8c8240b84d1cf86721ccf" + "0x03f8f8870c72dd9d5e883e7a011d830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c9686e77044883203656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a02daaea9286d7edb7568e0803a61bfdb1e1506156d27e93bdf1942564850646c683020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a02d932238962a79cf74fc0d1d98eb7eb35a6a95bb961538c9e439d457810940efa0607bd4ac5c4ab3080847eabc8647734c4f211dcbe0c02516bfac55bbb8bd4da6" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x57b73780cc42a6a36676ce7008459d5ba206389dc9300f1aecbd77c4b90277fa" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x5f5204c264b5967682836ed773aee0ea209840fe628fd1c8d61702c416b427ca", + [] ] }, { "jsonrpc": "2.0", "id": "np133", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc9a9cc06b8a5d6edad0116a50740cb23d1cb130f6c3052bae9f69a20abf639c3", + "parentHash": "0x1f7613cc089d031344e77e764174fee74d4eb6f501f467664b12220179d10fac", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1ec4000ab57cb0fec41b7221fff5ad7ec0dd4a042a739349045110b8116650c8", - "receiptsRoot": "0x870c88b91d896f4d6c0d6d8d9924dee345e36915e9244af9785f4ca1fea5fda3", - "logsBloom": "0x000000000008000000004000000000000000000000000000000000000000000400000000080000000000000000000000000000000000000000000000000c0000000000000000000002000000080000000000000000000004000000000000000000000000000000000000000000020000000400000000010000000040000000000000000000000000000004000000800008000100000202000000000000040000000000000000002000000000200000100000000000010000000000000001010000000000000000000000100000100000000401000000000000000000000000000000000000000000000000000000410000000800000000000000000000000000", + "stateRoot": "0x6cc6238c45c78f3aa66a619a09daf0d65769b3ef8698df424412d84e789d694c", + "receiptsRoot": "0xb85a4beec31e19cff4e11eedc6048b1458277fd803588a927a0b10645fbf09bb", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x85", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x532", "extraData": "0x", - "baseFeePerGas": "0x6840", - "blockHash": "0x4d61445a8ece151e7938bc9c2f4f819a10afddf32c0f2600d62281ecd6b1af69", + "baseFeePerGas": "0x19", + "blockHash": "0xab82fa0386891a0f6590a93f3b0c6852f582a38757c1a32d1d37a8195830c9ef", "transactions": [ - "0xf87a6b82684183011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa09ce0e0b4fb662dd87cf69350e376568655ce9436941c42e7815a0688db3d8281a037208359ff73e2b9389d9d6e32df5203a0239e5dbbf016e87b3714c122ff081f" + "0xf8737b1a830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c9080873b94ba4d37656d69748718e5bb3abd109fa039e86bd7baaa40d2feb73cc99b71b4ecca448258c13fbca6ade8b9148c464e22a07a9c6db0c1493357ac938689eb50dff7368fc83d774fb8779b6d3774b16dd2e9" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x217e8514ea30f1431dc3cd006fe730df721f961cebb5d0b52069d1b4e1ae5d13" + "0x5ba9a0326069e000b65b759236f46e54a0e052f379a876d242740c24f6c47aed", + [] ] }, { "jsonrpc": "2.0", "id": "np134", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4d61445a8ece151e7938bc9c2f4f819a10afddf32c0f2600d62281ecd6b1af69", + "parentHash": "0xab82fa0386891a0f6590a93f3b0c6852f582a38757c1a32d1d37a8195830c9ef", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb078e743044057e03f894971bfc3dca4dc78990d5cba60c7c979182c419528cf", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xb8f05e7edf45432becb47125a06723edfed825fe60d1c737495a2943f2931b94", + "receiptsRoot": "0x005fb2a0d0c8a6f3490f9594e6458703eea515262f1b69a1103492b61e8d0ee2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x86", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x53c", "extraData": "0x", - "baseFeePerGas": "0x5b3e", - "blockHash": "0xadcc471cc18ae64a1ece9ef42013441477843c72962bcc0f1291df9dc8906324", + "baseFeePerGas": "0x16", + "blockHash": "0xb0d4b43954c092e02e74342616a87ee25e15dabb9ba4d94c0bd474a907dff210", "transactions": [ - "0xf8656c825b3f8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0fd01a89a43af89dfba5de6077a24873a459ee0c8de3beaa03e444bb712fdbebda04f920e07882701d12f9016e32bfe5859d3c1bf971e844c6fcd336953190a8aad" + "0x02f869870c72dd9d5e883e7c011782520894eda8645ba6948855e3b3cd596bbb07596d59c6030180c001a08c9649b9b7aaf52480798b0a7cae37b11d92860c73e1b027f3fc679e6e4d7ccaa03075417132f7ae630e7e0f6b25b453fa59eec3098a931317d52c0578e02bef5a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x14b775119c252908bb10b13de9f8ae988302e1ea8b2e7a1b6d3c8ae24ba9396b" + "0xb40e9621d5634cd21f70274c345704af2e060c5befaeb2df109a78c7638167c2", + [] ] }, { "jsonrpc": "2.0", "id": "np135", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xadcc471cc18ae64a1ece9ef42013441477843c72962bcc0f1291df9dc8906324", + "parentHash": "0xb0d4b43954c092e02e74342616a87ee25e15dabb9ba4d94c0bd474a907dff210", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5ed1a679a1844883bb7c09f1349702b93a298fc8a77885f18810230f0322d292", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x3014013b123c35cd5d494cc382ce4fcb877bd594d6f34937fb169db6bd4b595e", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x87", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x546", "extraData": "0x", - "baseFeePerGas": "0x4fe0", - "blockHash": "0xd2e3126fb4b0cc3e1e98f8f2201e7a27192a721136d12c808f32a4ff0994601b", + "baseFeePerGas": "0x14", + "blockHash": "0xf14886af3d36d40608acfeebf709b67d679146b86594eb7f3d717ec214cb423c", "transactions": [ - "0x02f86b870c72dd9d5e883e6d01824fe1825208944bfa260a661d68110a7a0a45264d2d43af9727de0180c001a00bb105cab879992d2769014717857e3c9f036abf31aa59aed2c2da524d938ff8a03b5386a238de98973ff1a9cafa80c90cdcbdfdb4ca0e59ff2f48c925f0ea872e" + "0x01f868870c72dd9d5e883e7d1582520894d803681e487e6ac18053afc5a6cd813c86ec3e4d0180c001a09e397063008ad5f6e64e5523f5976457c60e7aa2b15caad46f81c8bf11bdd971a029ceb9831415f2670bacdba2bf1dfb10060b89df9ae3faf7cafc5186d89bf5c2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe736f0b3c5672f76332a38a6c1e66e5f39e0d01f1ddede2c24671f48e78daf63" + "0x70e26b74456e6fea452e04f8144be099b0af0e279febdff17dd4cdf9281e12a7", + [] ] }, { "jsonrpc": "2.0", "id": "np136", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd2e3126fb4b0cc3e1e98f8f2201e7a27192a721136d12c808f32a4ff0994601b", + "parentHash": "0xf14886af3d36d40608acfeebf709b67d679146b86594eb7f3d717ec214cb423c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd4db74075dc9ae020d6016214314a7602a834c72ec99e34396e1d326aa112a27", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xce9c1f4e0d2f824c7fd3f8d97a7d46b165f08b7f9e3cbd58bcff478ee5906e8d", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x88", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x550", "extraData": "0x", - "baseFeePerGas": "0x45e6", - "blockHash": "0xa503a85bc5c12d4108445d5eab6518f1e4ccaeab30434202b53204a9378419fa", - "transactions": [], - "withdrawals": [ - { - "index": "0xb", - "validatorIndex": "0x5", - "address": "0x4f362f9093bb8e7012f466224ff1237c0746d8c8", - "amount": "0x64" - } + "baseFeePerGas": "0x12", + "blockHash": "0xc310edfd4b8d1456b9d2f25ad392a0f409356115a0b6baa06c5055355e690380", + "transactions": [ + "0xf8667e13825208940c2c51a0990aee1d73c1228de15868834155750801808718e5bb3abd10a0a0a8e6163a5aaf23cc3407838738c30449547cab7596386147ca02e9187eb0223ca05f8d7500498eb3601b606146a5ca3e1e490aabbd8398f95f7498deddec90f868" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7d112c85b58c64c576d34ea7a7c18287981885892fbf95110e62add156ca572e" + "0x43d7158f48fb1f124b2962dff613c5b4b8ea415967f2b528af6e7ae280d658e5", + [] ] }, { "jsonrpc": "2.0", "id": "np137", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa503a85bc5c12d4108445d5eab6518f1e4ccaeab30434202b53204a9378419fa", + "parentHash": "0xc310edfd4b8d1456b9d2f25ad392a0f409356115a0b6baa06c5055355e690380", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xfd5f001adc20a6ab7bcb9cd5ce2ea1de26d9ecc573a7b595d2f6d682cf006610", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x34907069df9fccdce8426d160e557127cb90c64dd2a3c49eaffaec5cfce14889", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x89", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x55a", "extraData": "0x", - "baseFeePerGas": "0x3d2a", - "blockHash": "0xe0b036f2df5813e2e265d606ee533cd46924a8a7de2988e0e872c8b92c26399c", - "transactions": [ - "0xf8836e823d2b830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0e853c07d5aba01cfcacc3a4191551d7b47d2e90aba323bd29b5b552147bc4055a03a7e1dee0d461376b43ac4c0dd1a85cc94e9fa64aa8effec98c026293e47240a" + "baseFeePerGas": "0x10", + "blockHash": "0xeb26879fc8d9023ee720917ace6b9bfebe36c4b18c476581524c26ff6b1b1770", + "transactions": [], + "withdrawals": [ + { + "index": "0xb", + "validatorIndex": "0x5", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x28fbeedc649ed9d2a6feda6e5a2576949da6812235ebdfd030f8105d012f5074" + "0xb50b2b14efba477dddca9682df1eafc66a9811c9c5bd1ae796abbef27ba14eb4", + [] ] }, { "jsonrpc": "2.0", "id": "np138", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe0b036f2df5813e2e265d606ee533cd46924a8a7de2988e0e872c8b92c26399c", + "parentHash": "0xeb26879fc8d9023ee720917ace6b9bfebe36c4b18c476581524c26ff6b1b1770", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3bf11932c08c5317c7463697409eba5a6904575cc03593cb0eac6c82093d79b7", - "receiptsRoot": "0x3ef7cc7ec86f1ace231cdf7c7fadaf27ae84ad4afdd5f2261b60d5be03794001", - "logsBloom": "0x00000000000000000000080000000000000000000000000000000000000000000000000010000000004000008000000000000000000000000000000080001000000020000000000000000000000000000000000000000000000010000010200000040220000000000000000000010001000000800000000000400000002000000000000000000000400000000000000800000000000400000000000000080000500000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000004002000000000008000000000002000000400000000000000000000000000002000000000002000000000000002000000", + "stateRoot": "0xf24a7ac20ba67253c7f7dbcd1f1fb58f3b560da554fdf15787adcc2ea7352f04", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x8a", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x564", "extraData": "0x", - "baseFeePerGas": "0x358a", - "blockHash": "0xfcca6f4e35f290be297bf6403b84c99d1a7b6d78299b5e2690d915bf834e85da", + "baseFeePerGas": "0xe", + "blockHash": "0xbc885f1dd76d6044edf950a00f65f8b7e09037b64694a8a5bf040a8f875df73d", "transactions": [ - "0xf87a6f82358b83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0c28b8f557aaf82e47d9e1425824709427513131908ac636f142990468e40909ea05fe11510da000868cfe1a05bdf689a8c1954c87afeb9ef2defbed3075458a6ad" + "0xf8817f0f8301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa00e72485654ffa94bcd36d1670fc89157d9195087a4958e6ea2c10562eced83c1a077968946182406940484c4909601e11ed580e2696f3493c7175fbddd19312c93" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6f7410cf59e390abe233de2a3e3fe022b63b78a92f6f4e3c54aced57b6c3daa6" + "0xc14936902147e9a121121f424ecd4d90313ce7fc603f3922cebb7d628ab2c8dd", + [] ] }, { "jsonrpc": "2.0", "id": "np139", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfcca6f4e35f290be297bf6403b84c99d1a7b6d78299b5e2690d915bf834e85da", + "parentHash": "0xbc885f1dd76d6044edf950a00f65f8b7e09037b64694a8a5bf040a8f875df73d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe8258bde0dceac7f4b4734c8fa80fe5be662ae7238d9beb9669bc3ae4699efa8", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x374c1bfe201a2258607d0523b591bb3ab9321842477f16707d83aac398f7f16b", + "receiptsRoot": "0xbd8b87a861501658112e3db9724e09bd5b25d0893525ffda947d4779df5c8b9b", + "logsBloom": "0x00000000040000000000000000000000000000000000200000080000000000000000000000000000000000000000000000000000040000400000100000000000000000000001000000000004000000000000000008000002200000000000080000800000000000000000000000000000080800000000000000001040100080000000000000000000000000000000000000000000000000004000000101000200000000004000000000010000000800000000000000000000000100000000000010000000080020000000000000000000000000000000000000000000040000000000000000000000000000000000000000800000000000000000000008000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x8b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x56e", "extraData": "0x", - "baseFeePerGas": "0x2edc", - "blockHash": "0x762df3955fc857f4c97acb59e4d7b69779986e20e3a8ea6bc5219dfd9e5a3d7e", + "baseFeePerGas": "0xd", + "blockHash": "0x3f8e6751bb589f71b4529f33b341be4bcbb64cc89a86ac00ba2ecd28b96843f4", "transactions": [ - "0xf86570822edd8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a02206472edd9c816508c6711c004500028a4a6a206caf23b20c6828dd60e1533fa0186dc116a92a8455d1cb92ed4b599c3f7cade6cf59da63b1aef46936c3a507e9" + "0xf87981800e83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa02e68a3e01e0491870679191bd5d5a8f24c9ad0695c0e466a5b2083bb17939812a02c6946e6087d40aa0f34fbf65c20f71298b0acab2931d114f9253ca0bd2aeeee" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd5edc3d8781deea3b577e772f51949a8866f2aa933149f622f05cde2ebba9adb" + "0x86609ed192561602f181a9833573213eb7077ee69d65107fa94f657f33b144d2", + [] ] }, { "jsonrpc": "2.0", "id": "np140", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x762df3955fc857f4c97acb59e4d7b69779986e20e3a8ea6bc5219dfd9e5a3d7e", + "parentHash": "0x3f8e6751bb589f71b4529f33b341be4bcbb64cc89a86ac00ba2ecd28b96843f4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9ff9a193050e74dfa00105084fa236099def4aa7993691c911db0a3f93422aeb", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xe12f0c307f5b8dbd21ffb62035a3a29f8214b886fb4ab820d52e777272739527", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x8c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x578", "extraData": "0x", - "baseFeePerGas": "0x2906", - "blockHash": "0xffe6c202961ee6b5098db912c7203b49aa3b303b4482234371b49f7ef7a95f84", + "baseFeePerGas": "0xc", + "blockHash": "0x53c40989ba0f74285db823aeb706fbdd2f34e53b65edf8edda6054f6fe0154f0", "transactions": [ - "0xf86871822907825208949defb0a9e163278be0e05aa01b312ec78cfa372601808718e5bb3abd109fa04adf7509b10551a97f2cb6262c331096d354c6c8742aca384e63986006b8ac93a0581250d189e9e1557ccc88190cff66de404c99754b4eb3c94bb3c6ce89157281" + "0xf86481810d8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0790f5ed3e0a86db50c08e8f8be00a4ffba3441d16fb346dc9770eb3ed42d3382a04e5977b201718f87ecefd86cb78c73e445490319a286721ea8eca3e1d9d56326" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x20308d99bc1e1b1b0717f32b9a3a869f4318f5f0eb4ed81fddd10696c9746c6b" + "0x0a71a6dbc360e176a0f665787ed3e092541c655024d0b136a04ceedf572c57c5", + [] ] }, { "jsonrpc": "2.0", "id": "np141", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xffe6c202961ee6b5098db912c7203b49aa3b303b4482234371b49f7ef7a95f84", + "parentHash": "0x53c40989ba0f74285db823aeb706fbdd2f34e53b65edf8edda6054f6fe0154f0", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf63dc083849dc5e722a7ca08620f43fc5cd558669664a485a3933b4dae3b84f4", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xf54e2a19725ec61f6c584507212b46c69f46612692deb8831b23169f30c7d8c3", + "receiptsRoot": "0xa8125b1762025ce748089560e745a695d68cd5f1d6bce93b9c203e3ead57e848", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000008000000000000000000000000004000000000000204000000000000000000000000002000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x8d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x582", "extraData": "0x", - "baseFeePerGas": "0x23e6", - "blockHash": "0xfa0dcd8b9d6e1c42eeea7bb90a311dd8b7215d858b6c4fb0f64ee01f2be00cfe", - "transactions": [], - "withdrawals": [ - { - "index": "0xc", - "validatorIndex": "0x5", - "address": "0x075198bfe61765d35f990debe90959d438a943ce", - "amount": "0x64" - } + "baseFeePerGas": "0xb", + "blockHash": "0x56aac6e61bbe149532c6f833c15bea8fd7739b35b114c63d0c81d1b6803a9324", + "transactions": [ + "0x02f8d3870c72dd9d5e883e8182010c830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ccbf493b3fd5e21b0656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0b9f03edd278ccfc90e45785c1fea3f972618a32899f836dd4fe0e63eaf8c7c4001a0b3b89d84c11187bb50f67a342fdae6a35e024b4a6a4ff546733645767045760ca05e1eeee847ab7f53450eccdf65f9dcc0d41c4e709dd5d9ea938fbeff783e5d68" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x91f7a302057a2e21d5e0ef4b8eea75dfb8b37f2c2db05c5a84517aaebc9d5131" + "0xa4bcbab632ddd52cb85f039e48c111a521e8944b9bdbaf79dd7c80b20221e4d6", + [] ] }, { "jsonrpc": "2.0", "id": "np142", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfa0dcd8b9d6e1c42eeea7bb90a311dd8b7215d858b6c4fb0f64ee01f2be00cfe", + "parentHash": "0x56aac6e61bbe149532c6f833c15bea8fd7739b35b114c63d0c81d1b6803a9324", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6222bb96d397776358dd71f14580f5464202313769960ec680c50d9ccc2fa778", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xb964b6c8e95c7efa510287147e3ff724e70b308f6057ab45a7b2145b39747d25", + "receiptsRoot": "0x9d62ba578ebcff7a0054729605a139f9f7292833c6773b0ef0125f3e7723f404", + "logsBloom": "0x04000000000000000000000000000000000000000000000000000000800002000000000000000000000001000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x8e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x58c", "extraData": "0x", - "baseFeePerGas": "0x1f6a", - "blockHash": "0xe501e9f498cd6b1a6d22c96a556c9218e3a7960eea3e9ab4ac2760cc09fdca0d", + "baseFeePerGas": "0xa", + "blockHash": "0x20a194b00f602fcb1db01bb84014dda4654f7bbf59de521992100e4c90d95eae", "transactions": [ - "0xf88372821f6b830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa067091ae37d21fdc5f9eed2877bddb24e52f69e80af27a89608b6fba1c5053f32a04817ab7dc0c3eaac266b08a1683c34fcd43098c6219ea5771d35fa3387b705a1" + "0x01f8d2870c72dd9d5e883e81830b830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cff183a49015bd7b5656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a02df4cc92987ab73b08a3474750456382a0add51fa25f928480762f3d993f298480a0db78a0e59dce232f5116604b4eedf3edf585172a505530cd0ced9c1574be944ea051d0573c904c5fbddea3424251c85cc629f7d4c8e4ec14a25d6bfa929c375b22" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x743e5d0a5be47d489b121edb9f98dad7d0a85fc260909083656fabaf6d404774" + "0x2bc468eab4fad397f9136f80179729b54caa2cb47c06b0695aab85cf9813620d", + [] ] }, { "jsonrpc": "2.0", "id": "np143", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe501e9f498cd6b1a6d22c96a556c9218e3a7960eea3e9ab4ac2760cc09fdca0d", + "parentHash": "0x20a194b00f602fcb1db01bb84014dda4654f7bbf59de521992100e4c90d95eae", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbe8a51adbc81161927f0b6f3e562cd046f1894145010a1b3d77394780478df3c", - "receiptsRoot": "0x8c32e3da3725025cad909cb977e252fd127d54c4f4da3852d18ef3976bfe4610", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000001000000000000004000000000000000000000000000800000000000000000000028000000020008000000008000000000000000000000000010000000000080000100000400100000000000000000000000100000000010000000000000000000000000000004000000000000000000008000000000080008000000000000000000000000000000000000000000080002800000000000120000000000004000000000000000000000004000000400000002000800000020000000080000000000000008000000000000000000000000000", + "stateRoot": "0x4ec7a8beedb541399d064d98c10425602e479459c9dc4a3e3ea520bff571c303", + "receiptsRoot": "0x7a3e7656e97605f422dad63c732f0d4f9b377abf5f689e6797fb4ac3a371eb97", + "logsBloom": "0x00000000000000000000000000000000000000000000200000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000200000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x8f", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x596", "extraData": "0x", - "baseFeePerGas": "0x1b7f", - "blockHash": "0xdb3eb92355d58f317e762879ec891a76e0d9ba32a43f0a70f862af93780ef078", + "baseFeePerGas": "0x9", + "blockHash": "0x6a7e2a65b2c12ddb337eef91aa0772eae0064f24028cbb5f8d4d7c0c8f1437f9", "transactions": [ - "0xf87a73821b8083011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0de521643ceaf711d0d3b6cda406ef8fba599658fccc750139851846435eba8afa057f5427948ca8d46609925641f81f72115860c16228821020b8020846a4c3158" + "0x03f8f9870c72dd9d5e883e8184010a830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c3a4d2a2d8e89dcaa656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0faca663a6ed04f52c0e7a8981cb438545f614a2cf84f9077659d0fce0045cda783020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a026afa46d3cb08b993c92000c3d8ee74b6abc12ab63e64adfcb0555404d56b899a0420f20f106de44b6e28510d45b612268c1c0172aaceae7569db3ffd1cd1da249" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xcdcf99c6e2e7d0951f762e787bdbe0e2b3b320815c9d2be91e9cd0848653e839" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xfc7f9a432e6fd69aaf025f64a326ab7221311147dd99d558633579a4d8a0667b", + [] ] }, { "jsonrpc": "2.0", "id": "np144", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xdb3eb92355d58f317e762879ec891a76e0d9ba32a43f0a70f862af93780ef078", + "parentHash": "0x6a7e2a65b2c12ddb337eef91aa0772eae0064f24028cbb5f8d4d7c0c8f1437f9", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb7933a921b5acf566cc2b8edb815d81a221222a0ac36dac609927aa75744daaf", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x4eec2647b04de80dc0d87bbea4c6b0ab96e8b2bc11ee339fe44817f348e5e296", + "receiptsRoot": "0x7d644822f58fb3e699e5d3b1d271ffae81684f751f34c5b7fa47ab9dda46fce7", + "logsBloom": "0x00000040000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000200000200000000000000000000000000002000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x90", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x5a0", "extraData": "0x", - "baseFeePerGas": "0x1811", - "blockHash": "0x6718dc62462698e0df2188c40596275679d2b8a49ab6fd6532a3d7c37efd30a6", + "baseFeePerGas": "0x8", + "blockHash": "0x2f3f1707049c34f0ce4b2222d6cbe9f149d79a0e2c1ea6101058cefe33e9b3f6", "transactions": [ - "0xf865748218128302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0afbda9fa76936bc6be4d26905bc000b4b14cae781a8e3acb69675b6c5be20835a03858ad4e7e694bf0da56994a1e5f855ff845bae344de14109ae46607aa4172ca" + "0xf874818509830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c80c3c5cf7f5cf0b5656d69748718e5bb3abd10a0a0e0ac4eff9ebab8559197243bef5cd2c60aa79adebc4497312e60029f504dcf14a02434c08e81ef95b7ecf18451d4ed1840da75b11851e68df7a9854c74be700af1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xcc9476183d27810e9738f382c7f2124976735ed89bbafc7dc19c99db8cfa9ad1" + "0x949613bd67fb0a68cf58a22e60e7b9b2ccbabb60d1d58c64c15e27a9dec2fb35", + [] ] }, { "jsonrpc": "2.0", "id": "np145", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6718dc62462698e0df2188c40596275679d2b8a49ab6fd6532a3d7c37efd30a6", + "parentHash": "0x2f3f1707049c34f0ce4b2222d6cbe9f149d79a0e2c1ea6101058cefe33e9b3f6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa8a6a6386a956afbc3163f2ccdcaeffeb9b12c10d4bb40f2ef67bcb6df7cf64c", + "stateRoot": "0xc45cb8b8a6cc4822bb401e7544b060f50bfaa1a177423c129d9c54ea0e67e3eb", "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x91", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x5aa", "extraData": "0x", - "baseFeePerGas": "0x1512", - "blockHash": "0x891051fb49d284166b72a30c29b63bfe59994c9db2d89e54ca0791b4dfdb68fb", + "baseFeePerGas": "0x8", + "blockHash": "0xb7332dcef7339e1aaf6fe2b41257738e00b916fbb030c919dafa065f36889886", "transactions": [ - "0x02f86b870c72dd9d5e883e7501821513825208947da59d0dfbe21f43e842e8afb43e12a6445bbac00180c080a06ca026ba6084e875f3ae5220bc6beb1cdb34e8415b4082a23dd2a0f7c13f81eca0568da83b9f5855b786ac46fb241eee56b6165c3cc350d604e155aca72b0e0eb1" + "0x02f86a870c72dd9d5e883e81860109825208947435ed30a8b4aeb0877cef0c6e8cffe834eb865f0180c080a090531038e16ae92f428682d1c2c7d7f318184674978738bab0b4981d95fd10b3a01e7d766f9c50ecd0b97fbe73e9256debb5113427989e5ea170f9d8dd62952e6b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf67e5fab2e7cacf5b89acd75ec53b0527d45435adddac6ee7523a345dcbcdceb" + "0x289ddb1aee772ad60043ecf17a882c36a988101af91ac177954862e62012fc0e", + [] ] }, { "jsonrpc": "2.0", "id": "np146", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x891051fb49d284166b72a30c29b63bfe59994c9db2d89e54ca0791b4dfdb68fb", + "parentHash": "0xb7332dcef7339e1aaf6fe2b41257738e00b916fbb030c919dafa065f36889886", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9ee7ad908d7c553d62d14ecd6a1e9eac6ed728f9a0d0dd8aa8db149e6e803262", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x943ea463107bb78f57c7c9b85983de8d4d60b6d134b20fecd0795eee98b5053a", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x92", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x5b4", "extraData": "0x", - "baseFeePerGas": "0x1271", - "blockHash": "0x2ef94fa352357c07d9be6e271d8096b2cbf7dcae9bad922e95bc7c7c24375e7c", - "transactions": [], - "withdrawals": [ - { - "index": "0xd", - "validatorIndex": "0x5", - "address": "0x956062137518b270d730d4753000896de17c100a", - "amount": "0x64" - } + "baseFeePerGas": "0x8", + "blockHash": "0x03c384271631c83751232b695f032adf6fb4244c81cbebf3e6fdd030b61e384b", + "transactions": [ + "0x01f869870c72dd9d5e883e81870982520894d803681e487e6ac18053afc5a6cd813c86ec3e4d0180c001a0e9b2c7aa279c415491f684a96341e7f0423497e2709f335a338642e0ef35f01ba04438415c1afa592f8319c78f4b7b6c38da34495df036c9291d063b14d33b1997" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe20f8ab522b2f0d12c068043852139965161851ad910b840db53604c8774a579" + "0xbfa48b05faa1a2ee14b3eaed0b75f0d265686b6ce3f2b7fa051b8dc98bc23d6a", + [] ] }, { "jsonrpc": "2.0", "id": "np147", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2ef94fa352357c07d9be6e271d8096b2cbf7dcae9bad922e95bc7c7c24375e7c", + "parentHash": "0x03c384271631c83751232b695f032adf6fb4244c81cbebf3e6fdd030b61e384b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x14111c2a0f5c36f6b8ea455b9b897ab921a0f530aaee00447af56ffc35940e32", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x327d285af76733061aa1841998502862449c00ef7f48e95ab14bd3d27d96b3d6", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x93", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x5be", "extraData": "0x", - "baseFeePerGas": "0x1023", - "blockHash": "0x406fbf5c2aa4db48fce6fe0041d09a3387c2c18c57a4fb77eca5d073586ca3ea", + "baseFeePerGas": "0x8", + "blockHash": "0x5d72bae0b85bb59e94d55b7f439c6c0a9a1a8a47fa242f5dc64a82b880260cfe", "transactions": [ - "0xf88376821024830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa08e5e1207971ec2479337fa7c80f843dd80d51224eb9f9d8c37b1758d3d5acae4a04d2f89fb9005dc18fa4c72e8b1b4e611f90ca9c5e346b6201dfe4b83ec39c519" + "0xf8678188098252089414e46043e63d0e3cdcf2530519f4cfaf35058cb201808718e5bb3abd10a0a060af856a9de223c16e8b15052f3917b808c2e18c2f3053604b378fa1b4722761a07d65c79888d1e83e012b101aed962efcdce3d1f4feb0d63547137c2f822f3122" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf982160785861cb970559d980208dd00e6a2ec315f5857df175891b171438eeb" + "0x7bf49590a866893dc77444d89717942e09acc299eea972e8a7908e9d694a1150", + [] ] }, { "jsonrpc": "2.0", "id": "np148", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x406fbf5c2aa4db48fce6fe0041d09a3387c2c18c57a4fb77eca5d073586ca3ea", + "parentHash": "0x5d72bae0b85bb59e94d55b7f439c6c0a9a1a8a47fa242f5dc64a82b880260cfe", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc43ae2200cea3bdd1b211157150bd773118c818669e2650659ef3807ac7d2c29", - "receiptsRoot": "0x1f4bdefd1b3ded1be79051fe46e6e09f4543d4c983fdc21dee02b1e43fb34959", - "logsBloom": "0x00000000000000000000000000000110000000000002000000000000000000020008000000000000000800001000000000000000000000000020000010000400000000000000000000001000000000000000000000000000000020000000000000101000000000800000000000000000080000000000000000000000000000010000080000080000800000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000200000020000000000000000000000000002000001000000000040002000000024000000000280000000000000000000000000020000", + "stateRoot": "0xbde8a50be5930aa6dac2c84e5826117c2f051180a1f6029b8148245bd25c1f8d", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x94", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x5c8", "extraData": "0x", - "baseFeePerGas": "0xe20", - "blockHash": "0x34ca9a29c1cef7e8011dcce6240c1e36ee8e64643fc0ed98cb436d2f9a21baa2", - "transactions": [ - "0xf87a77820e2183011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0b5b7b281fbe78ca0f9819a9015997a42ee896462db5ea7de089cd7e2cf84b346a02bc85175e51da947f89f947c30d7c1d77daa6e654a0007e56de98812039a76bd" + "baseFeePerGas": "0x8", + "blockHash": "0xb3a80dd6748adaba8d2598da58441cc645b165d96de91b605122e82caff076d8", + "transactions": [], + "withdrawals": [ + { + "index": "0xc", + "validatorIndex": "0x5", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x230954c737211b72d5c7dcfe420bb07d5d72f2b4868c5976dd22c00d3df0c0b6" + "0x992f76aee242737eb21f14b65827f3ebc42524fb422b17f414f33c35a24092db", + [] ] }, { "jsonrpc": "2.0", "id": "np149", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x34ca9a29c1cef7e8011dcce6240c1e36ee8e64643fc0ed98cb436d2f9a21baa2", + "parentHash": "0xb3a80dd6748adaba8d2598da58441cc645b165d96de91b605122e82caff076d8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x21cafe51bfa7793c9a02f20282b59cbb5156dce1e252ab61f98fdd5cdecf8495", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xdb57798d9239d49ad7beff96ac5d91cca083a8d83e6847a8f645d921b0445d7c", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x95", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x5d2", "extraData": "0x", - "baseFeePerGas": "0xc5d", - "blockHash": "0xed939dcec9a20516bd7bb357af132b884efb9f6a6fc2bc04d4a1e5063f653031", + "baseFeePerGas": "0x7", + "blockHash": "0x32305ca5493b007b7c591c7ea565ad705010ad747126202b191c78ffb49ea51e", "transactions": [ - "0xf86578820c5e8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0371194d9f0d8b28bc888d45cc571dd73c9dd620d54184b9776256d5e07049350a05f7bfb7cdccb54a2f0ea01374f1474e694daa1b128076bdc33efcee9bc0d56a7" + "0xf8828189088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a01c38a62689270d465f4bda87acb5d75a053abb6bbbf49e6fc7cd16208906fba5a06de900ab669c0bda07ae794da2fc54a615003fb80e57615fd5b9b0f586915f5f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb7743e65d6bbe09d5531f1bc98964f75943d8c13e27527ca6afd40ca069265d4" + "0xda6e4f935d966e90dffc6ac0f6d137d9e9c97d65396627e5486d0089b94076fa", + [] ] }, { "jsonrpc": "2.0", "id": "np150", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xed939dcec9a20516bd7bb357af132b884efb9f6a6fc2bc04d4a1e5063f653031", + "parentHash": "0x32305ca5493b007b7c591c7ea565ad705010ad747126202b191c78ffb49ea51e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x503c44cab4d6c0010c3493e219249f1e30cfff1979b9da7268fd1121af73d872", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x89e41795c7ad30582f1551e838f9801c8ef860a3306fb2d644e46d2cd92402e7", + "receiptsRoot": "0x17f90c244a9a77995c62ce193b5d9794f865c66a53604d9a9d1b78f3742b3634", + "logsBloom": "0x00000000000000000000000000000000008000000000000008000000000000000000000000000000000000008100000000000000000000000000400000000000800000000000000000000000000000000080000000000000000040000002040400440010000000000008000000000000010000000000000040000000000000000000000000000000000000000040000000000020000000000001000000004000000000000000000000000000080000000008000000000000840000000000000040000000008000000000000000000000080000000000000000002000000000040004000000000000000000000000000000000010000000000000100000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x96", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x5dc", "extraData": "0x", - "baseFeePerGas": "0xad3", - "blockHash": "0x136665ab7316f05d4419e1f96315d3386b85ec0baeed10c0233f6e4148815746", + "baseFeePerGas": "0x7", + "blockHash": "0x11b82f7fbb7a781b00b4eb695a56aacd1a5477a2bc4e8167d4c08b95c4186e4c", "transactions": [ - "0xf86879820ad48252089484873854dba02cf6a765a6277a311301b2656a7f01808718e5bb3abd10a0a0ab3202c9ba5532322b9d4eb7f4bdf19369f04c97f008cf407a2668f5353e8a1fa05affa251c8d29f1741d26b42a8720c416f7832593cd3b64dff1311a337799e8f" + "0xf879818a0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0fb6bc8abefcdf980e3381a9e578c4cf34833af1c70660974f233fe998c298865a020bf2bbe3972007569c1ae08084b52510f8814b4f769fa66d962aadbb9537776" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x31ac943dc649c639fa6221400183ca827c07b812a6fbfc1795eb835aa280adf3" + "0x65467514ed80f25b299dcf74fb74e21e9bb929832a349711cf327c2f8b60b57f", + [] ] }, { "jsonrpc": "2.0", "id": "np151", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x136665ab7316f05d4419e1f96315d3386b85ec0baeed10c0233f6e4148815746", + "parentHash": "0x11b82f7fbb7a781b00b4eb695a56aacd1a5477a2bc4e8167d4c08b95c4186e4c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2e257bca2ea424f7c304c42fc35b14c8d3fd46c9066c7f895f775a2065a14bab", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x49c3d821bbff9c9c40c6f7394732381dcbb37e24e9f3f74691f394705e3d2be6", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x97", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x5e6", "extraData": "0x", - "baseFeePerGas": "0x979", - "blockHash": "0xefc08cafa0b7c0e0bc67c0dbd563a855ba55f389d947bd9c524be5ef789505ba", - "transactions": [], - "withdrawals": [ - { - "index": "0xe", - "validatorIndex": "0x5", - "address": "0x2a0ab732b4e9d85ef7dc25303b64ab527c25a4d7", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0x7ad16d4c674b10a59ca3364904af33fa3713db2e963cf7c36da3f3172a917aaa", + "transactions": [ + "0xf864818b088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa08e7741ea80652f87e939c0f591416f0f73151b81bcc63ae349f0c9bf56908a95a06ee9f7164b8ddce20836b87a826a5c526ffdfb40990a65a087ac7d87d364fceb" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xded49c937c48d466987a4130f4b6d04ef658029673c3afc99f70f33b552e178d" + "0xcc2ac03d7a26ff16c990c5f67fa03dabda95641a988deec72ed2fe38c0f289d6", + [] ] }, { "jsonrpc": "2.0", "id": "np152", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xefc08cafa0b7c0e0bc67c0dbd563a855ba55f389d947bd9c524be5ef789505ba", + "parentHash": "0x7ad16d4c674b10a59ca3364904af33fa3713db2e963cf7c36da3f3172a917aaa", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa124fe0abd3682da7263262172c9d2c57fb42d4f131cbc9f24ddea0ec1505e48", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x37df5f0770949e923cb083680259e9e615f6bc1a603a2023a2abc463a88ef54c", + "receiptsRoot": "0xac2a853b1066ff5e9270a7a956abece9e2bd883772b78533d9df88a8b4a1f7b8", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x98", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x5f0", "extraData": "0x", - "baseFeePerGas": "0x84a", - "blockHash": "0xb7a12ba1b0cd24019d0b9864ed28c0d460425eb1bd32837538d99da90f5c65b7", + "baseFeePerGas": "0x7", + "blockHash": "0xe756ee647aad508c521e5463abc774c9ad8d3ac6f25a52c4b6970a04f716331d", "transactions": [ - "0xf8837a82084b830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0be58da9e68f28cf1dd209a610214982ba767249f3b92cd8c0fb3850a9ee194d6a0613f59eec6c092b6d2fc55de85bc67b21c261dc48f1ddb74af3aac438b27ccd5" + "0x02f8d3870c72dd9d5e883e818c0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c6053ba2fde42abfb656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a072be914df22404e1ed45a8224b52201a77605d52065746a00af5f60980fa4c9980a0522b27fdb7acd48ea02e87e558d437f945b892fc546ca6bd82a043e0153b28b8a06cae65c67e0dd039ec3d58ea6f186c847da741c79ee2173f06659592a285c797" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa0effc449cab515020d2012897155a792bce529cbd8d5a4cf94d0bbf141afeb6" + "0x096dbe9a0190c6badf79de3747abfd4d5eda3ab95b439922cae7ec0cfcd79290", + [] ] }, { "jsonrpc": "2.0", "id": "np153", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb7a12ba1b0cd24019d0b9864ed28c0d460425eb1bd32837538d99da90f5c65b7", + "parentHash": "0xe756ee647aad508c521e5463abc774c9ad8d3ac6f25a52c4b6970a04f716331d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3c05bdceef0bdc9f676a3a0c00151f975e469e5bb08ab08f3eed090987119672", - "receiptsRoot": "0x73faa109b88bfbf7e2a71c36d556d9286c0a26988680cbe3058f045fd361b3b0", - "logsBloom": "0x00004000000800000000000000000000000000000000000000000000000000000004000000080000000000000800000000000000500000000000000000000200000000001000000800000000000002008000080000000000000000000000000000000000000000000008000200000000000000000000000000000001000000000000000000101000004000000000000000000000000000000000000000000000000000000080000000000000000000008200000000000080000000000000000000000000000000000800000000000000000000000400000080020002000000001040000000000000000000000000004000000000000000008000008000000000", + "stateRoot": "0x9017dac7007df13ce16ccdf5385ba94ee95ab77dd4f1351b3caf925f6616166f", + "receiptsRoot": "0x8e9254ee48bb358e97f45c836031761c1a46f624715a4ba1b30c2d86bc19d704", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000009000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x99", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x5fa", "extraData": "0x", - "baseFeePerGas": "0x742", - "blockHash": "0x0292db163d287eeb39bd22b82c483c9b83a9103a0c425a4f3954ef2330cc1718", + "baseFeePerGas": "0x7", + "blockHash": "0x1a924af515c53c392afb3be5839f952f6495116f677ba7cc630c76d08fa12e24", "transactions": [ - "0xf87a7b82074383011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0b9eb0510fdc334dde88b8ac75869aa2dd53988191ae1df94b7b926eae9b18050a00cbd9e12b7185723ed407175a7a70fa5cc0dbc4014b3040a9ade24a4eb97c8c1" + "0x01f8d2870c72dd9d5e883e818d08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ca6e511cffb46c94d656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0f8b0a158a81e46d2f46d268e7726acaf7c33fc321c36f6157f07abbf7fa49e5b01a0715913aa6cf5380403ee348bd55e7c9a3dfc41f1b9a4e28a7955e310be9aaa9ea02fec01c6a963c199e0797a76be983eb17c1ec48c18fd2a17f9490337497f584b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x1f36d9c66a0d437d8e49ffaeaa00f341e9630791b374e8bc0c16059c7445721f" + "0x0c659c769744094f60332ec247799d7ed5ae311d5738daa5dcead3f47ca7a8a2", + [] ] }, { "jsonrpc": "2.0", "id": "np154", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x0292db163d287eeb39bd22b82c483c9b83a9103a0c425a4f3954ef2330cc1718", + "parentHash": "0x1a924af515c53c392afb3be5839f952f6495116f677ba7cc630c76d08fa12e24", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc2e93862e26d4df238b2b83a3ee0e008f25123aa211d83906fcd77bc9fd226ab", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xe438b4371e3f6c985c10f21afbe1df068e63ae81bed7214ebc6ab201ac562903", + "receiptsRoot": "0x4c32e94ddeb7664373b789e8223b53175959a2abdbd83227de34a34669f3b84a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000c00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x9a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x604", "extraData": "0x", - "baseFeePerGas": "0x65b", - "blockHash": "0xaeab3fe4b09329235bd8a0399db4d944fe1b247a91055c7de7f53703c94357ea", + "baseFeePerGas": "0x7", + "blockHash": "0x0de1dee56d87848e4730dd05feae6c512a356a38bd52304e1e399e8d48be718b", "transactions": [ - "0xf8657c82065c8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0e5959821e9fe4b896ef2559fe6524aadead228d89f923061b6d2d340f6b9307fa02ed2929f37d24a57229f7a579aaab2d9551e71b0822895e91f04e7824da9a861" + "0x03f8f9870c72dd9d5e883e818e0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c9ff25288d1780279656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0e6a5227fabefc934ddc0a3142a50747ad1157ad0829ec0bbc389d5e22e3282c283020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a080987e3e15e1c0d42cfb26bb7680ac355d8dc6a1984ec21d99001393e2164d36a0787b1b461bd9e5a1924ca1cbdf05320add9bb8021bed65b80f07707b2aa6cf9f" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x34f89e6134f26e7110b47ffc942a847d8c03deeed1b33b9c041218c4e1a1a4e6" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x9cb8a0d41ede6b951c29182422db215e22aedfa1a3549cd27b960a768f6ed522", + [] ] }, { "jsonrpc": "2.0", "id": "np155", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xaeab3fe4b09329235bd8a0399db4d944fe1b247a91055c7de7f53703c94357ea", + "parentHash": "0x0de1dee56d87848e4730dd05feae6c512a356a38bd52304e1e399e8d48be718b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0c94e7ea002f7b3bcc5100783e1e792160fb73ff4e836cd295e34423ff72f2a6", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xce08dc560fbc13b5694bdc9f5e22f3708caed3ed03102074fcf4425a6c451018", + "receiptsRoot": "0x687695a315f4cdc3fcdd030f1478f03077e99bba681e7a2b1e9b2f4c616033a2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000100000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000040000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x9b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x60e", "extraData": "0x", - "baseFeePerGas": "0x591", - "blockHash": "0xcc221bd9ee16f8302994c688cd7cc18313e686cf21f29edea5da5ac08a28a9b6", + "baseFeePerGas": "0x7", + "blockHash": "0xde590f5a6aa2882e34cb6894bf54e16296d5abeb244c7df2c0b12ec627c41432", "transactions": [ - "0x02f86b870c72dd9d5e883e7d01820592825208948d36bbb3d6fbf24f38ba020d9ceeef5d4562f5f20180c001a0f9075613b9069dab277505c54e8381b0bb91032f688a6fe036ef83f016771897a04cb4fc2e695439af564635863f0855e1f40865997663d900bc2ab572e78a70a2" + "0xf874818f08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c67720111e9886ccf656d69748718e5bb3abd10a0a00c9e5d0c1e1d14bd227c8daf4d9d1a15293c6a488248dcf111ecf973274988f9a008ec61336a0c67d4cc8567abd645aaec105905d1f3638a195a1ad9d0d81eb250" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x774404c430041ca4a58fdc281e99bf6fcb014973165370556d9e73fdec6d597b" + "0x2510f8256a020f4735e2be224e3bc3e8c14e56f7588315f069630fe24ce2fa26", + [] ] }, { "jsonrpc": "2.0", "id": "np156", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcc221bd9ee16f8302994c688cd7cc18313e686cf21f29edea5da5ac08a28a9b6", + "parentHash": "0xde590f5a6aa2882e34cb6894bf54e16296d5abeb244c7df2c0b12ec627c41432", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x04ba5addea7916f0483658ea884c052ea6d759eeda62b9b47ee307bd46525bb0", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x346aaa3da9697932f0716771cd128bc92e7ce3616e4fe38278a93cdc844e993e", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x9c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x618", "extraData": "0x", - "baseFeePerGas": "0x4df", - "blockHash": "0x8c922bb4a1c7aad6fdc09082e5c90427d0643ffd281d0154cdd71a372108c5da", - "transactions": [], - "withdrawals": [ - { - "index": "0xf", - "validatorIndex": "0x5", - "address": "0x6e3faf1e27d45fca70234ae8f6f0a734622cff8a", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0xcf5949ad3562b8f632d82c9af77116a0b83b9b9806e86d0c2bce517c7be2e842", + "transactions": [ + "0x02f86a870c72dd9d5e883e81900108825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df0180c080a0732ede76830c2550b47c03a4df6dc6c1690ee0ebab6bc51c2f411a513be950bca0030ab88f2cde156cb8f2646f2f6c85ec20d8639c17fe58d708902c976e692519" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd616971210c381584bf4846ab5837b53e062cbbb89d112c758b4bd00ce577f09" + "0x2d3deb2385a2d230512707ece0bc6098ea788e3d5debb3911abe9a710dd332ea", + [] ] }, { "jsonrpc": "2.0", "id": "np157", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8c922bb4a1c7aad6fdc09082e5c90427d0643ffd281d0154cdd71a372108c5da", + "parentHash": "0xcf5949ad3562b8f632d82c9af77116a0b83b9b9806e86d0c2bce517c7be2e842", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3ae465791b7ce8492961c071fc50b34434552a1ab36c1854fbc308f55729e827", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x38c9484710c5444a193d3fc1448b8ed06532fa7073760da3393403ca34057c9f", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x9d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x622", "extraData": "0x", - "baseFeePerGas": "0x444", - "blockHash": "0x1a883eed15a2f61dc157140d45f50e4bc6cc08ead08adf3ff0804ec9f1104c8a", + "baseFeePerGas": "0x7", + "blockHash": "0xb158abf8e49c9fa6cf8103699f81039a82d085721e5cff677edec8c43bee073d", "transactions": [ - "0xf8837e820445830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0140e450a0bc12c61bdf6acca1a56178466d88014d00a4a09c1088ce184128327a07daad374bb0d7fe879212bd7bdc8d454b4996bd7bebd6f6d0d4636ec7df28d0b" + "0x01f869870c72dd9d5e883e81910882520894e7d13f7aa2a838d24c59b40186a0aca1e21cffcc0180c001a0d1bbed0389a5e060eee006d53bae7c7fd7c6890b17a4132712081a6b4cc5865ca021c33c5e1aeb65f26efcd10806ffa37f5703430185c700867bd46d0a782ed315" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xcdf6383634b0431468f6f5af19a2b7a087478b42489608c64555ea1ae0a7ee19" + "0x1cec4b230f3bccfff7ca197c4a35cb5b95ff7785d064be3628235971b7aff27c", + [] ] }, { "jsonrpc": "2.0", "id": "np158", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1a883eed15a2f61dc157140d45f50e4bc6cc08ead08adf3ff0804ec9f1104c8a", + "parentHash": "0xb158abf8e49c9fa6cf8103699f81039a82d085721e5cff677edec8c43bee073d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe01f0f54fba649cdc0d6da6a9f519b6918149d82f134845e99847ff7b362b050", - "receiptsRoot": "0x36340e11a5f180862d423a676049d1c934b8d27940fdd50dc8704563ffd27b0f", - "logsBloom": "0x00000000000000008000000000800080000000000000000018040000000100100000000000010000000000000000000000000000000000000000000000010000000080080000800000000000010000000010000000000802000000000000000000000000001000000000004000000000000000000000004000000000000000004000000000000000000000000000000000000000000000401000000000010000000000000000000000000000000080000000000000000000000040000240000000000000000000000001000000000000000000000000100000000080000040000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xe25e53409bfccf98112b91a7055943795d2113d83922d66880721a98d54cad66", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x9e", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x62c", "extraData": "0x", - "baseFeePerGas": "0x3bc", - "blockHash": "0x5efcd9acd57f0652b1aa46406cf889b0da1f05e34fa9b642f7dec1bd924f3fd0", + "baseFeePerGas": "0x7", + "blockHash": "0x4c5f50016d24ab6a9b40d925d7b4be07d51679d2f5b12565958dfa80229031fa", "transactions": [ - "0xf87a7f8203bd83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0331dd2ec5bf4bddde96cacb8a28ed1cc577d4a2289bae6da0e6ef3c9b1287fc3a04c2925895dfbed2b00ac9a2040371970da1a7fd333dc1e551e2e268c56717c79" + "0xf8678192088252089483c7e323d189f18725ac510004fdc2941f8c4a7801808718e5bb3abd10a0a06dac6d4bfed86b0059948afae52133c3e337647d78d1fa5936c9ae819e786645a01cb72ae9ae1feebdc94e332cb21e9180e56e8a604d94c8d100002f260a96cb2a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x00ec22e5df77320b4142c54fceaf2fe7ea30d1a72dc9c969a22acf66858d582b" + "0x18e4a4238d43929180c7a626ae6f8c87a88d723b661549f2f76ff51726833598", + [] ] }, { "jsonrpc": "2.0", "id": "np159", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5efcd9acd57f0652b1aa46406cf889b0da1f05e34fa9b642f7dec1bd924f3fd0", + "parentHash": "0x4c5f50016d24ab6a9b40d925d7b4be07d51679d2f5b12565958dfa80229031fa", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa6e1d00e54b539beb170e510a8594fdd73ad2bf8e695a0f052291454ee1f3ade", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xc65e57367ac6ff6635a710d5bc27bebe7f80d0021157eda2596ccb455f88f048", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x9f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x636", "extraData": "0x", - "baseFeePerGas": "0x345", - "blockHash": "0x97570840bed5a39a4580302a64cbaf7ed55bcc82e9296502c4873d84f8384004", - "transactions": [ - "0xf86681808203468302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0f4a1b0681bb3c513fa757b560ef9cf0f004b8da91d920e157506ebb60d0d3954a0738da3b003ce68a9b4032770c0fe6481f54ea43baba54cad7153369486728790" + "baseFeePerGas": "0x7", + "blockHash": "0xdbbf71ab7420933453fd51ae3e6cdb95f05e1c25016e979fbe33deb794ea9ae2", + "transactions": [], + "withdrawals": [ + { + "index": "0xd", + "validatorIndex": "0x5", + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xcb32d77facfda4decff9e08df5a5810fa42585fdf96f0db9b63b196116fbb6af" + "0x700e1755641a437c8dc888df24a5d80f80f9eaa0d17ddab17db4eb364432a1f5", + [] ] }, { "jsonrpc": "2.0", "id": "np160", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x97570840bed5a39a4580302a64cbaf7ed55bcc82e9296502c4873d84f8384004", + "parentHash": "0xdbbf71ab7420933453fd51ae3e6cdb95f05e1c25016e979fbe33deb794ea9ae2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9277b9454326e993436cef0b9a2e775cff46439f3d683da55a983e9850943a20", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xea0aba9aaa2ae0cf32fec0e4b08a632e9b8d8887865acf1e68540e4f4a4afe84", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x640", "extraData": "0x", - "baseFeePerGas": "0x2dd", - "blockHash": "0x4b01a4f9f924e7e386d2c94653c80bab2e3069d744ab107dd181d9b5f5d176d0", + "baseFeePerGas": "0x7", + "blockHash": "0xe2e850cb3176df3accc03247b8e9cdb15261ac3021c4911839aad275fe2a42ef", "transactions": [ - "0xf86981818202de82520894c19a797fa1fd590cd2e5b42d1cf5f246e29b916801808718e5bb3abd109fa0857754afc3330f54a3e6400f502ad4a850a968671b641e271dcb9f68aacea291a07d8f3fb2f3062c39d4271535a7d02960be9cb5a0a8de0baef2211604576369bf" + "0xf8828193088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a040f8d2fcd495c8f12942431ed7a6d5256b628943b9fa7a303335348cf89c8885a00313b5b242e626a8d8add5c6534c8bfd4a8e89216286c97b4bd5afa5c0029f47" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6d76316f272f0212123d0b4b21d16835fe6f7a2b4d1960386d8a161da2b7c6a2" + "0xcad29ceb73b2f3c90d864a2c27a464b36b980458e2d8c4c7f32f70afad707312", + [] ] }, { "jsonrpc": "2.0", "id": "np161", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4b01a4f9f924e7e386d2c94653c80bab2e3069d744ab107dd181d9b5f5d176d0", + "parentHash": "0xe2e850cb3176df3accc03247b8e9cdb15261ac3021c4911839aad275fe2a42ef", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc9f74f81ace1e39dd67d9903221e22f1558da032968a4aaff354eaa92289f5c6", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x134a16436f36855eedcee6544782decc1791b81080f1ed90a44b8b75eeb08605", + "receiptsRoot": "0x4cc54ac939400db6a2166180135b79d2c15a4bd2809d5bcebc29edcb76790555", + "logsBloom": "0x000000000080000000010000200000000000000080000000000000000000000000000000000040000000000400000000000000000000008000000000000002000000000000000000000000000004000800080000000000000000000000100000000200000000000000000000000000000000000008000000000000000000000000000000100000000000000000000000000000000000000400200000000000000000010000000000000001010080000400000100000000000000000000c0001020000000000000000000000000000000000000000001000000200000000000000000000100000000000000000000010000000040200000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x64a", "extraData": "0x", - "baseFeePerGas": "0x282", - "blockHash": "0x9431a8d1844da9cc43e8b338de21722e23f78ed5b46391a6d924595759773286", - "transactions": [], - "withdrawals": [ - { - "index": "0x10", - "validatorIndex": "0x5", - "address": "0x8a8950f7623663222542c9469c73be3c4c81bbdf", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0x5fd45fdf3f74bde3842258b46aec022feec7f5148302447a63b6e480d4444330", + "transactions": [ + "0xf87981940883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa00fa1d4ec54187e3d7d841b1e6593ecaf79255268f6ff6de216214efde80089c7a06575a46743117ed35853698e47b367112b81b09d8cef718f35f4e811114cc260" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2de2da72ae329e359b655fc6311a707b06dc930126a27261b0e8ec803bdb5cbf" + "0xa85e892063a7fd41d37142ae38037967eb047436c727fcf0bad813d316efe09f", + [] ] }, { "jsonrpc": "2.0", "id": "np162", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9431a8d1844da9cc43e8b338de21722e23f78ed5b46391a6d924595759773286", + "parentHash": "0x5fd45fdf3f74bde3842258b46aec022feec7f5148302447a63b6e480d4444330", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x853c0a8e4e964cc857f2dd40b10de2cefb2294a7da4d83d7b1da2f9581ee0961", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xb0c8f232687dbcac3ee4d9142855aeaa4623b0a201f5fb0dbc6206e76daec3a8", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x654", "extraData": "0x", - "baseFeePerGas": "0x232", - "blockHash": "0x604f361dbc1085fb70812b618e53035d4747c3969a96620e4c179a93be5d124d", + "baseFeePerGas": "0x7", + "blockHash": "0x639a8f45c9f9219f27cf4db4c33de2d346df8a09dcc770ac6044f60184330864", "transactions": [ - "0xf8848182820233830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa01a7b8af754eba43e369957a413a3fef1255659f2bd05f902b29ee213c3989d46a00ca88ac892d58fdb0d9bd7640ca797280081275886cc2ac155a814eb498e7d7b" + "0xf8648195088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0cd33c99152a08debe65994ef384af02421d2608bd849e3edf699f2a1e0e60b64a030dcdc834dd98a1f6f8ea6f840146af61439872287267af4e461ab8494c28dc1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x08bed4b39d14dc1e72e80f605573cde6145b12693204f9af18bbc94a82389500" + "0x040100f17208bcbd9456c62d98846859f7a5efa0e45a5b3a6f0b763b9c700fec", + [] ] }, { "jsonrpc": "2.0", "id": "np163", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x604f361dbc1085fb70812b618e53035d4747c3969a96620e4c179a93be5d124d", + "parentHash": "0x639a8f45c9f9219f27cf4db4c33de2d346df8a09dcc770ac6044f60184330864", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd89e02bde63bf214ad6a3bc94f3b092bc2a1fbc13f172049c854ecb070630fe6", - "receiptsRoot": "0x596413315e1e3fd6fc21e4ce81e618b76ad2bf7babfa040c822a5bcbffeb63be", - "logsBloom": "0x00080000001044010000000800000000000000000010000000040000000020000000800000000040000000000000000001008000000000800000000000000000000000001000000000020000080000000000000000000000000000000000000002000044000000000000000000000000000000000000000000000000000000000000002000000000000000800000000000000000000000000000000000104000800000000000000004000004000002000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000800020000000000000000000040000000000000000020", + "stateRoot": "0xdd32fc8571657d3464251558c486ff861307737b49054d272262dbe5fcbdd593", + "receiptsRoot": "0x9066b594cce8a9e20431c038c86c396aa3496faedf1d9e1e5ff05387c36ed966", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000002000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa3", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x65e", "extraData": "0x", - "baseFeePerGas": "0x1ec", - "blockHash": "0x00979cd18ef128aa75a51ad8606b381ce53f72c37d17bc6c6613d8de722abcfa", + "baseFeePerGas": "0x7", + "blockHash": "0x45941317b4ff496cb5e8832d48f69c5f1d611cf609bf3d2933dba68dae211c49", "transactions": [ - "0xf87b81838201ed83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa06e6e8187c035f2788ba44e3f47b4102a1f263ae2f601b2fbfa9e2cdc3b0c22b1a06c229eebca1bdda1aba424cd8cf296f386cf2d50a6add950fd6cb34aac442c5a" + "0x02f8d3870c72dd9d5e883e81960108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c690ca2dda4d66fb3656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0ff5c526fc525d03cecce39f4ec167af09f80525e2d44e60ee4df33a357b24ed201a0c7f4fb8e478d0b3739b860f0368dbbca53502c2d71bca014ae9f8eea8262a3cba04efef6442d91a5470a0c8382d0804a6f1e1496722c12794354965577eb687605" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe437f0465ac29b0e889ef4f577c939dd39363c08fcfc81ee61aa0b4f55805f69" + "0x49d54a5147de1f5208c509b194af6d64b509398e4f255c20315131e921f7bd04", + [] ] }, { "jsonrpc": "2.0", "id": "np164", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x00979cd18ef128aa75a51ad8606b381ce53f72c37d17bc6c6613d8de722abcfa", + "parentHash": "0x45941317b4ff496cb5e8832d48f69c5f1d611cf609bf3d2933dba68dae211c49", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe2672f9ae97aeaeb22f42c389301a3b79ad6c47ad88c54e18e1d7a4ed5e9c903", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x5553e1692be29a202dee1fd0a0faccc7277830f2c548d8ed47f7b893c563dcb2", + "receiptsRoot": "0x38a18fba7aa21f6f6ceb46a7528f7d9c29d6b4df3481cb302f43b2f2b5084d8b", + "logsBloom": "0x04000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x668", "extraData": "0x", - "baseFeePerGas": "0x1af", - "blockHash": "0xcabf8c1b47839908f6eb28261876b52404f3f8787c94d8aadc0aca721ff35d13", + "baseFeePerGas": "0x7", + "blockHash": "0x471066471af127a34b62c9f34c3fbfb26ba29d233f81d568f4d120d35d50ceaa", "transactions": [ - "0xf86681848201b08302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa08ab61fe0265afe289954f7c2af8e070f3c40dda39e6cb6ff5c798fc7bc87b55ba00a8a440a7ba5a04a7bb73b093e94734dda228d33a43c640d719aef5ea5e81764" + "0x01f8d2870c72dd9d5e883e819708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c3ca23be55f2c8073656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a085ca3ddf1ae9fb0aeadecd8109961dc5d5eaff16ef7adc672149a7826c69da9780a02c872933387857b9fec1927c3c165793e90839365712494d58200e9de8b2f857a049ec239515f6ed48ce0fa7a523131fded9c6c580edc6df2a3b7f76544b617cc4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x89ca120183cc7085b6d4674d779fc4fbc9de520779bfbc3ebf65f9663cb88080" + "0x810ff6fcafb9373a4df3e91ab1ca64a2955c9e42ad8af964f829e38e0ea4ee20", + [] ] }, { "jsonrpc": "2.0", "id": "np165", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcabf8c1b47839908f6eb28261876b52404f3f8787c94d8aadc0aca721ff35d13", + "parentHash": "0x471066471af127a34b62c9f34c3fbfb26ba29d233f81d568f4d120d35d50ceaa", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4d9cd7b52c0daaec9a019730c237a2c3424f5d5a004c8bc9fa23997f3ec33768", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xc5a4ddf07d3a195d208631b627fa15b7b25e9ab983a75f5b037195df8a509ec9", + "receiptsRoot": "0x5eff3beb82c599d5d1f903ed5c7e366d0d784353dbc0e531e781fa82ca4f8cc5", + "logsBloom": "0x00000000000000000000000000008000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa5", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x672", "extraData": "0x", - "baseFeePerGas": "0x17a", - "blockHash": "0x6dcec039f7777c1fd96bbdd342e0ed787211132f753cf73a59847dc6cb30a6ff", + "baseFeePerGas": "0x7", + "blockHash": "0xe89e5d3756805d8458b5057f19b7d97faa7fa2351b2a08ddd75405c00af3a8c6", "transactions": [ - "0x02f86c870c72dd9d5e883e81850182017b825208946922e93e3827642ce4b883c756b31abf800366490180c080a089e6d36baf81743f164397205ded9e5b3c807e943610d5b9adb9cfeb71b90299a03d56c57f842a92a5eb71c8f9f394fe106d993960421c711498013806957fdcaf" + "0x03f8f9870c72dd9d5e883e81980108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cc6f00ba448f8e0bc656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a06a99e5276c6ea0c0894cfaf376fbbfdc736b359e1560a77365c14fcdf6cbbf5383020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a04848c847e1db33fa57a37324f5ea2bc8c0d73c1b5e8bb55277ed9abd8c1935cba05f7b4fbf6d345db1d94535937a709d81e9965d747b2c70195c6c5c32881dc0ab" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xb15d5954c7b78ab09ede922684487c7a60368e82fdc7b5a0916842e58a44422b" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x9b72096b8b672ac6ff5362c56f5d06446d1693c5d2daa94a30755aa636320e78", + [] ] }, { "jsonrpc": "2.0", "id": "np166", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6dcec039f7777c1fd96bbdd342e0ed787211132f753cf73a59847dc6cb30a6ff", + "parentHash": "0xe89e5d3756805d8458b5057f19b7d97faa7fa2351b2a08ddd75405c00af3a8c6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x03629dac3f669a8262e8246d46bac9acfb7cbca336d02e90c081561fa0b22aba", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x82f560474af8d995c875164f8e5ccc4a4c3c775f28cfc1dc00fd4edaea33eb62", + "receiptsRoot": "0xa876268e414ed930180e4e8f99b97830f96c76546b212484b43f4a722a275053", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000080000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000001000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x67c", "extraData": "0x", - "baseFeePerGas": "0x14b", - "blockHash": "0x760da169c77450231e6a0d2dd4aad67de84633eb6918fc8607a3a709eea07bef", - "transactions": [], - "withdrawals": [ - { - "index": "0x11", - "validatorIndex": "0x5", - "address": "0xfe1dcd3abfcd6b1655a026e60a05d03a7f71e4b6", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0x8052bf3205c8803a64bb4cc52c4e86516db9734d9bf0ff47349a337e9bbe10e0", + "transactions": [ + "0xf874819908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c2989ce0858ff5f25656d69748718e5bb3abd109fa06ed33391e8205c7a247b82ab2cb6c28ff92e6fab9130115cc6d5538918433677a05fb41e0f3d9636d598ae9e4d4627cf27d782e5b412cdf7718020426523191e05" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xad13055a49d2b6a4ffc8b781998ff79086adad2fd6470a0563a43b740128c5f2" + "0xf68bff777db51db5f29afc4afe38bd1bf5cdec29caa0dc52535b529e6d99b742", + [] ] }, { "jsonrpc": "2.0", "id": "np167", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x760da169c77450231e6a0d2dd4aad67de84633eb6918fc8607a3a709eea07bef", + "parentHash": "0x8052bf3205c8803a64bb4cc52c4e86516db9734d9bf0ff47349a337e9bbe10e0", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4f5e79d4af5565b3b53649b1ddc3a03209cb583e7beb03db8b32924c641e6912", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x85d3721cd9e6fbf5dd19125a46b3bfdd52c5400508ca9dd504118719ca09f4a4", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa7", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x686", "extraData": "0x", - "baseFeePerGas": "0x122", - "blockHash": "0xfcb210229cb48baf3d535e48a7577041268eadd6027942084a56dbec8f8423a9", + "baseFeePerGas": "0x7", + "blockHash": "0xdcf632311be8dfd6de736c05b4ae66e2aea72f7825fb23294bb8ccfeb218f486", "transactions": [ - "0xf8848186820123830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0b2aafb3e2678dd48e6f31874bd478778480815c9d110ec8cc77a42f7d52999daa00705b1266fc1087167cc531caa9d2e0a0c8779e4ad5020d9d3a16500bf5b96a1" + "0x02f86a870c72dd9d5e883e819a01088252089414e46043e63d0e3cdcf2530519f4cfaf35058cb20180c001a03f7964062354cfc08584c3f5788a33d09e1d64681ce283f5582f11f55ceff565a07eeefc310b165a51dc3a0fd06f07f835e9c2ade6781709504a0b2523cca73546" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9e9909e4ed44f5539427ee3bc70ee8b630ccdaea4d0f1ed5337a067e8337119f" + "0x9566690bde717eec59f828a2dba90988fa268a98ed224f8bc02b77bce10443c4", + [] ] }, { "jsonrpc": "2.0", "id": "np168", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfcb210229cb48baf3d535e48a7577041268eadd6027942084a56dbec8f8423a9", + "parentHash": "0xdcf632311be8dfd6de736c05b4ae66e2aea72f7825fb23294bb8ccfeb218f486", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8c6c100b7c75ced82b38315fd50c5439478a7ee256073ce17b845e0815912eab", - "receiptsRoot": "0xf8f8c85b17ada66c06f8e41b58b45213619bb309a197896adbaff4e9139967b1", - "logsBloom": "0x80000000000000000000000000000000800000000004008000200000000000000002820000000000000000000000000000000000000040020400000000000000000000000200000000000000000000000000000040000400000000000000000000000000000000000000000000000000000000000000100000000000000000000000000040080000000000000000000000000000000000200000000000000080000200000000000000000000000000000000000000000000000000000100000003000200000000000000000000000000000000000000200000000000000000000000004000000004000000040001010000000080400000000000000040000000", + "stateRoot": "0xbcbeeb50071dd1d8c9390988cfc6aedd2a137cded25825e554269057bf0a2339", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa8", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x690", "extraData": "0x", - "baseFeePerGas": "0xfe", - "blockHash": "0x796a4e02d1da9c86b1a2e7b2ef1d82e1ebdac143ec7ff4a67dae2b241b22c3c1", + "baseFeePerGas": "0x7", + "blockHash": "0xf4d88732713252e8ab1932ca55135b3819ef47a73a05002a338e5aa5617e7d9d", "transactions": [ - "0xf87a818781ff83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0b1e7ca73ef581fc880deb34aa6cf7958f6ce110efd121d48fb2292a747864815a02bf94b17dc034d8934b885faa269a9430a755ebfb4c6e87378376a094704f464" + "0x01f869870c72dd9d5e883e819b08825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df0180c080a0f9075df943f26e91ecd0f87e2d5cba53345aaaeea86a9ae71f571f3f9446e8c5a0648499cecaa5f66e84d6fdef0ad70eb732edfbe27e7d8f0aa0ad36dcf1a1f013" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xbf1f3aba184e08d4c650f05fe3d948bdda6c2d6982f277f2cd6b1a60cd4f3dac" + "0xd0e821fbd57a4d382edd638b5c1e6deefb81352d41aa97da52db13f330e03097", + [] ] }, { "jsonrpc": "2.0", "id": "np169", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x796a4e02d1da9c86b1a2e7b2ef1d82e1ebdac143ec7ff4a67dae2b241b22c3c1", + "parentHash": "0xf4d88732713252e8ab1932ca55135b3819ef47a73a05002a338e5aa5617e7d9d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9f527744fd44cf4c2ba60fe62d25d4f19e64c034cbf24785e0128d5fafa19e2a", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xcd074008f02ff8e77540321cd30af0917f5519990a3fa89750911df721222d97", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xa9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x69a", "extraData": "0x", - "baseFeePerGas": "0xdf", - "blockHash": "0x29a0d081e8aec6b2dcb307d73ca48d7d50e434617daf0e81fd28b35be9c7995d", + "baseFeePerGas": "0x7", + "blockHash": "0x5f5f3976768eaf850e525d41f05497af4731aa637d2b323dbc69154553943c50", "transactions": [ - "0xf865818881e08302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0c583bd1010c1e4158466575fb0c09ff710a5ff07c8f7a6e7960d90bffef8bd34a059ea0ba5c6fc64aad73252c780de287599d3100d80f7b1d3201b4865d82c0cad" + "0xf867819c08825208941f5bde34b4afc686f136c7a3cb6ec376f735775901808718e5bb3abd10a0a0ca6eeaf7f7ddbb82c0374b0eee910d70ca9469397d5bb0b597666c38fca8f7b6a01b4a657dc2c418102526186ddc7c9cbcef74881083391ed51d9dad587db1d4a4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xbb70fe131f94783dba356c8d4d9d319247ef61c768134303f0db85ee3ef0496f" + "0x43f9aa6fa63739abec56c4604874523ac6dabfcc08bb283195072aeb29d38dfe", + [] ] }, { "jsonrpc": "2.0", "id": "np170", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x29a0d081e8aec6b2dcb307d73ca48d7d50e434617daf0e81fd28b35be9c7995d", + "parentHash": "0x5f5f3976768eaf850e525d41f05497af4731aa637d2b323dbc69154553943c50", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x45c5f07a7d94c320222f43c12b04081fdbe870be18a2b76f7122bd7f4554118b", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x2e6fa7f5528da8a715dd74c4b756d34e23732ecd2627b9d4663c2d2592d22fe8", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xaa", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x6a4", "extraData": "0x", - "baseFeePerGas": "0xc4", - "blockHash": "0xe878e98d05f60a8fd741a4aaab17a91c538f21552ac41922fe2b755e4f0e534c", - "transactions": [ - "0xf868818981c582520894bceef655b5a034911f1c3718ce056531b45ef03b01808718e5bb3abd109fa0626dfd18ca500eedb8b439667d9b8d965da2f2d8ffcd36a5c5b60b9a05a52d9fa07271175e4b74032edeb9b678ffb5e460edb2986652e45ff9123aece5f6c66838" + "baseFeePerGas": "0x7", + "blockHash": "0xc1a9ccd5f651aa46a26433e521d6e7c4fcc6714f8fb9068ee4f1e0a8d043da0d", + "transactions": [], + "withdrawals": [ + { + "index": "0xe", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6a81ebd3bde6cc54a2521aa72de29ef191e3b56d94953439a72cafdaa2996da0" + "0x54ebfa924e887a63d643a8277c3394317de0e02e63651b58b6eb0e90df8a20cd", + [] ] }, { "jsonrpc": "2.0", "id": "np171", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe878e98d05f60a8fd741a4aaab17a91c538f21552ac41922fe2b755e4f0e534c", + "parentHash": "0xc1a9ccd5f651aa46a26433e521d6e7c4fcc6714f8fb9068ee4f1e0a8d043da0d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf4a19b9765604687783462dbf36a0063ada2ba7babb4dd1c4857b2449565a41d", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xc8dec30c9a01e3cb25857fea4c9fec2588e9a88c04964ec88446def8b92c1dd1", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xab", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x6ae", "extraData": "0x", - "baseFeePerGas": "0xac", - "blockHash": "0xc3f33c71274b456303efd80efacba7d5fccb0ed278ee24e5594a38c45a294315", - "transactions": [], - "withdrawals": [ - { - "index": "0x12", - "validatorIndex": "0x5", - "address": "0x087d80f7f182dd44f184aa86ca34488853ebcc04", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0x9fb16206a35f8b4b9d8c30570c7010b5bc6a4149b5aa2ce42da9d60c92b5ea1d", + "transactions": [ + "0xf882819d088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0e745f6682c5edbc361349ac85db663d445e657534cab54042b4e7a929c71b3dfa01da4ada16183397c613a392e286749ce543cb828887825535209225ba2cbce1b" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4c83e809a52ac52a587d94590c35c71b72742bd15915fca466a9aaec4f2dbfed" + "0x9e414c994ee35162d3b718c47f8435edc2c93394a378cb41037b671366791fc8", + [] ] }, { "jsonrpc": "2.0", "id": "np172", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc3f33c71274b456303efd80efacba7d5fccb0ed278ee24e5594a38c45a294315", + "parentHash": "0x9fb16206a35f8b4b9d8c30570c7010b5bc6a4149b5aa2ce42da9d60c92b5ea1d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4f9e280291036fb6cd64598fe0517d64d6da264d07d7fc3b8d664221d7af9021", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x4367db6c6b954c306e2e3d3a3cb846b43cf3a484741c8fd6d0a49099dcb68c32", + "receiptsRoot": "0x1dfa260a60333675b1de018c45c25c44470a3f3159a99821318421f2c1f4e58a", + "logsBloom": "0x00000400000000000002000000000000000000010000000000000000400020002000400000000000000000200000000000204000000000000000000000400000000000000000000000000008400000000000000000000008080000000000002040000000000000000008000040000000000000000000000000000000000000000000001000000000000044000000000000000000000000000000008000000080000000000000000002008000001000000000000000000000000000000000000000000000000000000000840000000000000000004000000000000000000000000000000000000000000040000041000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xac", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x6b8", "extraData": "0x", - "baseFeePerGas": "0x97", - "blockHash": "0xd785018f59628b9f13cc2d4a45e0b4b3af183acce4e5752346e79dbcdf7de4e5", + "baseFeePerGas": "0x7", + "blockHash": "0x4d980e42bd8ab35744bf9b5aa58fbc8b71efd85b839b90e2e50584246a3831f8", "transactions": [ - "0xf883818a8198830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a05f47b0ab77130dcc8f7143a2afaace6a2d1f82e25839cb9adee5aaebfe7dc681a05af90b75de35c90709b83861d8fdfd7805a89b1e76a4bdd5987e578ba72fc37e" + "0xf879819e0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a05431136f2ece8ba6297f27c127413c8f219ba3be455c05b1a07e064b1de4e36ca01ca3eb0aa10c2cf4de708b21daf94ea3cc4a14e47b42f50ccef6f288b300dfe2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x268fc70790f00ad0759497585267fbdc92afba63ba01e211faae932f0639854a" + "0x4356f072bb235238abefb3330465814821097327842b6e0dc4a0ef95680c4d34", + [] ] }, { "jsonrpc": "2.0", "id": "np173", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd785018f59628b9f13cc2d4a45e0b4b3af183acce4e5752346e79dbcdf7de4e5", + "parentHash": "0x4d980e42bd8ab35744bf9b5aa58fbc8b71efd85b839b90e2e50584246a3831f8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe01cadedc509806ea9cd7475312a3768de034d1c849abadc46237b8cd4163179", - "receiptsRoot": "0x15dc68f6de1b068b96d32dbc11a048b915e7d62bd3662689ae5c095bb6ddab37", - "logsBloom": "0x00000100000000004000000004000000000000000000000000000000000000000000000004000000018004000000000000000000000000000002000000000000000020002000400000002000020000000100000000000000000080010000400000000000000200000000040000000000000000000000010000002000000000000000000000000004040000000000000000000000000000000000000000004000000000000000000000080000004000000000000000000000001000000000000100000800040000000000000000000000000000000000000000000000000000000000000000400000000000004001000000000000000000000000000000000000", + "stateRoot": "0x001a7058a39d22062714eccf3366ff07d3406f5d5c1cc173a5c9fc2d0b2cfef8", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xad", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x6c2", "extraData": "0x", - "baseFeePerGas": "0x85", - "blockHash": "0xbcff8f4e8c3d70d310900cd8246c3456e237ab8ea9fc036601995404b141e3bb", + "baseFeePerGas": "0x7", + "blockHash": "0xc9f402d074ac593ae2f09a8bb846b9e46963c305a8c33690c08ca0c8e0ac719f", "transactions": [ - "0xf87a818b818683011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa04a74ea0833e42d624ba0d9b589a16e05feae1c2dee89abfb29df95b650d3e756a037135f3e24572eb9d927a02c0c4eee7fd5d8a181e2384ef3b3b04c49c9dbbbe1" + "0xf864819f088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0705afe706be82a4c7f9a5964e09c9e265b285e4382028136ec8af1e7fb0c7aa2a03f927fc55ed798c4cfb0ef7beb90c044b5325a7b61c45a16504dcc5ddf712d3f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7e544f42df99d5666085b70bc57b3ca175be50b7a9643f26f464124df632d562" + "0x215df775ab368f17ed3f42058861768a3fba25e8d832a00b88559ca5078b8fbc", + [] ] }, { "jsonrpc": "2.0", "id": "np174", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xbcff8f4e8c3d70d310900cd8246c3456e237ab8ea9fc036601995404b141e3bb", + "parentHash": "0xc9f402d074ac593ae2f09a8bb846b9e46963c305a8c33690c08ca0c8e0ac719f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa862687747ffc388414ee5953589a70f2161a130886348157257a52347be9157", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x564d65ae8bc86bf22cb161dc6c91a654b73d6d2c221f7048b77fc31b6aa08ed5", + "receiptsRoot": "0xb8137d0711f48435401dd4cab75c13b44ad3e5241d683b34e44073ebaf1c1193", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000400000200000000000000000000000000002000000000000000000000000000000800000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xae", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x6cc", "extraData": "0x", - "baseFeePerGas": "0x75", - "blockHash": "0x943b23302ffed329664d45fee15ca334c92aa6195b22cb44c7fdd5bdbbe4e7d4", + "baseFeePerGas": "0x7", + "blockHash": "0x7c6e0e3b4dfc0728d41f7d5729a60d53758cafbab878bca3beed01bdc5ae9c56", "transactions": [ - "0xf864818c768302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a024414367540c94b1bd3ce29dd0b4ee6bdece373f9417e96f0ef8d632e82c4ecba031dae9539e84f7351a5b92f1246dfd909dd5a383011fbd44bb8e87fb6870189b" + "0x02f8d3870c72dd9d5e883e81a00108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c4a593ce54c67c2ac656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a087fc0239418406958902bcd8e059f9ddc08fb2683a4be0cfd47b1eb97418be1e01a00ed05cf53044f80bc23a49fd3dc69816901a3ff92e1f24bc7fd1fc5cfb87396ca057644e118120719799ba3ebd9b1aa684eb57c6dc92119684adbf26dbd4fdadbc" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd59cf5f55903ba577be835706b27d78a50cacb25271f35a5f57fcb88a3b576f3" + "0xd17835a18d61605a04d2e50c4f023966a47036e5c59356a0463db90a76f06e3e", + [] ] }, { "jsonrpc": "2.0", "id": "np175", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x943b23302ffed329664d45fee15ca334c92aa6195b22cb44c7fdd5bdbbe4e7d4", + "parentHash": "0x7c6e0e3b4dfc0728d41f7d5729a60d53758cafbab878bca3beed01bdc5ae9c56", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd70339e1158ecc97dc7db86b3177202ffa3dcba386fd52e54e6fe8b728003154", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x232b2e0f21a64714fbe5752dae331bf86b0d26ffc92322b62504607a474b224c", + "receiptsRoot": "0xf5d1435054aadeb055c81d3f19a4e56814ce25c8f3a64a413d39681990c927a2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000004800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xaf", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x6d6", "extraData": "0x", - "baseFeePerGas": "0x67", - "blockHash": "0xd2a0fc154d0bb77b346c7bb3532d24581bc1a5b5bf9ced18b419a6309ff84351", + "baseFeePerGas": "0x7", + "blockHash": "0x36daac85c3d71809d96b04586cf5c50594ae2cafa74b9734491f6fb31b85142c", "transactions": [ - "0x02f86a870c72dd9d5e883e818d0168825208945a6e7a4754af8e7f47fc9493040d853e7b01e39d0180c001a08c62285d8318f84e669d3a135f99bbfe054422c48e44c5b9ce95891f87a37122a028e75a73707ee665c58ff54791b62bd43a79de1522918f4f13f00ed4bd82b71b" + "0x01f8d2870c72dd9d5e883e81a108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c963a3b3b836863cc656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a073b2b230124967b31546c7e2fedbc5ab108a537ef6d645621fe74fcdc0644b2801a0ef1453210d03f1651ebad4cfcf238686c7c450a8a2488d0f442db7ea291923caa0798c152e68943ea3a4326bb6c39a8e9956c7d87e5391ecbe6de1f839ae11afad" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x551cced461be11efdeaf8e47f3a91bb66d532af7294c4461c8009c5833bdbf57" + "0x875032d74e62dbfd73d4617754d36cd88088d1e5a7c5354bf3e0906c749e6637", + [] ] }, { "jsonrpc": "2.0", "id": "np176", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd2a0fc154d0bb77b346c7bb3532d24581bc1a5b5bf9ced18b419a6309ff84351", + "parentHash": "0x36daac85c3d71809d96b04586cf5c50594ae2cafa74b9734491f6fb31b85142c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1bc27508b52de3a750cc928dd89954462b4e4dbfb60707442e60b4b23aabb816", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xe868a681d8537e3e322ab2e64f5b6735416f171863eb9343ae96f8f8d51356ef", + "receiptsRoot": "0x04403e16895c094448badf3e31688d759f0993ccf9d9b2cc1fc84d82800f2cec", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000040002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000010000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x6e0", "extraData": "0x", - "baseFeePerGas": "0x5b", - "blockHash": "0xe3072603b13de812d2c58ece96eeb4f32ff7e3e93c8b9121dd18f0682a750970", - "transactions": [], - "withdrawals": [ - { - "index": "0x13", - "validatorIndex": "0x5", - "address": "0xf4f97c88c409dcf3789b5b518da3f7d266c48806", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0xedd306e502f0e098d70102017c0f33272d5934bbf766ef1c5ece71713d4f59c2", + "transactions": [ + "0x03f8f9870c72dd9d5e883e81a20108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c2502e1f0dd547127656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0bdfd2b337ff30e9e15c09313bf796d3c75177943e0aa0445f479fbd2dd5c1d6e83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0e41316ae994091bbaf7e2e97d273ce1a16381c60af07c363bee1aea6c89c83f3a04c1879555adec4de34049425b52f6d4e547ac57a1deda752cf0aea86d599b638" ], - "blobGasUsed": "0x0", + "withdrawals": [], + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xc1e0e6907a57eefd12f1f95d28967146c836d72d281e7609de23d0a02351e978" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x6f22ae25f70f4b03a2a2b17f370ace1f2b15d17fc7c2457824348a8f2a1eff9f", + [] ] }, { "jsonrpc": "2.0", "id": "np177", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe3072603b13de812d2c58ece96eeb4f32ff7e3e93c8b9121dd18f0682a750970", + "parentHash": "0xedd306e502f0e098d70102017c0f33272d5934bbf766ef1c5ece71713d4f59c2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x78497ebf1fbf03732772a8c96b2fe6902af5ab844e49f2685763b4366ce8ddf6", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd58cceebab8ff9038ced6500866b8edffabd41017ff99914350deed71f660bc8", + "receiptsRoot": "0x2af5beed5b567fac7c47bd8e37184bbc6f8ad91cffc3e43116f17c16ea798b81", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000002000000000000000000000000000000000000040000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x6ea", "extraData": "0x", - "baseFeePerGas": "0x50", - "blockHash": "0x996acbdde853cdc1e21426f4e53d07c09a13ed50798ee071582f24cc1014e238", + "baseFeePerGas": "0x7", + "blockHash": "0x1fdd1686c4e06bf2baf2287347ed95a45855aa4b546244e83e7aea4c6dd56a72", "transactions": [ - "0xf882818e51830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0fd5ea8b7df5c3ecd87220b8ad7d15198722d94a64b0e8e099c8c7384c1d08a33a039707925aba6dad8d06c162fd292df0bf03033b7b6d1204ae4be0ce6f487fa71" + "0xf87481a308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c72faa693d5bb5456656d69748718e5bb3abd10a0a0f23547199e74f2ba75c5dff20d614778a8826e0da6574b86b8e6cec15bdd7786a02461f37d47a7d68db841e7b2d3ec9e999a04fb55ecfda0b3213c451a3418199f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9d580c0ac3a7f00fdc3b135b758ae7c80ab135e907793fcf9621a3a3023ca205" + "0xf11fdf2cb985ce7472dc7c6b422c3a8bf2dfbbc6b86b15a1fa62cf9ebae8f6cf", + [] ] }, { "jsonrpc": "2.0", "id": "np178", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x996acbdde853cdc1e21426f4e53d07c09a13ed50798ee071582f24cc1014e238", + "parentHash": "0x1fdd1686c4e06bf2baf2287347ed95a45855aa4b546244e83e7aea4c6dd56a72", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x197c4166e7f8f68ee6965c87c8ce720bee776a7b7119870371e6262bc913468d", - "receiptsRoot": "0x7c66f99e4434aa19cdf8845c495068fa5be336b71978d6fa90966129f300218a", - "logsBloom": "0x00000000000000000000000000400200000000000000800000000000000000008000008000000000000000000000000000000000000000000040000004000041004000000000000000000000000800000000000000000000000000000000080100000000000000000000000020000000004200000000001000000002000000100008080200000004000000000000200000000000000010000000000000000000000000000000000000000000000000000000000000000020000000000000000000800000000000000000000800000000200000000000000000000100002000000000000000000002000000000000000000100000000000000000000000000000", + "stateRoot": "0x7159f8b467ffa4666bb640be0fbac17072bba7a084d2591c7123ad506e71d455", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb2", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x6f4", "extraData": "0x", - "baseFeePerGas": "0x47", - "blockHash": "0xf00d6a4f13579131abcd2c856040cf9295caed200698d7cf7a1574690b36b0bf", + "baseFeePerGas": "0x7", + "blockHash": "0xa69441f08a1bef357d6f34fb74e4eeeaff0feb787f61e10879faf72609aeae24", "transactions": [ - "0xf879818f4883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a03e0f9aa0ca6ec8b4f9e7fccd9b710c0de4414618726e298b36816cd6d689a89aa07d3950b5ebbaa58f5c4e0bc0571499d9d58d563ce2c039664cf210815e43d0e5" + "0x02f86a870c72dd9d5e883e81a40108825208941f5bde34b4afc686f136c7a3cb6ec376f73577590180c001a021303b463c6aafaeebeba14b0276f77308dfb02aee5d8cf8d18c7a6b0f8f5f20a017d70f0dfcc668f51b412ecdb441eabaa92c3a05f649e027922a37a858e6be1e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa7fd4dbac4bb62307ac7ad285ffa6a11ec679d950de2bd41839b8a846e239886" + "0xbbc97696e588f80fbe0316ad430fd4146a29c19b926248febe757cd9408deddc", + [] ] }, { "jsonrpc": "2.0", "id": "np179", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf00d6a4f13579131abcd2c856040cf9295caed200698d7cf7a1574690b36b0bf", + "parentHash": "0xa69441f08a1bef357d6f34fb74e4eeeaff0feb787f61e10879faf72609aeae24", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf56610f73e08c2ccaaa314c23bc79022214919c02d450cab12975da3546b68fd", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xad7daddd8ac491c23cb54f9805b98cfa1ec0455bf333a1c5cbb0f69f7dd69cfe", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb3", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x6fe", "extraData": "0x", - "baseFeePerGas": "0x3f", - "blockHash": "0x5711092388b2fd00bf4234aca7eede2bdc9329ea12e2777893d9001f4f2c8468", + "baseFeePerGas": "0x7", + "blockHash": "0xc37e2ca4253945c00e611fd26819875ef83d98dc20bb326a8e4ebbd804613214", "transactions": [ - "0xf8648190408302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0f41a67e92f032c43cc601daa205026cc5a97affb0f92064991122a1aa92428dfa0237053c462847907c840ada5076caab16adc071da181e9277926a310adcb8e3d" + "0x01f869870c72dd9d5e883e81a508825208941f5bde34b4afc686f136c7a3cb6ec376f73577590180c001a027058d63f06541a9d1096de84b552d3ed9d9c3a1f9fffb5ec09eb534572d4d63a0725d37562a61ee9f0c8f67350f939ff0149289340fb21b0fd6eee4cdfb3675d4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6ba7b0ac30a04e11a3116b43700d91359e6b06a49058e543198d4b21e75fb165" + "0x71dd15be02efd9f3d5d94d0ed9b5e60a205f439bb46abe6226879e857668881e", + [] ] }, { "jsonrpc": "2.0", "id": "np180", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5711092388b2fd00bf4234aca7eede2bdc9329ea12e2777893d9001f4f2c8468", + "parentHash": "0xc37e2ca4253945c00e611fd26819875ef83d98dc20bb326a8e4ebbd804613214", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xfa57370da0cc72170d7838b8f8198b0ebd949e629ca3a09795b9c344dead4af5", + "stateRoot": "0x055e26ef6ae3fa56e6e9d7a0c149e4d5a4cba9e6cc3dcf761f4b57fb545dc1f8", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb4", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x708", "extraData": "0x", - "baseFeePerGas": "0x38", - "blockHash": "0xb58807a37c03cf3b0f1c9104cfd96f6cb02b1e08e0eecdd369cac48d0003b517", + "baseFeePerGas": "0x7", + "blockHash": "0x8564835e8d24f3fd01643847625fac3fa7bb13ba829c1a5ad7efd6ceda4f5bed", "transactions": [ - "0xf8678191398252089427952171c7fcdf0ddc765ab4f4e1c537cb29e5e501808718e5bb3abd109fa076a045602a7de6b1414bdc881a321db0ce5255e878a65513bad6ac3b7f473aa7a01a33017b5bcf6e059de612293db8e62b4c4a3414a7ba057c08dd6172fb78a86c" + "0xf86781a608825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df01808718e5bb3abd109fa06bb8cef12c0ac6f6490be490baea684d8ee3fb5a4adda03e890f9fc1f81bf48ca06bbe16d08e1776119189560e89057ba6d8af45c383c2ec23c1b74fdaa7395102" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x8835104ed35ffd4db64660b9049e1c0328e502fd4f3744749e69183677b8474b" + "0xb90e98bd91f1f7cc5c4456bb7a8868a2bb2cd3dda4b5dd6463b88728526dceea", + [] ] }, { "jsonrpc": "2.0", "id": "np181", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb58807a37c03cf3b0f1c9104cfd96f6cb02b1e08e0eecdd369cac48d0003b517", + "parentHash": "0x8564835e8d24f3fd01643847625fac3fa7bb13ba829c1a5ad7efd6ceda4f5bed", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6d3f029e56f9ee3db9ed8f9156cd853fb1fcafe05475ec8c2a4dd337a5e3e20e", + "stateRoot": "0xd203aca206010f7376fa398f9973cd163e7edb2e666af495953f132f0abd8a35", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb5", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", "timestamp": "0x712", "extraData": "0x", - "baseFeePerGas": "0x32", - "blockHash": "0x56b5aa12ccfcbd86737fe279608cb7585fbc1e48ddfcdac859bb959f4d3aa92a", + "baseFeePerGas": "0x7", + "blockHash": "0xc64398436144bb3196587e5ee9267e878400c5616f97cf97fd0921bae181bad4", "transactions": [], "withdrawals": [ { - "index": "0x14", + "index": "0xf", "validatorIndex": "0x5", - "address": "0x892f60b39450a0e770f00a836761c8e964fd7467", + "address": "0x2d389075be5be9f2246ad654ce152cf05990b209", "amount": "0x64" } ], @@ -3377,1704 +5727,1739 @@ "excessBlobGas": "0x0" }, [], - "0x562f276b9f9ed46303e700c8863ad75fadff5fc8df27a90744ea04ad1fe8e801" + "0x4e80fd3123fda9b404a737c9210ccb0bacc95ef93ac40e06ce9f7511012426c4", + [] ] }, { "jsonrpc": "2.0", "id": "np182", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x56b5aa12ccfcbd86737fe279608cb7585fbc1e48ddfcdac859bb959f4d3aa92a", + "parentHash": "0xc64398436144bb3196587e5ee9267e878400c5616f97cf97fd0921bae181bad4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x58a6332c9e7b85155106515f20355c54bb03c6682024baa694cbaff31c3b84ff", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xbe2a810abab83cd951177184055b77b27c030508188678587cbe8132de994797", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x71c", "extraData": "0x", - "baseFeePerGas": "0x2c", - "blockHash": "0xb0d7fbd46bd67d4c3fa51d0e1b1defaf69237d0f6e2049486c907b049b47e01c", + "baseFeePerGas": "0x7", + "blockHash": "0x12d4a656b5b4d8d9c55515a7698a254fa74a397390a57167f785a2d3602539a6", "transactions": [ - "0xf88281922d830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa01ae40537174a716b5f33d153e9251ae8c1d72852da25823f6d954b9dbc5740cca02ff07812990e0645cab5c9d89028f7255f50d0eee5bee334b3ba10d71485c421" + "0xf88281a7088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa0c5bb4c7666740a63b896f57906ea516686a3f0e3501001e8d1aa27ea158717f1a064ae416a38b4a7a973b0d0ed713577647767e09f12968f8b7dd7bcf2f1f014e3" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd19f68026d22ae0f60215cfe4a160986c60378f554c763651d872ed82ad69ebb" + "0xafb50d96b2543048dc93045b62357cc18b64d0e103756ce3ad0e04689dd88282", + [] ] }, { "jsonrpc": "2.0", "id": "np183", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb0d7fbd46bd67d4c3fa51d0e1b1defaf69237d0f6e2049486c907b049b47e01c", + "parentHash": "0x12d4a656b5b4d8d9c55515a7698a254fa74a397390a57167f785a2d3602539a6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x55d4e87d040358926c84414b854fc47a75b9963df75e359a2182464c51201088", - "receiptsRoot": "0x1fccfe93768ce1ed60d0f83cbc8bef650cb1d056c35a4b233ae41a1b8219f92d", - "logsBloom": "0x00000080000000000000000000000000000000000000004000000000000010000000000000000000000000000000014000800000000000000100102000000000000000000000020000000000200000000000000000100000000000200000002000000000000000000000002000000000000000000000000000000000000000001000002000400020040000000000000200000000000000000000000000000000000000002000000000000000000000100000000000022000000000000000000000000000000004000000080000000000000000000000000004004000000000040002000040000000000000000000000000000000000000000000000000100000", + "stateRoot": "0x6329ac409b68501594692643f9c388498a7de1c41ad6789fd1af4b37aceff22a", + "receiptsRoot": "0x98b6f0626985aa0ccf4936d47825312e988b42eaadf98e729290b3bc943f88fe", + "logsBloom": "0x00000080000000000000000000000000000000000000004000000000000010000000000000000000000000000000014000800000000000000000102000000000080000000000020000000000200000000000000000100000000000200000002000000000000000000000002000000000000000000000000000000000000000000000002000000020040000000000000200000000000000000000000000000000000000002000000000000000000040100000000000022000000000000000000000000000000004000000080000000000080000000000000004004000000000040002000040000000000000000000000000000000000000000000000000100000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb7", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", "timestamp": "0x726", "extraData": "0x", - "baseFeePerGas": "0x27", - "blockHash": "0x66011454670d5664e8e555d01d612c70cadabfb6a4a317f375495ef3daa9d1b4", + "baseFeePerGas": "0x7", + "blockHash": "0xc858dea4bf702c29161d33ba7c02bfb4977169668843521b0df693d5eebcf5a3", "transactions": [ - "0xf87981932883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa02d1dcc844efba97a51917ab3d79f837680f42e2e76ab51b4b630cbe9a6e4e10ea03d3f624c82de14b23b0c5553621cc9a4c649cd856a616f5a91bad8bf0c0d1709" + "0xf87981a80883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa04a9bf10e11abbcc9a33e6d7d71b5593164b7c112aaac0ae2ae7eeed4c7442c04a065d51bda999af8cfece3c43c6f48d89fac8a82a2d2f576204a9d32991cf16b13" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf087a515b4b62d707991988eb912d082b85ecdd52effc9e8a1ddf15a74388860" + "0xd73341a1c9edd04a890f949ede6cc1e942ad62b63b6a60177f0f692f141a7e95", + [] ] }, { "jsonrpc": "2.0", "id": "np184", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x66011454670d5664e8e555d01d612c70cadabfb6a4a317f375495ef3daa9d1b4", + "parentHash": "0xc858dea4bf702c29161d33ba7c02bfb4977169668843521b0df693d5eebcf5a3", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd3ec16ab633987e17a4e8c573014b1fc9919f004b3cb80da11280d1caad1fe3e", + "stateRoot": "0x4e962e27aad16223647ac79606e777971b1debc744616ab3a2d40872adf77287", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb8", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", "timestamp": "0x730", "extraData": "0x", - "baseFeePerGas": "0x23", - "blockHash": "0x36e1e3513460407c80dfcfab2d2826ea432dadb99aa7415f9cffcf56faf27f94", + "baseFeePerGas": "0x7", + "blockHash": "0x347ad864a477308c79cb4f766e8a6b62f4ece0a981cdfe49987e542acd89b5ac", "transactions": [ - "0xf8648194248302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a01e5301a3386e11893c0275367ac5d31fea88f31731e66ee769bfddc3486cff1aa0203dbf8bbfa9df2d635e1889d51e06611e8c2a769609908aeb5e97decb03b141" + "0xf86481a9088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a046152e7f3fede1276e473bb9aafaa72e9cfa60447b0f30bc961ddf840fa45b1da068a9cbc1ffee81b72b52d9c1bb698240d7bf0f1a5673d108c3de46614306afaf" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf7e28b7daff5fad40ec1ef6a2b7e9066558126f62309a2ab0d0d775d892a06d6" + "0xc26601e9613493118999d9268b401707e42496944ccdbfa91d5d7b791a6d18f1", + [] ] }, { "jsonrpc": "2.0", "id": "np185", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x36e1e3513460407c80dfcfab2d2826ea432dadb99aa7415f9cffcf56faf27f94", + "parentHash": "0x347ad864a477308c79cb4f766e8a6b62f4ece0a981cdfe49987e542acd89b5ac", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x692ddd6938f00a07474233619f579b30c1eaaef353a2b0cc24b47d7898aa5c49", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x2790bbb5ba41428ab0b184406e5725bf4d5fbbb603d8a15325eb1b847b4346d9", + "receiptsRoot": "0xeebb7dba7001e7060c6d18cc19e463b790ceab439dd73fc5c2d6907700acb6e9", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000002000000000000000002000000000000001000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xb9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x73a", "extraData": "0x", - "baseFeePerGas": "0x1f", - "blockHash": "0x44e05b6820cf1d7cf9cd2148d6f71a6a649c9a829b861539d2c950f701e27260", + "baseFeePerGas": "0x7", + "blockHash": "0xac0c873a3d9942f92427ae37009ee280b326788fa803baba4dbbcc31736ff2ff", "transactions": [ - "0x02f86a870c72dd9d5e883e819501208252089404d6c0c946716aac894fc1653383543a91faab600180c080a0039c18634a9f085ba0cd63685a54ef8f5c5b648856382896c7b0812ee603cd8aa05ecfde61ea3757f59f0d8f0c77df00c0e68392eea1d8b76e726cb94fb5052b8a" + "0x02f8d3870c72dd9d5e883e81aa0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cee5a944cf4c7c482656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a085c0042b81b23b846d1e4881b0131b4bbff774dd9bdece2e74fa92ebdb053c3480a0ab91a3e2fdf14c51273af6668fc2fa61f476555b41d52a466d663dcd5d6c776ea07ab7fe8ae84e3e65f3dbe646961c27216943f9d9eb9b2d3c48571cb1fee9f027" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x77361844a8f4dd2451e6218d336378b837ba3fab921709708655e3f1ea91a435" + "0xfb4619fb12e1b9c4b508797833eef7df65fcf255488660d502def2a7ddceef6d", + [] ] }, { "jsonrpc": "2.0", "id": "np186", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x44e05b6820cf1d7cf9cd2148d6f71a6a649c9a829b861539d2c950f701e27260", + "parentHash": "0xac0c873a3d9942f92427ae37009ee280b326788fa803baba4dbbcc31736ff2ff", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9eac86abf4371646a564bb6df622644682e5de5bf01fed388ccaf10700e46e88", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x75397ed7dffd9a11c4edcbeeb1e639eb77305bd178dc500dcab6ec8b3faf0408", + "receiptsRoot": "0x22cd406e847641904efd5d8ac1f487eb2623b4fc895fd69ee449f25ad57d6f4f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000010000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xba", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x744", "extraData": "0x", - "baseFeePerGas": "0x1c", - "blockHash": "0xcc3b1096f3ce63881c77751baec2048561baa2dc84ea0ef9d3a5515061aa74e0", - "transactions": [], - "withdrawals": [ - { - "index": "0x15", - "validatorIndex": "0x5", - "address": "0x281c93990bac2c69cf372c9a3b66c406c86cca82", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0x5f67af973e604193cdcd68a80dea8ff0622ee1341330c1b8601502020617c2cd", + "transactions": [ + "0x01f8d2870c72dd9d5e883e81ab08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c6508b81f8764eb37656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a046765aab85a7ee88496ecde24f93cd5ce361b5a9fb43a2641d77bfbc9792801001a0341b7f2ef62ec29717a389a4940e28475731569675759ae3e8a33f3ca3157861a01538b9cd1c41315974a941a54a6e8f59bf9319214877dbe5b29da3d6500b917c" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe3cb33c7b05692a6f25470fbd63ab9c986970190729fab43191379da38bc0d8c" + "0xd08b7458cd9d52905403f6f4e9dac15ad18bea1f834858bf48ecae36bf854f98", + [] ] }, { "jsonrpc": "2.0", "id": "np187", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcc3b1096f3ce63881c77751baec2048561baa2dc84ea0ef9d3a5515061aa74e0", + "parentHash": "0x5f67af973e604193cdcd68a80dea8ff0622ee1341330c1b8601502020617c2cd", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xff13e99ee95ffe82139758f33a816389654a5c73169b82983de9cf2f1f3dbd9f", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x48bdda61ea2778c74512475292f1383ad3858049a72ae7db5e30bd3fbf2bd624", + "receiptsRoot": "0x71352a0ec9727dcb65a37d458c233348bdf13252737a63c23cad594194349710", + "logsBloom": "0x00000000000000200000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000040000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xbb", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x74e", "extraData": "0x", - "baseFeePerGas": "0x19", - "blockHash": "0x871cb66f77db23f8e70541a647329c5ca9b6d40afd3950d48df4915f300e664a", + "baseFeePerGas": "0x7", + "blockHash": "0x493bf6336f7b638f36a29952c86afbb58526152b62be20eb6433bee0474d62a8", "transactions": [ - "0xf88281961a830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0276782d84f5f6ab0805be5e57923747bae9fa2b06ed4b45bcc364bdb4f09eca1a0484f9fc2a31a4b5f24ba33da54649e6a3261c0bee52d91576246bb54698c1535" + "0x03f8f9870c72dd9d5e883e81ac0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c5f69e43b76f789f0656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a023c2e06f633f91e89e0d95cf87dce47fe1cb2b95434ff45773f1fd560ad2dcf683020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0d0263d59ac408ad76fb77656223a8015758a80eab5dff92e7088f0254143ca70a068b79a5e30ce091911f3bca90ade5affc350907f6c8bf8af1dcd860808d126b0" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xc893f9de119ec83fe37b178b5671d63448e9b5cde4de9a88cace3f52c2591194" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xdf979da2784a3bb9e07c368094dc640aafc514502a62a58b464e50e5e50a34bd", + [] ] }, { "jsonrpc": "2.0", "id": "np188", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x871cb66f77db23f8e70541a647329c5ca9b6d40afd3950d48df4915f300e664a", + "parentHash": "0x493bf6336f7b638f36a29952c86afbb58526152b62be20eb6433bee0474d62a8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x522c1eb0c4d1332668a2e3676efd54899579d85fd4e7007fd228702d9c964baa", - "receiptsRoot": "0x90d4e326daf1e15e41687f281f8e638992c4cdfbe590eb4956fd943aa39f1bba", - "logsBloom": "0x48000040000000000000000000004000000000000000000000400000000000002000000000000000000000000000000018000000000000000000002000000000000000000000100000002000000800000000000000000000000000002000000000000000000000000000000000000000040000020000040000000000000000000000000101000000000000000000010000000000040000000000000000000000008000000000000000000000800000000000201008000000000000001000000000000010000000000000100000000000000000000000040100000000000000000008000000000000000000000000000000000000004000000000000000000000", + "stateRoot": "0x80fd3239645de81ad57f1ebccda32eb45a50668e451b3b26e7218ac0dcadbeef", + "receiptsRoot": "0x247cd528261f6874860ba6679d6568e67b880e47319f8c3b0dd31bc1fb6755d3", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000002000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xbc", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x758", "extraData": "0x", - "baseFeePerGas": "0x16", - "blockHash": "0x174a8681a0d28b9a3d49afb279714acb2bfe4a3abfe490522bb3d899d3c71c8d", + "baseFeePerGas": "0x7", + "blockHash": "0x2febc2674bc628df6cde532fe9c598bfca92240c5f240d189aa372425c24487a", "transactions": [ - "0xf87981971783011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0870548904b9e901c294fd1c04a6cff92fbb40491e00a1ffcbc551c6c5eba2db3a0524ff53000a94b71aef3a2c516354bc5d7fdb3f236d4647020762a56d9bd2fbf" + "0xf87481ad08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c9d643f50f3c3ae83656d69748718e5bb3abd109fa0b3e7127bf0e21a500b9b3b883ec9def5eae78ce9bc8fee10d6cdeffdc0c13f60a00e74798f17ce1b4972603e58546b548c1e24bfba21c3d96bb035c709efeb8490" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x39c96a6461782ac2efbcb5aaac2e133079b86fb29cb5ea69b0101bdad684ef0d" + "0x15855037d4712ce0019f0169dcd58b58493be8373d29decfa80b8df046e3d6ba", + [] ] }, { "jsonrpc": "2.0", "id": "np189", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x174a8681a0d28b9a3d49afb279714acb2bfe4a3abfe490522bb3d899d3c71c8d", + "parentHash": "0x2febc2674bc628df6cde532fe9c598bfca92240c5f240d189aa372425c24487a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xfb0eecb29a002997c00e0f67a77d21dd4fa07f2db85e3e362af4bbfcb69b6c12", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xbf8e94c61c11a129156b7e3fa9ba0de86d54dc00d74a4471e9c98ba815759b38", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xbd", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x762", "extraData": "0x", - "baseFeePerGas": "0x14", - "blockHash": "0x1b56a73d407c9a5e222c2097149c2f2cbb480a70437ee41779974b8ab968a8e1", + "baseFeePerGas": "0x7", + "blockHash": "0x341223f936840f7f6a33fd74e14e5ebe4300b215cfadf77a8f6e88bfed017dad", "transactions": [ - "0xf8648198158302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0111d3d32f82c89fc830943a4aa0b20e013886491e06acede59ea4252b3366c05a07b9f9199ecdb210151db8a50c74fa1488b198db4e5dda3ad1fa003b70d9bd03a" + "0x02f86a870c72dd9d5e883e81ae0108825208944340ee1b812acb40a1eb561c019c327b243b92df0180c001a0ed38f6f89589e40421e3b475ea232220aaf132fa8b2f8a429b56aaa847116b9da0097910c31d39272f66c86d4146ca7e354af1e69ef3bfa8c18d40d2b95e4db5f5" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x72a2724cdf77138638a109f691465e55d32759d3c044a6cb41ab091c574e3bdb" + "0xfd1462a68630956a33e4b65c8e171a08a131097bc7faf5d7f90b5503ab30b69c", + [] ] }, { "jsonrpc": "2.0", "id": "np190", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1b56a73d407c9a5e222c2097149c2f2cbb480a70437ee41779974b8ab968a8e1", + "parentHash": "0x341223f936840f7f6a33fd74e14e5ebe4300b215cfadf77a8f6e88bfed017dad", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x36fce9409ec76cfda58bd4145be0289d761c81131ed0102347b96127fd0888e2", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x204529ee2f764b20eaaf6435c4f230829529269cacb29935eb0c3a7120bc1921", + "receiptsRoot": "0xbe3866dc0255d0856720d6d82370e49f3695ca287b4f8b480dfc69bbc2dc7168", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xbe", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x76c", "extraData": "0x", - "baseFeePerGas": "0x12", - "blockHash": "0x07d1571c1d0fbaf6cd5c2fa18e868d6dfc2aa56f7ee3bd5aaf61fa816d775ee9", + "baseFeePerGas": "0x7", + "blockHash": "0xfcacae1b8715635bf3bbb10a375c44c799c2a882cab116306400381ff62e71f2", "transactions": [ - "0xf86781991382520894478508483cbb05defd7dcdac355dadf06282a6f201808718e5bb3abd109fa0910304dbb7d545a9c528785d26bf9e4c06d4c84fdb1b8d38bc6ee28f3db06178a02ffc39c46a66af7b3af96e1e016a62ca92fc5e7e6b9dbe631acbdc325b7230a1" + "0x01f869870c72dd9d5e883e81af0882520894eda8645ba6948855e3b3cd596bbb07596d59c6030180c080a056843c6013ef0f7e993d7d4a299d7333722cae8844b9bda606a8f85236a7ae66a06e0498193d10d4767c06dc92c7945d7e8e0fb727437f5f683c4d15d7520aca67" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x178ba15f24f0a8c33eed561d7927979c1215ddec20e1aef318db697ccfad0e03" + "0xedad57fee633c4b696e519f84ad1765afbef5d2781b382acd9b8dfcf6cd6d572", + [] ] }, { "jsonrpc": "2.0", "id": "np191", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x07d1571c1d0fbaf6cd5c2fa18e868d6dfc2aa56f7ee3bd5aaf61fa816d775ee9", + "parentHash": "0xfcacae1b8715635bf3bbb10a375c44c799c2a882cab116306400381ff62e71f2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd5d1fc871c3a4694da0e9a9f453c0e6f4c8f38fbef45db36c67cd354e22eb303", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xfd9c7a4406ab2c46dcc6be382fb183735b1d3e070a9d1f1635a7bbb429b1f90b", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xbf", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x776", "extraData": "0x", - "baseFeePerGas": "0x10", - "blockHash": "0xda1708aede1e87f052ee6e9637f879462b613e4cbddacb18aa49907b55094ce4", - "transactions": [], - "withdrawals": [ - { - "index": "0x16", - "validatorIndex": "0x5", - "address": "0xb12dc850a3b0a3b79fc2255e175241ce20489fe4", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0xddb665db1612487f7e1e333fbb5f607b93bcfc618983de7dd61d76dac6f3d948", + "transactions": [ + "0xf86781b008825208944340ee1b812acb40a1eb561c019c327b243b92df01808718e5bb3abd10a0a015432bdd04ffc5215aa37318a4e5ac3bfbd95cb9f9fdeda20ed2366c03b0ccc2a03f18a7bbed8d5056b9cf1b0f48a57f2a697b4374aee87989304389efd91b8c82" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf7b2c01b7c625588c9596972fdebae61db89f0d0f2b21286d4c0fa76683ff946" + "0xc2641ba296c2daa6edf09b63d0f1cfcefd51451fbbc283b6802cbd5392fb145c", + [] ] }, { "jsonrpc": "2.0", "id": "np192", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xda1708aede1e87f052ee6e9637f879462b613e4cbddacb18aa49907b55094ce4", + "parentHash": "0xddb665db1612487f7e1e333fbb5f607b93bcfc618983de7dd61d76dac6f3d948", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4d19a2ce0d61642b6420c9f23ea32bb72ebe24384ed110394d7e5ca98589f055", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x62ba3f65349e4c111e0d29f69d2b8e23e737f8b593645d9bd27527b4b6a281c2", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x780", "extraData": "0x", - "baseFeePerGas": "0xe", - "blockHash": "0x082079039cffbdf78a5cc86fddb47d96c888e0e90b092f9e0591e0099086cc45", - "transactions": [ - "0xf882819a0f830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa02356373d8d8ca7c15e547e717f7327ab0d803867cfabedf8d75e4d1cb264862ca011a3879ae15ab356e9558926382b7fa68b5c5a5c5b127b6f5176523dfe0ae986" + "baseFeePerGas": "0x7", + "blockHash": "0xcdeb0c3a06240f7f742c497bb142ac2477df943a878f8296b911b9f1169c1e46", + "transactions": [], + "withdrawals": [ + { + "index": "0x10", + "validatorIndex": "0x5", + "address": "0x2d389075be5be9f2246ad654ce152cf05990b209", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x16e43284b041a4086ad1cbab9283d4ad3e8cc7c3a162f60b3df5538344ecdf54" + "0x5615d64e1d3a10972cdea4e4b106b4b6e832bc261129f9ab1d10a670383ae446", + [] ] }, { "jsonrpc": "2.0", "id": "np193", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x082079039cffbdf78a5cc86fddb47d96c888e0e90b092f9e0591e0099086cc45", + "parentHash": "0xcdeb0c3a06240f7f742c497bb142ac2477df943a878f8296b911b9f1169c1e46", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd67263b379522c5059bb0a7164b9cd3fa70697e4012b3b5c519ecf888dbc5700", - "receiptsRoot": "0xc1c820ad9bde8ce9524a7fa712d4849dc2f9f9553e8c00f1fe6c41323e31fbf7", - "logsBloom": "0x00000000000000000000000000000000000000000080000000000200000040000000000000000000000000000000000000000000000000000000001000000000000000000000000000001002000004020000000000000000000011000000000000000080000082000082080000000404000000080010000000000000000000000000100000010000000000000400000000000000000000000000000000400402000000000000000000000000000000000000000000200000000000002000000004000000400000002000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000800000000000000", + "stateRoot": "0xeed15dc1d1c3aa58ec844a312c71e28df4da173c397548d8054958fd9935c25b", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc1", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x78a", "extraData": "0x", - "baseFeePerGas": "0xd", - "blockHash": "0xe1207296a903bee61a02dd94d685640d76ab57ea96dd5789819583e35f2d7eb3", + "baseFeePerGas": "0x7", + "blockHash": "0x24b14515d27271ed944fd78cdea5855bbedf6cd84d65f925f8f06a426f7b1e4b", "transactions": [ - "0xf879819b0e83011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa03423551e59962468cb263c416cb4025c462624b8c8c687177571976c345a8d20a0190d3ab5979e300998fc96429a75c50e1c195115cada83e01fb14a28f2e294de" + "0xf88281b1088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0e10c5cbc9b32e3884f89ae0b846ec590fac27b518c0b94d4073b29c8bec9f0f6a0211543469b2609d656ed3cf1c81d0c46a1b9d9fe3e40f4db0470629d2dd7a87c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x0a98ea7f737e17706432eba283d50dde10891b49c3424d46918ed2b6af8ecf90" + "0x0757c6141fad938002092ff251a64190b060d0e31c31b08fb56b0f993cc4ef0d", + [] ] }, { "jsonrpc": "2.0", "id": "np194", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe1207296a903bee61a02dd94d685640d76ab57ea96dd5789819583e35f2d7eb3", + "parentHash": "0x24b14515d27271ed944fd78cdea5855bbedf6cd84d65f925f8f06a426f7b1e4b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2111d275b4901e864fcded894a9d9a046f9077d8f6c5af65a72c2243a32dbeaa", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x2fe80dd71f69b62d75eed163395dfc900797e0aea020977a6e407545190fbfb7", + "receiptsRoot": "0xfa5f21241960744e16ad565849246d4f375208ad4df418933fb3f903cb4e8ee4", + "logsBloom": "0x00000000000000010000001000000000000800000000000000000000010000000000000000020000000000004200000000000000000000000000000000000080000040040000000000000000004000001000800000000000100000000000000000000001010040000000000000000000000000000000000000000000040000000000000000000020020000000000000000000000000000000000000000000000000000000000004800000080000000000010000000000102000000000000000300000000000800000000000000000000040000000000000000000000000000000000000000000000000000000000000020000000000000004000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x794", "extraData": "0x", - "baseFeePerGas": "0xc", - "blockHash": "0x8fd42cbdbbe1b8de72a5bb13684131e04572585077e0d61a0dfbb38d72ef309f", + "baseFeePerGas": "0x7", + "blockHash": "0xd5f960e48e2767108920eba4e8e326c9fc3233c3a2fa349770f04debccc14826", "transactions": [ - "0xf864819c0d8302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0b4dac384ec258b1a752856b3fcda42244c3e648577bf52d74f25313b3327bf1ca02f7b54b9475768335aab1778fd7ec882f3adbc9e78d4d04a0b78e93e4d41a76b" + "0xf87981b20883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0ea8ac7e4b44a2483e97723230e913a48bf2a489c115c4ac4ec032391cb653adfa0600e5992a204e2b0537dae104e1ca272eeb87767082c4eb860ef8b3fcb80a242" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7637225dd61f90c3cb05fae157272985993b34d6c369bfe8372720339fe4ffd2" + "0x14ddc31bc9f9c877ae92ca1958e6f3affca7cc3064537d0bbe8ba4d2072c0961", + [] ] }, { "jsonrpc": "2.0", "id": "np195", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8fd42cbdbbe1b8de72a5bb13684131e04572585077e0d61a0dfbb38d72ef309f", + "parentHash": "0xd5f960e48e2767108920eba4e8e326c9fc3233c3a2fa349770f04debccc14826", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2efd726637cb91156021ac4ae337a87f9a1f28efd620de55b77faef0d3b84b22", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0xa6c3339ba4148d799a285ee82ba2a3d078288592249d5f83e42b99b06f157370", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc3", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x79e", "extraData": "0x", - "baseFeePerGas": "0xb", - "blockHash": "0x326484b702b3c743f907227c8aad8733b1a6b7fda510512fe4fec0380bfbc0f1", + "baseFeePerGas": "0x7", + "blockHash": "0xcbfad2a8bdfe5205c485383414e29d8e0a9c8b10812151d25bb51a74c95549a2", "transactions": [ - "0x02f86a870c72dd9d5e883e819d010c82520894ae3f4619b0413d70d3004b9131c3752153074e450180c001a07cb73f8bf18eacc2c753098683a80208ac92089492d43bc0349e3ca458765c54a03bf3eb6da85497e7865d119fde3718cdac76e73109384a997000c0b153401677" + "0xf86481b3088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a07fd2ac2b263f2af12a338119e615fae0d3051dea3796964c46d16c0f941546b5a05414f2148eebe1d2ad114e32ca88ab51e1439fac716bedd3cb87c2110e39d9f3" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6a7d064bc053c0f437707df7c36b820cca4a2e9653dd1761941af4070f5273b6" + "0x490b0f08777ad4364f523f94dccb3f56f4aacb2fb4db1bb042a786ecfd248c79", + [] ] }, { "jsonrpc": "2.0", "id": "np196", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x326484b702b3c743f907227c8aad8733b1a6b7fda510512fe4fec0380bfbc0f1", + "parentHash": "0xcbfad2a8bdfe5205c485383414e29d8e0a9c8b10812151d25bb51a74c95549a2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xeba72457992e05a38b43a77a78ba648857cec13beb5412b632f6623521fe248d", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xb9543b5c0e7a63e34155d717234d5205c636cc3e6988b66dcf579d56fc91821a", + "receiptsRoot": "0x736e6281d7032bd4ba22922bc0bb6327c4c5b291b7d3cdcb1ed2a8f9ad3a5fa2", + "logsBloom": "0x00000000000000000000000001000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000004000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x7a8", "extraData": "0x", - "baseFeePerGas": "0xa", - "blockHash": "0x6a40d1d491a8624685fa20d913a684f691f1281da37059d527241526c965874d", - "transactions": [], - "withdrawals": [ - { - "index": "0x17", - "validatorIndex": "0x5", - "address": "0xd1211001882d2ce16a8553e449b6c8b7f71e6183", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0x078aa96db2936406a8d1d69a59f72bd60a908cbde5d2abb12166b41ff714977b", + "transactions": [ + "0x02f8d3870c72dd9d5e883e81b40108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c67fc28af42e5f642656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a032984cfbb954e0815427570f4ceaef21a3691026950e5ad80401232f687620e701a021bb96eed8ad52a0a4f89d5bd6584a666acd40f58e0ac4abf20005b8bf18d8cba02a3ce328668299ad47d4e7dfa4ed46db5b4bc9b661db9c081654eef1f82f837e" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x91c1e6eec8f7944fd6aafdce5477f45d4f6e29298c9ef628a59e441a5e071fae" + "0x4a37c0e55f539f2ecafa0ce71ee3d80bc9fe33fb841583073c9f524cc5a2615a", + [] ] }, { "jsonrpc": "2.0", "id": "np197", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6a40d1d491a8624685fa20d913a684f691f1281da37059d527241526c965874d", + "parentHash": "0x078aa96db2936406a8d1d69a59f72bd60a908cbde5d2abb12166b41ff714977b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8713a1c42af83625ae9515312298d02425330b20a14b7040ec38f0655cb65317", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xb00ebb7f6604fb250e1351de6bac6befa9e7e6ce445dafb62ab501fbe85531d5", + "receiptsRoot": "0x44882009e0eee4abe404df368647481c05b2c6c068b0c8c1df0ce88f47bae444", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000040000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc5", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x7b2", "extraData": "0x", - "baseFeePerGas": "0x9", - "blockHash": "0x25702b83ea77e2ad219178c026a506fa7a9c3f625b023963bc9c13c0d5cfeb14", + "baseFeePerGas": "0x7", + "blockHash": "0xc03fc9d4b6d49d1599717fbf75a9ad47496efb1ec6fafaa5b4bee2afae9bee30", "transactions": [ - "0xf882819e0a830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa02ed567eed3a763f56fe05c1e44575993df5b6cf67e093e0e9b5ec069ecaf76a2a04891e566e0d136b24d62ffe17f2bfaa0736a68f97b91e298b31897c790b2ed28" + "0x01f8d2870c72dd9d5e883e81b508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c2b5bb2644ee8dc40656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0d0e6005ee39e02d654cc2db358df9659d8265e24d7362df88a7df9200438f6ba80a0f649eb6ccffab94e9a5c90d0e9ca5e0c684ec630d63ab9fa111a9e3c228a1caea05eac0ee3d924d0666bd81261897d914f3018747fa0e061a5e6a55cce4d575dbd" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa1c227db9bbd2e49934bef01cbb506dd1e1c0671a81aabb1f90a90025980a3c3" + "0x133295fdf94e5e4570e27125807a77272f24622750bcf408be0360ba0dcc89f2", + [] ] }, { "jsonrpc": "2.0", "id": "np198", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x25702b83ea77e2ad219178c026a506fa7a9c3f625b023963bc9c13c0d5cfeb14", + "parentHash": "0xc03fc9d4b6d49d1599717fbf75a9ad47496efb1ec6fafaa5b4bee2afae9bee30", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2250f011d079600d76d5905dca93324f2fceb110390e8a7e7177569bd8ec73fd", - "receiptsRoot": "0x8027ec2e573bf62c00695cb9a0f67e28e4cce8dc44dc641d7388e4864d8ff78a", - "logsBloom": "0x00080000100000000000100000000840000000000000000000000000000000000000000000000000000000000000000000000000080080000080000000000000000000004000000000000000000000000000000000000000000000000000000200000000000000100100000000008001000000000000000000800000000000020010000000000000000000000000001000800000200000000000000000008000000000000000000000000000000000000000000000000000000000000001000000000000000000012000000000000000000040800000040004000000040000800001000000000000000000000000000000010000100000000000000000000000", + "stateRoot": "0xb0c41dffbade6271470b8f8c5b780ad0b1f02a2119260335d471965ed57569ee", + "receiptsRoot": "0x891fd12b9e201bc60c807e319a161d32840bbe493d9c44a1db9b58083f874dbc", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000009000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc6", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x7bc", "extraData": "0x", - "baseFeePerGas": "0x8", - "blockHash": "0xa752bd3886362e9e5e57dba077628fedbfbca6b2a657df205ad20d739b035c22", + "baseFeePerGas": "0x7", + "blockHash": "0x0fa887a20612f7ab9a00abfeb074c01ae4b509b4859c48c2e24abf27b7d7fed3", "transactions": [ - "0xf879819f0983011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0c362dc6d498fcbd0eab0518a012a348d87fe4f2e53f7843f350662c43258609ba026d83d49fd9654704da7435b3400713ed7909a7203d6c55b8d43dd1e9fe67226" + "0x03f8f9870c72dd9d5e883e81b60108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c28b4f9f2367ebabf656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a03c8110e03f1b54de6085ff899d0dccd87806b788d1ef3fddbca1de4c356266e783020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a04d341d72ad1244a3c31bc3b0015fb98913e5335530a4a62559c93853fb44cdf3a06d3d0dd50c842fe58e16e08248ab122efc34c430b8d750fc332644664c3e5b09" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x8fcfc1af10f3e8671505afadfd459287ae98be634083b5a35a400cc9186694cf" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xa73eb87c45c96b121f9ab081c095bff9a49cfe5a374f316e9a6a66096f532972", + [] ] }, { "jsonrpc": "2.0", "id": "np199", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa752bd3886362e9e5e57dba077628fedbfbca6b2a657df205ad20d739b035c22", + "parentHash": "0x0fa887a20612f7ab9a00abfeb074c01ae4b509b4859c48c2e24abf27b7d7fed3", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa8faa1ccb44b8d8d3ad926bdcb75a9e9fd18fa77728ef12aa9c4ba7be1906d3f", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xe72ad6c35d2223bf7e059940350eaabe3e8981c6378596be49864116d0f657a1", + "receiptsRoot": "0xd1e721c5ecad92ff5f7a0d380819f14b87b579ac4df1d2968489b730f9b40d9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000802000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000009000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc7", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x7c6", "extraData": "0x", - "baseFeePerGas": "0x8", - "blockHash": "0x5d80c24a7a87ae0ab200b864029fbfe7bb750ba0a01c07191b7f52330d2c79ad", + "baseFeePerGas": "0x7", + "blockHash": "0xbdc33ca00ea1641cf1ca2816913824999b73d47a92e7d5303c4104035ae78725", "transactions": [ - "0xf86481a0098302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a08683c22fc25a5413b758a32c5a6515b1b055541ad523ae4159c4d04c3f864260a06c8f2e1e929e9df95158a161e793ae162e1e4297f8042bf9358dcc119f5545e5" + "0xf87481b708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cbf894c2fffdcdbd0656d69748718e5bb3abd109fa036a4779c859e40e5aedd04afbdc0b99e5c1b2fa06f706e75c8d30952858c566ea05ba2bffb61a84a9947a0c93159d4315826133aa2842fa1931bbc4ff2f60f4eeb" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xcc1ea9c015bd3a6470669f85c5c13e42c1161fc79704143df347c4a621dff44f" + "0x9040bc28f6e830ca50f459fc3dac39a6cd261ccc8cd1cca5429d59230c10f34c", + [] ] }, { "jsonrpc": "2.0", "id": "np200", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5d80c24a7a87ae0ab200b864029fbfe7bb750ba0a01c07191b7f52330d2c79ad", + "parentHash": "0xbdc33ca00ea1641cf1ca2816913824999b73d47a92e7d5303c4104035ae78725", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe4f7f192080fd853f053608561854cdb68eb8de9eda499fd7ad840ca729487d3", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xae965001554c570fdf099944449e4a8619bb09413c1b150ad226f240b28c09a6", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc8", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x7d0", "extraData": "0x", - "baseFeePerGas": "0x8", - "blockHash": "0x0fd7e67081119b73ebe7ae0483ce2154a2dfb8c503545d231e2af1f8942406ae", + "baseFeePerGas": "0x7", + "blockHash": "0x44aa9401e0d5848c03c53c87cb883698f3a346340416803b666fce0eb7912595", "transactions": [ - "0xf86781a109825208947c5bd2d144fdde498406edcb9fe60ce65b0dfa5f01808718e5bb3abd109fa015f510b05236b83a9370eb084e66272f93b4b646e225bdef016b01b3ac406391a03b4a2b683af1cb3ecae367c8a8e59c76c259ce2c5c5ffd1dc81de5066879e4b8" + "0x02f86a870c72dd9d5e883e81b80108825208942d389075be5be9f2246ad654ce152cf05990b2090180c001a0627cc882a43d440583c3751b3cd55df3486c73273d7a96078c16a6ebde51f31ba062b06acb893608526565b6b55122fdbf4312e143f2af2a32154bd057f050c4df" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb0a22c625dd0c6534e29bccc9ebf94a550736e2c68140b9afe3ddc7216f797de" + "0xec1d134c49cde6046ee295672a8f11663b6403fb71338181a89dc6bc92f7dea8", + [] ] }, { "jsonrpc": "2.0", "id": "np201", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x0fd7e67081119b73ebe7ae0483ce2154a2dfb8c503545d231e2af1f8942406ae", + "parentHash": "0x44aa9401e0d5848c03c53c87cb883698f3a346340416803b666fce0eb7912595", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5188152524460d35f0c837dab28ac48f6aac93a75ecbb0bcb4af6a9c95e18a67", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x217fa2954ee1343cc299de1fd1145da676980d65134ea921cc5b2c1b1041214c", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xc9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x7da", "extraData": "0x", - "baseFeePerGas": "0x8", - "blockHash": "0x3043a03ed3369ba0dfdddac07cae4ca805dbbb0b411b3f5dd5e66198928a715b", - "transactions": [], - "withdrawals": [ - { - "index": "0x18", - "validatorIndex": "0x5", - "address": "0x4fb733bedb74fec8d65bedf056b935189a289e92", - "amount": "0x64" - } + "baseFeePerGas": "0x7", + "blockHash": "0xabf8b8c18e738be05befb8682083d8212b57c009c599b65535c4a7f47930bfa8", + "transactions": [ + "0x01f869870c72dd9d5e883e81b9088252089484e75c28348fb86acea1a93a39426d7d60f4cc460180c080a0f18f3e9683cdbef4545211391dc53712720b86cbf3eaa4644fd33713f571a874a009b214615dc2e3423998b3b16d8e8d74d48240a6c2bff07c4cf200d0f6d50419" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x92b8e6ca20622e5fd91a8f58d0d4faaf7be48a53ea262e963bcf26a1698f9df3" + "0x3130a4c80497c65a7ee6ac20f6888a95bd5b05636d6b4bd13d616dcb01591e16", + [] ] }, { "jsonrpc": "2.0", "id": "np202", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3043a03ed3369ba0dfdddac07cae4ca805dbbb0b411b3f5dd5e66198928a715b", + "parentHash": "0xabf8b8c18e738be05befb8682083d8212b57c009c599b65535c4a7f47930bfa8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x09f47830b792bc39aa6b0c12b7024fa34d561ff9e0d32c27eab5127239799bb0", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xcaba00e546f770e334b071bdb4d3f4ea77da9722b5bb0c7a0a865d8abd661c97", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xca", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x7e4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9178b45b38e39c3e3f4bc590a301254543eedb5b146bed0900465b194aaf94e8", + "blockHash": "0xc61c8872972b975d28191544f7200c3f3684a9e152c87f626b6c85aa56af4a22", "transactions": [ - "0xf88281a208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a03b50dfd68a93199762b4b47c08ca4c9f67d99e772f3fec9843a4e1c3ae4d6963a070a7b2cc31e53de9d1fa14f55f28b212979bd83bbd9e9097e65845e05a9ee40f" + "0xf86781ba08825208947435ed30a8b4aeb0877cef0c6e8cffe834eb865f01808718e5bb3abd10a0a063c98b14032fb2c822eb17147b7063eb5c85bb109db346745c9686f12f56884aa0730758544ae9aa1dd644331ddca4a97df3a5cc880fe78c433a80877756440deb" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf6253b8e2f31df6ca7a97086c3b4d49d9cbbbdfc5be731b0c3040a4381161c53" + "0xccdfd5b42f2cbd29ab125769380fc1b18a9d272ac5d3508a6bbe4c82360ebcca", + [] ] }, { "jsonrpc": "2.0", "id": "np203", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9178b45b38e39c3e3f4bc590a301254543eedb5b146bed0900465b194aaf94e8", + "parentHash": "0xc61c8872972b975d28191544f7200c3f3684a9e152c87f626b6c85aa56af4a22", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6a0d6e0a749247b4271d54ddfd2732ceb5b377c1db1ac40aa1d2339d3a143aaa", - "receiptsRoot": "0x189141497b4062bfbe61a7fb2f96cc8a95543e38c077c9150b740f8d01a313a8", - "logsBloom": "0x00000000000000000000040040000000000000000000080000000000004000000000000000004000000000008000000000000000000080000002008001000000000000000010000000000080000000000000000000200000002000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000020000000000000000000000800040000000000000000400000000000000000400001000000004000001000000000020000000000010000000000000000000000000000000000000000008000000000010000100000000000000001000000010000000000000800000000000000202000000000000000000000", + "stateRoot": "0x8f04f9a48e73c999528f2cf1176cd4b3d3029d20066292517fe649c0cb705624", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xcb", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x7ee", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9a575aa75a5f08a27533140141ffc7ed7d6e981da97316baf296dd1f8d1007d7", - "transactions": [ - "0xf87881a30883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109f9f3c7a9aedd154caa41f602593b4bc78db1101336a81095174d4487dd8338878a0458e45144a4d1a634950ae79ac251065204776baa96a3f94c6d71a00323fe9b4" + "blockHash": "0x1e7e2004a340707d31625b7ac9ea03d7add6dddfa7c32922e6222147b86aa4b6", + "transactions": [], + "withdrawals": [ + { + "index": "0x11", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xea8d762903bd24b80037d7ffe80019a086398608ead66208c18f0a5778620e67" + "0x74342c7f25ee7dd1ae6eb9cf4e5ce5bcab56c798aea36b554ccb31a660e123af", + [] ] }, { "jsonrpc": "2.0", "id": "np204", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9a575aa75a5f08a27533140141ffc7ed7d6e981da97316baf296dd1f8d1007d7", + "parentHash": "0x1e7e2004a340707d31625b7ac9ea03d7add6dddfa7c32922e6222147b86aa4b6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xda96365c5a33f358ed732463139254c4f186e899ad00b05d9a30ff39d4d1a27d", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xb5e6b4f20465ce1176c50efeeb839321c9c4e8094097f7f7108b6c133dd62dc7", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xcc", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x7f8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb35f9d9c454a03adc1eeeaa9fef20caeb8f9445663a4768d18bc0bc1790650b1", + "blockHash": "0x13676db30bae04c5f3b7f190e44e72d1c1b1299567e9e3757603554f30ff45f5", "transactions": [ - "0xf86481a4088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0a82c39f1be580d16334c133165d5ceb8d9942b184ecccea09e73ff45120ac523a04432d6958bb18882f9f07e851abe454039a5b38d61fd975c7da486a834107204" + "0xf88281bb088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa019a238a4412caee8f29267c4c04a9570f4d39d62a947012241b6f44e13f75caaa0783f12ca97199c3ca3165a6756de7e8026f49c4aba3753d5b03557938dbf44fb" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x543382975e955588ba19809cfe126ea15dc43c0bfe6a43d861d7ad40eac2c2f4" + "0xf6f75f51a452481c30509e5de96edae82892a61f8c02c88d710dc782b5f01fc7", + [] ] }, { "jsonrpc": "2.0", "id": "np205", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb35f9d9c454a03adc1eeeaa9fef20caeb8f9445663a4768d18bc0bc1790650b1", + "parentHash": "0x13676db30bae04c5f3b7f190e44e72d1c1b1299567e9e3757603554f30ff45f5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2258c0e37e5bedab21f7ea2f65190d1d51f781743653168d02181c8f16246c71", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x171d9a961fefe91fd1792a751cf4fde90239576fa142b5bd9f588ae9d4d896ce", + "receiptsRoot": "0xa04c112180a3fffdcc1655e8f47a8103a63799fd47aa23ec9b102d827ad96ce3", + "logsBloom": "0x00000000000000000040000000000000080400000000000000000002004000000000000000000000000001000000000000000000000000000000004000000000014000000000000000000006000000000000001000000001000000408000000000000001000000000000000000000000000000000000000000010000000000081000000008000000002000000000000008000000000000000000000000000000002000000000000000000000000000080010000000000000000000040000000000000000000000000010000000000000000000800000000000000002000028000000010000000000000200000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xcd", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x802", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x97f4a4e64ede52b5dfd694236e783d130206d111cf6a5eb83a3bb9a230dfd952", + "blockHash": "0x20836fb907f186aefcdcb5764e3d7c48fcd1b16bc98b967edd65b354e68a3e79", "transactions": [ - "0x02f86a870c72dd9d5e883e81a50108825208949a7b7b3a5d50781b4f4768cd7ce223168f6b449b0180c080a04f3e818870a240e585d8990561b00ad3538cf64a189d0f5703a9431bc8fd5f25a0312f64dd9ab223877e94c71d83cb3e7fe359b96250d6a3c7253238979dd2f32a" + "0xf87981bc0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa08a8ec366f0bf0013e493ef12013a96ca99ac07150b9b7df31d5d97a634e428c9a030674d41ad2c7628441bd42eee190439577b04f2e19e5193e8290b4f18cad676" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x095294f7fe3eb90cf23b3127d40842f61b85da2f48f71234fb94d957d865a8a2" + "0x7ce6539cc82db9730b8c21b12d6773925ff7d1a46c9e8f6c986ada96351f36e9", + [] ] }, { "jsonrpc": "2.0", "id": "np206", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x97f4a4e64ede52b5dfd694236e783d130206d111cf6a5eb83a3bb9a230dfd952", + "parentHash": "0x20836fb907f186aefcdcb5764e3d7c48fcd1b16bc98b967edd65b354e68a3e79", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xda2ecb481078839fd39c044b3fceae6468338266d9572da0f2281e58b9596914", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xc6f62b62137ceb0a14ad1b3fde8fa84c7aa3817990780aeb851e34068f9e169b", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xce", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x80c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb3c2c9a5de90f0637203e60288b50ecb21d17a2437cccf553d2424321fa112d4", - "transactions": [], - "withdrawals": [ - { - "index": "0x19", - "validatorIndex": "0x5", - "address": "0xc337ded6f56c07205fb7b391654d7d463c9e0c72", - "amount": "0x64" - } + "blockHash": "0x5936f662e12c0f1b392611803d3cddbe33bb2d7605769956e334c560b372537a", + "transactions": [ + "0xf86481bd088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa029e6e202c55f9d645b907bc215cd740d2778d6e9d804394013051e786b753969a0037d7a826d61cb0657e04993e66a822a5aba369a49cb548c74c822f50472cde3" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x144c2dd25fd12003ccd2678d69d30245b0222ce2d2bfead687931a7f6688482f" + "0x1983684da5e48936b761c5e5882bbeb5e42c3a7efe92989281367fa5ab25e918", + [] ] }, { "jsonrpc": "2.0", "id": "np207", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb3c2c9a5de90f0637203e60288b50ecb21d17a2437cccf553d2424321fa112d4", + "parentHash": "0x5936f662e12c0f1b392611803d3cddbe33bb2d7605769956e334c560b372537a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf0f20309e2cec2fb6af448c58c40e206b788241bb88e62a8e7479aadc6bfa94e", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x16a2bf920aecbb10ddfa63e5b2401f42894e33699c457972c2dff7f8b352bbfa", + "receiptsRoot": "0x78163770546821afe0210ddf4d9b40d3ded121339b8329cac20c43d146e0e972", + "logsBloom": "0x00000000000000000000000000000000004000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000210000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xcf", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x816", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9e63e1a7df1b726901e3139cfb429592ef8d2107aa566bcae5f3b8e21f99f0da", + "blockHash": "0xfa49b5f47466644348d75c491db8ff92813c96fb5b3f4a4deaa02bc92e3e134d", "transactions": [ - "0xf88281a608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa079aa26a33abe2e9504cfc6552c6b39434478b081f5cbbb613269d64980edaf93a079ffe44aec63b05644681b948ea0e5a996e106f3e074a90991c963ff3e7a8aa6" + "0x02f8d3870c72dd9d5e883e81be0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c979e5a5fe124c246656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0d34d30c2584168001b907965762f784cb4337381aa8090ae36bc66bd515849b580a088110c04c0c6652f487085c6ceda215e70df1c33b1125ac7bcb0af5d489bdd03a054ab88f5af3d8f0dcfaff237bb154395d0c6a59814458a682fed5887ccdd70b1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7295f7d57a3547b191f55951f548479cbb9a60b47ba38beb8d85c4ccf0e4ae4c" + "0xc564aa993f2b446325ee674146307601dd87eb7409266a97e695e4bb09dd8bf5", + [] ] }, { "jsonrpc": "2.0", "id": "np208", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9e63e1a7df1b726901e3139cfb429592ef8d2107aa566bcae5f3b8e21f99f0da", + "parentHash": "0xfa49b5f47466644348d75c491db8ff92813c96fb5b3f4a4deaa02bc92e3e134d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x177fc88f477d3dd466f7cac43b50d4b2b77fd468ef479177ed562d2401acd6c0", - "receiptsRoot": "0xd1458a51a7ca8d2c87390d85d986956f392bdd634ffbe4d5a7e2b09a142ce514", - "logsBloom": "0x00200000000000000000000000000000000000000400000000400000000000000000100400000000000000000010108000000000000000000000200800000000000004000000000000000002000000000000000000000000000000020002000408000021000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000010000000000002000000000000000000000400000000000000000000020000000000000000000000800000000000080000000000000000000000800000810002000000000400000000000000000000000000000000000000000000020000000000000000000000010080000000000", + "stateRoot": "0x23c36b132f262810c3858b7e846e553e8c5b4157f0cc759dd4d06cc5b1e2acba", + "receiptsRoot": "0x039055b9ec999e72f11bd659bb792a736d3cc09a343ef525508c39e56c466436", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800100000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000009000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd0", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x820", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4e8e6e31a8922b68a96992288e49ab9716dd37f1da1ae5b22391bc62d61ac75a", + "blockHash": "0x6cedc591e85ed32d70655274734b636e3482105a5e9d416e62ef1dda2ddd4a9d", "transactions": [ - "0xf87981a70883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0969f6d3d90ca6b62cbda31ed28b7522b297d847e9aa41e0eae0b9f70c9de1e01a0274e038abf0b9f2fba70485f52e4566901af94c9645b22a46b19aebb53b4c25d" + "0x01f8d2870c72dd9d5e883e81bf08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c8676dcf035dc0936656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a04323bceecd4ef7216d5b57b9dd12ecf03842ed56d87fe43d0959436f408f44c401a006d444f4f74e5eea0c3eaaa7254b1749c2620e613021fe3118fb522709af0d49a06893fc0e845a1bf821c0d571ca39aca9143876955a810d4f8c22dcdadbedc7b0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9e8e241e13f76a4e6d777a2dc64072de4737ac39272bb4987bcecbf60739ccf4" + "0x9ca2ff57d59decb7670d5f49bcca68fdaf494ba7dc06214d8e838bfcf7a2824e", + [] ] }, { "jsonrpc": "2.0", "id": "np209", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4e8e6e31a8922b68a96992288e49ab9716dd37f1da1ae5b22391bc62d61ac75a", + "parentHash": "0x6cedc591e85ed32d70655274734b636e3482105a5e9d416e62ef1dda2ddd4a9d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x55980d8ac0e8bfd779b40795a6d125a712db70daa937ace1f22a5fcd5fd2dfa6", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x270b9ee22c74c4a262b9a8d5bbc2d91acab5a3d227276856c5db8b57035ab2e5", + "receiptsRoot": "0xb19edeea01beedca72ba67077e0ec43a996a180c8a53de05e2258484987bc1c8", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000800000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x82a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xaf3e413fc388e1a5508f683df5806fe31d29f5df4552ccf2d6c6662816fae5fd", + "blockHash": "0x53bfe21b477b2780bf2e1aa15b19710aa9bb5100cd7bb69c8cc3a881ae50ab54", "transactions": [ - "0xf86481a8088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa04973c2a9d2fcff13428e8a3b3f0979185222cad34366777db8dfc6438cdac357a0128ad521391c000e18211ad8ffa45b41962fca43be83a50ce299d3bd4407f44b" + "0x03f8f9870c72dd9d5e883e81c00108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038ca2da1c555f06d1f8656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a05d7c0426d6595c1819b962730e5d2a44644703ebd960ec3ac51297ad937692f483020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0ac9d964fcceb3bb9986d78e3355e6759b0c09aa500b94f8d45a56b387f4e0a9da043a7692fee848877dea8f525b33bfa8ce74fa83d23863b6089b9aacda57aff16" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xfc753bcea3e720490efded4853ef1a1924665883de46c21039ec43e371e96bb9" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x6d7b7476cecc036d470a691755f9988409059bd104579c0a2ded58f144236045", + [] ] }, { "jsonrpc": "2.0", "id": "np210", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xaf3e413fc388e1a5508f683df5806fe31d29f5df4552ccf2d6c6662816fae5fd", + "parentHash": "0x53bfe21b477b2780bf2e1aa15b19710aa9bb5100cd7bb69c8cc3a881ae50ab54", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x522d0f5f8de1ef5b02ad61a3bff28c2bd0ce74abca03116e21f8af6e564d7fd2", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xfdac4f685bce039b15ebcf355bdea6d1bdcb23fd1fa61d5e605d92be7ffb65e5", + "receiptsRoot": "0xc82851acbbbc23f6dcb23ae872dbe441b63e88a28797c7f64d078f287f00aad9", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000020000000000000000000000004000000000000200000000000000000000000000002100000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x834", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa5b31d7aaa42b7be0c35a0fa375718d25441f90296550c10325a3e0f4d63217c", + "blockHash": "0x4c30c648a319319788200f7273f6de74e321f1796b01a2988f98840a11e307f1", "transactions": [ - "0xf86781a9088252089485f97e04d754c81dac21f0ce857adc81170d08c601808718e5bb3abd109fa0547e9550b5c687a2eb89c66ea85e7cd06aa776edd3b6e3e696676e22a90382b0a028cb3ab4ef2761a5b530f4e05ef50e5fc957cfbc0342f98b04aa2882eec906b2" + "0xf87481c108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c6cb6df52764cfebc656d69748718e5bb3abd109fa07b559e33b774aecd9aacf0286e66cf455b956de0d23d65e0890b6f8af7824e0ea07d0d6856bf3a5f25b3c38567f1e4c82b67fdbe1fec56883d1a311f858693aef4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x5f5204c264b5967682836ed773aee0ea209840fe628fd1c8d61702c416b427ca" + "0x417504d79d00b85a29f58473a7ad643f88e9cdfe5da2ed25a5965411390fda4a", + [] ] }, { "jsonrpc": "2.0", "id": "np211", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa5b31d7aaa42b7be0c35a0fa375718d25441f90296550c10325a3e0f4d63217c", + "parentHash": "0x4c30c648a319319788200f7273f6de74e321f1796b01a2988f98840a11e307f1", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xda7dd7f5babcf1b3c407e141b4ea76932922489f13265a468fb6ab88891ff588", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x5829a4e6c3ba50f94b040eebbd055206d5ff8549d0013b43359d680bf4581b62", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd3", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x83e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa1ffa80abb4f7f92b3932aa0ca90de5bb4a2908866b3d6727b05d5d41139e003", - "transactions": [], - "withdrawals": [ - { - "index": "0x1a", - "validatorIndex": "0x5", - "address": "0x28969cdfa74a12c82f3bad960b0b000aca2ac329", - "amount": "0x64" - } + "blockHash": "0xf490758a0266199a571a859efe170beefeb78de97d3a20328ac3d4bf07240fdb", + "transactions": [ + "0x02f86a870c72dd9d5e883e81c201088252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c080a0aef9e39d76c8457e0a7bb9c8756d1bfa6345f68099e474f8e30f3740a1d6ddfca06fbc5fba7e481cec9942305199b40aec155fec75b61945f4f9f9669e593e6a1b" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x5ba9a0326069e000b65b759236f46e54a0e052f379a876d242740c24f6c47aed" + "0xe910eb040bf32e56e9447d63497799419957ed7df2572e89768b9139c6fa6a23", + [] ] }, { "jsonrpc": "2.0", "id": "np212", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa1ffa80abb4f7f92b3932aa0ca90de5bb4a2908866b3d6727b05d5d41139e003", + "parentHash": "0xf490758a0266199a571a859efe170beefeb78de97d3a20328ac3d4bf07240fdb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb6724f1d73bee909624707836e66ffbb21b568dd5bd697668ce18a4ae31818a4", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x9fa6c6e9301b88853215e45c7486e03668c41923a9433035600c6774c3f70ac1", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x848", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9a77bcf7bf0d7e6cebeb8c60b4c36538b4fab0e633b9683ba589981c293a009c", + "blockHash": "0x0a1e9c1d1ad91f4d574599fe8247974beb2ab68c78b43cdda303870ede057f49", "transactions": [ - "0xf88281aa08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0e582e9d64ed6f95da074eaeb70ca1e47e8627bb7cd4e34d5aab01ff49ee6dd90a022cc32cc7c3030b0b47f1f69911311acd2ae3e95f19f766b69ebb67804676262" + "0x01f869870c72dd9d5e883e81c308825208942d389075be5be9f2246ad654ce152cf05990b2090180c001a09c5619eb9696478f17d50fb6170ee50d8af515c6cbd08e108487c4f3777211aea05db82c382e1cf0861b97e06484e0a3fb71dccfeba88b69d211a8782962b7cd2e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb40e9621d5634cd21f70274c345704af2e060c5befaeb2df109a78c7638167c2" + "0x8e462d3d5b17f0157bc100e785e1b8d2ad3262e6f27238fa7e9c62ba29e9c692", + [] ] }, { "jsonrpc": "2.0", "id": "np213", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9a77bcf7bf0d7e6cebeb8c60b4c36538b4fab0e633b9683ba589981c293a009c", + "parentHash": "0x0a1e9c1d1ad91f4d574599fe8247974beb2ab68c78b43cdda303870ede057f49", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6a1c08c9dfcc48c37e349407f37f9c10d9d4c4b1d6c28d30af2630679c74ea96", - "receiptsRoot": "0x730ab6f592da8dfc7815bcba110f6de8dd0343aa932f55b589ff99d83b9ec358", - "logsBloom": "0x00000000000000000000000000000000000000200000000400000000000000002008008000100100000800000000000020000000000000000000000000000000800001000000002000000000000000800000010000000000000000420008000004000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000004000000000000008000000000000000000000000000000000000000000000000000000400010000000000004000000000000008000000840000000000000000040000000000000000000000000000120000001000000100000000000000000000000000000000000000000000", + "stateRoot": "0x7acb7b8b3870b4776f57a820b541ae9bde134f1d1972ab0294e2e66ac60e6736", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd5", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x852", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xecb42acc218101eb9c6d883a333d07c7736d7ed0b233f3730f5b9c9a75314cf5", + "blockHash": "0xd89a67d59bfca6ef7942ef28cb121005dfd9c18b404a8dfb95e7c4d1b405a87e", "transactions": [ - "0xf87981ab0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a08747d48d3358eb47195c17f67f22af5eca1177fba591b82b8b626058a347b2e5a0420e02657efee51f73f95017b354b1bca2850269a5de7b307a280c63830f3333" + "0xf86781c4088252089414e46043e63d0e3cdcf2530519f4cfaf35058cb201808718e5bb3abd109fa08e1059084e07382e7c3f645d2adf302436c9114e70e26b5bdbfa2adff7dbd48ca03c3d1e78c1a4db22758155af5ece83f71158ab8163f9066b651745a186872fc5" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x70e26b74456e6fea452e04f8144be099b0af0e279febdff17dd4cdf9281e12a7" + "0x3e6f040dc96b2e05961c4e28df076fa654761f4b0e2e30f5e36b06f65d1893c1", + [] ] }, { "jsonrpc": "2.0", "id": "np214", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xecb42acc218101eb9c6d883a333d07c7736d7ed0b233f3730f5b9c9a75314cf5", + "parentHash": "0xd89a67d59bfca6ef7942ef28cb121005dfd9c18b404a8dfb95e7c4d1b405a87e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x67ca707e9bd81330c2fb9060e88ce0b0905c85c9be26ae4779874f3892ebab0c", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x981e76609731467dfeeb081989c54862b48595f14366b0717dad9ce88d967997", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x85c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1191fbb4f2692461fc0ae4aa7141a1743a345c101dc9db157bc7ad3072fe1e9d", - "transactions": [ - "0xf86481ac088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a03752a40997c9b7b9c5dfd48f88990ddc727517540c403dadcb7476b8a4a9d4f6a0780178975646114017be4b06fae0689a979a45166f810604f76934239b0a2b9e" + "blockHash": "0x44e4a64750e4c9f6511df524c16e9cb23554a89325cf503b74f8f25f16253cec", + "transactions": [], + "withdrawals": [ + { + "index": "0x12", + "validatorIndex": "0x5", + "address": "0x84e75c28348fb86acea1a93a39426d7d60f4cc46", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x43d7158f48fb1f124b2962dff613c5b4b8ea415967f2b528af6e7ae280d658e5" + "0x07e71d03691704a4bd83c728529642884fc1b1a8cfeb1ddcbf659c9b71367637", + [] ] }, { "jsonrpc": "2.0", "id": "np215", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1191fbb4f2692461fc0ae4aa7141a1743a345c101dc9db157bc7ad3072fe1e9d", + "parentHash": "0x44e4a64750e4c9f6511df524c16e9cb23554a89325cf503b74f8f25f16253cec", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3b5ca86f1650f79fb42d74e523dc4e631989a3175023ced9a239e9bcc2c15a8e", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0xd00459f2dd9d486fd22a4c2a34cf9793da5a6b76b9020e151db7db7eb402e5f5", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd7", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x866", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9b9e271d571b730c9e6acd133c99eba1ccd8b8174ffe080540fc3b1a5625943a", + "blockHash": "0x9a379148fa0512b767d90e2a9a20248c6c19441d7f9284b00f802de8d40c5404", "transactions": [ - "0x02f869870c72dd9d5e883e81ad010882520894414a21e525a759e3ffeb22556be6348a92d5a13e0180c001a0047b3309af68dd86089494d30d3356a69a33aa30945e1f52a924298f3167ab669fb8b7bd6670a8bbcb89555528ff5719165363988aad1905a90a26c02633f8b9" + "0xf88281c5088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a029fc410923581507d7291574037a67f6e1eac9f100ffdce835f42d20fa508971a03d3e1a36a3adcc64bc95d036c1335989bd3cd8810a7009fe910d469a0b384b0c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb50b2b14efba477dddca9682df1eafc66a9811c9c5bd1ae796abbef27ba14eb4" + "0xf4d05f5986e4b92a845467d2ae6209ca9b7c6c63ff9cdef3df180660158163ef", + [] ] }, { "jsonrpc": "2.0", "id": "np216", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9b9e271d571b730c9e6acd133c99eba1ccd8b8174ffe080540fc3b1a5625943a", + "parentHash": "0x9a379148fa0512b767d90e2a9a20248c6c19441d7f9284b00f802de8d40c5404", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc1ab95016db7b79d93ee0303af69ce00bdb090d39e20a739d280beb3e301c9d5", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x3dedfe9b872cff7e3a73dc6415b388469f09609fc9b9ea8e87d988f3acdb2c40", + "receiptsRoot": "0x44356f2265ddbe65555b4b95e21c7ef48964641e03ab3082353b07d9078f8f51", + "logsBloom": "0x00000000000000000000000000000000000008000000000080000000000000000000000000000000000000000040000000000000000000400009000000000008001000010000000040000000000000000000000000000000000000000018000000000000000000000000000000000000000080000000100000000000000002000000000000000000000000000000000000000000000000000000000000000000004002022002000000044000000040800000000000000000000000000001000000000000000000000000000000000800000000100000000000000000000000000000000000000400000006001000000000000000000080002000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd8", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x870", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4e27c497c83c3d06d4b209e7d5068920d7e22bb3c959daa4be5485d6ab0cce54", - "transactions": [], - "withdrawals": [ - { - "index": "0x1b", - "validatorIndex": "0x5", - "address": "0xaf193a8cdcd0e3fb39e71147e59efa5cad40763d", - "amount": "0x64" - } + "blockHash": "0x96ce02bc5a0630bbf7d4c1340ff68ba3cbc53a401d8ced01339937d2d764980e", + "transactions": [ + "0xf87981c60883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa030a9d121bc9e2cfecc1898c345a758637c76cd12bff359a9fae9fa5fd4159ca5a079825054df53269360ab9971dbb4fdd41654d53af7ea4b63a9649138e499326f" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc14936902147e9a121121f424ecd4d90313ce7fc603f3922cebb7d628ab2c8dd" + "0x5ca251408392b25af49419f1ecd9338d1f4b5afa536dc579ab54e1e3ee6914d4", + [] ] }, { "jsonrpc": "2.0", "id": "np217", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4e27c497c83c3d06d4b209e7d5068920d7e22bb3c959daa4be5485d6ab0cce54", + "parentHash": "0x96ce02bc5a0630bbf7d4c1340ff68ba3cbc53a401d8ced01339937d2d764980e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf8c17319b995ce543f9ace79aab7f7c928b36facae4e6e0dd50991f95bed1542", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x2befec4b322b55dd859c81bafc76ee06de698ba0a0e1a80100dfc52ecf3a5da9", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xd9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x87a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xdf05b4a3aff6236d0d3c1ee058b874309c37005a2bbb41a37432b470ed49e678", + "blockHash": "0x41eea349b7529f1465e872f4eeb3958da339bd18193b9055d1f77649b5b5a8b1", "transactions": [ - "0xf88281ae08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa05a8e9e2a3556016a65d5b99849bd44cd6ab17cfb15d7850356c9b491357f0611a01f7d3c43fe1759b4ec768275e918e12dae75db56a5d2140d1403ef3df41f56df" + "0xf86481c7088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0cb1af42d19318f59a0ac8d3cede5c0676a469b9321ba05d79b399c6f797643baa028a8a87701ac2d081f04455ad349560814f8587a534598361d105c7abf886af7" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x86609ed192561602f181a9833573213eb7077ee69d65107fa94f657f33b144d2" + "0xe98b64599520cf62e68ce0e2cdf03a21d3712c81fa74b5ade4885b7d8aec531b", + [] ] }, { "jsonrpc": "2.0", "id": "np218", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xdf05b4a3aff6236d0d3c1ee058b874309c37005a2bbb41a37432b470ed49e678", + "parentHash": "0x41eea349b7529f1465e872f4eeb3958da339bd18193b9055d1f77649b5b5a8b1", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x05bd7288ee80780a92b234fec2f8bb5bb4d0425721ddbf89d866c62b288f6bff", - "receiptsRoot": "0xbebbd614564d81a64e904001523ad2e17a94b946d6dfc779928ec9048cf9a3f7", - "logsBloom": "0x40000000000020000000000040000000000000000000001000000000000000021000000000004008000000000002000001000100000000000000002000000000000400000000000008002000000000000000100000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000100000400000000000000000000000000000000000000000000000000000020000000000010040000002000000000000000000000000000000000000000000000000020000000000200000000000200000000000000011000000000201400000000000001000000000", + "stateRoot": "0xa59cae76341e126fdd5fdefebd48eaa5a60c0545051f79d5cdbb3fbcfe96ab37", + "receiptsRoot": "0x7336229ff06445fc64883e750bb07c2ac1556b12458cb4981ea24c2fefde5c07", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000140000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xda", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x884", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf9a9d8409219172c2a602cfb9eadffdeb13a68c55a48e048a19c3b17d85e3b46", + "blockHash": "0xecdbfed50e09e8bea9b23b0c056b9ef72bd724fd104590fdccfed99e26401a78", "transactions": [ - "0xf87981af0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0b3a49ddc2fc9f12cb1dc0a67623d5a1a6a1b5bf59a8f1736c9f0ab3b564250d3a05fc1ca6dab6b9337827afb55342af8a51fae064157e9c78b76dacd66bbea55d1" + "0x02f8d3870c72dd9d5e883e81c80108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ca593b76d11072099656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a03982f6a73961b17f67a84959ebc42a5a3ebdd1faa925399f3f276cc2de65f2fb80a0d670ad4d51a872c140a4fe0209330c2e44232837dcb8ab09afff5fc171348c9da04298e929bef7c3d15e8b40dcc6046337ca4e725704f513c2e84286e67f8b7b05" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x0a71a6dbc360e176a0f665787ed3e092541c655024d0b136a04ceedf572c57c5" + "0xd62ec5a2650450e26aac71a21d45ef795e57c231d28a18d077a01f761bc648fe", + [] ] }, { "jsonrpc": "2.0", "id": "np219", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf9a9d8409219172c2a602cfb9eadffdeb13a68c55a48e048a19c3b17d85e3b46", + "parentHash": "0xecdbfed50e09e8bea9b23b0c056b9ef72bd724fd104590fdccfed99e26401a78", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8236fb6bc66022c43d12c08612fd031d8b42852bef9a2dec04c1bc4b83cba489", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd3d3012407a941194dba4e6a98cf30f376facbea5142628a3ea5606967259d43", + "receiptsRoot": "0x4c08bb651446370eb08574678f4868ba4e705afaf09438505c2ec10b6fd39ace", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000008", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xdb", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x88e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf69983460a4d977eceea022607df6db15b3d8103f78e58d73eeac3593053dbc6", + "blockHash": "0xfa439516704748050ea45b059aad351048e40ae85f495fd0ec4e77c34a02325f", "transactions": [ - "0xf86481b0088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa08a2bbd86fd1bb42e548fa4b4c4710f6c6ed03b4700f9e3a213bc70d17f016a3ca076d8bf736d722af615228680c31acd9815b9380a8bc5895cddb2361170274a7f" + "0x01f8d2870c72dd9d5e883e81c908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cce282565ecdd5bc9656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a081607ef8d6fd479d2d0f55ec50762ee5fc35883ee5600525ce1e9ef3398d5aa501a0c3c70831d5587c9351e2459dd471faf12422892116d4c8d42b9a63243d9606d9a07300a31913c6ee1498e1f4eb9bf30503ccfe418b0d48dcbd01ab9cd342882f65" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa4bcbab632ddd52cb85f039e48c111a521e8944b9bdbaf79dd7c80b20221e4d6" + "0x4d3fb38cf24faf44f5b37f248553713af2aa9c3d99ddad4a534e49cd06bb8098", + [] ] }, { "jsonrpc": "2.0", "id": "np220", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf69983460a4d977eceea022607df6db15b3d8103f78e58d73eeac3593053dbc6", + "parentHash": "0xfa439516704748050ea45b059aad351048e40ae85f495fd0ec4e77c34a02325f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1d9d412ef451097aa53e4fc8f67393acfd520382a1c4cfa6c99e2fb180a661db", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xa9888352cf098a936c7ca1bd6dcf29c67a1269911598a3ad2532349bc1878095", + "receiptsRoot": "0xae08072b6df3427088c5c0fe33f7d710b6536f08bcbd142288632314b8757901", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000804000000000000200000000000000000000000000002000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xdc", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x898", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xecea5d6aa092dc29520fcd6cd44102c571c415fd5d641e978af4933c476020a6", + "blockHash": "0x8967b48c91a9a3ac039752dc1b0b5c091e38b28635f934949604b9ad0e2017e9", "transactions": [ - "0xf86781b10882520894fb95aa98d6e6c5827a57ec17b978d647fcc01d9801808718e5bb3abd10a0a0c71a69f756a2ef145f1fb1c9b009ff10af72ba0ee80ce59269708f917878bfb0a03bfe6a6c41b3fe72e8e12c2927ee5df6d3d37bd94346a2398d4fcf80e1028dde" + "0x03f8f9870c72dd9d5e883e81ca0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c7c3a8ef48b3cebe9656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0e207f028cce1624a1fc76c56f1794c2704a692c1f214685291d618e40733ff1b83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a051c209d8f78486a77a18312b2a8d08bb75d4a5add1c8499c9683a1a798bd9da7a00faf9bffc5ebaa9f6e1a348321daaabcd83479aa3e844d01d583a4d1a5595030" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x2bc468eab4fad397f9136f80179729b54caa2cb47c06b0695aab85cf9813620d" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x36e90abacae8fbe712658e705ac28fa9d00118ef55fe56ea893633680147148a", + [] ] }, { "jsonrpc": "2.0", "id": "np221", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xecea5d6aa092dc29520fcd6cd44102c571c415fd5d641e978af4933c476020a6", + "parentHash": "0x8967b48c91a9a3ac039752dc1b0b5c091e38b28635f934949604b9ad0e2017e9", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x830dfc2fb9acb72d3c03a6181b026becbcdca1abf4ab584b2dd00c48fd2f6a62", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x0103e3b78da1bc9f87e6c73115cca698b429eff7aba71492f1f64d551a56a857", + "receiptsRoot": "0x058846f9ac88fafd60b7a79014917afcf9b3015dc0f98a5aa3ab58700bc35cf1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000020002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xdd", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x8a2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xbc664826810922530f7e9876cd57ef0185f2f5f9bbafb8ee9f6db2d6e67be311", - "transactions": [], - "withdrawals": [ - { - "index": "0x1c", - "validatorIndex": "0x5", - "address": "0x2795044ce0f83f718bc79c5f2add1e52521978df", - "amount": "0x64" - } + "blockHash": "0x4a6fe8bfb3d8209f060b20fd83362433e87e45b6059450ecd92207e5bb4bbdad", + "transactions": [ + "0xf87481cb08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cf2b2ffddc2dde581656d69748718e5bb3abd10a0a020d836af511621c71c81861e9c0f57225cfd85e18ec6b35ed22a285e3b51f8e2a03d6ee47e8e5d7d5b239153906a7129278cae4941edc1d80ee1116e56c9a4c7e3" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xfc7f9a432e6fd69aaf025f64a326ab7221311147dd99d558633579a4d8a0667b" + "0x164177f08412f7e294fae37457d238c4dd76775263e2c7c9f39e8a7ceca9028a", + [] ] }, { "jsonrpc": "2.0", "id": "np222", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xbc664826810922530f7e9876cd57ef0185f2f5f9bbafb8ee9f6db2d6e67be311", + "parentHash": "0x4a6fe8bfb3d8209f060b20fd83362433e87e45b6059450ecd92207e5bb4bbdad", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7492f26a06f6b66d802f0ac93de1640ec7001652e4f9498afa5d279c1c405ccd", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x01cb1e199169e38b74db5252fd7c4e85a1c3c434cd4ee9175f41923b28317d41", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xde", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x8ac", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb908ac3bd269a873b62219e78d5f36fdfd6fb7c9393ad50c624b4e8fd045b794", + "blockHash": "0x58f4f818948eb949af6ebbe9c9922a6742c45eb6c60cc272027488d0d0fb8207", "transactions": [ - "0xf88281b208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa09765f880d3815c484a796d3fd4c1791ab32f501ba8167bfd55cde417b868e459a0310fdd4d8d953cf38b27fa32ad6e8922ef0d5bd7ba3e61539dd18942669187f1" + "0x02f86a870c72dd9d5e883e81cc0108825208944dde844b71bcdf95512fb4dc94e84fb67b512ed80180c001a033bfa67c45c7321f9c73581990967d07c95309544419108b403b1872567fc5c5a02f15eb8aeff6e7295cd5a48666b0db706fe17c02d590d4a29ec041af67aef794" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x949613bd67fb0a68cf58a22e60e7b9b2ccbabb60d1d58c64c15e27a9dec2fb35" + "0xaa5a5586bf2f68df5c206dbe45a9498de0a9b5a2ee92235b740971819838a010", + [] ] }, { "jsonrpc": "2.0", "id": "np223", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb908ac3bd269a873b62219e78d5f36fdfd6fb7c9393ad50c624b4e8fd045b794", + "parentHash": "0x58f4f818948eb949af6ebbe9c9922a6742c45eb6c60cc272027488d0d0fb8207", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1e515c524c17bcb3f8a1e8bd65c8403ae534c5c2c2fc0bddce2e69942c57028a", - "receiptsRoot": "0x336f567c728ef05cbd3f71c4a9e9195b8e9cd61f8f040fdd6583daf0580a0551", - "logsBloom": "0x00000000000000000000000000000000000000000000400000000000002000080000080000000000000000000000000000000000000000000000000000000000008000000040000030040000000000800000000006000000000008010001000000004000000000000020000000000000000000000000000000000000040000000400080000000000000000020000000000000040000020000000000000000000000020000001000000000000000000000000100000000000010000000000000001000000000000000000000002000000000000800000000000000200000000000000000000000000000000000020000000000000000000001000000000000000", + "stateRoot": "0x6321fb11cded8d0f04d07ae0cd09591a76b1f645051ff9c38c8482c5c5a734ed", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xdf", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x8b6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x2e8980e0390ae8503a42316b0e8ceb3bbe99245131ab69115f2b5555d4ac1f4e", + "blockHash": "0x75150cd02c717d33df03986668fca9287fa715ae9b3dc786e9a012689cbb4f2b", "transactions": [ - "0xf87981b30883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0cdd0a69ca9a6c3977ae1734d40175aa0720a866ff9353ce4aadfd8a4cd762e53a0290a5ac57e2f318959aaadec811bf9f8017191594476415923ddafef9a25de7c" + "0x01f869870c72dd9d5e883e81cd0882520894654aa64f5fbefb84c270ec74211b81ca8c44a72e0180c080a0e4c3a90362ec63060f76c892b83612c948dfdd1de2737c2239a052597e8284eda01411079de57054dba22fbf68440b0532614dda48338f16aba134c921308f3c58" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x289ddb1aee772ad60043ecf17a882c36a988101af91ac177954862e62012fc0e" + "0x99d001850f513efdc613fb7c8ede12a943ff543c578a54bebbb16daecc56cec5", + [] ] }, { "jsonrpc": "2.0", "id": "np224", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2e8980e0390ae8503a42316b0e8ceb3bbe99245131ab69115f2b5555d4ac1f4e", + "parentHash": "0x75150cd02c717d33df03986668fca9287fa715ae9b3dc786e9a012689cbb4f2b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa0a11d77a69e2c62b3cc952c07b650c8f13be0d6860ddf5ba26ef560cefd2000", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xed039258f8abcd18b3eb25a20c2ed8798ce6dbcfd9cc3220a5e611a886388d40", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x8c0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xcd2f03e81d096f1c361b6b0a1d28ae2c0ec1d42a90909026754f3759717a65db", + "blockHash": "0x4b087119094ef790b1981596fe9adfed930802ffbf33a9b5f91cf06b36aac5cf", "transactions": [ - "0xf86481b4088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0e55768f282e2db5f2e48da696a07d1bff5687ca7fa5941800d02a1c49a4781b4a00eb30d56234ac991413000037e0f7fb87c8c08b88ae75aa33cb316714b638e1b" + "0xf86781ce0882520894654aa64f5fbefb84c270ec74211b81ca8c44a72e01808718e5bb3abd10a0a0876a442f175fe09eeb195fa0a9bf7d7fd0b81017cf723c52d4e46a2d8d4c55fca07c3d774813ab31a2d4bb6f07267865be0d0dd7cf05512ff5ecc86c10532b696f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xbfa48b05faa1a2ee14b3eaed0b75f0d265686b6ce3f2b7fa051b8dc98bc23d6a" + "0x30a4501d58b23fc7eee5310f5262783b2dd36a94922d11e5e173ec763be8accb", + [] ] }, { "jsonrpc": "2.0", "id": "np225", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcd2f03e81d096f1c361b6b0a1d28ae2c0ec1d42a90909026754f3759717a65db", + "parentHash": "0x4b087119094ef790b1981596fe9adfed930802ffbf33a9b5f91cf06b36aac5cf", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd8287e5675676595007edfbfff082b9f6f86f21bb0371e336ca22e12c6218f68", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0xfb1c2e225033ea79370ea89f66289c2fe60fcad15cc0cc2f0e44b0f538540c6d", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x8ca", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x2a2c4240cf6512959534cdaf586119243f718b4ff992ad851a61211a1ea744d8", - "transactions": [ - "0x02f86a870c72dd9d5e883e81b5010882520894f031efa58744e97a34555ca98621d4e8a52ceb5f0180c001a099b1b125ecb6df9a13deec5397266d4f19f7b87e067ef95a2bc8aba7b9822348a056e2ee0d8be47d342fe36c22d4a9be2f26136dba3bd79fa6fe47900e93e40bf3" + "blockHash": "0xf7c7c5456af3ba05c94cd1d23c70ac90ea4b79b78e561045c649b08bfdaae321", + "transactions": [], + "withdrawals": [ + { + "index": "0x13", + "validatorIndex": "0x5", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7bf49590a866893dc77444d89717942e09acc299eea972e8a7908e9d694a1150" + "0xa804188a0434260c0825a988483de064ae01d3e50cb111642c4cfb65bfc2dfb7", + [] ] }, { "jsonrpc": "2.0", "id": "np226", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2a2c4240cf6512959534cdaf586119243f718b4ff992ad851a61211a1ea744d8", + "parentHash": "0xf7c7c5456af3ba05c94cd1d23c70ac90ea4b79b78e561045c649b08bfdaae321", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1e3c75d8db0bd225181cc77b2ec19c7033a35ba033f036a97ba8b683d57d0909", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x52e80785d861bf8a6cc6be5dd4bfc993448cbcf27df9a3eeaca02e933e60b0fd", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x8d4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1fb4e86909057635bfe8d130d4d606c1e9a32bd5e8da002df510861246633a96", - "transactions": [], - "withdrawals": [ - { - "index": "0x1d", - "validatorIndex": "0x5", - "address": "0x30a5bfa58e128af9e5a4955725d8ad26d4d574a5", - "amount": "0x64" - } + "blockHash": "0x918ae7ac657fc84fc8cb10dcb3794f22ee74635bc3c48a09447f82525c8b4cff", + "transactions": [ + "0xf88281cf088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa0d9bd9ba3bc4d8d9712cf4f58d49cd71c1e9d160c4283af86642828cb29a86881a078ed288cdb8c0bb6c587538b05a2960ac5dbbe5372a6d4a30c415455279b6123" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x992f76aee242737eb21f14b65827f3ebc42524fb422b17f414f33c35a24092db" + "0xc554c79292c950bce95e9ef57136684fffb847188607705454909aa5790edc64", + [] ] }, { "jsonrpc": "2.0", "id": "np227", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1fb4e86909057635bfe8d130d4d606c1e9a32bd5e8da002df510861246633a96", + "parentHash": "0x918ae7ac657fc84fc8cb10dcb3794f22ee74635bc3c48a09447f82525c8b4cff", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xacca3ad17c81310c870a9cf0df50479973bd92ade4a46b61a2012fa87c7b8a0f", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x7f06aab010cf4664949f79c5df9ee9b20994444245a8c62f7c284d9947303dd1", + "receiptsRoot": "0xf6c2782752ebf597acafad6abf0e6202a2eb97b2ec68517799c69bacf47d86d9", + "logsBloom": "0x00000000000000000000000000000000000010000001000000000000000000000000000000000000000000000000000200000000000000000040001000000800800008000000000804440000002000000000080000000004000000000000000000000004000020000000000000000200000000000000000002000800000000000000000000000002000000000000000000000000000000000000000080000000000000000000000001000000000000000000000000024000000000000000000001020000000000000000000000000020000000000000000000000100000000000000000080000000000000000000000000000000000000000080000000000600", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe3", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x8de", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x6f03c5c20de46ba707f29a6219e4902bc719b5f9e700c9182d76345fa8b86177", + "blockHash": "0xb77cf24f0c1fb354f7bf7c80e1804fdc2328774a1af50eb7959a46a8fe51a590", "transactions": [ - "0xf88281b608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa05147ab82c47d0c6f6298c21b54a83bc404088dcf119f5719034a1154f2c69acaa035070fffcba987b70efcfc6efbf5a43974de5e11331879bbfbfe7556915da7b2" + "0xf87981d00883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa098f00f0dd1331f7d9de3cf956fe0464b2e0984cc2262b81128a7507572839978a0561657f3d9e0be3d34aaa3b6087cb9055eae540180ea81358be1c7d9cf1a3be8" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xda6e4f935d966e90dffc6ac0f6d137d9e9c97d65396627e5486d0089b94076fa" + "0xc89e3673025beff5031d48a885098da23d716b743449fd5533a04f25bd2cd203", + [] ] }, { "jsonrpc": "2.0", "id": "np228", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6f03c5c20de46ba707f29a6219e4902bc719b5f9e700c9182d76345fa8b86177", + "parentHash": "0xb77cf24f0c1fb354f7bf7c80e1804fdc2328774a1af50eb7959a46a8fe51a590", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0468ebde6657b86a2f1561ae8ef57c6cbe23b7dc08cc0ad823ea3831388e1691", - "receiptsRoot": "0x591e45121efd9a319ad048f68a35db27c69b829a65d0c7817224a1c5071ab327", - "logsBloom": "0x00000005000000000010000000080000000000000000000000000008200000004000002080000001000000000000000000010000000000080000000000000000000000000000800000000000000000000000000000000000000000000000000b00000200000000000000000000200000000000200001400000000000100000000000000000000400000000000000000000000000000000000000000000000000000002008000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000020000000010000080000000000000114000000000000000000000040000000000000000000", + "stateRoot": "0xaaa416970b533c6a6842c7930d502904027f76a8f862dd7bf57e1b7010960dfe", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe4", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x8e8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8c7ac6681ed2a5020837149f8953a2762227b7bb41f2f46bc0c33508190c3e72", + "blockHash": "0xb3317abdbcc0bdc256a422a5c333572f99ff8651f095922cdd5b995b44185a49", "transactions": [ - "0xf87981b70883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa04ccccf5fa7c7ed5b48d30bee3e8b61c99f8ff9ddecff89747e5685b059d70fa7a042982d8d2a54f9a055fd75df65488462a0ceae67b8a80966427c5d7ea1cf563b" + "0xf86481d1088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a04569e675422075ad4ebd160dd8022e55321509fdbe93f360b3bd35db8104400aa054a06595c32949d3b1baa931e20ca03839c15311c83489df49a9edd73ff409ef" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x65467514ed80f25b299dcf74fb74e21e9bb929832a349711cf327c2f8b60b57f" + "0x44c310142a326a3822abeb9161413f91010858432d27c9185c800c9c2d92aea6", + [] ] }, { "jsonrpc": "2.0", "id": "np229", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8c7ac6681ed2a5020837149f8953a2762227b7bb41f2f46bc0c33508190c3e72", + "parentHash": "0xb3317abdbcc0bdc256a422a5c333572f99ff8651f095922cdd5b995b44185a49", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9f5936ddc444db8ba3787be50038f195ddb86663f39b62d556f7700334f441d1", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x8a5e1328b9170468421131678aff4a27c60534242f9ab63212e3b38fa255a58e", + "receiptsRoot": "0xb75a29ffc033968354f87e14e356ca2f90c49c9f3bcbc6224261c048498afe00", + "logsBloom": "0x00000000004000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe5", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x8f2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x01bb09f016e5dfda9ef7170f45fe4b648dd3761b26c83c18bb0eea828bbc8663", + "blockHash": "0x3958180bd85edf4b17cf80881d40b68216a23a2dbadb92fff52757661070ec35", "transactions": [ - "0xf86481b8088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa07cc4f254afaef8c4953d8a30221c41a50b92629846448a90a62ebdc76de8b2eea073f46d5c867c718486a68dfdf1cd471d65caa8a2495faba0f0a19ca704201e1b" + "0x02f8d3870c72dd9d5e883e81d20108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c15314adb38ad874e656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0782a285a3a645a32202a71e713e4a813bbaef9f50ce10e4caa0122c110d86bf680a0524664d3bd0879e248a9ec4a8e1caaba5d51a5d50eb6bb9899be1c2b712a0b69a03df458a145f697af315e747b3dfc8fe53920ba921a5447a7313ee7bfeb3a125d" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xcc2ac03d7a26ff16c990c5f67fa03dabda95641a988deec72ed2fe38c0f289d6" + "0xae3f497ee4bd619d651097d3e04f50caac1f6af55b31b4cbde4faf1c5ddc21e8", + [] ] }, { "jsonrpc": "2.0", "id": "np230", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x01bb09f016e5dfda9ef7170f45fe4b648dd3761b26c83c18bb0eea828bbc8663", + "parentHash": "0x3958180bd85edf4b17cf80881d40b68216a23a2dbadb92fff52757661070ec35", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x57dc2fdfe5e59055a9effb9660cfc7af5e87d25a03c9f90ce99ee320996a1991", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x31ccb550a59d99bfada2947f48481c5fb19963be2aa56fbb37f6b2f9da6115f8", + "receiptsRoot": "0x16b250651438c816ab67a4cf2fd473107a4b1bff0fff288d1f48d8cabd8267d0", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000080000000000004000000000000200000000000000000000002000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x8fc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x15d41d78de758ec47434a48dc695897705ad5990ac584d2a51d8b7a51419abe0", + "blockHash": "0xb1503e5b89008f2ec7cf91492da840a6786f020d11cd33a8ebfd68ee824313ea", "transactions": [ - "0xf86781b908825208940a3aaee7ccfb1a64f6d7bcd46657c27cb1f4569a01808718e5bb3abd109fa0d2aa10777b7c398921921258eeecaff46668278fd6f814ea4edb06f2a1076353a0542ef4ed484a1403494238e418bb8d613012871710e72dde77bb1fa877f1fae3" + "0x01f8d2870c72dd9d5e883e81d308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cf92aa615f9b4e91c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0b36949b816cb2ec4ab90f345d0bed84f55b8fcbeffd22198724c45d8a30b20a680a0d5a6eaf83827edf2c33a97e9909dd47f64e6bac6ab6b343e840f8897df4e5b6aa02999286ada33637076dfc36acb4718a034bcab145843cc4d76eb1895ad8eb5ab" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x096dbe9a0190c6badf79de3747abfd4d5eda3ab95b439922cae7ec0cfcd79290" + "0x3287d70a7b87db98964e828d5c45a4fa4cd7907be3538a5e990d7a3573ccb9c1", + [] ] }, { "jsonrpc": "2.0", "id": "np231", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x15d41d78de758ec47434a48dc695897705ad5990ac584d2a51d8b7a51419abe0", + "parentHash": "0xb1503e5b89008f2ec7cf91492da840a6786f020d11cd33a8ebfd68ee824313ea", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc6a8588f5fa71465604ccee5244d5c72a296994fb2bf1be478b664bc2aa77c39", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x3df027b36c56a135b888b77de630950a40e69281e5be0eaddcec18db6afcbb16", + "receiptsRoot": "0x105f1535835d30dc0d749e0d4cb7d0c3d18e64e74e8f7e158695ce6d057d241f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000080000000000000000001000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe7", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x906", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa3b4d9f55cfc3ed49c694fa2a634b73f397d5847b73b340d123b2111ba5adc71", - "transactions": [], - "withdrawals": [ - { - "index": "0x1e", - "validatorIndex": "0x5", - "address": "0xd0752b60adb148ca0b3b4d2591874e2dabd34637", - "amount": "0x64" - } + "blockHash": "0x74b7c334b7e246ba4cbdb9a91cf69bf72a3491ca4e39c2cda81e39c080bbe720", + "transactions": [ + "0x03f8f9870c72dd9d5e883e81d40108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038ca7b2474c2b69133f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a018fbf0ae0e2133584c461cbd43169854c7c7e818e8b5779892da244f24d27b5683020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0b4c11de109225403f2ed87e63a7eef36369da1db9fcf5fa469ad526bd948cee2a01ec6b85c41b4cc079ea1804ef0f7343edb57a71780fecdf5897b0285e2889788" ], - "blobGasUsed": "0x0", + "withdrawals": [], + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x0c659c769744094f60332ec247799d7ed5ae311d5738daa5dcead3f47ca7a8a2" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xb52bb578e25d833410fcca7aa6f35f79844537361a43192dce8dcbc72d15e09b", + [] ] }, { "jsonrpc": "2.0", "id": "np232", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa3b4d9f55cfc3ed49c694fa2a634b73f397d5847b73b340d123b2111ba5adc71", + "parentHash": "0x74b7c334b7e246ba4cbdb9a91cf69bf72a3491ca4e39c2cda81e39c080bbe720", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x38cdb4e70eb9771bab194d9310b56dbfcba5d9912cd827406fff94bddf8549d3", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xfa9de399a80e099e176e71ab4c1a0d628e21f1ebe37a100858b3ea6c1996f0fc", + "receiptsRoot": "0x95482d5c3c390e57fab959a9832bc6e46f7cc877207ccea7fbf81eab51318fa5", + "logsBloom": "0x00000000000002000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe8", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x910", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4ff6fbd3afcc33972501397c65fe211d7f0bf85a3bde8b31e4b6836375d09098", + "blockHash": "0x5e06576f385d64e5475da19a55db8a1b49a905e54cdd00bc833f9a6e0d1821de", "transactions": [ - "0xf88281ba08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a06f8db09016d87e96d45d0835a60822fb305336ab1d792944f6f0aa909b73c9d7a01da7c6ba739bf780143672031e860f222149e1e6314171737fee23537a1e7f0c" + "0xf87481d508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ca3b82995153488b2656d69748718e5bb3abd10a0a07eae71aefd59e673c777592dc069c9500c2c9cbef7d64fada0a7f34516c5b29aa048780b89098362f47f20ebeb192901c96db681450badc981a2e3fe0266bad08d" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9cb8a0d41ede6b951c29182422db215e22aedfa1a3549cd27b960a768f6ed522" + "0xff8f6f17c0f6d208d27dd8b9147586037086b70baf4f70c3629e73f8f053d34f", + [] ] }, { "jsonrpc": "2.0", "id": "np233", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4ff6fbd3afcc33972501397c65fe211d7f0bf85a3bde8b31e4b6836375d09098", + "parentHash": "0x5e06576f385d64e5475da19a55db8a1b49a905e54cdd00bc833f9a6e0d1821de", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbf1db5dc400fd491fad1abd61287f081ebd7398c76f20ecc0a6c9afb30ba5508", - "receiptsRoot": "0xed257fe243a1ffa922e5a62e40ffb504d403afc1d870fdcacd7f0aaf714e9ca1", - "logsBloom": "0x200000000000000000000000000000000000000000000000000009000000800000000000104010000000000000000000000000000000000000000100000000080008000000000000000000800000000000000000000000000008000000000000400000000000004040000000000000000000002000000000080004010000000000000000100000000000000000000040000000000000000000000080010000000000000002000000020c0000000000000000000000000000000000000000000000000000000000000000000000000000080000000080000000000000000000000000400080000000400000000000080000000000000000000000000000000000", + "stateRoot": "0x21f8e87041249c1ba465194c8b715ef58ec364a0b6018f13d524156bd563f74d", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xe9", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x91a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf1364f41ffcf3f76e045b1634e4f62db38f5c053edfa7d0a13d87299896ddff9", + "blockHash": "0xcdf017d14aa10cc174c1f3f7d597eb085f52da7793e92fd8f84f0032009962df", "transactions": [ - "0xf87981bb0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0ef0e59c1798c0a7645f75f893cf81eae4aff9f49159b7365b8d4e907367f91f6a0095a58cb4d8be1816acf8b4e11f9d9b2a03d3f392eee1f19bea70b50ed151584" + "0x02f86a870c72dd9d5e883e81d60108825208944dde844b71bcdf95512fb4dc94e84fb67b512ed80180c001a09f04acf081827c526e799759177320566ce80aeb5f40c64bb24fe9636c8de9c2a007126608b53aa815dd075c43c20ff4f8da9bab03923fe2c03f847260ea95617e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2510f8256a020f4735e2be224e3bc3e8c14e56f7588315f069630fe24ce2fa26" + "0x70bccc358ad584aacb115076c8aded45961f41920ffedf69ffa0483e0e91fa52", + [] ] }, { "jsonrpc": "2.0", "id": "np234", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf1364f41ffcf3f76e045b1634e4f62db38f5c053edfa7d0a13d87299896ddff9", + "parentHash": "0xcdf017d14aa10cc174c1f3f7d597eb085f52da7793e92fd8f84f0032009962df", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5b75a7bfd5eb4c649cb36b69c5ccf86fecb002188d9e0f36c0fdbc8a160e4ac6", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x1b33f7de0c2d5985d1b09d684947d984700f244819f685a91cb0cc45ee4724a1", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xea", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x924", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa2474d57b356b865a29ccfb79623d9a34ed84db9f056da5dd4e963f816baa180", + "blockHash": "0xd85b3616680a40d04d64e6ee0d1b0dfbf1967634ca82b0a38be88513a556fce6", "transactions": [ - "0xf86481bc088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a078dfab2121885d4181d63c7088757f7feb65131b155ad74541de35c055c31ec3a005cccd843ec8a535a567451c3b5034e05bac10f9328c63aa0b4893ee4f910ba2" + "0x01f869870c72dd9d5e883e81d708825208940c2c51a0990aee1d73c1228de1586883415575080180c080a0b74bdf8180bf53defa1de1178eab5ee3390868af0c625f4cd9c5e90703326318a03e4b8d27029ff92f18b8c5c9a11edf7a4656513af34736fc8d518ba7b793716e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2d3deb2385a2d230512707ece0bc6098ea788e3d5debb3911abe9a710dd332ea" + "0xe3881eba45a97335a6d450cc37e7f82b81d297c111569e38b6ba0c5fb0ae5d71", + [] ] }, { "jsonrpc": "2.0", "id": "np235", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa2474d57b356b865a29ccfb79623d9a34ed84db9f056da5dd4e963f816baa180", + "parentHash": "0xd85b3616680a40d04d64e6ee0d1b0dfbf1967634ca82b0a38be88513a556fce6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3f130c3409ad205204d14e6b5be4ccf2e65559d39cc98dfc265e1436990e5964", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x35abc62183846924a22493fc22e165f8cc0b1a6d6cc11ec9150956b8b671a995", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xeb", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x92e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9a195498e43997a5769957e54f0fa6f56d8442e54f8a26efafbf89130446fd4d", + "blockHash": "0xaeb7dd5da8baa32aeb4a33f9d87914815fa0c941f5bc08e595d4e37bfdae7025", "transactions": [ - "0x02f86a870c72dd9d5e883e81bd010882520894f8d20e598df20877e4d826246fc31ffb4615cbc00180c001a0c982933a25dd67a6d0b714f50be154f841a72970b3ed52d0d12c143e6a273350a07a9635960c75551def5d050beee4014e4fef2353c39d300e649c199eebc8fd5e" + "0xf86781d808825208945f552da00dfb4d3749d9e62dcee3c918855a86a001808718e5bb3abd10a0a077b27af56bab269e10d8c4120c827ea8a6e267e410dcc43f940ccb21aaf725aca055f4af3cb45acc78c5dd2ee9025229ea3c52dd746f032ca0f6e892ee1bb7aa39" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x1cec4b230f3bccfff7ca197c4a35cb5b95ff7785d064be3628235971b7aff27c" + "0x2217beb48c71769d8bf9caaac2858237552fd68cd4ddefb66d04551e7beaa176", + [] ] }, { "jsonrpc": "2.0", "id": "np236", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9a195498e43997a5769957e54f0fa6f56d8442e54f8a26efafbf89130446fd4d", + "parentHash": "0xaeb7dd5da8baa32aeb4a33f9d87914815fa0c941f5bc08e595d4e37bfdae7025", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1ad56a036d6b544ee8f96f2d3e72dfdb360fa3c81edef33dd9e9fc1779d174a4", + "stateRoot": "0xae24678714258a0678a642f2019faee2b2a60be135f63c7216c65f266ffaa8d8", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xec", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", "timestamp": "0x938", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xca48eaf8da077241a7938435cf1576b2628c65afea7b1aa2665c74573e352205", + "blockHash": "0xd522a23cf0118178de9b0c94528f7161fa5f0e0c954ff141d86f7335fbed4276", "transactions": [], "withdrawals": [ { - "index": "0x1f", + "index": "0x14", "validatorIndex": "0x5", - "address": "0x45f83d17e10b34fca01eb8f4454dac34a777d940", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", "amount": "0x64" } ], @@ -5082,1704 +7467,1739 @@ "excessBlobGas": "0x0" }, [], - "0x18e4a4238d43929180c7a626ae6f8c87a88d723b661549f2f76ff51726833598" + "0x06b56638d2545a02757e7f268b25a0cd3bce792fcb1e88da21b0cc21883b9720", + [] ] }, { "jsonrpc": "2.0", "id": "np237", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xca48eaf8da077241a7938435cf1576b2628c65afea7b1aa2665c74573e352205", + "parentHash": "0xd522a23cf0118178de9b0c94528f7161fa5f0e0c954ff141d86f7335fbed4276", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf43c19d64439e20deb920de4efbb248d44d4f43d0dfecd11350501bc1a4bf240", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x98514467ea14630203e7f8752b2861b363ad510a1795389c5257082298d0c6f3", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xed", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x942", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd6a5ae0ebd55680da60432b756f7914f8fb8bbcead368348e3b7f07c8cfa501e", + "blockHash": "0xc24d834bba0307acaf2621819d979f535f972358a557d008cdd4374d6d7279e4", "transactions": [ - "0xf88281be08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa06ba7d56fdfaf77a1a66bfef9529419b73d68fc1aa9edef961ac3a8898f04e5caa054635ee7b91858d97e66944311c81fd4f57d328ee4fbdf8ce730633909a75f01" + "0xf88281d9088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0675450801a9ff0ba52e0d0c6a9919e99ee02fbcc1f777c783a3a1f458e376ecea0114e5fe0b93d270f3d78915b9fb62e9f640b7024db11cfa38e879ccbff473605" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x700e1755641a437c8dc888df24a5d80f80f9eaa0d17ddab17db4eb364432a1f5" + "0xebdc8c9e2a85a1fb6582ca30616a685ec8ec25e9c020a65a85671e8b9dacc6eb", + [] ] }, { "jsonrpc": "2.0", "id": "np238", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd6a5ae0ebd55680da60432b756f7914f8fb8bbcead368348e3b7f07c8cfa501e", + "parentHash": "0xc24d834bba0307acaf2621819d979f535f972358a557d008cdd4374d6d7279e4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x05a62e01803a967ff89e7e9febf8d50b1b3092aab5580c7f85f465e7d70fef3f", - "receiptsRoot": "0x294eca38bb21bd8afeb2e5f59d0d4625058d237e2109428dfb41b97138478318", - "logsBloom": "0x00000040000000001000000000008000000000000000200000000000000000000000008000000000000000020000000040000000000000000000000004000000000000000000800000000000000000000000000000000080000000000000001000000000400000000400000000000000000000000000000000000000000000000880000000000400002000000040000000000000000000000000000810000100000080000080000000000000080000000000000001000000000000000000000000000000080000002000000000000010000000000000000010000000000000002000000000800000000400000000000000000000080000000000000000000000", + "stateRoot": "0x7e34cffa4512765540682e386ccecb352c2939095d4c0705a98e87ce3c50b9da", + "receiptsRoot": "0x0982027ef8748748f3f43f93d29f704d942455b23d272ef229e30020ec561a98", + "logsBloom": "0x00000040000000001000000000008000000000000000200000200000000000000000008000000000000000020000000040000000000000000002000004000000000000000000000000000000000000000000000000000080000000000000001000000000000000000400000000000000000000000000000000000000000000000880000000000400002000000040000000000400000000000000000810000100000000000080000000000000080000000000000001000000000000000000000000000000080000002000000000000010000000000000000010000000000000002000000000800000000400000000000000000000080000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xee", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", "timestamp": "0x94c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x06466f86e40c982578b247579fa1fa5773d6169e77a79a625950c4aa16ce88b1", + "blockHash": "0xbc7ccdf6cbccc29bfcb63055c8f06b26648f3b719434b29a74a477466fefaa5e", "transactions": [ - "0xf87981bf0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0548377761079f73162f83bdc2cfb09dcde9e08c8db66d4d983f1856c5145fe6fa06b2bd1223fbb1b72016150f57bc7ae1f8cce5c0fd301bb9216bb804c89bf0a97" + "0xf87981da0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0d59a28faa98ddfa84972f7929fbec44330a628fb5bef71f778cebfd935bcaee3a02cd31b98758b8b921a23dc0e8499be4f6ea77c1ebbe2bf67957b699af942e6c5" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xcad29ceb73b2f3c90d864a2c27a464b36b980458e2d8c4c7f32f70afad707312" + "0x738f3edb9d8d273aac79f95f3877fd885e1db732e86115fa3d0da18e6c89e9cf", + [] ] }, { "jsonrpc": "2.0", "id": "np239", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x06466f86e40c982578b247579fa1fa5773d6169e77a79a625950c4aa16ce88b1", + "parentHash": "0xbc7ccdf6cbccc29bfcb63055c8f06b26648f3b719434b29a74a477466fefaa5e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbca1fef6bcfcbb170b7b349f92a3b92fe03296dac1fd64ccda295c496a261a16", + "stateRoot": "0xbc99bcc1d52e9f4766e23368257dc9c64781b15b59232171c60c4115dce203d4", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xef", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", "timestamp": "0x956", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x74b00e695ebf3210bda9ad8b3aa1523475d922fd556e551cfd606ebcf807d681", + "blockHash": "0x84f81fe1c154c744c26786ae33b6ace4bc6e4e9318fd57b03a61e9d18ca64711", "transactions": [ - "0xf86481c0088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa08cfe044eb5748d538f72e560c45c7a01f94f4b7c6e9b1245bade89c0d97f9932a02b21fe651e5fb05d1f8de320dcf8cc037b2c0e989793f6b445f397c77f42a4f0" + "0xf86481db088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0c22c5f39061382a2ef0994d92c08dfcb184e64bbda5c809b7e9105ead307a742a053e1ea72ec9869938790b2d96b105f7b39db6b423cf370074474e16385b45f5c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa85e892063a7fd41d37142ae38037967eb047436c727fcf0bad813d316efe09f" + "0xae5ccfc8201288b0c5981cdb60e16bc832ac92edc51149bfe40ff4a935a0c13a", + [] ] }, { "jsonrpc": "2.0", "id": "np240", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x74b00e695ebf3210bda9ad8b3aa1523475d922fd556e551cfd606ebcf807d681", + "parentHash": "0x84f81fe1c154c744c26786ae33b6ace4bc6e4e9318fd57b03a61e9d18ca64711", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x82a80ad266f2a1539a79b2dcf8827aabedcc1deeb6cfb4869a8ed2ea26923726", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x7a68d970418201b546fd51691c989867e1c29978eea373e2375bb60b385ce4a9", + "receiptsRoot": "0x627ec21f4de1c579315e005c05b00e19d0186ecbc6377fb85a68878fe8079cd5", + "logsBloom": "0x00000020000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000020200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x960", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd908ab400c351cee493619c9b0b56c6ae4d90bd6e995e59ac9302a7b20c13fc3", + "blockHash": "0xca2b42e197de583b704164d6db489ec43fe7394d38dd8a5752be70f52854ca58", "transactions": [ - "0xf86781c10882520894fde502858306c235a3121e42326b53228b7ef46901808718e5bb3abd10a0a03d79397e88a64f6c2ca58b5ec7ba305012e619331946e60d6ab7c40e84bf1a34a04278773d2796a0944f6bedadea3794b7ad6a18ffd01496aabf597d4a7cf75e17" + "0x02f8d3870c72dd9d5e883e81dc0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cd9b3346dfd0e60ce656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a044dc9099d91b074b843002013672df4de9f691cf60546fa74eccafa9044a75a280a08e839541f45f093117f75e17bb6c5d90e060d95d635df5e508df75ae4ea15d02a04a37a82b8fb0d5c28bd196c2dff563b98943f4c294be797f927a9f20c4f93eb6" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x040100f17208bcbd9456c62d98846859f7a5efa0e45a5b3a6f0b763b9c700fec" + "0x69a7a19c159c0534e50a98e460707c6c280e7e355fb97cf2b5e0fd56c45a0a97", + [] ] }, { "jsonrpc": "2.0", "id": "np241", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd908ab400c351cee493619c9b0b56c6ae4d90bd6e995e59ac9302a7b20c13fc3", + "parentHash": "0xca2b42e197de583b704164d6db489ec43fe7394d38dd8a5752be70f52854ca58", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x59b60dbf89d7c0e705c1e05f6d861bfb38bec347663df6063be9eb020e49972a", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x9693fa6d1b00303f873a8ad1471a142a790f8b6306e0f1ca9e3f3cdc799f5f33", + "receiptsRoot": "0x776bbccca0cbbdb94db3be7cbb0d3ed277ade8c66c9e4f0cd3b5375ef26cb454", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000080000000000000000400000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x96a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x13fdff4106d52399ab52ee5d1e6a03097f6db6de8066597f88be7a797a183cb7", - "transactions": [], - "withdrawals": [ - { - "index": "0x20", - "validatorIndex": "0x5", - "address": "0xd4f09e5c5af99a24c7e304ca7997d26cb0090169", - "amount": "0x64" - } + "blockHash": "0xa09abb195168c21894826ccd65fa0c8549eb923a5b399c62cf9fd1011c465b69", + "transactions": [ + "0x01f8d2870c72dd9d5e883e81dd08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c420286a1fdfc0e5e656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a040c619388e6393f420e805451bd48b10c670de7d51e916a3ffe5ac3c96b8193880a095c62361aa8837bc1855c305ba620d2626ab06fa3c0f9e53e15a2514a9107b51a0338b0de9a2eae1aa2a4ab316146123ec3c5c186cfca763aec26070ce1b9fccb5" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x49d54a5147de1f5208c509b194af6d64b509398e4f255c20315131e921f7bd04" + "0x4d2a1e9207a1466593e5903c5481a579e38e247afe5e80bd41d629ac3342e6a4", + [] ] }, { "jsonrpc": "2.0", "id": "np242", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x13fdff4106d52399ab52ee5d1e6a03097f6db6de8066597f88be7a797a183cb7", + "parentHash": "0xa09abb195168c21894826ccd65fa0c8549eb923a5b399c62cf9fd1011c465b69", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1e5d7390e70d057c7dc29e173e338e7285e276a108eaecf3164dc734ce2fd9b5", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x8eebf0393ed59ddc4859f5692ade88d664163044283c2fccf142ea9ae3506833", + "receiptsRoot": "0xf3febfa0beb41ed1c3b2dde301a1af4a1900ac13bc37322396ba28a3a0809745", + "logsBloom": "0x00000000000000000000000000000000000000000000000000002000800000000000000000000000000000000000000000000000000000000000000020000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x974", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9cfff0339ca5c7928180f0d37f080f2c8cc4c00bfa2b6be3754b9d228219779f", + "blockHash": "0xb4020e4b07dcf86bae80b8743a2ea666f6f3d45a5df2284109c25d7f51609ec5", "transactions": [ - "0xf88281c208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0057b9bf7b2b99c50cf16c0b995e2846ba833edc03f6efc1b97566022651cabeca0237b38f74a2a8c39a2c344ef2d7fe811c37cd20ed2f4d47bfc38d896f3c9db75" + "0x03f8f9870c72dd9d5e883e81de0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c7071be300963ff92656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0e8a78860d5ffde377f4eb0849fe59ed491d4a12fd51edebc2bceab3549d8346383020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a04f7d0bf8f16c7a0e75ce26ac545d0d575ff7f413e2a16e5027afb8a5c4b7f26fa063e8202466a1dfe963f6db436894e47e6eb7e0098800e35cfc1d5254af2077eb" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x810ff6fcafb9373a4df3e91ab1ca64a2955c9e42ad8af964f829e38e0ea4ee20" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xd3e7d679c0d232629818cbb94251c24797ce36dd2a45dbe8c77a6a345231c3b3", + [] ] }, { "jsonrpc": "2.0", "id": "np243", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9cfff0339ca5c7928180f0d37f080f2c8cc4c00bfa2b6be3754b9d228219779f", + "parentHash": "0xb4020e4b07dcf86bae80b8743a2ea666f6f3d45a5df2284109c25d7f51609ec5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8725e2687d45a52ad320e82b90e009b1aa5effe7ebfe994116afa25daa09468f", - "receiptsRoot": "0x2f9d61b38064fb9da0bb0f93ff73e1021c62ba761714e96a6674cd927bde4f9c", - "logsBloom": "0x00000000000800000000000000000000001000000000000000000000000000010000000000000000000000000000000000000000000000040000000000000000000000000010000000008000400000000000600000000000000000000800000140000000000080000000000000000000000200000000000000000000000000000000000000000180000000000000000000000000000000000000000000001000000000000000000100020000000000000001020000000000000080000000000000080000000000000000040000000000000000000000000000024080200000000000000000040000000208000000000000010000000000000000001000000000", + "stateRoot": "0xa268f440925802a0673a23ed9f85bbc06c22f5d2500ce472b384aea395f774d4", + "receiptsRoot": "0xd7f23872614f396dbd94d6ba150b6ef7539f1428c8df485d79def87a8a0785cb", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000400000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf3", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x97e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x0c71dc4665ac65f63a44434a3d55ffc285af6ec8b90b4ddfd4b4001add0e93c0", + "blockHash": "0x787fcaaf148ba19e63da9cd7d513303b2e8565baf64c4c28680996276e57c93c", "transactions": [ - "0xf87981c30883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa017b61104ac6d28f1262b3750475b328dfd50f8496e0772bf19047d9d1ee9e56da01aed9f9280926e68fb66065edcf80320cab6f6d7c7af4bc8d9d007e1ea6a168d" + "0xf87481df08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c3389deedf755957b656d69748718e5bb3abd109fa01e50b3cb9c04e70ceb18374d66620c5441f9e5f23971bbf4e0176d9a973b1137a05b14a56ab599e3f1344627bf3387e3ab72c6d4e34bdfae32c7ad88ee018969ec" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9b72096b8b672ac6ff5362c56f5d06446d1693c5d2daa94a30755aa636320e78" + "0xd1835b94166e1856dddb6eaa1cfdcc6979193f2ff4541ab274738bd48072899c", + [] ] }, { "jsonrpc": "2.0", "id": "np244", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x0c71dc4665ac65f63a44434a3d55ffc285af6ec8b90b4ddfd4b4001add0e93c0", + "parentHash": "0x787fcaaf148ba19e63da9cd7d513303b2e8565baf64c4c28680996276e57c93c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc5f9b1665244a32dc0885794d5aaf3ce0b464eed1208412ca14abcfe4b908f64", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x8940dfd9f8d3951b612ad8d6210ccf787fc72c21129453cda59091cec9e42459", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x988", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1f7b85304f578a197b65ce6f6f9e0c90cf680cdb3f35a95d10ea0a32238df606", + "blockHash": "0x9d81061f02d7bf9a3a57e1b2b291bbe6100fdd34168fcc324a3e4c360168a058", "transactions": [ - "0xf86481c4088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0a93d446ef64bccf6c88d5285e78e7625fd5c9ac9c8aa11ad45db01b95b6694a5a0761620f10b11ee3cc1932adf95133349f5107aed7b8c150192fa89665ecd7552" + "0x02f86a870c72dd9d5e883e81e001088252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c001a03cb7b4f18d670562fe957a5f6ce00c3f4f472eb49b06bcdeb554183884eba2cfa017e043c09ffbab9304b2f96729fbeb6ffca00aab56a5bc5b27854eebc9642635" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf68bff777db51db5f29afc4afe38bd1bf5cdec29caa0dc52535b529e6d99b742" + "0x1f12c89436a94d427a69bca5a080edc328bd2424896f3f37223186b440deb45e", + [] ] }, { "jsonrpc": "2.0", "id": "np245", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1f7b85304f578a197b65ce6f6f9e0c90cf680cdb3f35a95d10ea0a32238df606", + "parentHash": "0x9d81061f02d7bf9a3a57e1b2b291bbe6100fdd34168fcc324a3e4c360168a058", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5bacfe50ff7f0200bc1a4ea28e3fbe1a269ea7cbdbe7fb5d83bde19774c92e7e", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x1216a69e570307973e76a594d89cda1e9e79f8d357d46aca9cba98aaaf0f3009", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf5", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x992", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8f3a666d3d090603513d1e31ac73c5b47a7fe8279c7359a3bad523a8fd414a96", + "blockHash": "0x111ebb07018c6d7bf8df23b0454405dd991d7f8407d7c14f8bb86a0bd78032ac", "transactions": [ - "0x02f86a870c72dd9d5e883e81c501088252089427abdeddfe8503496adeb623466caa47da5f63ab0180c001a0deade75f98612138653ca1c81d8cc74eeda3e46ecf43c1f8fde86428a990ae25a065f40f1aaf4d29268956348b7cc7fa054133ccb1522a045873cb43a9ffa25283" + "0x01f869870c72dd9d5e883e81e108825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df0180c080a09310fb7d3a437d4c9463094aaf7375a66a58cd9577c736f75bba7330f7fe4113a0145d516d95878524a261a4c34a9c4f0256f7701db03e6f4c5dd900306719fdb2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9566690bde717eec59f828a2dba90988fa268a98ed224f8bc02b77bce10443c4" + "0xccb765890b7107fd98056a257381b6b1d10a83474bbf1bdf8e6b0b8eb9cef2a9", + [] ] }, { "jsonrpc": "2.0", "id": "np246", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8f3a666d3d090603513d1e31ac73c5b47a7fe8279c7359a3bad523a8fd414a96", + "parentHash": "0x111ebb07018c6d7bf8df23b0454405dd991d7f8407d7c14f8bb86a0bd78032ac", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1c407d215d7fa96b64c583107e028bcf1e789783c39c37482326b4d4dd522e05", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xad350a4099570877c1704f074b19c5f3dcea56dca6c9e792016e2a56b379ee52", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x99c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf1191b23680ae545b3ad4ffb3fd05209a7adefefc71e30970d1a4c72c383b5df", - "transactions": [], - "withdrawals": [ - { - "index": "0x21", - "validatorIndex": "0x5", - "address": "0xb0b2988b6bbe724bacda5e9e524736de0bc7dae4", - "amount": "0x64" - } + "blockHash": "0xf0fff4c5758d8f5bc9e659c933b0267500c3dcd25916df0c0cd11f51a80057e4", + "transactions": [ + "0xf86781e208825208944dde844b71bcdf95512fb4dc94e84fb67b512ed801808718e5bb3abd10a0a0c74c4a0d4a72241c9d5837ddc4891eedc641596acc6d6b63ce03d98a10ac501aa0599e554c304a4d88ac4be7aa118b76dcc057fcbf2c4652ba0095f954f61e710a" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd0e821fbd57a4d382edd638b5c1e6deefb81352d41aa97da52db13f330e03097" + "0x8bbf4e534dbf4580edc5a973194a725b7283f7b9fbb7d7d8deb386aaceebfa84", + [] ] }, { "jsonrpc": "2.0", "id": "np247", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf1191b23680ae545b3ad4ffb3fd05209a7adefefc71e30970d1a4c72c383b5df", + "parentHash": "0xf0fff4c5758d8f5bc9e659c933b0267500c3dcd25916df0c0cd11f51a80057e4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x16a2c4f318277ea20b75f32c7c986673d92c14098e36dde553e451f131c21a66", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xc27bc2d5cb669f6c51c6a5ff47e1c7636846e82c3a3ef76be73cdbf01577b022", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf7", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x9a6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x2e34605bbfd5f548e1e9003c8d573e41a9286968bec837ba1f2b7780e3337288", - "transactions": [ - "0xf88281c608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa02648ce9c5825b33559225aada97c08de484ab8282549d90cfc1e086052c22be8a02054d7eeb1e8bf4ab25b2581ccb0b0a3500625cf7a0315860202eb2eaf094f9c" + "blockHash": "0x4063e7bd93501354cbef2184f7139559650a22eeca85d60bd62f4a468f2bd22c", + "transactions": [], + "withdrawals": [ + { + "index": "0x15", + "validatorIndex": "0x5", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x43f9aa6fa63739abec56c4604874523ac6dabfcc08bb283195072aeb29d38dfe" + "0x85a0516088f78d837352dcf12547ee3c598dda398e78a9f4d95acfbef19f5e19", + [] ] }, { "jsonrpc": "2.0", "id": "np248", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2e34605bbfd5f548e1e9003c8d573e41a9286968bec837ba1f2b7780e3337288", + "parentHash": "0x4063e7bd93501354cbef2184f7139559650a22eeca85d60bd62f4a468f2bd22c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x291c5ca9a114bdb7bf296b4ff4182b930dc869905eaa1219cbb5188e8feaa9ab", - "receiptsRoot": "0x9f35106348d01548df28e681773a27cffe40648e4d923974e4b87903f578da11", - "logsBloom": "0x00000001000000000000000800000000000000000000000000000000100000000000000200080000000000080001000000000000000000000000000001000000000202000000000000000000000000000002000002000000000000040000000000000000000000000200800000000000800002000000000000000000008000000000000000000000000400008000000000008000000000000000000002000000000000000000000010000000000000000000000000000000000000100000000000000000000000000000000181000000800000000000000000000000002000200000000000000000000000000280000000000000000000000000040000000000", + "stateRoot": "0x0991eed72783cbb17cb6cdbc85373e808feeb2134a1663c7b7356514635f4b9e", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf8", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x9b0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x22d7e31bcd496b70c0256f88d985be54cd46604897969a5edde95d8d75e2fc6a", + "blockHash": "0x161049c951eaacfafd5b046be03ee813c9a9a6d3167fe4591f75673f0ff5097a", "transactions": [ - "0xf87981c70883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a09f49a6018e3736ea3599def5663a57cfe19cb3f27bfdd80657503262a5bcfc87a02a26782058025cfe1205be964cc9ac31cdf510a8a9f867bff2317275b13ed02c" + "0xf88281e3088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a018eea4cbb63e21a12b7091ab411cbfe92334a0cce67c4cb3d8e33e7c7d442ed9a07dc5c68241d131de386967a2cf4da3e73d483574b0fe5f3989423fb9ba522cb0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x54ebfa924e887a63d643a8277c3394317de0e02e63651b58b6eb0e90df8a20cd" + "0x0f669bc7780e2e5719f9c05872a112f6511e7f189a8649cda5d8dda88d6b8ac3", + [] ] }, { "jsonrpc": "2.0", "id": "np249", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x22d7e31bcd496b70c0256f88d985be54cd46604897969a5edde95d8d75e2fc6a", + "parentHash": "0x161049c951eaacfafd5b046be03ee813c9a9a6d3167fe4591f75673f0ff5097a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x359fe6cc7b7596b4455fdc075bc490d3697d4366c39c40dd6fc935da0ceac7e7", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x14b379a9fd456004e3447097b74c17d5142fa544a85caee69bd3f06e143746ad", + "receiptsRoot": "0xf4c9c04b70aac8e92168f4194367a03efb812d78ea2c1b88ff85f330e155d270", + "logsBloom": "0x04000000000000000000000000000000000000000000000008000000800800000000000000000001000000000000000000000000000000018000000000000000000200000000000200000000000200000000000800000000000080000000000000200000000000000000000000000000000000000000000000000000000000002080040000000110000000000000200000000000200004800000000000000008000000000200000000000000000000000000000020000000800000000000000000000000000000000000000040400000000000000000000000000000020000000000000000000000000000200000000000000000000000000000000000000040", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xf9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x9ba", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1767170da9f173007588517f005241a12087642444518ce31bcf3ad27de4efcf", + "blockHash": "0xf10eb78649d3c7dccd8a00576e460bed3eedf5e1e9b94e96cd2cdcf11c4171e7", "transactions": [ - "0xf86481c8088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa043e1ad9aa519d9a1e8a15918ee6bbc0fd98061db6058597bd984098600495f96a01d5edd1b3fc3b45ff2a17a9c7eee3ad4c75e24fc090a4a0e48f39da49e7ad263" + "0xf87981e40883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0401981fa89684c53c54fa7cac07db4b9adaa4fab50210204ce297bbd3893456aa055c506967e336b46424dd6adc093947469947f517a4101251f4dee49584f404a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9e414c994ee35162d3b718c47f8435edc2c93394a378cb41037b671366791fc8" + "0xa7816288f9712fcab6a2b6fbd0b941b8f48c2acb635580ed80c27bed7e840a57", + [] ] }, { "jsonrpc": "2.0", "id": "np250", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1767170da9f173007588517f005241a12087642444518ce31bcf3ad27de4efcf", + "parentHash": "0xf10eb78649d3c7dccd8a00576e460bed3eedf5e1e9b94e96cd2cdcf11c4171e7", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc73008737d0cfdbec09b3074d48f44e406f0598003eab9a1f4c733de38512855", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x51e359714f3797b19f69d62e42532edc6e1a77905de51d5f71cb791a02fcaba7", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xfa", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x9c4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x163dc4f5b453d5fb626263184121f08cdb616a75e2f8ef978d38e91f5b995ee6", + "blockHash": "0x9d9c2b94a73067a8ba8736b77b159187bad6ce53b4372d3d0d0aa534aae1d7bd", "transactions": [ - "0xf86781c90882520894aa7225e7d5b0a2552bbb58880b3ec00c286995b801808718e5bb3abd109fa00968ae76ffc10f7b50ca349156119aaf1d81a8772683d1c3ed005147f4682694a060f5f10a015e8685a3099140c2cc3ba0dc69026df97fb46748008c08978d162a" + "0xf86481e5088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0bd39af3df2a11f6261e939824dabf6a9e71a3a2c8c1bb063500678af676108e5a009b9c69c3a0de121dcc763befe353b95f0eba94610f3787372819b5ab152f9e1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4356f072bb235238abefb3330465814821097327842b6e0dc4a0ef95680c4d34" + "0xda5168c8c83ac67dfc2772af49d689f11974e960dee4c4351bac637db1a39e82", + [] ] }, { "jsonrpc": "2.0", "id": "np251", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x163dc4f5b453d5fb626263184121f08cdb616a75e2f8ef978d38e91f5b995ee6", + "parentHash": "0x9d9c2b94a73067a8ba8736b77b159187bad6ce53b4372d3d0d0aa534aae1d7bd", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x693db83454936d0dacd29b34de3d2c49dc469bbe4337faec428b028e0d967642", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xb73d161455722e25876b549dd5e50384c3d558b9c41a6d212c27ab93f00e073d", + "receiptsRoot": "0x6195d7c85c340ae69791a06465e39d5a202cb53bfb9950da9be615af1fa1c49f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000804000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000800000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xfb", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x9ce", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8f9b318e4cd81ddd537dff3fcfe099d3609b357f3a4f2aed390edc103a5aa7a6", - "transactions": [], - "withdrawals": [ - { - "index": "0x22", - "validatorIndex": "0x5", - "address": "0x04b8d34e20e604cadb04b9db8f6778c35f45a2d2", - "amount": "0x64" - } + "blockHash": "0xa4b169ebb5479f117266df73694d46f704685c3d756d411dcb5fc0b15f500f47", + "transactions": [ + "0x02f8d3870c72dd9d5e883e81e60108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cf88292cc89bf0c81656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a01bf804b21bbd284f3f59e4862747fabb1d91cd202d99df811fbcd650c8916ef101a07a6aa4a316190d2d4190f770ddb893b1460e70fbd3650250387cea8bb5d252cea075c4ad6724b9fd04714eacc8a9fcf101cb4c379177c4903e610d15d80ad1c58f" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x215df775ab368f17ed3f42058861768a3fba25e8d832a00b88559ca5078b8fbc" + "0x3f720ecec02446f1af948de4eb0f54775562f2d615726375c377114515ac545b", + [] ] }, { "jsonrpc": "2.0", "id": "np252", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8f9b318e4cd81ddd537dff3fcfe099d3609b357f3a4f2aed390edc103a5aa7a6", + "parentHash": "0xa4b169ebb5479f117266df73694d46f704685c3d756d411dcb5fc0b15f500f47", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd358fe0baedc04a81fdaf6cdfc71c2c874291e47d16dd51cc032f0678078a009", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x7af673b579848cf739d0977946fbd5e08ece6e8d39f46aaa4092adca0297131b", + "receiptsRoot": "0x90f07e67f04ced23fa47da5ee86634d02744163e2a0c9345a2892e2ac573f8b9", + "logsBloom": "0x00000000000000000000000000000000000000000000000000100000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xfc", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x9d8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x23a585160ac1b5428ad1dea7e732b641ace396c4135dbf899ab2559f869bb5fb", + "blockHash": "0x205a14b20d2c13f174859295063f88da3779c22b3cd8cf8d3718cf014f8c0af9", "transactions": [ - "0xf88281ca08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0941941ac43420c855cda955414a23d3bad4d0f2bfbeda999250f2f87d228878da0357223781ec5d666a8d5e8088721e9952f00a762d5fc078133bea6bc657c947e" + "0x01f8d2870c72dd9d5e883e81e708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c9a60100c3b84dcd2656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a22721490cd06a0e77bc2b085bb4d57e7e5e0b459a2afc65ec4697d51926e1b801a0bdda6e7c6e57e00f3a00b472b4a480c2c87440d4b19e5e5482a08fdb666378bea00a82355c7bac100d5dc94f6b76c352b07c531e7cf98d746e089624ee6176d086" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd17835a18d61605a04d2e50c4f023966a47036e5c59356a0463db90a76f06e3e" + "0x273830a0087f6cef0fdb42179aa1c6c8c19f7bc83c3dc7aa1a56e4e05ca473ea", + [] ] }, { "jsonrpc": "2.0", "id": "np253", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x23a585160ac1b5428ad1dea7e732b641ace396c4135dbf899ab2559f869bb5fb", + "parentHash": "0x205a14b20d2c13f174859295063f88da3779c22b3cd8cf8d3718cf014f8c0af9", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xcb19946b2b5a905882151fff9a12cce6e4c3be46f7da6b67263b0cc781fbe80a", - "receiptsRoot": "0x9b15dea2f021c6c74dc60deea77fd6a1ce29c9efc2596cbaaf73ef60370a03e3", - "logsBloom": "0x0000000000000100800000000000000000800000000000010000000000000000000000000000000000000000000080000000000000000000000000400000000000002000000000000000000000000000000000000000000000000000100008000000000000000000000000000000000020000000000000a004200000000000800000000000000000000000000000100000000000000000000000000440000000000000001001000010000000010000004000000000000000000000200000000000000000000000000000000000000000000400000000000000000000000200000000000000000440000000000120000c00000001000000000000000000000000", + "stateRoot": "0xda95fcdaffc081ecc6ee8aeb8fc0c34af8d264d206679f8117abcf4ac790aded", + "receiptsRoot": "0xb88d784bbfd12192ec4b0785299fc73c6a5520012b7dc507f6c10f550dc6c11b", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000100000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000001000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xfd", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x9e2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x706168d939a58a0dd048595d1c88fe1735dbeee42111dfbb2adee0ea9ef1d77b", + "blockHash": "0x68ee7090901b0083e417d17e1e9eb637b50146077b32d5f3b63568a738220c98", "transactions": [ - "0xf87981cb0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa06fb97cf9fb9b8f7159a9dc549e412001ca969f0dafc3c9294b0e081741aa3d9aa003ed12873ddb354ccf7b0f8e511136ff335a8e4ff6bb7f93ce19e097970c9774" + "0x03f8f9870c72dd9d5e883e81e80108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c77a74f070310737f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a09138868b39f601dde19efa6e9a154230a51805e9a6cabaf28fed5163aea5832883020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0357ca9f0031cc59e4be7c4b351da952e631b306646cfa1a0d24a1f9d54392e39a064bad8e978674e591d8b7999ef85fdabb7aea42d32310e005b695f4d98cb5d2e" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x875032d74e62dbfd73d4617754d36cd88088d1e5a7c5354bf3e0906c749e6637" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x7044f700543fd542e87e7cdb94f0126b0f6ad9488d0874a8ac903a72bade34e9", + [] ] }, { "jsonrpc": "2.0", "id": "np254", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x706168d939a58a0dd048595d1c88fe1735dbeee42111dfbb2adee0ea9ef1d77b", + "parentHash": "0x68ee7090901b0083e417d17e1e9eb637b50146077b32d5f3b63568a738220c98", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x907ae262cf7f9a93ecd0d1522c6a093ffe39594b65ec185c5059dfa7b3394371", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x086b21523f79b6a1d0bcd4d46a705a225bc8019a10d832acc835ca6d325547de", + "receiptsRoot": "0xf71010c9701f748e035d4cdd1eca78bc13330e2390c1107ae5578dd636d6f6dc", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000808000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000201000000000000000001000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xfe", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x9ec", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xffd5337b506a04e2362e4a34847711bf688591ceb3ac4b7da257072ecef36a55", + "blockHash": "0x1d4e0daba7e6bdc87c5ecff530bca645bbe36a6a538e27b956c9c106607d982e", "transactions": [ - "0xf86481cc088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a082f832d1212a980978d5716dca8820344200eb6967b24adb2bd112a896b4dda3a0393b965bcf272398cdd6de788c3aa929a67a42466883a472538fb1dad06c07ef" + "0xf87481e908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c729a65bda31a91e7656d69748718e5bb3abd109fa021ff0b4ad222bba50e9623a46935ff2ccacc88cd21a12ff2bcefe083acb12188a03a105b75e0e54e676cb822a1c85854bdb35b41e517c3b2c8a917325dca037d5c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6f22ae25f70f4b03a2a2b17f370ace1f2b15d17fc7c2457824348a8f2a1eff9f" + "0xf63a7ff76bb9713bea8d47831a1510d2c8971accd22a403d5bbfaaa3dc310616", + [] ] }, { "jsonrpc": "2.0", "id": "np255", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xffd5337b506a04e2362e4a34847711bf688591ceb3ac4b7da257072ecef36a55", + "parentHash": "0x1d4e0daba7e6bdc87c5ecff530bca645bbe36a6a538e27b956c9c106607d982e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc39a9999ffd22de07bcf6a6a16b5cf1da7675dcb135e3503111a1dd50913cf0c", + "stateRoot": "0xb36ba377ca20ab99b4babb2408e48bad77df897f4bcd5e8d04a7903ab87166c7", "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0xff", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x9f6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xcbf2f33d5616ea98f1b1cf12bdd145d35b4a928e4cb8b0fa41a6bd788ca3cbd2", + "blockHash": "0xadf3ad66db1c5384657a2b75a1753887c646c629bd10a8a50d15097b79c14cbc", "transactions": [ - "0x02f86a870c72dd9d5e883e81cd010882520894a8100ae6aa1940d0b663bb31cd466142ebbdbd510180c080a054eafef27c71a73357c888f788f1936378929e1cdb226a205644dc1e2d68f32ba059af490b8ef4a4e98a282d9046655fc8818758e2af8ace2489927aaa3890fda3" + "0x02f86a870c72dd9d5e883e81ea0108825208941f4924b14f34e24159387c0a4cdbaa32f3ddb0cf0180c001a033b27b4f7423b03e6e2fadd430fa2f7e913ef796faf7e7266513fb2d93c8a77fa02420d42939972bab5a6fe4e1198f47cec08194808b4e5cf4d5cf30f9e5972e9a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf11fdf2cb985ce7472dc7c6b422c3a8bf2dfbbc6b86b15a1fa62cf9ebae8f6cf" + "0xa68dbd9898dd1589501ca3220784c44d41852ad997a270e215539d461ec090f8", + [] ] }, { "jsonrpc": "2.0", "id": "np256", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcbf2f33d5616ea98f1b1cf12bdd145d35b4a928e4cb8b0fa41a6bd788ca3cbd2", + "parentHash": "0xadf3ad66db1c5384657a2b75a1753887c646c629bd10a8a50d15097b79c14cbc", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x979018c4d3a004db4c94102d34d495dd3a4dc9c3c4bcd27d1a001f8095384208", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x97e68aafb0b19c385ac8546331867122911edc8c22a288849a8cc318082eda74", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x100", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xa00", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x01b45ed6ccf0908b2e4b513eeea6aa86514677cb6d6d06d936e1871fc422daca", - "transactions": [], - "withdrawals": [ - { - "index": "0x23", - "validatorIndex": "0x5", - "address": "0x47dc540c94ceb704a23875c11273e16bb0b8a87a", - "amount": "0x64" - } + "blockHash": "0x9ae54ebf672230a7e3ae4ef423aacf24189f52e240c1356817cb32d767618063", + "transactions": [ + "0x01f869870c72dd9d5e883e81eb088252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c001a0cc554cf1b152fa1c01e7e409f59f1e2ae8aa77511b726144f7e43136b67bcaa4a0261707e0abe087ed97585f530ffaa0b30f685ef1a20a7f063a34de1672467f17" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xbbc97696e588f80fbe0316ad430fd4146a29c19b926248febe757cd9408deddc" + "0x59e501ae3ba9e0c3adafdf0f696d2e6a358e1bec43cbe9b0258c2335dd8d764f", + [] ] }, { "jsonrpc": "2.0", "id": "np257", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x01b45ed6ccf0908b2e4b513eeea6aa86514677cb6d6d06d936e1871fc422daca", + "parentHash": "0x9ae54ebf672230a7e3ae4ef423aacf24189f52e240c1356817cb32d767618063", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x55e1fa04203cc0edebab3501d9552eaf0ac3bba421bf3480a50e1549cd479dc5", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x6a7e15a097391ede75bbf2a63347ffe9b7cb42135899d0295ff15749e00acb53", + "receiptsRoot": "0x642cd2bcdba228efb3996bf53981250d3608289522b80754c4e3c085c93c806f", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x101", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xa0a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x48f84c09e8d4bd8effd3865e8b3ac4202cb0dc0fb72299f35c8bad4558b895dc", + "blockHash": "0xed093194e152b98e10d55a8db6403780d17346e9eff9c511712725e08c422381", "transactions": [ - "0xf88281ce08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a08a7526f8f209ff44329b503a7d726f569b861894584401651a83668be3971cbfa040314bdfa618ead4fa21933ed3a8af7e814620e3befa914828b981b391096441" + "0xf86781ec0882520894eda8645ba6948855e3b3cd596bbb07596d59c60301808718e5bb3abd109fa0f9040bc146997f43cf4322ae00653a6f48de8da4718552435c5b42ca8c54e359a04f0f757fd150d6d5e9856ee6a925e5191c90aad31452327effed832c764f4349" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x71dd15be02efd9f3d5d94d0ed9b5e60a205f439bb46abe6226879e857668881e" + "0x4f19cff0003bdc03c2fee20db950f0efb323be170f0b09c491a20abcf26ecf43", + [] ] }, { "jsonrpc": "2.0", "id": "np258", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x48f84c09e8d4bd8effd3865e8b3ac4202cb0dc0fb72299f35c8bad4558b895dc", + "parentHash": "0xed093194e152b98e10d55a8db6403780d17346e9eff9c511712725e08c422381", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8d05cad792af190bb84ad7a0bebd232c433cf16b90cffea9f4f824d562ec0eb5", - "receiptsRoot": "0x7b32e50058711e6aa1981f911bb5fb6bd05182c7e7850480874c3754788e5ee2", - "logsBloom": "0x000000000000000000000000000000000400000000000000000000000200000000000000000000000000000000002000000000000040000000000000000000800000000000000000000080080000000000040000000002002000002000008000000008000100000000000400000000000000000000000000000000000000200000000000002000000000002000000000004000000000000000000000000000020000000000000000010800000001000000000000000000000000000000000000000c0000010000000000000000000000000000000000000020000000000040000000000000000000000000300000000000000000000800008000000000400000", + "stateRoot": "0x3175246abc21d105322ad9b1b3bba97d2dbae62d42054dd51b59786ae702e3f8", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x102", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xa14", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xed832bf95db43a650d06fac15b9b6474b7d82d03b27bd43835eee199c95b64f1", - "transactions": [ - "0xf87981cf0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0fa1c9705b3794f376d02943123846aaae435a6590ddb802e16e91f87ae13c910a0609129061ec7d065ea3c154152c452f76a7894f2459c42c33675af6a20c9ad3c" + "blockHash": "0xcd35112597db3095f6c10b644aee930651c44a03d8c168581d8aff8d26050491", + "transactions": [], + "withdrawals": [ + { + "index": "0x16", + "validatorIndex": "0x5", + "address": "0x84e75c28348fb86acea1a93a39426d7d60f4cc46", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb90e98bd91f1f7cc5c4456bb7a8868a2bb2cd3dda4b5dd6463b88728526dceea" + "0x52b1b89795a8fabd3c8594bd571b44fd72279979aaa1d49ea7105c787f8f5fa6", + [] ] }, { "jsonrpc": "2.0", "id": "np259", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xed832bf95db43a650d06fac15b9b6474b7d82d03b27bd43835eee199c95b64f1", + "parentHash": "0xcd35112597db3095f6c10b644aee930651c44a03d8c168581d8aff8d26050491", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x06ffd1eba12cda277819f77a9a89a4f78265f7aed5158dc51332218976856e82", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x8f2c077936f439e11f80611dc95c720ad9f4dceb3f0ea11713514b308d279490", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x103", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xa1e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x65f5a3780beee8d82281e7fe3e82b81dae2a14ef861e9df584590dd429b8d632", + "blockHash": "0x46728f520936c769482557b2d4d05386f030a3d9c03cca9d123940d3d3fc97be", "transactions": [ - "0xf86481d0088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa07de64020fd82a08d2737ded6967d6a6095c02858161988f0626bad7dd2238057a00ad64af462ef2241d4e4c0da1dc108871126cf2aa2b82afd98d7069fc79d9085" + "0xf88281ed088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a05ff5043201525e47b2a17bd2efc4aae132dd6f168252e51b2f20fb6fb7ac6043a05476a8576d657d8ff75014e8bcc77e6e9657526efa8b79f085f8f78ca70d3ce7" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4e80fd3123fda9b404a737c9210ccb0bacc95ef93ac40e06ce9f7511012426c4" + "0x7c1416bd4838b93bc87990c9dcca108675bafab950dd0faf111d9eddc4e54327", + [] ] }, { "jsonrpc": "2.0", "id": "np260", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x65f5a3780beee8d82281e7fe3e82b81dae2a14ef861e9df584590dd429b8d632", + "parentHash": "0x46728f520936c769482557b2d4d05386f030a3d9c03cca9d123940d3d3fc97be", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3d72e9a90b2dbfc909c697987538e4e9a8f2b127a783109fbb869bf3760bd7a0", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x8b08ae94f43b6cde596fead75fc65515098159157826766c042df86e8ee39fbb", + "receiptsRoot": "0xe96c8af980d88dfdb57bb4e77d6139098674406977393b19a5a4a06d409ed1e8", + "logsBloom": "0x80400000000000000000000000000000040000000000000000000000001020000000000000000000000010000000000000000000200000010000000000000000000000000000000000000000001008000000000000000000000800000400000000000000000000000000080000020400000000000000000800000000000000000000000000000000000000000000000200000000010000000000000000000000000020000080000000008000400500000020000000400000400000000000000000000000000000000004000000000000000400000000000000100000000000000000000000000000000000000000000004001000000000000000000000000001", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x104", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xa28", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xcab55b4abc18bcf8e1b24ae34df180dc00edeadc072fa2e52ed54f2b09c6367f", + "blockHash": "0x65989a6ce9bd74150837c8f8feea080d86236e1706b2b1d9bb42ae329a212110", "transactions": [ - "0xf86781d10882520894a8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e01808718e5bb3abd109fa004c1d18013fb8b0554b8aaa549ee64a5a33c98edd5e51257447b4dd3b37f2adea05e3a37e5ddec2893b3fd38c4983b356c26dab5abb8b8ba6f56ac1ab9e747268b" + "0xf87981ee0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0249a03e12c72b484b782d7dd0202a67a7e362781b8037c07502d359ff95d49e5a00966596e0c65871380a7525de7d858c6f29b5262df7672499db7e39ba7779ec2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xafb50d96b2543048dc93045b62357cc18b64d0e103756ce3ad0e04689dd88282" + "0xef87a35bb6e56e7d5a1f804c63c978bbd1c1516c4eb70edad2b8143169262c9f", + [] ] }, { "jsonrpc": "2.0", "id": "np261", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcab55b4abc18bcf8e1b24ae34df180dc00edeadc072fa2e52ed54f2b09c6367f", + "parentHash": "0x65989a6ce9bd74150837c8f8feea080d86236e1706b2b1d9bb42ae329a212110", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8c514217bbc30325a9d832e82e0f1816cff5d7fed0868f80269eb801957b22a0", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x2a7940a6da7cd8688d8fff2706eb485e00b273a76cb1c620612243f456dd136b", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x105", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xa32", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x687b7f705112cf8d76b18d5ab3bc59fab146131c4b8efa05a38b42a14bcb251c", - "transactions": [], - "withdrawals": [ - { - "index": "0x24", - "validatorIndex": "0x5", - "address": "0xbc5959f43bc6e47175374b6716e53c9a7d72c594", - "amount": "0x64" - } + "blockHash": "0x1244e39eddc59b8d38c3c9e609867b149bb1222e3087fcde4e60d1785f9ca6fb", + "transactions": [ + "0xf86481ef088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0f71990113edc7bbd8fb0652e4f147e4cf8454da209758a3edeae5d85d8ce6348a064c11008d0f851e7b753f6b8557dfa300044fde1503c10d518795b97ca0baaa9" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd73341a1c9edd04a890f949ede6cc1e942ad62b63b6a60177f0f692f141a7e95" + "0xe978f25d16f468c0a0b585994d1e912837f55e1cd8849e140f484a2702385ef2", + [] ] }, { "jsonrpc": "2.0", "id": "np262", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x687b7f705112cf8d76b18d5ab3bc59fab146131c4b8efa05a38b42a14bcb251c", + "parentHash": "0x1244e39eddc59b8d38c3c9e609867b149bb1222e3087fcde4e60d1785f9ca6fb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x32fc9182d259ea7090be7140ec35dee534b5e755af25c3a41b2fe23452cd75ae", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xc28b9a58e85ba57dc108f326dec626ef81a0b16946c895ad90961c1cf43c23d6", + "receiptsRoot": "0x2c661ac051aa0ffbf53e7fb3e9fbc5527454a4d1e22c9eece00da386134aaae5", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000040000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x106", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xa3c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x59763420efabb84b6d4ae2b2a34f6db6108950debfe1feba4f706ad5227eca5f", + "blockHash": "0x9b11fa343fc18df51ad37fa94c9d6c17916786bbbab8bc10e3a3d1c0580e0b2f", "transactions": [ - "0xf88281d208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0010b2ab5421f3fe86f38332dd1c862ddcfc711b2255d8f2a677985d3858b643aa025f4fec49790d44c9b50ed1bea3c5700de165dc239173328e0d0c045f0dd4558" + "0x02f8d3870c72dd9d5e883e81f00108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cc4b2277a673e7dea656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0628887ea9304aeb7f3934543b9d14ab4e7e5cd422ba572d39d6ee10c3304534580a04216844f9698b4c3ac489b56ede5c1330ac2dcf5ab2f0d44882d60f2565d7c34a04f6922b75af7e0fccc73af8aa2253cb6a690121061c83dbbe40890d778514ac6" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc26601e9613493118999d9268b401707e42496944ccdbfa91d5d7b791a6d18f1" + "0xc3e85e9260b6fad139e3c42587cc2df7a9da07fadaacaf2381ca0d4a0c91c819", + [] ] }, { "jsonrpc": "2.0", "id": "np263", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x59763420efabb84b6d4ae2b2a34f6db6108950debfe1feba4f706ad5227eca5f", + "parentHash": "0x9b11fa343fc18df51ad37fa94c9d6c17916786bbbab8bc10e3a3d1c0580e0b2f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xdbed2b577f83fcb221ae85377d9c4f41b8ca95de085a3a697098ceaa937d23f8", - "receiptsRoot": "0xf4e79fec628d38bdc719707be2f797b74efbc9468ba5a3ae9415877e11c21db4", - "logsBloom": "0x00000000000008004000000000000000000000000000000010800000000000000040000000000000020000000000800410800000008000040000000000000000000000000000000000040000040000000000000000000000000000001000000000020000000000000400200000000100002000000000000000000000000000000008000010000000000000000020004400000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000008000000000000080010000000000000000000000000000000200000000000020000000000000000000000000000020000800000000000000000", + "stateRoot": "0xac12a5a83732b8e0cfb72b17b98da2c647d6c43aafc8781cec9bc934c4667cea", + "receiptsRoot": "0x6a3af165755b8f4ddfb198a02c1ea6fa0e476be8a9e91d41195866f75a6c65bd", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000200000000004000000000000200000000000000000000000000002000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x107", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xa46", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf95bd5a6a4d1d51c8f00e6421bb1ecdb2a4b19222261aa412dcb4c371eea1af5", + "blockHash": "0x6bd2bb001303e7dfb428c75ea4bd6dd7115d6ff61add2924cb23a0115c920884", "transactions": [ - "0xf87981d30883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0aa1f3a14b2bee05c15deffd1fcbad6d16deb140557251b04ddb61574fa8c70d8a0614a539b7fe8c276d26cabc1ff36c88c3f6b9cf3bc8836309a1d3f46626b5153" + "0x01f8d2870c72dd9d5e883e81f108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c1b6adcc983ad4086656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0ac748acc1af284e25d06434a8c1bbbf75bb8154a06f53f75d4f36edb656a49ba01a003a3e9854f243d54d673cb575bebb4d014860aa9e0053491cc0fe1cc10aaa8ffa0502f1bf5418002e6a5e19bf6387aec07f366edad070548e4271359c07e1c8dbd" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xfb4619fb12e1b9c4b508797833eef7df65fcf255488660d502def2a7ddceef6d" + "0xbd2647c989abfd1d340fd05add92800064ad742cd82be8c2ec5cc7df20eb0351", + [] ] }, { "jsonrpc": "2.0", "id": "np264", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf95bd5a6a4d1d51c8f00e6421bb1ecdb2a4b19222261aa412dcb4c371eea1af5", + "parentHash": "0x6bd2bb001303e7dfb428c75ea4bd6dd7115d6ff61add2924cb23a0115c920884", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2eb443ed50d07a6b1dbb2c154cc221cfb0475593b39ca2d3569224ea7a08030e", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xafb2da9323c0f07fd5d9356a2c9bf67b082d7e36db4871d76339ce059d0caa5f", + "receiptsRoot": "0xc5610bcb5002376ea2eabd88001c2b2fac4b1c3dd0c0046f926c16c3f0c852f3", + "logsBloom": "0x00000000800000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x108", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xa50", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x68bd9ab4e0b622e480296f040ad58d1b7f048c712ad5b46c7a596265d5f8e9fc", + "blockHash": "0xdb94bbffb05461e4f8a83c827cb5b0cc8e54ce71af9f4b57fd712c7bf245a67e", "transactions": [ - "0xf86481d4088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0533560fb23c458df00902dbacef307e98096d91f179c49458d99e2eecaeaf3d3a0314508cba155f195ff77eff1a25ed4f454a07b404ac82d3ea73796bd9af3128d" + "0x03f8f9870c72dd9d5e883e81f20108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c6fc8c6364b779b27656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a04348597bdcdee80c8e110d94f771eb7edce9c8691b2f90b71c0d11f729f086c983020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0f4f3451f3c730bab02a9b6000e8fa5cb299d75f3963eb0e1ba4e926a284c93e3a0107d70040f1a155b756b0130439565c52db057287755e9e721e3f24d6655506f" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xd08b7458cd9d52905403f6f4e9dac15ad18bea1f834858bf48ecae36bf854f98" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x99ac5ad7b62dd843abca85e485a6d4331e006ef9d391b0e89fb2eeccef1d29a2", + [] ] }, { "jsonrpc": "2.0", "id": "np265", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x68bd9ab4e0b622e480296f040ad58d1b7f048c712ad5b46c7a596265d5f8e9fc", + "parentHash": "0xdb94bbffb05461e4f8a83c827cb5b0cc8e54ce71af9f4b57fd712c7bf245a67e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6e68dd5ff68bf8a325446716e5bc1629a4e77167c3b5c9249ac2e440b35dea9b", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x06aa6955d876a1263894ecbb03fb81460996e83dfd0bd1f67700abf52f69434c", + "receiptsRoot": "0x82a4ca68aa94d5dad5dab5df853ef13aa848d3e427c2264269dafff205d3e4d0", + "logsBloom": "0x0000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400400000000020000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000d000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x109", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xa5a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xfd61bbebf4026ea51b90fafefc671dc4540e83436c83eb9bc51e6b2b15db5dc9", + "blockHash": "0x669d2fdcd20848e3f746c76753dac2763d798d43492e58e75eec82ef4fb156b3", "transactions": [ - "0x02f86a870c72dd9d5e883e81d5010882520894ac9e61d54eb6967e212c06aab15408292f8558c40180c001a0898d514a1f15103335e066d0625c4ec34a69a03480d67dcb3d3fe0f4f932100aa07e130fed862c1482467d112f64fb59e005068b52c291003c908b625b4993e20e" + "0xf87481f308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c62087a44acecfb2c656d69748718e5bb3abd109fa0fe8ea091430d3b75ba298e74524e5fb6fe481c4950b522fffccf1e94206ad5c7a013bb8d11137fbf2826ff165447f9f15b8b4acfab5d0e0b092632975f351dbf73" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xdf979da2784a3bb9e07c368094dc640aafc514502a62a58b464e50e5e50a34bd" + "0x02a4349c3ee7403fe2f23cad9cf2fb6933b1ae37e34c9d414dc4f64516ea9f97", + [] ] }, { "jsonrpc": "2.0", "id": "np266", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfd61bbebf4026ea51b90fafefc671dc4540e83436c83eb9bc51e6b2b15db5dc9", + "parentHash": "0x669d2fdcd20848e3f746c76753dac2763d798d43492e58e75eec82ef4fb156b3", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4783eb369238bf2856e00bbc632735adf5ea404b766a0a70c27913314e170bac", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xa3f1d1f3a5479545b0e1a5e8ede05281f5c19182191663ebceb9d877d674175a", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x10a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xa64", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xaa8b392a2333d1f8a498c60f1c9884705d0bff7dd5a524b5a119f547b0d6579c", - "transactions": [], - "withdrawals": [ - { - "index": "0x25", - "validatorIndex": "0x5", - "address": "0xc04b5bb1a5b2eb3e9cd4805420dba5a9d133da5b", - "amount": "0x64" - } + "blockHash": "0x8bc68b8a166d2b68a73be23ea20193dccd82a3bfedac661f969bdc32fcd454a4", + "transactions": [ + "0x02f86a870c72dd9d5e883e81f4010882520894c7b99a164efd027a93f147376cc7da7c67c6bbe00180c001a0614813ef71b15ae6c0e87a53fdce19608fb50a3f85b90d201fa9fe374e9b28f9a00d51baec84d22441726cfa3d3c87a08e190a791d39736d820726d270edd8c29e" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x15855037d4712ce0019f0169dcd58b58493be8373d29decfa80b8df046e3d6ba" + "0x627b41fdbdf4a95381da5e5186123bf808c119b849dfdd3f515fa8d54c19c771", + [] ] }, { "jsonrpc": "2.0", "id": "np267", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xaa8b392a2333d1f8a498c60f1c9884705d0bff7dd5a524b5a119f547b0d6579c", + "parentHash": "0x8bc68b8a166d2b68a73be23ea20193dccd82a3bfedac661f969bdc32fcd454a4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd0b9db5bce164e65b476f578ff93039bad1be78c8d1f595ff8496c2f7a67fea4", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x08dab9f63e2c2aafaa520e12138b01b3e0c23c308893968af25a0d38b15d6c00", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x10b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xa6e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa33f601ca31d93d804b269042c783f9a6f79857919289dbb935e81ba1fed86ea", + "blockHash": "0xf8160bbab91163c4b7120ab3c60606cc47ba1ec0e765daf1d68ca0dcf52d2787", "transactions": [ - "0xf88281d608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa03329c0816ba8af740dd07a393681abfd26c3f0a121cdfa2390607d0d1832e741a051d0d0b427004563def4552ee51b81a2ca1f41bb48e8b9ae20615381c353d9b3" + "0x01f869870c72dd9d5e883e81f50882520894654aa64f5fbefb84c270ec74211b81ca8c44a72e0180c001a0a6f0f360c5a1a83b44c9596dd1f56ce31b234d0420f6156884a29a66cfbc42bfa0669e36bd373c9265ca998588d043303e88da8c2f8ec8898ca0be6009218d00b6" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xfd1462a68630956a33e4b65c8e171a08a131097bc7faf5d7f90b5503ab30b69c" + "0xc087b16d7caa58e1361a7b158159469975f55582a4ef760465703a40123226d7", + [] ] }, { "jsonrpc": "2.0", "id": "np268", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa33f601ca31d93d804b269042c783f9a6f79857919289dbb935e81ba1fed86ea", + "parentHash": "0xf8160bbab91163c4b7120ab3c60606cc47ba1ec0e765daf1d68ca0dcf52d2787", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xcb8d1404a32030e577a2628884f57433fe91b36b838f8576471bc36d87784132", - "receiptsRoot": "0x65c1a0ac45edc227576188f00c72612cd6c4d27cdac8d997bc6c9f499d21565c", - "logsBloom": "0x00000000020000000000000000000001000000000000000000000000402000000000000001000010000000000000000000000000000000000000000000000000000000000800040080000100000006000000000000000000000008000000000000000000000000000001000000000000001000040000000000000000000000000000000000000000080000100000000000000100200000000000000000000000000000000000080000000000000000000040000000000000000000000001000000000040000000000000000000000000000000000100000000000000000100002000000000200000000000000000008000000000000000008010000000000000", + "stateRoot": "0x7b0f4215fad37adedc45506bbf63d576e0546ec58e3715743bda1d182a87173c", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x10c", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xa78", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x295de1a3c0821f092b15b4e51f02dd17ab7f1753f22f97c88a2081f9a19ffa01", + "blockHash": "0x3f4cebd4ebd414ba3710ad5eabfefa06fc5f007c62ef0900e07c263e1923889f", "transactions": [ - "0xf87981d70883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0310faf1dfcbc5597e207ab627226d2deeea1eedec7ffd8e68740fb76545586d1a01919f4683f202d4ccb3ab524d89d11119e7115645707333703d70f6fbe3c610d" + "0xf86781f6088252089483c7e323d189f18725ac510004fdc2941f8c4a7801808718e5bb3abd10a0a0b657470f4dd51519c81a036de7f51b2e5554575d49a376a08f4bc155880f2a91a02b9e03016faed61ecece3dddea17a7c27b6e75076cc1351a06966a18ac98636d" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xedad57fee633c4b696e519f84ad1765afbef5d2781b382acd9b8dfcf6cd6d572" + "0xf7a477c0c27d4890e3fb56eb2dc0386e7409d1c59cab6c7f22b84de45b4c6867", + [] ] }, { "jsonrpc": "2.0", "id": "np269", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x295de1a3c0821f092b15b4e51f02dd17ab7f1753f22f97c88a2081f9a19ffa01", + "parentHash": "0x3f4cebd4ebd414ba3710ad5eabfefa06fc5f007c62ef0900e07c263e1923889f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0199e03e7400c428fb1bba7126f4eb3a12becd96c4458bff54952e5535b4a3d0", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x2554f77d3552a0ee983978ced700fedd929024bc7690cdf168f1e9ca0c5ada7d", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x10d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xa82", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x494693083463dc335450802ab50c97022e63c21e326ff7cebd7870802411db3e", - "transactions": [ - "0xf86481d8088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0ea5ad6553fb67639cec694e6697ac7b718bd7044fcdf5608fa64f6058e67db93a03953b5792d7d9ef7fc602fbe260e7a290760e8adc634f99ab1896e2c0d55afcb" + "blockHash": "0x51a4821b633b80775e02a85aafd3a58ed2796e158c03aea46004e25ca138eaa1", + "transactions": [], + "withdrawals": [ + { + "index": "0x17", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc2641ba296c2daa6edf09b63d0f1cfcefd51451fbbc283b6802cbd5392fb145c" + "0x1cb440b7d88e98ceb953bc46b003fde2150860be05e11b9a5abae2c814a71571", + [] ] }, { "jsonrpc": "2.0", "id": "np270", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x494693083463dc335450802ab50c97022e63c21e326ff7cebd7870802411db3e", + "parentHash": "0x51a4821b633b80775e02a85aafd3a58ed2796e158c03aea46004e25ca138eaa1", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xad6e3dc4bf8e680448a8a6292fc7b9f69129c16eb7d853992c13ce0c91e7d1ce", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x5d2d837f98e90f380271bc4eaaa543f15630b485a755956ab1d023e14d41ef2c", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x10e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xa8c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc54e865454d4ba4a092904e151d7afdc9b7b7ef9723dee0325ee075eb6a9a5c0", + "blockHash": "0x6904e188fffed4cc41632df32452ec9bd4cafdee6f5d76c36e1b2efd33ad9079", "transactions": [ - "0xf86781d90882520894653b3bb3e18ef84d5b1e8ff9884aecf1950c7a1c01808718e5bb3abd109fa0f1c5d5e335842170288da2c7c7af6856ea0b566d2b4ab4b00a19cb94144d466ca02043677d1c397a96a2f8a355431a59a0d5c40fc053e9c45b6872464f3c77c5dc" + "0xf88281f7088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0bbeeb602a74706ac6e91e64344c1844808b21eda8b2303c2fe5d6a0072be018ba03b5274579f02a9f98c995311ab714ba8f8f83d782cb802aa7eab0d47627f90c8" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x5615d64e1d3a10972cdea4e4b106b4b6e832bc261129f9ab1d10a670383ae446" + "0x72613e3e30445e37af38976f6bb3e3bf7debbcf70156eb37c5ac4e41834f9dd2", + [] ] }, { "jsonrpc": "2.0", "id": "np271", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc54e865454d4ba4a092904e151d7afdc9b7b7ef9723dee0325ee075eb6a9a5c0", + "parentHash": "0x6904e188fffed4cc41632df32452ec9bd4cafdee6f5d76c36e1b2efd33ad9079", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4347088d10fe319fb00e8eee17f1b872f2e044cbe1cb797657294404bf370e30", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x2408c8ee1b99f42499120241935b75233442b2ced2ee4df0b662845fd312da2e", + "receiptsRoot": "0x0d4f58d0c68a50f97304f479e8cafe31adfb13cbd601e084066af748100882c7", + "logsBloom": "0x00200000000000000040400000000000000000000002000000000000000000000420000000000000000000000001000000000000080000000000000000000000002000000100000010000000000000000000200004000000000000000100000120000000020000000000000000000000010000800000001000000000000000000000000000000000000200000000000000000000040080000000000000000000000000000000000000000004000400000000000000000000000000000000000000000000000000000000000010000000000008000000201000000000000000000000000001000002002000000000200000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x10f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xa96", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc33055476392adfe03f3bd812f9bb09b7184dc8d58beefab62db84ee34860bed", - "transactions": [], - "withdrawals": [ - { - "index": "0x26", - "validatorIndex": "0x5", - "address": "0x24255ef5d941493b9978f3aabb0ed07d084ade19", - "amount": "0x64" - } + "blockHash": "0xf6354df3badf86b25e2f88f4630610c9c756a76eab5489bf84dc4b5faa5dfcad", + "transactions": [ + "0xf87981f80883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa074dc1ffa4861a35bcc8448c8e6b1405fbd4b51a3f750a4afcf44ee192c186bcea01755d34cbd340f9c8439880745cad348449f931dc18dc31c69e8b60bccca14b3" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x0757c6141fad938002092ff251a64190b060d0e31c31b08fb56b0f993cc4ef0d" + "0xe69e7568b9e70ee7e71ebad9548fc8afad5ff4435df5d55624b39df9e8826c91", + [] ] }, { "jsonrpc": "2.0", "id": "np272", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc33055476392adfe03f3bd812f9bb09b7184dc8d58beefab62db84ee34860bed", + "parentHash": "0xf6354df3badf86b25e2f88f4630610c9c756a76eab5489bf84dc4b5faa5dfcad", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa9c73e0cd551b43953f3b13ee9c65436102e647a83bfefa9443ad27733d0371c", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x656387ab387b18449d508730369f7633ecc8ad248063a0d2106374a5a72ea043", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x110", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xaa0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x39f74e3f7d2c3f4ab7e89f3b597535ffebd200abe4b1aa67f721ffaa13cbc2b4", + "blockHash": "0xa3f857458c4f8e850d17825dd663d51219737a227a157cb9f3eb21a7dabf3c12", "transactions": [ - "0xf88281da08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0972f048bcd4f8e2678a209e354570de7452fa342744fab1e44b7af67b2484d9ea0076f82074ff9697256d2661ad9f9a7321ff54fa3100ecc479166286a9a22ada5" + "0xf86481f9088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0c169d3545078ccd936ab6cd33f5f22548618c895668c4f84af4f9ebc950eec38a06c86ddbbf36b2aa97dd38d268b4e64b967167f51530c48c63e3a23e24bcae4b3" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x14ddc31bc9f9c877ae92ca1958e6f3affca7cc3064537d0bbe8ba4d2072c0961" + "0xc3f1682f65ee45ce7019ee7059d65f8f1b0c0a8f68f94383410f7e6f46f26577", + [] ] }, { "jsonrpc": "2.0", "id": "np273", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x39f74e3f7d2c3f4ab7e89f3b597535ffebd200abe4b1aa67f721ffaa13cbc2b4", + "parentHash": "0xa3f857458c4f8e850d17825dd663d51219737a227a157cb9f3eb21a7dabf3c12", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf003762d896629dcd3a92a67ee13b96b080f4a3e71402a1dcbf9f444377329b5", - "receiptsRoot": "0x4d68fb9bfae6768b9578f5a63f455867ea5993ec2261fad2a25b45794d092f7c", - "logsBloom": "0x00000000000000000001000000000000000000000000000000000000000000000000000080000000000000100000008000000000000000800000000000000000000000000000000000000000000000400000000040000000240001100000000000000000000000000800000000000000000000000000000000060000000000000000000000000000040000000000002000000000000000080000000200000000000000000000000800000040000000040000000000000000000000000000100800000000000800100000000000000000000000000000002000800000000000000000000800000000014000040000000800000000000400000000000000000000", + "stateRoot": "0x803db5b17b6a762269881f87517f2941a1a9c42fcd0cddfe7544945544566c49", + "receiptsRoot": "0xecb4f3e60b707949e677bf6d670c9f95cb89f881a643f318b0147d300b110a10", + "logsBloom": "0x00000000000020000000000000000000000100000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x111", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xaaa", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x23408e1ac73e1dd9c3a735776a73b4c79249e5a9eb62ec9f9012f7f6c11ba7d0", + "blockHash": "0xa9e96ee23c11f8d5762340e128d2280d87ee788885951468baa9a384665b95f7", "transactions": [ - "0xf87981db0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a08883be3af4b0a273883412ad320e6dcace1f505d9b20194e8f9e2e092c8d5ce4a03da92647d3d92d2868d5b9c479d98faf263e78eb67f259101a65ff56ee1eccbf" + "0x02f8d3870c72dd9d5e883e81fa0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c1edb46f05849d382656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0ee181b97fd68754f6245c655a0a0686e8d12aa4eac5f1d059e7e3b8d6a92407380a0d1c9df9a238c482417fc0bb6a007472f4bc8e77e2c87eb0b31e25370cfdfba11a065fe3cbb739fc600e9a03210f5dbe449df426cb872cfbbc7a9d19c20dec09381" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x490b0f08777ad4364f523f94dccb3f56f4aacb2fb4db1bb042a786ecfd248c79" + "0x93ee1e4480ed7935097467737e54c595a2a6424cf8eaed5eacc2bf23ce368192", + [] ] }, { "jsonrpc": "2.0", "id": "np274", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x23408e1ac73e1dd9c3a735776a73b4c79249e5a9eb62ec9f9012f7f6c11ba7d0", + "parentHash": "0xa9e96ee23c11f8d5762340e128d2280d87ee788885951468baa9a384665b95f7", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x741d337861f144fc811cfac1db596e3bedb837b0fb090a3d013e5492bf02b233", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x54cffe7d4fef024de316515ce8a1b8d45facfc45060afe9422513b076d3d7d60", + "receiptsRoot": "0x2c4e34289f602c7112bedf7b63c453a4b8ca4d68eb2c6aa24af4ef274deefa2b", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000040000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x112", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xab4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc7578d8b738ac9f5ab97605ce1c8101160faa615feeb8fc43282d8bd6ae450ac", + "blockHash": "0x443c32584ab5e94cf1393eba7de764dcbf40a903572c0b1737a2198537886269", "transactions": [ - "0xf86481dc088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0bcd2b139343048e9174e86251017c9b7c4da9fc36e4a84cf98eaf3855561f8e3a01c25a7b3ff3ebd7d9cbed5aa65515f8ba06fb8860d0764a98591da24e7d1c842" + "0x01f8d2870c72dd9d5e883e81fb08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c84eb17e70e299b7f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a04edb05f465bc71ee02c59ac9b5b50ddd974960ea2bd7e8cf7ae91c38c0b5789c01a0f27f117e815339f2749850a97c719a6c69358b37864d12e9898e689f446a9ceea015788df7af934298d0184f55d371f2ad0c79cf140b9ece4e8518d8a5f0a21efc" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4a37c0e55f539f2ecafa0ce71ee3d80bc9fe33fb841583073c9f524cc5a2615a" + "0xb07f8855348b496166d3906437b8b76fdf7918f2e87858d8a78b1deece6e2558", + [] ] }, { "jsonrpc": "2.0", "id": "np275", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc7578d8b738ac9f5ab97605ce1c8101160faa615feeb8fc43282d8bd6ae450ac", + "parentHash": "0x443c32584ab5e94cf1393eba7de764dcbf40a903572c0b1737a2198537886269", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe1ce5b13d3189869321889bb12feb5da33a621bf0dbc4612b370a4b6973201f7", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x26a0e4a442d51c93e770373c6818c0c67ef9ddd7d626707a1f1de5cab25a8086", + "receiptsRoot": "0xc06b7b23d29690d39174ae317e01ab8a941444749c462ce9f86508e504b7b4e2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000400000000000000000000000004000000000000200000000000000000000040000002000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x113", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xabe", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x0bd8ca5ecbf0c960433cbe52bec31810c325088860cd911a1df20174fd30243a", + "blockHash": "0x1910146905689fbbc61f374a7bde5325be084f307a5617b7bdb319691d7cbe7e", "transactions": [ - "0x02f86a870c72dd9d5e883e81dd010882520894d8c50d6282a1ba47f0a23430d177bbfbb72e2b840180c001a04330fe20e8b84e751616253b9bccc5ff2d896e00593bfbef92e81e72b4d98a85a07977b87c7eca1f6a8e4a535cb26860e32487c6b4b826623a7390df521b21eac7" + "0x03f8f9870c72dd9d5e883e81fc0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cd67b2566c143f645656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0af1c2654b2e98e9ffbb02f14d88617a245a9a1679162be29776a4836185dc2fa83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0e0f28063ea2a24086eab327a71ff3e93f1fe235ae1e1b4481a15c47a53d5bd9ca019cc7b23d66b225280440f0a95b90d9213c83bbf26e5a4d4e6a7a8dc4c72c4a8" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x133295fdf94e5e4570e27125807a77272f24622750bcf408be0360ba0dcc89f2" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xec60e51de32061c531b80d2c515bfa8f81600b9b50fc02beaf4dc01dd6e0c9ca", + [] ] }, { "jsonrpc": "2.0", "id": "np276", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x0bd8ca5ecbf0c960433cbe52bec31810c325088860cd911a1df20174fd30243a", + "parentHash": "0x1910146905689fbbc61f374a7bde5325be084f307a5617b7bdb319691d7cbe7e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x76aa5a1d0fc7c2f7e01a8c515f018e30afb794badc14b5d8e3651096458947a0", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x365814495fb3a18e4e09db0619a45be4ad5122707ea2dfd6884b63b5e1c2dcd0", + "receiptsRoot": "0xdb1dd143b29f2936ae059b08853ae6e6a89db350809c3185de6ea9c618ea6920", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000008002000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x114", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xac8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x604c3b8dbc400712146239b5b6e70426361e47c118c6fff4c1761554c3ad2e47", - "transactions": [], - "withdrawals": [ - { - "index": "0x27", - "validatorIndex": "0x5", - "address": "0xdbe726e81a7221a385e007ef9e834a975a4b528c", - "amount": "0x64" - } + "blockHash": "0x5d602bc5189b5a955faeb7842825c53c4cd335c0cac7756599e3a7d7a9b1e604", + "transactions": [ + "0xf87481fd08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ce6d182630e8ffca8656d69748718e5bb3abd10a0a05e0045c49ffc8d2f6c70cd6fc2033bcd0a31c6515b8744720686836a04a2236ba02411fd9607b7640df6c5a2ac2eef30895bd0ed221718ad5b37a5d23d719398a7" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa73eb87c45c96b121f9ab081c095bff9a49cfe5a374f316e9a6a66096f532972" + "0x2fc9f34b3ed6b3cabd7b2b65b4a21381ad4419670eed745007f9efa8dd365ef1", + [] ] }, { "jsonrpc": "2.0", "id": "np277", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x604c3b8dbc400712146239b5b6e70426361e47c118c6fff4c1761554c3ad2e47", + "parentHash": "0x5d602bc5189b5a955faeb7842825c53c4cd335c0cac7756599e3a7d7a9b1e604", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xaad6081261920a2bddee7ad943a54ceebdb32edf169b206bd185bd957c029389", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xef3660b1a4ef1379d8611613bfdd0fa481d0cb0c447ba91662ed3061407ea867", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x115", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xad2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3dbceccc7aefcec187b98fc34ab00c1be2753676f6201a1e5e1356b5ce09c309", + "blockHash": "0x7cdd5d09a0af5e26bad74166fd6a4324185ee337b005e5df5f4f67f00155cce9", "transactions": [ - "0xf88281de08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a092ec956d91708337ef4625bb87caed7a2bab63e40c8e65e8c9ee79a89b525b53a02bfff0c6dadfbf70dbd9fb2d75a12414d808ee6cce90826132d63f8ef2ce96b5" + "0x02f86a870c72dd9d5e883e81fe010882520894e7d13f7aa2a838d24c59b40186a0aca1e21cffcc0180c001a08fc9a8d1ebbdace1c8111cb137b3024b0620a4311574a5bcc3af2c0c5a0b5b7ba0238b44f3d32d593eafedec3d2cca2bbfe3e68dc96e333dc5b7c0b4c0141b4af2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9040bc28f6e830ca50f459fc3dac39a6cd261ccc8cd1cca5429d59230c10f34c" + "0xf4af3b701f9b088d23f93bb6d5868370ed1cdcb19532ddd164ed3f411f3e5a95", + [] ] }, { "jsonrpc": "2.0", "id": "np278", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3dbceccc7aefcec187b98fc34ab00c1be2753676f6201a1e5e1356b5ce09c309", + "parentHash": "0x7cdd5d09a0af5e26bad74166fd6a4324185ee337b005e5df5f4f67f00155cce9", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xac5c584edba5f948690abb0f1c0f9bef685dec896c8f6c5c66ef8dd65810d53e", - "receiptsRoot": "0xdd1d7486ff21ad1c1e17b4d06cf0af6b4a32f650ac495deff2aae6cb73338de3", - "logsBloom": "0x00000000000000000000002000000200400000000082000000000000020100000000000000000000000000000000000000000000000000088000000000000010000000000000000000000800000800000000000000000000000000000000000000000000100000000004001004880000000000000000000000000000000000480000000000000000002000000000801000000000000000000000000000000080000010000000800000000000000000000000000000000000000000000000000040000000000000000000000000008010000100000000000100000000000000000000000000000000000000000000000000000000000000200000000010000000", + "stateRoot": "0x17d40d4bf412667ea693c2b08587f543806e84f610c1b5a360a9b0be7b25cee6", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x116", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xadc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe69bddf40ecef2219c3ce0f27015125fb42d2339c75675f8e0dc587246cf617c", + "blockHash": "0xda06797d4ea9e2d242a7f1d77163e4cd0d18aa7e9ae04a2357c7a359c3a7897b", "transactions": [ - "0xf87981df0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa099b6473bcd99e0f32d82c046bad2e1824a8468bae8347768d907768e2fe64a2ba051f3f8b7323eab23d5543c8e372e4e184bc3ee108eab5455b89d40d9cbc23008" + "0x01f869870c72dd9d5e883e81ff088252089484e75c28348fb86acea1a93a39426d7d60f4cc460180c080a08b3ceb8078fd45b2305a1cbe2d116976b180ec20267f1af943ce1548112d7aaaa008999b87bb4d79a8fa0ec280bb0f35435852ec683167f3ccdd63f3987da1209a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xec1d134c49cde6046ee295672a8f11663b6403fb71338181a89dc6bc92f7dea8" + "0x8272e509366a028b8d6bbae2a411eb3818b5be7dac69104a4e72317e55a9e697", + [] ] }, { "jsonrpc": "2.0", "id": "np279", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe69bddf40ecef2219c3ce0f27015125fb42d2339c75675f8e0dc587246cf617c", + "parentHash": "0xda06797d4ea9e2d242a7f1d77163e4cd0d18aa7e9ae04a2357c7a359c3a7897b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x909007de8369b2fd9597dd7b84ab31e36b949026383fa8957befdba94703689b", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x5f02ae67228f20bbde12c883504a1579c4d976759a0e50f2e940e3ffbc481591", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x117", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xae6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3f0eb43bfa229f0449d1b975632be01a69ed6c63eda12fb61bf83a2f8cde3c87", + "blockHash": "0x69c23b6cef19f994ec1120ebe41647daae8fc602ceeccb500bef3599ea8dc4d6", "transactions": [ - "0xf86481e0088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0d8414a9d94412185c316893b53c874ae28ad6c0d67910ec66b39051f7842408ea05329ebb7080c9a6ae9372e8004706b78f7465746c3492816b6255fcba4d84979" + "0xf86882010008825208947435ed30a8b4aeb0877cef0c6e8cffe834eb865f01808718e5bb3abd10a0a04ae4a6f0f05c189b4c0a428d6be613758e3a1d6510bebbd6eb33ad3798621ba5a0147389eb4a565503213a8cd391c0896dd64feb7221e25dff795671cf193d970b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x3130a4c80497c65a7ee6ac20f6888a95bd5b05636d6b4bd13d616dcb01591e16" + "0xa194d76f417dafe27d02a6044a913c0b494fe893840b5b745386ae6078a44e9c", + [] ] }, { "jsonrpc": "2.0", "id": "np280", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3f0eb43bfa229f0449d1b975632be01a69ed6c63eda12fb61bf83a2f8cde3c87", + "parentHash": "0x69c23b6cef19f994ec1120ebe41647daae8fc602ceeccb500bef3599ea8dc4d6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4dcb18dbea7ec4b9dc13b208172da29eb275e2095a6f8c6aeee59d62d5c9dd76", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x96484f33b10331b3839e43593cccf2809ecb6e009c3a8b0de26dae14f2b77454", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x118", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xaf0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x12c3c44447da5af2e83d37224a825c26890db2483d5732e4bac08b87fe3ce5fa", - "transactions": [ - "0xf86781e10882520894b519be874447e0f0a38ee8ec84ecd2198a9fac7701808718e5bb3abd109fa0cfbd9ff7eeb9aef477970dcba479f89c7573e6167d16d0882ead77b20aaee690a01e34175b1b1758a581ca13f2ca021698933b1e8269c70fcb94c5e4aa39ee9b8e" + "blockHash": "0x1be678ea3efa6308b7fb5b3102651a8493462715c6b09f6cd9697efd05fc7d0e", + "transactions": [], + "withdrawals": [ + { + "index": "0x18", + "validatorIndex": "0x5", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xccdfd5b42f2cbd29ab125769380fc1b18a9d272ac5d3508a6bbe4c82360ebcca" + "0xa255e59e9a27c16430219b18984594fc1edaf88fe47dd427911020fbc0d92507", + [] ] }, { "jsonrpc": "2.0", "id": "np281", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x12c3c44447da5af2e83d37224a825c26890db2483d5732e4bac08b87fe3ce5fa", + "parentHash": "0x1be678ea3efa6308b7fb5b3102651a8493462715c6b09f6cd9697efd05fc7d0e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xcbbdc9e51f0cde277f8f0ba02544d4d2be87cb7a5853a501524d760b00ec5e57", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xf6d58eabd98bd5598e385d578a8ff15f667d36691225d10c633f928d2d689ba6", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x119", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xafa", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x2ca033d3c29586c8a38da6008d4a446814d845565ed5955418b125fdbe4602e0", - "transactions": [], - "withdrawals": [ - { - "index": "0x28", - "validatorIndex": "0x5", - "address": "0xae58b7e08e266680e93e46639a2a7e89fde78a6f", - "amount": "0x64" - } + "blockHash": "0xf776a4d1d5c352151872b684cb240fb3b7d163b655fd5939337a070a7c896d7a", + "transactions": [ + "0xf883820101088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa01549f55cbe39fb1cba5adf3e7f319c7d79d4fde019b360b322dfa2db5e155727a05961f7e708d6cfa0831a1ba4ad345c01627fc5b952c825aed42912aa8725fb53" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x74342c7f25ee7dd1ae6eb9cf4e5ce5bcab56c798aea36b554ccb31a660e123af" + "0x7996946b8891ebd0623c7887dd09f50a939f6f29dea4ca3c3630f50ec3c575cb", + [] ] }, { "jsonrpc": "2.0", "id": "np282", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2ca033d3c29586c8a38da6008d4a446814d845565ed5955418b125fdbe4602e0", + "parentHash": "0xf776a4d1d5c352151872b684cb240fb3b7d163b655fd5939337a070a7c896d7a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa5f40d100045883afd309122196cd37e687124adc5ec4c609e9d4ea9e8050be1", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x18cd75fc41ff27a21a24a3cfb6bf9ee4635411cabd10c7519fbea1d7faea8a80", + "receiptsRoot": "0xeee70baf6dc22b8457f4fe7e2b8f1e5414f56cd212e6b199d50e0a88c1ad764c", + "logsBloom": "0x00000000000000000000000000000000000000000000040000000020000000000000002000000000200000000000000000800200000002000000000000000100000200000000040001000000004000000000000048400000000004000000080000000000000000000000000000000000400000800000000001000000000000002c00000000000000000000000000000000008000000080000000800000010000000000000000000080000000000000000000000000000000000000000000000000000000000000100000000000200000000000000400000000000000000000000000000000000000000000000001000000000000000002000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x11a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xb04", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x38ae7bdbc3e96e43871baeea0577a4a6e40dd3b4d2c6fea0b50d63e24dd24382", + "blockHash": "0x9dc4808f611d1b29c89fe57085c64ec7815675f779d602734d45848babdaa5ce", "transactions": [ - "0xf88281e208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a02a4dd1a40886d389cecff4ca095a57e2f1e924b8d0e80e95c67961bec5af4b34a00adc6e41c4fe22eb93c7bc6ac529c405a8beb3b75d3f82a24029c560d293bee1" + "0xf87a8201020883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa06595f7a77a4e8c661b3e414b74d407c99eaf12519f8e25800117c63249b616d2a06f667e8299ab690f9e8bca562a0931b49ccaab00bbf3ac4e18a3370d0a7259f0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf6f75f51a452481c30509e5de96edae82892a61f8c02c88d710dc782b5f01fc7" + "0xb04cbab069405f18839e6c6cf85cc19beeb9ee98c159510fcb67cb84652b7db9", + [] ] }, { "jsonrpc": "2.0", "id": "np283", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x38ae7bdbc3e96e43871baeea0577a4a6e40dd3b4d2c6fea0b50d63e24dd24382", + "parentHash": "0x9dc4808f611d1b29c89fe57085c64ec7815675f779d602734d45848babdaa5ce", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7a69e46d9beb12acb2476f649cf7fa7d31624c8b521351b533e302290b7ce166", - "receiptsRoot": "0x8f6545857c380d6f9aefa3a76d16cc79ce6d3e8d951a9041f19d57cbde82f55f", - "logsBloom": "0x00000800000000000004000000000001000000000040000000000800025000000000000000000000000000020000000000000000000080000008000000000000000000000000000000000000000041000000000008000000000000800000000000000000000000000080000000000000000080000000000000000000000000000000000000000000000000000010000000000000000000000000040000000000000040000000200000000081000400000000800000000010000000000000000000800000000000001000000000000000000000200000000000000000000008000000000000000000000000000000000000000080000004010000000000000000", + "stateRoot": "0x22e2c1b880fa2a250f7d054acb7ef6b8111655409519759fc81d381890285875", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x11b", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xb0e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xbf711951f526479f4c5a6a945594daacff51aacb288122fc4eea157e7f26c46b", + "blockHash": "0xe015df4bb2e84589a3bf64fa91b73091581910b42e0ee91f1d6cf25912d60027", "transactions": [ - "0xf87981e30883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0ac71118aff6dbdfd117ed52c41169a3c1eec7c7b137fed7ec058a48916198f2da05b684d53b4cc1cdafdba987f894eb9c42da47785983593ee1318f8a79f83eff7" + "0xf865820103088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0e0be39b51a060c97c9269d342c0afbbc6dd2435241c31100c744a50ff3bb560ea04165ba1f56b87012d4bb382b551a94e4f01f7a6e59451039b43c7a4b29a18b4c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7ce6539cc82db9730b8c21b12d6773925ff7d1a46c9e8f6c986ada96351f36e9" + "0x6f241a5e530d1e261ef0f5800d7ff252c33ce148865926e6231d4718f0b9eded", + [] ] }, { "jsonrpc": "2.0", "id": "np284", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xbf711951f526479f4c5a6a945594daacff51aacb288122fc4eea157e7f26c46b", + "parentHash": "0xe015df4bb2e84589a3bf64fa91b73091581910b42e0ee91f1d6cf25912d60027", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2d7b3e2f3ea5d7c34423a2461c1f17a4639b72a0a2f4715757ca44018b416be0", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x8bd72ff011c3ef2840fabbc5a422d1083fd40fe66ef36041c5a26d8555a54224", + "receiptsRoot": "0xa521888fe7f59d6f4ca65e0a1e98a920cf3352adaff79f113375281dcbd20b5b", + "logsBloom": "0x00000020000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000020000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x11c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xb18", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf5882e396311b698818e2e02c699c77a0865ea6320dc69499197aaf8fd8e6daa", + "blockHash": "0x9f3faf24dbf97542f5dcac91d35da491af51e24504e58f42c328ba2758b0b268", "transactions": [ - "0xf86481e4088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa088575e3574fdfafb5c288b553973607350d846bd81b304beddaa6ef3dd349eada03cacc2455d5296189c0fc6890380a3c405b96cecfc45dc04a7f7dafe76be64c9" + "0x02f8d4870c72dd9d5e883e8201040108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c1787f004c4316268656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0f0ca8a88096a033508993a424f4e40ee1d800f62390dfe4ed5dd74a0f6785e2580a0c0ef0c887b5a20d77bce56cc1a830c3e40be563bdfd1869dc8b7b844f8f87974a059b3da2bf65afd778bbe63dbdd64af23a66818ac2babbcf63a0d241a04eeef37" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x1983684da5e48936b761c5e5882bbeb5e42c3a7efe92989281367fa5ab25e918" + "0xfcfa9f1759f8db6a7e452af747a972cf3b1b493a216dbd32db21f7c2ce279cce", + [] ] }, { "jsonrpc": "2.0", "id": "np285", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf5882e396311b698818e2e02c699c77a0865ea6320dc69499197aaf8fd8e6daa", + "parentHash": "0x9f3faf24dbf97542f5dcac91d35da491af51e24504e58f42c328ba2758b0b268", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xdc0d40e96eaa22025544b17cc122fab8f236a1a5d0bfa1a07a6ea680fc31661c", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x25ad05d939524d40cddd283c1a7d67244e5dabb0c3e91442fc5b3259f830bdfe", + "receiptsRoot": "0x2e98deb47717de4589517376b85dcf871454659477b5c5c389be57ce31fa4dc8", + "logsBloom": "0x00000000000000000000000000000000000500000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x11d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xb22", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x0fabca07111b96e64ef425173cb375ed75f3e1b8ee34eed7593fe8930c9f487d", + "blockHash": "0x594c9091455bd0cd08631909cab257feeae3a05401a43544e423c759be125f77", "transactions": [ - "0x02f86a870c72dd9d5e883e81e5010882520894af2c6f1512d1cabedeaf129e0643863c574197320180c001a0c23170a740ba640770aca9fb699a2799d072b2466c97f126a834d86bdb22f516a03f242217b60ab672f352ae51249a8876a034ee51b6b4ad4a41b4d300c48e79f4" + "0x01f8d3870c72dd9d5e883e82010508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cadcad3ba169a8a51656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a00678ff21f84e5213aa8d1d173b3517f8e6c3d1523959c101c75a31daa70ab94201a023c96758cd5fee077920a67e2ff017fa227e63f7486eb5f696507a64d50fad86a006755b6e7016c5e2d1532ef8bf3868845066ae9697920deea92230848988c6ce" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc564aa993f2b446325ee674146307601dd87eb7409266a97e695e4bb09dd8bf5" + "0xdf880227742710ac4f31c0466a6da7c56ec54caccfdb8f58e5d3f72e40e800f3", + [] ] }, { "jsonrpc": "2.0", "id": "np286", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x0fabca07111b96e64ef425173cb375ed75f3e1b8ee34eed7593fe8930c9f487d", + "parentHash": "0x594c9091455bd0cd08631909cab257feeae3a05401a43544e423c759be125f77", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6d0b749b8735df89c9d0bd4fff2d180d87a7ff86301fc157573ff0e774a942fc", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x7d09b29b87c32bfcf4565856ff0ea4de4f86cfa15376b1f386adf7e193408f83", + "receiptsRoot": "0x84ee5d98c63a630bb6674d0045378f8ddedb2bf68b7f89189eb4477927016868", + "logsBloom": "0x00000000000000000000000000000000000000000000040000000000800000000000000010000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x11e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xb2c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x29d8373309b28aa3b206208c60bf6be454db83f0d5c4140604ec288251b4c5aa", - "transactions": [], - "withdrawals": [ - { - "index": "0x29", - "validatorIndex": "0x5", - "address": "0x5df7504bc193ee4c3deadede1459eccca172e87c", - "amount": "0x64" - } + "blockHash": "0x1f1d279ca073fab2be1f425ff8c09696653b77632516524baee6171427d75532", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8201060108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c8443769f598e5687656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a081260b78e72018d5773b6ba1df006b09a387fd733e59ad152c119d9848ecf1f983020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a00a4d0dfa4ef6445e63d10894fc07f68cc4c8849d23419c3d055690cad04445cba0463eb2a9bf761bfe759d65ce21ac7036ea3624c89321931dac40082f1bc24988" ], - "blobGasUsed": "0x0", + "withdrawals": [], + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x9ca2ff57d59decb7670d5f49bcca68fdaf494ba7dc06214d8e838bfcf7a2824e" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xadfe28a0f8afc89c371dc7b724c78c2e3677904d03580c7141d32ba32f0ed46f", + [] ] }, { "jsonrpc": "2.0", "id": "np287", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x29d8373309b28aa3b206208c60bf6be454db83f0d5c4140604ec288251b4c5aa", + "parentHash": "0x1f1d279ca073fab2be1f425ff8c09696653b77632516524baee6171427d75532", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x06f453054ff02cd966887e3e22bf509aacb23ee18ca302b612f10d2fb473cfa3", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x6d864643a0d723539b741f6ec461b719d9ec8b15954e446782bdd2fb1daf9657", + "receiptsRoot": "0x05a287c710d49390a940418bb5b4e9156adcb109f5fd95e33bf9032646f7bf19", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000080002000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x11f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xb36", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x84b99bc78800f925e5ba4da02f58581a21a3ae711a6306147ff4379435e655ee", + "blockHash": "0xc48ec13e43df85d25ae98c82d9ef4c2d1d09195aec3de87dd7b36f9cb530e234", "transactions": [ - "0xf88281e608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0bac48741d1f314ffaab63f07d4e7a0bc34c68dde478b439f4bca7dcf0b0a1493a036448a9a4150cad5f24411e8a9bbe89096d555ad08818e90d524bbad8b380b7a" + "0xf87582010708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c3f20aa6ef3a2d29e656d69748718e5bb3abd109fa05be6a5b4b3ee3ed08965f80adff402ac1d4c42bd388b9c5ad8e65d517ee676e4a01275191545b88aca4a31f12601a4d515bf666a03c61639d0832acd2e9fb6abc4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6d7b7476cecc036d470a691755f9988409059bd104579c0a2ded58f144236045" + "0xb264d19d2daf7d5fcf8d2214eba0aacf72cabbc7a2617219e535242258d43a31", + [] ] }, { "jsonrpc": "2.0", "id": "np288", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x84b99bc78800f925e5ba4da02f58581a21a3ae711a6306147ff4379435e655ee", + "parentHash": "0xc48ec13e43df85d25ae98c82d9ef4c2d1d09195aec3de87dd7b36f9cb530e234", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb45e7c8ace763c55943f9c73da1319566234dad9d29651d6b08227eb88c9c4fe", - "receiptsRoot": "0x490106e6f82f2847cc9eb542a9836943df09d8a6b2e4a4fafba322228449195a", - "logsBloom": "0x40000000000000000000100000000000000000000002000000000000000000000008000000000100000000400000000000000000000040000000000000040000000000000000004000002000000000000200000000000000000204000000000000000000000100000000000000000008000000000000000002000000200000000000000000000000000000000000000000000000008000000000000000010800000000000000004200000000000040008000000100000000000000000000000000000000000010000000000000000000000000000000080000400000000000000000000000000000000000000000000000000000040000200000000004800000", + "stateRoot": "0x5db606d71cea1cec324482204654ef78a867c6eb0f07f449640020833b509661", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x120", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xb40", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc7104befaf82feba7ad56db858cc6743e8ac2af4b6a1a0949c9c1ba51c0fe869", + "blockHash": "0x082ba48558d19f6911b12db3e969c8f770871c5836cbd2a02d6686624c744c88", "transactions": [ - "0xf87981e70883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa017d70f5a57065bf0973a62206ec4a9b7f1f329904de722faf30fff8e2dca5719a006d0438164dd0ff38d669ebaa44dd53cec0b81d8cfe855a9aedee94b3b1f724d" + "0x02f86b870c72dd9d5e883e82010801088252089484e75c28348fb86acea1a93a39426d7d60f4cc460180c001a02c524f745ada3ce6c926875babfecf9f8756339cd21fb66cc4ada274d84ffbcca07b3c97003cbd3a0321f3d2f927dfc68696d17600b8c5f9cb0f785d188f75d530" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x417504d79d00b85a29f58473a7ad643f88e9cdfe5da2ed25a5965411390fda4a" + "0xf2207420648dccc4f01992831e219c717076ff3c74fb88a96676bbcfe1e63f38", + [] ] }, { "jsonrpc": "2.0", "id": "np289", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc7104befaf82feba7ad56db858cc6743e8ac2af4b6a1a0949c9c1ba51c0fe869", + "parentHash": "0x082ba48558d19f6911b12db3e969c8f770871c5836cbd2a02d6686624c744c88", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4c863fc026d042a28f4ee149361f77c9dae309e18ea2497255ae91f8c41e0055", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xe45abb3f86c7ca4f95eba76b969b2b194ec3b8b90e0562567c04502ce0203c9f", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x121", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xb4a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x38c868f4adbaf9c38505eee26eb316eb5065c194df8aeed5c605f8c309d4b68a", + "blockHash": "0x1e9ef85d67a81bd278cb21a68a068060358717f518aa9a31059b0ea52e9470f5", "transactions": [ - "0xf86481e8088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0428b809dd6147da7fc27a9520ae39b6a361b8f646b4eae45b3b32e3e406d766ea00c794c60066a8d4e435ba368662d9a6c0ffdd57ec6c49fdb0c2d4c07a69875cf" + "0x01f86a870c72dd9d5e883e82010908825208941f5bde34b4afc686f136c7a3cb6ec376f73577590180c080a079cd6136faed0aa7f90de446a33df400fc30558589ea33c79ee41dca8ec1904aa060c35b52f54ade9734135680f625dd5790fad894704e08a9e631a53d6aca1de3" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe910eb040bf32e56e9447d63497799419957ed7df2572e89768b9139c6fa6a23" + "0x41e8fae73b31870db8546eea6e11b792e0c9daf74d2fbb6471f4f6c6aaead362", + [] ] }, { "jsonrpc": "2.0", "id": "np290", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x38c868f4adbaf9c38505eee26eb316eb5065c194df8aeed5c605f8c309d4b68a", + "parentHash": "0x1e9ef85d67a81bd278cb21a68a068060358717f518aa9a31059b0ea52e9470f5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4849e0698f5f4b970db7b185d122842a6f842611058a838fe4c48bf3c63b89b6", + "stateRoot": "0x2412974147eafbd2d6c512e7832d37fa6d15590e35d393651b5548ee0f50e940", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x122", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0xb54", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x962c229b0020efff007766682c8af73f38bc87fa2a83cf4a520b1e6706ced05e", + "blockHash": "0x92ccd6105a6a3d6636516fc3de3d1d5b83476e27c6c15f0d1f0a4ac3cdb77f96", "transactions": [ - "0xf86781e90882520894b70654fead634e1ede4518ef34872c9d4f083a5301808718e5bb3abd10a0a0953d5aa69077225dba6a0333ea4d69a05f652e0d2abb8df492a7e6a9d0cdbe3da004e41cb847aa131b9bb1e19cb3dd5f7a6cc2ac8b7f459ab8c3061380d41721ff" + "0xf86882010a08825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c01808718e5bb3abd109fa0e48eab7a2337ecd9a7d93785dfb1a302c4ded058ec53dfb818fc0c5a30eb53eca027a97d55006822944807657fc6326c6f5468c9338f28b9922e7cbce40d184201" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x8e462d3d5b17f0157bc100e785e1b8d2ad3262e6f27238fa7e9c62ba29e9c692" + "0x4e7a5876c1ee2f1833267b5bd85ac35744a258cc3d7171a8a8cd5c87811078a2", + [] ] }, { "jsonrpc": "2.0", "id": "np291", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x962c229b0020efff007766682c8af73f38bc87fa2a83cf4a520b1e6706ced05e", + "parentHash": "0x92ccd6105a6a3d6636516fc3de3d1d5b83476e27c6c15f0d1f0a4ac3cdb77f96", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6334127515360bcab6eb39030e54b05d61d464576fb4f99fbece693ffa600610", + "stateRoot": "0x190e225db93099517b36effe3f597034d5fe7fd0f772595c7a2d772a3bafdb69", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x123", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", "timestamp": "0xb5e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd8f175dd35dd4a5d97e51309a5fdeb6e713aef85c25c9e2d661075535cf8d8c1", + "blockHash": "0x59eb05ad455dd8785b7a82a8ec0b14908b49b9b99b89438e48a64f2c35dbec5f", "transactions": [], "withdrawals": [ { - "index": "0x2a", + "index": "0x19", "validatorIndex": "0x5", - "address": "0xb71de80778f2783383f5d5a3028af84eab2f18a4", + "address": "0xeda8645ba6948855e3b3cd596bbb07596d59c603", "amount": "0x64" } ], @@ -6787,1704 +9207,1739 @@ "excessBlobGas": "0x0" }, [], - "0x3e6f040dc96b2e05961c4e28df076fa654761f4b0e2e30f5e36b06f65d1893c1" + "0x8d4a424d1a0ee910ccdfc38c7e7f421780c337232d061e3528e025d74b362315", + [] ] }, { "jsonrpc": "2.0", "id": "np292", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd8f175dd35dd4a5d97e51309a5fdeb6e713aef85c25c9e2d661075535cf8d8c1", + "parentHash": "0x59eb05ad455dd8785b7a82a8ec0b14908b49b9b99b89438e48a64f2c35dbec5f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6a53dd10b53014df9fed6a4ae0fee8fc21111c58421916e9c770906b7676cbaf", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x602b8a0196a45e1c76fcfb3da25e5ab5577be52d365fbd68a7574f02fd9c5a21", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x124", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xb68", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x56a449bf5c7dba876a8f68b55d9dbbb06c0dddd3c5f586ec4a95317a0f00c79d", + "blockHash": "0x8aff95cd5730ce6970eca865968ba524b1e66c7688319793c6edaa11791b0a33", "transactions": [ - "0xf88281ea08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a04efd756d15757c98077f04c9f50a22f7e74b1f28f970614a6824b4a406c11d0ba01c4bc3461a415a9c4dbfd4406c3c684a5427ce1490c93d7a9f5e43891dedc709" + "0xf88382010b088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0c0d1b53f8fa79401d3b27c1e82ed9e037a75cb9b147879399c9fe3c1084e8357a031aa98f702ea2eb4f7940dac34ac8c9d1ee30292458599593b553534af013f67" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x07e71d03691704a4bd83c728529642884fc1b1a8cfeb1ddcbf659c9b71367637" + "0xfa65829d54aba84896370599f041413d50f1acdc8a178211b2960827c1f85cbf", + [] ] }, { "jsonrpc": "2.0", "id": "np293", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x56a449bf5c7dba876a8f68b55d9dbbb06c0dddd3c5f586ec4a95317a0f00c79d", + "parentHash": "0x8aff95cd5730ce6970eca865968ba524b1e66c7688319793c6edaa11791b0a33", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x82f613ee711de05f2cc6a4a107500bdd5045f1ba99ce2738222f343f6081efe6", - "receiptsRoot": "0x2c3a6865afbff0ff9319c72cb9974b085dfe9a34eb9b34e0f4bc267272a883ca", - "logsBloom": "0x00000800000000000000004000010000000000000000000000000000000000000180000000000000800000400000000000001000000000000000100000000000000000000000000008000400008000000000000000000000001000000004000001000000000000000008000000000000000000000000000000000000000000000000000000000000090800000000000000004000000000000100000000002400000000000800000000000000000000000000000000000000000000000000000000000000000000000000200001000000000000000000000000000000000000002000000000000000000200000040000000000008008000000000000000022000", + "stateRoot": "0xfffd80f0432d0b41f5c21f59c2310f41a6d0f518a02fefecfd70a262d28bd1b7", + "receiptsRoot": "0xcac9bc12b1a5ea1f1749945728fc4827d6be026580117754514f28543ea90065", + "logsBloom": "0x00000800000000000000004000010000000000000000000000000000000000000180000000000000800000400000000000001000000000000000100000000000000000000004000008000400008000000000000000000000001000000000000001000000000000000008000000000000000000000000000000000000000000000000000000000000090800000000000000004000000000000100000000002400000000000800000000000000000000000000000000000000000000000400000000200000000000000000000000000000000000000000000000000000000000002000000000000000000200000040000000000008008000000000000000022000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x125", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", "timestamp": "0xb72", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x45a502a5a428913c585b13dbdd0857fbf4ffc3e928b942b5e96c98aced1a1736", + "blockHash": "0xe9652de769d861b7ae1ff71d6086d0049ff01ee57126e7b37f8acb1009efdcb7", "transactions": [ - "0xf87981eb0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a03cbaa69de647fe3ea352a6e71bab2ee53555fb8ab88c5e68efe28f2e5d687b9ea063c88d4e12b282eb4075d28f2fc6f36c7017ed0d91e36dbfd9d63a358e96abac" + "0xf87a82010c0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0bd455370a23cf28aba44289a9d2d01f09d02e24617a22c876330c1a634e5cfe2a0533da1d94bf07e6d9f5c1fbf84ba789600fa7db1d43672012af0c66c72ae610c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf4d05f5986e4b92a845467d2ae6209ca9b7c6c63ff9cdef3df180660158163ef" + "0xda5dfc12da14eafad2ac2a1456c241c4683c6e7e40a7c3569bc618cfc9d6dca3", + [] ] }, { "jsonrpc": "2.0", "id": "np294", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x45a502a5a428913c585b13dbdd0857fbf4ffc3e928b942b5e96c98aced1a1736", + "parentHash": "0xe9652de769d861b7ae1ff71d6086d0049ff01ee57126e7b37f8acb1009efdcb7", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x291d2f7ab3a39d6c34a1b1c66e69262273221f6a8b2bac448e37e64da2330694", + "stateRoot": "0x223b61f461d72039063ef208e4d34ade4ab6182ac9286802e92e34ed451da91f", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x126", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", "timestamp": "0xb7c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x00f4447478e16a0e4dbe26e2398381d77367268754921e89d20bb152c1648910", + "blockHash": "0x62defc14b1b4b19b963574f0ddbe0b887a8017d28661a9d889c55729a388a40b", "transactions": [ - "0xf86481ec088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0aa81d6aa3b28238a33a52a3e3b5f00fa2300402a222f10c0e7451318b3f81e25a0223f13ffcec992f0ed7592df411b58352aad6d277dd16e7d0a55e5ab5702a18a" + "0xf86582010d088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a05c79f636d4fff235cf268f4628807ebaf6f678544021908341b8042efc4b4dfaa062ccc5326a5c336e6ec4c42b4c5914b316ccb5a01241a866d21f447b4bc4f828" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x5ca251408392b25af49419f1ecd9338d1f4b5afa536dc579ab54e1e3ee6914d4" + "0x16243e7995312ffa3983c5858c6560b2abc637c481746003b6c2b58c62e9a547", + [] ] }, { "jsonrpc": "2.0", "id": "np295", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x00f4447478e16a0e4dbe26e2398381d77367268754921e89d20bb152c1648910", + "parentHash": "0x62defc14b1b4b19b963574f0ddbe0b887a8017d28661a9d889c55729a388a40b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe3e06a047edd89fc5a4f9ee475d8e10ace0a0bae37ad4df6613a6077870fcae4", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x24c2880a28d4e01ecf7bfd004e4dde71ac8b2eceae57ca38aef54b5cafaafb68", + "receiptsRoot": "0x9f1aec51311c99ff2556e7ae510cfc0e13b0b9568362b661cfe1caa4d333b386", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000008000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x127", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca90", "timestamp": "0xb86", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1480b67138d2eb8359bf102ee31219dea9776af6c7fed33e8f4847ce943365c4", + "blockHash": "0x98539ac0cea39c8cc5774cb783fa5993c03ab9e2dcc9e2e24ac18d9af67dacb6", "transactions": [ - "0x02f86a870c72dd9d5e883e81ed010882520894be3eea9a483308cb3134ce068e77b56e7c25af190180c080a0190737acd3a2a298d5a6f96a60ced561e536dd9d676c8494bc6d71e8b8a90b60a02c407a67004643eba03f80965fea491c4a6c25d90d5a9fd53c6a61b62971e7c5" + "0x02f8d4870c72dd9d5e883e82010e0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c5d741e496f004f3e656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0d2dcfcdea157f70f8422558eb02bdc6a503cf24126f8f2dc2b52a644f5f0227101a03988ba449890e872876769b683ea83684aa9dfab1698dbe8c583052e14772fb4a02965eafe834e54c031b9d56a8ba549ae0e0947f8cdab83a52f5ff3057da40ada" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe98b64599520cf62e68ce0e2cdf03a21d3712c81fa74b5ade4885b7d8aec531b" + "0xb75f0189b31abbbd88cd32c47ed311c93ec429f1253ee715a1b00d1ca6a1e094", + [] ] }, { "jsonrpc": "2.0", "id": "np296", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1480b67138d2eb8359bf102ee31219dea9776af6c7fed33e8f4847ce943365c4", + "parentHash": "0x98539ac0cea39c8cc5774cb783fa5993c03ab9e2dcc9e2e24ac18d9af67dacb6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8d04702ac0333be2a1e6ae46e4aa31fe4fe23f5458c6899a7fd8800d24162bc5", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xb2f3b4b778f8095c0150536a7d267de8df138835ae2815940481daad4a528535", + "receiptsRoot": "0x3eaa13309f383a89aaadf58231da7f07a8b193ca8772a87fb6c32ebf0ed7c164", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000100000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000002000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x128", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xb90", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5b6e5684623ac4835ad30948dca710bb10d4bf48695089a4eca9e472300f37d7", - "transactions": [], - "withdrawals": [ - { - "index": "0x2b", - "validatorIndex": "0x5", - "address": "0x1c972398125398a3665f212930758ae9518a8c94", - "amount": "0x64" - } + "blockHash": "0x84018a2df44823700329319d9aff27b73093f4284a45402e4a40958dde3ef298", + "transactions": [ + "0x01f8d3870c72dd9d5e883e82010f08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c526ae023b07bd13d656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0b3750ecb88b6e11e5f686cbacb3d24e61396cef4a1525b30d5a30edc4b3fdec080a0d21b4680a8c217acd22a05694031efcabec0311ec4c932df9f776e1a3799ba59a04b555912c1ed496307b90b872a43cfc1b9fafbcc370dd9c65dc691ce6e54e21e" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd62ec5a2650450e26aac71a21d45ef795e57c231d28a18d077a01f761bc648fe" + "0xd087eb94d6347da9322e3904add7ff7dd0fd72b924b917a8e10dae208251b49d", + [] ] }, { "jsonrpc": "2.0", "id": "np297", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5b6e5684623ac4835ad30948dca710bb10d4bf48695089a4eca9e472300f37d7", + "parentHash": "0x84018a2df44823700329319d9aff27b73093f4284a45402e4a40958dde3ef298", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb59802d3b42a67087c2362fe27807e97ea95f8894d734e3711d61768b0779cc5", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xe750fcd9e9232f9f78e3710665189f967d03b76d8d8ddbd667e961b3c7e53a21", + "receiptsRoot": "0x0d0970d40d588ca540695901d111652461d1246630331bf30cb857868404e0f2", + "logsBloom": "0x00800000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000200000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x129", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xb9a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5903dfb3ecee5d8bc0e0cc0208b17dfc9a0dc86de2eaaee48da23ea0877b6c87", + "blockHash": "0xe2c8b858ba858e6c7b73dbc23702f10a9a75117fbeaa447084be91921cfbe7f5", "transactions": [ - "0xf88281ee08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a01a3bb1f736220feefc5706b013d9cd88f2e5d5c1ee3398b15ba14e84ed6a12c9a078068efcdcd82d92408e849bb10f551cc406e796ff1d2e7d20e06a273d27dfdf" + "0x03f8fa870c72dd9d5e883e8201100108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c8a1488f31c40de0e656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0f9b648439e7b876f9aa1b178fc6381f44bcaee23754d8da33b2d44e78cf47bb183020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a05e89472cf12cb81f835386e94bfe860f236decc11fa90459166e73dbb264c336a0164dc5735512cbd95aaeb58f3e75044bbd10c59ae433dfa87179c1cfe915e6f2" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x4d3fb38cf24faf44f5b37f248553713af2aa9c3d99ddad4a534e49cd06bb8098" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xbc17244b8519292d8fbb455f6253e57ecc16b5803bd58f62b0d94da7f8b2a1d6", + [] ] }, { "jsonrpc": "2.0", "id": "np298", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5903dfb3ecee5d8bc0e0cc0208b17dfc9a0dc86de2eaaee48da23ea0877b6c87", + "parentHash": "0xe2c8b858ba858e6c7b73dbc23702f10a9a75117fbeaa447084be91921cfbe7f5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x18be7053419eb1d23d487c6a3df27d208a2f8973d17b6b3e78417df0d3ab1644", - "receiptsRoot": "0xa7318d908cd687d0e6d982ec99a33a54b0cb9d1bbe3782f31ae731231e79039f", - "logsBloom": "0x00000000000000000000000400000000000000000000000000000000000000000000000000000008000000000000000000000000040000000000800000000000000000000000000800000010000000110000000000000000000020000000000200000000000000000000000004000000001000000000000000000000000000040100000000000000000000000000200000000800040000080040000000004000000000000000200000000000000204000000000000000000000100000000400008008000080000000100000000000000000000000000000000000000000001000000000000000000000000000000001000000000000000000100000000800000", + "stateRoot": "0x917f884041821b758a575dfb1dc88c0b12796fdc1023c638ef6c9ad881ac82e1", + "receiptsRoot": "0x64750f5470b09938713b1ee31a83a785fc2d232be127c7f839bf78fe5bb0ab04", + "logsBloom": "0x00000000000000000000000000000000000000000000000000020000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000008000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x12a", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xba4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x19f2a0716399f123d47e625de34fb2d6fbeadc26b2993e89504e73db85248052", + "blockHash": "0x0a1092b8900b3db78271854ecef3b6b400f1fec980047d9ff07a130255a910f2", "transactions": [ - "0xf87981ef0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0dc80fe6320cc01dd2ab63a42dd099e2fa5e0a640e6ccdf8ed634ca0c7382bd9fa04b356107e6a61d8852e7dc24f02691a9bd203564fed22da46bc9d9cd560c3dd4" + "0xf87582011108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cf9a5cb54664ef5f8656d69748718e5bb3abd10a0a00f564c0588a89fc970c508b4377f92cdae44a4d9da6d1ce161d62dcf4b7dc534a02343246e2d82d714b18ce75beb3115172b7f680be54ea957410cc4a59d97f75b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x36e90abacae8fbe712658e705ac28fa9d00118ef55fe56ea893633680147148a" + "0x3ff8b39a3c6de6646124497b27e8d4e657d103c72f2001bdd4c554208a0566e3", + [] ] }, { "jsonrpc": "2.0", "id": "np299", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x19f2a0716399f123d47e625de34fb2d6fbeadc26b2993e89504e73db85248052", + "parentHash": "0x0a1092b8900b3db78271854ecef3b6b400f1fec980047d9ff07a130255a910f2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf704271ace032c151b512221e777247a677847e2588ffb6fdea3de9af775b059", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x5b6235b02e42e778f6d3c97d4e08e717c74b4674a305652e696c84789a899abe", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x12b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xbae", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x2d68907fbe46b2958a1e07b483359dd1e1ac8a6fa0b13e0a9c012cb5de4bf458", + "blockHash": "0xa1e26afee8565c8352f0dcc623e984f72d24e09e005aba99f916fdb7c3807ab7", "transactions": [ - "0xf86481f0088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa06074cb58acfc1417684962272c546809696c6d2110b75735b19852066839a38ea03bd4f9b9b32c074215420391000ce0358e01e65745d7a6aa5513c4f857dd6579" + "0x02f86b870c72dd9d5e883e8201120108825208944dde844b71bcdf95512fb4dc94e84fb67b512ed80180c080a0ff9e3913d23c05e13e847479ef40474942fb7cb8c8bbd8b6802587b50ccb69d4a02b1eb6dda4520f42c3b23c1c8334a1c0012b41370ae5652ebf3c07f3bbae72f0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x164177f08412f7e294fae37457d238c4dd76775263e2c7c9f39e8a7ceca9028a" + "0x4d0f765d2b6a01f0c787bbb13b1360c1624704883e2fd420ea36037fa7e3a563", + [] ] }, { "jsonrpc": "2.0", "id": "np300", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2d68907fbe46b2958a1e07b483359dd1e1ac8a6fa0b13e0a9c012cb5de4bf458", + "parentHash": "0xa1e26afee8565c8352f0dcc623e984f72d24e09e005aba99f916fdb7c3807ab7", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0d6f0609afeda40249aad175bb482c3560b6f0e2fb612addd06c6f3953662531", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x38eb1f6c274b1f9babffc45e581441e4896d82c332ec61d562f5f4e94e11bbf4", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x12c", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0xbb8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe7554d8e76e3ae2d92eceade591334e211020b97e176762c99573ba526c7fdc6", + "blockHash": "0xdba21acb5043d419d3e972fad568d8e6179cffb0654e73c7f093a48877f38e9c", "transactions": [ - "0xf86781f1088252089408037e79bb41c0f1eda6751f0dabb5293ca2d5bf01808718e5bb3abd109fa0e3edf14f32e7cacb36fd116b5381fac6b12325a5908dcec2b8e2c6b5517f5ec5a051429c4c1e479fa018b7907e7e3b02a448e968368a5ce9e2ea807525d363f85e" + "0x01f86a870c72dd9d5e883e82011308825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c0180c001a0cd7d371b7e0f8162c06104886a132576bf82ae6a13250bd07db3e91dd3eeb879a038ade257128163d69601b8640d431ebf72fc3b45d47a3276a23eac921a643f57" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xaa5a5586bf2f68df5c206dbe45a9498de0a9b5a2ee92235b740971819838a010" + "0xf6f1dc891258163196785ce9516a14056cbe823b17eb9b90eeee7a299c1ce0e0", + [] ] }, { "jsonrpc": "2.0", "id": "np301", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe7554d8e76e3ae2d92eceade591334e211020b97e176762c99573ba526c7fdc6", + "parentHash": "0xdba21acb5043d419d3e972fad568d8e6179cffb0654e73c7f093a48877f38e9c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4ebd469b936b8d119664429fa99c55d75c007d4d12b7eb4db058248fa52b7f46", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x8a186f5fa70bc32b4def07f2f57dc4f6179ea83d21554890bf9a7286f81638cb", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x12d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xbc2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x20cae70a3b0dbe466c0cb52294f4a0fcc2fdae8e8e23a070cfa0ebe6a9fabab9", - "transactions": [], - "withdrawals": [ - { - "index": "0x2c", - "validatorIndex": "0x5", - "address": "0x1c123d5c0d6c5a22ef480dce944631369fc6ce28", - "amount": "0x64" - } + "blockHash": "0x4d7b2d7c56da60a9b57c4210cdedba40311978ea1aebf519aac65867e16f6a3e", + "transactions": [ + "0xf86882011408825208940c2c51a0990aee1d73c1228de15868834155750801808718e5bb3abd10a0a0fe2259e6d738f53a75a9a67fddb88bffd1ccf316b25a1666ae5e90d907128a0ca033c772738145475a5a6aaae112d3b1ee7ee5ef23ad1ec4c39b78632c1afdedbe" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x99d001850f513efdc613fb7c8ede12a943ff543c578a54bebbb16daecc56cec5" + "0x1dbf19b70c0298507d20fb338cc167d9b07b8747351785047e1a736b42d999d1", + [] ] }, { "jsonrpc": "2.0", "id": "np302", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x20cae70a3b0dbe466c0cb52294f4a0fcc2fdae8e8e23a070cfa0ebe6a9fabab9", + "parentHash": "0x4d7b2d7c56da60a9b57c4210cdedba40311978ea1aebf519aac65867e16f6a3e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4e0e374db1e769d72af232e15f83b61024ab42a410b4088ad54ae31fb7ab24c2", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x74dfc7e86aea9f99ad82259ee8bca79aa19d7b9c129773af3bccb6ef49758f9a", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x12e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xbcc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8088940507cc523f7c12bcec9729eed01e631ccef6faa8a6413a89d77f109c0b", - "transactions": [ - "0xf88281f208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a03f816a6f00b46ffee7ae7dc0a8472c822003d7f175c03fc883435b5303662e29a053e91a9fcfb952b9d2ee2d3017e3d02c8988bb4abcb9c343b66d90094e9b9817" + "blockHash": "0x5ee998d96985103ae9e6f31a41ee0d44a4da62003a63b5ff4f29570aa42ddee4", + "transactions": [], + "withdrawals": [ + { + "index": "0x1a", + "validatorIndex": "0x5", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x30a4501d58b23fc7eee5310f5262783b2dd36a94922d11e5e173ec763be8accb" + "0xc3b71007b20abbe908fdb7ea11e3a3f0abff3b7c1ced865f82b07f100167de57", + [] ] }, { "jsonrpc": "2.0", "id": "np303", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8088940507cc523f7c12bcec9729eed01e631ccef6faa8a6413a89d77f109c0b", + "parentHash": "0x5ee998d96985103ae9e6f31a41ee0d44a4da62003a63b5ff4f29570aa42ddee4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5cd39242444b2f075de43272eb00a7435191e5d07d4da17022f05f91167f8a71", - "receiptsRoot": "0x8c5ae4043b8c3ac3c3faf57678b01a0a80043b682d0a8ae2681dc5c892d7a562", - "logsBloom": "0x00000000000000008000808000000040000000000008000000010000000100000000000040000000000000000000001000000000000000000000000000000000100004000000000000800000000000000008008000000008000000000000000020000000000000000000000000000000000000040000000400000000000000000002000000000000000000000000000000000060000000000000000010000000000000000000001020000000080000400000000000000000000000000000000000000400100000000000000000000000200000400000000000000000800000000000000000000000000000000000000010000000004000000000000000000000", + "stateRoot": "0x153776d17db6371e53f002afb53b2db67197ef79d802bf1500ea8cf0196cc1ef", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x12f", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xbd6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3cfeeb3c000dbf1a34a7d601bacf17a26ab0618b14a821b61f847d10d41dd47d", + "blockHash": "0x81db24e85960807d0f347bacc0364a9327e64955fecca02ab5fcc55efdc4a37f", "transactions": [ - "0xf87981f30883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0cdff6973fabfb503b56e50264fa9d542805c351a2cf282d14e9a7e3f90df3bcea03fc2b2ef3d6e5c8d141f20dab6ea64a6ad2f7c5ab3da95c98cff7a73429036a1" + "0xf883820115088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a08cddb5ad687d9cfb5635935429f6bc6f73da0d0f14602aedb753d50fb90c11cfa04481220f6b763ec9de7a2ea8a2e64af551a6b90dd3d95d135deab8442aafd85b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa804188a0434260c0825a988483de064ae01d3e50cb111642c4cfb65bfc2dfb7" + "0x3f45edc424499d0d4bbc0fd5837d1790cb41c08f0269273fdf66d682429c25cc", + [] ] }, { "jsonrpc": "2.0", "id": "np304", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3cfeeb3c000dbf1a34a7d601bacf17a26ab0618b14a821b61f847d10d41dd47d", + "parentHash": "0x81db24e85960807d0f347bacc0364a9327e64955fecca02ab5fcc55efdc4a37f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb8480fa4b2321e09e390c660f11ec0d4466411bae4a7016975b2b4fd843260dd", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xf9fc5c25631e000a316925fb6b7190dd60ad610dc5866db54c1bc91c412f1aa6", + "receiptsRoot": "0x8499e3e63985d28600cbd00c0cffcd173218e8c1df3db90d1ab97a16e7c6e9b7", + "logsBloom": "0x00000000000000002000000000000001000000000004000000000000800000000000000001020000000000000000100040000000000000000000400020000000000000000000008000000000000000000000000000000000000000000000000000000000200000000000000000000050000000000000020040010000000000000000000000020000000000000000000000000000000000000000000000000080000000000000000000010000000010000000100000000000000010000000000000900000004800000020000000001000000000000000000000000000000000000000000400000000000000000000080000000000000000000020000000000008", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x130", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xbe0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xcb128d5be67707747d086abaf2a724879f3a54b7ca2bda6844678eb52a2d225f", + "blockHash": "0x9cbca6aa8b06935a740ab85580674c5cd4b2a840d078c92e005294241a7eac81", "transactions": [ - "0xf86481f4088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0ceb79cfa45773ae766de6daf76c67f63fbf14c7cd3853b6cd9ba8cd7cd1608baa019c783f138465d2c59039c902cc9b90cbff0e71a09672939e2373390b1f8c4c5" + "0xf87a8201160883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa039c0aabe6c9bd83ba7ce680430dae1ebfcd48db47589f2e66855d8869c0c9480a0175f7631a70797beed4bd4d075cadc7d86d638def72c6a2644cc767662bc24a0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc554c79292c950bce95e9ef57136684fffb847188607705454909aa5790edc64" + "0xcb8f5db9446c485eaae7edbc03e3afed72892fa7f11ad8eb7fa9dffbe3c220eb", + [] ] }, { "jsonrpc": "2.0", "id": "np305", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcb128d5be67707747d086abaf2a724879f3a54b7ca2bda6844678eb52a2d225f", + "parentHash": "0x9cbca6aa8b06935a740ab85580674c5cd4b2a840d078c92e005294241a7eac81", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x022e2901949be09d1a92be5055ced3cd0770b41c850daf830834dc7da22c9af3", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0xfc236631b79f578cf1f730acf4ea9cd3083f4c12d72fa4d909968a88bfa2f1ee", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x131", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xbea", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x36ddc7075c24073ea0b9b997ebf4a82596f13b41a831293600aaf876d5d1e0e0", + "blockHash": "0x5121438babb00581bb8862b84bfedfa4d586d59b08f7de67cad8988693061458", "transactions": [ - "0x02f86a870c72dd9d5e883e81f5010882520894f16ba6fa61da3398815be2a6c0f7cb1351982dbc0180c001a08dac03d829e6f8eab08661cd070c8a58eed41467ad9e526bb3b9c939e3fd4482a02ac7208f150195c44c455ddeea0bbe104b9121fef5cba865311940f4de428eec" + "0xf865820117088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0e6ec4a35afc15586c4dd750e4610c8b5401687e10ad12f251a4c56f663a8d9dca04c89c681c9d15f4059cc1bfc3e0ccb2228b8d757e810671e8548d5c3ae36a295" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc89e3673025beff5031d48a885098da23d716b743449fd5533a04f25bd2cd203" + "0x3d151527b5ba165352a450bee69f0afc78cf2ea9645bb5d8f36fb04435f0b67c", + [] ] }, { "jsonrpc": "2.0", "id": "np306", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x36ddc7075c24073ea0b9b997ebf4a82596f13b41a831293600aaf876d5d1e0e0", + "parentHash": "0x5121438babb00581bb8862b84bfedfa4d586d59b08f7de67cad8988693061458", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xec2a36c595c95a6b095a795e22415b66f5875f243697e72c945361b4f440c3bc", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xac1f35c169de27ab0497059cb09328b0e2f70022723b371d66a94f99db12baab", + "receiptsRoot": "0xc60042a0f586b4655b929d1f35cf04df2a18799eb4ff8258d47b6b643ab92d14", + "logsBloom": "0x00000000000000000000000000000000004000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x132", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xbf4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x90eae29a9b788583ec3624dac546f4372b97d2b1b58edbcca1b9f82e62b0d3c6", - "transactions": [], - "withdrawals": [ - { - "index": "0x2d", - "validatorIndex": "0x5", - "address": "0x7f774bb46e7e342a2d9d0514b27cee622012f741", - "amount": "0x64" - } + "blockHash": "0x2c00478ccf60b7813adf88eae40d7f36cb2bb19d7d3a5e41904411d59f85b85a", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8201180108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cc45ec4c5c9153907656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a04d4855c520c09f3435e2cb46ceb4d2a12df59c127a1f2e871e7e9e8203fd6ce180a065dc63e2ecf0ec0098c02f9d874bb7809d9ea529e99a35efd267944f9f021d6ea057461847abc4de428ee5deca8fa2a6dde61d653ee897a03134d6ab1111edbcfe" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x44c310142a326a3822abeb9161413f91010858432d27c9185c800c9c2d92aea6" + "0xdd96b35b4ffabce80d377420a0b00b7fbf0eff6a910210155d22d9bd981be5d3", + [] ] }, { "jsonrpc": "2.0", "id": "np307", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x90eae29a9b788583ec3624dac546f4372b97d2b1b58edbcca1b9f82e62b0d3c6", + "parentHash": "0x2c00478ccf60b7813adf88eae40d7f36cb2bb19d7d3a5e41904411d59f85b85a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x427bbc009fe03135af46fb83f7cdcf27c022159be37615c8caceff14061d2f1f", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x09ae7bf54009cd877f0f4133dd934f1a7ffd44ce1700eca8ddc4fc3dd47a9138", + "receiptsRoot": "0xc6bbe32048f874de5ca9d433a0888e2d71c39fa006e27ba75a563a3f15860984", + "logsBloom": "0x00000000000000000000004000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x133", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xbfe", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xdce2eeeafbf4e8ff4dbfa786434262fe7881254d7abcea2eabca03f5af5aa250", + "blockHash": "0xbd2d25d7773172160974f1a8b6b790c629e44a011321c53a0cb08888b9cac459", "transactions": [ - "0xf88281f608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa07b4f78cff0cb04bb8cb3d81e0aabef7b54c34db7438322bc8c1554448a37b027a00b760535ea891c9b4af5c70ac5726b3829418f5b21632aa8dda9ed2a91a7e30f" + "0x01f8d3870c72dd9d5e883e82011908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ce355c4e09ad571c8656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a038570ba11cfca6a25bea615c7ec09ae671516245a92a5f8fc61d2e82529454e880a021fc4049285e37a5ffddc71b565a74354b78b3ae23768ddd78f4f89769cca8d2a0506f4888cd6ac4b74e51e1fd2f41c9413ac7dc3e7164594bdd19a9bddb0d13a7" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xae3f497ee4bd619d651097d3e04f50caac1f6af55b31b4cbde4faf1c5ddc21e8" + "0xace0c30b543d3f92f37eaac45d6f8730fb15fcaaaad4097ea42218abe57cb9f4", + [] ] }, { "jsonrpc": "2.0", "id": "np308", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xdce2eeeafbf4e8ff4dbfa786434262fe7881254d7abcea2eabca03f5af5aa250", + "parentHash": "0xbd2d25d7773172160974f1a8b6b790c629e44a011321c53a0cb08888b9cac459", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4b11a079f7e911f563ce2c7a0bcda57feaea847b827bfceb4b0f0a1fde490e41", - "receiptsRoot": "0x2cea15106bcab9c8122ea9fc8d7b5ace9f0650a79134ad9732b933221eb0c440", - "logsBloom": "0x000000020000080000000000000000000000000000000000800000000000040000000001000000000000000000000001010000000010000000000000800000000000000000020008000080000000000000000000000000000000000080080000000000000000000000000200000100000000000000000000000002001000000000000000000800200000000000000000000000000000002000000000020020000008000000000000000000000000000000000000000000000000000000000100000000000004c0000000000000000000000010000000000000200000000000000000000000000010000000000004000200000000000000000000000000000000", + "stateRoot": "0x447376f436dbcd45154e2d2bcd6ddfe920e413f2ef9a075ba4caae45548871f5", + "receiptsRoot": "0x3ae89f3114f462c13ae1e0805dbcc594921657a098d21c128f119a43a13ef1d7", + "logsBloom": "0x00000000000000000000000000000000000000000800000000000000800000000000000000000000000000000000000000010000000000000000008000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x134", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xc08", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd619d2e9c151c94d9610527d55ab721a092f2566b79a92821e4c7c8a106cce4f", + "blockHash": "0xa8a4ee8234dac48e460f619c77d02008ff818db6cf1a0a80de6a81af3e0d7e91", "transactions": [ - "0xf87981f70883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a03d6fef2d466b342db8155272b9e676d55fdc0fedab7d1fce3b3be54459203a44a016b740412be1021d3f480fbf75fa6733d5a233489a0e1cf72bf56c8b37a0ef80" + "0x03f8fa870c72dd9d5e883e82011a0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c7906a8e7d74f757e656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0befb4ff6aefe6c4d85158d11057517eb9cb1e1cae3e9d2d9c90ff40b2cceb54683020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a007d97ba541e40dea07923e06265c253c519d279feb2e3e53a79e72946e3b66ada06f694b98cad48d402d39ce4d034fc8ca75f5ebee4b4bb9b1a2eb67c188a49435" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x3287d70a7b87db98964e828d5c45a4fa4cd7907be3538a5e990d7a3573ccb9c1" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xf6342dd31867c9bef6ffa06b6cf192db23d0891ed8fe610eb8d1aaa79726da01", + [] ] }, { "jsonrpc": "2.0", "id": "np309", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd619d2e9c151c94d9610527d55ab721a092f2566b79a92821e4c7c8a106cce4f", + "parentHash": "0xa8a4ee8234dac48e460f619c77d02008ff818db6cf1a0a80de6a81af3e0d7e91", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0d7fe7c7c5e17180dd3c5d11953d20c0df05569d83f29789680311e835d44c92", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xf90b6e0f42a055c9b33ca1ca15998bf55c39408aa568028028daa46d9ff67c14", + "receiptsRoot": "0x0afed92b676a3b1e3c4945631c2f35f307b341f6fcc961101935f91fbf6a2475", + "logsBloom": "0x00000000000000000000000000000200000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000008000000000000004000000000000200000000000000000000000000002000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x135", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xc12", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x722090df82f4d2bf93cc1d092239e427a1ed045284bc56b5aa142b02d2cb3955", + "blockHash": "0x11ddcb0efb438a2965ba558170ed3ccb27ac43bc3f7028628edcb3406a1d4623", "transactions": [ - "0xf86481f8088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0b82807e311788292f679bc187111f494eb67171b03e417afdfb54e17f53b9ecfa05d9e1261b6bd95693c5e7859fa6e9ac0f380083750f46dec3f5058026c00aa54" + "0xf87582011b08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c34cb6faed8212f15656d69748718e5bb3abd109fa09e8eed2041c0b3fb16bc35e8ef8410ba6a311729651c095c3dd63a2de47e79c8a056b251d337e880ef0a3377774c6b911689f29cf74fecf094438e39f5d59c2cee" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb52bb578e25d833410fcca7aa6f35f79844537361a43192dce8dcbc72d15e09b" + "0xa6589e823979c2c2ac55e034d547b0c63aa02109133575d9f159e8a7677f03cb", + [] ] }, { "jsonrpc": "2.0", "id": "np310", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x722090df82f4d2bf93cc1d092239e427a1ed045284bc56b5aa142b02d2cb3955", + "parentHash": "0x11ddcb0efb438a2965ba558170ed3ccb27ac43bc3f7028628edcb3406a1d4623", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x97742ddf818bf71e18497c37e9532561f45ff6f209555d67e694ec0cec856e7e", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x1e2b5442751f07806f0aa28e34525050adbff63fa3f8e6a882c3915d87656f05", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x136", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0xc1c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x81f5ce1e85499179e132dbe7b9eb21403c7f3df276820c668ed86a018065dbfa", + "blockHash": "0xccff97103894795edef27f3a29b05a2109a4f024d3c935233faff6be394b92f7", "transactions": [ - "0xf86781f9088252089417333b15b4a5afd16cac55a104b554fc63cc873101808718e5bb3abd109fa0f2179ec11444804bb595a6a2f569ea474b66e654ff8d6d162ec6ed565f83c1aaa0657ed11774d5d4bb0ed0eb1206d1d254735434a0c267912713099336c2dc147a" + "0x02f86b870c72dd9d5e883e82011c0108825208942d389075be5be9f2246ad654ce152cf05990b2090180c080a00a17151e389df51a00e7bf3feadef3191ea0ad38ec1be3fd7476baacdfe7d8eba04cdbe251df1c62cb3f1d59821bc6353909447d7267a172254f184967500e515f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xff8f6f17c0f6d208d27dd8b9147586037086b70baf4f70c3629e73f8f053d34f" + "0x9ce48bc641cc1d54ffdb409aab7da1304d5ee08042596b3542ca9737bb2b79a8", + [] ] }, { "jsonrpc": "2.0", "id": "np311", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x81f5ce1e85499179e132dbe7b9eb21403c7f3df276820c668ed86a018065dbfa", + "parentHash": "0xccff97103894795edef27f3a29b05a2109a4f024d3c935233faff6be394b92f7", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5feed3f1d6bc9de7faac7b8c1d3cfe80d29fbf205455bc25ac4c94ff5f514ca3", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xf595ac6b9f66304ef0c2e38e43c9b96ab2360dc87317a74c84eef96614e093c1", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x137", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xc26", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x685678cda85d28dbe24cd7ef896866decc88be80af44933953112194baeb70df", - "transactions": [], - "withdrawals": [ - { - "index": "0x2e", - "validatorIndex": "0x5", - "address": "0x06f647b157b8557a12979ba04cf5ba222b9747cf", - "amount": "0x64" - } + "blockHash": "0xaac581c002035b4c80879f87a1418a3129921f493472482a52b09d0fb6233f04", + "transactions": [ + "0x01f86a870c72dd9d5e883e82011d08825208941f4924b14f34e24159387c0a4cdbaa32f3ddb0cf0180c001a03cb049339eda9bb3c16ca7a3cd92102728378f3d2d232f60d3b45323d821eb8fa004242cea89f245dd65d9a0180c437b23e265a262607b7785eab2683e1779fe1f" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x70bccc358ad584aacb115076c8aded45961f41920ffedf69ffa0483e0e91fa52" + "0xa44be801bd978629775c00d70df6d70b76d0ba918595e81415a27d1e3d6fdee9", + [] ] }, { "jsonrpc": "2.0", "id": "np312", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x685678cda85d28dbe24cd7ef896866decc88be80af44933953112194baeb70df", + "parentHash": "0xaac581c002035b4c80879f87a1418a3129921f493472482a52b09d0fb6233f04", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xde4840156998638689e0d07c0c706d3f79031636ae0d810638ecdd66c85516f4", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x7965f70a4268dacdca0ed3c4136a4d8c56dea966fdfa0bf518bd9404481270d2", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x138", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xc30", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xabbd38fb9a670e62ceca6b3f5cb525834dc1208cd8bc51b3a855932951e34ee3", + "blockHash": "0x7e3909c2f8ede6f928c0820363dbd9abb712eec9f7be844bfcf8d3d04a538bfe", "transactions": [ - "0xf88281fa08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa06193bab90c2a0e05f830df90babae78be711ea74e7fa7da80fb57bf1eac7b01ba007568dc41c59c9a3e9f4c46ad8bac850ecee5fdbe8add1a840db65266062453c" + "0xf86882011e08825208940c2c51a0990aee1d73c1228de15868834155750801808718e5bb3abd10a0a07eb9ca4cb5e5dc6d8a4a12a87d3176e97df25a11cef96653b54f5764840d31d9a0173cbdb2a5bb18932a30b3826c0fe27605f622eca7dbc36c42fca92e3ff94e0c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe3881eba45a97335a6d450cc37e7f82b81d297c111569e38b6ba0c5fb0ae5d71" + "0xce17f1e7af9f7ea8a99b2780d87b15d8b80a68fb29ea52f962b00fecfc6634e0", + [] ] }, { "jsonrpc": "2.0", "id": "np313", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xabbd38fb9a670e62ceca6b3f5cb525834dc1208cd8bc51b3a855932951e34ee3", + "parentHash": "0x7e3909c2f8ede6f928c0820363dbd9abb712eec9f7be844bfcf8d3d04a538bfe", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6fc93047d0ff562c8abee419aecf2b174b1c382f506dedcbb5ba04955cd985c7", - "receiptsRoot": "0xcd59afd93dd989872aa9f89197f533f1c6a90364b872e145f50ff782af2b758b", - "logsBloom": "0x00000000000000000000000001000000000000000000000010000000000000000000000800000000000000000000000004011000000000400000001000000000004000000000000000080000000080000000000000004000800000000400001000000000000000000008000000800004000000000000000000000000080008000000000040000000000000000000000000000020000001000000000000000000000400000000000000000300000000000000000000000000000000400000000000000000000000000000000000000000000400000000000000000000000000000010000000000000001000000000000000010000000000000000400000000040", + "stateRoot": "0x12fe5f9fd18b1d449fd3c25d815c065e9782e2c28cda214d77b45560fc932896", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x139", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xc3a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x323e57df6d8869c18eac5a0746e2e3fa96645813704b4af06659dfea08d2473c", - "transactions": [ - "0xf87981fb0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0465ab07ff3930a9a8f24c5108701be4a0475480d72147e12305f9d67017af925a07b3dd5fbeae129ce4ea30381c15b2afd9be701e4969422415e07ecea3df82db1" + "blockHash": "0xbd1f3e51c77a927fc30973f8452ada7e030b8452273afd75dff18884af8a204c", + "transactions": [], + "withdrawals": [ + { + "index": "0x1b", + "validatorIndex": "0x5", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2217beb48c71769d8bf9caaac2858237552fd68cd4ddefb66d04551e7beaa176" + "0x4bd91febab8df3770c957560e6185e8af59d2a42078756c525cd7769eb943894", + [] ] }, { "jsonrpc": "2.0", "id": "np314", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x323e57df6d8869c18eac5a0746e2e3fa96645813704b4af06659dfea08d2473c", + "parentHash": "0xbd1f3e51c77a927fc30973f8452ada7e030b8452273afd75dff18884af8a204c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xcae6ffdf3092bcb2ebdc66df86177bce69bf2f5921e5c4d482d94f2fd5f6649b", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x3bbfaf4efde9a24437c51d9ae86ad6bf8287f5ebbd8fe8ebc15c3619a602c6d6", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x13a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xc44", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x36c686b156ca6fb1280730a2f86acfd8bcee71bb9666a473d00f0c7813fe5a2c", + "blockHash": "0xf976366428e1f9e79b69a03a333c3ea2d57804cafad16ea0301def95480afa16", "transactions": [ - "0xf86481fc088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0d92908e16f6965c17390bafa5649b05b9150b6db7cb63fccfa3d8ccc1f18ec7fa04082aba5936ac8d14c3f78d12f12d9437b575cebd82337c4499f2176afb74cba" + "0xf88382011f088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa02e045ae41ba056fdd3328bd0ac90d86f6f3add947c60dc848d79fdc23e242a84a00bf35d683f8fd6a4e287c87c7c8bccb31d736c126602c55917e4641e902124bc" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x06b56638d2545a02757e7f268b25a0cd3bce792fcb1e88da21b0cc21883b9720" + "0x414c2a52de31de93a3c69531247b016ac578435243073acc516d4ea673c8dd80", + [] ] }, { "jsonrpc": "2.0", "id": "np315", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x36c686b156ca6fb1280730a2f86acfd8bcee71bb9666a473d00f0c7813fe5a2c", + "parentHash": "0xf976366428e1f9e79b69a03a333c3ea2d57804cafad16ea0301def95480afa16", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x1220b41d89a79f31d67f2373ea8563b54fb61661818e9aab06059361fc1412ca", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x11f4b017e2e14ef950b5fb2ca09ea0e8546b9f9bb912ab2c493482b5af85b401", + "receiptsRoot": "0x874bf4080d916fe835dd08d3faffc7a4ebe2a8782654f36aae4b318a177e6e70", + "logsBloom": "0x00020000000020280000200000000000000000000000000000000100000000000000000000000000000000000080000000000000082000000000000004000000000000000000000008000000000040000004000000000000000000000000000000000000000000000000000004000000000000000000000000008080000000000000000000000000000000000000000000200000000000000000000000000000000000000000000010000000080240000200000080000400000000000000000000000000000000000000000000000000000000020000000002080002000010000000000000400000000000000400000000000800000000000000000000000040", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x13b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xc4e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe5456434219d6d602162c56859d7a24895a28aac0958bd46bef986d7d8cab2e0", + "blockHash": "0x3752f226d6f4f227e0d59f153fcdefff90cc3aa9566c14b02bf86a5ba7e5f740", "transactions": [ - "0x02f86a870c72dd9d5e883e81fd010882520894d20b702303d7d7c8afe50344d66a8a711bae14250180c001a067bed94b25c4f3ab70b3aae5cd44c648c9807cdf086299e77cf2977b9bce8244a076661b80df9b49579fce2e2201a51b08ecc4eb503d5f5517ecb20156fde7ec5a" + "0xf87a8201200883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0b220dbb522cd4c5abed86b07e4d87f62cd190c0bc3b535096a8006efc574b1e7a018a5c6b5be430f923a15c2b1b06de19dd8d1ac808da574f75e7c9254478fae01" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xebdc8c9e2a85a1fb6582ca30616a685ec8ec25e9c020a65a85671e8b9dacc6eb" + "0x647fb60bdf2683bd46b63d6884745782364a5522282ed1dc67d9e17c4aaab17d", + [] ] }, { "jsonrpc": "2.0", "id": "np316", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe5456434219d6d602162c56859d7a24895a28aac0958bd46bef986d7d8cab2e0", + "parentHash": "0x3752f226d6f4f227e0d59f153fcdefff90cc3aa9566c14b02bf86a5ba7e5f740", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x65c692f846c2dc380a912a71c1387fec7221a2b0fffae2451370c30ed15350d1", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xeee8e0dee166ef99e5fa64f9b7c3616cb8fccab712bbe198c9e17ceea46b5d86", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x13c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xc58", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa0f3387ab2dd15ebc6dc9522d5d0ee33f01548722c7fde856fb0f4f00fc6a7a1", - "transactions": [], - "withdrawals": [ - { - "index": "0x2f", - "validatorIndex": "0x5", - "address": "0xcccc369c5141675a9e9b1925164f30cdd60992dc", - "amount": "0x64" - } + "blockHash": "0xbd34ef105826797a46b3ccc8b4a82c61897bce87047aa90ca88d590887dcef52", + "transactions": [ + "0xf865820121088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a041a8dcd438529e1583b280d53972be37cc7ca049ce3643d8752f19e74c503de9a033fef9a4edbfc399a4652ebd1de044d19cde1cf51ee7c438d535c627d836439b" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x738f3edb9d8d273aac79f95f3877fd885e1db732e86115fa3d0da18e6c89e9cf" + "0xfa681ffd0b0dd6f6775e99a681241b86a3a24446bc8a69cdae915701243e3855", + [] ] }, { "jsonrpc": "2.0", "id": "np317", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa0f3387ab2dd15ebc6dc9522d5d0ee33f01548722c7fde856fb0f4f00fc6a7a1", + "parentHash": "0xbd34ef105826797a46b3ccc8b4a82c61897bce87047aa90ca88d590887dcef52", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3dc5f82b5983ab440abc575ac26ea2f4962c8c31f7e8721b537ea53d385827d5", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xc8f81fc12020b9daf991498ee4c67716c5e529cd6ea105b9620ebca5ca0062da", + "receiptsRoot": "0x4910e91c5e2a39c0c7abd39d435d5ee2788849ddfd7b6b0c5fe5d3dbede8f0a1", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000801000000000000000000000080000000000000000000000000000000000000000000000000000000000002000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x13d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xc62", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf0da8bf67d04b148efa37b1c72f83bad458c873c35390e45853916d2a6011efa", + "blockHash": "0xa2689bec112dc66781dfbbfe0877f3b56c055872e331b6d45acd6e8d97e046e6", "transactions": [ - "0xf88281fe08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0f5f035f73b86709cffa1134edc422e41e8ec49f3455943045c8571f4f12e8f6fa0659c80c0802ca16b9c71c90a8c1d7c32580b8dc2e33eb246d05e9c4920314a31" + "0x02f8d4870c72dd9d5e883e8201220108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ca4875981ed75b054656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a08a76d1e2fd58cc0018aa306e83990d74d16ba9aeab4794595fc72551f046547601a027fec5a40c1948d0ef8fb2c9b078ba930dc8d8592f691f20f104421b34aa7bf4a065e542ab66d86bf61ec21b6efa043928ad96a6e34cde2d1c44f103f1628927e1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xae5ccfc8201288b0c5981cdb60e16bc832ac92edc51149bfe40ff4a935a0c13a" + "0x106ca692777b30cb2aa23ca59f5591514b28196ee8e9b06aa2b4deaea30d9ef6", + [] ] }, { "jsonrpc": "2.0", "id": "np318", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf0da8bf67d04b148efa37b1c72f83bad458c873c35390e45853916d2a6011efa", + "parentHash": "0xa2689bec112dc66781dfbbfe0877f3b56c055872e331b6d45acd6e8d97e046e6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb0a0edf94f736c11dfd920d0d386b5857441067979baff670d45380f5ce9c2b2", - "receiptsRoot": "0xbe0275e0c21d0b23665e6d0b34bbb1669b585dfb6ef89c0903dcf8586ec86d00", - "logsBloom": "0x00000020000000000000000000000000000100000000000000000000000040000000001000000000000040000000001000000000000000000000000000000000000000000000000000000000000001000000000000000400000000000002000000000000000000000000000000000000004800000000000000000000000000000000000020000000001004000000000004000000000000000100000800000401008000000000000000000800000000000100000000200000000000002000000000000000020002000000000000000000000000000000000000000200004002000004000000000000000000080200000000000000000000000000010000000000", + "stateRoot": "0x2635a59927f7b04cd4536a0592c61c64bd6c746df1418ab57d7c318e9b7d057f", + "receiptsRoot": "0xfdf07728708e04bcc7e76047ee1911f309757477f5df93a25114e24b5630af7a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000009000000004000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x13e", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xc6c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9b47d293dedc13b8b02e999ebaf1bf25c233229acf97e7ff9e9491ffbdbcf859", + "blockHash": "0x3f028560d99874cc15a76dd76b7da32cdb9548a9e262b5c986bc62ae920e643a", "transactions": [ - "0xf87981ff0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a03b9f00d5731e51c973193cb6169cb8024b864d02e5347f287f8de4807e343922a04763ef63ac8ddc3fab7ccc70a4890b69fc944f330f5dd92f1b0266aaa6730eb6" + "0x01f8d3870c72dd9d5e883e82012308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c5bd1cbdccbb7a3a8656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0d5eb8e9a486b23e10cf0092ca8690e7bd6d6c90932960cdfa5da36d1e1f2042380a03e7e1bb13e2ca57486b2f72bbb4a64a7320520d20c4d8a37499a739a6090713aa038d501ca743320bb18155ced455be09ca9802c7715746d355db1942f04d3d57b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x69a7a19c159c0534e50a98e460707c6c280e7e355fb97cf2b5e0fd56c45a0a97" + "0x494ac6d09377eb6a07ff759df61c2508e65e5671373d756c82e648bd9086d91a", + [] ] }, { "jsonrpc": "2.0", "id": "np319", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9b47d293dedc13b8b02e999ebaf1bf25c233229acf97e7ff9e9491ffbdbcf859", + "parentHash": "0x3f028560d99874cc15a76dd76b7da32cdb9548a9e262b5c986bc62ae920e643a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe7a75428fc4aadb70c1e0ac2ae59a54df93458845525804742ae02a83d4f235e", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x11042b90c5b05bf61a5b314e291ecb32c4feb8964fb002a69c7334e0d74915de", + "receiptsRoot": "0xf2e9f16617598b8bd3b8029a0e67f45874e0fcdec0515e73f20f677a43ba6aa4", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000010002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000100000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x13f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xc76", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa2c25b920f18b7c73332a155d3ab99a4a88b6454f70c1bdfddfcbfe50311c702", + "blockHash": "0xa0755b0908be2efd8534b105a279c0045087852b3c412f2d3a888988e4fa475c", "transactions": [ - "0xf865820100088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa08c4b5e491ee67e169155453cdfc9f7ee6f122aeda5d73caf8337d6c29be1be3ca06b9a4038e45c6b5e858787dda6d1fe8d3c502a42996b4fe1abd2de1b834cf5fe" + "0x03f8fa870c72dd9d5e883e8201240108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c15917920cd0da2be656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a09575996f3ad6e9709d7122224335451a59395327d297fd7967004e8dc139130883020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a05a856ee6dffab5fbfd8e1c4ff819353145b18b607699bd9e634af1af2b9081d3a06ab060ac1af8ddfa65300f04c3c68a441c754f390cfa1255626c29391278e71d" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x4d2a1e9207a1466593e5903c5481a579e38e247afe5e80bd41d629ac3342e6a4" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x0ae4ccd2bffa603714cc453bfd92f769dce6c9731c03ac3e2083f35388e6c795", + [] ] }, { "jsonrpc": "2.0", "id": "np320", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa2c25b920f18b7c73332a155d3ab99a4a88b6454f70c1bdfddfcbfe50311c702", + "parentHash": "0xa0755b0908be2efd8534b105a279c0045087852b3c412f2d3a888988e4fa475c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xda3147e8c80cfa63013d1700016a432d64c00213231ac510ab15f7011eea14e8", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x6cfcc9ad804ee654482854af83dcdc7f83c693fcbe07c7188bcbbdddddf3927c", + "receiptsRoot": "0xef73cc140dd423c074df587c3d1dc998c1ef798f26acfcd7b4375010adedb9f5", + "logsBloom": "0x08000000000000000000000000000000000000000000000040000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x140", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xc80", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xde65dcf316b36cd1d205e6df4a905df46ceedb163133ebffbab07fb6225d246d", + "blockHash": "0xdc88273a8339355e4c23b544329f1564ff0f17cda095b1ec2dff43d3dd0e39ed", "transactions": [ - "0xf8688201010882520894dd1e2826c0124a6d4f7397a5a71f633928926c0601808718e5bb3abd109fa01f5208621cee9149c99848d808ee0fa8d57b358afbd39dc594f383b7f525f4c6a01960c6254e869f06cfa3263972aa8e7cc79aec12caa728515c420d35b1336c0e" + "0xf87582012508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ca0eb3590d415621b656d69748718e5bb3abd10a0a056263d5515ea59d6ea7821724b2d3600cd4ec52cfd38e5145999c1b46abbf679a003bd6826947fd80264e99af1ab05dc826e5f5545ab7d40be5c77c46a4a5e853c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd3e7d679c0d232629818cbb94251c24797ce36dd2a45dbe8c77a6a345231c3b3" + "0xd860c999490d9836cc00326207393c78445b7fb90b12aa1d3607e3662b3d32cd", + [] ] }, { "jsonrpc": "2.0", "id": "np321", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xde65dcf316b36cd1d205e6df4a905df46ceedb163133ebffbab07fb6225d246d", + "parentHash": "0xdc88273a8339355e4c23b544329f1564ff0f17cda095b1ec2dff43d3dd0e39ed", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x05dcc2c2d7e87e4e1d836888d7158131800d123c6b2de255ba83054dfa109b02", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x34c42ce2ae63c16b981127388494b5a674542730742e466dcfd45e6444c536be", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x141", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xc8a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf2fb525ebc86939eeafb51c320f9793182f89f7bc58ad12900362db56d9d4322", - "transactions": [], - "withdrawals": [ - { - "index": "0x30", - "validatorIndex": "0x5", - "address": "0xacfa6b0e008d0208f16026b4d17a4c070e8f9f8d", - "amount": "0x64" - } + "blockHash": "0xea4108c88374dcffd042b2fd53de46cc82aa3a0c1573c6228198529dd90ad350", + "transactions": [ + "0x02f86b870c72dd9d5e883e820126010882520894c7b99a164efd027a93f147376cc7da7c67c6bbe00180c001a0c0be9c595e579a6396a39470d43578ea9c7797439481f5a538a3e30968f54689a02aba0937f802edac589ec6bebf62ff7f4578c242cb7df2d1873d3ad2fecd8890" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd1835b94166e1856dddb6eaa1cfdcc6979193f2ff4541ab274738bd48072899c" + "0x9587384f876dfec24da857c0bcdb3ded17f3328f28a4d59aa35ca7c25c8102cf", + [] ] }, { "jsonrpc": "2.0", "id": "np322", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf2fb525ebc86939eeafb51c320f9793182f89f7bc58ad12900362db56d9d4322", + "parentHash": "0xea4108c88374dcffd042b2fd53de46cc82aa3a0c1573c6228198529dd90ad350", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5efe08d743bbae45240fc20d02ab6e38e923dedc1027cf7bc3caff52a138dc06", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x9c3444d082b3419f2c1aabbc3d270af0aa1d68c9f7d1d2f225955807b46129cb", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x142", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xc94", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x815a67d4526461c4d40a205f5e8cbd11964bd0ed1079edc334250475a0efe1f2", + "blockHash": "0x89aa4d141def4c923b06aed9552126683bfb54e96f310d8fbc98bdef21e3b319", "transactions": [ - "0xf88382010208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0f8cf692109b242d13af60f7def7e34fc16e4589de28a3fc445e83fece028b046a07ab0d98800bffd516adf4a56b048f67b4d5ffcf438c8463d82a0fe41509f51e6" + "0x01f86a870c72dd9d5e883e82012708825208940c2c51a0990aee1d73c1228de1586883415575080180c080a0bc2274e5af7d6af7375fabff23d452d07fccc3ab64e4a8255f456d403182d234a059110fbe12731f4269b029c5b17c1d30f337a2794516d08f30ecb4e953069068" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x1f12c89436a94d427a69bca5a080edc328bd2424896f3f37223186b440deb45e" + "0x4df8093d29bc0ec4e2a82be427771e77a206566194734a73c23477e1a9e451f8", + [] ] }, { "jsonrpc": "2.0", "id": "np323", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x815a67d4526461c4d40a205f5e8cbd11964bd0ed1079edc334250475a0efe1f2", + "parentHash": "0x89aa4d141def4c923b06aed9552126683bfb54e96f310d8fbc98bdef21e3b319", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe6408a88797a6a4177fdb082766f6f35cd304745d96ceec7ba85908cf887ba77", - "receiptsRoot": "0xf0fa46b5337f820bd96b8bf1a50706c91cf6e2d8a9bb0fd9859f0f80d60009e3", - "logsBloom": "0x00400000000000080000000060000000000000020000000000100000100000040000040000000004000010000000000400000000000001020400000000000000000000000000000000000000000000000000000000000100000000000000400000000000020000800000100000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000014000000008000000000000000000000000800000000004000000000000000000000000000000020000000000010000800000000000000000000000000000000800000000000000000000000000000000000000000000400000000010000000000000000", + "stateRoot": "0xc039aa511d618a79634afb4b7038f6674069cce2dd0ec0d1f97d195b836a9ac0", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x143", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xc9e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc80438a37c405d0d3748ca7c92fb89f010ba9b06bd2136b919b563978f1ae6c1", + "blockHash": "0x5e09d28a6f9e43be4a5f908f764b9c25db1fcb323d9af4d54a9a486721b6b766", "transactions": [ - "0xf87a8201030883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa04d42d5415cbd9d939ef53ef60dbdffb80d016dc6e0704059b94ea4c1d398a2c6a06276655ceed05dd6ed9d6adcb9bb38bf699ae5f7ad1d8e47871404cd3ca98a00" + "0xf86882012808825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c01808718e5bb3abd10a0a02fff8f6f955c6177c3f68cc124a27d9b3865e467cdd2cfe8575dfded052b350ba038ce7fd03ddd6880c63946f71a580a34831c38a4bcbba3de6665448fbcb7ad11" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xccb765890b7107fd98056a257381b6b1d10a83474bbf1bdf8e6b0b8eb9cef2a9" + "0xc56640f78acbd1da07701c365369766f09a19800ba70276f1f1d3cd1cf6e0686", + [] ] }, { "jsonrpc": "2.0", "id": "np324", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc80438a37c405d0d3748ca7c92fb89f010ba9b06bd2136b919b563978f1ae6c1", + "parentHash": "0x5e09d28a6f9e43be4a5f908f764b9c25db1fcb323d9af4d54a9a486721b6b766", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x38475f9f9a763356a2e995dd7ff0e2b3376078bd3048aa3d25bfec5257e1cf3f", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x88214fefb638436f3e36c6e8f552adff7a18e75de8ef1ca40c9115f9666e10e2", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x144", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xca8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1efad9b7aa7d15c849d6055ea15823066111fed8860177b6b0be3ed187a22664", - "transactions": [ - "0xf865820104088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0654811f90e5259072ba79ea3e5a6ca7bfe8659e198ded895d149d1fc2bfe0167a052842cb4b3a0b0f2d722ec25a5c948bb2b78c3cd2d750303a5869a8812f17eed" + "blockHash": "0xa8e614e1553ea89015d1c2d2d90ef31794bacd4f661a9b8ca0e8f57cb8358a99", + "transactions": [], + "withdrawals": [ + { + "index": "0x1c", + "validatorIndex": "0x5", + "address": "0x84e75c28348fb86acea1a93a39426d7d60f4cc46", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x8bbf4e534dbf4580edc5a973194a725b7283f7b9fbb7d7d8deb386aaceebfa84" + "0x7173d4210aa525eece6b4b19b16bab23686ff9ac71bb9d16008bb114365e79f2", + [] ] }, { "jsonrpc": "2.0", "id": "np325", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1efad9b7aa7d15c849d6055ea15823066111fed8860177b6b0be3ed187a22664", + "parentHash": "0xa8e614e1553ea89015d1c2d2d90ef31794bacd4f661a9b8ca0e8f57cb8358a99", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xda41e628e9aa8c362284b556f48a4e3f9e3e0daec75c7950cd5d4ea75b9f8223", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0xf3cfefcaf0d1829c13c22b2c2a272f81664f58b1264bd3d6ce81587433bad033", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x145", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xcb2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8cfb3cab3103d0431ed161ebec0a29ffce5b82e8fa5b00520169a8be360b9054", + "blockHash": "0x772516ae20b52f5521b3a703dd4fcecd98f348fa2f0523f85aa4b801d46b8a2d", "transactions": [ - "0x02f86b870c72dd9d5e883e8201050108825208941219c38638722b91f3a909f930d3acc16e3098040180c001a063adb9abb5014935b3dbf8c31059d6f1d9e12068a3f13bd3465db2b5a7f27f98a056f0f5bed39985d0921989b132e9638472405a2b1ba757e22df3276ca9b527fa" + "0xf883820129088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a08b5ea5a1d6a55227e31b8c30960a96dfddbe2cf11c4d54d294e3c13f31e80a4ca017c92582dacae25bc23fd2f006f45f478a8afab54135dfb63899a9ae4ec8f27c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x85a0516088f78d837352dcf12547ee3c598dda398e78a9f4d95acfbef19f5e19" + "0x89698b41d7ac70e767976a9f72ae6a46701456bc5ad8d146c248548409c90015", + [] ] }, { "jsonrpc": "2.0", "id": "np326", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8cfb3cab3103d0431ed161ebec0a29ffce5b82e8fa5b00520169a8be360b9054", + "parentHash": "0x772516ae20b52f5521b3a703dd4fcecd98f348fa2f0523f85aa4b801d46b8a2d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbcdb535ac430393001427eab3b9ff8330ae1c997c2631196da62db6c3c5a5a08", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xbd91b74f92f8b1f1512c0c16e4d4d6a0cff41ebcd1024b73a590b8190cf870cb", + "receiptsRoot": "0xb08f0d9dedf1fbd11cab90ab1cb4a13c5e5988497da8ed6abbbeb80482029125", + "logsBloom": "0x00000000000000000000000000020000000000000000000000000000000000000000010020000000000000000000000000000000000010000000000002000000040000000000000000000002000000008000000000000000000000000000000000000000000080000000000000000080001000000000000000000040000000000000004000000000000000040004002000000000000000000000040040000080000800000100000040040000000000000000000000000000002000800000000000000001000000000080000000000000000000000000000000000000800002000000000000000000000002400000000001000000002000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x146", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xcbc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xacef7ee8af09f4b94fc20d862eb2426993ad2e2807e22be468143ea8cb585d0f", - "transactions": [], - "withdrawals": [ - { - "index": "0x31", - "validatorIndex": "0x5", - "address": "0x6a632187a3abf9bebb66d43368fccd612f631cbc", - "amount": "0x64" - } + "blockHash": "0x40137062068c2bef8766bb8df571f0e0c341f3877dc1d7311c84177331165a5a", + "transactions": [ + "0xf87a82012a0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa03e1a10d66caaef6e2b05ea47a618cdb3d493e18deb0d1014c2cda62f2f63b41fa059eae72098410e95b8ac649e5cb4e89f88f4e8869afd63751232883dbb47ceb7" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x0f669bc7780e2e5719f9c05872a112f6511e7f189a8649cda5d8dda88d6b8ac3" + "0x5b605ab5048d9e4a51ca181ac3fa7001ef5d415cb20335b095c54a40c621dbff", + [] ] }, { "jsonrpc": "2.0", "id": "np327", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xacef7ee8af09f4b94fc20d862eb2426993ad2e2807e22be468143ea8cb585d0f", + "parentHash": "0x40137062068c2bef8766bb8df571f0e0c341f3877dc1d7311c84177331165a5a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf54751e3cc778e70000823cc9800dbecaf86c60afe48ddd4f942c9c26f606d6f", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xf79638445390b53b07ef4d608b9d08c40cbdef73771ed96e0524353c0870c483", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x147", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xcc6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x61642769719bcfbed733fd6b7c2cd51038dc1404f0e77f50c330ac8c9629b8c4", + "blockHash": "0xc10d42ae21c805f56d5f486087ab29e6c5f16d2743dceea53e68b4c4ec8c41de", "transactions": [ - "0xf88382010608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0af7d5214c1fa8aff20cfd3e89d0db2ff361cf5c23dae0823c6719d9bd3c3a996a0581c85fafb49fa0753c67f65e6ad04871fab4a72a9bf5d9ab3bd7aa33b230225" + "0xf86582012b088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa09671ecdeaae37b39f175061ce6dfe09d47d0b4234656fcd52771e7604356075ca059c42b5a6ddd0b2cb0438604a0770962df4c4e0b510a48b3daec27b10aab464d" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa7816288f9712fcab6a2b6fbd0b941b8f48c2acb635580ed80c27bed7e840a57" + "0x9129a84b729e7f69a5522a7020db57e27bf8cbb6042e030106c0cbd185bf0ab8", + [] ] }, { "jsonrpc": "2.0", "id": "np328", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x61642769719bcfbed733fd6b7c2cd51038dc1404f0e77f50c330ac8c9629b8c4", + "parentHash": "0xc10d42ae21c805f56d5f486087ab29e6c5f16d2743dceea53e68b4c4ec8c41de", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xaf3502d0a6862e2cde40bbf084cba5e582a0ba3b3bc0beec6791a712c3d171e3", - "receiptsRoot": "0x52236ae99e7647366a3e31ba24153828332656ea5d242e422ffca1dbf576701d", - "logsBloom": "0x00000000000000004000000000000000000000001010000000000000000008000040000000000000000000000000000000020000200000000080000000000000000000200000000000000021000000000000400000000020000000000000000000000000000080000200000102000000000000000000000000000002000000000000000000000000000000000000000800000000000000000000000088000000800000000000000000000000000000000000020200004000000004000000000000000000002000000000000000000000020000002000080000000000000000000000402000000000000000000000000000000000000000000000000000000008", + "stateRoot": "0x9c7b6d27985ea981fdacf1a7e5dd136d0d3de60b5bdfbd2c63aea8c1c31b661c", + "receiptsRoot": "0xec2e029e4137b461c04f9b94fdbda71b6f4249479b9adb0095317c11a399f011", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000010000000000000000000000000000000000000000000000000000400000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x148", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca90", "timestamp": "0xcd0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3acbeee2cb8786a166d6caf512afc82b72ed1ccbfbe39dd32dd53f842046866a", + "blockHash": "0xf37ed9b3c15bebe2c65743e7013c97fa8b75f97e8791a353c033c16171a82fe8", "transactions": [ - "0xf87a8201070883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a015a81314b3c04efc725ff998badcf9278fb668561e5f9cdd42336845be60ec6ea04c593cfd5526eaf42203a3e6b5020e612ddd4053fa3123f51ae02bf8dde98eb3" + "0x02f8d4870c72dd9d5e883e82012c0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c712fd7264800465c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a07a63090121e41c76eee07564883abe3bd839fb20a0d2513bc9bc524f6c16f88a80a0e2dc2c6fca7b8a278c94417088f7a8b8437187328bfd007920d513824b1bef35a0022bfdea3b75175f59d0447dec7ab34f0584df815d06f1e70ba9c7361f6f7f1e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xda5168c8c83ac67dfc2772af49d689f11974e960dee4c4351bac637db1a39e82" + "0x31a63d6d54153ab35fc57068db205a3e68908be238658ca82d8bee9873f82159", + [] ] }, { "jsonrpc": "2.0", "id": "np329", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3acbeee2cb8786a166d6caf512afc82b72ed1ccbfbe39dd32dd53f842046866a", + "parentHash": "0xf37ed9b3c15bebe2c65743e7013c97fa8b75f97e8791a353c033c16171a82fe8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2a4691469da94625b4626e0a10273a2854e342a71b0711acebc46c8553eb8f0e", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xaa3a2d4acb17ce1ea988794b3335606e349baf071a6418c4d2262737a78e2c21", + "receiptsRoot": "0x50d115fa5f6857f190b2f2e00f1f97beb32711184258c05a2d6334140958c2e6", + "logsBloom": "0x08000000000010000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x149", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xcda", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1c012e1db133493333b09aff51ca8a110b148221aaf1f28c3d21b41382b0d058", + "blockHash": "0x8271d4efd4a54b038c0cc02e2a437d7cc3d96aed9148763fb2825fcc1ca58a1c", "transactions": [ - "0xf865820108088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0f9f0dcc20f1b62b8c567ac92dc1fbf50908f8bcd504fff3a342de336052e66bea00d38043fb1b141dc3fa2b97eaf09bc490be62e1cf7c40b670503ce0fbd8f6dce" + "0x01f8d3870c72dd9d5e883e82012d08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c44ae3eac6b9e5d37656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0b5e95d5da3e73f937bfbc9b4990bfdbd865c6d3a3b50478657e20b507fac754180a067a4f15c1e36c36e16f90109a5d4ce480d2f1941ee0ec885fe89df52552e1b51a07e0c91908cb4177b81c87ecf6f6e6d7b1e642d29e441f698a8d431ed1ea3cdb1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x3f720ecec02446f1af948de4eb0f54775562f2d615726375c377114515ac545b" + "0x828641bcea1bc6ee1329bc39dca0afddc11e6867f3da13d4bb5170c54158860d", + [] ] }, { "jsonrpc": "2.0", "id": "np330", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1c012e1db133493333b09aff51ca8a110b148221aaf1f28c3d21b41382b0d058", + "parentHash": "0x8271d4efd4a54b038c0cc02e2a437d7cc3d96aed9148763fb2825fcc1ca58a1c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x44248f33cb76fe58bf53afa7a07e7b3d1d1efb1dcde8379ba1719d987a4cb83e", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x85f16877081694ae3dc66ee4b6d931e6a3f85d3a6b56055fc61a350430c8dc5a", + "receiptsRoot": "0x54f709424481c40c85d8249a8dd2d11c088ab7eae925a4150441225b960ac786", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000010002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000009000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x14a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xce4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4e325a3f368a7235db02d7e604501ef2b416494a13136c23026e9dd3a3f38547", + "blockHash": "0xa9505142d5e8f2f3585f3d753c6cc615395b9694739c2aaebfdfbd52ea22d378", "transactions": [ - "0xf86882010908825208941f5746736c7741ae3e8fa0c6e947cade81559a8601808718e5bb3abd109fa0edd3402a6c7a96114e4c8520d7bf3f06c00d9f24ee08de4c8afdbf05b4487b7da068cd4cf2242a8df916b3594055ee05551b77021bbea9b9eb9740f9a8e6466d80" + "0x03f8fa870c72dd9d5e883e82012e0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c9b8c3a423a55b426656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a791ce367786fdc4c5216c8b94dfe1076746e058166dabda25b5e6a3266ce85783020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0db2322624476ad46dd2320b019f59466ce8ebf0b9a56c2fb14349b334ad6911ca050725915ee3893eaa2709708aefe5d8daae00786aeb6cc44438bad13dd9271ad" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x273830a0087f6cef0fdb42179aa1c6c8c19f7bc83c3dc7aa1a56e4e05ca473ea" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x7e0752ddd86339f512ec1b647d3bf4b9b50c45e309ab9e70911da7716454b053", + [] ] }, { "jsonrpc": "2.0", "id": "np331", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4e325a3f368a7235db02d7e604501ef2b416494a13136c23026e9dd3a3f38547", + "parentHash": "0xa9505142d5e8f2f3585f3d753c6cc615395b9694739c2aaebfdfbd52ea22d378", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x30f652c6dbb2b9b0f66b7031f6fd0a8c163866de7b7f33c3e8a0d1f9b37a6d20", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xf64b7bf6dd3782b691a65d074c515dc96dcbbc5b654c41b1bb561b9171febc65", + "receiptsRoot": "0x9f8321c089b9a301b52205bdab9f5c7c5906a7307859eb67580623ae764a40e4", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000028000000000000000000000000000000000010000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x14b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xcee", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb1a056033a59f165c7df49320a7a67b1fdf266039f12ca8cd2ca8b904425dadf", - "transactions": [], - "withdrawals": [ - { - "index": "0x32", - "validatorIndex": "0x5", - "address": "0x984c16459ded76438d98ce9b608f175c28a910a0", - "amount": "0x64" - } + "blockHash": "0x4d6b8d46d03208985e99ee7ca9d38e3ff54871672663c6a1cb4d8a558fe8b5fc", + "transactions": [ + "0xf87582012f08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c85b0cf6f2ed6a4c9656d69748718e5bb3abd10a0a0080ede13d861e65459ccfda69653b507eef89c9ae71c31e0514bf89d368bf505a05d18a3565ae14331ad7336b97842425228126f33c6e477b3a5e9f8eb11e6e69a" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7044f700543fd542e87e7cdb94f0126b0f6ad9488d0874a8ac903a72bade34e9" + "0x31d973051189456d5998e05b500da6552138644f8cdbe4ec63f96f21173cb6a1", + [] ] }, { "jsonrpc": "2.0", "id": "np332", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb1a056033a59f165c7df49320a7a67b1fdf266039f12ca8cd2ca8b904425dadf", + "parentHash": "0x4d6b8d46d03208985e99ee7ca9d38e3ff54871672663c6a1cb4d8a558fe8b5fc", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7ef2bb0e7090f0d465ded8b1064d0aafb5da43bc603b3ae8e39b678616f22f04", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xf472cd60d56758c2d3646fa51d854ed0b56f9266db923772edef4e5bf0745785", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x14c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xcf8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x961da5e8745e0e4ae8287d73382c5b0d651110a7c7f900abf5f04b3e114b4776", + "blockHash": "0x317d6cd8a8783099c05585ff4132c92fa56746ac04dc89d01f90a6087d95e3fa", "transactions": [ - "0xf88382010a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0b67083c09c180ffba5ddc095999eaacd6d2cec077395c58d882c7a0706954896a02aaa853bfdbcdac9eefd90ff627107b5ca67b0c3969f3a770a4545a3b9d01514" + "0x02f86b870c72dd9d5e883e820130010882520894d803681e487e6ac18053afc5a6cd813c86ec3e4d0180c080a0f548c826f4e2b8c513899f21fedf09191bb02e657d036f2b312e534f346e1d89a04a1527da2c52c307743f6d31c941ec2d3575b540e89b5fb70bd21c7d3067d7d6" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf63a7ff76bb9713bea8d47831a1510d2c8971accd22a403d5bbfaaa3dc310616" + "0xe33e65b3d29c3b55b2d7b584c5d0540eb5c00c9f157287863b0b619339c302f0", + [] ] }, { "jsonrpc": "2.0", "id": "np333", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x961da5e8745e0e4ae8287d73382c5b0d651110a7c7f900abf5f04b3e114b4776", + "parentHash": "0x317d6cd8a8783099c05585ff4132c92fa56746ac04dc89d01f90a6087d95e3fa", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xff5f5d4ea4c9cb2944bea27f92a309b59ac66d45d231125258186ad3fcd58b61", - "receiptsRoot": "0xd5a4c662356c2fb912cf7df7798aabe0c8598dd3918c2c7e05db6619b76d855e", - "logsBloom": "0x00000000044004000000000000000100000000000000001000000000800000000000000000000000000000001000000000000002000101000002000000000000080000100000000000000000000000000000000000000200000000000000000010000000000000000000000100000800800000000000000000004000000800000000020000001000000002000000000000000000000000000000000000000000000000000000000000000100200000000000000000000000000200200080000000000000000000000000000002000000200000000080000000000008000000000000000000400000000000000000000000000000000000000000000000000000", + "stateRoot": "0x38d13fd335d3ff58df3bceceddd00a98f9a65076c295b474cb913443df6855a5", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x14d", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xd02", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa966ce90648fa40427896d7206976e783f96979437cbb3aed9cc9b050675763c", + "blockHash": "0x1aa7fbd954a82016be127f3624a93bda8d45351191031f3671060abf2fbc7140", "transactions": [ - "0xf87a82010b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0e65e3fb877a256ecdcf4de6dc51df2bd755e14acad6b24c68e7168dbdfcf77b5a017ffeb5a31596ad459195610c5c5e3f348468dab79d930d49cddc0601cd5a965" + "0x01f86a870c72dd9d5e883e82013108825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df0180c080a08b4402e18a1769ab35ad1c02fa3b3979e6cb5e2499015a08b523d95fbbdc556ca02055eeb30f2f30be3f98032663d662106c441fabd3faf595bb6446464de85d42" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa68dbd9898dd1589501ca3220784c44d41852ad997a270e215539d461ec090f8" + "0x78d55514bcef24b40c7eb0fbe55f922d4468c194f313898f28ba85d8534df82c", + [] ] }, { "jsonrpc": "2.0", "id": "np334", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa966ce90648fa40427896d7206976e783f96979437cbb3aed9cc9b050675763c", + "parentHash": "0x1aa7fbd954a82016be127f3624a93bda8d45351191031f3671060abf2fbc7140", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc8b1d4c2863741606d2cb870ed951e27495def1661f5192eef61cea97b8cd79d", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x041f809591aed092d570607d5814744284ede19b1e54f129be243ec696ea8ae1", + "receiptsRoot": "0x642cd2bcdba228efb3996bf53981250d3608289522b80754c4e3c085c93c806f", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x14e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xd0c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x266c92734d3a74137a12e4f6af6fe2cc401992b473d8af9121edbf3a78e4cf8a", + "blockHash": "0xf0a0f1e9079642d9be82b1a2c786bf1c89f4e0bec03cbd6c1be96b92c47cbeeb", "transactions": [ - "0xf86582010c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa041e92995e25443285655d748126496dbe98874a5cee8a1f0e58ea9f6a650f862a07feb73712a079a889322fcb61999780dab187d69eef21757af3eb0c9825f64c1" + "0xf8688201320882520894eda8645ba6948855e3b3cd596bbb07596d59c60301808718e5bb3abd10a0a0b8bcc7e609ee631b36339e1e6ccb48055c09c7b0a2ba3303178302dcf4af06b0a07420abb736eb6501693bb726a81507236a738ec8fa0b0e81292ed59f08f1b7f0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x59e501ae3ba9e0c3adafdf0f696d2e6a358e1bec43cbe9b0258c2335dd8d764f" + "0x2e0f4be4d8adf8690fd64deddbc543f35c5b4f3c3a27b10a77b1fdb8d590f1ee", + [] ] }, { "jsonrpc": "2.0", "id": "np335", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x266c92734d3a74137a12e4f6af6fe2cc401992b473d8af9121edbf3a78e4cf8a", + "parentHash": "0xf0a0f1e9079642d9be82b1a2c786bf1c89f4e0bec03cbd6c1be96b92c47cbeeb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x53e02e88b716b3d80f9cac4ea6e30497d8a5e0f2dc4df131a20a9ffb78fe8cda", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x74a65347258f456cb834196ea2439718d86593bad1b6246e957eacfd0b198a56", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x14f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xd16", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xebbfb2910659e643ff415b200900100e8e116b6d84a3e8e17b87d3e93dcdf3be", - "transactions": [ - "0x02f86b870c72dd9d5e883e82010d0108825208949ae62b6d840756c238b5ce936b910bb99d5650470180c080a0025cc19f12be3ff2a51342412dc152953e8e8b61c9c3858c9d476cc214be4e30a0193960b0d01b790ef99b9a39b7475d18e83499f1635fc0a3868fc67c4da5b2c3" + "blockHash": "0x286ee500a7ccd24305014fc9ed773b472aa0e9de2005f98b0136bbba193e89f9", + "transactions": [], + "withdrawals": [ + { + "index": "0x1d", + "validatorIndex": "0x5", + "address": "0x4340ee1b812acb40a1eb561c019c327b243b92df", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4f19cff0003bdc03c2fee20db950f0efb323be170f0b09c491a20abcf26ecf43" + "0xe1b83ea8c4329f421296387826c89100d82bdc2263ffd8eb9368806a55d9b83b", + [] ] }, { "jsonrpc": "2.0", "id": "np336", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xebbfb2910659e643ff415b200900100e8e116b6d84a3e8e17b87d3e93dcdf3be", + "parentHash": "0x286ee500a7ccd24305014fc9ed773b472aa0e9de2005f98b0136bbba193e89f9", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6be6c01d240a951a6adb298d9cb4e7c9e5e8960540de958b4b458fcfa489bf36", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x5f377cadc6b9379c381701e2fa03a1b8d60018477a76628e6d5c022b7778a32e", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x150", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xd20", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1f86807324e8cce9f4294076c96c4b2007acb0d2aba5c9ad2695e68aad468f8c", - "transactions": [], - "withdrawals": [ - { - "index": "0x33", - "validatorIndex": "0x5", - "address": "0x2847213288f0988543a76512fab09684131809d9", - "amount": "0x64" - } + "blockHash": "0x2f60754b89d3acfa2cd8e479e2b94e90c07bc5ca92f5e49b3d0280a30775893c", + "transactions": [ + "0xf883820133088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a00c230c2c6cb704d59fe5ffccb904f6cf5b95915d05b320eb186477831604f30da00138622287e1cd74e8b94f83db1a37b906e7381952de02a27ed354c8cfb237dc" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x52b1b89795a8fabd3c8594bd571b44fd72279979aaa1d49ea7105c787f8f5fa6" + "0x4ddad36d7262dd9201c5bdd58523f4724e3b740fddbed2185e32687fecacdf6b", + [] ] }, { "jsonrpc": "2.0", "id": "np337", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1f86807324e8cce9f4294076c96c4b2007acb0d2aba5c9ad2695e68aad468f8c", + "parentHash": "0x2f60754b89d3acfa2cd8e479e2b94e90c07bc5ca92f5e49b3d0280a30775893c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd2cd6e558f19ab03db7ee9677a850741b4f1f763c3de94539a16d54c27f6cac0", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x3360e3947013a74b2bd63f3112f968512361bb63b15562b26486a30c4672aba8", + "receiptsRoot": "0xa234730f8e7ba7c91f2cafe17e1c638dcd8835ad12aa27770f24e3a49a031784", + "logsBloom": "0x04000040800000040000000000000000800000000000400000000000002000004030008000000000000000000000000010000001000000000000000000000002000000000000000000000000000400004000000000000002000000000000000000000000000000200000000000000000000000000000000008000000080000000000000000000080000000000000000000020000800000000000000000000000000000800000000000000000200000000000000000001000000000080000000000000000000000000000000000000000000000000000000000000000000000000000004000000000400001800000000000000000000000080000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x151", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xd2a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x7cec5c4064e153c1c3adeda621a8764ebd7a693aa70891ef0bc7b6f95e64ae7b", + "blockHash": "0x1d2172c03aa39bcb2ff80dc3a80b157ee311f01f1972c3ae61df2fbc08581df1", "transactions": [ - "0xf88382010e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a057a97e1fae6dc03c4a29ad01b4d2ebea7069f1bef844b28b92875346d4454c46a01f5821fcf724aa6b0a3b082a6462e5f191a3c5659ba1b66b82cd42cf3175ba59" + "0xf87a8201340883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0e78b28732bf01b7e0f9ac86de0370156a1cec747b602f1720e9bb70319ac0c0da01b0570b525a20760358ab113ec97686d6e849ee0ad08743894366d9c8c6241d7" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7c1416bd4838b93bc87990c9dcca108675bafab950dd0faf111d9eddc4e54327" + "0x156c0674e46cdec70505443c5269d42c7bb14ee6c00f86a23962f08906cbb846", + [] ] }, { "jsonrpc": "2.0", "id": "np338", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x7cec5c4064e153c1c3adeda621a8764ebd7a693aa70891ef0bc7b6f95e64ae7b", + "parentHash": "0x1d2172c03aa39bcb2ff80dc3a80b157ee311f01f1972c3ae61df2fbc08581df1", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe1531cb938cfb7009f343d7ce9de03c63fe99878807b1ec8954b3a29a2d630f1", - "receiptsRoot": "0xa8c44170e431c7d7adf58109a7dbb58eeb38a19244c8a866311ef3a45fd13dfd", - "logsBloom": "0x00000000000000000000000000002000000000000000000000000000000080000000002000000000000000000000000000000000008000010000000000000000000000000000000000000000000000000800000040000420000400000000000000000000000000000000000000000000000000000000004000000000000000000200000018000000040000008400000000000000000000000000000001000000201000000010000001000400000000000000000000000000000002002000000000000400000000000000000000000000000000001000000000000000000000000000000000000080000000000004100000101000001000000000000000000000", + "stateRoot": "0x35cf21dfc0aace304593e0b5f92a4b86080f2d77f42e0a6df1a38316e0699b16", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x152", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xd34", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x11bd9e6153d072615b7e129ce56e720c40c048dd37afb5fdbfff09f994ae4a13", + "blockHash": "0xb5038ea078e022c5f7c97429a3f36c5b15ef525012266a78784315d5f5f8f742", "transactions": [ - "0xf87a82010f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0de79b818723588fa8952e0d007ef1e1db2240b355f4f0f69f2af9df6b3408407a00962c062cd7fc4b8bf627bab2c0a00349d7b1bfc6f7875ca3a18967ad30ff219" + "0xf865820135088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa05c10478b2c093f52e6576817dfb0ca2c716eccc77bc3dcc43e3482a14b62aa6fa0183b8f5a623bec5c593fd56f02844a7cb3d358cd61894ff8dcf56bb6b0a50726" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xef87a35bb6e56e7d5a1f804c63c978bbd1c1516c4eb70edad2b8143169262c9f" + "0xdfc56ec6c218a08b471d757e0e7de8dddec9e82f401cb7d77df1f2a9ca54c607", + [] ] }, { "jsonrpc": "2.0", "id": "np339", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x11bd9e6153d072615b7e129ce56e720c40c048dd37afb5fdbfff09f994ae4a13", + "parentHash": "0xb5038ea078e022c5f7c97429a3f36c5b15ef525012266a78784315d5f5f8f742", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd35f874d00597dfb19f0363bbab78f3356e12ec8b4ee89f2883285139d7a3c29", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd1878ecb20758419ab44897b3c479570e4917dc2a18611df054680a838162dca", + "receiptsRoot": "0x33917054a5e8342edac692f717af9212958d9e262cae6256fc670896a6ac7159", + "logsBloom": "0x00000000000000000000000080000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000020000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x153", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xd3e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf7122487788d84678b120512a25b1393417a66e19db5b507d471dd17628a84ea", + "blockHash": "0xb63287f903b3d2cd28cec281f1de235c85ed05ba3857e28cc86f9c29f39d57da", "transactions": [ - "0xf865820110088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa083a20e0b736688ba1f10440def989495ff253a281368f0ca21154d327c0468b8a0119312bdfeff761612ef529e4066bd28b4ed46895e5b67593fb0a3a897d3aa16" + "0x02f8d4870c72dd9d5e883e8201360108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c76ed30898ed7a9d0656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0c4f8d20ccba0b50d46d9c87f28cebf8c165fced694a2b34412a4b6153b987a1780a0a62a69f48f7b52ee09e21c86e91fb9bdf25246ecc175a9dadd9ad58187b78a32a0534a6c65d782c27d335d7d0ec0817041faed9e63ea864da2169b1dac9cb62e13" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe978f25d16f468c0a0b585994d1e912837f55e1cd8849e140f484a2702385ef2" + "0x395d660f77c4360705cdc0be895907ec183097f749fac18b6eaa0245c1009074", + [] ] }, { "jsonrpc": "2.0", "id": "np340", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf7122487788d84678b120512a25b1393417a66e19db5b507d471dd17628a84ea", + "parentHash": "0xb63287f903b3d2cd28cec281f1de235c85ed05ba3857e28cc86f9c29f39d57da", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xfa5b72ef0354b0b53f973b5285234c441e1bbf86d26374dd3856b36627d5caa3", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xe849e500d56ee2ada110a6081ee1c6617be2adcf083a1caf42e265a067b61aa3", + "receiptsRoot": "0x2dc20a0000586ebc72ed5256aee2947505381983c7d080a69ef8c68d3b802280", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000800000000004000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x154", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xd48", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb1d88e8bd186bb264de8def507f6a5876ec6f3af27be936763dfd39213ab07e8", + "blockHash": "0x9c476efe697f7d3482e8a3a620811c6dc88ed3b98cdc752a53bb756d13a6dcb5", "transactions": [ - "0xf8688201110882520894b55a3d332d267493105927b892545d2cd4c83bd601808718e5bb3abd10a0a073cc84153b8891468325ac12743faf7e373b78dbf8b9f856cb2622c7b4fd10e1a0388714fe9d2f85a88b962e213cbe1fa3c4a9823cea051cf91c607ecbd90093d8" + "0x01f8d3870c72dd9d5e883e82013708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ce481f18bdff3a685656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a3e65c2aeaf352e79173be13e572f691d8d75ea1064610b8418246d95bcc421c01a07939e49d0e5b19e71cd5225a0ce00fce92b05235773d9b97194d5333f9929387a0144d3d0ce7f1c3218e46f3f02b7bbace6c0064be726954bc3d9b399e865501d4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc3e85e9260b6fad139e3c42587cc2df7a9da07fadaacaf2381ca0d4a0c91c819" + "0x84c0060087da2c95dbd517d0f2dd4dfba70691a5952fe4048c310e88e9c06e4f", + [] ] }, { "jsonrpc": "2.0", "id": "np341", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb1d88e8bd186bb264de8def507f6a5876ec6f3af27be936763dfd39213ab07e8", + "parentHash": "0x9c476efe697f7d3482e8a3a620811c6dc88ed3b98cdc752a53bb756d13a6dcb5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xac6b9759a537d44a1629532184219d1f658f68745491b27e81c87361e72ad602", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xeb9a8fabeb5e95490ffb76f24c9af75ba76542e9bf057cef47022880c907a6e8", + "receiptsRoot": "0xbfd591c5699b876e0ffac9c863e7d879eb9e84fd53f09eb7209130d6fddd4a5e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000002000000000000000000000000000000000000000200000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x155", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xd52", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x70dad5a0db225381e8f841db9d8adf9a350051128cc22c0e5a00ad990c592b0d", - "transactions": [], - "withdrawals": [ - { - "index": "0x34", - "validatorIndex": "0x5", - "address": "0x1037044fabf0421617c47c74681d7cc9c59f136c", - "amount": "0x64" - } + "blockHash": "0xde9ba0e426dbd981f0ea6eb968d6f3a725b664f175d245e6e9e2478ff44afb72", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8201380108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c225431167194f3d1656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a06df5983ddc40ef2c7ffa2c79bf9402568f2ee0ec7b675ca15aaa20b536d2a5f283020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0045a6e1a7be12514ed1b4efb3a494e830a1bb319191b159e22b087b1eb54b9b5a03a9c077a4fb3b3c677d901b35817f68a7fd370d207cf131535c5e099b3bb42e1" ], - "blobGasUsed": "0x0", + "withdrawals": [], + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xbd2647c989abfd1d340fd05add92800064ad742cd82be8c2ec5cc7df20eb0351" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xf4df943c52b1d5fb9c1f73294ca743577d83914ec26d6e339b272cdeb62de586", + [] ] }, { "jsonrpc": "2.0", "id": "np342", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x70dad5a0db225381e8f841db9d8adf9a350051128cc22c0e5a00ad990c592b0d", + "parentHash": "0xde9ba0e426dbd981f0ea6eb968d6f3a725b664f175d245e6e9e2478ff44afb72", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe579eb979cbfd580c19ef8583f73a0fda902ee0895903a767d544ade95c50baa", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x371ed66c922382b1d523ea4195c56699910652c6012551f348e3c9f3bf436eaa", + "receiptsRoot": "0x488144f2ced26a3a3d1625aec2b9c5da10348700ae76d648175adeb8d1338372", + "logsBloom": "0x00000000020000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x156", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xd5c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb9b47ee8f7c38e7e1f69148756182d3da3a7d0c123948d2c56e5268357fced99", + "blockHash": "0x36e28ee4cdd767038d87e898e8b59f777b31454f9960e87ab3fc258223c5b212", "transactions": [ - "0xf88382011208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0874d69f306b86e76465f6f0ad314cadee41f0f0d1844d35408201c3b2f690de0a0698f29877cb7dec8ee91a42a74f0f5270cbb391836fdaeda1e0876d3c16177b9" + "0xf87582013908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c932062c9eeeeb3ed656d69748718e5bb3abd10a0a01212b3d30e6b13040680917257beb75539068dd48a14e7fd8521dec956c0c37aa001697ca60a4210a55ee2ef7fa50227de02aadc61edec2fff5af8e30ba63373fc" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x99ac5ad7b62dd843abca85e485a6d4331e006ef9d391b0e89fb2eeccef1d29a2" + "0x0bb47661741695863ef89d5c2b56666772f871be1cc1dccf695bd357e4bb26d6", + [] ] }, { "jsonrpc": "2.0", "id": "np343", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb9b47ee8f7c38e7e1f69148756182d3da3a7d0c123948d2c56e5268357fced99", + "parentHash": "0x36e28ee4cdd767038d87e898e8b59f777b31454f9960e87ab3fc258223c5b212", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf9106c3c4fcc77588a382ba0c2f605f6e07fcc418edac1cdd7de3b0e70f81b9f", - "receiptsRoot": "0x07a001dcc7eec5d1e8aa3508d61fcf5d511b4f9b766801b63319aa423ef08c3f", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000010000800000000000000000000840000004000000000080000010000000000000000000000000000000000000000000000020000000000000000008000010000000000000000000000000000000100000000108000000000000210000000000100000000000000000000002000000408000000000030000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200008800008000008000000000000000400000100000000000000008000000000000000000000080000000000000000000001010000000000", + "stateRoot": "0x317db0374b2ad9e322ab95b31c69e1859fc2f2b5975a2c348bd6377779eb672a", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x157", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xd66", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xde78022135caa19aa76718718d5de70d69e3f2488ff6769aee87c1d765237214", + "blockHash": "0x2955e6adbcf58ce3f34fc93da829c9c44a6641382ff92336f8cdedd1734669bd", "transactions": [ - "0xf87a8201130883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa084f91b21758f4c28d386fa99e8b7e126d27a1f9e293e5df2683057e09a9c6a2fa051772044b702ac375f615dc0d6aaa8c1d38c3ac2a830539d2ab62935c5132921" + "0x02f86b870c72dd9d5e883e82013a01088252089483c7e323d189f18725ac510004fdc2941f8c4a780180c001a060996b291aa6694897f4fd95c881f9c8831551f65d91c2edb0398f8a3ba31c61a00fec3df98ac224517ad5c762dd10caf4bb737e813993340c856a9aa3f63d24ef" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x02a4349c3ee7403fe2f23cad9cf2fb6933b1ae37e34c9d414dc4f64516ea9f97" + "0x4a1f7691f29900287c6931545884881143ecae44cb26fdd644892844fde65dac", + [] ] }, { "jsonrpc": "2.0", "id": "np344", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xde78022135caa19aa76718718d5de70d69e3f2488ff6769aee87c1d765237214", + "parentHash": "0x2955e6adbcf58ce3f34fc93da829c9c44a6641382ff92336f8cdedd1734669bd", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x19268b0f7992afe0cf1f3c0ac73b371ed7d9e79dddf0435b72bc45e1682a9c74", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x54016558c8961722006c12d3c14a0e63f83acb89ffe3111a8e23ed00fa021d93", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x158", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xd70", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8123c0650f836341cace6e65f0826a678974333748bc91a93d569224d63f832a", + "blockHash": "0x4ef098ab7baa897a6c538545fe29382fbc85c59ac78a01b5428a0db58bb5bfca", "transactions": [ - "0xf865820114088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0904e2a23972254826c8f3f5efa2d39122f980811cb9dd3e5d2869618d458856aa00fd104e760443aa8abcbdfbf2263d45a32a7aec32e59548b3e73575bc21f0243" + "0x01f86a870c72dd9d5e883e82013b0882520894654aa64f5fbefb84c270ec74211b81ca8c44a72e0180c001a061490ee93d7aef29c2ca23db661ecbe276001f15fd2760c5b6e068a844c8e806a02295e4ea97c85188c5accaa5ef1125ce2af9f791ebddb1d37be6a72809c81ed1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x627b41fdbdf4a95381da5e5186123bf808c119b849dfdd3f515fa8d54c19c771" + "0x9b133cc50cbc46d55ce2910eebaf8a09ab6d4e606062c94aac906da1646bc33f", + [] ] }, { "jsonrpc": "2.0", "id": "np345", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8123c0650f836341cace6e65f0826a678974333748bc91a93d569224d63f832a", + "parentHash": "0x4ef098ab7baa897a6c538545fe29382fbc85c59ac78a01b5428a0db58bb5bfca", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3ef70ee0614b3ae112271af4be70033c61a89f337aa527b8657df19422d94913", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x8e469b68b653164eb3983c967ddce5c94c6427eb70f9b8e087cb0f369169ee1d", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x159", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0xd7a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc74bc2976b5c5cbcfd64757534333c98d56bcac3109fc4504e3c324801f27530", + "blockHash": "0xee27e318aea1e83eb7b252d701fc255f8a295bc048819b674977db2140507eaf", "transactions": [ - "0x02f86b870c72dd9d5e883e820115010882520894b68176634dde4d9402ecb148265db047d17cb4ab0180c080a09f3175e9aa2fe2332600b71de0b0977c7c60ccbeee66ea360226326817f2d59ba06a870e0876002f789b3203f4a33d5e621ac67051704e1f2260b80d816260b3e6" + "0xf86882013c08825208944dde844b71bcdf95512fb4dc94e84fb67b512ed801808718e5bb3abd109fa0b230939d00d05d9935edc1612d35a4d651d0e5799ece9623548a3b863fae8dc4a0696d1b595f4c07376bfd0d6c5cdf8bf551cdef599da5b3bc81251eb0d9c49809" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc087b16d7caa58e1361a7b158159469975f55582a4ef760465703a40123226d7" + "0x473b076b542da72798f9de31c282cb1dcd76cba2a22adc7391670ffdbc910766", + [] ] }, { "jsonrpc": "2.0", "id": "np346", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc74bc2976b5c5cbcfd64757534333c98d56bcac3109fc4504e3c324801f27530", + "parentHash": "0xee27e318aea1e83eb7b252d701fc255f8a295bc048819b674977db2140507eaf", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbbec06f293095304adb3f03ba055fd08a691c89d5de1ade4c1ed31b9c6672989", + "stateRoot": "0x5eb753f46d09f0dac91bca6ca550b735c2402def5c8b90df0a2e54c72a14485f", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x15a", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", "timestamp": "0xd84", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x60a82197fb6b3b7d9a4912ec6ac783460863e449f48c28d68a45b4d4bf0a99f4", + "blockHash": "0x99c16f02cab4384eae354d510b84f49fb3cc77ac1a2deeaa87c7342894ce256b", "transactions": [], "withdrawals": [ { - "index": "0x35", + "index": "0x1e", "validatorIndex": "0x5", - "address": "0x8cf42eb93b1426f22a30bd22539503bdf838830c", + "address": "0x3ae75c08b4c907eb63a8960c45b86e1e9ab6123c", "amount": "0x64" } ], @@ -8492,1704 +10947,1739 @@ "excessBlobGas": "0x0" }, [], - "0xf7a477c0c27d4890e3fb56eb2dc0386e7409d1c59cab6c7f22b84de45b4c6867" + "0x225dd472ef6b36a51de5c322a31a9f71c80f0f350432884526d9844bb2e676d3", + [] ] }, { "jsonrpc": "2.0", "id": "np347", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x60a82197fb6b3b7d9a4912ec6ac783460863e449f48c28d68a45b4d4bf0a99f4", + "parentHash": "0x99c16f02cab4384eae354d510b84f49fb3cc77ac1a2deeaa87c7342894ce256b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x169c28a15311ed314bc0a4529aaddacc79d5fd6becdaaae69276079408d57eda", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xf8fb0d5f0b03dbce3ec0306a54eafcfe052b73623ad18e2893c3aa563c9c2cd5", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x15b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xd8e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xefbb190d45953f5e6292e14fc50b51539bca514890f94eda3e3ba2553417303a", + "blockHash": "0x38c75f8d455709c7dbb8ac586e04a2579d9e7d28a4d33a460588b70612a882e8", "transactions": [ - "0xf88382011608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a065a20271c4b6acc45c7e172465adcdc218b164c0936999de9bdd37c4a4c63fd0a003792daae8ab2be81df0df962c26697830d30af560c8a85a0fba05e5cfc82d66" + "0xf88382013d088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa0532bdb455b7324083403ddc1e13da4549613978a1ec591d46995f3eb2c5a0b3ba04ca1c0a37e2de03d4ef5c2ebb955e541ba2085c46d1dc8a85743b8c67afe2e2f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x1cb440b7d88e98ceb953bc46b003fde2150860be05e11b9a5abae2c814a71571" + "0x31df97b2c9fc65b5520b89540a42050212e487f46fac67685868f1c3e652a9aa", + [] ] }, { "jsonrpc": "2.0", "id": "np348", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xefbb190d45953f5e6292e14fc50b51539bca514890f94eda3e3ba2553417303a", + "parentHash": "0x38c75f8d455709c7dbb8ac586e04a2579d9e7d28a4d33a460588b70612a882e8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x704fde0fccaf5957d60018e958bfb8cc7bb7e77eed37cee3bdcdcca280b3b1fb", - "receiptsRoot": "0x0016ae7d40181cb711af89f17dc40dfb53384c5ef535847ae4982b1d58bfadd1", - "logsBloom": "0x00000000000000000000000004800000000000000000000000000000000200000000000000000000000000008000000020000000000200000000000000000000000000000000000000000000000000000000000000004000000000000008000000000008010000000000100008000000000020000000000400000080000000080000000000040000000080000000000002000000000000000000000000001000000000200000000000800100000000000000000040000008000000000000000000000040200000000000000000000000000000000000000000000000020000000000200000020000001008000001000000000000000000000000000000000000", + "stateRoot": "0x1f6f555d6e1a61e23db2f07df96d47f070643806deda0e021bac0a3c75461cd0", + "receiptsRoot": "0x24845ea0fc4154b4598890122a5384b3fc9fceccb83c56364d61d4a3a42299bf", + "logsBloom": "0x00000000000000000002000004800000000000000000000000000000000200000000000000000000000000008000000020000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000008010000000000000008000000000020000004000400000000000000080000000000040000000080000000000002000000000000000000000000001000000000200000000000800100000000000000000040000008000000000000000000000040200000000000000000000000000000000000000000000000020000000000200000020000001008000001000000000000000000200000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x15c", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", "timestamp": "0xd98", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xac7efb8f8fa8949755e520c30b52d9c292eb7e46eb8cac907f1267f72de81237", + "blockHash": "0x346083b60f44fd307e10d7e0f67b5da3d1230332adf26749cb5c80d00003300b", "transactions": [ - "0xf87a8201170883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0a7fe70291d9f18d3daffb9c6845116569c9be21f8b04c47235999ad35c20a079a03ad45b41a4993ea744bb28012bae4998ad6e97da464162d4ce51810e442e3ccc" + "0xf87a82013e0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0012ead7b881a49a22e7b9eb57c01088ec1e72c9939e582f16ef3558afa51147ea019f4d510d02d8bb75f75f20bd37711605c8c338385f2dfcffdaf6a6a895c6c81" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x72613e3e30445e37af38976f6bb3e3bf7debbcf70156eb37c5ac4e41834f9dd2" + "0x4416d885f34ad479409bb9e05e8846456a9be7e74655b9a4d7568a8d710aa06a", + [] ] }, { "jsonrpc": "2.0", "id": "np349", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xac7efb8f8fa8949755e520c30b52d9c292eb7e46eb8cac907f1267f72de81237", + "parentHash": "0x346083b60f44fd307e10d7e0f67b5da3d1230332adf26749cb5c80d00003300b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x898ac18f3ec544e0908e3a1c5434515aa421b796a41501b0474375f49fba30c8", + "stateRoot": "0x63b1e01af28bea08292e308f0eb39db17751900ef949289cd5b4da93d6440ef9", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x15d", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", "timestamp": "0xda2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x498a0d50858ecbfd2fe317843b04c02a00dfa8c2ee6a0e3641947439f0eb7dba", + "blockHash": "0xdef08200cf595f64a706819f16a1c39b7409cbbc14fc29a87b50c95a3f9e0464", "transactions": [ - "0xf865820118088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0027208b707b49c8686502030a1029e738d91a7c0bf9dff86bb90ccda2e5fc158a04b1d06ac6269fc336d1e6d0bac45e82b7d47ca4c271c7fed3bd1c6599b4bd0c6" + "0xf86582013f088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa05503af9f6399474958ec75701b360f133e8767010db164cb4e1c0fc415e806bfa0660e8b86200fb2a10af8ee02f9645b8e1d48042c5380542b53797fc255884094" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe69e7568b9e70ee7e71ebad9548fc8afad5ff4435df5d55624b39df9e8826c91" + "0xae627f8802a46c1357fa42a8290fd1366ea21b8ccec1cc624e42022647c53802", + [] ] }, { "jsonrpc": "2.0", "id": "np350", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x498a0d50858ecbfd2fe317843b04c02a00dfa8c2ee6a0e3641947439f0eb7dba", + "parentHash": "0xdef08200cf595f64a706819f16a1c39b7409cbbc14fc29a87b50c95a3f9e0464", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3a29d14904f05f088f4aede9ab588a53f6a54db4f43cd77f0227445a0d7c8386", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x82f87064f0098ed17ea770b3040e2a8833923f0e159ea09ee1e0e142cd2193cc", + "receiptsRoot": "0x6e519d18eadaffe71c1fd8e69d0b0ed1012b8fd9f79e97da742a5bd2a119becb", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x15e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xdac", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xac94cbd2aa423a9fc3dd35e9918a288b31a6b6127f829ef08b3d106212d5c005", + "blockHash": "0x701b50b242d6e6062020d66c4134f678c49fc7887ba1f962f97863b7648626f2", "transactions": [ - "0xf8688201190882520894dfe052578c96df94fa617102199e66110181ed2c01808718e5bb3abd109fa0020ee6a1ada31c18eac485e0281a56fc6d8c4152213d0629e6d8dd325adb60b1a00f72e01c463b98817219db62e689416c510866450efc878a6035e9346a70795f" + "0x02f8d4870c72dd9d5e883e8201400108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cda2a1c4a6f29dc43656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a04b916e15bdb0f5b4bccaa3447694db53cc34095b5bc26299c14a9f573bd6c75801a05b3c47bad5778a6f2b5f618f1746185144a162ed303258d23f52d6d3b3ea4b0ba043b36639da4429ce3a5c7d6e0fc7da8d99b8535ad730aa357e277c1a4a485987" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc3f1682f65ee45ce7019ee7059d65f8f1b0c0a8f68f94383410f7e6f46f26577" + "0x8961e8b83d91487fc32b3d6af26b1d5e7b4010dd8d028fe165187cdfb04e151c", + [] ] }, { "jsonrpc": "2.0", "id": "np351", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xac94cbd2aa423a9fc3dd35e9918a288b31a6b6127f829ef08b3d106212d5c005", + "parentHash": "0x701b50b242d6e6062020d66c4134f678c49fc7887ba1f962f97863b7648626f2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x693ec0330efa3e07b25a9a758d30a43389876e03846885dda5cdb009ff0e2674", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x6f0f84289a9bde0f88dc60d0ca020fde4b803200f53882b4133da32fa23e11f1", + "receiptsRoot": "0x505408927d83279aff752328f9d0bccad95e9e4eef621b6daddd4b8ca4400627", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000400000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x15f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xdb6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5c72e42631163c4ff7bb5a0e0051317b4b432609769052e2efe6043155ead48c", - "transactions": [], - "withdrawals": [ - { - "index": "0x36", - "validatorIndex": "0x5", - "address": "0x6b2884fef44bd4288621a2cda9f88ca07b480861", - "amount": "0x64" - } + "blockHash": "0x3265fc38a6c5684461c72e9c03fe1ddd99a53cddb2d371d0fc1188a130d76e79", + "transactions": [ + "0x01f8d3870c72dd9d5e883e82014108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c9544ff5cb729419c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0cd78e90ed1705eeff092f3df07b16a382082e9c388030ec3188daefa57a731dd80a05e969015af64fe334d2efcb6140612c74081ea1b13cb4b3e6fff55c5c09587c7a040e997ea1855f5eec240cea3d1d78506e6e2029d8cf3e1ba09a8276224c77902" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x93ee1e4480ed7935097467737e54c595a2a6424cf8eaed5eacc2bf23ce368192" + "0xc22e39f021605c6f3d967aef37f0bf40b09d776bac3edb4264d0dc07389b9845", + [] ] }, { "jsonrpc": "2.0", "id": "np352", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5c72e42631163c4ff7bb5a0e0051317b4b432609769052e2efe6043155ead48c", + "parentHash": "0x3265fc38a6c5684461c72e9c03fe1ddd99a53cddb2d371d0fc1188a130d76e79", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc25a9e84540d654be4abb3e8581cd2cc7cf97e54895e7a62d08eb78431d3f244", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x96671fc468fca5490c17be95a600802bf2e9aec1fc65ef02f06e08a7eb750b57", + "receiptsRoot": "0x18cf9fb8fd5c05afa7e14a1e88a774e6901368001f71c84e9e0f69dcab86e19b", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000020000000000000000000000000000000000000000000000000000000000000000000000004000000002000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x160", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xdc0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf3760efebd2ee1fbbda6bfff5aded8bb4ac38928857a4b22edab12bda293a2d7", + "blockHash": "0x84bf2031465aeaaa042fc5f12c7cf61ce1cdb3225525bf961b115bffb477ba2d", "transactions": [ - "0xf88382011a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a00df7ffb1778e645f4fc3b0e2236b34c038c43aacbbc43abc8d710c3fc33901e5a00d7d3d9cbc790b2e206b30639a4b55c1d2f3c2ea18c058a5085f16d72b50455b" + "0x03f8fa870c72dd9d5e883e8201420108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c63d51adce824b5da656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a040325cfcd159fa7bf89d8c252b6ff47cbc17aafff5e7feb92014d00285484cfd83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0d091dd0d488f94804707798f84d010809a6af6449224dd237629331078f91c3ba045a80c3a55fe668cabd867d15b92607311061af5ef4d15f2de9fb3732367d1e6" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xb07f8855348b496166d3906437b8b76fdf7918f2e87858d8a78b1deece6e2558" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x7cfa4c7066c690c12b9e8727551bef5fe05b750ac6637a5af632fce4ceb4e2ce", + [] ] }, { "jsonrpc": "2.0", "id": "np353", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf3760efebd2ee1fbbda6bfff5aded8bb4ac38928857a4b22edab12bda293a2d7", + "parentHash": "0x84bf2031465aeaaa042fc5f12c7cf61ce1cdb3225525bf961b115bffb477ba2d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x911acb703f25c08267716b25fc43b19bf4ce43a053393e6f1dce78c1cba8c485", - "receiptsRoot": "0x758b6a000deb6b7275c48ea96b2cbf580372445f0bc5b285eb764ed1800e8747", - "logsBloom": "0x00000000000005001000000000000000000000000000908000000200420000000000020000000000000000004000800010000000000000000200000000000000004000000002000000000000000080000000000000000000040000000000000000000000100400000000400000000000000000000000010000000400000000000000010000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000100000000000000000000000000000040000000000000000000000000000200000000000000000000000020000820000800000000000000", + "stateRoot": "0xa328fd0afd4855ac88654b9232abcfb46f0160928ab05db2b041993d60ef50a4", + "receiptsRoot": "0x1a56364363167e0e0d22ef01ae11d49ff6fdfa179e1e93ff9cfe93b66f7a9e69", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000009000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x161", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xdca", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9584dd2f0e20e3b4c274103aa168c495888b69ef8de7fe40cf413b6964c8393d", + "blockHash": "0x95d03fc9c7ab7b1f91a38325076295ba7251541246ff6929d4c3b4d7af875705", "transactions": [ - "0xf87a82011b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0c6d3e03aa8b0625a3225e077addb3cf47c9d061148da25021b22a0746083cc11a06176a93c704e6c5088e9d18cbaca7eab1de348207c2ba50083934c4e215a079d" + "0xf87582014308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cd120caade914624c656d69748718e5bb3abd10a0a0f9ad5ab1339e6df5515b0a06ed1b5fcefdfb497a458a10d1f6c4d7ddff785f34a075ffb836a3c0f32cdc485d56cffd5877eec01e02f952dbed1f3b24dd7e4578e6" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xec60e51de32061c531b80d2c515bfa8f81600b9b50fc02beaf4dc01dd6e0c9ca" + "0x943d79e4329b86f8e53e8058961955f2b0a205fc3edeea2aae54ba0c22b40c31", + [] ] }, { "jsonrpc": "2.0", "id": "np354", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9584dd2f0e20e3b4c274103aa168c495888b69ef8de7fe40cf413b6964c8393d", + "parentHash": "0x95d03fc9c7ab7b1f91a38325076295ba7251541246ff6929d4c3b4d7af875705", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xaca595525f5aa4f17314e44a3fdc0dae0f4037a1ee0a12bfb1bec7b9219f8d6c", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xf4beeeba7e78c83863ab3df26df08f8eef086f7ca90ab6d626873bc57ff24c19", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x162", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xdd4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x55a29172dc5a0a9d27b1778bec1c1591c0c8ec114d322fe60f5a39258e1783a0", + "blockHash": "0xd7e39656fea33b079d0fffa85665bda655e35ac8cd609b24db52fc10dd22030b", "transactions": [ - "0xf86582011c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0ad6f8d4d86d80157b67311edc959413ac3f525a5ec6334cc826125dfb1908b05a02e91a1d46e2df7c7eb4dc92224252298c66dbbf321fbb6c827a6e2d348277298" + "0x02f86b870c72dd9d5e883e820144010882520894717f8aa2b982bee0e29f573d31df288663e1ce160180c080a06bd165a9d39e2cde94707e00703d551c677d194c8a27bc0958a95f1cf5cc3b66a077dd528aac9a99930887ae334cae6579651a3f537da469d6b58467b7f6eae8d3" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2fc9f34b3ed6b3cabd7b2b65b4a21381ad4419670eed745007f9efa8dd365ef1" + "0x66598070dab784e48a153bf9c6c3e57d8ca92bed6592f0b9e9abe308a17aedf0", + [] ] }, { "jsonrpc": "2.0", "id": "np355", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x55a29172dc5a0a9d27b1778bec1c1591c0c8ec114d322fe60f5a39258e1783a0", + "parentHash": "0xd7e39656fea33b079d0fffa85665bda655e35ac8cd609b24db52fc10dd22030b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa307681299c7c385c512cbf83195ee62d35d29487665eb57cf2698c1b3e82066", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x3f3333213a8cabf535c44779e3a714381b1fc54f4bcb9c103a56dce09a0e2ac2", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x163", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0xdde", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb99cdd27bfb2535b0247fef5fe8097fc4e60f2a1c54a9adb3243192dafe1e657", + "blockHash": "0x56f28aefa9c8a192e22bfd3ba9946ca3b8d1e96897d3599f8f7ce0af473662b6", "transactions": [ - "0x02f86b870c72dd9d5e883e82011d01088252089433fc6e8ad066231eb5527d1a39214c1eb390985d0180c001a0167190e2e0fed95ab5c7265a53f25a92d659e1d46eb9ecbac193e7151b82ec1ca0269353e9c5ef331135563e2983279669220687652e7f231725303ccf7d2a8ebd" + "0x01f86a870c72dd9d5e883e82014508825208945f552da00dfb4d3749d9e62dcee3c918855a86a00180c080a040b7abdaae14c9c548d77583eaf61153bdcf2af46f724abe4efd423d61077e13a02bf59a5961a1fb1d1a00b6c35d78d95b0f0e00d3b7bd6fa0bb4b16eaaf0bccd2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf4af3b701f9b088d23f93bb6d5868370ed1cdcb19532ddd164ed3f411f3e5a95" + "0xac8fe4eb91577288510a9bdae0d5a8c40b8225172379cd70988465d8b98cfa70", + [] ] }, { "jsonrpc": "2.0", "id": "np356", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb99cdd27bfb2535b0247fef5fe8097fc4e60f2a1c54a9adb3243192dafe1e657", + "parentHash": "0x56f28aefa9c8a192e22bfd3ba9946ca3b8d1e96897d3599f8f7ce0af473662b6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb36926502e2ee904451fa5970a453aebe89f5bc25cd8c1dcae196810968617c1", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x786ef26f04264a255c620783ab3f8ad48ee353ec00032be699f581aa59459502", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x164", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xde8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xbdd33f47e688a8c88c0bb8514d3eff12f6f1ca570d3ae31aab000689d8dd4af3", - "transactions": [], - "withdrawals": [ - { - "index": "0x37", - "validatorIndex": "0x5", - "address": "0xf6152f2ad8a93dc0f8f825f2a8d162d6da46e81f", - "amount": "0x64" - } + "blockHash": "0xa256e8a74e0d5f0db511d6df3d329492b15504f515278ff998d108a49902a8d6", + "transactions": [ + "0xf868820146088252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c01808718e5bb3abd109fa025de91a23f27d8c900dc950bbb17e06495339c1f24a8b6c6e06f11a1c4468450a01737e65efad4010e16860a4b4944c6ef6624d5f2c1fd29bc7626f55e99e80a01" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x8272e509366a028b8d6bbae2a411eb3818b5be7dac69104a4e72317e55a9e697" + "0x2b0018a8548e5ce2a6b6b879f56e3236cc69d2efff80f48add54efd53681dfce", + [] ] }, { "jsonrpc": "2.0", "id": "np357", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xbdd33f47e688a8c88c0bb8514d3eff12f6f1ca570d3ae31aab000689d8dd4af3", + "parentHash": "0xa256e8a74e0d5f0db511d6df3d329492b15504f515278ff998d108a49902a8d6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x67558b87a732daed74e1b9ed7aef6326aabe984df466494d2fc59d9ea951c6c6", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x8367e96cedb6544c9f21058628d72ff78e4be19aeb9e3581eb254cf62a580005", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x165", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xdf2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x60fbbf44b7687b97e348c42a24637f027125b00a39e5e63995405da84de95ce0", - "transactions": [ - "0xf88382011e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0b20886ab8d36222d79bf9dad933333062a51e71dbd6de720f872874edb727276a05f68ff1bcbb8019f43e4e37a481075cc5565512eb56d34ccb707e8aec00a4204" + "blockHash": "0xfda145c2f89e067fcb82e98c5a201fb8f9949d578a1b87241e6f7c103fbda5d4", + "transactions": [], + "withdrawals": [ + { + "index": "0x1f", + "validatorIndex": "0x5", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa194d76f417dafe27d02a6044a913c0b494fe893840b5b745386ae6078a44e9c" + "0x823445936237e14452e253a6692290c1be2e1be529ddbeecc35c9f54f7ea9887", + [] ] }, { "jsonrpc": "2.0", "id": "np358", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x60fbbf44b7687b97e348c42a24637f027125b00a39e5e63995405da84de95ce0", + "parentHash": "0xfda145c2f89e067fcb82e98c5a201fb8f9949d578a1b87241e6f7c103fbda5d4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x15bdc9a6fcc0d4d133bc86adbda378e2110d51fc60304207240f24f60d4fc99d", - "receiptsRoot": "0xf9f06ad2e1bbf826b5cbeabfd01d508c4d7bc0781b946c5afc105a2e20d9155a", - "logsBloom": "0x0020000200000000000004000000000000000000010000001000000000000400000000000000008000000000000400000000a820000000000000000004000001001000000800000000000000000000000000000000000000100020000002000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000040000000000000000000002000000000000000000000000008000000000000000000000000000000000000000000004000000000000000000000000000000000140000000000000800000000000010000000000000000000000004000000000010000000000004401000000000", + "stateRoot": "0xa2185fee71394ba245d483bb95d117c04e584a1e3486154dbda7ac23d5e5d6c3", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x166", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xdfc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb32a72eff6c1fed26a63381d9de7254e9a85e9c459fad22c037e8a11eb95d04f", + "blockHash": "0xc60a413c6267e5f34ee8e27efcb89e2bbcdd4b839cb0c961f7dd37805181626f", "transactions": [ - "0xf87a82011f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0c35e2924126964cdf4a8847f4cb4a870f24a4654de527a3dc9fad248d338aab6a00d9292c8e92050bebef84a83b3deacddf95a33015a3d284b578cb0f1621c5a70" + "0xf883820147088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0f91141179eb75a36e3f88edefa1b6aea266f623647afe0f3a269019f22ff823aa04e9bd3bdeca6818a15445105ae924e61f126ae9355741307b4a5955699b0104e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa255e59e9a27c16430219b18984594fc1edaf88fe47dd427911020fbc0d92507" + "0x3051a0d0701d233836b2c802060d6ee629816c856a25a62dc73bb2f2fc93b918", + [] ] }, { "jsonrpc": "2.0", "id": "np359", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb32a72eff6c1fed26a63381d9de7254e9a85e9c459fad22c037e8a11eb95d04f", + "parentHash": "0xc60a413c6267e5f34ee8e27efcb89e2bbcdd4b839cb0c961f7dd37805181626f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x21d7cc2931eed33ddb03977b7d99c97ac378c41ed2ac25331478cd1fbd583e7a", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x5c401a283294494c8cb499c7017ec143afc3880bbf163332bd4f85257fde02b3", + "receiptsRoot": "0xa6efaa2bd5e8b55c9ee7555c2010566ebce0eceb665633bf89fc058554243280", + "logsBloom": "0x00000000040000000000400080000000000040000000000000000000000000800800000001000000000000000000010000000000000002000000000000000000000000000000000020000000004000000000000000000000000000000000000000000000860000001000080010040010000000000000000000000000000000800800001000000004000000000000000000000000000400000000001000000000000000000000000000000000000000000000000000000000000000000000080000000000800000080000000000000000000000000000004000000000000020000000000000000000000001000000000000000000000000100000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x167", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xe06", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x31483924290768786929b9836507966e24a775f86f3724200851b2eaa262ac36", + "blockHash": "0x9267c3d2e49d9a2fbb84a69db614d9fb33bae938ee4bd0fadcf5cc033562bd8c", "transactions": [ - "0xf865820120088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0aab9710502eb45f06f5470674b88b22c30fdc865a22c86a7095f355629fb6d11a01d905abe10e39ed037ad29a46a81d0af6d52d9de2d7bef20e7b02db8c1cf13a0" + "0xf87a8201480883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0d18d9add1c775ef5e466f61a1519ab1701644a82a77e2fe7f2919eee9be1f271a03bc8219f96194b5cb1414c95ee3839ad3e868bf3e60d4b33e45ced1b73b52401" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7996946b8891ebd0623c7887dd09f50a939f6f29dea4ca3c3630f50ec3c575cb" + "0x44a50fda08d2f7ca96034186475a285a8a570f42891f72d256a52849cb188c85", + [] ] }, { "jsonrpc": "2.0", "id": "np360", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x31483924290768786929b9836507966e24a775f86f3724200851b2eaa262ac36", + "parentHash": "0x9267c3d2e49d9a2fbb84a69db614d9fb33bae938ee4bd0fadcf5cc033562bd8c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x128ac2d4c23be8773c460ed383defee0e767a4fe0a55e9f600a60e0fe051735b", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x58b966da2254b60e84562b9b265b24b27f440c3148decb437e8eb759ecedd58b", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x168", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xe10", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xdfabceebb90036f92ea3e859b9fcadd8642f00dcdf45278c09d93fb56d320b04", + "blockHash": "0xf66d68a2b0dd9fbc45a5646cebcb99e8af641c8a372724264058493e141eaa46", "transactions": [ - "0xf8688201210882520894662fb906c0fb671022f9914d6bba12250ea6adfb01808718e5bb3abd10a0a0d3a858be3712102b61ec73c8317d1e557043f308869f4a04e3a4578e2d9aa7e7a0202a5f044cc84da719ec69b7985345b2ef82cf6b0357976e99e46b38c77fe613" + "0xf865820149088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a066053e37815a04b8665e4108e806ed564fd57af67c7f28cc40b79272e011ec75a0095d99837cab6fc1a53b126936c0d8c2ca339ac55af799229323b7ea128e33cb" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb04cbab069405f18839e6c6cf85cc19beeb9ee98c159510fcb67cb84652b7db9" + "0x6e60069a12990ef960c0ac825fd0d9eb44aec9eb419d0df0c25d7a1d16c282e7", + [] ] }, { "jsonrpc": "2.0", "id": "np361", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xdfabceebb90036f92ea3e859b9fcadd8642f00dcdf45278c09d93fb56d320b04", + "parentHash": "0xf66d68a2b0dd9fbc45a5646cebcb99e8af641c8a372724264058493e141eaa46", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa8f8fd676089911db9824cafe64222a854d4767d0cc5fded3fa1643f735afd80", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x4453faa136a6236d91bfa955406d6bd7989ad4e6fb06f331d0b8328d4ce02162", + "receiptsRoot": "0xbfbc3f80b299340eaab4e22415e1ed57ebb1d5a83d4431f7189a1851e9ab94f4", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000040000020000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x169", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xe1a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa7dab2cd20b59a5961ff34f49d421a579c939d6898b084ae4db8971604df1380", - "transactions": [], - "withdrawals": [ - { - "index": "0x38", - "validatorIndex": "0x5", - "address": "0x8fa24283a8c1cc8a0f76ac69362139a173592567", - "amount": "0x64" - } + "blockHash": "0xcafa23b21dd847e0a6863e2d6a9e81749d2ae6174e340bf3ed6c27e030ed38fe", + "transactions": [ + "0x02f8d3870c72dd9d5e883e82014a0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cc5d1b5234d598db7656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a07975cc1088361453b019ff19e2177b264cfea56f4c09b1a8a086f6c405dd516c01a0e02857fe8d948db7745f2b17a5cd9713b92a60da8da7daa70d5b1713b12a62ba9f8e03e24b97096b677d1bed7544c3ecc4a18d98989b9dc0bdc5d9a9a7e25fa3" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6f241a5e530d1e261ef0f5800d7ff252c33ce148865926e6231d4718f0b9eded" + "0x581ddf7753c91af00c894f8d5ab22b4733cfeb4e75c763725ebf46fb889fa76a", + [] ] }, { "jsonrpc": "2.0", "id": "np362", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa7dab2cd20b59a5961ff34f49d421a579c939d6898b084ae4db8971604df1380", + "parentHash": "0xcafa23b21dd847e0a6863e2d6a9e81749d2ae6174e340bf3ed6c27e030ed38fe", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb19cdea25a29e5ba5bf0a69180560c2bcf35823b81d82d8b97499ad1cc22873b", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x37fb7cae9e1c94703e61e83bc7ef00f5677ec59a3ac867818e3c55010afc2648", + "receiptsRoot": "0xd212385e4afdb5978e6dcb1ce04cf85af1c33c1878da895bc40c97df4abef905", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000040000000000000000000000000000000004000000000000200000000000100000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x16a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca90", "timestamp": "0xe24", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x0f9c87bb2b9d07ca411420399c22658ea7be36c5bd1fbbf1c759592959cc3a94", + "blockHash": "0xd6aca4fd2acf5ca563efa815897afcfaa175b8955931f699ae4018ac86eeea91", "transactions": [ - "0xf88382012208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa034e8481ee12e75836d1e4cc88aef813a6bc8247b73aeb7a466a1ce95bca6e5fea07585402e69f5856a5724a9e83a9bf9cf77bc92cc619489f9903f09b8c3530f24" + "0x01f8d3870c72dd9d5e883e82014b08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c5b00e11941ab7046656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0490b9d550a200295b38f2456a42525d3a43c345d2fa1431e770fea9656b2672301a025d780cad1d212faf6744c9e152ba4b6ab144f30edd18a15680fbfdc5bf8e08ba00bebac8aa02d02642c519f1182de690b3d42fa44389d0be8239f41cc97d2de09" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xfcfa9f1759f8db6a7e452af747a972cf3b1b493a216dbd32db21f7c2ce279cce" + "0x9a1dfba8b68440fcc9e89b86e2e290367c5e5fb0833b34612d1f4cfc53189526", + [] ] }, { "jsonrpc": "2.0", "id": "np363", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x0f9c87bb2b9d07ca411420399c22658ea7be36c5bd1fbbf1c759592959cc3a94", + "parentHash": "0xd6aca4fd2acf5ca563efa815897afcfaa175b8955931f699ae4018ac86eeea91", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x09f1a8d40ad941a3c47fd34c32682a0058f79387d467a7ebb5d957455aab9fb6", - "receiptsRoot": "0xde87ab5715c2af5f977bcf679cd4e771796d49365c3111487aba12fdb69483a2", - "logsBloom": "0x00800000000000000000000040000000000000000000000000000000000000000000000000080000000000000000000000000000008000000000000000000000000000002000000000000000000000000001020000000000000000000104000004000000000000000000000000000000000000000000800001000000040000000000000002000000000000000001000000000008400000000000000100000000000000000000001000000000000000040000000000000000010200000000000000000000000000080000000000000000000020002000000020000100400000000000000000000040000000000000100000010000000000000001000040000000", + "stateRoot": "0xc47ec5827b3096b1f71cfb5615412890ced2d0e4e25c6b809e54647f92007a0d", + "receiptsRoot": "0x51dc4d1b69b22caadb80e85c68166344898ffbc5d4767ee1214c717c46416a88", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000009000000000000000000000000800000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x16b", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xe2e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xcdbbd78682fb1c3e75c9821acce03f6fd048226147e7041d84952c6aa3c18b5e", + "blockHash": "0x16b4cebad9f39a7db380791451d3a9dd9c35dbadc751254c41f94cae8280358e", "transactions": [ - "0xf87a8201230883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0317931eb522b3488621079d412251962cc5a02794939e3a3b0c94c92df0b4da5a001348209aa47bc1a55590243d5168b2beb06c929b46104d144ba526070b2e5ea" + "0x03f8fa870c72dd9d5e883e82014c0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c0581a3f309f9b7a9656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0039a54e14fa9769f840074356dec3dbd47c3588fe71fe942fb7aec5edfd0a09683020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a093f8d363100badb86a1cfaa2bf17b1d051130d2c906dd48c0c44038f4e5f3a5ba0236c43ff36fb2dd731590896717db4c534db3e2e2937fdfead8bf6d2e1d3b4f3" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xdf880227742710ac4f31c0466a6da7c56ec54caccfdb8f58e5d3f72e40e800f3" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x54a623060b74d56f3c0d6793e40a9269c56f90bcd19898855113e5f9e42abc2d", + [] ] }, { "jsonrpc": "2.0", "id": "np364", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xcdbbd78682fb1c3e75c9821acce03f6fd048226147e7041d84952c6aa3c18b5e", + "parentHash": "0x16b4cebad9f39a7db380791451d3a9dd9c35dbadc751254c41f94cae8280358e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x96f076c6c4d61d649b8f9c4290ff81fad55bfebe6e171f2d2bedb4b941977873", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x089e671fabff27b7a6a5bec573cf9815686c0597138d9284647a5fe97590d738", + "receiptsRoot": "0x7ac3337326ead8b549b53abed41fcc43cf5d7b8545dc05588173145a617cf712", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000800000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x16c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xe38", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xab15226c228033c1118398e475d860a1ea7534e4d620ae9ceb2893fa3a73ff7a", + "blockHash": "0x505a6bf5ab0f40712af88078826c83c152e5ec99fd74ae718e47c0f1b6c7c0fb", "transactions": [ - "0xf865820124088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0886d94140ef16f0079167a92ea5577d300a4e87982588af41676d8d9a7a7f043a0388a734d4f7a8eb510a5e7aba3141505773bd329a70ff438be40d7b378fdafa6" + "0xf87582014d08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cdddf70b2f66dd741656d69748718e5bb3abd109fa0a67de64d6cb2c553afbb804db1871168ceaeaac9e6ad06e8ec141cfc01757178a06d770bae5765c71dd7d77a11ec2e4a15bc84453dbd2016d66a0756c340bcdbc9" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xadfe28a0f8afc89c371dc7b724c78c2e3677904d03580c7141d32ba32f0ed46f" + "0x1cfeb8cd5d56e1d202b4ec2851f22e99d6ad89af8a4e001eb014b724d2d64924", + [] ] }, { "jsonrpc": "2.0", "id": "np365", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xab15226c228033c1118398e475d860a1ea7534e4d620ae9ceb2893fa3a73ff7a", + "parentHash": "0x505a6bf5ab0f40712af88078826c83c152e5ec99fd74ae718e47c0f1b6c7c0fb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x208cc1a739ecf1c8aed87a70e4f580b28d06f7dba19ef679a4b809870c0e66a4", + "stateRoot": "0xe6d3d3f1f1dedd2bf3fddb34a7ad6d5af258eb1080793c91ee8f8844f26ddce9", "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x16d", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0xe42", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe3c3b2311857f76f1031d8384102288970bf25ab710e5e8ca3e7fee19ea3fcde", + "blockHash": "0x0f15f04e28de513a6e468d22860d94e5389a07b5b630f8a8e7b84ed7bc0b8558", "transactions": [ - "0x02f86b870c72dd9d5e883e820125010882520894f1fc98c0060f0d12ae263986be65770e2ae42eae0180c080a06563737b6bfddfb8bc5ec084651a8e51e3b95fe6ed4361065c988acaf764f210a00a96a1747559028cd02304adb52867678419ebef0f66012733fea03ee4eae43b" + "0x02f86b870c72dd9d5e883e82014e0108825208945f552da00dfb4d3749d9e62dcee3c918855a86a00180c001a005b69e48a3446f70511c54ab36235de711ac546cf056d7e97bc902215e365ec9a02a292f3b4f719296a9a548a42464b52e79d70703a662122c809146ef351c73e5" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb264d19d2daf7d5fcf8d2214eba0aacf72cabbc7a2617219e535242258d43a31" + "0xad223cbf591f71ffd29e2f1c676428643313e3a8e8a7d0b0e623181b3047be92", + [] ] }, { "jsonrpc": "2.0", "id": "np366", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe3c3b2311857f76f1031d8384102288970bf25ab710e5e8ca3e7fee19ea3fcde", + "parentHash": "0x0f15f04e28de513a6e468d22860d94e5389a07b5b630f8a8e7b84ed7bc0b8558", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf4a7f460684eacde84218991911d63333e89a5a8fe5293e43b2b283209bb7297", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x85571fdc8cc44636348f3c10cdf031ffa5504dc9eedd3598b0710ddad0efe28b", + "receiptsRoot": "0xbe3866dc0255d0856720d6d82370e49f3695ca287b4f8b480dfc69bbc2dc7168", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x16e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xe4c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf1f80c035c0860545aeb848923615c5bb8cbd15305ddc6a87b9d9a4d509a8d5c", - "transactions": [], - "withdrawals": [ - { - "index": "0x39", - "validatorIndex": "0x5", - "address": "0x19041ad672875015bc4041c24b581eafc0869aab", - "amount": "0x64" - } + "blockHash": "0x7371118bf9383f5e8b92bbb6cc9aaff94c06477228cde2abfffc48cabafc1bec", + "transactions": [ + "0x01f86a870c72dd9d5e883e82014f0882520894eda8645ba6948855e3b3cd596bbb07596d59c6030180c080a072885b5a14a5cae7134e7aa308ef77fdebcd2cb995d9d9c4bdedaa8733fd6cd0a05eb1d201d26f47f1eca74d1f787f91c43f9089ecfb050f67af872352e0431a14" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf2207420648dccc4f01992831e219c717076ff3c74fb88a96676bbcfe1e63f38" + "0xe13f31f026d42cad54958ad2941f133d8bd85ee159f364a633a79472f7843b67", + [] ] }, { "jsonrpc": "2.0", "id": "np367", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf1f80c035c0860545aeb848923615c5bb8cbd15305ddc6a87b9d9a4d509a8d5c", + "parentHash": "0x7371118bf9383f5e8b92bbb6cc9aaff94c06477228cde2abfffc48cabafc1bec", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x44f6e5c8fd3452b71ade752a742ca9f61626aeeaa20e89d47fe414d1df414745", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x2fcb885f5cd5d4b9bf40eb6d5c0fd445648f559beee2dc7e8c0690c36d31ef8c", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x16f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xe56", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xaa0d0fadd5774766ac1a78447bd5ef9f5a816c9068d28097c78d02737ce7f05a", + "blockHash": "0x77d7c2eb0af7749896c1be40161508d650c019a8fdfdabab4b34b47f0caa5a80", "transactions": [ - "0xf88382012608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a00d5ce478373461565e41764365499cc4a43519643829503796c5453e1bc7ff0ea03ef00a5fe608838a9156d394317734b358ac026af08b33c2aabfea8e9d485dfa" + "0xf868820150088252089483c7e323d189f18725ac510004fdc2941f8c4a7801808718e5bb3abd109fa086aab378b3165e20297e9d6ff3d5da704f3e4b3d1f087ad9131a8d5bc5a3c8eda03aa230322dcea454aa1edae6bc9a9af8a0a2c40d5836334b3f2c4fbe1b59c046" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x41e8fae73b31870db8546eea6e11b792e0c9daf74d2fbb6471f4f6c6aaead362" + "0xb45099ae3bbe17f4417d7d42951bd4425bce65f1db69a354a64fead61b56306d", + [] ] }, { "jsonrpc": "2.0", "id": "np368", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xaa0d0fadd5774766ac1a78447bd5ef9f5a816c9068d28097c78d02737ce7f05a", + "parentHash": "0x77d7c2eb0af7749896c1be40161508d650c019a8fdfdabab4b34b47f0caa5a80", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7fd199408596db163d237e6d25f64b90ac2bc04158524e8baac5d55f881bb52b", - "receiptsRoot": "0x8d3f058248d263db5e6d6d78ddf91fd2ec0183f2bdf3e9e142af87a53388e526", - "logsBloom": "0x00000000000000000000000000000100000200008000000000000000000000000000400000000000000000000000000000000000010008000000000000000000000020000600000000000020000002000010000000000000000000000000000000000000080000000020200000000000000000000000000000000001000000000000000000800000002000000800000000000000010000000000000000000000000000000000000000000000004000000000008000000000000000000000000000000000040000000000000000000000200000000000000000000000401000000009800000000010000000000000000000000000000000000000808000000800", + "stateRoot": "0x727be1133b3b99853b987da08d0e07e8b01358cd426ba12896fe05bb20ec75a6", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x170", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xe60", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4b263e57c931fa090da8bc6890c9d6fc2ad2dd5a66bb3a5563cc477735893a96", - "transactions": [ - "0xf87a8201270883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a008faafda0a060040eca56f846ecbd6a399914482c31359f1ec04c98cc476ce82a04d2b02adc2c947898fa00cbedb4532f471cb5eb92ee19a30697ddd0c713132e3" + "blockHash": "0xc3c6a43b0a9fec6d3e9c232cd9048eb4b655f8c779ff7c510195e75d4c3cb3dc", + "transactions": [], + "withdrawals": [ + { + "index": "0x20", + "validatorIndex": "0x5", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4e7a5876c1ee2f1833267b5bd85ac35744a258cc3d7171a8a8cd5c87811078a2" + "0x9d2b65379c5561a607df4dae8b36eca78818acec4455eb47cfa437a0b1941707", + [] ] }, { "jsonrpc": "2.0", "id": "np369", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4b263e57c931fa090da8bc6890c9d6fc2ad2dd5a66bb3a5563cc477735893a96", + "parentHash": "0xc3c6a43b0a9fec6d3e9c232cd9048eb4b655f8c779ff7c510195e75d4c3cb3dc", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2a2360860a67f9187f50f56201c50d2309c961a2b408072e7c3d069c8c1216cd", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x6aa75134a379dc98080f0313ed78800dfac8e76e701b63edee260fffe7dd0182", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x171", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xe6a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x0adc9e078ab6f0799b5cbc8e46e53a0d96d4fe4ba0b6ff75088445c304000226", + "blockHash": "0x024a6e084b404338002e6dd8b70331a3ad6d896cdedecd23db0c7db0cca13ea7", "transactions": [ - "0xf865820128088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0da49c9575be5d906d247a5f4f0574e76d1edb1368dbdda1b4a5b58fba3fca82da00fa1c561fc766acefeeabf085384962f2599b3ca6b02996962095eed297df611" + "0xf883820151088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0b7f14a7de3212ac6e25fcc2e7727627619c71692e0a9d8c723f7337738fec4cea0745eab42b319407c929087225440ea9007b7d47751fec14db91ef9bfd055a8b8" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x8d4a424d1a0ee910ccdfc38c7e7f421780c337232d061e3528e025d74b362315" + "0x5855b3546d3becda6d5dd78c6440f879340a5734a18b06340576a3ce6a48d9a0", + [] ] }, { "jsonrpc": "2.0", "id": "np370", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x0adc9e078ab6f0799b5cbc8e46e53a0d96d4fe4ba0b6ff75088445c304000226", + "parentHash": "0x024a6e084b404338002e6dd8b70331a3ad6d896cdedecd23db0c7db0cca13ea7", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x971bbdee0e408ff826563636c5eccce30540c1cba590880849a72ac21f74a4e4", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x94edb1c63ebe96190bba51941774daccf9601236019266f0a758d2d43ce14fa7", + "receiptsRoot": "0x7251de47ca910034b44cc1b34a11098cb7cb41a4251591cbd744030fa6e56070", + "logsBloom": "0x00000000000000000000000000000000000000040000000000000000000020000800000000000000000000000000000000000000000100800000000000000000000000000000000000000000000000200000000000000002000000000000000000000000000000000000000000000000000000000000008000000000000080000040000000000000000000000000000000021000000000201000000000000000000008000000000000000000000800000000000000000000000000004000000100400000000000000080000400000000000000000000000001000000000000000000000000000080004000040004000100000000010010000400000000000805", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x172", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xe74", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1636ca42281a5e77303d2d1095d71b2c59f0b175c98a3adb9630cd6463d2be04", + "blockHash": "0x4ac493337944aac392f8ec72d0187775a98712347f2d3a8ce5e6dfade5fc88e1", "transactions": [ - "0xf8688201290882520894a92bb60b61e305ddd888015189d6591b0eab023301808718e5bb3abd109fa0626bd8978288bcf1d7719926fba91597d6aa8ead945c89044693d780523a05dda0074494ccf5362aa73db798940296b77b80a7ec6037f5ed2c946094b9df8a2347" + "0xf87a8201520883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa09ffdca5ddee51f70d71957df581c7af8b647e7ce3cca634b713703fa2056b8eda0633e4ec86b1a5621be40b8b90ee6ab1c6ced4b8f24038739623a7fd720c37cc2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xfa65829d54aba84896370599f041413d50f1acdc8a178211b2960827c1f85cbf" + "0xd6a61c76ae029bb5bca86d68422c55e8241d9fd9b616556b375c91fb7224b79e", + [] ] }, { "jsonrpc": "2.0", "id": "np371", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1636ca42281a5e77303d2d1095d71b2c59f0b175c98a3adb9630cd6463d2be04", + "parentHash": "0x4ac493337944aac392f8ec72d0187775a98712347f2d3a8ce5e6dfade5fc88e1", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2a239ffb7957e73c3eebeb33b01444599ddcd5861f1dfb4bbe31584061f11389", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x9deac8e88d661e3853fcf27372aa74ee3e8a0564581abf2229380cb91bae7285", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x173", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xe7e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xbf62c63fdcd8b0648bfec616e9270243233b47c513a9519932cb82d70ed5c2be", - "transactions": [], - "withdrawals": [ - { - "index": "0x3a", - "validatorIndex": "0x5", - "address": "0x2bb3295506aa5a21b58f1fd40f3b0f16d6d06bbc", - "amount": "0x64" - } + "blockHash": "0x53f13c2ada283dad19b4c6e1f5d01844ecdfce9b5e5cc064e025aafaa95c97fc", + "transactions": [ + "0xf865820153088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa01c4c4dad5cc48dc34f7de3b598ffb02acfa6bd18bbc39ff5f48a7430f1d7e2d6a066a0b6a1d3d70b98a58c1f596a1285cabbe35ebf5365b26e894eed6d8d6c2bf9" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xda5dfc12da14eafad2ac2a1456c241c4683c6e7e40a7c3569bc618cfc9d6dca3" + "0x96ac5006561083735919ae3cc8d0762a9cba2bdefd4a73b8e69f447f689fba31", + [] ] }, { "jsonrpc": "2.0", "id": "np372", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xbf62c63fdcd8b0648bfec616e9270243233b47c513a9519932cb82d70ed5c2be", + "parentHash": "0x53f13c2ada283dad19b4c6e1f5d01844ecdfce9b5e5cc064e025aafaa95c97fc", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xadbba859a71886f49ccd216fbc6c51a42a7a6eff927970b298d4e0f6e2a9597d", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x9e53e02a391036fd160aa186d64c5c624a55126dcf665e641e61b04e9ea19536", + "receiptsRoot": "0x14b7dc4ec7b9ec6c7fd91c49ac7aaa6cc4f8f48ff188006e4b72f3b3c862dd0f", + "logsBloom": "0x00000000000000000000000000000000000000000000004000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004002000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x174", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xe88", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x349a0919fb81864d824dd7345c583a9fb5c99ef0bd9c549be68b10e72e7c8c2a", + "blockHash": "0x5aebb1a84a124ace93a6955bad2c1d3e26769ad5c4c8f7952bca62ffa6ecbb72", "transactions": [ - "0xf88382012a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa085c885407da43158c33afe4c9d10a846d4cf5bb820c70f019ff8b6ee9dfb027ba077c0e90a4a029bea55eadf3b0d39261b6204a5c1b8e5e80838ebeef5c9fd456c" + "0x02f8d4870c72dd9d5e883e8201540108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c5ed5f2eba43b9d6e656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a05423899586eb1d932cb9da03e478e1dd5d4cbbcb66d24262c7d67e543185c2ef80a035dfd635ab1210be852d9275b75490f908301278d8ecbb2d474367286494ea4fa0488d69db83f65da1b0bd9b15bff90193f94540e8fc85e50bc64fd3e0e04c13ab" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x16243e7995312ffa3983c5858c6560b2abc637c481746003b6c2b58c62e9a547" + "0x4ced18f55676b924d39aa7bcd7170bac6ff4fbf00f6a800d1489924c2a091412", + [] ] }, { "jsonrpc": "2.0", "id": "np373", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x349a0919fb81864d824dd7345c583a9fb5c99ef0bd9c549be68b10e72e7c8c2a", + "parentHash": "0x5aebb1a84a124ace93a6955bad2c1d3e26769ad5c4c8f7952bca62ffa6ecbb72", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe5a5661f0d0f149de13c6a68eadbb59e31cb30cf6e18629346fe80789b1f3fbc", - "receiptsRoot": "0x97965a7b5cca18575c284022cd83e7efb8af6fcf19595c26001b159771ffb0ce", - "logsBloom": "0x80000000000000000000000100000000000000000000000000000010000008100180000000000000200040000000000002000000000000000000000040000000000000000000000000000000000100000000000000000000000000400000020020000000000000000000000000000000000008000000000000000000000000000000000000002000000000000000000000000000000000048200000000000000000000000000000000000000000000000000000000000000000000000100000800000000000000000000000000000000000000000000000000000000440000000000000000121400000000000000000000040001000020000000000040000200", + "stateRoot": "0x92918085a958a3055fb1d5f08b63e9d93cad3c7dad9663e1298a31effb229074", + "receiptsRoot": "0x42df6f859795da6ef2cbdd440584688a8e875ce5708e87120336cf44292c4ec3", + "logsBloom": "0x20000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000009000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x175", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xe92", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x90c6119a5ecf366ff337473422f9872fddac4e2b193a2e0a065cf7de60644992", + "blockHash": "0x722cb497906813e0dac64a5e558aebc697f65a0929bdc4c9b763507b37d17442", "transactions": [ - "0xf87a82012b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa03e8b18cd5d8c796e69f450a4c00e75d7e2d38cf9d25dd19e2033fbd56fbf4b84a0175ca19057500b32a52b668251a0aec6c8f3e1e92dec9c6741a13ffe3fb214cc" + "0x01f8d3870c72dd9d5e883e82015508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c7eccf8bd8f40396c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0cb35fbd0ebf79655e6882326c19855ff90befcd2e589418566ec2e3a1efd65d880a0b5b75892245daeb02357c3cda72945b5cbc657144f86830ce3d44cd376c7d496a040829b65800769ce56e763b9f4f6b4c75cd3e2a4cffe4f83c62a44543385f6b0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb75f0189b31abbbd88cd32c47ed311c93ec429f1253ee715a1b00d1ca6a1e094" + "0xc95a6a7efdbefa710a525085bcb57ea2bf2d4ae9ebfcee4be3777cfcc3e534ea", + [] ] }, { "jsonrpc": "2.0", "id": "np374", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x90c6119a5ecf366ff337473422f9872fddac4e2b193a2e0a065cf7de60644992", + "parentHash": "0x722cb497906813e0dac64a5e558aebc697f65a0929bdc4c9b763507b37d17442", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0a82334be200ef303c1c3b95b92b6f397df138b7e6eb23d830fb306996f1c79b", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xb313932927133a6c5633b2359129debddf853188e91c7f6c1a1ea15a78310c4b", + "receiptsRoot": "0x0c6b26f41076d265df6003902de96f7e86c075dc5e9a63f8f48a1267d0597426", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x176", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xe9c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb023fb820fb7f3cc5b8c8ffec71401eae32858e7f5e69ffbdbdd71751bf1c23d", + "blockHash": "0x86eef2cdfc7f44f813f99a5699adb200ac3e48a490a1e01656f2991f1655f387", "transactions": [ - "0xf86582012c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0519fcc6ae02e4901d4ccfcd2b0560f06bf13478b459310ddaae39f44b7ed1394a03b529b53be6c0451a4b644f5031746cb1db62cfbe43b962da26aff507d4293ef" + "0x03f8fa870c72dd9d5e883e8201560108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cfe2939afc4f11be2656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0927e4ce70caf344a9e108ea8803cd49216852109c3e4922dfed2680e9f24361d83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0ec40ba7acaa9407312daa093659c29c50aa57686f5ed6c0ee253eaa2ec69caa3a07eac3c4bcdd598a852f6b2820f9560ceeb947b77aa25df5d7b8c2d626ac5b0d7" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xd087eb94d6347da9322e3904add7ff7dd0fd72b924b917a8e10dae208251b49d" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x2b2917b5b755eb6af226e16781382bd22a907c9c7411c34a248af2b5a0439079", + [] ] }, { "jsonrpc": "2.0", "id": "np375", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb023fb820fb7f3cc5b8c8ffec71401eae32858e7f5e69ffbdbdd71751bf1c23d", + "parentHash": "0x86eef2cdfc7f44f813f99a5699adb200ac3e48a490a1e01656f2991f1655f387", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8e7778cdef2ec78802c7431cdd44768e4a4f6d9c6cc494ae02dc20c10bc6eead", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x3cbbeca49a1945127768c0baff5802baa1b8e628e4488ed812d556689fe73bef", + "receiptsRoot": "0xdf52941811dbd734ad63629b45095b537ed4ea55e67c677ff846c59d39594956", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000020000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x177", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xea6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xafe3e6ffafc8cd84d8aa5f81d7b622b3e18df979dbffb44601eb239bc22132bf", + "blockHash": "0xf80b907a5268d198f59415e895a2dbd2d2f0ee499394f873bcaad64be35ba295", "transactions": [ - "0x02f86b870c72dd9d5e883e82012d010882520894469542b3ece7ae501372a11c673d7627294a85ca0180c080a09add65921c40226ee4a686b9fa70c7582eba8c033ccc9c27775c6bc33c9232fba021a6e73ccb2f16e540594b4acbba2c852a3e853742359fcbc772880879fe1197" + "0xf87582015708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cb5b303999df36021656d69748718e5bb3abd10a0a02616c26eab0952df93c0d803a3e77215f6291c78b8c8c06cd6db33c82f250740a038c446a1a88f1b808599ebe1fef015f19a071b51127078f2267f52fcc7358ac4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xbc17244b8519292d8fbb455f6253e57ecc16b5803bd58f62b0d94da7f8b2a1d6" + "0x18d5804f2e9ad3f891ecf05e0bfc2142c2a9f7b4de03aebd1cf18067a1ec6490", + [] ] }, { "jsonrpc": "2.0", "id": "np376", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xafe3e6ffafc8cd84d8aa5f81d7b622b3e18df979dbffb44601eb239bc22132bf", + "parentHash": "0xf80b907a5268d198f59415e895a2dbd2d2f0ee499394f873bcaad64be35ba295", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0b7ff239a80d7ca996fe534cf3d36898e55e3b4dbd6c130cc433dfb10d83c2dd", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xee441adb4bd9619daedecd5e1159e20ec049eed25fa122b221edfc99bab92964", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x178", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xeb0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x2b7573e48bca65c866e82401d2160b5bcaec5f8cd92fba6354d2fa8c50128e2c", - "transactions": [], - "withdrawals": [ - { - "index": "0x3b", - "validatorIndex": "0x5", - "address": "0x23c86a8aded0ad81f8111bb07e6ec0ffb00ce5bf", - "amount": "0x64" - } + "blockHash": "0xc4db6912f2653a9382b68bac827e5dd2eb40e3231f203a2f1f8eef0f72e6f02b", + "transactions": [ + "0x02f86b870c72dd9d5e883e8201580108825208944dde844b71bcdf95512fb4dc94e84fb67b512ed80180c080a0ec5d5b723b5308b6e3d040a18b25da216cd567053aa39e428de32f696081e037a01f5d2bc541a323b6809774727bd3bcde8f0119aeacf17016ee9a64a15f0623ca" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x3ff8b39a3c6de6646124497b27e8d4e657d103c72f2001bdd4c554208a0566e3" + "0xb47682f0ce3783700cbe5ffbb95d22c943cc74af12b9c79908c5a43f10677478", + [] ] }, { "jsonrpc": "2.0", "id": "np377", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2b7573e48bca65c866e82401d2160b5bcaec5f8cd92fba6354d2fa8c50128e2c", + "parentHash": "0xc4db6912f2653a9382b68bac827e5dd2eb40e3231f203a2f1f8eef0f72e6f02b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5cac010e2605b327b97a4ef6f78d4c65554588283336081d8ef497a3860fdbde", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xfe9441c6fb0bea27580b114b71918de7c6a52fd9b4476596ba6f1c61203d9144", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x179", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xeba", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x77b6c58098c59ec84605e8f12c7fbe8a358d52adf77948577ce7396ae18aaac3", + "blockHash": "0x499ed1595f081f971a86fa5d465264ec4ebcf362ca75b566c64ed9e143779b92", "transactions": [ - "0xf88382012e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a015118995d271e570428c3c349d49390af0fd81d3217f90159fc25b9d0791d6efa018c1a844d5d3523ce37308f0cd2e46e8d6ef99a9eb750e7325ca2c67d59aaf85" + "0x01f86a870c72dd9d5e883e82015908825208941f4924b14f34e24159387c0a4cdbaa32f3ddb0cf0180c001a0a5ef9f26c5bc750525a80636c71e0e8108fd2ddb4f7f578c8d0a028e9109fdf9a046dce974cdccbe68db42073fe3cc2fe7ed24213042a89baf3c62c9d6884b7d82" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4d0f765d2b6a01f0c787bbb13b1360c1624704883e2fd420ea36037fa7e3a563" + "0xe4b60e5cfb31d238ec412b0d0e3ad9e1eb00e029c2ded4fea89288f900f7db0e", + [] ] }, { "jsonrpc": "2.0", "id": "np378", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x77b6c58098c59ec84605e8f12c7fbe8a358d52adf77948577ce7396ae18aaac3", + "parentHash": "0x499ed1595f081f971a86fa5d465264ec4ebcf362ca75b566c64ed9e143779b92", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe908771dea594628e0f4d2b5d3354bbc6f9cfa04a97249657a74b792c3254b77", - "receiptsRoot": "0x8dc461a171023c5f8e3f5d78e0842291fbe7b0a502495a334a1bc98337a8a1b4", - "logsBloom": "0x00000004000000000000000000002000000000000000000000000100080000000000000020000000000020000000000000200100000000000000000010000000000000000000000008001000000000000000040200000000000000000000020000000000080000000000000000000000000000000000000100000000000000000000000000010000000000000000200000000400000000010000120000000010000008000000000000000000100000000000000000080000000200000000000000000800000000000400010000000000000000000000000000000000000000000004000000000000004000000000000000000000000000000000000000000000", + "stateRoot": "0x3f938be2a05406b71df1d2f0e7a39ac8e229ce087850ad6142bffbb884b06101", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x17a", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xec4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x891853e3e9dd73b513556fa241d000aa63fecc5452cf39b3cc756619e9cea7b4", + "blockHash": "0xb079707f805c9e021d3e353694af2c1295ff098e90f96b7e597f604df32d4f7d", "transactions": [ - "0xf87a82012f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0d0666f18210bb986b7239269bfbd56336376ed77bb97b56e15df7647c1f06fe3a0718dc6abdefe863e76f0c3c356364d456d34d399b20ed93b61ed93a77bccbe80" + "0xf86882015a08825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c01808718e5bb3abd10a0a0e4a8c4ab19bcffc864f8fd1231ed192ce8929410d06e442a6fd0ae7222385d26a0256ace97ccc4af6f32ad0b74fadad90576966cb20e2a09c0c01e866b42b6f99e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf6f1dc891258163196785ce9516a14056cbe823b17eb9b90eeee7a299c1ce0e0" + "0xfc0ea3604298899c10287bba84c02b9ec5d6289c1493e9fc8d58920e4eaef659", + [] ] }, { "jsonrpc": "2.0", "id": "np379", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x891853e3e9dd73b513556fa241d000aa63fecc5452cf39b3cc756619e9cea7b4", + "parentHash": "0xb079707f805c9e021d3e353694af2c1295ff098e90f96b7e597f604df32d4f7d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x197f321622808ee71925004345aaf99ac87a833c97ee852265b6d8be5c0656fe", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xeb98c7b011307451fd9a31dbb0759dded576923c4b6dfa33c88eee8e553591b6", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x17b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xece", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8d3b2038418a6d5e44a3f5aef149d7d76a20f3ebd5aa3c9d4565ddaa94d00c07", - "transactions": [ - "0xf865820130088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa02f7e9b19c96e60b8bd18eaadf71b049e0f204d42e826667e5b741041663c1963a01ff9a63ae688fc0c05047b819d1b8326c55f60b62f84658814bf35c63b3e5c65" + "blockHash": "0x07a887698ad470a92e0ea4b515f4e0c1eef4d02e005090f039ccad1f98dfa78e", + "transactions": [], + "withdrawals": [ + { + "index": "0x21", + "validatorIndex": "0x5", + "address": "0x4a0f1452281bcec5bd90c3dce6162a5995bfe9df", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x1dbf19b70c0298507d20fb338cc167d9b07b8747351785047e1a736b42d999d1" + "0x4c3301a70611b34e423cf713bda7f6f75bd2070f909681d3e54e3a9a6d202e5a", + [] ] }, { "jsonrpc": "2.0", "id": "np380", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8d3b2038418a6d5e44a3f5aef149d7d76a20f3ebd5aa3c9d4565ddaa94d00c07", + "parentHash": "0x07a887698ad470a92e0ea4b515f4e0c1eef4d02e005090f039ccad1f98dfa78e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x19c0d6f1bcdcb2c419bb69ed7f176bd58c4833c057faede354566c4e6d6e9f20", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xfa5fbe90adb6cd85bed45c22220141e4d4d688ee56d31f9e5ae9395b8c3542d9", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x17c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xed8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa63604362866798edab2056c5ddadc63dc1490c6f13bf5dd54008e1e0f64ecd1", + "blockHash": "0x37c51aeb36996d1204e1cc23f24fc8ce6a531230eac5fd95a0157afbae993408", "transactions": [ - "0xf86882013108825208947f2dce06acdeea2633ff324e5cb502ee2a42d97901808718e5bb3abd109fa0fd195ea41804b21ffffdbca38fd49a9874371e51e81642917d001d201a943e24a0542bca46a2dc92fddb9abffcf2b3e78dc491d6e95040692e6d1446a6b487a42a" + "0xf88382015b088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0fc733fa3fb48d3f13ee5eefc2c264d3403b8f29611cb31af2321865502c828bba059f364a077bf6aa468af37acd5c9eed697dbea3e4d35f230c96c6f0961214e44" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc3b71007b20abbe908fdb7ea11e3a3f0abff3b7c1ced865f82b07f100167de57" + "0x84a5b4e32a62bf3298d846e64b3896dffbbcc1fafb236df3a047b5223577d07b", + [] ] }, { "jsonrpc": "2.0", "id": "np381", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa63604362866798edab2056c5ddadc63dc1490c6f13bf5dd54008e1e0f64ecd1", + "parentHash": "0x37c51aeb36996d1204e1cc23f24fc8ce6a531230eac5fd95a0157afbae993408", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6c634927494436f7c4daaee4ea5c99813ec3066af379315b031f40fdf12c74d8", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x5dd19ed57b4f4d3f2fae68e07911c6940af44fb058c9a9454775e87433315e18", + "receiptsRoot": "0xaaf879f16bc945f981764629a68f186ca15a1cc726a6e0994ef7227794ef638a", + "logsBloom": "0x00000000000100000000000000000000100000000000000002000000000000000000000000000012000000000000002000000000010000000000000000004000000000004000008000000000100000000001000000000000000000000000000010000000000000000000000000000000000000000000000000000000080000000000000000000000000000080000000000000000000000000020000000000000000008000100000800000000000000000008080000000000000000000000000000100010000000040000000000000002009008000000000800200000000010000000000000000080000000000000000000000000000000000000000004000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x17d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xee2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x2187bb0b54e92e3bc6f0da1665631a818ac120ad68aa9674277d542f1e542f44", - "transactions": [], - "withdrawals": [ - { - "index": "0x3c", - "validatorIndex": "0x5", - "address": "0x96a1cabb97e1434a6e23e684dd4572e044c243ea", - "amount": "0x64" - } + "blockHash": "0xfb7823c99d6a8cecf4576cccad394131869c27c19903241a4bac149e8a9df5cb", + "transactions": [ + "0xf87a82015c0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0bca3972d67f3e443b15ef0b1f58d20971b740224462b717cb8a13fcee5381836a004c0d9a49c69b979caa2a1a507fdae8b61d34eb76652ceed6327bf4d4e75f02c" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x3f45edc424499d0d4bbc0fd5837d1790cb41c08f0269273fdf66d682429c25cc" + "0xff70b97d34af8e2ae984ada7bc6f21ed294d9b392a903ad8bbb1be8b44083612", + [] ] }, { "jsonrpc": "2.0", "id": "np382", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x2187bb0b54e92e3bc6f0da1665631a818ac120ad68aa9674277d542f1e542f44", + "parentHash": "0xfb7823c99d6a8cecf4576cccad394131869c27c19903241a4bac149e8a9df5cb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x04f641173e82bbe7455a3acd37242315859a80d9b4a19a56997645e31a1d1097", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x434fd480c866cda1d71f0ee80014364d4c42243823bf64409c1776409b4e7062", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x17e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xeec", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xdd46cd98c3f0f31bf7b060263fa47e9b0aa1c4e4c7206af16ad3a01dac3bff5f", + "blockHash": "0xb43189b040f33d48780cb23517066fa7ef9be143f72926c776dd2a0deb74cdd8", "transactions": [ - "0xf88382013208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a08bc9a47ee84ed9389b94c57e8c7014515fefd3e891eff0e1deac8cb1266cfb05a06612fac81c3e0a0b905873bb3f9137f9f8ae952344a174e4d425564b31851350" + "0xf86582015d088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0ebb83ef8d58970c8d0b8eef25ef497d0a50401368a20f8f8a7d0ba061cbe2d73a042360047a3fc34863766c17a2c7bbc10355084608fbf1041530d1a14e4c01288" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xcb8f5db9446c485eaae7edbc03e3afed72892fa7f11ad8eb7fa9dffbe3c220eb" + "0x73e186de72ef30e4be4aeebe3eaec84222f8a325d2d07cd0bd1a49f3939915ce", + [] ] }, { "jsonrpc": "2.0", "id": "np383", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xdd46cd98c3f0f31bf7b060263fa47e9b0aa1c4e4c7206af16ad3a01dac3bff5f", + "parentHash": "0xb43189b040f33d48780cb23517066fa7ef9be143f72926c776dd2a0deb74cdd8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2cc62d5cb6ca1b74dd31ced44a51655d15f0c67d9e8b4560584124ea91649145", - "receiptsRoot": "0x7288150e98b9056465e864af6976d5ec6de80da74cee77596b9a67de235177ac", - "logsBloom": "0x000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000040000000000008200000000000000000000000000000000000000000000000041000000000000000000000010000000800c0000000000000000400001000000000000001610000000080000200080000000000008000000001000000800000000000200000000008000000000000000000000000040000000002000000000080000000000000000000000000000000000000000000000000000000000000000000000000008000000000200000000040000800080", + "stateRoot": "0x463aef358cdff7e34839a185fb9f55a731b3494c97d0862eac151900b40fcf0c", + "receiptsRoot": "0xa34aba31a61b5b0f8a666d471417fe5a2b7b346b8cf7596cb7b91e574cdf33db", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000008200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x17f", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xef6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x808dd663054b022868554929395cf380b27661a0ae7333a92d69160769afbbbe", + "blockHash": "0x36d98a00fa9cb5f2d23adaac16766bf86c534154016d362227b77a09e466ed03", "transactions": [ - "0xf87a8201330883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0f1dbbd841499d2a51db61a05cf4a7a5650fd83eafe8516d0ad49e99db40c0d13a0542104414214add483f5e7397e9b98e95d336d60ff2b661eabfc8125548df848" + "0x02f8d4870c72dd9d5e883e82015e0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c9ccc0eb18b01c799656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0187c8bbc8cd3f478b5688bc03cf5eda82ee75aa605e946b39ed1898f0cc0e00f01a0fe9e522796cce1e5edeee1b4d839489efdf2a88716a677225586730033a452f8a042412e98bc67d6fece4f9e6e0295b8a7db6a654e3d3aa45189d7df51fefa9e8c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x3d151527b5ba165352a450bee69f0afc78cf2ea9645bb5d8f36fb04435f0b67c" + "0xed185ec518c0459392b274a3d10554e452577d33ecb72910f613941873e61215", + [] ] }, { "jsonrpc": "2.0", "id": "np384", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x808dd663054b022868554929395cf380b27661a0ae7333a92d69160769afbbbe", + "parentHash": "0x36d98a00fa9cb5f2d23adaac16766bf86c534154016d362227b77a09e466ed03", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf88d2d5d961b54872a1475e17a9107724ba2cd0ca28cb7320aad2f903dc74deb", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xeed54f9703bb531d2c17ad91c352a358544c949059e43a638688ebb06e5af764", + "receiptsRoot": "0x546613d89c675ca166e3b86c77b03920935c041b3652da17dd6f6cc04aff6678", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000001000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000020000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x180", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xf00", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x86bca890ff8f5be8c986745f38ef4a87ce167fcaacc0de928f4c8db469bba94a", + "blockHash": "0x864f50b8a89fc8049af6830206eeacfa26205d9ac2f1e9ef297c024532a57be4", "transactions": [ - "0xf865820134088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0922834adc69ced79913745b4a53a63ff0b0d73552c658f63c35b74fe831f1990a072af738962b2108e1e3e534c88145aa55764f2908bdbce0a4433ef88e3fbfb0c" + "0x01f8d3870c72dd9d5e883e82015f08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c036eab5d1496600f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0afc44d58dec637206e79248a528189c68365e20afc23410475deb5e5dc69c82a80a03228bf3e8e8afcf77dddab3e3c888665915421562e1ba75483734c20b3bccbd3a035e97ae4c4084f99cdc32d4971ccecc9da56b456a4290721283fa44c5d6dc8e9" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xdd96b35b4ffabce80d377420a0b00b7fbf0eff6a910210155d22d9bd981be5d3" + "0x5cfbad3e509733bce64e0f6492b3886300758c47a38e9edec4b279074c7966d4", + [] ] }, { "jsonrpc": "2.0", "id": "np385", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x86bca890ff8f5be8c986745f38ef4a87ce167fcaacc0de928f4c8db469bba94a", + "parentHash": "0x864f50b8a89fc8049af6830206eeacfa26205d9ac2f1e9ef297c024532a57be4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x248cbc35df3f48575474369a9105962a22bff30f3e973711545bb9cae1e06dff", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xc0b2c99de9c2cab2946d5074ed9201e9579af45846fb1d9e1c07487de30a9779", + "receiptsRoot": "0x4aecc944f33d425d167e974a14892ffee063fd9697823a42a2e0037e5a2c1d8d", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000009000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x181", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xf0a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x83132e862eb410579a38d85bbec7fdd5b890647bc9ccc2ad881361a9389cd3fa", + "blockHash": "0xa68dad1f5a2ca3fec7174293fb1eafeed1b3e1209dfc74ba1d4f67272530d1b9", "transactions": [ - "0x02f86b870c72dd9d5e883e8201350108825208943bcc2d6d48ffeade5ac5af3ee7acd7875082e50a0180c080a03931e5e7d02ed045834da39a409083c260fbc96dc256c1d927f1704147eeaeb6a0215269010bb3e7dd8f03d71db3e617985b447c2e0dd6fc0939c125db43039d0f" + "0x03f8fa870c72dd9d5e883e8201600108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038ccb602560a8ca054b656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0e2a0b166c03b200234eacf5eaf9ea11746c9bfd00e72f55d8cab76e0eca7195a83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a014ab990b716fd8be13e9a2439dd38ab3469f2ba1e9e5355031f7d57cc16fe28aa01fcc7a8080064238333c605ad57b373665d3ea857b58dcc4493ab055be5667ff" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xace0c30b543d3f92f37eaac45d6f8730fb15fcaaaad4097ea42218abe57cb9f4" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x867a7ab4c504e836dd175bd6a00e8489f36edaeda95db9ce4acbf9fb8df28926", + [] ] }, { "jsonrpc": "2.0", "id": "np386", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x83132e862eb410579a38d85bbec7fdd5b890647bc9ccc2ad881361a9389cd3fa", + "parentHash": "0xa68dad1f5a2ca3fec7174293fb1eafeed1b3e1209dfc74ba1d4f67272530d1b9", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x899d1787e12b4ee7d5e497ac1b07d460146316edd86d589dd357e4e39e6e50a5", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xbc6c97a060f00ab1be806a461d8e04d012651014ea6100c41753e932b3c43ec5", + "receiptsRoot": "0x4331ea2666467e36433120994481707bce23469d4639f5cb85785f8fc1daebfc", + "logsBloom": "0x08000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000040000000200400000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x182", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xf14", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb2b948b9139c380319a045813000f17a02153426ae3db02065a7bc6fb1b3d41e", - "transactions": [], - "withdrawals": [ - { - "index": "0x3d", - "validatorIndex": "0x5", - "address": "0xfd5e6e8c850fafa2ba2293c851479308c0f0c9e7", - "amount": "0x64" - } + "blockHash": "0xb5d6be7351994263965ff5d6bec155497dfae4101d9fa6f7474f4346432cc94f", + "transactions": [ + "0xf87482016108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c7ea611ad5cf07d1b656d69748718e5bb3abd10a0a0873a6822a956861366590a1156d256b1bbb07e02e15f6da3b166522ae0d2f50c9ff1915186b50164055d6b6e3a9b46df65ead3ed7889c2696bf87c0b89e2924b" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf6342dd31867c9bef6ffa06b6cf192db23d0891ed8fe610eb8d1aaa79726da01" + "0x0d01993fd605f101c950c68b4cc2b8096ef7d0009395dec6129f86f195eb2217", + [] ] }, { "jsonrpc": "2.0", "id": "np387", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb2b948b9139c380319a045813000f17a02153426ae3db02065a7bc6fb1b3d41e", + "parentHash": "0xb5d6be7351994263965ff5d6bec155497dfae4101d9fa6f7474f4346432cc94f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6fd59459f6805b1c3f35cd672f058d3f4215b8ba06217056195a249529106097", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x8203857ab0f4351d2fc345161fed67871eacce08f4c0590074372d0ffa2ef01b", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x183", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xf1e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xec59612429465042cb5bfe00c2720e2b06608cc0befdf12185f61213dede36a3", + "blockHash": "0x435041bdf7d03562f6cc28be67dd48e2a55cb6c36a8bde74217c78962fe35c04", "transactions": [ - "0xf88382013608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa02f68ef0be353bceb12bd978567947ea2ade48f275f8488d4d9089a6a5df54ecaa01ea605cad7ded16c6744be5446342cef46c0f802938d30db72ee4e35eb0ee726" + "0x02f86b870c72dd9d5e883e82016201088252089483c7e323d189f18725ac510004fdc2941f8c4a780180c001a02e258ae70f2eedc9eea027f8bb64f75b3f28c6c08d3c634d9f2bf63472a836bca01bda3a325bafa449bf2e7dc725b096b5fae087bb633c2fb250dd5b77122ca795" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa6589e823979c2c2ac55e034d547b0c63aa02109133575d9f159e8a7677f03cb" + "0x8e14fd675e72f78bca934e1ffad52b46fd26913063e7e937bce3fa11aed29075", + [] ] }, { "jsonrpc": "2.0", "id": "np388", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xec59612429465042cb5bfe00c2720e2b06608cc0befdf12185f61213dede36a3", + "parentHash": "0x435041bdf7d03562f6cc28be67dd48e2a55cb6c36a8bde74217c78962fe35c04", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x87aa8da72c4f54683d4ddfe7592b17518075332583bf40a0af34b072e1b8d5ca", - "receiptsRoot": "0x6b2a7f9df51def8b942a27f69021bd8954a4d01182bc78fe20171ec738d6a1cd", - "logsBloom": "0x00010000004000000000000000000000000000040000000020000000000000000000000100208000000000000004000000000000000000000000000000000000000000000000000020000000000002000000000000000000020000000000000048000000000000000000004810000000201000000000000000000000000000000000000000000008000000000000010000000000000000000000000080004000000000000000040000000000020000000000000010000000000000000000040000000080001000000400000000000000000000000000000000000000000000000000000000000000000000080000000000000020000200004000000000000000", + "stateRoot": "0x34e957b7fe8989ad1a1348053a6fcf0f60eb9831d3e0411557da90f20290b592", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x184", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xf28", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x18a50573c6144ce2d2c185b146827fbde1568f647d6bcc2c2556df64a00d3462", + "blockHash": "0x74659e9bea0d8d39ee2966f14026731c00cfeac2addae8ab7440f3897752035a", "transactions": [ - "0xf87a8201370883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a036602b451fdd27281014a28c261ac59feabe8c6730619162c51ccd6452e0efcfa01dbbc3cb987dd50dbb59072a156ce01b7825d252e5855249afbda11fd763436e" + "0x01f86a870c72dd9d5e883e82016308825208945f552da00dfb4d3749d9e62dcee3c918855a86a00180c080a06c29f5b2e14545a26d4c4fabd5be664ade5046e75bf947df58319e704cd15e83a0411cfb33b24f61406444f3b60bd7269aba228f69fb30073879e54c1d5a61f7a0" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9ce48bc641cc1d54ffdb409aab7da1304d5ee08042596b3542ca9737bb2b79a8" + "0x4ec1847e4361c22cdecc67633e244b9e6d04ec103f4019137f9ba1ecc90198f4", + [] ] }, { "jsonrpc": "2.0", "id": "np389", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x18a50573c6144ce2d2c185b146827fbde1568f647d6bcc2c2556df64a00d3462", + "parentHash": "0x74659e9bea0d8d39ee2966f14026731c00cfeac2addae8ab7440f3897752035a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4970ca728c597509e3afb689227e843d5da3be74aea9719a756d65db2694b152", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xea3a8543a0d754626f48f9e2bccafddf6b5391ed9da5a8e802d9aeff39ba3500", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x185", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xf32", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3ad7ba10baedb1b98556cd20670c57f2f3a4aa0ddfbf76c9a2cbbcec188dada5", + "blockHash": "0x8166e02057fbd66e2bdfdeb5e1b7348030fb8dcdf336c608186ecdf95a878d73", "transactions": [ - "0xf865820138088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a09a9bf09cafb07d6a97b972a3b405a1dd30dcd6945d9adda6cf921c211bc046e1a03c97b3b08d67e3ccfcb8408e39d2e0971761c1905fbd7028fb52a1f163fb92f3" + "0xf8688201640882520894c7b99a164efd027a93f147376cc7da7c67c6bbe001808718e5bb3abd10a0a0d892ded71ca2da8583433304c4936503f7c77abf5f5192edcc2f71445614fa3ba0578cb9c3c920c69eddae921e7c6d67ff6f7cde3c4b1f45f48724be79fe9a13b9" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa44be801bd978629775c00d70df6d70b76d0ba918595e81415a27d1e3d6fdee9" + "0xec69e9bbb0184bf0889df50ec7579fa4029651658d639af456a1f6a7543930ef", + [] ] }, { "jsonrpc": "2.0", "id": "np390", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3ad7ba10baedb1b98556cd20670c57f2f3a4aa0ddfbf76c9a2cbbcec188dada5", + "parentHash": "0x8166e02057fbd66e2bdfdeb5e1b7348030fb8dcdf336c608186ecdf95a878d73", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc5da7efe2ca6d0468002914ea2c334be08121fb5450b4a1b74baf08e65115192", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x2f9f3ce5b39159a1a49122bf41140eaee9ec2bb1a396e59fb7fb2520dd512096", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x186", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0xf3c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa2deafade520007dd7d127c439290f2bac7a2027b80ff616ccf8ce62eeba6506", - "transactions": [ - "0xf8688201390882520894f83af0ceb5f72a5725ffb7e5a6963647be7d884701808718e5bb3abd109fa0a38cf9766454bd02d4f06f5bd214f5fe9e53b7a299eda5c7523060704fcdb751a067c33351f6f7bbd9de5b5435f6cadc10ba5e94f3cbcc40ee53496c782f99d71f" + "blockHash": "0x686342d6e14add1de361c209a4f097174472120c2649d4b1e3c0d69478c573a5", + "transactions": [], + "withdrawals": [ + { + "index": "0x22", + "validatorIndex": "0x5", + "address": "0x2d389075be5be9f2246ad654ce152cf05990b209", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xce17f1e7af9f7ea8a99b2780d87b15d8b80a68fb29ea52f962b00fecfc6634e0" + "0xefdd626048ad0aa6fcf806c7c2ad7b9ae138136f10a3c2001dc5b6c920db1554", + [] ] }, { "jsonrpc": "2.0", "id": "np391", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa2deafade520007dd7d127c439290f2bac7a2027b80ff616ccf8ce62eeba6506", + "parentHash": "0x686342d6e14add1de361c209a4f097174472120c2649d4b1e3c0d69478c573a5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7f1f4d793182771fbacb9ef07a0736edbe4aa2417bf775c7b499b35ad791575a", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xa913a36ebb2c7286813fd5544542ba932c75ceebd10efa36b772066d1336b019", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x187", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xf46", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xfce102ce6fa4701cfa7ca7c4aae937b79190e29b55a453e67f31adece99c4f92", - "transactions": [], - "withdrawals": [ - { - "index": "0x3e", - "validatorIndex": "0x5", - "address": "0xf997ed224012b1323eb2a6a0c0044a956c6b8070", - "amount": "0x64" - } + "blockHash": "0x69ee2c164e201f10e82103b762fa299a98efcd3efb531d7f684cc93fe20877bc", + "transactions": [ + "0xf883820165088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a08f095627d823ccfe8ac3f93f8d6ce42a33865c729ec95941f9b1428590e1b922a01241e87129a475efd61aae53033db7e37576260983c403c1c3663a4e0cfce194" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4bd91febab8df3770c957560e6185e8af59d2a42078756c525cd7769eb943894" + "0x551de1e4cafd706535d77625558f8d3898173273b4353143e5e1c7e859848d6b", + [] ] }, { "jsonrpc": "2.0", "id": "np392", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfce102ce6fa4701cfa7ca7c4aae937b79190e29b55a453e67f31adece99c4f92", + "parentHash": "0x69ee2c164e201f10e82103b762fa299a98efcd3efb531d7f684cc93fe20877bc", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x58f87e8c7ffa26035df5258225c492a17f353b2d33420e0ac5b5413f0c29be1a", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x30136876a22c79da7c69981a1022b210879614e2cc999acd90f349bb81ed7876", + "receiptsRoot": "0x9dd67ebc56712a7467d9464a0af506a7e731935e3dfe70c7d0bfefbc10cc316d", + "logsBloom": "0x00000000000000000000000000000001000000000000000000000080000000000400000404000000000080000000000000000000000000000000000004000000000800000020000000000400002000001000000000080000000000000000000200000004000000000000000000050020000000000000010000000000000000000000000000000000000000000000000000200000001000000000000004000000000000000020000000000000000000000001000000000000000000000800000000000000000000000000000100000000000000000020000000040000000000800100000000000002000200000000000000000000000000000000000000004000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x188", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0xf50", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5aff5c82ef6756d97e6caaf6bc6084f4091ed2503b88083a0c4b0484f6e9525d", + "blockHash": "0x977c2a14bc576911c691938eb8badf6a77843c4214b0613133fa356a23aa7f92", "transactions": [ - "0xf88382013a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0e60cd99574bb50b626cf0b20d73ece21858aba52609136e6e2dc420a9fdc00eea00aeff0a4419c24268d9784a1ae211927004d8dbbbda3c47c0d0e2d32178ce8f4" + "0xf87a8201660883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a006e6eb4624ffee7629bad221ef5a8e8cf28e9acd1488f2762f76c254fbd5a5fea03eade6b173f9e255a9280f2e9c948a01fa5f67cbb75fa4107f30bfa818c1ee3b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x414c2a52de31de93a3c69531247b016ac578435243073acc516d4ea673c8dd80" + "0x137efe559a31d9c5468259102cd8634bba72b0d7a0c7d5bcfc449c5f4bdb997a", + [] ] }, { "jsonrpc": "2.0", "id": "np393", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5aff5c82ef6756d97e6caaf6bc6084f4091ed2503b88083a0c4b0484f6e9525d", + "parentHash": "0x977c2a14bc576911c691938eb8badf6a77843c4214b0613133fa356a23aa7f92", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x14a7327b3cff203afe17f16aca0470fbe12cfac971c79ef9bd5b3ef71bce5591", - "receiptsRoot": "0x3b0559fd9e27f69f8a378d27e3b5a82f18881f307f49ec63f89ad4bae18a1ee6", - "logsBloom": "0x00001000800000000000400040000000000010002000000000004000000000000000000000000000000000000000000000000000000000040000000020000000000000000000000000000000000001800000000200000000000000000000000021000000000000000000000000000000000000000000000000002000000000020000000008000002000000000000000000000000000000000000000000080100000000000000000000000000000020000000000040000000000000000000000000000000000000000020000000000000000001000000000000000200000000000000000000004000000000000000000004000080000000020000001000a00008", + "stateRoot": "0xd655197085c144158f70b071963f65898ac8b024e09f768aa23debb200627769", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x189", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0xf5a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb22e30af8a7f23e2b73275e505b5c6f482357576c82e3d718b0c4c33914d97e6", + "blockHash": "0xd9a295a0e39c94e3e9c9305b2e410aa89ee5380a8c343b901fc2ce60a19a431c", "transactions": [ - "0xf87a82013b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa061705b5163977bf95976fb0d2f44c1c581d19de8f68084001ed516813a7f5785a07daeb176a18749f11e1cec56a72e988c8362c2e15b86a9c5ae3e2cb2ddde0ce2" + "0xf865820167088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0d3dddbfaf3f7d67794a1af773a81224a033a1c309ed8d1256b0fdf41afa302f4a057c135428d584fec4526536760d0d6801243a495811b0ff25dcc9441fb5320c3" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x647fb60bdf2683bd46b63d6884745782364a5522282ed1dc67d9e17c4aaab17d" + "0xfb0a1b66acf5f6bc2393564580d74637945891687e61535aae345dca0b0f5e78", + [] ] }, { "jsonrpc": "2.0", "id": "np394", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb22e30af8a7f23e2b73275e505b5c6f482357576c82e3d718b0c4c33914d97e6", + "parentHash": "0xd9a295a0e39c94e3e9c9305b2e410aa89ee5380a8c343b901fc2ce60a19a431c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x02eb8f611a78bed4123c7b1ec6ca3148dee547538828183756744882a58b6993", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xe945c1dd5800f2dc2c10b812401b1d619f1052672ca44029c41780adff44296a", + "receiptsRoot": "0x6c5b098fbf232d565604bd4d7e82242720e0fa2629ef35404a6d74d66237c0db", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000800000000000000000000004000000000000200000000000000000000000000002000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x18a", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xf64", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9a348ddcb5d7c63d344358308acfd52c1be4432de1bdd02a4c1483521b95d7e0", + "blockHash": "0xf2d8812d4f28578755d4229aef19bd2162c69cd9dbc684dd6a0b0b64c979bd73", "transactions": [ - "0xf86582013c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0463d74275ffee97deea0603bdab389823c88c03997f176d4c349514d78d4dbc4a06b9796eed221b40094ded3ec3fa9bdbf097561ac3f8a142fef5e2c894a8296de" + "0x02f8d4870c72dd9d5e883e8201680108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c3ce71abfd2a9f6e3656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a01bf8eef1506aea16c94dd534ab271dfdae26648de569b3bf6fc8bf4c76bd1a9980a08a54ccd165615a3f6c5c494e2844295ccf525857205a2f86c053030f24d74587a040be30b7aeb05f7cc03b3d2ee39a6cb0c401083a305e93735e93eea1c3ed827b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xfa681ffd0b0dd6f6775e99a681241b86a3a24446bc8a69cdae915701243e3855" + "0x96eea2615f9111ee8386319943898f15c50c0120b8f3263fab029123c5fff80c", + [] ] }, { "jsonrpc": "2.0", "id": "np395", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9a348ddcb5d7c63d344358308acfd52c1be4432de1bdd02a4c1483521b95d7e0", + "parentHash": "0xf2d8812d4f28578755d4229aef19bd2162c69cd9dbc684dd6a0b0b64c979bd73", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe5d836ff1dc0a199a799bdb1aa945580acf9e06c96bd6b88cbc60903e5904b9c", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x5fc89e717b8110ffa180abbbf968a6e6a0fa0474f7b1384dbed83d5095b5351a", + "receiptsRoot": "0x125f11b4c9f735f497b05529580226e6e3e005be03a1957777846217f5357f0a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000800000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000109000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x18b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xf6e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x584b00c97139674af12f17a4a4828e59951c7f7d0c4fae83d5711ce5e582fdca", + "blockHash": "0xc64105453f3f4a50ea7452760ca6066140fc6f2115e16065c397778756460d79", "transactions": [ - "0x02f86b870c72dd9d5e883e82013d010882520894469dacecdef1d68cb354c4a5c015df7cb6d655bf0180c001a06faf4090490862eba3c27dfe0a030a442ccc89d4478eca3ed09039386554f07ba0656f741b64c54808ac5a6956540d3f7aaec811bf4efa7239a0ca0c7fb410b4d6" + "0x01f8d3870c72dd9d5e883e82016908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c885c8e7048f4f360656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a01f1860251182573015d583a718463a52050e45d795ec0f94d112206c3fd62e4580a02ac6dde1e6dff9ec4155a56114ddd824ef545648c7d523b4b1ece0b781cdcb89a06007350fcd96693d0dedbeea776518761a47dc51a714f55c031b20d443c3cee1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x106ca692777b30cb2aa23ca59f5591514b28196ee8e9b06aa2b4deaea30d9ef6" + "0x68725bebed18cd052386fd6af9b398438c01356223c5cc15f49093b92b673eff", + [] ] }, { "jsonrpc": "2.0", "id": "np396", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x584b00c97139674af12f17a4a4828e59951c7f7d0c4fae83d5711ce5e582fdca", + "parentHash": "0xc64105453f3f4a50ea7452760ca6066140fc6f2115e16065c397778756460d79", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8fc7b0893f25c43c0dd53f57c7f98653e86d2570923f1831840c09c7c728efab", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x6d3bb9ac8c90193e805743b2009e22877fcf38cef9e0fa3ad42b672c596a7785", + "receiptsRoot": "0x56aa14a0b1fc6db4ec5f0332dfefcd53238b912e98e4f8171f6ba5ebb1670f40", + "logsBloom": "0x00000000000000000000000000000000000000800000000000000000800000000000000000000000000000000000000000000000000000000000400000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x18c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xf78", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8e2b4e77e4fd7ab14ffaca65bc3a0868f14ce792ffe5f26cc0cc4abf8ebc5cd4", - "transactions": [], - "withdrawals": [ - { - "index": "0x3f", - "validatorIndex": "0x5", - "address": "0x6d09a879576c0d941bea7833fb2285051b10d511", - "amount": "0x64" - } + "blockHash": "0xff05bd7ed3a3f4e5abc2e5232c98d4343072bfd25121b241932703d33f875c0f", + "transactions": [ + "0x03f8fa870c72dd9d5e883e82016a0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cb3bbc461cd7b04b9656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a092da59b68bfd8a9c1cb1ca6a302ee966f829f2727a36823b0dc7fddf7790a10883020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a022c5c0771555973c9e1e3f6bc48bff07002eb74100e495b653e17e4681fce80aa0521757e341c26b96807d5659162b9a96382937584bafa07e43b5d3ac095da704" ], - "blobGasUsed": "0x0", + "withdrawals": [], + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x494ac6d09377eb6a07ff759df61c2508e65e5671373d756c82e648bd9086d91a" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xe2f1e4557ed105cf3bd8bc51ebaa4446f554dcb38c005619bd9f203f4494f5dd", + [] ] }, { "jsonrpc": "2.0", "id": "np397", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8e2b4e77e4fd7ab14ffaca65bc3a0868f14ce792ffe5f26cc0cc4abf8ebc5cd4", + "parentHash": "0xff05bd7ed3a3f4e5abc2e5232c98d4343072bfd25121b241932703d33f875c0f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb87cec8c84db91856e9ae32af116b449b8cb1d61cae190a182aebfb85d691e8f", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x3fc40ef76d78e19fac56084394db689edd279c048d0f449c09c39c04e5689494", + "receiptsRoot": "0x66b64724e3272f2ec6ef9d0c3f85a510900120dbfe843f1cda530557fd6c93cc", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000010000000000000000000000000000000000000000000000000000000001000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x18d", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xf82", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x657f16f62e12433129b4b3f80e92eee4a65d1cb6e8b847ce632d32cb79ba5abe", + "blockHash": "0x2fa9e1447264c03da65b930986c6c67078d887aa0b6252b49026c3bbc522ca59", "transactions": [ - "0xf88382013e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0065cd2e05815fd9bf6e9aced9947d0c43feed03d4bd010ce93828c5e45a9b483a019449b8fc18e639f9c1d7b0adbd3941622d1f2e8127b82993e0f8bb9cdc2999f" + "0xf87582016b08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c96c2e214be2bd0a2656d69748718e5bb3abd10a0a0eefa13b194da056212daca7c04fa697d680a2a7cf45a7eda53dfda0aa02692e1a06d27f41d4cb9322c0bde9008870c771aaeadd7a0dd25a0f965e07877d28854d7" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x0ae4ccd2bffa603714cc453bfd92f769dce6c9731c03ac3e2083f35388e6c795" + "0x48ef06d84d5ad34fe56ce62e095a34ea4a903bf597a8640868706af7b4de7288", + [] ] }, { "jsonrpc": "2.0", "id": "np398", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x657f16f62e12433129b4b3f80e92eee4a65d1cb6e8b847ce632d32cb79ba5abe", + "parentHash": "0x2fa9e1447264c03da65b930986c6c67078d887aa0b6252b49026c3bbc522ca59", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe154fbe6ca3c192310dea977b202b7e57523be45dfb36cf46816f7b1b86c910b", - "receiptsRoot": "0x09e88b070a05aab53918792ba761837b32e299692e1ee33a27d3b654a45ea25f", - "logsBloom": "0x00000001000000000400000000001000000008120000000220000000000400000000008000000000000000002000000000000000000000000000000000000000020000008000000000000000000004000000000000000000000000000000000080000000000000000000000000010000000000000200000000000000004004000000000010000000000001000008000000000000000000000000000000000008000000100000000000000000000000000010000000000000000000000000001000000000000000000000000000000010200000000004000010040000100000000000000000000000000000000000000000000000000000000000020000000000", + "stateRoot": "0x90bbc672313c5767ed1c21447ae06c6ebc9a1379a8d3bada37250d468cf4b6fd", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x18e", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xf8c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x677cd475087726e83d09edba4d2e6cdcaa5f1b9f5e7c26260ff6ebf4dd86a6aa", + "blockHash": "0x10c9eb1115f231e7a50650aa52acc568532a80c7c1e0d695517fe4da1d493a8e", "transactions": [ - "0xf87a82013f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a017bd3457b4b843b788bd719c6e49a5efad177ca349fa23ee93130c68a6c123a6a0595becbedbd04d964a7e8ca826f50061e1b1f16bea32c966670f7dbcc63dbbff" + "0x02f86b870c72dd9d5e883e82016c01088252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c001a096c29ad0d1f2947c8efd66353a3f3f2b4921d9bf5c58d0e4670348e29bf1b89da061bbc93071262fa15425909be708bf2c21d06886344e338e9e04dd196d7ba310" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd860c999490d9836cc00326207393c78445b7fb90b12aa1d3607e3662b3d32cd" + "0x5c57714b2a85d0d9331ce1ee539a231b33406ec19adcf1d8f4c88ab8c1f4fbae", + [] ] }, { "jsonrpc": "2.0", "id": "np399", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x677cd475087726e83d09edba4d2e6cdcaa5f1b9f5e7c26260ff6ebf4dd86a6aa", + "parentHash": "0x10c9eb1115f231e7a50650aa52acc568532a80c7c1e0d695517fe4da1d493a8e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x771db9f41d228f8d3e1a33889cc04468bb9691860cbdbf28203d90713eed1fb1", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x8db3010d08c4adcf5d271beb8e207ce75e9830c859070fdfc4dc4f30d6805c83", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x18f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xf96", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf60f85724891ffc25eb8c5c596e55846df4032b2edb35d0fc6ac64870db6b42f", + "blockHash": "0x5abe00a7721db9dc1fbf458d49714c666ca2424e476099adfb77fd8dd54a0eab", "transactions": [ - "0xf865820140088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0db06597d4b08ca3fef9b08c69896cef6505785b448bfd0e051ebc7616a2f5a1aa07ca5051c69a0dcb5fae23ba89cb806d860072426d2e450eda056e9e9d8ee360c" + "0x01f86a870c72dd9d5e883e82016d0882520894d803681e487e6ac18053afc5a6cd813c86ec3e4d0180c080a05451364a93364dc251918bf5d8f7cfffdf33b58bd3d48c3f333eab4daec6658ca0156953f7d30f24273a44d6a2f15e1520afcdcbbf7aedbd72f3c395d74cde0e92" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9587384f876dfec24da857c0bcdb3ded17f3328f28a4d59aa35ca7c25c8102cf" + "0x204299e7aa8dfe5328a0b863b20b6b4cea53a469d6dc8d4b31c7873848a93f33", + [] ] }, { "jsonrpc": "2.0", "id": "np400", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf60f85724891ffc25eb8c5c596e55846df4032b2edb35d0fc6ac64870db6b42f", + "parentHash": "0x5abe00a7721db9dc1fbf458d49714c666ca2424e476099adfb77fd8dd54a0eab", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd210aa806d0d5c95200a88fcc329357fb03782cc236bdc5f184c80246391162f", + "stateRoot": "0xcc7f1ba89ea6d4c2a5fbfcc4b42ef1609d9d10fcbad86d34eade03f4d447e7e8", "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x190", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0xfa0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe7a757335322c1008ee83083154c9a787ea3d93efce41c1b32882c8a6ea3a14f", + "blockHash": "0xade4149b0375ad07777a88bf87a50426806e7e69c98719e63763ebf8585d39be", "transactions": [ - "0xf8688201410882520894f14d90dc2815f1fc7536fc66ca8f73562feeedd101808718e5bb3abd109fa04a18131d30b0344910cae7c41ee5c1c23171c40292d34e9a82c9c7cef3d3836aa0598a3835ad1903c3d7ad158c57ff0db10e12d8acbef318ddd0514f671a08ce94" + "0xf86882016e08825208944dde844b71bcdf95512fb4dc94e84fb67b512ed801808718e5bb3abd10a0a030fd8987e8637c05b888e039311b4ce539062b9bb74e95bee4c1230a15316660a03b5edc40f556993df62f7210fa58a970b14bd8d4473a0df7590026589e83ea75" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4df8093d29bc0ec4e2a82be427771e77a206566194734a73c23477e1a9e451f8" + "0xb74eea6df3ce54ee9f069bebb188f4023673f8230081811ab78ce1c9719879e5", + [] ] }, { "jsonrpc": "2.0", "id": "np401", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe7a757335322c1008ee83083154c9a787ea3d93efce41c1b32882c8a6ea3a14f", + "parentHash": "0xade4149b0375ad07777a88bf87a50426806e7e69c98719e63763ebf8585d39be", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf77d84bb9077b7805492805f09aaeac8fdd72dadaba54464256d1b9633d7313d", + "stateRoot": "0xc2a2590076144444ddd91da89477bb827ca9153ac0d75676422ec75ff69577ff", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x191", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", "timestamp": "0xfaa", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x32976c704b12fd1ec0e6a409b89c8d3d5d0802f676bfd1848ae07cbb612f0289", + "blockHash": "0x90544280b5a1c89044d0a9acf28015355e9f87f99cebb6e423a2429593805c3b", "transactions": [], "withdrawals": [ { - "index": "0x40", + "index": "0x23", "validatorIndex": "0x5", - "address": "0x13dd437fc2ed1cd5d943ac1dd163524c815d305c", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", "amount": "0x64" } ], @@ -10197,1704 +12687,1739 @@ "excessBlobGas": "0x0" }, [], - "0xc56640f78acbd1da07701c365369766f09a19800ba70276f1f1d3cd1cf6e0686" + "0xaf5624a3927117b6f1055893330bdf07a64e96041241d3731b9315b5cd6d14d7", + [] ] }, { "jsonrpc": "2.0", "id": "np402", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x32976c704b12fd1ec0e6a409b89c8d3d5d0802f676bfd1848ae07cbb612f0289", + "parentHash": "0x90544280b5a1c89044d0a9acf28015355e9f87f99cebb6e423a2429593805c3b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8c45d111367d1e2766e18c8ef100cb4cbdd1db4171d269d0dee91b7789bf302e", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x816daf4319bb2e73679d9c72bc1197acfea24dcced35aacf7b959958b14b5748", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x192", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0xfb4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4cbab31c513775bdd5b7f91a153fff77cf1602430cedcebec80bedf0b6533658", + "blockHash": "0xcbaec457a9bb83f627a46b321256873866c0a5c079315e1294328fc71b7d8529", "transactions": [ - "0xf88382014208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0bab2abc49f4f65119331667d5bd95daefb8eec437cb7950b46f1b9a890efd4b7a065396085f5f690d669006b05bab15614816e44cf88bf49fcdf0a5857f364e6a1" + "0xf88382016f088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a05bb36f34fe06f126bd1110d297313d58ae78718e9e0fb3ff6e18afdfa56f3818a075ea98ed3729a3ece6704da4d80d5b13225ad6ebc6acfb834c2a8a669a991836" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7173d4210aa525eece6b4b19b16bab23686ff9ac71bb9d16008bb114365e79f2" + "0xc657b0e79c166b6fdb87c67c7fe2b085f52d12c6843b7d6090e8f230d8306cda", + [] ] }, { "jsonrpc": "2.0", "id": "np403", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4cbab31c513775bdd5b7f91a153fff77cf1602430cedcebec80bedf0b6533658", + "parentHash": "0xcbaec457a9bb83f627a46b321256873866c0a5c079315e1294328fc71b7d8529", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xade6dd841f231dcce74ab564f55972731c7eb4a0b5c3ec1a64bb979f754b786c", - "receiptsRoot": "0x424252c901f76c684b72e2637c97666a35b4020fe9fd8add1bd00fc83cf57512", - "logsBloom": "0x08000000000000000010000000000010002000000000000000000000040000200000000000000000001000000000020000000000000000000000000000000400010000000000000000000000000000000000000000000000000000000000000020400000000008100000040000000000000014000000028000000000000001000008000000000000000000000000000100000000001000000000000000000000000000020000000000000000000000000000000000000000000000000000800000000000080000000000000000000000000000000000000080000000000000001000000200800002000000000000000040000000000000000000000400000000", + "stateRoot": "0xb95406b5c576820d6fd109e71b527d4f9bb1dbb458ed2a4a6d90f8a6cb25b384", + "receiptsRoot": "0x4cd138fe4eb3a09100a9486093e73b7f05b48c286e7571fac1da38fa9c1e237b", + "logsBloom": "0x08000000000000004010000000000010002000000000000000000000040000000000000000000000001000000000020000000000000000000000000000000400010000000000000000000000000000000000000000000000000000000000000020000000000008100000040000000000000014000000020000000000000001000008000000000000000000000000000100000000001000000000000000000000000000020000000000000000000000000000000000000000020000000000800000000000080000000000000000000000000000000000000080000000000000001020000200800002000000000000000040000000000000000000000400000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x193", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", "timestamp": "0xfbe", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x64bfcedbb6b431f370027c5e2414fa70536e4cadaedca69d960d815570b1a514", + "blockHash": "0x888127ccf7a04b3ab6dc54a687036e7464c30e3fd813a0f4ddc69094cf250b90", "transactions": [ - "0xf87a8201430883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0097f470d08b374cc1ea0e0ecfb841f22e6f105c4989a6a41f23619320011f4dba06c843174399416f4a98ee5b5170a4330fbc487cc1bdc4e67f8eb3ca279fa8415" + "0xf87a8201700883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0c8616a2b954cfb2f2707c4a8fc6b8cc75c9fb1cd061be837d795c2174b773f77a04da08801f22e504206cac7fc792e4c0a65fb0ea8ca981381b419d3db08cc4b32" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x89698b41d7ac70e767976a9f72ae6a46701456bc5ad8d146c248548409c90015" + "0xa0e08ceff3f3c426ab2c30881eff2c2fc1edf04b28e1fb38e622648224ffbc6b", + [] ] }, { "jsonrpc": "2.0", "id": "np404", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x64bfcedbb6b431f370027c5e2414fa70536e4cadaedca69d960d815570b1a514", + "parentHash": "0x888127ccf7a04b3ab6dc54a687036e7464c30e3fd813a0f4ddc69094cf250b90", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x96e966680b69cd6f8f3c95b0bfcaa337959db055f2b4329813dd02f9e5350742", + "stateRoot": "0x6283fe7582b09ba2f3c59f797b270ac18c7ed091340aee4f4e8b2074b1b5d4d6", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x194", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", "timestamp": "0xfc8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4a13ab52191afd567f4587bee39174c54ca458576730a03854abfad2aca2e0da", + "blockHash": "0x08d7f2f015c06dee88d707cbc050021fd38afd6a253d3382a783e92ab30f22c8", "transactions": [ - "0xf865820144088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a09fd0702bca1c10269dcf83862a9f07981858a8a1579f3ed68642fdc8b77478cda027b1f49755229583c844b747c040251c2671dcfe83fa26df37d4bbfb54635864" + "0xf865820171088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0eeee915b6dcd97f488b2e0862ddf49be8f02b71ce27a970aa3d150a2b73c3d76a0151ede7670a2f2958cd967258efea3bebb7c9da0e7adadc47e07701477782f70" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x5b605ab5048d9e4a51ca181ac3fa7001ef5d415cb20335b095c54a40c621dbff" + "0xc9792da588df98731dfcbf54a6264082e791540265acc2b3ccca5cbd5c0c16de", + [] ] }, { "jsonrpc": "2.0", "id": "np405", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4a13ab52191afd567f4587bee39174c54ca458576730a03854abfad2aca2e0da", + "parentHash": "0x08d7f2f015c06dee88d707cbc050021fd38afd6a253d3382a783e92ab30f22c8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7fa007461e28a3bd63c35eb625b4c122197ed1d63a00b0a0959652cb745c034d", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x14d9fb7608ad2f76c0b79ea38c91e2f01743e40d5ce71a906ed89f44ce2d9a12", + "receiptsRoot": "0x83e14211439ab2e9769078e7d4bacb6da4763d09cfcd4fdda6b28526fa7e792d", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000010000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x195", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca90", "timestamp": "0xfd2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3c7adb6035b88d99e1113b076cd7ee852294e0f651e87e779f93b9625f50f173", + "blockHash": "0x729c0e22346bb677499d2b9af1da34dfaf7653ace58567673fc6894cf8d56289", "transactions": [ - "0x02f86b870c72dd9d5e883e820145010882520894360671abc40afd33ae0091e87e589fc320bf9e3d0180c080a09b0a44741dc7e6cb0f88199ca38f15034fab4164d9055788834e8123b7264c87a02c38a3ecda52aebc3725c65ee1cd0461a8d706ddfc9ed27d156cf50b61ef5069" + "0x02f8d4870c72dd9d5e883e8201720108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c07dd9b08a900173f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0434e2bcc5f4148668dd618144aac33ef5d463b292b3baad302a60aeb6be03b8601a087509826265d785d522c46423fbe09005b3a67c94c3c16add305eb7f8119ee71a02b871f33bb0bd2bbf2fdd46a0959e221ee03f0670343b9c4e8f6648cf9193d6c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9129a84b729e7f69a5522a7020db57e27bf8cbb6042e030106c0cbd185bf0ab8" + "0xc74f4bb0f324f42c06e7aeacb9446cd5ea500c3b014d5888d467610eafb69297", + [] ] }, { "jsonrpc": "2.0", "id": "np406", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3c7adb6035b88d99e1113b076cd7ee852294e0f651e87e779f93b9625f50f173", + "parentHash": "0x729c0e22346bb677499d2b9af1da34dfaf7653ace58567673fc6894cf8d56289", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3d03d9ffcd17834d8b99988eb8c1c9f36b8e627f50e2d850a6538d7610ba8457", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x203063aa2a6c46cf7d25340d80f0ddb56a22eadc507641d8af3809cbd8cf9937", + "receiptsRoot": "0xda00a4cb704a559e0a67e72cc49701afc18109c598434e05644724ad3f65dbac", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000200000000000000000000000000000000000000100000000000000000000000000000004000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x196", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xfdc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xda2511fe0f2d0c7384fdfaa42ba9d93127690645ed7f3bb5b48ab3bf31550561", - "transactions": [], - "withdrawals": [ - { - "index": "0x41", - "validatorIndex": "0x5", - "address": "0x6510225e743d73828aa4f73a3133818490bd8820", - "amount": "0x64" - } + "blockHash": "0xd60f9025487642346d1ff6fcb21558a0b719524dda4fb773e50254be6ea5cb70", + "transactions": [ + "0x01f8d3870c72dd9d5e883e82017308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cffdd7bff610bd696656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a019fbac480a243f8c051e10225cec11bcb7fb274fac8792ca7e36bab8e39d312c80a04bc739bceb821f509ae877ea8ea9bd82c253a7753543df995f20a5591ac284f7a0792682a6835e34c96fce7d5981820fe7205c6ecd5570acc8d5fcbe48d4487e90" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x31a63d6d54153ab35fc57068db205a3e68908be238658ca82d8bee9873f82159" + "0x1acd960a8e1dc68da5b1db467e80301438300e720a450ab371483252529a409b", + [] ] }, { "jsonrpc": "2.0", "id": "np407", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xda2511fe0f2d0c7384fdfaa42ba9d93127690645ed7f3bb5b48ab3bf31550561", + "parentHash": "0xd60f9025487642346d1ff6fcb21558a0b719524dda4fb773e50254be6ea5cb70", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xeb5feebaa9bd10619704d66efc97f95338c3e02dcebc2710be462faa47ddfc63", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xaa9c985aae31d5ca2a42624e5fafc7e2d4808cbf3dcfe033e719e1ac2bca7057", + "receiptsRoot": "0x1964831ba5d3c16a8539d764198bf986575324dd965ea3339e95c107e17177b1", + "logsBloom": "0x80000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000800000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x197", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0xfe6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x32704763870e0504f0386bb2e87511ccb2d033c83e9ef57a72327f5d23fd3996", + "blockHash": "0xc2f378a6349f5ff2413494603a2bf9bf387182e0d7b2e042e0aa9bdde16b44e6", "transactions": [ - "0xf88382014608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0e767d5dbf82d8857bccd947a04354b0023b0e283098f75e4d7d79348c24dca95a00a4d04094359f0817637570cf1ed12dcd2614da2e845751734d67175839a3903" + "0x03f8fa870c72dd9d5e883e8201740108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cef0bad2321e818b5656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0677a6b432bd3361f469c2e051c8e09ea92ed0d049eb563118ff8c680fc93a2a783020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0c44f471d116d1aca7299d564e3f5e2cd7a0d796310285dff60e4935815089e60a07e10d8cb1bff275ed9bedd1418aefc18e815db7568f529e032c0afc560d61b23" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x828641bcea1bc6ee1329bc39dca0afddc11e6867f3da13d4bb5170c54158860d" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x6cef279ba63cbac953676e889e4fe1b040994f044078196a6ec4e6d868b79aa1", + [] ] }, { "jsonrpc": "2.0", "id": "np408", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x32704763870e0504f0386bb2e87511ccb2d033c83e9ef57a72327f5d23fd3996", + "parentHash": "0xc2f378a6349f5ff2413494603a2bf9bf387182e0d7b2e042e0aa9bdde16b44e6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xaadc011ce89c8dd628f56494b7f19d8cf66c1555b3cb6b38fd6e31c908e83804", - "receiptsRoot": "0x0c78f3779ab455eed4ce5e60071fff80a3d289a33fd656e17017d53978fada5d", - "logsBloom": "0x00000000000000020000000040000000000080010000000000000000000000010000000000000000000000000000000000000000000000000000000004000000000000000000000000000001000000000000008001000000000000000000000000000000000000001000000000002000000000000000000000000000002000000000000000000000000000000810001000000004000000000000000000000000000000000040008000200000000000400000000000000000000800000000001000000000000000000000040100000000000000001000000000000000108000000000000000020000800000002000000100000000000000002000000000004000", + "stateRoot": "0x6e77461f7994d7cdf0faa3f3bbcc5f6aba9bf8c65d3a5b52e9eac397b37823c9", + "receiptsRoot": "0x1f55e6dc8eee0103c0154282873007279dc35597279793c98f6fcc2d4de2a915", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000020000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000020000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x198", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0xff0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x16f96f705d6378a460f67690c9df7ba0b0130dfb7bda8d79ac2ffe9fdee84606", + "blockHash": "0x2332603e1b89c41adb97428017bd2297310b5deeca32af3d79c88a23090d5aaf", "transactions": [ - "0xf87a8201470883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a00eab4059563c228f12cd79cdc77c5594af5bb5f9778dab439aead79a99c7da9aa010476536728e9bf977ad4c2cc25fb7d5587869148789e9fd6bf40d65b9e94bbb" + "0xf87582017508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c68c46027ef4b7464656d69748718e5bb3abd109fa019abe845ab42c8f4f0b26a3ce199dd4855ae4b18713465d1c48ab06574bc3654a034ad1f9c7406c18cdd07c4178899e6d3ac1e0836d38a915e532ec331cf97b78c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7e0752ddd86339f512ec1b647d3bf4b9b50c45e309ab9e70911da7716454b053" + "0x60eb986cb497a0642b684852f009a1da143adb3128764b772daf51f6efaae90a", + [] ] }, { "jsonrpc": "2.0", "id": "np409", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x16f96f705d6378a460f67690c9df7ba0b0130dfb7bda8d79ac2ffe9fdee84606", + "parentHash": "0x2332603e1b89c41adb97428017bd2297310b5deeca32af3d79c88a23090d5aaf", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0ed00985c27ccb9453093f70f7cae8594259e64c8962ee22121019210fe01824", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x77cc52aea1dd33ea8055a4f3224367ee609ee0724101acc80c44640e89b57c67", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x199", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0xffa", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x70c71163387d8226f299ed02fd7f266f79d708f11ea9133d28a6b13ee751e259", + "blockHash": "0x0b88f4a3ea4fe334e0f85983fc3ed8f0e5031f76642df83e9ffddff65637cf43", "transactions": [ - "0xf865820148088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0310416be8b0e49ec34116f9c8eb4dd4d4dc6e39e5c97ccb94ac96e8cd21a7333a029b7a950def860ab8bfd4e49e5f34bc731344ab60770ea27f656e64e6b2f90de" + "0x02f86b870c72dd9d5e883e820176010882520894654aa64f5fbefb84c270ec74211b81ca8c44a72e0180c080a0c35eb8c466b63ba1e03aaa0fe19df9e1e342fadf2146ac08e65d6d1df68343aca05d2d29e1d0c3eaac3128ceb1f97b49287e80dcfd9c4d352c5aa5c6cd306dcac6" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x31d973051189456d5998e05b500da6552138644f8cdbe4ec63f96f21173cb6a1" + "0xc50024557485d98123c9d0e728db4fc392091f366e1639e752dd677901681acc", + [] ] }, { "jsonrpc": "2.0", "id": "np410", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x70c71163387d8226f299ed02fd7f266f79d708f11ea9133d28a6b13ee751e259", + "parentHash": "0x0b88f4a3ea4fe334e0f85983fc3ed8f0e5031f76642df83e9ffddff65637cf43", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7ff6b18a2c62836e16cad9956e08422a430c268cda51f219422b628491066c6e", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x60ea844559cd2bf012d37b9820a350bfa749ab84e3dbce1773f4d223fcfb9297", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x19a", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x1004", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x67c274a189945d313dccd5b9cb4b7fd47614b59c716a4ed0944d8a1429781e78", + "blockHash": "0xd5359ec7c8dbda34bbb1391a68ee130ee2fd94cdd86f2e6683e4ca680ef2ee43", "transactions": [ - "0xf8688201490882520894579ab019e6b461188300c7fb202448d34669e5ff01808718e5bb3abd10a0a0de600e017080351550412ac87f184ec2c3f672e08f1c362ab58b94631e8864dca047d41b8691a1f7f8818e59ad473451a0edfc88826a6b808f84f56baed90d5634" + "0x01f86a870c72dd9d5e883e820177088252089484e75c28348fb86acea1a93a39426d7d60f4cc460180c080a0218999699955a193b336dfabf9ae461a76e2a706bdaa4210c77c0621106d4867a078c56e123752282d049c7f07b855516a29f56636dbb6584c645003e6a8d0a351" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe33e65b3d29c3b55b2d7b584c5d0540eb5c00c9f157287863b0b619339c302f0" + "0xb860632e22f3e4feb0fdf969b4241442eae0ccf08f345a1cc4bb62076a92d93f", + [] ] }, { "jsonrpc": "2.0", "id": "np411", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x67c274a189945d313dccd5b9cb4b7fd47614b59c716a4ed0944d8a1429781e78", + "parentHash": "0xd5359ec7c8dbda34bbb1391a68ee130ee2fd94cdd86f2e6683e4ca680ef2ee43", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x95d1e2783fcf975ce0a79a05166ad33628065812d76f1f92f88d8f77f5a49e88", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xb43131e2c4acc2d2e3c4b6a047e5c29d04db1dd153a9ef7f4512b8e557612ddf", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x19b", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x100e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x7ae0486d0457d3261e308c1074c7a206e11f3a41a8b3b49ff379d0998a62278c", - "transactions": [], - "withdrawals": [ - { - "index": "0x42", - "validatorIndex": "0x5", - "address": "0xd282cf9c585bb4f6ce71e16b6453b26aa8d34a53", - "amount": "0x64" - } + "blockHash": "0xe068d60356aae28f3154fa8f886f0f0067a7b74b524601c2f623610d258cbebb", + "transactions": [ + "0xf86882017808825208941f5bde34b4afc686f136c7a3cb6ec376f735775901808718e5bb3abd109fa06bb2030f614880eafeb4b5e867ccd0db435b5087d7ac256a1735f6bd31fe87fca02cd3a5b7ce81806d5ca89c9c27cfbe358f2aa39e2945b76f3cc1e4ca77390ec2" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x78d55514bcef24b40c7eb0fbe55f922d4468c194f313898f28ba85d8534df82c" + "0x21085bf2d264529bd68f206abc87ac741a2b796919eeee6292ed043e36d23edb", + [] ] }, { "jsonrpc": "2.0", "id": "np412", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x7ae0486d0457d3261e308c1074c7a206e11f3a41a8b3b49ff379d0998a62278c", + "parentHash": "0xe068d60356aae28f3154fa8f886f0f0067a7b74b524601c2f623610d258cbebb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa1e185a2970fcd9903cadff06453ace3bff731a5295334d332c3fafd1d50033a", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x91b38283503f272f386fd74b54f772dfacccfe91e92aee0ba9a5c4decd81bcf3", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x19c", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x1018", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb075a9e715b341d481dfad3f02ff0a123aa8043d4ae24d5f0574a7249cc00bcf", - "transactions": [ - "0xf88382014a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa06222a14090e09278dc92b9002ee33b54e5bbbecd9afe56fa18d00dfe761ce8a1a06e8ec220dc8219ae16f46f3a4696fc8b4046fd33fa41efb473222fc058d65ed4" + "blockHash": "0x650b963d47bb9f9b86c29b9d9e52c219bb70525460c04812bd6da741c0e4f90e", + "transactions": [], + "withdrawals": [ + { + "index": "0x24", + "validatorIndex": "0x5", + "address": "0x14e46043e63d0e3cdcf2530519f4cfaf35058cb2", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2e0f4be4d8adf8690fd64deddbc543f35c5b4f3c3a27b10a77b1fdb8d590f1ee" + "0x80052afb1f39f11c67be59aef7fe6551a74f6b7d155a73e3d91b3a18392120a7", + [] ] }, { "jsonrpc": "2.0", "id": "np413", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb075a9e715b341d481dfad3f02ff0a123aa8043d4ae24d5f0574a7249cc00bcf", + "parentHash": "0x650b963d47bb9f9b86c29b9d9e52c219bb70525460c04812bd6da741c0e4f90e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x19a70ab3d8102a74b87887d95a29fe82ce4d4ab36fe3f57f336ded8bd0a7b3d6", - "receiptsRoot": "0x2ac314ac40ad6f04e3ec1fc2b315d4ce6eb64537ae9bf3fad670a0a1df1e5e3a", - "logsBloom": "0x00000001008000000040000000000000000000000000000000000000000002000000000000000000000000200000000000001000000000002000000000000000001008000000002000000000000000000000000000000000000000000000000000000080000000000000008000080000002100000000000000000200000000000100000000000002040000000000000000000000000000000000200003000000000000004000000000000000000000020000000000000000000000000000000000040000000002000000002200000000000000000000000000000001000000004000000000000000000000000000000200000000100000000000000000000000", + "stateRoot": "0xe793c954b6162268e4323115f6365d84736afbafc70c8564364b56ae961afab4", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x19d", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x1022", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x936ce32cab37d0a985a937a8d3c7191ec7f48a10d524d04289d59efa4ca4e581", + "blockHash": "0xa36c2bf72d713f99a25528fb03aa69429831432f179f6c7c406918b542f76ea5", "transactions": [ - "0xf87a82014b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a07af33005afb5f1b38c17ed2bb2b83a0c1d0d6ecd30ab4e32091582d5a3eceb28a008bfc076226d8ebf0a2c86c5ea5f65ea1f1d0cb7b7036b2049444c2fcfb55031" + "0xf883820179088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a062f9d84758ddae03eefb5a4d51f524d42cd0d5a5cfa84ba6fdbe7f10587d1f15a079cd08882dbba6a8c5a3ed94d390e058c8682dd0b9b479df10928ed9444bfb89" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe1b83ea8c4329f421296387826c89100d82bdc2263ffd8eb9368806a55d9b83b" + "0xa3b0793132ed37459f24d6376ecfa8827c4b1d42afcd0a8c60f9066f230d7675", + [] ] }, { "jsonrpc": "2.0", "id": "np414", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x936ce32cab37d0a985a937a8d3c7191ec7f48a10d524d04289d59efa4ca4e581", + "parentHash": "0xa36c2bf72d713f99a25528fb03aa69429831432f179f6c7c406918b542f76ea5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0e4a2aebaaa31e943227335fd579582b6ed68abaa2706294b038ccb00ceae64f", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x894f1006a54555b3172661c3a5e6685eafc36ebc667efa983a102af3d75b26a0", + "receiptsRoot": "0xc0d1fae7a44f5a08a6509a062badef2b96f711095c30375cf335ee497308dc96", + "logsBloom": "0x00000400000020000002000000000040000000000000001000000000000000000020000000000000000000000000020000000000010000000000000000000000010000000008018000000000400002000000004008000000000010000000000000010000000000000000000000000000002000000000000010404000000000000800000000000000000000000000000000000000000004080000000000000080002000000000000002000000000000000000000000000000000000000000020000000000000000000000000044000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000001", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x19e", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x102c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd352dfead0be49f8a1f2f7954f90df4b3e4383f8adb54062abd8041b0a0878fd", + "blockHash": "0x3987af76d0a00951e4513199ee41aec1071161b52151ce66934cda577c4336c6", "transactions": [ - "0xf86582014c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa05e26cfc612b47c55ae5a521eca26d4adbeaefe893bf1b0226cd121cbd7cdb45aa00be4c1040e89e1db4b10b4f36b38ef682de4f3308fd65d4f39346ffcf016cfdb" + "0xf87a82017a0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa00f896411bf64843d5340737f541e899492806f8936469e4b6a9678e55156c71ba06e77e690e26a2d8b86020c19245ca4c3ee9c937adc0cf8ee86b469cfa2aa6fd2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4ddad36d7262dd9201c5bdd58523f4724e3b740fddbed2185e32687fecacdf6b" + "0xe69d353f4bc38681b4be8cd5bbce5eb4e819399688b0b6225b95384b08dcc8b0", + [] ] }, { "jsonrpc": "2.0", "id": "np415", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd352dfead0be49f8a1f2f7954f90df4b3e4383f8adb54062abd8041b0a0878fd", + "parentHash": "0x3987af76d0a00951e4513199ee41aec1071161b52151ce66934cda577c4336c6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc149cc44783e5dc5c6be9d4facfc2e9d3d31dff27f8495ea3fc2acfc22310516", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0xf1d3bae1b9a67dcf701164be3c70998e5abbf0eb3506c05e120e100f5a4db0c9", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x19f", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x1036", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xddf15ae692657c7be84b2e663acd7d669dc84a83622c9bbca07aba3a8461d8a6", + "blockHash": "0x7158030722716ed4b3153861925682677908d60a72f68d54c31732380dda9939", "transactions": [ - "0x02f86b870c72dd9d5e883e82014d01088252089488654f0e7be1751967bba901ed70257a3cb799400180c001a0a79b0ff9846673061d1b90a17cd8bd9e7c7f62b99b39fbe4749777d3ed4544e0a0750ecfe9895402861ebea87e9b483b2c116bc2d4920329aa1c29efb9dcdf47e6" + "0xf86582017b088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa002c0ddfb24254a26c7e83c8a2acb634669318b2d7d8f19d5137aaf6664bc9570a050eef823124703af3f339e533d639fd03f2cde4fd2d3c0edbaa02ecb0d0e8d22" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x156c0674e46cdec70505443c5269d42c7bb14ee6c00f86a23962f08906cbb846" + "0x221e784d42a121cd1d13d111128fcae99330408511609ca8b987cc6eecafefc4", + [] ] }, { "jsonrpc": "2.0", "id": "np416", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xddf15ae692657c7be84b2e663acd7d669dc84a83622c9bbca07aba3a8461d8a6", + "parentHash": "0x7158030722716ed4b3153861925682677908d60a72f68d54c31732380dda9939", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x39d41e6a842119b876ef50fcce4e677b2760950f191f0b17ac11bb61f5d271b0", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xcddab4e72b430f6ecb050f28fff1d86122c7026fd305f08a7e09bfd8361810f2", + "receiptsRoot": "0x0ab2aaedb87b9c5061ad67c8e9690c0a9808d4878de14c2f74723364438e2d8f", + "logsBloom": "0x00000000000000000000000000000400000000000000000000000000800000000000000000000000001000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1040", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5647e4a4349ab2ed23ddc1f61244c94f194735701ad4041ea62bc578654fecdb", - "transactions": [], - "withdrawals": [ - { - "index": "0x43", - "validatorIndex": "0x5", - "address": "0xa179dbdd51c56d0988551f92535797bcf47ca0e7", - "amount": "0x64" - } + "blockHash": "0xfe58c2367f07005a8773b7faee91e02dbafcb140bc800a5145ee2e31dcca251e", + "transactions": [ + "0x02f8d4870c72dd9d5e883e82017c0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028caadfe33857f4d842656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a07b95105ef96b105a85277c69993f6f56602d912fe712ddf6156cdfcd8c49060701a07ab3a43124121badbbb9366336cfb92a45c2543a5841f896c5d75db686dc4fcaa0121f0254852b6317571e856a781e2ac05dcb587b4b671c1ee5045fa969bf951d" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xdfc56ec6c218a08b471d757e0e7de8dddec9e82f401cb7d77df1f2a9ca54c607" + "0xdcd669ebef3fb5bebc952ce1c87ae4033b13f37d99cf887022428d024f3a3d2e", + [] ] }, { "jsonrpc": "2.0", "id": "np417", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5647e4a4349ab2ed23ddc1f61244c94f194735701ad4041ea62bc578654fecdb", + "parentHash": "0xfe58c2367f07005a8773b7faee91e02dbafcb140bc800a5145ee2e31dcca251e", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6f8f7979fade5692d7fd5e0f6253e0e3082614421af4bcfbd63c12f2df06876f", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x85f3cd564a6764dfe793c7fcbc39ce1eb4f27a57c846d7e2140233e1400526bb", + "receiptsRoot": "0x0580aa483cf3198d19d0b7f6e9de2a5331079abd9b266f246f031ecbb63bd95a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000020000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000009000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x104a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb50098d59b2351e10448f5560aff3f933bb24fed7101cda025bcdd5308fb4631", + "blockHash": "0xe75e1fff4381bbf11eaa336b11a4a79a82f0a39a8afeda3673bc6b98bf091f92", "transactions": [ - "0xf88382014e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0fea6631902fceb5662ca53076387bbbb0e0fd9bcac1df121172fd29bd6700434a0632755563256841b198d853ee1861224df35abe91c6d15ca60cb3f660ce05e2d" + "0x01f8d3870c72dd9d5e883e82017d08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c04708e04480c538d656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0fb2772a3127ac292efa3da20fad64d950bf973fb209892fdf834766aa8cdc3ba01a0173b8145bdb22dcce47f47388371d9f3f5974a982f12614c3ecf1bd97b07c419a0133b6d49e23902ba792b434f38f70ea44c830a2f9a7253c945c2cf470ff986ff" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x395d660f77c4360705cdc0be895907ec183097f749fac18b6eaa0245c1009074" + "0x4dd1eb9319d86a31fd56007317e059808f7a76eead67aecc1f80597344975f46", + [] ] }, { "jsonrpc": "2.0", "id": "np418", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb50098d59b2351e10448f5560aff3f933bb24fed7101cda025bcdd5308fb4631", + "parentHash": "0xe75e1fff4381bbf11eaa336b11a4a79a82f0a39a8afeda3673bc6b98bf091f92", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x26b3aa514e4bfed98a760b1cc6d5c7c855232ecac4f00826049369385376458b", - "receiptsRoot": "0xa3ea729352d4252acd6b48dcc940d3acfe0d657ca5d3091eda1ae882c7c14776", - "logsBloom": "0x00000080200000000000000000030000000000000000000008000000000000002000000400000400000000000080802000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000800000000000002000000080000000000000000000000000010000000800000000000000000000000000000200000000000000000080000000000000001000000000000000000000004000080000100100000000000000000200000000000040040000000000000000000040000000000100010080000000000000000000000000010000000000000000000000000000000000000000000000000040000000000000", + "stateRoot": "0x0e4bf4c311366cf2c4203cea923b148f91bca9c1fee87080893ae8396e5b73de", + "receiptsRoot": "0x424e342ad6537fd933701062b2254df294eadb9b0bae746c37bcceb2bbe5784a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000020000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000080000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a2", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1054", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd87426372101b44c6fb40defa47f5e64ced815cf6bcbe830367d328e52fa3bd5", + "blockHash": "0x7de3c0bd5e846119edcd858e4d51f0c0153974ea077bce8048eb3e7d191c3c65", "transactions": [ - "0xf87a82014f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa08ded8700920cf761c49ef0831076f10597be8fe624b891585941b1a1d145a18fa05640b1e1c59257bc6b6352be6bb6a7862a541b3fca52da28912b08b8072b57e5" + "0x03f8fa870c72dd9d5e883e82017e0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c96428e7ddf22a6f5656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0250ca62bfd18dde43e70bab089d01d591ce6ab28978434258ae1017c72f12b0a83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a073a74ab70a71e0aa0cfcaad84c73af0a2752d5fa3e498aa3a4838fa12578db20a05d16a6b804734303cb0d0f900a32e93c7cd9330a839dd27c9f09d175b333a77d" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x84c0060087da2c95dbd517d0f2dd4dfba70691a5952fe4048c310e88e9c06e4f" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x5e1834c653d853d146db4ab6d17509579497c5f4c2f9004598bcd83172f07a5f", + [] ] }, { "jsonrpc": "2.0", "id": "np419", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd87426372101b44c6fb40defa47f5e64ced815cf6bcbe830367d328e52fa3bd5", + "parentHash": "0x7de3c0bd5e846119edcd858e4d51f0c0153974ea077bce8048eb3e7d191c3c65", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x730477c9b8be2e32598ff45ddf03837963e5d2fcd5c8c07d23b47b385c22d4b7", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xc4d7ddce008ad84dd5f904814ff4db9da61e982622fccc0149f045e3ff6b295b", + "receiptsRoot": "0xca8c2f123e2ca46851eec7bf481705b1ab754040c83e62c04c6be43336e74235", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000004000000400000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a3", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x105e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xac9d6592b309e9e3ec0d899eda9ccd7d508e846553ac4a87da8b420c99173211", + "blockHash": "0xc6053e841c2e4bc75e4e959e1b74a9387b351bb4919ae295314e834c5d94e6ed", "transactions": [ - "0xf865820150088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0bb5b1c9e4a9e86b6381ce83f476e3efb45b847315ec3e27e1536539ba2290f42a07eee4b7b9b0d0dc1b873baf519a668f4605ccbb82ad619acb74598535a35bdd1" + "0xf87582017f08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ca4ea5930018eb6de656d69748718e5bb3abd10a0a087d67062c811df509205b9a98f5cd1149db0f711bef8dadd8afcceb3e2deb33fa0565434af06bcc29ccb45767e2f84becf7f31c9194eb9cc0b4073c2a93e252bc4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf4df943c52b1d5fb9c1f73294ca743577d83914ec26d6e339b272cdeb62de586" + "0x9f78a30e124d21168645b9196d752a63166a1cf7bbbb9342d0b8fee3363ca8de", + [] ] }, { "jsonrpc": "2.0", "id": "np420", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xac9d6592b309e9e3ec0d899eda9ccd7d508e846553ac4a87da8b420c99173211", + "parentHash": "0xc6053e841c2e4bc75e4e959e1b74a9387b351bb4919ae295314e834c5d94e6ed", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xef5088187720800d3dec63e4e25560c839cad852b7a795fd9e9876ee2a02b16a", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xd48aa6daa5c25bd835c2bc73a9ef497c742f596ac86390c1cdd08e726883ccd8", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a4", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x1068", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x834b28c2883caaa276a3a0f2603da1bb8171001967787b96071588f296b7671b", + "blockHash": "0x404b549fee0787cefdf4065cb76e3a0e66aab2ad8c6a318e9adfe0bc4a73b85d", "transactions": [ - "0xf868820151088252089447e642c9a2f80499964cfda089e0b1f52ed0f57d01808718e5bb3abd109fa0c37c23a91d6abced211855a2d6d5e383f54aa6ff40c26abc5f27a22cdafa5618a0190f82ff101eabad8b9c7041006dcb3e3a9a85c814938bef8ec7d1aa63fa5892" + "0x02f86b870c72dd9d5e883e820180010882520894e7d13f7aa2a838d24c59b40186a0aca1e21cffcc0180c080a008861b6f3d35926627f023b5813774cddb40cfa87d288c6ccfc964e5bad3212ea02dc34c0f4a392b7a6cd0930c1e2e997e90c65baa6f30809b42b421240986a64f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x0bb47661741695863ef89d5c2b56666772f871be1cc1dccf695bd357e4bb26d6" + "0x1f7c1081e4c48cef7d3cb5fd64b05135775f533ae4dabb934ed198c7e97e7dd8", + [] ] }, { "jsonrpc": "2.0", "id": "np421", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x834b28c2883caaa276a3a0f2603da1bb8171001967787b96071588f296b7671b", + "parentHash": "0x404b549fee0787cefdf4065cb76e3a0e66aab2ad8c6a318e9adfe0bc4a73b85d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8fa327b5c3e6a5036585a3b751910d613c3d2b6b56b0a5c1da7727ce50d4cb57", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x733956370b9a63c38e3b43a9476668130057597197e83611dccf93d236f948d6", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a5", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x1072", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1232a401598e285a5e94aaa0644787458ac9e410b4b50cbc103523f2d2d4c198", - "transactions": [], - "withdrawals": [ - { - "index": "0x44", - "validatorIndex": "0x5", - "address": "0x494d799e953876ac6022c3f7da5e0f3c04b549be", - "amount": "0x64" - } + "blockHash": "0x1ef7fa7c852474808b71df44ef25db220e3dbbb3fd5e18cbb7445b0546b2dbb7", + "transactions": [ + "0x01f86a870c72dd9d5e883e820181088252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c080a0305b41cda8519ea8cbdac25b01e849925a8f150a6a5d529a0acbc7eab39da49ca059338257b32dce95ba36161b8cbbe1a1532a96a00a69d18e51415eeafea7cdd3" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4a1f7691f29900287c6931545884881143ecae44cb26fdd644892844fde65dac" + "0x4d40a7ec354a68cf405cc57404d76de768ad71446e8951da553c91b06c7c2d51", + [] ] }, { "jsonrpc": "2.0", "id": "np422", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1232a401598e285a5e94aaa0644787458ac9e410b4b50cbc103523f2d2d4c198", + "parentHash": "0x1ef7fa7c852474808b71df44ef25db220e3dbbb3fd5e18cbb7445b0546b2dbb7", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa5eef4d5746f0409111e198bb292fd06bf9ac9a14dc734ca636005246e713e5c", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x91a24ce9c7807c4cc2a7e6c226ec8a673b4bfc54b51ee1fdf92fd54c2c40547a", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x107c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x271fd072d8e81da656b1f06548d486ce23f9fd399e070d3a01a3bd28c2d4eb7c", + "blockHash": "0xc5e3d5218b2e1a652c2f2d9613df0b5e389b8695c73562332f4c3381d59faddc", "transactions": [ - "0xf88382015208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0435a46c3720f21ff83b01b3d6e88f602e45dee024e69f7df083e47ee400fa063a020b2e545bea301a0322157c61d6f8bdee62066305c627c1c10fb9eb1fbdf0fed" + "0xf86882018208825208940c2c51a0990aee1d73c1228de15868834155750801808718e5bb3abd109fa051771698d0cbc3cb2bf6d62fe327745ad1f0a74a6c98ab0f7e08b61f9fd3a795a05b8f90ab7b967427dec2d5128cfaf53456a2e41dfe053028b15349615a38c993" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9b133cc50cbc46d55ce2910eebaf8a09ab6d4e606062c94aac906da1646bc33f" + "0xf653da50cdff4733f13f7a5e338290e883bdf04adf3f112709728063ea965d6c", + [] ] }, { "jsonrpc": "2.0", "id": "np423", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x271fd072d8e81da656b1f06548d486ce23f9fd399e070d3a01a3bd28c2d4eb7c", + "parentHash": "0xc5e3d5218b2e1a652c2f2d9613df0b5e389b8695c73562332f4c3381d59faddc", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5486d8d4c4159eb6389774b47a76d5e347e3b31ecf92c08eda9e261e3106f0cc", - "receiptsRoot": "0xc0c07d0984b850e6ccc2e081d26ec135c42d526e9bb51a6c1987784d659c07d5", - "logsBloom": "0x00000000000000000000000000000200000000000020000000400000000000000000000000000000000000100000000000000000000400000000000000200010000000000a00000008000000000200000000000000000200000000000000000000000000000000000000000000000001000000000000000000000000000000000000000806000000000000000048000000000000002000000040000500001000000002000000000000000000000000000000000000000000000000000000000000000000000000000000800000000800002008000000000000000000000000000000020000100010000000000000000000000000000000000000000010000000", + "stateRoot": "0x28febba9418b7966c83066c069f21ae146c56bae2c9be677413a522793ec89d4", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a7", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x1086", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x966f75efe4cd3d4171d4dd7dbe65453d3fae561f5af4d67142cc15ad53dae212", - "transactions": [ - "0xf87a8201530883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a015ae0fac40a467ff5ad10fe01c838c564f0d30707c8b02be656345842959fedda07a3d9842f721d8cb4494a2df6ff689c4c19e44c8c81f013d1f969624d49850b2" + "blockHash": "0x3bddbb879a8d46f692289da30f77e1ba669940bd42a1279d275b94c24dcaf9e0", + "transactions": [], + "withdrawals": [ + { + "index": "0x25", + "validatorIndex": "0x5", + "address": "0xeda8645ba6948855e3b3cd596bbb07596d59c603", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x473b076b542da72798f9de31c282cb1dcd76cba2a22adc7391670ffdbc910766" + "0x259ab95f666ac488c7d45e2a64d6f6c2bb8dc740b23d3e94a04617a0a3fbe0eb", + [] ] }, { "jsonrpc": "2.0", "id": "np424", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x966f75efe4cd3d4171d4dd7dbe65453d3fae561f5af4d67142cc15ad53dae212", + "parentHash": "0x3bddbb879a8d46f692289da30f77e1ba669940bd42a1279d275b94c24dcaf9e0", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa9339a9c149937412b8c9d01a85c7af270578af9eebb80ad2cf208764c40e608", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x00a97dd6125d423743fb0de7fa16cabb523a863ccce837e2efc525c197b887f8", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a8", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x1090", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x92a740edd1bceefb2f497e906a5f53bc10928c909069ba76b34663dabfc01f91", + "blockHash": "0x5ddb9e58b0ef297a051097bc988e136b1749d9f3445561b6b14a692fad23b8da", "transactions": [ - "0xf865820154088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0c14791fa1c6907f6279226a31c5f287c93702ba72f19fb9999b93b8ad612b36fa0371a0819796295976ab02fcafbe818a711cf6485a21d038dcb72b5000f04d63d" + "0xf883820183088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa04b4bf92950c32fe37f7e225b7ac450771573c14da0fc850e5bec45917d4e2112a063619497f80b1174cda00936abf5deb5adb18b6511a34d6bad1c011601de0933" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x225dd472ef6b36a51de5c322a31a9f71c80f0f350432884526d9844bb2e676d3" + "0xc4b808157fad1819c40973c2712d24ce49df04f8ad955ad0373625dcbcc5aa7b", + [] ] }, { "jsonrpc": "2.0", "id": "np425", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x92a740edd1bceefb2f497e906a5f53bc10928c909069ba76b34663dabfc01f91", + "parentHash": "0x5ddb9e58b0ef297a051097bc988e136b1749d9f3445561b6b14a692fad23b8da", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xac3cc175fd0ba02252342155b4d9dd7fb790eb49b667058912b43f5bd6e939d5", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x0dba2b3227bca5df06f4358a8f424d800b317f32f319a0a965fc0d31489a7b3c", + "receiptsRoot": "0xa95c0659ea55647106bb0421d6e846937fff8a0204b430d49515f001f39a76c6", + "logsBloom": "0x20000000000000000000000000000200000000000000000000000400000000000010000000000000100000000001000000400000000000400000000000000000000000000100000080000000800000000000000000000000000000000000001000000000000000000000000000000000000000000000000000040000140000000000080040000000000100000000000000480000000000000000000000000000000000000480000000000000000000004000000000000000000000000000000100000000000000004000000000000020080000000000000000000000a00000000000000000000000000000002000000000000000040080010000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1a9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x109a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5a7a3b8f0d389c13d810588336964f1a94b29184e3d9bc751eb64ef4635ad0f5", + "blockHash": "0x36be5e83ae2b1baebbb956bc7c44f540745e5a78a59f3ca2aa088fb994fc62c8", "transactions": [ - "0x02f86b870c72dd9d5e883e820155010882520894d854d6dd2b74dc45c9b883677584c3ac7854e01a0180c080a07a17de801de3309b57dd86df30b61553d5c04071581d243f33f43c4d64930e09a075f7e820212e8f96d7583c66548719db621537fe20f7568d5ee62176881b70e8" + "0xf87a8201840883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa00360adf25dc0ca9566cdbbda097786916c7c04d26534c99cc1f15f2de7207e55a034c2533a5ee702ef318af118fe07a2ad8be3071a75af6c299bcfeb3b3b6dab28" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x31df97b2c9fc65b5520b89540a42050212e487f46fac67685868f1c3e652a9aa" + "0xe7c5536cfd18a67450339a94845bc86835cab1386e7f8b3eff0b4e23e706c23e", + [] ] }, { "jsonrpc": "2.0", "id": "np426", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5a7a3b8f0d389c13d810588336964f1a94b29184e3d9bc751eb64ef4635ad0f5", + "parentHash": "0x36be5e83ae2b1baebbb956bc7c44f540745e5a78a59f3ca2aa088fb994fc62c8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe677d652ba3a8822155791a1d1491ee57497ebfa49e3e38c909752dd8067a9e8", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x62d6bd10e1c7d9799ce034ad0d67d6b8fd2a1c5ed1bba14fb7b0ad8ba4ba5b09", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1aa", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x10a4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf963480776054d809830c23d97833cfbf2971fc0fa04a6fe4974ea25a761f8c9", - "transactions": [], - "withdrawals": [ - { - "index": "0x45", - "validatorIndex": "0x5", - "address": "0xb4bc136e1fb4ea0b3340d06b158277c4a8537a13", - "amount": "0x64" - } + "blockHash": "0xcd0da9da1e9b992dbbc4e98d488adea3b884852750ac79bde2b2ea2265a65d9f", + "transactions": [ + "0xf865820185088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0bfd2c15f64a419a3af3fdf8b3876d98d34b5b8bde7b0c603b26b2a320b626abca02fe1bee07dac1dff99d8c00afce05afe089d45fb884f0ce0e363ab6b3bd1b0a9" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4416d885f34ad479409bb9e05e8846456a9be7e74655b9a4d7568a8d710aa06a" + "0x8f5d7fbf3369ffcc9cc71dc871a54df7fd2f391054043e91f4afd27937ad2571", + [] ] }, { "jsonrpc": "2.0", "id": "np427", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf963480776054d809830c23d97833cfbf2971fc0fa04a6fe4974ea25a761f8c9", + "parentHash": "0xcd0da9da1e9b992dbbc4e98d488adea3b884852750ac79bde2b2ea2265a65d9f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x08414161950ff53f6f053f2886c473a22eb595a0052de01fd24c7af1bc27a5ac", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xa21d9910200d72f9b7fb5cb2e75dfabe60d7686f27d43a2ebbf792503223b8e5", + "receiptsRoot": "0x961e82599eb3b2fe09e2d99b9454c55550f006bb8b24bedbeb265b4c8b8f0762", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000800800000000000000000000000000000000100000000000000000000000000000001000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ab", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x10ae", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe8c8baed11565acb9d54e46ed79327292e07686ada5cd14fb02558ac39c518ec", + "blockHash": "0xa5a646fb42670f9bb6782713ff7b2cdb24cd4bb3323b0586c5e2c03d03221d30", "transactions": [ - "0xf88382015608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa02f6b9a47dcc55d9130085e0dfd615fee0acea46517280eea07dff8ee6afd40e3a01fc33c02a467db6d30ccf56ad8b5bb32fd49ad9a7866db580e7a581987518921" + "0x02f8d4870c72dd9d5e883e8201860108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c2bf53f54e8dd4d5c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a02ecc9be98f9a8adac6e6acc5f160b0d15439b3856f0dee2a3005db79076252a101a02872d41683ea77b63dcf1907c1442d5785d5f06ce268b336b3a1d2c6a14f989da0140d4174638d1c19ce4e7256670b1dfde9f39cfe6ab4c5d2b9c25a0babf0f70c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xae627f8802a46c1357fa42a8290fd1366ea21b8ccec1cc624e42022647c53802" + "0x77b7c55aa160a8bb8011b7132e25c90653a099d1e2925643721c979dde14c1c2", + [] ] }, { "jsonrpc": "2.0", "id": "np428", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe8c8baed11565acb9d54e46ed79327292e07686ada5cd14fb02558ac39c518ec", + "parentHash": "0xa5a646fb42670f9bb6782713ff7b2cdb24cd4bb3323b0586c5e2c03d03221d30", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5afe7e66edc543cc377a33069ba58d5788801f1ef0f370d69ff71db5f63b6b88", - "receiptsRoot": "0xb278e6670351b21cd1c267f24972d7868327ae82ef7a3b377af968b4c6659925", - "logsBloom": "0xc0000000000000000020000000000000000000001000000001000000000020000000000000000004000008000000000000000000000000000000000000000000000000001000000000000000800010000000000000000001000000000000000000000000008000000000000000000201000001800000000000000000000000000000000001000840080000000000040000100000000000000000000000000000000000000000000000000000000800000000000000000000000000020000000000002000000000000000000000000040000000000000001000000400000000010000000000000000008000000000000000000000000000100000020000000000", + "stateRoot": "0x5668ab2632de1e192960b43729c4874cdaec8fdf971da4bb9a52d81bc6090c0e", + "receiptsRoot": "0x62f3226a4e64d6a22b562e03d1575571d22526bdc185564fe6066d8bfd4a3e1b", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000009000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ac", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x10b8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xedf9debf0ac1be313a1f9e6f0121d36c284e2c7962acac1fa5c8aae207c07b34", + "blockHash": "0xec2df5da5678a7b5ea6e5606f84879096c1b455ff0c9fe35679c9436c77953fd", "transactions": [ - "0xf87a8201570883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa06cbb3f84663bf7369864941fe566b1beb8d5db0095cbd49ebfdee89c164031e6a0461b62f4b01d15206e95e6c7bfe9364456d8b7edd446d1b488a2688c47b83775" + "0x01f8d3870c72dd9d5e883e82018708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c94159fe8d22ac484656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a90642da2f095eb8128f01811cb553162395cfcecbe5b077f12c62a1effa7c8280a0f2ec4363c51bf39f7d230d7b373ac487aad7feb17090149f86a5874c719dfe9ca02a086f083832d22833880e64ddd6be5e66edaded139778afa4944a0695fd9db5" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x8961e8b83d91487fc32b3d6af26b1d5e7b4010dd8d028fe165187cdfb04e151c" + "0x9cd67bbefa6a7a9ae1eab06e461086b6bad850bfb0bda838ea83dc58d0c20feb", + [] ] }, { "jsonrpc": "2.0", "id": "np429", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xedf9debf0ac1be313a1f9e6f0121d36c284e2c7962acac1fa5c8aae207c07b34", + "parentHash": "0xec2df5da5678a7b5ea6e5606f84879096c1b455ff0c9fe35679c9436c77953fd", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf1c25b007a4c84577aa49389214e8b8b63f81cb20b61095db784cd8e781fbdcc", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd148adac40832b208eeae2792b4f3993d7e0a77984621fd57184eea110e7ebd5", + "receiptsRoot": "0x360fcdd796679c1d4ac0abb9164036e531fc69bc66cbb05cf5289f179a7de02e", + "logsBloom": "0x00000000000000000000000000000000000000000080000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000002000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ad", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x10c2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x94a14e5fafedb96bffc4624affb9a20762f447e5abb90865c4418a539743932e", + "blockHash": "0x3b1fcf135ef30081e41bfa1d41b0fff91843274d326b76a81723c7cbcf81c7a5", "transactions": [ - "0xf865820158088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0a285aa615fe480c778997ca57059b8ddec5cee0e5a94ec05cd028a03d04aadaba07549f0c6ded9fe03eb40b413803b8f02d9dc51591e29977d12a204518648008e" + "0x03f8fa870c72dd9d5e883e8201880108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c79b38a395911e1de656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0cea8a961664f986542ebbc496878d052736682831cd7847bc769ae16e9eefb6583020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0f28c84cbbd1c15d7b491fdef5672bfb99f5c973911f83a2d9083fba59e896465a00824dd81cd879f51862d7cb3cf53ec6a83849e3665d4a1fba60220dd72ee17b4" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xc22e39f021605c6f3d967aef37f0bf40b09d776bac3edb4264d0dc07389b9845" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x060aba9d44a5513488273214452bed1c1e85dc18695bf28a44d98dd24d20cee5", + [] ] }, { "jsonrpc": "2.0", "id": "np430", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x94a14e5fafedb96bffc4624affb9a20762f447e5abb90865c4418a539743932e", + "parentHash": "0x3b1fcf135ef30081e41bfa1d41b0fff91843274d326b76a81723c7cbcf81c7a5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x401f1feec84dc7c894bb9f03dd52b5af121262ab2f6bd29e6de4e96c1ed67870", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x95df3ba204688c6f07e371a7804f555c5c6cadc52161403edfaee76dc75cec47", + "receiptsRoot": "0x9c2e5caec128d23b6bfc7d0b84bb065f516462d455584be36674424be7ba2858", + "logsBloom": "0x00000000000080000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ae", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x10cc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x855b2ccb1c00d717f49ec7074cee1f781edfc072eeef44012e18613a9172fc9d", + "blockHash": "0x76c48fbe8881579636df3e68fe55621e99026e7d9810b74ff9cdb7557873d056", "transactions": [ - "0xf8688201590882520894c305dd6cfc073cfe5e194fc817536c419410a27d01808718e5bb3abd109fa0163f29bc7be2e8fe3c6347fe4de06fa7330e3a3049c0e9dcded1795ff1c1e810a04ea7492a5e457fd21252166f5a5d5d9d5e5c7a19da2c7fd4a822bf60156b91a9" + "0xf87582018908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c59a78d4a871468d2656d69748718e5bb3abd109fa07e98f37b83b11f881db0fca02730e3c1230dc2dfadad408236e1968812196f57a02cb56b32722cfd2e1998f5971bc3b59989468f87910e6a73585589fcb34bfc1f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x7cfa4c7066c690c12b9e8727551bef5fe05b750ac6637a5af632fce4ceb4e2ce" + "0xd5fc23888bb73b0a9c6bf06b969040c7be41d5bfcbaf51388390fe09abbfe03f", + [] ] }, { "jsonrpc": "2.0", "id": "np431", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x855b2ccb1c00d717f49ec7074cee1f781edfc072eeef44012e18613a9172fc9d", + "parentHash": "0x76c48fbe8881579636df3e68fe55621e99026e7d9810b74ff9cdb7557873d056", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc97f5e63e102992e2a849afad97481ea818d213707de515acd9c2bc246cdf65f", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x6aebec23a3a1fa16eaff744a55cd2dda5b85cdc56ae1f26cd263347cf98c202b", + "receiptsRoot": "0x005fb2a0d0c8a6f3490f9594e6458703eea515262f1b69a1103492b61e8d0ee2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1af", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x10d6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4155e12dee1bb9ed17527871568425b8eb672004a2e2c19cb1947004fc5f0b0e", - "transactions": [], - "withdrawals": [ - { - "index": "0x46", - "validatorIndex": "0x5", - "address": "0x368b766f1e4d7bf437d2a709577a5210a99002b6", - "amount": "0x64" - } + "blockHash": "0xb0915a68a1ecb0bcafe6d483d3fddd6a93249d963db6e9650695570b2d494448", + "transactions": [ + "0x02f86b870c72dd9d5e883e82018a010882520894eda8645ba6948855e3b3cd596bbb07596d59c6030180c001a0971237415e49f25d91c059c902cbabcac9134a93470a1e50be6623609e9239afa04f15ac058a42f0589ca9667ba90c54f29623badc33777fab188cfcbcde1e2c8a" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x943d79e4329b86f8e53e8058961955f2b0a205fc3edeea2aae54ba0c22b40c31" + "0x7e0f61114c9e1271a083af0112a3d8e75c1945bdbf4436b2d06604cdd3e48ed4", + [] ] }, { "jsonrpc": "2.0", "id": "np432", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4155e12dee1bb9ed17527871568425b8eb672004a2e2c19cb1947004fc5f0b0e", + "parentHash": "0xb0915a68a1ecb0bcafe6d483d3fddd6a93249d963db6e9650695570b2d494448", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9c177f669a297c904a6a6ad51765a5916a0e0a3d9858b289e70bf054b370d685", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x6518db9c6e4925aecb5b221d3f27037a2b223de4a73411217f8df154d8fbc9aa", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x10e0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd660a48f06384f7ee4402d24193c76d2f4a00b85ca53ae9883b4ee3c07260586", + "blockHash": "0xfdda715666ca9712626e528f4570ffb24d48cdcc62e14571241d1a2f61576c46", "transactions": [ - "0xf88382015a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa078d6fdbc4224106e1f59483aff597485ed0eebf922317913522a0693727b5ee8a035876b3170b9a88dc391f83dcac8088aeb65233613c74d8f50f1d1d3b1ce842f" + "0x01f869870c72dd9d5e883e82018b08825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c0180c080a094a1ec3a9b3fb3f62f38dfac1f8d7c36d07dd6547a14f6dcc2d8c370c0c120e39fc62b895dd48527c1be40a87e5f771038e3449fc4f99f7aad6ac843a338463f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x66598070dab784e48a153bf9c6c3e57d8ca92bed6592f0b9e9abe308a17aedf0" + "0x8a6f4493c846bfcfb55e3813f2be3ce8a97c822d88bbf56ebe6070da480dca20", + [] ] }, { "jsonrpc": "2.0", "id": "np433", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd660a48f06384f7ee4402d24193c76d2f4a00b85ca53ae9883b4ee3c07260586", + "parentHash": "0xfdda715666ca9712626e528f4570ffb24d48cdcc62e14571241d1a2f61576c46", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x98d101f68f7aa5bb170cfdd60281d7a5c3ae335ab03c0f87bdb5e72cc022d55f", - "receiptsRoot": "0x1919995eb19582a49f7b79b55e7ec75fae399916006f29e4177543d99cc2a5e3", - "logsBloom": "0x00000000000040000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000080000040004000001000000008000000000000000000000000000000000000000000000000000000000800000000000000080000001000000000000080000000000400020000400000000000000000000000000000000000000000000001000000000000000000000000000000000000000000012000400000000000002000000000000000200000000100000000000000000000000000000000000000000000000000000000004004000000000000002000000000000002010000004000014000000000000080810000", + "stateRoot": "0x6f9f6aad7db1ac4ca3fd2599e952b004f573a52af118c075241ed55f520b1b53", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b1", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x10ea", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x73404b62b42dbc6a6604152b87426e852cc3b34847f45f27c0fca1f3a619f84a", + "blockHash": "0x91bab78100c2b6909b533e246d772659957330f8ddfcf194087a8fb67bdfb6f7", "transactions": [ - "0xf87a82015b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a09fb0d3ddf1fce9562d227b3cd6c35ac2e89f39141823d94cda0e6efb4519c715a06925af0950104623efa7954872196fe6d539eb269263a17db3740652382d100f" + "0xf86882018c0882520894654aa64f5fbefb84c270ec74211b81ca8c44a72e01808718e5bb3abd109fa00560b8397596944a06bec099e80d88b0eba0078a9278b7b48c38ba24dd7cddd9a07e3a0b1cd87163b082111f97a391e0711dd157dcd44ec6da0f2a0d73f5a9e9fd" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xac8fe4eb91577288510a9bdae0d5a8c40b8225172379cd70988465d8b98cfa70" + "0x83e6fd189fd00cd332b6a76e3806367f086beb3e0fd0060c0a3574d10cf86c8a", + [] ] }, { "jsonrpc": "2.0", "id": "np434", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x73404b62b42dbc6a6604152b87426e852cc3b34847f45f27c0fca1f3a619f84a", + "parentHash": "0x91bab78100c2b6909b533e246d772659957330f8ddfcf194087a8fb67bdfb6f7", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7d06044c1009a2320b83bdfe22ffe7b8ffa6fa1f65d5e42f7c1588417a8ff421", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x8c3a01f48611558c766a08174b1c9261f47caa7885ca5ef2656de8ce54c7af07", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x10f4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x9832bc48443f86a5809f75ad91caa04101363a43b300cef39918deaae8594e08", - "transactions": [ - "0xf86582015c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0aa24c6fb2c99f1ce21f7ffd84e87fb6f81ff76cebe06fb5c0871294a353210dfa0350602877ed48896e8b4124b35c0c47da66c17fc0d553d9248ca1de942114306" + "blockHash": "0xad585c5a49c5db92630ed7c7b67fc367f3405060a0bff9de9dd64b996505a66d", + "transactions": [], + "withdrawals": [ + { + "index": "0x26", + "validatorIndex": "0x5", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2b0018a8548e5ce2a6b6b879f56e3236cc69d2efff80f48add54efd53681dfce" + "0x775e887c6cb79392692d17fc58f861a98e70d013afd252b2a644073fa185034c", + [] ] }, { "jsonrpc": "2.0", "id": "np435", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x9832bc48443f86a5809f75ad91caa04101363a43b300cef39918deaae8594e08", + "parentHash": "0xad585c5a49c5db92630ed7c7b67fc367f3405060a0bff9de9dd64b996505a66d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x03d23380eb6a02b52fcfeb82c0fefd180c014e72a7f48f2627237e7bda6d5610", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x67e890251a1df44f1fdd8e95b3e3325a51c1e5d8e6b56a098dcfb4bb810bb615", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b3", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x10fe", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe5e23a0fd4a2515c0e1292823b094a1aeec3ed64db400675b591fc077bf34c3f", + "blockHash": "0xb8b4a3064cf8c569375764e5323ef7a03667dab6ea562bedcf67aeca7ad55e44", "transactions": [ - "0x02f86b870c72dd9d5e883e82015d0108825208942143e52a9d8ad4c55c8fdda755f4889e3e3e77210180c001a0673c5473955d0d26d49b25b82af905ee33ba365178f44dc4ac39221efec23c88a017f46fc9b15ba0c1ea78d4d9f773582d94f61f6471f2918cb0598f33eb9bc89b" + "0xf88382018d088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa0494f4ddedaa75cd53c5d2b2b18873541589fa6ff122d30a8c1fe9d1854e23f1ea0285043a32e0d1aba79a3fdd8fb2b8898584296a6a87f00616834ba6b9f34bf62" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x823445936237e14452e253a6692290c1be2e1be529ddbeecc35c9f54f7ea9887" + "0xd6f95bc3e63325669aa3b41a80caaaa350031821fc65f792cec135bbfca7b9a9", + [] ] }, { "jsonrpc": "2.0", "id": "np436", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe5e23a0fd4a2515c0e1292823b094a1aeec3ed64db400675b591fc077bf34c3f", + "parentHash": "0xb8b4a3064cf8c569375764e5323ef7a03667dab6ea562bedcf67aeca7ad55e44", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf8829f712e0ea692e266ae3c78400816c5f5bc1d75a3bff3816f7fef71b2044c", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xb2950cc3040ff95b8285e0f5023157a9f6f174b23b821ac6b477a9369ea87ddd", + "receiptsRoot": "0xb43680ba5a32c58cb1926993bfe009fce37108c8a7b2e732e7213c54c9e3e0ef", + "logsBloom": "0x40400000000000000000000400000000000000100000000000000000000000000000000000800000000000000100000004000001000000010000000000000000000000002000000000000000000000000000000800000000110400002000000000000000000000820000000000000100000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000004002000000000000000100000001000000000000000000000000000000000000000000000000000024000000000100000000000000000000000001104000100000000000000000000000000000000002000000000000000200000000080000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x1108", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x6e26197c94723ba471d049f6082abd0a6e684225b2ee9d8fa675b18ef11492c1", - "transactions": [], - "withdrawals": [ - { - "index": "0x47", - "validatorIndex": "0x5", - "address": "0x5123198d8a827fe0c788c409e7d2068afde64339", - "amount": "0x64" - } + "blockHash": "0x53611bef1500f1568f35390b80eb6baf31ffaf9d8a4d34aab3932e5adffcecb5", + "transactions": [ + "0xf87a82018e0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a073772e2e2652f74c11e6eab648cfc427cac926989470cc8ff4a0a14e83919427a03c84a88b5ee47058d530e52402f6130f7318043baff71a0d7bc021befd85d48c" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x3051a0d0701d233836b2c802060d6ee629816c856a25a62dc73bb2f2fc93b918" + "0xcbaab7c932a6465b5c3ff1d248ca02300484a6e6e9b6140983daeb58eb16a434", + [] ] }, { "jsonrpc": "2.0", "id": "np437", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6e26197c94723ba471d049f6082abd0a6e684225b2ee9d8fa675b18ef11492c1", + "parentHash": "0x53611bef1500f1568f35390b80eb6baf31ffaf9d8a4d34aab3932e5adffcecb5", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc66ecc1bdb4fa4b85c0b383d4db20fdaa2cba32973260dc444abb43e8536e93a", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x31a8c1120baafc802bd64c6831c84074573982654387f88b7b6dbc76f3644a07", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b5", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x1112", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb5f0ca3b4503c50b8eab9c63a95b209426af616a5b0d8468e63246c3f590caac", + "blockHash": "0xdd0f743e193c79a4a3ac080b01ed2ed15d9321300c002d70d74fb4c9b44564fb", "transactions": [ - "0xf88382015e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0179370023b242bccf25d4899c2f29936353b5f1c37a8f7c665e55b75f80bf297a018a66d1d2ef7072f7fc54af07d15edc14ecf5a71f510be740c090f0815178ff2" + "0xf86582018f088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a006c454e8035cd15a2911e3b903fe167f51c630e009e96e5728bbce23bececaa2a01ce57e3a4cb8cae72e443e34abb166ec39e127e063b281a172b2b70d3e9db923" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x44a50fda08d2f7ca96034186475a285a8a570f42891f72d256a52849cb188c85" + "0xa0d5f4fbf6dcc49bee52b3f185c619817e08a3dff2bfd11cfae07557bf3e5727", + [] ] }, { "jsonrpc": "2.0", "id": "np438", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb5f0ca3b4503c50b8eab9c63a95b209426af616a5b0d8468e63246c3f590caac", + "parentHash": "0xdd0f743e193c79a4a3ac080b01ed2ed15d9321300c002d70d74fb4c9b44564fb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa9b50e298c6a4bbd23a659ab24a3a7426b1087497561c39de2f1bf27da019b83", - "receiptsRoot": "0x8f45041560ebf83ec428723c6d69db271346e4c5a1b234b56efe318d549187cb", - "logsBloom": "0x00000000000400400000000000041000000000000004000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000202000000000000000000000000000080000000000000000000000010000000040000000004000004800000000000000400000000020000400000000000000000008000020400000000000000000000000000000000000000000000000000000000000000000000000000000000000800002000000001000000000000800002000000100000000000000000000000000000000004000009000000000008000000080000000000000000000000000000000900", + "stateRoot": "0x3ba3d7945f4a4c397d5dbaeeebe57a4f33a15b564598c7282babc9cfb20fd9ce", + "receiptsRoot": "0xdf851086fb2354fe79ca0d3e9e3bf40f1e41c7463ee9581918eb449a0fc555c8", + "logsBloom": "0x00000000000000000000000000001000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b6", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x111c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xfe8e1ceca43818cb8f2e4fc94ead6cea53a8fd515af2bc67a39a15584ec3cd86", + "blockHash": "0xcfffe2d9251de471b21928c131be8ecb1b332ec4a9ffc226e64f041820caec47", "transactions": [ - "0xf87a82015f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0354b9d4a470abdae9da30183321b96b5fd09bc96c1ebd3137b3c6350c21e8de2a026877262b14edc851e17cba052b022dd1038fd51ef65ecbaff09dd07186f035a" + "0x02f8d4870c72dd9d5e883e8201900108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c4370601485444f78656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0c452b6d808f45af81c3310dcf94a1704359eafc34709c45b0c7b95adf4cd02af80a06476a024de65684f7abf56ea2992795bc32b9eabca3dfd802f24104738659638a051b6383d626465cf6ff6073eeec5e9fd1759e5a5d5fa203e448eb0dbf03eb614" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6e60069a12990ef960c0ac825fd0d9eb44aec9eb419d0df0c25d7a1d16c282e7" + "0x7bcd5ed57e123ed0d2a16b433c4e584231867efef22b4903b0de3dba6c0249ff", + [] ] }, { "jsonrpc": "2.0", "id": "np439", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfe8e1ceca43818cb8f2e4fc94ead6cea53a8fd515af2bc67a39a15584ec3cd86", + "parentHash": "0xcfffe2d9251de471b21928c131be8ecb1b332ec4a9ffc226e64f041820caec47", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xad6a72de336a98aec47ed431bf7d39d537741125313255629633cba91b0097bd", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd2a9076a6c93bae04e4d50c5275761281942cf47668dfc8569587d6361e62970", + "receiptsRoot": "0xa9fb713fa5eca2599ae81d8cd7ab1a44a18ce704ce5949d7778e96bd30d85037", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000001000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b7", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1126", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xfd02d6b4d954d36af8829bf98464c0cc410de1e28216e45ac5e90fc1fc5780d3", + "blockHash": "0x758647ab7f0d8935064c2c38ef6a2a34457df9c78297c2d42376ce18051a4a56", "transactions": [ - "0xf865820160088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa09c6b3542e181028aad33517584cd16e92836f975955abdcbf1205b6250c921d4a040816d88e011c2d3073502523867b94987fa0781793a7857ff2453ec2d121444" + "0x01f8d3870c72dd9d5e883e82019108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cdb38dd98f8319698656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a075eb384e56c3a3a30a408622e6f0595d30705efaff129c133effc43c3b946de080a02bcf01133888df5ef0373d5382917ef6108b1e147cd3c726ccbd72d5156072e6a0671aeea102efacbde075bc75a80fbaab9e15a6e470ecb4717adbe436ef47503a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x581ddf7753c91af00c894f8d5ab22b4733cfeb4e75c763725ebf46fb889fa76a" + "0x24054b31c796a86751c71d8f0113d6f56397bc46dec675697960c4ee6d1370d7", + [] ] }, { "jsonrpc": "2.0", "id": "np440", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfd02d6b4d954d36af8829bf98464c0cc410de1e28216e45ac5e90fc1fc5780d3", + "parentHash": "0x758647ab7f0d8935064c2c38ef6a2a34457df9c78297c2d42376ce18051a4a56", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x863de67ea016127a436ee6670f8642bd5ab997ce75361c3cce667abbe90b7283", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x9d015c81c2be398fa128de167193c6852c7d31f1f63e6143987bc30b80acbe7b", + "receiptsRoot": "0x03859880c301da93fbc6097c99964de48eae15915c5720e0898b968b0e1e4c43", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000009000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b8", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1130", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe0c31051877e8d3f6f625498659eff12247ded622d4155f6fd4a498852e46192", + "blockHash": "0x1431bfb93a91538f50aebe4b46add424df29fddb8a479eb51c44539f7425d9c2", "transactions": [ - "0xf86882016108825208940fe037febcc3adf9185b4e2ad4ea43c125f0504901808718e5bb3abd10a0a0654dc39f93a879b9aec58ace2fdbd5c47e383cae2d14f1a49f6ec93d539be892a070505a0ef2e83f057e9844dbd56eda0949197f0c4a2b6d0f2979db1710fca4ed" + "0x03f8fa870c72dd9d5e883e8201920108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cff9997836ba653fb656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0e5f4774cc356a99594f072de9e8113739c65fb51b5d0fef3f40627cac02dd96383020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a067d170ea015f418a85dd9018a66eb5b3f497daeac2e3274aa6e81e12d64dc70ea06ccd0d6a09b13920187d3cc8dd09ed30bd66e8c79d7e7507a10f8fc53333c20e" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x9a1dfba8b68440fcc9e89b86e2e290367c5e5fb0833b34612d1f4cfc53189526" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x6a3a65f6fcf34e82edbc10f8ce17c7aac559454d22b5f8b865b0b26182a791b2", + [] ] }, { "jsonrpc": "2.0", "id": "np441", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe0c31051877e8d3f6f625498659eff12247ded622d4155f6fd4a498852e46192", + "parentHash": "0x1431bfb93a91538f50aebe4b46add424df29fddb8a479eb51c44539f7425d9c2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x66989995258d8db8bd3b8eac83c7762c50323b8f21f1aaddf3ad0208afc6318d", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x1dc00f12b4b67a4ff4469ae92ee5b06f5dec0fc9af1d77d900a374d4ec90e41f", + "receiptsRoot": "0xe4403f226ea34a50550c614e431141bcbc357496382725cf7ab388e550ed1a73", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000200000000000000000000000004100000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1b9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x113a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe9da2b3df6fbc520bf3a80b36bd3437210880763ea7acbf422076049724a14ac", - "transactions": [], - "withdrawals": [ - { - "index": "0x48", - "validatorIndex": "0x5", - "address": "0xd39b94587711196640659ec81855bcf397e419ff", - "amount": "0x64" - } + "blockHash": "0xf2d3d4be2e09a5499d838936b169c6ccf83a1dc510305e54e1e181243480bdcc", + "transactions": [ + "0xf87582019308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c104809bbbe393c1d656d69748718e5bb3abd109fa02b5dab3335cc19db2050fd831c2ae4fcbe18c229a211ea5ded9fe5f138453a1ca038ed41d85fa8d81885e0b0c20ef134cbf94674f344ef5188fa1f65040cdfe937" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x54a623060b74d56f3c0d6793e40a9269c56f90bcd19898855113e5f9e42abc2d" + "0x43a4a75cdb8ddebc28bf09b4ae12d71dc0765defafcd384de22c3711726a5d80", + [] ] }, { "jsonrpc": "2.0", "id": "np442", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe9da2b3df6fbc520bf3a80b36bd3437210880763ea7acbf422076049724a14ac", + "parentHash": "0xf2d3d4be2e09a5499d838936b169c6ccf83a1dc510305e54e1e181243480bdcc", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf37b2d059d8764938039410fc2581f4793fb4f9c66abf4f8a32276dd60334f4d", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x7612c719dd4e8378185ea148558b178f0b5eb37dfe856cdcec2057ffef4b6088", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ba", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x1144", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xeafce24dfb100daa2a1ee55da0030d8e057fc943b96b6e7f321af98b47e8107e", + "blockHash": "0x9b8c6ecde0c9f7d3096db113472984400265c16b8f423527046f7c9cacec1c0d", "transactions": [ - "0xf88382016208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0bf7859d7e53ab582f4189f50f06832f2fa9763498350b739d7a677b34df97861a03ab21050f73bda7c737cef08e6a77edc9766aa0ef14dfdfc22fbcfdb6771825e" + "0x02f86b870c72dd9d5e883e8201940108825208944dde844b71bcdf95512fb4dc94e84fb67b512ed80180c001a0c05fbff6fba6c5f9097b8a5bc7dcd23a1bef40852915fbdc672f2e03fc052a91a0540679ac128e14617a1ecc0e9d18925c965cfd379a01b7304025f3f5bb88fc0e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x1cfeb8cd5d56e1d202b4ec2851f22e99d6ad89af8a4e001eb014b724d2d64924" + "0x0d9b141fe39d89d2bedec5f3d98f0533f43a4d7c407d4df1e3faa9a386875fb0", + [] ] }, { "jsonrpc": "2.0", "id": "np443", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xeafce24dfb100daa2a1ee55da0030d8e057fc943b96b6e7f321af98b47e8107e", + "parentHash": "0x9b8c6ecde0c9f7d3096db113472984400265c16b8f423527046f7c9cacec1c0d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x23eacf2b963df64726e41314251669bf12f3925de3933e0b713863d1a7a6fc6b", - "receiptsRoot": "0xc97de406788b669a824183dab763b8caa8988371aea1f18b96e6b1f9abdee729", - "logsBloom": "0x04000000200100000000002000000204000000000000000000000000000008000800000000000000000000000000000001000080000000400000000000000000000000000000000000000000000000000000400000100000000000004000040000000000000000001000000000000000080000000000000000200000000000000000000000000000000000008000000000000000000000000000040000000000000000040100000000000000000000000000000000010000080000000000000000001000002000000000000400000100000000000004000040020000000000000000000000000000000000000000000010000010000000000000000000000000", + "stateRoot": "0x4187854dddfec6279591a4cd9f726102c4663d1c16c87b947effcadd52f9e692", + "receiptsRoot": "0xbe3866dc0255d0856720d6d82370e49f3695ca287b4f8b480dfc69bbc2dc7168", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1bb", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x114e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa53dc7dc3ac37fdd69bedd119e5113397594ab4171b7c010913864890dbd7f96", + "blockHash": "0x045aa374dc38d101b3846713180df1f69828e97bd630e2264149777bb19ece35", "transactions": [ - "0xf87a8201630883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0332397d6a00a7d2a3453bf053c8d158774d82d6ea252c2d564bbd48f9e882418a01187aef824b2759cba8c1574666919b77889353a9905720170518b03b38cc71d" + "0x01f86a870c72dd9d5e883e8201950882520894eda8645ba6948855e3b3cd596bbb07596d59c6030180c001a0a0df669968597ced5aded55893e3dd7d9b40fb05c02657c585877ba9c2aff66ca013e8c0042ac9517ca0e2b59635460a4258283501935b57efa48422b0f3542282" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xad223cbf591f71ffd29e2f1c676428643313e3a8e8a7d0b0e623181b3047be92" + "0x06747e12a0ff61f487ca91cc386c696148d6e20a1ece40d5a3528a3899f0536d", + [] ] }, { "jsonrpc": "2.0", "id": "np444", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa53dc7dc3ac37fdd69bedd119e5113397594ab4171b7c010913864890dbd7f96", + "parentHash": "0x045aa374dc38d101b3846713180df1f69828e97bd630e2264149777bb19ece35", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x71e7debe9374beede2414966d6eb2c2eadf548c293ba65821869bc274709badb", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x970698018f4fecbb86c13ddef6562a78648e7fb584fce6003cd0e01575241f5a", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1bc", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x1158", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x48640726ce7b39f951f82d46cfd4f8d71c93534109a0f93810c41289f6c97d2e", + "blockHash": "0xe316b409f1472bfb043c4be4e9654a37e2a898850d9bdc815cb9ca1a44b29118", "transactions": [ - "0xf865820164088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0b7296876d0713a392d440d71244cda1a3ecb09009a2f4d0ae5d26a398a8bee92a04dd844c3b7cbf88f10b080a3a0fd8a0e21e8d3041450c69786efe9ee7af18dcc" + "0xf868820196088252089414e46043e63d0e3cdcf2530519f4cfaf35058cb201808718e5bb3abd10a0a0de14126ae90f4e6f7172ac889d7788bdd6bbe19ccb3649b216b7a8f507af2e97a05576ccc32b95a6f5e588706f32dc88137bd9baea96e1743a6ead07f44d30a1d7" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe13f31f026d42cad54958ad2941f133d8bd85ee159f364a633a79472f7843b67" + "0x7886c0928a9559d88002185e1f2474adc78ea9c997a343656449cbb6ec97d65b", + [] ] }, { "jsonrpc": "2.0", "id": "np445", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x48640726ce7b39f951f82d46cfd4f8d71c93534109a0f93810c41289f6c97d2e", + "parentHash": "0xe316b409f1472bfb043c4be4e9654a37e2a898850d9bdc815cb9ca1a44b29118", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x58a574089cbd9986bf63c3ee8e0e8d400e9b97b8d1280166f7505de051f4c661", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x67c4905dadd5aaad517aa94d209cdc69989c8be8e39ff038f8931792508d1eea", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1bd", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x1162", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x40fa37188938bd349b17c8738f79a071533e0c0f6eaf4b1d6d6614fcae9925d6", - "transactions": [ - "0x02f86b870c72dd9d5e883e820165010882520894046dc70a4eba21473beb6d9460d880b8cfd666130180c080a09a954eff1b0e590a3a78b724b687c6ab944181990998780d56cc3593c704996ea0418db96b5dc1057f6acb018244f82ed6ece03d88c07f6ae767eaebe3b7ac9387" + "blockHash": "0x5cf2998fd231bdc16bd2c20b02d58af1f81d846a058464ac2e74f75a0485a33b", + "transactions": [], + "withdrawals": [ + { + "index": "0x27", + "validatorIndex": "0x5", + "address": "0x1f4924b14f34e24159387c0a4cdbaa32f3ddb0cf", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb45099ae3bbe17f4417d7d42951bd4425bce65f1db69a354a64fead61b56306d" + "0xc00472c88e5c05094693f81159e3b89cc45cac9dde868c41e1e418f6f09c8fbc", + [] ] }, { "jsonrpc": "2.0", "id": "np446", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x40fa37188938bd349b17c8738f79a071533e0c0f6eaf4b1d6d6614fcae9925d6", + "parentHash": "0x5cf2998fd231bdc16bd2c20b02d58af1f81d846a058464ac2e74f75a0485a33b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbd0820c57ebb5be91343940d7197af10c1d95a23a1b99bc5fa1a77997849273c", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x04994fb18b014bcd55798ba91dd1f026b23bff9e2273be08e1a90a1d67250247", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1be", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x116c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xeebf24886684542e08624e438bfad2c52eded1a4924aef3fd58d60ed6eaa1d19", - "transactions": [], - "withdrawals": [ - { - "index": "0x49", - "validatorIndex": "0x5", - "address": "0x6ca60a92cbf88c7f527978dc183a22e774755551", - "amount": "0x64" - } + "blockHash": "0x576518015f61ddc9e28fcf964fa2a13490057c8f8ab669ad82dd2e6bfa19879b", + "transactions": [ + "0xf883820197088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa0849cc75ee152d62a3fb486fbab7cd848e2ecc27b9fb566366572e443e33108f9a0603a1d5b2f13c657021472c600cdef596694268c678d88e5de5d3cb209ba5e9d" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9d2b65379c5561a607df4dae8b36eca78818acec4455eb47cfa437a0b1941707" + "0xc8d220c2229f22cc81c69ebdd7e54d6964acbe0d550eacc6a83eb488c4d5bda8", + [] ] }, { "jsonrpc": "2.0", "id": "np447", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xeebf24886684542e08624e438bfad2c52eded1a4924aef3fd58d60ed6eaa1d19", + "parentHash": "0x576518015f61ddc9e28fcf964fa2a13490057c8f8ab669ad82dd2e6bfa19879b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbc2acbe23d81c5bec8c73c20cfbb12be681cc92fa399ed4a44e7a91fb433c577", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xfab1e189dfb3cb6578b298363ad541e5355806fa45d0ee637004c23cfce550a3", + "receiptsRoot": "0xd6c1b856f2d2b69cadd746efc3b38a99237e658b25115819c0d394d46830876f", + "logsBloom": "0x00000000000040000800000000000001000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000002000008000000000000000020000000000010000800000000000000000010000000000020800000000000000000000000000000000000000000000000400000400200000000008000100000200000000005004000000000000000000000000000000000000000000000000000000000000000000000000200800008084000000000014800000004000000000401000000000010000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1bf", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x1176", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x837fc89a9611fa0b6a0d2f5a7dec3e06eda2ea3ee84bc6ce214c432b243c256f", + "blockHash": "0x21d1d59bcf21cac072a2803938f6fd69d922d1e47a8b7049d8818266bfc27951", "transactions": [ - "0xf88382016608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0daffe9dd6ca6d33e1a44ce5725c7e795639c4bd4a36cfb18d520c9fc892b7ca5a01286dcff57cb583238854ca89346c969387d982ca7e14cbd82413855fdda282a" + "0xf87a8201980883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0e0e84d0c2b2c6c49455f0fde3aa355f43de01b49ba6cc21add7a314e42e54b5da03b960f8f3f84bfa9314ed1fa56ecae25166b3245e306aa0520932e0f5256d2fd" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x5855b3546d3becda6d5dd78c6440f879340a5734a18b06340576a3ce6a48d9a0" + "0x26f2e58f0750c1fe9056a9a6392d3ef6af4c7ffc78033e2c42e9fdf96ca15361", + [] ] }, { "jsonrpc": "2.0", "id": "np448", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x837fc89a9611fa0b6a0d2f5a7dec3e06eda2ea3ee84bc6ce214c432b243c256f", + "parentHash": "0x21d1d59bcf21cac072a2803938f6fd69d922d1e47a8b7049d8818266bfc27951", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x95fea999be7fc8cfa0e1c8a9a10dc33d073417bf87ff698edab332c6e18ecc60", - "receiptsRoot": "0xcf29f818a1be0922fc0576d2500603f4e9ab8a9e251986d891170f993f0c8f0a", - "logsBloom": "0x00000000000000000000000004010001000020000000000000040000000000000000000000000000000000000001000000000080001000000000000000000400000000000800000000000000000000000000400004000000000000008000000000000000000000000000000000000000000010000000000000000040000008000000000000000000000000000000000020000004020000000000000000000002000208200000000000080000000000000000000000000000000080000020000000000001200000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000010018000100000000000", + "stateRoot": "0x85f8cf721945b935f88454cb7dcc80ed6077316a10ba2604bbd0a52f1d60b4f0", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c0", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x1180", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x05505959a8095b30ab40f55294926448248b48b0430ce33332c7b748e956aafa", + "blockHash": "0xe4e0607f25a8dcac8a8f7758373f3bbc1bc35176e239966d35a57925684b82fe", "transactions": [ - "0xf87a8201670883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0745918999757459ef7ab7145b734444d0437fa7b3939a6ca2a07652a727d1ef9a0074b0898accddb3ac54941b1fce130c31edd3d838dfefd506668cd989f4c5389" + "0xf865820199088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a036833029d4bfa43d4b9105e35e8df17007b71e832ea60faa678edf307b7cbef0a079cc8016b3453932fb5d5a5b6f4de361976a12d3859608299b9c76b129f8a0d3" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xd6a61c76ae029bb5bca86d68422c55e8241d9fd9b616556b375c91fb7224b79e" + "0x8aae197b8ccf12c586225a94624141507808c6ab7ee29e9ee6e324d01557fd5e", + [] ] }, { "jsonrpc": "2.0", "id": "np449", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x05505959a8095b30ab40f55294926448248b48b0430ce33332c7b748e956aafa", + "parentHash": "0xe4e0607f25a8dcac8a8f7758373f3bbc1bc35176e239966d35a57925684b82fe", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa4269875f0bd6dc1360830e3e07eae0956700e8c3aa69cd61b423abf51bfce54", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xa5458c65c7dbd987ae9d0926cc781bfd453a18b00eea106e8dc9a2c99a5dfa28", + "receiptsRoot": "0xe768f6ae38c5f2054e7ff83ad46a4cc93748c6d829e8f17f6091c07003ccc959", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000040000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000002000000020000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x118a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x57095cf08428bbd1fff32a14f1a811750ff2de206ee3ea1d6f6f18f7a2606d30", + "blockHash": "0x8b744a371a22b4986eeceb8ee0f512ca44affb56ecd495cea9e6c66a490e1f9b", "transactions": [ - "0xf865820168088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa01f0e57c3b6f3908a7afb46717ef32caf9b73c4a4b2f48b09e0fcbea02ae716e1a017c79cab83300efab682d0c0438b23b49136a17e22560e75d32014c5951b4fd4" + "0x02f8d4870c72dd9d5e883e82019a0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c50784d15bdea7b9e656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a07eae9da1da48fe866f64de7ac5c70c8e43644867b917aa8461f84915396d359801a05fa759f9d89dee838d6c206faaaca0274fc1ce0470137fd92b29414dc7385bc4a06ebb401fcc19aa9889892ff829c1787ad97bf27a553ab1020f96476679279d0f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x96ac5006561083735919ae3cc8d0762a9cba2bdefd4a73b8e69f447f689fba31" + "0x946d6d60fe20c81d1cf507d2a9567fc06ea539ac3a542d283373ccee3f82212d", + [] ] }, { "jsonrpc": "2.0", "id": "np450", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x57095cf08428bbd1fff32a14f1a811750ff2de206ee3ea1d6f6f18f7a2606d30", + "parentHash": "0x8b744a371a22b4986eeceb8ee0f512ca44affb56ecd495cea9e6c66a490e1f9b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd315f1048882fde9bc00a0bae351ab3229cec00efa7ef4b61fd5c1be40619f81", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x7580d75a460174096af8b7c511f879cf88f9d281b055d58651f1d274b7484a5c", + "receiptsRoot": "0x23c5f32b160f9cdb83afe13090caebc9ebeadcea470982a379a62325aa78b865", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000840800000100000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1194", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe6d3cb3da9e188604d0e8bc2f03a0df4fefa836f9bf4b679e54e97138f72dd08", + "blockHash": "0xca1d7f951d628dd35b23cac8c21070a5740d64bba614089170c895a0ec8f57ef", "transactions": [ - "0xf8688201690882520894104eb07eb9517a895828ab01a3595d3b94c766d501808718e5bb3abd10a0a0597dbb3f69603be721ae0f2a63eeee9f008829ff273b54243673f9ea192ddc0aa01f7dd04defb45af840d46a950b8bede0b3ce8a718004c1ca2f3bbd4efcbd7563" + "0x01f8d3870c72dd9d5e883e82019b08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c8da9dc6f96ca4d62656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a02aee290f6f3f6c60a6985d0150eab487f9de1c47962a779be7343cc0cff270f980a0257adcb05e25646f33deeb98bea0697f601355b5e72da46fcb1c1d0ea1d81fe5a051107d8771eb7448a728cc1a4e5edf15caed6246726977d2480ea42f187d1f0b" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4ced18f55676b924d39aa7bcd7170bac6ff4fbf00f6a800d1489924c2a091412" + "0xc43169ff521bf0728a5e972911abeacd2f597eff89b961f3132b2f91ce04dc20", + [] ] }, { "jsonrpc": "2.0", "id": "np451", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe6d3cb3da9e188604d0e8bc2f03a0df4fefa836f9bf4b679e54e97138f72dd08", + "parentHash": "0xca1d7f951d628dd35b23cac8c21070a5740d64bba614089170c895a0ec8f57ef", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3222feed7d40d321811eb16ac78aaa0561580b176e0605bfecc30427a7702996", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x626ca5ae10a12b2efd2b48e7c3bc1e6976cd77ed69722edb4f86b80c2c3a2661", + "receiptsRoot": "0x32ad5c4b7fa7b3c1a393566bab829ec3a4d407c36d8fdb1ddab694bbcd33d1e7", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000002200008000000000000000000000002000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c3", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x119e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x465bd8f010df142744fc22da07b631a4e2d11ae75bca1608f7592548c420178b", - "transactions": [], - "withdrawals": [ - { - "index": "0x4a", - "validatorIndex": "0x5", - "address": "0x102efa1f2e0ad16ada57759b815245b8f8d27ce4", - "amount": "0x64" - } + "blockHash": "0x410876f7d8880a998a060adf663027422ab139d54e12e973c1bb8342844cb351", + "transactions": [ + "0x03f8fa870c72dd9d5e883e82019c0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cc02a894c6c24e04c656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a06f9ff000b2dc3a554bbbb882ebc7726b700eb7afea141ab16e00a057f314d0db83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0d5cda3865be365c1ae76bd5e2b0b91f7637da3b11cacdedbfa21cab859942279a0013845f66b55919c176cb4f0647f6894b77cbf0ff4c88a2914124b84977d08a1" ], - "blobGasUsed": "0x0", + "withdrawals": [], + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0xc95a6a7efdbefa710a525085bcb57ea2bf2d4ae9ebfcee4be3777cfcc3e534ea" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x427e24cb2c8355bd1f18d20aa668805a4e4acfa1411ef2ec980839670499c0a7", + [] ] }, { "jsonrpc": "2.0", "id": "np452", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x465bd8f010df142744fc22da07b631a4e2d11ae75bca1608f7592548c420178b", + "parentHash": "0x410876f7d8880a998a060adf663027422ab139d54e12e973c1bb8342844cb351", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x96bcc6f26c5f94c33c57d1614edd2b385e36d9972250c79758eeaeb09927c0a8", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xa46ba3066c87ce7119b56ce58630ed0cc27373af242719b16976cd670d8ae556", + "receiptsRoot": "0xa4870845d20ff24f436d4c5554b2a5e54400e3e3a9d3a5a2e16a97b91a6dc6cc", + "logsBloom": "0x00000000000000000080000000000000000000000000000000000000808000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x11a8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc7131bb27a6e1395d028d543cfd6f9e71ec4f2d2ecbc44cef53b5b626e01cad9", + "blockHash": "0xb30c453a9fb88e026819b182903ff90738d44f4237cf66139fe010a93c83ffb4", "transactions": [ - "0xf88382016a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a03fc929c6e9476221ddd5f2f5093981cc13f4b8206ee3454720f06c0bd5c95caba038f23a2c21ba59155127a15502ddd731f30d6f94c6aafde8e73fbe39237766a2" + "0xf87582019d08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c8a743c95d9f14e1c656d69748718e5bb3abd109fa03be3a8d50842a232a28fcf0b3a18425ea2e6f39bbc75d0d5e3e65230e64b3f2ea0289e148b41d97dc01ad89dad1158eeb20f42d906387502cd5beafbb5655670c9" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x2b2917b5b755eb6af226e16781382bd22a907c9c7411c34a248af2b5a0439079" + "0xb96ddc711361deb1db8cbe6a3bf2bfa883bce23e2f2260c3a0f3c6758f3fcabb", + [] ] }, { "jsonrpc": "2.0", "id": "np453", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc7131bb27a6e1395d028d543cfd6f9e71ec4f2d2ecbc44cef53b5b626e01cad9", + "parentHash": "0xb30c453a9fb88e026819b182903ff90738d44f4237cf66139fe010a93c83ffb4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x168c847144cfea8b88e6ec4f673ebddbf18331bde8002e044b1d1df7408edf04", - "receiptsRoot": "0x4ff26b781abcaf6d8a14f4f5283feeee87038dbcb46b9987d6042a01b1b07f9a", - "logsBloom": "0x00000000000400000000000000800000000000002000008000200000020000000000000000000000000040000000000000000000000000000000000000800000000000000020000000000000000000000000000000000000400000000000000000000000000000000000000000800400000000000000000000000400020000000000000000800000000010000000000000004000000000000000800000000000000000001000000000000000800000000000000004010000000000000004000000000000000000000000008000000000000000000000000004000020010000000008000000000000000000000000000000100100000010000020000004000000", + "stateRoot": "0xd607b37fd2cb910a26e9a84b69095bfc848b823c57d979da9cbf70b8ddfb5849", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c5", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x11b2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x6d6eba2abd0851251651f038c9bcd8b21c56e6cefc95adb259a2b0c3ae4f158d", + "blockHash": "0x5588cd9a04aa1c7e5590c15bf201aa722f59c4aa952bedd1e0de2cd2026c016b", "transactions": [ - "0xf87a82016b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa07061a8a3f917f765ec8aef5e4ad237d377c0131f63f31da7bdc6af9942a1bc4aa051bf3e7c6676f2fbde507834995f4e269113adf35b98bc71cd22d9c168692f5c" + "0x02f86b870c72dd9d5e883e82019e0108825208940c2c51a0990aee1d73c1228de1586883415575080180c001a0f5f044b3c2b0e5cac578371ff5332de04f8752ba742606f0899c231dd8960c91a022c3cefad9171af45288b936783781dff0ef8210fc66235a0071d8bf7c72af17" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x18d5804f2e9ad3f891ecf05e0bfc2142c2a9f7b4de03aebd1cf18067a1ec6490" + "0xc92246b2394e70d0d0d5c3fd1a5f6c585293d1ee7589b5c8bb37e997e0985b82", + [] ] }, { "jsonrpc": "2.0", "id": "np454", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x6d6eba2abd0851251651f038c9bcd8b21c56e6cefc95adb259a2b0c3ae4f158d", + "parentHash": "0x5588cd9a04aa1c7e5590c15bf201aa722f59c4aa952bedd1e0de2cd2026c016b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7e75fe29c17414bea5febf41c577c117b57c1a731aa7a18b6c5d2ba9e3bc27dd", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xa07aee3a994f4786a9132255d8d82a9ceffe0a586b3b66dfc26b517c7ae9263f", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x11bc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5cfbc66c760f871b8cf6d87140887788db0622a0f54274737f9cd043b156f50c", + "blockHash": "0xac273cc7933a2407ec16281e6c7e43bb9b24efd517f53122d265c0fd8e400e6b", "transactions": [ - "0xf86582016c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0ec3fe55b96a9d14e22fc0a8aa5991138ba954245754c0e0dda2b5b7dbb6711caa0296a6b87da18224fac7c922e2a7f0ec41330a6f510934a1e0e3c6a65dd72dfcb" + "0x01f86a870c72dd9d5e883e82019f08825208941f5bde34b4afc686f136c7a3cb6ec376f73577590180c080a07b02bc124dd50bc80814d08749d075bede4b4c13202a5fad804135b8b493754da002629acd4c30c01ce1c63f74d44d505f544a35cdb087482b803e5e01bf98cc76" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb47682f0ce3783700cbe5ffbb95d22c943cc74af12b9c79908c5a43f10677478" + "0x487f419b494cf102fa1813eb824fe3809d34806cc2548e6a41a9e3f755f6c131", + [] ] }, { "jsonrpc": "2.0", "id": "np455", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5cfbc66c760f871b8cf6d87140887788db0622a0f54274737f9cd043b156f50c", + "parentHash": "0xac273cc7933a2407ec16281e6c7e43bb9b24efd517f53122d265c0fd8e400e6b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xdf26695268f674fc809ad21c323bcab53727af440302b923eec2d46ee3cd7aa3", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x80cbabc0bbc66c40593eac7415a5e92ae1c19d77abf691cd6aa369fbd5410449", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c7", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x11c6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x8f4a24fc6a150744744d03371d34758cf69d4216538804395397ed081692c7fb", + "blockHash": "0xde0c3b47b2a8550abaebd952555b5a604916b2aa0c3516ac07f7cf9bf6d289b6", "transactions": [ - "0x02f86b870c72dd9d5e883e82016d01088252089446b61db0aac95a332cecadad86e52531e578cf1f0180c080a0774ced5c8674413b351ae8ac3b96705d1d3db10deae39134572be985f16c008ba06f3e4b250f84fcf95ae85946da8a1c79f922a211dbe516fcfcff0180911429b8" + "0xf8688201a008825208944dde844b71bcdf95512fb4dc94e84fb67b512ed801808718e5bb3abd10a0a0fe551bca46e599932399359e23ba76065cd515b2a6096048cef9a7c127737dd2a052a0df5bbac278462e0f84337ffc1ae8c2667a58205eac272d6596c8e9116ea1" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe4b60e5cfb31d238ec412b0d0e3ad9e1eb00e029c2ded4fea89288f900f7db0e" + "0x4ae0132498c0baaa78d768792661893e0455eea248e8e334e9aabcbec8909a0c", + [] ] }, { "jsonrpc": "2.0", "id": "np456", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x8f4a24fc6a150744744d03371d34758cf69d4216538804395397ed081692c7fb", + "parentHash": "0xde0c3b47b2a8550abaebd952555b5a604916b2aa0c3516ac07f7cf9bf6d289b6", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x358b2d72362d209f8c7131a484e49caff1dda8f550fe6103be80ac369cfe49fc", + "stateRoot": "0x65c9d878df12d376f241b7359e683f079b80cfef32ab553ac6d6f19cd09a66c3", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c8", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", "timestamp": "0x11d0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xafcf58746fc811dd74a0e4a66d91efbb00b2ab2c96680e132234a947798abf7a", + "blockHash": "0x305bd96c60a6435f5371739f23364940ac2ee253e9a6f8d3bd89a623112533e8", "transactions": [], "withdrawals": [ { - "index": "0x4b", + "index": "0x28", "validatorIndex": "0x5", - "address": "0xfcc8d4cd5a42cca8ac9f9437a6d0ac09f1d08785", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "amount": "0x64" } ], @@ -11902,1239 +14427,1391 @@ "excessBlobGas": "0x0" }, [], - "0xfc0ea3604298899c10287bba84c02b9ec5d6289c1493e9fc8d58920e4eaef659" + "0xb3c4c107e197af6bc4e5542501108ae40e405c8065c54c4f75784b217cddf40a", + [] ] }, { "jsonrpc": "2.0", "id": "np457", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xafcf58746fc811dd74a0e4a66d91efbb00b2ab2c96680e132234a947798abf7a", + "parentHash": "0x305bd96c60a6435f5371739f23364940ac2ee253e9a6f8d3bd89a623112533e8", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x2dd7146f049ba679aae26c42d1da7f6660ea964a7b227509e5296a9d0170e93e", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xe81f2fc60ae550918e122a070d583ce4eadb9dda94f028f04b5c2585627a9c0f", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1c9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x11da", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5346eb38677572982317e96be00144f1600800e5a738c875522183ad74f408d4", + "blockHash": "0x322c4d0e57f585f032d5cbfff69c3adb7ac8084c95761a9bbad98b97f101327f", "transactions": [ - "0xf88382016e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa038214a2cc756a0ffe043200d5e12183223f81912c0156df732c3b1d85bc2a237a0744a52bf9fca64223bc279e589d21b9fda190325bf3b576f41a792ccbec5bc08" + "0xf8838201a1088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa010d014cb65ac522ff899f3b31c72ab16b980f306d0243add48333b3aa655ff66a0103a6f272e55d5c5454f473227432bba2671535641717072db7a9a299ab87074" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4c3301a70611b34e423cf713bda7f6f75bd2070f909681d3e54e3a9a6d202e5a" + "0x5bb5995473e555f6b3a3649155d6c305866a8266f3a8e6d549fbb4b5c6a785a4", + [] ] }, { "jsonrpc": "2.0", "id": "np458", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5346eb38677572982317e96be00144f1600800e5a738c875522183ad74f408d4", + "parentHash": "0x322c4d0e57f585f032d5cbfff69c3adb7ac8084c95761a9bbad98b97f101327f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x62b1bdf3b4a63f480b24af9f3b55dc6ad6e52bb81caa13b286960694b3b600b0", - "receiptsRoot": "0x25a0fc424c07569fb4229958de04f1d6497b3d8b6a78757f42963f95c354e2b1", - "logsBloom": "0x10001020000000000000000000000000000000000000000100000100000000000000000000000000000000800000000000000000000000000000000040000000000000000000000000000000020000080000000000000000400000000000000000001400000000010006000000000000000000800200800000000000000000000000000000002000000000000000000080000000000000000000000001000000000000000000000000800000000000000000000000000000000000000000000000080000000008004000000080000000000000000000000000000000000000000200000000020000000000000000400080000008004000000400000000000000", + "stateRoot": "0x1c3e70f87cf00906c14ca168c6b2013992feab17ce72ed6c25ba1941fc5894a9", + "receiptsRoot": "0xef465287d76259c60ad703f515c44ee922414d482c2a6522e489a568d5e7333f", + "logsBloom": "0x10001000000000000000000000000000000000000000000000000100000000000000000000000000000000800000000000000000000000000000000040000000000000000000000000000000000000080000000000000000400000000000000000001400000000010006000000000000000000800200800000000000000000000000000000002000000000000000000080000000000000000200000001000000000000000000000000800000000000000000000000000000000000000000000000080000000008004000000080000000000000000000000000000000000000000200000000020000000020000000400080000008004000000400000000001000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ca", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", "timestamp": "0x11e4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x83f464b150683ab5ce359179f4f9d6e960049959d2ec46a4ae7a07af2de41a6c", + "blockHash": "0x721f94cdb4c6e847bfbc88d65c74a8eb476178d1fa868af25151fd17256aa5cb", "transactions": [ - "0xf87a82016f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa05e304ec406ec4c83644417e1e58b49757d3ac78da5c5280fbda19b1f149137daa035b73caa8da3b6ce0e5f1b014c127f93f7be595f104cd933b5ff07549fd1812b" + "0xf87a8201a20883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa081f406b3a913530deb0925331aa8467e902ffec9a5425e75c4f662ca9a2f27a1a013b947b3ff5824ccde3401fef17837608be8f786eeccfeae8e3a9e902fbef5d5" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x84a5b4e32a62bf3298d846e64b3896dffbbcc1fafb236df3a047b5223577d07b" + "0x034986be3995c99d86ded5f0984cb1c60f4d01157905782157f447054303e1c6", + [] ] }, { "jsonrpc": "2.0", "id": "np459", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x83f464b150683ab5ce359179f4f9d6e960049959d2ec46a4ae7a07af2de41a6c", + "parentHash": "0x721f94cdb4c6e847bfbc88d65c74a8eb476178d1fa868af25151fd17256aa5cb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5614ae860626ff1e044740a53f3cb5126f72002928c034aecbdfe4291ce73b91", + "stateRoot": "0x27bc1b69541d7cc57bbfc82baa65a943bf40ae8402d5a77505a6a5c3995e05d5", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1cb", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", "timestamp": "0x11ee", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3c1ccfa2b5f88830245f76a22fa29ce22fb5b284de5937ff66adc67a445bf5c5", + "blockHash": "0xe98015589d78db8a32de341208e325d7613c6db8683c7d1376113589e15acf0f", "transactions": [ - "0xf865820170088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a05d0d172a5fb9787aa2ee5205e5986de935984adf6030d5668be0e31332f7b145a022c4c7a89391e8f4508095fc5c1ed16aa0c08da6790be108240dc64763d42dae" + "0xf8658201a3088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0fcb36b193135dcc545402c100aa7515eca3114a58ec3ddad2222389dada34c93a04274b8e22b8a65231a168d3e874add304538b0e84fcadcdf667de1c457ec6576" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xff70b97d34af8e2ae984ada7bc6f21ed294d9b392a903ad8bbb1be8b44083612" + "0xea092ecb252e475b5493c71739404f66771dfe92e90554924e7c979b1ac68c1f", + [] ] }, { "jsonrpc": "2.0", "id": "np460", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3c1ccfa2b5f88830245f76a22fa29ce22fb5b284de5937ff66adc67a445bf5c5", + "parentHash": "0xe98015589d78db8a32de341208e325d7613c6db8683c7d1376113589e15acf0f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x715b0d1e4306032fa54c79f84599828d98bc84ed9cdb52a407e58730b4c112db", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x534a22a7bb7f69a06a59da75fc8e0177fb324c75cf4193eebb37cf0415fe1325", + "receiptsRoot": "0x2e70f6fe320c333766de84b318783349f7bb1037cf5ac5f612703d2439f6aece", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1cc", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x11f8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xfc7412d30ba5b6f5b319b07e51296906a42fdae50a88c1f90016d487b1df41f6", + "blockHash": "0xca13a2bf7d0eb0db6335849b7706678ec18caf013540bf57873532d5bc5cced4", "transactions": [ - "0xf86882017108825208948a817bc42b2e2146dc4ca4dc686db0a4051d294401808718e5bb3abd10a0a0a755d1c641b8965ea140ad348135496fc412ffa43a72bbd2c7c0e26b814a75f1a067d81cca370b6ea40ccd2ad3662d16fa36bd380845bee04c55c6531455d0687d" + "0x02f8d4870c72dd9d5e883e8201a40108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c7025e3856d4257fc656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0492ae6c575840126917090c30d003aec0892cd6250f877b99f33b72133b94f2380a0493823516fb5621e5a2fb93f68383f54d9df203babab75c5511e756def8a623ba052e62f5274027ac06f53bcf3fdb0e92f64b12e47ac3034d28e4541c76f2d7b82" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x73e186de72ef30e4be4aeebe3eaec84222f8a325d2d07cd0bd1a49f3939915ce" + "0x70403edcf814de8d55741ccb378648ba8de7893d6affa4ba0e5549d0de6bcb2b", + [] ] }, { "jsonrpc": "2.0", "id": "np461", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xfc7412d30ba5b6f5b319b07e51296906a42fdae50a88c1f90016d487b1df41f6", + "parentHash": "0xca13a2bf7d0eb0db6335849b7706678ec18caf013540bf57873532d5bc5cced4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8c6710fa12f6392a52eaa92d776fe1c24245dd52883ff2276547e65c34952eeb", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x4806e71590b11d66562b670bfbb4227af9255f94e8fc0176fdb281bd7675f5c7", + "receiptsRoot": "0x2e8de0056d0fc190139defd3579bc5c7fec36ff1ae323626a9506b593849b1e3", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1cd", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1202", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xdad167dfa9bb65a470a36a3996f0587d645b3fbfe9e3522a1436f1dd6a3a37f3", - "transactions": [], - "withdrawals": [ - { - "index": "0x4c", - "validatorIndex": "0x5", - "address": "0x48701721ec0115f04bc7404058f6c0f386946e09", - "amount": "0x64" - } + "blockHash": "0x4d93ae5d91ac6a55b6fe9e452210d4e60472cb09900262104063f91e1c4475fb", + "transactions": [ + "0x01f8d3870c72dd9d5e883e8201a508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c068ce3b3f4387cea656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a041b546f355dc0dd009ac5da8bfd17c8e197595c1c1f21aabbb1f3b18343a071880a01412cdbfb14747299cd2225b102548b2d7db5ab760d6ee92d7dfd502dd40ba60a061a8e13fed190951bc37b4d53414fd44b3eafac7c6455f0e83c70c56db6398dd" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xed185ec518c0459392b274a3d10554e452577d33ecb72910f613941873e61215" + "0xb8b758a473ba28008dfe949d230cd8a73b4340bc0687cfe8b0326eded2558ba1", + [] ] }, { "jsonrpc": "2.0", "id": "np462", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xdad167dfa9bb65a470a36a3996f0587d645b3fbfe9e3522a1436f1dd6a3a37f3", + "parentHash": "0x4d93ae5d91ac6a55b6fe9e452210d4e60472cb09900262104063f91e1c4475fb", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x8c73a23f75ee594dacc63d24a5d5655a1ccbeead972dba58ad86787c44442c6c", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd01d51aef5c56620f82b4a65c4de929f29de75529a0f8f39caccf5cb20f5d1df", + "receiptsRoot": "0xe0cb24dd872908c91fbc43cb557530d5965d1875176bb5f5b0c3330cd869b44f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000010000000000000000000000000000000000000000000000000000000000010000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ce", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x120c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc50795e72a34041bdabf74a87f77d78f3a07f2005396dcf9925b08a8a686bd61", + "blockHash": "0x4557b30a7674af7cbacde7748dff90a2d7b4b2a86f9d79d791e89d39f818a4b2", "transactions": [ - "0xf88382017208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0567311948632a5f4d53e0491aa8e7f939a3e0da38be1db4b6c757422de3f8bf6a01134e092948e423c7f8867c02822c95f3ce21b6d4e8d3666e2cf47ca88ad7499" + "0x03f8fa870c72dd9d5e883e8201a60108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cc3396aa113bce01b656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0fd6fc192aa03eedb6505372aa1dcda93dd186fb3eded0bcafdaa4f2829fe43b583020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a083bf65495878dd9268b7b195bc145b7ad21da1c74abd11f3b8c14ce5c5ccf56ca05c3b754eeb0bc0f79c3f06c9cb839a04fc654da6adbcfaef5de25b0f42f1d36f" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x5cfbad3e509733bce64e0f6492b3886300758c47a38e9edec4b279074c7966d4" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x76daa53b1c8d26a50bd4e4eca2703ba4bcad8248f6ad3227ed0af745d19d8ae4", + [] ] }, { "jsonrpc": "2.0", "id": "np463", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc50795e72a34041bdabf74a87f77d78f3a07f2005396dcf9925b08a8a686bd61", + "parentHash": "0x4557b30a7674af7cbacde7748dff90a2d7b4b2a86f9d79d791e89d39f818a4b2", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb6a995ce6f848e4f2f2ad8ced5491859a5d0a3b6767108f3ce5cfcb33303349f", - "receiptsRoot": "0x5bb341cd099f8898164b032e64db73752f528a10e8d9c60c9b4fff08af32dcf5", - "logsBloom": "0x000002040000000000000000000000000000000000000000200000000000000000000000000000000000000000000300000000000000000000010020000000080000000000000000000000000000000000000000000200000000000000201000000000000000080000000000000000000000000000000040100000000010000080100000002000000000000000004000000008a0000000100000000000400000000000000000200000000000200400000000000000000000000000000000000000000000000000200000000000000002000000000000000000000000000000000000000000000000030000000000000200000000000000000000000000000000", + "stateRoot": "0x6f28e7c311ff4014108eaa947693b7e142229cd3511fd91708744809a3ae3f5a", + "receiptsRoot": "0x803ef636ba01c78ca5c2de004aa09486ba182fbf479f6e4c274f62e0c4c6a8cf", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000800000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1cf", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x1216", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x69a26219f28581c8898c2790cf785e3f2b0081a416d51722d85b5ac313d5f36d", + "blockHash": "0x07a8c620ead87a45afb4e0e815a54ca217e4054077635d1524710f1ce5ecea24", "transactions": [ - "0xf87a8201730883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a06092eab6a3d9e41841ad4b9c97154ac35269c852606da6dd04940a1a055fa979a052a6e3e769e27310acdef840cb1182f4a2b6b08583b01cb8325c98253feaf7aa" + "0xf8758201a708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c1bf41e5570d77f5f656d69748718e5bb3abd109fa0e8b18ebd47bd5fe6b3d0da3e846fecc95bfe019238497660fd044622d333ee68a01c2021e56a61b76b9d4b2cee62f1fd038a60d891897ad0c842b0afd39a709956" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x867a7ab4c504e836dd175bd6a00e8489f36edaeda95db9ce4acbf9fb8df28926" + "0x2143743a63aa6ab5a7a6586dc404e48493f59fcb7021c079cd5e7efbe4a9fc62", + [] ] }, { "jsonrpc": "2.0", "id": "np464", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x69a26219f28581c8898c2790cf785e3f2b0081a416d51722d85b5ac313d5f36d", + "parentHash": "0x07a8c620ead87a45afb4e0e815a54ca217e4054077635d1524710f1ce5ecea24", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf54cc52e78b0ea88b082230970d262fc78070bff347c000f60c53400d111a59c", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0xa3bec6f881c7947a0f7f0862184894e824488ebca6c7c737c3b2d4ce9649adec", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x1220", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3ed11b20d6eced6314897749d304a677d345ce9343fe964143548980ea71615e", + "blockHash": "0x87bca64e4e6c1a83cf43da1257fa59a376009b2c9f2f37487f85eb8013fb2f0f", "transactions": [ - "0xf865820174088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0342c58642563f78afdb5cf7b9fbc935268a8fd81a5bd7997c33f61cdff8fb9c2a07466870d997603b5dd7755f151b76f056d4948ae82372b05babc01b9addaad19" + "0x02f86b870c72dd9d5e883e8201a8010882520894654aa64f5fbefb84c270ec74211b81ca8c44a72e0180c001a04004c9e1e07f1fcb40b17fd0155a6ad6512d31c0be3e7975a470536834fa6a7aa032ce14734e673e544c999078ea52e7b5f99c334dacbc37fe09545f4992974742" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x0d01993fd605f101c950c68b4cc2b8096ef7d0009395dec6129f86f195eb2217" + "0x6919ec8682908f8de7753ac9fb4e8fb1b6c0b6cc2d2d1a7df12eef58d8c6c841", + [] ] }, { "jsonrpc": "2.0", "id": "np465", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3ed11b20d6eced6314897749d304a677d345ce9343fe964143548980ea71615e", + "parentHash": "0x87bca64e4e6c1a83cf43da1257fa59a376009b2c9f2f37487f85eb8013fb2f0f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5b583ecaeffb409a488709df2c592c932e93a9b954bb5b62c36739324ae7d89c", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "stateRoot": "0x717549302dad496e69418af6eea2f9b487baed0236ba4b90d13f46b8df45d3be", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d1", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x122a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x20ca98d23c09a37aa1805c3989ca7a7bfff9ade344de4575f5063a10c60510ca", + "blockHash": "0x5984be6ef98b1e35c943bed4caf24066c34bea65dd09cf99762e7e3b6e41ae03", "transactions": [ - "0x02f86b870c72dd9d5e883e82017501088252089423e6931c964e77b02506b08ebf115bad0e1eca660180c080a06263b1d5b9028231af73bfa386be8fc770e11f60137428378137c34f12c2c242a02b340f5b45217d9b914921a191ce5f7ba67af038e3b3c2c72aaca471412b02f7" + "0x01f86a870c72dd9d5e883e8201a908825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c0180c001a09abcdf1c2570570e59c823ab3a69bbfddc6d1008562623128e2c1f61e7b6f0dfa03995c9953c9b0931904e8b8d2e6a05128f9f292f0a6763e576ec5176e6cc4a6e" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x8e14fd675e72f78bca934e1ffad52b46fd26913063e7e937bce3fa11aed29075" + "0x3c61846fc931a63f5fc1fb0dec6dfa5bee9c19104acc5a1dbd0fdfe331827dca", + [] ] }, { "jsonrpc": "2.0", "id": "np466", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x20ca98d23c09a37aa1805c3989ca7a7bfff9ade344de4575f5063a10c60510ca", + "parentHash": "0x5984be6ef98b1e35c943bed4caf24066c34bea65dd09cf99762e7e3b6e41ae03", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xdaf72de0a7092d2a2a6d31336c138ab45852ca65398578fbc435b3c591fa7c3a", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x47528cdf5370069155e80e30d1f5ca1c7038610dd2a594fd0b40184b32daa753", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x1234", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd1c6165f74a48fb1da29dde0ec4588f1b5708d1b810696ab128a6db9ce08a1eb", - "transactions": [], - "withdrawals": [ - { - "index": "0x4d", - "validatorIndex": "0x5", - "address": "0x706be462488699e89b722822dcec9822ad7d05a7", - "amount": "0x64" - } + "blockHash": "0x223fd06ad6b3a95d0ca0b0fac2819ca9cc7abbcf53686cd3cc9ea9a7099aed2a", + "transactions": [ + "0xf8688201aa0882520894c7b99a164efd027a93f147376cc7da7c67c6bbe001808718e5bb3abd10a0a07a7094e56286d07a0843ec216423dd2e25b45950cd30267a31673a2a03ebbacda079b43cc4f41e5edd1dc8d07ef006668d9b1481e724ac8f5361f431fe2aaf11af" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4ec1847e4361c22cdecc67633e244b9e6d04ec103f4019137f9ba1ecc90198f4" + "0x65e7c42e7c1674ca5d52dacbd9fdc6fad75a0cd87294e8641c56aaf12092774c", + [] ] }, { "jsonrpc": "2.0", "id": "np467", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd1c6165f74a48fb1da29dde0ec4588f1b5708d1b810696ab128a6db9ce08a1eb", + "parentHash": "0x223fd06ad6b3a95d0ca0b0fac2819ca9cc7abbcf53686cd3cc9ea9a7099aed2a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb9f6529424870d0fbfe7d70438762f3ccf9d2f212d3e42c837f6e9218d72451a", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x4a805ac2d1c6c3f45e4aa754b3c3f9d92a0c4f02b5b5a6d735ace7041b26081f", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d3", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x123e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xee2b973ebc00c239bf4fd6c382cc78890065370286476ae02a9b1bd76788f810", - "transactions": [ - "0xf88382017608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0e42b1ec38a455f867d421d170e634c86f8a84a2cb00ec5024f343667042f303ea067797c75de08e6eafd819d4c408324fba318e16b378b7dedbc0708056aebb696" + "blockHash": "0xbf9df0134a7722c090ee27e9061af8e32ba1f36de3561cf540aa19c1e0301694", + "transactions": [], + "withdrawals": [ + { + "index": "0x29", + "validatorIndex": "0x5", + "address": "0x4a0f1452281bcec5bd90c3dce6162a5995bfe9df", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xec69e9bbb0184bf0889df50ec7579fa4029651658d639af456a1f6a7543930ef" + "0xd17d5eec3cbd76848cac5f8fb453911fcf5d896670703252da7925f33f6597ca", + [] ] }, { "jsonrpc": "2.0", "id": "np468", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xee2b973ebc00c239bf4fd6c382cc78890065370286476ae02a9b1bd76788f810", + "parentHash": "0xbf9df0134a7722c090ee27e9061af8e32ba1f36de3561cf540aa19c1e0301694", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3017b68d781fb29ccbca4c6ff597a9e18d6cee4f02974dbb32f04b5a7f519271", - "receiptsRoot": "0x00fbb0bcdb236cd79dbbefe84d42f31ee3274cc5e9116ffb0d70301b983dbd52", - "logsBloom": "0x00000000010008200000000000000000200400000000000000000000022000000000000000000000000000000000000000000000000800000000000000000000000000200080000002000000000000000000000000008000000000000000000000000800080000000004004000000000000000001000000000000000000000000010000000000200000002000000000000010000000000000004000000000000000000000400000000000000000000000040000000000000000000000080000000000200000000000000000000000108000000000000000000000020010000000000000000000000000000000000000000000000000000000040000040000000", + "stateRoot": "0xad4453dbba65e66c8793ae1a41e1c1c430f00c1bbe8a6e30663cfa1b13d6ebdf", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d4", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x1248", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x66a71dd383d4ead0e00787a06fcfb3c75c36fa72b5d98f39dc37ca129315b8d9", + "blockHash": "0x3426b1051fd2963cf74c091c9281236fec075e3b1a6207e0ea8bd590d234231f", "transactions": [ - "0xf87a8201770883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa01975b5adb5e05e7dbaf63d31d34e5dfb802c4ca28127176811ada2b0a9411be6a02b9cd65ba817631163e95275ec2bd5319edeef4f74eb6efb32150a523282db16" + "0xf8838201ab088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa07f301798a3e8eac769613ffe0c2b89d2a35a386254117a17cadd0ec7ac71d7ffa048e580964d38c0fc0468c0f2a82331e1afe0565d47329be39f2dcb58e7c26583" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xefdd626048ad0aa6fcf806c7c2ad7b9ae138136f10a3c2001dc5b6c920db1554" + "0xaa5ae82882c7a2a53ab35d0499ae76069be55e70153ee47d3c712f48f24be400", + [] ] }, { "jsonrpc": "2.0", "id": "np469", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x66a71dd383d4ead0e00787a06fcfb3c75c36fa72b5d98f39dc37ca129315b8d9", + "parentHash": "0x3426b1051fd2963cf74c091c9281236fec075e3b1a6207e0ea8bd590d234231f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7da79133a491b6c2566dc329ed006ee0010fe59b515fbce5589eda0f31dd091b", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd6604a1a483323a25dbb76b0d43c9c7e328e4182688d2b5a588d37665e2b24fb", + "receiptsRoot": "0x13d0652e24c37c769d347b120265923055f96ae713b9d77ff70edac07e2b97ab", + "logsBloom": "0x0000000400000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000020022000000000000100000000100000000800000000000000000100000020200000010000000000080200000000000000001000000000000c000100000000000000040000200000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000004004002000000000000000000000000000000000020000000000000000000000000800000000000040000000004000000080000000000000000000000000000000100000008200000040000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d5", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x1252", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x7f166dd54e16fcd0e302579768e0bb090b06f4e35cba5b48b0b5c42e367c0832", + "blockHash": "0x108535b032c23c831ea3f0e5e60b628b1653a8d4ff2a04f84ea0c28a5f7a334c", "transactions": [ - "0xf865820178088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa02a73665ddc16b8e231ef04b5f0ad8afa56248db6f43222848032c72e97a807b8a00a17dda1a1d0ba616354fda9e86c836bcb002c7e54153be4cc95776446c6b2a5" + "0xf87a8201ac0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa089e20aa467ccbe356f76641d9d5cd4fed171b7c95fa49a16980f2fe2a009ea12a047599499ea6eaf56f04c07564a72c486750251dcebc77a37ae34c02b326b886c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x551de1e4cafd706535d77625558f8d3898173273b4353143e5e1c7e859848d6b" + "0x5cd2ace5b0d5e6867c6d71e22516a625f6c5ab69e7067998cb789a2867c96b8e", + [] ] }, { "jsonrpc": "2.0", "id": "np470", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x7f166dd54e16fcd0e302579768e0bb090b06f4e35cba5b48b0b5c42e367c0832", + "parentHash": "0x108535b032c23c831ea3f0e5e60b628b1653a8d4ff2a04f84ea0c28a5f7a334c", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xcbeab9491879fdd48e387106f31e983546cff3f4795ff5190722d2ac1f3792b6", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0xdc68060e9a8798d536f700d4e95e4a7d65072e218d15704879d6ae2697129ae1", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x125c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xeedbf487ab11603d1a8e08d672886d16cd318bc421a358d199df281a473ac7b0", + "blockHash": "0xc57d09bf4689a42694a8b98bb6ef2cb60c0af0446b6dbd1f55fb9d19743d0b6f", "transactions": [ - "0xf8688201790882520894878dedd9474cfa24d91bccc8b771e180cf01ac4001808718e5bb3abd109fa0515a62775619f55c366d080a7c397ea42dcfd2fdcce1862ef98dab875077f367a023756d4f3bd644dde1c25f8cde45fbea557dacf0492bbecb409f6b2cdacbb9b8" + "0xf8658201ad088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0402b2c34f4929951c4ac6235d801ea3ac81b76f9fcd89a7ff457d5e7623d7940a031a80cf58f13a978fd87ef8f856a4d194ee9ff56144c8c1070b5f75771c04314" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x137efe559a31d9c5468259102cd8634bba72b0d7a0c7d5bcfc449c5f4bdb997a" + "0xc5ff6ef86066abbe0d48a2de1a1a2c4a5e9c695a1be00ada4e3ab8402b15b476", + [] ] }, { "jsonrpc": "2.0", "id": "np471", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xeedbf487ab11603d1a8e08d672886d16cd318bc421a358d199df281a473ac7b0", + "parentHash": "0xc57d09bf4689a42694a8b98bb6ef2cb60c0af0446b6dbd1f55fb9d19743d0b6f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x60452d4fa157207a12986fb9c810855fe19a2492ad046335ec9b4fe41e48de19", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x7f50235f00afa9a49c4ab915fbae8a3967ce90aa5e1b98ef4c2d3549adf74ebe", + "receiptsRoot": "0x52c0a49dc885b9730273efa05b99464faa0b07a33714b5f0c1f2ecff60c052cc", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000004000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d7", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1266", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe2cefda7c9752d4706e180cf9228524bd767f36f6380f0c6255498abedc66ce7", - "transactions": [], - "withdrawals": [ - { - "index": "0x4e", - "validatorIndex": "0x5", - "address": "0xe5ec19296e6d1518a6a38c1dbc7ad024b8a1a248", - "amount": "0x64" - } + "blockHash": "0x62ec7b9a65be76bed69c2d1b89c7338fd99f11c52ce57d223d0978ad2623b666", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8201ae0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c575c87bc04e9291a656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0c8bbb420578d2d80897ca392a55fce5e4834f1d641472c0fd6a9698b7a8e786601a05fc12f7471072f1ea6a98b7cd2f0c7f07f0e1cbb78f71c04f4be678636daae25a01bf0a3c0b5161dffb0fe80025e912d42c79d7370819f162f598c312790ea27e2" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xfb0a1b66acf5f6bc2393564580d74637945891687e61535aae345dca0b0f5e78" + "0x1b68873106bbf102095733021e2f7f49c4822f297c0930460d6358864868e09d", + [] ] }, { "jsonrpc": "2.0", "id": "np472", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe2cefda7c9752d4706e180cf9228524bd767f36f6380f0c6255498abedc66ce7", + "parentHash": "0x62ec7b9a65be76bed69c2d1b89c7338fd99f11c52ce57d223d0978ad2623b666", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x0b580cdca4b5a562a85801f2e45bd99e764124b9715915fd4bfc6f6eb483ef96", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xfb7c33ebafcb6cbfa3b0aa70a6cfc12de4fac7274242a2c970b9fdad17f74bb6", + "receiptsRoot": "0x99009295049bbc6668b80a4398a19de7347c72fa2aeeaf7e11906e87c57a06e6", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000001000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000800000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d8", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1270", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x35f103c6c3cfc385bf9f512f7b4d7903e314b60cb715df196cf574391b8506df", + "blockHash": "0x88fc2bd51129c6a76a5fc4d74e5bca399695ea9b272f65febb655c211ffecccf", "transactions": [ - "0xf88382017a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa05c8cad8eec0edc7394b3bace08088ee19b7eacb754b0a5695fc52a0cd17c19f6a0033d27e9eeb87fa5ae4868a14d0b66d941f0ffa3a3781e60cbb751bab7b507da" + "0x01f8d3870c72dd9d5e883e8201af08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cbf2de05a5f3c3298656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0ca27d6fc8e6016df20a295f26b57b2f6ac7a8cec98224571f416ea88c0ee7b9701a0e6226076cfd8bf43fca38277ffd730aa478ace3525224344c3624d3dfb198151a05a4909aa856a16e38a9daca59a24444b99977e4a10aa825abba4890817466af9" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x96eea2615f9111ee8386319943898f15c50c0120b8f3263fab029123c5fff80c" + "0xc55e7bb8bdeeaaae3b84adac51bddd9ba7a8c23b66e1a73325fef138edbe1fcc", + [] ] }, { "jsonrpc": "2.0", "id": "np473", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x35f103c6c3cfc385bf9f512f7b4d7903e314b60cb715df196cf574391b8506df", + "parentHash": "0x88fc2bd51129c6a76a5fc4d74e5bca399695ea9b272f65febb655c211ffecccf", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd08b438590148463c602be8f8899fd6c2cb42972fe2df0e71cb42ebefea3f404", - "receiptsRoot": "0x307ca5ba4dfd34e9f362cea8e1f54ff58f9318a35cf7e1ae24823d41572d7742", - "logsBloom": "0x00000000000000000000000000000000800000000000000000008000000000000000000000040000000000000000100000000000000000000000000000000001000000000000000000000400000000000000000000000000300000000001000000002040000000000000008000000000000000000000000000000000000100000010000000000000000401000000000000000000000000000000000000000080000000000058400000000400000800000000000000000000000000000000000001000000000000000000000000004000000000000100100000000000000000000000000000000200400000000000100000000000002000040000000000100000", + "stateRoot": "0x8d7f1216133c42f768e27b8aea317b208bc85bd0dd7df779a73f848f4004aa67", + "receiptsRoot": "0x3790f8072f001910a81933cec43d8df45f92389bbec3f61d73660404da6590cd", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000400000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1d9", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x127a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x1f50e2662ba03c36242e9717f767077fd0d1659ed1a5e2e5024bf1a9de6303f1", + "blockHash": "0x4a6fe7d7a0b3433c8c0017a34efcd408751e24ee224d865746e43ee5dbc6b72f", "transactions": [ - "0xf87a82017b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa06cfb2ecb740895c1bdd352c502898651d83d35cb17ec4a0b30b04fe190a05758a02606cabbaa5b1d57ff9da73837cff8cbd03f242b83880f8cf3ba6f0ee907d538" + "0x03f8fa870c72dd9d5e883e8201b00108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038ca9a00d7fed08a726656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0506c0723b5e537632209d4a824a6073d5eccadb36b9b8717b2ecc9e2d5cacda283020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a05ca17d0e9f7fcc7e49fa76b0028de5cb6788be576198194960ff4672e6a309a9a04df6d7a4e2a05d0d9917c68215bbe868461ffc8d3c3816930cf2a92da2ce7dc2" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x68725bebed18cd052386fd6af9b398438c01356223c5cc15f49093b92b673eff" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xb9b10d869f9b60ca46c5484073a0bb44fe92a031955f3555ed291fe0ffd8328a", + [] ] }, { "jsonrpc": "2.0", "id": "np474", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x1f50e2662ba03c36242e9717f767077fd0d1659ed1a5e2e5024bf1a9de6303f1", + "parentHash": "0x4a6fe7d7a0b3433c8c0017a34efcd408751e24ee224d865746e43ee5dbc6b72f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6d86e3351111e6c2d4eafc36553273c03636a22fae54a9e076be2e7cb0cdf9d7", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x2f0f3af3ff59064bcba740401a4b8159ee53e9603974f178483083cf618e4d9e", + "receiptsRoot": "0xbb95ad607d48a3ca500b5faef910c56816051b61786acf3e0ba108ec22807fca", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000008000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1da", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x1284", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa3baf412ffd440d9baceb4d19fc213652de91fee569633fb5f8f77b737dd23f3", + "blockHash": "0xb4d421616ea7a4adc51abdc1eb68ae4517c83a7e65545ad5bd8570fea865bbe4", "transactions": [ - "0xf86582017c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a044380da66c7033fceaa15191e7549bd08fed4c16f96cf1282b2f39bccaad1ff0a00d036ed4649f8300b82a534b03a19b4547784997b61328ba41dd7fa5380de99b" + "0xf8758201b108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cc69de6f1cebe0728656d69748718e5bb3abd10a0a0a49c19f71e8331b897802ff1ac62f66cb63247f31993d6fc3776696f4b17c729a05bba34c418b3147244fa9d4fccd8890d222c7f44190d9017ca38c7f6bced2095" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe2f1e4557ed105cf3bd8bc51ebaa4446f554dcb38c005619bd9f203f4494f5dd" + "0xba29f52ef7aa5b2c71b61919ff7890c9c8d37234ba7fde07a58301b90296e3b2", + [] ] }, { "jsonrpc": "2.0", "id": "np475", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa3baf412ffd440d9baceb4d19fc213652de91fee569633fb5f8f77b737dd23f3", + "parentHash": "0xb4d421616ea7a4adc51abdc1eb68ae4517c83a7e65545ad5bd8570fea865bbe4", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4e2eff0a0a0cfaa9726ffd557089d4a85855fabe4b81334326bd400289f5ed12", + "stateRoot": "0xb88eb1c1760f6a7a8ba8daffb098eb4560ceafe894dd33354ef3026cdb00a7ae", "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1db", - "gasLimit": "0x47e7c40", + "gasLimit": "0x23f3e20", "gasUsed": "0x5208", "timestamp": "0x128e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa63c5dedb28356376c60a58b8b766be086203e9b8d9c016e0863fd4e8cf42a06", + "blockHash": "0x35ca0c82bbc6c2a282e04efd935ad91744a76f738b1a05f543f362089b077549", "transactions": [ - "0x02f86b870c72dd9d5e883e82017d01088252089445dcb3e20af2d8ba583d774404ee8fedcd97672b0180c001a0d3b69c226bf73db84babb6185a83b0dd491467adfc01d279df4c09d5d2d3fba4a0368ddb772caa32963df97961cf8ef0db33e0df5945000f0e39d9a288bd73ee30" + "0x02f86b870c72dd9d5e883e8201b201088252089484e75c28348fb86acea1a93a39426d7d60f4cc460180c001a0af05a64f1aca07aedd20d06dd8e6e3c4ceefcde58d487bcfd54bdfaab1c7d274a00302f428e3a63afcfe2be921c12e6ee23e607e08e7ff6ce15d6af2a407f77686" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x48ef06d84d5ad34fe56ce62e095a34ea4a903bf597a8640868706af7b4de7288" + "0x990f0ab0ebf53ff997b27d831eb969965736cabf07d38003adb40a66d0a758bd", + [] ] }, { "jsonrpc": "2.0", "id": "np476", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa63c5dedb28356376c60a58b8b766be086203e9b8d9c016e0863fd4e8cf42a06", + "parentHash": "0x35ca0c82bbc6c2a282e04efd935ad91744a76f738b1a05f543f362089b077549", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x3de8e5ff6961615b029591cbe9ea51723c809d965421da4f3f8ae26ffe59d69d", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x7665d8970349ea14cbebfdda189a477293e19ca82343a488ff177f4d7440a0d7", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1dc", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x1298", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xbcf5e09e90541f9a8e36eca4ce43a64e1e05e93f4aba193be8e2da860b5ba0bc", - "transactions": [], - "withdrawals": [ - { - "index": "0x4f", - "validatorIndex": "0x5", - "address": "0x2e350f8e7f890a9301f33edbf55f38e67e02d72b", - "amount": "0x64" - } + "blockHash": "0xa2e71dde107bc1f02f8f2303e84580a4061adb821347fd065dea806464488543", + "transactions": [ + "0x01f86a870c72dd9d5e883e8201b308825208942d389075be5be9f2246ad654ce152cf05990b2090180c080a017ce16ee9af5b82c7f29ab98a1bac8aa25420afd16954fb36221582db90ab964a0367033c2da81dabfaddc542ffea3d7e7acf0e75567de6ae4a6170985887bfe82" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x5c57714b2a85d0d9331ce1ee539a231b33406ec19adcf1d8f4c88ab8c1f4fbae" + "0xbda84af9ce3c88c3243669481454971f19d18b777e3a15ab7d87a7559d77ed43", + [] ] }, { "jsonrpc": "2.0", "id": "np477", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xbcf5e09e90541f9a8e36eca4ce43a64e1e05e93f4aba193be8e2da860b5ba0bc", + "parentHash": "0xa2e71dde107bc1f02f8f2303e84580a4061adb821347fd065dea806464488543", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x6eb0d2ff3e3dd2cdaad61b121b06afcf7863f34152ecbdf8b8773604630a56b3", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xc79190bbbaa9d1892a4030dfad5eba2b9e0475d43bca555735ed542fda15f2cd", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1dd", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x12a2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd5c167589a4663ae0585e5fff8fe256f35baaa26843df17dedcf6040709d6257", + "blockHash": "0x8c2efd84e25c29636ce86228e1fa39045936581562d1d80d1273951d3a7e5b5b", "transactions": [ - "0xf88382017e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a0939d9f6f260f24b45073aeabe00660f617f1dbfcf522cd6c90ef189dfc9dbfa0a02dfd90c6f1a6822039b8fbd5bff435e939882da970ed1b58a4639eddcb79b23b" + "0xf8688201b4088252089483c7e323d189f18725ac510004fdc2941f8c4a7801808718e5bb3abd109fa0d1a8bb93f8b00fd581da6c59f4b2fe8164085b721ceea7768a8ffe0622ebc0d9a04085917721c3989a38169b02489a0a47161f7197e1254c9795a85e505272e6f4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x204299e7aa8dfe5328a0b863b20b6b4cea53a469d6dc8d4b31c7873848a93f33" + "0x2c5d55a9ee442f1a84215cfcc70e2fe9ca0504b238c4b121587b015a43a8feed", + [] ] }, { "jsonrpc": "2.0", "id": "np478", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd5c167589a4663ae0585e5fff8fe256f35baaa26843df17dedcf6040709d6257", + "parentHash": "0x8c2efd84e25c29636ce86228e1fa39045936581562d1d80d1273951d3a7e5b5b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xfadd61dbce8d90cae8144c1b2297209079517cb13f3a4e60a6c8f2ea7b4d3770", - "receiptsRoot": "0x3ec27c047700a74288e3ee48062fed9fbba71b1704febedea9f4e9e3a92faabf", - "logsBloom": "0x00100000000000000000000040004000000000000800008080000000000000100000000000000001000000000000000000000000000004000008000008200000002000004000000400000000000000000000000008000000000000000000004000000000000000000000000040000000800004000000000000400000000000000000001000000000000000000410010000000000000000000400000000020000000000000000000100000000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010080000000000000000100000000000800000000000000000000000000000000000000", + "stateRoot": "0x67e66504545bc74878b8ab06179caf460f30c6d642352ee54b67ec5d2602eed8", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1de", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x12ac", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xb061affdd716a0d4c5d081a1c3659d0201dce5c698ae942440565ca789e55b00", - "transactions": [ - "0xf87a82017f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0dffee1543462b1d024b5d54728f2e3284d90d8fd24b94fd96bd027b4ca51e768a02ed5ddd2050f1b7bcbc123e31fb0536fbf1661a8f7541c7a10729e8a505cc080" + "blockHash": "0xae195bb8f9a28f440a0a10bbf872db2c50aae4f08d49089e3b8783187b8b2d5b", + "transactions": [], + "withdrawals": [ + { + "index": "0x2a", + "validatorIndex": "0x5", + "address": "0x4340ee1b812acb40a1eb561c019c327b243b92df", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb74eea6df3ce54ee9f069bebb188f4023673f8230081811ab78ce1c9719879e5" + "0x02e3afb0a7cbd95fb5926b8e9ca36f742f6a9981ed37f1a6dec56be6bf1081bc", + [] ] }, { "jsonrpc": "2.0", "id": "np479", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xb061affdd716a0d4c5d081a1c3659d0201dce5c698ae942440565ca789e55b00", + "parentHash": "0xae195bb8f9a28f440a0a10bbf872db2c50aae4f08d49089e3b8783187b8b2d5b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x931dde8f1566d5b88162261e5f8c8fede3f14bfab1c11934aae8f2a38aca7b36", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x66547ac00f48e5f20225bde1cbeb6e6f863f04ab15824f641aa9e9ec9c072573", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1df", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x12b6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xd8fd694b37ff2f40373350baa6cbf326e675330a7d070dedf57065b72304aece", + "blockHash": "0xd74fba51d365cdfe355295a9a9cb7470ab1ddb53070cc23dc84706d30a1c9d65", "transactions": [ - "0xf865820180088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0c2e07d6867be2220a74a18404d2b9b9adb2f6b1764907aaec954f46e0b9fd18aa01504fbbb49a910d6469e64741d99ea5031c14d4721e488998ef2f594022f34e2" + "0xf8838201b5088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0f4bde21ce8013a82ddd78f70733543867415604c7f83e83e0d9983d1c2042f09a02fa838ccec26ff6ed33a6a253318f6b36fde84386ccff6828731b20a873f8947" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xaf5624a3927117b6f1055893330bdf07a64e96041241d3731b9315b5cd6d14d7" + "0xead6fe3098cd7db5dbe406cbf0977458fe24bdba875ac5964f42607c7756ece3", + [] ] }, { "jsonrpc": "2.0", "id": "np480", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xd8fd694b37ff2f40373350baa6cbf326e675330a7d070dedf57065b72304aece", + "parentHash": "0xd74fba51d365cdfe355295a9a9cb7470ab1ddb53070cc23dc84706d30a1c9d65", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x452e515470ad9f96543d5a469c85e77c4f675f70a56662537491b01528898b99", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x51bfce1b3b28f09cfa61606b2238f6b463ed521abd10bc0dec419b0b9dcbb452", + "receiptsRoot": "0xf45df5f4db771d6e3e81e5adb7565f1c865fad3fd735887f7774795b5edac729", + "logsBloom": "0x00000000000000000000008000000400020000000000000000000000000000000000000400000000000000000200400000000000004000000000000000000000000000000000000000000000400000000400000000000000000000000000000001002000000000000000000020000000000002000000000000000000000000010004000000000000000000000000000800000000000000000002000000000000000004000000000000001040000000006000000000000000105000000000004800000000000000008000000000000002000001000000000000000000000200000000000000000000000000000001000000000000000000000000000080000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e0", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x12c0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xee3a60bb251ec04e27e020f297aa6f159dad08673e76b280e67114583478aec9", + "blockHash": "0x586bfb94de868a094829593278f0059423d4b3a4fa381118368e866ac9ad174d", "transactions": [ - "0xf868820181088252089450996999ff63a9a1a07da880af8f8c745a7fe72c01808718e5bb3abd109fa0f06ad492cdd04b44f321abe9cb98e5977f03909173e4b6361f50d44c080f9d6aa07fdc23c04fab8e0a576e6896b13a661b2dcb256cf8ca42fa21f0f370097a53a4" + "0xf87a8201b60883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0921567dd55a14824f6f5143836996b8922c81586b17d75347e0bc8a2b7a801bca0131f215ee5fc6ebd61c03573fbe0aca770913b85f5dfaee4a24eb6338dcedc97" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc657b0e79c166b6fdb87c67c7fe2b085f52d12c6843b7d6090e8f230d8306cda" + "0xf10709ee045c777c61651e6ccf2b40b539f12fdb42642af7eaeb020ed05b1a15", + [] ] }, { "jsonrpc": "2.0", "id": "np481", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xee3a60bb251ec04e27e020f297aa6f159dad08673e76b280e67114583478aec9", + "parentHash": "0x586bfb94de868a094829593278f0059423d4b3a4fa381118368e866ac9ad174d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa424a562451b0728dc1451b83451fb65f9cad240a6e12ae45314a3c0fc49c4bd", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0xde2f8aa7fcd1b76f0f530a100c0a12756c25d5690ab1575e547bbbee2cb8f02f", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x12ca", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe261b4fbd07d32f5f19564c572258acbe4be1a6b2ea03a57ccbb94e254f37cd5", - "transactions": [], - "withdrawals": [ - { - "index": "0x50", - "validatorIndex": "0x5", - "address": "0xc57aa6a4279377063b17c554d3e33a3490e67a9a", - "amount": "0x64" - } + "blockHash": "0xed9fa0da61fcefb49df7807a0e827069520dd2e1b7823c23b6c8316f261a1526", + "transactions": [ + "0xf8658201b7088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0aecf3049dc7efad3353bc715162e1b9dde150cdf5e73bedf97d46143b653b1caa059150a8228653539febb5d7fc110bc90267c4daa458447ee2a6cd74d6cf84abf" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa0e08ceff3f3c426ab2c30881eff2c2fc1edf04b28e1fb38e622648224ffbc6b" + "0xd60510beb7cc6faff2dbdf5571982f0fe16806f7099f5b96be88b34c884ad75d", + [] ] }, { "jsonrpc": "2.0", "id": "np482", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe261b4fbd07d32f5f19564c572258acbe4be1a6b2ea03a57ccbb94e254f37cd5", + "parentHash": "0xed9fa0da61fcefb49df7807a0e827069520dd2e1b7823c23b6c8316f261a1526", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x5a1ad989a90bb48e30208fafcd5131d4dec171928eb27a8ab446df6086df0f94", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x15c9e6b89f4e66587fd549b5f8a4b383585a915cba6660d8b06fdfbbb52d69db", + "receiptsRoot": "0xce3f0a477c2a7c5cab029ccb48c1898c02bd2489da74880f776886d5cfe1ec85", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000008000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e2", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x12d4", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe8f039d9e217e95c5622ac64609dcaaa54abbf24376fe6c65a29d2b50060cff1", + "blockHash": "0x2d4f68ab5cb1b7d5942ed325911da4de560c281bc4165f12e79b40896faf9240", "transactions": [ - "0xf88382018208830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd10a0a085873eb64b12c743e5652beb56056bd656368a87247a72b159667d4755d7a714a0134397c5062d25029e41def2275efe8c56e466e3a1547d3525533e29641d203f" + "0x02f8d4870c72dd9d5e883e8201b80108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c03aca25852d251d4656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a03a970a6d07c991261dcb566f26d21a76c578d05d1565c47dbc1fc071934c8c4380a06cc1446084f31de8ff2d02d5bdde83a5e6590f378258dcc4c9c0f8333a6ee1eba0421801793f6f0a0741d1eb34af7fdfbeab593a6b79da2fb321759296c32dab96" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc9792da588df98731dfcbf54a6264082e791540265acc2b3ccca5cbd5c0c16de" + "0x52d158762abaf754f45eedfacbdfe8d5d4cea5ecbca4315e9c42c14e22021a10", + [] ] }, { "jsonrpc": "2.0", "id": "np483", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe8f039d9e217e95c5622ac64609dcaaa54abbf24376fe6c65a29d2b50060cff1", + "parentHash": "0x2d4f68ab5cb1b7d5942ed325911da4de560c281bc4165f12e79b40896faf9240", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x54928b5673094b4ce9833ecf8c1490381f0317ac2e9d51f47673e386b82ae93d", - "receiptsRoot": "0xeda5fd4b20fab5a0732205bfe235b5b212cfa5eb525752ae8b9bb0ca224262ec", - "logsBloom": "0x04000000000420002000000000000000020000000000000000000000000000000000000000000000000000100000000040000102000000000000000080000000008000000000000000000000900000000000000000000000040000000000000000000000000000000000100000100000000000001000010000000000000000010000000000000001000040000000000000000000000000000100000000000000000000000020010000000008000000000002000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000080000000400000000000010000000000000000000000000000000002020000", + "stateRoot": "0x7418feb7a3b18f559a82312bdf476251e2015a73489fc0a24c054f2198e6e4e2", + "receiptsRoot": "0xb962be4ba02b6d4a9f438029040b74e9fef16c46e3afe1c644f163387ca2d7ae", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000100000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000200000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e3", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x12de", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x4b31828b7c27c371fdbc62a7b0b6807d1050d15ad53736f73c4063b391aa8b91", + "blockHash": "0x173ba1064b822d7fd886f79df09291855941c7e187348cb1be74b4f3853ac46a", "transactions": [ - "0xf87a8201830883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a05c87beb281558e43744b39a1d0b62e75dfb5ea245fd2d66c657ff053fa5c45e1a077a1c629133272d7fef83436c8f67f327fc77bedea95009b3d569a5f03485b50" + "0x01f8d3870c72dd9d5e883e8201b908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ccd7535d68ec8cda3656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0d1a0570d06c0cc4198b4475cb892ec41ca3239ff670666bcd97faeb62c1db6bb80a034ff1d0664e9a113b7d67aaf8dac7887dc3cd46cda5b46f9be63942bb7ec7617a0762f090dd6f3994d24e026bbbf0309b9d1dad5a365d1ced9f43aa69942a5838c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc74f4bb0f324f42c06e7aeacb9446cd5ea500c3b014d5888d467610eafb69297" + "0x542256a140e92ed9eb4280c21acc962f287cb81fdb913adad4ca43b89d3a7920", + [] ] }, { "jsonrpc": "2.0", "id": "np484", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x4b31828b7c27c371fdbc62a7b0b6807d1050d15ad53736f73c4063b391aa8b91", + "parentHash": "0x173ba1064b822d7fd886f79df09291855941c7e187348cb1be74b4f3853ac46a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf92302c8ac6987ab39ddc9a7413f552337da61d611a086900a5e47b9b3c1422f", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x6ecb1e3489f8078a29b87e0eb6d2fd6e945896714d99eddee74d85a4851c1cd9", + "receiptsRoot": "0x58311e701f652cdacdebe59e7b45f8b1b0ebff606fe210236709f712d6f9063d", + "logsBloom": "0x00000000000000000200000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca90", "timestamp": "0x12e8", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x56c5997ee01e4a2bad320a6af0120843f01908c525450d04458eca33799e7958", + "blockHash": "0x5fe23349b74796ea88667c124d31b7f83d1ea6c55888612d0546fcd8781469f0", "transactions": [ - "0xf865820184088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0ef66b5859d5e5be7e02ce0b7d103b957ceba18d69047aec94746e87945b7230ba071c5785cce709e44dd94db5684b4e552e343a44862fba233c49a3fa99b0d63f9" + "0x03f8fa870c72dd9d5e883e8201ba0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c1877e1001127f07b656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a027edda711baed4a613c44d8ac8678531c9938eea106e7c5649e438f3d24b8fe383020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a067af6f0192162151e653097d20f7f403d55f09c1017f56c8b99b6b8d54cb57a7a0321c7a4916061de4a010df3a26b3e925d5780f2ae481dc180f845beedab7fe68" ], "withdrawals": [], - "blobGasUsed": "0x0", + "blobGasUsed": "0x20000", "excessBlobGas": "0x0" }, - [], - "0x1acd960a8e1dc68da5b1db467e80301438300e720a450ab371483252529a409b" + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x79b058ec1c5cbe0920b5952501060f137989ac99cce216800bd06649890c3be1", + [] ] }, { "jsonrpc": "2.0", "id": "np485", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x56c5997ee01e4a2bad320a6af0120843f01908c525450d04458eca33799e7958", + "parentHash": "0x5fe23349b74796ea88667c124d31b7f83d1ea6c55888612d0546fcd8781469f0", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x89822c6bc267d77690ae905ebc8dbe9426f9a83764224d4bc9624104881db28e", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x27390abd199fe04144543d27d967696f694d14f167df82a55dd83bc3c40878d9", + "receiptsRoot": "0x7739ee9e2c025b802aca02f952dd550a19f4b1f2f88320592f42157b192eb663", + "logsBloom": "0x00000100000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000400000000000000000000000009000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e5", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", "timestamp": "0x12f2", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xa5d5571bc983cefbe29844e1914f948256b70833f1e99d8dcb0282e1f9dbbfef", + "blockHash": "0x44b4ee4af4ea93cdc1f6d6a7600b78b1f18918e5adb36a95773fb69f0c95960b", "transactions": [ - "0x02f86b870c72dd9d5e883e820185010882520894913f841dfc8703ae76a4e1b8b84cd67aab15f17a0180c080a0d4b8d15fc05f29b58f0459b336dc48b142e8d14572edad06e346aa7728491ce8a064c8078691ba1c4bb110f6dff74e26d3c0df2505940558746a1c617091ddc61a" + "0xf8758201bb08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cba2beb3c8594f746656d69748718e5bb3abd10a0a0e661c2c68de66c165b67b63e4d3f2f38ea26a81665d63e8f74e6d11e81d3fc85a001ddd2c77206d9343887e41e90004a1cd663a3925c152df47d96a822781c744a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x6cef279ba63cbac953676e889e4fe1b040994f044078196a6ec4e6d868b79aa1" + "0xf4c5320c831d84242a9194e38951a279654456e3eb90f3712c14fdac4d326723", + [] ] }, { "jsonrpc": "2.0", "id": "np486", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xa5d5571bc983cefbe29844e1914f948256b70833f1e99d8dcb0282e1f9dbbfef", + "parentHash": "0x44b4ee4af4ea93cdc1f6d6a7600b78b1f18918e5adb36a95773fb69f0c95960b", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xe88ebfc2a7990356801a2e5a308418fa8fe4445548fafe8227f4382f64ad8597", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "stateRoot": "0x50d5213b8e73149d638d379da242d321106af3f234c0c1bf2a77431c669537e0", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e6", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x12fc", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x686566b93e0b0c5d08d2de9e0547a5639e6878d15c59baab066c48365ce7e350", - "transactions": [], - "withdrawals": [ - { - "index": "0x51", - "validatorIndex": "0x5", - "address": "0x311df588ca5f412f970891e4cc3ac23648968ca2", - "amount": "0x64" - } + "blockHash": "0x6e1a5f320d6c603aebe7b47c6f98bab7e6ca3f63648853117f90681ef82be343", + "transactions": [ + "0x02f86b870c72dd9d5e883e8201bc0108825208942d389075be5be9f2246ad654ce152cf05990b2090180c080a04c6e4253cf03fcfd3b8c654c9d4c722cbf7599f527ddb8c29c4cb700928ab211a033779b52f70e001e25329224c6a3faee756bd10e3534b7ab6ad99a5652623c5f" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x60eb986cb497a0642b684852f009a1da143adb3128764b772daf51f6efaae90a" + "0xc00307f2fde3105322eab259007d6fdfda80cef1b9472584e82bb321d1827305", + [] ] }, { "jsonrpc": "2.0", "id": "np487", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x686566b93e0b0c5d08d2de9e0547a5639e6878d15c59baab066c48365ce7e350", + "parentHash": "0x6e1a5f320d6c603aebe7b47c6f98bab7e6ca3f63648853117f90681ef82be343", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xb852ee14e385a383f894d49c4dabd2d0704216e924283102b9b281ae5306a291", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x17c5048dbe3b6539839d450f5c43586cf6048ff932a9699d67fb9f23551bc833", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e7", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x1306", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xc005c46cb9de70c37edd02e3ae623bb8b6e4160674fafbbd34a802f85d2725b6", + "blockHash": "0x0e0736ecbc21d8283a34e648718dfde99dcf213778a19cbb385a528281994d02", "transactions": [ - "0xf88382018608830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0ddc578e5c190613c2dc0ce34585e98c512fc9b4ae877b0b3f9b85e01a36b90b5a044c7152f99374ce61bb3b9ebb9ec9e5c4f623faa9b8972cf80f891fd45be9bbf" + "0x01f86a870c72dd9d5e883e8201bd08825208947435ed30a8b4aeb0877cef0c6e8cffe834eb865f0180c001a0b32fa00b190ac2b9eb4b3268aa9141cb78a8916b05f6c0a40f206ee664c8a719a012c6432eb6a03755afae2c6de4391acd53acb4d1883a8ace297e86ed36bfdedb" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xc50024557485d98123c9d0e728db4fc392091f366e1639e752dd677901681acc" + "0xf64129691e90ca381d267b0e80bcd562d68049c21d623c8ac7284edf560bf253", + [] ] }, { "jsonrpc": "2.0", "id": "np488", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xc005c46cb9de70c37edd02e3ae623bb8b6e4160674fafbbd34a802f85d2725b6", + "parentHash": "0x0e0736ecbc21d8283a34e648718dfde99dcf213778a19cbb385a528281994d02", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa3f2cdabc9ec81196b1930e223115ab39e3aa82a3267c2eab58dfcd4ac28879d", - "receiptsRoot": "0xa98965822a3cbebe261b9e53038a23e30a7a9ea1878b91ee19c2b9ae55907433", - "logsBloom": "0x0000000000000000000000000000000c000000000000000000000000000000000000000000002000000000800000000008000000000000000000000000000000000000000000200200000000002004000000000000000000000000000000000000000000000000000000020000040000000000080000000000004000000000000000000000000000000000000000100000000200000000000000200000000800040000000000000000000000441000000000000000000000000000000000004020400000000000000000000800000000000000002000000000040000000000000000000000000000000000000000000100000000000000400100000200000010", + "stateRoot": "0xc219431ca24a3d75c7de17bafe6d3d0929836c9e3671768301f2438d78d91ec7", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e8", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", "timestamp": "0x1310", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xabe558d433bc22296ae2fc7412d05672f2ec66c7940ef6a76f9bb22aa09b219d", + "blockHash": "0x8d71815cf7e21c74cf91c9f2ff59fd941cbcf127084f929254498163c494f183", "transactions": [ - "0xf87a8201870883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a09d84bd49c461dee138a01ba1116ba5a0866c4d398db99b3b6e8ec5119ddaf31da046d87610c10b340e616174c09a5addfb8ef7f1b64dcadf4edd14af37ec74a55c" + "0xf8688201be088252089484e75c28348fb86acea1a93a39426d7d60f4cc4601808718e5bb3abd10a0a0d5da0e78527ea2676cda16dbf0ca9fb8853ef3d655e4ec8b9b6767b495bb25e1a0631003e734b6121487daf284ca1039416efe86e21334eaffb8ff56c86afceeba" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xb860632e22f3e4feb0fdf969b4241442eae0ccf08f345a1cc4bb62076a92d93f" + "0x730279e1ea668c639d5c41d5d4cbb1b7f474dc359bc977017be59d5c4da6c2e4", + [] ] }, { "jsonrpc": "2.0", "id": "np489", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xabe558d433bc22296ae2fc7412d05672f2ec66c7940ef6a76f9bb22aa09b219d", + "parentHash": "0x8d71815cf7e21c74cf91c9f2ff59fd941cbcf127084f929254498163c494f183", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x39ebb75595ae4b664d792fdf4b702a8a4cec3fb1fa62debd297075d3543e05af", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "stateRoot": "0x9e33a5b74ae3ae525bea4008b6dcf596742e4a6bfb70da6dac944a5bcd8fad08", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1e9", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", "timestamp": "0x131a", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5591e9a74a56e9765790e3088a82c8e6e39ef0d75071afe13fa51c9b130413db", - "transactions": [ - "0xf865820188088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a06ffd1874ec840566ae82b8a15038ee44b5241705bdb421b459c17100d1300d1aa0121f314d9f41658c831f52b82d4a13b333413d68809cea260e790de9283a434b" + "blockHash": "0xbff2f568d9a26daaaedd8e26e46d3eecb122cfb8c091bc194d6326c88d058f1d", + "transactions": [], + "withdrawals": [ + { + "index": "0x2b", + "validatorIndex": "0x5", + "address": "0x83c7e323d189f18725ac510004fdc2941f8c4a78", + "amount": "0x64" + } ], - "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x21085bf2d264529bd68f206abc87ac741a2b796919eeee6292ed043e36d23edb" + "0x09d9cafda4e28b50bba8823b4bf20a39646b273df60467b5cba6bcd04a9e417d", + [] ] }, { "jsonrpc": "2.0", "id": "np490", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5591e9a74a56e9765790e3088a82c8e6e39ef0d75071afe13fa51c9b130413db", + "parentHash": "0xbff2f568d9a26daaaedd8e26e46d3eecb122cfb8c091bc194d6326c88d058f1d", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xa3d5920be7fa102b7b35c191800c65c8b8806bd7c8c04cdc0342a3d28aeafa3c", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "stateRoot": "0x877e7f78c65e7e3685b7683704a0eb62a1c55b982bcc836455d2d3a9c12eeefd", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ea", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", "timestamp": "0x1324", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x38cee342db6a91998dd73c4d25bca6d8730977aaa19f0a092d47c00ff10c4edb", + "blockHash": "0x509d2a2521abc4c30ba8b397d9e86976e6134a844bea08ebeac4a4b009bfdd32", "transactions": [ - "0xf8688201890882520894b47f70b774d780c3ec5ac411f2f9198293b9df7a01808718e5bb3abd10a0a0d33c0cd7f521603ea8deaa363ab591627f5af193759f0aeb8cd9fe4f22a4dd5ca0667bb0ee041403cba2e562882bb9afc43bd560af3c95136c7bf4f1e361355316" + "0xf8838201bf088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa0ab9145a13f1f6ee6429e1b007c4fd516dad28c5c8cde6f1d12abc7c715e4ef6ea0495d16fc67a9781f1de9758ea4bd665a7234f9ea5708dc90916ee927d85c2ee5" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x80052afb1f39f11c67be59aef7fe6551a74f6b7d155a73e3d91b3a18392120a7" + "0xb0424ee936aae94e0394ede6947b15427dc1664a14d82a17969162ec6e838ec3", + [] ] }, { "jsonrpc": "2.0", "id": "np491", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x38cee342db6a91998dd73c4d25bca6d8730977aaa19f0a092d47c00ff10c4edb", + "parentHash": "0x509d2a2521abc4c30ba8b397d9e86976e6134a844bea08ebeac4a4b009bfdd32", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xf1034fb8a7585c73d7df19cae6b0581d6836278bd57d05fa19f18c6501eace46", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xb3e38a9114049cd2a23f3ea7a946ee0dc2d5436e82e7407809abb4ee54727456", + "receiptsRoot": "0xdd42cfcddceb6322a92d9a307599a410f09f67d7a46c17fbd43a5ba7d862f8f4", + "logsBloom": "0x00000000000000000000000000000000001000000000000400000000000000040800400000000000000000000000010000000100080000004000000100000000000000000000000000000000000024000000000400000000000000000000000200000108000000080000000000000000040000000000000000000000000000000000000000000000000000000000000000000000001000000200200000000000000000000000000020008000000000000000000000000000000000000080000000400000000000000400000000040020000000002000000000000000000000000000000000000000000000006000000000000000000000000000000000020000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1eb", - "gasLimit": "0x47e7c40", - "gasUsed": "0x0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", "timestamp": "0x132e", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x669efe3cceb25caf14b93a424eaa152070686561e028d50b8adbf87d45f4d18f", - "transactions": [], - "withdrawals": [ - { - "index": "0x52", - "validatorIndex": "0x5", - "address": "0x3f31becc97226d3c17bf574dd86f39735fe0f0c1", - "amount": "0x64" - } + "blockHash": "0xc73fe82ce95274c1aca827b1e2bcbdc56663f172a9a808e02fb03b594afd5494", + "transactions": [ + "0xf87a8201c00883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa06de4d59a4c5a3ad0afbe74ddf01646de5300055e3fb8c58de0c3aa607a407946a0469a4b7411a764a83be3c34664f12faf29c4c1808825f1b440aa502db5f3f402" ], + "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xa3b0793132ed37459f24d6376ecfa8827c4b1d42afcd0a8c60f9066f230d7675" + "0xbbe5b3daa5def4caff6e3e2ccaa0d77694cb0886d68b6844888838d720c8a1ad", + [] ] }, { "jsonrpc": "2.0", "id": "np492", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x669efe3cceb25caf14b93a424eaa152070686561e028d50b8adbf87d45f4d18f", + "parentHash": "0xc73fe82ce95274c1aca827b1e2bcbdc56663f172a9a808e02fb03b594afd5494", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9b830dad01831671e183f743996cc400135e0b324f1270468af08b37e83b8b17", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0xd2d759f0c7df5bee393757eb8d19a2f338e5fc379c375645a6c72088364b5d09", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ec", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", "timestamp": "0x1338", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x92932a0312ff65482174399e2cd29656c7051fa3747e47a906b54207c4fd1a92", + "blockHash": "0x8e940db2d4e9688d0eac137008f26832b205e32c67877475cc0348c38be128ab", "transactions": [ - "0xf88382018a08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0e94663b4e19d1c2f86adde879e4cb965b7eda513a542ba26136b7010aae11681a03e7d58f3bef3bba01e70b75c70bc0d070f95bba8994c9f12705f2a5281160f47" + "0xf8658201c1088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0a815113aa8040972264e983cb3903de2084ffe5b6557ef6a2717111dca7693dea07fb1c0149302c30af0a272c7b2463730984775bad879350692b7f60aab3f24d4" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xe69d353f4bc38681b4be8cd5bbce5eb4e819399688b0b6225b95384b08dcc8b0" + "0x29cf1633458442d2d60c8597fd7e8e3032c77f715695390f6c6c79a56a1f6c41", + [] ] }, { "jsonrpc": "2.0", "id": "np493", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x92932a0312ff65482174399e2cd29656c7051fa3747e47a906b54207c4fd1a92", + "parentHash": "0x8e940db2d4e9688d0eac137008f26832b205e32c67877475cc0348c38be128ab", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xc616c572be45daa3d7eae2481876e5d8f753631f976d4da110a6ad29bdfad30f", - "receiptsRoot": "0x78902fbbd0a8ab65f6b731f1145a5f6f467f9fdae375707236cff65e050bbfeb", - "logsBloom": "0x00000000002000000000080000000000800000000000000000800000000100000000000000000000000000000000000000000000000004000000000010000000000040000000000010000000000400000000000000000000000000080000000000020000000000000000000000000000000000000000000010000000000000000000000000008000000000000000000000000000000000400000000001000040000000000000000000000000000000000000000040000000040000000880000000008020000000800000008000000000000040020180000000000000000000400800000000000000000000000080000200000000000000000000000000000000", + "stateRoot": "0xaee5de9b102d4af57cb0ab48df984fa280d8189a0808f7f4c595050b40b221af", + "receiptsRoot": "0xa2b618c505ef3395f557921dfeac32a668e58693fa54e4c0b0412235a373fe65", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000008800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002010000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ed", - "gasLimit": "0x47e7c40", - "gasUsed": "0xfc65", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1342", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x52b55abe0e252ea389cc21f01782fd70ca4e4ef6031883f6b79c097de33964d4", + "blockHash": "0xc4686ab32da32550e9cc95adc86e731d96b3498f28c3454972b8647922a8c775", "transactions": [ - "0xf87a82018b0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0fbd0141af6d135ce0949d33ba4beba57e9b7f388c37e9725b762cb61e8db17dea05ecd43ff335efc34b06551202c4223fc39e1c842d4edfad8e46f19bc7a93f57f" + "0x02f8d4870c72dd9d5e883e8201c20108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cbdbdb63ec06dbc4d656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a051524a498a88953303410a83d67c2b8c69ddafeb99b570accaaed774fbc8583e01a02d00dcf0c9f72c9480f3a2f32d53f2d1bd9cc9c7e57c939faabf531d74b5d592a022f86ce2737fe4d613c5c85cec6dc7bf30499d75a43e8af7f8929ab623bad2b2" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x221e784d42a121cd1d13d111128fcae99330408511609ca8b987cc6eecafefc4" + "0xaf082fe588954fe25630edd8bb48a91725372f8615834cfa45e1994b2fe75b84", + [] ] }, { "jsonrpc": "2.0", "id": "np494", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x52b55abe0e252ea389cc21f01782fd70ca4e4ef6031883f6b79c097de33964d4", + "parentHash": "0xc4686ab32da32550e9cc95adc86e731d96b3498f28c3454972b8647922a8c775", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x7e626fcfe3b1ca7a31dc26a08fbc503c7a85876a64a22a270ec99ef534566c45", - "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xd02c8177f7c4cf3ab2b848531bcca041fc894e2d86df57796d3323527d5b481d", + "receiptsRoot": "0xb59464b3db3775db16d568e667b0b003728a26c5ef1b495b5a851f8701bb1bbc", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ee", - "gasLimit": "0x47e7c40", - "gasUsed": "0x1d36e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x134c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x5370ce9fa467f03411f240030b4a0b9fcbb05c5b97b09356d071ade6548767e8", + "blockHash": "0x2acc9875f08bf7c9185aea7dcce6c1163b303e620de25993fb494a866f831b9a", "transactions": [ - "0xf86582018c088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a05a02d5d03439ebbdf2c3b2d98305dda7adbed1ce5549c474b4b9e4f7200d4beaa016d123a1de79c4a654c1d1ab2169ee672c66922fa036e951c60fec9fe4643ee9" + "0x01f8d3870c72dd9d5e883e8201c308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028caf8e348bf4f0a699656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a6602e59691514abf1ee46e71c1f4c7411eddb76e687f8f4aaa1ebf305b97f6c80a077b4fbc6b2b04c54b28551086048b86633d30baddcac9cfb815f60f60d5f52c6a0307d634630eecf0ea9ed75b079936760730effb7113d0fe8cead79b67c7ce759" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xdcd669ebef3fb5bebc952ce1c87ae4033b13f37d99cf887022428d024f3a3d2e" + "0x1d2385a885bc5bbab703e39a21c87909b765fee7808ceb7d64f6e0e1dcdbeada", + [] ] }, { "jsonrpc": "2.0", "id": "np495", - "method": "engine_newPayloadV3", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x5370ce9fa467f03411f240030b4a0b9fcbb05c5b97b09356d071ade6548767e8", + "parentHash": "0x2acc9875f08bf7c9185aea7dcce6c1163b303e620de25993fb494a866f831b9a", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x9d90c0fd0677204966d6fdbcafcfacc7fe93a465748d2ce8afbc76b6d9b9bbe1", - "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0xa7b6f6132a35d132c8373b83275fdb1899f009f55697d912a487d1e73dac389b", + "receiptsRoot": "0x69272db254a554362866187ba8d083482ba41778b8b26368260a30cd99da7f0f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000080000000040004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", "blockNumber": "0x1ef", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", "timestamp": "0x1356", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x58488c77f4726356a586e999547ffa283a73f17058064f3f56eeb02a5f67b4b4", + "blockHash": "0xe5e2de3cd1a2a8f6551e93be0ab3644c84c9653cae77d63caa4a10f5b805ffd4", "transactions": [ - "0x02f86b870c72dd9d5e883e82018d0108825208946e3d512a9328fa42c7ca1e20064071f88958ed930180c080a0990aa3c805c666109799583317176d55a73d96137ff886be719a36537d577e3da05d1244d8c33e85b49e2061112549e616b166a1860b07f00ff963a0b37c29bcaa" + "0x03f8fa870c72dd9d5e883e8201c40108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cbfc7b909ffb8a701656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0bae4f13d358194452066fc1305964decaafbc9c56a2fd16936d25d9521a57a1983020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a01e19794d92c3e106531229523c5651f09eebad9b1ab8af16b4f574986cddf370a04e514870232ca6580c57baaea9f826b732ccc92bea5f776f60cb6a6667a92f1f" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x9f7e031c508d86e139947f5b167bce022363da48a40dc260d10b7056ac51cf31", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np496", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xe5e2de3cd1a2a8f6551e93be0ab3644c84c9653cae77d63caa4a10f5b805ffd4", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0ce171ab00e064bd363971bdfb9342cd0d45256cd988fa0bd05197d3d027418a", + "receiptsRoot": "0x331c72dc5228abe1d292e038f6ac92d48b45608a0bb99b821a629112eaa757e2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800200000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1f0", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x1360", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x6413cdb135c067bf7c9894bc05cbef70350d5d2bcd089f661257b80a28d71a26", + "transactions": [ + "0xf8758201c508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c6cbb5e7a4b55690b656d69748718e5bb3abd10a0a0693fb616abfdf9147a81ba213e94679ff3efdcbc80075a645b33eef4673cd6f4a0696a52ef0e40d7dc5540b69f994bd6a38449159100cde3fbdba155fc26ac297c" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4dd1eb9319d86a31fd56007317e059808f7a76eead67aecc1f80597344975f46" + "0xae2de0af5de73a96ed6b567a73e6a11b603d6cd010885f5c0311faafa922f2cf", + [] ] }, { "jsonrpc": "2.0", - "id": "np496", - "method": "engine_newPayloadV3", + "id": "np497", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x58488c77f4726356a586e999547ffa283a73f17058064f3f56eeb02a5f67b4b4", + "parentHash": "0x6413cdb135c067bf7c9894bc05cbef70350d5d2bcd089f661257b80a28d71a26", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x32f6d8bc2270e39de3a25c3d8d7b31595eef7d3eb5122eece96edf18a7b8290f", + "stateRoot": "0x7a70c9dfdacb14eddf9099658ab558b18bee5226ac70462bfd133bb44e08244f", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1f1", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x136a", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xe800f779e224dcc43b5c7bb57da2d643e20dbdb53e1cd60e41207b620a040b5c", + "transactions": [ + "0x02f86b870c72dd9d5e883e8201c601088252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c001a0b14191fe5a86ab1c2eefb3e545ed407a50427c4ab05e43b533fa630b54822b00a05269dabe1ed832d6827d152774e95ab4962dac9c030381d89f8dc5419c955fd3" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x25b6a571ef6a73ada1798c7c6f5c6bfafe256c766329fec4f10bf8bad197ef43", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np498", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xe800f779e224dcc43b5c7bb57da2d643e20dbdb53e1cd60e41207b620a040b5c", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd5389d4e7c476363d1aa9bc8c47483bdf71f3993ec983fabb617dd69454ab4d2", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1f2", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1374", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xe3bd2dc0e6af6253299c175f22a860b34d75ee109faa0c7dc437c94c8e35643f", + "transactions": [ + "0x01f86a870c72dd9d5e883e8201c708825208940c2c51a0990aee1d73c1228de1586883415575080180c080a01251136e3ff24d4eddd91f954ca0024980b54ff7f34d9b0254e4af434c121087a047c647dc9ffa9dc78c540c1847bcb598e573d498b6e218ccad749a138bffffa4" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xa13ee26b6abfa659eab111d6d431ab808f24de841d7946e3972c71f886cf3b7e", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np499", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xe3bd2dc0e6af6253299c175f22a860b34d75ee109faa0c7dc437c94c8e35643f", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x96d35284d3c35cc0f1109ee9387ed55f921c875c60d0ebe1086295c55898a214", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1f3", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x137e", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x44924c88d1ebadca339c20badf7e5e22ce7ec673cfcb7305d46487417a852cde", + "transactions": [ + "0xf8688201c808825208945f552da00dfb4d3749d9e62dcee3c918855a86a001808718e5bb3abd109fa06a85e590feffd58fc2903caa04a04bcd5c3f5824b42db665d2190652de42a998a060c02bb53efc5d6c73b2f019d8258cd71c1bed7bf3226ca1b3c6f5e4f19f26f2" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x7472248ce56a1577d4471f3da8cf5cde06f8950286675ca5a1194796a28a4005", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np500", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x44924c88d1ebadca339c20badf7e5e22ce7ec673cfcb7305d46487417a852cde", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x955e191119551f055a9e6f3e11d07af09851acf643d64a5d0c1f129b894a1609", "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x1f0", - "gasLimit": "0x47e7c40", + "blockNumber": "0x1f4", + "gasLimit": "0x23f3e20", "gasUsed": "0x0", - "timestamp": "0x1360", + "timestamp": "0x1388", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xe521dace14e46c9d8491f262d38c1741f6fa385466a68c7ceadd08c1515600d3", + "blockHash": "0x7151d7993c13af657fb9afbcad9340ddb46fac82b873b64baf85f8f5780151df", "transactions": [], "withdrawals": [ { - "index": "0x53", + "index": "0x2c", "validatorIndex": "0x5", - "address": "0x6cc0ab95752bf25ec58c91b1d603c5eb41b8fbd7", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "amount": "0x64" } ], @@ -13142,127 +15819,3171 @@ "excessBlobGas": "0x0" }, [], - "0x5e1834c653d853d146db4ab6d17509579497c5f4c2f9004598bcd83172f07a5f" + "0xb152754c5a5cc6999ca01b88a6d422090559b16c7ead087411458740c57a128a", + [] ] }, { "jsonrpc": "2.0", - "id": "np497", - "method": "engine_newPayloadV3", + "id": "np501", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xe521dace14e46c9d8491f262d38c1741f6fa385466a68c7ceadd08c1515600d3", + "parentHash": "0x7151d7993c13af657fb9afbcad9340ddb46fac82b873b64baf85f8f5780151df", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0x4e1202b318372f0cacbc989e0aa420c4280dcb8ecd7c3bb05c645bf9fb27d54e", - "receiptsRoot": "0x18ff29662320d2c1d830d59b45b908cc2e4b65c1df400d3b8492ba583a1e3342", + "stateRoot": "0x96e8ab6546be093aedbe2325151a1cf208e1bc9e5469883ef677a00cdc310520", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x1f1", - "gasLimit": "0x47e7c40", - "gasUsed": "0x146ec", - "timestamp": "0x136a", + "blockNumber": "0x1f5", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x1392", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x3464afae6c8c9839a124b8dba3d363e646b61c9160a61b1c231c67a6a72daff5", + "blockHash": "0xeb6625cb0981451d810c0172e25819ca3b6fc2035ea04542f3dee1dce7c516df", "transactions": [ - "0xf88382018e08830146ec8080ae43600052600060205260405b604060002060208051600101905281526020016102408110600b57506102006040f38718e5bb3abd109fa0d9866a4e71a4efbccc717617f5c712557608513ce8b49f6e24fc06e0d717b7b6a056d3c051f6dbe09a1c94e23499ba8014f74e123caa3252068ee67e8f25e1e323" + "0xf8838201c9088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa09f242f7711b79cdfb5a72c58154bde5cdb442725057daf94dbae85dc50d69feea022df1168ec1f2265cd4caa1a6e79f68efa4ebf524029e655b27d6e9b58428399" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x9f78a30e124d21168645b9196d752a63166a1cf7bbbb9342d0b8fee3363ca8de" + "0x651093fcc06254ac1de6075cba7da2cd7406b6a90a0f1425a26c7496f2f60dab", + [] ] }, { "jsonrpc": "2.0", - "id": "np498", - "method": "engine_newPayloadV3", + "id": "np502", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x3464afae6c8c9839a124b8dba3d363e646b61c9160a61b1c231c67a6a72daff5", + "parentHash": "0xeb6625cb0981451d810c0172e25819ca3b6fc2035ea04542f3dee1dce7c516df", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xd04a20f359c38d0cb7a31e5e7b002251c15e0242b864964ddbe9642d1c8f7e30", - "receiptsRoot": "0xe40714733f96bc282c17b688a91dfb6d070114fc7bc3f095887afa3567af588c", - "logsBloom": "0x00400000000001400400000000000000020000000000000000000000400000000000000000400000000000000000000000040100000000800000000000000000000000000000010000000000000000080000000000000000008100000000000000000000000000000000000000200000300000008000000000000010002000000000000000008000000000000000000000000000000000000000100000000000000000000000000000000004000000000000100001000000480000000000000000000000000000000000000000000000000000440000000000000000000010000000000100000000000000000000000000000000000000000000000000800000", + "stateRoot": "0xf0bc8cdc892895d0382a37436fbae7a42d95b0b86fc6b6e09d53546a0207dfac", + "receiptsRoot": "0x8f1810576b4069894550fda7f0bd820eb92d3b664107d4cafb0fa4f94dc2c5f6", + "logsBloom": "0x00000000000000000000000000200000000800000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000080000002000000000000080000800000000400000080000000000000000102020000000000040000002000000000000000000400000000000000000000000000000000200000800000040000000000000000000000000000000000000000000200100000000000000000010000000000000000000000000000000000000000400000082000000000020000000000000020000000000000000000000024000000000000002000000000000000000000800001000008000000000000080", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x1f2", - "gasLimit": "0x47e7c40", + "blockNumber": "0x1f6", + "gasLimit": "0x23f3e20", "gasUsed": "0xfc65", - "timestamp": "0x1374", + "timestamp": "0x139c", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0xf7ad3df877f1a7ac6d94087db3f3e01a80264b0909e681bf9c7d21879df0df5d", + "blockHash": "0xefab54ac6e96aa6fc5d3270f7a928f03ab557ce9b7d2ed68f08825ca50c6307f", "transactions": [ - "0xf87a82018f0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa0dd12539d461aa41247581166cecdf2eb60a75ac780929c9e6b982d9625aadc1fa06b813ce4e36c5147759f90672f6e239fab2851a63ac3b998ead89c0ead85589b" + "0xf87a8201ca0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa039c9ec5087989e0ccbd6bcd6d6d98f4088fb0106d55f845c3270d8341d641229a02360f0209d0f71281c3ea6422573e4a818aecaf0d549e29993b48bac4b2df08f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x1f7c1081e4c48cef7d3cb5fd64b05135775f533ae4dabb934ed198c7e97e7dd8" + "0xb93351b11b6a73ecb4818697b1ee7cea2eaf192a56caf8df1454b9bc7510f722", + [] ] }, { "jsonrpc": "2.0", - "id": "np499", - "method": "engine_newPayloadV3", + "id": "np503", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0xf7ad3df877f1a7ac6d94087db3f3e01a80264b0909e681bf9c7d21879df0df5d", + "parentHash": "0xefab54ac6e96aa6fc5d3270f7a928f03ab557ce9b7d2ed68f08825ca50c6307f", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xbd38c27a1fad5fb839aad98a9c6719652d1714351f24d786b23bf23076b31ba6", + "stateRoot": "0x28edc0ed8c0f0ea206e56a325c0d472b6270596e9254797cb248638b7a9fec42", "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x1f3", - "gasLimit": "0x47e7c40", + "blockNumber": "0x1f7", + "gasLimit": "0x23f3e20", "gasUsed": "0x1d36e", - "timestamp": "0x137e", + "timestamp": "0x13a6", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x96a73007443980c5e0985dfbb45279aa496dadea16918ad42c65c0bf8122ec39", + "blockHash": "0xf0591fc75f0711d3d9234011205cb9bd2c40a3477994d943e6d7a12c72e8d613", "transactions": [ - "0xf865820190088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a012969b1c46cb1b69a3fdf15b8bbccc1574572b79b38bf81803c91b0384309545a06d1c09143ad2bfeccbb04d63441058c83b60a5cbfdad87db36421dfcf008cd16" + "0xf8658201cb088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0d1923c8d37e8ccf7655dc86d425eed22c0463724e8fad35e7b08f509ede8e6c8a04f2f8a02f1d8dc629c0cc259e537e28f4522a3116298c1b24c7be64f9131712f" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0x4d40a7ec354a68cf405cc57404d76de768ad71446e8951da553c91b06c7c2d51" + "0x7f4e75a6d4ab8d9dbe0728bda7f7ebf8bdc1942aecc5912f25573fdb9bafe803", + [] ] }, { "jsonrpc": "2.0", - "id": "np500", - "method": "engine_newPayloadV3", + "id": "np504", + "method": "engine_newPayloadV4", "params": [ { - "parentHash": "0x96a73007443980c5e0985dfbb45279aa496dadea16918ad42c65c0bf8122ec39", + "parentHash": "0xf0591fc75f0711d3d9234011205cb9bd2c40a3477994d943e6d7a12c72e8d613", "feeRecipient": "0x0000000000000000000000000000000000000000", - "stateRoot": "0xea4c1f4d9fa8664c22574c5b2f948a78c4b1a753cebc1861e7fb5b1aa21c5a94", - "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", - "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "stateRoot": "0x3d7616976d4d75fc2791c04abab12aac2c78ff3b23f040c0d5dfc1d392d9407b", + "receiptsRoot": "0xea5be4c117d6e881a0a1fec4529a98caab71dd5d707a0876a1621aab324b7505", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000008002000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000009000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", - "blockNumber": "0x1f4", - "gasLimit": "0x47e7c40", - "gasUsed": "0x5208", - "timestamp": "0x1388", + "blockNumber": "0x1f8", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x13b0", "extraData": "0x", "baseFeePerGas": "0x7", - "blockHash": "0x36a166f0dcd160fc5e5c61c9a7c2d7f236d9175bf27f43aaa2150e291f092ef7", + "blockHash": "0xdf54b762c56706ef7861a0725b7fd4f01aaadcac614d3d3f39569cb8e621fd1a", "transactions": [ - "0xf868820191088252089415af6900147a8730b5ce3e1db6333f33f64ebb2c01808718e5bb3abd109fa085b3c275e830c2034a4666e3a57c8640a8e5e7b7c8d0687467e205c037b4c5d7a052e2aa8b60be142eee26f197b1e0a983f8df844c770881d820dfc4d1bb3d9adc" + "0x02f8d4870c72dd9d5e883e8201cc0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028ccd2e3086ddc2ace4656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a096c0d209b0a5b8b06947cc4c7ca723df55c5b972711b6c08ec7b9c393fa6e8ea80a07fe69218a844aee02158afa85fcbff97e407b786542649788f12ca2fee4d1860a020e258ab41db1a20c0c56271edf7f26e16649cc18853668e1c49837a63993a4a" ], "withdrawals": [], "blobGasUsed": "0x0", "excessBlobGas": "0x0" }, [], - "0xf653da50cdff4733f13f7a5e338290e883bdf04adf3f112709728063ea965d6c" + "0x767177cd603c7e3eb94583c38141b0d701b15631173ffb7a35beb5a7515c7fff", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np505", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xdf54b762c56706ef7861a0725b7fd4f01aaadcac614d3d3f39569cb8e621fd1a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xe7f32766b9aacad31862ca17d8c92188805f7979821e77fbb6061ec9b320b613", + "receiptsRoot": "0x1f914c56592f749fd28f2caa300a6799e1c32c2e45a73828c28a84759e9f2a96", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000104000000000000200000000000000000000000000002008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1f9", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x13ba", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x4effa3cb8383f0ece82c3391e95ce6a88be26f87bddcc62dfd99cd7a5a11dbfe", + "transactions": [ + "0x01f8d3870c72dd9d5e883e8201cd08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cba96783a3c242e12656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a00a5a37a1db2e0068ee9791dbe377a74c4f7bc36bc27af57ca7e49059127e8eb080a0062b5a038fc99ab6efd44780c98ae6cd61f31cf04c26fd39c7b3bec8ac03c134a07c9f218dcd1403f4f06eeedacfdc6cd59568e55b48b6f87358b80cd9cd50d4d3" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xb7cbac00a090b3cf081c92da779bab61f22c7f83e8b9c5dce4e91c8c1d208b7c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np506", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4effa3cb8383f0ece82c3391e95ce6a88be26f87bddcc62dfd99cd7a5a11dbfe", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0807efd5f3ab55636012ada7ec38da71e53884084e30f6a897d7b05a5c5fc7c3", + "receiptsRoot": "0x7d42d51cb89c85398dffa2c7bf080ceec75a6b26afdccd37a22d621f438e7bfb", + "logsBloom": "0x00000000000000000000000000000000000000000001000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000009001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1fa", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x13c4", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x2d903ece7c308b988d585304235cb0f3bacbafb64ec0b62da27c1f77aeb18d76", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8201ce0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cc1493cb1f9cdc80f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0989e02934facff928d8e788f174ab7d48838c62b07d420a8527cb7eaabdbe91b83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0168d3c7a04bcc073bb45ffa0b8fd35031efcdc8e9cfb08579208573d2acc3142a02af9d8933f7d5abf54870b26a17a465ffaeff4df77230346f9044e11dea6978b" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x38a90f286b0a1fe34e7d3b9ff797c39789970041d2818e5adc11b91e0579537c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np507", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x2d903ece7c308b988d585304235cb0f3bacbafb64ec0b62da27c1f77aeb18d76", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xf75bf5befb9b72b7c11ca0f64b9cdb20ff4390f70955370f2cff744bedfaafaf", + "receiptsRoot": "0x19dc9bb39d5f6f19a6d2a4521d0630d23599b30a077d025fc8f7bc7bf57c719b", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000100000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1fb", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x13ce", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x005a1cd86c8a2bb05874d5fd341035e7228067175a1c757b91f442dc34922a1b", + "transactions": [ + "0xf8758201cf08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c4d992d778a781294656d69748718e5bb3abd10a0a0b6df52cd6d5c870905e39a359ac9ce37ac8d151c60eae85736fe3c0e21d8d489a07655a80dc2c45e6713f4d40840a5cb8b3de31b4bc7592e238a41d75d3a4b9544" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc19bcd1a95bf2edb1eaa8cf59fb23d053422845e57f4a41a2832500d1f415f5a", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np508", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x005a1cd86c8a2bb05874d5fd341035e7228067175a1c757b91f442dc34922a1b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7ba3acfe7f78ab817ecc275982440c85e8ceefa241edf02fb5bda27d40715afc", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1fc", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x13d8", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x9e7ffa6ebba334b9810de0937096a05f054a43eb03621ca8874411e5ddaf7543", + "transactions": [ + "0x02f86b870c72dd9d5e883e8201d00108825208940c2c51a0990aee1d73c1228de1586883415575080180c080a09b2154776de3ec96562664c4cefd5a0e42c48789d13b04c1ee7fc45c9d695fa7a067389d062cc02c3a9500d08b206f4f8bc0363aa685b8b9a8a5ef4a81eb82d4d9" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x1beb8053a04c4c9a4a885576977da294a141c196be9e4af9fd21d7801196559f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np509", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x9e7ffa6ebba334b9810de0937096a05f054a43eb03621ca8874411e5ddaf7543", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x87e1f05da062baba064a0625b957dd18d2afce4914e5a57971dd4c08b789aa98", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1fd", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x13e2", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x68b50078b3394b06d6ee3a3b12462a38eb85286023c07d90e290ba808b5da702", + "transactions": [ + "0x01f86a870c72dd9d5e883e8201d108825208947435ed30a8b4aeb0877cef0c6e8cffe834eb865f0180c080a0214ea359664d05afcaa80e32b3381041386921a2fc2959dab6b640751fb38ddea07d738ad38513b5651ba8bfc08cb21557223086eba81ccdb9f19cd934f59134a6" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x6514900951391e916e7d78ae0340e1fa0cd5b3e4c1319438aa4db66177eba45c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np510", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x68b50078b3394b06d6ee3a3b12462a38eb85286023c07d90e290ba808b5da702", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x633881f7142b2012e0c6bad7bc4c51e40679d0c01c8c19ba3aa1608c96c69eaf", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1fe", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x13ec", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xbae08b3b1ac544135b3a06fbaafb931229a99d0e47434318580146086ce0dab3", + "transactions": [ + "0xf8688201d208825208941f5bde34b4afc686f136c7a3cb6ec376f735775901808718e5bb3abd10a0a0e917c71f21dfb1b319d11f2bca6800be74fad51f8e6f728460a9ac8bbe27827ea029942083348d7b4b32fe2c081b415970337e60e99675ba18590101fd3e5de0d9" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x96836b3cb8f807083b6a006ae323d1e829d82357fedc171e8d20dacfe39755a9", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np511", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xbae08b3b1ac544135b3a06fbaafb931229a99d0e47434318580146086ce0dab3", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1b77c1aeefa6f0f0c54074c34f4036d6131bbd246208612b75f6b370a32dd2d9", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1ff", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x13f6", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x91711182ab4cdd63dfaac9e02b07f4d49016fe1ac744ff90843bd1f52f893761", + "transactions": [], + "withdrawals": [ + { + "index": "0x2d", + "validatorIndex": "0x5", + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xb4e2322123051b7ae894776aba06808205c6bf96a70e56b0c628a51408e5c28e", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np512", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x91711182ab4cdd63dfaac9e02b07f4d49016fe1ac744ff90843bd1f52f893761", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xe7d3338604fdbbe66dc8f1bb3bd9b8d66ef7f1659671827316f61b261799b4a5", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x200", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x1400", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xfc6438ea7c3138aca8cf840a05aa7e627ecea40cec8d6166406f98449ba6182f", + "transactions": [ + "0xf8838201d3088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a06c77e9d2b020f89b08ac3b941ced9fa71750062c2023d25ffae22a3b62c7ee96a074e9fc4218a4af7745759a2cc801d188b8c126cb0851c0d521774e4f6eee728f" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xdb00a732067d4f7ab43e113731f05922c7acc4c9d937dcf77cca57ed319b3290", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np513", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xfc6438ea7c3138aca8cf840a05aa7e627ecea40cec8d6166406f98449ba6182f", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xce3babe7367acf2a20f05e38f7ef7ab85e308db3405803f7e9d83b2312d9bf70", + "receiptsRoot": "0xe764d433a3fcdf26dd0789611144e14219aec816ff6b5d755df8cef4a4e23783", + "logsBloom": "0x20000000000000000040000000000000001000000000002000000000000000000000000000004040000000000800000000000060000000000000000004000000000000000000000000000000000400000000000000004000000000000000000000000000000200000000000000008000010000000000000000000000000000000008000000000000000000000000000000000002100080200000000000000000000000000040001000000000000000000000000000000000000000000008040000000020000000000000000000000000000000100100000200001008000000000000000000000000000000000000000040000000000000000000080000200000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x201", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x140a", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xd7d6cfbe9f350fc0643592dbd7a2a98639f92b0183cee49ef6f5d99aba72b47a", + "transactions": [ + "0xf87a8201d40883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0ec40fb21e72abbf085d2b8cb926a287b4e68de48301c538a60be1d31156b50fca07c6315ac48acc96969968e60e283fd046e31c32811865d5d3302389bca84e589" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x085cd56145b890e872ccab3784b1ec282a8adf95bb90f918fb400c03ca25b188", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np514", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xd7d6cfbe9f350fc0643592dbd7a2a98639f92b0183cee49ef6f5d99aba72b47a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xa176a68ba3c1ecb49e1fd1acc1ed5b300b0cefb6c520e6d88155b92dc2d8d621", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x202", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x1414", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xe42d2c63e650101bc54d149c19d67b78ec05431cfc15134146790f1da71548b2", + "transactions": [ + "0xf8658201d5088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa07fa54a77142f2ca3c948e34cdf94db1d9ea75232b08ddba064f58d7d1b4081d8a06f6b19500cdfe707a22f0febdc08d281ef27b87b2522194e5a02745c61698839" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x43fc6f30f79ff0be21aab95d8db8fa7b819fa91382063a80f286051f9f2d9aa9", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np515", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xe42d2c63e650101bc54d149c19d67b78ec05431cfc15134146790f1da71548b2", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xff3d8349337fdd2205778b8a03c55b0313cf6a59c855ab9d98f7b9716194773c", + "receiptsRoot": "0x246cbacfcb463724b93536f5433ff6394ba997b12924adeb1ee57f771700bacd", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000020000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x203", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x141e", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x718c2451b8df916754650ca5d9a3fca98e0f9209d41cdafd30d3ee9343b12216", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8201d60108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cd04c9c422abfc528656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a039410f5a8f450e0b7fe63aa93e214a7c5cbe78786c815ebc926f1e8a2a14f4bb80a07951a771241a4c9da56ec3d101b386c01aaaa5993f05cc6d824a1c99bb7bcb8ba07a9576937beaedc82156293b534c1e2624d7dcb41d2c7ac5d587340d0458fca4" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xbb26c41420c8eccc97109bec0db605657b7ad911842ea5c892af203f5dc72b0a", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np516", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x718c2451b8df916754650ca5d9a3fca98e0f9209d41cdafd30d3ee9343b12216", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x298da922dad8f43ce69c938556232f0eed7f747036e3961ebb5476616577f79a", + "receiptsRoot": "0xbd98f2dc2a79fd7f904ca89c03703911ce6a2f9ae74bbc57857af94b74244656", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000100000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000010000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x204", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1428", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x64f5dc426951c8d5c389bed1af605f9101235dbfaa4822f2ba83bbe9973be25b", + "transactions": [ + "0x01f8d3870c72dd9d5e883e8201d708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cff6bcf94f901ef8f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0b50dcc47e811f76cc69369cb397936a5c70520a51f33b84f1b54591da145e82380a0fa698bdc90fd08a9f3f1ab954bfe1236b8534f57fe8fb4f5ddd6885e9bca938ca06e75008087626148ebaa8c850497b8511af50ca8a5dd45524cfaec940b29aa5f" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x79e7d775b35bea6224afd7e2f838079f88413410f667f16dcaf54f2124a68de7", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np517", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x64f5dc426951c8d5c389bed1af605f9101235dbfaa4822f2ba83bbe9973be25b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xba26112fc1c8049c8f452bfc2c8f32fb9a675a345e25b5ee216d461df7db6203", + "receiptsRoot": "0xc927ac9f5187e2207bffcd8b6530ddee8970370c321c33c3942a120de068d618", + "logsBloom": "0x00000001000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x205", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1432", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x1841a4c413f59d37b93421bc6d165288e0546f1261e25357feae9c96a66402e3", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8201d80108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cf79d15aecc7ad11f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0e891146f52235abb9f53919fc0e41a678d5a8a807a2247177d67539a2bcc3d1a83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a0541fee253cfa9457ab460ad9b861e6d894b303ac93e8dbb0d9222e9d2f025859a00eb8085ea838b18113febf57834095a4606646d9694b290e133d9acc7a523491" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x5f4be0643a56b90ece82db7ff08963e8d9796840afd11d6a1d0d39b4498fa26e", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np518", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x1841a4c413f59d37b93421bc6d165288e0546f1261e25357feae9c96a66402e3", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7d4ddda2b28be342f1458924b4f860e59a0cc00953b848d7686827dde5f3d514", + "receiptsRoot": "0x5a656d8918863a21cc2ce891040bb31b0ef68b4f6fe333b63dbc9eed8d97ef1a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000002000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x206", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x143c", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x289f40c44da44e6d545900ecfab81d0d86b9756e74d6bfa2fb0095cf28a93cdd", + "transactions": [ + "0xf8758201d908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c777feac9ca0bfcc3656d69748718e5bb3abd109fa01a2065ee360d4a5bc46515858e6464c6529ee55ba3c714fa94b8a90bed4dc6f4a0425c529b6e0b928072abdf1f6b0fbc3f329bc68d80ea1f9a88e89fb672049174" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x15b308f32252d593d6f48353f3217f10c391d03cff6eb9742f3bccbe6d1d6145", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np519", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x289f40c44da44e6d545900ecfab81d0d86b9756e74d6bfa2fb0095cf28a93cdd", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x21cc4bf891fa35781985475468fe6e4973891cee2be5ce2a40512413e21c911c", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x207", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1446", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xb80db8759f920638458bd60e8f97e9a0773970c30941cf2744f4db475b5c53a8", + "transactions": [ + "0x02f86b870c72dd9d5e883e8201da010882520894c7b99a164efd027a93f147376cc7da7c67c6bbe00180c080a0bd058792f7ad1149ac662402304d2f4aa1b9fc78836dd7332185356a4059b763a062a11cbb48aa986174da2d746dad05ae5b4c0292f9782adf3cdd65324ff7f7e5" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x959068ffcb9b2830276c8aba06e7272d43aa3aa1b7220b9357ccf0f57c3c004d", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np520", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xb80db8759f920638458bd60e8f97e9a0773970c30941cf2744f4db475b5c53a8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xdbabffdcf20b39b47375cb2813dc7b5ef1386fd2fedc073f4a39269326eb42b9", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x208", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1450", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x4280ca715e955153245aa296395bd7f179a13606f4e909119b1d58b7b0457e34", + "transactions": [ + "0x01f86a870c72dd9d5e883e8201db088252089414e46043e63d0e3cdcf2530519f4cfaf35058cb20180c001a0a3445dea2e057243a7cade92be94c8a047ef1d7e225e0903c7cc1d284d54837da02c5353c9bcd1e1bda954dedda00d7a487916882e4924ebee445a577cdc37073e" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x00e75e86a54290b92d8664fb2f08a2f88c05b4d97d79fe482da765f8386c614f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np521", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4280ca715e955153245aa296395bd7f179a13606f4e909119b1d58b7b0457e34", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xaf7ca220478eaaa309220cdf2b29be6989118676c4bb3605ff4e06d3f52cebce", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x209", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x145a", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x56c95098c7c859b8b786bc2f776f739ba109a1d662beb8545294938b9ce5ef4f", + "transactions": [ + "0xf8688201dc0882520894717f8aa2b982bee0e29f573d31df288663e1ce1601808718e5bb3abd10a0a0fa276d4cb8eca10e037988083dc9ccc88d525b2e0103bbe0595a1cf7ae6cdc17a0430d478df942ce08d2cbff40008fa68efee94bbbf2d02a9b8b406b580a215ecb" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x2b736a8b6f16cc86e1adc0f2970e29ca45ed79734255a30ecf92a40549d7bd56", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np522", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x56c95098c7c859b8b786bc2f776f739ba109a1d662beb8545294938b9ce5ef4f", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x27370273d3893ce3bbbbeb8bce070f64c2ad3ddbf21b5b91ae05af0ca5a51a80", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x20a", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x1464", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xed614b855d979afefa3c40027ca4b6fff89a1467173e85302b48a478bfa7abad", + "transactions": [], + "withdrawals": [ + { + "index": "0x2e", + "validatorIndex": "0x5", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc46c8a987f02fc5b5185de4713c08a87ff4de7c745df1d52326418c60ab262b2", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np523", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xed614b855d979afefa3c40027ca4b6fff89a1467173e85302b48a478bfa7abad", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x02aa4ef008879baf8013e7423aec03edce2bb972deaed85a328fb3091b4ed15e", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x20b", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x146e", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xf379747713313c3ef604ea0d5446066edf0b695213acfb86388ba46e6c926bae", + "transactions": [ + "0xf8838201dd088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a023dc415db791f292cabc61a8b7283f85bce4e465f6874575754d609e1f3ce941a0700ac3dda3383581af5d6955cd810cbb7307ec7137ded66c03b7e22358454d5d" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x4c5566cbcba6320f9081048390d01c905f9bc09b731d3e7f6d41a463755a8b58", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np524", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xf379747713313c3ef604ea0d5446066edf0b695213acfb86388ba46e6c926bae", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0cd299e9c060969fe6593b7ea08a63355e4280a3f2922270ff3095637dd7948f", + "receiptsRoot": "0x2cb4423ee880ff1ea3b8a2183d7f06169300ebc9b6fe32056fbced32f27b1be7", + "logsBloom": "0x00000000040000000000200000020000000000000000040000000000000000000000000004800000000008000000000000000000080000000000000000000800000000040000000009000000200000000000000000000200000000000000000000000000000000000000000000000000000000002000000000000000000800000000000000001000000000000000000000000000000000000000000000880000001000001000400000000000000000000023000000020100000000000000000000000000000000000040000000000000000000000000000004000000000000000000000000000000000000004000000000008000000000000040000000008000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x20c", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x1478", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x71345ffec2ba388522c6703f19f24c5af1eb742a44d2ae6749276739d138912e", + "transactions": [ + "0xf87a8201de0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a05c1d31b87f32db69d5b9d2e257a848d4c1cb58cd4732960d72e270da0683e93ea01a6781141f8fbb42eadaa7d0a2a57590405d3ffa3890a0f7c648769c3989100f" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xda6fa07274e44043f94ee45fa0ceb22272d43aa0af21c6c9cc97edc786407138", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np525", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x71345ffec2ba388522c6703f19f24c5af1eb742a44d2ae6749276739d138912e", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x4ea5649d17703d51dac0fe529718f0f0cf21f44cc8d509d2543d3d4f90d12719", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x20d", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x1482", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xc73d56854a544ce56956bab6d4ffab7beca0ec861ff5cf5906aa2aec20682c75", + "transactions": [ + "0xf8658201df088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa01720814975890f03e1a3279eb0d5af0541a4b8e217f481890cee5a0dd8ac4023a02843cd3100592f8bf4347b31728aa75f3f75cea374b67f80d3e71527fd65c016" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x874290457e263452e8d382faa3fbe492ccdb28cee1c8a5ff61c039977c20c053", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np526", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xc73d56854a544ce56956bab6d4ffab7beca0ec861ff5cf5906aa2aec20682c75", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x190daba25ceaf68c12492a2d923af7d8c96b4afceebc901351efb217d9775367", + "receiptsRoot": "0x10047deb371c2c9cb54cd89eb2eab6b6797c5d35722426601ce4389b6de76f54", + "logsBloom": "0x00000000000000000000000000000000000000000000000000010000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x20e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x148c", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xd543d5b576ae572d9996cd3d05295368b201e3c618ae5da30fbec43cf24b52a3", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8201e00108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cc37096f89eb8687f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0075a739ccce514f063220aa4bb66f08a7966189b0f24a2c5ad4692133d7aa6cb80a0fb8b4fc683ed078751d7cb16998f23fee9c6c518cb6cb7e53f358166b70be89ea01e42a4c3032a587f5d47a21bb164b61c3dea45c85ce2135315c43ca4cf50b464" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x0ffe5e304347d11e92a03004fd66c66fb058267e5c835b2ff6f4dade1ed6159e", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np527", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xd543d5b576ae572d9996cd3d05295368b201e3c618ae5da30fbec43cf24b52a3", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x69e05db1324cc8ff7d7db4d31bc7d3a3c2402ca7111bf4f5392dfeefc6197a4a", + "receiptsRoot": "0x03a983607249a979042b87909c438e5c752cc71e90cd1d80608242f9c900d81a", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000800000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x20f", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1496", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xdba4322406050555a1a8cfbae1c6fd627bee7757384059a41bfd5b6147543f53", + "transactions": [ + "0x01f8d3870c72dd9d5e883e8201e108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c4dd208cc7281960f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0c6bea923a54f8cf570edfddbda896a2ebf7b53d33b1dac8914ed024ff0621f1880a0a1b21815f9c5e92dc5dd6d6de2de28a6cb43d213da883f52b3713b5c82772fa4a0799b9eab259ac6b761d6d5dff843ccd407f5fc75d73cf3048db0ef83514ddebf" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x9ae315e6ecd4a85e734e737190ea4501b8d0f5d0885ccaa267509bddb290bd07", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np528", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xdba4322406050555a1a8cfbae1c6fd627bee7757384059a41bfd5b6147543f53", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x6eb258534e7dc87b92c21e0b551b5ba4b7cbe61220ff88cac3f745c57ced124e", + "receiptsRoot": "0xe78cde3d52f87a1ad382ccdd7c7856f8d373afb165be7c463efcb1996196ceab", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000010000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x210", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x14a0", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x9eadaf49e03a16c9c7cb8d2ea59c3285d7530750a462d6a9338e9a9e730b1055", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8201e20108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c6892c905221f3788656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0ab15322a52f3de5dda0553d7abbf171524cabb9c97dacea8806c750361d472df83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a0ad577f0e6c48f80b38cd100b0209f429072e28e557bcd66fdefe6218dcdafbc9a0382bce4cba9056329b00ca3921f927c3ca90a41f36a3f3e195f3b4d1e2161824" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xb9808a96196fba3329eb714aa00743098723d9850510689ad18fd6952b655882", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np529", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x9eadaf49e03a16c9c7cb8d2ea59c3285d7530750a462d6a9338e9a9e730b1055", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xfd8541477e0d1ae87c8d86a53a130c1a3dca87b079202aa93d60b191a75de382", + "receiptsRoot": "0xbd9775274f3b90081fefb52407bc7b88acf25c5822271cc5b6fcfb34878e391c", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000002000000002000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x211", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x14aa", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xeefa15b3aa7fbee117a78b61a365f6e38b6d8ae21482bc2eda241e637d43af8a", + "transactions": [ + "0xf8758201e308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c315c130cd091bd0d656d69748718e5bb3abd109fa00783dd9ccbdecdb119bd9f6c0fc409abea3f74be77e87fbf7452de4b522b9db0a00a46e1b4c79bbfccd0c4c1b3966b26a26e5dac23650d62371e8685c2914d7db6" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x3cacbae26791d03a0ba1bec3ba0599219257c88708b022bbddb7e7673ef818e1", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np530", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xeefa15b3aa7fbee117a78b61a365f6e38b6d8ae21482bc2eda241e637d43af8a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x465a36ea30cba123d3b7913756c9c00d129550e958bfc4d6b316d39048c408fc", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x212", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x14b4", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x3c7d782eb5bbcdd254bbdb120e432c90d9b0510a3c7e64507ed2c82fc01a2a7a", + "transactions": [ + "0x02f86b870c72dd9d5e883e8201e40108825208940c2c51a0990aee1d73c1228de1586883415575080180c001a0f2cf4a1cc75a89cfc63c40d50d28eb5ca1cfc27dc639bb63cf27b8a550a495fca05c00f451e22fffa147a2febb5e19fcc67110fd7dae790449b0fb7d7123b73601" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x97874b014835a49286b4ea56d5a282b34220b0950c69558ef0e38877061c88d9", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np531", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x3c7d782eb5bbcdd254bbdb120e432c90d9b0510a3c7e64507ed2c82fc01a2a7a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x262abcbb09739f0c4315c4f1cc05812ed8517ddb9490aad148028dc7fa469e4c", + "receiptsRoot": "0xbe3866dc0255d0856720d6d82370e49f3695ca287b4f8b480dfc69bbc2dc7168", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x213", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x14be", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x56d781324e6bdab32f417adff9cc2b4c645f819184b323f47ec974574121b309", + "transactions": [ + "0x01f86a870c72dd9d5e883e8201e50882520894eda8645ba6948855e3b3cd596bbb07596d59c6030180c001a0272979494bc567f4068b0a0045c47c7a4d5b61830336ca2f0b5dfb71b360b5b2a06e18389eef16507c32a65a33657d91c0c86ba494fd098e4597c8dfcda5adcdac" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x30671eff1dd3e3e79d6269eacaca22ff3b4d4fd320a192c10d9cfa56d5553c3a", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np532", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x56d781324e6bdab32f417adff9cc2b4c645f819184b323f47ec974574121b309", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7a641000a828fc192ecc11aa311654b566eed5e1b3bc965c728d6e5acb96ef1b", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x214", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x14c8", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x997c22b77767599b4d1f9f7d21ad9b34b1e13e5ba18986d4dee06d282e89e453", + "transactions": [ + "0xf8688201e60882520894c7b99a164efd027a93f147376cc7da7c67c6bbe001808718e5bb3abd10a0a0a0159c130ac25ae9f757ddb7ce145902e9d9c6b2bca2367aee5c0c177138b3e6a06eb8a315be9419b53fffdc809106fe98042b1282ebc54139bed557f95d3cb9d0" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xd8d54c092190a712f5ac8e0a4b7e10b349220075f76775f9e4c4d4890954999a", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np533", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x997c22b77767599b4d1f9f7d21ad9b34b1e13e5ba18986d4dee06d282e89e453", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7d0ac3c7e061d59804dfb4c844c4d6a6c3daf56fb399b9a693a08432128a377b", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x215", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x14d2", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x49223c27247cbb012c480dd78497ea761f0de37eab920e169067d710a6c697a6", + "transactions": [], + "withdrawals": [ + { + "index": "0x2f", + "validatorIndex": "0x5", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xb3e8460e8c6dccf295d6a48d8335d66e44d66ce1a1a422340fa5851b4eee9d88", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np534", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x49223c27247cbb012c480dd78497ea761f0de37eab920e169067d710a6c697a6", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x97d7c32f96e823071bd92e3ce789ffb7f71a577d045524345567215b20e9c5d4", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x216", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x14dc", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x09f9f3b73c653b5d3440ff550da397d5d6b4dd3e3297a2f2d3c5e67bb128afc9", + "transactions": [ + "0xf8838201e7088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0a65d61b55253835ba754891614405c576b15fab6aaedcf41e661ad09ddc3249aa01c58d6a0533b60d246426b0475bf951081ad130b8a4ecf17ca3fe45817bc54d7" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x6c0b1e570cc4d4a7db18835084f04878f61c4c184bb120ade6d0079cdddc0f03", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np535", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x09f9f3b73c653b5d3440ff550da397d5d6b4dd3e3297a2f2d3c5e67bb128afc9", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x06e29a646e53e63f21496c4a3750ab792ae936c9f6aba8ef6c0b394c4162b7ee", + "receiptsRoot": "0x4dc3ce129c50f0f33376b2873180d30ad489254d84227440afda885d13128bc7", + "logsBloom": "0x00000000000800000000000000000000200000000000000000000000000200000000200000000000004000000000008000000000200000400000000000000000100000000000000000005000000000400000000000000000000000000400000000000800000000000100000002000000000000100000000000000000000400000040000000000000000000000040000000000000000000040000020000000000000000000800000000000002000000000009200000000004000000000000001000000000000000000800000000000008000000040000000000000000000000000000000000000000000000000000000004000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x217", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x14e6", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x6e277d1000baa83809de9f5f90fc8a3387d1ff660f9a7d7857ec4c3e66f70d57", + "transactions": [ + "0xf87a8201e80883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a02d4072f0fa61da269b2848af2a7c2301b26e411ce33bd229fc1147c4b627b49aa00316bbe2cee82df396f55967d0087d87803bba9f596022542d4e58b23f6fbc6c" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x22590be535e87808bcbfed1999053f2a159b4ec2d830ee2983ebd95b2c7cb7e9", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np536", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x6e277d1000baa83809de9f5f90fc8a3387d1ff660f9a7d7857ec4c3e66f70d57", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xf8d9694b5feb43df6c73fb0bd5319235826db3cc7e0cb14bdd5623a50bbd234f", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x218", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x14f0", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xeacee55ad16ffef8f34262dd2351947882b5c327565581fdaece63fe35c8044c", + "transactions": [ + "0xf8658201e9088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa022c7b242e1ef059218eb70cf070b49f60caa6fa032bb8b8632f5f09d29f80c35a03c4ce2290d2679e8b9b97050a9ea8831fddff3867a0252c0cbc9ef00e4280e5c" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x5c147544dcb51e46004d656f863d8c78c08d7801fa1142e9c81e231ceab7f91c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np537", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xeacee55ad16ffef8f34262dd2351947882b5c327565581fdaece63fe35c8044c", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd115c5969ec12b4c5bdc21f5d83d9579a719dcfb222d3ff0283db5e289d98a5d", + "receiptsRoot": "0xce729af5fa5f299bdcd0ff1a99fc476c251d9e0bbf22c3b46addefc7b85f9c29", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000040000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000008000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x219", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x14fa", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xd13cb1082077f93cf162c8868d1e2ddfa3987c12f0b4d17de8f4e456ba9f646b", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8201ea0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c07626586e3a0f1ec656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a09f5941a130f6c2ff98ec21bb2517998dc5c8512230dcb37ede3cb8a4694175ab01a0fb5fb3892fb8cd6a9be0f5b801786a8c79e88b0d9ef5449d56f0c98d185d7d2ea076ecbe90f25a389ad5def021d71350df29f6b730378b85ccf791a8f44c2ac96a" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x9579f88762d50f0b88eb438cc616ce1a2fce24a0655bfa18c17600f37bcd84a9", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np538", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xd13cb1082077f93cf162c8868d1e2ddfa3987c12f0b4d17de8f4e456ba9f646b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x81dc32740002a865b0568ecce82a55ff87f3102900c79b2ced81f0436469cecf", + "receiptsRoot": "0xe60b0698c810d1736de5e101f9ef3c378d764079246b845b4b3b2497748b7adc", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000080000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x21a", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1504", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x323fc2bb76f6f190369ed67f4eed60233e9ace45b6b77a8a545147f6e2a12826", + "transactions": [ + "0x01f8d3870c72dd9d5e883e8201eb08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c983c2551657b63bc656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0b296a1364260e1c8d47bcf2239f26b6b909a0a7687250af4af545eff0ea95ed701a08a1e2bea85d17cc28b85ba5aa259d8ecd80f18f356953fd6700bb69a1c4db7b4a046a33e75aa1e0b4dee47a01767b6dc71865ce4520ea58069ffe116cb781bafab" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xbe71754b5029b99b3f84d2f972f2f3364e404e211f30737d6e19fe2ed70bd3a1", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np539", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x323fc2bb76f6f190369ed67f4eed60233e9ace45b6b77a8a545147f6e2a12826", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x747e7773e984de4004d7c2fc72ed3d964cff24311f52642022b8d08627233b99", + "receiptsRoot": "0xd84d1f3c040aa4e5e5c4655e4e31423fd5d4c2ca46d25cb7693bc6bde4c923a8", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000004000000000000000020000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x21b", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x150e", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x1a26d12a9846cfa2af53cc33f21eadb49c2f39560b460bbb1d7c253025da7917", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8201ec0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038ccb38a78682f396bb656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a06c172610999b0729fbb6bb1ba27e7a0009f1b584ad6f8307d3dcc7d24a18087483020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6801a066648a01bc2252d7e0633c6b759cccd6c6d121ac88f86a69fc118d657e4f6740a01c809c36c3734566dcd0329b3ef0ed31c03a6c7637050bc71f371f875f943bbc" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x72ac7ccbdef2d82e39f5ea95cccfdb59f5d1c4a9a83e7e32a275dd2cf71db91b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np540", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x1a26d12a9846cfa2af53cc33f21eadb49c2f39560b460bbb1d7c253025da7917", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x69f76adb56454f7d5f754a13c539416c6c7f06afadd175bb91be5a6f39f45414", + "receiptsRoot": "0x02bf599be82af8d5d9e94a53483a4491b53a865e277f526e8de25320e409ca91", + "logsBloom": "0x00000000000000000000000000000000000000000008000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x21c", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x1518", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xa68b828d73467b4edbb8f3a188d1d23b8de8113e1157ebe14ec188e8f266637e", + "transactions": [ + "0xf8758201ed08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c73f53dd5c5a5b8e6656d69748718e5bb3abd109fa07d2f8da526aca447b41d7e8128a8043efa6181ba64f9a80d4e328fe707ac92c8a068a7bf6266e3a6bd7628ecb2df712e9e0fef35fa5e6de05411680d753e797401" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x2f72d33db4de041ba2707492686a6f045671d2b63383cc70a770a94f39244793", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np541", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xa68b828d73467b4edbb8f3a188d1d23b8de8113e1157ebe14ec188e8f266637e", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x056f995edf8b4f996fd33e30c6822d5826b8a00b41c400c12782b8b3a0e813a7", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x21d", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1522", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x46d5ce094294750e8d8c4508cea607a110ac887c6876460834bb7f944fb3cba0", + "transactions": [ + "0x02f86b870c72dd9d5e883e8201ee010882520894d803681e487e6ac18053afc5a6cd813c86ec3e4d0180c001a045477c69fb8e39de6fbb74e2f46fad8a0100af2422237e37b5381c0f68a79966a06c71c781157867e0ee7e162f1a938b634665f3f31a948fce4681c9ba26370cff" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x400bbdb9ea1f1982431a31e5d0830c0affe0fbd940c7083bdc1d774e0f6cd9cd", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np542", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x46d5ce094294750e8d8c4508cea607a110ac887c6876460834bb7f944fb3cba0", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x55f9573aaadb8fc314ca55c112fd5dc4e4d954e062e593d2e11a12cec791d44a", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x21e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x152c", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x8d3698f018ddc839a43997a360b3715b80f6f8fbf70836166601ecc42439b1df", + "transactions": [ + "0x01f86a870c72dd9d5e883e8201ef088252089414e46043e63d0e3cdcf2530519f4cfaf35058cb20180c001a01f2f31fc6b3aed1b75d585c4d97bc8dcc68d59face5224e5ac09d09bd9e5e3c7a0064ff5892a02c786cbd932238664e43b0655e87c2b14939c70f3253121e28d12" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xe010c49cc710b1249238f6dbda9f74d529142c897b1b786eee0e01a41751ccd0", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np543", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x8d3698f018ddc839a43997a360b3715b80f6f8fbf70836166601ecc42439b1df", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x3ff7261f715a6e65f20e6b3891169cad8aadba6e833ee6d9d19bd4be4aebb1ea", + "receiptsRoot": "0x642cd2bcdba228efb3996bf53981250d3608289522b80754c4e3c085c93c806f", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x21f", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1536", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xbdaeadf6d9045a0a986c15262d81d49e1f12a3301035d7d7d03855f315498397", + "transactions": [ + "0xf8688201f00882520894eda8645ba6948855e3b3cd596bbb07596d59c60301808718e5bb3abd10a0a06277e04f735948e7b3587c9a498a1cbd1cf26e757597dcaacb670ced21fd851da0419c5056ebae72ab55a9f66fc7a781841fbe5ef02d3eacbde641c11ac45abf97" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x4130c014364b543cbea200a882ca0e2ee707740042e3b252f079f4774e906e72", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np544", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xbdaeadf6d9045a0a986c15262d81d49e1f12a3301035d7d7d03855f315498397", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xe359a229439c935d37eb15692119abf3f62f0d44121173742451cbe3c5125978", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x220", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x1540", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x4466a1b8ce15a2b972b93d345e42e24d6c55e49e6e6b390daa111115737c8893", + "transactions": [], + "withdrawals": [ + { + "index": "0x30", + "validatorIndex": "0x5", + "address": "0x1f5bde34b4afc686f136c7a3cb6ec376f7357759", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x506cb52170cb9a25fec6c4454c306efa32f9368e4a71b333a1b211ad18a45d1b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np545", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4466a1b8ce15a2b972b93d345e42e24d6c55e49e6e6b390daa111115737c8893", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x276a6f0667818b0b9e48329b0df3a12c55432a69b7a2e18d804ab0438b9a6981", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x221", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x154a", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xaac5449b0cee4d0ff7e6dc495061712400e5f908b5f5699bd489f8433c7f3ce6", + "transactions": [ + "0xf8838201f1088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0b64f8faa510164cddef08b97617a6d5080fcbab753249ff2069fdebd9bcf18daa03295fb60880b2d53920760615f698f90d44dbf6be4a6b043b842d245e80611a9" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xadfba1e3ff9978ca95fd32570e09cb9ff7d6c8874aa044e0aaaaa2771443405a", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np546", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xaac5449b0cee4d0ff7e6dc495061712400e5f908b5f5699bd489f8433c7f3ce6", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0d95bdf7c340d3e2da1a434be9aaeed806ec9df50c6981f59f5fcf28e38837cb", + "receiptsRoot": "0x8651d247e3bca392f863186a65208d131bf252e4150ed9ffd7087e51751ba514", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000004040100000000000000000000008000200000000040008000000000000000000000000000000000000000000000000000000000400000000000000000080000000000001000000100000000000100100000000100000000800000000080000000000000000000000040000200000020000000200000000400000000000000000000000000000000000000000000000000000000000000000000000104000800040004000000004200000000000000000000080000000000000000000000000000000000001000000000000000000000000408000400000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x222", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x1554", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xbfc6905b39a1fd70f2d85dbd0ec084fc9bba34dd6bb89e4feae605de3472a46a", + "transactions": [ + "0xf87a8201f20883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa055096b6dc4a45fbf9170e9c187b9bc41f2438258148bb7d806d75359079ba6b3a044b007eb890bb333264526a6b7e7c92a6d517de42713ac3f96a0b57f2a4ee607" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x2f527ed6b4ddae83034b3cd789d451f3b7131bd8f196126cb60f0754cf15fca3", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np547", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xbfc6905b39a1fd70f2d85dbd0ec084fc9bba34dd6bb89e4feae605de3472a46a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x8c3fac07843541c61d52b4eb13fef58d805669c15dd83653eebce4e9715b1867", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x223", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x155e", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x1320207357e4a928664d17895ca63c2e929115bf3078b13a0623a42b1361a27e", + "transactions": [ + "0xf8658201f3088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a06ab85e777a6cc0b2dbd52f9c3516390edff3e0e948e7dd2386e7519d8a70e413a05b740cd62710ab8d44076701ed2162a4bd272d2f60800640256f0cd4d6805cdb" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xa72fcd0c929130353532dc56f8c43a7e4ba9748f56fa2f3cb39bff62b4ce04bf", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np548", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x1320207357e4a928664d17895ca63c2e929115bf3078b13a0623a42b1361a27e", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x145414168f2684ac713c1caf12bf80f01f1f9dc4f715f864682ed163654362cc", + "receiptsRoot": "0x91bed430019e3f90cc84ef5e5d56f4276141d26e047324f5e3fb3c631cac4539", + "logsBloom": "0x00000400000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000002080000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x224", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1568", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x6988fc4983a5d91cb76203880fcb0be8d513013f9eda28c6db7c27d0e457f417", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8201f40108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c637837799e0edd06656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a030335bc132be5a5f3bf464e0eed03a3c74f180cb9906552e187e4c04f024b80401a0b8c1fd8af8304dfa9ea0a05efca1dc046c0ee303d2480d33d3571b26ac1cac60a02d88376e9ef62f084881d7cf42a02e196b01d008a3f8162b87b72fc5d0898520" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x295fe8a5ddc346bf5e6f66db4e8961178d57e41915af94f89da7d40ece7b8f70", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np549", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x6988fc4983a5d91cb76203880fcb0be8d513013f9eda28c6db7c27d0e457f417", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd6fcd0749b8b8f49a67d5942c805262f2713201ef2b6ec63b03b6f07de933c62", + "receiptsRoot": "0x844343467c0c25b600bcdee7a3390b3dd9c8ff6bdbe8a74cd849c574c7f096b6", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000010000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x225", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1572", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x293913aa6fd6784e2dabfa7bdbf08dbcceac77ec746f2beaffe37f5c82ebd6e7", + "transactions": [ + "0x01f8d3870c72dd9d5e883e8201f508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c2dbeda6b380ad817656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0142951613bf93db71eba96bb48c57a42168fcfded6491e1229ea2b8570f77e7f01a03dba7195885ae53d62969038775930e5c3836122abd090a07c76596de48a59b3a029534862b9449692777ea4f45389c1ca850bdf164e951c3db834325a39798096" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x673fd177d3d2b3486f6250e98100855417df12d7a090b7ed709bba223e03276e", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np550", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x293913aa6fd6784e2dabfa7bdbf08dbcceac77ec746f2beaffe37f5c82ebd6e7", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x51e463c94ba9dfedc74f013b95d9a29f55f140f4fc8959bf37e5744fef64988b", + "receiptsRoot": "0xcf20b8f39841205271cd4ae3ff22bcebb43f26f931e0bf0ad958927e914bbf67", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000029000000000000000000000000000000004000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x226", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x157c", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x3c64be9f5fc05b3a06c21263201805872058b6dd89f5871f56126074937d7d69", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8201f60108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c909c95399f08d166656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a344ff63ecb6c6cbbd711b06a84844147910ef79a57679958664abf4af9938d383020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a013ed2516b753d14620bca1a0422f2396eb472cf0d7eaf692644e3f7c2bbb9e4da0335f33a96e11fad5cc14e20505ec96498459e66485ce9949cc2a25748218ddc3" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xc5ea3d95ee2c22d741f6c48ac6d87e445e826cc8f6d25a1b2c12f3d9a447a353", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np551", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x3c64be9f5fc05b3a06c21263201805872058b6dd89f5871f56126074937d7d69", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1bba34157476fa72f9a3d061f9fb9cf626def503bad27fe5d6b29f4e3d51f021", + "receiptsRoot": "0xf0fdb3e364bbf5d119e2eeed252eef654a0a76118cc40780c49ec0aab44fe863", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000008000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x227", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x1586", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x9c0e5ad32b88aabd00d4e08f111128f36d2b3b9d00ec205b4deea450d7e20f52", + "transactions": [ + "0xf8758201f708830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c448907ad05bd07de656d69748718e5bb3abd109fa03dae5b6b96f83657923f3df7a39f0c556348cdaafdc2d0164a981238e2f802c4a01aea0f93b7403c476e0475b00a54e552ac60c9035d81f549dc394c00e5d61b46" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x4085071556a9ec9d229d1d9b802b3e89cdd093f9f9139ea42eb5abe892541ff8", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np552", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x9c0e5ad32b88aabd00d4e08f111128f36d2b3b9d00ec205b4deea450d7e20f52", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x8fdbd867ec5bb8ea8003e3d4e44f084399bbb492e18fe9181cd118bd4fa0d8d7", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x228", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1590", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xee8f988f3c18a72c2abea54699c856a15afdbaeae545924997985cb47210c6d7", + "transactions": [ + "0x02f86b870c72dd9d5e883e8201f80108825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df0180c080a04956daf7db75c5ee31cc0222de61402254b0ae5673fa3ecb6f10eae2da9c0f0da046ef206b998dfe4a0fd4211738e9feacb9bbc383b4bca9d8f2f86678c9262fd4" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x220bddb698fba55c2a96db728cf5caffae495e6903a27d57e74e61991634a7e3", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np553", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xee8f988f3c18a72c2abea54699c856a15afdbaeae545924997985cb47210c6d7", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1dda48a48b4ae196dd289c4b65ee93793862b910a1ed7446434c5f11ae9b6beb", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x229", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x159a", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x90036a13de8b68ad7fa9658cb90a841951763c528de8a3891db006570d06760b", + "transactions": [ + "0x01f86a870c72dd9d5e883e8201f908825208943ae75c08b4c907eb63a8960c45b86e1e9ab6123c0180c080a0b550fec75bc8acf21764afaa05eb86ee6e4e69353b0ad78d09557614e93d4786a0727f2c3ee4f3f7bc4c42ce9f5237958dc70f61007f90731764de7aeaa8628274" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x1f6b1570460ec8766ca6e568bd30d50175e71cc8ae45039bfbd2e82ca991041f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np554", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x90036a13de8b68ad7fa9658cb90a841951763c528de8a3891db006570d06760b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd758afcb5f2401ee815721c8170216980c0b8e02fd72d239f50d445efb4925cb", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x22a", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x15a4", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x641e4d31a221b340b02dfbe9aa430eab15367721b41a224ad5aaf44d60bfb649", + "transactions": [ + "0xf8688201fa0882520894654aa64f5fbefb84c270ec74211b81ca8c44a72e01808718e5bb3abd109fa0c004a45a8d6c03d0407993c24893342e0b3d765f3cd2be95c41222f0d5bcdf2ba078eb1e3e86929285260ec472b40b720db7b1df51009c4f614ab18fdf65a33b93" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xd323f7e63c7ee0244d6795f2d05907b6d0361e6e8b5757cdcff96f2ade53e181", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np555", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x641e4d31a221b340b02dfbe9aa430eab15367721b41a224ad5aaf44d60bfb649", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xc83c6683fac973de49a9b4c8aeda81273118113e44ae6113a15c5c7937283a90", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x22b", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x15ae", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xdfa68efde1f8c73371b729e119655153388ca5404df5f27cb8aef2d5dc49d472", + "transactions": [], + "withdrawals": [ + { + "index": "0x31", + "validatorIndex": "0x5", + "address": "0x5f552da00dfb4d3749d9e62dcee3c918855a86a0", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc7709a90d90185b34b5d069558a1a0e23279c82cb5b9c80b9a054a1747a100b2", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np556", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xdfa68efde1f8c73371b729e119655153388ca5404df5f27cb8aef2d5dc49d472", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7f9a1949008ffd79638b1722265e65a2ec6e7febf650b5246318eb249aab28fe", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x22c", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x15b8", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xe069e5bf125ec3bd85fc691a6e299363e03130bbbdcbb1d4c0e7ed74c44d19ae", + "transactions": [ + "0xf8838201fb088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a00bb0355e05dff14ae7f093498b4243cb3f5ec8b786d9bc58875d08f7dcb7c0f9a030677e88a404292fe6afbdcb47585f66a8ce2ce7e32f6974314733c8af6fe032" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xf41d4fd21005f25600285ed8c8119a41a59af6c0c295cb06a26a29f87ff25aba", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np557", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xe069e5bf125ec3bd85fc691a6e299363e03130bbbdcbb1d4c0e7ed74c44d19ae", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x925dccff4419cd0be1f34db61ebb25b1bedf06c688bc8dd95845ff1a3af5cb89", + "receiptsRoot": "0xe77c45568257ac258a041df8558ba0bfcf5ba6d92493d955fe531307b348c97d", + "logsBloom": "0x08800012000000000001000400000000000000000000208000008000000100002000200000040000000000000000000000000000000200000000000020000000010000000000000000000000000000000080000400000000000400000000000000000000000000008000000000000000000020000000000000000000000000000000000000000000000180000200000000000000000000000000000200000000000000000000000000000000020100000000000000120000000000000000080000000000000000000000000800000000000000000000000000000000000000000000000000080000000000000000400000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x22d", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x15c2", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x7d4c7faff291a34dab9ad08cc22b38e3e0623fbd96e53041f1936aefea2d3d01", + "transactions": [ + "0xf87a8201fc0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa022d44bf5f520547c3d62b3af2a668c38a875402603b1761ad0739cbbf6d949fba07d7e176f316d43054bfcbdcbd949c9fa509f66b01d4e43017c3e464b4ad3011e" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x925086e21edd2723f3b5556821ac5a4bdc2ff1f673ac084cbac931be2ba37290", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np558", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x7d4c7faff291a34dab9ad08cc22b38e3e0623fbd96e53041f1936aefea2d3d01", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x36392ba06448a6cf31c42cb250684201926f0ef3a52485c34a6b6465e2316f2a", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x22e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x15cc", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x35fcbe1e362b97d634c17b08b78c253df56c0f4a52fdcc1da23c4c56871485aa", + "transactions": [ + "0xf8658201fd088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a0e96d4d5bf4aefc09603bc653170722a3d3f6fcd29ca3d386c9559d7147078ae5a01529eca727370b97f6b345c20f6e92c687d8e75cbe2cf2ad859e79f74b8c486c" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x2662096fc52fdc578d134fceb1b462236b7003d5f2228536b1b3e9642a49e0d3", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np559", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x35fcbe1e362b97d634c17b08b78c253df56c0f4a52fdcc1da23c4c56871485aa", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd15854e44e4578650c11096a7c5dca9372abb9e52fff061a36a4865caf71b224", + "receiptsRoot": "0xcafafc113c46cd8f5bb6742a25cd34b0805b1fae9ed6e020f013acac38019f5d", + "logsBloom": "0x00000000020000800000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x22f", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x15d6", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x944867748f6677c888eeffa2f0ab037f72791f19d4957c1b015300f87e8f6946", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8201fe0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c013b74e9ecf6eb94656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0c668aa05d66c2f88a95db12354386f3b6a1722a98aade506e117201f2fd0511f01a0c8ec83bcb1f4c322ab9372efd5360da4dc73819f230fb165b44fc294d1c6d7caa044ea233abe9745a9ea796049df9b6580c6f8ac2cba9a57642fbeb0abea41b4cf" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x13bc04c697ce8353ef9332bf77b0a9dfaa3b46750477b2d6c3ec0320b667fa44", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np560", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x944867748f6677c888eeffa2f0ab037f72791f19d4957c1b015300f87e8f6946", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xbeee5aed5c512fe2aba90434b11ca3cd83cfe2363f9f1e4542b45fc592163f07", + "receiptsRoot": "0xd620721bcdd8db78ee477a81e7dcc0da3e86b50bba6bc734e1bd7fcb760f6f47", + "logsBloom": "0x00000000000000000000000000000000000000000400000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000200000000000000000000000002000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x230", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x15e0", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xe2a46fb9f878a562bb0392bec6634965964c742d80102bed78abf111455c1530", + "transactions": [ + "0x01f8d2870c72dd9d5e883e8201ff08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c1f9e851ca16e6cb9656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a99b8fb9a23a3a24ef3330a371d081c4158ea1b75c9af3c2bda5440857bc8237019fe363a7a627edb29fd42f641a4694ba154799ce85e5a089f3edb570a69bcfbda0012663e85e981501f5ece5197c12aba3a097cd8de77deedbfef0e9fec5024b94" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x5c9c995de8502ece5f040c187feb066888f95c5c18f19e26d22fd33c214f1797", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np561", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xe2a46fb9f878a562bb0392bec6634965964c742d80102bed78abf111455c1530", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x789226dabdabfbf7f597dac2cb52db1b2e268ea801b28231c64b7cecfa70adc3", + "receiptsRoot": "0x6c3240fa7b3dad315fd76137e8b64fbc73fdd42666fa325ba022d6515817de0d", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000080002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x231", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x15ea", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xb229d60b67c1708d3994b81cb282f73ef6d2ae75438e401f4c8025562e2340fa", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8202000108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c544caaa25bed802a656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a088edc52ba848622b1d92e73d2c311c1c83420986c621546fbadac23c3428c57083020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a097709dec1bc6016459a45d2525e964c2e6096b513dd70f369034e621f2f40c87a067a4d43475d8fe708b6a474c73678d638d91c70ff39973670da0278a2f522ae3" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x80e9466bece8ddfabc70825bcec4e24aa55e1acf4ede6dc91e58bbd507b89106", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np562", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xb229d60b67c1708d3994b81cb282f73ef6d2ae75438e401f4c8025562e2340fa", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x84b817485cb14c9eae65f776c34caa5e958edccc2b42a3d7ac864ee5bbc88631", + "receiptsRoot": "0xd66e37e7c990514ad3bbcafb9158eadbce5669b8d56f61675eba2473a8890b66", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000200009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x232", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x15f4", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xb3b6afe52f6d14dd44a71f1ff185ed96179409250f324659fa1d1abd1b232739", + "transactions": [ + "0xf87582020108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c714a7ce99187d89b656d69748718e5bb3abd109fa095b150f56f03a017ede55787d2b0258ca65a9760df427ff0234099e5e0196c2ea06815159cf1061de7fcd19095e685a4469d8a6efa28d7cd8ed7d19531970d447e" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xb60ebee302c2151ccc37af32e3613b07defd9503e344434d344ba3f8331954fa", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np563", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xb3b6afe52f6d14dd44a71f1ff185ed96179409250f324659fa1d1abd1b232739", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xa523e6ff0e4803aa8dbe968c322a315db96a3e88d1b7058534df79c7db027dd9", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x233", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x15fe", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xadafa5a8ecaf727c48b659ef4ab3204554e7cf7b27e69207926a5a62c24fcab6", + "transactions": [ + "0x02f86b870c72dd9d5e883e8202020108825208944a0f1452281bcec5bd90c3dce6162a5995bfe9df0180c001a0acab93bf4cb4b97fcd49b3e4df8b1c86c8f11bd672b9fb9745dcd6e544ffafa0a07e7d4a3efd96afa71faaaa62585632f9b490365abd96856dcd992c0c75cdf01e" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x11c42898638189fe88536cc1845ddf768fc26b99b993c356b1f5dcc14dcadccb", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np564", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xadafa5a8ecaf727c48b659ef4ab3204554e7cf7b27e69207926a5a62c24fcab6", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x0add3d869b6d31d27b406a0b296ad46480417ec18534319ee366f06f559a7326", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x234", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1608", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xdabd6ae95f5c2d68740f3001b8321ff60efcbd343b4c1d27e425b6e1d6dcbbef", + "transactions": [ + "0x01f86a870c72dd9d5e883e8202030882520894717f8aa2b982bee0e29f573d31df288663e1ce160180c001a0e24f830339f5be384db5c29002a98cb0a34f2738d1c9872e2aa0a29cc0544dd8a033e12812533b46a55b9559ec498b72f7dc1b75ce991e2006e10b5c276a3cdbc1" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xb623473143c27ada98b34a5cfcbabf6b70860e562953e346a03770e4237b16c8", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np565", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xdabd6ae95f5c2d68740f3001b8321ff60efcbd343b4c1d27e425b6e1d6dcbbef", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x965ac1ac3accdab7930879f4ee756efac7007fb4576f1da9cd6c05563079ea2e", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x235", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1612", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xbc4039fe1b1fe6767d379b48649f0208eedd6211fd09012c410e96231a70bd32", + "transactions": [ + "0xf8688202040882520894e7d13f7aa2a838d24c59b40186a0aca1e21cffcc01808718e5bb3abd10a0a07258d0e5116a06fac217d7dd9e68efdf1dd0a41cfca170707ca91e13b66a47fca07124963ae3315bbf6d55b6f57b6b9d0cc9e99b89359e1f80a25f7ab119ac6888" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xeb4739b0ae9d202f1529006ae74d98da58dbec8dfad38902ca920e6923beb35b", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np566", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xbc4039fe1b1fe6767d379b48649f0208eedd6211fd09012c410e96231a70bd32", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xce63da29607372e5fb2bd2e3cfc40ad9c32a06a0d75e94b450ece4fbd1782dbc", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x236", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x161c", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x83db531e70791b6207c14af0b6321145a00614c977b70fd0668270988de4d5b6", + "transactions": [], + "withdrawals": [ + { + "index": "0x32", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x506e559f06fc9dbf1609acbdc09d2ae31dc353794a5f742e2645791d3b9b92b2", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np567", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x83db531e70791b6207c14af0b6321145a00614c977b70fd0668270988de4d5b6", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xfba0205e6afe3530dfd7f7ca2f566e5e3fec41a1b72768cef1bd130e0896db9d", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x237", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x1626", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xd790766e32a204eba62eb8748875d63e58f290375cb77e1a8e06cee26be50aa0", + "transactions": [ + "0xf883820205088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd109fa08a3293f922745d79e457a90657c7800d24062b70cbd24731cc509cc035a826a5a02418be783d16ad760c9008ff9bc552ff330273c1b77300054a827e1e537078f0" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x3cf622b6ae96fd95cb12ce270854ed7ae4f651268000e01e37574dfc0f33ce6f", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np568", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xd790766e32a204eba62eb8748875d63e58f290375cb77e1a8e06cee26be50aa0", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x02e8449319a691d4372e57402adf68b09a0c127eacf25dd8c5d24b99ff592f1c", + "receiptsRoot": "0xab5236843c6ec7a9a5c1c857233c1a31227c51fff87b08748241e6e356e656a8", + "logsBloom": "0x0000040000000000000000000000000000004000000804000000000000000000000000000000000200044000040000000000100000000000000000000000001000000000000008000000000000000400000000000000200000000000200000800202000000000000000000000000040000000000008000000000000000000000000000000000000000000000000000000000000000000010000000000000002000000000c000000000000000000000000000000000000000000000000000000000000000400000000000004100000000000000008000000000100000000000020000000000000000000000000000000000000008000000020000000008000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x238", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x1630", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x5f7355f8b08daee6ee6be9e9522ecedee0db5282463952021b5eef1bf8fc6c7e", + "transactions": [ + "0xf87a8202060883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a0152333c4db61c12a484f33619b7494425c4fb730fa90c830e7440f1a51185003a02373ac712cabf3578803bbff9524b1eca00561fbf30a54e5a6d635eb3a1d42b2" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xeeef194c98225e4ce5119ad6bf465ff5b4a542475152471fbe5bb408035137b5", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np569", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x5f7355f8b08daee6ee6be9e9522ecedee0db5282463952021b5eef1bf8fc6c7e", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x9f1f21f14844bbf78578c02bfdab936943f011175e11d57192f110a015e6c69e", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x239", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x163a", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xcd23cbad2ba375c546161adcaee6c4c81319c164b1ad8466811b7490b95e286b", + "transactions": [ + "0xf865820207088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0258584a1147b37a17be31c06af2090dd5eb443f969c020363b2f2cdc459a9596a0282b4f2574e1ec52f6c5289fb36aa4817f07f8fa2b55357f8c918accad542069" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xd8d4edf4122ac50f05b76868187eefbe56393c634490733ab80b12adf4fee4ff", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np570", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xcd23cbad2ba375c546161adcaee6c4c81319c164b1ad8466811b7490b95e286b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd5fb4dd1825b5b107a175ea86e678c666d0e3a7856767e9ea03a8d6fe66852f8", + "receiptsRoot": "0x40e99d7d453a379f204ed089fd42ece7ec4f5231d41153766f315683085eb5fa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000040000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000000000000000000000000000409000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x23a", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1644", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xf1357f71ed1cdbcf8c1a31552f1223403b9d85b44dd4ff2c9a3683ee440c95c8", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8202080108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c364818558262ea3f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0fc6dfdea8f35e8af49faf38c0164a3deacd65c3927eeece6023868f32fd382a701a02b4279a6f9ec69f63621cb880a47c59e094f6fddf49b9095256bcef44d629798a0674c21917344a22cee20997863b3a49fa450283aa7af2f6b0777b734190d4e05" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x05efbc961556af4359a25fa1bb0ade5e3dd4b058ef14e80b0aaeee81da998c26", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np571", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xf1357f71ed1cdbcf8c1a31552f1223403b9d85b44dd4ff2c9a3683ee440c95c8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x827c4203000de525ba92f76614d6007fbd4696e3a62bc974c3dacba3f6a9817f", + "receiptsRoot": "0x0531e3172fd7f36101c399b4954b96f5e3ca6b52b24b166dc8014ed3ec2a6c5e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000200000000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x23b", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x164e", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xb69086a5e21ff6ac0b0177b825eb4ac57307f19211d34d5d27f270d74ca07a17", + "transactions": [ + "0x01f8d3870c72dd9d5e883e82020908830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c7ec75a9a44cbd37a656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0b9a419e057752857f289694284890ff1fcbfbe5d736b5e52bb8568e077f4988301a0612f7a0e06dd7918c6389d3bd4f8bc57e10b32d70da74e884f0dda3b53761209a066d37136bacb647658ec9a497ba10f778bfb78a68f0a1d812d010e56705984d3" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x65490c264abcd05d08f11c260d49dc0f2c55f3459f2f902400cc3751ae16115d", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np572", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xb69086a5e21ff6ac0b0177b825eb4ac57307f19211d34d5d27f270d74ca07a17", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xfc7105c3a5bf1b58cef7558dc26078ae7adc4a72d55093a1af5a25c1efd40b3f", + "receiptsRoot": "0xe963bcbf726070b5ddc6f9d75c199509949be21a06df053d721b3483a55e0b30", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000001000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000800000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x23c", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1658", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xd5c1878d16190ffce6abc0972a9250ab129a383fecf447dd5e1e5fe9c560e2b7", + "transactions": [ + "0x03f8fa870c72dd9d5e883e82020a0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038cdfd0fe3a4aba411e656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a07a536b71187079aaf5462b7d483063e3d25cea8e3a6790ebdbb284666fe8106883020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a011d5b637e77b5987aede42c7762b7fbd44f55cd97820b01c4601b58fc40686c4a059ce5c1474f7dbdc38706a8663fa0a2d2b22f7cf0aabfcb68de52b863d87dc03" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xa662fe4e7f5b359da22861957ebabef233d14df689a0a378333f9caaae8ddcc1", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np573", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xd5c1878d16190ffce6abc0972a9250ab129a383fecf447dd5e1e5fe9c560e2b7", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x85ac092ae2e24e0ddaf4dad90aa0c735d6a3986bc5cc14cb2aee394ee03f5974", + "receiptsRoot": "0x6a9f814aa655c257313a8eb715a3a9b779ff613959c7527c5a3e7b839425a1eb", + "logsBloom": "0x00000000000800000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000004000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x23d", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x1662", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x7adf3774b7bd3f89b0948e1ddbbf300835f06dcee2f437e09ee4473df6c8a07c", + "transactions": [ + "0xf87582020b08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c48fa07464a4e8d5b656d69748718e5bb3abd10a0a0db116037fd0b9637c96295f7c48bc7ab5362b2fe6b64a7fe14a816fb948be9bfa00e01886ea233240e06d6c3d593c31d257f47ae07ba00f8cc91ab4471a83cecb6" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x4e99f494a9bb40f134a5ef00de1bcdf3f971b37c873330d5aeb3d49efbcb4c00", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np574", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x7adf3774b7bd3f89b0948e1ddbbf300835f06dcee2f437e09ee4473df6c8a07c", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x168521f6122464c3f1a43faebf1d77414c95c5d95a87201b9bd00437195c19b7", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x23e", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x166c", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x2dfc4f087156df89e8f26744590b923f3a81642defd298dd1a1db5bbce0b3d89", + "transactions": [ + "0x02f86b870c72dd9d5e883e82020c01088252089416c57edf7fa9d9525378b0b81bf8a3ced0620c1c0180c001a0a42fb001ff2a98cf4adfc09b23851b6fb8da636779221bc8b41c346091630e0fa049a5f535ef66a2f57688fbafaee8d90671f6231df0629f00de594d1bef8728ac" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x67e21c966ca98e58bd6989dff5e94d2bd4e74bd63e0c1419a6d1af34e7cf6a20", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np575", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x2dfc4f087156df89e8f26744590b923f3a81642defd298dd1a1db5bbce0b3d89", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x4202c11970a82d82c8fee99ca6add1ec9866f1ec626ddd4bf865f4762580bcf6", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x23f", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1676", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xe58a461ab85b4e2208262ab6de81621a9fe3c96e4eadb9253e7baecdec571434", + "transactions": [ + "0x01f86a870c72dd9d5e883e82020d08825208944dde844b71bcdf95512fb4dc94e84fb67b512ed80180c001a03f3d6d379ab516c497b0af6290227424b16953bbf968837762326ac2f290bac1a006aab01c6bdfcee9a191a5c9e874e6f34035aa41b07b8785483ffc00b705a8eb" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xe359cbd3a9dff480adcd4cd1aae545e0a0043a076ab291d897dee9316e8a6286", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np576", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xe58a461ab85b4e2208262ab6de81621a9fe3c96e4eadb9253e7baecdec571434", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xd5f511f8949fd8dc7d1098d4c4ed5ab7f9147c89d4235efe097844de896bed23", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x240", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1680", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x0bdeb401cf2ad8a1f33f3e6a71602b0720182bc5a290cbf92a20ad5a47b421df", + "transactions": [ + "0xf86882020e08825208944340ee1b812acb40a1eb561c019c327b243b92df01808718e5bb3abd10a0a05a23960f1d1161a098f5641967203fe3edb3c7e42ee612a474396843253189a7a01e0088b2a97fb0295f0d618ade3f3969d8148fc6577023ae0482060a0f872280" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xa35fac8a05400bf2a27ce6d8720f3c0bcaf373aede26d8b2b858ebfae843a327", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np577", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x0bdeb401cf2ad8a1f33f3e6a71602b0720182bc5a290cbf92a20ad5a47b421df", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x101b820600d1c50ee651d71c08332c9c5fffb5be36dfc5e605adfc7d2c135d65", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x241", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x168a", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x29456e95da920f3dbc36b3dc0a926f2dec210b800550386ca672ed6110b169c6", + "transactions": [], + "withdrawals": [ + { + "index": "0x33", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x5b5c8208e8820c4e2730cf589ab50d61729dfd14468f06ec0ec9f7941a64f0db", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np578", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x29456e95da920f3dbc36b3dc0a926f2dec210b800550386ca672ed6110b169c6", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xfc527558007c4f087e899bb1b473615a09e153d997c6cc52fd0a6620f88d6dcc", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x242", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x1694", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xae6208b2d4c5f776a63eb1e4dc138b366387fe7ddecf72fd98130637bf65dfeb", + "transactions": [ + "0xf88282020f088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0a57ec1616eb73d62f45ea8a0a64baa948e495d7d227b19fd2a1a8ae15e1583569f1aef5b444ca71d6e75d73f714f9bbc5af70b6c4c0919b43dd7711d010d38f6" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xfdc9e6eb33d8f37b2d9599ab0c98fbbb7cada3861352e1244d31d2ec5d4acf49", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np579", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xae6208b2d4c5f776a63eb1e4dc138b366387fe7ddecf72fd98130637bf65dfeb", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x84f3f8d900f4fffe9bd7cedaf36f2ce7782b849d48687b2b4928e7b2f9c97416", + "receiptsRoot": "0x0db8ebc21dbec5d968112dd938204da0a80726a51093c6550507fd204d7ba3a7", + "logsBloom": "0x02000000040000000000100000100000000000000000000000000010000000000000000000008000000020004000000040080000000000000000000000008000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000020000002000000000000000800000040000008002000800000000000000000000000000000000008008000000000120000000000000000000800000000000000002000000000000000000000000000400000000000000000004000000000000800001000000000000000010000000002000000000000000000000000000000004", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x243", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x169e", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xbba5107c05a512e72c49b459b20a6ecdc1cfec225f866ef045c9a3693df05905", + "transactions": [ + "0xf8798202100883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd10a0a02db5572b1b643362370466278086633f4a8b861f4cd3c66fec25129b6f67ad639fa072b90382203dd402b353b789d846eccf6c56c88c49469b852233677fbaa1" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x380c81a5a4ff1291139f4d753060a10393993331c5c422be8f84788bd29709ef", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np580", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xbba5107c05a512e72c49b459b20a6ecdc1cfec225f866ef045c9a3693df05905", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1451a8d4cd68bbb4d5d6f4fe56ad0ab8b35af1200daa855eb3737484c4196b9f", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x244", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x16a8", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x626d2bcb3645a3cab73403328051faad33be5e5f5f75ff38e195b77dfb0fba01", + "transactions": [ + "0xf865820211088302088a808090435b8080556001015a6161a8106001578718e5bb3abd109fa0a96441d65104c23cf9a7088dc28637f66e0622e6b1e5255df248ee585f2e1b31a078dd2974918e32b1927eb9287a7707a78a8811f95522a812266e254c06dbe696" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x84f551d9aedb25cafb6326fd75774b6bd3a7e13666cdf07ed4f43989915856f4", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np581", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x626d2bcb3645a3cab73403328051faad33be5e5f5f75ff38e195b77dfb0fba01", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x9e6b0afec3d1916e27584af48d680684c7ebd341dbc32150e62191b6e1567cb9", + "receiptsRoot": "0xf0305f035bddf00f19ac42d5ccf9c28b3c82c1aec51c2140e5134160855bda60", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000002000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000001000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x245", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x16b2", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xaf6d014836a41c11af83a95a92d5324c0dd0e063a6feda19a05966c97cbeadf0", + "transactions": [ + "0x02f8d4870c72dd9d5e883e8202120108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cfd2bb460afdb41a7656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a014ec3dfb63100132cf23ef71b80689146033fc6ceb9f8c0f0a65ef93cd18c2c701a0b9ab2ed269132f6bcf5993e88b5a2dc4ef5570c0b458f3298a2fe5b52ffa72f0a06749f3b679e3b44c0719696e00ff6b617236313c0968bd2a57bb8071aa6c9171" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x724715f1a28b0b873df27b080122f16d318ae96da7d3adc1ca1e06ed62fa7c19", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np582", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xaf6d014836a41c11af83a95a92d5324c0dd0e063a6feda19a05966c97cbeadf0", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x1db89cc805b90fb11a5ecbcc4799cd83273d928d594710e61b5b3f9f1c0a236a", + "receiptsRoot": "0xccfd2a7a120d603bcbed46bc9f503dd0b3b4b143fe3968b0d072ff5f576bdd5c", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000202000000000000000000000000802000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x246", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x16bc", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x6268abdce6bb3bee101c9e848666f3522cf429cab4725f23a27a5eb9575ed2fe", + "transactions": [ + "0x01f8d3870c72dd9d5e883e82021308830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c93e6b57cd7fc7d47656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0e0fa1a4e967a01f4a84aa6715b0977cc111d3cc0834c5d04f0f1d87e0d561a7101a01ef6a9871216401c4675b1e0fd92fa9f3e9852afe2b6db70b677a848a9fee53ea04088e3e07660ed373cf7c1cccc9006fc0606725d9f8cf0e806c7648033092b2b" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xa3fa3c1b9234dd7e0e566d7f8b57a65f8c4b39d7a0a2346e822afd34a6852a80", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np583", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x6268abdce6bb3bee101c9e848666f3522cf429cab4725f23a27a5eb9575ed2fe", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x981e30545692b2c9117c021ba3fd7200ab656a0516acce07ce55671afb03f178", + "receiptsRoot": "0x1f2cb774b67f97bda6ed769189bba6aa75e9b1255e3e2737494c6731cd4dbcbd", + "logsBloom": "0x00000000000000000000000000000000000000000000000000800000800000000000000000000000000000000000000000000000000000000000000000000000800000000000000000004000000000000200000000000000000000000000002000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x247", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x16c6", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x5f5a1ffa3df60840b186c814fe10bee8d745a195f68174d5097067663eb692c8", + "transactions": [ + "0x03f8fa870c72dd9d5e883e8202140108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c171fa5153d9de7dc656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0a0c2e429d47e77e9b7c98c1aa4aefb731206f41b64a6587678905a86d14a7d7583020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a06c389f2f897e70da12b4b3f34239da178f4ad032d13217b485a72c39257d4081a059985e5a30367433b076881ca953326c2c205ac46a46b5a5c5b3de8af8bff067" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0xf48ee127fa2d3b4a69eff4f11cc838cf34b88ea4eb595db690e2f098af6dc64e", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np584", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x5f5a1ffa3df60840b186c814fe10bee8d745a195f68174d5097067663eb692c8", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xb0d405e8c5e405de5557c8129aeb800b257c8ce69d6e85aac49969b2412d8c89", + "receiptsRoot": "0xa20442a8b2cea953b63f35f3702d29b408aa490d1cbb05ed89f116110422444f", + "logsBloom": "0x00000000000000400000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000200000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x248", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x16d0", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xb43bd5c412948cb43408ac47c85d080b9bcdcecc982ec14aa3a09dd531edbda6", + "transactions": [ + "0xf87582021508830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028c1bea227fe2612720656d69748718e5bb3abd109fa0ab1b2a24caee27f36c27c4b9d6146de80abc99d51fc459b4fa40c6639497beb1a035b0e865c5e6c2246bfb766bde2c9b9af8d1fa737efeda5f0c9c6594fa615739" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x0c047872d9588bf22e89ea7ec207e8be8486d0bfa775d147ea49b25a9847b3c6", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np585", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xb43bd5c412948cb43408ac47c85d080b9bcdcecc982ec14aa3a09dd531edbda6", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x7640efa3ea726c17a2a644d3f633e4872f488073eeb9d1d0fa7d6a76da8de37b", + "receiptsRoot": "0x005fb2a0d0c8a6f3490f9594e6458703eea515262f1b69a1103492b61e8d0ee2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x249", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x16da", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xfea440ef23de659e22508daedb4d4dd91a5bb39df9d3f039a24cde8ffa6527e4", + "transactions": [ + "0x02f86b870c72dd9d5e883e820216010882520894eda8645ba6948855e3b3cd596bbb07596d59c6030180c001a0143c22b16b7469abc885b8df50817d05005239f4a88f1e36dec1acd976aee532a0239432b2462737698c72307a848e65f79e2aaec778ee225064553b9cd6c47024" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x855d87626620858c83ac8ac407d521c183da8a43964f92d9b9285389f90a6d02", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np586", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xfea440ef23de659e22508daedb4d4dd91a5bb39df9d3f039a24cde8ffa6527e4", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x30298c9c7cdf0f7300b7e99e37cba2246fe79b05ff63d6cddf56f0e120e92a38", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x24a", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x16e4", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x5bda26af5e60d0a9bdccc94a59421b97f0d82cc828a117643b021ca4dbaa4372", + "transactions": [ + "0x01f86a870c72dd9d5e883e82021708825208945f552da00dfb4d3749d9e62dcee3c918855a86a00180c080a0066d4c75c7fa794a218f4da41cfe23b5ae88fd68d035e330accc26dfe734d3a3a0057990c5f8dd5982ab7701725beca4af30f550063e131145dc0469dc56e62a2f" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x7101dac063e1ce1cb178112d72d1b8abbd9615086ef636f6655d652e70f2aa64", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np587", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x5bda26af5e60d0a9bdccc94a59421b97f0d82cc828a117643b021ca4dbaa4372", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x3464c5fa5ece202889ee11c62b4a5ae4ddc886286f322b86fa5297f630750b77", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x24b", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x16ee", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xbd1d9841873dd0a26419f9a183a78370dedd826f922adeff78afef05811f8f71", + "transactions": [ + "0xf868820218088252089414e46043e63d0e3cdcf2530519f4cfaf35058cb201808718e5bb3abd109fa076571d850861e7b1df4aaa542979d07e265dcb85c2f6dff257793323843a1c40a05bd6105d6a281fd6b83642c6c3ccf034586fcc2e7acfd3128112ed3e1e05d7e0" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x506d8aa3d5c8509b51930509c98cf6f5badc86968812fe7ab2d4762d9352f4e3", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np588", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xbd1d9841873dd0a26419f9a183a78370dedd826f922adeff78afef05811f8f71", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x44d0fdb391789dad1ba58d79be1c608a15e0b85f0c56a3af181ac8d4b1c8a561", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x24c", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x16f8", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x5f40f6bc01be52c0a6f0f800c4120e73ae430d2a0e2cc6cfd6958ef33aad54e6", + "transactions": [], + "withdrawals": [ + { + "index": "0x34", + "validatorIndex": "0x5", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x95ea210881696a1062dddaf3b2b082b5c4bf40e8232113d7b86da72999b1d2ba", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np589", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x5f40f6bc01be52c0a6f0f800c4120e73ae430d2a0e2cc6cfd6958ef33aad54e6", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x8ac4b662fee7b371a7a1677ece50909770c14a335438a5d0a2c1b45b7c0c7e35", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x24d", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x1702", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x5528f6ef151d9a9f71dae57e39b1cd2c5c6e5c7e0cd3a419afbee06e313d9f47", + "transactions": [ + "0xf883820219088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a019c2fc75ed9320542c35ca28052512936b9954b33a2707282c709bd3103e6567a04f66fe0576ef6b87d76061f4b50262f2b410bd91ed81ed6ef20161440c302b75" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x0c83a90f2b9a311c3cd7c7643087802a075de0891995be8c92a6b6e1891778dc", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np590", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x5528f6ef151d9a9f71dae57e39b1cd2c5c6e5c7e0cd3a419afbee06e313d9f47", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x00b336f0e8aaf230ebe5b4cc09829786b2ccb66b49bafbd29cb019b16745cbe5", + "receiptsRoot": "0x2451e6fbb51a782a188493c5fe74bfcbb29e3e0ab32a5c3b0d4f12455ee15966", + "logsBloom": "0x00000000000100000800010000000000000000000000000020008000001000000000000000000000000001004000004000000000000000000000000000000000008000200000000050002000000000000080000000000200000000004000000000100000008000001000000000000000000000000000000000000400000000000000000000000000100000000000000000000000000000000020000000000000000000000000000000000000000000000000000008000000000000400001100000000000020000000000000000000000000001001000041000000000000000000000000000000000000000000200000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x24e", + "gasLimit": "0x23f3e20", + "gasUsed": "0xfc65", + "timestamp": "0x170c", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xdff8f0703a0840e4d227f77f46348869d6c8b8c30b872137b26a9e2842914410", + "transactions": [ + "0xf87a82021a0883011f588080a54360005260006020525b604060002060208051600101905260206020a15a612710106009578718e5bb3abd109fa081f24574bb6d5fd961496bf2911b1dff1157f69a39cbda71261b5812716324f9a0611602fa072852d98a4b658d42cb9be3ab41a857244cd38449a2ca2843cfb2b6" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xaa9ef93934d889062636008fcf4837d7b8d272bbd14e81b50b2248a4911d7c67", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np591", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0xdff8f0703a0840e4d227f77f46348869d6c8b8c30b872137b26a9e2842914410", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x8fd5156899dd8a8847796b80fae5cb28aa68432d14c7982faeb871c452efb7cb", + "receiptsRoot": "0x8e47c51ae3cc2e7f29232aac553163472046f2668ba19aa17733e156999a8234", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x24f", + "gasLimit": "0x23f3e20", + "gasUsed": "0x1d36e", + "timestamp": "0x1716", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x4ce9196d2fbc4bda9fcb9ab61e86167c9e1b547e873a7e5226f922b18db59953", + "transactions": [ + "0xf86582021b088302088a808090435b8080556001015a6161a8106001578718e5bb3abd10a0a07da1cc208fc8db65c8310f6a595651f7b9a44d36fb7855cfe1f3021236af7b12a0154d8dea9bb629b9574b8f738435b4a4d91b93637a0725247025d9353f4b5435" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x00f0c8a0bbba4bed135f2022b60bc785bd514b1c5b7f3db99c37124f5bcd403c", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np592", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x4ce9196d2fbc4bda9fcb9ab61e86167c9e1b547e873a7e5226f922b18db59953", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x2b1d33774c57b125dc481095f387ec1e12ffc071dbd98027f4aa545c74fe7b20", + "receiptsRoot": "0xb09954e33355e8b7fea3b4fba9111d225dfc44667568a936f3a27675f05b4555", + "logsBloom": "0x00000000000000000000010000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000210000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x250", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1720", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x5ba98af8b68bbf0d86879ec911858300293e7bbe347abc02548c5084ab5a0d3e", + "transactions": [ + "0x02f8d4870c72dd9d5e883e82021c0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cbf89b8d49503bdf3656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a05571137d48f7d081e62051a6bbca9d1e25c93ac6f84b7a3bc146f126ac80928d01a021b98f88ca8c35bd6d21a37b6a2519ec36c67c517cef173141ac82c2eeb611a0a021575bbda347f6e57138b220cce4ccd9664eaf6dece4b2f99045267c81da9a5e" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x08e29d129649f398887792f5fa5eff38572306a1efb3604008b74eca49c40774", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np593", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x5ba98af8b68bbf0d86879ec911858300293e7bbe347abc02548c5084ab5a0d3e", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xfed11f6990ebf4a1e995149d9531df1b9c75eb063347ee56a56b12cdca216ee7", + "receiptsRoot": "0x0656eac35536632b283e78d198105757c78d5ca745dd7c155d6f4e18b6c85f53", + "logsBloom": "0x00000000000000000000000000800000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x251", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x172a", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x3d33f3036b1399cf00cc8966e85b8553b5d7d4127ad121f382df765661a6627a", + "transactions": [ + "0x01f8d3870c72dd9d5e883e82021d08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cf395506d95a7654f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a0701960547b78067b00883157f5e9fca3bbea742385129f0db7e1e69ce445dfef01a0187066d8724b64ae34dee9c210e49d16ad5ba5b4c2341ebec15c6b5a4362c66ba02d3b474d88899bad59ba824935a87aec4c6b59660a6408728b157db70eb7d087" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x64fa01a0000ef58c90fac82ae28c33b45f947097be7cf43737d60e6568486204", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np594", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x3d33f3036b1399cf00cc8966e85b8553b5d7d4127ad121f382df765661a6627a", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xeb44311abb1ba7528b75d2454b74e669f9e3f62e7cf84642adafebca15c46a38", + "receiptsRoot": "0xc23ba9703a5d1c83cc099524b48c9c1f1d9cdb06c970a9d26200d8643a6f74ec", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000002400000000000000000000000000000004000000000000200000000000000000000000000002000000040000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x252", + "gasLimit": "0x23f3e20", + "gasUsed": "0xca9c", + "timestamp": "0x1734", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x3ed14e1e4d79669a7104b244f12d0dbbda1873230eddacca3ddf00d5e278be9b", + "transactions": [ + "0x03f8fa870c72dd9d5e883e82021e0108830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df038c8bb77ba856e3d12f656d6974f85bf859947dcd17433742f4c0ca53122ab541d0ba67fc27dff842a00000000000000000000000000000000000000000000000000000000000000000a048ca1081e747a7f831228b894dd5fc401d64c6496a2b9e578dd3c59b8f0df2cc83020000e1a0015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f6880a07968587982d4ec1553c6256dcd929997fae662a778950a5cedc82d409ece8f46a075a549540d89b304904d14d4af525bf0a6989a7c63602e5c5390da5451a0927c" + ], + "withdrawals": [], + "blobGasUsed": "0x20000", + "excessBlobGas": "0x0" + }, + [ + "0x015a4cab4911426699ed34483de6640cf55a568afc5c5edffdcbd8bcd4452f68" + ], + "0x18104f198e6c84cec4875b8b6d2734b6b9b8ce4bbbe158adfa81bfdb239595e2", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np595", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x3ed14e1e4d79669a7104b244f12d0dbbda1873230eddacca3ddf00d5e278be9b", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x415e45d750fdc4726e897237d64fb00fec0992a1323c4bce1af1d3d526ff8043", + "receiptsRoot": "0x7925339d2acc12b05a73a129f8b2737689c6336bd6e01f999c561249cbe6fe01", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000200000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000400000000009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x253", + "gasLimit": "0x23f3e20", + "gasUsed": "0xc268", + "timestamp": "0x173e", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x93a7231507f57e163e3b2e48a47132fc1eff83375b041b46a35e61a090ded25e", + "transactions": [ + "0xf87582021f08830186a0947dcd17433742f4c0ca53122ab541d0ba67fc27df028cdbc56807623499cf656d69748718e5bb3abd10a0a0d18bc40c1e3a5823d9f91a0b507e49b77eadf82ed88419fce974ac277690920ba053a0eacf14f315dc03e6bfc73c7d61571ebd6eaa67b5e7889c6ce1194bba7310" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x64f9ed7df2e19a503f0b6f5b79e4d7b512c66623c28887e7f8968750f081f06a", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np596", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x93a7231507f57e163e3b2e48a47132fc1eff83375b041b46a35e61a090ded25e", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x30a4cff5811cdeb2add55e03102e2cd5cc9e7750540d186bb4a2a165167401e7", + "receiptsRoot": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x254", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1748", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x42f57c5994becd0c778c625c4564b288f2ddd5523bf3505dcba11d4f31e317ea", + "transactions": [ + "0x02f86b870c72dd9d5e883e820220010882520894d803681e487e6ac18053afc5a6cd813c86ec3e4d0180c080a0061a9064cafcc779bebfc3410463e27e57ef4b69b13b063d79a9a258a363d917a0279a658e80bd6527683f521da84fd287422105c3bddeff127c20420dde99b7f6" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x020d16dfaa507ca4120cf799ddb20a8998f07a68b2dec691dc61a14e5c929b17", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np597", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x42f57c5994becd0c778c625c4564b288f2ddd5523bf3505dcba11d4f31e317ea", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x571f92dc76ef8c4ec47f5e496abe8c7182c5c4331537aeae052f95c2521b28c7", + "receiptsRoot": "0xd3a6acf9a244d78b33831df95d472c4128ea85bf079a1d41e32ed0b7d2244c9e", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x255", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x1752", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x05b8baa80ba3a0782ff6cade5129fb4e3cc8733de5d8da918d2338245ab76b6c", + "transactions": [ + "0x01f86a870c72dd9d5e883e82022108825208947435ed30a8b4aeb0877cef0c6e8cffe834eb865f0180c080a017fe88f6088755cd0167e286cff24eda1e4d2d4cdb035a966036882fc5ce8e92a045ead0434b8343a5db8eefa40b4f88b7191c771313a83550aae586d18be22036" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0x792b0101e0c969be7fda601c282846dbf3f1216b265d7086b3b1acd49882cce5", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np598", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x05b8baa80ba3a0782ff6cade5129fb4e3cc8733de5d8da918d2338245ab76b6c", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x6b8f10ea0c744a4333a8ba86f8204a648ba50145d4263af8d1ce8d35bfdcc6e3", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x256", + "gasLimit": "0x23f3e20", + "gasUsed": "0x5208", + "timestamp": "0x175c", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x7d4219f429001b5f014e933f9a36aa865d09955de79a8292aac8a00e75ba0f03", + "transactions": [ + "0xf86882022208825208941f5bde34b4afc686f136c7a3cb6ec376f735775901808718e5bb3abd10a0a0256584d11c94a5ec9fc723cbd9961e7a2569a48a23bc1eae505a74b46065f33ea0120d196163359143ae54697ae076c590ef82df3a89e275147f807fa12a9b34d9" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xc331bb6e00dfa4489c3cbe3840bd49c936bb3eb6ef0424f076e2b2a3215545ad", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np599", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x7d4219f429001b5f014e933f9a36aa865d09955de79a8292aac8a00e75ba0f03", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0x2335c84c9cbec7fa7456b92b69afcb95a075433eaacf4aea36c3eb4b9564a333", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x257", + "gasLimit": "0x23f3e20", + "gasUsed": "0x0", + "timestamp": "0x1766", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0x65151b101682b54cd08ba226f640c14c86176865ff9bfc57e0147dadaeac34bb", + "transactions": [], + "withdrawals": [ + { + "index": "0x35", + "validatorIndex": "0x5", + "address": "0x1f4924b14f34e24159387c0a4cdbaa32f3ddb0cf", + "amount": "0x64" + } + ], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xbf47e8a69bb557bccb9c04b516f1c68adaf982a10fdaada6bea4bb12cb40d818", + [] + ] + }, + { + "jsonrpc": "2.0", + "id": "np600", + "method": "engine_newPayloadV4", + "params": [ + { + "parentHash": "0x65151b101682b54cd08ba226f640c14c86176865ff9bfc57e0147dadaeac34bb", + "feeRecipient": "0x0000000000000000000000000000000000000000", + "stateRoot": "0xce423ebc60fc7764a43f09f1fe3ae61eef25e3eb8d09b1108f7e7eb77dfff5e6", + "receiptsRoot": "0xfe160832b1ca85f38c6674cb0aae3a24693bc49be56e2ecdf3698b71a794de86", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "prevRandao": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x258", + "gasLimit": "0x23f3e20", + "gasUsed": "0x19d36", + "timestamp": "0x1770", + "extraData": "0x", + "baseFeePerGas": "0x7", + "blockHash": "0xce8d86ba17a2ec303155f0e264c58a4b8f94ce3436274cf1924f91acdb7502d0", + "transactions": [ + "0xf883820223088301bc1c8080ae43600052600060205260405b604060002060208051600101905281526020016101408110600b57506101006040f38718e5bb3abd10a0a0b0889fe12fde37694f828cdb251c94d1e3abed2fd46e321ceb40d28e9747cb85a048aaf8240ecfb1382b4bc47b52ed705786f67b1ae71fbc2a00eb0169f43d0ec5" + ], + "withdrawals": [], + "blobGasUsed": "0x0", + "excessBlobGas": "0x0" + }, + [], + "0xf5003fc8f92358e790a114bce93ce1d9c283c85e1787f8d7d56714d3489b49e6", + [] ] } ] \ No newline at end of file diff --git a/cmd/devp2p/internal/ethtest/testdata/txinfo.json b/cmd/devp2p/internal/ethtest/testdata/txinfo.json index 8e1d917fb7..254b59d346 100644 --- a/cmd/devp2p/internal/ethtest/testdata/txinfo.json +++ b/cmd/devp2p/internal/ethtest/testdata/txinfo.json @@ -7,2329 +7,2813 @@ "contract": "0x17e7eedce4ac02ef114a7ed9fe6e2f33feba1667", "block": "0x2" }, + "deploy-callrevert": { + "contract": "0x0ee3ab1371c93e7c0c281cc0c2107cdebc8b1930", + "block": "0x3" + }, "randomcode": null, "randomlogs": null, "randomstorage": null, - "uncles": { - "11": { - "hashes": [ - "0x900edfd7e6de8a4a4ae18d2e7df829de69427e06eb9a381c3fe1e3002a750d75" - ] - }, - "16": { - "hashes": [ - "0x750eda0129037fbbcfcbfd6362a60ffbbc53a3f14ba9259cf2ac7f02da2a827c" - ] - }, - "21": { - "hashes": [ - "0x763d1a545e23079b4796461f2146cd3b24cc45ceab6e932db010bd2736e45403" - ] - }, - "26": { - "hashes": [ - "0x98180f6103a7e303444de4e152e81539ad614d0cd755e0e655715ab676d11e32" - ] - }, - "31": { - "hashes": [ - "0x04a8c9b6d23b2ada25bff618036c08bf6428fb35b89bce694607fac697f470e3" - ] - }, - "36": { - "hashes": [ - "0x9225da0395e14243f1e626b330ea8fe6afde356e50e8448936a29e1c203d661d" - ] - }, - "41": { - "hashes": [ - "0x74a80b9b13a264aff16e9156de67474c916de966327e9e1666fc2027e1bf63ad" - ] - }, - "46": { - "hashes": [ - "0xcf2bddf3649c7af6e9c8592aa5fad693f39f46369749e1c7127848d4ae9ff1ec" - ] - }, - "51": { - "hashes": [ - "0xeb31c29a94de8cf2fc3d0b80023b716fb5d31cc24d695d606eef2389705ade45" - ] - }, - "56": { - "hashes": [ - "0xb3a6af7632306e2dbd56b3bbf0e77d7b5c199053f348c74ce938afae615cd4fe" - ] - }, - "6": { - "hashes": [ - "0x97186bc5df663e72934212ab5a7b4449f07f12f44b267e119817791fe0ed66c5" - ] - }, - "61": { - "hashes": [ - "0x3a2cf075f456fcf264293a32d41f72506ad8cf9697d6b6d8ab3d8258cdaa90bd" - ] - }, - "66": { - "hashes": [ - "0x94d338db2e75740d17df19b0d8a111d5d68b2dfa38819b88929190b4b08b5993" - ] - }, - "71": { - "hashes": [ - "0xe9938f6ac90bc4dfdea315ed630b03ad9392b264d362ee1e1b2703fb3db5047a" - ] - } + "tx-eip7702": { + "account": "0xeda8645ba6948855e3b3cd596bbb07596d59c603", + "proxyAddr": "0x417fe11f58b6a2d089826b60722fbed1d2db96dd", + "authorizeTx": "0x09fd47ebbdfe396288c03b04fd643183097559faff558e5cfbf64cdc1a224d4c" }, - "valuetransfer": [ + "tx-emit-eip1559": [ { + "txhash": "0xaceca283c1a65deea29cfb78389fb2dc90df8ac9426d63d83c9fe67cb0cb7839", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "block": "0x7", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "nonce": "0x5", - "to": "0xca358758f6d27e6cf45272937977a748fd88391d", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x1c", - "r": "0x7252efaed5a8dbefd451c8e39a3940dc5c6a1e81899e0252e892af3060fd90ed", - "s": "0x30b6bd9550c9685a1175cece7f680732ac7d3d5445160f8d9309ec1ddba414be", - "hash": "0xd04f2bb15db6c40aaf1dcb5babc47914b5f6033b2925cb9daa3c0e0dab493fcb" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x3569f740e521d8bb11c5b72660dc96272ad66bfd811ed918c3a9e02acd4ade8f" }, { - "block": "0xc", + "txhash": "0xd463f0b9ea6530b1d24d8b8b7021979d48dac8452ed957fb722263a5a1b5ed08", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x9", - "to": "0xef6cbd2161eaea7943ce8693b9824d23d1793ffb", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x1160803ff1253dead1d84d68a06cb92fcbb265ddb0edb9a5200b28b8c834ce6b", - "s": "0x4f1f42c91a7b177f696fc1890de6936097c205f9dcd1d17a4a83ac4d93d84d9c", - "hash": "0x778450f223b07f789e343c18207a3388c01070c2f6a89506f2db4c656bc1a37f" - } + "block": "0x14", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xcb55d89f2ee070d017b426876d6072d91c2a7311ade9a1bed2f8200127ec380e" }, { - "block": "0x11", + "txhash": "0xe131203a45328fe320b0820698177e8ad2f3b3ee8c552787ddb1db725a2c4484", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xd", - "to": "0x4a64a107f0cb32536e5bce6c98c393db21cca7f4", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0xea20f9d952a58697ffb40cefcab9627f552c9658b3181498fd706418f89a3360", - "s": "0x4988596c88fe69f7d032df8e6f515a618a2c2e30f330febb3b548eb4fc1e8ca2", - "hash": "0xc2cffc70d847fbe50a53d618de21a24629b97e8dd4c1bcbf73979b2a48ee16df" - } + "block": "0x1f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x73286395f2a86bb5537d9b45ca7c681044645f31475a11d49285d6a0f028b8f0" }, { - "block": "0x16", + "txhash": "0x4cee3118350175e8ddab6edac9672440c672baea4c9eecd53e4dd411a978a990", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x11", - "to": "0x7cb7c4547cf2653590d7a9ace60cc623d25148ad", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x5f315b1989161bf29054e9e030a05b05b3d7efb4c60e39531b96af1690913f91", - "s": "0x6f1d8de5adad6f76ed0d2b4c6885d3a5502c12dae1d124b310e8c8856bd22099", - "hash": "0xfa9cd1e12446cd8c23fc76b0ae9beba0ebdc021aa87726b6febcd5ba4a504f01" - } - }, - { - "block": "0x1b", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x15", - "to": "0x77adfc95029e73b173f60e556f915b0cd8850848", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x148500c79a2f0d59158458da4e3b2a5ace441bf314942243c9e05da3457d394e", - "s": "0x2a83c5f921ffddd3c0b2a05999f820d1d03bce9ac9810941bb286c4db4ce9939", - "hash": "0xbfeeb9406545ede112801fe48aeaf30c8e2384739e8e585f1c0e726689abc4b8" - } - }, - { - "block": "0x20", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x19", - "to": "0x36a9e7f1c95b82ffb99743e0c5c4ce95d83c9a43", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x14346079d6d3690f923625efde8933b2ad99c2bfda9310983a21b60e3c261d3c", - "s": "0x501ae278f370f3c0283fb04f966b6c501cbee0ad4c784f4187e38fcc38a9ccbb", - "hash": "0x792614188c26e2f348ac3223813794c60de97b83a298e84f4bae51dda6de140c" - } - }, - { - "block": "0x25", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x1d", - "to": "0xbbf3f11cb5b43e700273a78d12de55e4a7eab741", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x86bc86521cc6091198253d75caf394a8e23fd4fb82b48236d29f81a95aeebec5", - "s": "0xae9de4ac4265e3f415514905d8f8c747c959771080fa031dc5fd9b7333ffc28", - "hash": "0xc44716fcd212d538b2d143ddec3003b209667bfc977e209e7da1e8bf3c5223b8" - } - }, - { "block": "0x2a", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x21", - "to": "0x684888c0ebb17f374298b65ee2807526c066094c", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x88fa9d9bbc92e44b8edcda67ee23aca611deac4cec336b215fb72547a1d0e07e", - "s": "0x297c4d7054cb545bee5221a70454b6270e098f39f91bf25c0526aa8c0a0a441c", - "hash": "0xc97ceb5b227ade5363592a68c39dcf1788abbf67b2440934b1ae11cf4b19417c" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x35f96bc70aa62a539fa99d9153b0f8aaa4594abf70cc8a8d9018e04e39a17982" }, { - "block": "0x2f", + "txhash": "0x0cdaf3e63a21eacdaf83b844b5ee98f7ea540667d68f6c527af01a8724bd23b1", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x25", - "to": "0x8a5edab282632443219e051e4ade2d1d5bbc671c", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x649b4ad4dcf07bcfba3dd7afd2ce220d0ae463c1bcc891ab1fcae84eca6fcc69", - "s": "0x5c69b0ad46c90eee811e4b71ce0aed22f479c207bee813dac8cce07e5a65adae", - "hash": "0xaf340a1b347c756a11e331e771d37d9205eada520f4f0d8d27f725d7c196aed1" - } + "block": "0x35", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xefcb86facadbec33b8779888975eacca8f44a9073a845521617f1fb30e1ac818" }, { - "block": "0x34", + "txhash": "0xd2a4dda75edef4c514a21ca9167f310fe3d296497ab78e66a2861d07dbe38585", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x29", - "to": "0x4b227777d4dd1fc61c6f884f48641d02b4d121d3", - "gas": "0x5208", - "gasPrice": "0x1", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x7d015036540013eb6aa141a2475fa1dd88d3bee57a67beaf6ef5de8f40969601", - "s": "0x4dc750a08f793ff3105479e7919508d14abe56748698375046b995d86267b18c", - "hash": "0x07a2a98ac904bcf4c17a773426b34d2b3120af65b12f9bfd437d48c175f364eb" - } + "block": "0x40", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x905cfe802dc4c667312ea08fdbe97798b88cfb11049ade2b18ad9001e8b6dd7c" }, { - "block": "0x39", + "txhash": "0xfeb2fe04b5241685c79ee42b624b2144a8c6e2871e12d2da75d39b03a9b9a950", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x2d", - "to": "0x19581e27de7ced00ff1ce50b2047e7a567c76b1c", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x27f555e9", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0xde8b08caa214d0087ffd11206d485cb5cde6a6b6a76b390f53d94a8c16691593", - "s": "0x14dfe16ec3e37b8c6d3257deaf987b70b0776b97e4213c1f912c367e7d558370", - "yParity": "0x1", - "hash": "0xa883c918fb6e392a2448ef21051482bfcbeb5d26b7ebfad2a010a40e188cb43b" - } + "block": "0x4b", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x0d968817f6ab6815faa1501ac1eafc810f4bc9b7423abc4f1bd5e65e791b4e0b" }, { - "block": "0x3e", + "txhash": "0x3d08d1fdf8a7b74fe2af54dcff575b87ff4c0203810df3647ba2a02793710b5e", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x31", - "to": "0x62b67e1f685b7fef51102005dddd27774be3fee3", - "gas": "0x5208", - "gasPrice": "0x14847701", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x6797c616a0fe0fad65b6020fc658541fd25577a3f0e7de47a65690ab81c7a34b", - "s": "0x115e6d138f23c97d35422f53aa98d666877d513dbe5d4d8c4654500ead1f4f8f", - "hash": "0xb2203865a1a1eace5b82c5154f369d86de851d8c5cd6a19e187f437a1ae28e94" - } + "block": "0x56", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa0634d80c0a702c2b06dfe60ace0d8f788b99406f1d2ac44ad3a26faa3fc1464" }, { - "block": "0x43", + "txhash": "0x8be5109fe8dddab4ee47ee4ea8e5c1973eeedcf13749be4e4fca93d9c0550a6e", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x35", - "to": "0x6b23c0d5f35d1b11f9b683f0b0a617355deb1127", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0xa88fcba", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0xdc3f3d86de44ee4dd795ff8ab480f4f5273c8ca61edb4c7561a369c80fbbb983", - "s": "0x43a90e087a6f5ba014e17316ec63b97a5a9ada19ab78177c87cb39ded9b37b0d", - "yParity": "0x0", - "hash": "0x647d637e54f1de1216cdfd83477a067308365c837c6c317febc9d3593907c7cc" - } + "block": "0x61", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x50495437ee69f7b12c5d6eb55cdcd8f5ce12a2eac21a2a42a7549e9f5289b1fb" }, { - "block": "0x48", + "txhash": "0x37d1d547768ea14ceef7274f5f24c8bfeabe795faf8626556a6688a4b72485a3", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x39", - "to": "0x44bd7ae60f478fae1061e11a7739f4b94d1daf91", - "gas": "0x5208", - "gasPrice": "0x568d2fa", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x50fc2310f542cf90b3376f54d296158f5be7ad852db200f9956e3210c0f8125c", - "s": "0x4f880fe872915a7843c37147a69758eff0a93cfaf8ce54f36502190e54b6e5c7", - "hash": "0x77050c3fb6b1212cf2f739f781b024b210177b3bcbd5b62e2b3c00f1d41764d1" - } + "block": "0x6c", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x59b1019e8b01471b1dd478e65c30667d2d1780ed0c8bf5fc784b1413789b2f82" }, { - "block": "0x4c", + "txhash": "0xf2fc33ca3b9e09c698e75ddef6db493d606edc4d36803966341cc0937be3dcb1", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x3d", - "to": "0x72dfcfb0c470ac255cde83fb8fe38de8a128188e", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x32ca5d0", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x116da1fc19daf120ddc2cc3fa0a834f9c176028e65d5f5d4c86834a0b4fe2a36", - "s": "0x17001c3ad456650dd1b28c12f41c94f50b4571da5b62e9f2a95dff4c8c3f61fd", - "yParity": "0x0", - "hash": "0x3e4639389b6a41ff157523860ffc77eb3e66a31aee867eb4148dcc5ee8b3c66f" - } + "block": "0x77", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x47cd31a1b89686fa610642222d2da6119e54ee8ca761bd01a649e3759e47746c" }, { - "block": "0x50", + "txhash": "0xe6cd7289688ee233a5cc20add1ce439e3faee022bb954c80b84b4ce3c84690d4", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x41", - "to": "0x5c62e091b8c0565f1bafad0dad5934276143ae2c", - "gas": "0x5208", - "gasPrice": "0x1dce189", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0xb82a5be85322581d1e611c5871123983563adb99e97980574d63257ab98807d5", - "s": "0xdd49901bf0b0077d71c9922c4bd8449a78e2918c6d183a6653be9aaa334148", - "hash": "0x9c9de14ea0ce069a4df1c658e70e48aa7baaf64fddd4ab31bf4cb6d5550a4691" - } - }, - { - "block": "0x55", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x45", - "to": "0xa25513c7e0f6eaa80a3337ee18081b9e2ed09e00", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0xf4dd50", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0xe8ac7cb5028b3e20e8fc1ec90520dab2be89c8f50f4a14e315f6aa2229d33ce8", - "s": "0x7c2504ac2e5b2fe4d430db81a923f6cc2d73b8fd71281d9f4e75ee9fc18759b9", - "yParity": "0x0", - "hash": "0xff5e3c25f68d57ee002b3b39229ffba0879390475a00fa67a679b707997df530" - } - }, - { - "block": "0x5a", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x49", - "to": "0xbbeebd879e1dff6918546dc0c179fdde505f2a21", - "gas": "0x5208", - "gasPrice": "0x7dbb16", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x2f0119acaae03520f87748a1a855d0ef7ac4d5d1961d8f72f42734b5316a849", - "s": "0x182ad3a9efddba6be75007e91afe800869a18a36a11feee4743dde2ab6cc54d9", - "hash": "0xd696adb31daca7c3121e65d11dc00e5d5fdb72c227c701a2925dc19a46fbd43e" - } - }, - { - "block": "0x5f", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x4d", - "to": "0xd2e2adf7177b7a8afddbc12d1634cf23ea1a7102", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x408f23", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x8556dcfea479b34675db3fe08e29486fe719c2b22f6b0c1741ecbbdce4575cc6", - "s": "0x1cd48009ccafd6b9f1290bbe2ceea268f94101d1d322c787018423ebcbc87ab4", - "yParity": "0x1", - "hash": "0x385b9f1ba5dbbe419dcbbbbf0840b76b941f3c216d383ec9deb9b1a323ee0cea" - } - }, - { - "block": "0x64", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x51", - "to": "0x18ac3e7343f016890c510e93f935261169d9e3f5", - "gas": "0x5208", - "gasPrice": "0x212636", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x99aba91f70df4d53679a578ed17e955f944dc96c7c449506b577ac1288dac6d4", - "s": "0x582c7577f2343dd5a7c7892e723e98122227fca8486debd9a43cd86f65d4448a", - "hash": "0xd622bf64af8b9bd305e0c86152721b0711b6d24abe3748e2a8cd3a3245f6f878" - } - }, - { - "block": "0x69", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x55", - "to": "0xde7d1b721a1e0632b7cf04edf5032c8ecffa9f9a", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x11056e", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x2a6c70afb68bff0d4e452f17042700e1ea43c10fc75e55d842344c1eb55e2e97", - "s": "0x27c64f6f48cfa60dc47bfb2063f9f742a0a4f284d6b65cb394871caca2928cde", - "yParity": "0x0", - "hash": "0x47efc21f94ef1ef4e9a7d76d9370713acdf8c2b822ad35409566b9251fb0bf5c" - } - }, - { - "block": "0x6e", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x59", - "to": "0x1b16b1df538ba12dc3f97edbb85caa7050d46c14", - "gas": "0x5208", - "gasPrice": "0x8bd6d", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xabbde17fddcc6495e854f86ae50052db04671ae3b6f502d45ba1363ae68ee62c", - "s": "0x3aa20e294b56797a930e48eda73a4b036b0d9389893806f65af26b05f303100f", - "hash": "0xcf4a0a2b8229fa2f772a90fdef00d073c821c8f56d93bce703007fc5eb528e71" - } - }, - { - "block": "0x73", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x5d", - "to": "0x043a718774c572bd8a25adbeb1bfcd5c0256ae11", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x47cdd", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x2ae4b3f6fa0e08145814f9e8da8305b9ca422e0da5508a7ae82e21f17d8c1196", - "s": "0x77a6ea7a39bbfe93f6b43a48be83fa6f9363775a5bdb956c8d36d567216ea648", - "yParity": "0x1", - "hash": "0xded7c87461fb84ffd49426b474741c2eace8982edf07af918bf8794415742384" - } - }, - { - "block": "0x78", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x61", - "to": "0x2d711642b726b04401627ca9fbac32f5c8530fb1", - "gas": "0x5208", - "gasPrice": "0x24deb", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xb4d70622cd8182ff705beb3dfa5ffa4b8c9e4b6ad5ad00a14613e28b076443f6", - "s": "0x676eb97410d3d70cfa78513f5ac156b9797abbecc7a8c69df814135947dc7d42", - "hash": "0x9e2b47fc494a2285f98c89949878e11f7c6d47d24ae95bdab2801333ea8d11a7" - } - }, - { - "block": "0x7d", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x65", - "to": "0xd10b36aa74a59bcf4a88185837f658afaf3646ef", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x12eea", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x882e961b849dc71672ce1014a55792da7aa8a43b07175d2b7452302c5b3cac2a", - "s": "0x41356d00a158aa670c1a280b28b3bc8bb9d194a159c05812fa0a545f5b4bc57b", - "yParity": "0x0", - "hash": "0x240efcc882536fad14fcd34be50b508cb4c39b39f1493b8d64682760505b6cf7" - } - }, - { "block": "0x82", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x69", - "to": "0xa5ab782c805e8bfbe34cb65742a0471cf5a53a97", - "gas": "0x5208", - "gasPrice": "0x9b8c", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x78e180a6afd88ae67d063c032ffa7e1ee629ec053306ce2c0eb305b2fb98245e", - "s": "0x7563e1d27126c9294391a71da19044cb964fd6c093e8bc2a606b6cb5a0a604ac", - "hash": "0xa28d808cbc5ef9e82cd5023ea542fab4052895618b8627c000bb8cc8ccc2e693" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x562f817652b4478bc1e434240cd21e00774a5a1210833cbf0225273e2b98bae2" }, { - "block": "0x87", + "txhash": "0xda6e57b6ed17f0591bb5313cc927800303bae5fcb20507a1eae0d5c24b4da809", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x6d", - "to": "0x4bfa260a661d68110a7a0a45264d2d43af9727de", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x4fe1", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0xbb105cab879992d2769014717857e3c9f036abf31aa59aed2c2da524d938ff8", - "s": "0x3b5386a238de98973ff1a9cafa80c90cdcbdfdb4ca0e59ff2f48c925f0ea872e", - "yParity": "0x1", - "hash": "0x83adc66f82e98155384ae9ef0e5be253eba9be959a50bcb48a7a3e6df97d6996" - } + "block": "0x8d", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb9f03edd278ccfc90e45785c1fea3f972618a32899f836dd4fe0e63eaf8c7c40" }, { - "block": "0x8c", + "txhash": "0x3e01b65976317255bd0ebd2ed6e506c7c44671e5786302052367a9d9c5fe1b70", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x71", - "to": "0x9defb0a9e163278be0e05aa01b312ec78cfa3726", - "gas": "0x5208", - "gasPrice": "0x2907", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x4adf7509b10551a97f2cb6262c331096d354c6c8742aca384e63986006b8ac93", - "s": "0x581250d189e9e1557ccc88190cff66de404c99754b4eb3c94bb3c6ce89157281", - "hash": "0x8e285b12f0ec16977055c8bc17008411883af1b5b33883a8128e50ed3e585685" - } + "block": "0x98", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x72be914df22404e1ed45a8224b52201a77605d52065746a00af5f60980fa4c99" }, { - "block": "0x91", + "txhash": "0xfc6bafe4ad86d5d2343cdcaa2d695050931b1d2a49a63e5be4deccd97b84bcaf", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x75", - "to": "0x7da59d0dfbe21f43e842e8afb43e12a6445bbac0", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x1513", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x6ca026ba6084e875f3ae5220bc6beb1cdb34e8415b4082a23dd2a0f7c13f81ec", - "s": "0x568da83b9f5855b786ac46fb241eee56b6165c3cc350d604e155aca72b0e0eb1", - "yParity": "0x0", - "hash": "0x41ca48c0312c6d3fc433f9fd363281dae924885f73ab7466f9e8c97d6ea3b993" - } + "block": "0xa3", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xff5c526fc525d03cecce39f4ec167af09f80525e2d44e60ee4df33a357b24ed2" }, { - "block": "0x96", + "txhash": "0x687bb7707e54385064c6b22425f9ad06fa0377ee68b8bab7ffe34f592c79b8d5", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x79", - "to": "0x84873854dba02cf6a765a6277a311301b2656a7f", - "gas": "0x5208", - "gasPrice": "0xad4", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0xab3202c9ba5532322b9d4eb7f4bdf19369f04c97f008cf407a2668f5353e8a1f", - "s": "0x5affa251c8d29f1741d26b42a8720c416f7832593cd3b64dff1311a337799e8f", - "hash": "0x7527f1a2c9cad727c70ca0d2117fc52dbfff87962411d0b821e7418a42abd273" - } + "block": "0xae", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x87fc0239418406958902bcd8e059f9ddc08fb2683a4be0cfd47b1eb97418be1e" }, { - "block": "0x9b", + "txhash": "0x20add83f7f234cace1af3d3bfc50e28ad885767711f4a143f397b09359999353", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x7d", - "to": "0x8d36bbb3d6fbf24f38ba020d9ceeef5d4562f5f2", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x592", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0xf9075613b9069dab277505c54e8381b0bb91032f688a6fe036ef83f016771897", - "s": "0x4cb4fc2e695439af564635863f0855e1f40865997663d900bc2ab572e78a70a2", - "yParity": "0x1", - "hash": "0xab2e87692b96ba3083b497227a9a17671bc5eee7ff12d50b850f442a4cdcd8b5" - } - }, - { - "block": "0xa0", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x81", - "to": "0xc19a797fa1fd590cd2e5b42d1cf5f246e29b9168", - "gas": "0x5208", - "gasPrice": "0x2de", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x857754afc3330f54a3e6400f502ad4a850a968671b641e271dcb9f68aacea291", - "s": "0x7d8f3fb2f3062c39d4271535a7d02960be9cb5a0a8de0baef2211604576369bf", - "hash": "0x64f8f0ad9c6526cb33e626626a25b8660a546aefa002692e46cd4d0331cd26ed" - } - }, - { - "block": "0xa5", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x85", - "to": "0x6922e93e3827642ce4b883c756b31abf80036649", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x17b", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x89e6d36baf81743f164397205ded9e5b3c807e943610d5b9adb9cfeb71b90299", - "s": "0x3d56c57f842a92a5eb71c8f9f394fe106d993960421c711498013806957fdcaf", - "yParity": "0x0", - "hash": "0x33b886e4c1c43507a08f0da97d083aa507cf905a90c17ffe20a2a24296f2db31" - } - }, - { - "block": "0xaa", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x89", - "to": "0xbceef655b5a034911f1c3718ce056531b45ef03b", - "gas": "0x5208", - "gasPrice": "0xc5", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x626dfd18ca500eedb8b439667d9b8d965da2f2d8ffcd36a5c5b60b9a05a52d9f", - "s": "0x7271175e4b74032edeb9b678ffb5e460edb2986652e45ff9123aece5f6c66838", - "hash": "0xe92638806137815555a0ffe5cc4c2b63b29171fd6f2473736201d8c3c3dbb748" - } - }, - { - "block": "0xaf", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x8d", - "to": "0x5a6e7a4754af8e7f47fc9493040d853e7b01e39d", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x68", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x8c62285d8318f84e669d3a135f99bbfe054422c48e44c5b9ce95891f87a37122", - "s": "0x28e75a73707ee665c58ff54791b62bd43a79de1522918f4f13f00ed4bd82b71b", - "yParity": "0x1", - "hash": "0x3f9133ad0b7430b124cc4b1213bc3fa72be41a58584ca05e8d863ec728890873" - } - }, - { - "block": "0xb4", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x91", - "to": "0x27952171c7fcdf0ddc765ab4f4e1c537cb29e5e5", - "gas": "0x5208", - "gasPrice": "0x39", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x76a045602a7de6b1414bdc881a321db0ce5255e878a65513bad6ac3b7f473aa7", - "s": "0x1a33017b5bcf6e059de612293db8e62b4c4a3414a7ba057c08dd6172fb78a86c", - "hash": "0x201f5041569d4dd9e5cc533867f1864daf1a7ee1a424d703d7aa8a43b07b491d" - } - }, - { "block": "0xb9", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x95", - "to": "0x04d6c0c946716aac894fc1653383543a91faab60", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x20", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x39c18634a9f085ba0cd63685a54ef8f5c5b648856382896c7b0812ee603cd8a", - "s": "0x5ecfde61ea3757f59f0d8f0c77df00c0e68392eea1d8b76e726cb94fb5052b8a", - "yParity": "0x0", - "hash": "0xf83394fd19018fd54a5004121bc780995f99cb47832ddb11f7c50bf507606202" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x85c0042b81b23b846d1e4881b0131b4bbff774dd9bdece2e74fa92ebdb053c34" }, { - "block": "0xbe", + "txhash": "0x5133df1193a2f8e63c0eee29b4cf93edad7b35ec68e5bdd214d959096b330aa2", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x99", - "to": "0x478508483cbb05defd7dcdac355dadf06282a6f2", - "gas": "0x5208", - "gasPrice": "0x13", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x910304dbb7d545a9c528785d26bf9e4c06d4c84fdb1b8d38bc6ee28f3db06178", - "s": "0x2ffc39c46a66af7b3af96e1e016a62ca92fc5e7e6b9dbe631acbdc325b7230a1", - "hash": "0x586f6726554ffef84726c93123de9fb1f0194dfd55ed7ca3ceae67e27b1f4fef" - } + "block": "0xc4", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x32984cfbb954e0815427570f4ceaef21a3691026950e5ad80401232f687620e7" }, { - "block": "0xc3", + "txhash": "0xa2c5369f2abed72c2a9826e79228b372e4b1a387e5832965af5d0d874df68576", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x9d", - "to": "0xae3f4619b0413d70d3004b9131c3752153074e45", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0xc", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x7cb73f8bf18eacc2c753098683a80208ac92089492d43bc0349e3ca458765c54", - "s": "0x3bf3eb6da85497e7865d119fde3718cdac76e73109384a997000c0b153401677", - "yParity": "0x1", - "hash": "0xadfacbcb99b52f33c74cbd7c45d1f0d31efc4a3f025f9832cf28e666c79c8e4c" - } + "block": "0xcf", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xd34d30c2584168001b907965762f784cb4337381aa8090ae36bc66bd515849b5" }, { - "block": "0xc8", + "txhash": "0x82abb81ce6873ac4e3dda7b2276c80923283f8a43671eed167b41720f6bdbb27", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xa1", - "to": "0x7c5bd2d144fdde498406edcb9fe60ce65b0dfa5f", - "gas": "0x5208", - "gasPrice": "0x9", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x15f510b05236b83a9370eb084e66272f93b4b646e225bdef016b01b3ac406391", - "s": "0x3b4a2b683af1cb3ecae367c8a8e59c76c259ce2c5c5ffd1dc81de5066879e4b8", - "hash": "0xed00ce6bd533009ddfb39d7735f1e2c468a231cf4c5badb59d1e1234c5fe3794" - } + "block": "0xda", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x3982f6a73961b17f67a84959ebc42a5a3ebdd1faa925399f3f276cc2de65f2fb" }, { - "block": "0xcd", + "txhash": "0x302d4582613dfd96d4c9e18bfecb1017f40a8d8313ef13356e1885575d21622f", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xa5", - "to": "0x9a7b7b3a5d50781b4f4768cd7ce223168f6b449b", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x4f3e818870a240e585d8990561b00ad3538cf64a189d0f5703a9431bc8fd5f25", - "s": "0x312f64dd9ab223877e94c71d83cb3e7fe359b96250d6a3c7253238979dd2f32a", - "yParity": "0x0", - "hash": "0x883c915c1ef312df1e499ef78d09767a374706d8ec89af9c65c46acd675bf817" - } + "block": "0xe5", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x782a285a3a645a32202a71e713e4a813bbaef9f50ce10e4caa0122c110d86bf6" }, { - "block": "0xd2", + "txhash": "0xaab104ba3538ee8a11349279ac0ba9374cff8b325fbbadab6bac24828f297a49", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xa9", - "to": "0x85f97e04d754c81dac21f0ce857adc81170d08c6", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x547e9550b5c687a2eb89c66ea85e7cd06aa776edd3b6e3e696676e22a90382b0", - "s": "0x28cb3ab4ef2761a5b530f4e05ef50e5fc957cfbc0342f98b04aa2882eec906b2", - "hash": "0x27d83955c23134e42c9beaa88332f770d09e589354c1047870328b7a2f8612c9" - } - }, - { - "block": "0xd7", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xad", - "to": "0x414a21e525a759e3ffeb22556be6348a92d5a13e", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x47b3309af68dd86089494d30d3356a69a33aa30945e1f52a924298f3167ab66", - "s": "0xb8b7bd6670a8bbcb89555528ff5719165363988aad1905a90a26c02633f8b9", - "yParity": "0x1", - "hash": "0xb75adb0bd26a8060f67c947b699471d71a66c61f2b8c6903a776c3eca7ad731e" - } - }, - { - "block": "0xdc", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xb1", - "to": "0xfb95aa98d6e6c5827a57ec17b978d647fcc01d98", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0xc71a69f756a2ef145f1fb1c9b009ff10af72ba0ee80ce59269708f917878bfb0", - "s": "0x3bfe6a6c41b3fe72e8e12c2927ee5df6d3d37bd94346a2398d4fcf80e1028dde", - "hash": "0x0301d78cc4bc0330c468026de4671377a07560c2356293c2af44334e6424361a" - } - }, - { - "block": "0xe1", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xb5", - "to": "0xf031efa58744e97a34555ca98621d4e8a52ceb5f", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x99b1b125ecb6df9a13deec5397266d4f19f7b87e067ef95a2bc8aba7b9822348", - "s": "0x56e2ee0d8be47d342fe36c22d4a9be2f26136dba3bd79fa6fe47900e93e40bf3", - "yParity": "0x1", - "hash": "0x6e07cf26de1881f062629d9efa026c55b9e8084082086e974ddeb66654cd9530" - } - }, - { - "block": "0xe6", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xb9", - "to": "0x0a3aaee7ccfb1a64f6d7bcd46657c27cb1f4569a", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xd2aa10777b7c398921921258eeecaff46668278fd6f814ea4edb06f2a1076353", - "s": "0x542ef4ed484a1403494238e418bb8d613012871710e72dde77bb1fa877f1fae3", - "hash": "0xd77aeb22fbd8f99b75c970995d226b6985f2dcac6f22d65aa5d492d66e90f53f" - } - }, - { - "block": "0xeb", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xbd", - "to": "0xf8d20e598df20877e4d826246fc31ffb4615cbc0", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0xc982933a25dd67a6d0b714f50be154f841a72970b3ed52d0d12c143e6a273350", - "s": "0x7a9635960c75551def5d050beee4014e4fef2353c39d300e649c199eebc8fd5e", - "yParity": "0x1", - "hash": "0x597bc815e8b0c315e692257aabe4ecfce7055fa3659f02dd8444c7d58c9055f3" - } - }, - { "block": "0xf0", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xc1", - "to": "0xfde502858306c235a3121e42326b53228b7ef469", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x3d79397e88a64f6c2ca58b5ec7ba305012e619331946e60d6ab7c40e84bf1a34", - "s": "0x4278773d2796a0944f6bedadea3794b7ad6a18ffd01496aabf597d4a7cf75e17", - "hash": "0xe9c1c01813ee52f2a9b8aa63e200714c7527315caf55d054890c10acc73c6cec" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x44dc9099d91b074b843002013672df4de9f691cf60546fa74eccafa9044a75a2" }, { - "block": "0xf5", + "txhash": "0xc6c2d288432ce16555d12b522398b07beb749eb44f6162c4d71c90670b59df79", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xc5", - "to": "0x27abdeddfe8503496adeb623466caa47da5f63ab", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0xdeade75f98612138653ca1c81d8cc74eeda3e46ecf43c1f8fde86428a990ae25", - "s": "0x65f40f1aaf4d29268956348b7cc7fa054133ccb1522a045873cb43a9ffa25283", - "yParity": "0x1", - "hash": "0x2beff883cd58f8d155069d608dfc47f730a07f1ed361987b008c17a4b8b84a4b" - } + "block": "0xfb", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x1bf804b21bbd284f3f59e4862747fabb1d91cd202d99df811fbcd650c8916ef1" }, { - "block": "0xfa", + "txhash": "0x205e93a639805b8104b073a1aac798821403d8deeac62a463f934df64907808f", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xc9", - "to": "0xaa7225e7d5b0a2552bbb58880b3ec00c286995b8", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x968ae76ffc10f7b50ca349156119aaf1d81a8772683d1c3ed005147f4682694", - "s": "0x60f5f10a015e8685a3099140c2cc3ba0dc69026df97fb46748008c08978d162a", - "hash": "0x084d5438c574a2332976d95cfae552edb797001b5af69eacf4486538ab4bdbd2" - } + "block": "0x106", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x628887ea9304aeb7f3934543b9d14ab4e7e5cd422ba572d39d6ee10c33045345" }, { - "block": "0xff", + "txhash": "0x64e12e4bcceab36795d18fa5758676bd96d4f6ae943c206bba9782dc96c3ef6b", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xcd", - "to": "0xa8100ae6aa1940d0b663bb31cd466142ebbdbd51", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x54eafef27c71a73357c888f788f1936378929e1cdb226a205644dc1e2d68f32b", - "s": "0x59af490b8ef4a4e98a282d9046655fc8818758e2af8ace2489927aaa3890fda3", - "yParity": "0x0", - "hash": "0xecce661913425dbe38e2d30e7ec20ead32185d76f516525148d2647ee94aac8e" - } + "block": "0x111", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xee181b97fd68754f6245c655a0a0686e8d12aa4eac5f1d059e7e3b8d6a924073" }, { - "block": "0x104", + "txhash": "0xfce43c4ea272fb22e6443782eee4d50c567c17e7e9def4573569778f0ac8558a", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xd1", - "to": "0xa8d5dd63fba471ebcb1f3e8f7c1e1879b7152a6e", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x4c1d18013fb8b0554b8aaa549ee64a5a33c98edd5e51257447b4dd3b37f2ade", - "s": "0x5e3a37e5ddec2893b3fd38c4983b356c26dab5abb8b8ba6f56ac1ab9e747268b", - "hash": "0x0d903532e3740a8fb644943befee0187e6180eb31a327afc73e042ec314c02cc" - } + "block": "0x11c", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xf0ca8a88096a033508993a424f4e40ee1d800f62390dfe4ed5dd74a0f6785e25" }, { - "block": "0x109", + "txhash": "0x92457c1dd22ebbf0c6b477646b4efa376d5f5c4a55b8cc267e84304b61ca2449", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xd5", - "to": "0xac9e61d54eb6967e212c06aab15408292f8558c4", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x898d514a1f15103335e066d0625c4ec34a69a03480d67dcb3d3fe0f4f932100a", - "s": "0x7e130fed862c1482467d112f64fb59e005068b52c291003c908b625b4993e20e", - "yParity": "0x1", - "hash": "0xdd62d8c48dd14b156b3ea74d123fe3ddd7bc7700d0f189df3761ec7a8d65d1e9" - } - }, - { - "block": "0x10e", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xd9", - "to": "0x653b3bb3e18ef84d5b1e8ff9884aecf1950c7a1c", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xf1c5d5e335842170288da2c7c7af6856ea0b566d2b4ab4b00a19cb94144d466c", - "s": "0x2043677d1c397a96a2f8a355431a59a0d5c40fc053e9c45b6872464f3c77c5dc", - "hash": "0x284452da997f42dbe0e511078f5005514fdeda8d0905439fe2f3a5ecc3aec1ac" - } - }, - { - "block": "0x113", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xdd", - "to": "0xd8c50d6282a1ba47f0a23430d177bbfbb72e2b84", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x4330fe20e8b84e751616253b9bccc5ff2d896e00593bfbef92e81e72b4d98a85", - "s": "0x7977b87c7eca1f6a8e4a535cb26860e32487c6b4b826623a7390df521b21eac7", - "yParity": "0x1", - "hash": "0xd667f29e2cccf282a82791cb46f9181ad04c8179bc11af957c499b3627907a6f" - } - }, - { - "block": "0x118", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xe1", - "to": "0xb519be874447e0f0a38ee8ec84ecd2198a9fac77", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xcfbd9ff7eeb9aef477970dcba479f89c7573e6167d16d0882ead77b20aaee690", - "s": "0x1e34175b1b1758a581ca13f2ca021698933b1e8269c70fcb94c5e4aa39ee9b8e", - "hash": "0x935596bc447ea87dca90e3bac15f679129af2c813abe1657811f70dcafe660c2" - } - }, - { - "block": "0x11d", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xe5", - "to": "0xaf2c6f1512d1cabedeaf129e0643863c57419732", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0xc23170a740ba640770aca9fb699a2799d072b2466c97f126a834d86bdb22f516", - "s": "0x3f242217b60ab672f352ae51249a8876a034ee51b6b4ad4a41b4d300c48e79f4", - "yParity": "0x1", - "hash": "0xc659a1be386492afe2ca97cbbe9d1645763b502030c17e3acf9d539e22b74093" - } - }, - { - "block": "0x122", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xe9", - "to": "0xb70654fead634e1ede4518ef34872c9d4f083a53", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x953d5aa69077225dba6a0333ea4d69a05f652e0d2abb8df492a7e6a9d0cdbe3d", - "s": "0x4e41cb847aa131b9bb1e19cb3dd5f7a6cc2ac8b7f459ab8c3061380d41721ff", - "hash": "0x6f7f93620049c80ba6429e3c2f7563f7048f725f245c22bcc6de438fd394bb7e" - } - }, - { "block": "0x127", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xed", - "to": "0xbe3eea9a483308cb3134ce068e77b56e7c25af19", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x190737acd3a2a298d5a6f96a60ced561e536dd9d676c8494bc6d71e8b8a90b60", - "s": "0x2c407a67004643eba03f80965fea491c4a6c25d90d5a9fd53c6a61b62971e7c5", - "yParity": "0x0", - "hash": "0xe48311c620199dfc77bc280caa0a1bcbbd00457b079a7154a6f8bc229beb41f1" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xd2dcfcdea157f70f8422558eb02bdc6a503cf24126f8f2dc2b52a644f5f02271" }, { - "block": "0x12c", + "txhash": "0x99a7fc49256d1f8092db5990270645ab9a4d96b49fb9224bafe6fddb7f6f86f0", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xf1", - "to": "0x08037e79bb41c0f1eda6751f0dabb5293ca2d5bf", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xe3edf14f32e7cacb36fd116b5381fac6b12325a5908dcec2b8e2c6b5517f5ec5", - "s": "0x51429c4c1e479fa018b7907e7e3b02a448e968368a5ce9e2ea807525d363f85e", - "hash": "0xa960e3583c41a164dc743eac939626f891f20f7dfdf71f204c2f84ca1087ae90" - } + "block": "0x132", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4d4855c520c09f3435e2cb46ceb4d2a12df59c127a1f2e871e7e9e8203fd6ce1" }, { - "block": "0x131", + "txhash": "0xcf272615d5e4bf4555cf867154234f5df2e230442c1c87508c051e407e2811d7", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xf5", - "to": "0xf16ba6fa61da3398815be2a6c0f7cb1351982dbc", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x8dac03d829e6f8eab08661cd070c8a58eed41467ad9e526bb3b9c939e3fd4482", - "s": "0x2ac7208f150195c44c455ddeea0bbe104b9121fef5cba865311940f4de428eec", - "yParity": "0x1", - "hash": "0xc7ccef252840e9fc1821f2c2eb0ca8c9508ff3f4c23f85322e09dd9313849694" - } + "block": "0x13d", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x8a76d1e2fd58cc0018aa306e83990d74d16ba9aeab4794595fc72551f0465476" }, { - "block": "0x136", + "txhash": "0x26501c0425d7865224b5b38b85ec90d07881f213813c81f85aa863c94109bd64", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xf9", - "to": "0x17333b15b4a5afd16cac55a104b554fc63cc8731", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xf2179ec11444804bb595a6a2f569ea474b66e654ff8d6d162ec6ed565f83c1aa", - "s": "0x657ed11774d5d4bb0ed0eb1206d1d254735434a0c267912713099336c2dc147a", - "hash": "0x45ed5258df6ecd5ba8b99db384e39d22c193662830e79f972547d81e3857cc70" - } + "block": "0x148", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x7a63090121e41c76eee07564883abe3bd839fb20a0d2513bc9bc524f6c16f88a" }, { - "block": "0x13b", + "txhash": "0x49249dfc575b61369ae47f58f81cd66315038672a912cb900babfa535e52ed9f", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0xfd", - "to": "0xd20b702303d7d7c8afe50344d66a8a711bae1425", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x67bed94b25c4f3ab70b3aae5cd44c648c9807cdf086299e77cf2977b9bce8244", - "s": "0x76661b80df9b49579fce2e2201a51b08ecc4eb503d5f5517ecb20156fde7ec5a", - "yParity": "0x1", - "hash": "0xa3b085cc524be64d822be105f3bb92c05c773cb93bffc774ba9aac21f9603ce6" - } + "block": "0x153", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xc4f8d20ccba0b50d46d9c87f28cebf8c165fced694a2b34412a4b6153b987a17" }, { - "block": "0x140", + "txhash": "0x0f88d2f5193f44c1595c53019d68fce6fe715e2f9aa8fa4edd751546cbc21475", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x101", - "to": "0xdd1e2826c0124a6d4f7397a5a71f633928926c06", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x1f5208621cee9149c99848d808ee0fa8d57b358afbd39dc594f383b7f525f4c6", - "s": "0x1960c6254e869f06cfa3263972aa8e7cc79aec12caa728515c420d35b1336c0e", - "hash": "0x34671329e36adeee3261ea7313388804f481e6a0e2f77cce6961aed112498803" - } - }, - { - "block": "0x145", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x105", - "to": "0x1219c38638722b91f3a909f930d3acc16e309804", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x63adb9abb5014935b3dbf8c31059d6f1d9e12068a3f13bd3465db2b5a7f27f98", - "s": "0x56f0f5bed39985d0921989b132e9638472405a2b1ba757e22df3276ca9b527fa", - "yParity": "0x1", - "hash": "0x7bfa3e961b16291e9ee2f4dc0b6489bb0b12ff7a6ed6491c100dd1041472ff9e" - } - }, - { - "block": "0x14a", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x109", - "to": "0x1f5746736c7741ae3e8fa0c6e947cade81559a86", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xedd3402a6c7a96114e4c8520d7bf3f06c00d9f24ee08de4c8afdbf05b4487b7d", - "s": "0x68cd4cf2242a8df916b3594055ee05551b77021bbea9b9eb9740f9a8e6466d80", - "hash": "0x90ea391ff615d345ad4e35e53af26e283fc2fd9ecb3221a9610fb2a376c38caf" - } - }, - { - "block": "0x14f", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x10d", - "to": "0x9ae62b6d840756c238b5ce936b910bb99d565047", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x25cc19f12be3ff2a51342412dc152953e8e8b61c9c3858c9d476cc214be4e30", - "s": "0x193960b0d01b790ef99b9a39b7475d18e83499f1635fc0a3868fc67c4da5b2c3", - "yParity": "0x0", - "hash": "0xa1ea0831d6727a0e7316822d3cc3815f1e2ba71e124fcd8b886610d5d42fd5ff" - } - }, - { - "block": "0x154", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x111", - "to": "0xb55a3d332d267493105927b892545d2cd4c83bd6", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x73cc84153b8891468325ac12743faf7e373b78dbf8b9f856cb2622c7b4fd10e1", - "s": "0x388714fe9d2f85a88b962e213cbe1fa3c4a9823cea051cf91c607ecbd90093d8", - "hash": "0xd30ff6e59e0e1278dab8083cb01e1e66900adc72cc4263cbdffc98e08a728b89" - } - }, - { - "block": "0x159", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x115", - "to": "0xb68176634dde4d9402ecb148265db047d17cb4ab", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x9f3175e9aa2fe2332600b71de0b0977c7c60ccbeee66ea360226326817f2d59b", - "s": "0x6a870e0876002f789b3203f4a33d5e621ac67051704e1f2260b80d816260b3e6", - "yParity": "0x0", - "hash": "0x5565d4f07ad007f4bfe27837904f2ce365cff6c036aa5169df651f217944b1f4" - } - }, - { "block": "0x15e", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x119", - "to": "0xdfe052578c96df94fa617102199e66110181ed2c", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x20ee6a1ada31c18eac485e0281a56fc6d8c4152213d0629e6d8dd325adb60b1", - "s": "0xf72e01c463b98817219db62e689416c510866450efc878a6035e9346a70795f", - "hash": "0x9055a34f1c764ce297f1bce6c94680a0e8d532debeb6af642c956122f4c7d079" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4b916e15bdb0f5b4bccaa3447694db53cc34095b5bc26299c14a9f573bd6c758" }, { - "block": "0x163", + "txhash": "0xa164fc90c20e70842b76427eaca6ef266fa3ba71e933c5ce9df68d2e817f6197", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x11d", - "to": "0x33fc6e8ad066231eb5527d1a39214c1eb390985d", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x167190e2e0fed95ab5c7265a53f25a92d659e1d46eb9ecbac193e7151b82ec1c", - "s": "0x269353e9c5ef331135563e2983279669220687652e7f231725303ccf7d2a8ebd", - "yParity": "0x1", - "hash": "0x0aa77f1fa0e9ab541616fb3104788109f84010d4b410508e5779f052ee49c5b9" - } + "block": "0x169", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x7975cc1088361453b019ff19e2177b264cfea56f4c09b1a8a086f6c405dd516c" }, { - "block": "0x168", + "txhash": "0x25b5c50473f34a2940ccccf2080dbd466a264e936c2a38ee6b1410ee4d5798e5", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x121", - "to": "0x662fb906c0fb671022f9914d6bba12250ea6adfb", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0xd3a858be3712102b61ec73c8317d1e557043f308869f4a04e3a4578e2d9aa7e7", - "s": "0x202a5f044cc84da719ec69b7985345b2ef82cf6b0357976e99e46b38c77fe613", - "hash": "0x01bdc2fb7f53293c98e430dc42b1ef18773493f0f1bd03460eb45e438168048d" - } + "block": "0x174", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x5423899586eb1d932cb9da03e478e1dd5d4cbbcb66d24262c7d67e543185c2ef" }, { - "block": "0x16d", + "txhash": "0x14f08427a199620151f7cbe9d4d4a6a6b087e41e294e80ac23d7bb89e9100378", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x125", - "to": "0xf1fc98c0060f0d12ae263986be65770e2ae42eae", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x6563737b6bfddfb8bc5ec084651a8e51e3b95fe6ed4361065c988acaf764f210", - "s": "0xa96a1747559028cd02304adb52867678419ebef0f66012733fea03ee4eae43b", - "yParity": "0x0", - "hash": "0x36cf0f21e046b484333889a22e4880ad05807f2922340e6e822591cfa5138815" - } + "block": "0x17f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x187c8bbc8cd3f478b5688bc03cf5eda82ee75aa605e946b39ed1898f0cc0e00f" }, { - "block": "0x172", + "txhash": "0x5b5626eb904ccbd5e3f96a12ae819a7997238d6950a6eead7e55171e9c8aab3f", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x129", - "to": "0xa92bb60b61e305ddd888015189d6591b0eab0233", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x626bd8978288bcf1d7719926fba91597d6aa8ead945c89044693d780523a05dd", - "s": "0x74494ccf5362aa73db798940296b77b80a7ec6037f5ed2c946094b9df8a2347", - "hash": "0x8cb5e311a3e79a31c06afaecbbf9c814759f039f55b06ead4e8a1c2933766c8c" - } + "block": "0x18a", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x1bf8eef1506aea16c94dd534ab271dfdae26648de569b3bf6fc8bf4c76bd1a99" }, { - "block": "0x177", + "txhash": "0xece63f7c604356e632fdd80e92222629c86f470612feabf2e7059fdb7d09a11d", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x12d", - "to": "0x469542b3ece7ae501372a11c673d7627294a85ca", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x9add65921c40226ee4a686b9fa70c7582eba8c033ccc9c27775c6bc33c9232fb", - "s": "0x21a6e73ccb2f16e540594b4acbba2c852a3e853742359fcbc772880879fe1197", - "yParity": "0x0", - "hash": "0x55c8ee8da8d54305ca22c9d7b4226539a60741ed599327d33013f8d0385c61bd" - } - }, - { - "block": "0x17c", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x131", - "to": "0x7f2dce06acdeea2633ff324e5cb502ee2a42d979", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xfd195ea41804b21ffffdbca38fd49a9874371e51e81642917d001d201a943e24", - "s": "0x542bca46a2dc92fddb9abffcf2b3e78dc491d6e95040692e6d1446a6b487a42a", - "hash": "0x3964c50008f0dce6974ef2c088a84207191eb56ab4ac86cbf5d149a661ecb479" - } - }, - { - "block": "0x181", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x135", - "to": "0x3bcc2d6d48ffeade5ac5af3ee7acd7875082e50a", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x3931e5e7d02ed045834da39a409083c260fbc96dc256c1d927f1704147eeaeb6", - "s": "0x215269010bb3e7dd8f03d71db3e617985b447c2e0dd6fc0939c125db43039d0f", - "yParity": "0x0", - "hash": "0x23583194a4443b0144115327770bf71f645283515ca26fc775dd23244a876e83" - } - }, - { - "block": "0x186", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x139", - "to": "0xf83af0ceb5f72a5725ffb7e5a6963647be7d8847", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xa38cf9766454bd02d4f06f5bd214f5fe9e53b7a299eda5c7523060704fcdb751", - "s": "0x67c33351f6f7bbd9de5b5435f6cadc10ba5e94f3cbcc40ee53496c782f99d71f", - "hash": "0x41019c72018f2f499368e96aed89293b24873f611018c3787eeb81a0a01b667b" - } - }, - { - "block": "0x18b", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x13d", - "to": "0x469dacecdef1d68cb354c4a5c015df7cb6d655bf", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x6faf4090490862eba3c27dfe0a030a442ccc89d4478eca3ed09039386554f07b", - "s": "0x656f741b64c54808ac5a6956540d3f7aaec811bf4efa7239a0ca0c7fb410b4d6", - "yParity": "0x1", - "hash": "0x054500013715ec41cb39492f2856925c7f22f80fd22365f19de8124b14e77e90" - } - }, - { - "block": "0x190", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x141", - "to": "0xf14d90dc2815f1fc7536fc66ca8f73562feeedd1", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x4a18131d30b0344910cae7c41ee5c1c23171c40292d34e9a82c9c7cef3d3836a", - "s": "0x598a3835ad1903c3d7ad158c57ff0db10e12d8acbef318ddd0514f671a08ce94", - "hash": "0x1b562d975247f54df92dc775c61ef8fb004714fd57d0c804dd64e44be2f10cb5" - } - }, - { "block": "0x195", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x145", - "to": "0x360671abc40afd33ae0091e87e589fc320bf9e3d", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x9b0a44741dc7e6cb0f88199ca38f15034fab4164d9055788834e8123b7264c87", - "s": "0x2c38a3ecda52aebc3725c65ee1cd0461a8d706ddfc9ed27d156cf50b61ef5069", - "yParity": "0x0", - "hash": "0x3e3bec1253082bf314cb1155ef241912bc842b8ced86b70e5e3b24585a130d66" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x434e2bcc5f4148668dd618144aac33ef5d463b292b3baad302a60aeb6be03b86" }, { - "block": "0x19a", + "txhash": "0x5b8bef43f888a81d06bb9757ebfbc240f379bcdfef6efbefd76c6974a2b844be", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x149", - "to": "0x579ab019e6b461188300c7fb202448d34669e5ff", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0xde600e017080351550412ac87f184ec2c3f672e08f1c362ab58b94631e8864dc", - "s": "0x47d41b8691a1f7f8818e59ad473451a0edfc88826a6b808f84f56baed90d5634", - "hash": "0x519fbf530d16289510ebb27b099ad16ad03e72227497db7a62e6c0e89d3a708a" - } + "block": "0x1a0", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x7b95105ef96b105a85277c69993f6f56602d912fe712ddf6156cdfcd8c490607" }, { - "block": "0x19f", + "txhash": "0x1e0ee081c4d5b43e12ed4eb80f14a1519f6e47f1d2ed7d88eea2097b1f2fa0db", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x14d", - "to": "0x88654f0e7be1751967bba901ed70257a3cb79940", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0xa79b0ff9846673061d1b90a17cd8bd9e7c7f62b99b39fbe4749777d3ed4544e0", - "s": "0x750ecfe9895402861ebea87e9b483b2c116bc2d4920329aa1c29efb9dcdf47e6", - "yParity": "0x1", - "hash": "0x6364bf260fee1aea143ec4a4c596d64e15252f8fa4c7ab7ae69d51ff4cbd343b" - } + "block": "0x1ab", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x2ecc9be98f9a8adac6e6acc5f160b0d15439b3856f0dee2a3005db79076252a1" }, { - "block": "0x1a4", + "txhash": "0x4a2c9d2193f39a13e47237e14bd645267a17d3f096fd7ee6646ec0f4b71ea82e", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x151", - "to": "0x47e642c9a2f80499964cfda089e0b1f52ed0f57d", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xc37c23a91d6abced211855a2d6d5e383f54aa6ff40c26abc5f27a22cdafa5618", - "s": "0x190f82ff101eabad8b9c7041006dcb3e3a9a85c814938bef8ec7d1aa63fa5892", - "hash": "0x2ee70986d957daba62588ac40c9bf75f6707a34dc5ef5897ae7cd3998f2e05bc" - } + "block": "0x1b6", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xc452b6d808f45af81c3310dcf94a1704359eafc34709c45b0c7b95adf4cd02af" }, { - "block": "0x1a9", + "txhash": "0x5d0a088f57e56aeaaff5958232ae8a0e4846cee85333b465d43c4462714558d0", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x155", - "to": "0xd854d6dd2b74dc45c9b883677584c3ac7854e01a", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x7a17de801de3309b57dd86df30b61553d5c04071581d243f33f43c4d64930e09", - "s": "0x75f7e820212e8f96d7583c66548719db621537fe20f7568d5ee62176881b70e8", - "yParity": "0x0", - "hash": "0xbaf8e87ba94a0d70e37443c4475b2525806827b3ae964b30eb4dad7936b2eb6e" - } + "block": "0x1c1", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x7eae9da1da48fe866f64de7ac5c70c8e43644867b917aa8461f84915396d3598" }, { - "block": "0x1ae", + "txhash": "0x169f28d6c3062de156f293def5ccad7deff2211443ffd2a44e3e1a711df25478", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x159", - "to": "0xc305dd6cfc073cfe5e194fc817536c419410a27d", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x163f29bc7be2e8fe3c6347fe4de06fa7330e3a3049c0e9dcded1795ff1c1e810", - "s": "0x4ea7492a5e457fd21252166f5a5d5d9d5e5c7a19da2c7fd4a822bf60156b91a9", - "hash": "0x4a84eeb0addd194ae92631aa43ed4f4fece16258bcbbc91de6324e20bde0f914" - } - }, - { - "block": "0x1b3", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x15d", - "to": "0x2143e52a9d8ad4c55c8fdda755f4889e3e3e7721", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0x673c5473955d0d26d49b25b82af905ee33ba365178f44dc4ac39221efec23c88", - "s": "0x17f46fc9b15ba0c1ea78d4d9f773582d94f61f6471f2918cb0598f33eb9bc89b", - "yParity": "0x1", - "hash": "0x01b1e85401ca88bc02c33956d0bfeea9ec0b6c916f1478d4eae39818e999cb74" - } - }, - { - "block": "0x1b8", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x161", - "to": "0x0fe037febcc3adf9185b4e2ad4ea43c125f05049", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x654dc39f93a879b9aec58ace2fdbd5c47e383cae2d14f1a49f6ec93d539be892", - "s": "0x70505a0ef2e83f057e9844dbd56eda0949197f0c4a2b6d0f2979db1710fca4ed", - "hash": "0xf8c7948d4418ad9948d7352c6c21dcb5b7f72664dfcfe553dfc444df7afc9c0b" - } - }, - { - "block": "0x1bd", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x165", - "to": "0x046dc70a4eba21473beb6d9460d880b8cfd66613", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x9a954eff1b0e590a3a78b724b687c6ab944181990998780d56cc3593c704996e", - "s": "0x418db96b5dc1057f6acb018244f82ed6ece03d88c07f6ae767eaebe3b7ac9387", - "yParity": "0x0", - "hash": "0xf09a7e0da3b14049923d019fb5d457531ddaa4456cf84124a17479b0bfd6261b" - } - }, - { - "block": "0x1c2", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x169", - "to": "0x104eb07eb9517a895828ab01a3595d3b94c766d5", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0x597dbb3f69603be721ae0f2a63eeee9f008829ff273b54243673f9ea192ddc0a", - "s": "0x1f7dd04defb45af840d46a950b8bede0b3ce8a718004c1ca2f3bbd4efcbd7563", - "hash": "0x00c458459a2d2f501907a6a4122fba7ae70fb3ef632676e492912231022f80c8" - } - }, - { - "block": "0x1c7", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x16d", - "to": "0x46b61db0aac95a332cecadad86e52531e578cf1f", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x774ced5c8674413b351ae8ac3b96705d1d3db10deae39134572be985f16c008b", - "s": "0x6f3e4b250f84fcf95ae85946da8a1c79f922a211dbe516fcfcff0180911429b8", - "yParity": "0x0", - "hash": "0x6603c100a34224ddb8aaeb9e234f0c611d40a5df807de68803b71e0ff0f3aea8" - } - }, - { "block": "0x1cc", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x171", - "to": "0x8a817bc42b2e2146dc4ca4dc686db0a4051d2944", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0xa755d1c641b8965ea140ad348135496fc412ffa43a72bbd2c7c0e26b814a75f1", - "s": "0x67d81cca370b6ea40ccd2ad3662d16fa36bd380845bee04c55c6531455d0687d", - "hash": "0x46e00cb4ede9be515c8910a31881df229ebb2804722ad9d6723e1101a87f1889" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x492ae6c575840126917090c30d003aec0892cd6250f877b99f33b72133b94f23" }, { - "block": "0x1d1", + "txhash": "0xa1deb6e1a31c1eefc0b4348baddcd41b9671fa0189eb32643fde34dfd21a1774", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x175", - "to": "0x23e6931c964e77b02506b08ebf115bad0e1eca66", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x6263b1d5b9028231af73bfa386be8fc770e11f60137428378137c34f12c2c242", - "s": "0x2b340f5b45217d9b914921a191ce5f7ba67af038e3b3c2c72aaca471412b02f7", - "yParity": "0x0", - "hash": "0xa5b751caaaff89a472fb427c17ac7637b4a9de7cda34beaaf891516278655479" - } + "block": "0x1d7", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xc8bbb420578d2d80897ca392a55fce5e4834f1d641472c0fd6a9698b7a8e7866" }, { - "block": "0x1d6", + "txhash": "0x383b1359ef9168e0c519618b865a0b2bd246f40574f854c56b3dfab642a4c5bd", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x179", - "to": "0x878dedd9474cfa24d91bccc8b771e180cf01ac40", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x515a62775619f55c366d080a7c397ea42dcfd2fdcce1862ef98dab875077f367", - "s": "0x23756d4f3bd644dde1c25f8cde45fbea557dacf0492bbecb409f6b2cdacbb9b8", - "hash": "0x2e232fb6d73423c9dcaff38257d36fcad74a2c627a70030b43a0bed36d136625" - } + "block": "0x1e2", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x3a970a6d07c991261dcb566f26d21a76c578d05d1565c47dbc1fc071934c8c43" }, { - "block": "0x1db", + "txhash": "0x17551b7e94b2b97a41b94ac50c71106bfa09ea50ea92512fb63057557c05a644", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x17d", - "to": "0x45dcb3e20af2d8ba583d774404ee8fedcd97672b", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x1", - "r": "0xd3b69c226bf73db84babb6185a83b0dd491467adfc01d279df4c09d5d2d3fba4", - "s": "0x368ddb772caa32963df97961cf8ef0db33e0df5945000f0e39d9a288bd73ee30", - "yParity": "0x1", - "hash": "0xc80615944f9bfeb945b7416052667eec0a78b2f3beb7c2811ebb9e9210e45c4c" - } + "block": "0x1ed", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x51524a498a88953303410a83d67c2b8c69ddafeb99b570accaaed774fbc8583e" }, { - "block": "0x1e0", + "txhash": "0xd2d67b7bee59a1bc320887f03e4c39e9c771af365a2949b53621402857985a7a", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x181", - "to": "0x50996999ff63a9a1a07da880af8f8c745a7fe72c", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0xf06ad492cdd04b44f321abe9cb98e5977f03909173e4b6361f50d44c080f9d6a", - "s": "0x7fdc23c04fab8e0a576e6896b13a661b2dcb256cf8ca42fa21f0f370097a53a4", - "hash": "0x8c1f1466ce25a97e88ab37bc9b5362eaf95fb523fb80d176429fa41c2fa2d629" - } + "block": "0x1f8", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x96c0d209b0a5b8b06947cc4c7ca723df55c5b972711b6c08ec7b9c393fa6e8ea" }, { - "block": "0x1e5", + "txhash": "0xb826afbbbb480140ac552e49ffb3985f7d3dfe9f37dcb3271ec5c35d71c9c844", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x185", - "to": "0x913f841dfc8703ae76a4e1b8b84cd67aab15f17a", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0xd4b8d15fc05f29b58f0459b336dc48b142e8d14572edad06e346aa7728491ce8", - "s": "0x64c8078691ba1c4bb110f6dff74e26d3c0df2505940558746a1c617091ddc61a", - "yParity": "0x0", - "hash": "0x969e178ea1a76626b96bf06e207edb6299c36c6a14e46462960832feb93f6d42" - } + "block": "0x203", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x39410f5a8f450e0b7fe63aa93e214a7c5cbe78786c815ebc926f1e8a2a14f4bb" }, { - "block": "0x1ea", + "txhash": "0x5be0a9f1701d01528926726a6a63fda07641d87172d1138b3a76c15af80cf396", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x189", - "to": "0xb47f70b774d780c3ec5ac411f2f9198293b9df7a", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd10a0", - "r": "0xd33c0cd7f521603ea8deaa363ab591627f5af193759f0aeb8cd9fe4f22a4dd5c", - "s": "0x667bb0ee041403cba2e562882bb9afc43bd560af3c95136c7bf4f1e361355316", - "hash": "0xa35c19e4e8154c35656544b92e88fb62c4210e38f09608248e2a99841ac99964" - } + "block": "0x20e", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x075a739ccce514f063220aa4bb66f08a7966189b0f24a2c5ad4692133d7aa6cb" }, { + "txhash": "0xdf443c6601c8656a7bffdfb38d9cc4ec15c324ed50e099546f2a548d1fd6bf6a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x219", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x9f5941a130f6c2ff98ec21bb2517998dc5c8512230dcb37ede3cb8a4694175ab" + }, + { + "txhash": "0x5c94f25cebcaeaea9dce953b49dafa01f5ebab6bab84ac85257a4df50d216ff5", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x224", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x30335bc132be5a5f3bf464e0eed03a3c74f180cb9906552e187e4c04f024b804" + }, + { + "txhash": "0xd7ea9612e78bfd71cd959c1bb7b860fb96010f6132326724dd4fe1cd89262928", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x22f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xc668aa05d66c2f88a95db12354386f3b6a1722a98aade506e117201f2fd0511f" + }, + { + "txhash": "0x71f54b7f3f4acfdb51b3bc5e822e3a491a6a892b9ef7dee7493d38f135d69df5", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x23a", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xfc6dfdea8f35e8af49faf38c0164a3deacd65c3927eeece6023868f32fd382a7" + }, + { + "txhash": "0x34c7189ae7c5894d908d9df8038d9f15d46bf8fef3b44c179f4bf5c194a49963", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x245", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x14ec3dfb63100132cf23ef71b80689146033fc6ceb9f8c0f0a65ef93cd18c2c7" + }, + { + "txhash": "0x801afe1e8d16b2fa9dca00d4ce5aca48efe8cfb7fedaa9ca4e60e3ec5ba7e9ce", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x250", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x5571137d48f7d081e62051a6bbca9d1e25c93ac6f84b7a3bc146f126ac80928d" + } + ], + "tx-emit-eip2930": [ + { + "txhash": "0xc9303fcbe3f18d9b5f259e62f7b59d8fe7ef6545b301a3022610c8cc32e3d12a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x8", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x881a8434f98b103a2ee48727304618ca54234f1474c44bef70c21accc4dbc0a7" + }, + { + "txhash": "0xe7ec4729b421badeb6aeae0214ad958c9b51516d617f089dc8fbd514380630de", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x15", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xf77c749ecb156f605e2334b14caea388100bed09b4c16579c952a96e90355629" + }, + { + "txhash": "0x06e43cd84b25d35ea82b3b04c4778d565b7370b2551b36382bb0e971d27961fb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x20", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x415feb809041baabc4d9246223e40f1083963cbe1ef6dedb8b153e49d02ee7ce" + }, + { + "txhash": "0x414663e2a0b7c8300c9e4f7f6836ff392e626ac8442023e81f479028e0bef79b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x2b", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x89c17d9392b73a55738ba19aae192f2f9c5612dc8bd803ca23b9c2fb9c309e56" + }, + { + "txhash": "0xc6fa80c16effc705553d70ec5776c402eaaceee2ecb41dc444da158ed0166d8a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x36", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x9038344c39b01167bfa8e99a6425d34bca24c27ceb191e8eba70ab5a8f719ce5" + }, + { + "txhash": "0x84efb3f3887121d539cadf5e973689d70d91389fc03435e4f51ad361d089ce19", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x41", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4b3120af8064823e074758c51cd6cd0954587c0d94b5b37b336261fc7aa2ddb3" + }, + { + "txhash": "0x9fad4904eed2887e05f4f5d2152f2c89a36d9d936c29c50a7ce7601effd8b19c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x4c", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x41565ae6f06f2555139f444c467d6b709b45180aa0c6b15bb5b1388d55ef952c" + }, + { + "txhash": "0xeb53887ad3621080290ea5f1ea0adf1f8085bec14df74c5b81b3c7efe4b7efde", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x57", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x00f7ca033c24d91f8fc39cbf0edc8a43192507f93d7316f311b05eeb85921eed" + }, + { + "txhash": "0xbc3f4e9e137c2e0c8973401ad6f64795c04b7d47ac215feb6011aa9a7ed03c7d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x62", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x761bf5fb1730fee0e499bb1806b9ae14394e673ab9c1dc12e95b9d3f1647cecd" + }, + { + "txhash": "0x86c2c4e5a08428efde69db7036025b1349438f22d85c2bbc9714544473f984d0", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x6d", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x468eae0ffdb87a4dc081a86c494969801637f690e1e1da15fb4a9d2c78272da8" + }, + { + "txhash": "0x90439c435817e3a77f33a7746c3f79961ecd321fab300519708d661fc7ec65eb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x78", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xdbc7a073eb54d33d8e6dec5b0b635a874204bda1c23234ff0cca057ff8ed77f5" + }, + { + "txhash": "0x88792d2ea77fce18827a27f02f6aaf54824e5bd6e60215e26e69fe73d00de657", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x83", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x7a9cae3647128ba14914f547c5f27444cd7325bbc37e5038abc31eea45003034" + }, + { + "txhash": "0x1492acea121d6e2e74507e43a99ed8146c57ed80720f2d108cf9c31a22cb5951", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x8e", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x2df4cc92987ab73b08a3474750456382a0add51fa25f928480762f3d993f2984" + }, + { + "txhash": "0x36c80351a5e5b1af63afa0bcf9b3ba0cbda0ec541b3744977b7f049654c54eef", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x99", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xf8b0a158a81e46d2f46d268e7726acaf7c33fc321c36f6157f07abbf7fa49e5b" + }, + { + "txhash": "0x15417bc19302807aa8dfa6e7f27d558b7bc3cc63fe1e420ed02cb33d0b7098ab", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xa4", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x85ca3ddf1ae9fb0aeadecd8109961dc5d5eaff16ef7adc672149a7826c69da97" + }, + { + "txhash": "0x02ffd0bf00551df3bdba55994ac9ace84b08169515ca7ad46018caf13cfcfe15", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xaf", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x73b2b230124967b31546c7e2fedbc5ab108a537ef6d645621fe74fcdc0644b28" + }, + { + "txhash": "0x322d17f7800f157cab844c56b8997f73a4af682c2b9d1896e7febd234f5e3055", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xba", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x46765aab85a7ee88496ecde24f93cd5ce361b5a9fb43a2641d77bfbc97928010" + }, + { + "txhash": "0x58e2dd04291740326a8f8fe3475781d8c1dee08176a2ae44eadac4c7518c6bcc", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xc5", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xd0e6005ee39e02d654cc2db358df9659d8265e24d7362df88a7df9200438f6ba" + }, + { + "txhash": "0x095eb45d2c81cff8a691af38b0b7e3bbf69a77a740a8362f8ad4d7e710de08de", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xd0", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4323bceecd4ef7216d5b57b9dd12ecf03842ed56d87fe43d0959436f408f44c4" + }, + { + "txhash": "0xf69b4d268ccdd64739eb9f74d76e06b6d7ed43e1e86d0d6e7deef093826718f5", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xdb", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x81607ef8d6fd479d2d0f55ec50762ee5fc35883ee5600525ce1e9ef3398d5aa5" + }, + { + "txhash": "0x8e430bb7a64d7757860a881f31b721c8457b80b69332dd67668be803f48e5d35", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xe6", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb36949b816cb2ec4ab90f345d0bed84f55b8fcbeffd22198724c45d8a30b20a6" + }, + { + "txhash": "0x61f149d4cfff2ec32410a4684600ef4dff10be09284ae170d4693b9590642e14", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xf1", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x40c619388e6393f420e805451bd48b10c670de7d51e916a3ffe5ac3c96b81938" + }, + { + "txhash": "0x7ca86b15d7e14a9bbe4a012edf616f8341625a032c2bfb16b0361742165b6033", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xfc", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa22721490cd06a0e77bc2b085bb4d57e7e5e0b459a2afc65ec4697d51926e1b8" + }, + { + "txhash": "0xd9fca30f3482e9d19271c9f1223ced48fd7e315ca4d0ea28c038afa16ba17d3f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x107", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xac748acc1af284e25d06434a8c1bbbf75bb8154a06f53f75d4f36edb656a49ba" + }, + { + "txhash": "0xb5bd2b2a1e89dbfc78b28316727a351716033e8968a5832f0fc6f5fad06061a3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x112", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4edb05f465bc71ee02c59ac9b5b50ddd974960ea2bd7e8cf7ae91c38c0b5789c" + }, + { + "txhash": "0xa620915661e953c73734bc32bb5d340ff2616906dd600a08a777c02f01a752cd", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x11d", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x0678ff21f84e5213aa8d1d173b3517f8e6c3d1523959c101c75a31daa70ab942" + }, + { + "txhash": "0x792c9815f48f974bb737f43e351015f573dde750d3c5bc2ecf78524381addc46", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x128", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb3750ecb88b6e11e5f686cbacb3d24e61396cef4a1525b30d5a30edc4b3fdec0" + }, + { + "txhash": "0x66f4a947f820d53549e32402217beb1fa688d0a3a9df01393883b43add1af7ba", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x133", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x38570ba11cfca6a25bea615c7ec09ae671516245a92a5f8fc61d2e82529454e8" + }, + { + "txhash": "0xd62159aaeae3823a577e60ec54af48a461c39a2a8d84db012ba6cf9f9716e65a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x13e", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xd5eb8e9a486b23e10cf0092ca8690e7bd6d6c90932960cdfa5da36d1e1f20423" + }, + { + "txhash": "0xa5c399b1c83feee457bd10e9cb5443f4184e28f49d44aa75432061e3b379934b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x149", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb5e95d5da3e73f937bfbc9b4990bfdbd865c6d3a3b50478657e20b507fac7541" + }, + { + "txhash": "0xdf6e0917de58a976925e579a3bf7be58bc52009f6307ca89aea3564ea78059dc", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x154", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa3e65c2aeaf352e79173be13e572f691d8d75ea1064610b8418246d95bcc421c" + }, + { + "txhash": "0xec034419430d4e6672f6e20c2145c4fadf17f3e06a3e821e9ca6a786c9b45515", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x15f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xcd78e90ed1705eeff092f3df07b16a382082e9c388030ec3188daefa57a731dd" + }, + { + "txhash": "0xd1b8042da59f6d7a3f740c84f28c46cba7706397e581b7b9c5b2cc80f17586f4", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x16a", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x490b9d550a200295b38f2456a42525d3a43c345d2fa1431e770fea9656b26723" + }, + { + "txhash": "0x96566916710216635e35febde8ce995b9c109a38e5870706cf77279f609ddb98", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x175", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xcb35fbd0ebf79655e6882326c19855ff90befcd2e589418566ec2e3a1efd65d8" + }, + { + "txhash": "0x3d5e920028d1218989019830525bff1e6f08eb79953470d4f2692476849db51f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x180", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xafc44d58dec637206e79248a528189c68365e20afc23410475deb5e5dc69c82a" + }, + { + "txhash": "0x4c04efa9772f455ce5d77eac6037dcf8f8a904d7849dcc139f1c98b9d90d0471", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x18b", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x1f1860251182573015d583a718463a52050e45d795ec0f94d112206c3fd62e45" + }, + { + "txhash": "0x0ee54e10b675053fa6e447175e8a0e64af66d0f3c4938f5a545e392c329e1e73", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x196", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x19fbac480a243f8c051e10225cec11bcb7fb274fac8792ca7e36bab8e39d312c" + }, + { + "txhash": "0x6bd480320bb019a63d45deeac7ed513db679147d411f6e8c7a884430d5e9f684", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1a1", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xfb2772a3127ac292efa3da20fad64d950bf973fb209892fdf834766aa8cdc3ba" + }, + { + "txhash": "0x27cdbcc53409169cfaf19ca3c19a424308dd879a53bfb34f0cb622e98341e09c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1ac", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa90642da2f095eb8128f01811cb553162395cfcecbe5b077f12c62a1effa7c82" + }, + { + "txhash": "0x691d488d31d23773b488470cbd25e0036b2bfa466ba08e951eea23b856f3f908", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1b7", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x75eb384e56c3a3a30a408622e6f0595d30705efaff129c133effc43c3b946de0" + }, + { + "txhash": "0x8878d98141b90199635b3989109699d477c828c5faedf356781f6eb587c4344b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1c2", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x2aee290f6f3f6c60a6985d0150eab487f9de1c47962a779be7343cc0cff270f9" + }, + { + "txhash": "0xf59da47c6804c63a8634cc67a08092994451fdd5fa56b7225c40a67edc23e635", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1cd", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x41b546f355dc0dd009ac5da8bfd17c8e197595c1c1f21aabbb1f3b18343a0718" + }, + { + "txhash": "0xeab623e58b8f2d54649a24878731423ef914b23194a1ffed91b143b877fd69f8", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1d8", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xca27d6fc8e6016df20a295f26b57b2f6ac7a8cec98224571f416ea88c0ee7b97" + }, + { + "txhash": "0x0f68375d9c8575badff105441ec3f3fa0227c2fd5015fd3fb288cab15a0dc269", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1e3", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xd1a0570d06c0cc4198b4475cb892ec41ca3239ff670666bcd97faeb62c1db6bb" + }, + { + "txhash": "0x5e1845a8cd15ad7e127cdede8899eb6a473e59045ad5cac8cbceac140b6ae52b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1ee", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa6602e59691514abf1ee46e71c1f4c7411eddb76e687f8f4aaa1ebf305b97f6c" + }, + { + "txhash": "0xa56dc267f90bde33765a9acdb6853250ea8405b0819e0884ddb2cd26af1ed262", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1f9", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x0a5a37a1db2e0068ee9791dbe377a74c4f7bc36bc27af57ca7e49059127e8eb0" + }, + { + "txhash": "0xc97c6242194520c2185b98119eb572ff29243d6b86afe9e78209c2c0633f8e43", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x204", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb50dcc47e811f76cc69369cb397936a5c70520a51f33b84f1b54591da145e823" + }, + { + "txhash": "0x102f1c2680bb4bbde8b42b0ed2b27d0f53b0741f6bfafce3326300f0ba02d461", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x20f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xc6bea923a54f8cf570edfddbda896a2ebf7b53d33b1dac8914ed024ff0621f18" + }, + { + "txhash": "0xf312429462bdb087f27b05d3485452aad3177090d1c834c4c3b1febae3ebdeb3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x21a", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb296a1364260e1c8d47bcf2239f26b6b909a0a7687250af4af545eff0ea95ed7" + }, + { + "txhash": "0x6b99996554a4f85b731230f246e924a1d5c455311909d76074a378e2ad0dc344", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x225", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x142951613bf93db71eba96bb48c57a42168fcfded6491e1229ea2b8570f77e7f" + }, + { + "txhash": "0xe0909f2b9a4d6b4064c61ed92c0914edf5bdc08ea9454cad75409f8edc2b99fc", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x230", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa99b8fb9a23a3a24ef3330a371d081c4158ea1b75c9af3c2bda5440857bc8237" + }, + { + "txhash": "0xec379187efb4e736e8274e899cc4bc4b8c1f94596e67999d57ad1950a9e12e91", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x23b", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb9a419e057752857f289694284890ff1fcbfbe5d736b5e52bb8568e077f49883" + }, + { + "txhash": "0xeb7451aba7fe97573c34ea34bdf06b8782335c6de5ba4507aa55c799b1446032", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x246", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe0fa1a4e967a01f4a84aa6715b0977cc111d3cc0834c5d04f0f1d87e0d561a71" + }, + { + "txhash": "0x73bb7b0c0bfe122b47a7242c5cb85473bfb1b6ab532968acb36e2e95d28abd80", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x251", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x701960547b78067b00883157f5e9fca3bbea742385129f0db7e1e69ce445dfef" + } + ], + "tx-emit-eip4844": [ + { + "txhash": "0xf420e289a5ee4f9f9741ede7f240216b93ddb6e9b6e54859db1d33e57edfb174", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x9", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x63cde520fb894276a981d2c9099bef9beb949121c1be98f3abe1b721d880899f" + }, + { + "txhash": "0xd5b23faaf6a0054ef645601b6a3882ff63368c518afc2f6555408d35f41adab6", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x16", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa41cb4f2ab2731a8889754ae1a340c666cb8107b497b922073df80a9b255e31b" + }, + { + "txhash": "0xddcf88da9d1942ff808a887b92501dcd74b01cfb8031324b684a4ee29fb63c1b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x21", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb2416e7ca12669406e6cd5154ad5177841b7d0cddeb2760249c28e1aa151f970" + }, + { + "txhash": "0x45a0afbc813c5795a8a3f22ff93dfe6810a1557a96e1fb87c90e68d6e834bf6b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x2c", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x11f0a8ac2adda075c95bbf6be534e3254dafa759f62cbcf0e91bc6f0335e70aa" + }, + { + "txhash": "0x39bec15647bf657b5d91d4571f2e68e7c86705d521d48c09c35c2bd40eed7c0e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x37", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x8460e232c64e6cd9f816c02d855c892755984ebbb91592e683cda80aaba4ba22" + }, + { + "txhash": "0x64505ad9b89241532e82029f9eae4c180ac6c32b09a29b1f452c92da1af320a9", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x42", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe7d55978188f31ab090b1f10d8d401a66356b11ca8c296384a0a51e36e6ec11f" + }, + { + "txhash": "0x7191d4d64827164b565c87480409d22354811d609572d1c2a314c86560fa4302", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x4d", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x24a4daf5b3cac3bf3066902cda09da0fc862e0a6723c47981ed601782ad69079" + }, + { + "txhash": "0xe94af7e94ff9b3cc7ec58666ef5333ffdd8cec10340e270f519ac5a95277eddf", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x58", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x7c24a68c92e3b68daa153ae82eff9be1ebbab973384e0f4b256f158f93c5d525" + }, + { + "txhash": "0xade7523b78f2e5f6c67cd47e6d7e2f8011534e6ed32552d5bf8d8e5bc3a56d1c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x63", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x02bd9d62880450596e11c3417f2644a81f7cc233a05394bbbfb58428ed53f413" + }, + { + "txhash": "0x3292412496ffb7d9778bfb58cb3831b7faad4fd66db3d0eb781fc42acfff63cb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x6e", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x0dcf6219856f226889a2440b388d8e15f5df0eb64a7b443f3a7a5dca7b87b0f2" + }, + { + "txhash": "0x647ebc00e9b4f1745b906d55709623d4565c4ee37cc43cce3294e86fbb06af9c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x79", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x0f624930606bfcd2386d583abca6ab10227d71fc1633fea53f94bd146c152b8f" + }, + { + "txhash": "0xb19cf34f280a82abe8279d9037a23cff23592f19805be3d08683929a618523ae", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x84", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x2daaea9286d7edb7568e0803a61bfdb1e1506156d27e93bdf1942564850646c6" + }, + { + "txhash": "0x36f1fabea1bdec555c4febcf4c87ea5bcdf9ae5a1bd9a10726287649704d94c2", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x8f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xfaca663a6ed04f52c0e7a8981cb438545f614a2cf84f9077659d0fce0045cda7" + }, + { + "txhash": "0x4b518ca4f87136c909ff5c85233c42466d29a1a07991ad4e5a757d81c2b4c9f9", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x9a", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe6a5227fabefc934ddc0a3142a50747ad1157ad0829ec0bbc389d5e22e3282c2" + }, + { + "txhash": "0xfb9370f7667bbfae1f6223e3abff4af8464d2ae0639e915d7f33e0b8fd9db0b5", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xa5", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x6a99e5276c6ea0c0894cfaf376fbbfdc736b359e1560a77365c14fcdf6cbbf53" + }, + { + "txhash": "0x3673b0487371e7e696dafa1a8e4564fb345c950362dac3641d570b2f37018940", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xb0", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xbdfd2b337ff30e9e15c09313bf796d3c75177943e0aa0445f479fbd2dd5c1d6e" + }, + { + "txhash": "0x1117f306b532c07bc696dd2b53a66fc8ea8c7be319c8db8149b13a564d9964eb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xbb", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x23c2e06f633f91e89e0d95cf87dce47fe1cb2b95434ff45773f1fd560ad2dcf6" + }, + { + "txhash": "0xd589b01ccc4b4c2004a2bd5b3f83fe8749ecce32dc8d96b3a5ee0be0b452374d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xc6", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x3c8110e03f1b54de6085ff899d0dccd87806b788d1ef3fddbca1de4c356266e7" + }, + { + "txhash": "0x2ae3fdf2e8671f02c712cc2f0ed0a64464e2b3eb69324b4b3291adc850eafb4c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xd1", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x5d7c0426d6595c1819b962730e5d2a44644703ebd960ec3ac51297ad937692f4" + }, + { + "txhash": "0x3896b74ebf76ff849f44241bec1e1f649653376971e657ad787801cf89bc002e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xdc", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe207f028cce1624a1fc76c56f1794c2704a692c1f214685291d618e40733ff1b" + }, + { + "txhash": "0xa0416d5370e59e86c33919e17cbef2ddc5aec738068d627a5158b46513115470", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xe7", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x18fbf0ae0e2133584c461cbd43169854c7c7e818e8b5779892da244f24d27b56" + }, + { + "txhash": "0x36e00ad068d4b0aeec3c2d5a7a196da7feb1ae69b19289156477b7b5a025a908", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xf2", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe8a78860d5ffde377f4eb0849fe59ed491d4a12fd51edebc2bceab3549d83463" + }, + { + "txhash": "0x8ae68021325ec15d383dac77654f45002c2540c113c8069496b4c7b7ae847f42", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xfd", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x9138868b39f601dde19efa6e9a154230a51805e9a6cabaf28fed5163aea58328" + }, + { + "txhash": "0xa0521c7d9e65b85ce70e1047a30fc0f40716c958e5d26ed1b892dbb58c631623", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x108", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4348597bdcdee80c8e110d94f771eb7edce9c8691b2f90b71c0d11f729f086c9" + }, + { + "txhash": "0xd08c91a1bd8cedb22608d15dcc429cd8fe2785c0e28f8aff323d8a47957b22d2", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x113", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xaf1c2654b2e98e9ffbb02f14d88617a245a9a1679162be29776a4836185dc2fa" + }, + { + "txhash": "0x50266b81dee4437511591aaa60df86717642524cab47d508be3cfe16248574a9", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x11e", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x81260b78e72018d5773b6ba1df006b09a387fd733e59ad152c119d9848ecf1f9" + }, + { + "txhash": "0x0dab5929cbcf54b4b6742c4e7ea56774f9f07c5ee046151312accbad330ab7d1", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x129", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xf9b648439e7b876f9aa1b178fc6381f44bcaee23754d8da33b2d44e78cf47bb1" + }, + { + "txhash": "0xd72795a9627079d42e1f65998602783c0e1152b1a6ee62b5f399955aaf1a3808", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x134", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xbefb4ff6aefe6c4d85158d11057517eb9cb1e1cae3e9d2d9c90ff40b2cceb546" + }, + { + "txhash": "0x1f049fea47d8615029fae54748b820cca1369ac4fb2bd01e570a5bd2478c683e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x13f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x9575996f3ad6e9709d7122224335451a59395327d297fd7967004e8dc1391308" + }, + { + "txhash": "0xa507e1f9dc79761107510d4f931dbcc1d2d846bb2c2007faae7198c926431d61", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x14a", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa791ce367786fdc4c5216c8b94dfe1076746e058166dabda25b5e6a3266ce857" + }, + { + "txhash": "0xdc4ebad42a33cedb2c56f2963b7f665b806c7e76a95b3527e03dcee1e8d3aac0", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x155", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x6df5983ddc40ef2c7ffa2c79bf9402568f2ee0ec7b675ca15aaa20b536d2a5f2" + }, + { + "txhash": "0xc1631f848ee48f93986a0d7f3a3856229d6d7f2ab448da79299ae65ef5c9c72d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x160", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x40325cfcd159fa7bf89d8c252b6ff47cbc17aafff5e7feb92014d00285484cfd" + }, + { + "txhash": "0xa8b3e0feee69ef4ad9f164709f9d8c93cb0cef54b547d6df3d3bd60d9373ac61", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x16b", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x039a54e14fa9769f840074356dec3dbd47c3588fe71fe942fb7aec5edfd0a096" + }, + { + "txhash": "0x59a87b6c242eee2b5bfb727160765d68198245907faeabf342d28663f9695bc0", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x176", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x927e4ce70caf344a9e108ea8803cd49216852109c3e4922dfed2680e9f24361d" + }, + { + "txhash": "0xb6e6ee58c5cdab20b7a2ab2593716985f53644bdab28c89f5cf05c4704b9a43a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x181", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe2a0b166c03b200234eacf5eaf9ea11746c9bfd00e72f55d8cab76e0eca7195a" + }, + { + "txhash": "0xf8b2538634ae7c9012e0298b5658de6faf19edbcc7a6ad8ad9409c3e876ca311", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x18c", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x92da59b68bfd8a9c1cb1ca6a302ee966f829f2727a36823b0dc7fddf7790a108" + }, + { + "txhash": "0x3a93ba0531ec222285241aa65a45f44ab14900e4d9c5389f0713456436881b60", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x197", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x677a6b432bd3361f469c2e051c8e09ea92ed0d049eb563118ff8c680fc93a2a7" + }, + { + "txhash": "0x1e7d6ae181604098663d2a7b69f2d6a5ef30fe23e953ef480595751a24b63899", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1a2", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x250ca62bfd18dde43e70bab089d01d591ce6ab28978434258ae1017c72f12b0a" + }, + { + "txhash": "0x80223c925ca21ffa9b819dbdb802b1483b8828f209a1e44a6b66e777aeecfd5f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1ad", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xcea8a961664f986542ebbc496878d052736682831cd7847bc769ae16e9eefb65" + }, + { + "txhash": "0x05f3165887c2a6fe74c26b7a5561c22124331bb248a8c83400f9e84254a0a656", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1b8", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe5f4774cc356a99594f072de9e8113739c65fb51b5d0fef3f40627cac02dd963" + }, + { + "txhash": "0x9bdf145cf420be4935f61d48d278854fbb146c5dce686a81f586a6b72e2f1697", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1c3", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x6f9ff000b2dc3a554bbbb882ebc7726b700eb7afea141ab16e00a057f314d0db" + }, + { + "txhash": "0xb1c7a90ffebb5658771131f7286426643259c1d9d3c6581d97a2faccacd3f2b3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1ce", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xfd6fc192aa03eedb6505372aa1dcda93dd186fb3eded0bcafdaa4f2829fe43b5" + }, + { + "txhash": "0x837101affb0ad970b9101a914f733b437fa042e2550b3d781f6775285fc8cb99", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1d9", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x506c0723b5e537632209d4a824a6073d5eccadb36b9b8717b2ecc9e2d5cacda2" + }, + { + "txhash": "0x4a5060608b481087ac139068f55d76edcd8a4fa189abca438bf0b18d25450638", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1e4", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x27edda711baed4a613c44d8ac8678531c9938eea106e7c5649e438f3d24b8fe3" + }, + { + "txhash": "0x7bf955bd6b528d2435096d3d88b3b39deaee5f7702b206c6e0e9cadf739b2aab", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "block": "0x1ef", - "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x2", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x18d", - "to": "0x6e3d512a9328fa42c7ca1e20064071f88958ed93", - "gas": "0x5208", - "gasPrice": null, - "maxPriorityFeePerGas": "0x1", - "maxFeePerGas": "0x8", - "value": "0x1", - "input": "0x", - "accessList": [], - "v": "0x0", - "r": "0x990aa3c805c666109799583317176d55a73d96137ff886be719a36537d577e3d", - "s": "0x5d1244d8c33e85b49e2061112549e616b166a1860b07f00ff963a0b37c29bcaa", - "yParity": "0x0", - "hash": "0xeb282a48d309db881eead661ee7c64696b2699fa7c431d39a573ecaa0bc31052" - } + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xbae4f13d358194452066fc1305964decaafbc9c56a2fd16936d25d9521a57a19" }, { - "block": "0x1f4", + "txhash": "0x20ffe88022aa6e1b6a9ff7f2a6465a3db959aad55dd70dc3380d63087e7ee390", "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", - "tx": { - "type": "0x0", - "chainId": "0xc72dd9d5e883e", - "nonce": "0x191", - "to": "0x15af6900147a8730b5ce3e1db6333f33f64ebb2c", - "gas": "0x5208", - "gasPrice": "0x8", - "maxPriorityFeePerGas": null, - "maxFeePerGas": null, - "value": "0x1", - "input": "0x", - "v": "0x18e5bb3abd109f", - "r": "0x85b3c275e830c2034a4666e3a57c8640a8e5e7b7c8d0687467e205c037b4c5d7", - "s": "0x52e2aa8b60be142eee26f197b1e0a983f8df844c770881d820dfc4d1bb3d9adc", - "hash": "0x22e616c85493bcd23147d1c9f5dd081b32daf5c7b3e824f61b5fc1bd34a47e67" - } + "block": "0x1fa", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x989e02934facff928d8e788f174ab7d48838c62b07d420a8527cb7eaabdbe91b" + }, + { + "txhash": "0x4b5bb822f7a362c9e204624b436f342b3abded4c548e19e9a01d36d3493c8a32", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x205", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe891146f52235abb9f53919fc0e41a678d5a8a807a2247177d67539a2bcc3d1a" + }, + { + "txhash": "0x4a8d2ceec1465c2db3990dabd36c0027303110f516a7b591c01a733ef7e7cbed", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x210", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xab15322a52f3de5dda0553d7abbf171524cabb9c97dacea8806c750361d472df" + }, + { + "txhash": "0x56a530e9c72cfcf61a6b0d1fe735f3df56792dd25f942baec63e0ccbb2a41a8a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x21b", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x6c172610999b0729fbb6bb1ba27e7a0009f1b584ad6f8307d3dcc7d24a180874" + }, + { + "txhash": "0x4233ea782ca4eb51f939a929af9257a374af873d136c50fac14d2df85564e5d3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x226", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa344ff63ecb6c6cbbd711b06a84844147910ef79a57679958664abf4af9938d3" + }, + { + "txhash": "0x9f26d7fa9f6598f111b1ff50e143b2579520afa7fd5013544762b1378d2ab4ec", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x231", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x88edc52ba848622b1d92e73d2c311c1c83420986c621546fbadac23c3428c570" + }, + { + "txhash": "0xfb7f1b4cae168e0c7c37155044d0f8907514472726a682ad14dc562cb86ef124", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x23c", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x7a536b71187079aaf5462b7d483063e3d25cea8e3a6790ebdbb284666fe81068" + }, + { + "txhash": "0xda8372595a6f7b652d57a878d3de4a14ed4f4ec71a0c465e01ba8bc29c542cd4", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x247", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa0c2e429d47e77e9b7c98c1aa4aefb731206f41b64a6587678905a86d14a7d75" + }, + { + "txhash": "0xdec9676345f2218dcc1eb83512845910541be142c407b8ec119aab5323132dfc", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x252", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x48ca1081e747a7f831228b894dd5fc401d64c6496a2b9e578dd3c59b8f0df2cc" + } + ], + "tx-emit-legacy": [ + { + "txhash": "0x93b1dc3b8982a6c8bd8cecb7d5cf45af27ee28b41daf9c801e51065eb7dc60d4", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xa", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xb8d28e7b703baf999848ecbba44026cb6479b3f0466037bcf2221ffc3f8549f9" + }, + { + "txhash": "0x56d2f9f1862cf585c2419e181e919504b73608b705237dde572bd616f1d650a3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x17", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xa6d01173df2aa437fb0118d181e64a8f8e05713fc01c42fbfd2250516639ae95" + }, + { + "txhash": "0x86073ac16f561025c7719c0cea52c04a136770717a5d0a9f70e3dcd87efb4e5c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x22", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe94d0b2545ec05c3ce3431c4d45c3b62fcab156563e8308fae1ebd27a2810c1a" + }, + { + "txhash": "0xb19203054582d226c20a830e5ae3337d13af37db285d2936f7949eee221dd332", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x2d", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x6551251b96ca27f3af8a2c500d6dd1ea5b9ab7002b3d923b66db0493f4a7123e" + }, + { + "txhash": "0x794c81d1b630164f8bd2b0abb4ff9606598f03e56e5475526b6736b449feee46", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x38", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xfa29cff134420b6526f434ab690a9c3a140aa27b8479ae3d8d83b6c799acbc23" + }, + { + "txhash": "0x0fcdbb8b331a37eae304599f5e40496965eba8649cdd28319abe9a5184186285", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x43", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x412379b7f583981ea6e84408cba75ced69039e07ce9cdaa32a8a9dac997aaafb" + }, + { + "txhash": "0x6bf0e75233c60170a92dcff17d3906533daf2aecc20a427a3cb6260717103396", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x4e", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x87dfa85154edde1626e3a09196eab4b60f71887ec7b50ccbbe7ec76c0be6bdff" + }, + { + "txhash": "0x95a5b38bf61dedf258cbaec502c5e0c09e1e19e90c504dd48af18f9412ea487c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x59", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x6e2466f20ef20cb42d216dbf4a0d934199213e9b8d75bedc9c2d3e038a587474" + }, + { + "txhash": "0x4e6eaacb23cdbedac1a0468927c2b1cdeec1448cbf57936620ccfdd0f75ae91a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x64", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xd75c9abb1414054ca164bba2f8c09917fb90c24789feaa311ee34a0b3f4a82f0" + }, + { + "txhash": "0xb83984637e9c41986b59bfc847b7c922363add3a6412024a73357549f27bf4dc", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x6f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x165e0e0cc13ca53c5af4860637550364c5c90a512906490ace14efb534873741" + }, + { + "txhash": "0x4f70c780915a9595d214c9c9fc4d96eb7bda3776cd2301f89f831421c13ea768", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x7a", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x16bee816935475cd45501fc5fd01bf913f8ef54330a43d80ef73101a4c728b34" + }, + { + "txhash": "0x37967eef8dec21d44420c96212a7723608eae9c9df5587b70e3f324a09e0c1bd", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x85", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xaf1f0d50933e49dd24b61a24c670809a5b875e3b746862636288dead8579dc4e" + }, + { + "txhash": "0x15880426a7d1d3df1aa32e7693cb507f8fc69ab9d90e5559eddd9424cdb4f80d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x90", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x5b300d53be5798f53b472dadb8966674169ff3e8d08eccb3f065bd827abd7b77" + }, + { + "txhash": "0xf1aae9cd76d3f95b8796faf9b2d46303421eb3f8bf370b2367a72817d2600eb8", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x9b", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x970a64830f255bfc38886621b37a7f1a7284bad6c4a04b6a2442ad212e19a6a2" + }, + { + "txhash": "0x43c353bb6e0361414d7df069730164f8049957afc9376e24fbce3cf8659b8085", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xa6", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x611f5b5e5ee263412fed40f169d0727f4e6e1a2bc94caf668d2bcf22cddca8c1" + }, + { + "txhash": "0xe70aa05480e8ec451e6063031138f83fd569c1b9ec1edd2ce6e5256e7e92965e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xb1", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4632fe8e9579f33e2e42e68811d49a09ad1af1f01a68e7ae742f765e8e797ff8" + }, + { + "txhash": "0x5b7c43d070aea7cb7e9c8daa027e319ebf8662e56701abbedfe2bef07daa9eb1", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xbc", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x205bcc2489f954a3af7a16da4d6042a75fcd6eb69b848c52b3448acb24b23580" + }, + { + "txhash": "0x6fafd835f52299368f36bcc17c548df55adfa18f26e56847114893b7ce9de699", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xc7", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x0a2bc3fd72bd3f8bb7f1de9a7dc9e928a7c6a831237124e65c60c25f8348af19" + }, + { + "txhash": "0xa53506fce1b528bd18d18154b72025ebf9c8297ccd17cc52a94c2bcc03a504c1", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xd2", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4c3dffb6198347c61671fa1fafd5d80f384ab67a494f5c7bc7428bcb6ca5a445" + }, + { + "txhash": "0xd21d210873d8178c9ca4b9fd98e3d90e4f6fb00f81d82eb44d6f0c5c2d3b69ac", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xdd", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x8a38792846734575025e5114061b62006064b0636caf6733294eb26895bda2ac" + }, + { + "txhash": "0x00fe86870f7e16b7b184caef8aafe35112faa784d316c71a1932d2e0eca799fb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xe8", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe70ed54757ba10a0b95454f6483d3d2e11613828f13d57d50b8a3a98e2c8df1c" + }, + { + "txhash": "0x182de5a2fa9261eb867b7c233750ec22f6456a9902af2677476fef9747af3d65", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xf3", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x427b8ffdff6454ea85c8251407144400ed4e693ffb6a74f319e0238c0e72afad" + }, + { + "txhash": "0x5e8121133745699e0ffdd3cdf62fcce14ad16005c7ec53225df1aac03fc067a7", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xfe", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x2dd51e8325001014c6845bc5ad51b134ab237f95ab18da55cabc4275b029bf3f" + }, + { + "txhash": "0x06cf9afd2a64d19c462dff4acb3c32bf9603478d308a5107ae197acf716be505", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x109", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x321c62425869f150c2cb7f489691c3e5cd49f7cd62d07ecbb7477c4148aaaa0b" + }, + { + "txhash": "0x0390a326d5615bea72add73e2398cda64b160a4f7980038997006feeb1721d62", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x114", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x1f6ebf3e4d9c96ec86b866137bbec9bbb56d188e7126babfccc6394fdcc6a3d4" + }, + { + "txhash": "0xaa9089bc7bf3a9fff0ac8c3d8974ebcbbdf24c494c6be9f6dc330700e0c511ac", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x11f", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x9ebbf91a66183d0d37b03faf46daf8fe238c1aa2b24e6663dc14e50557d432c7" + }, + { + "txhash": "0xc4740d2ec8cc977d641f18f97c1d789b0a761e0a8057105437acaf8f7e5f33cb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x12a", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x94605c950838b2b0b1ce76f58acfb91a94c2aba787d02add7187360989745a4e" + }, + { + "txhash": "0xaab8e9062dcf651d0bd5fff9cb086ee779f3f91bce1c9a090baba71e0500d696", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x135", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x3eb32abcff52bfdf0887e9aebaeeaee4a61b76f2fbc9a183c2afc8552d46c3f6" + }, + { + "txhash": "0xe1fb51da4cd5656875be51625ad129bbaef0a28066ccf1729dc8d4809f636240", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x140", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xd314fafd686fcd729a24ff511ae5e19248bd6ac6de8c28c79918df72de20e63e" + }, + { + "txhash": "0xed9806dd032752f6fdd4234b61a6aa6941af207de555aaaac5610b04f4be967f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x14b", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x951b3b37c2a87b5a67918e750832a50c5565298a35390bad3ffffadb2f7b4afe" + }, + { + "txhash": "0x66cbbe01979712ff30beed89a5088350249b13ea9d1c162b3d770c4ae98387c0", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x156", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe067f85eba81feba79bf640415c11ab4448d5cc4a41652fc0a200be4d2661786" + }, + { + "txhash": "0xfca2d9cd7cf664cc092bc71e1ff0e6ebefb991bd0a83d1a42d2ebb0fd6b5a50f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x161", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xd73688caabee79f6ecf3a0b092d26e639b7e486e45c00031db80d3d7abe8c683" + }, + { + "txhash": "0x576ac317e0aa5ce1268c528945bc17fddb69b3391b22df0db5ef6ac7d3d9eced", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x16c", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x945c01f307d13fcdab0a2a3a4c4bd5ebb69a00c3dd59896a959664e01ce10695" + }, + { + "txhash": "0xed8db5d85b8d9618a7c012715866440ab390b23bacb24885a9638b9d48028faa", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x177", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x3f410a22d042d915c50f9269337a2bc7155f86d79bbff1721d83f44153635ac2" + }, + { + "txhash": "0x90dd94f9997d05a851a81789518079ba4251ca0c3485083dea817e32df80a2b0", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x182", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x4b85d3d5e4e06787a4e7e6d00f4e2f6d7e0358d9e511177ab584553d4ca06038" + }, + { + "txhash": "0x019dd8e438d6818397398da44bf836cc9eab53e49fe604be0048bd72d06f7ecf", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x18d", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x0c8e91bcf03d65aedba99f4f76d3ff8cd007668948ce12daf4dded4761c7b19d" + }, + { + "txhash": "0x694c644dd4e60de18a392c912e6c883a9fe177f6995d3ac4b1d0e121ed0b7b2b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x198", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x82a4bb68f7522b711c9f22b00f9c5e050f52cb2bc5f0f50eadcb12a5f1c30839" + }, + { + "txhash": "0x48578438fdd693c25ed25e30c141ed5db0743f49c55a4d355c774f5da6ba0a12", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1a3", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xce87527a0ad3ddb4d0d57d8077e84d48a6f3810f2a5672143d3b6969b0f86d6e" + }, + { + "txhash": "0x6daaa691e14a7a4c586ce5f411c60671c793c2ac01710ceae2e36b2cc2631822", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1ae", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe3cb3b98042d005e52e8bbbf49b25e11be63ec7c63ae5a5043e44c545fce633e" + }, + { + "txhash": "0x7e1ef2e07a223c6ad828353b5052bba8a87b5c5115ba507f4bd22f9e842a499b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1b9", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x1fac03facd67f44699ff86330a7f959ed3745add76d323f4832bc17c35be45c9" + }, + { + "txhash": "0xfee141740da30da512d76b3db294ba34e78a108433fc76054c9d93a6222023d8", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1c4", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe4c7ff156c2f31d046217715d0f193c8a6b3a7af6341d6abe0e28c49d1210638" + }, + { + "txhash": "0x41f54d93a2f08e78459286b2502954cfa13dc70a18ca7ec73dc1905905544aca", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1cf", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x9225354562a563158ba2ce0e86cfeed7fde0ed27c77342aaea09551b9c00ea19" + }, + { + "txhash": "0x63dfd5f89048de40697cf44e045668ed559be531969a8a1e70d0276e5379335d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1da", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x231eb803c34ec183e74b466c105b5518b554ce215bbc31bfa52c384138b8479a" + }, + { + "txhash": "0x7244fa2b6a90be34eb69c9c848da7784cff392463f1b4c52307df75bffcf36c8", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1e5", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x17f29f600f5128013ce183ac10efc609231aff556df37c8f5d6802c1240c22f4" + }, + { + "txhash": "0x8f31383336ceaa850f701b920f47617acca17664ca5f4c971df87ddd0650ebbd", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1f0", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x8405cb4703a08e5160e343c37d42df5f045091f6b22664b0ec3f587df18d2d82" + }, + { + "txhash": "0xf08771ff65480e0a952226da4d9f994451e971e3acf08185b9442a106ab9c586", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1fb", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xe865c3418b47b88e94c28956b326a799298fb44c62a7a6bb55fd991f7c0442ca" + }, + { + "txhash": "0xebec9c429aacd0d3b9a9b0650e3136763b70799015d78d0718a37a56bb840130", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x206", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xec200bf1cc6a2c5d58960dc3476cc4794ba1a9fca2ac3d09b63e7811b7299c3d" + }, + { + "txhash": "0x52edf7a236dd4d81f928a63f9249a8b3d60e09ae1e44801ace03c2f806cf539c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x211", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x09b79212fdf6dfcd322d6aabd5ba752b962d7e575cf299112bead28ab955f4c8" + }, + { + "txhash": "0x08a32aa63fce9746806dc432b63c5059c988cae94575471a64e898dda449209b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x21c", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xce285eb20810f2d026bc0b62faf3735df2193835ffd85df244ecc2df24f43b00" + }, + { + "txhash": "0x160b312c6247f5629ef3557427776e40b11c6da95495086f92bd3e68796ead01", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x227", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xf26b2f780c4b92b3f15f1d6e90f7d5a176b58eefea6f0d9cf2f8a0d1f86a139f" + }, + { + "txhash": "0x112b594c142d35c4888d2ea319c3d2128fa6d485fd127abca1c1fca07c10ad23", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x232", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xab5140d25dce39c42d511dba633cde87b45465d48aa4ec211b27de998abbadfc" + }, + { + "txhash": "0xcbb68fb40512406853eae3d8378920825b17ba9ed6849ebfb115f21e07803425", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x23d", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xc558392238c2d11cdd04a6ae37065f3541a22140500f92c0d8006ff95e8df595" + }, + { + "txhash": "0x4aa773330bd4bbf6ff2b0754b34ec922c9cc1466702f07aae225637e0bf812b9", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x248", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0x69626497767f58c222726a6a3c65050bcfdbb9346f9e5d146ef02bf59275b3d2" + }, + { + "txhash": "0xe5af8b4f6d6aa91fe8d453312890cf607a28bd49e3f6aa4fa032dd3d8606498b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x253", + "indexInBlock": 0, + "logtopic0": "0x00000000000000000000000000000000000000000000000000000000656d6974", + "logtopic1": "0xee0b894f33a9643c94e4e2237077260f4191c5bf6bb3c17a2212b86af6f67df4" + } + ], + "tx-request-eip7002": { + "txhash": "0x45d9e01d8dc308a89f2911954f518bc0721d7975d5692f6969217a05bc0e23a0", + "block": "0xd" + }, + "tx-transfer-eip1559": [ + { + "txhash": "0xbc83f75c374dc1b4418ef18bf183ed000b3f7c1fca3da045c0f5253eb0177939", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xb", + "indexInBlock": 0 + }, + { + "txhash": "0x374ca7fe3bceee86e9b9d9ecb31858eeec3ac7ea7a632e56be943bba4e587fd4", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x18", + "indexInBlock": 0 + }, + { + "txhash": "0x9ff78644fb64277ebe7838620b5817a0dbfbaf6b45713b80698628246492cc83", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x23", + "indexInBlock": 0 + }, + { + "txhash": "0x7f7b81c472c91ca8c511f29cab406ac201c770fad32270459a79f54d86c52614", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x2e", + "indexInBlock": 0 + }, + { + "txhash": "0x2ab6b266e3072e1ecbb21ae3111da1face60d84b41191287fa0f95971944e888", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x39", + "indexInBlock": 0 + }, + { + "txhash": "0x25b39f052f73a5bac64ba238ce4ffb9770a35dbd835136cb9ac66f4c3ac936de", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x44", + "indexInBlock": 0 + }, + { + "txhash": "0x9de0b20d432dbbe839b178aa91cfa5381bcd84af3603bf48c4494042f716d507", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x4f", + "indexInBlock": 0 + }, + { + "txhash": "0x610925d303403f4e3aca2495a12e5dc1688839b4f256f80dca33dba22ed45e63", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x5a", + "indexInBlock": 0 + }, + { + "txhash": "0x4abe64b41866828e0be88788bae36cb03dcbf85d070807670ccf27160e5a9a4d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x65", + "indexInBlock": 0 + }, + { + "txhash": "0x39f187a146d61009a03fecd06cb2f4c4b38cd26765905c3362fde02c046c0c85", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x70", + "indexInBlock": 0 + }, + { + "txhash": "0x2f0d711bdc3d0b2f8efecc78a50bef10cad8dbe36a636685df0ce5e77ff2f470", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x7b", + "indexInBlock": 0 + }, + { + "txhash": "0x0131d1b2950a637e2709deaffd487fd6b395485df174fd33dda6650bcf6fd42a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x86", + "indexInBlock": 0 + }, + { + "txhash": "0x7a1a947af6d0713ec475e0e401ac0c30502f9d23a3eec761f40116bd1dc9f0c9", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x91", + "indexInBlock": 0 + }, + { + "txhash": "0xc991b6e9ea27ca67d7b00afb5c3dcb0d9de6d2890d5ce4e3f032d9e7b2cb44ed", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x9c", + "indexInBlock": 0 + }, + { + "txhash": "0xd190fa45214c261223635b2a8c2659b2a142d8f213a470917075ebf2482e0d28", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xa7", + "indexInBlock": 0 + }, + { + "txhash": "0xb4ae0934d6d6775fa216a6f14f638ff0d394bcbfbc97108863a64cf239e0eaab", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xb2", + "indexInBlock": 0 + }, + { + "txhash": "0xe41f1f5bb0c5f4328c608347f2b347ba249793f47395aa57f735d45fbe564463", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xbd", + "indexInBlock": 0 + }, + { + "txhash": "0xff3473cad2636d1688009c27d790172c3f359a12b2c46fae71932cfdd62982c4", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xc8", + "indexInBlock": 0 + }, + { + "txhash": "0xf3892f186643cfa58ecc5a2770c3c06dcdfa06a7701e08e42a8817d7af24093b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xd3", + "indexInBlock": 0 + }, + { + "txhash": "0x258d7184e3022ec70cef833ae3a66dce9a36e42a7d2dd0d9e5cc14ed1fb5eedf", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xde", + "indexInBlock": 0 + }, + { + "txhash": "0x07fa584efe43c50c1ee8bdca6369841ffa7121576750cb7c08bc251356e80a15", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xe9", + "indexInBlock": 0 + }, + { + "txhash": "0x092365255715c991b48ab31b184ae51f2758c17b2ac1aaf7d1036f105bb333a9", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xf4", + "indexInBlock": 0 + }, + { + "txhash": "0x8034b5908a0204004211f252b06d2f4efd19d276adf6aafbed3de97e5435499f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xff", + "indexInBlock": 0 + }, + { + "txhash": "0xcb89f9e7e062c3d72798c6cc38f7c4ec26a5fa6d8cf86b33b9859657264d32f7", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x10a", + "indexInBlock": 0 + }, + { + "txhash": "0xd37c021b3d8923723a80a78eaf9840a72f4d89aaccc63c80af112d52434fe886", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x115", + "indexInBlock": 0 + }, + { + "txhash": "0x653da2892fc5b19e542ee54ea44cec8b98c7a6a778a6e15cb4007db8b76ed34d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x120", + "indexInBlock": 0 + }, + { + "txhash": "0xf0721ceefdbd4ad6518652cb402c0611180101bc655545c973018120484c8d7c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x12b", + "indexInBlock": 0 + }, + { + "txhash": "0xb79eab5bad9b2b9c51873f53ee7820e99446c6530ac407be032d0bda6cd601a5", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x136", + "indexInBlock": 0 + }, + { + "txhash": "0xb000e7ae9e2b767464fc90d633aff286a663f6aa4c33b27b8649867f403b8848", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x141", + "indexInBlock": 0 + }, + { + "txhash": "0xa79af0ce0ef3d6c97f08ad0519ee84eb102a8611ff9bbfdb513b737582c66a71", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x14c", + "indexInBlock": 0 + }, + { + "txhash": "0xf3b4d8172c990c289f658b6c3ecf980ce627bfe540ea7a9a11cc4708a38d1e0a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x157", + "indexInBlock": 0 + }, + { + "txhash": "0x385cb2c14d85546645d1cbefa13c01bd6b2eb7f848fc132dd33631b3693d0234", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x162", + "indexInBlock": 0 + }, + { + "txhash": "0x2cfecb05aa5dff4016e567291331de567995aef33595892dcc8da9e8626c5e29", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x16d", + "indexInBlock": 0 + }, + { + "txhash": "0x3c551a5bcb06c70c5ed8a024b9c3092d145806ec47c79711e728b776581ba933", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x178", + "indexInBlock": 0 + }, + { + "txhash": "0xf212343a00e92eecaa2882a9028a974cdb53427925ca5e8e514686429783b660", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x183", + "indexInBlock": 0 + }, + { + "txhash": "0x1690ab67922c40b4feba88cb3dadb633142ee6f8e394b61d5ce74efe81aaa7a3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x18e", + "indexInBlock": 0 + }, + { + "txhash": "0x5051062bb54302b19e2f01987ce412c4026a6eccd8b1224adf89638a893d2ce6", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x199", + "indexInBlock": 0 + }, + { + "txhash": "0x45b3d0b9de23a95ed6af569805c29bbb67e6a70bfa5f5af994b4d134f68b9fbd", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1a4", + "indexInBlock": 0 + }, + { + "txhash": "0xb3446d893246dd626944b802651f051f7e1f52827b8c1b1a1e1b4ab597286726", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1af", + "indexInBlock": 0 + }, + { + "txhash": "0x99d235917c941efc6dc2799623a2b36fc4f5eb2a975952e0a402cd368b2c5c3e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1ba", + "indexInBlock": 0 + }, + { + "txhash": "0x1841d6e9976ab0bcbc4b00cd67922c026eedd7663122d8f97ad4108f47d70813", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1c5", + "indexInBlock": 0 + }, + { + "txhash": "0x22c29f259f4f88ba7758679ceba786815af37b386f899e91fe0196729acee24d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1d0", + "indexInBlock": 0 + }, + { + "txhash": "0xa157bad573954d4fab243dbb5fc73435233bd00ce8be8dbcd9f7be80b1d17a49", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1db", + "indexInBlock": 0 + }, + { + "txhash": "0xe0f9de399946816e8a2db32d0738e41d22cce9f444f60824128e5b76ba0e813b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1e6", + "indexInBlock": 0 + }, + { + "txhash": "0xf78a2067ea28bab199b8d21a42e09553c1bb8e5df791c76f3ebf77f9162e0da3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1f1", + "indexInBlock": 0 + }, + { + "txhash": "0x754486a577ea77ec5e00664bf0451166b2d5dd9fe42e3b55b9824f78aa628d49", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1fc", + "indexInBlock": 0 + }, + { + "txhash": "0x5eee12b1b419ef402143847e1940476be871883c16c3a0a7229b817123c2a408", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x207", + "indexInBlock": 0 + }, + { + "txhash": "0x5970e58e6ed36d823ef504f70b1a28acc9433b76284ddf1a3814b3beba37146d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x212", + "indexInBlock": 0 + }, + { + "txhash": "0xf5166d4fec3e9457916b4079e7526672cf797bcf7824b69a54867aa78e2f2691", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x21d", + "indexInBlock": 0 + }, + { + "txhash": "0x9a1c5ba87f390597ebd00d8ad572fd3c8b95c68910e62644cb055a0ef06e8eeb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x228", + "indexInBlock": 0 + }, + { + "txhash": "0xef08e643ee3fc351e62c29536758cddb55b8978a71e0fd3ef60fc347d5e6965a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x233", + "indexInBlock": 0 + }, + { + "txhash": "0x5ffa342f7f5240c5fe829b8e171f0e206b71626337c84e091f08fbc38a64a04f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x23e", + "indexInBlock": 0 + }, + { + "txhash": "0x93c697d79b649351a04237604f19f399b797ca5756ec56c83657f06ceda7f06f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x249", + "indexInBlock": 0 + }, + { + "txhash": "0xd8d2d00485bb8b861ebfe6cf40ff7244593d92fa9d30f8200542527ced99e37d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x254", + "indexInBlock": 0 + } + ], + "tx-transfer-eip2930": [ + { + "txhash": "0xe0b7691cf34a37b87a56a79d2887ebb9e1f132d58b0e34c93e51ac80ae361965", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xe", + "indexInBlock": 0 + }, + { + "txhash": "0xe404d773d3dd0560096e006eca641ba5345090871591f3fe7e375e7a430c98c7", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x19", + "indexInBlock": 0 + }, + { + "txhash": "0x0714cd906571480a922fe8d78c1f1061fc40db2cd1ed8cbb4369fda866626a0e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x24", + "indexInBlock": 0 + }, + { + "txhash": "0xfe336bb145af0acfb0aaccafd4318827ed629b8dd51c3e9acd799bb8831bc5f7", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x2f", + "indexInBlock": 0 + }, + { + "txhash": "0x996f4a409ebc40722579170f38948bc8df1aaceddd57fe43799895e989e9037b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x3a", + "indexInBlock": 0 + }, + { + "txhash": "0x3723f923685f12cc032c922ea5b3bb33c3801e3501fd5c33efe367036068e209", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x45", + "indexInBlock": 0 + }, + { + "txhash": "0x0920572b6c461143bad4fb1c8fce1172555e1e7def25fa332aa4f925b257372e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x50", + "indexInBlock": 0 + }, + { + "txhash": "0x14976ca88889d8e531c3e6e857777514216db60edbc5275e54e07bc1bca12f9d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x5b", + "indexInBlock": 0 + }, + { + "txhash": "0x27bbf3f736afb8fcaecb7ac3ccc9c213884eeb5fc7eb657954e148231ff3bcb0", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x66", + "indexInBlock": 0 + }, + { + "txhash": "0x9acc4d59b8d8c2266714935b4a6f240f58816db5d957883864be194491038cf0", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x71", + "indexInBlock": 0 + }, + { + "txhash": "0xe6aa517bcd4b76ad664af114669499b69d4cd4fa9482e12ac17b519d35d040e1", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x7c", + "indexInBlock": 0 + }, + { + "txhash": "0xc282a609762a7ddd8fbf2202f132e7c6e94c63f05ae94a26833cedeb55f3e7ec", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x87", + "indexInBlock": 0 + }, + { + "txhash": "0xbba59f4b08448ce6e94e457da75e10871594f2fb719b47a94d01354b06db8b4b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x92", + "indexInBlock": 0 + }, + { + "txhash": "0x26e0ad605b9338c5f9396bd4da0857e4711b6e67303ab777d2f3e304eeb0198b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x9d", + "indexInBlock": 0 + }, + { + "txhash": "0x9c2232aba0d6cea846a96d85fff3444cc9a9c2b4063232d1ebbb3b00a5bacda3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xa8", + "indexInBlock": 0 + }, + { + "txhash": "0x1eacd4527bb933ad6054547d9f245ac44e26dbfa11610ed6e835772c6ac8ae48", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xb3", + "indexInBlock": 0 + }, + { + "txhash": "0x38647f25a7e7a05902d512884a52a2733603be1e5f20fe9eeda0e2f2dc6fb89e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xbe", + "indexInBlock": 0 + }, + { + "txhash": "0x35ba3e88129db4e62c1806e016e731c72b4d202c2ed1664af0d751558e0b2f5f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xc9", + "indexInBlock": 0 + }, + { + "txhash": "0x714288a3625459cfae682e2e053fb9a6366dd0e37e655da8ac8a603b0c2c879b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xd4", + "indexInBlock": 0 + }, + { + "txhash": "0x638d97e8a1034faf96ade4fb9ca6abacf25c66ccdfe5824a999cde11eaa3b8ed", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xdf", + "indexInBlock": 0 + }, + { + "txhash": "0xc1382a6685aa78c36e5ed96410da6fdb90549678bd5017ed89412a19ed199f81", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xea", + "indexInBlock": 0 + }, + { + "txhash": "0xb446f8fe040ee764827538219e03981d204c329070db7c0a48cd44adeb24db8f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xf5", + "indexInBlock": 0 + }, + { + "txhash": "0xa358a78375426e23e7c6662acd42da119b8f87f2e2888adc163a170cd5e826c7", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x100", + "indexInBlock": 0 + }, + { + "txhash": "0x7a7611969dfd1bde5325f206a97e22c2bc462ff5d2081e71ff89d28777f31c06", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x10b", + "indexInBlock": 0 + }, + { + "txhash": "0x457a238e8a1daf3960fc558f8f84033fd33f59fb988b9a9adae36f873ff3c3b4", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x116", + "indexInBlock": 0 + }, + { + "txhash": "0x4c2d91cbcb732caa6abcbd4140976d0645f6c22d108e477617ee2db2d8129e67", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x121", + "indexInBlock": 0 + }, + { + "txhash": "0x8c9d1f3bb047963383dadc9ff7cb858b97773169532212e283a5695eea9e033f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x12c", + "indexInBlock": 0 + }, + { + "txhash": "0x4c09711bf3edf86842c892fcb260674ec524f014ef5c90f9f3bb23794a8b3956", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x137", + "indexInBlock": 0 + }, + { + "txhash": "0x31992687ad2485da5c31dfda4dbeeec248a65f5ed003563af394e704dfacfc88", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x142", + "indexInBlock": 0 + }, + { + "txhash": "0x661dde8fed4e46c464a33c0f20ee5403250ff3f3c3f99fa55d4307d911b874de", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x14d", + "indexInBlock": 0 + }, + { + "txhash": "0x923cb21db498ee179399dfdb8ebca0e0d9822bca94b1127bcd1f11489845e381", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x158", + "indexInBlock": 0 + }, + { + "txhash": "0xb72ca20dc96db26fec00f01efa1b251f29bb12a1ceb311bfe8bf39431769221b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x163", + "indexInBlock": 0 + }, + { + "txhash": "0xd156edd6076ac206519a5851bdb1ec90a88452c2948ae3fba2be79f1e91dbfe3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x16e", + "indexInBlock": 0 + }, + { + "txhash": "0xf1743d554afb4af9f068901f7ad89b3b432d1bd7a88cbfaeab307a020f14e1de", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x179", + "indexInBlock": 0 + }, + { + "txhash": "0x642dd19ff447e4f83c81c529faeaaf07c811215f9fab8967018ec9ff4c9570ef", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x184", + "indexInBlock": 0 + }, + { + "txhash": "0x259e0e9918735fd7786872176cec8a4669e0bfcae37a6ce496023d871407d395", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x18f", + "indexInBlock": 0 + }, + { + "txhash": "0x34fe95d74f6232b0273cdac075cba7ab6438ae662e89aa71e8b99206bfc57153", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x19a", + "indexInBlock": 0 + }, + { + "txhash": "0xcf826d5d3ccfe1773b5b83a3ec29de8826c92566e310cabf8940733d71ad1cba", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1a5", + "indexInBlock": 0 + }, + { + "txhash": "0x5a88d1e506f286c57a7a3a6f68cab3b18e9f3ef279b574e6910cca83bdaf7daf", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1b0", + "indexInBlock": 0 + }, + { + "txhash": "0xe383a01e0ad60a5f35cadbe8938a1459a679b7717166a9373512c1a832f24423", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1bb", + "indexInBlock": 0 + }, + { + "txhash": "0x65efb74528143a9b3fcedcb4e94892d25661480613c1485fccc00691c7488c8d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1c6", + "indexInBlock": 0 + }, + { + "txhash": "0x54dcbac0ede42273e9b00e78dbc44bd30122cd3b5b17fbf7b8b761bee5de60f7", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1d1", + "indexInBlock": 0 + }, + { + "txhash": "0x725e6fdd298ee6d7a0c85da4b86338b179d0e1e2412042302e14e2d1f80fc7c2", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1dc", + "indexInBlock": 0 + }, + { + "txhash": "0x9b4e47130328936b6c1c0b1eba493d17c314f973dfe7e75b42a3db206e504a23", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1e7", + "indexInBlock": 0 + }, + { + "txhash": "0xece1d40c8ee54ccb4e80533dc30cc365e44f97f62b66173819bf3d8629b69381", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1f2", + "indexInBlock": 0 + }, + { + "txhash": "0x76a2d9684d03b8e18b262d1d27a0d6b21753b93efd510b3913ce0ebe1767945c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1fd", + "indexInBlock": 0 + }, + { + "txhash": "0x46351b527c01acf613175fc763cd5a2a70e35c38c7c76ee0b6555f787d86c6e2", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x208", + "indexInBlock": 0 + }, + { + "txhash": "0xc954c8d329f749ec212c19a85f38482b2a3970da384441ca205ba09a792ea1f7", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x213", + "indexInBlock": 0 + }, + { + "txhash": "0x96ee75e8ef38f2fdaef65165ea3b03d125558e45a74568479ef47db03aa6c5fc", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x21e", + "indexInBlock": 0 + }, + { + "txhash": "0x2a843d73fc5567275043097afb99799acc38822f63b279d4b1a027fda110968b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x229", + "indexInBlock": 0 + }, + { + "txhash": "0x32858610393c1bbc5506b9126e2c6be2030c82c93d298fba9c14cc0ada2513d2", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x234", + "indexInBlock": 0 + }, + { + "txhash": "0xccc59651e1e4c4b64d645f6110eb5433ce8848b4bcdd5bd7d628eed653a9b32b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x23f", + "indexInBlock": 0 + }, + { + "txhash": "0x0f6365dd89c14374995007394ad902ef1b4076160ca7c469a2f40db5143e40fb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x24a", + "indexInBlock": 0 + }, + { + "txhash": "0x2bdf049c6e42fb2882aa350ae0b1ea17e1cc696505a755f97710a13ab5dd2100", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x255", + "indexInBlock": 0 + } + ], + "tx-transfer-legacy": [ + { + "txhash": "0xf5d6671f1963c4b2803a03776a06fe6fcc7ebae6fcc714f2ba9abaa6b9c4331c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xf", + "indexInBlock": 0 + }, + { + "txhash": "0x2c4880155cc7084393750b60732e44dfcc36b5da126d7dafd2e3e679d1fe1456", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1a", + "indexInBlock": 0 + }, + { + "txhash": "0x836d8aef2c4549477e76f9d2250a7818d2659551d4e46d979b3a9c0695824fd5", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x25", + "indexInBlock": 0 + }, + { + "txhash": "0x4142c689b6edab80bd472c19730a883236279ffa68be403a4e0062d34b095cde", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x30", + "indexInBlock": 0 + }, + { + "txhash": "0x3d15ef5c40d1abe4006d81bc88a3d7918853099afa1d6ce499747ae49181deb8", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x3b", + "indexInBlock": 0 + }, + { + "txhash": "0x36b77745eacf696b87e1cefa6eb7308299c022fd04ca579f67bbf9f88a769670", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x46", + "indexInBlock": 0 + }, + { + "txhash": "0x7bd16c7de942d1dfd8a330d3b4f4388897b88c1e55e29950aaa67ab5d340d63b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x51", + "indexInBlock": 0 + }, + { + "txhash": "0x70aa1c05d32af66dadf90df365318ff39bb29204c01e52e7687c2fa03bcd7792", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x5c", + "indexInBlock": 0 + }, + { + "txhash": "0x53fb233255b5c3a627afe4bb562c30bcff7c001bbd84118daf5bf7dab3f6b741", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x67", + "indexInBlock": 0 + }, + { + "txhash": "0xfd5f8f34059ec5a386048f048022aebe3977b326babac83b34d43f1810aea93c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x72", + "indexInBlock": 0 + }, + { + "txhash": "0x98e0d4060dbb4451b13a56dfee901f55d212981e156ad9672cb4bc32e95f7744", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x7d", + "indexInBlock": 0 + }, + { + "txhash": "0xdf35c584e51084b3e1ce88e6927f8dfe4b338538026e0119ed44a8a06ee8680f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x88", + "indexInBlock": 0 + }, + { + "txhash": "0xdd0cdb19583b486fe64aea158301d580605ce93f722e5ed76b6d091ef33cb36b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x93", + "indexInBlock": 0 + }, + { + "txhash": "0x5fbf81465a08a6fd6c858ba525a6449759ad4dd9772e88aefa7d70b40f59fe94", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x9e", + "indexInBlock": 0 + }, + { + "txhash": "0x0707d1ec61cbc124e3cc6dd2b3617df6d15c247b4513776fbc64d6749e212564", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xa9", + "indexInBlock": 0 + }, + { + "txhash": "0x15ce9de77512ff529b9493f36c4faa3b287e2f48634f444ebf33db2bb26f019a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xb4", + "indexInBlock": 0 + }, + { + "txhash": "0x81109d5ba61fc6be29b6825aaa3de407d2691364584ec4465853891a1f9a9092", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xbf", + "indexInBlock": 0 + }, + { + "txhash": "0x741a9b3cb46fb639934e6705950e754a35be54cde90edaa7dc7a7367b964ec1c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xca", + "indexInBlock": 0 + }, + { + "txhash": "0xc74ac6c61b5fa34bd613863335dc814d646c9670319c6b78c5ff78edd303a148", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xd5", + "indexInBlock": 0 + }, + { + "txhash": "0x4cb8d6ad80fb3d560e3c99f89a1e6e949706ee34ac60dfee6d3bac5742defeea", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xe0", + "indexInBlock": 0 + }, + { + "txhash": "0x43e55b80d307da89ba157e2404b4f74486379b82442d2c439b796d05f0b0cc48", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xeb", + "indexInBlock": 0 + }, + { + "txhash": "0x2d78dabdfdf32911d516e48b7630ef0c38d1f23e824a0d206126076ab27ea9de", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0xf6", + "indexInBlock": 0 + }, + { + "txhash": "0x1b87238c602d7af7240cc63513ffa0ded2851e43587ed3b6a4a9278ebd666f7c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x101", + "indexInBlock": 0 + }, + { + "txhash": "0x07796620f21dbc0f24cc465703dec79d4d1ede06e4203229a98ce5a1e3838f97", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x10c", + "indexInBlock": 0 + }, + { + "txhash": "0xe42627e627add33a75bac9aa36bbafd70ce5c225805c6c38e1cfe4d172d5115c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x117", + "indexInBlock": 0 + }, + { + "txhash": "0x63a4e7940479d26fe0540ec179765a76ad718016c46f50b091700bc445e94090", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x122", + "indexInBlock": 0 + }, + { + "txhash": "0x7069110601d62a25c9f53b0d8014a7a350ef57c49e6f4f065db8dcf2d3df424a", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x12d", + "indexInBlock": 0 + }, + { + "txhash": "0x908826470714e97daa2f45cca9b77e61fe6187cfd2382cc6855851c3ab6777e6", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x138", + "indexInBlock": 0 + }, + { + "txhash": "0xe5e41eee4792cc57e81231553406f05ee5f5d0b1064e93eb113b22a5c67120e1", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x143", + "indexInBlock": 0 + }, + { + "txhash": "0x502f2197f9a78a84978ad877be0fe29c5c3277895337c7fba7dd2723644763de", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x14e", + "indexInBlock": 0 + }, + { + "txhash": "0xba56db6e61a61cd1a3aaade35a19f85c614ff0e7afbb7156986118a0dee9af6b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x159", + "indexInBlock": 0 + }, + { + "txhash": "0xc68be8d777be9b31eeffc3daf17761f3a5075875655fe029e82e18cf884b0102", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x164", + "indexInBlock": 0 + }, + { + "txhash": "0xcd438fbb83757586be3d83f4d004024f8cbf464f6bf1662671ba4e97177e86b1", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x16f", + "indexInBlock": 0 + }, + { + "txhash": "0x90a4b393275d8a4e40764b90b1820365ae3b0ebd92c14593789618e08fb44b29", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x17a", + "indexInBlock": 0 + }, + { + "txhash": "0xa82459bb400a4fa392738753dc867627d2ee8436d95e143119505120808bb756", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x185", + "indexInBlock": 0 + }, + { + "txhash": "0xba5383efd6209b60452c61ff20f5faf687ddcbb5426b3d202717a3a0f09cc655", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x190", + "indexInBlock": 0 + }, + { + "txhash": "0xb99807ee84bbedc5e0f04e8bf82400919ffac94c7daa74ce717a9dfcd692dedb", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x19b", + "indexInBlock": 0 + }, + { + "txhash": "0x1b50a9075eea2053d04b1149a22ceb5982115642e42a46f8773b1e75132ba334", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1a6", + "indexInBlock": 0 + }, + { + "txhash": "0x607ef258fe227a1f5fb6a5bfaa714df94bc22567731591ebf3d2be6435735c85", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1b1", + "indexInBlock": 0 + }, + { + "txhash": "0x6337272ab1f627a38c734a263da2debe7958c2154f6607f880d2d9c76cc70c88", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1bc", + "indexInBlock": 0 + }, + { + "txhash": "0xd41f6909931b295eea7c3463a11c979d7174df197110ab3aeb77c16075b0e5be", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1c7", + "indexInBlock": 0 + }, + { + "txhash": "0x5dbc467c60a1655ffc50b47ae6250331a9cdc7818deca6a630e3f00be2fdd419", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1d2", + "indexInBlock": 0 + }, + { + "txhash": "0xad3cdc85f95156f0e6b5cba9228e01db5f4cadea36238ace690321e8150780b7", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1dd", + "indexInBlock": 0 + }, + { + "txhash": "0x0c35c17ae34707eb557bd7e3d6d56a0e3f39841365b4ef46b586131ffd80d93e", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1e8", + "indexInBlock": 0 + }, + { + "txhash": "0x2660c57fca0ca07684524e301982e6ce557d2eef665d60a92c1bbac586b1daa3", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1f3", + "indexInBlock": 0 + }, + { + "txhash": "0x57c142cf1c0eb125de13729a590e4e44dc4b65936068286e4fafa1d144c8548c", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x1fe", + "indexInBlock": 0 + }, + { + "txhash": "0x4ec028beafac0f493add6acd0e5389d4767f6e756cfbebed4c907312bd990a7b", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x209", + "indexInBlock": 0 + }, + { + "txhash": "0x92da32c91120e188fd7a7945c1f9632faa33b85b1c2d63e71da6c5e65d2597ef", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x214", + "indexInBlock": 0 + }, + { + "txhash": "0xb31ea80795c9bba23c7509df3148f04d0b6545e29d463e47ebbb59eb19bfc09d", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x21f", + "indexInBlock": 0 + }, + { + "txhash": "0x84ce5e0adc7ecf6da455c89cbb2fb88b19a6530fe3908dc78a3f48e053304bb2", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x22a", + "indexInBlock": 0 + }, + { + "txhash": "0x2660f8cda902bad9c28fe68cc88cd1c8e168ed676b721a1d62ece206520f3ed9", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x235", + "indexInBlock": 0 + }, + { + "txhash": "0x9bfb5a154892c511155e70f2897ec9191acc3826d3d94b7f59e14c393f9b82cf", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x240", + "indexInBlock": 0 + }, + { + "txhash": "0x0fbd5dc542001c414af0d21f05c33a425491f56488994d16505c09782cf67076", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x24b", + "indexInBlock": 0 + }, + { + "txhash": "0xbf6d4db691b6c5c6810508476aea4812982794ed5a399fc00c0290dc85901c3f", + "sender": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "block": "0x256", + "indexInBlock": 0 } ], "withdrawals": { - "101": { - "withdrawals": [ - { - "index": "0x4", - "validatorIndex": "0x5", - "address": "0x3f79bb7b435b05321651daefd374cdc681dc06fa", - "amount": "0x64" - } - ] - }, - "106": { - "withdrawals": [ - { - "index": "0x5", - "validatorIndex": "0x5", - "address": "0x189f40034be7a199f1fa9891668ee3ab6049f82d", - "amount": "0x64" - } - ] - }, - "111": { - "withdrawals": [ - { - "index": "0x6", - "validatorIndex": "0x5", - "address": "0x65c74c15a686187bb6bbf9958f494fc6b8006803", - "amount": "0x64" - } - ] - }, - "116": { - "withdrawals": [ - { - "index": "0x7", - "validatorIndex": "0x5", - "address": "0xe3b98a4da31a127d4bde6e43033f66ba274cab0e", - "amount": "0x64" - } - ] - }, - "121": { + "104": { "withdrawals": [ { "index": "0x8", "validatorIndex": "0x5", - "address": "0xa1fce4363854ff888cff4b8e7875d600c2682390", + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", + "amount": "0x64" + } + ] + }, + "115": { + "withdrawals": [ + { + "index": "0x9", + "validatorIndex": "0x5", + "address": "0xe7d13f7aa2a838d24c59b40186a0aca1e21cffcc", "amount": "0x64" } ] }, "126": { - "withdrawals": [ - { - "index": "0x9", - "validatorIndex": "0x5", - "address": "0x7ace431cb61584cb9b8dc7ec08cf38ac0a2d6496", - "amount": "0x64" - } - ] - }, - "131": { "withdrawals": [ { "index": "0xa", "validatorIndex": "0x5", - "address": "0x5ee0dd4d4840229fab4a86438efbcaf1b9571af9", + "address": "0x4340ee1b812acb40a1eb561c019c327b243b92df", "amount": "0x64" } ] }, - "136": { + "137": { "withdrawals": [ { "index": "0xb", "validatorIndex": "0x5", - "address": "0x4f362f9093bb8e7012f466224ff1237c0746d8c8", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", "amount": "0x64" } ] }, - "141": { + "148": { "withdrawals": [ { "index": "0xc", "validatorIndex": "0x5", - "address": "0x075198bfe61765d35f990debe90959d438a943ce", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", "amount": "0x64" } ] }, - "146": { + "159": { "withdrawals": [ { "index": "0xd", "validatorIndex": "0x5", - "address": "0x956062137518b270d730d4753000896de17c100a", + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", "amount": "0x64" } ] }, - "151": { + "16": { + "withdrawals": [ + { + "index": "0x0", + "validatorIndex": "0x5", + "address": "0x5f552da00dfb4d3749d9e62dcee3c918855a86a0", + "amount": "0x64" + } + ] + }, + "170": { "withdrawals": [ { "index": "0xe", "validatorIndex": "0x5", - "address": "0x2a0ab732b4e9d85ef7dc25303b64ab527c25a4d7", - "amount": "0x64" - } - ] - }, - "156": { - "withdrawals": [ - { - "index": "0xf", - "validatorIndex": "0x5", - "address": "0x6e3faf1e27d45fca70234ae8f6f0a734622cff8a", - "amount": "0x64" - } - ] - }, - "161": { - "withdrawals": [ - { - "index": "0x10", - "validatorIndex": "0x5", - "address": "0x8a8950f7623663222542c9469c73be3c4c81bbdf", - "amount": "0x64" - } - ] - }, - "166": { - "withdrawals": [ - { - "index": "0x11", - "validatorIndex": "0x5", - "address": "0xfe1dcd3abfcd6b1655a026e60a05d03a7f71e4b6", - "amount": "0x64" - } - ] - }, - "171": { - "withdrawals": [ - { - "index": "0x12", - "validatorIndex": "0x5", - "address": "0x087d80f7f182dd44f184aa86ca34488853ebcc04", - "amount": "0x64" - } - ] - }, - "176": { - "withdrawals": [ - { - "index": "0x13", - "validatorIndex": "0x5", - "address": "0xf4f97c88c409dcf3789b5b518da3f7d266c48806", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "amount": "0x64" } ] @@ -2337,109 +2821,49 @@ "181": { "withdrawals": [ { - "index": "0x14", + "index": "0xf", "validatorIndex": "0x5", - "address": "0x892f60b39450a0e770f00a836761c8e964fd7467", + "address": "0x2d389075be5be9f2246ad654ce152cf05990b209", "amount": "0x64" } ] }, - "186": { + "192": { "withdrawals": [ { - "index": "0x15", + "index": "0x10", "validatorIndex": "0x5", - "address": "0x281c93990bac2c69cf372c9a3b66c406c86cca82", + "address": "0x2d389075be5be9f2246ad654ce152cf05990b209", "amount": "0x64" } ] }, - "191": { + "203": { "withdrawals": [ { - "index": "0x16", + "index": "0x11", "validatorIndex": "0x5", - "address": "0xb12dc850a3b0a3b79fc2255e175241ce20489fe4", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "amount": "0x64" } ] }, - "196": { + "214": { "withdrawals": [ { - "index": "0x17", + "index": "0x12", "validatorIndex": "0x5", - "address": "0xd1211001882d2ce16a8553e449b6c8b7f71e6183", + "address": "0x84e75c28348fb86acea1a93a39426d7d60f4cc46", "amount": "0x64" } ] }, - "201": { + "225": { "withdrawals": [ { - "index": "0x18", + "index": "0x13", "validatorIndex": "0x5", - "address": "0x4fb733bedb74fec8d65bedf056b935189a289e92", - "amount": "0x64" - } - ] - }, - "206": { - "withdrawals": [ - { - "index": "0x19", - "validatorIndex": "0x5", - "address": "0xc337ded6f56c07205fb7b391654d7d463c9e0c72", - "amount": "0x64" - } - ] - }, - "211": { - "withdrawals": [ - { - "index": "0x1a", - "validatorIndex": "0x5", - "address": "0x28969cdfa74a12c82f3bad960b0b000aca2ac329", - "amount": "0x64" - } - ] - }, - "216": { - "withdrawals": [ - { - "index": "0x1b", - "validatorIndex": "0x5", - "address": "0xaf193a8cdcd0e3fb39e71147e59efa5cad40763d", - "amount": "0x64" - } - ] - }, - "221": { - "withdrawals": [ - { - "index": "0x1c", - "validatorIndex": "0x5", - "address": "0x2795044ce0f83f718bc79c5f2add1e52521978df", - "amount": "0x64" - } - ] - }, - "226": { - "withdrawals": [ - { - "index": "0x1d", - "validatorIndex": "0x5", - "address": "0x30a5bfa58e128af9e5a4955725d8ad26d4d574a5", - "amount": "0x64" - } - ] - }, - "231": { - "withdrawals": [ - { - "index": "0x1e", - "validatorIndex": "0x5", - "address": "0xd0752b60adb148ca0b3b4d2591874e2dabd34637", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", "amount": "0x64" } ] @@ -2447,109 +2871,59 @@ "236": { "withdrawals": [ { - "index": "0x1f", + "index": "0x14", "validatorIndex": "0x5", - "address": "0x45f83d17e10b34fca01eb8f4454dac34a777d940", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", "amount": "0x64" } ] }, - "241": { + "247": { "withdrawals": [ { - "index": "0x20", + "index": "0x15", "validatorIndex": "0x5", - "address": "0xd4f09e5c5af99a24c7e304ca7997d26cb0090169", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", "amount": "0x64" } ] }, - "246": { + "258": { "withdrawals": [ { - "index": "0x21", + "index": "0x16", "validatorIndex": "0x5", - "address": "0xb0b2988b6bbe724bacda5e9e524736de0bc7dae4", + "address": "0x84e75c28348fb86acea1a93a39426d7d60f4cc46", "amount": "0x64" } ] }, - "251": { + "269": { "withdrawals": [ { - "index": "0x22", + "index": "0x17", "validatorIndex": "0x5", - "address": "0x04b8d34e20e604cadb04b9db8f6778c35f45a2d2", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "amount": "0x64" } ] }, - "256": { + "27": { "withdrawals": [ { - "index": "0x23", + "index": "0x1", "validatorIndex": "0x5", - "address": "0x47dc540c94ceb704a23875c11273e16bb0b8a87a", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", "amount": "0x64" } ] }, - "261": { + "280": { "withdrawals": [ { - "index": "0x24", + "index": "0x18", "validatorIndex": "0x5", - "address": "0xbc5959f43bc6e47175374b6716e53c9a7d72c594", - "amount": "0x64" - } - ] - }, - "266": { - "withdrawals": [ - { - "index": "0x25", - "validatorIndex": "0x5", - "address": "0xc04b5bb1a5b2eb3e9cd4805420dba5a9d133da5b", - "amount": "0x64" - } - ] - }, - "271": { - "withdrawals": [ - { - "index": "0x26", - "validatorIndex": "0x5", - "address": "0x24255ef5d941493b9978f3aabb0ed07d084ade19", - "amount": "0x64" - } - ] - }, - "276": { - "withdrawals": [ - { - "index": "0x27", - "validatorIndex": "0x5", - "address": "0xdbe726e81a7221a385e007ef9e834a975a4b528c", - "amount": "0x64" - } - ] - }, - "281": { - "withdrawals": [ - { - "index": "0x28", - "validatorIndex": "0x5", - "address": "0xae58b7e08e266680e93e46639a2a7e89fde78a6f", - "amount": "0x64" - } - ] - }, - "286": { - "withdrawals": [ - { - "index": "0x29", - "validatorIndex": "0x5", - "address": "0x5df7504bc193ee4c3deadede1459eccca172e87c", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", "amount": "0x64" } ] @@ -2557,109 +2931,49 @@ "291": { "withdrawals": [ { - "index": "0x2a", + "index": "0x19", "validatorIndex": "0x5", - "address": "0xb71de80778f2783383f5d5a3028af84eab2f18a4", + "address": "0xeda8645ba6948855e3b3cd596bbb07596d59c603", "amount": "0x64" } ] }, - "296": { + "302": { "withdrawals": [ { - "index": "0x2b", + "index": "0x1a", "validatorIndex": "0x5", - "address": "0x1c972398125398a3665f212930758ae9518a8c94", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", "amount": "0x64" } ] }, - "301": { + "313": { "withdrawals": [ { - "index": "0x2c", + "index": "0x1b", "validatorIndex": "0x5", - "address": "0x1c123d5c0d6c5a22ef480dce944631369fc6ce28", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", "amount": "0x64" } ] }, - "306": { + "324": { "withdrawals": [ { - "index": "0x2d", + "index": "0x1c", "validatorIndex": "0x5", - "address": "0x7f774bb46e7e342a2d9d0514b27cee622012f741", + "address": "0x84e75c28348fb86acea1a93a39426d7d60f4cc46", "amount": "0x64" } ] }, - "311": { + "335": { "withdrawals": [ { - "index": "0x2e", + "index": "0x1d", "validatorIndex": "0x5", - "address": "0x06f647b157b8557a12979ba04cf5ba222b9747cf", - "amount": "0x64" - } - ] - }, - "316": { - "withdrawals": [ - { - "index": "0x2f", - "validatorIndex": "0x5", - "address": "0xcccc369c5141675a9e9b1925164f30cdd60992dc", - "amount": "0x64" - } - ] - }, - "321": { - "withdrawals": [ - { - "index": "0x30", - "validatorIndex": "0x5", - "address": "0xacfa6b0e008d0208f16026b4d17a4c070e8f9f8d", - "amount": "0x64" - } - ] - }, - "326": { - "withdrawals": [ - { - "index": "0x31", - "validatorIndex": "0x5", - "address": "0x6a632187a3abf9bebb66d43368fccd612f631cbc", - "amount": "0x64" - } - ] - }, - "331": { - "withdrawals": [ - { - "index": "0x32", - "validatorIndex": "0x5", - "address": "0x984c16459ded76438d98ce9b608f175c28a910a0", - "amount": "0x64" - } - ] - }, - "336": { - "withdrawals": [ - { - "index": "0x33", - "validatorIndex": "0x5", - "address": "0x2847213288f0988543a76512fab09684131809d9", - "amount": "0x64" - } - ] - }, - "341": { - "withdrawals": [ - { - "index": "0x34", - "validatorIndex": "0x5", - "address": "0x1037044fabf0421617c47c74681d7cc9c59f136c", + "address": "0x4340ee1b812acb40a1eb561c019c327b243b92df", "amount": "0x64" } ] @@ -2667,109 +2981,59 @@ "346": { "withdrawals": [ { - "index": "0x35", + "index": "0x1e", "validatorIndex": "0x5", - "address": "0x8cf42eb93b1426f22a30bd22539503bdf838830c", + "address": "0x3ae75c08b4c907eb63a8960c45b86e1e9ab6123c", "amount": "0x64" } ] }, - "351": { + "357": { "withdrawals": [ { - "index": "0x36", + "index": "0x1f", "validatorIndex": "0x5", - "address": "0x6b2884fef44bd4288621a2cda9f88ca07b480861", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", "amount": "0x64" } ] }, - "356": { + "368": { "withdrawals": [ { - "index": "0x37", + "index": "0x20", "validatorIndex": "0x5", - "address": "0xf6152f2ad8a93dc0f8f825f2a8d162d6da46e81f", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", "amount": "0x64" } ] }, - "361": { + "379": { "withdrawals": [ { - "index": "0x38", + "index": "0x21", "validatorIndex": "0x5", - "address": "0x8fa24283a8c1cc8a0f76ac69362139a173592567", + "address": "0x4a0f1452281bcec5bd90c3dce6162a5995bfe9df", "amount": "0x64" } ] }, - "366": { + "38": { "withdrawals": [ { - "index": "0x39", + "index": "0x2", "validatorIndex": "0x5", - "address": "0x19041ad672875015bc4041c24b581eafc0869aab", + "address": "0xe7d13f7aa2a838d24c59b40186a0aca1e21cffcc", "amount": "0x64" } ] }, - "371": { + "390": { "withdrawals": [ { - "index": "0x3a", + "index": "0x22", "validatorIndex": "0x5", - "address": "0x2bb3295506aa5a21b58f1fd40f3b0f16d6d06bbc", - "amount": "0x64" - } - ] - }, - "376": { - "withdrawals": [ - { - "index": "0x3b", - "validatorIndex": "0x5", - "address": "0x23c86a8aded0ad81f8111bb07e6ec0ffb00ce5bf", - "amount": "0x64" - } - ] - }, - "381": { - "withdrawals": [ - { - "index": "0x3c", - "validatorIndex": "0x5", - "address": "0x96a1cabb97e1434a6e23e684dd4572e044c243ea", - "amount": "0x64" - } - ] - }, - "386": { - "withdrawals": [ - { - "index": "0x3d", - "validatorIndex": "0x5", - "address": "0xfd5e6e8c850fafa2ba2293c851479308c0f0c9e7", - "amount": "0x64" - } - ] - }, - "391": { - "withdrawals": [ - { - "index": "0x3e", - "validatorIndex": "0x5", - "address": "0xf997ed224012b1323eb2a6a0c0044a956c6b8070", - "amount": "0x64" - } - ] - }, - "396": { - "withdrawals": [ - { - "index": "0x3f", - "validatorIndex": "0x5", - "address": "0x6d09a879576c0d941bea7833fb2285051b10d511", + "address": "0x2d389075be5be9f2246ad654ce152cf05990b209", "amount": "0x64" } ] @@ -2777,109 +3041,49 @@ "401": { "withdrawals": [ { - "index": "0x40", + "index": "0x23", "validatorIndex": "0x5", - "address": "0x13dd437fc2ed1cd5d943ac1dd163524c815d305c", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", "amount": "0x64" } ] }, - "406": { + "412": { "withdrawals": [ { - "index": "0x41", + "index": "0x24", "validatorIndex": "0x5", - "address": "0x6510225e743d73828aa4f73a3133818490bd8820", + "address": "0x14e46043e63d0e3cdcf2530519f4cfaf35058cb2", "amount": "0x64" } ] }, - "411": { + "423": { "withdrawals": [ { - "index": "0x42", + "index": "0x25", "validatorIndex": "0x5", - "address": "0xd282cf9c585bb4f6ce71e16b6453b26aa8d34a53", + "address": "0xeda8645ba6948855e3b3cd596bbb07596d59c603", "amount": "0x64" } ] }, - "416": { + "434": { "withdrawals": [ { - "index": "0x43", + "index": "0x26", "validatorIndex": "0x5", - "address": "0xa179dbdd51c56d0988551f92535797bcf47ca0e7", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", "amount": "0x64" } ] }, - "421": { + "445": { "withdrawals": [ { - "index": "0x44", + "index": "0x27", "validatorIndex": "0x5", - "address": "0x494d799e953876ac6022c3f7da5e0f3c04b549be", - "amount": "0x64" - } - ] - }, - "426": { - "withdrawals": [ - { - "index": "0x45", - "validatorIndex": "0x5", - "address": "0xb4bc136e1fb4ea0b3340d06b158277c4a8537a13", - "amount": "0x64" - } - ] - }, - "431": { - "withdrawals": [ - { - "index": "0x46", - "validatorIndex": "0x5", - "address": "0x368b766f1e4d7bf437d2a709577a5210a99002b6", - "amount": "0x64" - } - ] - }, - "436": { - "withdrawals": [ - { - "index": "0x47", - "validatorIndex": "0x5", - "address": "0x5123198d8a827fe0c788c409e7d2068afde64339", - "amount": "0x64" - } - ] - }, - "441": { - "withdrawals": [ - { - "index": "0x48", - "validatorIndex": "0x5", - "address": "0xd39b94587711196640659ec81855bcf397e419ff", - "amount": "0x64" - } - ] - }, - "446": { - "withdrawals": [ - { - "index": "0x49", - "validatorIndex": "0x5", - "address": "0x6ca60a92cbf88c7f527978dc183a22e774755551", - "amount": "0x64" - } - ] - }, - "451": { - "withdrawals": [ - { - "index": "0x4a", - "validatorIndex": "0x5", - "address": "0x102efa1f2e0ad16ada57759b815245b8f8d27ce4", + "address": "0x1f4924b14f34e24159387c0a4cdbaa32f3ddb0cf", "amount": "0x64" } ] @@ -2887,129 +3091,189 @@ "456": { "withdrawals": [ { - "index": "0x4b", + "index": "0x28", "validatorIndex": "0x5", - "address": "0xfcc8d4cd5a42cca8ac9f9437a6d0ac09f1d08785", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "amount": "0x64" } ] }, - "461": { + "467": { "withdrawals": [ { - "index": "0x4c", + "index": "0x29", "validatorIndex": "0x5", - "address": "0x48701721ec0115f04bc7404058f6c0f386946e09", + "address": "0x4a0f1452281bcec5bd90c3dce6162a5995bfe9df", "amount": "0x64" } ] }, - "466": { + "478": { "withdrawals": [ { - "index": "0x4d", + "index": "0x2a", "validatorIndex": "0x5", - "address": "0x706be462488699e89b722822dcec9822ad7d05a7", + "address": "0x4340ee1b812acb40a1eb561c019c327b243b92df", "amount": "0x64" } ] }, - "471": { + "489": { "withdrawals": [ { - "index": "0x4e", + "index": "0x2b", "validatorIndex": "0x5", - "address": "0xe5ec19296e6d1518a6a38c1dbc7ad024b8a1a248", + "address": "0x83c7e323d189f18725ac510004fdc2941f8c4a78", "amount": "0x64" } ] }, - "476": { - "withdrawals": [ - { - "index": "0x4f", - "validatorIndex": "0x5", - "address": "0x2e350f8e7f890a9301f33edbf55f38e67e02d72b", - "amount": "0x64" - } - ] - }, - "481": { - "withdrawals": [ - { - "index": "0x50", - "validatorIndex": "0x5", - "address": "0xc57aa6a4279377063b17c554d3e33a3490e67a9a", - "amount": "0x64" - } - ] - }, - "486": { - "withdrawals": [ - { - "index": "0x51", - "validatorIndex": "0x5", - "address": "0x311df588ca5f412f970891e4cc3ac23648968ca2", - "amount": "0x64" - } - ] - }, - "491": { - "withdrawals": [ - { - "index": "0x52", - "validatorIndex": "0x5", - "address": "0x3f31becc97226d3c17bf574dd86f39735fe0f0c1", - "amount": "0x64" - } - ] - }, - "496": { - "withdrawals": [ - { - "index": "0x53", - "validatorIndex": "0x5", - "address": "0x6cc0ab95752bf25ec58c91b1d603c5eb41b8fbd7", - "amount": "0x64" - } - ] - }, - "81": { - "withdrawals": [ - { - "index": "0x0", - "validatorIndex": "0x5", - "address": "0x4ae81572f06e1b88fd5ced7a1a000945432e83e1", - "amount": "0x64" - } - ] - }, - "86": { - "withdrawals": [ - { - "index": "0x1", - "validatorIndex": "0x5", - "address": "0xde5a6f78116eca62d7fc5ce159d23ae6b889b365", - "amount": "0x64" - } - ] - }, - "91": { - "withdrawals": [ - { - "index": "0x2", - "validatorIndex": "0x5", - "address": "0x245843abef9e72e7efac30138a994bf6301e7e1d", - "amount": "0x64" - } - ] - }, - "96": { + "49": { "withdrawals": [ { "index": "0x3", "validatorIndex": "0x5", - "address": "0x8d33f520a3c4cef80d2453aef81b612bfe1cb44c", + "address": "0xd803681e487e6ac18053afc5a6cd813c86ec3e4d", + "amount": "0x64" + } + ] + }, + "500": { + "withdrawals": [ + { + "index": "0x2c", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "amount": "0x64" + } + ] + }, + "511": { + "withdrawals": [ + { + "index": "0x2d", + "validatorIndex": "0x5", + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", + "amount": "0x64" + } + ] + }, + "522": { + "withdrawals": [ + { + "index": "0x2e", + "validatorIndex": "0x5", + "address": "0x0c2c51a0990aee1d73c1228de158688341557508", + "amount": "0x64" + } + ] + }, + "533": { + "withdrawals": [ + { + "index": "0x2f", + "validatorIndex": "0x5", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", + "amount": "0x64" + } + ] + }, + "544": { + "withdrawals": [ + { + "index": "0x30", + "validatorIndex": "0x5", + "address": "0x1f5bde34b4afc686f136c7a3cb6ec376f7357759", + "amount": "0x64" + } + ] + }, + "555": { + "withdrawals": [ + { + "index": "0x31", + "validatorIndex": "0x5", + "address": "0x5f552da00dfb4d3749d9e62dcee3c918855a86a0", + "amount": "0x64" + } + ] + }, + "566": { + "withdrawals": [ + { + "index": "0x32", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "amount": "0x64" + } + ] + }, + "577": { + "withdrawals": [ + { + "index": "0x33", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", + "amount": "0x64" + } + ] + }, + "588": { + "withdrawals": [ + { + "index": "0x34", + "validatorIndex": "0x5", + "address": "0xc7b99a164efd027a93f147376cc7da7c67c6bbe0", + "amount": "0x64" + } + ] + }, + "599": { + "withdrawals": [ + { + "index": "0x35", + "validatorIndex": "0x5", + "address": "0x1f4924b14f34e24159387c0a4cdbaa32f3ddb0cf", + "amount": "0x64" + } + ] + }, + "60": { + "withdrawals": [ + { + "index": "0x4", + "validatorIndex": "0x5", + "address": "0xe7d13f7aa2a838d24c59b40186a0aca1e21cffcc", + "amount": "0x64" + } + ] + }, + "71": { + "withdrawals": [ + { + "index": "0x5", + "validatorIndex": "0x5", + "address": "0x654aa64f5fbefb84c270ec74211b81ca8c44a72e", + "amount": "0x64" + } + ] + }, + "82": { + "withdrawals": [ + { + "index": "0x6", + "validatorIndex": "0x5", + "address": "0x717f8aa2b982bee0e29f573d31df288663e1ce16", + "amount": "0x64" + } + ] + }, + "93": { + "withdrawals": [ + { + "index": "0x7", + "validatorIndex": "0x5", + "address": "0x7435ed30a8b4aeb0877cef0c6e8cffe834eb865f", "amount": "0x64" } ] diff --git a/cmd/devp2p/rlpxcmd.go b/cmd/devp2p/rlpxcmd.go index 118731fd6c..1dc8f82460 100644 --- a/cmd/devp2p/rlpxcmd.go +++ b/cmd/devp2p/rlpxcmd.go @@ -143,9 +143,6 @@ type testParams struct { func cliTestParams(ctx *cli.Context) *testParams { nodeStr := ctx.String(testNodeFlag.Name) - if nodeStr == "" { - exit(fmt.Errorf("missing -%s", testNodeFlag.Name)) - } node, err := parseNode(nodeStr) if err != nil { exit(err) @@ -156,14 +153,5 @@ func cliTestParams(ctx *cli.Context) *testParams { jwt: ctx.String(testNodeJWTFlag.Name), chainDir: ctx.String(testChainDirFlag.Name), } - if p.engineAPI == "" { - exit(fmt.Errorf("missing -%s", testNodeEngineFlag.Name)) - } - if p.jwt == "" { - exit(fmt.Errorf("missing -%s", testNodeJWTFlag.Name)) - } - if p.chainDir == "" { - exit(fmt.Errorf("missing -%s", testChainDirFlag.Name)) - } return &p } diff --git a/cmd/devp2p/runtest.go b/cmd/devp2p/runtest.go index 7e3723c641..c40a4b8a01 100644 --- a/cmd/devp2p/runtest.go +++ b/cmd/devp2p/runtest.go @@ -39,26 +39,29 @@ var ( } // for eth/snap tests - testChainDirFlag = &cli.StringFlag{ + testChainDirFlag = &cli.PathFlag{ Name: "chain", Usage: "Test chain directory (required)", Category: flags.TestingCategory, + Required: true, } testNodeFlag = &cli.StringFlag{ Name: "node", Usage: "Peer-to-Peer endpoint (ENR) of the test node (required)", Category: flags.TestingCategory, + Required: true, } testNodeJWTFlag = &cli.StringFlag{ Name: "jwtsecret", Usage: "JWT secret for the engine API of the test node (required)", Category: flags.TestingCategory, - Value: "0x7365637265747365637265747365637265747365637265747365637265747365", + Required: true, } testNodeEngineFlag = &cli.StringFlag{ Name: "engineapi", Usage: "Engine API endpoint of the test node (required)", Category: flags.TestingCategory, + Required: true, } // These two are specific to the discovery tests. diff --git a/cmd/era/main.go b/cmd/era/main.go index 8b57fd695c..35a889d4dc 100644 --- a/cmd/era/main.go +++ b/cmd/era/main.go @@ -274,10 +274,10 @@ func checkAccumulator(e *era.Era) error { for it.Next() { // 1) next() walks the block index, so we're able to implicitly verify it. if it.Error() != nil { - return fmt.Errorf("error reading block %d: %w", it.Number(), err) + return fmt.Errorf("error reading block %d: %w", it.Number(), it.Error()) } block, receipts, err := it.BlockAndReceipts() - if it.Error() != nil { + if err != nil { return fmt.Errorf("error reading block %d: %w", it.Number(), err) } // 2) recompute tx root and verify against header. @@ -294,6 +294,9 @@ func checkAccumulator(e *era.Era) error { td.Add(td, block.Difficulty()) tds = append(tds, new(big.Int).Set(td)) } + if it.Error() != nil { + return fmt.Errorf("error reading block %d: %w", it.Number(), it.Error()) + } // 4+5) Verify accumulator and total difficulty. got, err := era.ComputeAccumulator(hashes, tds) if err != nil { diff --git a/cmd/evm/blockrunner.go b/cmd/evm/blockrunner.go index 31d1ba5ba1..c6fac5396e 100644 --- a/cmd/evm/blockrunner.go +++ b/cmd/evm/blockrunner.go @@ -17,16 +17,18 @@ package main import ( + "bufio" "encoding/json" - "errors" "fmt" "maps" "os" "regexp" "slices" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/tests" "github.com/urfave/cli/v2" ) @@ -34,33 +36,52 @@ import ( var blockTestCommand = &cli.Command{ Action: blockTestCmd, Name: "blocktest", - Usage: "Executes the given blockchain tests", + Usage: "Executes the given blockchain tests. Filenames can be fed via standard input (batch mode) or as an argument (one-off execution).", ArgsUsage: "", Flags: slices.Concat([]cli.Flag{ DumpFlag, HumanReadableFlag, RunFlag, WitnessCrossCheckFlag, + FuzzFlag, }, traceFlags), } func blockTestCmd(ctx *cli.Context) error { path := ctx.Args().First() - if len(path) == 0 { - return errors.New("path argument required") + + // If path is provided, run the tests at that path. + if len(path) != 0 { + var ( + collected = collectFiles(path) + results []testResult + ) + for _, fname := range collected { + r, err := runBlockTest(ctx, fname) + if err != nil { + return err + } + results = append(results, r...) + } + report(ctx, results) + return nil } - var ( - collected = collectFiles(path) - results []testResult - ) - for _, fname := range collected { - r, err := runBlockTest(ctx, fname) + // Otherwise, read filenames from stdin and execute back-to-back. + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + fname := scanner.Text() + if len(fname) == 0 { + return nil + } + results, err := runBlockTest(ctx, fname) if err != nil { return err } - results = append(results, r...) + // During fuzzing, we report the result after every block + if !ctx.IsSet(FuzzFlag.Name) { + report(ctx, results) + } } - report(ctx, results) return nil } @@ -79,6 +100,11 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) { } tracer := tracerFromFlags(ctx) + // Suppress INFO logs during fuzzing + if ctx.IsSet(FuzzFlag.Name) { + log.SetDefault(log.NewLogger(log.DiscardHandler())) + } + // Pull out keys to sort and ensure tests are run in order. keys := slices.Sorted(maps.Keys(tests)) @@ -88,16 +114,35 @@ func runBlockTest(ctx *cli.Context, fname string) ([]testResult, error) { if !re.MatchString(name) { continue } + test := tests[name] result := &testResult{Name: name, Pass: true} - if err := tests[name].Run(false, rawdb.HashScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) { + var finalRoot *common.Hash + if err := test.Run(false, rawdb.PathScheme, ctx.Bool(WitnessCrossCheckFlag.Name), tracer, func(res error, chain *core.BlockChain) { if ctx.Bool(DumpFlag.Name) { if s, _ := chain.State(); s != nil { result.State = dump(s) } } + // Capture final state root for end marker + if chain != nil { + root := chain.CurrentBlock().Root + finalRoot = &root + } }); err != nil { result.Pass, result.Error = false, err.Error() } + + // Always assign fork (regardless of pass/fail or tracer) + result.Fork = test.Network() + // Assign root if test succeeded + if result.Pass && finalRoot != nil { + result.Root = finalRoot + } + + // When fuzzing, write results after every block + if ctx.IsSet(FuzzFlag.Name) { + report(ctx, []testResult{*result}) + } results = append(results, *result) } return results, nil diff --git a/cmd/evm/internal/t8ntool/execution.go b/cmd/evm/internal/t8ntool/execution.go index da1fb3701f..44f15c322c 100644 --- a/cmd/evm/internal/t8ntool/execution.go +++ b/cmd/evm/internal/t8ntool/execution.go @@ -18,6 +18,7 @@ package t8ntool import ( "fmt" + stdmath "math" "math/big" "github.com/ethereum/go-ethereum/common" @@ -32,7 +33,6 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" @@ -44,8 +44,9 @@ import ( ) type Prestate struct { - Env stEnv `json:"env"` - Pre types.GenesisAlloc `json:"pre"` + Env stEnv `json:"env"` + Pre types.GenesisAlloc `json:"pre"` + TreeLeaves map[common.Hash]hexutil.Bytes `json:"vkt,omitempty"` } //go:generate go run github.com/fjl/gencodec -type ExecutionResult -field-override executionResultMarshaling -out gen_execresult.go @@ -143,7 +144,8 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, return h } var ( - statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre) + isEIP4762 = chainConfig.IsVerkle(big.NewInt(int64(pre.Env.Number)), pre.Env.Timestamp) + statedb = MakePreState(rawdb.NewMemoryDatabase(), pre.Pre, isEIP4762) signer = types.MakeSigner(chainConfig, new(big.Int).SetUint64(pre.Env.Number), pre.Env.Timestamp) gaspool = new(core.GasPool) blockHash = common.Hash{0x13, 0x37} @@ -152,7 +154,6 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, gasUsed = uint64(0) blobGasUsed = uint64(0) receipts = make(types.Receipts, 0) - txIndex = 0 ) gaspool.AddGas(pre.Env.GasLimit) vmContext := vm.BlockContext{ @@ -193,6 +194,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, Time: pre.Env.ParentTimestamp, ExcessBlobGas: pre.Env.ParentExcessBlobGas, BlobGasUsed: pre.Env.ParentBlobGasUsed, + BaseFee: pre.Env.ParentBaseFee, } header := &types.Header{ Time: pre.Env.Timestamp, @@ -250,24 +252,17 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, continue } } - statedb.SetTxContext(tx.Hash(), txIndex) + statedb.SetTxContext(tx.Hash(), len(receipts)) var ( snapshot = statedb.Snapshot() prevGas = gaspool.Gas() ) - if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxStart != nil { - evm.Config.Tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) - } - // (ret []byte, usedGas uint64, failed bool, err error) - msgResult, err := core.ApplyMessage(evm, msg, gaspool) + receipt, err := core.ApplyTransactionWithEVM(msg, gaspool, statedb, vmContext.BlockNumber, blockHash, pre.Env.Timestamp, tx, &gasUsed, evm) if err != nil { statedb.RevertToSnapshot(snapshot) log.Info("rejected tx", "index", i, "hash", tx.Hash(), "from", msg.From, "error", err) rejectedTxs = append(rejectedTxs, &rejectedTx{i, err.Error()}) gaspool.SetGas(prevGas) - if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxEnd != nil { - evm.Config.Tracer.OnTxEnd(nil, err) - } continue } includedTxs = append(includedTxs, tx) @@ -275,50 +270,11 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, return nil, nil, nil, NewError(ErrorMissingBlockhash, hashError) } blobGasUsed += txBlobGas - gasUsed += msgResult.UsedGas - - // Receipt: - { - var root []byte - if chainConfig.IsByzantium(vmContext.BlockNumber) { - statedb.Finalise(true) - } else { - root = statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)).Bytes() - } - - // Create a new receipt for the transaction, storing the intermediate root and - // gas used by the tx. - receipt := &types.Receipt{Type: tx.Type(), PostState: root, CumulativeGasUsed: gasUsed} - if msgResult.Failed() { - receipt.Status = types.ReceiptStatusFailed - } else { - receipt.Status = types.ReceiptStatusSuccessful - } - receipt.TxHash = tx.Hash() - receipt.GasUsed = msgResult.UsedGas - - // If the transaction created a contract, store the creation address in the receipt. - if msg.To == nil { - receipt.ContractAddress = crypto.CreateAddress(evm.TxContext.Origin, tx.Nonce()) - } - - // Set the receipt logs and create the bloom filter. - receipt.Logs = statedb.GetLogs(tx.Hash(), vmContext.BlockNumber.Uint64(), blockHash, vmContext.Time) - receipt.Bloom = types.CreateBloom(receipt) - - // These three are non-consensus fields: - //receipt.BlockHash - //receipt.BlockNumber - receipt.TransactionIndex = uint(txIndex) - receipts = append(receipts, receipt) - if evm.Config.Tracer != nil && evm.Config.Tracer.OnTxEnd != nil { - evm.Config.Tracer.OnTxEnd(receipt, nil) - } - } - - txIndex++ + receipts = append(receipts, receipt) } + statedb.IntermediateRoot(chainConfig.IsEIP158(vmContext.BlockNumber)) + // Add mining reward? (-1 means rewards are disabled) if miningReward >= 0 { // Add mining reward. The mining reward may be `0`, which only makes a difference in the cases @@ -348,6 +304,10 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, // Amount is in gwei, turn into wei amount := new(big.Int).Mul(new(big.Int).SetUint64(w.Amount), big.NewInt(params.GWei)) statedb.AddBalance(w.Address, uint256.MustFromBig(amount), tracing.BalanceIncreaseWithdrawal) + + if isEIP4762 { + statedb.AccessEvents().AddAccount(w.Address, true, stdmath.MaxUint64) + } } // Gather the execution-layer triggered requests. @@ -408,8 +368,7 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, execRs.Requests = requests } - // Re-create statedb instance with new root upon the updated database - // for accessing latest states. + // Re-create statedb instance with new root for MPT mode statedb, err = state.New(root, statedb.Database()) if err != nil { return nil, nil, nil, NewError(ErrorEVM, fmt.Errorf("could not reopen state: %v", err)) @@ -418,12 +377,20 @@ func (pre *Prestate) Apply(vmConfig vm.Config, chainConfig *params.ChainConfig, return statedb, execRs, body, nil } -func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB { - tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true}) +func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, isBintrie bool) *state.StateDB { + tdb := triedb.NewDatabase(db, &triedb.Config{Preimages: true, IsVerkle: isBintrie}) sdb := state.NewDatabase(tdb, nil) - statedb, _ := state.New(types.EmptyRootHash, sdb) + + root := types.EmptyRootHash + if isBintrie { + root = types.EmptyBinaryHash + } + statedb, err := state.New(root, sdb) + if err != nil { + panic(fmt.Errorf("failed to create initial statedb: %v", err)) + } for addr, a := range accounts { - statedb.SetCode(addr, a.Code) + statedb.SetCode(addr, a.Code, tracing.CodeChangeUnspecified) statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeGenesis) statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceIncreaseGenesisBalance) for k, v := range a.Storage { @@ -431,12 +398,23 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc) *state.StateDB } } // Commit and re-open to start with a clean state. - root, _ := statedb.Commit(0, false, false) - statedb, _ = state.New(root, sdb) + root, err = statedb.Commit(0, false, false) + if err != nil { + panic(fmt.Errorf("failed to commit initial state: %v", err)) + } + // If bintrie mode started, check if conversion happened + if isBintrie { + return statedb + } + // For MPT mode, reopen the state with the committed root + statedb, err = state.New(root, sdb) + if err != nil { + panic(fmt.Errorf("failed to reopen state after commit: %v", err)) + } return statedb } -func rlpHash(x interface{}) (h common.Hash) { +func rlpHash(x any) (h common.Hash) { hw := sha3.NewLegacyKeccak256() rlp.Encode(hw, x) hw.Sum(h[:0]) diff --git a/cmd/evm/internal/t8ntool/flags.go b/cmd/evm/internal/t8ntool/flags.go index f2606c86d1..a6ec33eacf 100644 --- a/cmd/evm/internal/t8ntool/flags.go +++ b/cmd/evm/internal/t8ntool/flags.go @@ -88,6 +88,14 @@ var ( "\t - into the file ", Value: "block.json", } + OutputBTFlag = &cli.StringFlag{ + Name: "output.vkt", + Usage: "Determines where to put the `BT` of the post-state.\n" + + "\t`stdout` - into the stdout output\n" + + "\t`stderr` - into the stderr output\n" + + "\t - into the file ", + Value: "vkt.json", + } InputAllocFlag = &cli.StringFlag{ Name: "input.alloc", Usage: "`stdin` or file name of where to find the prestate alloc to use.", @@ -123,6 +131,11 @@ var ( Usage: "`stdin` or file name of where to find the transactions list in RLP form.", Value: "txs.rlp", } + // TODO(@CPerezz): rename `Name` of the file in a follow-up PR (relays on EEST -> https://github.com/ethereum/execution-spec-tests/tree/verkle/main) + InputBTFlag = &cli.StringFlag{ + Name: "input.vkt", + Usage: "`stdin` or file name of where to find the prestate BT.", + } SealCliqueFlag = &cli.StringFlag{ Name: "seal.clique", Usage: "Seal block with Clique. `stdin` or file name of where to find the Clique sealing data.", diff --git a/cmd/evm/internal/t8ntool/transition.go b/cmd/evm/internal/t8ntool/transition.go index e946ccddd5..af60333cbd 100644 --- a/cmd/evm/internal/t8ntool/transition.go +++ b/cmd/evm/internal/t8ntool/transition.go @@ -28,15 +28,22 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/tracers" "github.com/ethereum/go-ethereum/eth/tracers/logger" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/tests" + "github.com/ethereum/go-ethereum/trie/bintrie" + "github.com/ethereum/go-ethereum/triedb" + "github.com/ethereum/go-ethereum/triedb/database" + "github.com/holiman/uint256" "github.com/urfave/cli/v2" ) @@ -75,10 +82,11 @@ var ( ) type input struct { - Alloc types.GenesisAlloc `json:"alloc,omitempty"` - Env *stEnv `json:"env,omitempty"` - Txs []*txWithKey `json:"txs,omitempty"` - TxRlp string `json:"txsRlp,omitempty"` + Alloc types.GenesisAlloc `json:"alloc,omitempty"` + Env *stEnv `json:"env,omitempty"` + BT map[common.Hash]hexutil.Bytes `json:"vkt,omitempty"` + Txs []*txWithKey `json:"txs,omitempty"` + TxRlp string `json:"txsRlp,omitempty"` } func Transition(ctx *cli.Context) error { @@ -90,16 +98,16 @@ func Transition(ctx *cli.Context) error { // stdin input or in files. // Check if anything needs to be read from stdin var ( - prestate Prestate - txIt txIterator // txs to apply - allocStr = ctx.String(InputAllocFlag.Name) - + prestate Prestate + txIt txIterator // txs to apply + allocStr = ctx.String(InputAllocFlag.Name) + btStr = ctx.String(InputBTFlag.Name) envStr = ctx.String(InputEnvFlag.Name) txStr = ctx.String(InputTxsFlag.Name) inputData = &input{} ) // Figure out the prestate alloc - if allocStr == stdinSelector || envStr == stdinSelector || txStr == stdinSelector { + if allocStr == stdinSelector || btStr == stdinSelector || envStr == stdinSelector || txStr == stdinSelector { decoder := json.NewDecoder(os.Stdin) if err := decoder.Decode(inputData); err != nil { return NewError(ErrorJson, fmt.Errorf("failed unmarshalling stdin: %v", err)) @@ -112,6 +120,13 @@ func Transition(ctx *cli.Context) error { } prestate.Pre = inputData.Alloc + if btStr != stdinSelector && btStr != "" { + if err := readFile(btStr, "BT", &inputData.BT); err != nil { + return err + } + } + prestate.TreeLeaves = inputData.BT + // Set the block environment if envStr != stdinSelector { var env stEnv @@ -182,9 +197,21 @@ func Transition(ctx *cli.Context) error { return err } // Dump the execution result - collector := make(Alloc) - s.DumpToCollector(collector, nil) - return dispatchOutput(ctx, baseDir, result, collector, body) + var ( + collector = make(Alloc) + btleaves map[common.Hash]hexutil.Bytes + ) + isBinary := chainConfig.IsVerkle(big.NewInt(int64(prestate.Env.Number)), prestate.Env.Timestamp) + if !isBinary { + s.DumpToCollector(collector, nil) + } else { + btleaves = make(map[common.Hash]hexutil.Bytes) + if err := s.DumpBinTrieLeaves(btleaves); err != nil { + return err + } + } + + return dispatchOutput(ctx, baseDir, result, collector, body, btleaves) } func applyLondonChecks(env *stEnv, chainConfig *params.ChainConfig) error { @@ -306,7 +333,7 @@ func saveFile(baseDir, filename string, data interface{}) error { // dispatchOutput writes the output data to either stderr or stdout, or to the specified // files -func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, alloc Alloc, body hexutil.Bytes) error { +func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, alloc Alloc, body hexutil.Bytes, bt map[common.Hash]hexutil.Bytes) error { stdOutObject := make(map[string]interface{}) stdErrObject := make(map[string]interface{}) dispatch := func(baseDir, fName, name string, obj interface{}) error { @@ -333,6 +360,13 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a if err := dispatch(baseDir, ctx.String(OutputBodyFlag.Name), "body", body); err != nil { return err } + // Only write bt output if we actually have binary trie leaves + if bt != nil { + if err := dispatch(baseDir, ctx.String(OutputBTFlag.Name), "vkt", bt); err != nil { + return err + } + } + if len(stdOutObject) > 0 { b, err := json.MarshalIndent(stdOutObject, "", " ") if err != nil { @@ -351,3 +385,168 @@ func dispatchOutput(ctx *cli.Context, baseDir string, result *ExecutionResult, a } return nil } + +// BinKey computes the tree key given an address and an optional slot number. +func BinKey(ctx *cli.Context) error { + if ctx.Args().Len() == 0 || ctx.Args().Len() > 2 { + return errors.New("invalid number of arguments: expecting an address and an optional slot number") + } + + addr, err := hexutil.Decode(ctx.Args().Get(0)) + if err != nil { + return fmt.Errorf("error decoding address: %w", err) + } + + if ctx.Args().Len() == 2 { + slot, err := hexutil.Decode(ctx.Args().Get(1)) + if err != nil { + return fmt.Errorf("error decoding slot: %w", err) + } + fmt.Printf("%#x\n", bintrie.GetBinaryTreeKeyStorageSlot(common.BytesToAddress(addr), slot)) + } else { + fmt.Printf("%#x\n", bintrie.GetBinaryTreeKeyBasicData(common.BytesToAddress(addr))) + } + return nil +} + +// BinKeys computes a set of tree keys given a genesis alloc. +func BinKeys(ctx *cli.Context) error { + var allocStr = ctx.String(InputAllocFlag.Name) + var alloc core.GenesisAlloc + // Figure out the prestate alloc + if allocStr == stdinSelector { + decoder := json.NewDecoder(os.Stdin) + if err := decoder.Decode(&alloc); err != nil { + return NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err)) + } + } + if allocStr != stdinSelector { + if err := readFile(allocStr, "alloc", &alloc); err != nil { + return err + } + } + db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults) + defer db.Close() + + bt, err := genBinTrieFromAlloc(alloc, db) + if err != nil { + return fmt.Errorf("error generating bt: %w", err) + } + + collector := make(map[common.Hash]hexutil.Bytes) + it, err := bt.NodeIterator(nil) + if err != nil { + panic(err) + } + for it.Next(true) { + if it.Leaf() { + collector[common.BytesToHash(it.LeafKey())] = it.LeafBlob() + } + } + + output, err := json.MarshalIndent(collector, "", "") + if err != nil { + return fmt.Errorf("error outputting tree: %w", err) + } + + fmt.Println(string(output)) + + return nil +} + +// BinTrieRoot computes the root of a Binary Trie from a genesis alloc. +func BinTrieRoot(ctx *cli.Context) error { + var allocStr = ctx.String(InputAllocFlag.Name) + var alloc core.GenesisAlloc + if allocStr == stdinSelector { + decoder := json.NewDecoder(os.Stdin) + if err := decoder.Decode(&alloc); err != nil { + return NewError(ErrorJson, fmt.Errorf("failed unmarshaling stdin: %v", err)) + } + } + if allocStr != stdinSelector { + if err := readFile(allocStr, "alloc", &alloc); err != nil { + return err + } + } + db := triedb.NewDatabase(rawdb.NewMemoryDatabase(), triedb.VerkleDefaults) + defer db.Close() + + bt, err := genBinTrieFromAlloc(alloc, db) + if err != nil { + return fmt.Errorf("error generating bt: %w", err) + } + fmt.Println(bt.Hash().Hex()) + + return nil +} + +// TODO(@CPerezz): Should this go to `bintrie` module? +func genBinTrieFromAlloc(alloc core.GenesisAlloc, db database.NodeDatabase) (*bintrie.BinaryTrie, error) { + bt, err := bintrie.NewBinaryTrie(types.EmptyBinaryHash, db) + if err != nil { + return nil, err + } + for addr, acc := range alloc { + for slot, value := range acc.Storage { + err := bt.UpdateStorage(addr, slot.Bytes(), value.Big().Bytes()) + if err != nil { + return nil, fmt.Errorf("error inserting storage: %w", err) + } + } + account := &types.StateAccount{ + Balance: uint256.MustFromBig(acc.Balance), + Nonce: acc.Nonce, + CodeHash: crypto.Keccak256Hash(acc.Code).Bytes(), + Root: common.Hash{}, + } + err := bt.UpdateAccount(addr, account, len(acc.Code)) + if err != nil { + return nil, fmt.Errorf("error inserting account: %w", err) + } + err = bt.UpdateContractCode(addr, common.BytesToHash(account.CodeHash), acc.Code) + if err != nil { + return nil, fmt.Errorf("error inserting code: %w", err) + } + } + return bt, nil +} + +// BinaryCodeChunkKey computes the tree key of a code-chunk for a given address. +func BinaryCodeChunkKey(ctx *cli.Context) error { + if ctx.Args().Len() == 0 || ctx.Args().Len() > 2 { + return errors.New("invalid number of arguments: expecting an address and an code-chunk number") + } + + addr, err := hexutil.Decode(ctx.Args().Get(0)) + if err != nil { + return fmt.Errorf("error decoding address: %w", err) + } + chunkNumberBytes, err := hexutil.Decode(ctx.Args().Get(1)) + if err != nil { + return fmt.Errorf("error decoding chunk number: %w", err) + } + var chunkNumber uint256.Int + chunkNumber.SetBytes(chunkNumberBytes) + + fmt.Printf("%#x\n", bintrie.GetBinaryTreeKeyCodeChunk(common.BytesToAddress(addr), &chunkNumber)) + + return nil +} + +// BinaryCodeChunkCode returns the code chunkification for a given code. +func BinaryCodeChunkCode(ctx *cli.Context) error { + if ctx.Args().Len() == 0 || ctx.Args().Len() > 1 { + return errors.New("invalid number of arguments: expecting a bytecode") + } + + bytecode, err := hexutil.Decode(ctx.Args().Get(0)) + if err != nil { + return fmt.Errorf("error decoding address: %w", err) + } + + chunkedCode := bintrie.ChunkifyCode(bytecode) + fmt.Printf("%#x\n", chunkedCode) + + return nil +} diff --git a/cmd/evm/main.go b/cmd/evm/main.go index bf5be9a359..57741b5f9c 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -55,6 +55,11 @@ var ( Usage: "benchmark the execution", Category: flags.VMCategory, } + FuzzFlag = &cli.BoolFlag{ + Name: "fuzz", + Usage: "adapts output format for fuzzing", + Category: flags.VMCategory, + } WitnessCrossCheckFlag = &cli.BoolFlag{ Name: "cross-check", Aliases: []string{"xc"}, @@ -146,16 +151,63 @@ var ( t8ntool.TraceEnableCallFramesFlag, t8ntool.OutputBasedir, t8ntool.OutputAllocFlag, + t8ntool.OutputBTFlag, t8ntool.OutputResultFlag, t8ntool.OutputBodyFlag, t8ntool.InputAllocFlag, t8ntool.InputEnvFlag, + t8ntool.InputBTFlag, t8ntool.InputTxsFlag, t8ntool.ForknameFlag, t8ntool.ChainIDFlag, t8ntool.RewardFlag, }, } + + verkleCommand = &cli.Command{ + Name: "verkle", + Aliases: []string{"vkt"}, + Usage: "Binary Trie helpers", + Subcommands: []*cli.Command{ + { + Name: "tree-keys", + Aliases: []string{"v"}, + Usage: "compute a set of binary trie keys, given their source addresses and optional slot numbers", + Action: t8ntool.BinKeys, + Flags: []cli.Flag{ + t8ntool.InputAllocFlag, + }, + }, + { + Name: "single-key", + Aliases: []string{"vk"}, + Usage: "compute the binary trie key given an address and optional slot number", + Action: t8ntool.BinKey, + }, + { + Name: "code-chunk-key", + Aliases: []string{"vck"}, + Usage: "compute the binary trie key given an address and chunk number", + Action: t8ntool.BinaryCodeChunkKey, + }, + { + Name: "chunkify-code", + Aliases: []string{"vcc"}, + Usage: "chunkify a given bytecode for a binary trie", + Action: t8ntool.BinaryCodeChunkCode, + }, + { + Name: "state-root", + Aliases: []string{"vsr"}, + Usage: "compute the state-root of a binary trie for the given alloc", + Action: t8ntool.BinTrieRoot, + Flags: []cli.Flag{ + t8ntool.InputAllocFlag, + }, + }, + }, + } + transactionCommand = &cli.Command{ Name: "transaction", Aliases: []string{"t9n"}, @@ -210,6 +262,7 @@ func init() { stateTransitionCommand, transactionCommand, blockBuilderCommand, + verkleCommand, } app.Before = func(ctx *cli.Context) error { flags.MigrateGlobalFlags(ctx) diff --git a/cmd/evm/runner.go b/cmd/evm/runner.go index b2cf28353b..ebb3e04461 100644 --- a/cmd/evm/runner.go +++ b/cmd/evm/runner.go @@ -322,7 +322,7 @@ func runCmd(ctx *cli.Context) error { } } else { if len(code) > 0 { - prestate.SetCode(receiver, code) + prestate.SetCode(receiver, code, tracing.CodeChangeUnspecified) } execFunc = func() ([]byte, uint64, error) { // don't mutate the state! diff --git a/cmd/evm/t8n_test.go b/cmd/evm/t8n_test.go index 46146be787..3c6fd90b47 100644 --- a/cmd/evm/t8n_test.go +++ b/cmd/evm/t8n_test.go @@ -296,6 +296,14 @@ func TestT8n(t *testing.T) { output: t8nOutput{alloc: true, result: true}, expOut: "exp.json", }, + { // Osaka test, EIP-7918 blob gas with parent base fee + base: "./testdata/34", + input: t8nInput{ + "alloc.json", "txs.json", "env.json", "Osaka", "", + }, + output: t8nOutput{alloc: true, result: true}, + expOut: "exp.json", + }, } { args := []string{"t8n"} args = append(args, tc.output.get()...) diff --git a/cmd/evm/testdata/1/exp.json b/cmd/evm/testdata/1/exp.json index 50662f35ea..6537c9517d 100644 --- a/cmd/evm/testdata/1/exp.json +++ b/cmd/evm/testdata/1/exp.json @@ -29,7 +29,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x5208", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x0" } ], diff --git a/cmd/evm/testdata/13/exp2.json b/cmd/evm/testdata/13/exp2.json index 6415a4f1f4..f716289cf7 100644 --- a/cmd/evm/testdata/13/exp2.json +++ b/cmd/evm/testdata/13/exp2.json @@ -17,7 +17,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x84d0", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x0" }, { @@ -31,7 +32,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x84d0", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x1" } ], diff --git a/cmd/evm/testdata/23/exp.json b/cmd/evm/testdata/23/exp.json index 7f36165e35..2d9cd492db 100644 --- a/cmd/evm/testdata/23/exp.json +++ b/cmd/evm/testdata/23/exp.json @@ -16,7 +16,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x520b", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x5", "transactionIndex": "0x0" } ], diff --git a/cmd/evm/testdata/24/exp.json b/cmd/evm/testdata/24/exp.json index 8f380c662b..0dd552e112 100644 --- a/cmd/evm/testdata/24/exp.json +++ b/cmd/evm/testdata/24/exp.json @@ -32,7 +32,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0xa861", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x0" }, { @@ -45,7 +46,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x5aa5", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x1" } ], diff --git a/cmd/evm/testdata/25/exp.json b/cmd/evm/testdata/25/exp.json index a674633762..3dac46aa60 100644 --- a/cmd/evm/testdata/25/exp.json +++ b/cmd/evm/testdata/25/exp.json @@ -28,7 +28,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x5208", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x0" } ], diff --git a/cmd/evm/testdata/28/exp.json b/cmd/evm/testdata/28/exp.json index b86c2d8def..15b29bc0ac 100644 --- a/cmd/evm/testdata/28/exp.json +++ b/cmd/evm/testdata/28/exp.json @@ -33,7 +33,10 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0xa865", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blobGasUsed": "0x20000", + "blobGasPrice": "0x1", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x0" } ], diff --git a/cmd/evm/testdata/29/exp.json b/cmd/evm/testdata/29/exp.json index 7fbdc18283..69c8661aa8 100644 --- a/cmd/evm/testdata/29/exp.json +++ b/cmd/evm/testdata/29/exp.json @@ -31,7 +31,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x5208", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x0" } ], diff --git a/cmd/evm/testdata/3/exp.json b/cmd/evm/testdata/3/exp.json index 831c078591..807cdccfb4 100644 --- a/cmd/evm/testdata/3/exp.json +++ b/cmd/evm/testdata/3/exp.json @@ -29,7 +29,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x521f", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x5", "transactionIndex": "0x0" } ], diff --git a/cmd/evm/testdata/30/exp.json b/cmd/evm/testdata/30/exp.json index a206c3bbdf..9861f5a071 100644 --- a/cmd/evm/testdata/30/exp.json +++ b/cmd/evm/testdata/30/exp.json @@ -30,7 +30,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x5208", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x0" }, { @@ -44,7 +45,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x5208", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x1" } ], diff --git a/cmd/evm/testdata/33/exp.json b/cmd/evm/testdata/33/exp.json index ae82ef3efa..b40ca9fee2 100644 --- a/cmd/evm/testdata/33/exp.json +++ b/cmd/evm/testdata/33/exp.json @@ -48,7 +48,8 @@ "contractAddress": "0x0000000000000000000000000000000000000000", "gasUsed": "0x15fa9", "effectiveGasPrice": null, - "blockHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "blockHash": "0x1337000000000000000000000000000000000000000000000000000000000000", + "blockNumber": "0x1", "transactionIndex": "0x0" } ], diff --git a/cmd/evm/testdata/34/README.md b/cmd/evm/testdata/34/README.md new file mode 100644 index 0000000000..a18f85ca14 --- /dev/null +++ b/cmd/evm/testdata/34/README.md @@ -0,0 +1,6 @@ +This test verifies that Osaka fork blob gas calculation works correctly when +parentBaseFee is provided. It tests the EIP-7918 reserve price calculation +which requires parent.BaseFee to be properly set. + +Regression test for: nil pointer dereference when parent.BaseFee was not +included in the parent header during Osaka fork blob gas calculations. \ No newline at end of file diff --git a/cmd/evm/testdata/34/alloc.json b/cmd/evm/testdata/34/alloc.json new file mode 100644 index 0000000000..199de13285 --- /dev/null +++ b/cmd/evm/testdata/34/alloc.json @@ -0,0 +1,6 @@ +{ + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x1000000000000000000", + "nonce": "0x0" + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/34/env.json b/cmd/evm/testdata/34/env.json new file mode 100644 index 0000000000..ae2bde5ef3 --- /dev/null +++ b/cmd/evm/testdata/34/env.json @@ -0,0 +1,18 @@ +{ + "currentCoinbase": "0x0000000000000000000000000000000000000000", + "currentDifficulty": "0x0", + "currentRandom": "0x0000000000000000000000000000000000000000000000000000000000000000", + "currentGasLimit": "0x5f5e100", + "currentNumber": "0x1", + "currentTimestamp": "0x1000", + "parentTimestamp": "0x0", + "currentBaseFee": "0x10", + "parentBaseFee": "0x0a", + "parentGasUsed": "0x0", + "parentGasLimit": "0x5f5e100", + "currentExcessBlobGas": "0x0", + "parentExcessBlobGas": "0x0", + "parentBlobGasUsed": "0x20000", + "parentBeaconBlockRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "withdrawals": [] +} \ No newline at end of file diff --git a/cmd/evm/testdata/34/exp.json b/cmd/evm/testdata/34/exp.json new file mode 100644 index 0000000000..56d24a532e --- /dev/null +++ b/cmd/evm/testdata/34/exp.json @@ -0,0 +1,23 @@ +{ + "alloc": { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x1000000000000000000" + } + }, + "result": { + "stateRoot": "0x01c28492482a1a1f66224726ef1059a7036fce69d1d2c991b65cd013725d5742", + "txRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "logsHash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "currentDifficulty": null, + "receipts": [], + "gasUsed": "0x0", + "currentBaseFee": "0x10", + "withdrawalsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "currentExcessBlobGas": "0x0", + "blobGasUsed": "0x0", + "requestsHash": "0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", + "requests": [] + } +} \ No newline at end of file diff --git a/cmd/evm/testdata/34/txs.json b/cmd/evm/testdata/34/txs.json new file mode 100644 index 0000000000..0637a088a0 --- /dev/null +++ b/cmd/evm/testdata/34/txs.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/cmd/geth/chaincmd.go b/cmd/geth/chaincmd.go index 112d1a539b..9d04dd0f1b 100644 --- a/cmd/geth/chaincmd.go +++ b/cmd/geth/chaincmd.go @@ -59,6 +59,8 @@ var ( Flags: slices.Concat([]cli.Flag{ utils.CachePreimagesFlag, utils.OverrideOsaka, + utils.OverrideBPO1, + utils.OverrideBPO2, utils.OverrideVerkle, }, utils.DatabaseFlags), Description: ` @@ -94,6 +96,7 @@ if one is set. Otherwise it prints the genesis from the datadir.`, utils.CacheNoPrefetchFlag, utils.CachePreimagesFlag, utils.NoCompactionFlag, + utils.LogSlowBlockFlag, utils.MetricsEnabledFlag, utils.MetricsEnabledExpensiveFlag, utils.MetricsHTTPFlag, @@ -108,6 +111,7 @@ if one is set. Otherwise it prints the genesis from the datadir.`, utils.MetricsInfluxDBTokenFlag, utils.MetricsInfluxDBBucketFlag, utils.MetricsInfluxDBOrganizationFlag, + utils.StateSizeTrackingFlag, utils.TxLookupLimitFlag, utils.VMTraceFlag, utils.VMTraceJsonConfigFlag, @@ -116,6 +120,8 @@ if one is set. Otherwise it prints the genesis from the datadir.`, utils.LogNoHistoryFlag, utils.LogExportCheckpointsFlag, utils.StateHistoryFlag, + utils.TrienodeHistoryFlag, + utils.TrienodeHistoryFullValueCheckpointFlag, }, utils.DatabaseFlags, debug.Flags), Before: func(ctx *cli.Context) error { flags.MigrateGlobalFlags(ctx) @@ -273,6 +279,14 @@ func initGenesis(ctx *cli.Context) error { v := ctx.Uint64(utils.OverrideOsaka.Name) overrides.OverrideOsaka = &v } + if ctx.IsSet(utils.OverrideBPO1.Name) { + v := ctx.Uint64(utils.OverrideBPO1.Name) + overrides.OverrideBPO1 = &v + } + if ctx.IsSet(utils.OverrideBPO2.Name) { + v := ctx.Uint64(utils.OverrideBPO2.Name) + overrides.OverrideBPO2 = &v + } if ctx.IsSet(utils.OverrideVerkle.Name) { v := ctx.Uint64(utils.OverrideVerkle.Name) overrides.OverrideVerkle = &v @@ -281,10 +295,10 @@ func initGenesis(ctx *cli.Context) error { chaindb := utils.MakeChainDatabase(ctx, stack, false) defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) + triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, ctx.Bool(utils.CachePreimagesFlag.Name), false, genesis.IsVerkle()) defer triedb.Close() - _, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides) + _, hash, compatErr, err := core.SetupGenesisBlockWithOverride(chaindb, triedb, genesis, &overrides, nil) if err != nil { utils.Fatalf("Failed to write genesis block: %v", err) } @@ -635,7 +649,7 @@ func dump(ctx *cli.Context) error { if err != nil { return err } - triedb := utils.MakeTrieDatabase(ctx, db, true, true, false) // always enable preimage lookup + triedb := utils.MakeTrieDatabase(ctx, stack, db, true, true, false) // always enable preimage lookup defer triedb.Close() state, err := state.New(root, state.NewDatabase(triedb, nil)) @@ -704,7 +718,7 @@ func pruneHistory(ctx *cli.Context) error { return nil } -// downladEra is the era1 file downloader tool. +// downloadEra is the era1 file downloader tool. func downloadEra(ctx *cli.Context) error { flags.CheckExclusive(ctx, eraBlockFlag, eraEpochFlag, eraAllFlag) diff --git a/cmd/geth/config.go b/cmd/geth/config.go index 96bd715e88..87627467d2 100644 --- a/cmd/geth/config.go +++ b/cmd/geth/config.go @@ -35,7 +35,6 @@ import ( "github.com/ethereum/go-ethereum/beacon/blsync" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/catalyst" "github.com/ethereum/go-ethereum/eth/ethconfig" @@ -209,7 +208,7 @@ func constructDevModeBanner(ctx *cli.Context, cfg gethConfig) string { 0x%x (10^49 ETH) `, cfg.Eth.Miner.PendingFeeRecipient) if cfg.Eth.Miner.PendingFeeRecipient == utils.DeveloperAddr { - devModeBanner += fmt.Sprintf(` + devModeBanner += fmt.Sprintf(` Private Key ------------------ 0x%x @@ -227,6 +226,14 @@ func makeFullNode(ctx *cli.Context) *node.Node { v := ctx.Uint64(utils.OverrideOsaka.Name) cfg.Eth.OverrideOsaka = &v } + if ctx.IsSet(utils.OverrideBPO1.Name) { + v := ctx.Uint64(utils.OverrideBPO1.Name) + cfg.Eth.OverrideBPO1 = &v + } + if ctx.IsSet(utils.OverrideBPO2.Name) { + v := ctx.Uint64(utils.OverrideBPO2.Name) + cfg.Eth.OverrideBPO2 = &v + } if ctx.IsSet(utils.OverrideVerkle.Name) { v := ctx.Uint64(utils.OverrideVerkle.Name) cfg.Eth.OverrideVerkle = &v @@ -265,11 +272,11 @@ func makeFullNode(ctx *cli.Context) *node.Node { // Configure synchronization override service var synctarget common.Hash if ctx.IsSet(utils.SyncTargetFlag.Name) { - hex := hexutil.MustDecode(ctx.String(utils.SyncTargetFlag.Name)) - if len(hex) != common.HashLength { - utils.Fatalf("invalid sync target length: have %d, want %d", len(hex), common.HashLength) + target := ctx.String(utils.SyncTargetFlag.Name) + if !common.IsHexHash(target) { + utils.Fatalf("sync target hash is not a valid hex hash: %s", target) } - synctarget = common.BytesToHash(hex) + synctarget = common.HexToHash(target) } utils.RegisterSyncOverrideService(stack, eth, synctarget, ctx.Bool(utils.ExitWhenSyncedFlag.Name)) diff --git a/cmd/geth/consolecmd_test.go b/cmd/geth/consolecmd_test.go index 4e1f6340a0..871e8c175f 100644 --- a/cmd/geth/consolecmd_test.go +++ b/cmd/geth/consolecmd_test.go @@ -39,8 +39,9 @@ const ( // child g gets a temporary data directory. func runMinimalGeth(t *testing.T, args ...string) *testgeth { // --holesky to make the 'writing genesis to disk' faster (no accounts) + // --networkid=1337 to avoid cache bump // --syncmode=full to avoid allocating fast sync bloom - allArgs := []string{"--holesky", "--authrpc.port", "0", "--syncmode=full", "--port", "0", + allArgs := []string{"--holesky", "--networkid", "1337", "--authrpc.port", "0", "--syncmode=full", "--port", "0", "--nat", "none", "--nodiscover", "--maxpeers", "0", "--cache", "64", "--datadir.minfreedisk", "0"} return runGeth(t, append(allArgs, args...)...) diff --git a/cmd/geth/dbcmd.go b/cmd/geth/dbcmd.go index 44a52521f0..fb688793e3 100644 --- a/cmd/geth/dbcmd.go +++ b/cmd/geth/dbcmd.go @@ -41,7 +41,6 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" - "github.com/olekukonko/tablewriter" "github.com/urfave/cli/v2" ) @@ -524,7 +523,7 @@ func dbDumpTrie(ctx *cli.Context) error { db := utils.MakeChainDatabase(ctx, stack, true) defer db.Close() - triedb := utils.MakeTrieDatabase(ctx, db, false, true, false) + triedb := utils.MakeTrieDatabase(ctx, stack, db, false, true, false) defer triedb.Close() var ( @@ -760,7 +759,7 @@ func showMetaData(ctx *cli.Context) error { data = append(data, []string{"headHeader.Root", fmt.Sprintf("%v", h.Root)}) data = append(data, []string{"headHeader.Number", fmt.Sprintf("%d (%#x)", h.Number, h.Number)}) } - table := tablewriter.NewWriter(os.Stdout) + table := rawdb.NewTableWriter(os.Stdout) table.SetHeader([]string{"Field", "Value"}) table.AppendBulk(data) table.Render() @@ -859,7 +858,7 @@ func inspectHistory(ctx *cli.Context) error { db := utils.MakeChainDatabase(ctx, stack, true) defer db.Close() - triedb := utils.MakeTrieDatabase(ctx, db, false, false, false) + triedb := utils.MakeTrieDatabase(ctx, stack, db, false, false, false) defer triedb.Close() var ( diff --git a/cmd/geth/logging_test.go b/cmd/geth/logging_test.go index 37fffecc30..d420c2d078 100644 --- a/cmd/geth/logging_test.go +++ b/cmd/geth/logging_test.go @@ -91,7 +91,7 @@ func testConsoleLogging(t *testing.T, format string, tStart, tEnd int) { have = censor(have, tStart, tEnd) want = censor(want, tStart, tEnd) if have != want { - t.Logf(nicediff([]byte(have), []byte(want))) + t.Log(nicediff([]byte(have), []byte(want))) t.Fatalf("format %v, line %d\nhave %v\nwant %v", format, i, have, want) } } @@ -142,7 +142,7 @@ func TestJsonLogging(t *testing.T) { } if !bytes.Equal(have, want) { // show an intelligent diff - t.Logf(nicediff(have, want)) + t.Log(nicediff(have, want)) t.Errorf("file content wrong") } } @@ -211,7 +211,7 @@ func TestFileOut(t *testing.T) { } if !bytes.Equal(have, want) { // show an intelligent diff - t.Logf(nicediff(have, want)) + t.Log(nicediff(have, want)) t.Errorf("file content wrong") } } @@ -231,7 +231,7 @@ func TestRotatingFileOut(t *testing.T) { } if !bytes.Equal(have, want) { // show an intelligent diff - t.Logf(nicediff(have, want)) + t.Log(nicediff(have, want)) t.Errorf("file content wrong") } } diff --git a/cmd/geth/main.go b/cmd/geth/main.go index 2da5c43216..9aabaaba98 100644 --- a/cmd/geth/main.go +++ b/cmd/geth/main.go @@ -63,7 +63,10 @@ var ( utils.USBFlag, utils.SmartCardDaemonPathFlag, utils.OverrideOsaka, + utils.OverrideBPO1, + utils.OverrideBPO2, utils.OverrideVerkle, + utils.OverrideGenesisFlag, utils.EnablePersonal, // deprecated utils.TxPoolLocalsFlag, utils.TxPoolNoLocalsFlag, @@ -91,6 +94,8 @@ var ( utils.LogNoHistoryFlag, utils.LogExportCheckpointsFlag, utils.StateHistoryFlag, + utils.TrienodeHistoryFlag, + utils.TrienodeHistoryFullValueCheckpointFlag, utils.LightKDFFlag, utils.EthRequiredBlocksFlag, utils.LegacyWhitelistFlag, // deprecated @@ -115,6 +120,7 @@ var ( utils.MinerGasPriceFlag, utils.MinerEtherbaseFlag, // deprecated utils.MinerExtraDataFlag, + utils.MinerMaxBlobsFlag, utils.MinerRecommitIntervalFlag, utils.MinerPendingFeeRecipientFlag, utils.MinerNewPayloadTimeoutFlag, // deprecated @@ -133,6 +139,8 @@ var ( utils.VMEnableDebugFlag, utils.VMTraceFlag, utils.VMTraceJsonConfigFlag, + utils.VMWitnessStatsFlag, + utils.VMStatelessSelfValidationFlag, utils.NetworkIdFlag, utils.EthStatsURLFlag, utils.GpoBlocksFlag, @@ -151,6 +159,7 @@ var ( utils.BeaconGenesisTimeFlag, utils.BeaconCheckpointFlag, utils.BeaconCheckpointFileFlag, + utils.LogSlowBlockFlag, }, utils.NetworkFlags, utils.DatabaseFlags) rpcFlags = []cli.Flag{ @@ -180,9 +189,13 @@ var ( utils.RPCGlobalGasCapFlag, utils.RPCGlobalEVMTimeoutFlag, utils.RPCGlobalTxFeeCapFlag, + utils.RPCGlobalLogQueryLimit, utils.AllowUnprotectedTxs, utils.BatchRequestLimit, utils.BatchResponseMaxSize, + utils.RPCTxSyncDefaultTimeoutFlag, + utils.RPCTxSyncMaxTimeoutFlag, + utils.RPCGlobalRangeLimitFlag, } metricsFlags = []cli.Flag{ @@ -200,6 +213,7 @@ var ( utils.MetricsInfluxDBTokenFlag, utils.MetricsInfluxDBBucketFlag, utils.MetricsInfluxDBOrganizationFlag, + utils.StateSizeTrackingFlag, } ) @@ -230,7 +244,6 @@ func init() { javascriptCommand, // See misccmd.go: versionCommand, - versionCheckCommand, licenseCommand, // See config.go dumpConfigCommand, @@ -240,8 +253,6 @@ func init() { utils.ShowDeprecated, // See snapshot.go snapshotCommand, - // See verkle.go - verkleCommand, } if logTestCommand != nil { app.Commands = append(app.Commands, logTestCommand) diff --git a/cmd/geth/misccmd.go b/cmd/geth/misccmd.go index 2d31f3abe7..f5c0d55ebb 100644 --- a/cmd/geth/misccmd.go +++ b/cmd/geth/misccmd.go @@ -27,16 +27,6 @@ import ( ) var ( - VersionCheckUrlFlag = &cli.StringFlag{ - Name: "check.url", - Usage: "URL to use when checking vulnerabilities", - Value: "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json", - } - VersionCheckVersionFlag = &cli.StringFlag{ - Name: "check.version", - Usage: "Version to check", - Value: version.ClientName(clientIdentifier), - } versionCommand = &cli.Command{ Action: printVersion, Name: "version", @@ -44,20 +34,6 @@ var ( ArgsUsage: " ", Description: ` The output of this command is supposed to be machine-readable. -`, - } - versionCheckCommand = &cli.Command{ - Action: versionCheck, - Flags: []cli.Flag{ - VersionCheckUrlFlag, - VersionCheckVersionFlag, - }, - Name: "version-check", - Usage: "Checks (online) for known Geth security vulnerabilities", - ArgsUsage: "", - Description: ` -The version-check command fetches vulnerability-information from https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities.json, -and displays information about any security vulnerabilities that affect the currently executing version. `, } licenseCommand = &cli.Command{ diff --git a/cmd/geth/snapshot.go b/cmd/geth/snapshot.go index aa9ae7087f..fc0658a59c 100644 --- a/cmd/geth/snapshot.go +++ b/cmd/geth/snapshot.go @@ -217,7 +217,7 @@ func verifyState(ctx *cli.Context) error { log.Error("Failed to load head block") return errors.New("no head block") } - triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, false, true, false) defer triedb.Close() var ( @@ -282,7 +282,7 @@ func traverseState(ctx *cli.Context) error { chaindb := utils.MakeChainDatabase(ctx, stack, true) defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, false, true, false) defer triedb.Close() headBlock := rawdb.ReadHeadBlock(chaindb) @@ -391,7 +391,7 @@ func traverseRawState(ctx *cli.Context) error { chaindb := utils.MakeChainDatabase(ctx, stack, true) defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, false, true, false) defer triedb.Close() headBlock := rawdb.ReadHeadBlock(chaindb) @@ -558,20 +558,14 @@ func dumpState(ctx *cli.Context) error { if err != nil { return err } - triedb := utils.MakeTrieDatabase(ctx, db, false, true, false) + triedb := utils.MakeTrieDatabase(ctx, stack, db, false, true, false) defer triedb.Close() - snapConfig := snapshot.Config{ - CacheSize: 256, - Recovery: false, - NoBuild: true, - AsyncBuild: false, - } - snaptree, err := snapshot.New(snapConfig, db, triedb, root) + stateIt, err := utils.NewStateIterator(triedb, db, root) if err != nil { return err } - accIt, err := snaptree.AccountIterator(root, common.BytesToHash(conf.Start)) + accIt, err := stateIt.AccountIterator(root, common.BytesToHash(conf.Start)) if err != nil { return err } @@ -605,7 +599,7 @@ func dumpState(ctx *cli.Context) error { if !conf.SkipStorage { da.Storage = make(map[common.Hash]string) - stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{}) + stIt, err := stateIt.StorageIterator(root, accIt.Hash(), common.Hash{}) if err != nil { return err } @@ -640,16 +634,16 @@ func snapshotExportPreimages(ctx *cli.Context) error { chaindb := utils.MakeChainDatabase(ctx, stack, true) defer chaindb.Close() - triedb := utils.MakeTrieDatabase(ctx, chaindb, false, true, false) + triedb := utils.MakeTrieDatabase(ctx, stack, chaindb, false, true, false) defer triedb.Close() var root common.Hash if ctx.NArg() > 1 { - rootBytes := common.FromHex(ctx.Args().Get(1)) - if len(rootBytes) != common.HashLength { + hash := ctx.Args().Get(1) + if !common.IsHexHash(hash) { return fmt.Errorf("invalid hash: %s", ctx.Args().Get(1)) } - root = common.BytesToHash(rootBytes) + root = common.HexToHash(hash) } else { headBlock := rawdb.ReadHeadBlock(chaindb) if headBlock == nil { @@ -658,17 +652,11 @@ func snapshotExportPreimages(ctx *cli.Context) error { } root = headBlock.Root() } - snapConfig := snapshot.Config{ - CacheSize: 256, - Recovery: false, - NoBuild: true, - AsyncBuild: false, - } - snaptree, err := snapshot.New(snapConfig, chaindb, triedb, root) + stateIt, err := utils.NewStateIterator(triedb, chaindb, root) if err != nil { return err } - return utils.ExportSnapshotPreimages(chaindb, snaptree, ctx.Args().First(), root) + return utils.ExportSnapshotPreimages(chaindb, stateIt, ctx.Args().First(), root) } // checkAccount iterates the snap data layers, and looks up the given account diff --git a/cmd/geth/testdata/vcheck/data.json b/cmd/geth/testdata/vcheck/data.json deleted file mode 100644 index e52fd84e67..0000000000 --- a/cmd/geth/testdata/vcheck/data.json +++ /dev/null @@ -1,202 +0,0 @@ -[ - { - "name": "CorruptedDAG", - "uid": "GETH-2020-01", - "summary": "Mining nodes will generate erroneous PoW on epochs > `385`.", - "description": "A mining flaw could cause miners to erroneously calculate PoW, due to an index overflow, if DAG size is exceeding the maximum 32 bit unsigned value.\n\nThis occurred on the ETC chain on 2020-11-06. This is likely to trigger for ETH mainnet around block `11550000`/epoch `385`, slated to occur early January 2021.\n\nThis issue is relevant only for miners, non-mining nodes are unaffected, since non-mining nodes use a smaller verification cache instead of a full DAG.", - "links": [ - "https://github.com/ethereum/go-ethereum/pull/21793", - "https://blog.ethereum.org/2020/11/12/geth-security-release", - "https://github.com/ethereum/go-ethereum/commit/567d41d9363706b4b13ce0903804e8acf214af49", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-v592-xf75-856p" - ], - "introduced": "v1.6.0", - "fixed": "v1.9.24", - "published": "2020-11-12", - "severity": "Medium", - "CVE": "CVE-2020-26240", - "check": "Geth\\/v1\\.(6|7|8)\\..*|Geth\\/v1\\.9\\.\\d-.*|Geth\\/v1\\.9\\.1.*|Geth\\/v1\\.9\\.2(0|1|2|3)-.*" - }, - { - "name": "Denial of service due to Go CVE-2020-28362", - "uid": "GETH-2020-02", - "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`", - "description": "The DoS issue can be used to crash all Geth nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of Geth (such as TurboGeth or ETC’s core-geth) which is built with versions of Go which contains the vulnerability.", - "links": [ - "https://blog.ethereum.org/2020/11/12/geth-security-release", - "https://groups.google.com/g/golang-announce/c/NpBGTTmKzpM", - "https://github.com/golang/go/issues/42552", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-m6gx-rhvj-fh52" - ], - "introduced": "v0.0.0", - "fixed": "v1.9.24", - "published": "2020-11-12", - "severity": "Critical", - "CVE": "CVE-2020-28362", - "check": "Geth.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$" - }, - { - "name": "ShallowCopy", - "uid": "GETH-2020-03", - "summary": "A consensus flaw in Geth, related to `datacopy` precompile", - "description": "Geth erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.", - "links": [ - "https://blog.ethereum.org/2020/11/12/geth-security-release", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-69v6-xc2j-r2jf" - ], - "introduced": "v1.9.7", - "fixed": "v1.9.17", - "published": "2020-11-12", - "severity": "Critical", - "CVE": "CVE-2020-26241", - "check": "Geth\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$" - }, - { - "name": "Geth DoS via MULMOD", - "uid": "GETH-2020-04", - "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing", - "description": "Affected versions suffer from a vulnerability which can be exploited through the `MULMOD` operation, by specifying a modulo of `0`: `mulmod(a,b,0)`, causing a `panic` in the underlying library. \nThe crash was in the `uint256` library, where a buffer [underflowed](https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L442).\n\n\tif `d == 0`, `dLen` remains `0`\n\nand https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L451 will try to access index `[-1]`.\n\nThe `uint256` library was first merged in this [commit](https://github.com/ethereum/go-ethereum/commit/cf6674539c589f80031f3371a71c6a80addbe454), on 2020-06-08. \nExploiting this vulnerabilty would cause all vulnerable nodes to drop off the network. \n\nThe issue was brought to our attention through a [bug report](https://github.com/ethereum/go-ethereum/issues/21367), showing a `panic` occurring on sync from genesis on the Ropsten network.\n \nIt was estimated that the least obvious way to fix this would be to merge the fix into `uint256`, make a new release of that library and then update the geth-dependency.\n", - "links": [ - "https://blog.ethereum.org/2020/11/12/geth-security-release", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-jm5c-rv3w-w83m", - "https://github.com/holiman/uint256/releases/tag/v1.1.1", - "https://github.com/holiman/uint256/pull/80", - "https://github.com/ethereum/go-ethereum/pull/21368" - ], - "introduced": "v1.9.16", - "fixed": "v1.9.18", - "published": "2020-11-12", - "severity": "Critical", - "CVE": "CVE-2020-26242", - "check": "Geth\\/v1\\.9.(16|17).*$" - }, - { - "name": "LES Server DoS via GetProofsV2", - "uid": "GETH-2020-05", - "summary": "A DoS vulnerability can make a LES server crash.", - "description": "A DoS vulnerability can make a LES server crash via malicious GetProofsV2 request from a connected LES client.\n\nThe vulnerability was patched in #21896.\n\nThis vulnerability only concern users explicitly running geth as a light server", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-r33q-22hv-j29q", - "https://github.com/ethereum/go-ethereum/pull/21896" - ], - "introduced": "v1.8.0", - "fixed": "v1.9.25", - "published": "2020-12-10", - "severity": "Medium", - "CVE": "CVE-2020-26264", - "check": "(Geth\\/v1\\.8\\.*)|(Geth\\/v1\\.9\\.\\d-.*)|(Geth\\/v1\\.9\\.1\\d-.*)|(Geth\\/v1\\.9\\.(20|21|22|23|24)-.*)$" - }, - { - "name": "SELFDESTRUCT-recreate consensus flaw", - "uid": "GETH-2020-06", - "introduced": "v1.9.4", - "fixed": "v1.9.20", - "summary": "A consensus-vulnerability in Geth could cause a chain split, where vulnerable versions refuse to accept the canonical chain.", - "description": "A flaw was repoted at 2020-08-11 by John Youngseok Yang (Software Platform Lab), where a particular sequence of transactions could cause a consensus failure.\n\n- Tx 1:\n - `sender` invokes `caller`.\n - `caller` invokes `0xaa`. `0xaa` has 3 wei, does a self-destruct-to-self\n - `caller` does a `1 wei` -call to `0xaa`, who thereby has 1 wei (the code in `0xaa` still executed, since the tx is still ongoing, but doesn't redo the selfdestruct, it takes a different path if callvalue is non-zero)\n\n-Tx 2:\n - `sender` does a 5-wei call to 0xaa. No exec (since no code). \n\nIn geth, the result would be that `0xaa` had `6 wei`, whereas OE reported (correctly) `5` wei. Furthermore, in geth, if the second tx was not executed, the `0xaa` would be destructed, resulting in `0 wei`. Thus obviously wrong. \n\nIt was determined that the root cause was this [commit](https://github.com/ethereum/go-ethereum/commit/223b950944f494a5b4e0957fd9f92c48b09037ad) from [this PR](https://github.com/ethereum/go-ethereum/pull/19953). The semantics of `createObject` was subtly changd, into returning a non-nil object (with `deleted=true`) where it previously did not if the account had been destructed. This return value caused the new object to inherit the old `balance`.\n", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-xw37-57qp-9mm4" - ], - "published": "2020-12-10", - "severity": "High", - "CVE": "CVE-2020-26265", - "check": "(Geth\\/v1\\.9\\.(4|5|6|7|8|9)-.*)|(Geth\\/v1\\.9\\.1\\d-.*)$" - }, - { - "name": "Not ready for London upgrade", - "uid": "GETH-2021-01", - "summary": "The client is not ready for the 'London' technical upgrade, and will deviate from the canonical chain when the London upgrade occurs (at block '12965000' around August 4, 2021.", - "description": "At (or around) August 4, Ethereum will undergo a technical upgrade called 'London'. Clients not upgraded will fail to progress on the canonical chain.", - "links": [ - "https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/mainnet-upgrades/london.md", - "https://notes.ethereum.org/@timbeiko/ropsten-postmortem" - ], - "introduced": "v1.10.1", - "fixed": "v1.10.6", - "published": "2021-07-22", - "severity": "High", - "check": "(Geth\\/v1\\.10\\.(1|2|3|4|5)-.*)$" - }, - { - "name": "RETURNDATA corruption via datacopy", - "uid": "GETH-2021-02", - "summary": "A consensus-flaw in the Geth EVM could cause a node to deviate from the canonical chain.", - "description": "A memory-corruption bug within the EVM can cause a consensus error, where vulnerable nodes obtain a different `stateRoot` when processing a maliciously crafted transaction. This, in turn, would lead to the chain being split: mainnet splitting in two forks.\n\nAll Geth versions supporting the London hard fork are vulnerable (the bug is older than London), so all users should update.\n\nThis bug was exploited on Mainnet at block 13107518.\n\nCredits for the discovery go to @guidovranken (working for Sentnl during an audit of the Telos EVM) and reported via bounty@ethereum.org.", - "links": [ - "https://github.com/ethereum/go-ethereum/blob/master/docs/postmortems/2021-08-22-split-postmortem.md", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-9856-9gg9-qcmq", - "https://github.com/ethereum/go-ethereum/releases/tag/v1.10.8" - ], - "introduced": "v1.10.0", - "fixed": "v1.10.8", - "published": "2021-08-24", - "severity": "High", - "CVE": "CVE-2021-39137", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7)-.*)$" - }, - { - "name": "DoS via malicious `snap/1` request", - "uid": "GETH-2021-03", - "summary": "A vulnerable node is susceptible to crash when processing a maliciously crafted message from a peer, via the snap/1 protocol. The crash can be triggered by sending a malicious snap/1 GetTrieNodes package.", - "description": "The `snap/1` protocol handler contains two vulnerabilities related to the `GetTrieNodes` packet, which can be exploited to crash the node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v)", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities", - "https://github.com/ethereum/go-ethereum/pull/23657" - ], - "introduced": "v1.10.0", - "fixed": "v1.10.9", - "published": "2021-10-24", - "severity": "Medium", - "CVE": "CVE-2021-41173", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8)-.*)$" - }, - { - "name": "DoS via malicious p2p message", - "uid": "GETH-2022-01", - "summary": "A vulnerable node can crash via p2p messages sent from an attacker node, if running with non-default log options.", - "description": "A vulnerable node, if configured to use high verbosity logging, can be made to crash when handling specially crafted p2p messages sent from an attacker node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5)", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities", - "https://github.com/ethereum/go-ethereum/pull/24507" - ], - "introduced": "v1.10.0", - "fixed": "v1.10.17", - "published": "2022-05-11", - "severity": "Low", - "CVE": "CVE-2022-29177", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$" - }, - { - "name": "DoS via malicious p2p message", - "uid": "GETH-2023-01", - "summary": "A vulnerable node can be made to consume unbounded amounts of memory when handling specially crafted p2p messages sent from an attacker node.", - "description": "The p2p handler spawned a new goroutine to respond to ping requests. By flooding a node with ping requests, an unbounded number of goroutines can be created, leading to resource exhaustion and potentially crash due to OOM.", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-ppjg-v974-84cm", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities" - ], - "introduced": "v1.10.0", - "fixed": "v1.12.1", - "published": "2023-09-06", - "severity": "High", - "CVE": "CVE-2023-40591", - "check": "(Geth\\/v1\\.(10|11)\\..*)|(Geth\\/v1\\.12\\.0-.*)$" - }, - { - "name": "DoS via malicious p2p message", - "uid": "GETH-2024-01", - "summary": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node.", - "description": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node. Full details will be available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652)", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities" - ], - "introduced": "v1.10.0", - "fixed": "v1.13.15", - "published": "2024-05-06", - "severity": "High", - "CVE": "CVE-2024-32972", - "check": "(Geth\\/v1\\.(10|11|12)\\..*)|(Geth\\/v1\\.13\\.\\d-.*)|(Geth\\/v1\\.13\\.1(0|1|2|3|4)-.*)$" - } -] diff --git a/cmd/geth/testdata/vcheck/minisig-sigs-new/data.json.minisig b/cmd/geth/testdata/vcheck/minisig-sigs-new/data.json.minisig deleted file mode 100644 index 987ffe92bb..0000000000 --- a/cmd/geth/testdata/vcheck/minisig-sigs-new/data.json.minisig +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RUQkliYstQBOKHklFEYCUjepz81dyUuDmIAxjAvXa+icjGuKcjtVfV06G7qfOMSpplS5EcntU12n+AnGNyuOM8zIctaIWcfG2w0= -trusted comment: timestamp:1752094689 file:data.json hashed -u2e4wo4HBTU6viQTSY/NVBHoWoPFJnnTvLZS0FYl3JdvSOYi6+qpbEsDhAIFqq/n8VmlS/fPqqf7vKCNiAgjAA== diff --git a/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1 b/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1 deleted file mode 100644 index 6b6aa900e3..0000000000 --- a/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.1 +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: signature from minisign secret key -RWQkliYstQBOKNoyq2O98hPmeVJQ6ShQLM58+4n0gkY0y0trFMDAsHuN/l4IyHfh8dDQ1ry0+IuZVrf/i8M/P3YFzFfAymDYCQ0= -trusted comment: timestamp:1752094703 file:data.json -cNyq3ZGlqo785HtWODb9ejWqF0HhSeXuLGXzC7z1IhnDrBObWBJngYd3qBG1dQcYlHQ+bgB/On5mSyMFn4UoCQ== diff --git a/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2 b/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2 deleted file mode 100644 index 704437de39..0000000000 --- a/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.2 +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: Here's a comment -RWQkliYstQBOKNoyq2O98hPmeVJQ6ShQLM58+4n0gkY0y0trFMDAsHuN/l4IyHfh8dDQ1ry0+IuZVrf/i8M/P3YFzFfAymDYCQ0= -trusted comment: Here's a trusted comment -dL7lO8sqFFCOXJO/u8SgoDk2nlXGWPRDbOTJkChMbmtUp9PB7sG831basXkZ/0CQ/l/vG7AbPyMNEVZyJn5NCg== diff --git a/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3 b/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3 deleted file mode 100644 index 806cd07316..0000000000 --- a/cmd/geth/testdata/vcheck/minisig-sigs/vulnerabilities.json.minisig.3 +++ /dev/null @@ -1,4 +0,0 @@ -untrusted comment: One more (untrusted™) comment -RWQkliYstQBOKNoyq2O98hPmeVJQ6ShQLM58+4n0gkY0y0trFMDAsHuN/l4IyHfh8dDQ1ry0+IuZVrf/i8M/P3YFzFfAymDYCQ0= -trusted comment: Here's a trusted comment -dL7lO8sqFFCOXJO/u8SgoDk2nlXGWPRDbOTJkChMbmtUp9PB7sG831basXkZ/0CQ/l/vG7AbPyMNEVZyJn5NCg== diff --git a/cmd/geth/testdata/vcheck/minisign.pub b/cmd/geth/testdata/vcheck/minisign.pub deleted file mode 100644 index 183dce5f6b..0000000000 --- a/cmd/geth/testdata/vcheck/minisign.pub +++ /dev/null @@ -1,2 +0,0 @@ -untrusted comment: minisign public key 284E00B52C269624 -RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp diff --git a/cmd/geth/testdata/vcheck/minisign.sec b/cmd/geth/testdata/vcheck/minisign.sec deleted file mode 100644 index 5c50715b20..0000000000 --- a/cmd/geth/testdata/vcheck/minisign.sec +++ /dev/null @@ -1,2 +0,0 @@ -untrusted comment: minisign encrypted secret key -RWRTY0Iyz8kmPMKrqk6DCtlO9a33akKiaOQG1aLolqDxs52qvPoAAAACAAAAAAAAAEAAAAAArEiggdvyn6+WzTprirLtgiYQoU+ihz/HyGgjhuF+Pz2ddMduyCO+xjCHeq+vgVVW039fbsI8hW6LRGJZLBKV5/jdxCXAVVQE7qTQ6xpEdO0z8Z731/pV1hlspQXG2PNd16NMtwd9dWw= diff --git a/cmd/geth/testdata/vcheck/signify-sigs/data.json.sig b/cmd/geth/testdata/vcheck/signify-sigs/data.json.sig deleted file mode 100644 index d704af7709..0000000000 --- a/cmd/geth/testdata/vcheck/signify-sigs/data.json.sig +++ /dev/null @@ -1,2 +0,0 @@ -untrusted comment: verify with signifykey.pub -RWSKLNhZb0KdARbMcGN40hbHzKQYZDgDOFhEUT1YpzMnqre/mbKJ8td/HVlG03Am1YCszATiI0DbnljjTy4iNHYwqBfzrFUqUg0= diff --git a/cmd/geth/testdata/vcheck/signifykey.pub b/cmd/geth/testdata/vcheck/signifykey.pub deleted file mode 100644 index 328f973ab4..0000000000 --- a/cmd/geth/testdata/vcheck/signifykey.pub +++ /dev/null @@ -1,2 +0,0 @@ -untrusted comment: signify public key -RWSKLNhZb0KdATtRT7mZC/bybI3t3+Hv/O2i3ye04Dq9fnT9slpZ1a2/ diff --git a/cmd/geth/testdata/vcheck/signifykey.sec b/cmd/geth/testdata/vcheck/signifykey.sec deleted file mode 100644 index 3279a2e58b..0000000000 --- a/cmd/geth/testdata/vcheck/signifykey.sec +++ /dev/null @@ -1,2 +0,0 @@ -untrusted comment: signify secret key -RWRCSwAAACpLQDLawSQCtI7eAVIvaiHzjTsTyJsfV5aKLNhZb0KdAWeICXJGa93/bHAcsY6jUh9I8RdEcDWEoGxmaXZC+IdVBPxDpkix9fBRGEUdKWHi3dOfqME0YRzErWI5AVg3cRw= diff --git a/cmd/geth/testdata/vcheck/vulnerabilities.json b/cmd/geth/testdata/vcheck/vulnerabilities.json deleted file mode 100644 index e52fd84e67..0000000000 --- a/cmd/geth/testdata/vcheck/vulnerabilities.json +++ /dev/null @@ -1,202 +0,0 @@ -[ - { - "name": "CorruptedDAG", - "uid": "GETH-2020-01", - "summary": "Mining nodes will generate erroneous PoW on epochs > `385`.", - "description": "A mining flaw could cause miners to erroneously calculate PoW, due to an index overflow, if DAG size is exceeding the maximum 32 bit unsigned value.\n\nThis occurred on the ETC chain on 2020-11-06. This is likely to trigger for ETH mainnet around block `11550000`/epoch `385`, slated to occur early January 2021.\n\nThis issue is relevant only for miners, non-mining nodes are unaffected, since non-mining nodes use a smaller verification cache instead of a full DAG.", - "links": [ - "https://github.com/ethereum/go-ethereum/pull/21793", - "https://blog.ethereum.org/2020/11/12/geth-security-release", - "https://github.com/ethereum/go-ethereum/commit/567d41d9363706b4b13ce0903804e8acf214af49", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-v592-xf75-856p" - ], - "introduced": "v1.6.0", - "fixed": "v1.9.24", - "published": "2020-11-12", - "severity": "Medium", - "CVE": "CVE-2020-26240", - "check": "Geth\\/v1\\.(6|7|8)\\..*|Geth\\/v1\\.9\\.\\d-.*|Geth\\/v1\\.9\\.1.*|Geth\\/v1\\.9\\.2(0|1|2|3)-.*" - }, - { - "name": "Denial of service due to Go CVE-2020-28362", - "uid": "GETH-2020-02", - "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing, due to an underlying bug in Go (CVE-2020-28362) versions < `1.15.5`, or `<1.14.12`", - "description": "The DoS issue can be used to crash all Geth nodes during block processing, the effects of which would be that a major part of the Ethereum network went offline.\n\nOutside of Go-Ethereum, the issue is most likely relevant for all forks of Geth (such as TurboGeth or ETC’s core-geth) which is built with versions of Go which contains the vulnerability.", - "links": [ - "https://blog.ethereum.org/2020/11/12/geth-security-release", - "https://groups.google.com/g/golang-announce/c/NpBGTTmKzpM", - "https://github.com/golang/go/issues/42552", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-m6gx-rhvj-fh52" - ], - "introduced": "v0.0.0", - "fixed": "v1.9.24", - "published": "2020-11-12", - "severity": "Critical", - "CVE": "CVE-2020-28362", - "check": "Geth.*\\/go1\\.(11(.*)|12(.*)|13(.*)|14|14\\.(\\d|10|11|)|15|15\\.[0-4])$" - }, - { - "name": "ShallowCopy", - "uid": "GETH-2020-03", - "summary": "A consensus flaw in Geth, related to `datacopy` precompile", - "description": "Geth erroneously performed a 'shallow' copy when the precompiled `datacopy` (at `0x00...04`) was invoked. An attacker could deploy a contract that uses the shallow copy to corrupt the contents of the `RETURNDATA`, thus causing a consensus failure.", - "links": [ - "https://blog.ethereum.org/2020/11/12/geth-security-release", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-69v6-xc2j-r2jf" - ], - "introduced": "v1.9.7", - "fixed": "v1.9.17", - "published": "2020-11-12", - "severity": "Critical", - "CVE": "CVE-2020-26241", - "check": "Geth\\/v1\\.9\\.(7|8|9|10|11|12|13|14|15|16).*$" - }, - { - "name": "Geth DoS via MULMOD", - "uid": "GETH-2020-04", - "summary": "A denial-of-service issue can be used to crash Geth nodes during block processing", - "description": "Affected versions suffer from a vulnerability which can be exploited through the `MULMOD` operation, by specifying a modulo of `0`: `mulmod(a,b,0)`, causing a `panic` in the underlying library. \nThe crash was in the `uint256` library, where a buffer [underflowed](https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L442).\n\n\tif `d == 0`, `dLen` remains `0`\n\nand https://github.com/holiman/uint256/blob/4ce82e695c10ddad57215bdbeafb68b8c5df2c30/uint256.go#L451 will try to access index `[-1]`.\n\nThe `uint256` library was first merged in this [commit](https://github.com/ethereum/go-ethereum/commit/cf6674539c589f80031f3371a71c6a80addbe454), on 2020-06-08. \nExploiting this vulnerabilty would cause all vulnerable nodes to drop off the network. \n\nThe issue was brought to our attention through a [bug report](https://github.com/ethereum/go-ethereum/issues/21367), showing a `panic` occurring on sync from genesis on the Ropsten network.\n \nIt was estimated that the least obvious way to fix this would be to merge the fix into `uint256`, make a new release of that library and then update the geth-dependency.\n", - "links": [ - "https://blog.ethereum.org/2020/11/12/geth-security-release", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-jm5c-rv3w-w83m", - "https://github.com/holiman/uint256/releases/tag/v1.1.1", - "https://github.com/holiman/uint256/pull/80", - "https://github.com/ethereum/go-ethereum/pull/21368" - ], - "introduced": "v1.9.16", - "fixed": "v1.9.18", - "published": "2020-11-12", - "severity": "Critical", - "CVE": "CVE-2020-26242", - "check": "Geth\\/v1\\.9.(16|17).*$" - }, - { - "name": "LES Server DoS via GetProofsV2", - "uid": "GETH-2020-05", - "summary": "A DoS vulnerability can make a LES server crash.", - "description": "A DoS vulnerability can make a LES server crash via malicious GetProofsV2 request from a connected LES client.\n\nThe vulnerability was patched in #21896.\n\nThis vulnerability only concern users explicitly running geth as a light server", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-r33q-22hv-j29q", - "https://github.com/ethereum/go-ethereum/pull/21896" - ], - "introduced": "v1.8.0", - "fixed": "v1.9.25", - "published": "2020-12-10", - "severity": "Medium", - "CVE": "CVE-2020-26264", - "check": "(Geth\\/v1\\.8\\.*)|(Geth\\/v1\\.9\\.\\d-.*)|(Geth\\/v1\\.9\\.1\\d-.*)|(Geth\\/v1\\.9\\.(20|21|22|23|24)-.*)$" - }, - { - "name": "SELFDESTRUCT-recreate consensus flaw", - "uid": "GETH-2020-06", - "introduced": "v1.9.4", - "fixed": "v1.9.20", - "summary": "A consensus-vulnerability in Geth could cause a chain split, where vulnerable versions refuse to accept the canonical chain.", - "description": "A flaw was repoted at 2020-08-11 by John Youngseok Yang (Software Platform Lab), where a particular sequence of transactions could cause a consensus failure.\n\n- Tx 1:\n - `sender` invokes `caller`.\n - `caller` invokes `0xaa`. `0xaa` has 3 wei, does a self-destruct-to-self\n - `caller` does a `1 wei` -call to `0xaa`, who thereby has 1 wei (the code in `0xaa` still executed, since the tx is still ongoing, but doesn't redo the selfdestruct, it takes a different path if callvalue is non-zero)\n\n-Tx 2:\n - `sender` does a 5-wei call to 0xaa. No exec (since no code). \n\nIn geth, the result would be that `0xaa` had `6 wei`, whereas OE reported (correctly) `5` wei. Furthermore, in geth, if the second tx was not executed, the `0xaa` would be destructed, resulting in `0 wei`. Thus obviously wrong. \n\nIt was determined that the root cause was this [commit](https://github.com/ethereum/go-ethereum/commit/223b950944f494a5b4e0957fd9f92c48b09037ad) from [this PR](https://github.com/ethereum/go-ethereum/pull/19953). The semantics of `createObject` was subtly changd, into returning a non-nil object (with `deleted=true`) where it previously did not if the account had been destructed. This return value caused the new object to inherit the old `balance`.\n", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-xw37-57qp-9mm4" - ], - "published": "2020-12-10", - "severity": "High", - "CVE": "CVE-2020-26265", - "check": "(Geth\\/v1\\.9\\.(4|5|6|7|8|9)-.*)|(Geth\\/v1\\.9\\.1\\d-.*)$" - }, - { - "name": "Not ready for London upgrade", - "uid": "GETH-2021-01", - "summary": "The client is not ready for the 'London' technical upgrade, and will deviate from the canonical chain when the London upgrade occurs (at block '12965000' around August 4, 2021.", - "description": "At (or around) August 4, Ethereum will undergo a technical upgrade called 'London'. Clients not upgraded will fail to progress on the canonical chain.", - "links": [ - "https://github.com/ethereum/eth1.0-specs/blob/master/network-upgrades/mainnet-upgrades/london.md", - "https://notes.ethereum.org/@timbeiko/ropsten-postmortem" - ], - "introduced": "v1.10.1", - "fixed": "v1.10.6", - "published": "2021-07-22", - "severity": "High", - "check": "(Geth\\/v1\\.10\\.(1|2|3|4|5)-.*)$" - }, - { - "name": "RETURNDATA corruption via datacopy", - "uid": "GETH-2021-02", - "summary": "A consensus-flaw in the Geth EVM could cause a node to deviate from the canonical chain.", - "description": "A memory-corruption bug within the EVM can cause a consensus error, where vulnerable nodes obtain a different `stateRoot` when processing a maliciously crafted transaction. This, in turn, would lead to the chain being split: mainnet splitting in two forks.\n\nAll Geth versions supporting the London hard fork are vulnerable (the bug is older than London), so all users should update.\n\nThis bug was exploited on Mainnet at block 13107518.\n\nCredits for the discovery go to @guidovranken (working for Sentnl during an audit of the Telos EVM) and reported via bounty@ethereum.org.", - "links": [ - "https://github.com/ethereum/go-ethereum/blob/master/docs/postmortems/2021-08-22-split-postmortem.md", - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-9856-9gg9-qcmq", - "https://github.com/ethereum/go-ethereum/releases/tag/v1.10.8" - ], - "introduced": "v1.10.0", - "fixed": "v1.10.8", - "published": "2021-08-24", - "severity": "High", - "CVE": "CVE-2021-39137", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7)-.*)$" - }, - { - "name": "DoS via malicious `snap/1` request", - "uid": "GETH-2021-03", - "summary": "A vulnerable node is susceptible to crash when processing a maliciously crafted message from a peer, via the snap/1 protocol. The crash can be triggered by sending a malicious snap/1 GetTrieNodes package.", - "description": "The `snap/1` protocol handler contains two vulnerabilities related to the `GetTrieNodes` packet, which can be exploited to crash the node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v)", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-59hh-656j-3p7v", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities", - "https://github.com/ethereum/go-ethereum/pull/23657" - ], - "introduced": "v1.10.0", - "fixed": "v1.10.9", - "published": "2021-10-24", - "severity": "Medium", - "CVE": "CVE-2021-41173", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8)-.*)$" - }, - { - "name": "DoS via malicious p2p message", - "uid": "GETH-2022-01", - "summary": "A vulnerable node can crash via p2p messages sent from an attacker node, if running with non-default log options.", - "description": "A vulnerable node, if configured to use high verbosity logging, can be made to crash when handling specially crafted p2p messages sent from an attacker node. Full details are available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5)", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-wjxw-gh3m-7pm5", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities", - "https://github.com/ethereum/go-ethereum/pull/24507" - ], - "introduced": "v1.10.0", - "fixed": "v1.10.17", - "published": "2022-05-11", - "severity": "Low", - "CVE": "CVE-2022-29177", - "check": "(Geth\\/v1\\.10\\.(0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|16)-.*)$" - }, - { - "name": "DoS via malicious p2p message", - "uid": "GETH-2023-01", - "summary": "A vulnerable node can be made to consume unbounded amounts of memory when handling specially crafted p2p messages sent from an attacker node.", - "description": "The p2p handler spawned a new goroutine to respond to ping requests. By flooding a node with ping requests, an unbounded number of goroutines can be created, leading to resource exhaustion and potentially crash due to OOM.", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-ppjg-v974-84cm", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities" - ], - "introduced": "v1.10.0", - "fixed": "v1.12.1", - "published": "2023-09-06", - "severity": "High", - "CVE": "CVE-2023-40591", - "check": "(Geth\\/v1\\.(10|11)\\..*)|(Geth\\/v1\\.12\\.0-.*)$" - }, - { - "name": "DoS via malicious p2p message", - "uid": "GETH-2024-01", - "summary": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node.", - "description": "A vulnerable node can be made to consume very large amounts of memory when handling specially crafted p2p messages sent from an attacker node. Full details will be available at the Github security [advisory](https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652)", - "links": [ - "https://github.com/ethereum/go-ethereum/security/advisories/GHSA-4xc9-8hmq-j652", - "https://geth.ethereum.org/docs/vulnerabilities/vulnerabilities" - ], - "introduced": "v1.10.0", - "fixed": "v1.13.15", - "published": "2024-05-06", - "severity": "High", - "CVE": "CVE-2024-32972", - "check": "(Geth\\/v1\\.(10|11|12)\\..*)|(Geth\\/v1\\.13\\.\\d-.*)|(Geth\\/v1\\.13\\.1(0|1|2|3|4)-.*)$" - } -] diff --git a/cmd/geth/verkle.go b/cmd/geth/verkle.go deleted file mode 100644 index 6490f832af..0000000000 --- a/cmd/geth/verkle.go +++ /dev/null @@ -1,214 +0,0 @@ -// Copyright 2022 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package main - -import ( - "bytes" - "encoding/hex" - "errors" - "fmt" - "os" - "slices" - - "github.com/ethereum/go-ethereum/cmd/utils" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-verkle" - "github.com/urfave/cli/v2" -) - -var ( - zero [32]byte - - verkleCommand = &cli.Command{ - Name: "verkle", - Usage: "A set of experimental verkle tree management commands", - Description: "", - Subcommands: []*cli.Command{ - { - Name: "verify", - Usage: "verify the conversion of a MPT into a verkle tree", - ArgsUsage: "", - Action: verifyVerkle, - Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), - Description: ` -geth verkle verify -This command takes a root commitment and attempts to rebuild the tree. - `, - }, - { - Name: "dump", - Usage: "Dump a verkle tree to a DOT file", - ArgsUsage: " [ ...]", - Action: expandVerkle, - Flags: slices.Concat(utils.NetworkFlags, utils.DatabaseFlags), - Description: ` -geth verkle dump [ ...] -This command will produce a dot file representing the tree, rooted at . -in which key1, key2, ... are expanded. - `, - }, - }, - } -) - -// recurse into each child to ensure they can be loaded from the db. The tree isn't rebuilt -// (only its nodes are loaded) so there is no need to flush them, the garbage collector should -// take care of that for us. -func checkChildren(root verkle.VerkleNode, resolver verkle.NodeResolverFn) error { - switch node := root.(type) { - case *verkle.InternalNode: - for i, child := range node.Children() { - childC := child.Commit().Bytes() - - childS, err := resolver(childC[:]) - if bytes.Equal(childC[:], zero[:]) { - continue - } - if err != nil { - return fmt.Errorf("could not find child %x in db: %w", childC, err) - } - // depth is set to 0, the tree isn't rebuilt so it's not a problem - childN, err := verkle.ParseNode(childS, 0) - if err != nil { - return fmt.Errorf("decode error child %x in db: %w", child.Commitment().Bytes(), err) - } - if err := checkChildren(childN, resolver); err != nil { - return fmt.Errorf("%x%w", i, err) // write the path to the erroring node - } - } - case *verkle.LeafNode: - // sanity check: ensure at least one value is non-zero - - for i := 0; i < verkle.NodeWidth; i++ { - if len(node.Value(i)) != 0 { - return nil - } - } - return errors.New("both balance and nonce are 0") - case verkle.Empty: - // nothing to do - default: - return fmt.Errorf("unsupported type encountered %v", root) - } - - return nil -} - -func verifyVerkle(ctx *cli.Context) error { - stack, _ := makeConfigNode(ctx) - defer stack.Close() - - chaindb := utils.MakeChainDatabase(ctx, stack, true) - defer chaindb.Close() - headBlock := rawdb.ReadHeadBlock(chaindb) - if headBlock == nil { - log.Error("Failed to load head block") - return errors.New("no head block") - } - if ctx.NArg() > 1 { - log.Error("Too many arguments given") - return errors.New("too many arguments") - } - var ( - rootC common.Hash - err error - ) - if ctx.NArg() == 1 { - rootC, err = parseRoot(ctx.Args().First()) - if err != nil { - log.Error("Failed to resolve state root", "error", err) - return err - } - log.Info("Rebuilding the tree", "root", rootC) - } else { - rootC = headBlock.Root() - log.Info("Rebuilding the tree", "root", rootC, "number", headBlock.NumberU64()) - } - - serializedRoot, err := chaindb.Get(rootC[:]) - if err != nil { - return err - } - root, err := verkle.ParseNode(serializedRoot, 0) - if err != nil { - return err - } - - if err := checkChildren(root, chaindb.Get); err != nil { - log.Error("Could not rebuild the tree from the database", "err", err) - return err - } - - log.Info("Tree was rebuilt from the database") - return nil -} - -func expandVerkle(ctx *cli.Context) error { - stack, _ := makeConfigNode(ctx) - defer stack.Close() - - chaindb := utils.MakeChainDatabase(ctx, stack, true) - defer chaindb.Close() - var ( - rootC common.Hash - keylist [][]byte - err error - ) - if ctx.NArg() >= 2 { - rootC, err = parseRoot(ctx.Args().First()) - if err != nil { - log.Error("Failed to resolve state root", "error", err) - return err - } - keylist = make([][]byte, 0, ctx.Args().Len()-1) - args := ctx.Args().Slice() - for i := range args[1:] { - key, err := hex.DecodeString(args[i+1]) - log.Info("decoded key", "arg", args[i+1], "key", key) - if err != nil { - return fmt.Errorf("error decoding key #%d: %w", i+1, err) - } - keylist = append(keylist, key) - } - log.Info("Rebuilding the tree", "root", rootC) - } else { - return fmt.Errorf("usage: %s root key1 [key 2...]", ctx.App.Name) - } - - serializedRoot, err := chaindb.Get(rootC[:]) - if err != nil { - return err - } - root, err := verkle.ParseNode(serializedRoot, 0) - if err != nil { - return err - } - - for i, key := range keylist { - log.Info("Reading key", "index", i, "key", keylist[0]) - root.Get(key, chaindb.Get) - } - - if err := os.WriteFile("dump.dot", []byte(verkle.ToDot(root)), 0600); err != nil { - log.Error("Failed to dump file", "err", err) - } else { - log.Info("Tree was dumped to file", "file", "dump.dot") - } - return nil -} diff --git a/cmd/geth/version_check.go b/cmd/geth/version_check.go deleted file mode 100644 index 237556788e..0000000000 --- a/cmd/geth/version_check.go +++ /dev/null @@ -1,170 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package main - -import ( - "encoding/json" - "errors" - "fmt" - "io" - "net/http" - "os" - "regexp" - "strings" - - "github.com/ethereum/go-ethereum/log" - "github.com/jedisct1/go-minisign" - "github.com/urfave/cli/v2" -) - -var gethPubKeys []string = []string{ - //@holiman, minisign public key FB1D084D39BAEC24 - "RWQk7Lo5TQgd+wxBNZM+Zoy+7UhhMHaWKzqoes9tvSbFLJYZhNTbrIjx", - //minisign public key 138B1CA303E51687 - "RWSHFuUDoxyLEzjszuWZI1xStS66QTyXFFZG18uDfO26CuCsbckX1e9J", - //minisign public key FD9813B2D2098484 - "RWSEhAnSshOY/b+GmaiDkObbCWefsAoavjoLcPjBo1xn71yuOH5I+Lts", -} - -type vulnJson struct { - Name string - Uid string - Summary string - Description string - Links []string - Introduced string - Fixed string - Published string - Severity string - Check string - CVE string -} - -func versionCheck(ctx *cli.Context) error { - url := ctx.String(VersionCheckUrlFlag.Name) - version := ctx.String(VersionCheckVersionFlag.Name) - log.Info("Checking vulnerabilities", "version", version, "url", url) - return checkCurrent(url, version) -} - -func checkCurrent(url, current string) error { - var ( - data []byte - sig []byte - err error - ) - if data, err = fetch(url); err != nil { - return fmt.Errorf("could not retrieve data: %w", err) - } - if sig, err = fetch(fmt.Sprintf("%v.minisig", url)); err != nil { - return fmt.Errorf("could not retrieve signature: %w", err) - } - if err = verifySignature(gethPubKeys, data, sig); err != nil { - return err - } - var vulns []vulnJson - if err = json.Unmarshal(data, &vulns); err != nil { - return err - } - allOk := true - for _, vuln := range vulns { - r, err := regexp.Compile(vuln.Check) - if err != nil { - return err - } - if r.MatchString(current) { - allOk = false - fmt.Printf("## Vulnerable to %v (%v)\n\n", vuln.Uid, vuln.Name) - fmt.Printf("Severity: %v\n", vuln.Severity) - fmt.Printf("Summary : %v\n", vuln.Summary) - fmt.Printf("Fixed in: %v\n", vuln.Fixed) - if len(vuln.CVE) > 0 { - fmt.Printf("CVE: %v\n", vuln.CVE) - } - if len(vuln.Links) > 0 { - fmt.Printf("References:\n") - for _, ref := range vuln.Links { - fmt.Printf("\t- %v\n", ref) - } - } - fmt.Println() - } - } - if allOk { - fmt.Println("No vulnerabilities found") - } - return nil -} - -// fetch makes an HTTP request to the given url and returns the response body -func fetch(url string) ([]byte, error) { - if filep := strings.TrimPrefix(url, "file://"); filep != url { - return os.ReadFile(filep) - } - res, err := http.Get(url) - if err != nil { - return nil, err - } - defer res.Body.Close() - body, err := io.ReadAll(res.Body) - if err != nil { - return nil, err - } - return body, nil -} - -// verifySignature checks that the sigData is a valid signature of the given -// data, for pubkey GethPubkey -func verifySignature(pubkeys []string, data, sigdata []byte) error { - sig, err := minisign.DecodeSignature(string(sigdata)) - if err != nil { - return err - } - // find the used key - var key *minisign.PublicKey - for _, pubkey := range pubkeys { - pub, err := minisign.NewPublicKey(pubkey) - if err != nil { - // our pubkeys should be parseable - return err - } - if pub.KeyId != sig.KeyId { - continue - } - key = &pub - break - } - if key == nil { - log.Info("Signing key not trusted", "keyid", keyID(sig.KeyId), "error", err) - return errors.New("signature could not be verified") - } - if ok, err := key.Verify(data, sig); !ok || err != nil { - log.Info("Verification failed error", "keyid", keyID(key.KeyId), "error", err) - return errors.New("signature could not be verified") - } - return nil -} - -// keyID turns a binary minisign key ID into a hex string. -// Note: key IDs are printed in reverse byte order. -func keyID(id [8]byte) string { - var rev [8]byte - for i := range id { - rev[len(rev)-1-i] = id[i] - } - return fmt.Sprintf("%X", rev) -} diff --git a/cmd/geth/version_check_test.go b/cmd/geth/version_check_test.go deleted file mode 100644 index fb5d1b2d69..0000000000 --- a/cmd/geth/version_check_test.go +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2020 The go-ethereum Authors -// This file is part of go-ethereum. -// -// go-ethereum is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// go-ethereum is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with go-ethereum. If not, see . - -package main - -import ( - "encoding/json" - "fmt" - "os" - "path/filepath" - "regexp" - "strconv" - "strings" - "testing" - - "github.com/jedisct1/go-minisign" -) - -func TestVerification(t *testing.T) { - t.Parallel() - // Signatures generated with `minisign`. Legacy format, not pre-hashed file. - t.Run("minisig-legacy", func(t *testing.T) { - t.Parallel() - // For this test, the pubkey is in testdata/vcheck/minisign.pub - // (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' ) - // 1. `minisign -S -l -s ./minisign.sec -m data.json -x ./minisig-sigs/vulnerabilities.json.minisig.1 -c "signature from minisign secret key"` - // 2. `minisign -S -l -s ./minisign.sec -m vulnerabilities.json -x ./minisig-sigs/vulnerabilities.json.minisig.2 -c "Here's a comment" -t "Here's a trusted comment"` - // 3. minisign -S -l -s ./minisign.sec -m vulnerabilities.json -x ./minisig-sigs/vulnerabilities.json.minisig.3 -c "One more (untrusted™) comment" -t "Here's a trusted comment" - pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp" - testVerification(t, pub, "./testdata/vcheck/minisig-sigs/") - }) - t.Run("minisig-new", func(t *testing.T) { - t.Parallel() - // For this test, the pubkey is in testdata/vcheck/minisign.pub - // (the privkey is `minisign.sec`, if we want to expand this test. Password 'test' ) - // `minisign -S -s ./minisign.sec -m data.json -x ./minisig-sigs-new/data.json.minisig` - pub := "RWQkliYstQBOKOdtClfgC3IypIPX6TAmoEi7beZ4gyR3wsaezvqOMWsp" - testVerification(t, pub, "./testdata/vcheck/minisig-sigs-new/") - }) - // Signatures generated with `signify-openbsd` - t.Run("signify-openbsd", func(t *testing.T) { - t.Parallel() - t.Skip("This currently fails, minisign expects 4 lines of data, signify provides only 2") - // For this test, the pubkey is in testdata/vcheck/signifykey.pub - // (the privkey is `signifykey.sec`, if we want to expand this test. Password 'test' ) - // `signify -S -s signifykey.sec -m data.json -x ./signify-sigs/data.json.sig` - pub := "RWSKLNhZb0KdATtRT7mZC/bybI3t3+Hv/O2i3ye04Dq9fnT9slpZ1a2/" - testVerification(t, pub, "./testdata/vcheck/signify-sigs/") - }) -} - -func testVerification(t *testing.T, pubkey, sigdir string) { - // Data to verify - data, err := os.ReadFile("./testdata/vcheck/data.json") - if err != nil { - t.Fatal(err) - } - // Signatures, with and without comments, both trusted and untrusted - files, err := os.ReadDir(sigdir) - if err != nil { - t.Fatal(err) - } - if len(files) == 0 { - t.Fatal("Missing tests") - } - for _, f := range files { - sig, err := os.ReadFile(filepath.Join(sigdir, f.Name())) - if err != nil { - t.Fatal(err) - } - err = verifySignature([]string{pubkey}, data, sig) - if err != nil { - t.Fatal(err) - } - } -} - -func versionUint(v string) int { - mustInt := func(s string) int { - a, err := strconv.Atoi(s) - if err != nil { - panic(v) - } - return a - } - components := strings.Split(strings.TrimPrefix(v, "v"), ".") - a := mustInt(components[0]) - b := mustInt(components[1]) - c := mustInt(components[2]) - return a*100*100 + b*100 + c -} - -// TestMatching can be used to check that the regexps are correct -func TestMatching(t *testing.T) { - t.Parallel() - data, _ := os.ReadFile("./testdata/vcheck/vulnerabilities.json") - var vulns []vulnJson - if err := json.Unmarshal(data, &vulns); err != nil { - t.Fatal(err) - } - check := func(version string) { - vFull := fmt.Sprintf("Geth/%v-unstable-15339cf1-20201204/linux-amd64/go1.15.4", version) - for _, vuln := range vulns { - r, err := regexp.Compile(vuln.Check) - vulnIntro := versionUint(vuln.Introduced) - vulnFixed := versionUint(vuln.Fixed) - current := versionUint(version) - if err != nil { - t.Fatal(err) - } - if vuln.Name == "Denial of service due to Go CVE-2020-28362" { - // this one is not tied to geth-versions - continue - } - if vulnIntro <= current && vulnFixed > current { - // Should be vulnerable - if !r.MatchString(vFull) { - t.Errorf("Should be vulnerable, version %v, intro: %v, fixed: %v %v %v", - version, vuln.Introduced, vuln.Fixed, vuln.Name, vuln.Check) - } - } else { - if r.MatchString(vFull) { - t.Errorf("Should not be flagged vulnerable, version %v, intro: %v, fixed: %v %v %d %d %d", - version, vuln.Introduced, vuln.Fixed, vuln.Name, vulnIntro, current, vulnFixed) - } - } - } - } - for major := 1; major < 2; major++ { - for minor := 0; minor < 30; minor++ { - for patch := 0; patch < 30; patch++ { - vShort := fmt.Sprintf("v%d.%d.%d", major, minor, patch) - check(vShort) - } - } - } -} - -func TestGethPubKeysParseable(t *testing.T) { - t.Parallel() - for _, pubkey := range gethPubKeys { - _, err := minisign.NewPublicKey(pubkey) - if err != nil { - t.Errorf("Should be parseable") - } - } -} - -func TestKeyID(t *testing.T) { - t.Parallel() - type args struct { - id [8]byte - } - tests := []struct { - name string - args args - want string - }{ - {"@holiman key", args{id: extractKeyId(gethPubKeys[0])}, "FB1D084D39BAEC24"}, - {"second key", args{id: extractKeyId(gethPubKeys[1])}, "138B1CA303E51687"}, - {"third key", args{id: extractKeyId(gethPubKeys[2])}, "FD9813B2D2098484"}, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - if got := keyID(tt.args.id); got != tt.want { - t.Errorf("keyID() = %v, want %v", got, tt.want) - } - }) - } -} - -func extractKeyId(pubkey string) [8]byte { - p, _ := minisign.NewPublicKey(pubkey) - return p.KeyId -} diff --git a/cmd/keeper/1192c3_block.rlp b/cmd/keeper/1192c3_block.rlp new file mode 100644 index 0000000000..e788c2b8fd Binary files /dev/null and b/cmd/keeper/1192c3_block.rlp differ diff --git a/cmd/keeper/1192c3_witness.rlp b/cmd/keeper/1192c3_witness.rlp new file mode 100644 index 0000000000..4990f2299f Binary files /dev/null and b/cmd/keeper/1192c3_witness.rlp differ diff --git a/cmd/keeper/README.md b/cmd/keeper/README.md new file mode 100644 index 0000000000..4737a22674 --- /dev/null +++ b/cmd/keeper/README.md @@ -0,0 +1,69 @@ +# Keeper - geth as a zkvm guest + +Keeper command is a specialized tool for validating stateless execution of Ethereum blocks. It's designed to run as a zkvm guest. + +## Overview + +The keeper reads an RLP-encoded payload containing: +- A block to execute +- A witness with the necessary state data +- A chainID + +It then executes the block statelessly and validates that the computed state root and receipt root match the values in the block header. + +## Building Keeper + +The keeper uses build tags to compile platform-specific input methods and chain configurations: + +### Example Implementation + +See `getpayload_example.go` for a complete example with embedded Hoodi block data: + +```bash +# Build example with different chain configurations +go build -tags "example" ./cmd/keeper +``` + +### Ziren zkVM Implementation + +Build for the Ziren zkVM platform, which is a MIPS ISA-based zkvm: + +```bash +GOOS=linux GOARCH=mipsle GOMIPS=softfloat go build -tags "ziren" ./cmd/keeper +``` + +As an example runner, refer to https://gist.github.com/gballet/7b669a99eb3ab2b593324e3a76abd23d + +## Creating a Custom Platform Implementation + +To add support for a new platform (e.g., "myplatform"), create a new file with the appropriate build tag: + +### 1. Create `getinput_myplatform.go` + +```go +//go:build myplatform + +package main + +import ( + "github.com/ethereum/go-ethereum/params" + // ... other imports as needed +) + +// getInput returns the RLP-encoded payload +func getInput() []byte { + // Your platform-specific code to retrieve the RLP-encoded payload + // This might read from: + // - Memory-mapped I/O + // - Hardware registers + // - Serial port + // - Network interface + // - File system + + // The payload must be RLP-encoded and contain: + // - Block with transactions + // - Witness with parent headers and state data + + return encodedPayload +} +``` diff --git a/cmd/keeper/chainconfig.go b/cmd/keeper/chainconfig.go new file mode 100644 index 0000000000..c9859d450f --- /dev/null +++ b/cmd/keeper/chainconfig.go @@ -0,0 +1,38 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package main + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/params" +) + +// getChainConfig returns the appropriate chain configuration based on the chainID. +// Returns an error for unsupported chain IDs. +func getChainConfig(chainID uint64) (*params.ChainConfig, error) { + switch chainID { + case 0, params.MainnetChainConfig.ChainID.Uint64(): + return params.MainnetChainConfig, nil + case params.SepoliaChainConfig.ChainID.Uint64(): + return params.SepoliaChainConfig, nil + case params.HoodiChainConfig.ChainID.Uint64(): + return params.HoodiChainConfig, nil + default: + return nil, fmt.Errorf("unsupported chain ID: %d", chainID) + } +} diff --git a/cmd/keeper/getpayload_example.go b/cmd/keeper/getpayload_example.go new file mode 100644 index 0000000000..683cc79248 --- /dev/null +++ b/cmd/keeper/getpayload_example.go @@ -0,0 +1,102 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +//go:build example + +package main + +import ( + _ "embed" + "fmt" + "os" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/stateless" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/rlp" +) + +// ExtWitness is a witness RLP encoding for transferring across clients. +// This is taken from PR #32216 until it's merged. +// It contains block headers, contract codes, state nodes, and storage keys +// required for stateless execution verification. +type ExtWitness struct { + Headers []*types.Header `json:"headers"` + Codes []hexutil.Bytes `json:"codes"` + State []hexutil.Bytes `json:"state"` + Keys []hexutil.Bytes `json:"keys"` +} + +// This is taken from PR #32216 until it's merged +// fromExtWitness converts the consensus witness format into our internal one. +func fromExtWitness(ext *ExtWitness) (*stateless.Witness, error) { + w := &stateless.Witness{} + w.Headers = ext.Headers + + w.Codes = make(map[string]struct{}, len(ext.Codes)) + for _, code := range ext.Codes { + w.Codes[string(code)] = struct{}{} + } + w.State = make(map[string]struct{}, len(ext.State)) + for _, node := range ext.State { + w.State[string(node)] = struct{}{} + } + return w, nil +} + +//go:embed 1192c3_witness.rlp +var witnessRlp []byte + +//go:embed 1192c3_block.rlp +var blockRlp []byte + +// getInput is a platform-specific function that will recover the input payload +// and returns it as a slice. It is expected to be an RLP-encoded Payload structure +// that contains the witness and the block. +// This is a demo version, that is intended to run on a regular computer, so what +// it does is embed a small Hoodi block, encodes the Payload structure containing +// the block and its witness as RLP, and returns the encoding. +func getInput() []byte { + var block types.Block + err := rlp.DecodeBytes(blockRlp, &block) + if err != nil { + panic(err) + } + + var extwitness ExtWitness + err = rlp.DecodeBytes(witnessRlp, &extwitness) + if err != nil { + panic(err) + } + witness, err := fromExtWitness(&extwitness) + if err != nil { + panic(err) + } + + payload := Payload{ + ChainID: params.HoodiChainConfig.ChainID.Uint64(), + Block: &block, + Witness: witness, + } + + encoded, err := rlp.EncodeToBytes(payload) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to encode payload: %v\n", err) + os.Exit(20) + } + return encoded +} diff --git a/rlp/unsafe.go b/cmd/keeper/getpayload_ziren.go similarity index 64% rename from rlp/unsafe.go rename to cmd/keeper/getpayload_ziren.go index 10868caaf2..bc373db94f 100644 --- a/rlp/unsafe.go +++ b/cmd/keeper/getpayload_ziren.go @@ -1,4 +1,4 @@ -// Copyright 2021 The go-ethereum Authors +// Copyright 2025 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -14,17 +14,18 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build !nacl && !js && cgo -// +build !nacl,!js,cgo +//go:build ziren -package rlp +package main import ( - "reflect" - "unsafe" + zkruntime "github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime" ) -// byteArrayBytes returns a slice of the byte array v. -func byteArrayBytes(v reflect.Value, length int) []byte { - return unsafe.Slice((*byte)(unsafe.Pointer(v.UnsafeAddr())), length) +// getInput reads the input payload from the zkVM runtime environment. +// The zkVM host provides the RLP-encoded Payload structure containing +// the block and witness data through the runtime's input mechanism. +func getInput() []byte { + input := zkruntime.Read[[]byte]() + return input } diff --git a/cmd/keeper/go.mod b/cmd/keeper/go.mod new file mode 100644 index 0000000000..cee1ce05a7 --- /dev/null +++ b/cmd/keeper/go.mod @@ -0,0 +1,41 @@ +module github.com/ethereum/go-ethereum/cmd/keeper + +go 1.24.0 + +require ( + github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 + github.com/ethereum/go-ethereum v0.0.0-00010101000000-000000000000 +) + +require ( + github.com/StackExchange/wmi v1.2.1 // indirect + github.com/VictoriaMetrics/fastcache v1.13.0 // indirect + github.com/bits-and-blooms/bitset v1.20.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/consensys/gnark-crypto v0.18.1 // indirect + github.com/crate-crypto/go-eth-kzg v1.4.0 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect + github.com/emicklei/dot v1.6.2 // indirect + github.com/ethereum/c-kzg-4844/v2 v2.1.5 // indirect + github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab // indirect + github.com/ferranbt/fastssz v0.1.4 // indirect + github.com/go-ole/go-ole v1.3.0 // indirect + github.com/gofrs/flock v0.12.1 // indirect + github.com/golang/snappy v1.0.0 // indirect + github.com/holiman/bloomfilter/v2 v2.0.3 // indirect + github.com/holiman/uint256 v1.3.2 // indirect + github.com/klauspost/cpuid/v2 v2.0.9 // indirect + github.com/minio/sha256-simd v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.4.1 // indirect + github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect + github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe // indirect + github.com/tklauser/go-sysconf v0.3.12 // indirect + github.com/tklauser/numcpus v0.6.1 // indirect + golang.org/x/crypto v0.36.0 // indirect + golang.org/x/sync v0.12.0 // indirect + golang.org/x/sys v0.39.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect +) + +replace github.com/ethereum/go-ethereum => ../../ diff --git a/cmd/keeper/go.sum b/cmd/keeper/go.sum new file mode 100644 index 0000000000..62f10968e2 --- /dev/null +++ b/cmd/keeper/go.sum @@ -0,0 +1,133 @@ +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI= +github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= +github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= +github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0= +github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= +github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3MdfoPyRVU= +github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= +github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= +github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce/go.mod h1:9/y3cnZ5GKakj/H4y9r9GTjCvAFta7KLgSHPJJYc52M= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b h1:r6VH0faHjZeQy818SGhaone5OnYfxFR/+AzdY3sf5aE= +github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b/go.mod h1:Vz9DsVWQQhf3vs21MhPMZpMGSht7O/2vFW2xusFUVOs= +github.com/cockroachdb/pebble v1.1.5 h1:5AAWCBWbat0uE0blr8qzufZP5tBjkRyy/jWe1QWLnvw= +github.com/cockroachdb/pebble v1.1.5/go.mod h1:17wO9el1YEigxkP/YtV8NtCivQDgoCyBg5c4VR/eOWo= +github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwPJ30= +github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= +github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= +github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI= +github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= +github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= +github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= +github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= +github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= +github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= +github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s= +github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= +github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= +github.com/ferranbt/fastssz v0.1.4/go.mod h1:Ea3+oeoRGGLGm5shYAeDgu6PGUlcvQhE2fILyD9+tGg= +github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= +github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= +github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= +github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= +github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= +github.com/gofrs/flock v0.12.1 h1:MTLVXXHf8ekldpJk3AKicLij9MdwOWkZ+a/jHHZby9E= +github.com/gofrs/flock v0.12.1/go.mod h1:9zxTsyu5xtJ9DK+1tFZyibEV7y3uwDxPPfbxeeHCoD0= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= +github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= +github.com/holiman/uint256 v1.3.2 h1:a9EgMPSC1AAaj1SZL5zIQD3WbwTuHrMGOerLjGmM/TA= +github.com/holiman/uint256 v1.3.2/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.11 h1:vRjThO1EKPb/1NsDXuDrzldR28RLkBflWYcU9CvzWu4= +github.com/leanovate/gopter v0.2.11/go.mod h1:aK3tzZP/C+p1m3SPRE4SYZFGP7jjkuSI4f7Xvpt0S9c= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= +github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= +github.com/mitchellh/mapstructure v1.4.1 h1:CpVNEelQCZBooIPDn+AR3NpivK/TIKU8bDxdASFVQag= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.15.0 h1:5fCgGYogn0hFdhyhLbw7hEsWxufKtY9klyvdNfFlFhM= +github.com/prometheus/client_golang v1.15.0/go.mod h1:e9yaBhRPU2pPNsZwE+JdQl0KEt1N9XgF6zxWmaC0xOk= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/prysmaticlabs/gohashtree v0.0.4-beta h1:H/EbCuXPeTV3lpKeXGPpEV9gsUpkqOOVnWapUyeWro4= +github.com/prysmaticlabs/gohashtree v0.0.4-beta/go.mod h1:BFdtALS+Ffhg3lGQIHv9HDWuHS8cTvHZzrHWxwOtGOs= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= +github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe h1:nbdqkIGOGfUAD54q1s2YBcBz/WcsxCO9HUQ4aGV5hUw= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= +github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI= +github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk= +github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY= +golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34= +golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME= +golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw= +golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= +golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY= +golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/cmd/keeper/main.go b/cmd/keeper/main.go new file mode 100644 index 0000000000..9b459f6f36 --- /dev/null +++ b/cmd/keeper/main.go @@ -0,0 +1,68 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package main + +import ( + "fmt" + "os" + "runtime/debug" + + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/stateless" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/rlp" +) + +// Payload represents the input data for stateless execution containing +// a block and its associated witness data for verification. +type Payload struct { + ChainID uint64 + Block *types.Block + Witness *stateless.Witness +} + +func init() { + debug.SetGCPercent(-1) // Disable garbage collection +} + +func main() { + input := getInput() + var payload Payload + rlp.DecodeBytes(input, &payload) + + chainConfig, err := getChainConfig(payload.ChainID) + if err != nil { + fmt.Fprintf(os.Stderr, "failed to get chain config: %v\n", err) + os.Exit(13) + } + vmConfig := vm.Config{} + + crossStateRoot, crossReceiptRoot, err := core.ExecuteStateless(chainConfig, vmConfig, payload.Block, payload.Witness) + if err != nil { + fmt.Fprintf(os.Stderr, "stateless self-validation failed: %v\n", err) + os.Exit(10) + } + if crossStateRoot != payload.Block.Root() { + fmt.Fprintf(os.Stderr, "stateless self-validation root mismatch (cross: %x local: %x)\n", crossStateRoot, payload.Block.Root()) + os.Exit(11) + } + if crossReceiptRoot != payload.Block.ReceiptHash() { + fmt.Fprintf(os.Stderr, "stateless self-validation receipt root mismatch (cross: %x local: %x)\n", crossReceiptRoot, payload.Block.ReceiptHash()) + os.Exit(12) + } +} diff --git a/rlp/safe.go b/cmd/keeper/stubs.go similarity index 68% rename from rlp/safe.go rename to cmd/keeper/stubs.go index 3c910337b6..04a3bc735b 100644 --- a/rlp/safe.go +++ b/cmd/keeper/stubs.go @@ -1,4 +1,4 @@ -// Copyright 2021 The go-ethereum Authors +// Copyright 2025 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -14,14 +14,13 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build nacl || js || !cgo -// +build nacl js !cgo +//go:build !example && !ziren -package rlp +package main -import "reflect" - -// byteArrayBytes returns a slice of the byte array v. -func byteArrayBytes(v reflect.Value, length int) []byte { - return v.Slice(0, length).Bytes() +// getInput is a stub implementation for when no platform-specific build tags are set. +// This allows golangci-lint to typecheck the code without errors. +// The actual implementations are provided in platform-specific files. +func getInput() []byte { + panic("stub") } diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index b332a060de..3e337a3d00 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -25,6 +25,7 @@ import ( "errors" "fmt" "io" + "math" "math/big" "os" "os/signal" @@ -48,6 +49,7 @@ import ( "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/triedb" "github.com/urfave/cli/v2" ) @@ -310,7 +312,7 @@ func ImportHistory(chain *core.BlockChain, dir string, network string) error { return fmt.Errorf("error reading receipts %d: %w", it.Number(), err) } encReceipts := types.EncodeBlockReceiptLists([]types.Receipts{receipts}) - if _, err := chain.InsertReceiptChain([]*types.Block{block}, encReceipts, 2^64-1); err != nil { + if _, err := chain.InsertReceiptChain([]*types.Block{block}, encReceipts, math.MaxUint64); err != nil { return fmt.Errorf("error inserting body %d: %w", it.Number(), err) } imported += 1 @@ -567,9 +569,64 @@ func ExportPreimages(db ethdb.Database, fn string) error { return nil } +// StateIterator is a temporary structure for traversing state in order. It serves +// as an aggregator for both path scheme and hash scheme implementations and should +// be removed once the hash scheme is fully deprecated. +type StateIterator struct { + scheme string + root common.Hash + triedb *triedb.Database + snapshots *snapshot.Tree +} + +// NewStateIterator constructs the state iterator with the specific root. +func NewStateIterator(triedb *triedb.Database, db ethdb.Database, root common.Hash) (*StateIterator, error) { + if triedb.Scheme() == rawdb.PathScheme { + return &StateIterator{ + scheme: rawdb.PathScheme, + root: root, + triedb: triedb, + }, nil + } + config := snapshot.Config{ + CacheSize: 256, + Recovery: false, + NoBuild: true, + AsyncBuild: false, + } + snapshots, err := snapshot.New(config, db, triedb, root) + if err != nil { + return nil, err + } + return &StateIterator{ + scheme: rawdb.HashScheme, + root: root, + triedb: triedb, + snapshots: snapshots, + }, nil +} + +// AccountIterator creates a new account iterator for the specified root hash and +// seeks to a starting account hash. +func (it *StateIterator) AccountIterator(root common.Hash, start common.Hash) (snapshot.AccountIterator, error) { + if it.scheme == rawdb.PathScheme { + return it.triedb.AccountIterator(root, start) + } + return it.snapshots.AccountIterator(root, start) +} + +// StorageIterator creates a new storage iterator for the specified root hash and +// account. The iterator will be moved to the specific start position. +func (it *StateIterator) StorageIterator(root common.Hash, accountHash common.Hash, start common.Hash) (snapshot.StorageIterator, error) { + if it.scheme == rawdb.PathScheme { + return it.triedb.StorageIterator(root, accountHash, start) + } + return it.snapshots.StorageIterator(root, accountHash, start) +} + // ExportSnapshotPreimages exports the preimages corresponding to the enumeration of // the snapshot for a given root. -func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn string, root common.Hash) error { +func ExportSnapshotPreimages(chaindb ethdb.Database, stateIt *StateIterator, fn string, root common.Hash) error { log.Info("Exporting preimages", "file", fn) fh, err := os.OpenFile(fn, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.ModePerm) @@ -602,7 +659,7 @@ func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn ) go func() { defer close(hashCh) - accIt, err := snaptree.AccountIterator(root, common.Hash{}) + accIt, err := stateIt.AccountIterator(root, common.Hash{}) if err != nil { log.Error("Failed to create account iterator", "error", err) return @@ -619,7 +676,7 @@ func ExportSnapshotPreimages(chaindb ethdb.Database, snaptree *snapshot.Tree, fn hashCh <- hashAndPreimageSize{Hash: accIt.Hash(), Size: common.AddressLength} if acc.Root != (common.Hash{}) && acc.Root != types.EmptyRootHash { - stIt, err := snaptree.StorageIterator(root, accIt.Hash(), common.Hash{}) + stIt, err := stateIt.StorageIterator(root, accIt.Hash(), common.Hash{}) if err != nil { log.Error("Failed to create storage iterator", "error", err) return diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go index cbc1d925e4..844397b734 100644 --- a/cmd/utils/flags.go +++ b/cmd/utils/flags.go @@ -20,11 +20,9 @@ package utils import ( "context" "crypto/ecdsa" - "encoding/hex" "encoding/json" "errors" "fmt" - "math" "math/big" "net" "net/http" @@ -116,7 +114,7 @@ var ( Usage: "Root directory for era1 history (default = inside ancient/chain)", Category: flags.EthCategory, } - MinFreeDiskSpaceFlag = &flags.DirectoryFlag{ + MinFreeDiskSpaceFlag = &cli.IntFlag{ Name: "datadir.minfreedisk", Usage: "Minimum free disk space in MB, once reached triggers auto shut down (default = --cache.gc converted to MB, 0 = disabled)", Category: flags.EthCategory, @@ -139,7 +137,7 @@ var ( } NetworkIdFlag = &cli.Uint64Flag{ Name: "networkid", - Usage: "Explicitly set network id (integer)(For testnets: use --sepolia, --holesky, --hoodi instead)", + Usage: "Explicitly set network ID (integer)(For testnets: use --sepolia, --holesky, --hoodi instead)", Value: ethconfig.Defaults.NetworkId, Category: flags.EthCategory, } @@ -248,11 +246,26 @@ var ( Usage: "Manually specify the Osaka fork timestamp, overriding the bundled setting", Category: flags.EthCategory, } + OverrideBPO1 = &cli.Uint64Flag{ + Name: "override.bpo1", + Usage: "Manually specify the bpo1 fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } + OverrideBPO2 = &cli.Uint64Flag{ + Name: "override.bpo2", + Usage: "Manually specify the bpo2 fork timestamp, overriding the bundled setting", + Category: flags.EthCategory, + } OverrideVerkle = &cli.Uint64Flag{ Name: "override.verkle", Usage: "Manually specify the Verkle fork timestamp, overriding the bundled setting", Category: flags.EthCategory, } + OverrideGenesisFlag = &cli.StringFlag{ + Name: "override.genesis", + Usage: "Load genesis block and configuration from file at this path", + Category: flags.EthCategory, + } SyncModeFlag = &cli.StringFlag{ Name: "syncmode", Usage: `Blockchain sync mode ("snap" or "full")`, @@ -270,12 +283,30 @@ var ( Usage: "Scheme to use for storing ethereum state ('hash' or 'path')", Category: flags.StateCategory, } + StateSizeTrackingFlag = &cli.BoolFlag{ + Name: "state.size-tracking", + Usage: "Enable state size tracking, retrieve state size with debug_stateSize.", + Value: ethconfig.Defaults.EnableStateSizeTracking, + Category: flags.StateCategory, + } StateHistoryFlag = &cli.Uint64Flag{ Name: "history.state", Usage: "Number of recent blocks to retain state history for, only relevant in state.scheme=path (default = 90,000 blocks, 0 = entire chain)", Value: ethconfig.Defaults.StateHistory, Category: flags.StateCategory, } + TrienodeHistoryFlag = &cli.Int64Flag{ + Name: "history.trienode", + Usage: "Number of recent blocks to retain trienode history for, only relevant in state.scheme=path (default/negative = disabled, 0 = entire chain)", + Value: ethconfig.Defaults.TrienodeHistory, + Category: flags.StateCategory, + } + TrienodeHistoryFullValueCheckpointFlag = &cli.UintFlag{ + Name: "history.trienode.full-value-checkpoint", + Usage: "The frequency of full-value encoding. Every n-th node is stored in full-value format; all other nodes are stored as diffs relative to their predecessor", + Value: uint(ethconfig.Defaults.NodeFullValueCheckpoint), + Category: flags.StateCategory, + } TransactionHistoryFlag = &cli.Uint64Flag{ Name: "history.transactions", Usage: "Number of recent blocks to maintain transactions index for (default = about one year, 0 = entire chain)", @@ -534,6 +565,11 @@ var ( Usage: "0x prefixed public address for the pending block producer (not used for actual block production)", Category: flags.MinerCategory, } + MinerMaxBlobsFlag = &cli.IntFlag{ + Name: "miner.maxblobs", + Usage: "Maximum number of blobs per block (falls back to protocol maximum if unspecified)", + Category: flags.MinerCategory, + } // Account settings PasswordFileFlag = &cli.PathFlag{ @@ -565,6 +601,16 @@ var ( Value: "{}", Category: flags.VMCategory, } + VMWitnessStatsFlag = &cli.BoolFlag{ + Name: "vmwitnessstats", + Usage: "Enable collection of witness trie access statistics (automatically enables witness generation)", + Category: flags.VMCategory, + } + VMStatelessSelfValidationFlag = &cli.BoolFlag{ + Name: "stateless-self-validation", + Usage: "Generate execution witnesses and self-check against them (testing purpose)", + Category: flags.VMCategory, + } // API options. RPCGlobalGasCapFlag = &cli.Uint64Flag{ Name: "rpc.gascap", @@ -584,6 +630,30 @@ var ( Value: ethconfig.Defaults.RPCTxFeeCap, Category: flags.APICategory, } + RPCGlobalLogQueryLimit = &cli.IntFlag{ + Name: "rpc.logquerylimit", + Usage: "Maximum number of alternative addresses or topics allowed per search position in eth_getLogs filter criteria (0 = no cap)", + Value: ethconfig.Defaults.LogQueryLimit, + Category: flags.APICategory, + } + RPCTxSyncDefaultTimeoutFlag = &cli.DurationFlag{ + Name: "rpc.txsync.defaulttimeout", + Usage: "Default timeout for eth_sendRawTransactionSync (e.g. 2s, 500ms)", + Value: ethconfig.Defaults.TxSyncDefaultTimeout, + Category: flags.APICategory, + } + RPCTxSyncMaxTimeoutFlag = &cli.DurationFlag{ + Name: "rpc.txsync.maxtimeout", + Usage: "Maximum allowed timeout for eth_sendRawTransactionSync (e.g. 5m)", + Value: ethconfig.Defaults.TxSyncMaxTimeout, + Category: flags.APICategory, + } + RPCGlobalRangeLimitFlag = &cli.Uint64Flag{ + Name: "rpc.rangelimit", + Usage: "Maximum block range (end - begin) allowed for range queries (0 = unlimited)", + Value: ethconfig.Defaults.RangeLimit, + Category: flags.APICategory, + } // Authenticated RPC HTTP settings AuthListenFlag = &cli.StringFlag{ Name: "authrpc.addr", @@ -620,6 +690,12 @@ var ( Usage: "Disables db compaction after import", Category: flags.LoggingCategory, } + LogSlowBlockFlag = &cli.DurationFlag{ + Name: "debug.logslowblock", + Usage: "Block execution time threshold beyond which detailed statistics will be logged (0 means disable)", + Value: ethconfig.Defaults.SlowBlockThreshold, + Category: flags.LoggingCategory, + } // MISC settings SyncTargetFlag = &cli.StringFlag{ @@ -812,14 +888,14 @@ var ( Aliases: []string{"discv4"}, Usage: "Enables the V4 discovery mechanism", Category: flags.NetworkingCategory, - Value: true, + Value: node.DefaultConfig.P2P.DiscoveryV4, } DiscoveryV5Flag = &cli.BoolFlag{ Name: "discovery.v5", Aliases: []string{"discv5"}, Usage: "Enables the V5 discovery mechanism", Category: flags.NetworkingCategory, - Value: true, + Value: node.DefaultConfig.P2P.DiscoveryV5, } NetrestrictFlag = &cli.StringFlag{ Name: "netrestrict", @@ -1293,15 +1369,10 @@ func setEtherbase(ctx *cli.Context, cfg *ethconfig.Config) { return } addr := ctx.String(MinerPendingFeeRecipientFlag.Name) - if strings.HasPrefix(addr, "0x") || strings.HasPrefix(addr, "0X") { - addr = addr[2:] - } - b, err := hex.DecodeString(addr) - if err != nil || len(b) != common.AddressLength { + if !common.IsHexAddress(addr) { Fatalf("-%s: invalid pending block producer address %q", MinerPendingFeeRecipientFlag.Name, addr) - return } - cfg.Miner.PendingFeeRecipient = common.BytesToAddress(b) + cfg.Miner.PendingFeeRecipient = common.HexToAddress(addr) } func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { @@ -1321,13 +1392,17 @@ func SetP2PConfig(ctx *cli.Context, cfg *p2p.Config) { cfg.MaxPendingPeers = ctx.Int(MaxPendingPeersFlag.Name) } if ctx.IsSet(NoDiscoverFlag.Name) { - cfg.NoDiscovery = true + cfg.NoDiscovery = ctx.Bool(NoDiscoverFlag.Name) } flags.CheckExclusive(ctx, DiscoveryV4Flag, NoDiscoverFlag) flags.CheckExclusive(ctx, DiscoveryV5Flag, NoDiscoverFlag) - cfg.DiscoveryV4 = ctx.Bool(DiscoveryV4Flag.Name) - cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name) + if ctx.IsSet(DiscoveryV4Flag.Name) { + cfg.DiscoveryV4 = ctx.Bool(DiscoveryV4Flag.Name) + } + if ctx.IsSet(DiscoveryV5Flag.Name) { + cfg.DiscoveryV5 = ctx.Bool(DiscoveryV5Flag.Name) + } if netrestrict := ctx.String(NetrestrictFlag.Name); netrestrict != "" { list, err := netutil.ParseNetlist(netrestrict) @@ -1373,7 +1448,7 @@ func SetNodeConfig(ctx *cli.Context, cfg *node.Config) { cfg.KeyStoreDir = ctx.String(KeyStoreDirFlag.Name) } if ctx.IsSet(DeveloperFlag.Name) { - cfg.UseLightweightKDF = true + cfg.UseLightweightKDF = ctx.Bool(DeveloperFlag.Name) } if ctx.IsSet(LightKDFFlag.Name) { cfg.UseLightweightKDF = ctx.Bool(LightKDFFlag.Name) @@ -1529,6 +1604,9 @@ func setMiner(ctx *cli.Context, cfg *miner.Config) { log.Warn("The flag --miner.newpayload-timeout is deprecated and will be removed, please use --miner.recommit") cfg.Recommit = ctx.Duration(MinerNewPayloadTimeoutFlag.Name) } + if ctx.IsSet(MinerMaxBlobsFlag.Name) { + cfg.MaxBlobsPerBlock = ctx.Int(MinerMaxBlobsFlag.Name) + } } func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) { @@ -1561,8 +1639,8 @@ func setRequiredBlocks(ctx *cli.Context, cfg *ethconfig.Config) { // SetEthConfig applies eth-related command line flags to the config. func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { - // Avoid conflicting network flags, don't allow network id override on preset networks - flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag, HoodiFlag, NetworkIdFlag) + // Avoid conflicting network flags + flags.CheckExclusive(ctx, MainnetFlag, DeveloperFlag, SepoliaFlag, HoleskyFlag, HoodiFlag, OverrideGenesisFlag) flags.CheckExclusive(ctx, DeveloperFlag, ExternalSignerFlag) // Can't use both ephemeral unlocked and external signer // Set configurations from CLI flags @@ -1588,7 +1666,7 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } // Ensure Go's GC ignores the database cache for trigger percentage cache := ctx.Int(CacheFlag.Name) - gogc := math.Max(20, math.Min(100, 100/(float64(cache)/1024))) + gogc := max(20, min(100, 100/(float64(cache)/1024))) log.Debug("Sanitizing Go's GC trigger", "percent", int(gogc)) godebug.SetGCPercent(int(gogc)) @@ -1609,9 +1687,6 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { } } - if ctx.IsSet(NetworkIdFlag.Name) { - cfg.NetworkId = ctx.Uint64(NetworkIdFlag.Name) - } if ctx.IsSet(CacheFlag.Name) || ctx.IsSet(CacheDatabaseFlag.Name) { cfg.DatabaseCache = ctx.Int(CacheFlag.Name) * ctx.Int(CacheDatabaseFlag.Name) / 100 } @@ -1632,8 +1707,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.IsSet(CacheNoPrefetchFlag.Name) { cfg.NoPrefetch = ctx.Bool(CacheNoPrefetchFlag.Name) } - // Read the value from the flag no matter if it's set or not. - cfg.Preimages = ctx.Bool(CachePreimagesFlag.Name) + if ctx.IsSet(CachePreimagesFlag.Name) { + cfg.Preimages = ctx.Bool(CachePreimagesFlag.Name) + } if cfg.NoPruning && !cfg.Preimages { cfg.Preimages = true log.Info("Enabling recording of key preimages since archive mode is used") @@ -1641,6 +1717,12 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.IsSet(StateHistoryFlag.Name) { cfg.StateHistory = ctx.Uint64(StateHistoryFlag.Name) } + if ctx.IsSet(TrienodeHistoryFlag.Name) { + cfg.TrienodeHistory = ctx.Int64(TrienodeHistoryFlag.Name) + } + if ctx.IsSet(TrienodeHistoryFullValueCheckpointFlag.Name) { + cfg.NodeFullValueCheckpoint = uint32(ctx.Uint(TrienodeHistoryFullValueCheckpointFlag.Name)) + } if ctx.IsSet(StateSchemeFlag.Name) { cfg.StateScheme = ctx.String(StateSchemeFlag.Name) } @@ -1666,7 +1748,10 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { cfg.LogHistory = ctx.Uint64(LogHistoryFlag.Name) } if ctx.IsSet(LogNoHistoryFlag.Name) { - cfg.LogNoHistory = true + cfg.LogNoHistory = ctx.Bool(LogNoHistoryFlag.Name) + } + if ctx.IsSet(LogSlowBlockFlag.Name) { + cfg.SlowBlockThreshold = ctx.Duration(LogSlowBlockFlag.Name) } if ctx.IsSet(LogExportCheckpointsFlag.Name) { cfg.LogExportCheckpoints = ctx.String(LogExportCheckpointsFlag.Name) @@ -1683,6 +1768,18 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.IsSet(CacheLogSizeFlag.Name) { cfg.FilterLogCacheSize = ctx.Int(CacheLogSizeFlag.Name) } + if ctx.IsSet(RPCGlobalLogQueryLimit.Name) { + cfg.LogQueryLimit = ctx.Int(RPCGlobalLogQueryLimit.Name) + } + if ctx.IsSet(RPCTxSyncDefaultTimeoutFlag.Name) { + cfg.TxSyncDefaultTimeout = ctx.Duration(RPCTxSyncDefaultTimeoutFlag.Name) + } + if ctx.IsSet(RPCTxSyncMaxTimeoutFlag.Name) { + cfg.TxSyncMaxTimeout = ctx.Duration(RPCTxSyncMaxTimeoutFlag.Name) + } + if ctx.IsSet(RPCGlobalRangeLimitFlag.Name) { + cfg.RangeLimit = ctx.Uint64(RPCGlobalRangeLimitFlag.Name) + } if !ctx.Bool(SnapshotFlag.Name) || cfg.SnapshotCache == 0 { // If snap-sync is requested, this flag is also required if cfg.SyncMode == ethconfig.SnapSync { @@ -1701,6 +1798,16 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if ctx.IsSet(VMEnableDebugFlag.Name) { cfg.EnablePreimageRecording = ctx.Bool(VMEnableDebugFlag.Name) } + if ctx.IsSet(VMWitnessStatsFlag.Name) { + cfg.EnableWitnessStats = ctx.Bool(VMWitnessStatsFlag.Name) + } + if ctx.IsSet(VMStatelessSelfValidationFlag.Name) { + cfg.StatelessSelfValidation = ctx.Bool(VMStatelessSelfValidationFlag.Name) + } + // Auto-enable StatelessSelfValidation when witness stats are enabled + if ctx.Bool(VMWitnessStatsFlag.Name) { + cfg.StatelessSelfValidation = true + } if ctx.IsSet(RPCGlobalGasCapFlag.Name) { cfg.RPCGasCap = ctx.Uint64(RPCGlobalGasCapFlag.Name) @@ -1726,6 +1833,9 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { cfg.EthDiscoveryURLs = SplitAndTrim(urls) } } + if ctx.Bool(StateSizeTrackingFlag.Name) { + cfg.EnableStateSizeTracking = true + } // Override any default configs for hard coded networks. switch { case ctx.Bool(MainnetFlag.Name): @@ -1826,11 +1936,31 @@ func SetEthConfig(ctx *cli.Context, stack *node.Node, cfg *ethconfig.Config) { if !ctx.IsSet(MinerGasPriceFlag.Name) { cfg.Miner.GasPrice = big.NewInt(1) } + case ctx.String(OverrideGenesisFlag.Name) != "": + f, err := os.Open(ctx.String(OverrideGenesisFlag.Name)) + if err != nil { + Fatalf("Failed to read genesis file: %v", err) + } + defer f.Close() + + genesis := new(core.Genesis) + if err := json.NewDecoder(f).Decode(genesis); err != nil { + Fatalf("Invalid genesis file: %v", err) + } + cfg.Genesis = genesis default: - if cfg.NetworkId == 1 { + if ctx.Uint64(NetworkIdFlag.Name) == 1 { SetDNSDiscoveryDefaults(cfg, params.MainnetGenesisHash) } } + if ctx.IsSet(NetworkIdFlag.Name) { + // Typically it's best to automatically set the network ID to the chainID, + // by not passing the --networkid flag at all. Emit a warning when set + // explicitly in case overriding the network ID is not the user's intention. + id := ctx.Uint64(NetworkIdFlag.Name) + log.Warn("Setting network ID with command-line flag", "id", id) + cfg.NetworkId = id + } // Set any dangling config values if ctx.String(CryptoKZGFlag.Name) != "gokzg" && ctx.String(CryptoKZGFlag.Name) != "ckzg" { Fatalf("--%s flag must be 'gokzg' or 'ckzg'", CryptoKZGFlag.Name) @@ -1893,11 +2023,15 @@ func MakeBeaconLightConfig(ctx *cli.Context) bparams.ClientConfig { } else { Fatalf("Could not parse --%s: %v", BeaconGenesisRootFlag.Name, err) } - configFile := ctx.String(BeaconConfigFlag.Name) - if err := config.ChainConfig.LoadForks(configFile); err != nil { - Fatalf("Could not load beacon chain config '%s': %v", configFile, err) + configPath := ctx.String(BeaconConfigFlag.Name) + file, err := os.ReadFile(configPath) + if err != nil { + Fatalf("failed to read beacon chain config file '%s': %v", configPath, err) } - log.Info("Using custom beacon chain config", "file", configFile) + if err := config.ChainConfig.LoadForks(file); err != nil { + Fatalf("Could not load beacon chain config '%s': %v", configPath, err) + } + log.Info("Using custom beacon chain config", "file", configPath) } else { if ctx.IsSet(BeaconGenesisRootFlag.Name) { Fatalf("Genesis root is specified but custom beacon chain config is missing") @@ -1988,7 +2122,9 @@ func RegisterGraphQLService(stack *node.Node, backend ethapi.Backend, filterSyst // RegisterFilterAPI adds the eth log filtering RPC API to the node. func RegisterFilterAPI(stack *node.Node, backend ethapi.Backend, ethcfg *ethconfig.Config) *filters.FilterSystem { filterSystem := filters.NewFilterSystem(backend, filters.Config{ - LogCacheSize: ethcfg.FilterLogCacheSize, + LogCacheSize: ethcfg.FilterLogCacheSize, + LogQueryLimit: ethcfg.LogQueryLimit, + RangeLimit: ethcfg.RangeLimit, }) stack.RegisterAPIs([]rpc.API{{ Namespace: "eth", @@ -2191,15 +2327,18 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh Fatalf("%v", err) } options := &core.BlockChainConfig{ - TrieCleanLimit: ethconfig.Defaults.TrieCleanCache, - NoPrefetch: ctx.Bool(CacheNoPrefetchFlag.Name), - TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache, - ArchiveMode: ctx.String(GCModeFlag.Name) == "archive", - TrieTimeLimit: ethconfig.Defaults.TrieTimeout, - SnapshotLimit: ethconfig.Defaults.SnapshotCache, - Preimages: ctx.Bool(CachePreimagesFlag.Name), - StateScheme: scheme, - StateHistory: ctx.Uint64(StateHistoryFlag.Name), + TrieCleanLimit: ethconfig.Defaults.TrieCleanCache, + NoPrefetch: ctx.Bool(CacheNoPrefetchFlag.Name), + TrieDirtyLimit: ethconfig.Defaults.TrieDirtyCache, + ArchiveMode: ctx.String(GCModeFlag.Name) == "archive", + TrieTimeLimit: ethconfig.Defaults.TrieTimeout, + SnapshotLimit: ethconfig.Defaults.SnapshotCache, + Preimages: ctx.Bool(CachePreimagesFlag.Name), + StateScheme: scheme, + StateHistory: ctx.Uint64(StateHistoryFlag.Name), + TrienodeHistory: ctx.Int64(TrienodeHistoryFlag.Name), + NodeFullValueCheckpoint: uint32(ctx.Uint(TrienodeHistoryFullValueCheckpointFlag.Name)), + // Disable transaction indexing/unindexing. TxLookupLimit: -1, @@ -2208,6 +2347,12 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh // - DATADIR/triedb/merkle.journal // - DATADIR/triedb/verkle.journal TrieJournalDirectory: stack.ResolvePath("triedb"), + + // Enable state size tracking if enabled + StateSizeTracking: ctx.Bool(StateSizeTrackingFlag.Name), + + // Configure the slow block statistic logger + SlowBlockThreshold: ctx.Duration(LogSlowBlockFlag.Name), } if options.ArchiveMode && !options.Preimages { options.Preimages = true @@ -2231,6 +2376,8 @@ func MakeChain(ctx *cli.Context, stack *node.Node, readonly bool) (*core.BlockCh } vmcfg := vm.Config{ EnablePreimageRecording: ctx.Bool(VMEnableDebugFlag.Name), + EnableWitnessStats: ctx.Bool(VMWitnessStatsFlag.Name), + StatelessSelfValidation: ctx.Bool(VMStatelessSelfValidationFlag.Name) || ctx.Bool(VMWitnessStatsFlag.Name), } if ctx.IsSet(VMTraceFlag.Name) { if name := ctx.String(VMTraceFlag.Name); name != "" { @@ -2269,7 +2416,7 @@ func MakeConsolePreloads(ctx *cli.Context) []string { } // MakeTrieDatabase constructs a trie database based on the configured scheme. -func MakeTrieDatabase(ctx *cli.Context, disk ethdb.Database, preimage bool, readOnly bool, isVerkle bool) *triedb.Database { +func MakeTrieDatabase(ctx *cli.Context, stack *node.Node, disk ethdb.Database, preimage bool, readOnly bool, isVerkle bool) *triedb.Database { config := &triedb.Config{ Preimages: preimage, IsVerkle: isVerkle, @@ -2285,10 +2432,13 @@ func MakeTrieDatabase(ctx *cli.Context, disk ethdb.Database, preimage bool, read config.HashDB = hashdb.Defaults return triedb.NewDatabase(disk, config) } + var pathConfig pathdb.Config if readOnly { - config.PathDB = pathdb.ReadOnly + pathConfig = *pathdb.ReadOnly } else { - config.PathDB = pathdb.Defaults + pathConfig = *pathdb.Defaults } + pathConfig.JournalDirectory = stack.ResolvePath("triedb") + config.PathDB = &pathConfig return triedb.NewDatabase(disk, config) } diff --git a/cmd/workload/README.md b/cmd/workload/README.md index 1b84dd05db..ee1d6acbc9 100644 --- a/cmd/workload/README.md +++ b/cmd/workload/README.md @@ -34,4 +34,5 @@ the following commands (in this directory) against a synced mainnet node: > go run . filtergen --queries queries/filter_queries_mainnet.json http://host:8545 > go run . historygen --history-tests queries/history_mainnet.json http://host:8545 > go run . tracegen --trace-tests queries/trace_mainnet.json --trace-start 4000000 --trace-end 4000100 http://host:8545 +> go run . proofgen --proof-tests queries/proof_mainnet.json --proof-states 3000 http://host:8545 ``` diff --git a/cmd/workload/filtertest.go b/cmd/workload/filtertest.go index 11062122b8..d77cbc5768 100644 --- a/cmd/workload/filtertest.go +++ b/cmd/workload/filtertest.go @@ -92,7 +92,7 @@ func (s *filterTestSuite) filterShortRange(t *utesting.T) { }, s.queryAndCheck) } -// filterShortRange runs all long-range filter tests. +// filterLongRange runs all long-range filter tests. func (s *filterTestSuite) filterLongRange(t *utesting.T) { s.filterRange(t, func(query *filterQuery) bool { return query.ToBlock+1-query.FromBlock > filterRangeThreshold @@ -182,13 +182,14 @@ func (s *filterTestSuite) loadQueries() error { // filterQuery is a single query for testing. type filterQuery struct { - FromBlock int64 `json:"fromBlock"` - ToBlock int64 `json:"toBlock"` - Address []common.Address `json:"address"` - Topics [][]common.Hash `json:"topics"` - ResultHash *common.Hash `json:"resultHash,omitempty"` - results []types.Log - Err error `json:"error,omitempty"` + FromBlock int64 `json:"fromBlock"` + ToBlock int64 `json:"toBlock"` + lastBlockHash common.Hash + Address []common.Address `json:"address"` + Topics [][]common.Hash `json:"topics"` + ResultHash *common.Hash `json:"resultHash,omitempty"` + results []types.Log + Err error `json:"error,omitempty"` } func (fq *filterQuery) isWildcard() bool { diff --git a/cmd/workload/filtertestfuzz.go b/cmd/workload/filtertestfuzz.go new file mode 100644 index 0000000000..3549f4db56 --- /dev/null +++ b/cmd/workload/filtertestfuzz.go @@ -0,0 +1,337 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "context" + "fmt" + "math/big" + "reflect" + "slices" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/lru" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rpc" + "github.com/urfave/cli/v2" +) + +const maxFilterRangeForTestFuzz = 300 + +var ( + filterFuzzCommand = &cli.Command{ + Name: "filterfuzz", + Usage: "Generates queries and compares results against matches derived from receipts", + ArgsUsage: "", + Action: filterFuzzCmd, + Flags: []cli.Flag{}, + } +) + +// filterFuzzCmd is the main function of the filter fuzzer. +func filterFuzzCmd(ctx *cli.Context) error { + f := newFilterTestGen(ctx, maxFilterRangeForTestFuzz) + var lastHead *types.Header + headerCache := lru.NewCache[common.Hash, *types.Header](200) + + commonAncestor := func(oldPtr, newPtr *types.Header) *types.Header { + if oldPtr == nil || newPtr == nil { + return nil + } + if newPtr.Number.Uint64() > oldPtr.Number.Uint64()+100 || oldPtr.Number.Uint64() > newPtr.Number.Uint64()+100 { + return nil + } + for oldPtr.Hash() != newPtr.Hash() { + if newPtr.Number.Uint64() >= oldPtr.Number.Uint64() { + if parent, _ := headerCache.Get(newPtr.ParentHash); parent != nil { + newPtr = parent + } else { + newPtr, _ = getHeaderByHash(f.client, newPtr.ParentHash) + if newPtr == nil { + return nil + } + headerCache.Add(newPtr.Hash(), newPtr) + } + } + if oldPtr.Number.Uint64() > newPtr.Number.Uint64() { + oldPtr, _ = headerCache.Get(oldPtr.ParentHash) + if oldPtr == nil { + return nil + } + } + } + return newPtr + } + + fetchHead := func() (*types.Header, bool) { + currentHead, err := getLatestHeader(f.client) + if err != nil { + fmt.Println("Could not fetch head block", err) + return nil, false + } + headerCache.Add(currentHead.Hash(), currentHead) + if lastHead != nil && currentHead.Hash() == lastHead.Hash() { + return currentHead, false + } + f.blockLimit = currentHead.Number.Int64() + ca := commonAncestor(lastHead, currentHead) + fmt.Print("*** New head ", f.blockLimit) + if ca == nil { + fmt.Println(" ") + } else { + if reorged := lastHead.Number.Uint64() - ca.Number.Uint64(); reorged > 0 { + fmt.Print(" reorged ", reorged) + } + if missed := currentHead.Number.Uint64() - ca.Number.Uint64() - 1; missed > 0 { + fmt.Print(" missed ", missed) + } + fmt.Println() + } + lastHead = currentHead + return currentHead, true + } + + tryExtendQuery := func(query *filterQuery) *filterQuery { + for { + extQuery := f.extendRange(query) + if extQuery == nil { + return query + } + extQuery.checkLastBlockHash(f.client) + extQuery.run(f.client, nil) + if extQuery.Err == nil && len(extQuery.results) == 0 { + // query is useless now due to major reorg; abandon and continue + fmt.Println("Zero length results") + return nil + } + if extQuery.Err != nil { + extQuery.printError() + return nil + } + if len(extQuery.results) > maxFilterResultSize { + return query + } + query = extQuery + } + } + + var ( + mmQuery *filterQuery + mmRetry, mmNextRetry int + ) + +mainLoop: + for { + select { + case <-ctx.Done(): + return nil + default: + } + var query *filterQuery + if mmQuery != nil { + if mmRetry == 0 { + query = mmQuery + mmRetry = mmNextRetry + mmNextRetry *= 2 + query.checkLastBlockHash(f.client) + query.run(f.client, nil) + if query.Err != nil { + query.printError() + continue + } + fmt.Println("Retrying query from:", query.FromBlock, "to:", query.ToBlock, "results:", len(query.results)) + } else { + mmRetry-- + } + } + if query == nil { + currentHead, isNewHead := fetchHead() + if currentHead == nil { + select { + case <-ctx.Done(): + return nil + case <-time.After(time.Second): + } + continue mainLoop + } + if isNewHead { + query = f.newHeadSeedQuery(currentHead.Number.Int64()) + } else { + query = f.newQuery() + } + query.checkLastBlockHash(f.client) + query.run(f.client, nil) + if query.Err != nil { + query.printError() + continue + } + fmt.Println("New query from:", query.FromBlock, "to:", query.ToBlock, "results:", len(query.results)) + if len(query.results) == 0 || len(query.results) > maxFilterResultSize { + continue mainLoop + } + if query = tryExtendQuery(query); query == nil { + continue mainLoop + } + } + if !query.checkLastBlockHash(f.client) { + fmt.Println("Reorg during search") + continue mainLoop + } + // now we have a new query; check results + results, err := query.getResultsFromReceipts(f.client) + if err != nil { + fmt.Println("Could not fetch results from receipts", err) + continue mainLoop + } + if !query.checkLastBlockHash(f.client) { + fmt.Println("Reorg during search") + continue mainLoop + } + if !reflect.DeepEqual(query.results, results) { + fmt.Println("Results mismatch from:", query.FromBlock, "to:", query.ToBlock, "addresses:", query.Address, "topics:", query.Topics) + resShared, resGetLogs, resReceipts := compareResults(query.results, results) + fmt.Println(" shared:", len(resShared)) + fmt.Println(" only from getLogs:", len(resGetLogs), resGetLogs) + fmt.Println(" only from receipts:", len(resReceipts), resReceipts) + if mmQuery != query { + mmQuery = query + mmRetry = 0 + mmNextRetry = 1 + } + continue mainLoop + } + fmt.Println("Successful query from:", query.FromBlock, "to:", query.ToBlock, "results:", len(query.results)) + f.storeQuery(query) + } +} + +func compareResults(a, b []types.Log) (shared, onlya, onlyb []types.Log) { + for len(a) > 0 && len(b) > 0 { + if reflect.DeepEqual(a[0], b[0]) { + shared = append(shared, a[0]) + a = a[1:] + b = b[1:] + } else { + for i := 1; ; i++ { + if i >= len(a) { // b[0] not found in a + onlyb = append(onlyb, b[0]) + b = b[1:] + break + } + if i >= len(b) { // a[0] not found in b + onlya = append(onlya, a[0]) + a = a[1:] + break + } + if reflect.DeepEqual(b[0], a[i]) { // a[:i] not found in b + onlya = append(onlya, a[:i]...) + a = a[i:] + break + } + if reflect.DeepEqual(a[0], b[i]) { // b[:i] not found in a + onlyb = append(onlyb, b[:i]...) + b = b[i:] + break + } + } + } + } + onlya = append(onlya, a...) + onlyb = append(onlyb, b...) + return +} + +func getLatestHeader(client *client) (*types.Header, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + return client.Eth.HeaderByNumber(ctx, big.NewInt(int64(rpc.LatestBlockNumber))) +} + +func getHeaderByHash(client *client, hash common.Hash) (*types.Header, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) + defer cancel() + + return client.Eth.HeaderByHash(ctx, hash) +} + +// newHeadSeedQuery creates a query that gets all logs from the latest head. +func (s *filterTestGen) newHeadSeedQuery(head int64) *filterQuery { + return &filterQuery{ + FromBlock: head, + ToBlock: head, + } +} + +func (fq *filterQuery) checkLastBlockHash(client *client) bool { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + + header, err := client.Eth.HeaderByNumber(ctx, big.NewInt(fq.ToBlock)) + if err != nil { + fmt.Println("Cound not fetch last block hash of query number:", fq.ToBlock, "error:", err) + fq.lastBlockHash = common.Hash{} + return false + } + hash := header.Hash() + if fq.lastBlockHash == hash { + return true + } + fq.lastBlockHash = hash + return false +} + +func (fq *filterQuery) filterLog(log *types.Log) bool { + if len(fq.Address) > 0 && !slices.Contains(fq.Address, log.Address) { + return false + } + // If the to filtered topics is greater than the amount of topics in logs, skip. + if len(fq.Topics) > len(log.Topics) { + return false + } + for i, sub := range fq.Topics { + if len(sub) == 0 { + continue // empty rule set == wildcard + } + if !slices.Contains(sub, log.Topics[i]) { + return false + } + } + return true +} + +func (fq *filterQuery) getResultsFromReceipts(client *client) ([]types.Log, error) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*30) + defer cancel() + + var results []types.Log + for blockNumber := fq.FromBlock; blockNumber <= fq.ToBlock; blockNumber++ { + receipts, err := client.Eth.BlockReceipts(ctx, rpc.BlockNumberOrHashWithNumber(rpc.BlockNumber(blockNumber))) + if err != nil { + return nil, err + } + for _, receipt := range receipts { + for _, log := range receipt.Logs { + if fq.filterLog(log) { + results = append(results, *log) + } + } + } + } + return results, nil +} diff --git a/cmd/workload/filtertestgen.go b/cmd/workload/filtertestgen.go index 6d1f639819..603e3dea67 100644 --- a/cmd/workload/filtertestgen.go +++ b/cmd/workload/filtertestgen.go @@ -32,6 +32,17 @@ import ( "github.com/urfave/cli/v2" ) +const ( + // Parameter of the random filter query generator. + maxFilterRangeForTestGen = 100000000000 + maxFilterResultSize = 1000 + filterBuckets = 10 + maxFilterBucketSize = 100 + filterSeedChance = 10 + filterMergeChance = 45 + filterExtendChance = 50 +) + var ( filterGenerateCommand = &cli.Command{ Name: "filtergen", @@ -58,7 +69,7 @@ var ( // filterGenCmd is the main function of the filter tests generator. func filterGenCmd(ctx *cli.Context) error { - f := newFilterTestGen(ctx) + f := newFilterTestGen(ctx, maxFilterRangeForTestGen) lastWrite := time.Now() for { select { @@ -67,7 +78,7 @@ func filterGenCmd(ctx *cli.Context) error { default: } - f.updateFinalizedBlock() + f.setLimitToFinalizedBlock() query := f.newQuery() query.run(f.client, nil) if query.Err != nil { @@ -75,7 +86,7 @@ func filterGenCmd(ctx *cli.Context) error { exit("filter query failed") } if len(query.results) > 0 && len(query.results) <= maxFilterResultSize { - for { + for rand.Intn(100) < filterExtendChance { extQuery := f.extendRange(query) if extQuery == nil { break @@ -108,39 +119,32 @@ func filterGenCmd(ctx *cli.Context) error { // filterTestGen is the filter query test generator. type filterTestGen struct { - client *client - queryFile string + client *client + queryFile string + maxFilterRange int64 - finalizedBlock int64 - queries [filterBuckets][]*filterQuery + blockLimit int64 + queries [filterBuckets][]*filterQuery } -func newFilterTestGen(ctx *cli.Context) *filterTestGen { +func newFilterTestGen(ctx *cli.Context, maxFilterRange int64) *filterTestGen { return &filterTestGen{ - client: makeClient(ctx), - queryFile: ctx.String(filterQueryFileFlag.Name), + client: makeClient(ctx), + queryFile: ctx.String(filterQueryFileFlag.Name), + maxFilterRange: maxFilterRange, } } -func (s *filterTestGen) updateFinalizedBlock() { - s.finalizedBlock = mustGetFinalizedBlock(s.client) +func (s *filterTestGen) setLimitToFinalizedBlock() { + s.blockLimit = mustGetFinalizedBlock(s.client) } -const ( - // Parameter of the random filter query generator. - maxFilterRange = 10000000 - maxFilterResultSize = 300 - filterBuckets = 10 - maxFilterBucketSize = 100 - filterSeedChance = 10 - filterMergeChance = 45 -) - // storeQuery adds a filter query to the output file. func (s *filterTestGen) storeQuery(query *filterQuery) { query.ResultHash = new(common.Hash) *query.ResultHash = query.calculateHash() - logRatio := math.Log(float64(len(query.results))*float64(s.finalizedBlock)/float64(query.ToBlock+1-query.FromBlock)) / math.Log(float64(s.finalizedBlock)*maxFilterResultSize) + maxFilterRange := min(s.maxFilterRange, s.blockLimit) + logRatio := math.Log(float64(len(query.results))*float64(maxFilterRange)/float64(query.ToBlock+1-query.FromBlock)) / math.Log(float64(maxFilterRange)*maxFilterResultSize) bucket := int(math.Floor(logRatio * filterBuckets)) if bucket >= filterBuckets { bucket = filterBuckets - 1 @@ -160,13 +164,13 @@ func (s *filterTestGen) storeQuery(query *filterQuery) { func (s *filterTestGen) extendRange(q *filterQuery) *filterQuery { rangeLen := q.ToBlock + 1 - q.FromBlock extLen := rand.Int63n(rangeLen) + 1 - if rangeLen+extLen > s.finalizedBlock { + if rangeLen+extLen > min(s.maxFilterRange, s.blockLimit) { return nil } extBefore := min(rand.Int63n(extLen+1), q.FromBlock) extAfter := extLen - extBefore - if q.ToBlock+extAfter > s.finalizedBlock { - d := q.ToBlock + extAfter - s.finalizedBlock + if q.ToBlock+extAfter > s.blockLimit { + d := q.ToBlock + extAfter - s.blockLimit extAfter -= d if extBefore+d <= q.FromBlock { extBefore += d @@ -203,7 +207,7 @@ func (s *filterTestGen) newQuery() *filterQuery { // newSeedQuery creates a query that gets all logs in a random non-finalized block. func (s *filterTestGen) newSeedQuery() *filterQuery { - block := rand.Int63n(s.finalizedBlock + 1) + block := rand.Int63n(s.blockLimit + 1) return &filterQuery{ FromBlock: block, ToBlock: block, @@ -358,6 +362,7 @@ func (s *filterTestGen) writeQueries() { func mustGetFinalizedBlock(client *client) int64 { ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) defer cancel() + header, err := client.Eth.HeaderByNumber(ctx, big.NewInt(int64(rpc.FinalizedBlockNumber))) if err != nil { exit(fmt.Errorf("could not fetch finalized header (error: %v)", err)) diff --git a/cmd/workload/filtertestperf.go b/cmd/workload/filtertestperf.go index c7d2fdd02a..d4f1a155f1 100644 --- a/cmd/workload/filtertestperf.go +++ b/cmd/workload/filtertestperf.go @@ -152,7 +152,7 @@ func (st *bucketStats) print(name string) { name, st.count, float64(st.blocks)/float64(st.count), float64(st.logs)/float64(st.count), st.runtime/time.Duration(st.count)) } -// writeQueries serializes the generated errors to the error file. +// writeErrors serializes the generated errors to the error file. func writeErrors(errorFile string, errors []*filterQuery) { file, err := os.Create(errorFile) if err != nil { diff --git a/cmd/workload/main.go b/cmd/workload/main.go index 32618d6a79..4ee894e962 100644 --- a/cmd/workload/main.go +++ b/cmd/workload/main.go @@ -48,7 +48,9 @@ func init() { historyGenerateCommand, filterGenerateCommand, traceGenerateCommand, + proofGenerateCommand, filterPerfCommand, + filterFuzzCommand, } } diff --git a/cmd/workload/prooftest.go b/cmd/workload/prooftest.go new file mode 100644 index 0000000000..dcc063d30e --- /dev/null +++ b/cmd/workload/prooftest.go @@ -0,0 +1,105 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see . + +package main + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "os" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/utesting" + "github.com/urfave/cli/v2" +) + +// proofTest is the content of a state-proof test. +type proofTest struct { + BlockNumbers []uint64 `json:"blockNumbers"` + Addresses [][]common.Address `json:"addresses"` + StorageKeys [][][]string `json:"storageKeys"` + Results [][]common.Hash `json:"results"` +} + +type proofTestSuite struct { + cfg testConfig + tests proofTest + invalidDir string +} + +func newProofTestSuite(cfg testConfig, ctx *cli.Context) *proofTestSuite { + s := &proofTestSuite{ + cfg: cfg, + invalidDir: ctx.String(proofTestInvalidOutputFlag.Name), + } + if err := s.loadTests(); err != nil { + exit(err) + } + return s +} + +func (s *proofTestSuite) loadTests() error { + file, err := s.cfg.fsys.Open(s.cfg.proofTestFile) + if err != nil { + // If not found in embedded FS, try to load it from disk + if !os.IsNotExist(err) { + return err + } + file, err = os.OpenFile(s.cfg.proofTestFile, os.O_RDONLY, 0666) + if err != nil { + return fmt.Errorf("can't open proofTestFile: %v", err) + } + } + defer file.Close() + if err := json.NewDecoder(file).Decode(&s.tests); err != nil { + return fmt.Errorf("invalid JSON in %s: %v", s.cfg.proofTestFile, err) + } + if len(s.tests.BlockNumbers) == 0 { + return fmt.Errorf("proofTestFile %s has no test data", s.cfg.proofTestFile) + } + return nil +} + +func (s *proofTestSuite) allTests() []workloadTest { + return []workloadTest{ + newArchiveWorkloadTest("Proof/GetProof", s.getProof), + } +} + +func (s *proofTestSuite) getProof(t *utesting.T) { + ctx := context.Background() + for i, blockNumber := range s.tests.BlockNumbers { + for j := 0; j < len(s.tests.Addresses[i]); j++ { + res, err := s.cfg.client.Geth.GetProof(ctx, s.tests.Addresses[i][j], s.tests.StorageKeys[i][j], big.NewInt(int64(blockNumber))) + if err != nil { + t.Errorf("State proving fails, blockNumber: %d, address: %x, keys: %v, err: %v\n", blockNumber, s.tests.Addresses[i][j], strings.Join(s.tests.StorageKeys[i][j], " "), err) + continue + } + blob, err := json.Marshal(res) + if err != nil { + t.Fatalf("State proving fails: error %v", err) + continue + } + if crypto.Keccak256Hash(blob) != s.tests.Results[i][j] { + t.Errorf("State proof mismatch, %d, number: %d, address: %x, keys: %v: invalid result", i, blockNumber, s.tests.Addresses[i][j], strings.Join(s.tests.StorageKeys[i][j], " ")) + } + } + } +} diff --git a/cmd/workload/prooftestgen.go b/cmd/workload/prooftestgen.go new file mode 100644 index 0000000000..5d92eea114 --- /dev/null +++ b/cmd/workload/prooftestgen.go @@ -0,0 +1,355 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of go-ethereum. +// +// go-ethereum is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// go-ethereum is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with go-ethereum. If not, see + +package main + +import ( + "context" + "encoding/json" + "fmt" + "math/big" + "math/rand" + "os" + "path/filepath" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/eth/tracers/native" + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/internal/testrand" + "github.com/ethereum/go-ethereum/log" + "github.com/urfave/cli/v2" +) + +var ( + proofGenerateCommand = &cli.Command{ + Name: "proofgen", + Usage: "Generates tests for state proof verification", + ArgsUsage: "", + Action: generateProofTests, + Flags: []cli.Flag{ + proofTestFileFlag, + proofTestResultOutputFlag, + proofTestStatesFlag, + proofTestStartBlockFlag, + proofTestEndBlockFlag, + }, + } + + proofTestFileFlag = &cli.StringFlag{ + Name: "proof-tests", + Usage: "JSON file containing proof test queries", + Value: "proof_tests.json", + Category: flags.TestingCategory, + } + proofTestResultOutputFlag = &cli.StringFlag{ + Name: "proof-output", + Usage: "Folder containing detailed trace output files", + Value: "", + Category: flags.TestingCategory, + } + proofTestStatesFlag = &cli.Int64Flag{ + Name: "proof-states", + Usage: "Number of states to generate proof against", + Value: 10000, + Category: flags.TestingCategory, + } + proofTestInvalidOutputFlag = &cli.StringFlag{ + Name: "proof-invalid", + Usage: "Folder containing the mismatched state proof output files", + Value: "", + Category: flags.TestingCategory, + } + proofTestStartBlockFlag = &cli.Uint64Flag{ + Name: "proof-start", + Usage: "The number of starting block for proof verification (included)", + Category: flags.TestingCategory, + } + proofTestEndBlockFlag = &cli.Uint64Flag{ + Name: "proof-end", + Usage: "The number of ending block for proof verification (excluded)", + Category: flags.TestingCategory, + } +) + +type proofGenerator func(cli *client, startBlock uint64, endBlock uint64, number int) ([]uint64, [][]common.Address, [][][]string, error) + +func genAccountProof(cli *client, startBlock uint64, endBlock uint64, number int) ([]uint64, [][]common.Address, [][][]string, error) { + var ( + blockNumbers []uint64 + accountAddresses [][]common.Address + storageKeys [][][]string + nAccounts int + ctx = context.Background() + start = time.Now() + ) + chainID, err := cli.Eth.ChainID(ctx) + if err != nil { + return nil, nil, nil, err + } + signer := types.LatestSignerForChainID(chainID) + + for { + if nAccounts >= number { + break + } + blockNumber := uint64(rand.Intn(int(endBlock-startBlock))) + startBlock + + block, err := cli.Eth.BlockByNumber(context.Background(), big.NewInt(int64(blockNumber))) + if err != nil { + continue + } + var ( + addresses []common.Address + keys [][]string + gather = func(address common.Address) { + addresses = append(addresses, address) + keys = append(keys, nil) + nAccounts++ + } + ) + for _, tx := range block.Transactions() { + if nAccounts >= number { + break + } + sender, err := signer.Sender(tx) + if err != nil { + log.Error("Failed to resolve the sender address", "hash", tx.Hash(), "err", err) + continue + } + gather(sender) + + if tx.To() != nil { + gather(*tx.To()) + } + } + blockNumbers = append(blockNumbers, blockNumber) + accountAddresses = append(accountAddresses, addresses) + storageKeys = append(storageKeys, keys) + } + log.Info("Generated tests for account proof", "blocks", len(blockNumbers), "accounts", nAccounts, "elapsed", common.PrettyDuration(time.Since(start))) + return blockNumbers, accountAddresses, storageKeys, nil +} + +func genNonExistentAccountProof(cli *client, startBlock uint64, endBlock uint64, number int) ([]uint64, [][]common.Address, [][][]string, error) { + var ( + blockNumbers []uint64 + accountAddresses [][]common.Address + storageKeys [][][]string + total int + ) + for i := 0; i < number/5; i++ { + var ( + addresses []common.Address + keys [][]string + blockNumber = uint64(rand.Intn(int(endBlock-startBlock))) + startBlock + ) + for j := 0; j < 5; j++ { + addresses = append(addresses, testrand.Address()) + keys = append(keys, nil) + } + total += len(addresses) + blockNumbers = append(blockNumbers, blockNumber) + accountAddresses = append(accountAddresses, addresses) + storageKeys = append(storageKeys, keys) + } + log.Info("Generated tests for non-existing account proof", "blocks", len(blockNumbers), "accounts", total) + return blockNumbers, accountAddresses, storageKeys, nil +} + +func genStorageProof(cli *client, startBlock uint64, endBlock uint64, number int) ([]uint64, [][]common.Address, [][][]string, error) { + var ( + blockNumbers []uint64 + accountAddresses [][]common.Address + storageKeys [][][]string + + nAccounts int + nStorages int + start = time.Now() + ) + for { + if nAccounts+nStorages >= number { + break + } + blockNumber := uint64(rand.Intn(int(endBlock-startBlock))) + startBlock + + block, err := cli.Eth.BlockByNumber(context.Background(), big.NewInt(int64(blockNumber))) + if err != nil { + continue + } + var ( + addresses []common.Address + slots [][]string + tracer = "prestateTracer" + configBlob, _ = json.Marshal(native.PrestateTracerConfig{ + DiffMode: false, + DisableCode: true, + DisableStorage: false, + }) + ) + for _, tx := range block.Transactions() { + if nAccounts+nStorages >= number { + break + } + if tx.To() == nil { + continue + } + ret, err := cli.Geth.TraceTransaction(context.Background(), tx.Hash(), &tracers.TraceConfig{ + Tracer: &tracer, + TracerConfig: configBlob, + }) + if err != nil { + log.Error("Failed to trace the transaction", "blockNumber", blockNumber, "hash", tx.Hash(), "err", err) + continue + } + blob, err := json.Marshal(ret) + if err != nil { + log.Error("Failed to marshal data", "err", err) + continue + } + var accounts map[common.Address]*types.Account + if err := json.Unmarshal(blob, &accounts); err != nil { + log.Error("Failed to decode trace result", "blockNumber", blockNumber, "hash", tx.Hash(), "err", err) + continue + } + for addr, account := range accounts { + if len(account.Storage) == 0 { + continue + } + addresses = append(addresses, addr) + nAccounts += 1 + + var keys []string + for k := range account.Storage { + keys = append(keys, k.Hex()) + } + nStorages += len(keys) + + var emptyKeys []string + for i := 0; i < 3; i++ { + emptyKeys = append(emptyKeys, testrand.Hash().Hex()) + } + nStorages += len(emptyKeys) + + slots = append(slots, append(keys, emptyKeys...)) + } + } + blockNumbers = append(blockNumbers, blockNumber) + accountAddresses = append(accountAddresses, addresses) + storageKeys = append(storageKeys, slots) + } + log.Info("Generated tests for storage proof", "blocks", len(blockNumbers), "accounts", nAccounts, "storages", nStorages, "elapsed", common.PrettyDuration(time.Since(start))) + return blockNumbers, accountAddresses, storageKeys, nil +} + +func genProofRequests(cli *client, startBlock, endBlock uint64, states int) (*proofTest, error) { + var ( + blockNumbers []uint64 + accountAddresses [][]common.Address + storageKeys [][][]string + ) + ratio := []float64{0.2, 0.1, 0.7} + for i, fn := range []proofGenerator{genAccountProof, genNonExistentAccountProof, genStorageProof} { + numbers, addresses, keys, err := fn(cli, startBlock, endBlock, int(float64(states)*ratio[i])) + if err != nil { + return nil, err + } + blockNumbers = append(blockNumbers, numbers...) + accountAddresses = append(accountAddresses, addresses...) + storageKeys = append(storageKeys, keys...) + } + return &proofTest{ + BlockNumbers: blockNumbers, + Addresses: accountAddresses, + StorageKeys: storageKeys, + }, nil +} + +func generateProofTests(clictx *cli.Context) error { + var ( + client = makeClient(clictx) + ctx = context.Background() + states = clictx.Int(proofTestStatesFlag.Name) + outputFile = clictx.String(proofTestFileFlag.Name) + outputDir = clictx.String(proofTestResultOutputFlag.Name) + startBlock = clictx.Uint64(proofTestStartBlockFlag.Name) + endBlock = clictx.Uint64(proofTestEndBlockFlag.Name) + ) + head, err := client.Eth.BlockNumber(ctx) + if err != nil { + exit(err) + } + if startBlock > head || endBlock > head { + return fmt.Errorf("chain is out of proof range, head %d, start: %d, limit: %d", head, startBlock, endBlock) + } + if endBlock == 0 { + endBlock = head + } + log.Info("Generating proof states", "startBlock", startBlock, "endBlock", endBlock, "states", states) + + test, err := genProofRequests(client, startBlock, endBlock, states) + if err != nil { + exit(err) + } + for i, blockNumber := range test.BlockNumbers { + var hashes []common.Hash + for j := 0; j < len(test.Addresses[i]); j++ { + res, err := client.Geth.GetProof(ctx, test.Addresses[i][j], test.StorageKeys[i][j], big.NewInt(int64(blockNumber))) + if err != nil { + log.Error("Failed to prove the state", "number", blockNumber, "address", test.Addresses[i][j], "slots", len(test.StorageKeys[i][j]), "err", err) + continue + } + blob, err := json.Marshal(res) + if err != nil { + return err + } + hashes = append(hashes, crypto.Keccak256Hash(blob)) + + writeStateProof(outputDir, blockNumber, test.Addresses[i][j], res) + } + test.Results = append(test.Results, hashes) + } + writeJSON(outputFile, test) + return nil +} + +func writeStateProof(dir string, blockNumber uint64, address common.Address, result any) { + if dir == "" { + return + } + // Ensure the directory exists + if err := os.MkdirAll(dir, os.ModePerm); err != nil { + exit(fmt.Errorf("failed to create directories: %w", err)) + } + fname := fmt.Sprintf("%d-%x", blockNumber, address) + name := filepath.Join(dir, fname) + file, err := os.Create(name) + if err != nil { + exit(fmt.Errorf("error creating %s: %v", name, err)) + return + } + defer file.Close() + + data, _ := json.MarshalIndent(result, "", " ") + _, err = file.Write(data) + if err != nil { + exit(fmt.Errorf("error writing %s: %v", name, err)) + return + } +} diff --git a/cmd/workload/testsuite.go b/cmd/workload/testsuite.go index 25dc17a49e..80cbd15352 100644 --- a/cmd/workload/testsuite.go +++ b/cmd/workload/testsuite.go @@ -50,7 +50,9 @@ var ( filterQueryFileFlag, historyTestFileFlag, traceTestFileFlag, + proofTestFileFlag, traceTestInvalidOutputFlag, + proofTestInvalidOutputFlag, }, } testPatternFlag = &cli.StringFlag{ @@ -95,6 +97,7 @@ type testConfig struct { historyTestFile string historyPruneBlock *uint64 traceTestFile string + proofTestFile string } var errPrunedHistory = errors.New("attempt to access pruned history") @@ -145,6 +148,12 @@ func testConfigFromCLI(ctx *cli.Context) (cfg testConfig) { } else { cfg.traceTestFile = "queries/trace_mainnet.json" } + if ctx.IsSet(proofTestFileFlag.Name) { + cfg.proofTestFile = ctx.String(proofTestFileFlag.Name) + } else { + cfg.proofTestFile = "queries/proof_mainnet.json" + } + cfg.historyPruneBlock = new(uint64) *cfg.historyPruneBlock = history.PrunePoints[params.MainnetGenesisHash].BlockNumber case ctx.Bool(testSepoliaFlag.Name): @@ -164,6 +173,12 @@ func testConfigFromCLI(ctx *cli.Context) (cfg testConfig) { } else { cfg.traceTestFile = "queries/trace_sepolia.json" } + if ctx.IsSet(proofTestFileFlag.Name) { + cfg.proofTestFile = ctx.String(proofTestFileFlag.Name) + } else { + cfg.proofTestFile = "queries/proof_sepolia.json" + } + cfg.historyPruneBlock = new(uint64) *cfg.historyPruneBlock = history.PrunePoints[params.SepoliaGenesisHash].BlockNumber default: @@ -171,6 +186,7 @@ func testConfigFromCLI(ctx *cli.Context) (cfg testConfig) { cfg.filterQueryFile = ctx.String(filterQueryFileFlag.Name) cfg.historyTestFile = ctx.String(historyTestFileFlag.Name) cfg.traceTestFile = ctx.String(traceTestFileFlag.Name) + cfg.proofTestFile = ctx.String(proofTestFileFlag.Name) } return cfg } @@ -222,11 +238,13 @@ func runTestCmd(ctx *cli.Context) error { filterSuite := newFilterTestSuite(cfg) historySuite := newHistoryTestSuite(cfg) traceSuite := newTraceTestSuite(cfg, ctx) + proofSuite := newProofTestSuite(cfg, ctx) // Filter test cases. tests := filterSuite.allTests() tests = append(tests, historySuite.allTests()...) tests = append(tests, traceSuite.allTests()...) + tests = append(tests, proofSuite.allTests()...) utests := filterTests(tests, ctx.String(testPatternFlag.Name), func(t workloadTest) bool { if t.Slow && !ctx.Bool(testSlowFlag.Name) { diff --git a/common/bitutil/bitutil.go b/common/bitutil/bitutil.go index a18a6d18ee..578da1cf49 100644 --- a/common/bitutil/bitutil.go +++ b/common/bitutil/bitutil.go @@ -8,6 +8,7 @@ package bitutil import ( + "crypto/subtle" "runtime" "unsafe" ) @@ -17,46 +18,16 @@ const supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" | // XORBytes xors the bytes in a and b. The destination is assumed to have enough // space. Returns the number of bytes xor'd. +// +// If dst does not have length at least n, +// XORBytes panics without writing anything to dst. +// +// dst and x or y may overlap exactly or not at all, +// otherwise XORBytes may panic. +// +// Deprecated: use crypto/subtle.XORBytes func XORBytes(dst, a, b []byte) int { - if supportsUnaligned { - return fastXORBytes(dst, a, b) - } - return safeXORBytes(dst, a, b) -} - -// fastXORBytes xors in bulk. It only works on architectures that support -// unaligned read/writes. -func fastXORBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - w := n / wordSize - if w > 0 { - dw := *(*[]uintptr)(unsafe.Pointer(&dst)) - aw := *(*[]uintptr)(unsafe.Pointer(&a)) - bw := *(*[]uintptr)(unsafe.Pointer(&b)) - for i := 0; i < w; i++ { - dw[i] = aw[i] ^ bw[i] - } - } - for i := n - n%wordSize; i < n; i++ { - dst[i] = a[i] ^ b[i] - } - return n -} - -// safeXORBytes xors one by one. It works on all architectures, independent if -// it supports unaligned read/writes or not. -func safeXORBytes(dst, a, b []byte) int { - n := len(a) - if len(b) < n { - n = len(b) - } - for i := 0; i < n; i++ { - dst[i] = a[i] ^ b[i] - } - return n + return subtle.XORBytes(dst, a, b) } // ANDBytes ands the bytes in a and b. The destination is assumed to have enough diff --git a/common/bitutil/bitutil_test.go b/common/bitutil/bitutil_test.go index 12f3fe24a6..1748029794 100644 --- a/common/bitutil/bitutil_test.go +++ b/common/bitutil/bitutil_test.go @@ -29,7 +29,7 @@ func TestXOR(t *testing.T) { d2 := make([]byte, 1023+alignD)[alignD:] XORBytes(d1, p, q) - safeXORBytes(d2, p, q) + naiveXOR(d2, p, q) if !bytes.Equal(d1, d2) { t.Error("not equal", d1, d2) } @@ -38,6 +38,18 @@ func TestXOR(t *testing.T) { } } +// naiveXOR xors bytes one by one. +func naiveXOR(dst, a, b []byte) int { + n := len(a) + if len(b) < n { + n = len(b) + } + for i := 0; i < n; i++ { + dst[i] = a[i] ^ b[i] + } + return n +} + // Tests that bitwise AND works for various alignments. func TestAND(t *testing.T) { for alignP := 0; alignP < 2; alignP++ { @@ -134,7 +146,7 @@ func benchmarkBaseXOR(b *testing.B, size int) { p, q := make([]byte, size), make([]byte, size) for i := 0; i < b.N; i++ { - safeXORBytes(p, p, q) + naiveXOR(p, p, q) } } diff --git a/build/tools/tools.go b/common/eta.go similarity index 61% rename from build/tools/tools.go rename to common/eta.go index e9e2241d2f..72c838f93d 100644 --- a/build/tools/tools.go +++ b/common/eta.go @@ -1,4 +1,4 @@ -// Copyright 2019 The go-ethereum Authors +// Copyright 2025 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -14,14 +14,17 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build tools -// +build tools +package common -package tools +import "time" -import ( - // Tool imports for go:generate. - _ "github.com/fjl/gencodec" - _ "golang.org/x/tools/cmd/stringer" - _ "google.golang.org/protobuf/cmd/protoc-gen-go" -) +// CalculateETA calculates the estimated remaining time based on the +// number of finished task, remaining task, and the time cost for finished task. +func CalculateETA(done, left uint64, elapsed time.Duration) time.Duration { + if done == 0 || elapsed.Milliseconds() == 0 { + return 0 + } + + speed := float64(done) / float64(elapsed.Milliseconds()) + return time.Duration(float64(left)/speed) * time.Millisecond +} diff --git a/common/eta_test.go b/common/eta_test.go new file mode 100644 index 0000000000..b1dbb09e6c --- /dev/null +++ b/common/eta_test.go @@ -0,0 +1,60 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package common + +import ( + "testing" + "time" +) + +func TestCalculateETA(t *testing.T) { + type args struct { + done uint64 + left uint64 + elapsed time.Duration + } + tests := []struct { + name string + args args + want time.Duration + }{ + { + name: "zero done", + args: args{done: 0, left: 100, elapsed: time.Second}, + want: 0, + }, + { + name: "zero elapsed", + args: args{done: 1, left: 100, elapsed: 0}, + want: 0, + }, + { + name: "@Jolly23 's case", + args: args{done: 16858580, left: 41802252, elapsed: 66179848 * time.Millisecond}, + want: 164098440 * time.Millisecond, + // wrong msg: msg="Indexing state history" processed=16858580 left=41802252 elapsed=18h22m59.848s eta=11h36m42.252s + // should be around 45.58 hours + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := CalculateETA(tt.args.done, tt.args.left, tt.args.elapsed); got != tt.want { + t.Errorf("CalculateETA() = %v ms, want %v ms", got.Milliseconds(), tt.want) + } + }) + } +} diff --git a/common/format.go b/common/format.go index 7af41f52d5..31e08831f5 100644 --- a/common/format.go +++ b/common/format.go @@ -69,7 +69,7 @@ func (t PrettyAge) String() string { result, prec := "", 0 for _, unit := range ageUnits { - if diff > unit.Size { + if diff >= unit.Size { result = fmt.Sprintf("%s%d%s", result, diff/unit.Size, unit.Symbol) diff %= unit.Size diff --git a/common/hexutil/json_test.go b/common/hexutil/json_test.go index a014438458..3dc19680f9 100644 --- a/common/hexutil/json_test.go +++ b/common/hexutil/json_test.go @@ -408,7 +408,6 @@ func TestUnmarshalFixedUnprefixedText(t *testing.T) { {input: "0x2", wantErr: ErrOddLength}, {input: "2", wantErr: ErrOddLength}, {input: "4444", wantErr: errors.New("hex string has length 4, want 8 for x")}, - {input: "4444", wantErr: errors.New("hex string has length 4, want 8 for x")}, // check that output is not modified for partially correct input {input: "444444gg", wantErr: ErrSyntax, want: []byte{0, 0, 0, 0}}, {input: "0x444444gg", wantErr: ErrSyntax, want: []byte{0, 0, 0, 0}}, diff --git a/common/math/integer_test.go b/common/math/integer_test.go index 4643a43f20..feb761c6dc 100644 --- a/common/math/integer_test.go +++ b/common/math/integer_test.go @@ -110,7 +110,7 @@ func TestMustParseUint64(t *testing.T) { func TestMustParseUint64Panic(t *testing.T) { defer func() { if recover() == nil { - t.Error("MustParseBig should've panicked") + t.Error("MustParseUint64 should've panicked") } }() MustParseUint64("ggg") diff --git a/common/path.go b/common/path.go index 49c6a5efc2..841946348e 100644 --- a/common/path.go +++ b/common/path.go @@ -17,6 +17,8 @@ package common import ( + "errors" + "io/fs" "os" "path/filepath" ) @@ -24,10 +26,7 @@ import ( // FileExist checks if a file exists at filePath. func FileExist(filePath string) bool { _, err := os.Stat(filePath) - if err != nil && os.IsNotExist(err) { - return false - } - return true + return !errors.Is(err, fs.ErrNotExist) } // AbsolutePath returns datadir + filename, or filename if it is absolute. @@ -37,3 +36,14 @@ func AbsolutePath(datadir string, filename string) string { } return filepath.Join(datadir, filename) } + +// IsNonEmptyDir checks if a directory exists and is non-empty. +func IsNonEmptyDir(dir string) bool { + f, err := os.Open(dir) + if err != nil { + return false + } + defer f.Close() + names, _ := f.Readdirnames(1) + return len(names) > 0 +} diff --git a/common/size.go b/common/size.go index 097b6304a8..e7f504a082 100644 --- a/common/size.go +++ b/common/size.go @@ -26,13 +26,13 @@ type StorageSize float64 // String implements the stringer interface. func (s StorageSize) String() string { - if s > 1099511627776 { + if s >= 1099511627776 { return fmt.Sprintf("%.2f TiB", s/1099511627776) - } else if s > 1073741824 { + } else if s >= 1073741824 { return fmt.Sprintf("%.2f GiB", s/1073741824) - } else if s > 1048576 { + } else if s >= 1048576 { return fmt.Sprintf("%.2f MiB", s/1048576) - } else if s > 1024 { + } else if s >= 1024 { return fmt.Sprintf("%.2f KiB", s/1024) } else { return fmt.Sprintf("%.2f B", s) @@ -42,13 +42,13 @@ func (s StorageSize) String() string { // TerminalString implements log.TerminalStringer, formatting a string for console // output during logging. func (s StorageSize) TerminalString() string { - if s > 1099511627776 { + if s >= 1099511627776 { return fmt.Sprintf("%.2fTiB", s/1099511627776) - } else if s > 1073741824 { + } else if s >= 1073741824 { return fmt.Sprintf("%.2fGiB", s/1073741824) - } else if s > 1048576 { + } else if s >= 1048576 { return fmt.Sprintf("%.2fMiB", s/1048576) - } else if s > 1024 { + } else if s >= 1024 { return fmt.Sprintf("%.2fKiB", s/1024) } else { return fmt.Sprintf("%.2fB", s) diff --git a/common/types.go b/common/types.go index db4de8bcbd..a96d6c7c83 100644 --- a/common/types.go +++ b/common/types.go @@ -71,6 +71,15 @@ func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } // If b is larger than len(h), b will be cropped from the left. func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } +// IsHexHash verifies whether a string can represent a valid hex-encoded +// Ethereum hash or not. +func IsHexHash(s string) bool { + if has0xPrefix(s) { + s = s[2:] + } + return len(s) == 2*HashLength && isHex(s) +} + // Cmp compares two hashes. func (h Hash) Cmp(other Hash) int { return bytes.Compare(h[:], other[:]) diff --git a/consensus/beacon/consensus.go b/consensus/beacon/consensus.go index 196cbc857c..eed27407a5 100644 --- a/consensus/beacon/consensus.go +++ b/consensus/beacon/consensus.go @@ -71,16 +71,6 @@ func New(ethone consensus.Engine) *Beacon { return &Beacon{ethone: ethone} } -// isPostMerge reports whether the given block number is assumed to be post-merge. -// Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or -// PoA chain for unit testing purposes. -func isPostMerge(config *params.ChainConfig, blockNum uint64, timestamp uint64) bool { - mergedAtGenesis := config.TerminalTotalDifficulty != nil && config.TerminalTotalDifficulty.Sign() == 0 - return mergedAtGenesis || - config.MergeNetsplitBlock != nil && blockNum >= config.MergeNetsplitBlock.Uint64() || - config.ShanghaiTime != nil && timestamp >= *config.ShanghaiTime -} - // Author implements consensus.Engine, returning the verified author of the block. func (beacon *Beacon) Author(header *types.Header) (common.Address, error) { if !beacon.IsPoSHeader(header) { @@ -268,11 +258,11 @@ func (beacon *Beacon) verifyHeader(chain consensus.ChainHeaderReader, header, pa if !cancun { switch { case header.ExcessBlobGas != nil: - return fmt.Errorf("invalid excessBlobGas: have %d, expected nil", header.ExcessBlobGas) + return fmt.Errorf("invalid excessBlobGas: have %d, expected nil", *header.ExcessBlobGas) case header.BlobGasUsed != nil: - return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", header.BlobGasUsed) + return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", *header.BlobGasUsed) case header.ParentBeaconRoot != nil: - return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", header.ParentBeaconRoot) + return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", *header.ParentBeaconRoot) } } else { if header.ParentBeaconRoot == nil { @@ -328,7 +318,7 @@ func (beacon *Beacon) verifyHeaders(chain consensus.ChainHeaderReader, headers [ // Prepare implements consensus.Engine, initializing the difficulty field of a // header to conform to the beacon protocol. The changes are done inline. func (beacon *Beacon) Prepare(chain consensus.ChainHeaderReader, header *types.Header) error { - if !isPostMerge(chain.Config(), header.Number.Uint64(), header.Time) { + if !chain.Config().IsPostMerge(header.Number.Uint64(), header.Time) { return beacon.ethone.Prepare(chain, header) } header.Difficulty = beaconDifficulty @@ -375,46 +365,7 @@ func (beacon *Beacon) FinalizeAndAssemble(chain consensus.ChainHeaderReader, hea header.Root = state.IntermediateRoot(true) // Assemble the final block. - block := types.NewBlock(header, body, receipts, trie.NewStackTrie(nil)) - - // Create the block witness and attach to block. - // This step needs to happen as late as possible to catch all access events. - if chain.Config().IsVerkle(header.Number, header.Time) { - keys := state.AccessEvents().Keys() - - // Open the pre-tree to prove the pre-state against - parent := chain.GetHeaderByNumber(header.Number.Uint64() - 1) - if parent == nil { - return nil, fmt.Errorf("nil parent header for block %d", header.Number) - } - preTrie, err := state.Database().OpenTrie(parent.Root) - if err != nil { - return nil, fmt.Errorf("error opening pre-state tree root: %w", err) - } - postTrie := state.GetTrie() - if postTrie == nil { - return nil, errors.New("post-state tree is not available") - } - vktPreTrie, okpre := preTrie.(*trie.VerkleTrie) - vktPostTrie, okpost := postTrie.(*trie.VerkleTrie) - - // The witness is only attached iff both parent and current block are - // using verkle tree. - if okpre && okpost { - if len(keys) > 0 { - verkleProof, stateDiff, err := vktPreTrie.Proof(vktPostTrie, keys) - if err != nil { - return nil, fmt.Errorf("error generating verkle proof for block %d: %w", header.Number, err) - } - block = block.WithWitness(&types.ExecutionWitness{ - StateDiff: stateDiff, - VerkleProof: verkleProof, - }) - } - } - } - - return block, nil + return types.NewBlock(header, body, receipts, trie.NewStackTrie(nil)), nil } // Seal generates a new sealing request for the given input block and pushes @@ -442,7 +393,7 @@ func (beacon *Beacon) SealHash(header *types.Header) common.Hash { // the difficulty that a new block should have when created at time // given the parent block's time and difficulty. func (beacon *Beacon) CalcDifficulty(chain consensus.ChainHeaderReader, time uint64, parent *types.Header) *big.Int { - if !isPostMerge(chain.Config(), parent.Number.Uint64()+1, time) { + if !chain.Config().IsPostMerge(parent.Number.Uint64()+1, time) { return beacon.ethone.CalcDifficulty(chain, time, parent) } return beaconDifficulty diff --git a/consensus/clique/clique.go b/consensus/clique/clique.go index b593d2117d..a6f02c8c2b 100644 --- a/consensus/clique/clique.go +++ b/consensus/clique/clique.go @@ -305,11 +305,11 @@ func (c *Clique) verifyHeader(chain consensus.ChainHeaderReader, header *types.H // Verify the non-existence of cancun-specific header fields switch { case header.ExcessBlobGas != nil: - return fmt.Errorf("invalid excessBlobGas: have %d, expected nil", header.ExcessBlobGas) + return fmt.Errorf("invalid excessBlobGas: have %d, expected nil", *header.ExcessBlobGas) case header.BlobGasUsed != nil: - return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", header.BlobGasUsed) + return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", *header.BlobGasUsed) case header.ParentBeaconRoot != nil: - return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", header.ParentBeaconRoot) + return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", *header.ParentBeaconRoot) } // All basic checks passed, verify cascading fields return c.verifyCascadingFields(chain, header, parents) diff --git a/consensus/ethash/consensus.go b/consensus/ethash/consensus.go index 4f92f1282b..376cbac8c0 100644 --- a/consensus/ethash/consensus.go +++ b/consensus/ethash/consensus.go @@ -278,11 +278,11 @@ func (ethash *Ethash) verifyHeader(chain consensus.ChainHeaderReader, header, pa // Verify the non-existence of cancun-specific header fields switch { case header.ExcessBlobGas != nil: - return fmt.Errorf("invalid excessBlobGas: have %d, expected nil", header.ExcessBlobGas) + return fmt.Errorf("invalid excessBlobGas: have %d, expected nil", *header.ExcessBlobGas) case header.BlobGasUsed != nil: - return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", header.BlobGasUsed) + return fmt.Errorf("invalid blobGasUsed: have %d, expected nil", *header.BlobGasUsed) case header.ParentBeaconRoot != nil: - return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", header.ParentBeaconRoot) + return fmt.Errorf("invalid parentBeaconRoot, have %#x, expected nil", *header.ParentBeaconRoot) } // Add some fake checks for tests if ethash.fakeDelay != nil { diff --git a/consensus/misc/eip4844/eip4844.go b/consensus/misc/eip4844/eip4844.go index fc143027dd..47b54d2e85 100644 --- a/consensus/misc/eip4844/eip4844.go +++ b/consensus/misc/eip4844/eip4844.go @@ -19,6 +19,7 @@ package eip4844 import ( "errors" "fmt" + "math" "math/big" "github.com/ethereum/go-ethereum/core/types" @@ -29,6 +30,66 @@ var ( minBlobGasPrice = big.NewInt(params.BlobTxMinBlobGasprice) ) +// BlobConfig contains the parameters for blob-related formulas. +// These can be adjusted in a fork. +type BlobConfig struct { + Target int + Max int + UpdateFraction uint64 +} + +func (bc *BlobConfig) maxBlobGas() uint64 { + return uint64(bc.Max) * params.BlobTxBlobGasPerBlob +} + +// blobBaseFee computes the blob fee. +func (bc *BlobConfig) blobBaseFee(excessBlobGas uint64) *big.Int { + return fakeExponential(minBlobGasPrice, new(big.Int).SetUint64(excessBlobGas), new(big.Int).SetUint64(bc.UpdateFraction)) +} + +// blobPrice returns the price of one blob in Wei. +func (bc *BlobConfig) blobPrice(excessBlobGas uint64) *big.Int { + f := bc.blobBaseFee(excessBlobGas) + return new(big.Int).Mul(f, big.NewInt(params.BlobTxBlobGasPerBlob)) +} + +func latestBlobConfig(cfg *params.ChainConfig, time uint64) *BlobConfig { + if cfg.BlobScheduleConfig == nil { + return nil + } + var ( + london = cfg.LondonBlock + s = cfg.BlobScheduleConfig + bc *params.BlobConfig + ) + switch { + case cfg.IsBPO5(london, time) && s.BPO5 != nil: + bc = s.BPO5 + case cfg.IsBPO4(london, time) && s.BPO4 != nil: + bc = s.BPO4 + case cfg.IsBPO3(london, time) && s.BPO3 != nil: + bc = s.BPO3 + case cfg.IsBPO2(london, time) && s.BPO2 != nil: + bc = s.BPO2 + case cfg.IsBPO1(london, time) && s.BPO1 != nil: + bc = s.BPO1 + case cfg.IsOsaka(london, time) && s.Osaka != nil: + bc = s.Osaka + case cfg.IsPrague(london, time) && s.Prague != nil: + bc = s.Prague + case cfg.IsCancun(london, time) && s.Cancun != nil: + bc = s.Cancun + default: + return nil + } + + return &BlobConfig{ + Target: bc.Target, + Max: bc.Max, + UpdateFraction: bc.UpdateFraction, + } +} + // VerifyEIP4844Header verifies the presence of the excessBlobGas field and that // if the current block contains no transactions, the excessBlobGas is updated // accordingly. @@ -36,21 +97,27 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade if header.Number.Uint64() != parent.Number.Uint64()+1 { panic("bad header pair") } - // Verify the header is not malformed + + bcfg := latestBlobConfig(config, header.Time) + if bcfg == nil { + panic("called before EIP-4844 is active") + } + if header.ExcessBlobGas == nil { return errors.New("header is missing excessBlobGas") } if header.BlobGasUsed == nil { return errors.New("header is missing blobGasUsed") } + // Verify that the blob gas used remains within reasonable limits. - maxBlobGas := MaxBlobGasPerBlock(config, header.Time) - if *header.BlobGasUsed > maxBlobGas { - return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", *header.BlobGasUsed, maxBlobGas) + if *header.BlobGasUsed > bcfg.maxBlobGas() { + return fmt.Errorf("blob gas used %d exceeds maximum allowance %d", *header.BlobGasUsed, bcfg.maxBlobGas()) } if *header.BlobGasUsed%params.BlobTxBlobGasPerBlob != 0 { - return fmt.Errorf("blob gas used %d not a multiple of blob gas per blob %d", header.BlobGasUsed, params.BlobTxBlobGasPerBlob) + return fmt.Errorf("blob gas used %d not a multiple of blob gas per blob %d", *header.BlobGasUsed, params.BlobTxBlobGasPerBlob) } + // Verify the excessBlobGas is correct based on the parent header expectedExcessBlobGas := CalcExcessBlobGas(config, parent, header.Time) if *header.ExcessBlobGas != expectedExcessBlobGas { @@ -62,38 +129,41 @@ func VerifyEIP4844Header(config *params.ChainConfig, parent, header *types.Heade // CalcExcessBlobGas calculates the excess blob gas after applying the set of // blobs on top of the excess blob gas. func CalcExcessBlobGas(config *params.ChainConfig, parent *types.Header, headTimestamp uint64) uint64 { - var ( - parentExcessBlobGas uint64 - parentBlobGasUsed uint64 - ) + isOsaka := config.IsOsaka(config.LondonBlock, headTimestamp) + bcfg := latestBlobConfig(config, headTimestamp) + return calcExcessBlobGas(isOsaka, bcfg, parent) +} + +func calcExcessBlobGas(isOsaka bool, bcfg *BlobConfig, parent *types.Header) uint64 { + var parentExcessBlobGas, parentBlobGasUsed uint64 if parent.ExcessBlobGas != nil { parentExcessBlobGas = *parent.ExcessBlobGas parentBlobGasUsed = *parent.BlobGasUsed } + var ( excessBlobGas = parentExcessBlobGas + parentBlobGasUsed - target = targetBlobsPerBlock(config, headTimestamp) - targetGas = uint64(target) * params.BlobTxBlobGasPerBlob + targetGas = uint64(bcfg.Target) * params.BlobTxBlobGasPerBlob ) if excessBlobGas < targetGas { return 0 } - if !config.IsOsaka(config.LondonBlock, headTimestamp) { - // Pre-Osaka, we use the formula defined by EIP-4844. - return excessBlobGas - targetGas + + // EIP-7918 (post-Osaka) introduces a different formula for computing excess, + // in cases where the price is lower than a 'reserve price'. + if isOsaka { + var ( + baseCost = big.NewInt(params.BlobBaseCost) + reservePrice = baseCost.Mul(baseCost, parent.BaseFee) + blobPrice = bcfg.blobPrice(parentExcessBlobGas) + ) + if reservePrice.Cmp(blobPrice) > 0 { + scaledExcess := parentBlobGasUsed * uint64(bcfg.Max-bcfg.Target) / uint64(bcfg.Max) + return parentExcessBlobGas + scaledExcess + } } - // EIP-7918 (post-Osaka) introduces a different formula for computing excess. - var ( - baseCost = big.NewInt(params.BlobBaseCost) - reservePrice = baseCost.Mul(baseCost, parent.BaseFee) - blobPrice = calcBlobPrice(config, parent) - ) - if reservePrice.Cmp(blobPrice) > 0 { - max := MaxBlobsPerBlock(config, headTimestamp) - scaledExcess := parentBlobGasUsed * uint64(max-target) / uint64(max) - return parentExcessBlobGas + scaledExcess - } + // Original EIP-4844 formula. return excessBlobGas - targetGas } @@ -103,7 +173,7 @@ func CalcBlobFee(config *params.ChainConfig, header *types.Header) *big.Int { if blobConfig == nil { panic("calculating blob fee on unsupported fork") } - return fakeExponential(minBlobGasPrice, new(big.Int).SetUint64(*header.ExcessBlobGas), new(big.Int).SetUint64(blobConfig.UpdateFraction)) + return blobConfig.blobBaseFee(*header.ExcessBlobGas) } // MaxBlobsPerBlock returns the max blobs per block for a block at the given timestamp. @@ -115,36 +185,6 @@ func MaxBlobsPerBlock(cfg *params.ChainConfig, time uint64) int { return blobConfig.Max } -func latestBlobConfig(cfg *params.ChainConfig, time uint64) *params.BlobConfig { - if cfg.BlobScheduleConfig == nil { - return nil - } - var ( - london = cfg.LondonBlock - s = cfg.BlobScheduleConfig - ) - switch { - case cfg.IsBPO5(london, time) && s.BPO5 != nil: - return s.BPO5 - case cfg.IsBPO4(london, time) && s.BPO4 != nil: - return s.BPO4 - case cfg.IsBPO3(london, time) && s.BPO3 != nil: - return s.BPO3 - case cfg.IsBPO2(london, time) && s.BPO2 != nil: - return s.BPO2 - case cfg.IsBPO1(london, time) && s.BPO1 != nil: - return s.BPO1 - case cfg.IsOsaka(london, time) && s.Osaka != nil: - return s.Osaka - case cfg.IsPrague(london, time) && s.Prague != nil: - return s.Prague - case cfg.IsCancun(london, time) && s.Cancun != nil: - return s.Cancun - default: - return nil - } -} - // MaxBlobGasPerBlock returns the maximum blob gas that can be spent in a block at the given timestamp. func MaxBlobGasPerBlock(cfg *params.ChainConfig, time uint64) uint64 { return uint64(MaxBlobsPerBlock(cfg, time)) * params.BlobTxBlobGasPerBlob @@ -153,34 +193,15 @@ func MaxBlobGasPerBlock(cfg *params.ChainConfig, time uint64) uint64 { // LatestMaxBlobsPerBlock returns the latest max blobs per block defined by the // configuration, regardless of the currently active fork. func LatestMaxBlobsPerBlock(cfg *params.ChainConfig) int { - s := cfg.BlobScheduleConfig - if s == nil { - return 0 - } - switch { - case s.BPO5 != nil: - return s.BPO5.Max - case s.BPO4 != nil: - return s.BPO4.Max - case s.BPO3 != nil: - return s.BPO3.Max - case s.BPO2 != nil: - return s.BPO2.Max - case s.BPO1 != nil: - return s.BPO1.Max - case s.Osaka != nil: - return s.Osaka.Max - case s.Prague != nil: - return s.Prague.Max - case s.Cancun != nil: - return s.Cancun.Max - default: + bcfg := latestBlobConfig(cfg, math.MaxUint64) + if bcfg == nil { return 0 } + return bcfg.Max } -// targetBlobsPerBlock returns the target number of blobs in a block at the given timestamp. -func targetBlobsPerBlock(cfg *params.ChainConfig, time uint64) int { +// TargetBlobsPerBlock returns the target blobs per block for a block at the given timestamp. +func TargetBlobsPerBlock(cfg *params.ChainConfig, time uint64) int { blobConfig := latestBlobConfig(cfg, time) if blobConfig == nil { return 0 @@ -204,9 +225,3 @@ func fakeExponential(factor, numerator, denominator *big.Int) *big.Int { } return output.Div(output, denominator) } - -// calcBlobPrice calculates the blob price for a block. -func calcBlobPrice(config *params.ChainConfig, header *types.Header) *big.Int { - blobBaseFee := CalcBlobFee(config, header) - return new(big.Int).Mul(blobBaseFee, big.NewInt(params.BlobTxBlobGasPerBlob)) -} diff --git a/consensus/misc/eip4844/eip4844_test.go b/consensus/misc/eip4844/eip4844_test.go index 555324db65..35934370af 100644 --- a/consensus/misc/eip4844/eip4844_test.go +++ b/consensus/misc/eip4844/eip4844_test.go @@ -28,9 +28,10 @@ import ( func TestCalcExcessBlobGas(t *testing.T) { var ( config = params.MainnetChainConfig - targetBlobs = targetBlobsPerBlock(config, *config.CancunTime) + targetBlobs = config.BlobScheduleConfig.Cancun.Target targetBlobGas = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob ) + var tests = []struct { excess uint64 blobs int @@ -90,6 +91,65 @@ func TestCalcBlobFee(t *testing.T) { } } +func TestCalcBlobFeePostOsaka(t *testing.T) { + zero := uint64(0) + bpo1 := uint64(1754836608) + bpo2 := uint64(1754934912) + bpo3 := uint64(1755033216) + + tests := []struct { + excessBlobGas uint64 + blobGasUsed uint64 + blobfee uint64 + basefee uint64 + parenttime uint64 + headertime uint64 + }{ + {5149252, 1310720, 5617366, 30, 1754904516, 1754904528}, + {19251039, 2490368, 20107103, 50, 1755033204, 1755033216}, + } + for i, tt := range tests { + config := ¶ms.ChainConfig{ + LondonBlock: big.NewInt(0), + CancunTime: &zero, + PragueTime: &zero, + OsakaTime: &zero, + BPO1Time: &bpo1, + BPO2Time: &bpo2, + BPO3Time: &bpo3, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: ¶ms.BlobConfig{ + Target: 9, + Max: 14, + UpdateFraction: 8832827, + }, + BPO2: ¶ms.BlobConfig{ + Target: 14, + Max: 21, + UpdateFraction: 13739630, + }, + BPO3: ¶ms.BlobConfig{ + Target: 21, + Max: 32, + UpdateFraction: 20609697, + }, + }} + parent := &types.Header{ + ExcessBlobGas: &tt.excessBlobGas, + BlobGasUsed: &tt.blobGasUsed, + BaseFee: big.NewInt(int64(tt.basefee)), + Time: tt.parenttime, + } + have := CalcExcessBlobGas(config, parent, tt.headertime) + if have != tt.blobfee { + t.Errorf("test %d: blobfee mismatch: have %v want %v", i, have, tt.blobfee) + } + } +} + func TestFakeExponential(t *testing.T) { tests := []struct { factor int64 @@ -131,9 +191,10 @@ func TestFakeExponential(t *testing.T) { func TestCalcExcessBlobGasEIP7918(t *testing.T) { var ( cfg = params.MergedTestChainConfig - targetBlobs = targetBlobsPerBlock(cfg, *cfg.CancunTime) + targetBlobs = cfg.BlobScheduleConfig.Osaka.Target blobGasTarget = uint64(targetBlobs) * params.BlobTxBlobGasPerBlob ) + makeHeader := func(parentExcess, parentBaseFee uint64, blobsUsed int) *types.Header { blobGasUsed := uint64(blobsUsed) * params.BlobTxBlobGasPerBlob return &types.Header{ diff --git a/consensus/misc/gaslimit.go b/consensus/misc/gaslimit.go index dfcabd9a80..9ae8c95f4b 100644 --- a/consensus/misc/gaslimit.go +++ b/consensus/misc/gaslimit.go @@ -32,7 +32,7 @@ func VerifyGaslimit(parentGasLimit, headerGasLimit uint64) error { } limit := parentGasLimit / params.GasLimitBoundDivisor if uint64(diff) >= limit { - return fmt.Errorf("invalid gas limit: have %d, want %d +-= %d", headerGasLimit, parentGasLimit, limit-1) + return fmt.Errorf("invalid gas limit: have %d, want %d +/- %d", headerGasLimit, parentGasLimit, limit-1) } if headerGasLimit < params.MinGasLimit { return fmt.Errorf("invalid gas limit below %d", params.MinGasLimit) diff --git a/console/prompt/prompter.go b/console/prompt/prompter.go index 2a20b6906a..5a0a89e76a 100644 --- a/console/prompt/prompter.go +++ b/console/prompt/prompter.go @@ -142,7 +142,7 @@ func (p *terminalPrompter) PromptPassword(prompt string) (passwd string, err err // PromptConfirm displays the given prompt to the user and requests a boolean // choice to be made, returning that choice. func (p *terminalPrompter) PromptConfirm(prompt string) (bool, error) { - input, err := p.Prompt(prompt + " [y/n] ") + input, err := p.PromptInput(prompt + " [y/n] ") if len(input) > 0 && strings.EqualFold(input[:1], "y") { return true, nil } diff --git a/core/bench_test.go b/core/bench_test.go index 2830022662..932188f8e2 100644 --- a/core/bench_test.go +++ b/core/bench_test.go @@ -301,7 +301,7 @@ func makeChainForBench(db ethdb.Database, genesis *Genesis, full bool, count uin func benchWriteChain(b *testing.B, full bool, count uint64) { genesis := &Genesis{Config: params.AllEthashProtocolChanges} - for i := 0; i < b.N; i++ { + for b.Loop() { pdb, err := pebble.New(b.TempDir(), 1024, 128, "", false) if err != nil { b.Fatalf("error opening database: %v", err) @@ -326,9 +326,7 @@ func benchReadChain(b *testing.B, full bool, count uint64) { db.Close() options := DefaultConfig().WithArchive(true) b.ReportAllocs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { + for b.Loop() { pdb, err = pebble.New(dir, 1024, 128, "", false) if err != nil { b.Fatalf("error opening database: %v", err) diff --git a/core/bintrie_witness_test.go b/core/bintrie_witness_test.go new file mode 100644 index 0000000000..7704ba41fb --- /dev/null +++ b/core/bintrie_witness_test.go @@ -0,0 +1,237 @@ +// Copyright 2024 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "encoding/binary" + "fmt" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus/beacon" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/triedb" +) + +var ( + testVerkleChainConfig = ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + Ethash: new(params.EthashConfig), + ShanghaiTime: u64(0), + VerkleTime: u64(0), + TerminalTotalDifficulty: common.Big0, + EnableVerkleAtGenesis: true, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Verkle: params.DefaultPragueBlobConfig, + }, + } +) + +func TestProcessVerkle(t *testing.T) { + var ( + code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`) + intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, nil, true, true, true, true) + // A contract creation that calls EXTCODECOPY in the constructor. Used to ensure that the witness + // will not contain that copied data. + // Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985 + codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`) + intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, nil, true, true, true, true) + signer = types.LatestSigner(testVerkleChainConfig) + testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain + coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") + gspec = &Genesis{ + Config: testVerkleChainConfig, + Alloc: GenesisAlloc{ + coinbase: { + Balance: big.NewInt(1000000000000000000), // 1 ether + Nonce: 0, + }, + params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0}, + params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0}, + params.WithdrawalQueueAddress: {Nonce: 1, Code: params.WithdrawalQueueCode, Balance: common.Big0}, + params.ConsolidationQueueAddress: {Nonce: 1, Code: params.ConsolidationQueueCode, Balance: common.Big0}, + }, + } + ) + // Verkle trees use the snapshot, which must be enabled before the + // data is saved into the tree+database. + // genesis := gspec.MustCommit(bcdb, triedb) + options := DefaultConfig().WithStateScheme(rawdb.PathScheme) + options.SnapshotLimit = 0 + blockchain, _ := NewBlockChain(bcdb, gspec, beacon.New(ethash.NewFaker()), options) + defer blockchain.Stop() + + txCost1 := params.TxGas + txCost2 := params.TxGas + contractCreationCost := intrinsicContractCreationGas + + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* creation with value */ + 739 /* execution costs */ + codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas + + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (tx) */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at pc=0x20) */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */ + params.WitnessChunkReadCost + /* SLOAD in constructor */ + params.WitnessChunkWriteCost + /* SSTORE in constructor */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at PC=0x121) */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */ + params.WitnessChunkReadCost + /* SLOAD in constructor */ + params.WitnessChunkWriteCost + /* SSTORE in constructor */ + params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash for tx creation */ + 15*(params.WitnessChunkReadCost+params.WitnessChunkWriteCost) + /* code chunks #0..#14 */ + uint64(4844) /* execution costs */ + blockGasUsagesExpected := []uint64{ + txCost1*2 + txCost2, + txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas, + } + _, chain, _ := GenerateChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { + gen.SetPoS() + + // TODO need to check that the tx cost provided is the exact amount used (no remaining left-over) + tx, _ := types.SignTx(types.NewTransaction(uint64(i)*3, common.Address{byte(i), 2, 3}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey) + gen.AddTx(tx) + tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+1, common.Address{}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey) + gen.AddTx(tx) + tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+2, common.Address{}, big.NewInt(0), txCost2, big.NewInt(875000000), nil), signer, testKey) + gen.AddTx(tx) + + // Add two contract creations in block #2 + if i == 1 { + tx, _ = types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 6, + Value: big.NewInt(16), + Gas: 3000000, + GasPrice: big.NewInt(875000000), + Data: code, + }) + gen.AddTx(tx) + + tx, _ = types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 7, + Value: big.NewInt(0), + Gas: 3000000, + GasPrice: big.NewInt(875000000), + Data: codeWithExtCodeCopy, + }) + gen.AddTx(tx) + } + }) + + for i, b := range chain { + fmt.Printf("%d %x\n", i, b.Root()) + } + endnum, err := blockchain.InsertChain(chain) + if err != nil { + t.Fatalf("block %d imported with error: %v", endnum, err) + } + + for i := range 2 { + b := blockchain.GetBlockByNumber(uint64(i) + 1) + if b == nil { + t.Fatalf("expected block %d to be present in chain", i+1) + } + if b.Hash() != chain[i].Hash() { + t.Fatalf("block #%d not found at expected height", b.NumberU64()) + } + if b.GasUsed() != blockGasUsagesExpected[i] { + t.Fatalf("expected block #%d txs to use %d, got %d\n", b.NumberU64(), blockGasUsagesExpected[i], b.GasUsed()) + } + } +} + +func TestProcessParentBlockHash(t *testing.T) { + // This test uses blocks where, + // block 1 parent hash is 0x0100.... + // block 2 parent hash is 0x0200.... + // etc + checkBlockHashes := func(statedb *state.StateDB, isVerkle bool) { + statedb.SetNonce(params.HistoryStorageAddress, 1, tracing.NonceChangeUnspecified) + statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode, tracing.CodeChangeUnspecified) + // Process n blocks, from 1 .. num + var num = 2 + for i := 1; i <= num; i++ { + header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)} + chainConfig := params.MergedTestChainConfig + if isVerkle { + chainConfig = testVerkleChainConfig + } + vmContext := NewEVMBlockContext(header, nil, new(common.Address)) + evm := vm.NewEVM(vmContext, statedb, chainConfig, vm.Config{}) + ProcessParentBlockHash(header.ParentHash, evm) + } + // Read block hashes for block 0 .. num-1 + for i := 0; i < num; i++ { + have, want := getContractStoredBlockHash(statedb, uint64(i), isVerkle), common.Hash{byte(i + 1)} + if have != want { + t.Errorf("block %d, verkle=%v, have parent hash %v, want %v", i, isVerkle, have, want) + } + } + } + t.Run("MPT", func(t *testing.T) { + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + checkBlockHashes(statedb, false) + }) + t.Run("Verkle", func(t *testing.T) { + db := rawdb.NewMemoryDatabase() + cacheConfig := DefaultConfig().WithStateScheme(rawdb.PathScheme) + cacheConfig.SnapshotLimit = 0 + triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) + statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil)) + checkBlockHashes(statedb, true) + }) +} + +// getContractStoredBlockHash is a utility method which reads the stored parent blockhash for block 'number' +func getContractStoredBlockHash(statedb *state.StateDB, number uint64, isVerkle bool) common.Hash { + ringIndex := number % params.HistoryServeWindow + var key common.Hash + binary.BigEndian.PutUint64(key[24:], ringIndex) + if isVerkle { + return statedb.GetState(params.HistoryStorageAddress, key) + } + return statedb.GetState(params.HistoryStorageAddress, key) +} diff --git a/core/blockchain.go b/core/blockchain.go index 0b92a94b6c..8741b8b937 100644 --- a/core/blockchain.go +++ b/core/blockchain.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "io" - "math" "math/big" "runtime" "slices" @@ -76,6 +75,7 @@ var ( storageReadTimer = metrics.NewRegisteredResettingTimer("chain/storage/reads", nil) storageUpdateTimer = metrics.NewRegisteredResettingTimer("chain/storage/updates", nil) storageCommitTimer = metrics.NewRegisteredResettingTimer("chain/storage/commits", nil) + codeReadTimer = metrics.NewRegisteredResettingTimer("chain/code/reads", nil) accountCacheHitMeter = metrics.NewRegisteredMeter("chain/account/reads/cache/process/hit", nil) accountCacheMissMeter = metrics.NewRegisteredMeter("chain/account/reads/cache/process/miss", nil) @@ -89,6 +89,7 @@ var ( accountReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/account/single/reads", nil) storageReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/storage/single/reads", nil) + codeReadSingleTimer = metrics.NewRegisteredResettingTimer("chain/code/single/reads", nil) snapshotCommitTimer = metrics.NewRegisteredResettingTimer("chain/snapshot/commits", nil) triedbCommitTimer = metrics.NewRegisteredResettingTimer("chain/triedb/commits", nil) @@ -168,10 +169,24 @@ type BlockChainConfig struct { TrieNoAsyncFlush bool // Whether the asynchronous buffer flushing is disallowed TrieJournalDirectory string // Directory path to the journal used for persisting trie data across node restarts - Preimages bool // Whether to store preimage of trie key to the disk - StateHistory uint64 // Number of blocks from head whose state histories are reserved. - StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top - ArchiveMode bool // Whether to enable the archive mode + Preimages bool // Whether to store preimage of trie key to the disk + StateScheme string // Scheme used to store ethereum states and merkle tree nodes on top + ArchiveMode bool // Whether to enable the archive mode + + // Number of blocks from the chain head for which state histories are retained. + // If set to 0, all state histories across the entire chain will be retained; + StateHistory uint64 + + // Number of blocks from the chain head for which trienode histories are retained. + // If set to 0, all trienode histories across the entire chain will be retained; + // If set to -1, no trienode history will be retained; + TrienodeHistory int64 + + // The frequency of full-value encoding. For example, a value of 16 means + // that, on average, for a given trie node across its 16 consecutive historical + // versions, only one version is stored in full format, while the others + // are stored in diff mode for storage compression. + NodeFullValueCheckpoint uint32 // State snapshot related options SnapshotLimit int // Memory allowance (MB) to use for caching snapshot entries in memory @@ -193,6 +208,13 @@ type BlockChainConfig struct { // If the value is zero, all transactions of the entire chain will be indexed. // If the value is -1, indexing is disabled. TxLookupLimit int64 + + // StateSizeTracking indicates whether the state size tracking is enabled. + StateSizeTracking bool + + // SlowBlockThreshold is the block execution time threshold beyond which + // detailed statistics will be logged. + SlowBlockThreshold time.Duration } // DefaultConfig returns the default config. @@ -243,17 +265,22 @@ func (cfg *BlockChainConfig) triedbConfig(isVerkle bool) *triedb.Config { } if cfg.StateScheme == rawdb.PathScheme { config.PathDB = &pathdb.Config{ - StateHistory: cfg.StateHistory, - EnableStateIndexing: cfg.ArchiveMode, - TrieCleanSize: cfg.TrieCleanLimit * 1024 * 1024, - StateCleanSize: cfg.SnapshotLimit * 1024 * 1024, - JournalDirectory: cfg.TrieJournalDirectory, - + TrieCleanSize: cfg.TrieCleanLimit * 1024 * 1024, + StateCleanSize: cfg.SnapshotLimit * 1024 * 1024, // TODO(rjl493456442): The write buffer represents the memory limit used // for flushing both trie data and state data to disk. The config name // should be updated to eliminate the confusion. - WriteBufferSize: cfg.TrieDirtyLimit * 1024 * 1024, - NoAsyncFlush: cfg.TrieNoAsyncFlush, + WriteBufferSize: cfg.TrieDirtyLimit * 1024 * 1024, + JournalDirectory: cfg.TrieJournalDirectory, + + // Historical state configurations + StateHistory: cfg.StateHistory, + TrienodeHistory: cfg.TrienodeHistory, + EnableStateIndexing: cfg.ArchiveMode, + FullValueCheckpoint: cfg.NodeFullValueCheckpoint, + + // Testing configurations + NoAsyncFlush: cfg.TrieNoAsyncFlush, } } return config @@ -300,6 +327,7 @@ type BlockChain struct { chainHeadFeed event.Feed logsFeed event.Feed blockProcFeed event.Feed + newPayloadFeed event.Feed // Feed for engine API newPayload events blockProcCounter int32 scope event.SubscriptionScope genesisBlock *types.Block @@ -330,8 +358,10 @@ type BlockChain struct { prefetcher Prefetcher processor Processor // Block transaction processor interface logger *tracing.Hooks + stateSizer *state.SizeTracker // State size tracking - lastForkReadyAlert time.Time // Last time there was a fork readiness print out + lastForkReadyAlert time.Time // Last time there was a fork readiness print out + slowBlockThreshold time.Duration // Block execution time threshold beyond which detailed statistics will be logged } // NewBlockChain returns a fully initialised block chain using information @@ -353,7 +383,7 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine, // yet. The corresponding chain config will be returned, either from the // provided genesis or from the locally stored configuration if the genesis // has already been initialized. - chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, cfg.Overrides) + chainConfig, genesisHash, compatErr, err := SetupGenesisBlockWithOverride(db, triedb, genesis, cfg.Overrides, cfg.VmConfig.Tracer) if err != nil { return nil, err } @@ -366,19 +396,20 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine, log.Info("") bc := &BlockChain{ - chainConfig: chainConfig, - cfg: cfg, - db: db, - triedb: triedb, - triegc: prque.New[int64, common.Hash](nil), - chainmu: syncx.NewClosableMutex(), - bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit), - bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit), - receiptsCache: lru.NewCache[common.Hash, []*types.Receipt](receiptsCacheLimit), - blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit), - txLookupCache: lru.NewCache[common.Hash, txLookup](txLookupCacheLimit), - engine: engine, - logger: cfg.VmConfig.Tracer, + chainConfig: chainConfig, + cfg: cfg, + db: db, + triedb: triedb, + triegc: prque.New[int64, common.Hash](nil), + chainmu: syncx.NewClosableMutex(), + bodyCache: lru.NewCache[common.Hash, *types.Body](bodyCacheLimit), + bodyRLPCache: lru.NewCache[common.Hash, rlp.RawValue](bodyCacheLimit), + receiptsCache: lru.NewCache[common.Hash, []*types.Receipt](receiptsCacheLimit), + blockCache: lru.NewCache[common.Hash, *types.Block](blockCacheLimit), + txLookupCache: lru.NewCache[common.Hash, txLookup](txLookupCacheLimit), + engine: engine, + logger: cfg.VmConfig.Tracer, + slowBlockThreshold: cfg.SlowBlockThreshold, } bc.hc, err = NewHeaderChain(db, chainConfig, engine, bc.insertStopped) if err != nil { @@ -388,7 +419,7 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine, bc.statedb = state.NewDatabase(bc.triedb, nil) bc.validator = NewBlockValidator(chainConfig, bc) bc.prefetcher = newStatePrefetcher(chainConfig, bc.hc) - bc.processor = NewStateProcessor(chainConfig, bc.hc) + bc.processor = NewStateProcessor(bc.hc) genesisHeader := bc.GetHeaderByNumber(0) if genesisHeader == nil { @@ -523,6 +554,17 @@ func NewBlockChain(db ethdb.Database, genesis *Genesis, engine consensus.Engine, if bc.cfg.TxLookupLimit >= 0 { bc.txIndexer = newTxIndexer(uint64(bc.cfg.TxLookupLimit), bc) } + + // Start state size tracker + if bc.cfg.StateSizeTracking { + stateSizer, err := state.NewSizeTracker(bc.db, bc.triedb) + if err == nil { + bc.stateSizer = stateSizer + log.Info("Enabled state size metrics") + } else { + log.Info("Failed to setup size tracker", "err", err) + } + } return bc, nil } @@ -720,21 +762,7 @@ func (bc *BlockChain) SetHead(head uint64) error { if _, err := bc.setHeadBeyondRoot(head, 0, common.Hash{}, false); err != nil { return err } - // Send chain head event to update the transaction pool - header := bc.CurrentBlock() - if block := bc.GetBlock(header.Hash(), header.Number.Uint64()); block == nil { - // In a pruned node the genesis block will not exist in the freezer. - // It should not happen that we set head to any other pruned block. - if header.Number.Uint64() > 0 { - // This should never happen. In practice, previously currentBlock - // contained the entire block whereas now only a "marker", so there - // is an ever so slight chance for a race we should handle. - log.Error("Current block not found in database", "block", header.Number, "hash", header.Hash()) - return fmt.Errorf("current block missing: #%d [%x..]", header.Number, header.Hash().Bytes()[:4]) - } - } - bc.chainHeadFeed.Send(ChainHeadEvent{Header: header}) - return nil + return bc.sendChainHeadEvent() } // SetHeadWithTimestamp rewinds the local chain to a new head that has at max @@ -745,7 +773,12 @@ func (bc *BlockChain) SetHeadWithTimestamp(timestamp uint64) error { if _, err := bc.setHeadBeyondRoot(0, timestamp, common.Hash{}, false); err != nil { return err } - // Send chain head event to update the transaction pool + return bc.sendChainHeadEvent() +} + +// sendChainHeadEvent notifies all subscribers about the new chain head, +// checking first that the current block is actually available. +func (bc *BlockChain) sendChainHeadEvent() error { header := bc.CurrentBlock() if block := bc.GetBlock(header.Hash(), header.Number.Uint64()); block == nil { // In a pruned node the genesis block will not exist in the freezer. @@ -928,7 +961,8 @@ func (bc *BlockChain) rewindPathHead(head *types.Header, root common.Hash) (*typ // Recover if the target state if it's not available yet. if !bc.HasState(head.Root) { if err := bc.triedb.Recover(head.Root); err != nil { - log.Crit("Failed to rollback state", "err", err) + log.Error("Failed to rollback state, resetting to genesis", "err", err) + return bc.genesisBlock.Header(), rootNumber } } log.Info("Rewound to block with state", "number", head.Number, "hash", head.Hash()) @@ -1079,25 +1113,60 @@ func (bc *BlockChain) setHeadBeyondRoot(head uint64, time uint64, root common.Ha bc.txLookupCache.Purge() // Clear safe block, finalized block if needed - if safe := bc.CurrentSafeBlock(); safe != nil && head < safe.Number.Uint64() { + headBlock := bc.CurrentBlock() + if safe := bc.CurrentSafeBlock(); safe != nil && headBlock.Number.Uint64() < safe.Number.Uint64() { log.Warn("SetHead invalidated safe block") bc.SetSafe(nil) } - if finalized := bc.CurrentFinalBlock(); finalized != nil && head < finalized.Number.Uint64() { + if finalized := bc.CurrentFinalBlock(); finalized != nil && headBlock.Number.Uint64() < finalized.Number.Uint64() { log.Error("SetHead invalidated finalized block") bc.SetFinalized(nil) } return rootNumber, bc.loadLastState() } -// SnapSyncCommitHead sets the current head block to the one defined by the hash -// irrelevant what the chain contents were prior. -func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error { +// SnapSyncStart disables the underlying databases (such as the trie DB and the +// optional state snapshot) to prevent potential concurrent mutations between +// snap sync and other chain operations. +func (bc *BlockChain) SnapSyncStart() error { + if !bc.chainmu.TryLock() { + return errChainStopped + } + defer bc.chainmu.Unlock() + + // Snap sync will directly modify the persistent state, making the entire + // trie database unusable until the state is fully synced. To prevent any + // subsequent state reads, explicitly disable the trie database and state + // syncer is responsible to address and correct any state missing. + if bc.TrieDB().Scheme() == rawdb.PathScheme { + if err := bc.TrieDB().Disable(); err != nil { + return err + } + } + // Snap sync uses the snapshot namespace to store potentially flaky data until + // sync completely heals and finishes. Pause snapshot maintenance in the mean- + // time to prevent access. + if snapshots := bc.Snapshots(); snapshots != nil { // Only nil in tests + snapshots.Disable() + } + return nil +} + +// SnapSyncComplete sets the current head block to the block identified by the +// given hash, regardless of the chain contents prior to snap sync. It is +// invoked once snap sync completes and assumes that SnapSyncStart was called +// previously. +func (bc *BlockChain) SnapSyncComplete(hash common.Hash) error { // Make sure that both the block as well at its state trie exists block := bc.GetBlockByHash(hash) if block == nil { return fmt.Errorf("non existent block [%x..]", hash[:4]) } + if !bc.chainmu.TryLock() { + return errChainStopped + } + defer bc.chainmu.Unlock() + // Reset the trie database with the fresh snap synced state. root := block.Root() if bc.triedb.Scheme() == rawdb.PathScheme { @@ -1108,19 +1177,16 @@ func (bc *BlockChain) SnapSyncCommitHead(hash common.Hash) error { if !bc.HasState(root) { return fmt.Errorf("non existent state [%x..]", root[:4]) } - // If all checks out, manually set the head block. - if !bc.chainmu.TryLock() { - return errChainStopped - } - bc.currentBlock.Store(block.Header()) - headBlockGauge.Update(int64(block.NumberU64())) - bc.chainmu.Unlock() - // Destroy any existing state snapshot and regenerate it in the background, // also resuming the normal maintenance of any previously paused snapshot. if bc.snaps != nil { bc.snaps.Rebuild(root) } + + // If all checks out, manually set the head block. + bc.currentBlock.Store(block.Header()) + headBlockGauge.Update(int64(block.NumberU64())) + log.Info("Committed new head block", "number", block.Number(), "hash", hash) return nil } @@ -1249,6 +1315,10 @@ func (bc *BlockChain) stopWithoutSaving() { // Signal shutdown to all goroutines. bc.InterruptInsert(true) + // Stop state size tracker + if bc.stateSizer != nil { + bc.stateSizer.Stop() + } // Now wait for all chain modifications to end and persistent goroutines to exit. // // Note: Close waits for the mutex to become available, i.e. any running chain @@ -1575,17 +1645,47 @@ func (bc *BlockChain) writeBlockWithState(block *types.Block, receipts []*types. // // Note all the components of block(hash->number map, header, body, receipts) // should be written atomically. BlockBatch is used for containing all components. - blockBatch := bc.db.NewBatch() - rawdb.WriteBlock(blockBatch, block) - rawdb.WriteReceipts(blockBatch, block.Hash(), block.NumberU64(), receipts) - rawdb.WritePreimages(blockBatch, statedb.Preimages()) - if err := blockBatch.Write(); err != nil { + var ( + batch = bc.db.NewBatch() + start = time.Now() + ) + rawdb.WriteBlock(batch, block) + rawdb.WriteReceipts(batch, block.Hash(), block.NumberU64(), receipts) + rawdb.WritePreimages(batch, statedb.Preimages()) + if err := batch.Write(); err != nil { log.Crit("Failed to write block into disk", "err", err) } - // Commit all cached state changes into underlying memory database. - root, err := statedb.Commit(block.NumberU64(), bc.chainConfig.IsEIP158(block.Number()), bc.chainConfig.IsCancun(block.Number(), block.Time())) - if err != nil { - return err + log.Debug("Committed block data", "size", common.StorageSize(batch.ValueSize()), "elapsed", common.PrettyDuration(time.Since(start))) + + var ( + err error + root common.Hash + isEIP158 = bc.chainConfig.IsEIP158(block.Number()) + isCancun = bc.chainConfig.IsCancun(block.Number(), block.Time()) + hasStateHook = bc.logger != nil && bc.logger.OnStateUpdate != nil + hasStateSizer = bc.stateSizer != nil + ) + if hasStateHook || hasStateSizer { + r, update, err := statedb.CommitWithUpdate(block.NumberU64(), isEIP158, isCancun) + if err != nil { + return err + } + if hasStateHook { + trUpdate, err := update.ToTracingUpdate() + if err != nil { + return err + } + bc.logger.OnStateUpdate(trUpdate) + } + if hasStateSizer { + bc.stateSizer.Notify(update) + } + root = r + } else { + root, err = statedb.Commit(block.NumberU64(), isEIP158, isCancun) + if err != nil { + return err + } } // If node is running in path mode, skip explicit gc operation // which is unnecessary in this mode. @@ -1665,7 +1765,12 @@ func (bc *BlockChain) writeBlockAndSetHead(block *types.Block, receipts []*types // Set new head. bc.writeHeadBlock(block) - bc.chainFeed.Send(ChainEvent{Header: block.Header()}) + bc.chainFeed.Send(ChainEvent{ + Header: block.Header(), + Receipts: receipts, + Transactions: block.Transactions(), + }) + if len(logs) > 0 { bc.logsFeed.Send(logs) } @@ -1817,7 +1922,7 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness // still need re-execution to generate snapshots that are missing case err != nil && !errors.Is(err, ErrKnownBlock): stats.ignored += len(it.chain) - bc.reportBlock(block, nil, err) + bc.reportBadBlock(block, nil, err) return nil, it.index, err } // Track the singleton witness from this chain insertion (if any) @@ -1881,10 +1986,18 @@ func (bc *BlockChain) insertChain(chain types.Blocks, setHead bool, makeWitness } // The traced section of block import. start := time.Now() - res, err := bc.processBlock(parent.Root, block, setHead, makeWitness && len(chain) == 1) + res, err := bc.ProcessBlock(parent.Root, block, setHead, makeWitness && len(chain) == 1) if err != nil { return nil, it.index, err } + res.stats.reportMetrics() + + // Log slow block only if a single block is inserted (usually after the + // initial sync) to not overwhelm the users. + if len(chain) == 1 { + res.stats.logSlow(block, bc.slowBlockThreshold) + } + // Report the import stats before returning the various results stats.processed++ stats.usedGas += res.usedGas @@ -1945,11 +2058,20 @@ type blockProcessingResult struct { procTime time.Duration status WriteStatus witness *stateless.Witness + stats *ExecuteStats } -// processBlock executes and validates the given block. If there was no error +func (bpr *blockProcessingResult) Witness() *stateless.Witness { + return bpr.witness +} + +func (bpr *blockProcessingResult) Stats() *ExecuteStats { + return bpr.stats +} + +// ProcessBlock executes and validates the given block. If there was no error // it writes the block and associated state to database. -func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, setHead bool, makeWitness bool) (_ *blockProcessingResult, blockEndErr error) { +func (bc *BlockChain) ProcessBlock(parentRoot common.Hash, block *types.Block, setHead bool, makeWitness bool) (result *blockProcessingResult, blockEndErr error) { var ( err error startTime = time.Now() @@ -1983,16 +2105,22 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s } // Upload the statistics of reader at the end defer func() { - stats := prefetch.GetStats() - accountCacheHitPrefetchMeter.Mark(stats.AccountHit) - accountCacheMissPrefetchMeter.Mark(stats.AccountMiss) - storageCacheHitPrefetchMeter.Mark(stats.StorageHit) - storageCacheMissPrefetchMeter.Mark(stats.StorageMiss) - stats = process.GetStats() - accountCacheHitMeter.Mark(stats.AccountHit) - accountCacheMissMeter.Mark(stats.AccountMiss) - storageCacheHitMeter.Mark(stats.StorageHit) - storageCacheMissMeter.Mark(stats.StorageMiss) + pStat := prefetch.GetStats() + accountCacheHitPrefetchMeter.Mark(pStat.AccountCacheHit) + accountCacheMissPrefetchMeter.Mark(pStat.AccountCacheMiss) + storageCacheHitPrefetchMeter.Mark(pStat.StorageCacheHit) + storageCacheMissPrefetchMeter.Mark(pStat.StorageCacheMiss) + + rStat := process.GetStats() + accountCacheHitMeter.Mark(rStat.AccountCacheHit) + accountCacheMissMeter.Mark(rStat.AccountCacheMiss) + storageCacheHitMeter.Mark(rStat.StorageCacheHit) + storageCacheMissMeter.Mark(rStat.StorageCacheMiss) + + if result != nil { + result.stats.StatePrefetchCacheStats = pStat + result.stats.StateReadCacheStats = rStat + } }() go func(start time.Time, throwaway *state.StateDB, block *types.Block) { @@ -2011,7 +2139,10 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s // If we are past Byzantium, enable prefetching to pull in trie node paths // while processing transactions. Before Byzantium the prefetcher is mostly // useless due to the intermediate root hashing after each transaction. - var witness *stateless.Witness + var ( + witness *stateless.Witness + witnessStats *stateless.WitnessStats + ) if bc.chainConfig.IsByzantium(block.Number()) { // Generate witnesses either if we're self-testing, or if it's the // only block being inserted. A bit crude, but witnesses are huge, @@ -2021,8 +2152,11 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s if err != nil { return nil, err } + if bc.cfg.VmConfig.EnableWitnessStats { + witnessStats = stateless.NewWitnessStats() + } } - statedb.StartPrefetcher("chain", witness) + statedb.StartPrefetcher("chain", witness, witnessStats) defer statedb.StopPrefetcher() } @@ -2043,14 +2177,14 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s pstart := time.Now() res, err := bc.processor.Process(block, statedb, bc.cfg.VmConfig) if err != nil { - bc.reportBlock(block, res, err) + bc.reportBadBlock(block, res, err) return nil, err } ptime := time.Since(pstart) vstart := time.Now() if err := bc.validator.ValidateState(block, statedb, res, false); err != nil { - bc.reportBlock(block, res, err) + bc.reportBadBlock(block, res, err) return nil, err } vtime := time.Since(vstart) @@ -2083,26 +2217,31 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s return nil, fmt.Errorf("stateless self-validation receipt root mismatch (cross: %x local: %x)", crossReceiptRoot, block.ReceiptHash()) } } - xvtime := time.Since(xvstart) - proctime := time.Since(startTime) // processing + validation + cross validation + var ( + xvtime = time.Since(xvstart) + proctime = time.Since(startTime) // processing + validation + cross validation + stats = &ExecuteStats{} + ) // Update the metrics touched during block processing and validation - accountReadTimer.Update(statedb.AccountReads) // Account reads are complete(in processing) - storageReadTimer.Update(statedb.StorageReads) // Storage reads are complete(in processing) - if statedb.AccountLoaded != 0 { - accountReadSingleTimer.Update(statedb.AccountReads / time.Duration(statedb.AccountLoaded)) - } - if statedb.StorageLoaded != 0 { - storageReadSingleTimer.Update(statedb.StorageReads / time.Duration(statedb.StorageLoaded)) - } - accountUpdateTimer.Update(statedb.AccountUpdates) // Account updates are complete(in validation) - storageUpdateTimer.Update(statedb.StorageUpdates) // Storage updates are complete(in validation) - accountHashTimer.Update(statedb.AccountHashes) // Account hashes are complete(in validation) - triehash := statedb.AccountHashes // The time spent on tries hashing - trieUpdate := statedb.AccountUpdates + statedb.StorageUpdates // The time spent on tries update - blockExecutionTimer.Update(ptime - (statedb.AccountReads + statedb.StorageReads)) // The time spent on EVM processing - blockValidationTimer.Update(vtime - (triehash + trieUpdate)) // The time spent on block validation - blockCrossValidationTimer.Update(xvtime) // The time spent on stateless cross validation + stats.AccountReads = statedb.AccountReads // Account reads are complete(in processing) + stats.StorageReads = statedb.StorageReads // Storage reads are complete(in processing) + stats.AccountUpdates = statedb.AccountUpdates // Account updates are complete(in validation) + stats.StorageUpdates = statedb.StorageUpdates // Storage updates are complete(in validation) + stats.AccountHashes = statedb.AccountHashes // Account hashes are complete(in validation) + stats.CodeReads = statedb.CodeReads + + stats.AccountLoaded = statedb.AccountLoaded + stats.AccountUpdated = statedb.AccountUpdated + stats.AccountDeleted = statedb.AccountDeleted + stats.StorageLoaded = statedb.StorageLoaded + stats.StorageUpdated = int(statedb.StorageUpdated.Load()) + stats.StorageDeleted = int(statedb.StorageDeleted.Load()) + stats.CodeLoaded = statedb.CodeLoaded + + stats.Execution = ptime - (statedb.AccountReads + statedb.StorageReads + statedb.CodeReads) // The time spent on EVM processing + stats.Validation = vtime - (statedb.AccountHashes + statedb.AccountUpdates + statedb.StorageUpdates) // The time spent on block validation + stats.CrossValidation = xvtime // The time spent on stateless cross validation // Write the block to the chain and get the status. var ( @@ -2118,25 +2257,28 @@ func (bc *BlockChain) processBlock(parentRoot common.Hash, block *types.Block, s if err != nil { return nil, err } + // Report the collected witness statistics + if witnessStats != nil { + witnessStats.ReportMetrics(block.NumberU64()) + } + // Update the metrics touched during block commit - accountCommitTimer.Update(statedb.AccountCommits) // Account commits are complete, we can mark them - storageCommitTimer.Update(statedb.StorageCommits) // Storage commits are complete, we can mark them - snapshotCommitTimer.Update(statedb.SnapshotCommits) // Snapshot commits are complete, we can mark them - triedbCommitTimer.Update(statedb.TrieDBCommits) // Trie database commits are complete, we can mark them + stats.AccountCommits = statedb.AccountCommits // Account commits are complete, we can mark them + stats.StorageCommits = statedb.StorageCommits // Storage commits are complete, we can mark them + stats.SnapshotCommit = statedb.SnapshotCommits // Snapshot commits are complete, we can mark them + stats.TrieDBCommit = statedb.TrieDBCommits // Trie database commits are complete, we can mark them + stats.BlockWrite = time.Since(wstart) - max(statedb.AccountCommits, statedb.StorageCommits) /* concurrent */ - statedb.SnapshotCommits - statedb.TrieDBCommits - blockWriteTimer.Update(time.Since(wstart) - max(statedb.AccountCommits, statedb.StorageCommits) /* concurrent */ - statedb.SnapshotCommits - statedb.TrieDBCommits) elapsed := time.Since(startTime) + 1 // prevent zero division - blockInsertTimer.Update(elapsed) - - // TODO(rjl493456442) generalize the ResettingTimer - mgasps := float64(res.GasUsed) * 1000 / float64(elapsed) - chainMgaspsMeter.Update(time.Duration(mgasps)) + stats.TotalTime = elapsed + stats.MgasPerSecond = float64(res.GasUsed) * 1000 / float64(elapsed) return &blockProcessingResult{ usedGas: res.GasUsed, procTime: proctime, status: status, witness: witness, + stats: stats, }, nil } @@ -2301,6 +2443,13 @@ func (bc *BlockChain) recoverAncestors(block *types.Block, makeWitness bool) (co // collectLogs collects the logs that were generated or removed during the // processing of a block. These logs are later announced as deleted or reborn. func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log { + _, logs := bc.collectReceiptsAndLogs(b, removed) + return logs +} + +// collectReceiptsAndLogs retrieves receipts from the database and returns both receipts and logs. +// This avoids duplicate database reads when both are needed. +func (bc *BlockChain) collectReceiptsAndLogs(b *types.Block, removed bool) ([]*types.Receipt, []*types.Log) { var blobGasPrice *big.Int if b.ExcessBlobGas() != nil { blobGasPrice = eip4844.CalcBlobFee(bc.chainConfig, b.Header()) @@ -2318,7 +2467,7 @@ func (bc *BlockChain) collectLogs(b *types.Block, removed bool) []*types.Log { logs = append(logs, log) } } - return logs + return receipts, logs } // reorg takes two blocks, an old chain and a new chain and will reconstruct the @@ -2547,8 +2696,14 @@ func (bc *BlockChain) SetCanonical(head *types.Block) (common.Hash, error) { bc.writeHeadBlock(head) // Emit events - logs := bc.collectLogs(head, false) - bc.chainFeed.Send(ChainEvent{Header: head.Header()}) + receipts, logs := bc.collectReceiptsAndLogs(head, false) + + bc.chainFeed.Send(ChainEvent{ + Header: head.Header(), + Receipts: receipts, + Transactions: head.Transactions(), + }) + if len(logs) > 0 { bc.logsFeed.Send(logs) } @@ -2608,8 +2763,8 @@ func (bc *BlockChain) skipBlock(err error, it *insertIterator) bool { return false } -// reportBlock logs a bad block error. -func (bc *BlockChain) reportBlock(block *types.Block, res *ProcessResult, err error) { +// reportBadBlock logs a bad block error. +func (bc *BlockChain) reportBadBlock(block *types.Block, res *ProcessResult, err error) { var receipts types.Receipts if res != nil { receipts = res.Receipts @@ -2621,13 +2776,11 @@ func (bc *BlockChain) reportBlock(block *types.Block, res *ProcessResult, err er // logForkReadiness will write a log when a future fork is scheduled, but not // active. This is useful so operators know their client is ready for the fork. func (bc *BlockChain) logForkReadiness(block *types.Block) { - config := bc.Config() - current, last := config.LatestFork(block.Time()), config.LatestFork(math.MaxUint64) + current := bc.Config().LatestFork(block.Time()) - // Short circuit if the timestamp of the last fork is undefined, - // or if the network has already passed the last configured fork. - t := config.Timestamp(last) - if t == nil || current >= last { + // Short circuit if the timestamp of the last fork is undefined. + t := bc.Config().Timestamp(current + 1) + if t == nil { return } at := time.Unix(int64(*t), 0) @@ -2637,7 +2790,7 @@ func (bc *BlockChain) logForkReadiness(block *types.Block) { // - Enough time has passed since last alert now := time.Now() if now.Before(at) && now.After(bc.lastForkReadyAlert.Add(forkReadyInterval)) { - log.Info("Ready for fork activation", "fork", last, "date", at.Format(time.RFC822), + log.Info("Ready for fork activation", "fork", current+1, "date", at.Format(time.RFC822), "remaining", time.Until(at).Round(time.Second), "timestamp", at.Unix()) bc.lastForkReadyAlert = time.Now() } @@ -2776,3 +2929,8 @@ func (bc *BlockChain) SetTrieFlushInterval(interval time.Duration) { func (bc *BlockChain) GetTrieFlushInterval() time.Duration { return time.Duration(bc.flushInterval.Load()) } + +// StateSizer returns the state size tracker, or nil if it's not initialized +func (bc *BlockChain) StateSizer() *state.SizeTracker { + return bc.stateSizer +} diff --git a/core/blockchain_insert.go b/core/blockchain_insert.go index ac6a156d3e..07a250a1bb 100644 --- a/core/blockchain_insert.go +++ b/core/blockchain_insert.go @@ -131,28 +131,6 @@ func (it *insertIterator) next() (*types.Block, error) { return it.chain[it.index], it.validator.ValidateBody(it.chain[it.index]) } -// peek returns the next block in the iterator, along with any potential validation -// error for that block, but does **not** advance the iterator. -// -// Both header and body validation errors (nil too) is cached into the iterator -// to avoid duplicating work on the following next() call. -// nolint:unused -func (it *insertIterator) peek() (*types.Block, error) { - // If we reached the end of the chain, abort - if it.index+1 >= len(it.chain) { - return nil, nil - } - // Wait for verification result if not yet done - if len(it.errors) <= it.index+1 { - it.errors = append(it.errors, <-it.results) - } - if it.errors[it.index+1] != nil { - return it.chain[it.index+1], it.errors[it.index+1] - } - // Block header valid, ignore body validation since we don't have a parent anyway - return it.chain[it.index+1], nil -} - // previous returns the previous header that was being processed, or nil. func (it *insertIterator) previous() *types.Header { if it.index < 1 { diff --git a/core/blockchain_reader.go b/core/blockchain_reader.go index 4894523b0e..ee15c152c4 100644 --- a/core/blockchain_reader.go +++ b/core/blockchain_reader.go @@ -522,3 +522,13 @@ func (bc *BlockChain) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscript func (bc *BlockChain) SubscribeBlockProcessingEvent(ch chan<- bool) event.Subscription { return bc.scope.Track(bc.blockProcFeed.Subscribe(ch)) } + +// SubscribeNewPayloadEvent registers a subscription for NewPayloadEvent. +func (bc *BlockChain) SubscribeNewPayloadEvent(ch chan<- NewPayloadEvent) event.Subscription { + return bc.scope.Track(bc.newPayloadFeed.Subscribe(ch)) +} + +// SendNewPayloadEvent sends a NewPayloadEvent to subscribers. +func (bc *BlockChain) SendNewPayloadEvent(ev NewPayloadEvent) { + bc.newPayloadFeed.Send(ev) +} diff --git a/core/blockchain_stats.go b/core/blockchain_stats.go new file mode 100644 index 0000000000..b6e9c614c5 --- /dev/null +++ b/core/blockchain_stats.go @@ -0,0 +1,165 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package core + +import ( + "fmt" + "strings" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +// ExecuteStats includes all the statistics of a block execution in details. +type ExecuteStats struct { + // State read times + AccountReads time.Duration // Time spent on the account reads + StorageReads time.Duration // Time spent on the storage reads + AccountHashes time.Duration // Time spent on the account trie hash + AccountUpdates time.Duration // Time spent on the account trie update + AccountCommits time.Duration // Time spent on the account trie commit + StorageUpdates time.Duration // Time spent on the storage trie update + StorageCommits time.Duration // Time spent on the storage trie commit + CodeReads time.Duration // Time spent on the contract code read + + AccountLoaded int // Number of accounts loaded + AccountUpdated int // Number of accounts updated + AccountDeleted int // Number of accounts deleted + StorageLoaded int // Number of storage slots loaded + StorageUpdated int // Number of storage slots updated + StorageDeleted int // Number of storage slots deleted + CodeLoaded int // Number of contract code loaded + + Execution time.Duration // Time spent on the EVM execution + Validation time.Duration // Time spent on the block validation + CrossValidation time.Duration // Optional, time spent on the block cross validation + SnapshotCommit time.Duration // Time spent on snapshot commit + TrieDBCommit time.Duration // Time spent on database commit + BlockWrite time.Duration // Time spent on block write + TotalTime time.Duration // The total time spent on block execution + MgasPerSecond float64 // The million gas processed per second + + // Cache hit rates + StateReadCacheStats state.ReaderStats + StatePrefetchCacheStats state.ReaderStats +} + +// reportMetrics uploads execution statistics to the metrics system. +func (s *ExecuteStats) reportMetrics() { + if s.AccountLoaded != 0 { + accountReadTimer.Update(s.AccountReads) + accountReadSingleTimer.Update(s.AccountReads / time.Duration(s.AccountLoaded)) + } + if s.StorageLoaded != 0 { + storageReadTimer.Update(s.StorageReads) + storageReadSingleTimer.Update(s.StorageReads / time.Duration(s.StorageLoaded)) + } + if s.CodeLoaded != 0 { + codeReadTimer.Update(s.CodeReads) + codeReadSingleTimer.Update(s.CodeReads / time.Duration(s.CodeLoaded)) + } + accountUpdateTimer.Update(s.AccountUpdates) // Account updates are complete(in validation) + storageUpdateTimer.Update(s.StorageUpdates) // Storage updates are complete(in validation) + accountHashTimer.Update(s.AccountHashes) // Account hashes are complete(in validation) + accountCommitTimer.Update(s.AccountCommits) // Account commits are complete, we can mark them + storageCommitTimer.Update(s.StorageCommits) // Storage commits are complete, we can mark them + + blockExecutionTimer.Update(s.Execution) // The time spent on EVM processing + blockValidationTimer.Update(s.Validation) // The time spent on block validation + blockCrossValidationTimer.Update(s.CrossValidation) // The time spent on stateless cross validation + snapshotCommitTimer.Update(s.SnapshotCommit) // Snapshot commits are complete, we can mark them + triedbCommitTimer.Update(s.TrieDBCommit) // Trie database commits are complete, we can mark them + blockWriteTimer.Update(s.BlockWrite) // The time spent on block write + blockInsertTimer.Update(s.TotalTime) // The total time spent on block execution + chainMgaspsMeter.Update(time.Duration(s.MgasPerSecond)) // TODO(rjl493456442) generalize the ResettingTimer + + // Cache hit rates + accountCacheHitPrefetchMeter.Mark(s.StatePrefetchCacheStats.AccountCacheHit) + accountCacheMissPrefetchMeter.Mark(s.StatePrefetchCacheStats.AccountCacheMiss) + storageCacheHitPrefetchMeter.Mark(s.StatePrefetchCacheStats.StorageCacheHit) + storageCacheMissPrefetchMeter.Mark(s.StatePrefetchCacheStats.StorageCacheMiss) + + accountCacheHitMeter.Mark(s.StateReadCacheStats.AccountCacheHit) + accountCacheMissMeter.Mark(s.StateReadCacheStats.AccountCacheMiss) + storageCacheHitMeter.Mark(s.StateReadCacheStats.StorageCacheHit) + storageCacheMissMeter.Mark(s.StateReadCacheStats.StorageCacheMiss) +} + +// logSlow prints the detailed execution statistics if the block is regarded as slow. +func (s *ExecuteStats) logSlow(block *types.Block, slowBlockThreshold time.Duration) { + if slowBlockThreshold == 0 { + return + } + if s.TotalTime < slowBlockThreshold { + return + } + msg := fmt.Sprintf(` +########## SLOW BLOCK ######### +Block: %v (%#x) txs: %d, mgasps: %.2f, elapsed: %v + +EVM execution: %v + +Validation: %v + Account hash: %v + Storage hash: %v + +State read: %v + Account read: %v(%d) + Storage read: %v(%d) + Code read: %v(%d) + +State write: %v + Trie commit: %v + State write: %v + Block write: %v + +%s +############################## +`, block.Number(), block.Hash(), len(block.Transactions()), s.MgasPerSecond, common.PrettyDuration(s.TotalTime), + // EVM execution + common.PrettyDuration(s.Execution), + + // Block validation + common.PrettyDuration(s.Validation+s.CrossValidation+s.AccountHashes+s.AccountUpdates+s.StorageUpdates), + common.PrettyDuration(s.AccountHashes+s.AccountUpdates), + common.PrettyDuration(s.StorageUpdates), + + // State read + common.PrettyDuration(s.AccountReads+s.StorageReads+s.CodeReads), + common.PrettyDuration(s.AccountReads), s.AccountLoaded, + common.PrettyDuration(s.StorageReads), s.StorageLoaded, + common.PrettyDuration(s.CodeReads), s.CodeLoaded, + + // State write + common.PrettyDuration(max(s.AccountCommits, s.StorageCommits)+s.TrieDBCommit+s.SnapshotCommit+s.BlockWrite), + common.PrettyDuration(max(s.AccountCommits, s.StorageCommits)), + common.PrettyDuration(s.TrieDBCommit+s.SnapshotCommit), + common.PrettyDuration(s.BlockWrite), + + // cache statistics + s.StateReadCacheStats, + ) + for _, line := range strings.Split(msg, "\n") { + if line == "" { + continue + } + log.Info(line) + } +} diff --git a/core/blockchain_test.go b/core/blockchain_test.go index b749798f9c..73ffce93fb 100644 --- a/core/blockchain_test.go +++ b/core/blockchain_test.go @@ -162,12 +162,12 @@ func testBlockChainImport(chain types.Blocks, blockchain *BlockChain) error { } res, err := blockchain.processor.Process(block, statedb, vm.Config{}) if err != nil { - blockchain.reportBlock(block, res, err) + blockchain.reportBadBlock(block, res, err) return err } err = blockchain.validator.ValidateState(block, statedb, res, false) if err != nil { - blockchain.reportBlock(block, res, err) + blockchain.reportBadBlock(block, res, err) return err } @@ -4515,3 +4515,45 @@ func TestGetCanonicalReceipt(t *testing.T) { } } } + +// TestSetHeadBeyondRootFinalizedBug tests the issue where the finalized block +// is not cleared when rewinding past it using setHeadBeyondRoot. +func TestSetHeadBeyondRootFinalizedBug(t *testing.T) { + // Create a clean blockchain with 100 blocks using PathScheme (PBSS) + _, _, blockchain, err := newCanonical(ethash.NewFaker(), 100, true, rawdb.PathScheme) + if err != nil { + t.Fatalf("failed to create pristine chain: %v", err) + } + defer blockchain.Stop() + + // Set the "Finalized" marker to the current Head (Block 100) + headBlock := blockchain.CurrentBlock() + if headBlock.Number.Uint64() != 100 { + t.Fatalf("Setup failed: expected head 100, got %d", headBlock.Number.Uint64()) + } + blockchain.SetFinalized(headBlock) + + // Verify setup + if blockchain.CurrentFinalBlock().Number.Uint64() != 100 { + t.Fatalf("Setup failed: Finalized block should be 100") + } + targetBlock := blockchain.GetBlockByNumber(50) + + // Call setHeadBeyondRoot with: + // head = 100 + // repair = true + if _, err := blockchain.setHeadBeyondRoot(100, 0, targetBlock.Root(), true); err != nil { + t.Fatalf("Failed to rewind: %v", err) + } + + currentFinal := blockchain.CurrentFinalBlock() + currentHead := blockchain.CurrentBlock().Number.Uint64() + + // The previous finalized block (100) is now invalid because we rewound to 50. + // The function should have cleared the finalized marker (set to nil). + if currentFinal != nil && currentFinal.Number.Uint64() > currentHead { + t.Errorf("Chain Head: %d , Finalized Block: %d , Finalized block was >= head block.", + currentHead, + currentFinal.Number.Uint64()) + } +} diff --git a/core/chain_makers.go b/core/chain_makers.go index af55716cca..7ce86b14e9 100644 --- a/core/chain_makers.go +++ b/core/chain_makers.go @@ -32,7 +32,6 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/triedb" - "github.com/ethereum/go-verkle" "github.com/holiman/uint256" ) @@ -427,7 +426,11 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse } // Forcibly use hash-based state scheme for retaining all nodes in disk. - triedb := triedb.NewDatabase(db, triedb.HashDefaults) + var triedbConfig *triedb.Config = triedb.HashDefaults + if config.IsVerkle(config.ChainID, 0) { + triedbConfig = triedb.VerkleDefaults + } + triedb := triedb.NewDatabase(db, triedbConfig) defer triedb.Close() for i := 0; i < n; i++ { @@ -472,9 +475,13 @@ func GenerateChain(config *params.ChainConfig, parent *types.Block, engine conse // then generate chain on top. func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (ethdb.Database, []*types.Block, []types.Receipts) { db := rawdb.NewMemoryDatabase() - triedb := triedb.NewDatabase(db, triedb.HashDefaults) + var triedbConfig *triedb.Config = triedb.HashDefaults + if genesis.Config != nil && genesis.Config.IsVerkle(genesis.Config.ChainID, 0) { + triedbConfig = triedb.VerkleDefaults + } + triedb := triedb.NewDatabase(db, triedbConfig) defer triedb.Close() - _, err := genesis.Commit(db, triedb) + _, err := genesis.Commit(db, triedb, nil) if err != nil { panic(err) } @@ -482,117 +489,6 @@ func GenerateChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, return db, blocks, receipts } -func GenerateVerkleChain(config *params.ChainConfig, parent *types.Block, engine consensus.Engine, db ethdb.Database, trdb *triedb.Database, n int, gen func(int, *BlockGen)) ([]*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { - if config == nil { - config = params.TestChainConfig - } - proofs := make([]*verkle.VerkleProof, 0, n) - keyvals := make([]verkle.StateDiff, 0, n) - cm := newChainMaker(parent, config, engine) - - genblock := func(i int, parent *types.Block, triedb *triedb.Database, statedb *state.StateDB) (*types.Block, types.Receipts) { - b := &BlockGen{i: i, cm: cm, parent: parent, statedb: statedb, engine: engine} - b.header = cm.makeHeader(parent, statedb, b.engine) - - // TODO uncomment when proof generation is merged - // Save pre state for proof generation - // preState := statedb.Copy() - - // EIP-2935 / 7709 - blockContext := NewEVMBlockContext(b.header, cm, &b.header.Coinbase) - blockContext.Random = &common.Hash{} // enable post-merge instruction set - evm := vm.NewEVM(blockContext, statedb, cm.config, vm.Config{}) - ProcessParentBlockHash(b.header.ParentHash, evm) - - // Execute any user modifications to the block. - if gen != nil { - gen(i, b) - } - - requests := b.collectRequests(false) - if requests != nil { - reqHash := types.CalcRequestsHash(requests) - b.header.RequestsHash = &reqHash - } - - body := &types.Body{ - Transactions: b.txs, - Uncles: b.uncles, - Withdrawals: b.withdrawals, - } - block, err := b.engine.FinalizeAndAssemble(cm, b.header, statedb, body, b.receipts) - if err != nil { - panic(err) - } - - // Write state changes to DB. - root, err := statedb.Commit(b.header.Number.Uint64(), config.IsEIP158(b.header.Number), config.IsCancun(b.header.Number, b.header.Time)) - if err != nil { - panic(fmt.Sprintf("state write error: %v", err)) - } - if err = triedb.Commit(root, false); err != nil { - panic(fmt.Sprintf("trie write error: %v", err)) - } - - proofs = append(proofs, block.ExecutionWitness().VerkleProof) - keyvals = append(keyvals, block.ExecutionWitness().StateDiff) - - return block, b.receipts - } - - sdb := state.NewDatabase(trdb, nil) - - for i := 0; i < n; i++ { - statedb, err := state.New(parent.Root(), sdb) - if err != nil { - panic(err) - } - block, receipts := genblock(i, parent, trdb, statedb) - - // Post-process the receipts. - // Here we assign the final block hash and other info into the receipt. - // In order for DeriveFields to work, the transaction and receipt lists need to be - // of equal length. If AddUncheckedTx or AddUncheckedReceipt are used, there will be - // extra ones, so we just trim the lists here. - receiptsCount := len(receipts) - txs := block.Transactions() - if len(receipts) > len(txs) { - receipts = receipts[:len(txs)] - } else if len(receipts) < len(txs) { - txs = txs[:len(receipts)] - } - var blobGasPrice *big.Int - if block.ExcessBlobGas() != nil { - blobGasPrice = eip4844.CalcBlobFee(cm.config, block.Header()) - } - if err := receipts.DeriveFields(config, block.Hash(), block.NumberU64(), block.Time(), block.BaseFee(), blobGasPrice, txs); err != nil { - panic(err) - } - - // Re-expand to ensure all receipts are returned. - receipts = receipts[:receiptsCount] - - // Advance the chain. - cm.add(block, receipts) - parent = block - } - return cm.chain, cm.receipts, proofs, keyvals -} - -func GenerateVerkleChainWithGenesis(genesis *Genesis, engine consensus.Engine, n int, gen func(int, *BlockGen)) (common.Hash, ethdb.Database, []*types.Block, []types.Receipts, []*verkle.VerkleProof, []verkle.StateDiff) { - db := rawdb.NewMemoryDatabase() - cacheConfig := DefaultConfig().WithStateScheme(rawdb.PathScheme) - cacheConfig.SnapshotLimit = 0 - triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) - defer triedb.Close() - genesisBlock, err := genesis.Commit(db, triedb) - if err != nil { - panic(err) - } - blocks, receipts, proofs, keyvals := GenerateVerkleChain(genesis.Config, genesisBlock, engine, db, triedb, n, gen) - return genesisBlock.Hash(), db, blocks, receipts, proofs, keyvals -} - func (cm *chainMaker) makeHeader(parent *types.Block, state *state.StateDB, engine consensus.Engine) *types.Header { time := parent.Time() + 10 // block time is fixed at 10 seconds parentHeader := parent.Header() diff --git a/core/events.go b/core/events.go index 5ad2cb1f7b..ed853f1790 100644 --- a/core/events.go +++ b/core/events.go @@ -17,6 +17,9 @@ package core import ( + "time" + + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" ) @@ -27,9 +30,18 @@ type NewTxsEvent struct{ Txs []*types.Transaction } type RemovedLogsEvent struct{ Logs []*types.Log } type ChainEvent struct { - Header *types.Header + Header *types.Header + Receipts []*types.Receipt + Transactions []*types.Transaction } type ChainHeadEvent struct { Header *types.Header } + +// NewPayloadEvent is posted when engine_newPayloadVX processes a block. +type NewPayloadEvent struct { + Hash common.Hash + Number uint64 + ProcessingTime time.Duration +} diff --git a/core/evm.go b/core/evm.go index 41b4e6ac58..18d940fdd2 100644 --- a/core/evm.go +++ b/core/evm.go @@ -25,21 +25,16 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" ) // ChainContext supports retrieving headers and consensus parameters from the // current blockchain to be used during transaction processing. type ChainContext interface { + consensus.ChainHeaderReader + // Engine retrieves the chain's consensus engine. Engine() consensus.Engine - - // GetHeader returns the header corresponding to the hash/number argument pair. - GetHeader(common.Hash, uint64) *types.Header - - // Config returns the chain's configuration. - Config() *params.ChainConfig } // NewEVMBlockContext creates a new context for use in the EVM. diff --git a/core/filtermaps/checkpoints_mainnet.json b/core/filtermaps/checkpoints_mainnet.json index 2ea065ddb7..795967405d 100644 --- a/core/filtermaps/checkpoints_mainnet.json +++ b/core/filtermaps/checkpoints_mainnet.json @@ -288,5 +288,32 @@ {"blockNumber": 22958100, "blockId": "0xe38e0ff7b0c4065ca42ea577bc32f2566ca46f2ddeedcc4bc1f8fb00e7f26329", "firstIndex": 19260242424}, {"blockNumber": 22988600, "blockId": "0x04ca74758b22e0ea54b8c992022ff21c16a2af9c45144c3b0f80de921a7eee82", "firstIndex": 19327351273}, {"blockNumber": 23018392, "blockId": "0x61cc979b00bc97b48356f986a5b9ec997d674bc904c2a2e4b0f17de08e50b3bb", "firstIndex": 19394459627}, -{"blockNumber": 23048524, "blockId": "0x489de15d95739ede4ab15e8b5151d80d4dc85ae10e7be800b1a4723094a678df", "firstIndex": 19461570073} +{"blockNumber": 23048524, "blockId": "0x489de15d95739ede4ab15e8b5151d80d4dc85ae10e7be800b1a4723094a678df", "firstIndex": 19461570073}, +{"blockNumber": 23078983, "blockId": "0xd64da4fe45a0a349101b8ce1a6336fb099d8b00cc274d0eb59356e134190b8f2", "firstIndex": 19528679292}, +{"blockNumber": 23109224, "blockId": "0xbb6c29f91820fcf6caef881bdfe61eb690f9796f8f139c56eaf27aa601fe5ed2", "firstIndex": 19595787850}, +{"blockNumber": 23136690, "blockId": "0xc1915739edff731d469ec1500ad05102c0d68cc1ef062411d2e9741b8ebdc571", "firstIndex": 19662896969}, +{"blockNumber": 23164324, "blockId": "0x97d0078f2a22a8fbde4660d5f11846d00a669c606e42291df55e863190914a9f", "firstIndex": 19730004997}, +{"blockNumber": 23192975, "blockId": "0x8463749ec09f55fccdd962498f93d6468d744faedc35da8097642cd4609e08f2", "firstIndex": 19797111604}, +{"blockNumber": 23219805, "blockId": "0x76ca51d01b5724f1b0f6c3acb50dfcdb00e1648a475dd7599174b301c25e5517", "firstIndex": 19864222312}, +{"blockNumber": 23236331, "blockId": "0x388f9e36b3ec2120d2b4adfdcdb0c0b8de139eef107e327670dd77fc581c2c5f", "firstIndex": 19931331831}, +{"blockNumber": 23260849, "blockId": "0xe4a467164dbc8f9beebf0c8478a9e7ee16dfce65e2da423b1048601831222ba7", "firstIndex": 19998441286}, +{"blockNumber": 23282795, "blockId": "0x74ad210aa1bfdd4bcf61298ebff622da758c36c38d62d001f2440d09e73ef6c7", "firstIndex": 20065548083}, +{"blockNumber": 23300759, "blockId": "0xa405f5ea21a5207d3cde718a1e3fb7f0ce3dd87ac6040a0db52da0e9488e63f6", "firstIndex": 20132623334}, +{"blockNumber": 23319772, "blockId": "0xafae645dd057af450eddf69c7604bde0136524abc5b7d6697426427ef2d30724", "firstIndex": 20199767615}, +{"blockNumber": 23342113, "blockId": "0x8482c4be13294cfd862d500051c8b4efb95b50f4a79717da6aeabb2a6ff3e199", "firstIndex": 20266874986}, +{"blockNumber": 23366974, "blockId": "0xf6047cafea5da7aaf20691df700d759fe84f5aa2176d9dd42c6ae138899a29ea", "firstIndex": 20333983351}, +{"blockNumber": 23397579, "blockId": "0xe94815fe0278659a26e15b023c0c3877abf6f1265710c5dfddf161ee8af01b40", "firstIndex": 20401094335}, +{"blockNumber": 23425940, "blockId": "0xa98d6d48b93d9ef848c340b47cf9d191f36e76375dd747d8adcb39d72251822d", "firstIndex": 20468200506}, +{"blockNumber": 23452402, "blockId": "0x5f26ff308c0883a04f4a92411bcd05e50538d95a96532452f43b71fde4af908d", "firstIndex": 20535311178}, +{"blockNumber": 23478884, "blockId": "0x23a81186c21218f7034ee81dcd72db71edcbc0e97da26703b8026b6d4a81f693", "firstIndex": 20602384106}, +{"blockNumber": 23507136, "blockId": "0xb1d4a2bd836c5d78b678f0bfffd651bdfeae8b7965639b640f8745193b142323", "firstIndex": 20669529935}, +{"blockNumber": 23535463, "blockId": "0x1886a719a6376352753242ec5093c434938b9a90356facdbdaafd2670da97d82", "firstIndex": 20736637374}, +{"blockNumber": 23564278, "blockId": "0xcdc5a1349f45430771fa2080555f20b80b2d84f575728dbb8bd3b633fbb0a00b", "firstIndex": 20803747399}, +{"blockNumber": 23594711, "blockId": "0xbbf41e407367feeb865b305e38aee8bef84ba62b66efbd6fcd3b16a5d50cc055", "firstIndex": 20870854523}, +{"blockNumber": 23627417, "blockId": "0x1b3c6bd39c5aa7c73101e7e946964b3d7afecf3f253efda8de5610dd99cbee82", "firstIndex": 20937963176}, +{"blockNumber": 23660347, "blockId": "0xadc8ac88c281f50c3aaf1d08149100e8f91a16bbe09b28ac86665bcea681d41b", "firstIndex": 21005072865}, +{"blockNumber": 23692228, "blockId": "0xeb4040468161d9d5b6863eb62e4f21f72a1944f910ecfa95ee6a9dbc39e92ef0", "firstIndex": 21072181753}, +{"blockNumber": 23722331, "blockId": "0xdfc9be1b43488148868da0c8ac56e99e0ffde18bcc418755c4765e745fe74024", "firstIndex": 21139291342}, +{"blockNumber": 23752866, "blockId": "0xb9cf0dfee429a1450f5fb7a237729cf7d0c49e7e35c00dc3709f197c091f8b39", "firstIndex": 21206399901}, +{"blockNumber": 23784485, "blockId": "0x92f5f119078b4ef7ad99273e2ae6f874cfb663e80d741a821e0bb7c25c0369c7", "firstIndex": 21273505141} ] diff --git a/core/filtermaps/filtermaps.go b/core/filtermaps/filtermaps.go index fede54df57..f6b1ef26d0 100644 --- a/core/filtermaps/filtermaps.go +++ b/core/filtermaps/filtermaps.go @@ -434,7 +434,7 @@ func (f *FilterMaps) safeDeleteWithLogs(deleteFn func(db ethdb.KeyValueStore, ha lastLogPrinted = start ) switch err := deleteFn(f.db, f.hashScheme, func(deleted bool) bool { - if deleted && !logPrinted || time.Since(lastLogPrinted) > time.Second*10 { + if deleted && (!logPrinted || time.Since(lastLogPrinted) > time.Second*10) { log.Info(action+" in progress...", "elapsed", common.PrettyDuration(time.Since(start))) logPrinted, lastLogPrinted = true, time.Now() } diff --git a/core/filtermaps/indexer.go b/core/filtermaps/indexer.go index 3571f9f375..ca50fb466c 100644 --- a/core/filtermaps/indexer.go +++ b/core/filtermaps/indexer.go @@ -30,7 +30,7 @@ const ( headLogDelay = time.Second // head indexing log info delay (do not log if finished faster) ) -// updateLoop initializes and updates the log index structure according to the +// indexerLoop initializes and updates the log index structure according to the // current targetView. func (f *FilterMaps) indexerLoop() { defer f.closeWg.Done() @@ -221,7 +221,7 @@ func (f *FilterMaps) processSingleEvent(blocking bool) bool { return true } -// setTargetView updates the target chain view of the iterator. +// setTarget updates the target chain view of the iterator. func (f *FilterMaps) setTarget(target targetUpdate) { f.targetView = target.targetView f.historyCutoff = target.historyCutoff diff --git a/core/filtermaps/math.go b/core/filtermaps/math.go index 33ac07f721..68fd6debd6 100644 --- a/core/filtermaps/math.go +++ b/core/filtermaps/math.go @@ -22,7 +22,7 @@ import ( "fmt" "hash/fnv" "math" - "sort" + "slices" "github.com/ethereum/go-ethereum/common" ) @@ -245,7 +245,7 @@ func (p *Params) potentialMatches(rows []FilterRow, mapIndex uint32, logValue co panic("potentialMatches: insufficient list of row alternatives") } } - sort.Sort(results) + slices.Sort(results) // remove duplicates j := 0 for i, match := range results { @@ -260,12 +260,7 @@ func (p *Params) potentialMatches(rows []FilterRow, mapIndex uint32, logValue co // potentialMatches is a strictly monotonically increasing list of log value // indices in the range of a filter map that are potential matches for certain // filter criteria. -// potentialMatches implements sort.Interface. // Note that nil is used as a wildcard and therefore means that all log value // indices in the filter map range are potential matches. If there are no // potential matches in the given map's range then an empty slice should be used. type potentialMatches []uint64 - -func (p potentialMatches) Len() int { return len(p) } -func (p potentialMatches) Less(i, j int) bool { return p[i] < p[j] } -func (p potentialMatches) Swap(i, j int) { p[i], p[j] = p[j], p[i] } diff --git a/core/forkid/forkid_test.go b/core/forkid/forkid_test.go index 413e4d77a8..c78ff23cd6 100644 --- a/core/forkid/forkid_test.go +++ b/core/forkid/forkid_test.go @@ -76,10 +76,16 @@ func TestCreation(t *testing.T) { {20000000, 1681338454, ID{Hash: checksumToBytes(0xf0afd0e3), Next: 1681338455}}, // Last Gray Glacier block {20000000, 1681338455, ID{Hash: checksumToBytes(0xdce96c2d), Next: 1710338135}}, // First Shanghai block {30000000, 1710338134, ID{Hash: checksumToBytes(0xdce96c2d), Next: 1710338135}}, // Last Shanghai block - {40000000, 1710338135, ID{Hash: checksumToBytes(0x9f3d2254), Next: 1746612311}}, // First Cancun block + {30000000, 1710338135, ID{Hash: checksumToBytes(0x9f3d2254), Next: 1746612311}}, // First Cancun block {30000000, 1746022486, ID{Hash: checksumToBytes(0x9f3d2254), Next: 1746612311}}, // Last Cancun block - {30000000, 1746612311, ID{Hash: checksumToBytes(0xc376cf8b), Next: 0}}, // First Prague block - {50000000, 2000000000, ID{Hash: checksumToBytes(0xc376cf8b), Next: 0}}, // Future Prague block + {30000000, 1746612311, ID{Hash: checksumToBytes(0xc376cf8b), Next: 1764798551}}, // First Prague block + {30000000, 1764798550, ID{Hash: checksumToBytes(0xc376cf8b), Next: 1764798551}}, // Last Prague block + {30000000, 1764798551, ID{Hash: checksumToBytes(0x5167e2a6), Next: 1765290071}}, // First Osaka block + {30000000, 1765290070, ID{Hash: checksumToBytes(0x5167e2a6), Next: 1765290071}}, // Last Osaka block + {30000000, 1765290071, ID{Hash: checksumToBytes(0xcba2a1c0), Next: 1767747671}}, // First BPO1 block + {30000000, 1767747670, ID{Hash: checksumToBytes(0xcba2a1c0), Next: 1767747671}}, // Last BPO1 block + {30000000, 1767747671, ID{Hash: checksumToBytes(0x07c9462e), Next: 0}}, // First BPO2 block + {50000000, 2000000000, ID{Hash: checksumToBytes(0x07c9462e), Next: 0}}, // Future BPO2 block }, }, // Sepolia test cases @@ -95,8 +101,14 @@ func TestCreation(t *testing.T) { {1735372, 1706655071, ID{Hash: checksumToBytes(0xf7f9bc08), Next: 1706655072}}, // Last Shanghai block {1735372, 1706655072, ID{Hash: checksumToBytes(0x88cf81d9), Next: 1741159776}}, // First Cancun block {1735372, 1741159775, ID{Hash: checksumToBytes(0x88cf81d9), Next: 1741159776}}, // Last Cancun block - {1735372, 1741159776, ID{Hash: checksumToBytes(0xed88b5fd), Next: 0}}, // First Prague block - {1735372, 2741159776, ID{Hash: checksumToBytes(0xed88b5fd), Next: 0}}, // Future Prague block + {1735372, 1741159776, ID{Hash: checksumToBytes(0xed88b5fd), Next: 1760427360}}, // First Prague block + {1735372, 1760427359, ID{Hash: checksumToBytes(0xed88b5fd), Next: 1760427360}}, // Last Prague block + {1735372, 1760427360, ID{Hash: checksumToBytes(0xe2ae4999), Next: 1761017184}}, // First Osaka block + {1735372, 1761017183, ID{Hash: checksumToBytes(0xe2ae4999), Next: 1761017184}}, // Last Osaka block + {1735372, 1761017184, ID{Hash: checksumToBytes(0x56078a1e), Next: 1761607008}}, // First BPO1 block + {1735372, 1761607007, ID{Hash: checksumToBytes(0x56078a1e), Next: 1761607008}}, // Last BPO1 block + {1735372, 1761607008, ID{Hash: checksumToBytes(0x268956b6), Next: 0}}, // First BPO2 block + {1735372, 2000000000, ID{Hash: checksumToBytes(0x268956b6), Next: 0}}, // Future BPO2 block }, }, // Holesky test cases @@ -110,8 +122,14 @@ func TestCreation(t *testing.T) { {123, 1707305663, ID{Hash: checksumToBytes(0xfd4f016b), Next: 1707305664}}, // Last Shanghai block {123, 1707305664, ID{Hash: checksumToBytes(0x9b192ad0), Next: 1740434112}}, // First Cancun block {123, 1740434111, ID{Hash: checksumToBytes(0x9b192ad0), Next: 1740434112}}, // Last Cancun block - {123, 1740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 0}}, // First Prague block - {123, 2740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 0}}, // Future Prague block + {123, 1740434112, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 1759308480}}, // First Prague block + {123, 1759308479, ID{Hash: checksumToBytes(0xdfbd9bed), Next: 1759308480}}, // Last Prague block + {123, 1759308480, ID{Hash: checksumToBytes(0x783def52), Next: 1759800000}}, // First Osaka block + {123, 1759799999, ID{Hash: checksumToBytes(0x783def52), Next: 1759800000}}, // Last Osaka block + {123, 1759800000, ID{Hash: checksumToBytes(0xa280a45c), Next: 1760389824}}, // First BPO1 block + {123, 1760389823, ID{Hash: checksumToBytes(0xa280a45c), Next: 1760389824}}, // Last BPO1 block + {123, 1760389824, ID{Hash: checksumToBytes(0x9bc6cb31), Next: 0}}, // First BPO2 block + {123, 2000000000, ID{Hash: checksumToBytes(0x9bc6cb31), Next: 0}}, // Future BPO1 block }, }, // Hoodi test cases @@ -121,8 +139,14 @@ func TestCreation(t *testing.T) { []testcase{ {0, 0, ID{Hash: checksumToBytes(0xbef71d30), Next: 1742999832}}, // Unsynced, last Frontier, Homestead, Tangerine, Spurious, Byzantium, Constantinople, Petersburg, Istanbul, Berlin, London, Paris, Shanghai, Cancun block {123, 1742999831, ID{Hash: checksumToBytes(0xbef71d30), Next: 1742999832}}, // Last Cancun block - {123, 1742999832, ID{Hash: checksumToBytes(0x0929e24e), Next: 0}}, // First Prague block - {123, 2740434112, ID{Hash: checksumToBytes(0x0929e24e), Next: 0}}, // Future Prague block + {123, 1742999832, ID{Hash: checksumToBytes(0x0929e24e), Next: 1761677592}}, // First Prague block + {123, 1761677591, ID{Hash: checksumToBytes(0x0929e24e), Next: 1761677592}}, // Last Prague block + {123, 1761677592, ID{Hash: checksumToBytes(0xe7e0e7ff), Next: 1762365720}}, // First Osaka block + {123, 1762365719, ID{Hash: checksumToBytes(0xe7e0e7ff), Next: 1762365720}}, // Last Osaka block + {123, 1762365720, ID{Hash: checksumToBytes(0x3893353e), Next: 1762955544}}, // First BPO1 block + {123, 1762955543, ID{Hash: checksumToBytes(0x3893353e), Next: 1762955544}}, // Last BPO1 block + {123, 1762955544, ID{Hash: checksumToBytes(0x23aa1351), Next: 0}}, // First BPO2 block + {123, 2000000000, ID{Hash: checksumToBytes(0x23aa1351), Next: 0}}, // Future BPO2 block }, }, } @@ -144,6 +168,9 @@ func TestValidation(t *testing.T) { legacyConfig.ShanghaiTime = nil legacyConfig.CancunTime = nil legacyConfig.PragueTime = nil + legacyConfig.OsakaTime = nil + legacyConfig.BPO1Time = nil + legacyConfig.BPO2Time = nil tests := []struct { config *params.ChainConfig @@ -343,11 +370,11 @@ func TestValidation(t *testing.T) { // Local is mainnet Shanghai, remote is random Shanghai. {params.MainnetChainConfig, 20000000, 1681338455, ID{Hash: checksumToBytes(0x12345678), Next: 0}, ErrLocalIncompatibleOrStale}, - // Local is mainnet Prague, far in the future. Remote announces Gopherium (non existing fork) + // Local is mainnet BPO2, far in the future. Remote announces Gopherium (non existing fork) // at some future timestamp 8888888888, for itself, but past block for local. Local is incompatible. // // This case detects non-upgraded nodes with majority hash power (typical Ropsten mess). - {params.MainnetChainConfig, 88888888, 8888888888, ID{Hash: checksumToBytes(0xc376cf8b), Next: 8888888888}, ErrLocalIncompatibleOrStale}, + {params.MainnetChainConfig, 88888888, 8888888888, ID{Hash: checksumToBytes(0x07c9462e), Next: 8888888888}, ErrLocalIncompatibleOrStale}, // Local is mainnet Shanghai. Remote is also in Shanghai, but announces Gopherium (non existing // fork) at timestamp 1668000000, before Cancun. Local is incompatible. diff --git a/core/genesis.go b/core/genesis.go index f1a620da57..983ad4c3cb 100644 --- a/core/genesis.go +++ b/core/genesis.go @@ -153,7 +153,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { if account.Balance != nil { statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance) } - statedb.SetCode(addr, account.Code) + statedb.SetCode(addr, account.Code, tracing.CodeChangeGenesis) statedb.SetNonce(addr, account.Nonce, tracing.NonceChangeGenesis) for key, value := range account.Storage { statedb.SetState(addr, key, value) @@ -164,7 +164,7 @@ func hashAlloc(ga *types.GenesisAlloc, isVerkle bool) (common.Hash, error) { // flushAlloc is very similar with hash, but the main difference is all the // generated states will be persisted into the given database. -func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, error) { +func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database, tracer *tracing.Hooks) (common.Hash, error) { emptyRoot := types.EmptyRootHash if triedb.IsVerkle() { emptyRoot = types.EmptyVerkleHash @@ -179,18 +179,34 @@ func flushAlloc(ga *types.GenesisAlloc, triedb *triedb.Database) (common.Hash, e // already captures the allocations. statedb.AddBalance(addr, uint256.MustFromBig(account.Balance), tracing.BalanceIncreaseGenesisBalance) } - statedb.SetCode(addr, account.Code) + statedb.SetCode(addr, account.Code, tracing.CodeChangeGenesis) statedb.SetNonce(addr, account.Nonce, tracing.NonceChangeGenesis) for key, value := range account.Storage { statedb.SetState(addr, key, value) } } - root, err := statedb.Commit(0, false, false) - if err != nil { - return common.Hash{}, err + + var root common.Hash + if tracer != nil && tracer.OnStateUpdate != nil { + r, update, err := statedb.CommitWithUpdate(0, false, false) + if err != nil { + return common.Hash{}, err + } + trUpdate, err := update.ToTracingUpdate() + if err != nil { + return common.Hash{}, err + } + tracer.OnStateUpdate(trUpdate) + root = r + } else { + root, err = statedb.Commit(0, false, false) + if err != nil { + return common.Hash{}, err + } } + // Commit newly generated states into disk if it's not empty. - if root != types.EmptyRootHash { + if root != emptyRoot { if err := triedb.Commit(root, true); err != nil { return common.Hash{}, err } @@ -259,6 +275,8 @@ func (e *GenesisMismatchError) Error() string { // ChainOverrides contains the changes to chain config. type ChainOverrides struct { OverrideOsaka *uint64 + OverrideBPO1 *uint64 + OverrideBPO2 *uint64 OverrideVerkle *uint64 } @@ -270,6 +288,12 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error { if o.OverrideOsaka != nil { cfg.OsakaTime = o.OverrideOsaka } + if o.OverrideBPO1 != nil { + cfg.BPO1Time = o.OverrideBPO1 + } + if o.OverrideBPO2 != nil { + cfg.BPO2Time = o.OverrideBPO2 + } if o.OverrideVerkle != nil { cfg.VerkleTime = o.OverrideVerkle } @@ -288,10 +312,10 @@ func (o *ChainOverrides) apply(cfg *params.ChainConfig) error { // specify a fork block below the local head block). In case of a conflict, the // error is a *params.ConfigCompatError and the new, unwritten config is returned. func SetupGenesisBlock(db ethdb.Database, triedb *triedb.Database, genesis *Genesis) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { - return SetupGenesisBlockWithOverride(db, triedb, genesis, nil) + return SetupGenesisBlockWithOverride(db, triedb, genesis, nil, nil) } -func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { +func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, genesis *Genesis, overrides *ChainOverrides, tracer *tracing.Hooks) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { // Copy the genesis, so we can operate on a copy. genesis = genesis.copy() // Sanitize the supplied genesis, ensuring it has the associated chain @@ -312,7 +336,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g return nil, common.Hash{}, nil, err } - block, err := genesis.Commit(db, triedb) + block, err := genesis.Commit(db, triedb, tracer) if err != nil { return nil, common.Hash{}, nil, err } @@ -340,7 +364,7 @@ func SetupGenesisBlockWithOverride(db ethdb.Database, triedb *triedb.Database, g if hash := genesis.ToBlock().Hash(); hash != ghash { return nil, common.Hash{}, nil, &GenesisMismatchError{ghash, hash} } - block, err := genesis.Commit(db, triedb) + block, err := genesis.Commit(db, triedb, tracer) if err != nil { return nil, common.Hash{}, nil, err } @@ -514,6 +538,11 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block { if head.BlobGasUsed == nil { head.BlobGasUsed = new(uint64) } + } else { + if g.ExcessBlobGas != nil { + log.Warn("Invalid genesis, unexpected ExcessBlobGas set before Cancun, allowing it for testing purposes") + head.ExcessBlobGas = g.ExcessBlobGas + } } if conf.IsPrague(num, g.Timestamp) { head.RequestsHash = &types.EmptyRequestsHash @@ -524,7 +553,7 @@ func (g *Genesis) toBlockWithRoot(root common.Hash) *types.Block { // Commit writes the block and state of a genesis specification to the database. // The block is committed as the canonical head block. -func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Block, error) { +func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database, tracer *tracing.Hooks) (*types.Block, error) { if g.Number != 0 { return nil, errors.New("can't commit genesis block with number > 0") } @@ -539,7 +568,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo return nil, errors.New("can't start clique chain without signers") } // flush the data to disk and compute the state root - root, err := flushAlloc(&g.Alloc, triedb) + root, err := flushAlloc(&g.Alloc, triedb, tracer) if err != nil { return nil, err } @@ -565,7 +594,7 @@ func (g *Genesis) Commit(db ethdb.Database, triedb *triedb.Database) (*types.Blo // MustCommit writes the genesis block and state to db, panicking on error. // The block is committed as the canonical head block. func (g *Genesis) MustCommit(db ethdb.Database, triedb *triedb.Database) *types.Block { - block, err := g.Commit(db, triedb) + block, err := g.Commit(db, triedb, nil) if err != nil { panic(err) } @@ -656,23 +685,24 @@ func DeveloperGenesisBlock(gasLimit uint64, faucet *common.Address) *Genesis { BaseFee: big.NewInt(params.InitialBaseFee), Difficulty: big.NewInt(0), Alloc: map[common.Address]types.Account{ - common.BytesToAddress([]byte{0x01}): {Balance: big.NewInt(1)}, // ECRecover - common.BytesToAddress([]byte{0x02}): {Balance: big.NewInt(1)}, // SHA256 - common.BytesToAddress([]byte{0x03}): {Balance: big.NewInt(1)}, // RIPEMD - common.BytesToAddress([]byte{0x04}): {Balance: big.NewInt(1)}, // Identity - common.BytesToAddress([]byte{0x05}): {Balance: big.NewInt(1)}, // ModExp - common.BytesToAddress([]byte{0x06}): {Balance: big.NewInt(1)}, // ECAdd - common.BytesToAddress([]byte{0x07}): {Balance: big.NewInt(1)}, // ECScalarMul - common.BytesToAddress([]byte{0x08}): {Balance: big.NewInt(1)}, // ECPairing - common.BytesToAddress([]byte{0x09}): {Balance: big.NewInt(1)}, // BLAKE2b - common.BytesToAddress([]byte{0x0a}): {Balance: big.NewInt(1)}, // KZGPointEval - common.BytesToAddress([]byte{0x0b}): {Balance: big.NewInt(1)}, // BLSG1Add - common.BytesToAddress([]byte{0x0c}): {Balance: big.NewInt(1)}, // BLSG1MultiExp - common.BytesToAddress([]byte{0x0d}): {Balance: big.NewInt(1)}, // BLSG2Add - common.BytesToAddress([]byte{0x0e}): {Balance: big.NewInt(1)}, // BLSG2MultiExp - common.BytesToAddress([]byte{0x0f}): {Balance: big.NewInt(1)}, // BLSG1Pairing - common.BytesToAddress([]byte{0x10}): {Balance: big.NewInt(1)}, // BLSG1MapG1 - common.BytesToAddress([]byte{0x11}): {Balance: big.NewInt(1)}, // BLSG2MapG2 + common.BytesToAddress([]byte{0x01}): {Balance: big.NewInt(1)}, // ECRecover + common.BytesToAddress([]byte{0x02}): {Balance: big.NewInt(1)}, // SHA256 + common.BytesToAddress([]byte{0x03}): {Balance: big.NewInt(1)}, // RIPEMD + common.BytesToAddress([]byte{0x04}): {Balance: big.NewInt(1)}, // Identity + common.BytesToAddress([]byte{0x05}): {Balance: big.NewInt(1)}, // ModExp + common.BytesToAddress([]byte{0x06}): {Balance: big.NewInt(1)}, // ECAdd + common.BytesToAddress([]byte{0x07}): {Balance: big.NewInt(1)}, // ECScalarMul + common.BytesToAddress([]byte{0x08}): {Balance: big.NewInt(1)}, // ECPairing + common.BytesToAddress([]byte{0x09}): {Balance: big.NewInt(1)}, // BLAKE2b + common.BytesToAddress([]byte{0x0a}): {Balance: big.NewInt(1)}, // KZGPointEval + common.BytesToAddress([]byte{0x0b}): {Balance: big.NewInt(1)}, // BLSG1Add + common.BytesToAddress([]byte{0x0c}): {Balance: big.NewInt(1)}, // BLSG1MultiExp + common.BytesToAddress([]byte{0x0d}): {Balance: big.NewInt(1)}, // BLSG2Add + common.BytesToAddress([]byte{0x0e}): {Balance: big.NewInt(1)}, // BLSG2MultiExp + common.BytesToAddress([]byte{0x0f}): {Balance: big.NewInt(1)}, // BLSG1Pairing + common.BytesToAddress([]byte{0x10}): {Balance: big.NewInt(1)}, // BLSG1MapG1 + common.BytesToAddress([]byte{0x11}): {Balance: big.NewInt(1)}, // BLSG2MapG2 + common.BytesToAddress([]byte{0x1, 00}): {Balance: big.NewInt(1)}, // P256Verify // Pre-deploy system contracts params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0}, params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0}, diff --git a/core/genesis_test.go b/core/genesis_test.go index a41dfce578..821c71feb9 100644 --- a/core/genesis_test.go +++ b/core/genesis_test.go @@ -88,7 +88,7 @@ func testSetupGenesis(t *testing.T, scheme string) { name: "custom block in DB, genesis == nil", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - customg.Commit(db, tdb) + customg.Commit(db, tdb, nil) return SetupGenesisBlock(db, tdb, nil) }, wantHash: customghash, @@ -98,7 +98,7 @@ func testSetupGenesis(t *testing.T, scheme string) { name: "custom block in DB, genesis == sepolia", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - customg.Commit(db, tdb) + customg.Commit(db, tdb, nil) return SetupGenesisBlock(db, tdb, DefaultSepoliaGenesisBlock()) }, wantErr: &GenesisMismatchError{Stored: customghash, New: params.SepoliaGenesisHash}, @@ -107,7 +107,7 @@ func testSetupGenesis(t *testing.T, scheme string) { name: "custom block in DB, genesis == hoodi", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - customg.Commit(db, tdb) + customg.Commit(db, tdb, nil) return SetupGenesisBlock(db, tdb, DefaultHoodiGenesisBlock()) }, wantErr: &GenesisMismatchError{Stored: customghash, New: params.HoodiGenesisHash}, @@ -116,7 +116,7 @@ func testSetupGenesis(t *testing.T, scheme string) { name: "compatible config in DB", fn: func(db ethdb.Database) (*params.ChainConfig, common.Hash, *params.ConfigCompatError, error) { tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - oldcustomg.Commit(db, tdb) + oldcustomg.Commit(db, tdb, nil) return SetupGenesisBlock(db, tdb, &customg) }, wantHash: customghash, @@ -128,7 +128,7 @@ func testSetupGenesis(t *testing.T, scheme string) { // Commit the 'old' genesis block with Homestead transition at #2. // Advance to block #4, past the homestead transition block of customg. tdb := triedb.NewDatabase(db, newDbConfig(scheme)) - oldcustomg.Commit(db, tdb) + oldcustomg.Commit(db, tdb, nil) bc, _ := NewBlockChain(db, &oldcustomg, ethash.NewFullFaker(), DefaultConfig().WithStateScheme(scheme)) defer bc.Stop() @@ -308,7 +308,7 @@ func TestVerkleGenesisCommit(t *testing.T) { }, } - expected := common.FromHex("018d20eebb130b5e2b796465fe36aafab650650729a92435aec071bf2386f080") + expected := common.FromHex("19056b480530799a4fdaa9fd9407043b965a3a5c37b4d2a1a9a4f3395a327561") got := genesis.ToBlock().Root().Bytes() if !bytes.Equal(got, expected) { t.Fatalf("invalid genesis state root, expected %x, got %x", expected, got) diff --git a/core/headerchain_test.go b/core/headerchain_test.go index b51fb8f226..dba04e2cf2 100644 --- a/core/headerchain_test.go +++ b/core/headerchain_test.go @@ -69,7 +69,7 @@ func TestHeaderInsertion(t *testing.T) { db = rawdb.NewMemoryDatabase() gspec = &Genesis{BaseFee: big.NewInt(params.InitialBaseFee), Config: params.AllEthashProtocolChanges} ) - gspec.Commit(db, triedb.NewDatabase(db, nil)) + gspec.Commit(db, triedb.NewDatabase(db, nil), nil) hc, err := NewHeaderChain(db, gspec.Config, ethash.NewFaker(), func() bool { return false }) if err != nil { t.Fatal(err) diff --git a/core/overlay/state_transition.go b/core/overlay/state_transition.go index 90b5c9431a..a52d9139c9 100644 --- a/core/overlay/state_transition.go +++ b/core/overlay/state_transition.go @@ -60,6 +60,7 @@ func (ts *TransitionState) Copy() *TransitionState { CurrentSlotHash: ts.CurrentSlotHash, CurrentPreimageOffset: ts.CurrentPreimageOffset, StorageProcessed: ts.StorageProcessed, + BaseRoot: ts.BaseRoot, } if ts.CurrentAccountAddress != nil { addr := *ts.CurrentAccountAddress @@ -96,7 +97,7 @@ func LoadTransitionState(db ethdb.KeyValueReader, root common.Hash, isVerkle boo // Initialize the first transition state, with the "ended" // field set to true if the database was created // as a verkle database. - log.Debug("no transition state found, starting fresh", "is verkle", db) + log.Debug("no transition state found, starting fresh", "verkle", isVerkle) // Start with a fresh state ts = &TransitionState{Ended: isVerkle} diff --git a/core/rawdb/accessors_chain.go b/core/rawdb/accessors_chain.go index 0782a0e7da..6ae64fb2fd 100644 --- a/core/rawdb/accessors_chain.go +++ b/core/rawdb/accessors_chain.go @@ -83,65 +83,6 @@ type NumberHash struct { Hash common.Hash } -// ReadAllHashesInRange retrieves all the hashes assigned to blocks at certain -// heights, both canonical and reorged forks included. -// This method considers both limits to be _inclusive_. -func ReadAllHashesInRange(db ethdb.Iteratee, first, last uint64) []*NumberHash { - var ( - start = encodeBlockNumber(first) - keyLength = len(headerPrefix) + 8 + 32 - hashes = make([]*NumberHash, 0, 1+last-first) - it = db.NewIterator(headerPrefix, start) - ) - defer it.Release() - for it.Next() { - key := it.Key() - if len(key) != keyLength { - continue - } - num := binary.BigEndian.Uint64(key[len(headerPrefix) : len(headerPrefix)+8]) - if num > last { - break - } - hash := common.BytesToHash(key[len(key)-32:]) - hashes = append(hashes, &NumberHash{num, hash}) - } - return hashes -} - -// ReadAllCanonicalHashes retrieves all canonical number and hash mappings at the -// certain chain range. If the accumulated entries reaches the given threshold, -// abort the iteration and return the semi-finish result. -func ReadAllCanonicalHashes(db ethdb.Iteratee, from uint64, to uint64, limit int) ([]uint64, []common.Hash) { - // Short circuit if the limit is 0. - if limit == 0 { - return nil, nil - } - var ( - numbers []uint64 - hashes []common.Hash - ) - // Construct the key prefix of start point. - start, end := headerHashKey(from), headerHashKey(to) - it := db.NewIterator(nil, start) - defer it.Release() - - for it.Next() { - if bytes.Compare(it.Key(), end) >= 0 { - break - } - if key := it.Key(); len(key) == len(headerPrefix)+8+1 && bytes.Equal(key[len(key)-1:], headerHashSuffix) { - numbers = append(numbers, binary.BigEndian.Uint64(key[len(headerPrefix):len(headerPrefix)+8])) - hashes = append(hashes, common.BytesToHash(it.Value())) - // If the accumulated entries reaches the limit threshold, return. - if len(numbers) >= limit { - break - } - } - } - return numbers, hashes -} - // ReadHeaderNumber returns the header number assigned to a hash. func ReadHeaderNumber(db ethdb.KeyValueReader, hash common.Hash) (uint64, bool) { data, _ := db.Get(headerNumberKey(hash)) @@ -664,15 +605,6 @@ func DeleteReceipts(db ethdb.KeyValueWriter, hash common.Hash, number uint64) { } } -// storedReceiptRLP is the storage encoding of a receipt. -// Re-definition in core/types/receipt.go. -// TODO: Re-use the existing definition. -type storedReceiptRLP struct { - PostStateOrStatus []byte - CumulativeGasUsed uint64 - Logs []*types.Log -} - // ReceiptLogs is a barebone version of ReceiptForStorage which only keeps // the list of logs. When decoding a stored receipt into this object we // avoid creating the bloom filter. @@ -682,11 +614,11 @@ type receiptLogs struct { // DecodeRLP implements rlp.Decoder. func (r *receiptLogs) DecodeRLP(s *rlp.Stream) error { - var stored storedReceiptRLP - if err := s.Decode(&stored); err != nil { + var rs types.ReceiptForStorage + if err := rs.DecodeRLP(s); err != nil { return err } - r.Logs = stored.Logs + r.Logs = rs.Logs return nil } @@ -895,40 +827,6 @@ func WriteBadBlock(db ethdb.KeyValueStore, block *types.Block) { } } -// DeleteBadBlocks deletes all the bad blocks from the database -func DeleteBadBlocks(db ethdb.KeyValueWriter) { - if err := db.Delete(badBlockKey); err != nil { - log.Crit("Failed to delete bad blocks", "err", err) - } -} - -// FindCommonAncestor returns the last common ancestor of two block headers -func FindCommonAncestor(db ethdb.Reader, a, b *types.Header) *types.Header { - for bn := b.Number.Uint64(); a.Number.Uint64() > bn; { - a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) - if a == nil { - return nil - } - } - for an := a.Number.Uint64(); an < b.Number.Uint64(); { - b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) - if b == nil { - return nil - } - } - for a.Hash() != b.Hash() { - a = ReadHeader(db, a.ParentHash, a.Number.Uint64()-1) - if a == nil { - return nil - } - b = ReadHeader(db, b.ParentHash, b.Number.Uint64()-1) - if b == nil { - return nil - } - } - return a -} - // ReadHeadHeader returns the current canonical head header. func ReadHeadHeader(db ethdb.Reader) *types.Header { headHeaderHash := ReadHeadHeaderHash(db) diff --git a/core/rawdb/accessors_chain_test.go b/core/rawdb/accessors_chain_test.go index 196f3dac8f..02d51f4dd2 100644 --- a/core/rawdb/accessors_chain_test.go +++ b/core/rawdb/accessors_chain_test.go @@ -23,7 +23,6 @@ import ( "math/big" "math/rand" "os" - "reflect" "testing" "github.com/ethereum/go-ethereum/common" @@ -246,16 +245,9 @@ func TestBadBlockStorage(t *testing.T) { } for i := 0; i < len(badBlocks)-1; i++ { if badBlocks[i].NumberU64() < badBlocks[i+1].NumberU64() { - t.Fatalf("The bad blocks are not sorted #[%d](%d) < #[%d](%d)", i, i+1, badBlocks[i].NumberU64(), badBlocks[i+1].NumberU64()) + t.Fatalf("The bad blocks are not sorted #[%d](%d) < #[%d](%d)", i, badBlocks[i].NumberU64(), i+1, badBlocks[i+1].NumberU64()) } } - - // Delete all bad blocks - DeleteBadBlocks(db) - badBlocks = ReadAllBadBlocks(db) - if len(badBlocks) != 0 { - t.Fatalf("Failed to delete bad blocks") - } } // Tests that canonical numbers can be mapped to hashes and retrieved. @@ -511,38 +503,7 @@ func TestWriteAncientHeaderChain(t *testing.T) { t.Fatalf("unexpected body returned") } if blob := ReadReceiptsRLP(db, header.Hash(), header.Number.Uint64()); len(blob) != 0 { - t.Fatalf("unexpected body returned") - } - } -} - -func TestCanonicalHashIteration(t *testing.T) { - var cases = []struct { - from, to uint64 - limit int - expect []uint64 - }{ - {1, 8, 0, nil}, - {1, 8, 1, []uint64{1}}, - {1, 8, 10, []uint64{1, 2, 3, 4, 5, 6, 7}}, - {1, 9, 10, []uint64{1, 2, 3, 4, 5, 6, 7, 8}}, - {2, 9, 10, []uint64{2, 3, 4, 5, 6, 7, 8}}, - {9, 10, 10, nil}, - } - // Test empty db iteration - db := NewMemoryDatabase() - numbers, _ := ReadAllCanonicalHashes(db, 0, 10, 10) - if len(numbers) != 0 { - t.Fatalf("No entry should be returned to iterate an empty db") - } - // Fill database with testing data. - for i := uint64(1); i <= 8; i++ { - WriteCanonicalHash(db, common.Hash{}, i) - } - for i, c := range cases { - numbers, _ := ReadAllCanonicalHashes(db, c.from, c.to, c.limit) - if !reflect.DeepEqual(numbers, c.expect) { - t.Fatalf("Case %d failed, want %v, got %v", i, c.expect, numbers) + t.Fatalf("unexpected receipts returned") } } } @@ -565,18 +526,6 @@ func TestHashesInRange(t *testing.T) { total++ } } - if have, want := len(ReadAllHashesInRange(db, 10, 10)), 10; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashesInRange(db, 10, 9)), 0; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashesInRange(db, 0, 100)), total; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } - if have, want := len(ReadAllHashesInRange(db, 9, 10)), 9+10; have != want { - t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) - } if have, want := len(ReadAllHashes(db, 10)), 10; have != want { t.Fatalf("Wrong number of hashes read, want %d, got %d", want, have) } diff --git a/core/rawdb/accessors_history.go b/core/rawdb/accessors_history.go index cf1073f387..95a8907edc 100644 --- a/core/rawdb/accessors_history.go +++ b/core/rawdb/accessors_history.go @@ -46,6 +46,27 @@ func DeleteStateHistoryIndexMetadata(db ethdb.KeyValueWriter) { } } +// ReadTrienodeHistoryIndexMetadata retrieves the metadata of trienode history index. +func ReadTrienodeHistoryIndexMetadata(db ethdb.KeyValueReader) []byte { + data, _ := db.Get(headTrienodeHistoryIndexKey) + return data +} + +// WriteTrienodeHistoryIndexMetadata stores the metadata of trienode history index +// into database. +func WriteTrienodeHistoryIndexMetadata(db ethdb.KeyValueWriter, blob []byte) { + if err := db.Put(headTrienodeHistoryIndexKey, blob); err != nil { + log.Crit("Failed to store the metadata of trienode history index", "err", err) + } +} + +// DeleteTrienodeHistoryIndexMetadata removes the metadata of trienode history index. +func DeleteTrienodeHistoryIndexMetadata(db ethdb.KeyValueWriter) { + if err := db.Delete(headTrienodeHistoryIndexKey); err != nil { + log.Crit("Failed to delete the metadata of trienode history index", "err", err) + } +} + // ReadAccountHistoryIndex retrieves the account history index with the provided // account address. func ReadAccountHistoryIndex(db ethdb.KeyValueReader, addressHash common.Hash) []byte { @@ -95,6 +116,30 @@ func DeleteStorageHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, } } +// ReadTrienodeHistoryIndex retrieves the trienode history index with the provided +// account address and storage key hash. +func ReadTrienodeHistoryIndex(db ethdb.KeyValueReader, addressHash common.Hash, path []byte) []byte { + data, err := db.Get(trienodeHistoryIndexKey(addressHash, path)) + if err != nil || len(data) == 0 { + return nil + } + return data +} + +// WriteTrienodeHistoryIndex writes the provided trienode history index into database. +func WriteTrienodeHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, path []byte, data []byte) { + if err := db.Put(trienodeHistoryIndexKey(addressHash, path), data); err != nil { + log.Crit("Failed to store trienode history index", "err", err) + } +} + +// DeleteTrienodeHistoryIndex deletes the specified trienode index from the database. +func DeleteTrienodeHistoryIndex(db ethdb.KeyValueWriter, addressHash common.Hash, path []byte) { + if err := db.Delete(trienodeHistoryIndexKey(addressHash, path)); err != nil { + log.Crit("Failed to delete trienode history index", "err", err) + } +} + // ReadAccountHistoryIndexBlock retrieves the index block with the provided // account address along with the block id. func ReadAccountHistoryIndexBlock(db ethdb.KeyValueReader, addressHash common.Hash, blockID uint32) []byte { @@ -143,6 +188,30 @@ func DeleteStorageHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common. } } +// ReadTrienodeHistoryIndexBlock retrieves the index block with the provided state +// identifier along with the block id. +func ReadTrienodeHistoryIndexBlock(db ethdb.KeyValueReader, addressHash common.Hash, path []byte, blockID uint32) []byte { + data, err := db.Get(trienodeHistoryIndexBlockKey(addressHash, path, blockID)) + if err != nil || len(data) == 0 { + return nil + } + return data +} + +// WriteTrienodeHistoryIndexBlock writes the provided index block into database. +func WriteTrienodeHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, path []byte, id uint32, data []byte) { + if err := db.Put(trienodeHistoryIndexBlockKey(addressHash, path, id), data); err != nil { + log.Crit("Failed to store trienode index block", "err", err) + } +} + +// DeleteTrienodeHistoryIndexBlock deletes the specified index block from the database. +func DeleteTrienodeHistoryIndexBlock(db ethdb.KeyValueWriter, addressHash common.Hash, path []byte, id uint32) { + if err := db.Delete(trienodeHistoryIndexBlockKey(addressHash, path, id)); err != nil { + log.Crit("Failed to delete trienode index block", "err", err) + } +} + // increaseKey increase the input key by one bit. Return nil if the entire // addition operation overflows. func increaseKey(key []byte) []byte { @@ -155,14 +224,26 @@ func increaseKey(key []byte) []byte { return nil } -// DeleteStateHistoryIndex completely removes all history indexing data, including +// DeleteStateHistoryIndexes completely removes all history indexing data, including // indexes for accounts and storages. -// -// Note, this method assumes the storage space with prefix `StateHistoryIndexPrefix` -// is exclusively occupied by the history indexing data! -func DeleteStateHistoryIndex(db ethdb.KeyValueRangeDeleter) { - start := StateHistoryIndexPrefix - limit := increaseKey(bytes.Clone(StateHistoryIndexPrefix)) +func DeleteStateHistoryIndexes(db ethdb.KeyValueRangeDeleter) { + DeleteHistoryByRange(db, StateHistoryAccountMetadataPrefix) + DeleteHistoryByRange(db, StateHistoryStorageMetadataPrefix) + DeleteHistoryByRange(db, StateHistoryAccountBlockPrefix) + DeleteHistoryByRange(db, StateHistoryStorageBlockPrefix) +} + +// DeleteTrienodeHistoryIndexes completely removes all trienode history indexing data. +func DeleteTrienodeHistoryIndexes(db ethdb.KeyValueRangeDeleter) { + DeleteHistoryByRange(db, TrienodeHistoryMetadataPrefix) + DeleteHistoryByRange(db, TrienodeHistoryBlockPrefix) +} + +// DeleteHistoryByRange completely removes all database entries with the specific prefix. +// Note, this method assumes the space with the given prefix is exclusively occupied! +func DeleteHistoryByRange(db ethdb.KeyValueRangeDeleter, prefix []byte) { + start := prefix + limit := increaseKey(bytes.Clone(prefix)) // Try to remove the data in the range by a loop, as the leveldb // doesn't support the native range deletion. diff --git a/core/rawdb/accessors_indexes.go b/core/rawdb/accessors_indexes.go index a725f144d4..10eb454015 100644 --- a/core/rawdb/accessors_indexes.go +++ b/core/rawdb/accessors_indexes.go @@ -148,7 +148,7 @@ func findTxInBlockBody(blockbody rlp.RawValue, target common.Hash) (*types.Trans txIndex := uint64(0) for iter.Next() { if iter.Err() != nil { - return nil, 0, err + return nil, 0, iter.Err() } // The preimage for the hash calculation of legacy transactions // is just their RLP encoding. For typed (EIP-2718) transactions, diff --git a/core/rawdb/accessors_metadata.go b/core/rawdb/accessors_metadata.go index 859566f722..6996031be2 100644 --- a/core/rawdb/accessors_metadata.go +++ b/core/rawdb/accessors_metadata.go @@ -174,16 +174,3 @@ func UpdateUncleanShutdownMarker(db ethdb.KeyValueStore) { log.Warn("Failed to write unclean-shutdown marker", "err", err) } } - -// ReadTransitionStatus retrieves the eth2 transition status from the database -func ReadTransitionStatus(db ethdb.KeyValueReader) []byte { - data, _ := db.Get(transitionStatusKey) - return data -} - -// WriteTransitionStatus stores the eth2 transition status to the database -func WriteTransitionStatus(db ethdb.KeyValueWriter, data []byte) { - if err := db.Put(transitionStatusKey, data); err != nil { - log.Crit("Failed to store the eth2 transition status", "err", err) - } -} diff --git a/core/rawdb/accessors_state.go b/core/rawdb/accessors_state.go index 44f041d82e..b97c7a07a1 100644 --- a/core/rawdb/accessors_state.go +++ b/core/rawdb/accessors_state.go @@ -119,13 +119,6 @@ func WriteStateID(db ethdb.KeyValueWriter, root common.Hash, id uint64) { } } -// DeleteStateID deletes the specified state lookup from the database. -func DeleteStateID(db ethdb.KeyValueWriter, root common.Hash) { - if err := db.Delete(stateIDKey(root)); err != nil { - log.Crit("Failed to delete state ID", "err", err) - } -} - // ReadPersistentStateID retrieves the id of the persistent state from the database. func ReadPersistentStateID(db ethdb.KeyValueReader) uint64 { data, _ := db.Get(persistentStateIDKey) @@ -177,9 +170,11 @@ func ReadStateHistoryMetaList(db ethdb.AncientReaderOp, start uint64, count uint return db.AncientRange(stateHistoryMeta, start-1, count, 0) } -// ReadStateAccountIndex retrieves the state root corresponding to the specified -// state history. Compute the position of state history in freezer by minus one -// since the id of first state history starts from one(zero for initial state). +// ReadStateAccountIndex retrieves the account index blob for the specified +// state history. The index contains fixed-size entries with offsets and lengths +// into the concatenated account data table. Compute the position of state +// history in freezer by minus one since the id of first state history starts +// from one (zero for initial state). func ReadStateAccountIndex(db ethdb.AncientReaderOp, id uint64) []byte { blob, err := db.Ancient(stateHistoryAccountIndex, id-1) if err != nil { @@ -188,37 +183,30 @@ func ReadStateAccountIndex(db ethdb.AncientReaderOp, id uint64) []byte { return blob } -// ReadStateStorageIndex retrieves the state root corresponding to the specified -// state history. Compute the position of state history in freezer by minus one -// since the id of first state history starts from one(zero for initial state). -func ReadStateStorageIndex(db ethdb.AncientReaderOp, id uint64) []byte { - blob, err := db.Ancient(stateHistoryStorageIndex, id-1) - if err != nil { - return nil - } - return blob +// ReadStateStorageIndex retrieves the storage index blob for the specified +// state history. The index contains fixed-size entries that locate storage slot +// data in the concatenated storage data table. Compute the position of state +// history in freezer by minus one since the id of first state history starts +// from one (zero for initial state). +func ReadStateStorageIndex(db ethdb.AncientReaderOp, id uint64, offset, length int) ([]byte, error) { + return db.AncientBytes(stateHistoryStorageIndex, id-1, uint64(offset), uint64(length)) } -// ReadStateAccountHistory retrieves the state root corresponding to the specified -// state history. Compute the position of state history in freezer by minus one -// since the id of first state history starts from one(zero for initial state). -func ReadStateAccountHistory(db ethdb.AncientReaderOp, id uint64) []byte { - blob, err := db.Ancient(stateHistoryAccountData, id-1) - if err != nil { - return nil - } - return blob +// ReadStateAccountHistory retrieves the concatenated account data blob for the +// specified state history. Offsets and lengths are resolved via the account +// index. Compute the position of state history in freezer by minus one since +// the id of first state history starts from one (zero for initial state). +func ReadStateAccountHistory(db ethdb.AncientReaderOp, id uint64, offset, length int) ([]byte, error) { + return db.AncientBytes(stateHistoryAccountData, id-1, uint64(offset), uint64(length)) } -// ReadStateStorageHistory retrieves the state root corresponding to the specified -// state history. Compute the position of state history in freezer by minus one -// since the id of first state history starts from one(zero for initial state). -func ReadStateStorageHistory(db ethdb.AncientReaderOp, id uint64) []byte { - blob, err := db.Ancient(stateHistoryStorageData, id-1) - if err != nil { - return nil - } - return blob +// ReadStateStorageHistory retrieves the concatenated storage slot data blob for +// the specified state history. Locations are resolved via the account and +// storage indexes. Compute the position of state history in freezer by minus +// one since the id of first state history starts from one (zero for initial +// state). +func ReadStateStorageHistory(db ethdb.AncientReaderOp, id uint64, offset, length int) ([]byte, error) { + return db.AncientBytes(stateHistoryStorageData, id-1, uint64(offset), uint64(length)) } // ReadStateHistory retrieves the state history from database with provided id. @@ -299,3 +287,76 @@ func WriteStateHistory(db ethdb.AncientWriter, id uint64, meta []byte, accountIn }) return err } + +// ReadTrienodeHistory retrieves the trienode history corresponding to the specified id. +// Compute the position of trienode history in freezer by minus one since the id of first +// trienode history starts from one(zero for initial state). +func ReadTrienodeHistory(db ethdb.AncientReaderOp, id uint64) ([]byte, []byte, []byte, error) { + header, err := db.Ancient(trienodeHistoryHeaderTable, id-1) + if err != nil { + return nil, nil, nil, err + } + keySection, err := db.Ancient(trienodeHistoryKeySectionTable, id-1) + if err != nil { + return nil, nil, nil, err + } + valueSection, err := db.Ancient(trienodeHistoryValueSectionTable, id-1) + if err != nil { + return nil, nil, nil, err + } + return header, keySection, valueSection, nil +} + +// ReadTrienodeHistoryHeader retrieves the header section of trienode history. +func ReadTrienodeHistoryHeader(db ethdb.AncientReaderOp, id uint64) ([]byte, error) { + return db.Ancient(trienodeHistoryHeaderTable, id-1) +} + +// ReadTrienodeHistoryKeySection retrieves the key section of trienode history. +func ReadTrienodeHistoryKeySection(db ethdb.AncientReaderOp, id uint64, offset uint64, length uint64) ([]byte, error) { + return db.AncientBytes(trienodeHistoryKeySectionTable, id-1, offset, length) +} + +// ReadTrienodeHistoryValueSection retrieves the value section of trienode history. +func ReadTrienodeHistoryValueSection(db ethdb.AncientReaderOp, id uint64, offset uint64, length uint64) ([]byte, error) { + return db.AncientBytes(trienodeHistoryValueSectionTable, id-1, offset, length) +} + +// ReadTrienodeHistoryList retrieves the a list of trienode history corresponding +// to the specified range. +// Compute the position of trienode history in freezer by minus one since the id +// of first trienode history starts from one(zero for initial state). +func ReadTrienodeHistoryList(db ethdb.AncientReaderOp, start uint64, count uint64) ([][]byte, [][]byte, [][]byte, error) { + header, err := db.AncientRange(trienodeHistoryHeaderTable, start-1, count, 0) + if err != nil { + return nil, nil, nil, err + } + keySection, err := db.AncientRange(trienodeHistoryKeySectionTable, start-1, count, 0) + if err != nil { + return nil, nil, nil, err + } + valueSection, err := db.AncientRange(trienodeHistoryValueSectionTable, start-1, count, 0) + if err != nil { + return nil, nil, nil, err + } + if len(header) != len(keySection) || len(header) != len(valueSection) { + return nil, nil, nil, errors.New("trienode history is corrupted") + } + return header, keySection, valueSection, nil +} + +// WriteTrienodeHistory writes the provided trienode history to database. +// Compute the position of trienode history in freezer by minus one since +// the id of first state history starts from one(zero for initial state). +func WriteTrienodeHistory(db ethdb.AncientWriter, id uint64, header []byte, keySection []byte, valueSection []byte) error { + _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + if err := op.AppendRaw(trienodeHistoryHeaderTable, id-1, header); err != nil { + return err + } + if err := op.AppendRaw(trienodeHistoryKeySectionTable, id-1, keySection); err != nil { + return err + } + return op.AppendRaw(trienodeHistoryValueSectionTable, id-1, valueSection) + }) + return err +} diff --git a/core/rawdb/accessors_trie.go b/core/rawdb/accessors_trie.go index e154ab527b..7d8b266c15 100644 --- a/core/rawdb/accessors_trie.go +++ b/core/rawdb/accessors_trie.go @@ -150,7 +150,7 @@ func HasTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash c if len(blob) == 0 { return false } - return crypto.Keccak256Hash(blob) == hash // exists but not match + return crypto.Keccak256Hash(blob) == hash // exist and match default: panic(fmt.Sprintf("Unknown scheme %v", scheme)) } @@ -173,7 +173,7 @@ func ReadTrieNode(db ethdb.KeyValueReader, owner common.Hash, path []byte, hash return nil } if crypto.Keccak256Hash(blob) != hash { - return nil // exists but not match + return nil // exist but not match } return blob default: diff --git a/core/rawdb/ancient_scheme.go b/core/rawdb/ancient_scheme.go index 1ffebed3e7..afec7848c8 100644 --- a/core/rawdb/ancient_scheme.go +++ b/core/rawdb/ancient_scheme.go @@ -75,15 +75,38 @@ var stateFreezerTableConfigs = map[string]freezerTableConfig{ stateHistoryStorageData: {noSnappy: false, prunable: true}, } +const ( + trienodeHistoryHeaderTable = "trienode.header" + trienodeHistoryKeySectionTable = "trienode.key" + trienodeHistoryValueSectionTable = "trienode.value" +) + +// trienodeFreezerTableConfigs configures the settings for tables in the trienode freezer. +var trienodeFreezerTableConfigs = map[string]freezerTableConfig{ + trienodeHistoryHeaderTable: {noSnappy: false, prunable: true}, + + // Disable snappy compression to allow efficient partial read. + trienodeHistoryKeySectionTable: {noSnappy: true, prunable: true}, + + // Disable snappy compression to allow efficient partial read. + trienodeHistoryValueSectionTable: {noSnappy: true, prunable: true}, +} + // The list of identifiers of ancient stores. var ( - ChainFreezerName = "chain" // the folder name of chain segment ancient store. - MerkleStateFreezerName = "state" // the folder name of state history ancient store. - VerkleStateFreezerName = "state_verkle" // the folder name of state history ancient store. + ChainFreezerName = "chain" // the folder name of chain segment ancient store. + MerkleStateFreezerName = "state" // the folder name of state history ancient store. + VerkleStateFreezerName = "state_verkle" // the folder name of state history ancient store. + MerkleTrienodeFreezerName = "trienode" // the folder name of trienode history ancient store. + VerkleTrienodeFreezerName = "trienode_verkle" // the folder name of trienode history ancient store. ) // freezers the collections of all builtin freezers. -var freezers = []string{ChainFreezerName, MerkleStateFreezerName, VerkleStateFreezerName} +var freezers = []string{ + ChainFreezerName, + MerkleStateFreezerName, VerkleStateFreezerName, + MerkleTrienodeFreezerName, VerkleTrienodeFreezerName, +} // NewStateFreezer initializes the ancient store for state history. // @@ -103,3 +126,22 @@ func NewStateFreezer(ancientDir string, verkle bool, readOnly bool) (ethdb.Reset } return newResettableFreezer(name, "eth/db/state", readOnly, stateHistoryTableSize, stateFreezerTableConfigs) } + +// NewTrienodeFreezer initializes the ancient store for trienode history. +// +// - if the empty directory is given, initializes the pure in-memory +// trienode freezer (e.g. dev mode). +// - if non-empty directory is given, initializes the regular file-based +// trienode freezer. +func NewTrienodeFreezer(ancientDir string, verkle bool, readOnly bool) (ethdb.ResettableAncientStore, error) { + if ancientDir == "" { + return NewMemoryFreezer(readOnly, trienodeFreezerTableConfigs), nil + } + var name string + if verkle { + name = filepath.Join(ancientDir, VerkleTrienodeFreezerName) + } else { + name = filepath.Join(ancientDir, MerkleTrienodeFreezerName) + } + return newResettableFreezer(name, "eth/db/trienode", readOnly, stateHistoryTableSize, trienodeFreezerTableConfigs) +} diff --git a/core/rawdb/ancient_utils.go b/core/rawdb/ancient_utils.go index f4909d86e7..0ed974b745 100644 --- a/core/rawdb/ancient_utils.go +++ b/core/rawdb/ancient_utils.go @@ -34,14 +34,10 @@ type freezerInfo struct { name string // The identifier of freezer head uint64 // The number of last stored item in the freezer tail uint64 // The number of first stored item in the freezer + count uint64 // The number of stored items in the freezer sizes []tableSize // The storage size per table } -// count returns the number of stored items in the freezer. -func (info *freezerInfo) count() uint64 { - return info.head - info.tail + 1 -} - // size returns the storage size of the entire freezer. func (info *freezerInfo) size() common.StorageSize { var total common.StorageSize @@ -65,7 +61,11 @@ func inspect(name string, order map[string]freezerTableConfig, reader ethdb.Anci if err != nil { return freezerInfo{}, err } - info.head = ancients - 1 + if ancients > 0 { + info.head = ancients - 1 + } else { + info.head = 0 + } // Retrieve the number of first stored item tail, err := reader.Tail() @@ -73,6 +73,12 @@ func inspect(name string, order map[string]freezerTableConfig, reader ethdb.Anci return freezerInfo{}, err } info.tail = tail + + if ancients == 0 { + info.count = 0 + } else { + info.count = info.head - info.tail + 1 + } return info, nil } @@ -105,6 +111,23 @@ func inspectFreezers(db ethdb.Database) ([]freezerInfo, error) { } infos = append(infos, info) + case MerkleTrienodeFreezerName, VerkleTrienodeFreezerName: + datadir, err := db.AncientDatadir() + if err != nil { + return nil, err + } + f, err := NewTrienodeFreezer(datadir, freezer == VerkleTrienodeFreezerName, true) + if err != nil { + continue // might be possible the trienode freezer is not existent + } + defer f.Close() + + info, err := inspect(freezer, trienodeFreezerTableConfigs, f) + if err != nil { + return nil, err + } + infos = append(infos, info) + default: return nil, fmt.Errorf("unknown freezer, supported ones: %v", freezers) } @@ -126,6 +149,8 @@ func InspectFreezerTable(ancient string, freezerName string, tableName string, s path, tables = resolveChainFreezerDir(ancient), chainFreezerTableConfigs case MerkleStateFreezerName, VerkleStateFreezerName: path, tables = filepath.Join(ancient, freezerName), stateFreezerTableConfigs + case MerkleTrienodeFreezerName, VerkleTrienodeFreezerName: + path, tables = filepath.Join(ancient, freezerName), trienodeFreezerTableConfigs default: return fmt.Errorf("unknown freezer, supported ones: %v", freezers) } diff --git a/core/rawdb/ancienttest/testsuite.go b/core/rawdb/ancienttest/testsuite.go index e33e768947..7512c1f44b 100644 --- a/core/rawdb/ancienttest/testsuite.go +++ b/core/rawdb/ancienttest/testsuite.go @@ -48,12 +48,16 @@ func basicRead(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { ) defer db.Close() - db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + if _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i := 0; i < len(data); i++ { - op.AppendRaw("a", uint64(i), data[i]) + if err := op.AppendRaw("a", uint64(i), data[i]); err != nil { + return err + } } return nil - }) + }); err != nil { + t.Fatalf("Failed to write ancient data %v", err) + } db.TruncateTail(10) db.TruncateHead(90) @@ -109,12 +113,16 @@ func batchRead(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { ) defer db.Close() - db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + if _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i := 0; i < 100; i++ { - op.AppendRaw("a", uint64(i), data[i]) + if err := op.AppendRaw("a", uint64(i), data[i]); err != nil { + return err + } } return nil - }) + }); err != nil { + t.Fatalf("Failed to write ancient data %v", err) + } db.TruncateTail(10) db.TruncateHead(90) @@ -189,7 +197,9 @@ func basicWrite(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { // The ancient write to tables should be aligned _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i := 0; i < 100; i++ { - op.AppendRaw("a", uint64(i), dataA[i]) + if err := op.AppendRaw("a", uint64(i), dataA[i]); err != nil { + return err + } } return nil }) @@ -200,8 +210,12 @@ func basicWrite(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { // Test normal ancient write size, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i := 0; i < 100; i++ { - op.AppendRaw("a", uint64(i), dataA[i]) - op.AppendRaw("b", uint64(i), dataB[i]) + if err := op.AppendRaw("a", uint64(i), dataA[i]); err != nil { + return err + } + if err := op.AppendRaw("b", uint64(i), dataB[i]); err != nil { + return err + } } return nil }) @@ -217,8 +231,12 @@ func basicWrite(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { db.TruncateHead(90) _, err = db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i := 90; i < 100; i++ { - op.AppendRaw("a", uint64(i), dataA[i]) - op.AppendRaw("b", uint64(i), dataB[i]) + if err := op.AppendRaw("a", uint64(i), dataA[i]); err != nil { + return err + } + if err := op.AppendRaw("b", uint64(i), dataB[i]); err != nil { + return err + } } return nil }) @@ -227,11 +245,15 @@ func basicWrite(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { } // Write should work after truncating everything - db.TruncateTail(0) + db.TruncateHead(0) _, err = db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i := 0; i < 100; i++ { - op.AppendRaw("a", uint64(i), dataA[i]) - op.AppendRaw("b", uint64(i), dataB[i]) + if err := op.AppendRaw("a", uint64(i), dataA[i]); err != nil { + return err + } + if err := op.AppendRaw("b", uint64(i), dataB[i]); err != nil { + return err + } } return nil }) @@ -245,14 +267,18 @@ func nonMutable(t *testing.T, newFn func(kinds []string) ethdb.AncientStore) { defer db.Close() // We write 100 zero-bytes to the freezer and immediately mutate the slice - db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + if _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { data := make([]byte, 100) - op.AppendRaw("a", uint64(0), data) + if err := op.AppendRaw("a", uint64(0), data); err != nil { + return err + } for i := range data { data[i] = 0xff } return nil - }) + }); err != nil { + t.Fatalf("Failed to write ancient data %v", err) + } // Now read it. data, err := db.Ancient("a", uint64(0)) if err != nil { @@ -275,23 +301,31 @@ func TestResettableAncientSuite(t *testing.T, newFn func(kinds []string) ethdb.R ) defer db.Close() - db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + if _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i := 0; i < 100; i++ { - op.AppendRaw("a", uint64(i), data[i]) + if err := op.AppendRaw("a", uint64(i), data[i]); err != nil { + return err + } } return nil - }) + }); err != nil { + t.Fatalf("Failed to write ancient data %v", err) + } db.TruncateTail(10) db.TruncateHead(90) // Ancient write should work after resetting db.Reset() - db.ModifyAncients(func(op ethdb.AncientWriteOp) error { + if _, err := db.ModifyAncients(func(op ethdb.AncientWriteOp) error { for i := 0; i < 100; i++ { - op.AppendRaw("a", uint64(i), data[i]) + if err := op.AppendRaw("a", uint64(i), data[i]); err != nil { + return err + } } return nil - }) + }); err != nil { + t.Fatalf("Failed to write ancient data %v", err) + } }) } diff --git a/core/rawdb/chain_freezer.go b/core/rawdb/chain_freezer.go index c12f2ab8fe..d33f7ce33d 100644 --- a/core/rawdb/chain_freezer.go +++ b/core/rawdb/chain_freezer.go @@ -403,6 +403,10 @@ func (f *chainFreezer) AncientRange(kind string, start, count, maxBytes uint64) return f.ancients.AncientRange(kind, start, count, maxBytes) } +func (f *chainFreezer) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) { + return f.ancients.AncientBytes(kind, id, offset, length) +} + func (f *chainFreezer) ModifyAncients(fn func(ethdb.AncientWriteOp) error) (int64, error) { return f.ancients.ModifyAncients(fn) } diff --git a/core/rawdb/chain_iterator.go b/core/rawdb/chain_iterator.go index e7c89ca8d9..713c3d8ae2 100644 --- a/core/rawdb/chain_iterator.go +++ b/core/rawdb/chain_iterator.go @@ -87,6 +87,7 @@ func InitDatabaseFromFreezer(db ethdb.Database) { type blockTxHashes struct { number uint64 hashes []common.Hash + err error } // iterateTransactions iterates over all transactions in the (canon) block @@ -144,17 +145,22 @@ func iterateTransactions(db ethdb.Database, from uint64, to uint64, reverse bool }() for data := range rlpCh { var body types.Body + var result *blockTxHashes if err := rlp.DecodeBytes(data.rlp, &body); err != nil { log.Warn("Failed to decode block body", "block", data.number, "error", err) - return - } - var hashes []common.Hash - for _, tx := range body.Transactions { - hashes = append(hashes, tx.Hash()) - } - result := &blockTxHashes{ - hashes: hashes, - number: data.number, + result = &blockTxHashes{ + number: data.number, + err: err, + } + } else { + var hashes []common.Hash + for _, tx := range body.Transactions { + hashes = append(hashes, tx.Hash()) + } + result = &blockTxHashes{ + hashes: hashes, + number: data.number, + } } // Feed the block to the aggregator, or abort on interrupt select { @@ -214,6 +220,10 @@ func indexTransactions(db ethdb.Database, from uint64, to uint64, interrupt chan // Next block available, pop it off and index it delivery := queue.PopItem() lastNum = delivery.number + if delivery.err != nil { + log.Warn("Skipping tx indexing for block with missing/corrupt body", "block", delivery.number, "error", delivery.err) + continue + } WriteTxLookupEntries(batch, delivery.number, delivery.hashes) blocks++ txs += len(delivery.hashes) @@ -307,6 +317,10 @@ func unindexTransactions(db ethdb.Database, from uint64, to uint64, interrupt ch } delivery := queue.PopItem() nextNum = delivery.number + 1 + if delivery.err != nil { + log.Warn("Skipping tx unindexing for block with missing/corrupt body", "block", delivery.number, "error", delivery.err) + continue + } DeleteTxLookupEntries(batch, delivery.hashes) txs += len(delivery.hashes) blocks++ diff --git a/core/rawdb/chain_iterator_test.go b/core/rawdb/chain_iterator_test.go index 75bd5a9a94..089ebfe828 100644 --- a/core/rawdb/chain_iterator_test.go +++ b/core/rawdb/chain_iterator_test.go @@ -218,6 +218,36 @@ func TestIndexTransactions(t *testing.T) { verify(0, 8, false, 8) } +func TestUnindexTransactionsMissingBody(t *testing.T) { + // Construct test chain db + chainDB := NewMemoryDatabase() + blocks, _ := initDatabaseWithTransactions(chainDB) + + // Index the entire chain. + lastBlock := blocks[len(blocks)-1].NumberU64() + IndexTransactions(chainDB, 0, lastBlock+1, nil, false) + + // Prove that block 2 body exists in the database. + if raw := ReadCanonicalBodyRLP(chainDB, 2, nil); len(raw) == 0 { + t.Fatalf("Block 2 body does not exist in the database.") + } + + // Delete body for block 2. This simulates a corrupted database. + key := blockBodyKey(2, blocks[2].Hash()) + if err := chainDB.Delete(key); err != nil { + t.Fatalf("Failed to delete block body %v", err) + } + + // Unindex blocks [0, 3) + UnindexTransactions(chainDB, 0, 3, nil, false) + + // Verify that tx index tail is updated to 3. + tail := ReadTxIndexTail(chainDB) + if tail == nil || *tail != 3 { + t.Fatalf("The tx index tail is wrong: got %v want %d", *tail, 3) + } +} + func TestPruneTransactionIndex(t *testing.T) { chainDB := NewMemoryDatabase() blocks, _ := initDatabaseWithTransactions(chainDB) diff --git a/core/rawdb/database.go b/core/rawdb/database.go index 25cd20d164..a5335ea56b 100644 --- a/core/rawdb/database.go +++ b/core/rawdb/database.go @@ -18,13 +18,17 @@ package rawdb import ( "bytes" + "context" "errors" "fmt" "maps" "os" "path/filepath" + "runtime" "slices" "strings" + "sync" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common" @@ -32,7 +36,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethdb/memorydb" "github.com/ethereum/go-ethereum/log" - "github.com/olekukonko/tablewriter" + "golang.org/x/sync/errgroup" ) var ErrDeleteRangeInterrupted = errors.New("safe delete range operation interrupted") @@ -96,6 +100,12 @@ func (db *nofreezedb) AncientRange(kind string, start, max, maxByteSize uint64) return nil, errNotSupported } +// AncientBytes retrieves the value segment of the element specified by the id +// and value offsets. +func (db *nofreezedb) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) { + return nil, errNotSupported +} + // Ancients returns an error as we don't have a backing chain freezer. func (db *nofreezedb) Ancients() (uint64, error) { return 0, errNotSupported @@ -167,7 +177,7 @@ func resolveChainFreezerDir(ancient string) string { // - chain freezer exists in legacy location (root ancient folder) freezer := filepath.Join(ancient, ChainFreezerName) if !common.FileExist(freezer) { - if !common.FileExist(ancient) { + if !common.FileExist(ancient) || !common.IsNonEmptyDir(ancient) { // The entire ancient store is not initialized, still use the sub // folder for initialization. } else { @@ -320,6 +330,7 @@ func Open(db ethdb.KeyValueStore, opts OpenOptions) (ethdb.Database, error) { }() } return &freezerdb{ + readOnly: opts.ReadOnly, ancientRoot: opts.Ancient, KeyValueStore: db, chainFreezer: frdb, @@ -363,36 +374,36 @@ func (c counter) Percentage(current uint64) string { return fmt.Sprintf("%d", current*100/uint64(c)) } -// stat stores sizes and count for a parameter +// stat provides lock-free statistics aggregation using atomic operations type stat struct { - size common.StorageSize - count counter + size uint64 + count uint64 } -// Add size to the stat and increase the counter by 1 -func (s *stat) Add(size common.StorageSize) { - s.size += size - s.count++ +func (s *stat) empty() bool { + return atomic.LoadUint64(&s.count) == 0 } -func (s *stat) Size() string { - return s.size.String() +func (s *stat) add(size common.StorageSize) { + atomic.AddUint64(&s.size, uint64(size)) + atomic.AddUint64(&s.count, 1) } -func (s *stat) Count() string { - return s.count.String() +func (s *stat) sizeString() string { + return common.StorageSize(atomic.LoadUint64(&s.size)).String() +} + +func (s *stat) countString() string { + return counter(atomic.LoadUint64(&s.count)).String() } // InspectDatabase traverses the entire database and checks the size // of all different categories of data. func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { - it := db.NewIterator(keyPrefix, keyStart) - defer it.Release() - var ( - count int64 - start = time.Now() - logged = time.Now() + start = time.Now() + count atomic.Int64 + total atomic.Uint64 // Key-value store statistics headers stat @@ -418,7 +429,8 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { filterMapBlockLV stat // Path-mode archive data - stateIndex stat + stateIndex stat + trienodeIndex stat // Verkle statistics verkleTries stat @@ -428,144 +440,212 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { metadata stat unaccounted stat - // Totals - total common.StorageSize - // This map tracks example keys for unaccounted data. // For each unique two-byte prefix, the first unaccounted key encountered // by the iterator will be stored. unaccountedKeys = make(map[[2]byte][]byte) + unaccountedMu sync.Mutex ) - // Inspect key-value database first. - for it.Next() { - var ( - key = it.Key() - size = common.StorageSize(len(key) + len(it.Value())) - ) - total += size - switch { - case bytes.HasPrefix(key, headerPrefix) && len(key) == (len(headerPrefix)+8+common.HashLength): - headers.Add(size) - case bytes.HasPrefix(key, blockBodyPrefix) && len(key) == (len(blockBodyPrefix)+8+common.HashLength): - bodies.Add(size) - case bytes.HasPrefix(key, blockReceiptsPrefix) && len(key) == (len(blockReceiptsPrefix)+8+common.HashLength): - receipts.Add(size) - case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerTDSuffix): - tds.Add(size) - case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerHashSuffix): - numHashPairings.Add(size) - case bytes.HasPrefix(key, headerNumberPrefix) && len(key) == (len(headerNumberPrefix)+common.HashLength): - hashNumPairings.Add(size) - case IsLegacyTrieNode(key, it.Value()): - legacyTries.Add(size) - case bytes.HasPrefix(key, stateIDPrefix) && len(key) == len(stateIDPrefix)+common.HashLength: - stateLookups.Add(size) - case IsAccountTrieNode(key): - accountTries.Add(size) - case IsStorageTrieNode(key): - storageTries.Add(size) - case bytes.HasPrefix(key, CodePrefix) && len(key) == len(CodePrefix)+common.HashLength: - codes.Add(size) - case bytes.HasPrefix(key, txLookupPrefix) && len(key) == (len(txLookupPrefix)+common.HashLength): - txLookups.Add(size) - case bytes.HasPrefix(key, SnapshotAccountPrefix) && len(key) == (len(SnapshotAccountPrefix)+common.HashLength): - accountSnaps.Add(size) - case bytes.HasPrefix(key, SnapshotStoragePrefix) && len(key) == (len(SnapshotStoragePrefix)+2*common.HashLength): - storageSnaps.Add(size) - case bytes.HasPrefix(key, PreimagePrefix) && len(key) == (len(PreimagePrefix)+common.HashLength): - preimages.Add(size) - case bytes.HasPrefix(key, configPrefix) && len(key) == (len(configPrefix)+common.HashLength): - metadata.Add(size) - case bytes.HasPrefix(key, genesisPrefix) && len(key) == (len(genesisPrefix)+common.HashLength): - metadata.Add(size) - case bytes.HasPrefix(key, skeletonHeaderPrefix) && len(key) == (len(skeletonHeaderPrefix)+8): - beaconHeaders.Add(size) - case bytes.HasPrefix(key, CliqueSnapshotPrefix) && len(key) == 7+common.HashLength: - cliqueSnaps.Add(size) - // new log index - case bytes.HasPrefix(key, filterMapRowPrefix) && len(key) <= len(filterMapRowPrefix)+9: - filterMapRows.Add(size) - case bytes.HasPrefix(key, filterMapLastBlockPrefix) && len(key) == len(filterMapLastBlockPrefix)+4: - filterMapLastBlock.Add(size) - case bytes.HasPrefix(key, filterMapBlockLVPrefix) && len(key) == len(filterMapBlockLVPrefix)+8: - filterMapBlockLV.Add(size) - - // old log index (deprecated) - case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength): - bloomBits.Add(size) - case bytes.HasPrefix(key, bloomBitsMetaPrefix) && len(key) < len(bloomBitsMetaPrefix)+8: - bloomBits.Add(size) - - // Path-based historic state indexes - case bytes.HasPrefix(key, StateHistoryIndexPrefix) && len(key) >= len(StateHistoryIndexPrefix)+common.HashLength: - stateIndex.Add(size) - - // Verkle trie data is detected, determine the sub-category - case bytes.HasPrefix(key, VerklePrefix): - remain := key[len(VerklePrefix):] + inspectRange := func(ctx context.Context, r byte) error { + var s []byte + if len(keyStart) > 0 { switch { - case IsAccountTrieNode(remain): - verkleTries.Add(size) - case bytes.HasPrefix(remain, stateIDPrefix) && len(remain) == len(stateIDPrefix)+common.HashLength: - verkleStateLookups.Add(size) - case bytes.Equal(remain, persistentStateIDKey): - metadata.Add(size) - case bytes.Equal(remain, trieJournalKey): - metadata.Add(size) - case bytes.Equal(remain, snapSyncStatusFlagKey): - metadata.Add(size) + case r < keyStart[0]: + return nil + case r == keyStart[0]: + s = keyStart[1:] default: - unaccounted.Add(size) + // entire key range is included for inspection } + } + it := db.NewIterator(append(keyPrefix, r), s) + defer it.Release() - // Metadata keys - case slices.ContainsFunc(knownMetadataKeys, func(x []byte) bool { return bytes.Equal(x, key) }): - metadata.Add(size) + for it.Next() { + var ( + key = it.Key() + size = common.StorageSize(len(key) + len(it.Value())) + ) + total.Add(uint64(size)) + count.Add(1) - default: - unaccounted.Add(size) - if len(key) >= 2 { - prefix := [2]byte(key[:2]) - if _, ok := unaccountedKeys[prefix]; !ok { - unaccountedKeys[prefix] = bytes.Clone(key) + switch { + case bytes.HasPrefix(key, headerPrefix) && len(key) == (len(headerPrefix)+8+common.HashLength): + headers.add(size) + case bytes.HasPrefix(key, blockBodyPrefix) && len(key) == (len(blockBodyPrefix)+8+common.HashLength): + bodies.add(size) + case bytes.HasPrefix(key, blockReceiptsPrefix) && len(key) == (len(blockReceiptsPrefix)+8+common.HashLength): + receipts.add(size) + case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerTDSuffix): + tds.add(size) + case bytes.HasPrefix(key, headerPrefix) && bytes.HasSuffix(key, headerHashSuffix): + numHashPairings.add(size) + case bytes.HasPrefix(key, headerNumberPrefix) && len(key) == (len(headerNumberPrefix)+common.HashLength): + hashNumPairings.add(size) + case IsLegacyTrieNode(key, it.Value()): + legacyTries.add(size) + case bytes.HasPrefix(key, stateIDPrefix) && len(key) == len(stateIDPrefix)+common.HashLength: + stateLookups.add(size) + case IsAccountTrieNode(key): + accountTries.add(size) + case IsStorageTrieNode(key): + storageTries.add(size) + case bytes.HasPrefix(key, CodePrefix) && len(key) == len(CodePrefix)+common.HashLength: + codes.add(size) + case bytes.HasPrefix(key, txLookupPrefix) && len(key) == (len(txLookupPrefix)+common.HashLength): + txLookups.add(size) + case bytes.HasPrefix(key, SnapshotAccountPrefix) && len(key) == (len(SnapshotAccountPrefix)+common.HashLength): + accountSnaps.add(size) + case bytes.HasPrefix(key, SnapshotStoragePrefix) && len(key) == (len(SnapshotStoragePrefix)+2*common.HashLength): + storageSnaps.add(size) + case bytes.HasPrefix(key, PreimagePrefix) && len(key) == (len(PreimagePrefix)+common.HashLength): + preimages.add(size) + case bytes.HasPrefix(key, configPrefix) && len(key) == (len(configPrefix)+common.HashLength): + metadata.add(size) + case bytes.HasPrefix(key, genesisPrefix) && len(key) == (len(genesisPrefix)+common.HashLength): + metadata.add(size) + case bytes.HasPrefix(key, skeletonHeaderPrefix) && len(key) == (len(skeletonHeaderPrefix)+8): + beaconHeaders.add(size) + case bytes.HasPrefix(key, CliqueSnapshotPrefix) && len(key) == 7+common.HashLength: + cliqueSnaps.add(size) + + // new log index + case bytes.HasPrefix(key, filterMapRowPrefix) && len(key) <= len(filterMapRowPrefix)+9: + filterMapRows.add(size) + case bytes.HasPrefix(key, filterMapLastBlockPrefix) && len(key) == len(filterMapLastBlockPrefix)+4: + filterMapLastBlock.add(size) + case bytes.HasPrefix(key, filterMapBlockLVPrefix) && len(key) == len(filterMapBlockLVPrefix)+8: + filterMapBlockLV.add(size) + + // old log index (deprecated) + case bytes.HasPrefix(key, bloomBitsPrefix) && len(key) == (len(bloomBitsPrefix)+10+common.HashLength): + bloomBits.add(size) + case bytes.HasPrefix(key, bloomBitsMetaPrefix) && len(key) < len(bloomBitsMetaPrefix)+8: + bloomBits.add(size) + + // Path-based historic state indexes + case bytes.HasPrefix(key, StateHistoryAccountMetadataPrefix) && len(key) == len(StateHistoryAccountMetadataPrefix)+common.HashLength: + stateIndex.add(size) + case bytes.HasPrefix(key, StateHistoryStorageMetadataPrefix) && len(key) == len(StateHistoryStorageMetadataPrefix)+2*common.HashLength: + stateIndex.add(size) + case bytes.HasPrefix(key, StateHistoryAccountBlockPrefix) && len(key) == len(StateHistoryAccountBlockPrefix)+common.HashLength+4: + stateIndex.add(size) + case bytes.HasPrefix(key, StateHistoryStorageBlockPrefix) && len(key) == len(StateHistoryStorageBlockPrefix)+2*common.HashLength+4: + stateIndex.add(size) + + case bytes.HasPrefix(key, TrienodeHistoryMetadataPrefix) && len(key) >= len(TrienodeHistoryMetadataPrefix)+common.HashLength: + trienodeIndex.add(size) + case bytes.HasPrefix(key, TrienodeHistoryBlockPrefix) && len(key) >= len(TrienodeHistoryBlockPrefix)+common.HashLength+4: + trienodeIndex.add(size) + + // Verkle trie data is detected, determine the sub-category + case bytes.HasPrefix(key, VerklePrefix): + remain := key[len(VerklePrefix):] + switch { + case IsAccountTrieNode(remain): + verkleTries.add(size) + case bytes.HasPrefix(remain, stateIDPrefix) && len(remain) == len(stateIDPrefix)+common.HashLength: + verkleStateLookups.add(size) + case bytes.Equal(remain, persistentStateIDKey): + metadata.add(size) + case bytes.Equal(remain, trieJournalKey): + metadata.add(size) + case bytes.Equal(remain, snapSyncStatusFlagKey): + metadata.add(size) + default: + unaccounted.add(size) + } + + // Metadata keys + case slices.ContainsFunc(knownMetadataKeys, func(x []byte) bool { return bytes.Equal(x, key) }): + metadata.add(size) + + default: + unaccounted.add(size) + if len(key) >= 2 { + prefix := [2]byte(key[:2]) + unaccountedMu.Lock() + if _, ok := unaccountedKeys[prefix]; !ok { + unaccountedKeys[prefix] = bytes.Clone(key) + } + unaccountedMu.Unlock() } } + + select { + case <-ctx.Done(): + return ctx.Err() + default: + } } - count++ - if count%1000 == 0 && time.Since(logged) > 8*time.Second { - log.Info("Inspecting database", "count", count, "elapsed", common.PrettyDuration(time.Since(start))) - logged = time.Now() - } + + return it.Error() } + + var ( + eg, ctx = errgroup.WithContext(context.Background()) + workers = runtime.NumCPU() + ) + eg.SetLimit(workers) + + // Progress reporter + done := make(chan struct{}) + go func() { + ticker := time.NewTicker(8 * time.Second) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + log.Info("Inspecting database", "count", count.Load(), "size", common.StorageSize(total.Load()), "elapsed", common.PrettyDuration(time.Since(start))) + case <-done: + return + } + } + }() + + // Inspect key-value database in parallel. + for i := 0; i < 256; i++ { + eg.Go(func() error { return inspectRange(ctx, byte(i)) }) + } + + if err := eg.Wait(); err != nil { + close(done) + return err + } + close(done) + // Display the database statistic of key-value store. stats := [][]string{ - {"Key-Value store", "Headers", headers.Size(), headers.Count()}, - {"Key-Value store", "Bodies", bodies.Size(), bodies.Count()}, - {"Key-Value store", "Receipt lists", receipts.Size(), receipts.Count()}, - {"Key-Value store", "Difficulties (deprecated)", tds.Size(), tds.Count()}, - {"Key-Value store", "Block number->hash", numHashPairings.Size(), numHashPairings.Count()}, - {"Key-Value store", "Block hash->number", hashNumPairings.Size(), hashNumPairings.Count()}, - {"Key-Value store", "Transaction index", txLookups.Size(), txLookups.Count()}, - {"Key-Value store", "Log index filter-map rows", filterMapRows.Size(), filterMapRows.Count()}, - {"Key-Value store", "Log index last-block-of-map", filterMapLastBlock.Size(), filterMapLastBlock.Count()}, - {"Key-Value store", "Log index block-lv", filterMapBlockLV.Size(), filterMapBlockLV.Count()}, - {"Key-Value store", "Log bloombits (deprecated)", bloomBits.Size(), bloomBits.Count()}, - {"Key-Value store", "Contract codes", codes.Size(), codes.Count()}, - {"Key-Value store", "Hash trie nodes", legacyTries.Size(), legacyTries.Count()}, - {"Key-Value store", "Path trie state lookups", stateLookups.Size(), stateLookups.Count()}, - {"Key-Value store", "Path trie account nodes", accountTries.Size(), accountTries.Count()}, - {"Key-Value store", "Path trie storage nodes", storageTries.Size(), storageTries.Count()}, - {"Key-Value store", "Path state history indexes", stateIndex.Size(), stateIndex.Count()}, - {"Key-Value store", "Verkle trie nodes", verkleTries.Size(), verkleTries.Count()}, - {"Key-Value store", "Verkle trie state lookups", verkleStateLookups.Size(), verkleStateLookups.Count()}, - {"Key-Value store", "Trie preimages", preimages.Size(), preimages.Count()}, - {"Key-Value store", "Account snapshot", accountSnaps.Size(), accountSnaps.Count()}, - {"Key-Value store", "Storage snapshot", storageSnaps.Size(), storageSnaps.Count()}, - {"Key-Value store", "Beacon sync headers", beaconHeaders.Size(), beaconHeaders.Count()}, - {"Key-Value store", "Clique snapshots", cliqueSnaps.Size(), cliqueSnaps.Count()}, - {"Key-Value store", "Singleton metadata", metadata.Size(), metadata.Count()}, + {"Key-Value store", "Headers", headers.sizeString(), headers.countString()}, + {"Key-Value store", "Bodies", bodies.sizeString(), bodies.countString()}, + {"Key-Value store", "Receipt lists", receipts.sizeString(), receipts.countString()}, + {"Key-Value store", "Difficulties (deprecated)", tds.sizeString(), tds.countString()}, + {"Key-Value store", "Block number->hash", numHashPairings.sizeString(), numHashPairings.countString()}, + {"Key-Value store", "Block hash->number", hashNumPairings.sizeString(), hashNumPairings.countString()}, + {"Key-Value store", "Transaction index", txLookups.sizeString(), txLookups.countString()}, + {"Key-Value store", "Log index filter-map rows", filterMapRows.sizeString(), filterMapRows.countString()}, + {"Key-Value store", "Log index last-block-of-map", filterMapLastBlock.sizeString(), filterMapLastBlock.countString()}, + {"Key-Value store", "Log index block-lv", filterMapBlockLV.sizeString(), filterMapBlockLV.countString()}, + {"Key-Value store", "Log bloombits (deprecated)", bloomBits.sizeString(), bloomBits.countString()}, + {"Key-Value store", "Contract codes", codes.sizeString(), codes.countString()}, + {"Key-Value store", "Hash trie nodes", legacyTries.sizeString(), legacyTries.countString()}, + {"Key-Value store", "Path trie state lookups", stateLookups.sizeString(), stateLookups.countString()}, + {"Key-Value store", "Path trie account nodes", accountTries.sizeString(), accountTries.countString()}, + {"Key-Value store", "Path trie storage nodes", storageTries.sizeString(), storageTries.countString()}, + {"Key-Value store", "Verkle trie nodes", verkleTries.sizeString(), verkleTries.countString()}, + {"Key-Value store", "Verkle trie state lookups", verkleStateLookups.sizeString(), verkleStateLookups.countString()}, + {"Key-Value store", "Trie preimages", preimages.sizeString(), preimages.countString()}, + {"Key-Value store", "Account snapshot", accountSnaps.sizeString(), accountSnaps.countString()}, + {"Key-Value store", "Storage snapshot", storageSnaps.sizeString(), storageSnaps.countString()}, + {"Key-Value store", "Historical state index", stateIndex.sizeString(), stateIndex.countString()}, + {"Key-Value store", "Historical trie index", trienodeIndex.sizeString(), trienodeIndex.countString()}, + {"Key-Value store", "Beacon sync headers", beaconHeaders.sizeString(), beaconHeaders.countString()}, + {"Key-Value store", "Clique snapshots", cliqueSnaps.sizeString(), cliqueSnaps.countString()}, + {"Key-Value store", "Singleton metadata", metadata.sizeString(), metadata.countString()}, } + // Inspect all registered append-only file store then. ancients, err := inspectFreezers(db) if err != nil { @@ -577,19 +657,20 @@ func InspectDatabase(db ethdb.Database, keyPrefix, keyStart []byte) error { fmt.Sprintf("Ancient store (%s)", strings.Title(ancient.name)), strings.Title(table.name), table.size.String(), - fmt.Sprintf("%d", ancient.count()), + fmt.Sprintf("%d", ancient.count), }) } - total += ancient.size() + total.Add(uint64(ancient.size())) } - table := tablewriter.NewWriter(os.Stdout) + + table := NewTableWriter(os.Stdout) table.SetHeader([]string{"Database", "Category", "Size", "Items"}) - table.SetFooter([]string{"", "Total", total.String(), " "}) + table.SetFooter([]string{"", "Total", common.StorageSize(total.Load()).String(), fmt.Sprintf("%d", count.Load())}) table.AppendBulk(stats) table.Render() - if unaccounted.size > 0 { - log.Error("Database contains unaccounted data", "size", unaccounted.size, "count", unaccounted.count) + if !unaccounted.empty() { + log.Error("Database contains unaccounted data", "size", unaccounted.sizeString(), "count", unaccounted.countString()) for _, e := range slices.SortedFunc(maps.Values(unaccountedKeys), bytes.Compare) { log.Error(fmt.Sprintf(" example key: %x", e)) } @@ -604,7 +685,7 @@ var knownMetadataKeys = [][]byte{ snapshotGeneratorKey, snapshotRecoveryKey, txIndexTailKey, fastTxLookupLimitKey, uncleanShutdownKey, badBlockKey, transitionStatusKey, skeletonSyncStatusKey, persistentStateIDKey, trieJournalKey, snapshotSyncStatusKey, snapSyncStatusFlagKey, - filterMapsRangeKey, headStateHistoryIndexKey, VerkleTransitionStatePrefix, + filterMapsRangeKey, headStateHistoryIndexKey, headTrienodeHistoryIndexKey, VerkleTransitionStatePrefix, } // printChainMetadata prints out chain metadata to stderr. diff --git a/core/rawdb/database_tablewriter.go b/core/rawdb/database_tablewriter.go new file mode 100644 index 0000000000..e1cda5c93f --- /dev/null +++ b/core/rawdb/database_tablewriter.go @@ -0,0 +1,209 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +// Naive stub implementation for tablewriter + +package rawdb + +import ( + "errors" + "fmt" + "io" + "strings" +) + +const ( + cellPadding = 1 // Number of spaces on each side of cell content + totalPadding = 2 * cellPadding // Total padding per cell. Its two because we pad equally on both sides +) + +type Table struct { + out io.Writer + headers []string + footer []string + rows [][]string +} + +func NewTableWriter(w io.Writer) *Table { + return &Table{out: w} +} + +// SetHeader sets the header row for the table. Headers define the column names +// and determine the number of columns for the entire table. +// +// All data rows and footer must have the same number of columns as the headers. +// +// Note: Headers are required - tables without headers will fail validation. +func (t *Table) SetHeader(headers []string) { + t.headers = headers +} + +// SetFooter sets an optional footer row for the table. +// +// The footer must have the same number of columns as the headers, or validation will fail. +func (t *Table) SetFooter(footer []string) { + t.footer = footer +} + +// AppendBulk sets all data rows for the table at once, replacing any existing rows. +// +// Each row must have the same number of columns as the headers, or validation +// will fail during Render(). +func (t *Table) AppendBulk(rows [][]string) { + t.rows = rows +} + +// Render outputs the complete table to the configured writer. The table is rendered +// with headers, data rows, and optional footer. +// +// If validation fails, an error message is written to the output and rendering stops. +func (t *Table) Render() { + if err := t.render(); err != nil { + fmt.Fprintf(t.out, "Error: %v\n", err) + return + } +} + +func (t *Table) render() error { + if err := t.validateColumnCount(); err != nil { + return err + } + + widths := t.calculateColumnWidths() + rowSeparator := t.buildRowSeparator(widths) + + if len(t.headers) > 0 { + fmt.Fprintln(t.out, rowSeparator) + t.printRow(t.headers, widths) + fmt.Fprintln(t.out, rowSeparator) + } + + for _, row := range t.rows { + t.printRow(row, widths) + } + + if len(t.footer) > 0 { + fmt.Fprintln(t.out, rowSeparator) + t.printRow(t.footer, widths) + fmt.Fprintln(t.out, rowSeparator) + } + + return nil +} + +// validateColumnCount checks that all rows and footer match the header column count +func (t *Table) validateColumnCount() error { + if len(t.headers) == 0 { + return errors.New("table must have headers") + } + + expectedCols := len(t.headers) + + // Check all rows have same column count as headers + for i, row := range t.rows { + if len(row) != expectedCols { + return fmt.Errorf("row %d has %d columns, expected %d", i, len(row), expectedCols) + } + } + + // Check footer has same column count as headers (if present) + footerPresent := len(t.footer) > 0 + if footerPresent && len(t.footer) != expectedCols { + return fmt.Errorf("footer has %d columns, expected %d", len(t.footer), expectedCols) + } + + return nil +} + +// calculateColumnWidths determines the minimum width needed for each column. +// +// This is done by finding the longest content in each column across headers, rows, and footer. +// +// Returns an int slice where widths[i] is the display width for column i (including padding). +func (t *Table) calculateColumnWidths() []int { + // Headers define the number of columns + cols := len(t.headers) + if cols == 0 { + return nil + } + + // Track maximum content width for each column (before padding) + widths := make([]int, cols) + + // Start with header widths + for i, h := range t.headers { + widths[i] = len(h) + } + + // Find max width needed for data cells in each column + for _, row := range t.rows { + for i, cell := range row { + widths[i] = max(widths[i], len(cell)) + } + } + + // Find max width needed for footer in each column + for i, f := range t.footer { + widths[i] = max(widths[i], len(f)) + } + + for i := range widths { + widths[i] += totalPadding + } + + return widths +} + +// buildRowSeparator creates a horizontal line to separate table rows. +// +// It generates a string with dashes (-) for each column width, joined by plus signs (+). +// +// Example output: "+----------+--------+-----------+" +func (t *Table) buildRowSeparator(widths []int) string { + parts := make([]string, len(widths)) + for i, w := range widths { + parts[i] = strings.Repeat("-", w) + } + return "+" + strings.Join(parts, "+") + "+" +} + +// printRow outputs a single row to the table writer. +// +// Each cell is padded with spaces and separated by pipe characters (|). +// +// Example output: "| Database | Size | Items |" +func (t *Table) printRow(row []string, widths []int) { + fmt.Fprintf(t.out, "|") + for i, cell := range row { + if i > 0 { + fmt.Fprint(t.out, "|") + } + + // Calculate centering pad without padding + contentWidth := widths[i] - totalPadding + cellLen := len(cell) + leftPadCentering := (contentWidth - cellLen) / 2 + rightPadCentering := contentWidth - cellLen - leftPadCentering + + // Build padded cell with centering + leftPadding := strings.Repeat(" ", cellPadding+leftPadCentering) + rightPadding := strings.Repeat(" ", cellPadding+rightPadCentering) + + fmt.Fprintf(t.out, "%s%s%s", leftPadding, cell, rightPadding) + } + fmt.Fprintf(t.out, "|") + fmt.Fprintln(t.out) +} diff --git a/core/rawdb/database_tablewriter_test.go b/core/rawdb/database_tablewriter_test.go new file mode 100644 index 0000000000..e9de5d8ce8 --- /dev/null +++ b/core/rawdb/database_tablewriter_test.go @@ -0,0 +1,121 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rawdb + +import ( + "bytes" + "strings" + "testing" +) + +func TestTableWriterTinyGo(t *testing.T) { + var buf bytes.Buffer + table := NewTableWriter(&buf) + + headers := []string{"Database", "Size", "Items", "Status"} + rows := [][]string{ + {"chaindata", "2.5 GB", "1,234,567", "Active"}, + {"state", "890 MB", "456,789", "Active"}, + {"ancient", "15.2 GB", "2,345,678", "Readonly"}, + {"logs", "120 MB", "89,012", "Active"}, + } + footer := []string{"Total", "18.71 GB", "4,125,046", "-"} + + table.SetHeader(headers) + table.AppendBulk(rows) + table.SetFooter(footer) + table.Render() + + output := buf.String() + t.Logf("Table output using custom stub implementation:\n%s", output) +} + +func TestTableWriterValidationErrors(t *testing.T) { + // Test missing headers + t.Run("MissingHeaders", func(t *testing.T) { + var buf bytes.Buffer + table := NewTableWriter(&buf) + + rows := [][]string{{"x", "y", "z"}} + + table.AppendBulk(rows) + table.Render() + + output := buf.String() + if !strings.Contains(output, "table must have headers") { + t.Errorf("Expected error for missing headers, got: %s", output) + } + }) + + t.Run("NotEnoughRowColumns", func(t *testing.T) { + var buf bytes.Buffer + table := NewTableWriter(&buf) + + headers := []string{"A", "B", "C"} + badRows := [][]string{ + {"x", "y"}, // Missing column + } + + table.SetHeader(headers) + table.AppendBulk(badRows) + table.Render() + + output := buf.String() + if !strings.Contains(output, "row 0 has 2 columns, expected 3") { + t.Errorf("Expected validation error for row 0, got: %s", output) + } + }) + + t.Run("TooManyRowColumns", func(t *testing.T) { + var buf bytes.Buffer + table := NewTableWriter(&buf) + + headers := []string{"A", "B", "C"} + badRows := [][]string{ + {"p", "q", "r", "s"}, // Extra column + } + + table.SetHeader(headers) + table.AppendBulk(badRows) + table.Render() + + output := buf.String() + if !strings.Contains(output, "row 0 has 4 columns, expected 3") { + t.Errorf("Expected validation error for row 0, got: %s", output) + } + }) + + // Test mismatched footer columns + t.Run("MismatchedFooterColumns", func(t *testing.T) { + var buf bytes.Buffer + table := NewTableWriter(&buf) + + headers := []string{"A", "B", "C"} + rows := [][]string{{"x", "y", "z"}} + footer := []string{"total", "sum"} // Missing column + + table.SetHeader(headers) + table.AppendBulk(rows) + table.SetFooter(footer) + table.Render() + + output := buf.String() + if !strings.Contains(output, "footer has 2 columns, expected 3") { + t.Errorf("Expected validation error for footer, got: %s", output) + } + }) +} diff --git a/core/rawdb/eradb/eradb.go b/core/rawdb/eradb/eradb.go index 29e658798e..a552b94da9 100644 --- a/core/rawdb/eradb/eradb.go +++ b/core/rawdb/eradb/eradb.go @@ -303,6 +303,7 @@ func (db *Store) openEraFile(epoch uint64) (*era.Era, error) { } // Sanity-check start block. if e.Start()%uint64(era.MaxEra1Size) != 0 { + e.Close() return nil, fmt.Errorf("pre-merge era1 file has invalid boundary. %d %% %d != 0", e.Start(), era.MaxEra1Size) } log.Debug("Opened era1 file", "epoch", epoch) diff --git a/core/rawdb/freezer.go b/core/rawdb/freezer.go index a9600c1eef..42cd2a7999 100644 --- a/core/rawdb/freezer.go +++ b/core/rawdb/freezer.go @@ -76,8 +76,9 @@ type Freezer struct { // NewFreezer creates a freezer instance for maintaining immutable ordered // data according to the given parameters. // -// The 'tables' argument defines the data tables. If the value of a map -// entry is true, snappy compression is disabled for the table. +// The 'tables' argument defines the freezer tables and their configuration. +// Each value is a freezerTableConfig specifying whether snappy compression is +// disabled (noSnappy) and whether the table is prunable (prunable). func NewFreezer(datadir string, namespace string, readonly bool, maxTableSize uint32, tables map[string]freezerTableConfig) (*Freezer, error) { // Create the initial freezer object var ( @@ -201,6 +202,15 @@ func (f *Freezer) AncientRange(kind string, start, count, maxBytes uint64) ([][] return nil, errUnknownTable } +// AncientBytes retrieves the value segment of the element specified by the id +// and value offsets. +func (f *Freezer) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) { + if table := f.tables[kind]; table != nil { + return table.RetrieveBytes(id, offset, length) + } + return nil, errUnknownTable +} + // Ancients returns the length of the frozen items. func (f *Freezer) Ancients() (uint64, error) { return f.frozen.Load(), nil diff --git a/core/rawdb/freezer_batch.go b/core/rawdb/freezer_batch.go index 7e46e49f43..080c0720a1 100644 --- a/core/rawdb/freezer_batch.go +++ b/core/rawdb/freezer_batch.go @@ -51,12 +51,18 @@ func newFreezerBatch(f *Freezer) *freezerBatch { // Append adds an RLP-encoded item of the given kind. func (batch *freezerBatch) Append(kind string, num uint64, item interface{}) error { - return batch.tables[kind].Append(num, item) + if table := batch.tables[kind]; table != nil { + return table.Append(num, item) + } + return errUnknownTable } // AppendRaw adds an item of the given kind. func (batch *freezerBatch) AppendRaw(kind string, num uint64, item []byte) error { - return batch.tables[kind].AppendRaw(num, item) + if table := batch.tables[kind]; table != nil { + return table.AppendRaw(num, item) + } + return errUnknownTable } // reset initializes the batch. diff --git a/core/rawdb/freezer_memory.go b/core/rawdb/freezer_memory.go index f5621ac4c6..a0d308f896 100644 --- a/core/rawdb/freezer_memory.go +++ b/core/rawdb/freezer_memory.go @@ -91,6 +91,13 @@ func (t *memoryTable) truncateHead(items uint64) error { if items < t.offset { return errors.New("truncation below tail") } + for i := int(items - t.offset); i < len(t.data); i++ { + if t.size > uint64(len(t.data[i])) { + t.size -= uint64(len(t.data[i])) + } else { + t.size = 0 + } + } t.data = t.data[:items-t.offset] t.items = items return nil @@ -108,6 +115,13 @@ func (t *memoryTable) truncateTail(items uint64) error { if t.items < items { return errors.New("truncation above head") } + for i := uint64(0); i < items-t.offset; i++ { + if t.size > uint64(len(t.data[i])) { + t.size -= uint64(len(t.data[i])) + } else { + t.size = 0 + } + } t.data = t.data[items-t.offset:] t.offset = items return nil @@ -412,3 +426,28 @@ func (f *MemoryFreezer) Reset() error { func (f *MemoryFreezer) AncientDatadir() (string, error) { return "", nil } + +// AncientBytes retrieves the value segment of the element specified by the id +// and value offsets. +func (f *MemoryFreezer) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + table := f.tables[kind] + if table == nil { + return nil, errUnknownTable + } + entries, err := table.retrieve(id, 1, 0) + if err != nil { + return nil, err + } + if len(entries) == 0 { + return nil, errOutOfBounds + } + data := entries[0] + + if offset > uint64(len(data)) || offset+length > uint64(len(data)) { + return nil, fmt.Errorf("requested range out of bounds: item size %d, offset %d, length %d", len(data), offset, length) + } + return data[offset : offset+length], nil +} diff --git a/core/rawdb/freezer_resettable.go b/core/rawdb/freezer_resettable.go index 9db71cfd0e..f531e668c3 100644 --- a/core/rawdb/freezer_resettable.go +++ b/core/rawdb/freezer_resettable.go @@ -126,6 +126,15 @@ func (f *resettableFreezer) AncientRange(kind string, start, count, maxBytes uin return f.freezer.AncientRange(kind, start, count, maxBytes) } +// AncientBytes retrieves the value segment of the element specified by the id +// and value offsets. +func (f *resettableFreezer) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) { + f.lock.RLock() + defer f.lock.RUnlock() + + return f.freezer.AncientBytes(kind, id, offset, length) +} + // Ancients returns the length of the frozen items. func (f *resettableFreezer) Ancients() (uint64, error) { f.lock.RLock() diff --git a/core/rawdb/freezer_table.go b/core/rawdb/freezer_table.go index 19c40cc16e..aedb2d8eed 100644 --- a/core/rawdb/freezer_table.go +++ b/core/rawdb/freezer_table.go @@ -100,7 +100,7 @@ type freezerTable struct { // should never be lower than itemOffset. itemHidden atomic.Uint64 - config freezerTableConfig // if true, disables snappy compression. Note: does not work retroactively + config freezerTableConfig // table configuration (compression, prunability). Note: compression flag does not apply retroactively to existing files readonly bool maxFileSize uint32 // Max file size for data-files name string @@ -1107,6 +1107,71 @@ func (t *freezerTable) retrieveItems(start, count, maxBytes uint64) ([]byte, []i return output, sizes, nil } +// RetrieveBytes retrieves the value segment of the element specified by the id +// and value offsets. +func (t *freezerTable) RetrieveBytes(item, offset, length uint64) ([]byte, error) { + t.lock.RLock() + defer t.lock.RUnlock() + + if t.index == nil || t.head == nil || t.metadata.file == nil { + return nil, errClosed + } + items, hidden := t.items.Load(), t.itemHidden.Load() + if items <= item || hidden > item { + return nil, errOutOfBounds + } + + // Retrieves the index entries for the specified ID and its immediate successor + indices, err := t.getIndices(item, 1) + if err != nil { + return nil, err + } + index0, index1 := indices[0], indices[1] + + itemStart, itemLimit, fileId := index0.bounds(index1) + itemSize := itemLimit - itemStart + + dataFile, exist := t.files[fileId] + if !exist { + return nil, fmt.Errorf("missing data file %d", fileId) + } + + // Perform the partial read if no-compression was enabled upon + if t.config.noSnappy { + if offset > uint64(itemSize) || offset+length > uint64(itemSize) { + return nil, fmt.Errorf("requested range out of bounds: item size %d, offset %d, length %d", itemSize, offset, length) + } + itemStart += uint32(offset) + + buf := make([]byte, length) + _, err = dataFile.ReadAt(buf, int64(itemStart)) + if err != nil { + return nil, err + } + t.readMeter.Mark(int64(length)) + return buf, nil + } else { + // If compressed, read the full item, decompress, then slice. + // Unfortunately, in this case, there is no performance gain + // by performing the partial read at all. + buf := make([]byte, itemSize) + _, err = dataFile.ReadAt(buf, int64(itemStart)) + if err != nil { + return nil, err + } + t.readMeter.Mark(int64(itemSize)) + + data, err := snappy.Decode(nil, buf) + if err != nil { + return nil, err + } + if offset > uint64(len(data)) || offset+length > uint64(len(data)) { + return nil, fmt.Errorf("requested range out of bounds: item size %d, offset %d, length %d", len(data), offset, length) + } + return data[offset : offset+length], nil + } +} + // size returns the total data size in the freezer table. func (t *freezerTable) size() (uint64, error) { t.lock.RLock() @@ -1131,8 +1196,7 @@ func (t *freezerTable) sizeNolock() (uint64, error) { } // advanceHead should be called when the current head file would outgrow the file limits, -// and a new file must be opened. The caller of this method must hold the write-lock -// before calling this method. +// and a new file must be opened. This method acquires the write-lock internally. func (t *freezerTable) advanceHead() error { t.lock.Lock() defer t.lock.Unlock() @@ -1153,7 +1217,9 @@ func (t *freezerTable) advanceHead() error { return err } t.releaseFile(t.headId) - t.openFile(t.headId, openFreezerFileForReadOnly) + if _, err := t.openFile(t.headId, openFreezerFileForReadOnly); err != nil { + return err + } // Swap out the current head. t.head = newHead diff --git a/core/rawdb/freezer_table_test.go b/core/rawdb/freezer_table_test.go index 96edac7e4a..fc21ea6c63 100644 --- a/core/rawdb/freezer_table_test.go +++ b/core/rawdb/freezer_table_test.go @@ -1571,3 +1571,65 @@ func TestTailTruncationCrash(t *testing.T) { t.Fatalf("Unexpected index flush offset, want: %d, got: %d", 26*indexEntrySize, f.metadata.flushOffset) } } + +func TestFreezerAncientBytes(t *testing.T) { + t.Parallel() + types := []struct { + name string + config freezerTableConfig + }{ + {"uncompressed", freezerTableConfig{noSnappy: true}}, + {"compressed", freezerTableConfig{noSnappy: false}}, + } + for _, typ := range types { + t.Run(typ.name, func(t *testing.T) { + f, err := newTable(os.TempDir(), fmt.Sprintf("ancientbytes-%s-%d", typ.name, rand.Uint64()), metrics.NewMeter(), metrics.NewMeter(), metrics.NewGauge(), 1000, typ.config, false) + if err != nil { + t.Fatal(err) + } + defer f.Close() + + for i := 0; i < 10; i++ { + data := getChunk(100, i) + batch := f.newBatch() + require.NoError(t, batch.AppendRaw(uint64(i), data)) + require.NoError(t, batch.commit()) + } + + for i := 0; i < 10; i++ { + full, err := f.Retrieve(uint64(i)) + require.NoError(t, err) + + // Full read + got, err := f.RetrieveBytes(uint64(i), 0, uint64(len(full))) + require.NoError(t, err) + if !bytes.Equal(got, full) { + t.Fatalf("full read mismatch for entry %d", i) + } + // Empty read + got, err = f.RetrieveBytes(uint64(i), 0, 0) + require.NoError(t, err) + if !bytes.Equal(got, full[:0]) { + t.Fatalf("empty read mismatch for entry %d", i) + } + // Middle slice + got, err = f.RetrieveBytes(uint64(i), 10, 50) + require.NoError(t, err) + if !bytes.Equal(got, full[10:60]) { + t.Fatalf("middle slice mismatch for entry %d", i) + } + // Single byte + got, err = f.RetrieveBytes(uint64(i), 99, 1) + require.NoError(t, err) + if !bytes.Equal(got, full[99:100]) { + t.Fatalf("single byte mismatch for entry %d", i) + } + // Out of bounds + _, err = f.RetrieveBytes(uint64(i), 100, 1) + if err == nil { + t.Fatalf("expected error for out-of-bounds read for entry %d", i) + } + } + }) + } +} diff --git a/core/rawdb/freezer_test.go b/core/rawdb/freezer_test.go index b8a3d4a6d2..fab3319a2a 100644 --- a/core/rawdb/freezer_test.go +++ b/core/rawdb/freezer_test.go @@ -239,7 +239,7 @@ func TestFreezerConcurrentModifyTruncate(t *testing.T) { // fails, otherwise it succeeds. In either case, the freezer should be positioned // at 10 after both operations are done. if truncateErr != nil { - t.Fatal("concurrent truncate failed:", err) + t.Fatal("concurrent truncate failed:", truncateErr) } if !(errors.Is(modifyErr, nil) || errors.Is(modifyErr, errOutOrderInsertion)) { t.Fatal("wrong error from concurrent modify:", modifyErr) diff --git a/core/rawdb/schema.go b/core/rawdb/schema.go index 72f9bd34ec..d9140c5fd6 100644 --- a/core/rawdb/schema.go +++ b/core/rawdb/schema.go @@ -80,6 +80,10 @@ var ( // been indexed. headStateHistoryIndexKey = []byte("LastStateHistoryIndex") + // headTrienodeHistoryIndexKey tracks the ID of the latest state history that has + // been indexed. + headTrienodeHistoryIndexKey = []byte("LastTrienodeHistoryIndex") + // txIndexTailKey tracks the oldest block whose transactions have been indexed. txIndexTailKey = []byte("TransactionIndexTail") @@ -95,7 +99,7 @@ var ( uncleanShutdownKey = []byte("unclean-shutdown") // config prefix for the db // transitionStatusKey tracks the eth2 transition status. - transitionStatusKey = []byte("eth2-transition") + transitionStatusKey = []byte("eth2-transition") // deprecated // snapSyncStatusFlagKey flags that status of snap sync. snapSyncStatusFlagKey = []byte("SnapSyncStatus") @@ -125,8 +129,10 @@ var ( StateHistoryIndexPrefix = []byte("m") // The global prefix of state history index data StateHistoryAccountMetadataPrefix = []byte("ma") // StateHistoryAccountMetadataPrefix + account address hash => account metadata StateHistoryStorageMetadataPrefix = []byte("ms") // StateHistoryStorageMetadataPrefix + account address hash + storage slot hash => slot metadata + TrienodeHistoryMetadataPrefix = []byte("mt") // TrienodeHistoryMetadataPrefix + account address hash + trienode path => trienode metadata StateHistoryAccountBlockPrefix = []byte("mba") // StateHistoryAccountBlockPrefix + account address hash + blockID => account block StateHistoryStorageBlockPrefix = []byte("mbs") // StateHistoryStorageBlockPrefix + account address hash + storage slot hash + blockID => slot block + TrienodeHistoryBlockPrefix = []byte("mbt") // TrienodeHistoryBlockPrefix + account address hash + trienode path + blockID => trienode block // VerklePrefix is the database prefix for Verkle trie data, which includes: // (a) Trie nodes @@ -384,21 +390,69 @@ func accountHistoryIndexKey(addressHash common.Hash) []byte { // storageHistoryIndexKey = StateHistoryStorageMetadataPrefix + addressHash + storageHash func storageHistoryIndexKey(addressHash common.Hash, storageHash common.Hash) []byte { - return append(append(StateHistoryStorageMetadataPrefix, addressHash.Bytes()...), storageHash.Bytes()...) + totalLen := len(StateHistoryStorageMetadataPrefix) + 2*common.HashLength + out := make([]byte, totalLen) + + off := 0 + off += copy(out[off:], StateHistoryStorageMetadataPrefix) + off += copy(out[off:], addressHash.Bytes()) + copy(out[off:], storageHash.Bytes()) + + return out +} + +// trienodeHistoryIndexKey = TrienodeHistoryMetadataPrefix + addressHash + trienode path +func trienodeHistoryIndexKey(addressHash common.Hash, path []byte) []byte { + totalLen := len(TrienodeHistoryMetadataPrefix) + common.HashLength + len(path) + out := make([]byte, totalLen) + + off := 0 + off += copy(out[off:], TrienodeHistoryMetadataPrefix) + off += copy(out[off:], addressHash.Bytes()) + copy(out[off:], path) + + return out } // accountHistoryIndexBlockKey = StateHistoryAccountBlockPrefix + addressHash + blockID func accountHistoryIndexBlockKey(addressHash common.Hash, blockID uint32) []byte { - var buf [4]byte - binary.BigEndian.PutUint32(buf[:], blockID) - return append(append(StateHistoryAccountBlockPrefix, addressHash.Bytes()...), buf[:]...) + totalLen := len(StateHistoryAccountBlockPrefix) + common.HashLength + 4 + out := make([]byte, totalLen) + + off := 0 + off += copy(out[off:], StateHistoryAccountBlockPrefix) + off += copy(out[off:], addressHash.Bytes()) + binary.BigEndian.PutUint32(out[off:], blockID) + + return out } // storageHistoryIndexBlockKey = StateHistoryStorageBlockPrefix + addressHash + storageHash + blockID func storageHistoryIndexBlockKey(addressHash common.Hash, storageHash common.Hash, blockID uint32) []byte { - var buf [4]byte - binary.BigEndian.PutUint32(buf[:], blockID) - return append(append(append(StateHistoryStorageBlockPrefix, addressHash.Bytes()...), storageHash.Bytes()...), buf[:]...) + totalLen := len(StateHistoryStorageBlockPrefix) + 2*common.HashLength + 4 + out := make([]byte, totalLen) + + off := 0 + off += copy(out[off:], StateHistoryStorageBlockPrefix) + off += copy(out[off:], addressHash.Bytes()) + off += copy(out[off:], storageHash.Bytes()) + binary.BigEndian.PutUint32(out[off:], blockID) + + return out +} + +// trienodeHistoryIndexBlockKey = TrienodeHistoryBlockPrefix + addressHash + trienode path + blockID +func trienodeHistoryIndexBlockKey(addressHash common.Hash, path []byte, blockID uint32) []byte { + totalLen := len(TrienodeHistoryBlockPrefix) + common.HashLength + len(path) + 4 + out := make([]byte, totalLen) + + off := 0 + off += copy(out[off:], TrienodeHistoryBlockPrefix) + off += copy(out[off:], addressHash.Bytes()) + off += copy(out[off:], path) + binary.BigEndian.PutUint32(out[off:], blockID) + + return out } // transitionStateKey = transitionStatusKey + hash diff --git a/core/rawdb/table.go b/core/rawdb/table.go index 45c8aecf0c..d38afdaa35 100644 --- a/core/rawdb/table.go +++ b/core/rawdb/table.go @@ -62,6 +62,12 @@ func (t *table) AncientRange(kind string, start, count, maxBytes uint64) ([][]by return t.db.AncientRange(kind, start, count, maxBytes) } +// AncientBytes is a noop passthrough that just forwards the request to the underlying +// database. +func (t *table) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) { + return t.db.AncientBytes(kind, id, offset, length) +} + // Ancients is a noop passthrough that just forwards the request to the underlying // database. func (t *table) Ancients() (uint64, error) { diff --git a/core/rlp_test.go b/core/rlp_test.go index bc37408537..69efa82551 100644 --- a/core/rlp_test.go +++ b/core/rlp_test.go @@ -149,8 +149,7 @@ func BenchmarkHashing(b *testing.B) { var got common.Hash var hasher = sha3.NewLegacyKeccak256() b.Run("iteratorhashing", func(b *testing.B) { - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { var hash common.Hash it, err := rlp.NewListIterator(bodyRlp) if err != nil { @@ -172,8 +171,7 @@ func BenchmarkHashing(b *testing.B) { }) var exp common.Hash b.Run("fullbodyhashing", func(b *testing.B) { - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { var body types.Body rlp.DecodeBytes(bodyRlp, &body) for _, tx := range body.Transactions { @@ -182,8 +180,7 @@ func BenchmarkHashing(b *testing.B) { } }) b.Run("fullblockhashing", func(b *testing.B) { - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { var block types.Block rlp.DecodeBytes(blockRlp, &block) for _, tx := range block.Transactions() { diff --git a/core/state/access_events.go b/core/state/access_events.go index 0575c9898a..86f44bd623 100644 --- a/core/state/access_events.go +++ b/core/state/access_events.go @@ -23,7 +23,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie/utils" + "github.com/ethereum/go-ethereum/trie/bintrie" "github.com/holiman/uint256" ) @@ -45,15 +45,12 @@ var zeroTreeIndex uint256.Int type AccessEvents struct { branches map[branchAccessKey]mode chunks map[chunkAccessKey]mode - - pointCache *utils.PointCache } -func NewAccessEvents(pointCache *utils.PointCache) *AccessEvents { +func NewAccessEvents() *AccessEvents { return &AccessEvents{ - branches: make(map[branchAccessKey]mode), - chunks: make(map[chunkAccessKey]mode), - pointCache: pointCache, + branches: make(map[branchAccessKey]mode), + chunks: make(map[chunkAccessKey]mode), } } @@ -75,8 +72,11 @@ func (ae *AccessEvents) Keys() [][]byte { // TODO: consider if parallelizing this is worth it, probably depending on len(ae.chunks). keys := make([][]byte, 0, len(ae.chunks)) for chunk := range ae.chunks { - basePoint := ae.pointCache.Get(chunk.addr[:]) - key := utils.GetTreeKeyWithEvaluatedAddress(basePoint, &chunk.treeIndex, chunk.leafKey) + var offset [32]byte + treeIndexBytes := chunk.treeIndex.Bytes32() + copy(offset[:31], treeIndexBytes[1:]) + offset[31] = chunk.leafKey + key := bintrie.GetBinaryTreeKey(chunk.addr, offset[:]) keys = append(keys, key) } return keys @@ -84,9 +84,8 @@ func (ae *AccessEvents) Keys() [][]byte { func (ae *AccessEvents) Copy() *AccessEvents { cpy := &AccessEvents{ - branches: maps.Clone(ae.branches), - chunks: maps.Clone(ae.chunks), - pointCache: ae.pointCache, + branches: maps.Clone(ae.branches), + chunks: maps.Clone(ae.chunks), } return cpy } @@ -95,12 +94,12 @@ func (ae *AccessEvents) Copy() *AccessEvents { // member fields of an account. func (ae *AccessEvents) AddAccount(addr common.Address, isWrite bool, availableGas uint64) uint64 { var gas uint64 // accumulate the consumed gas - consumed, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, isWrite, availableGas) + consumed, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.BasicDataLeafKey, isWrite, availableGas) if consumed < expected { return expected } gas += consumed - consumed, expected = ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite, availableGas-consumed) + consumed, expected = ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.CodeHashLeafKey, isWrite, availableGas-consumed) if consumed < expected { return expected + gas } @@ -112,7 +111,7 @@ func (ae *AccessEvents) AddAccount(addr common.Address, isWrite bool, availableG // cold member fields of an account, that need to be touched when making a message // call to that account. func (ae *AccessEvents) MessageCallGas(destination common.Address, availableGas uint64) uint64 { - _, expected := ae.touchAddressAndChargeGas(destination, zeroTreeIndex, utils.BasicDataLeafKey, false, availableGas) + _, expected := ae.touchAddressAndChargeGas(destination, zeroTreeIndex, bintrie.BasicDataLeafKey, false, availableGas) if expected == 0 { expected = params.WarmStorageReadCostEIP2929 } @@ -122,11 +121,11 @@ func (ae *AccessEvents) MessageCallGas(destination common.Address, availableGas // ValueTransferGas returns the gas to be charged for each of the currently // cold balance member fields of the caller and the callee accounts. func (ae *AccessEvents) ValueTransferGas(callerAddr, targetAddr common.Address, availableGas uint64) uint64 { - _, expected1 := ae.touchAddressAndChargeGas(callerAddr, zeroTreeIndex, utils.BasicDataLeafKey, true, availableGas) + _, expected1 := ae.touchAddressAndChargeGas(callerAddr, zeroTreeIndex, bintrie.BasicDataLeafKey, true, availableGas) if expected1 > availableGas { return expected1 } - _, expected2 := ae.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, utils.BasicDataLeafKey, true, availableGas-expected1) + _, expected2 := ae.touchAddressAndChargeGas(targetAddr, zeroTreeIndex, bintrie.BasicDataLeafKey, true, availableGas-expected1) if expected1+expected2 == 0 { return params.WarmStorageReadCostEIP2929 } @@ -138,8 +137,8 @@ func (ae *AccessEvents) ValueTransferGas(callerAddr, targetAddr common.Address, // address collision is done before the transfer, and so no write // are guaranteed to happen at this point. func (ae *AccessEvents) ContractCreatePreCheckGas(addr common.Address, availableGas uint64) uint64 { - consumed, expected1 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, false, availableGas) - _, expected2 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, false, availableGas-consumed) + consumed, expected1 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.BasicDataLeafKey, false, availableGas) + _, expected2 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.CodeHashLeafKey, false, availableGas-consumed) return expected1 + expected2 } @@ -147,9 +146,9 @@ func (ae *AccessEvents) ContractCreatePreCheckGas(addr common.Address, available // a contract creation. func (ae *AccessEvents) ContractCreateInitGas(addr common.Address, availableGas uint64) (uint64, uint64) { var gas uint64 - consumed, expected1 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, true, availableGas) + consumed, expected1 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.BasicDataLeafKey, true, availableGas) gas += consumed - consumed, expected2 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, true, availableGas-consumed) + consumed, expected2 := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.CodeHashLeafKey, true, availableGas-consumed) gas += consumed return gas, expected1 + expected2 } @@ -157,20 +156,20 @@ func (ae *AccessEvents) ContractCreateInitGas(addr common.Address, availableGas // AddTxOrigin adds the member fields of the sender account to the access event list, // so that cold accesses are not charged, since they are covered by the 21000 gas. func (ae *AccessEvents) AddTxOrigin(originAddr common.Address) { - ae.touchAddressAndChargeGas(originAddr, zeroTreeIndex, utils.BasicDataLeafKey, true, gomath.MaxUint64) - ae.touchAddressAndChargeGas(originAddr, zeroTreeIndex, utils.CodeHashLeafKey, false, gomath.MaxUint64) + ae.touchAddressAndChargeGas(originAddr, zeroTreeIndex, bintrie.BasicDataLeafKey, true, gomath.MaxUint64) + ae.touchAddressAndChargeGas(originAddr, zeroTreeIndex, bintrie.CodeHashLeafKey, false, gomath.MaxUint64) } // AddTxDestination adds the member fields of the sender account to the access event list, // so that cold accesses are not charged, since they are covered by the 21000 gas. func (ae *AccessEvents) AddTxDestination(addr common.Address, sendsValue, doesntExist bool) { - ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, sendsValue, gomath.MaxUint64) - ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, doesntExist, gomath.MaxUint64) + ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.BasicDataLeafKey, sendsValue, gomath.MaxUint64) + ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.CodeHashLeafKey, doesntExist, gomath.MaxUint64) } // SlotGas returns the amount of gas to be charged for a cold storage access. func (ae *AccessEvents) SlotGas(addr common.Address, slot common.Hash, isWrite bool, availableGas uint64, chargeWarmCosts bool) uint64 { - treeIndex, subIndex := utils.StorageIndex(slot.Bytes()) + treeIndex, subIndex := bintrie.StorageIndex(slot.Bytes()) _, expected := ae.touchAddressAndChargeGas(addr, *treeIndex, subIndex, isWrite, availableGas) if expected == 0 && chargeWarmCosts { expected = params.WarmStorageReadCostEIP2929 @@ -313,7 +312,7 @@ func (ae *AccessEvents) CodeChunksRangeGas(contractAddr common.Address, startPC, // Note that an access in write mode implies an access in read mode, whereas an // access in read mode does not imply an access in write mode. func (ae *AccessEvents) BasicDataGas(addr common.Address, isWrite bool, availableGas uint64, chargeWarmCosts bool) uint64 { - _, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.BasicDataLeafKey, isWrite, availableGas) + _, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.BasicDataLeafKey, isWrite, availableGas) if expected == 0 && chargeWarmCosts { if availableGas < params.WarmStorageReadCostEIP2929 { return availableGas @@ -329,7 +328,7 @@ func (ae *AccessEvents) BasicDataGas(addr common.Address, isWrite bool, availabl // Note that an access in write mode implies an access in read mode, whereas an access in // read mode does not imply an access in write mode. func (ae *AccessEvents) CodeHashGas(addr common.Address, isWrite bool, availableGas uint64, chargeWarmCosts bool) uint64 { - _, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, utils.CodeHashLeafKey, isWrite, availableGas) + _, expected := ae.touchAddressAndChargeGas(addr, zeroTreeIndex, bintrie.CodeHashLeafKey, isWrite, availableGas) if expected == 0 && chargeWarmCosts { if availableGas < params.WarmStorageReadCostEIP2929 { return availableGas diff --git a/core/state/access_events_test.go b/core/state/access_events_test.go index 5e1fee767c..0b39130e8d 100644 --- a/core/state/access_events_test.go +++ b/core/state/access_events_test.go @@ -22,7 +22,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie/utils" ) var ( @@ -38,7 +37,7 @@ func init() { } func TestAccountHeaderGas(t *testing.T) { - ae := NewAccessEvents(utils.NewPointCache(1024)) + ae := NewAccessEvents() // Check cold read cost gas := ae.BasicDataGas(testAddr, false, math.MaxUint64, false) @@ -93,7 +92,7 @@ func TestAccountHeaderGas(t *testing.T) { // TestContractCreateInitGas checks that the gas cost of contract creation is correctly // calculated. func TestContractCreateInitGas(t *testing.T) { - ae := NewAccessEvents(utils.NewPointCache(1024)) + ae := NewAccessEvents() var testAddr [20]byte for i := byte(0); i < 20; i++ { @@ -116,7 +115,7 @@ func TestContractCreateInitGas(t *testing.T) { // TestMessageCallGas checks that the gas cost of message calls is correctly // calculated. func TestMessageCallGas(t *testing.T) { - ae := NewAccessEvents(utils.NewPointCache(1024)) + ae := NewAccessEvents() // Check cold read cost, without a value gas := ae.MessageCallGas(testAddr, math.MaxUint64) @@ -131,7 +130,7 @@ func TestMessageCallGas(t *testing.T) { } gas = ae.CodeHashGas(testAddr, false, math.MaxUint64, false) if gas != params.WitnessChunkReadCost { - t.Fatalf("incorrect gas computed, got %d, want %d", gas, 0) + t.Fatalf("incorrect gas computed, got %d, want %d", gas, params.WitnessChunkReadCost) } // Check warm read cost diff --git a/core/state/access_list.go b/core/state/access_list.go index e3f1738864..0b830e7222 100644 --- a/core/state/access_list.go +++ b/core/state/access_list.go @@ -61,9 +61,10 @@ func newAccessList() *accessList { // Copy creates an independent copy of an accessList. func (al *accessList) Copy() *accessList { - cp := newAccessList() - cp.addresses = maps.Clone(al.addresses) - cp.slots = make([]map[common.Hash]struct{}, len(al.slots)) + cp := &accessList{ + addresses: maps.Clone(al.addresses), + slots: make([]map[common.Hash]struct{}, len(al.slots)), + } for i, slotMap := range al.slots { cp.slots[i] = maps.Clone(slotMap) } diff --git a/core/state/database.go b/core/state/database.go index b46e5d500d..4a5547d075 100644 --- a/core/state/database.go +++ b/core/state/database.go @@ -28,8 +28,9 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/bintrie" + "github.com/ethereum/go-ethereum/trie/transitiontrie" "github.com/ethereum/go-ethereum/trie/trienode" - "github.com/ethereum/go-ethereum/trie/utils" "github.com/ethereum/go-ethereum/triedb" ) @@ -39,9 +40,6 @@ const ( // Cache size granted for caching clean code. codeCacheSize = 256 * 1024 * 1024 - - // Number of address->curve point associations to keep. - pointCacheSize = 4096 ) // Database wraps access to tries and contract code. @@ -55,9 +53,6 @@ type Database interface { // OpenStorageTrie opens the storage trie of an account. OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, trie Trie) (Trie, error) - // PointCache returns the cache holding points used in verkle tree key computation - PointCache() *utils.PointCache - // TrieDB returns the underlying trie database for managing trie nodes. TrieDB() *triedb.Database @@ -81,11 +76,19 @@ type Trie interface { // be returned. GetAccount(address common.Address) (*types.StateAccount, error) + // PrefetchAccount attempts to resolve specific accounts from the database + // to accelerate subsequent trie operations. + PrefetchAccount([]common.Address) error + // GetStorage returns the value for key stored in the trie. The value bytes // must not be modified by the caller. If a node was not found in the database, // a trie.MissingNodeError is returned. GetStorage(addr common.Address, key []byte) ([]byte, error) + // PrefetchStorage attempts to resolve specific storage slots from the database + // to accelerate subsequent trie operations. + PrefetchStorage(addr common.Address, keys [][]byte) error + // UpdateAccount abstracts an account write to the trie. It encodes the // provided account object with associated algorithm and then updates it // in the trie with provided address. @@ -122,7 +125,7 @@ type Trie interface { // Witness returns a set containing all trie nodes that have been accessed. // The returned map could be nil if the witness is empty. - Witness() map[string]struct{} + Witness() map[string][]byte // NodeIterator returns an iterator that returns nodes of the trie. Iteration // starts at the key after the given start key. And error will be returned @@ -151,7 +154,6 @@ type CachingDB struct { snap *snapshot.Tree codeCache *lru.SizeConstrainedCache[common.Hash, []byte] codeSizeCache *lru.Cache[common.Hash, int] - pointCache *utils.PointCache // Transition-specific fields TransitionStatePerRoot *lru.Cache[common.Hash, *overlay.TransitionState] @@ -165,7 +167,6 @@ func NewDatabase(triedb *triedb.Database, snap *snapshot.Tree) *CachingDB { snap: snap, codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), - pointCache: utils.NewPointCache(pointCacheSize), TransitionStatePerRoot: lru.NewCache[common.Hash, *overlay.TransitionState](1000), } } @@ -176,8 +177,8 @@ func NewDatabaseForTesting() *CachingDB { return NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil) } -// Reader returns a state reader associated with the specified state root. -func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) { +// StateReader returns a state reader associated with the specified state root. +func (db *CachingDB) StateReader(stateRoot common.Hash) (StateReader, error) { var readers []StateReader // Configure the state reader using the standalone snapshot in hash mode. @@ -201,29 +202,38 @@ func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) { } // Configure the trie reader, which is expected to be available as the // gatekeeper unless the state is corrupted. - tr, err := newTrieReader(stateRoot, db.triedb, db.pointCache) + tr, err := newTrieReader(stateRoot, db.triedb) if err != nil { return nil, err } readers = append(readers, tr) - combined, err := newMultiStateReader(readers...) + return newMultiStateReader(readers...) +} + +// Reader implements Database, returning a reader associated with the specified +// state root. +func (db *CachingDB) Reader(stateRoot common.Hash) (Reader, error) { + sr, err := db.StateReader(stateRoot) if err != nil { return nil, err } - return newReader(newCachingCodeReader(db.disk, db.codeCache, db.codeSizeCache), combined), nil + return newReader(newCachingCodeReader(db.disk, db.codeCache, db.codeSizeCache), sr), nil } -// ReadersWithCacheStats creates a pair of state readers sharing the same internal cache and -// same backing Reader, but exposing separate statistics. -// and statistics. +// ReadersWithCacheStats creates a pair of state readers that share the same +// underlying state reader and internal state cache, while maintaining separate +// statistics respectively. func (db *CachingDB) ReadersWithCacheStats(stateRoot common.Hash) (ReaderWithStats, ReaderWithStats, error) { - reader, err := db.Reader(stateRoot) + r, err := db.StateReader(stateRoot) if err != nil { return nil, nil, err } - shared := newReaderWithCache(reader) - return newReaderWithCacheStats(shared), newReaderWithCacheStats(shared), nil + sr := newStateReaderWithCache(r) + + ra := newReaderWithStats(sr, newCachingCodeReader(db.disk, db.codeCache, db.codeSizeCache)) + rb := newReaderWithStats(sr, newCachingCodeReader(db.disk, db.codeCache, db.codeSizeCache)) + return ra, rb, nil } // OpenTrie opens the main account trie at a specific root hash. @@ -231,10 +241,12 @@ func (db *CachingDB) OpenTrie(root common.Hash) (Trie, error) { if db.triedb.IsVerkle() { ts := overlay.LoadTransitionState(db.TrieDB().Disk(), root, db.triedb.IsVerkle()) if ts.InTransition() { - panic("transition isn't supported yet") + panic("state tree transition isn't supported yet") } if ts.Transitioned() { - return trie.NewVerkleTrie(root, db.triedb, db.pointCache) + // Use BinaryTrie instead of VerkleTrie when IsVerkle is set + // (IsVerkle actually means Binary Trie mode in this codebase) + return bintrie.NewBinaryTrie(root, db.triedb) } } tr, err := trie.NewStateTrie(trie.StateTrieID(root), db.triedb) @@ -277,11 +289,6 @@ func (db *CachingDB) TrieDB() *triedb.Database { return db.triedb } -// PointCache returns the cache of evaluated curve points. -func (db *CachingDB) PointCache() *utils.PointCache { - return db.pointCache -} - // Snapshot returns the underlying state snapshot. func (db *CachingDB) Snapshot() *snapshot.Tree { return db.snap @@ -292,7 +299,7 @@ func mustCopyTrie(t Trie) Trie { switch t := t.(type) { case *trie.StateTrie: return t.Copy() - case *trie.VerkleTrie: + case *transitiontrie.TransitionTrie: return t.Copy() default: panic(fmt.Errorf("unknown trie type %T", t)) diff --git a/core/state/database_history.go b/core/state/database_history.go index 314c56c470..7a2be8fe4f 100644 --- a/core/state/database_history.go +++ b/core/state/database_history.go @@ -17,41 +17,39 @@ package state import ( - "errors" + "fmt" + "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/lru" "github.com/ethereum/go-ethereum/core/state/snapshot" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-ethereum/trie/utils" + "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/triedb" + "github.com/ethereum/go-ethereum/triedb/database" "github.com/ethereum/go-ethereum/triedb/pathdb" ) -// historicReader wraps a historical state reader defined in path database, -// providing historic state serving over the path scheme. -// -// TODO(rjl493456442): historicReader is not thread-safe and does not fully -// comply with the StateReader interface requirements, needs to be fixed. -// Currently, it is only used in a non-concurrent context, so it is safe for now. -type historicReader struct { +// historicStateReader implements StateReader, wrapping a historical state reader +// defined in path database and provide historic state serving over the path scheme. +type historicStateReader struct { reader *pathdb.HistoricalStateReader + lock sync.Mutex // Lock for protecting concurrent read } -// newHistoricReader constructs a reader for historic state serving. -func newHistoricReader(r *pathdb.HistoricalStateReader) *historicReader { - return &historicReader{reader: r} +// newHistoricStateReader constructs a reader for historical state serving. +func newHistoricStateReader(r *pathdb.HistoricalStateReader) *historicStateReader { + return &historicStateReader{reader: r} } // Account implements StateReader, retrieving the account specified by the address. -// -// An error will be returned if the associated snapshot is already stale or -// the requested account is not yet covered by the snapshot. -// -// The returned account might be nil if it's not existent. -func (r *historicReader) Account(addr common.Address) (*types.StateAccount, error) { +func (r *historicStateReader) Account(addr common.Address) (*types.StateAccount, error) { + r.lock.Lock() + defer r.lock.Unlock() + account, err := r.reader.Account(addr) if err != nil { return nil, err @@ -81,7 +79,10 @@ func (r *historicReader) Account(addr common.Address) (*types.StateAccount, erro // the requested storage slot is not yet covered by the snapshot. // // The returned storage slot might be empty if it's not existent. -func (r *historicReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) { +func (r *historicStateReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) { + r.lock.Lock() + defer r.lock.Unlock() + blob, err := r.reader.Storage(addr, key) if err != nil { return common.Hash{}, err @@ -98,6 +99,125 @@ func (r *historicReader) Storage(addr common.Address, key common.Hash) (common.H return slot, nil } +// historicTrieOpener is a wrapper of pathdb.HistoricalNodeReader, implementing +// the database.NodeDatabase by adding NodeReader function. +type historicTrieOpener struct { + root common.Hash + reader *pathdb.HistoricalNodeReader +} + +// newHistoricTrieOpener constructs the historical trie opener. +func newHistoricTrieOpener(root common.Hash, reader *pathdb.HistoricalNodeReader) *historicTrieOpener { + return &historicTrieOpener{ + root: root, + reader: reader, + } +} + +// NodeReader implements database.NodeDatabase, returning a node reader of a +// specified state. +func (o *historicTrieOpener) NodeReader(root common.Hash) (database.NodeReader, error) { + if root != o.root { + return nil, fmt.Errorf("state %x is not available", root) + } + return o.reader, nil +} + +// historicalTrieReader wraps a historical node reader defined in path database, +// providing historical node serving over the path scheme. +type historicalTrieReader struct { + root common.Hash + opener *historicTrieOpener + tr Trie + + subRoots map[common.Address]common.Hash // Set of storage roots, cached when the account is resolved + subTries map[common.Address]Trie // Group of storage tries, cached when it's resolved + lock sync.Mutex // Lock for protecting concurrent read +} + +// newHistoricalTrieReader constructs a reader for historical trie node serving. +func newHistoricalTrieReader(root common.Hash, r *pathdb.HistoricalNodeReader) (*historicalTrieReader, error) { + opener := newHistoricTrieOpener(root, r) + tr, err := trie.NewStateTrie(trie.StateTrieID(root), opener) + if err != nil { + return nil, err + } + return &historicalTrieReader{ + root: root, + opener: opener, + tr: tr, + subRoots: make(map[common.Address]common.Hash), + subTries: make(map[common.Address]Trie), + }, nil +} + +// account is the inner version of Account and assumes the r.lock is already held. +func (r *historicalTrieReader) account(addr common.Address) (*types.StateAccount, error) { + account, err := r.tr.GetAccount(addr) + if err != nil { + return nil, err + } + if account == nil { + r.subRoots[addr] = types.EmptyRootHash + } else { + r.subRoots[addr] = account.Root + } + return account, nil +} + +// Account implements StateReader, retrieving the account specified by the address. +// +// An error will be returned if the associated snapshot is already stale or +// the requested account is not yet covered by the snapshot. +// +// The returned account might be nil if it's not existent. +func (r *historicalTrieReader) Account(addr common.Address) (*types.StateAccount, error) { + r.lock.Lock() + defer r.lock.Unlock() + + return r.account(addr) +} + +// Storage implements StateReader, retrieving the storage slot specified by the +// address and slot key. +// +// An error will be returned if the associated snapshot is already stale or +// the requested storage slot is not yet covered by the snapshot. +// +// The returned storage slot might be empty if it's not existent. +func (r *historicalTrieReader) Storage(addr common.Address, key common.Hash) (common.Hash, error) { + r.lock.Lock() + defer r.lock.Unlock() + + tr, found := r.subTries[addr] + if !found { + root, ok := r.subRoots[addr] + + // The storage slot is accessed without account caching. It's unexpected + // behavior but try to resolve the account first anyway. + if !ok { + _, err := r.account(addr) + if err != nil { + return common.Hash{}, err + } + root = r.subRoots[addr] + } + var err error + tr, err = trie.NewStateTrie(trie.StorageTrieID(r.root, crypto.Keccak256Hash(addr.Bytes()), root), r.opener) + if err != nil { + return common.Hash{}, err + } + r.subTries[addr] = tr + } + ret, err := tr.GetStorage(addr, key.Bytes()) + if err != nil { + return common.Hash{}, err + } + var value common.Hash + value.SetBytes(ret) + return value, nil +} + // HistoricDB is the implementation of Database interface, with the ability to // access historical state. type HistoricDB struct { @@ -105,7 +225,6 @@ type HistoricDB struct { triedb *triedb.Database codeCache *lru.SizeConstrainedCache[common.Hash, []byte] codeSizeCache *lru.Cache[common.Hash, int] - pointCache *utils.PointCache } // NewHistoricDatabase creates a historic state database. @@ -115,33 +234,59 @@ func NewHistoricDatabase(disk ethdb.KeyValueStore, triedb *triedb.Database) *His triedb: triedb, codeCache: lru.NewSizeConstrainedCache[common.Hash, []byte](codeCacheSize), codeSizeCache: lru.NewCache[common.Hash, int](codeSizeCacheSize), - pointCache: utils.NewPointCache(pointCacheSize), } } // Reader implements Database interface, returning a reader of the specific state. func (db *HistoricDB) Reader(stateRoot common.Hash) (Reader, error) { - hr, err := db.triedb.HistoricReader(stateRoot) + var readers []StateReader + sr, err := db.triedb.HistoricStateReader(stateRoot) + if err == nil { + readers = append(readers, newHistoricStateReader(sr)) + } + nr, err := db.triedb.HistoricNodeReader(stateRoot) + if err == nil { + tr, err := newHistoricalTrieReader(stateRoot, nr) + if err == nil { + readers = append(readers, tr) + } + } + if len(readers) == 0 { + return nil, fmt.Errorf("historical state %x is not available", stateRoot) + } + combined, err := newMultiStateReader(readers...) if err != nil { return nil, err } - return newReader(newCachingCodeReader(db.disk, db.codeCache, db.codeSizeCache), newHistoricReader(hr)), nil + return newReader(newCachingCodeReader(db.disk, db.codeCache, db.codeSizeCache), combined), nil } // OpenTrie opens the main account trie. It's not supported by historic database. func (db *HistoricDB) OpenTrie(root common.Hash) (Trie, error) { - return nil, errors.New("not implemented") + nr, err := db.triedb.HistoricNodeReader(root) + if err != nil { + return nil, err + } + tr, err := trie.NewStateTrie(trie.StateTrieID(root), newHistoricTrieOpener(root, nr)) + if err != nil { + return nil, err + } + return tr, nil } // OpenStorageTrie opens the storage trie of an account. It's not supported by // historic database. -func (db *HistoricDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, trie Trie) (Trie, error) { - return nil, errors.New("not implemented") -} - -// PointCache returns the cache holding points used in verkle tree key computation -func (db *HistoricDB) PointCache() *utils.PointCache { - return db.pointCache +func (db *HistoricDB) OpenStorageTrie(stateRoot common.Hash, address common.Address, root common.Hash, _ Trie) (Trie, error) { + nr, err := db.triedb.HistoricNodeReader(stateRoot) + if err != nil { + return nil, err + } + id := trie.StorageTrieID(stateRoot, crypto.Keccak256Hash(address.Bytes()), root) + tr, err := trie.NewStateTrie(id, newHistoricTrieOpener(stateRoot, nr)) + if err != nil { + return nil, err + } + return tr, nil } // TrieDB returns the underlying trie database for managing trie nodes. diff --git a/core/state/dump.go b/core/state/dump.go index a4abc33733..829d106ed3 100644 --- a/core/state/dump.go +++ b/core/state/dump.go @@ -18,6 +18,7 @@ package state import ( "encoding/json" + "errors" "fmt" "time" @@ -27,6 +28,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/bintrie" ) // DumpConfig is a set of options to control what portions of the state will be @@ -221,6 +223,28 @@ func (s *StateDB) DumpToCollector(c DumpCollector, conf *DumpConfig) (nextKey [] return nextKey } +// DumpBinTrieLeaves collects all binary trie leaf nodes into the provided map. +func (s *StateDB) DumpBinTrieLeaves(collector map[common.Hash]hexutil.Bytes) error { + tr, err := s.db.OpenTrie(s.originalRoot) + if err != nil { + return err + } + btr, ok := tr.(*bintrie.BinaryTrie) + if !ok { + return errors.New("trie is not a binary trie") + } + it, err := btr.NodeIterator(nil) + if err != nil { + return err + } + for it.Next(true) { + if it.Leaf() { + collector[common.BytesToHash(it.LeafKey())] = it.LeafBlob() + } + } + return nil +} + // RawDump returns the state. If the processing is aborted e.g. due to options // reaching Max, the `Next` key is set on the returned Dump. func (s *StateDB) RawDump(opts *DumpConfig) Dump { diff --git a/core/state/pruner/pruner.go b/core/state/pruner/pruner.go index 46558a6fce..11f3963a3e 100644 --- a/core/state/pruner/pruner.go +++ b/core/state/pruner/pruner.go @@ -160,11 +160,8 @@ func prune(snaptree *snapshot.Tree, root common.Hash, maindb ethdb.Database, sta var eta time.Duration // Realistically will never remain uninited if done := binary.BigEndian.Uint64(key[:8]); done > 0 { - var ( - left = math.MaxUint64 - binary.BigEndian.Uint64(key[:8]) - speed = done/uint64(time.Since(pstart)/time.Millisecond+1) + 1 // +1s to avoid division by zero - ) - eta = time.Duration(left/speed) * time.Millisecond + left := math.MaxUint64 - binary.BigEndian.Uint64(key[:8]) + eta = common.CalculateETA(done, left, time.Since(pstart)) } if time.Since(logged) > 8*time.Second { log.Info("Pruning state data", "nodes", count, "skipped", skipped, "size", size, diff --git a/core/state/reader.go b/core/state/reader.go index f56a1bfae1..2db9d1f9b4 100644 --- a/core/state/reader.go +++ b/core/state/reader.go @@ -18,24 +18,31 @@ package state import ( "errors" + "fmt" "sync" "sync/atomic" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/lru" + "github.com/ethereum/go-ethereum/core/overlay" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" - "github.com/ethereum/go-ethereum/trie/utils" + "github.com/ethereum/go-ethereum/trie/bintrie" + "github.com/ethereum/go-ethereum/trie/transitiontrie" "github.com/ethereum/go-ethereum/triedb" "github.com/ethereum/go-ethereum/triedb/database" ) // ContractCodeReader defines the interface for accessing contract code. type ContractCodeReader interface { + // Has returns the flag indicating whether the contract code with + // specified address and hash exists or not. + Has(addr common.Address, codeHash common.Hash) bool + // Code retrieves a particular contract's code. // // - Returns nil code along with nil error if the requested contract code @@ -51,6 +58,13 @@ type ContractCodeReader interface { CodeSize(addr common.Address, codeHash common.Hash) (int, error) } +// ContractCodeReaderWithStats extends ContractCodeReader by adding GetStats to +// expose statistics of code reader. +type ContractCodeReaderWithStats interface { + ContractCodeReader + GetStats() (int64, int64) +} + // StateReader defines the interface for accessing accounts and storage slots // associated with a specific state. // @@ -85,10 +99,36 @@ type Reader interface { // ReaderStats wraps the statistics of reader. type ReaderStats struct { - AccountHit int64 - AccountMiss int64 - StorageHit int64 - StorageMiss int64 + // Cache stats + AccountCacheHit int64 + AccountCacheMiss int64 + StorageCacheHit int64 + StorageCacheMiss int64 + ContractCodeHit int64 + ContractCodeMiss int64 +} + +// String implements fmt.Stringer, returning string format statistics. +func (s ReaderStats) String() string { + var ( + accountCacheHitRate float64 + storageCacheHitRate float64 + contractCodeHitRate float64 + ) + if s.AccountCacheHit > 0 { + accountCacheHitRate = float64(s.AccountCacheHit) / float64(s.AccountCacheHit+s.AccountCacheMiss) * 100 + } + if s.StorageCacheHit > 0 { + storageCacheHitRate = float64(s.StorageCacheHit) / float64(s.StorageCacheHit+s.StorageCacheMiss) * 100 + } + if s.ContractCodeHit > 0 { + contractCodeHitRate = float64(s.ContractCodeHit) / float64(s.ContractCodeHit+s.ContractCodeMiss) * 100 + } + msg := fmt.Sprintf("Reader statistics\n") + msg += fmt.Sprintf("account: hit: %d, miss: %d, rate: %.2f\n", s.AccountCacheHit, s.AccountCacheMiss, accountCacheHitRate) + msg += fmt.Sprintf("storage: hit: %d, miss: %d, rate: %.2f\n", s.StorageCacheHit, s.StorageCacheMiss, storageCacheHitRate) + msg += fmt.Sprintf("code: hit: %d, miss: %d, rate: %.2f\n", s.ContractCodeHit, s.ContractCodeMiss, contractCodeHitRate) + return msg } // ReaderWithStats wraps the additional method to retrieve the reader statistics from. @@ -108,6 +148,10 @@ type cachingCodeReader struct { // they are natively thread-safe. codeCache *lru.SizeConstrainedCache[common.Hash, []byte] codeSizeCache *lru.Cache[common.Hash, int] + + // Cache statistics + hit atomic.Int64 // Number of code lookups found in the cache. + miss atomic.Int64 // Number of code lookups not found in the cache. } // newCachingCodeReader constructs the code reader. @@ -124,8 +168,11 @@ func newCachingCodeReader(db ethdb.KeyValueReader, codeCache *lru.SizeConstraine func (r *cachingCodeReader) Code(addr common.Address, codeHash common.Hash) ([]byte, error) { code, _ := r.codeCache.Get(codeHash) if len(code) > 0 { + r.hit.Add(1) return code, nil } + r.miss.Add(1) + code = rawdb.ReadCode(r.db, codeHash) if len(code) > 0 { r.codeCache.Add(codeHash, code) @@ -138,6 +185,7 @@ func (r *cachingCodeReader) Code(addr common.Address, codeHash common.Hash) ([]b // If the contract code doesn't exist, no error will be returned. func (r *cachingCodeReader) CodeSize(addr common.Address, codeHash common.Hash) (int, error) { if cached, ok := r.codeSizeCache.Get(codeHash); ok { + r.hit.Add(1) return cached, nil } code, err := r.Code(addr, codeHash) @@ -147,6 +195,18 @@ func (r *cachingCodeReader) CodeSize(addr common.Address, codeHash common.Hash) return len(code), nil } +// Has returns the flag indicating whether the contract code with +// specified address and hash exists or not. +func (r *cachingCodeReader) Has(addr common.Address, codeHash common.Hash) bool { + code, _ := r.Code(addr, codeHash) + return len(code) > 0 +} + +// GetStats returns the cache statistics fo the code reader. +func (r *cachingCodeReader) GetStats() (int64, int64) { + return r.hit.Load(), r.miss.Load() +} + // flatReader wraps a database state reader and is safe for concurrent access. type flatReader struct { reader database.StateReader @@ -231,9 +291,9 @@ type trieReader struct { lock sync.Mutex // Lock for protecting concurrent read } -// trieReader constructs a trie reader of the specific state. An error will be +// newTrieReader constructs a trie reader of the specific state. An error will be // returned if the associated trie specified by root is not existent. -func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCache) (*trieReader, error) { +func newTrieReader(root common.Hash, db *triedb.Database) (*trieReader, error) { var ( tr Trie err error @@ -241,8 +301,38 @@ func newTrieReader(root common.Hash, db *triedb.Database, cache *utils.PointCach if !db.IsVerkle() { tr, err = trie.NewStateTrie(trie.StateTrieID(root), db) } else { - // TODO @gballet determine the trie type (verkle or overlay) by transition state - tr, err = trie.NewVerkleTrie(root, db, cache) + // When IsVerkle() is true, create a BinaryTrie wrapped in TransitionTrie + binTrie, binErr := bintrie.NewBinaryTrie(root, db) + if binErr != nil { + return nil, binErr + } + + // Based on the transition status, determine if the overlay + // tree needs to be created, or if a single, target tree is + // to be picked. + ts := overlay.LoadTransitionState(db.Disk(), root, true) + if ts.InTransition() { + mpt, err := trie.NewStateTrie(trie.StateTrieID(ts.BaseRoot), db) + if err != nil { + return nil, err + } + tr = transitiontrie.NewTransitionTrie(mpt, binTrie, false) + } else { + // HACK: Use TransitionTrie with nil base as a wrapper to make BinaryTrie + // satisfy the Trie interface. This works around the import cycle between + // trie and trie/bintrie packages. + // + // TODO: In future PRs, refactor the package structure to avoid this hack: + // - Option 1: Move common interfaces (Trie, NodeIterator) to a separate + // package that both trie and trie/bintrie can import + // - Option 2: Create a factory function in the trie package that returns + // BinaryTrie as a Trie interface without direct import + // - Option 3: Move BinaryTrie to the main trie package + // + // The current approach works but adds unnecessary overhead and complexity + // by using TransitionTrie when there's no actual transition happening. + tr = transitiontrie.NewTransitionTrie(nil, binTrie, false) + } } if err != nil { return nil, err @@ -399,10 +489,10 @@ func newReader(codeReader ContractCodeReader, stateReader StateReader) *reader { } } -// readerWithCache is a wrapper around Reader that maintains additional state caches -// to support concurrent state access. -type readerWithCache struct { - Reader // safe for concurrent read +// stateReaderWithCache is a wrapper around StateReader that maintains additional +// state caches to support concurrent state access. +type stateReaderWithCache struct { + StateReader // Previously resolved state entries. accounts map[common.Address]*types.StateAccount @@ -418,11 +508,11 @@ type readerWithCache struct { } } -// newReaderWithCache constructs the reader with local cache. -func newReaderWithCache(reader Reader) *readerWithCache { - r := &readerWithCache{ - Reader: reader, - accounts: make(map[common.Address]*types.StateAccount), +// newStateReaderWithCache constructs the state reader with local cache. +func newStateReaderWithCache(sr StateReader) *stateReaderWithCache { + r := &stateReaderWithCache{ + StateReader: sr, + accounts: make(map[common.Address]*types.StateAccount), } for i := range r.storageBuckets { r.storageBuckets[i].storages = make(map[common.Address]map[common.Hash]common.Hash) @@ -435,7 +525,7 @@ func newReaderWithCache(reader Reader) *readerWithCache { // might be nil if it's not existent. // // An error will be returned if the state is corrupted in the underlying reader. -func (r *readerWithCache) account(addr common.Address) (*types.StateAccount, bool, error) { +func (r *stateReaderWithCache) account(addr common.Address) (*types.StateAccount, bool, error) { // Try to resolve the requested account in the local cache r.accountLock.RLock() acct, ok := r.accounts[addr] @@ -444,7 +534,7 @@ func (r *readerWithCache) account(addr common.Address) (*types.StateAccount, boo return acct, true, nil } // Try to resolve the requested account from the underlying reader - acct, err := r.Reader.Account(addr) + acct, err := r.StateReader.Account(addr) if err != nil { return nil, false, err } @@ -458,7 +548,7 @@ func (r *readerWithCache) account(addr common.Address) (*types.StateAccount, boo // The returned account might be nil if it's not existent. // // An error will be returned if the state is corrupted in the underlying reader. -func (r *readerWithCache) Account(addr common.Address) (*types.StateAccount, error) { +func (r *stateReaderWithCache) Account(addr common.Address) (*types.StateAccount, error) { account, _, err := r.account(addr) return account, err } @@ -466,7 +556,7 @@ func (r *readerWithCache) Account(addr common.Address) (*types.StateAccount, err // storage retrieves the storage slot specified by the address and slot key, along // with a flag indicating whether it's found in the cache or not. The returned // storage slot might be empty if it's not existent. -func (r *readerWithCache) storage(addr common.Address, slot common.Hash) (common.Hash, bool, error) { +func (r *stateReaderWithCache) storage(addr common.Address, slot common.Hash) (common.Hash, bool, error) { var ( value common.Hash ok bool @@ -483,7 +573,7 @@ func (r *readerWithCache) storage(addr common.Address, slot common.Hash) (common return value, true, nil } // Try to resolve the requested storage slot from the underlying reader - value, err := r.Reader.Storage(addr, slot) + value, err := r.StateReader.Storage(addr, slot) if err != nil { return common.Hash{}, false, err } @@ -504,23 +594,26 @@ func (r *readerWithCache) storage(addr common.Address, slot common.Hash) (common // existent. // // An error will be returned if the state is corrupted in the underlying reader. -func (r *readerWithCache) Storage(addr common.Address, slot common.Hash) (common.Hash, error) { +func (r *stateReaderWithCache) Storage(addr common.Address, slot common.Hash) (common.Hash, error) { value, _, err := r.storage(addr, slot) return value, err } -type readerWithCacheStats struct { - *readerWithCache - accountHit atomic.Int64 - accountMiss atomic.Int64 - storageHit atomic.Int64 - storageMiss atomic.Int64 +type readerWithStats struct { + *stateReaderWithCache + ContractCodeReaderWithStats + + accountCacheHit atomic.Int64 + accountCacheMiss atomic.Int64 + storageCacheHit atomic.Int64 + storageCacheMiss atomic.Int64 } -// newReaderWithCacheStats constructs the reader with additional statistics tracked. -func newReaderWithCacheStats(reader *readerWithCache) *readerWithCacheStats { - return &readerWithCacheStats{ - readerWithCache: reader, +// newReaderWithStats constructs the reader with additional statistics tracked. +func newReaderWithStats(sr *stateReaderWithCache, cr ContractCodeReaderWithStats) *readerWithStats { + return &readerWithStats{ + stateReaderWithCache: sr, + ContractCodeReaderWithStats: cr, } } @@ -528,15 +621,15 @@ func newReaderWithCacheStats(reader *readerWithCache) *readerWithCacheStats { // The returned account might be nil if it's not existent. // // An error will be returned if the state is corrupted in the underlying reader. -func (r *readerWithCacheStats) Account(addr common.Address) (*types.StateAccount, error) { - account, incache, err := r.readerWithCache.account(addr) +func (r *readerWithStats) Account(addr common.Address) (*types.StateAccount, error) { + account, incache, err := r.stateReaderWithCache.account(addr) if err != nil { return nil, err } if incache { - r.accountHit.Add(1) + r.accountCacheHit.Add(1) } else { - r.accountMiss.Add(1) + r.accountCacheMiss.Add(1) } return account, nil } @@ -546,25 +639,28 @@ func (r *readerWithCacheStats) Account(addr common.Address) (*types.StateAccount // existent. // // An error will be returned if the state is corrupted in the underlying reader. -func (r *readerWithCacheStats) Storage(addr common.Address, slot common.Hash) (common.Hash, error) { - value, incache, err := r.readerWithCache.storage(addr, slot) +func (r *readerWithStats) Storage(addr common.Address, slot common.Hash) (common.Hash, error) { + value, incache, err := r.stateReaderWithCache.storage(addr, slot) if err != nil { return common.Hash{}, err } if incache { - r.storageHit.Add(1) + r.storageCacheHit.Add(1) } else { - r.storageMiss.Add(1) + r.storageCacheMiss.Add(1) } return value, nil } // GetStats implements ReaderWithStats, returning the statistics of state reader. -func (r *readerWithCacheStats) GetStats() ReaderStats { +func (r *readerWithStats) GetStats() ReaderStats { + codeHit, codeMiss := r.ContractCodeReaderWithStats.GetStats() return ReaderStats{ - AccountHit: r.accountHit.Load(), - AccountMiss: r.accountMiss.Load(), - StorageHit: r.storageHit.Load(), - StorageMiss: r.storageMiss.Load(), + AccountCacheHit: r.accountCacheHit.Load(), + AccountCacheMiss: r.accountCacheMiss.Load(), + StorageCacheHit: r.storageCacheHit.Load(), + StorageCacheMiss: r.storageCacheMiss.Load(), + ContractCodeHit: codeHit, + ContractCodeMiss: codeMiss, } } diff --git a/core/state/snapshot/conversion.go b/core/state/snapshot/conversion.go index 4b0774f2ae..0d39687be4 100644 --- a/core/state/snapshot/conversion.go +++ b/core/state/snapshot/conversion.go @@ -171,20 +171,16 @@ func (stat *generateStats) report() { // If there's progress on the account trie, estimate the time to finish crawling it if done := binary.BigEndian.Uint64(stat.head[:8]) / stat.accounts; done > 0 { var ( - left = (math.MaxUint64 - binary.BigEndian.Uint64(stat.head[:8])) / stat.accounts - speed = done/uint64(time.Since(stat.start)/time.Millisecond+1) + 1 // +1s to avoid division by zero - eta = time.Duration(left/speed) * time.Millisecond + left = (math.MaxUint64 - binary.BigEndian.Uint64(stat.head[:8])) / stat.accounts + eta = common.CalculateETA(done, left, time.Since(stat.start)) ) // If there are large contract crawls in progress, estimate their finish time for acc, head := range stat.slotsHead { start := stat.slotsStart[acc] if done := binary.BigEndian.Uint64(head[:8]); done > 0 { - var ( - left = math.MaxUint64 - binary.BigEndian.Uint64(head[:8]) - speed = done/uint64(time.Since(start)/time.Millisecond+1) + 1 // +1s to avoid division by zero - ) + left := math.MaxUint64 - binary.BigEndian.Uint64(head[:8]) // Override the ETA if larger than the largest until now - if slotETA := time.Duration(left/speed) * time.Millisecond; eta < slotETA { + if slotETA := common.CalculateETA(done, left, time.Since(start)); eta < slotETA { eta = slotETA } } diff --git a/core/state/snapshot/difflayer.go b/core/state/snapshot/difflayer.go index 28957051d4..1286ded7e1 100644 --- a/core/state/snapshot/difflayer.go +++ b/core/state/snapshot/difflayer.go @@ -465,6 +465,6 @@ func (dl *diffLayer) StorageList(accountHash common.Hash) []common.Hash { storageList := slices.SortedFunc(maps.Keys(dl.storageData[accountHash]), common.Hash.Cmp) dl.storageList[accountHash] = storageList - dl.memory += uint64(len(dl.storageList)*common.HashLength + common.HashLength) + dl.memory += uint64(len(storageList)*common.HashLength + common.HashLength) return storageList } diff --git a/core/state/snapshot/difflayer_test.go b/core/state/snapshot/difflayer_test.go index b212098e75..90a265645d 100644 --- a/core/state/snapshot/difflayer_test.go +++ b/core/state/snapshot/difflayer_test.go @@ -198,6 +198,39 @@ func TestInsertAndMerge(t *testing.T) { } } +// TestStorageListMemoryAccounting ensures that StorageList increases dl.memory +// proportionally to the number of storage slots in the requested account and +// does not change memory usage on repeated calls for the same account. +func TestStorageListMemoryAccounting(t *testing.T) { + parent := newDiffLayer(emptyLayer(), common.Hash{}, nil, nil) + account := common.HexToHash("0x01") + + slots := make(map[common.Hash][]byte) + for i := 0; i < 3; i++ { + slots[randomHash()] = []byte{0x01} + } + storage := map[common.Hash]map[common.Hash][]byte{ + account: slots, + } + dl := newDiffLayer(parent, common.Hash{}, nil, storage) + + before := dl.memory + list := dl.StorageList(account) + if have, want := len(list), len(slots); have != want { + t.Fatalf("StorageList length mismatch: have %d, want %d", have, want) + } + expectedDelta := uint64(len(list)*common.HashLength + common.HashLength) + if have, want := dl.memory-before, expectedDelta; have != want { + t.Fatalf("StorageList memory delta mismatch: have %d, want %d", have, want) + } + + before = dl.memory + _ = dl.StorageList(account) + if dl.memory != before { + t.Fatalf("StorageList changed memory on cached call: have %d, want %d", dl.memory, before) + } +} + func emptyLayer() *diskLayer { return &diskLayer{ diskdb: memorydb.New(), @@ -229,8 +262,7 @@ func BenchmarkSearch(b *testing.B) { layer = fill(layer) } key := crypto.Keccak256Hash([]byte{0x13, 0x38}) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { layer.AccountRLP(key) } } @@ -269,8 +301,7 @@ func BenchmarkSearchSlot(b *testing.B) { for i := 0; i < 128; i++ { layer = fill(layer) } - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { layer.Storage(accountKey, storageKey) } } @@ -300,9 +331,7 @@ func BenchmarkFlatten(b *testing.B) { } return newDiffLayer(parent, common.Hash{}, accounts, storage) } - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StopTimer() + for b.Loop() { var layer snapshot layer = emptyLayer() for i := 1; i < 128; i++ { @@ -352,9 +381,7 @@ func BenchmarkJournal(b *testing.B) { for i := 1; i < 128; i++ { layer = fill(layer) } - b.ResetTimer() - - for i := 0; i < b.N; i++ { + for b.Loop() { layer.Journal(new(bytes.Buffer)) } } diff --git a/core/state/snapshot/iterator_test.go b/core/state/snapshot/iterator_test.go index 2e882f484e..dd6c4cf968 100644 --- a/core/state/snapshot/iterator_test.go +++ b/core/state/snapshot/iterator_test.go @@ -928,7 +928,7 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) { head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) b.Run("binary iterator keys", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { got := 0 it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) for it.Next() { @@ -940,7 +940,7 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) { } }) b.Run("binary iterator values", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { got := 0 it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) for it.Next() { @@ -953,7 +953,7 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) { } }) b.Run("fast iterator keys", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{}) defer it.Release() @@ -967,7 +967,7 @@ func BenchmarkAccountIteratorTraversal(b *testing.B) { } }) b.Run("fast iterator values", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{}) defer it.Release() @@ -1025,7 +1025,7 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) b.Run("binary iterator (keys)", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { got := 0 it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) for it.Next() { @@ -1037,7 +1037,7 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { } }) b.Run("binary iterator (values)", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { got := 0 it := head.(*diffLayer).newBinaryAccountIterator(common.Hash{}) for it.Next() { @@ -1051,7 +1051,7 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { } }) b.Run("fast iterator (keys)", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{}) defer it.Release() @@ -1065,7 +1065,7 @@ func BenchmarkAccountIteratorLargeBaselayer(b *testing.B) { } }) b.Run("fast iterator (values)", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { it, _ := snaps.AccountIterator(common.HexToHash("0x65"), common.Hash{}) defer it.Release() diff --git a/core/state/state_object.go b/core/state/state_object.go index 767f469bfd..3b11553f04 100644 --- a/core/state/state_object.go +++ b/core/state/state_object.go @@ -28,6 +28,9 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/bintrie" + "github.com/ethereum/go-ethereum/trie/transitiontrie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/holiman/uint256" ) @@ -333,7 +336,7 @@ func (s *stateObject) updateTrie() (Trie, error) { continue } if !exist { - log.Error("Storage slot is not found in pending area", s.address, "slot", key) + log.Error("Storage slot is not found in pending area", "address", s.address, "slot", key) continue } if (value != common.Hash{}) { @@ -437,6 +440,12 @@ func (s *stateObject) commit() (*accountUpdate, *trienode.NodeSet, error) { blob: s.code, } s.dirtyCode = false // reset the dirty flag + + if s.origin == nil { + op.code.originHash = types.EmptyCodeHash + } else { + op.code.originHash = common.BytesToHash(s.origin.CodeHash) + } } // Commit storage changes and the associated storage trie s.commitStorage(op) @@ -494,8 +503,20 @@ func (s *stateObject) deepCopy(db *StateDB) *stateObject { selfDestructed: s.selfDestructed, newContract: s.newContract, } - if s.trie != nil { + + switch s.trie.(type) { + case *bintrie.BinaryTrie: + // UBT uses only one tree, and the copy has already been + // made in mustCopyTrie. + obj.trie = db.trie + case *transitiontrie.TransitionTrie: + // Same thing for the transition tree, since the MPT is + // read-only. + obj.trie = db.trie + case *trie.StateTrie: obj.trie = mustCopyTrie(s.trie) + case nil: + // do nothing } return obj } @@ -517,6 +538,11 @@ func (s *stateObject) Code() []byte { if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { return nil } + defer func(start time.Time) { + s.db.CodeLoaded += 1 + s.db.CodeReads += time.Since(start) + }(time.Now()) + code, err := s.db.reader.Code(s.address, common.BytesToHash(s.CodeHash())) if err != nil { s.db.setError(fmt.Errorf("can't load code hash %x: %v", s.CodeHash(), err)) @@ -538,6 +564,11 @@ func (s *stateObject) CodeSize() int { if bytes.Equal(s.CodeHash(), types.EmptyCodeHash.Bytes()) { return 0 } + defer func(start time.Time) { + s.db.CodeLoaded += 1 + s.db.CodeReads += time.Since(start) + }(time.Now()) + size, err := s.db.reader.CodeSize(s.address, common.BytesToHash(s.CodeHash())) if err != nil { s.db.setError(fmt.Errorf("can't load code size %x: %v", s.CodeHash(), err)) diff --git a/core/state/state_object_test.go b/core/state/state_object_test.go index 42fd778025..0237f0580d 100644 --- a/core/state/state_object_test.go +++ b/core/state/state_object_test.go @@ -25,7 +25,7 @@ import ( func BenchmarkCutOriginal(b *testing.B) { value := common.HexToHash("0x01") - for i := 0; i < b.N; i++ { + for b.Loop() { bytes.TrimLeft(value[:], "\x00") } } @@ -33,14 +33,14 @@ func BenchmarkCutOriginal(b *testing.B) { func BenchmarkCutsetterFn(b *testing.B) { value := common.HexToHash("0x01") cutSetFn := func(r rune) bool { return r == 0 } - for i := 0; i < b.N; i++ { + for b.Loop() { bytes.TrimLeftFunc(value[:], cutSetFn) } } func BenchmarkCutCustomTrim(b *testing.B) { value := common.HexToHash("0x01") - for i := 0; i < b.N; i++ { + for b.Loop() { common.TrimLeftZeroes(value[:]) } } diff --git a/core/state/state_sizer.go b/core/state/state_sizer.go new file mode 100644 index 0000000000..fc6781ad93 --- /dev/null +++ b/core/state/state_sizer.go @@ -0,0 +1,674 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "container/heap" + "errors" + "fmt" + "maps" + "runtime" + "slices" + "sync" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" + "github.com/ethereum/go-ethereum/triedb" + "golang.org/x/sync/errgroup" +) + +const ( + statEvictThreshold = 128 // the depth of statistic to be preserved +) + +// Database key scheme for states. +var ( + accountKeySize = int64(len(rawdb.SnapshotAccountPrefix) + common.HashLength) + storageKeySize = int64(len(rawdb.SnapshotStoragePrefix) + common.HashLength*2) + accountTrienodePrefixSize = int64(len(rawdb.TrieNodeAccountPrefix)) + storageTrienodePrefixSize = int64(len(rawdb.TrieNodeStoragePrefix) + common.HashLength) + codeKeySize = int64(len(rawdb.CodePrefix) + common.HashLength) +) + +// State size metrics +var ( + stateSizeChainHeightGauge = metrics.NewRegisteredGauge("state/height", nil) + stateSizeAccountsCountGauge = metrics.NewRegisteredGauge("state/accounts/count", nil) + stateSizeAccountsBytesGauge = metrics.NewRegisteredGauge("state/accounts/bytes", nil) + stateSizeStoragesCountGauge = metrics.NewRegisteredGauge("state/storages/count", nil) + stateSizeStoragesBytesGauge = metrics.NewRegisteredGauge("state/storages/bytes", nil) + stateSizeAccountTrieNodesCountGauge = metrics.NewRegisteredGauge("state/trienodes/account/count", nil) + stateSizeAccountTrieNodesBytesGauge = metrics.NewRegisteredGauge("state/trienodes/account/bytes", nil) + stateSizeStorageTrieNodesCountGauge = metrics.NewRegisteredGauge("state/trienodes/storage/count", nil) + stateSizeStorageTrieNodesBytesGauge = metrics.NewRegisteredGauge("state/trienodes/storage/bytes", nil) + stateSizeContractsCountGauge = metrics.NewRegisteredGauge("state/contracts/count", nil) + stateSizeContractsBytesGauge = metrics.NewRegisteredGauge("state/contracts/bytes", nil) +) + +// SizeStats represents either the current state size statistics or the size +// differences resulting from a state transition. +type SizeStats struct { + StateRoot common.Hash // State root hash at the time of measurement + BlockNumber uint64 // Associated block number at the time of measurement + + Accounts int64 // Total number of accounts in the state + AccountBytes int64 // Total storage size used by all account data (in bytes) + Storages int64 // Total number of storage slots across all accounts + StorageBytes int64 // Total storage size used by all storage slot data (in bytes) + AccountTrienodes int64 // Total number of account trie nodes in the state + AccountTrienodeBytes int64 // Total storage size occupied by account trie nodes (in bytes) + StorageTrienodes int64 // Total number of storage trie nodes in the state + StorageTrienodeBytes int64 // Total storage size occupied by storage trie nodes (in bytes) + ContractCodes int64 // Total number of contract codes in the state + ContractCodeBytes int64 // Total size of all contract code (in bytes) +} + +func (s SizeStats) String() string { + return fmt.Sprintf("Accounts: %d(%s), Storages: %d(%s), AccountTrienodes: %d(%s), StorageTrienodes: %d(%s), Codes: %d(%s)", + s.Accounts, common.StorageSize(s.AccountBytes), + s.Storages, common.StorageSize(s.StorageBytes), + s.AccountTrienodes, common.StorageSize(s.AccountTrienodeBytes), + s.StorageTrienodes, common.StorageSize(s.StorageTrienodeBytes), + s.ContractCodes, common.StorageSize(s.ContractCodeBytes), + ) +} + +func (s SizeStats) publish() { + stateSizeChainHeightGauge.Update(int64(s.BlockNumber)) + stateSizeAccountsCountGauge.Update(s.Accounts) + stateSizeAccountsBytesGauge.Update(s.AccountBytes) + stateSizeStoragesCountGauge.Update(s.Storages) + stateSizeStoragesBytesGauge.Update(s.StorageBytes) + stateSizeAccountTrieNodesCountGauge.Update(s.AccountTrienodes) + stateSizeAccountTrieNodesBytesGauge.Update(s.AccountTrienodeBytes) + stateSizeStorageTrieNodesCountGauge.Update(s.StorageTrienodes) + stateSizeStorageTrieNodesBytesGauge.Update(s.StorageTrienodeBytes) + stateSizeContractsCountGauge.Update(s.ContractCodes) + stateSizeContractsBytesGauge.Update(s.ContractCodeBytes) +} + +// add applies the given state diffs and produces a new version of the statistics. +func (s SizeStats) add(diff SizeStats) SizeStats { + s.StateRoot = diff.StateRoot + s.BlockNumber = diff.BlockNumber + + s.Accounts += diff.Accounts + s.AccountBytes += diff.AccountBytes + s.Storages += diff.Storages + s.StorageBytes += diff.StorageBytes + s.AccountTrienodes += diff.AccountTrienodes + s.AccountTrienodeBytes += diff.AccountTrienodeBytes + s.StorageTrienodes += diff.StorageTrienodes + s.StorageTrienodeBytes += diff.StorageTrienodeBytes + s.ContractCodes += diff.ContractCodes + s.ContractCodeBytes += diff.ContractCodeBytes + return s +} + +// calSizeStats measures the state size changes of the provided state update. +func calSizeStats(update *stateUpdate) (SizeStats, error) { + stats := SizeStats{ + BlockNumber: update.blockNumber, + StateRoot: update.root, + } + + // Measure the account changes + for addr, oldValue := range update.accountsOrigin { + addrHash := crypto.Keccak256Hash(addr.Bytes()) + newValue, exists := update.accounts[addrHash] + if !exists { + return SizeStats{}, fmt.Errorf("account %x not found", addr) + } + oldLen, newLen := len(oldValue), len(newValue) + + switch { + case oldLen > 0 && newLen == 0: + // Account deletion + stats.Accounts -= 1 + stats.AccountBytes -= accountKeySize + int64(oldLen) + case oldLen == 0 && newLen > 0: + // Account creation + stats.Accounts += 1 + stats.AccountBytes += accountKeySize + int64(newLen) + default: + // Account update + stats.AccountBytes += int64(newLen - oldLen) + } + } + + // Measure storage changes + for addr, slots := range update.storagesOrigin { + addrHash := crypto.Keccak256Hash(addr.Bytes()) + subset, exists := update.storages[addrHash] + if !exists { + return SizeStats{}, fmt.Errorf("storage %x not found", addr) + } + for key, oldValue := range slots { + var ( + exists bool + newValue []byte + ) + if update.rawStorageKey { + newValue, exists = subset[crypto.Keccak256Hash(key.Bytes())] + } else { + newValue, exists = subset[key] + } + if !exists { + return SizeStats{}, fmt.Errorf("storage slot %x-%x not found", addr, key) + } + oldLen, newLen := len(oldValue), len(newValue) + + switch { + case oldLen > 0 && newLen == 0: + // Storage deletion + stats.Storages -= 1 + stats.StorageBytes -= storageKeySize + int64(oldLen) + case oldLen == 0 && newLen > 0: + // Storage creation + stats.Storages += 1 + stats.StorageBytes += storageKeySize + int64(newLen) + default: + // Storage update + stats.StorageBytes += int64(newLen - oldLen) + } + } + } + + // Measure trienode changes + for owner, subset := range update.nodes.Sets { + var ( + keyPrefix int64 + isAccount = owner == (common.Hash{}) + ) + if isAccount { + keyPrefix = accountTrienodePrefixSize + } else { + keyPrefix = storageTrienodePrefixSize + } + + // Iterate over Origins since every modified node has an origin entry + for path, oldNode := range subset.Origins { + newNode, exists := subset.Nodes[path] + if !exists { + return SizeStats{}, fmt.Errorf("node %x-%v not found", owner, path) + } + keySize := keyPrefix + int64(len(path)) + + switch { + case len(oldNode) > 0 && len(newNode.Blob) == 0: + // Node deletion + if isAccount { + stats.AccountTrienodes -= 1 + stats.AccountTrienodeBytes -= keySize + int64(len(oldNode)) + } else { + stats.StorageTrienodes -= 1 + stats.StorageTrienodeBytes -= keySize + int64(len(oldNode)) + } + case len(oldNode) == 0 && len(newNode.Blob) > 0: + // Node creation + if isAccount { + stats.AccountTrienodes += 1 + stats.AccountTrienodeBytes += keySize + int64(len(newNode.Blob)) + } else { + stats.StorageTrienodes += 1 + stats.StorageTrienodeBytes += keySize + int64(len(newNode.Blob)) + } + default: + // Node update + if isAccount { + stats.AccountTrienodeBytes += int64(len(newNode.Blob) - len(oldNode)) + } else { + stats.StorageTrienodeBytes += int64(len(newNode.Blob) - len(oldNode)) + } + } + } + } + + codeExists := make(map[common.Hash]struct{}) + for _, code := range update.codes { + if _, ok := codeExists[code.hash]; ok || code.duplicate { + continue + } + stats.ContractCodes += 1 + stats.ContractCodeBytes += codeKeySize + int64(len(code.blob)) + codeExists[code.hash] = struct{}{} + } + return stats, nil +} + +type stateSizeQuery struct { + root *common.Hash // nil means latest + err error // non-nil if the state size is not yet initialized + result chan *SizeStats // nil means the state is unknown +} + +// SizeTracker handles the state size initialization and tracks of state size metrics. +type SizeTracker struct { + db ethdb.KeyValueStore + triedb *triedb.Database + abort chan struct{} + aborted chan struct{} + updateCh chan *stateUpdate + queryCh chan *stateSizeQuery +} + +// NewSizeTracker creates a new state size tracker and starts it automatically +func NewSizeTracker(db ethdb.KeyValueStore, triedb *triedb.Database) (*SizeTracker, error) { + if triedb.Scheme() != rawdb.PathScheme { + return nil, errors.New("state size tracker is not compatible with hash mode") + } + t := &SizeTracker{ + db: db, + triedb: triedb, + abort: make(chan struct{}), + aborted: make(chan struct{}), + updateCh: make(chan *stateUpdate), + queryCh: make(chan *stateSizeQuery), + } + go t.run() + return t, nil +} + +func (t *SizeTracker) Stop() { + close(t.abort) + <-t.aborted +} + +// sizeStatsHeap is a heap.Interface implementation over statesize statistics for +// retrieving the oldest statistics for eviction. +type sizeStatsHeap []SizeStats + +func (h sizeStatsHeap) Len() int { return len(h) } +func (h sizeStatsHeap) Less(i, j int) bool { return h[i].BlockNumber < h[j].BlockNumber } +func (h sizeStatsHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] } + +func (h *sizeStatsHeap) Push(x any) { + *h = append(*h, x.(SizeStats)) +} + +func (h *sizeStatsHeap) Pop() any { + old := *h + n := len(old) + x := old[n-1] + *h = old[0 : n-1] + return x +} + +// run performs the state size initialization and handles updates +func (t *SizeTracker) run() { + defer close(t.aborted) + + var last common.Hash + stats, err := t.init() // launch background thread for state size init + if err != nil { + return + } + h := sizeStatsHeap(slices.Collect(maps.Values(stats))) + heap.Init(&h) + + for { + select { + case u := <-t.updateCh: + base, found := stats[u.originRoot] + if !found { + log.Debug("Ignored the state size without parent", "parent", u.originRoot, "root", u.root, "number", u.blockNumber) + continue + } + diff, err := calSizeStats(u) + if err != nil { + continue + } + stat := base.add(diff) + stats[u.root] = stat + last = u.root + + // Publish statistics to metric system + stat.publish() + + // Evict the stale statistics + heap.Push(&h, stats[u.root]) + for u.blockNumber-h[0].BlockNumber > statEvictThreshold { + delete(stats, h[0].StateRoot) + heap.Pop(&h) + } + log.Debug("Update state size", "number", stat.BlockNumber, "root", stat.StateRoot, "stat", stat) + + case r := <-t.queryCh: + var root common.Hash + if r.root != nil { + root = *r.root + } else { + root = last + } + if s, ok := stats[root]; ok { + r.result <- &s + } else { + r.result <- nil + } + + case <-t.abort: + return + } + } +} + +type buildResult struct { + stat SizeStats + root common.Hash + blockNumber uint64 + elapsed time.Duration + err error +} + +func (t *SizeTracker) init() (map[common.Hash]SizeStats, error) { + // Wait for snapshot completion and then init + ticker := time.NewTicker(10 * time.Second) + defer ticker.Stop() + +wait: + for { + select { + case <-ticker.C: + if t.triedb.SnapshotCompleted() { + break wait + } + case <-t.updateCh: + continue + case r := <-t.queryCh: + r.err = errors.New("state size is not initialized yet") + r.result <- nil + case <-t.abort: + return nil, errors.New("size tracker closed") + } + } + + var ( + updates = make(map[common.Hash]*stateUpdate) + children = make(map[common.Hash][]common.Hash) + done chan buildResult + ) + + for { + select { + case u := <-t.updateCh: + updates[u.root] = u + children[u.originRoot] = append(children[u.originRoot], u.root) + log.Debug("Received state update", "root", u.root, "blockNumber", u.blockNumber) + + case r := <-t.queryCh: + r.err = errors.New("state size is not initialized yet") + r.result <- nil + + case <-ticker.C: + // Only check timer if build hasn't started yet + if done != nil { + continue + } + root := rawdb.ReadSnapshotRoot(t.db) + if root == (common.Hash{}) { + continue + } + entry, exists := updates[root] + if !exists { + continue + } + done = make(chan buildResult) + go t.build(entry.root, entry.blockNumber, done) + log.Info("Measuring persistent state size", "root", root.Hex(), "number", entry.blockNumber) + + case result := <-done: + if result.err != nil { + return nil, result.err + } + var ( + stats = make(map[common.Hash]SizeStats) + apply func(root common.Hash, stat SizeStats) error + ) + apply = func(root common.Hash, base SizeStats) error { + for _, child := range children[root] { + entry, ok := updates[child] + if !ok { + return fmt.Errorf("the state update is not found, %x", child) + } + diff, err := calSizeStats(entry) + if err != nil { + return err + } + stats[child] = base.add(diff) + if err := apply(child, stats[child]); err != nil { + return err + } + } + return nil + } + if err := apply(result.root, result.stat); err != nil { + return nil, err + } + + // Set initial latest stats + stats[result.root] = result.stat + log.Info("Measured persistent state size", "root", result.root, "number", result.blockNumber, "stat", result.stat, "elapsed", common.PrettyDuration(result.elapsed)) + return stats, nil + + case <-t.abort: + return nil, errors.New("size tracker closed") + } + } +} + +func (t *SizeTracker) build(root common.Hash, blockNumber uint64, done chan buildResult) { + // Metrics will be directly updated by each goroutine + var ( + accounts, accountBytes int64 + storages, storageBytes int64 + codes, codeBytes int64 + + accountTrienodes, accountTrienodeBytes int64 + storageTrienodes, storageTrienodeBytes int64 + + group errgroup.Group + start = time.Now() + ) + + // Start all table iterations concurrently with direct metric updates + group.Go(func() error { + count, bytes, err := t.iterateTableParallel(t.abort, rawdb.SnapshotAccountPrefix, "account") + if err != nil { + return err + } + accounts, accountBytes = count, bytes + return nil + }) + + group.Go(func() error { + count, bytes, err := t.iterateTableParallel(t.abort, rawdb.SnapshotStoragePrefix, "storage") + if err != nil { + return err + } + storages, storageBytes = count, bytes + return nil + }) + + group.Go(func() error { + count, bytes, err := t.iterateTableParallel(t.abort, rawdb.TrieNodeAccountPrefix, "accountnode") + if err != nil { + return err + } + accountTrienodes, accountTrienodeBytes = count, bytes + return nil + }) + + group.Go(func() error { + count, bytes, err := t.iterateTableParallel(t.abort, rawdb.TrieNodeStoragePrefix, "storagenode") + if err != nil { + return err + } + storageTrienodes, storageTrienodeBytes = count, bytes + return nil + }) + + group.Go(func() error { + count, bytes, err := t.iterateTable(t.abort, rawdb.CodePrefix, "contractcode") + if err != nil { + return err + } + codes, codeBytes = count, bytes + return nil + }) + + // Wait for all goroutines to complete + if err := group.Wait(); err != nil { + done <- buildResult{err: err} + } else { + stat := SizeStats{ + StateRoot: root, + BlockNumber: blockNumber, + Accounts: accounts, + AccountBytes: accountBytes, + Storages: storages, + StorageBytes: storageBytes, + AccountTrienodes: accountTrienodes, + AccountTrienodeBytes: accountTrienodeBytes, + StorageTrienodes: storageTrienodes, + StorageTrienodeBytes: storageTrienodeBytes, + ContractCodes: codes, + ContractCodeBytes: codeBytes, + } + done <- buildResult{ + root: root, + blockNumber: blockNumber, + stat: stat, + elapsed: time.Since(start), + } + } +} + +// iterateTable performs iteration over a specific table and returns the results. +func (t *SizeTracker) iterateTable(closed chan struct{}, prefix []byte, name string) (int64, int64, error) { + var ( + start = time.Now() + logged = time.Now() + count, bytes int64 + ) + + iter := t.db.NewIterator(prefix, nil) + defer iter.Release() + + log.Debug("Iterating state", "category", name) + for iter.Next() { + count++ + bytes += int64(len(iter.Key()) + len(iter.Value())) + + if time.Since(logged) > time.Second*8 { + logged = time.Now() + + select { + case <-closed: + log.Debug("State iteration cancelled", "category", name) + return 0, 0, errors.New("size tracker closed") + default: + log.Debug("Iterating state", "category", name, "count", count, "size", common.StorageSize(bytes)) + } + } + } + // Check for iterator errors + if err := iter.Error(); err != nil { + log.Error("Iterator error", "category", name, "err", err) + return 0, 0, err + } + log.Debug("Finished state iteration", "category", name, "count", count, "size", common.StorageSize(bytes), "elapsed", common.PrettyDuration(time.Since(start))) + return count, bytes, nil +} + +// iterateTableParallel performs parallel iteration over a table by splitting into +// hex ranges. For storage tables, it splits on the first byte of the account hash +// (after the prefix). +func (t *SizeTracker) iterateTableParallel(closed chan struct{}, prefix []byte, name string) (int64, int64, error) { + var ( + totalCount int64 + totalBytes int64 + + start = time.Now() + workers = runtime.NumCPU() + group errgroup.Group + mu sync.Mutex + ) + group.SetLimit(workers) + log.Debug("Starting parallel state iteration", "category", name, "workers", workers) + + if len(prefix) > 0 { + if blob, err := t.db.Get(prefix); err == nil && len(blob) > 0 { + // If there's a direct hit on the prefix, include it in the stats + totalCount = 1 + totalBytes = int64(len(prefix) + len(blob)) + } + } + for i := 0; i < 256; i++ { + h := byte(i) + group.Go(func() error { + count, bytes, err := t.iterateTable(closed, slices.Concat(prefix, []byte{h}), fmt.Sprintf("%s-%02x", name, h)) + if err != nil { + return err + } + mu.Lock() + totalCount += count + totalBytes += bytes + mu.Unlock() + return nil + }) + } + if err := group.Wait(); err != nil { + return 0, 0, err + } + log.Debug("Finished parallel state iteration", "category", name, "count", totalCount, "size", common.StorageSize(totalBytes), "elapsed", common.PrettyDuration(time.Since(start))) + return totalCount, totalBytes, nil +} + +// Notify is an async method used to send the state update to the size tracker. +// It ignores empty updates (where no state changes occurred). +// If the channel is full, it drops the update to avoid blocking. +func (t *SizeTracker) Notify(update *stateUpdate) { + if update == nil || update.empty() { + return + } + select { + case t.updateCh <- update: + case <-t.abort: + return + } +} + +// Query returns the state size specified by the root, or nil if not available. +// If the root is nil, query the size of latest chain head; +// If the root is non-nil, query the size of the specified state; +func (t *SizeTracker) Query(root *common.Hash) (*SizeStats, error) { + r := &stateSizeQuery{ + root: root, + result: make(chan *SizeStats, 1), + } + select { + case <-t.aborted: + return nil, errors.New("state sizer has been closed") + case t.queryCh <- r: + return <-r.result, r.err + } +} diff --git a/core/state/state_sizer_test.go b/core/state/state_sizer_test.go new file mode 100644 index 0000000000..b3203afd74 --- /dev/null +++ b/core/state/state_sizer_test.go @@ -0,0 +1,239 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package state + +import ( + "testing" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/triedb" + "github.com/ethereum/go-ethereum/triedb/pathdb" + "github.com/holiman/uint256" +) + +func TestSizeTracker(t *testing.T) { + db := rawdb.NewMemoryDatabase() + defer db.Close() + + tdb := triedb.NewDatabase(db, &triedb.Config{PathDB: pathdb.Defaults}) + sdb := NewDatabase(tdb, nil) + + // Generate 50 blocks to establish a baseline + baselineBlockNum := uint64(50) + currentRoot := types.EmptyRootHash + + addr1 := common.BytesToAddress([]byte{1, 0, 0, 1}) + addr2 := common.BytesToAddress([]byte{1, 0, 0, 2}) + addr3 := common.BytesToAddress([]byte{1, 0, 0, 3}) + + // Create initial state with fixed accounts + state, _ := New(currentRoot, sdb) + state.AddBalance(addr1, uint256.NewInt(1000), tracing.BalanceChangeUnspecified) + state.SetNonce(addr1, 1, tracing.NonceChangeUnspecified) + state.SetState(addr1, common.HexToHash("0x1111"), common.HexToHash("0xaaaa")) + state.SetState(addr1, common.HexToHash("0x2222"), common.HexToHash("0xbbbb")) + + state.AddBalance(addr2, uint256.NewInt(2000), tracing.BalanceChangeUnspecified) + state.SetNonce(addr2, 2, tracing.NonceChangeUnspecified) + state.SetCode(addr2, []byte{0x60, 0x80, 0x60, 0x40, 0x52}, tracing.CodeChangeUnspecified) + + state.AddBalance(addr3, uint256.NewInt(3000), tracing.BalanceChangeUnspecified) + state.SetNonce(addr3, 3, tracing.NonceChangeUnspecified) + + currentRoot, err := state.Commit(1, true, false) + if err != nil { + t.Fatalf("Failed to commit initial state: %v", err) + } + if err := tdb.Commit(currentRoot, false); err != nil { + t.Fatalf("Failed to commit initial trie: %v", err) + } + + for i := 1; i < 50; i++ { // blocks 2-50 + blockNum := uint64(i + 1) + + newState, err := New(currentRoot, sdb) + if err != nil { + t.Fatalf("Failed to create new state at block %d: %v", blockNum, err) + } + testAddr := common.BigToAddress(uint256.NewInt(uint64(i + 100)).ToBig()) + newState.AddBalance(testAddr, uint256.NewInt(uint64((i+1)*1000)), tracing.BalanceChangeUnspecified) + newState.SetNonce(testAddr, uint64(i+10), tracing.NonceChangeUnspecified) + + if i%2 == 0 { + newState.SetState(addr1, common.BigToHash(uint256.NewInt(uint64(i+0x1000)).ToBig()), common.BigToHash(uint256.NewInt(uint64(i+0x2000)).ToBig())) + } + if i%3 == 0 { + newState.SetCode(testAddr, []byte{byte(i), 0x60, 0x80, byte(i + 1), 0x52}, tracing.CodeChangeUnspecified) + } + root, err := newState.Commit(blockNum, true, false) + if err != nil { + t.Fatalf("Failed to commit state at block %d: %v", blockNum, err) + } + if err := tdb.Commit(root, false); err != nil { + t.Fatalf("Failed to commit trie at block %d: %v", blockNum, err) + } + currentRoot = root + } + baselineRoot := currentRoot + + // Close and reopen the trie database so all async flushes triggered by the + // baseline commits are written before we measure the baseline snapshot. + if err := tdb.Close(); err != nil { + t.Fatalf("Failed to close triedb before baseline measurement: %v", err) + } + tdb = triedb.NewDatabase(db, &triedb.Config{PathDB: pathdb.Defaults}) + sdb = NewDatabase(tdb, nil) + + // Wait for snapshot completion + for !tdb.SnapshotCompleted() { + time.Sleep(100 * time.Millisecond) + } + + // Calculate baseline from the intermediate persisted state + baselineTracker := &SizeTracker{ + db: db, + triedb: tdb, + abort: make(chan struct{}), + } + done := make(chan buildResult) + + go baselineTracker.build(baselineRoot, baselineBlockNum, done) + var baselineResult buildResult + select { + case baselineResult = <-done: + if baselineResult.err != nil { + t.Fatalf("Failed to get baseline stats: %v", baselineResult.err) + } + case <-time.After(30 * time.Second): + t.Fatal("Timeout waiting for baseline stats") + } + baseline := baselineResult.stat + + // Now start the tracker and notify it of updates that happen AFTER the baseline + tracker, err := NewSizeTracker(db, tdb) + if err != nil { + t.Fatalf("Failed to create size tracker: %v", err) + } + defer tracker.Stop() + + var trackedUpdates []SizeStats + currentRoot = baselineRoot + + // Generate additional blocks beyond the baseline and track them + for i := 49; i < 130; i++ { // blocks 51-132 + blockNum := uint64(i + 2) + newState, err := New(currentRoot, sdb) + if err != nil { + t.Fatalf("Failed to create new state at block %d: %v", blockNum, err) + } + testAddr := common.BigToAddress(uint256.NewInt(uint64(i + 100)).ToBig()) + newState.AddBalance(testAddr, uint256.NewInt(uint64((i+1)*1000)), tracing.BalanceChangeUnspecified) + newState.SetNonce(testAddr, uint64(i+10), tracing.NonceChangeUnspecified) + + if i%2 == 0 { + newState.SetState(addr1, common.BigToHash(uint256.NewInt(uint64(i+0x1000)).ToBig()), common.BigToHash(uint256.NewInt(uint64(i+0x2000)).ToBig())) + } + if i%3 == 0 { + newState.SetCode(testAddr, []byte{byte(i), 0x60, 0x80, byte(i + 1), 0x52}, tracing.CodeChangeUnspecified) + } + ret, err := newState.commitAndFlush(blockNum, true, false, true) + if err != nil { + t.Fatalf("Failed to commit state at block %d: %v", blockNum, err) + } + tracker.Notify(ret) + + if err := tdb.Commit(ret.root, false); err != nil { + t.Fatalf("Failed to commit trie at block %d: %v", blockNum, err) + } + + diff, err := calSizeStats(ret) + if err != nil { + t.Fatalf("Failed to calculate size stats for block %d: %v", blockNum, err) + } + trackedUpdates = append(trackedUpdates, diff) + currentRoot = ret.root + } + finalRoot := rawdb.ReadSnapshotRoot(db) + + // Ensure all commits are flushed to disk + if err := tdb.Close(); err != nil { + t.Fatalf("Failed to close triedb: %v", err) + } + // Reopen the database to simulate a restart + tdb = triedb.NewDatabase(db, &triedb.Config{PathDB: pathdb.Defaults}) + defer tdb.Close() + + finalTracker := &SizeTracker{ + db: db, + triedb: tdb, + abort: make(chan struct{}), + } + finalDone := make(chan buildResult) + + go finalTracker.build(finalRoot, uint64(132), finalDone) + var result buildResult + select { + case result = <-finalDone: + if result.err != nil { + t.Fatalf("Failed to build final stats: %v", result.err) + } + case <-time.After(30 * time.Second): + t.Fatal("Timeout waiting for final stats") + } + actualStats := result.stat + + expectedStats := baseline + for _, diff := range trackedUpdates { + expectedStats = expectedStats.add(diff) + } + + // The final measured stats should match our calculated expected stats exactly + if actualStats.Accounts != expectedStats.Accounts { + t.Errorf("Account count mismatch: baseline(%d) + tracked_changes = %d, but final_measurement = %d", baseline.Accounts, expectedStats.Accounts, actualStats.Accounts) + } + if actualStats.AccountBytes != expectedStats.AccountBytes { + t.Errorf("Account bytes mismatch: expected %d, got %d", expectedStats.AccountBytes, actualStats.AccountBytes) + } + if actualStats.Storages != expectedStats.Storages { + t.Errorf("Storage count mismatch: baseline(%d) + tracked_changes = %d, but final_measurement = %d", baseline.Storages, expectedStats.Storages, actualStats.Storages) + } + if actualStats.StorageBytes != expectedStats.StorageBytes { + t.Errorf("Storage bytes mismatch: expected %d, got %d", expectedStats.StorageBytes, actualStats.StorageBytes) + } + if actualStats.ContractCodes != expectedStats.ContractCodes { + t.Errorf("Contract code count mismatch: baseline(%d) + tracked_changes = %d, but final_measurement = %d", baseline.ContractCodes, expectedStats.ContractCodes, actualStats.ContractCodes) + } + if actualStats.ContractCodeBytes != expectedStats.ContractCodeBytes { + t.Errorf("Contract code bytes mismatch: expected %d, got %d", expectedStats.ContractCodeBytes, actualStats.ContractCodeBytes) + } + if actualStats.AccountTrienodes != expectedStats.AccountTrienodes { + t.Errorf("Account trie nodes mismatch: expected %d, got %d", expectedStats.AccountTrienodes, actualStats.AccountTrienodes) + } + if actualStats.AccountTrienodeBytes != expectedStats.AccountTrienodeBytes { + t.Errorf("Account trie node bytes mismatch: expected %d, got %d", expectedStats.AccountTrienodeBytes, actualStats.AccountTrienodeBytes) + } + if actualStats.StorageTrienodes != expectedStats.StorageTrienodes { + t.Errorf("Storage trie nodes mismatch: expected %d, got %d", expectedStats.StorageTrienodes, actualStats.StorageTrienodes) + } + if actualStats.StorageTrienodeBytes != expectedStats.StorageTrienodeBytes { + t.Errorf("Storage trie node bytes mismatch: expected %d, got %d", expectedStats.StorageTrienodeBytes, actualStats.StorageTrienodeBytes) + } +} diff --git a/core/state/statedb.go b/core/state/statedb.go index 7aa6780cfa..39160aa1c7 100644 --- a/core/state/statedb.go +++ b/core/state/statedb.go @@ -22,6 +22,7 @@ import ( "fmt" "maps" "slices" + "sort" "sync" "sync/atomic" "time" @@ -37,7 +38,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" - "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" "golang.org/x/sync/errgroup" ) @@ -136,18 +136,21 @@ type StateDB struct { journal *journal // State witness if cross validation is needed - witness *stateless.Witness + witness *stateless.Witness + witnessStats *stateless.WitnessStats // Measurements gathered during execution for debugging purposes - AccountReads time.Duration - AccountHashes time.Duration - AccountUpdates time.Duration - AccountCommits time.Duration + AccountReads time.Duration + AccountHashes time.Duration + AccountUpdates time.Duration + AccountCommits time.Duration + StorageReads time.Duration StorageUpdates time.Duration StorageCommits time.Duration SnapshotCommits time.Duration TrieDBCommits time.Duration + CodeReads time.Duration AccountLoaded int // Number of accounts retrieved from the database during the state transition AccountUpdated int // Number of accounts updated during the state transition @@ -155,6 +158,7 @@ type StateDB struct { StorageLoaded int // Number of storage slots retrieved from the database during the state transition StorageUpdated atomic.Int64 // Number of storage slots updated during the state transition StorageDeleted atomic.Int64 // Number of storage slots deleted during the state transition + CodeLoaded int // Number of contract code loaded during the state transition } // New creates a new state from a given trie. @@ -183,7 +187,7 @@ func NewWithReader(root common.Hash, db Database, reader Reader) (*StateDB, erro transientStorage: newTransientStorage(), } if db.TrieDB().IsVerkle() { - sdb.accessEvents = NewAccessEvents(db.PointCache()) + sdb.accessEvents = NewAccessEvents() } return sdb, nil } @@ -191,12 +195,13 @@ func NewWithReader(root common.Hash, db Database, reader Reader) (*StateDB, erro // StartPrefetcher initializes a new trie prefetcher to pull in nodes from the // state trie concurrently while the state is mutated so that when we reach the // commit phase, most of the needed data is already hot. -func (s *StateDB) StartPrefetcher(namespace string, witness *stateless.Witness) { +func (s *StateDB) StartPrefetcher(namespace string, witness *stateless.Witness, witnessStats *stateless.WitnessStats) { // Terminate any previously running prefetcher s.StopPrefetcher() // Enable witness collection if requested s.witness = witness + s.witnessStats = witnessStats // With the switch to the Proof-of-Stake consensus algorithm, block production // rewards are now handled at the consensus layer. Consequently, a block may @@ -262,6 +267,9 @@ func (s *StateDB) Logs() []*types.Log { for _, lgs := range s.logs { logs = append(logs, lgs...) } + sort.Slice(logs, func(i, j int) bool { + return logs[i].Index < logs[j].Index + }) return logs } @@ -456,7 +464,7 @@ func (s *StateDB) SetNonce(addr common.Address, nonce uint64, reason tracing.Non } } -func (s *StateDB) SetCode(addr common.Address, code []byte) (prev []byte) { +func (s *StateDB) SetCode(addr common.Address, code []byte, reason tracing.CodeChangeReason) (prev []byte) { stateObject := s.getOrNewStateObject(addr) if stateObject != nil { return stateObject.SetCode(crypto.Keccak256Hash(code), code) @@ -501,21 +509,13 @@ func (s *StateDB) SetStorage(addr common.Address, storage map[common.Hash]common } // SelfDestruct marks the given account as selfdestructed. -// This clears the account balance. // // The account's state object is still available until the state is committed, // getStateObject will return a non-nil account after SelfDestruct. -func (s *StateDB) SelfDestruct(addr common.Address) uint256.Int { +func (s *StateDB) SelfDestruct(addr common.Address) { stateObject := s.getStateObject(addr) - var prevBalance uint256.Int if stateObject == nil { - return prevBalance - } - prevBalance = *(stateObject.Balance()) - // Regardless of whether it is already destructed or not, we do have to - // journal the balance-change, if we set it to zero here. - if !stateObject.Balance().IsZero() { - stateObject.SetBalance(new(uint256.Int)) + return } // If it is already marked as self-destructed, we do not need to add it // for journalling a second time. @@ -523,18 +523,6 @@ func (s *StateDB) SelfDestruct(addr common.Address) uint256.Int { s.journal.destruct(addr) stateObject.markSelfdestructed() } - return prevBalance -} - -func (s *StateDB) SelfDestruct6780(addr common.Address) (uint256.Int, bool) { - stateObject := s.getStateObject(addr) - if stateObject == nil { - return uint256.Int{}, false - } - if stateObject.newContract { - return s.SelfDestruct(addr), true - } - return *(stateObject.Balance()), false } // SetTransientState sets transient storage for a given account. It @@ -662,6 +650,16 @@ func (s *StateDB) CreateContract(addr common.Address) { } } +// IsNewContract reports whether the contract at the given address was deployed +// during the current transaction. +func (s *StateDB) IsNewContract(addr common.Address) bool { + obj := s.getStateObject(addr) + if obj == nil { + return false + } + return obj.newContract +} + // Copy creates a deep, independent copy of the state. // Snapshots of the copied state cannot be applied to the copy. func (s *StateDB) Copy() *StateDB { @@ -858,9 +856,17 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { continue } if trie := obj.getPrefetchedTrie(); trie != nil { - s.witness.AddState(trie.Witness()) + witness := trie.Witness() + s.witness.AddState(witness) + if s.witnessStats != nil { + s.witnessStats.Add(witness, obj.addrHash) + } } else if obj.trie != nil { - s.witness.AddState(obj.trie.Witness()) + witness := obj.trie.Witness() + s.witness.AddState(witness) + if s.witnessStats != nil { + s.witnessStats.Add(witness, obj.addrHash) + } } } // Pull in only-read and non-destructed trie witnesses @@ -874,9 +880,17 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { continue } if trie := obj.getPrefetchedTrie(); trie != nil { - s.witness.AddState(trie.Witness()) + witness := trie.Witness() + s.witness.AddState(witness) + if s.witnessStats != nil { + s.witnessStats.Add(witness, obj.addrHash) + } } else if obj.trie != nil { - s.witness.AddState(obj.trie.Witness()) + witness := obj.trie.Witness() + s.witness.AddState(witness) + if s.witnessStats != nil { + s.witnessStats.Add(witness, obj.addrHash) + } } } } @@ -942,7 +956,11 @@ func (s *StateDB) IntermediateRoot(deleteEmptyObjects bool) common.Hash { // If witness building is enabled, gather the account trie witness if s.witness != nil { - s.witness.AddState(s.trie.Witness()) + witness := s.trie.Witness() + s.witness.AddState(witness) + if s.witnessStats != nil { + s.witnessStats.Add(witness, common.Hash{}) + } } return hash } @@ -977,7 +995,7 @@ func (s *StateDB) fastDeleteStorage(snaps *snapshot.Tree, addrHash common.Hash, storageOrigins = make(map[common.Hash][]byte) // the set for tracking the original value of slot ) stack := trie.NewStackTrie(func(path []byte, hash common.Hash, blob []byte) { - nodes.AddNode(path, trienode.NewDeleted()) + nodes.AddNode(path, trienode.NewDeletedWithPrev(blob)) }) for iter.Next() { slot := common.CopyBytes(iter.Slot()) @@ -1028,7 +1046,7 @@ func (s *StateDB) slowDeleteStorage(addr common.Address, addrHash common.Hash, r if it.Hash() == (common.Hash{}) { continue } - nodes.AddNode(it.Path(), trienode.NewDeleted()) + nodes.AddNode(it.Path(), trienode.NewDeletedWithPrev(it.NodeBlob())) } if err := it.Error(); err != nil { return nil, nil, nil, err @@ -1133,7 +1151,7 @@ func (s *StateDB) GetTrie() Trie { // commit gathers the state mutations accumulated along with the associated // trie changes, resetting all internal flags with the new state as the base. -func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool) (*stateUpdate, error) { +func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool, blockNumber uint64) (*stateUpdate, error) { // Short circuit in case any database failure occurred earlier. if s.dbErr != nil { return nil, fmt.Errorf("commit aborted due to earlier error: %v", s.dbErr) @@ -1160,7 +1178,7 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool) (*stateU // // Given that some accounts may be destroyed and then recreated within // the same block, it's possible that a node set with the same owner - // may already exists. In such cases, these two sets are combined, with + // may already exist. In such cases, these two sets are combined, with // the later one overwriting the previous one if any nodes are modified // or deleted in both sets. // @@ -1285,16 +1303,21 @@ func (s *StateDB) commit(deleteEmptyObjects bool, noStorageWiping bool) (*stateU origin := s.originalRoot s.originalRoot = root - return newStateUpdate(noStorageWiping, origin, root, deletes, updates, nodes), nil + return newStateUpdate(noStorageWiping, origin, root, blockNumber, deletes, updates, nodes), nil } // commitAndFlush is a wrapper of commit which also commits the state mutations // to the configured data stores. -func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (*stateUpdate, error) { - ret, err := s.commit(deleteEmptyObjects, noStorageWiping) +func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorageWiping bool, deriveCodeFields bool) (*stateUpdate, error) { + ret, err := s.commit(deleteEmptyObjects, noStorageWiping, block) if err != nil { return nil, err } + if deriveCodeFields { + if err := ret.deriveCodeFields(s.reader); err != nil { + return nil, err + } + } // Commit dirty contract code if any exists if db := s.db.TrieDB().Disk(); db != nil && len(ret.codes) > 0 { batch := db.NewBatch() @@ -1349,13 +1372,23 @@ func (s *StateDB) commitAndFlush(block uint64, deleteEmptyObjects bool, noStorag // no empty accounts left that could be deleted by EIP-158, storage wiping // should not occur. func (s *StateDB) Commit(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, error) { - ret, err := s.commitAndFlush(block, deleteEmptyObjects, noStorageWiping) + ret, err := s.commitAndFlush(block, deleteEmptyObjects, noStorageWiping, false) if err != nil { return common.Hash{}, err } return ret.root, nil } +// CommitWithUpdate writes the state mutations and returns the state update for +// external processing (e.g., live tracing hooks or size tracker). +func (s *StateDB) CommitWithUpdate(block uint64, deleteEmptyObjects bool, noStorageWiping bool) (common.Hash, *stateUpdate, error) { + ret, err := s.commitAndFlush(block, deleteEmptyObjects, noStorageWiping, true) + if err != nil { + return common.Hash{}, nil, err + } + return ret.root, ret, nil +} + // Prepare handles the preparatory steps for executing a state transition with. // This method must be invoked before state transition. // @@ -1451,11 +1484,6 @@ func (s *StateDB) markUpdate(addr common.Address) { s.mutations[addr].typ = update } -// PointCache returns the point cache used by verkle tree. -func (s *StateDB) PointCache() *utils.PointCache { - return s.db.PointCache() -} - // Witness retrieves the current state witness being collected. func (s *StateDB) Witness() *stateless.Witness { return s.witness diff --git a/core/state/statedb_fuzz_test.go b/core/state/statedb_fuzz_test.go index 7dada63d45..8b6ac0ba64 100644 --- a/core/state/statedb_fuzz_test.go +++ b/core/state/statedb_fuzz_test.go @@ -89,7 +89,7 @@ func newStateTestAction(addr common.Address, r *rand.Rand, index int) testAction code := make([]byte, 16) binary.BigEndian.PutUint64(code, uint64(a.args[0])) binary.BigEndian.PutUint64(code[8:], uint64(a.args[1])) - s.SetCode(addr, code) + s.SetCode(addr, code, tracing.CodeChangeUnspecified) }, args: make([]int64, 2), }, @@ -228,7 +228,7 @@ func (test *stateTest) run() bool { } else { state.IntermediateRoot(true) // call intermediateRoot at the transaction boundary } - ret, err := state.commitAndFlush(0, true, false) // call commit at the block boundary + ret, err := state.commitAndFlush(0, true, false, false) // call commit at the block boundary if err != nil { panic(err) } diff --git a/core/state/statedb_hooked.go b/core/state/statedb_hooked.go index 3d1ef15031..48794a3f41 100644 --- a/core/state/statedb_hooked.go +++ b/core/state/statedb_hooked.go @@ -17,7 +17,9 @@ package state import ( + "bytes" "math/big" + "sort" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/stateless" @@ -25,7 +27,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" ) @@ -53,6 +54,10 @@ func (s *hookedStateDB) CreateContract(addr common.Address) { s.inner.CreateContract(addr) } +func (s *hookedStateDB) IsNewContract(addr common.Address) bool { + return s.inner.IsNewContract(addr) +} + func (s *hookedStateDB) GetBalance(addr common.Address) *uint256.Int { return s.inner.GetBalance(addr) } @@ -133,10 +138,6 @@ func (s *hookedStateDB) AddSlotToAccessList(addr common.Address, slot common.Has s.inner.AddSlotToAccessList(addr, slot) } -func (s *hookedStateDB) PointCache() *utils.PointCache { - return s.inner.PointCache() -} - func (s *hookedStateDB) Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) { s.inner.Prepare(rules, sender, coinbase, dest, precompiles, txAccesses) } @@ -189,14 +190,21 @@ func (s *hookedStateDB) SetNonce(address common.Address, nonce uint64, reason tr } } -func (s *hookedStateDB) SetCode(address common.Address, code []byte) []byte { - prev := s.inner.SetCode(address, code) - if s.hooks.OnCodeChange != nil { - prevHash := types.EmptyCodeHash - if len(prev) != 0 { - prevHash = crypto.Keccak256Hash(prev) +func (s *hookedStateDB) SetCode(address common.Address, code []byte, reason tracing.CodeChangeReason) []byte { + prev := s.inner.SetCode(address, code, reason) + + if s.hooks.OnCodeChangeV2 != nil || s.hooks.OnCodeChange != nil { + prevHash := crypto.Keccak256Hash(prev) + codeHash := crypto.Keccak256Hash(code) + + // Invoke the hooks only if the contract code is changed + if prevHash != codeHash { + if s.hooks.OnCodeChangeV2 != nil { + s.hooks.OnCodeChangeV2(address, prevHash, prev, codeHash, code, reason) + } else if s.hooks.OnCodeChange != nil { + s.hooks.OnCodeChange(address, prevHash, prev, codeHash, code) + } } - s.hooks.OnCodeChange(address, prevHash, prev, crypto.Keccak256Hash(code), code) } return prev } @@ -209,48 +217,8 @@ func (s *hookedStateDB) SetState(address common.Address, key common.Hash, value return prev } -func (s *hookedStateDB) SelfDestruct(address common.Address) uint256.Int { - var prevCode []byte - var prevCodeHash common.Hash - - if s.hooks.OnCodeChange != nil { - prevCode = s.inner.GetCode(address) - prevCodeHash = s.inner.GetCodeHash(address) - } - - prev := s.inner.SelfDestruct(address) - - if s.hooks.OnBalanceChange != nil && !prev.IsZero() { - s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct) - } - - if s.hooks.OnCodeChange != nil && len(prevCode) > 0 { - s.hooks.OnCodeChange(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil) - } - - return prev -} - -func (s *hookedStateDB) SelfDestruct6780(address common.Address) (uint256.Int, bool) { - var prevCode []byte - var prevCodeHash common.Hash - - if s.hooks.OnCodeChange != nil { - prevCodeHash = s.inner.GetCodeHash(address) - prevCode = s.inner.GetCode(address) - } - - prev, changed := s.inner.SelfDestruct6780(address) - - if s.hooks.OnBalanceChange != nil && changed && !prev.IsZero() { - s.hooks.OnBalanceChange(address, prev.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestruct) - } - - if s.hooks.OnCodeChange != nil && changed && len(prevCode) > 0 { - s.hooks.OnCodeChange(address, prevCodeHash, prevCode, types.EmptyCodeHash, nil) - } - - return prev, changed +func (s *hookedStateDB) SelfDestruct(address common.Address) { + s.inner.SelfDestruct(address) } func (s *hookedStateDB) AddLog(log *types.Log) { @@ -262,17 +230,58 @@ func (s *hookedStateDB) AddLog(log *types.Log) { } func (s *hookedStateDB) Finalise(deleteEmptyObjects bool) { - defer s.inner.Finalise(deleteEmptyObjects) - if s.hooks.OnBalanceChange == nil { + if s.hooks.OnBalanceChange == nil && s.hooks.OnNonceChangeV2 == nil && s.hooks.OnNonceChange == nil && s.hooks.OnCodeChangeV2 == nil && s.hooks.OnCodeChange == nil { + // Short circuit if no relevant hooks are set. + s.inner.Finalise(deleteEmptyObjects) return } + + // Collect all self-destructed addresses first, then sort them to ensure + // that state change hooks will be invoked in deterministic + // order when the accounts are deleted below + var selfDestructedAddrs []common.Address for addr := range s.inner.journal.dirties { obj := s.inner.stateObjects[addr] - if obj != nil && obj.selfDestructed { - // If ether was sent to account post-selfdestruct it is burnt. + if obj == nil || !obj.selfDestructed { + // Not self-destructed, keep searching. + continue + } + selfDestructedAddrs = append(selfDestructedAddrs, addr) + } + sort.Slice(selfDestructedAddrs, func(i, j int) bool { + return bytes.Compare(selfDestructedAddrs[i][:], selfDestructedAddrs[j][:]) < 0 + }) + + for _, addr := range selfDestructedAddrs { + obj := s.inner.stateObjects[addr] + // Bingo: state object was self-destructed, call relevant hooks. + + // If ether was sent to account post-selfdestruct, record as burnt. + if s.hooks.OnBalanceChange != nil { if bal := obj.Balance(); bal.Sign() != 0 { s.hooks.OnBalanceChange(addr, bal.ToBig(), new(big.Int), tracing.BalanceDecreaseSelfdestructBurn) } } + + // Nonce is set to reset on self-destruct. + if s.hooks.OnNonceChangeV2 != nil { + s.hooks.OnNonceChangeV2(addr, obj.Nonce(), 0, tracing.NonceChangeSelfdestruct) + } else if s.hooks.OnNonceChange != nil { + s.hooks.OnNonceChange(addr, obj.Nonce(), 0) + } + + // If an initcode invokes selfdestruct, do not emit a code change. + prevCodeHash := s.inner.GetCodeHash(addr) + if prevCodeHash == types.EmptyCodeHash { + continue + } + // Otherwise, trace the change. + if s.hooks.OnCodeChangeV2 != nil { + s.hooks.OnCodeChangeV2(addr, prevCodeHash, s.inner.GetCode(addr), types.EmptyCodeHash, nil, tracing.CodeChangeSelfDestruct) + } else if s.hooks.OnCodeChange != nil { + s.hooks.OnCodeChange(addr, prevCodeHash, s.inner.GetCode(addr), types.EmptyCodeHash, nil) + } } + + s.inner.Finalise(deleteEmptyObjects) } diff --git a/core/state/statedb_hooked_test.go b/core/state/statedb_hooked_test.go index f319b0e63c..6fe17ec1b4 100644 --- a/core/state/statedb_hooked_test.go +++ b/core/state/statedb_hooked_test.go @@ -49,6 +49,8 @@ func TestBurn(t *testing.T) { createAndDestroy := func(addr common.Address) { hooked.AddBalance(addr, uint256.NewInt(100), tracing.BalanceChangeUnspecified) hooked.CreateContract(addr) + // Simulate what the opcode handler does: clear balance before selfdestruct + hooked.SubBalance(addr, hooked.GetBalance(addr), tracing.BalanceDecreaseSelfdestruct) hooked.SelfDestruct(addr) // sanity-check that balance is now 0 if have, want := hooked.GetBalance(addr), new(uint256.Int); !have.Eq(want) { @@ -114,7 +116,7 @@ func TestHooks(t *testing.T) { sdb.AddBalance(common.Address{0xaa}, uint256.NewInt(100), tracing.BalanceChangeUnspecified) sdb.SubBalance(common.Address{0xaa}, uint256.NewInt(50), tracing.BalanceChangeTransfer) sdb.SetNonce(common.Address{0xaa}, 1337, tracing.NonceChangeGenesis) - sdb.SetCode(common.Address{0xaa}, []byte{0x13, 37}) + sdb.SetCode(common.Address{0xaa}, []byte{0x13, 37}, tracing.CodeChangeUnspecified) sdb.SetState(common.Address{0xaa}, common.HexToHash("0x01"), common.HexToHash("0x11")) sdb.SetState(common.Address{0xaa}, common.HexToHash("0x01"), common.HexToHash("0x22")) sdb.SetTransientState(common.Address{0xaa}, common.HexToHash("0x02"), common.HexToHash("0x01")) @@ -122,9 +124,51 @@ func TestHooks(t *testing.T) { sdb.AddLog(&types.Log{ Address: common.Address{0xbb}, }) + + if len(result) != len(wants) { + t.Fatalf("number of tracing events wrong, have %d want %d", len(result), len(wants)) + } + for i, want := range wants { if have := result[i]; have != want { - t.Fatalf("error event %d, have\n%v\nwant%v\n", i, have, want) + t.Fatalf("error event %d\nhave: %v\nwant: %v", i, have, want) + } + } +} + +func TestHooks_OnCodeChangeV2(t *testing.T) { + inner, _ := New(types.EmptyRootHash, NewDatabaseForTesting()) + + var result []string + var wants = []string{ + "0xaa00000000000000000000000000000000000000.code: (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) ->0x1325 (0xa12ae05590de0c93a00bc7ac773c2fdb621e44f814985e72194f921c0050f728) ContractCreation", + "0xbb00000000000000000000000000000000000000.code: (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) ->0x1326 (0x3c54516221d604e623f358bc95996ca3242aaa109bddabcebda13db9b3f90dcb) ContractCreation", + "0xaa00000000000000000000000000000000000000.code: 0x1325 (0xa12ae05590de0c93a00bc7ac773c2fdb621e44f814985e72194f921c0050f728) -> (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) SelfDestruct", + "0xbb00000000000000000000000000000000000000.code: 0x1326 (0x3c54516221d604e623f358bc95996ca3242aaa109bddabcebda13db9b3f90dcb) -> (0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470) SelfDestruct", + } + emitF := func(format string, a ...any) { + result = append(result, fmt.Sprintf(format, a...)) + } + sdb := NewHookedState(inner, &tracing.Hooks{ + OnCodeChangeV2: func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) { + emitF("%v.code: %#x (%v) ->%#x (%v) %s", addr, prevCode, prevCodeHash, code, codeHash, reason) + }, + }) + sdb.SetCode(common.Address{0xaa}, []byte{0x13, 37}, tracing.CodeChangeContractCreation) + sdb.SelfDestruct(common.Address{0xaa}) + + sdb.SetCode(common.Address{0xbb}, []byte{0x13, 38}, tracing.CodeChangeContractCreation) + sdb.CreateContract(common.Address{0xbb}) + sdb.SelfDestruct(common.Address{0xbb}) + sdb.Finalise(true) + + if len(result) != len(wants) { + t.Fatalf("number of tracing events wrong, have %d want %d", len(result), len(wants)) + } + + for i, want := range wants { + if have := result[i]; have != want { + t.Fatalf("error event %d\nhave: %v\nwant: %v", i, have, want) } } } diff --git a/core/state/statedb_test.go b/core/state/statedb_test.go index 67e27cc832..661d17bb7b 100644 --- a/core/state/statedb_test.go +++ b/core/state/statedb_test.go @@ -65,7 +65,7 @@ func TestUpdateLeaks(t *testing.T) { state.SetState(addr, common.BytesToHash([]byte{i, i, i}), common.BytesToHash([]byte{i, i, i, i})) } if i%3 == 0 { - state.SetCode(addr, []byte{i, i, i, i, i}) + state.SetCode(addr, []byte{i, i, i, i, i}, tracing.CodeChangeUnspecified) } } @@ -101,7 +101,7 @@ func TestIntermediateLeaks(t *testing.T) { state.SetState(addr, common.Hash{i, i, i, tweak}, common.Hash{i, i, i, i, tweak}) } if i%3 == 0 { - state.SetCode(addr, []byte{i, i, i, i, i, tweak}) + state.SetCode(addr, []byte{i, i, i, i, i, tweak}, tracing.CodeChangeUnspecified) } } @@ -374,7 +374,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { code := make([]byte, 16) binary.BigEndian.PutUint64(code, uint64(a.args[0])) binary.BigEndian.PutUint64(code[8:], uint64(a.args[1])) - s.SetCode(addr, code) + s.SetCode(addr, code, tracing.CodeChangeUnspecified) }, args: make([]int64, 2), }, @@ -403,7 +403,7 @@ func newTestAction(addr common.Address, r *rand.Rand) testAction { // which would cause a difference in state when unrolling // the journal. (CreateContact assumes created was false prior to // invocation, and the journal rollback sets it to false). - s.SetCode(addr, []byte{1}) + s.SetCode(addr, []byte{1}, tracing.CodeChangeUnspecified) } }, }, @@ -731,7 +731,7 @@ func TestCopyCommitCopy(t *testing.T) { sval := common.HexToHash("bbb") state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata state.SetState(addr, skey, sval) // Change the storage trie if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { @@ -772,7 +772,7 @@ func TestCopyCommitCopy(t *testing.T) { t.Fatalf("second copy non-committed storage slot mismatch: have %x, want %x", val, sval) } if val := copyTwo.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("second copy committed storage slot mismatch: have %x, want %x", val, sval) + t.Fatalf("second copy committed storage slot mismatch: have %x, want %x", val, common.Hash{}) } // Commit state, ensure states can be loaded from disk root, _ := state.Commit(0, false, false) @@ -804,7 +804,7 @@ func TestCopyCopyCommitCopy(t *testing.T) { sval := common.HexToHash("bbb") state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata state.SetState(addr, skey, sval) // Change the storage trie if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { @@ -859,7 +859,7 @@ func TestCopyCopyCommitCopy(t *testing.T) { t.Fatalf("third copy non-committed storage slot mismatch: have %x, want %x", val, sval) } if val := copyThree.GetCommittedState(addr, skey); val != (common.Hash{}) { - t.Fatalf("third copy committed storage slot mismatch: have %x, want %x", val, sval) + t.Fatalf("third copy committed storage slot mismatch: have %x, want %x", val, common.Hash{}) } } @@ -874,7 +874,7 @@ func TestCommitCopy(t *testing.T) { sval1, sval2 := common.HexToHash("b1"), common.HexToHash("b2") state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata state.SetState(addr, skey1, sval1) // Change the storage trie if balance := state.GetBalance(addr); balance.Cmp(uint256.NewInt(42)) != 0 { @@ -912,10 +912,10 @@ func TestCommitCopy(t *testing.T) { } // Slots cached in the stateDB, available after commit if val := copied.GetState(addr, skey2); val != sval2 { - t.Fatalf("unexpected storage slot: have %x", sval1) + t.Fatalf("unexpected storage slot: have %x, want %x", val, sval2) } if val := copied.GetCommittedState(addr, skey2); val != sval2 { - t.Fatalf("unexpected storage slot: have %x", val) + t.Fatalf("unexpected storage slot: have %x, want %x", val, sval2) } } @@ -987,10 +987,10 @@ func testMissingTrieNodes(t *testing.T, scheme string) { addr := common.BytesToAddress([]byte("so")) { state.SetBalance(addr, uint256.NewInt(1), tracing.BalanceChangeUnspecified) - state.SetCode(addr, []byte{1, 2, 3}) + state.SetCode(addr, []byte{1, 2, 3}, tracing.CodeChangeUnspecified) a2 := common.BytesToAddress([]byte("another")) state.SetBalance(a2, uint256.NewInt(100), tracing.BalanceChangeUnspecified) - state.SetCode(a2, []byte{1, 2, 4}) + state.SetCode(a2, []byte{1, 2, 4}, tracing.CodeChangeUnspecified) root, _ = state.Commit(0, false, false) t.Logf("root: %x", root) // force-flush diff --git a/core/state/stateupdate.go b/core/state/stateupdate.go index 75c4ca028c..0c1b76b4f8 100644 --- a/core/state/stateupdate.go +++ b/core/state/stateupdate.go @@ -17,17 +17,27 @@ package state import ( + "fmt" "maps" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/triedb" ) -// contractCode represents a contract code with associated metadata. +// contractCode represents contract bytecode along with its associated metadata. type contractCode struct { - hash common.Hash // hash is the cryptographic hash of the contract code. - blob []byte // blob is the binary representation of the contract code. + hash common.Hash // hash is the cryptographic hash of the current contract code. + blob []byte // blob is the binary representation of the current contract code. + originHash common.Hash // originHash is the cryptographic hash of the code before mutation. + + // Derived fields, populated only when state tracking is enabled. + duplicate bool // duplicate indicates whether the updated code already exists. + originBlob []byte // originBlob is the original binary representation of the contract code. } // accountDelete represents an operation for deleting an Ethereum account. @@ -64,8 +74,10 @@ type accountUpdate struct { // execution. It contains information about mutated contract codes, accounts, // and storage slots, along with their original values. type stateUpdate struct { - originRoot common.Hash // hash of the state before applying mutation - root common.Hash // hash of the state after applying mutation + originRoot common.Hash // hash of the state before applying mutation + root common.Hash // hash of the state after applying mutation + blockNumber uint64 // Associated block number + accounts map[common.Hash][]byte // accounts stores mutated accounts in 'slim RLP' encoding accountsOrigin map[common.Address][]byte // accountsOrigin stores the original values of mutated accounts in 'slim RLP' encoding @@ -80,8 +92,8 @@ type stateUpdate struct { storagesOrigin map[common.Address]map[common.Hash][]byte rawStorageKey bool - codes map[common.Address]contractCode // codes contains the set of dirty codes - nodes *trienode.MergedNodeSet // Aggregated dirty nodes caused by state changes + codes map[common.Address]*contractCode // codes contains the set of dirty codes + nodes *trienode.MergedNodeSet // Aggregated dirty nodes caused by state changes } // empty returns a flag indicating the state transition is empty or not. @@ -95,13 +107,13 @@ func (sc *stateUpdate) empty() bool { // // rawStorageKey is a flag indicating whether to use the raw storage slot key or // the hash of the slot key for constructing state update object. -func newStateUpdate(rawStorageKey bool, originRoot common.Hash, root common.Hash, deletes map[common.Hash]*accountDelete, updates map[common.Hash]*accountUpdate, nodes *trienode.MergedNodeSet) *stateUpdate { +func newStateUpdate(rawStorageKey bool, originRoot common.Hash, root common.Hash, blockNumber uint64, deletes map[common.Hash]*accountDelete, updates map[common.Hash]*accountUpdate, nodes *trienode.MergedNodeSet) *stateUpdate { var ( accounts = make(map[common.Hash][]byte) accountsOrigin = make(map[common.Address][]byte) storages = make(map[common.Hash]map[common.Hash][]byte) storagesOrigin = make(map[common.Address]map[common.Hash][]byte) - codes = make(map[common.Address]contractCode) + codes = make(map[common.Address]*contractCode) ) // Since some accounts might be destroyed and recreated within the same // block, deletions must be aggregated first. @@ -123,7 +135,7 @@ func newStateUpdate(rawStorageKey bool, originRoot common.Hash, root common.Hash // Aggregate dirty contract codes if they are available. addr := op.address if op.code != nil { - codes[addr] = *op.code + codes[addr] = op.code } accounts[addrHash] = op.data @@ -164,6 +176,7 @@ func newStateUpdate(rawStorageKey bool, originRoot common.Hash, root common.Hash return &stateUpdate{ originRoot: originRoot, root: root, + blockNumber: blockNumber, accounts: accounts, accountsOrigin: accountsOrigin, storages: storages, @@ -187,3 +200,170 @@ func (sc *stateUpdate) stateSet() *triedb.StateSet { RawStorageKey: sc.rawStorageKey, } } + +// deriveCodeFields derives the missing fields of contract code changes +// such as original code value. +// +// Note: This operation is expensive and not needed during normal state +// transitions. It is only required when SizeTracker or StateUpdate hook +// is enabled to produce accurate state statistics. +func (sc *stateUpdate) deriveCodeFields(reader ContractCodeReader) error { + cache := make(map[common.Hash]bool) + for addr, code := range sc.codes { + if code.originHash != types.EmptyCodeHash { + blob, err := reader.Code(addr, code.originHash) + if err != nil { + return err + } + code.originBlob = blob + } + if exists, ok := cache[code.hash]; ok { + code.duplicate = exists + continue + } + res := reader.Has(addr, code.hash) + cache[code.hash] = res + code.duplicate = res + } + return nil +} + +// ToTracingUpdate converts the internal stateUpdate to an exported tracing.StateUpdate. +func (sc *stateUpdate) ToTracingUpdate() (*tracing.StateUpdate, error) { + update := &tracing.StateUpdate{ + OriginRoot: sc.originRoot, + Root: sc.root, + BlockNumber: sc.blockNumber, + AccountChanges: make(map[common.Address]*tracing.AccountChange, len(sc.accountsOrigin)), + StorageChanges: make(map[common.Address]map[common.Hash]*tracing.StorageChange), + CodeChanges: make(map[common.Address]*tracing.CodeChange, len(sc.codes)), + TrieChanges: make(map[common.Hash]map[string]*tracing.TrieNodeChange), + } + // Gather all account changes + for addr, oldData := range sc.accountsOrigin { + addrHash := crypto.Keccak256Hash(addr.Bytes()) + newData, exists := sc.accounts[addrHash] + if !exists { + return nil, fmt.Errorf("account %x not found", addr) + } + change := &tracing.AccountChange{} + + if len(oldData) > 0 { + acct, err := types.FullAccount(oldData) + if err != nil { + return nil, err + } + change.Prev = &types.StateAccount{ + Nonce: acct.Nonce, + Balance: acct.Balance, + Root: acct.Root, + CodeHash: acct.CodeHash, + } + } + if len(newData) > 0 { + acct, err := types.FullAccount(newData) + if err != nil { + return nil, err + } + change.New = &types.StateAccount{ + Nonce: acct.Nonce, + Balance: acct.Balance, + Root: acct.Root, + CodeHash: acct.CodeHash, + } + } + update.AccountChanges[addr] = change + } + + // Gather all storage slot changes + for addr, slots := range sc.storagesOrigin { + addrHash := crypto.Keccak256Hash(addr.Bytes()) + subset, exists := sc.storages[addrHash] + if !exists { + return nil, fmt.Errorf("storage %x not found", addr) + } + storageChanges := make(map[common.Hash]*tracing.StorageChange, len(slots)) + + for key, encPrev := range slots { + // Get new value - handle both raw and hashed key formats + var ( + exists bool + encNew []byte + decPrev []byte + decNew []byte + err error + ) + if sc.rawStorageKey { + encNew, exists = subset[crypto.Keccak256Hash(key.Bytes())] + } else { + encNew, exists = subset[key] + } + if !exists { + return nil, fmt.Errorf("storage slot %x-%x not found", addr, key) + } + + // Decode the prev and new values + if len(encPrev) > 0 { + _, decPrev, _, err = rlp.Split(encPrev) + if err != nil { + return nil, fmt.Errorf("failed to decode prevValue: %v", err) + } + } + if len(encNew) > 0 { + _, decNew, _, err = rlp.Split(encNew) + if err != nil { + return nil, fmt.Errorf("failed to decode newValue: %v", err) + } + } + storageChanges[key] = &tracing.StorageChange{ + Prev: common.BytesToHash(decPrev), + New: common.BytesToHash(decNew), + } + } + update.StorageChanges[addr] = storageChanges + } + + // Gather all contract code changes + for addr, code := range sc.codes { + change := &tracing.CodeChange{ + New: &tracing.ContractCode{ + Hash: code.hash, + Code: code.blob, + Exists: code.duplicate, + }, + } + if code.originHash != types.EmptyCodeHash { + change.Prev = &tracing.ContractCode{ + Hash: code.originHash, + Code: code.originBlob, + Exists: true, + } + } + update.CodeChanges[addr] = change + } + + // Gather all trie node changes + if sc.nodes != nil { + for owner, subset := range sc.nodes.Sets { + nodeChanges := make(map[string]*tracing.TrieNodeChange, len(subset.Origins)) + for path, oldNode := range subset.Origins { + newNode, exists := subset.Nodes[path] + if !exists { + return nil, fmt.Errorf("node %x-%v not found", owner, path) + } + nodeChanges[path] = &tracing.TrieNodeChange{ + Prev: &trienode.Node{ + Hash: crypto.Keccak256Hash(oldNode), + Blob: oldNode, + }, + New: &trienode.Node{ + Hash: newNode.Hash, + Blob: newNode.Blob, + }, + } + } + update.TrieChanges[owner] = nodeChanges + } + } + return update, nil +} diff --git a/core/state/trie_prefetcher.go b/core/state/trie_prefetcher.go index 6f492cf9f2..a9faddcdff 100644 --- a/core/state/trie_prefetcher.go +++ b/core/state/trie_prefetcher.go @@ -388,6 +388,10 @@ func (sf *subfetcher) loop() { sf.tasks = nil sf.lock.Unlock() + var ( + addresses []common.Address + slots [][]byte + ) for _, task := range tasks { if task.addr != nil { key := *task.addr @@ -400,6 +404,7 @@ func (sf *subfetcher) loop() { sf.dupsCross++ continue } + sf.seenReadAddr[key] = struct{}{} } else { if _, ok := sf.seenReadAddr[key]; ok { sf.dupsCross++ @@ -409,7 +414,9 @@ func (sf *subfetcher) loop() { sf.dupsWrite++ continue } + sf.seenWriteAddr[key] = struct{}{} } + addresses = append(addresses, *task.addr) } else { key := *task.slot if task.read { @@ -421,6 +428,7 @@ func (sf *subfetcher) loop() { sf.dupsCross++ continue } + sf.seenReadSlot[key] = struct{}{} } else { if _, ok := sf.seenReadSlot[key]; ok { sf.dupsCross++ @@ -430,25 +438,19 @@ func (sf *subfetcher) loop() { sf.dupsWrite++ continue } + sf.seenWriteSlot[key] = struct{}{} } + slots = append(slots, key.Bytes()) } - if task.addr != nil { - sf.trie.GetAccount(*task.addr) - } else { - sf.trie.GetStorage(sf.addr, (*task.slot)[:]) + } + if len(addresses) != 0 { + if err := sf.trie.PrefetchAccount(addresses); err != nil { + log.Error("Failed to prefetch accounts", "err", err) } - if task.read { - if task.addr != nil { - sf.seenReadAddr[*task.addr] = struct{}{} - } else { - sf.seenReadSlot[*task.slot] = struct{}{} - } - } else { - if task.addr != nil { - sf.seenWriteAddr[*task.addr] = struct{}{} - } else { - sf.seenWriteSlot[*task.slot] = struct{}{} - } + } + if len(slots) != 0 { + if err := sf.trie.PrefetchStorage(sf.addr, slots); err != nil { + log.Error("Failed to prefetch storage", "err", err) } } diff --git a/core/state/trie_prefetcher_test.go b/core/state/trie_prefetcher_test.go index 4d1b627c4d..41349c0c0e 100644 --- a/core/state/trie_prefetcher_test.go +++ b/core/state/trie_prefetcher_test.go @@ -39,7 +39,7 @@ func filledStateDB() *StateDB { sval := common.HexToHash("bbb") state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata state.SetState(addr, skey, sval) // Change the storage trie for i := 0; i < 100; i++ { sk := common.BigToHash(big.NewInt(int64(i))) @@ -81,7 +81,7 @@ func TestVerklePrefetcher(t *testing.T) { sval := testrand.Hash() state.SetBalance(addr, uint256.NewInt(42), tracing.BalanceChangeUnspecified) // Change the account trie - state.SetCode(addr, []byte("hello")) // Change an external metadata + state.SetCode(addr, []byte("hello"), tracing.CodeChangeUnspecified) // Change an external metadata state.SetState(addr, skey, sval) // Change the storage trie root, _ := state.Commit(0, true, false) diff --git a/core/state_prefetcher.go b/core/state_prefetcher.go index c0ce705c77..1c738c1e38 100644 --- a/core/state_prefetcher.go +++ b/core/state_prefetcher.go @@ -111,12 +111,6 @@ func (p *statePrefetcher) Prefetch(block *types.Block, statedb *state.StateDB, c fails.Add(1) return nil // Ugh, something went horribly wrong, bail out } - // Pre-load trie nodes for the intermediate root. - // - // This operation incurs significant memory allocations due to - // trie hashing and node decoding. TODO(rjl493456442): investigate - // ways to mitigate this overhead. - stateCpy.IntermediateRoot(true) return nil }) } diff --git a/core/state_processor.go b/core/state_processor.go index ee98326467..b4b22e4318 100644 --- a/core/state_processor.go +++ b/core/state_processor.go @@ -35,18 +35,21 @@ import ( // // StateProcessor implements Processor. type StateProcessor struct { - config *params.ChainConfig // Chain configuration options - chain *HeaderChain // Canonical header chain + chain ChainContext // Chain context interface } // NewStateProcessor initialises a new StateProcessor. -func NewStateProcessor(config *params.ChainConfig, chain *HeaderChain) *StateProcessor { +func NewStateProcessor(chain ChainContext) *StateProcessor { return &StateProcessor{ - config: config, - chain: chain, + chain: chain, } } +// chainConfig returns the chain configuration. +func (p *StateProcessor) chainConfig() *params.ChainConfig { + return p.chain.Config() +} + // Process processes the state changes according to the Ethereum rules by running // the transaction messages using the statedb and applying any rewards to both // the processor (coinbase) and any included uncles. @@ -56,6 +59,7 @@ func NewStateProcessor(config *params.ChainConfig, chain *HeaderChain) *StatePro // transactions failed to execute due to insufficient gas it will return an error. func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg vm.Config) (*ProcessResult, error) { var ( + config = p.chainConfig() receipts types.Receipts usedGas = new(uint64) header = block.Header() @@ -65,27 +69,28 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg gp = new(GasPool).AddGas(block.GasLimit()) ) - // Mutate the block and state according to any hard-fork specs - if p.config.DAOForkSupport && p.config.DAOForkBlock != nil && p.config.DAOForkBlock.Cmp(block.Number()) == 0 { - misc.ApplyDAOHardFork(statedb) - } - var ( - context vm.BlockContext - signer = types.MakeSigner(p.config, header.Number, header.Time) - ) - - // Apply pre-execution system calls. var tracingStateDB = vm.StateDB(statedb) if hooks := cfg.Tracer; hooks != nil { tracingStateDB = state.NewHookedState(statedb, hooks) } + + // Mutate the block and state according to any hard-fork specs + if config.DAOForkSupport && config.DAOForkBlock != nil && config.DAOForkBlock.Cmp(block.Number()) == 0 { + misc.ApplyDAOHardFork(tracingStateDB) + } + var ( + context vm.BlockContext + signer = types.MakeSigner(config, header.Number, header.Time) + ) + + // Apply pre-execution system calls. context = NewEVMBlockContext(header, p.chain, nil) - evm := vm.NewEVM(context, tracingStateDB, p.config, cfg) + evm := vm.NewEVM(context, tracingStateDB, config, cfg) if beaconRoot := block.BeaconRoot(); beaconRoot != nil { ProcessBeaconBlockRoot(*beaconRoot, evm) } - if p.config.IsPrague(block.Number(), block.Time()) || p.config.IsVerkle(block.Number(), block.Time()) { + if config.IsPrague(block.Number(), block.Time()) || config.IsVerkle(block.Number(), block.Time()) { ProcessParentBlockHash(block.ParentHash(), evm) } @@ -106,24 +111,24 @@ func (p *StateProcessor) Process(block *types.Block, statedb *state.StateDB, cfg } // Read requests if Prague is enabled. var requests [][]byte - if p.config.IsPrague(block.Number(), block.Time()) { + if config.IsPrague(block.Number(), block.Time()) { requests = [][]byte{} // EIP-6110 - if err := ParseDepositLogs(&requests, allLogs, p.config); err != nil { - return nil, err + if err := ParseDepositLogs(&requests, allLogs, config); err != nil { + return nil, fmt.Errorf("failed to parse deposit logs: %w", err) } // EIP-7002 if err := ProcessWithdrawalQueue(&requests, evm); err != nil { - return nil, err + return nil, fmt.Errorf("failed to process withdrawal queue: %w", err) } // EIP-7251 if err := ProcessConsolidationQueue(&requests, evm); err != nil { - return nil, err + return nil, fmt.Errorf("failed to process consolidation queue: %w", err) } } // Finalize the block, applying any consensus engine specific extras (e.g. block rewards) - p.chain.engine.Finalize(p.chain, header, tracingStateDB, block.Body()) + p.chain.Engine().Finalize(p.chain, header, tracingStateDB, block.Body()) return &ProcessResult{ Receipts: receipts, diff --git a/core/state_transition.go b/core/state_transition.go index 681c300696..bf5ac07636 100644 --- a/core/state_transition.go +++ b/core/state_transition.go @@ -164,8 +164,12 @@ type Message struct { // or the state prefetching. SkipNonceChecks bool - // When SkipFromEOACheck is true, the message sender is not checked to be an EOA. - SkipFromEOACheck bool + // When set, the message is not treated as a transaction, and certain + // transaction-specific checks are skipped: + // + // - From is not verified to be an EOA + // - GasLimit is not checked against the protocol defined tx gaslimit + SkipTransactionChecks bool } // TransactionToMessage converts a transaction into a Message. @@ -182,7 +186,7 @@ func TransactionToMessage(tx *types.Transaction, s types.Signer, baseFee *big.In AccessList: tx.AccessList(), SetCodeAuthorizations: tx.SetCodeAuthorizations(), SkipNonceChecks: false, - SkipFromEOACheck: false, + SkipTransactionChecks: false, BlobHashes: tx.BlobHashes(), BlobGasFeeCap: tx.BlobGasFeeCap(), } @@ -320,7 +324,12 @@ func (st *stateTransition) preCheck() error { msg.From.Hex(), stNonce) } } - if !msg.SkipFromEOACheck { + isOsaka := st.evm.ChainConfig().IsOsaka(st.evm.Context.BlockNumber, st.evm.Context.Time) + if !msg.SkipTransactionChecks { + // Verify tx gas limit does not exceed EIP-7825 cap. + if isOsaka && msg.GasLimit > params.MaxTxGas { + return fmt.Errorf("%w (cap: %d, tx: %d)", ErrGasLimitTooHigh, params.MaxTxGas, msg.GasLimit) + } // Make sure the sender is an EOA code := st.state.GetCode(msg.From) _, delegated := types.ParseDelegation(code) @@ -354,7 +363,6 @@ func (st *stateTransition) preCheck() error { } } // Check the blob version validity - isOsaka := st.evm.ChainConfig().IsOsaka(st.evm.Context.BlockNumber, st.evm.Context.Time) if msg.BlobHashes != nil { // The to field of a blob tx type is mandatory, and a `BlobTx` transaction internally // has it as a non-nillable value, so any msg derived from blob transaction has it non-nil. @@ -398,10 +406,6 @@ func (st *stateTransition) preCheck() error { return fmt.Errorf("%w (sender %v)", ErrEmptyAuthList, msg.From) } } - // Verify tx gas limit does not exceed EIP-7825 cap. - if isOsaka && msg.GasLimit > params.MaxTxGas { - return fmt.Errorf("%w (cap: %d, tx: %d)", ErrGasLimitTooHigh, params.MaxTxGas, msg.GasLimit) - } return st.buyGas() } @@ -617,12 +621,12 @@ func (st *stateTransition) applyAuthorization(auth *types.SetCodeAuthorization) st.state.SetNonce(authority, auth.Nonce+1, tracing.NonceChangeAuthorization) if auth.Address == (common.Address{}) { // Delegation to zero address means clear. - st.state.SetCode(authority, nil) + st.state.SetCode(authority, nil, tracing.CodeChangeAuthorizationClear) return nil } // Otherwise install delegation to auth.Address. - st.state.SetCode(authority, types.AddressToDelegation(auth.Address)) + st.state.SetCode(authority, types.AddressToDelegation(auth.Address), tracing.CodeChangeAuthorization) return nil } diff --git a/core/stateless.go b/core/stateless.go index d21a62b4a5..b20c909da6 100644 --- a/core/stateless.go +++ b/core/stateless.go @@ -62,7 +62,7 @@ func ExecuteStateless(config *params.ChainConfig, vmconfig vm.Config, block *typ headerCache: lru.NewCache[common.Hash, *types.Header](256), engine: beacon.New(ethash.NewFaker()), } - processor := NewStateProcessor(config, chain) + processor := NewStateProcessor(chain) validator := NewBlockValidator(config, nil) // No chain, we only validate the state, not the block // Run the stateless blocks processing and self-validate certain fields diff --git a/core/stateless/encoding.go b/core/stateless/encoding.go index 5f4cb0ea3c..5c43159e66 100644 --- a/core/stateless/encoding.go +++ b/core/stateless/encoding.go @@ -19,20 +19,21 @@ package stateless import ( "io" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/rlp" ) -// toExtWitness converts our internal witness representation to the consensus one. -func (w *Witness) toExtWitness() *extWitness { - ext := &extWitness{ +// ToExtWitness converts our internal witness representation to the consensus one. +func (w *Witness) ToExtWitness() *ExtWitness { + ext := &ExtWitness{ Headers: w.Headers, } - ext.Codes = make([][]byte, 0, len(w.Codes)) + ext.Codes = make([]hexutil.Bytes, 0, len(w.Codes)) for code := range w.Codes { ext.Codes = append(ext.Codes, []byte(code)) } - ext.State = make([][]byte, 0, len(w.State)) + ext.State = make([]hexutil.Bytes, 0, len(w.State)) for node := range w.State { ext.State = append(ext.State, []byte(node)) } @@ -40,7 +41,7 @@ func (w *Witness) toExtWitness() *extWitness { } // fromExtWitness converts the consensus witness format into our internal one. -func (w *Witness) fromExtWitness(ext *extWitness) error { +func (w *Witness) fromExtWitness(ext *ExtWitness) error { w.Headers = ext.Headers w.Codes = make(map[string]struct{}, len(ext.Codes)) @@ -56,21 +57,22 @@ func (w *Witness) fromExtWitness(ext *extWitness) error { // EncodeRLP serializes a witness as RLP. func (w *Witness) EncodeRLP(wr io.Writer) error { - return rlp.Encode(wr, w.toExtWitness()) + return rlp.Encode(wr, w.ToExtWitness()) } // DecodeRLP decodes a witness from RLP. func (w *Witness) DecodeRLP(s *rlp.Stream) error { - var ext extWitness + var ext ExtWitness if err := s.Decode(&ext); err != nil { return err } return w.fromExtWitness(&ext) } -// extWitness is a witness RLP encoding for transferring across clients. -type extWitness struct { - Headers []*types.Header - Codes [][]byte - State [][]byte +// ExtWitness is a witness RLP encoding for transferring across clients. +type ExtWitness struct { + Headers []*types.Header `json:"headers"` + Codes []hexutil.Bytes `json:"codes"` + State []hexutil.Bytes `json:"state"` + Keys []hexutil.Bytes `json:"keys"` } diff --git a/core/stateless/stats.go b/core/stateless/stats.go new file mode 100644 index 0000000000..73ce031bff --- /dev/null +++ b/core/stateless/stats.go @@ -0,0 +1,99 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stateless + +import ( + "encoding/json" + "maps" + "slices" + "sort" + "strconv" + "strings" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/metrics" +) + +var accountTrieLeavesAtDepth [16]*metrics.Counter +var storageTrieLeavesAtDepth [16]*metrics.Counter + +func init() { + for i := 0; i < 16; i++ { + accountTrieLeavesAtDepth[i] = metrics.NewRegisteredCounter("witness/trie/account/leaves/depth_"+strconv.Itoa(i), nil) + storageTrieLeavesAtDepth[i] = metrics.NewRegisteredCounter("witness/trie/storage/leaves/depth_"+strconv.Itoa(i), nil) + } +} + +// WitnessStats aggregates statistics for account and storage trie accesses. +type WitnessStats struct { + accountTrieLeaves [16]int64 + storageTrieLeaves [16]int64 +} + +// NewWitnessStats creates a new WitnessStats collector. +func NewWitnessStats() *WitnessStats { + return &WitnessStats{} +} + +// Add records trie access depths from the given node paths. +// If `owner` is the zero hash, accesses are attributed to the account trie; +// otherwise, they are attributed to the storage trie of that account. +func (s *WitnessStats) Add(nodes map[string][]byte, owner common.Hash) { + // Extract paths from the nodes map + paths := slices.Collect(maps.Keys(nodes)) + sort.Strings(paths) + + for i, path := range paths { + // If current path is a prefix of the next path, it's not a leaf. + // The last path is always a leaf. + if i == len(paths)-1 || !strings.HasPrefix(paths[i+1], paths[i]) { + depth := len(path) + if owner == (common.Hash{}) { + if depth >= len(s.accountTrieLeaves) { + depth = len(s.accountTrieLeaves) - 1 + } + s.accountTrieLeaves[depth] += 1 + } else { + if depth >= len(s.storageTrieLeaves) { + depth = len(s.storageTrieLeaves) - 1 + } + s.storageTrieLeaves[depth] += 1 + } + } + } +} + +// ReportMetrics reports the collected statistics to the global metrics registry. +func (s *WitnessStats) ReportMetrics(blockNumber uint64) { + // Encode the metrics as JSON for easier consumption + accountLeavesJson, _ := json.Marshal(s.accountTrieLeaves) + storageLeavesJson, _ := json.Marshal(s.storageTrieLeaves) + + // Log account trie depth statistics + log.Info("Account trie depth stats", + "block", blockNumber, + "leavesAtDepth", string(accountLeavesJson)) + log.Info("Storage trie depth stats", + "block", blockNumber, + "leavesAtDepth", string(storageLeavesJson)) + + for i := 0; i < 16; i++ { + accountTrieLeavesAtDepth[i].Inc(s.accountTrieLeaves[i]) + storageTrieLeavesAtDepth[i].Inc(s.storageTrieLeaves[i]) + } +} diff --git a/core/stateless/stats_test.go b/core/stateless/stats_test.go new file mode 100644 index 0000000000..e77084df5d --- /dev/null +++ b/core/stateless/stats_test.go @@ -0,0 +1,219 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package stateless + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +func TestWitnessStatsAdd(t *testing.T) { + tests := []struct { + name string + nodes map[string][]byte + owner common.Hash + expectedAccountLeaves map[int64]int64 + expectedStorageLeaves map[int64]int64 + }{ + { + name: "empty nodes", + nodes: map[string][]byte{}, + owner: common.Hash{}, + }, + { + name: "single account trie leaf at depth 0", + nodes: map[string][]byte{ + "": []byte("data"), + }, + owner: common.Hash{}, + expectedAccountLeaves: map[int64]int64{0: 1}, + }, + { + name: "single account trie leaf", + nodes: map[string][]byte{ + "abc": []byte("data"), + }, + owner: common.Hash{}, + expectedAccountLeaves: map[int64]int64{3: 1}, + }, + { + name: "account trie with internal nodes", + nodes: map[string][]byte{ + "a": []byte("data1"), + "ab": []byte("data2"), + "abc": []byte("data3"), + }, + owner: common.Hash{}, + expectedAccountLeaves: map[int64]int64{3: 1}, // Only "abc" is a leaf + }, + { + name: "multiple account trie branches", + nodes: map[string][]byte{ + "a": []byte("data1"), + "ab": []byte("data2"), + "abc": []byte("data3"), + "b": []byte("data4"), + "bc": []byte("data5"), + "bcd": []byte("data6"), + }, + owner: common.Hash{}, + expectedAccountLeaves: map[int64]int64{3: 2}, // "abc" (3) + "bcd" (3) + }, + { + name: "siblings are all leaves", + nodes: map[string][]byte{ + "aa": []byte("data1"), + "ab": []byte("data2"), + "ac": []byte("data3"), + }, + owner: common.Hash{}, + expectedAccountLeaves: map[int64]int64{2: 3}, + }, + { + name: "storage trie leaves", + nodes: map[string][]byte{ + "1": []byte("data1"), + "12": []byte("data2"), + "123": []byte("data3"), + "124": []byte("data4"), + }, + owner: common.HexToHash("0x1234"), + expectedStorageLeaves: map[int64]int64{3: 2}, // "123" (3) + "124" (3) + }, + { + name: "complex trie structure", + nodes: map[string][]byte{ + "1": []byte("data1"), + "12": []byte("data2"), + "123": []byte("data3"), + "124": []byte("data4"), + "2": []byte("data5"), + "23": []byte("data6"), + "234": []byte("data7"), + "235": []byte("data8"), + "3": []byte("data9"), + }, + owner: common.Hash{}, + expectedAccountLeaves: map[int64]int64{1: 1, 3: 4}, // "123"(3) + "124"(3) + "234"(3) + "235"(3) + "3"(1) + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + stats := NewWitnessStats() + stats.Add(tt.nodes, tt.owner) + + var expectedAccountTrieLeaves [16]int64 + for depth, count := range tt.expectedAccountLeaves { + expectedAccountTrieLeaves[depth] = count + } + var expectedStorageTrieLeaves [16]int64 + for depth, count := range tt.expectedStorageLeaves { + expectedStorageTrieLeaves[depth] = count + } + + // Check account trie depth + if stats.accountTrieLeaves != expectedAccountTrieLeaves { + t.Errorf("Account trie total depth = %v, want %v", stats.accountTrieLeaves, expectedAccountTrieLeaves) + } + + // Check storage trie depth + if stats.storageTrieLeaves != expectedStorageTrieLeaves { + t.Errorf("Storage trie total depth = %v, want %v", stats.storageTrieLeaves, expectedStorageTrieLeaves) + } + }) + } +} + +func TestWitnessStatsMinMax(t *testing.T) { + stats := NewWitnessStats() + + // Add some account trie nodes with varying depths + stats.Add(map[string][]byte{ + "a": []byte("data1"), + "ab": []byte("data2"), + "abc": []byte("data3"), + "abcd": []byte("data4"), + "abcde": []byte("data5"), + }, common.Hash{}) + + // Only "abcde" is a leaf (depth 5) + for i, v := range stats.accountTrieLeaves { + if v != 0 && i != 5 { + t.Errorf("leaf found at invalid depth %d", i) + } + } + + // Add more leaves with different depths + stats.Add(map[string][]byte{ + "x": []byte("data6"), + "yz": []byte("data7"), + }, common.Hash{}) + + // Now we have leaves at depths 1, 2, and 5 + for i, v := range stats.accountTrieLeaves { + if v != 0 && (i != 5 && i != 2 && i != 1) { + t.Errorf("leaf found at invalid depth %d", i) + } + } +} + +func TestWitnessStatsAverage(t *testing.T) { + stats := NewWitnessStats() + + // Add nodes that will create leaves at depths 2, 3, and 4 + stats.Add(map[string][]byte{ + "aa": []byte("data1"), + "bb": []byte("data2"), + "ccc": []byte("data3"), + "dddd": []byte("data4"), + }, common.Hash{}) + + // All are leaves: 2 + 2 + 3 + 4 = 11 total, 4 samples + expectedAvg := int64(11) / int64(4) + var actualAvg, totalSamples int64 + for i, c := range stats.accountTrieLeaves { + actualAvg += c * int64(i) + totalSamples += c + } + actualAvg = actualAvg / totalSamples + + if actualAvg != expectedAvg { + t.Errorf("Account trie average depth = %d, want %d", actualAvg, expectedAvg) + } +} + +func BenchmarkWitnessStatsAdd(b *testing.B) { + // Create a realistic trie node structure + nodes := make(map[string][]byte) + for i := 0; i < 100; i++ { + base := string(rune('a' + i%26)) + nodes[base] = []byte("data") + for j := 0; j < 9; j++ { + key := base + string(rune('0'+j)) + nodes[key] = []byte("data") + } + } + + stats := NewWitnessStats() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + stats.Add(nodes, common.Hash{}) + } +} diff --git a/core/stateless/witness.go b/core/stateless/witness.go index aecfad1d52..588c895a2f 100644 --- a/core/stateless/witness.go +++ b/core/stateless/witness.go @@ -58,7 +58,7 @@ func NewWitness(context *types.Header, chain HeaderReader) (*Witness, error) { } headers = append(headers, parent) } - // Create the wtness with a reconstructed gutted out block + // Create the witness with a reconstructed gutted out block return &Witness{ context: context, Headers: headers, @@ -88,14 +88,20 @@ func (w *Witness) AddCode(code []byte) { } // AddState inserts a batch of MPT trie nodes into the witness. -func (w *Witness) AddState(nodes map[string]struct{}) { +func (w *Witness) AddState(nodes map[string][]byte) { if len(nodes) == 0 { return } w.lock.Lock() defer w.lock.Unlock() - maps.Copy(w.State, nodes) + for _, value := range nodes { + w.State[string(value)] = struct{}{} + } +} + +func (w *Witness) AddKey() { + panic("not yet implemented") } // Copy deep-copies the witness object. Witness.Block isn't deep-copied as it diff --git a/core/tracing/CHANGELOG.md b/core/tracing/CHANGELOG.md index a14e123d99..a94fa81b55 100644 --- a/core/tracing/CHANGELOG.md +++ b/core/tracing/CHANGELOG.md @@ -4,6 +4,27 @@ All notable changes to the tracing interface will be documented in this file. ## [Unreleased] +### Deprecated methods + +- `OnCodeChange(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte)`: This hook is deprecated in favor of `OnCodeChangeV2` which includes a reason parameter ([#32525](https://github.com/ethereum/go-ethereum/pull/32525)). + +### New methods + +- `OnCodeChangeV2(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason CodeChangeReason)`: This hook is called when a code change occurs. It is a successor to `OnCodeChange` with an additional reason parameter ([#32525](https://github.com/ethereum/go-ethereum/pull/32525)). + +### New types + +- `CodeChangeReason` is a new type used to provide a reason for code changes. It includes various reasons such as contract creation, genesis initialization, EIP-7702 authorization, self-destruct, and revert operations ([#32525](https://github.com/ethereum/go-ethereum/pull/32525)). + +## [v1.15.4](https://github.com/ethereum/go-ethereum/releases/tag/v1.15.4) + +### Modified types + +- `GasChangeReason` has been extended with auto-generated String() methods for better debugging and logging ([#31234](https://github.com/ethereum/go-ethereum/pull/31234)). +- `NonceChangeReason` has been extended with auto-generated String() methods for better debugging and logging ([#31234](https://github.com/ethereum/go-ethereum/pull/31234)). + +## [v1.15.0](https://github.com/ethereum/go-ethereum/releases/tag/v1.15.0) + The tracing interface has been extended with backwards-compatible changes to support more use-cases and simplify tracer code. The most notable change is a state journaling library which emits reverse events when a call is reverted. ### Deprecated methods @@ -23,8 +44,13 @@ The tracing interface has been extended with backwards-compatible changes to sup ### Modified types -- `VMContext.StateDB` has been extended with `GetCodeHash(addr common.Address) common.Hash` method used to retrieve the code hash an account. +- `VMContext.StateDB` has been extended with the following method: + - `GetCodeHash(addr common.Address) common.Hash` method used to retrieve the code hash of an account. +- `BlockEvent` has been modified: + - The `TD` (Total Difficulty) field has been removed ([#30744](https://github.com/ethereum/go-ethereum/pull/30744)). - `BalanceChangeReason` has been extended with the `BalanceChangeRevert` reason. More on that below. +- `GasChangeReason` has been extended with the following reason: + - `GasChangeTxDataFloor` is the amount of extra gas the transaction has to pay to reach the minimum gas requirement for the transaction data. This change will always be a negative change. ### State journaling @@ -49,6 +75,26 @@ The state changes that are covered by the journaling library are: - `OnCodeChange` - `OnStorageChange` +## [v1.14.12](https://github.com/ethereum/go-ethereum/releases/tag/v1.14.12) + +This release contains a change in behavior for `OnCodeChange` hook and an extension to the StateDB interface. + +### Modified types + +- `VMContext.StateDB` has been extended with the following method: + - `GetTransientState(addr common.Address, slot common.Hash) common.Hash` method used to access contract transient storage ([#30531](https://github.com/ethereum/go-ethereum/pull/30531)). + +### `OnCodeChange` change + +The `OnCodeChange` hook is now called when the code of a contract is removed due to a selfdestruct. Previously, no code change was emitted on such occasions. + +## [v1.14.10](https://github.com/ethereum/go-ethereum/releases/tag/v1.14.10) + +### Modified types + +- `OpContext` has been extended with the following method: + - `ContractCode() []byte` provides access to the contract bytecode within the OpContext interface ([#30466](https://github.com/ethereum/go-ethereum/pull/30466)). + ## [v1.14.9](https://github.com/ethereum/go-ethereum/releases/tag/v1.14.9) ### Modified types @@ -56,13 +102,6 @@ The state changes that are covered by the journaling library are: - `GasChangeReason` has been extended with the following reasons which will be enabled only post-Verkle. There shouldn't be any gas changes with those reasons prior to the fork. - `GasChangeWitnessContractCollisionCheck` flags the event of adding to the witness when checking for contract address collision. -## [v1.14.12] - -This release contains a change in behavior for `OnCodeChange` hook. - -### `OnCodeChange` change - -The `OnCodeChange` hook is now called when the code of a contract is removed due to a selfdestruct. Previously, no code change was emitted on such occasions. ## [v1.14.4] @@ -148,7 +187,12 @@ The hooks `CaptureStart` and `CaptureEnd` have been removed. These hooks signale - `CaptureState` -> `OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error)`. `op` is of type `byte` which can be cast to `vm.OpCode` when necessary. A `*vm.ScopeContext` is not passed anymore. It is replaced by `tracing.OpContext` which offers access to the memory, stack and current contract. - `CaptureFault` -> `OnFault(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, depth int, err error)`. Similar to above. -[unreleased]: https://github.com/ethereum/go-ethereum/compare/v1.14.8...master -[v1.14.0]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.0 -[v1.14.3]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.3 +[unreleased]: https://github.com/ethereum/go-ethereum/compare/v1.16.3...master +[v1.15.4]: https://github.com/ethereum/go-ethereum/releases/tag/v1.15.4 +[v1.15.0]: https://github.com/ethereum/go-ethereum/releases/tag/v1.15.0 +[v1.14.12]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.12 +[v1.14.10]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.10 +[v1.14.9]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.9 [v1.14.4]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.4 +[v1.14.3]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.3 +[v1.14.0]: https://github.com/ethereum/go-ethereum/releases/tag/v1.14.0 diff --git a/core/tracing/gen_code_change_reason_stringer.go b/core/tracing/gen_code_change_reason_stringer.go new file mode 100644 index 0000000000..9372954063 --- /dev/null +++ b/core/tracing/gen_code_change_reason_stringer.go @@ -0,0 +1,29 @@ +// Code generated by "stringer -type=CodeChangeReason -trimprefix=CodeChange -output gen_code_change_reason_stringer.go"; DO NOT EDIT. + +package tracing + +import "strconv" + +func _() { + // An "invalid array index" compiler error signifies that the constant values have changed. + // Re-run the stringer command to generate them again. + var x [1]struct{} + _ = x[CodeChangeUnspecified-0] + _ = x[CodeChangeContractCreation-1] + _ = x[CodeChangeGenesis-2] + _ = x[CodeChangeAuthorization-3] + _ = x[CodeChangeAuthorizationClear-4] + _ = x[CodeChangeSelfDestruct-5] + _ = x[CodeChangeRevert-6] +} + +const _CodeChangeReason_name = "UnspecifiedContractCreationGenesisAuthorizationAuthorizationClearSelfDestructRevert" + +var _CodeChangeReason_index = [...]uint8{0, 11, 27, 34, 47, 65, 77, 83} + +func (i CodeChangeReason) String() string { + if i >= CodeChangeReason(len(_CodeChangeReason_index)-1) { + return "CodeChangeReason(" + strconv.FormatInt(int64(i), 10) + ")" + } + return _CodeChangeReason_name[_CodeChangeReason_index[i]:_CodeChangeReason_index[i+1]] +} diff --git a/core/tracing/gen_nonce_change_reason_stringer.go b/core/tracing/gen_nonce_change_reason_stringer.go index f775c1f3a6..cd19200db8 100644 --- a/core/tracing/gen_nonce_change_reason_stringer.go +++ b/core/tracing/gen_nonce_change_reason_stringer.go @@ -15,11 +15,12 @@ func _() { _ = x[NonceChangeNewContract-4] _ = x[NonceChangeAuthorization-5] _ = x[NonceChangeRevert-6] + _ = x[NonceChangeSelfdestruct-7] } -const _NonceChangeReason_name = "UnspecifiedGenesisEoACallContractCreatorNewContractAuthorizationRevert" +const _NonceChangeReason_name = "UnspecifiedGenesisEoACallContractCreatorNewContractAuthorizationRevertSelfdestruct" -var _NonceChangeReason_index = [...]uint8{0, 11, 18, 25, 40, 51, 64, 70} +var _NonceChangeReason_index = [...]uint8{0, 11, 18, 25, 40, 51, 64, 70, 82} func (i NonceChangeReason) String() string { if i >= NonceChangeReason(len(_NonceChangeReason_index)-1) { diff --git a/core/tracing/hooks.go b/core/tracing/hooks.go index 0485f7a3eb..c85abe6482 100644 --- a/core/tracing/hooks.go +++ b/core/tracing/hooks.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie/trienode" "github.com/holiman/uint256" ) @@ -75,6 +76,56 @@ type BlockEvent struct { Safe *types.Header } +// StateUpdate represents the state mutations resulting from block execution. +// It provides access to account changes, storage changes, and contract code +// deployments with both previous and new values. +type StateUpdate struct { + OriginRoot common.Hash // State root before the update + Root common.Hash // State root after the update + BlockNumber uint64 + + // AccountChanges contains all account state changes keyed by address. + AccountChanges map[common.Address]*AccountChange + + // StorageChanges contains all storage slot changes keyed by address and storage slot key. + StorageChanges map[common.Address]map[common.Hash]*StorageChange + + // CodeChanges contains all contract code changes keyed by address. + CodeChanges map[common.Address]*CodeChange + + // TrieChanges contains trie node mutations keyed by address hash and trie node path. + TrieChanges map[common.Hash]map[string]*TrieNodeChange +} + +// AccountChange represents a change to an account's state. +type AccountChange struct { + Prev *types.StateAccount // nil if account was created + New *types.StateAccount // nil if account was deleted +} + +// StorageChange represents a change to a storage slot. +type StorageChange struct { + Prev common.Hash // previous value (zero if slot was created) + New common.Hash // new value (zero if slot was deleted) +} + +type ContractCode struct { + Hash common.Hash + Code []byte + Exists bool // true if the code was existent +} + +// CodeChange represents a change in contract code of an account. +type CodeChange struct { + Prev *ContractCode // nil if no code existed before + New *ContractCode +} + +type TrieNodeChange struct { + Prev *trienode.Node + New *trienode.Node +} + type ( /* - VM events - @@ -161,6 +212,11 @@ type ( // beacon block root. OnSystemCallEndHook = func() + // StateUpdateHook is called after state is committed for a block. + // It provides access to the complete state mutations including account changes, + // storage changes, trie node mutations, and contract code deployments. + StateUpdateHook = func(update *StateUpdate) + /* - State events - */ @@ -177,6 +233,9 @@ type ( // CodeChangeHook is called when the code of an account changes. CodeChangeHook = func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte) + // CodeChangeHookV2 is called when the code of an account changes. + CodeChangeHookV2 = func(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason CodeChangeReason) + // StorageChangeHook is called when the storage of an account changes. StorageChangeHook = func(addr common.Address, slot common.Hash, prev, new common.Hash) @@ -206,11 +265,13 @@ type Hooks struct { OnSystemCallStart OnSystemCallStartHook OnSystemCallStartV2 OnSystemCallStartHookV2 OnSystemCallEnd OnSystemCallEndHook + OnStateUpdate StateUpdateHook // State events OnBalanceChange BalanceChangeHook OnNonceChange NonceChangeHook OnNonceChangeV2 NonceChangeHookV2 OnCodeChange CodeChangeHook + OnCodeChangeV2 CodeChangeHookV2 OnStorageChange StorageChangeHook OnLog LogHook // Block hash read @@ -371,4 +432,35 @@ const ( // NonceChangeRevert is emitted when the nonce is reverted back to a previous value due to call failure. // It is only emitted when the tracer has opted in to use the journaling wrapper (WrapWithJournal). NonceChangeRevert NonceChangeReason = 6 + + // NonceChangeSelfdestruct is emitted when the nonce is reset to zero due to a self-destruct + NonceChangeSelfdestruct NonceChangeReason = 7 +) + +// CodeChangeReason is used to indicate the reason for a code change. +type CodeChangeReason byte + +//go:generate go run golang.org/x/tools/cmd/stringer -type=CodeChangeReason -trimprefix=CodeChange -output gen_code_change_reason_stringer.go + +const ( + CodeChangeUnspecified CodeChangeReason = 0 + + // CodeChangeContractCreation is when a new contract is deployed via CREATE/CREATE2 operations. + CodeChangeContractCreation CodeChangeReason = 1 + + // CodeChangeGenesis is when contract code is set during blockchain genesis or initial setup. + CodeChangeGenesis CodeChangeReason = 2 + + // CodeChangeAuthorization is when code is set via EIP-7702 Set Code Authorization. + CodeChangeAuthorization CodeChangeReason = 3 + + // CodeChangeAuthorizationClear is when EIP-7702 delegation is cleared by setting to zero address. + CodeChangeAuthorizationClear CodeChangeReason = 4 + + // CodeChangeSelfDestruct is when contract code is cleared due to self-destruct. + CodeChangeSelfDestruct CodeChangeReason = 5 + + // CodeChangeRevert is emitted when the code is reverted back to a previous value due to call failure. + // It is only emitted when the tracer has opted in to use the journaling wrapper (WrapWithJournal). + CodeChangeRevert CodeChangeReason = 6 ) diff --git a/core/tracing/journal.go b/core/tracing/journal.go index a402f1ac09..62a70d6c27 100644 --- a/core/tracing/journal.go +++ b/core/tracing/journal.go @@ -42,12 +42,15 @@ func WrapWithJournal(hooks *Hooks) (*Hooks, error) { return nil, errors.New("wrapping nil tracer") } // No state change to journal, return the wrapped hooks as is - if hooks.OnBalanceChange == nil && hooks.OnNonceChange == nil && hooks.OnNonceChangeV2 == nil && hooks.OnCodeChange == nil && hooks.OnStorageChange == nil { + if hooks.OnBalanceChange == nil && hooks.OnNonceChange == nil && hooks.OnNonceChangeV2 == nil && hooks.OnCodeChange == nil && hooks.OnCodeChangeV2 == nil && hooks.OnStorageChange == nil { return hooks, nil } if hooks.OnNonceChange != nil && hooks.OnNonceChangeV2 != nil { return nil, errors.New("cannot have both OnNonceChange and OnNonceChangeV2") } + if hooks.OnCodeChange != nil && hooks.OnCodeChangeV2 != nil { + return nil, errors.New("cannot have both OnCodeChange and OnCodeChangeV2") + } // Create a new Hooks instance and copy all hooks wrapped := *hooks @@ -72,6 +75,9 @@ func WrapWithJournal(hooks *Hooks) (*Hooks, error) { if hooks.OnCodeChange != nil { wrapped.OnCodeChange = j.OnCodeChange } + if hooks.OnCodeChangeV2 != nil { + wrapped.OnCodeChangeV2 = j.OnCodeChangeV2 + } if hooks.OnStorageChange != nil { wrapped.OnStorageChange = j.OnStorageChange } @@ -174,6 +180,19 @@ func (j *journal) OnCodeChange(addr common.Address, prevCodeHash common.Hash, pr } } +func (j *journal) OnCodeChangeV2(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason CodeChangeReason) { + j.entries = append(j.entries, codeChange{ + addr: addr, + prevCodeHash: prevCodeHash, + prevCode: prevCode, + newCodeHash: codeHash, + newCode: code, + }) + if j.hooks.OnCodeChangeV2 != nil { + j.hooks.OnCodeChangeV2(addr, prevCodeHash, prevCode, codeHash, code, reason) + } +} + func (j *journal) OnStorageChange(addr common.Address, slot common.Hash, prev, new common.Hash) { j.entries = append(j.entries, storageChange{addr: addr, slot: slot, prev: prev, new: new}) if j.hooks.OnStorageChange != nil { @@ -225,7 +244,9 @@ func (n nonceChange) revert(hooks *Hooks) { } func (c codeChange) revert(hooks *Hooks) { - if hooks.OnCodeChange != nil { + if hooks.OnCodeChangeV2 != nil { + hooks.OnCodeChangeV2(c.addr, c.newCodeHash, c.newCode, c.prevCodeHash, c.prevCode, CodeChangeRevert) + } else if hooks.OnCodeChange != nil { hooks.OnCodeChange(c.addr, c.newCodeHash, c.newCode, c.prevCodeHash, c.prevCode) } } diff --git a/core/tracing/journal_test.go b/core/tracing/journal_test.go index 99447e1e1d..e00447f5f3 100644 --- a/core/tracing/journal_test.go +++ b/core/tracing/journal_test.go @@ -23,6 +23,7 @@ import ( "testing" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" ) type testTracer struct { @@ -56,6 +57,11 @@ func (t *testTracer) OnCodeChange(addr common.Address, prevCodeHash common.Hash, t.code = code } +func (t *testTracer) OnCodeChangeV2(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason CodeChangeReason) { + t.t.Logf("OnCodeChangeV2(%v, %v -> %v, %v)", addr, prevCodeHash, codeHash, reason) + t.code = code +} + func (t *testTracer) OnStorageChange(addr common.Address, slot common.Hash, prev common.Hash, new common.Hash) { t.t.Logf("OnStorageCodeChange(%v, %v, %v -> %v)", addr, slot, prev, new) if t.storage == nil { @@ -232,6 +238,27 @@ func TestOnNonceChangeV2(t *testing.T) { } } +func TestOnCodeChangeV2(t *testing.T) { + tr := &testTracer{t: t} + wr, err := WrapWithJournal(&Hooks{OnCodeChangeV2: tr.OnCodeChangeV2}) + if err != nil { + t.Fatalf("failed to wrap test tracer: %v", err) + } + + addr := common.HexToAddress("0x1234") + code := []byte{1, 2, 3} + { + wr.OnEnter(2, 0, addr, addr, nil, 1000, big.NewInt(0)) + wr.OnCodeChangeV2(addr, common.Hash{}, nil, crypto.Keccak256Hash(code), code, CodeChangeContractCreation) + wr.OnExit(2, nil, 100, nil, true) + } + + // After revert, code should be nil + if tr.code != nil { + t.Fatalf("unexpected code after revert: %v", tr.code) + } +} + func TestAllHooksCalled(t *testing.T) { tracer := newTracerAllHooks() hooks := tracer.hooks() @@ -253,10 +280,6 @@ func TestAllHooksCalled(t *testing.T) { if field.Type.Kind() != reflect.Func { continue } - // Skip non-hooks, i.e. Copy - if field.Name == "copy" { - continue - } // Skip if field is not set if wrappedValue.Field(i).IsNil() { continue @@ -298,6 +321,7 @@ func newTracerAllHooks() *tracerAllHooks { t.hooksCalled[hooksType.Field(i).Name] = false } delete(t.hooksCalled, "OnNonceChange") + delete(t.hooksCalled, "OnCodeChange") return t } @@ -322,7 +346,7 @@ func (t *tracerAllHooks) hooks() *Hooks { hooksValue := reflect.ValueOf(h).Elem() for i := 0; i < hooksValue.NumField(); i++ { field := hooksValue.Type().Field(i) - if field.Name == "OnNonceChange" { + if field.Name == "OnNonceChange" || field.Name == "OnCodeChange" { continue } hookMethod := reflect.MakeFunc(field.Type, func(args []reflect.Value) []reflect.Value { diff --git a/core/txpool/blobpool/blobpool.go b/core/txpool/blobpool/blobpool.go index 81a18e5ac3..90903abbd7 100644 --- a/core/txpool/blobpool/blobpool.go +++ b/core/txpool/blobpool/blobpool.go @@ -28,6 +28,7 @@ import ( "path/filepath" "sort" "sync" + "sync/atomic" "time" "github.com/ethereum/go-ethereum/common" @@ -56,11 +57,17 @@ const ( // tiny overflows causing all txs to move a shelf higher, wasting disk space. txAvgSize = 4 * 1024 - // txMaxSize is the maximum size a single transaction can have, outside - // the included blobs. Since blob transactions are pulled instead of pushed, - // and only a small metadata is kept in ram, the rest is on disk, there is - // no critical limit that should be enforced. Still, capping it to some sane - // limit can never hurt. + // txBlobOverhead is an approximation of the overhead that an additional blob + // has on transaction size. This is added to the slotter to avoid tiny + // overflows causing all txs to move a shelf higher, wasting disk space. A + // small buffer is added to the proof overhead. + txBlobOverhead = uint32(kzg4844.CellProofsPerBlob*len(kzg4844.Proof{}) + 64) + + // txMaxSize is the maximum size a single transaction can have, including the + // blobs. Since blob transactions are pulled instead of pushed, and only a + // small metadata is kept in ram, the rest is on disk, there is no critical + // limit that should be enforced. Still, capping it to some sane limit can + // never hurt, which is aligned with maxBlobsPerTx constraint enforced internally. txMaxSize = 1024 * 1024 // maxBlobsPerTx is the maximum number of blobs that a single transaction can @@ -84,6 +91,20 @@ const ( // limboedTransactionStore is the subfolder containing the currently included // but not yet finalized transaction blobs. limboedTransactionStore = "limbo" + + // storeVersion is the current slotter layout used for the billy.Database + // store. + storeVersion = 1 + + // gappedLifetime is the approximate duration for which nonce-gapped transactions + // are kept before being dropped. Since gapped is only a reorder buffer and it + // is expected that the original transactions were inserted in the mempool in + // nonce order, the duration is kept short to avoid DoS vectors. + gappedLifetime = 1 * time.Minute + + // maxGappedTxs is the maximum number of gapped transactions kept overall. + // This is a safety limit to avoid DoS vectors. + maxGapped = 128 ) // blobTxMeta is the minimal subset of types.BlobTx necessary to validate and @@ -93,6 +114,7 @@ const ( type blobTxMeta struct { hash common.Hash // Transaction hash to maintain the lookup table vhashes []common.Hash // Blob versioned hashes to maintain the lookup table + version byte // Blob transaction version to determine proof type id uint64 // Storage ID in the pool's persistent store storageSize uint32 // Byte size in the pool's persistent store @@ -117,6 +139,7 @@ type blobTxMeta struct { type blobTxMetaMarshal struct { Hash common.Hash Vhashes []common.Hash + Version byte ID uint64 StorageSize uint32 @@ -136,6 +159,7 @@ func (b *blobTxMeta) EncodeRLP(w io.Writer) error { return rlp.Encode(w, &blobTxMetaMarshal{ Hash: b.hash, Vhashes: b.vhashes, + Version: b.version, ID: b.id, StorageSize: b.storageSize, Size: b.size, @@ -157,6 +181,7 @@ func (b *blobTxMeta) DecodeRLP(s *rlp.Stream) error { } b.hash = meta.Hash b.vhashes = meta.Vhashes + b.version = meta.Version b.id = meta.ID b.storageSize = meta.StorageSize b.size = meta.Size @@ -174,10 +199,16 @@ func (b *blobTxMeta) DecodeRLP(s *rlp.Stream) error { // newBlobTxMeta retrieves the indexed metadata fields from a blob transaction // and assembles a helper struct to track in memory. +// Requires the transaction to have a sidecar (or that we introduce a special version tag for no-sidecar). func newBlobTxMeta(id uint64, size uint64, storageSize uint32, tx *types.Transaction) *blobTxMeta { + if tx.BlobTxSidecar() == nil { + // This should never happen, as the pool only admits blob transactions with a sidecar + panic("missing blob tx sidecar") + } meta := &blobTxMeta{ hash: tx.Hash(), vhashes: tx.BlobHashes(), + version: tx.BlobTxSidecar().Version, id: id, storageSize: storageSize, size: size, @@ -371,12 +402,15 @@ type BlobPool struct { stored uint64 // Useful data size of all transactions on disk limbo *limbo // Persistent data store for the non-finalized blobs + gapped map[common.Address][]*types.Transaction // Transactions that are currently gapped (nonce too high) + gappedSource map[common.Hash]common.Address // Source of gapped transactions to allow rechecking on inclusion + signer types.Signer // Transaction signer to use for sender recovery chain BlockChain // Chain object to access the state through - head *types.Header // Current head of the chain - state *state.StateDB // Current state at the head of the chain - gasTip *uint256.Int // Currently accepted minimum gas tip + head atomic.Pointer[types.Header] // Current head of the chain + state *state.StateDB // Current state at the head of the chain + gasTip atomic.Pointer[uint256.Int] // Currently accepted minimum gas tip lookup *lookup // Lookup table mapping blobs to txs and txs to billy entries index map[common.Address][]*blobTxMeta // Blob transactions grouped by accounts, sorted by nonce @@ -404,12 +438,19 @@ func New(config Config, chain BlockChain, hasPendingAuth func(common.Address) bo lookup: newLookup(), index: make(map[common.Address][]*blobTxMeta), spent: make(map[common.Address]*uint256.Int), + gapped: make(map[common.Address][]*types.Transaction), + gappedSource: make(map[common.Hash]common.Address), } } // Filter returns whether the given transaction can be consumed by the blob pool. func (p *BlobPool) Filter(tx *types.Transaction) bool { - return tx.Type() == types.BlobTxType + return p.FilterType(tx.Type()) +} + +// FilterType returns whether the blob pool supports the given transaction type. +func (p *BlobPool) FilterType(kind byte) bool { + return kind == types.BlobTxType } // Init sets the gas price needed to keep a transaction in the pool and the chain @@ -432,16 +473,6 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reser return err } } - - // Pool initialized, attach the blob limbo to it to track blobs included - // recently but not yet finalized - limbo, err := newLimbo(limbodir, eip4844.LatestMaxBlobsPerBlock(p.chain.Config())) - if err != nil { - p.Close() - return err - } - p.limbo = limbo - // Initialize the state with head block, or fallback to empty one in // case the head state is not available (might occur when node is not // fully synced). @@ -452,8 +483,17 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reser if err != nil { return err } - p.head, p.state = head, state + p.head.Store(head) + p.state = state + // Create new slotter for pre-Osaka blob configuration. + slotter := newSlotter(params.BlobTxMaxBlobs) + + // See if we need to migrate the queue blob store after fusaka + slotter, err = tryMigrate(p.chain.Config(), slotter, queuedir) + if err != nil { + return err + } // Index all transactions on disk and delete anything unprocessable var fails []uint64 index := func(id uint64, size uint32, blob []byte) { @@ -461,18 +501,12 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reser fails = append(fails, id) } } - slotter := newSlotter(eip4844.LatestMaxBlobsPerBlock(p.chain.Config())) store, err := billy.Open(billy.Options{Path: queuedir, Repair: true}, slotter, index) if err != nil { return err } p.store = store - // If still exit blob txs in limbo, delete the old reset a new one without tx content. - if err = p.limbo.setTxMeta(p.store); err != nil { - return err - } - if len(fails) > 0 { log.Warn("Dropping invalidated blob transactions", "ids", fails) dropInvalidMeter.Mark(int64(len(fails))) @@ -490,13 +524,27 @@ func (p *BlobPool) Init(gasTip uint64, head *types.Header, reserver txpool.Reser p.recheck(addr, nil) } var ( - basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head)) + basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), head)) blobfee = uint256.NewInt(params.BlobTxMinBlobGasprice) ) - if p.head.ExcessBlobGas != nil { - blobfee = uint256.MustFromBig(eip4844.CalcBlobFee(p.chain.Config(), p.head)) + if head.ExcessBlobGas != nil { + blobfee = uint256.MustFromBig(eip4844.CalcBlobFee(p.chain.Config(), head)) } p.evict = newPriceHeap(basefee, blobfee, p.index) + + // Pool initialized, attach the blob limbo to it to track blobs included + // recently but not yet finalized + p.limbo, err = newLimbo(p.chain.Config(), limbodir) + if err != nil { + p.Close() + return err + } + + // If still exit blob txs in limbo, delete the old reset a new one without tx content. + if err = p.limbo.setTxMeta(p.store); err != nil { + return err + } + // Set the configured gas tip, triggering a filtering of anything just loaded basefeeGauge.Update(int64(basefee.Uint64())) blobfeeGauge.Update(int64(blobfee.Uint64())) @@ -552,12 +600,6 @@ func (p *BlobPool) parseTransaction(id uint64, size uint32, blob []byte) error { } meta := newBlobTxMeta(id, tx.Size(), size, tx) - - // If the tx metadata is already in limbo, we don't need to add it to the pool. - if p.limbo.existsAndSet(meta) { - return nil - } - if p.lookup.exists(meta.hash) { // This path is only possible after a crash, where deleted items are not // removed via the normal shutdown-startup procedure and thus may get @@ -619,11 +661,9 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 p.stored -= uint64(txs[i].storageSize) p.lookup.untrack(txs[i]) + // Included transactions blobs need to be moved to the limbo if filled && inclusions != nil { - // If the tx metadata is recorded by limbo, keep the tx in the db. - if p.offload(addr, txs[i], inclusions) { - ids = ids[:len(ids)-1] - } + p.offload(addr, txs[i], inclusions) } } delete(p.index, addr) @@ -664,10 +704,7 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 // Included transactions blobs need to be moved to the limbo if inclusions != nil { - // If the tx metadata is recorded by limbo, keep the tx in the db. - if p.offload(addr, txs[0], inclusions) { - ids = ids[:len(ids)-1] - } + p.offload(addr, txs[0], inclusions) } txs = txs[1:] } @@ -846,18 +883,16 @@ func (p *BlobPool) recheck(addr common.Address, inclusions map[common.Hash]uint6 // any of it since there's no clear error case. Some errors may be due to coding // issues, others caused by signers mining MEV stuff or swapping transactions. In // all cases, the pool needs to continue operating. -// Return bool type to let caller know whether the tx is offloaded to limbo successfully. -func (p *BlobPool) offload(addr common.Address, meta *blobTxMeta, inclusions map[common.Hash]uint64) bool { +func (p *BlobPool) offload(addr common.Address, meta *blobTxMeta, inclusions map[common.Hash]uint64) { block, ok := inclusions[meta.hash] if !ok { log.Warn("Blob transaction swapped out by signer", "from", addr, "nonce", meta.nonce, "id", meta.id) - return false + return } if err := p.limbo.push(meta, block); err != nil { log.Warn("Failed to offload blob tx into limbo", "err", err) - return false + return } - return true } // Reset implements txpool.SubPool, allowing the blob pool's internal state to be @@ -872,12 +907,15 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) { resettimeHist.Update(time.Since(start).Nanoseconds()) }(time.Now()) + // Handle reorg buffer timeouts evicting old gapped transactions + p.evictGapped() + statedb, err := p.chain.StateAt(newHead.Root) if err != nil { log.Error("Failed to reset blobpool state", "err", err) return } - p.head = newHead + p.head.Store(newHead) p.state = statedb // Run the reorg between the old and new head and figure out which accounts @@ -900,7 +938,8 @@ func (p *BlobPool) Reset(oldHead, newHead *types.Header) { } } // Flush out any blobs from limbo that are older than the latest finality - if p.chain.Config().IsCancun(p.head.Number, p.head.Time) { + if p.chain.Config().IsCancun(newHead.Number, newHead.Time) { + // Delete all limboed transactions up to the finalized block. p.limbo.finalize(p.chain.CurrentFinalBlock(), func(id uint64, txHash common.Hash) { if err := p.store.Delete(id); err != nil { log.Error("Failed to delete blob transaction", "hash", txHash, "id", id, "err", err) @@ -1088,14 +1127,15 @@ func (p *BlobPool) SetGasTip(tip *big.Int) { defer p.lock.Unlock() // Store the new minimum gas tip - old := p.gasTip - p.gasTip = uint256.MustFromBig(tip) + old := p.gasTip.Load() + newTip := uint256.MustFromBig(tip) + p.gasTip.Store(newTip) // If the min miner fee increased, remove transactions below the new threshold - if old == nil || p.gasTip.Cmp(old) > 0 { + if old == nil || newTip.Cmp(old) > 0 { for addr, txs := range p.index { for i, tx := range txs { - if tx.execTipCap.Cmp(p.gasTip) < 0 { + if tx.execTipCap.Cmp(newTip) < 0 { // Drop the offending transaction var ( ids = []uint64{tx.id} @@ -1155,10 +1195,10 @@ func (p *BlobPool) ValidateTxBasics(tx *types.Transaction) error { Config: p.chain.Config(), Accept: 1 << types.BlobTxType, MaxSize: txMaxSize, - MinTip: p.gasTip.ToBig(), + MinTip: p.gasTip.Load().ToBig(), MaxBlobCount: maxBlobsPerTx, } - return txpool.ValidateTransaction(tx, p.head, p.signer, opts) + return txpool.ValidateTransaction(tx, p.head.Load(), p.signer, opts) } // checkDelegationLimit determines if the tx sender is delegated or has a @@ -1196,16 +1236,18 @@ func (p *BlobPool) checkDelegationLimit(tx *types.Transaction) error { // validateTx checks whether a transaction is valid according to the consensus // rules and adheres to some heuristic limits of the local node (price and size). +// +// This function assumes the static validation has been performed already and +// only runs the stateful checks with lock protection. func (p *BlobPool) validateTx(tx *types.Transaction) error { - if err := p.ValidateTxBasics(tx); err != nil { - return err - } // Ensure the transaction adheres to the stateful pool filters (nonce, balance) stateOpts := &txpool.ValidationOptionsWithState{ State: p.state, FirstNonceGap: func(addr common.Address) uint64 { - // Nonce gaps are not permitted in the blob pool, the first gap will + // Nonce gaps are permitted in the blob pool, but only as part of the + // in-memory 'gapped' buffer. We expose the gap here to validateTx, + // then handle the error by adding to the buffer. The first gap will // be the next nonce shifted by however many transactions we already // have pooled. return p.state.GetNonce(addr) + uint64(len(p.index[addr])) @@ -1284,7 +1326,9 @@ func (p *BlobPool) Has(hash common.Hash) bool { p.lock.RLock() defer p.lock.RUnlock() - return p.lookup.exists(hash) + poolHas := p.lookup.exists(hash) + _, gapped := p.gappedSource[hash] + return poolHas || gapped } func (p *BlobPool) getRLP(hash common.Hash) []byte { @@ -1354,8 +1398,19 @@ func (p *BlobPool) GetMetadata(hash common.Hash) *txpool.TxMetadata { } // GetBlobs returns a number of blobs and proofs for the given versioned hashes. +// Blobpool must place responses in the order given in the request, using null +// for any missing blobs. +// +// For instance, if the request is [A_versioned_hash, B_versioned_hash, +// C_versioned_hash] and blobpool has data for blobs A and C, but doesn't have +// data for B, the response MUST be [A, null, C]. +// // This is a utility method for the engine API, enabling consensus clients to // retrieve blobs from the pools directly instead of the network. +// +// The version argument specifies the type of proofs to return, either the +// blob proofs (version 0) or the cell proofs (version 1). Proofs conversion is +// CPU intensive and prohibited in the blobpool explicitly. func (p *BlobPool) GetBlobs(vhashes []common.Hash, version byte) ([]*kzg4844.Blob, []kzg4844.Commitment, [][]kzg4844.Proof, error) { var ( blobs = make([]*kzg4844.Blob, len(vhashes)) @@ -1368,31 +1423,36 @@ func (p *BlobPool) GetBlobs(vhashes []common.Hash, version byte) ([]*kzg4844.Blo for i, h := range vhashes { indices[h] = append(indices[h], i) } + for _, vhash := range vhashes { - // Skip duplicate vhash that was already resolved in a previous iteration if _, ok := filled[vhash]; ok { + // Skip vhash that was already resolved in a previous iteration continue } - // Retrieve the corresponding blob tx with the vhash + + // Retrieve the corresponding blob tx with the vhash. p.lock.RLock() txID, exists := p.lookup.storeidOfBlob(vhash) p.lock.RUnlock() if !exists { - return nil, nil, nil, fmt.Errorf("blob with vhash %x is not found", vhash) + continue } data, err := p.store.Get(txID) if err != nil { - return nil, nil, nil, err + log.Error("Tracked blob transaction missing from store", "id", txID, "err", err) + continue } // Decode the blob transaction tx := new(types.Transaction) if err := rlp.DecodeBytes(data, tx); err != nil { - return nil, nil, nil, err + log.Error("Blobs corrupted for traced transaction", "id", txID, "err", err) + continue } sidecar := tx.BlobTxSidecar() if sidecar == nil { - return nil, nil, nil, fmt.Errorf("blob tx without sidecar %x", tx.Hash()) + log.Error("Blob tx without sidecar", "hash", tx.Hash(), "id", txID) + continue } // Traverse the blobs in the transaction for i, hash := range tx.BlobHashes() { @@ -1400,39 +1460,30 @@ func (p *BlobPool) GetBlobs(vhashes []common.Hash, version byte) ([]*kzg4844.Blo if !ok { continue // non-interesting blob } + // Mark hash as seen. + filled[hash] = struct{}{} + if sidecar.Version != version { + // Skip blobs with incompatible version. Note we still track the blob hash + // in `filled` here, ensuring that we do not resolve this tx another time. + continue + } + // Get or convert the proof. var pf []kzg4844.Proof switch version { case types.BlobSidecarVersion0: - if sidecar.Version == types.BlobSidecarVersion0 { - pf = []kzg4844.Proof{sidecar.Proofs[i]} - } else { - proof, err := kzg4844.ComputeBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i]) - if err != nil { - return nil, nil, nil, err - } - pf = []kzg4844.Proof{proof} - } + pf = []kzg4844.Proof{sidecar.Proofs[i]} case types.BlobSidecarVersion1: - if sidecar.Version == types.BlobSidecarVersion0 { - cellProofs, err := kzg4844.ComputeCellProofs(&sidecar.Blobs[i]) - if err != nil { - return nil, nil, nil, err - } - pf = cellProofs - } else { - cellProofs, err := sidecar.CellProofsAt(i) - if err != nil { - return nil, nil, nil, err - } - pf = cellProofs + cellProofs, err := sidecar.CellProofsAt(i) + if err != nil { + return nil, nil, nil, err } + pf = cellProofs } for _, index := range list { blobs[index] = &sidecar.Blobs[i] commitments[index] = sidecar.Commitments[i] proofs[index] = pf } - filled[hash] = struct{}{} } } return blobs, commitments, proofs, nil @@ -1455,24 +1506,19 @@ func (p *BlobPool) AvailableBlobs(vhashes []common.Hash) int { // Add inserts a set of blob transactions into the pool if they pass validation (both // consensus validity and pool restrictions). -// -// Note, if sync is set the method will block until all internal maintenance -// related to the add is finished. Only use this during tests for determinism. func (p *BlobPool) Add(txs []*types.Transaction, sync bool) []error { var ( - adds = make([]*types.Transaction, 0, len(txs)) errs = make([]error, len(txs)) + adds = make([]*types.Transaction, 0, len(txs)) ) for i, tx := range txs { - errs[i] = p.add(tx) - if errs[i] == nil { + if errs[i] = p.ValidateTxBasics(tx); errs[i] != nil { + continue + } + if errs[i] = p.add(tx); errs[i] == nil { adds = append(adds, tx.WithoutBlobTxSidecar()) } } - if len(adds) > 0 { - p.discoverFeed.Send(core.NewTxsEvent{Txs: adds}) - p.insertFeed.Send(core.NewTxsEvent{Txs: adds}) - } return errs } @@ -1491,6 +1537,13 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { addtimeHist.Update(time.Since(start).Nanoseconds()) }(time.Now()) + return p.addLocked(tx, true) +} + +// addLocked inserts a new blob transaction into the pool if it passes validation (both +// consensus validity and pool restrictions). It must be called with the pool lock held. +// Only for internal use. +func (p *BlobPool) addLocked(tx *types.Transaction, checkGapped bool) (err error) { // Ensure the transaction is valid from all perspectives if err := p.validateTx(tx); err != nil { log.Trace("Transaction validation failed", "hash", tx.Hash(), "err", err) @@ -1503,6 +1556,21 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { addStaleMeter.Mark(1) case errors.Is(err, core.ErrNonceTooHigh): addGappedMeter.Mark(1) + // Store the tx in memory, and revalidate later + from, _ := types.Sender(p.signer, tx) + allowance := p.gappedAllowance(from) + if allowance >= 1 && len(p.gapped) < maxGapped { + p.gapped[from] = append(p.gapped[from], tx) + p.gappedSource[tx.Hash()] = from + log.Trace("added tx to gapped blob queue", "allowance", allowance, "hash", tx.Hash(), "from", from, "nonce", tx.Nonce(), "qlen", len(p.gapped[from])) + return nil + } else { + // if maxGapped is reached, it is better to give time to gapped + // transactions by keeping the old and dropping this one. + // Thus replacing a gapped transaction with another gapped transaction + // is discouraged. + log.Trace("no gapped blob queue allowance", "allowance", allowance, "hash", tx.Hash(), "from", from, "nonce", tx.Nonce(), "qlen", len(p.gapped[from])) + } case errors.Is(err, core.ErrInsufficientFunds): addOverdraftedMeter.Mark(1) case errors.Is(err, txpool.ErrAccountLimitExceeded): @@ -1640,6 +1708,58 @@ func (p *BlobPool) add(tx *types.Transaction) (err error) { p.updateStorageMetrics() addValidMeter.Mark(1) + + // Notify all listeners of the new arrival + p.discoverFeed.Send(core.NewTxsEvent{Txs: []*types.Transaction{tx.WithoutBlobTxSidecar()}}) + p.insertFeed.Send(core.NewTxsEvent{Txs: []*types.Transaction{tx.WithoutBlobTxSidecar()}}) + + //check the gapped queue for this account and try to promote + if gtxs, ok := p.gapped[from]; checkGapped && ok && len(gtxs) > 0 { + // We have to add in nonce order, but we want to stable sort to cater for situations + // where transactions are replaced, keeping the original receive order for same nonce + sort.SliceStable(gtxs, func(i, j int) bool { + return gtxs[i].Nonce() < gtxs[j].Nonce() + }) + for len(gtxs) > 0 { + stateNonce := p.state.GetNonce(from) + firstgap := stateNonce + uint64(len(p.index[from])) + + if gtxs[0].Nonce() > firstgap { + // Anything beyond the first gap is not addable yet + break + } + + // Drop any buffered transactions that became stale in the meantime (included in chain or replaced) + // If we arrive to the transaction in the pending range (between the state Nonce and first gap, we + // try to add them now while removing from here. + tx := gtxs[0] + gtxs[0] = nil + gtxs = gtxs[1:] + delete(p.gappedSource, tx.Hash()) + + if tx.Nonce() < stateNonce { + // Stale, drop it. Eventually we could add to limbo here if hash matches. + log.Trace("Gapped blob transaction became stale", "hash", tx.Hash(), "from", from, "nonce", tx.Nonce(), "state", stateNonce, "qlen", len(p.gapped[from])) + continue + } + + if tx.Nonce() <= firstgap { + // If we hit the pending range, including the first gap, add it and continue to try to add more. + // We do not recurse here, but continue to loop instead. + // We are under lock, so we can add the transaction directly. + if err := p.addLocked(tx, false); err == nil { + log.Trace("Gapped blob transaction added to pool", "hash", tx.Hash(), "from", from, "nonce", tx.Nonce(), "qlen", len(p.gapped[from])) + } else { + log.Trace("Gapped blob transaction not accepted", "hash", tx.Hash(), "from", from, "nonce", tx.Nonce(), "err", err) + } + } + } + if len(gtxs) == 0 { + delete(p.gapped, from) + } else { + p.gapped[from] = gtxs + } + } return nil } @@ -1705,7 +1825,7 @@ func (p *BlobPool) drop() { func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*txpool.LazyTransaction { // If only plain transactions are requested, this pool is unsuitable as it // contains none, don't even bother. - if filter.OnlyPlainTxs { + if !filter.BlobTxs { return nil } // Track the amount of time waiting to retrieve the list of pending blob txs @@ -1726,6 +1846,11 @@ func (p *BlobPool) Pending(filter txpool.PendingFilter) map[common.Address][]*tx for addr, txs := range p.index { lazies := make([]*txpool.LazyTransaction, 0, len(txs)) for _, tx := range txs { + // Skip v0 or v1 blob transactions depending on the filter + if tx.version != filter.BlobVersion { + break // skip the rest because of nonce ordering + } + // If transaction filtering was requested, discard badly priced ones if filter.MinTip != nil && filter.BaseFee != nil { if tx.execFeeCap.Lt(filter.BaseFee) { @@ -1866,6 +1991,50 @@ func (p *BlobPool) Nonce(addr common.Address) uint64 { return p.state.GetNonce(addr) } +// gappedAllowance returns the number of gapped transactions still +// allowed for the given account. Allowance is based on a slow-start +// logic, allowing more gaps (resource usage) to accounts with a +// higher nonce. Can also return negative values. +func (p *BlobPool) gappedAllowance(addr common.Address) int { + // Gaps happen, but we don't want to allow too many. + // Use log10(nonce+1) as the allowance, with a minimum of 0. + nonce := p.state.GetNonce(addr) + allowance := int(math.Log10(float64(nonce + 1))) + // Cap the allowance to the remaining pool space + return min(allowance, maxTxsPerAccount-len(p.index[addr])) - len(p.gapped[addr]) +} + +// evictGapped removes the old transactions from the gapped reorder buffer. +// Concurrency: The caller must hold the pool lock before calling this function. +func (p *BlobPool) evictGapped() { + cutoff := time.Now().Add(-gappedLifetime) + for from, txs := range p.gapped { + nonce := p.state.GetNonce(from) + // Reuse the original slice to avoid extra allocations. + // This is safe because we only keep references to the original gappedTx objects, + // and we overwrite the slice for this account after filtering. + keep := txs[:0] + for i, gtx := range txs { + if gtx.Time().Before(cutoff) || gtx.Nonce() < nonce { + // Evict old or stale transactions + // Should we add stale to limbo here if it would belong? + delete(p.gappedSource, gtx.Hash()) + txs[i] = nil // Explicitly nil out evicted element + } else { + keep = append(keep, gtx) + } + } + if len(keep) < len(txs) { + log.Trace("Evicting old gapped blob transactions", "count", len(txs)-len(keep), "from", from) + } + if len(keep) == 0 { + delete(p.gapped, from) + } else { + p.gapped[from] = keep + } + } +} + // Stats retrieves the current pool stats, namely the number of pending and the // number of queued (non-executable) transactions. func (p *BlobPool) Stats() (int, int) { @@ -1900,9 +2069,15 @@ func (p *BlobPool) ContentFrom(addr common.Address) ([]*types.Transaction, []*ty // Status returns the known status (unknown/pending/queued) of a transaction // identified by their hashes. func (p *BlobPool) Status(hash common.Hash) txpool.TxStatus { - if p.Has(hash) { + p.lock.RLock() + defer p.lock.RUnlock() + + if p.lookup.exists(hash) { return txpool.TxStatusPending } + if _, gapped := p.gappedSource[hash]; gapped { + return txpool.TxStatusQueued + } return txpool.TxStatusUnknown } @@ -1953,7 +2128,7 @@ func (p *BlobPool) Clear() { p.spent = make(map[common.Address]*uint256.Int) var ( - basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head)) + basefee = uint256.MustFromBig(eip1559.CalcBaseFee(p.chain.Config(), p.head.Load())) blobfee = uint256.NewInt(params.BlobTxMinBlobGasprice) ) p.evict = newPriceHeap(basefee, blobfee, p.index) diff --git a/core/txpool/blobpool/blobpool_test.go b/core/txpool/blobpool/blobpool_test.go index 55eed86cff..4bb3567b69 100644 --- a/core/txpool/blobpool/blobpool_test.go +++ b/core/txpool/blobpool/blobpool_test.go @@ -24,9 +24,11 @@ import ( "fmt" "math" "math/big" + "math/rand" "os" "path/filepath" "reflect" + "slices" "sync" "testing" @@ -40,6 +42,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/kzg4844" + "github.com/ethereum/go-ethereum/internal/testrand" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/billy" @@ -47,11 +50,12 @@ import ( ) var ( - testBlobs []*kzg4844.Blob - testBlobCommits []kzg4844.Commitment - testBlobProofs []kzg4844.Proof - testBlobVHashes [][32]byte - testBlobIndices = make(map[[32]byte]int) + testBlobs []*kzg4844.Blob + testBlobCommits []kzg4844.Commitment + testBlobProofs []kzg4844.Proof + testBlobCellProofs [][]kzg4844.Proof + testBlobVHashes [][32]byte + testBlobIndices = make(map[[32]byte]int) ) const testMaxBlobsPerBlock = 6 @@ -67,6 +71,9 @@ func init() { testBlobProof, _ := kzg4844.ComputeBlobProof(testBlob, testBlobCommit) testBlobProofs = append(testBlobProofs, testBlobProof) + testBlobCellProof, _ := kzg4844.ComputeCellProofs(testBlob) + testBlobCellProofs = append(testBlobCellProofs, testBlobCellProof) + testBlobVHash := kzg4844.CalcBlobHashV1(sha256.New(), &testBlobCommit) testBlobIndices[testBlobVHash] = len(testBlobVHashes) testBlobVHashes = append(testBlobVHashes, testBlobVHash) @@ -81,6 +88,8 @@ type testBlockChain struct { statedb *state.StateDB blocks map[uint64]*types.Block + + blockTime *uint64 } func (bc *testBlockChain) Config() *params.ChainConfig { @@ -98,6 +107,10 @@ func (bc *testBlockChain) CurrentBlock() *types.Header { blockTime = *bc.config.CancunTime + 1 gasLimit = uint64(30_000_000) ) + if bc.blockTime != nil { + blockTime = *bc.blockTime + } + lo := new(big.Int) hi := new(big.Int).Mul(big.NewInt(5714), new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil)) @@ -257,8 +270,8 @@ func makeUnsignedTx(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap return makeUnsignedTxWithTestBlob(nonce, gasTipCap, gasFeeCap, blobFeeCap, rnd.Intn(len(testBlobs))) } -// makeUnsignedTx is a utility method to construct a random blob transaction -// without signing it. +// makeUnsignedTxWithTestBlob is a utility method to construct a random blob transaction +// with a specific test blob without signing it. func makeUnsignedTxWithTestBlob(nonce uint64, gasTipCap uint64, gasFeeCap uint64, blobFeeCap uint64, blobIdx int) *types.BlobTx { return &types.BlobTx{ ChainID: uint256.MustFromBig(params.MainnetChainConfig.ChainID), @@ -416,24 +429,36 @@ func verifyBlobRetrievals(t *testing.T, pool *BlobPool) { hashes = append(hashes, tx.vhashes...) } } - blobs, _, proofs, err := pool.GetBlobs(hashes, types.BlobSidecarVersion0) + blobs1, _, proofs1, err := pool.GetBlobs(hashes, types.BlobSidecarVersion0) + if err != nil { + t.Fatal(err) + } + blobs2, _, proofs2, err := pool.GetBlobs(hashes, types.BlobSidecarVersion1) if err != nil { t.Fatal(err) } // Cross validate what we received vs what we wanted - if len(blobs) != len(hashes) || len(proofs) != len(hashes) { - t.Errorf("retrieved blobs/proofs size mismatch: have %d/%d, want %d", len(blobs), len(proofs), len(hashes)) + if len(blobs1) != len(hashes) || len(proofs1) != len(hashes) { + t.Errorf("retrieved blobs/proofs size mismatch: have %d/%d, want %d", len(blobs1), len(proofs1), len(hashes)) + return + } + if len(blobs2) != len(hashes) || len(proofs2) != len(hashes) { + t.Errorf("retrieved blobs/proofs size mismatch: have %d/%d, want blobs %d, want proofs: %d", len(blobs2), len(proofs2), len(hashes), len(hashes)) return } for i, hash := range hashes { - // If an item is missing, but shouldn't, error - if blobs[i] == nil || proofs[i] == nil { + // If an item is missing from both, but shouldn't, error + if (blobs1[i] == nil || proofs1[i] == nil) && (blobs2[i] == nil || proofs2[i] == nil) { t.Errorf("tracked blob retrieval failed: item %d, hash %x", i, hash) continue } // Item retrieved, make sure it matches the expectation index := testBlobIndices[hash] - if *blobs[i] != *testBlobs[index] || proofs[i][0] != testBlobProofs[index] { + if blobs1[i] != nil && (*blobs1[i] != *testBlobs[index] || proofs1[i][0] != testBlobProofs[index]) { + t.Errorf("retrieved blob or proof mismatch: item %d, hash %x", i, hash) + continue + } + if blobs2[i] != nil && (*blobs2[i] != *testBlobs[index] || !slices.Equal(proofs2[i], testBlobCellProofs[index])) { t.Errorf("retrieved blob or proof mismatch: item %d, hash %x", i, hash) continue } @@ -963,7 +988,7 @@ func TestOpenCap(t *testing.T) { storage := t.TempDir() os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) - store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotter(testMaxBlobsPerBlock), nil) + store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, newSlotterEIP7594(testMaxBlobsPerBlock), nil) // Insert a few transactions from a few accounts var ( @@ -985,7 +1010,7 @@ func TestOpenCap(t *testing.T) { keep = []common.Address{addr1, addr3} drop = []common.Address{addr2} - size = uint64(2 * (txAvgSize + blobSize)) + size = 2 * (txAvgSize + blobSize + uint64(txBlobOverhead)) ) store.Put(blob1) store.Put(blob2) @@ -994,7 +1019,7 @@ func TestOpenCap(t *testing.T) { // Verify pool capping twice: first by reducing the data cap, then restarting // with a high cap to ensure everything was persisted previously - for _, datacap := range []uint64{2 * (txAvgSize + blobSize), 100 * (txAvgSize + blobSize)} { + for _, datacap := range []uint64{2 * (txAvgSize + blobSize + uint64(txBlobOverhead)), 1000 * (txAvgSize + blobSize + uint64(txBlobOverhead))} { // Create a blob pool out of the pre-seeded data, but cap it to 2 blob transaction statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) @@ -1142,6 +1167,115 @@ func TestChangingSlotterSize(t *testing.T) { } } +// TestBillyMigration tests the billy migration from the default slotter to +// the PeerDAS slotter. This tests both the migration of the slotter +// as well as increasing the slotter size of the new slotter. +func TestBillyMigration(t *testing.T) { + //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelTrace, true))) + + // Create a temporary folder for the persistent backend + storage := t.TempDir() + + os.MkdirAll(filepath.Join(storage, pendingTransactionStore), 0700) + os.MkdirAll(filepath.Join(storage, limboedTransactionStore), 0700) + // Create the billy with the old slotter + oldSlotter := newSlotterEIP7594(6) + store, _ := billy.Open(billy.Options{Path: filepath.Join(storage, pendingTransactionStore)}, oldSlotter, nil) + + // Create transactions from a few accounts. + var ( + key1, _ = crypto.GenerateKey() + key2, _ = crypto.GenerateKey() + key3, _ = crypto.GenerateKey() + + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + addr3 = crypto.PubkeyToAddress(key3.PublicKey) + + tx1 = makeMultiBlobTx(0, 1, 1000, 100, 6, 0, key1, types.BlobSidecarVersion0) + tx2 = makeMultiBlobTx(0, 1, 800, 70, 6, 0, key2, types.BlobSidecarVersion0) + tx3 = makeMultiBlobTx(0, 1, 800, 110, 24, 0, key3, types.BlobSidecarVersion0) + + blob1, _ = rlp.EncodeToBytes(tx1) + blob2, _ = rlp.EncodeToBytes(tx2) + ) + + // Write the two safely sized txs to store. note: although the store is + // configured for a blob count of 6, it can also support around ~1mb of call + // data - all this to say that we aren't using the the absolute largest shelf + // available. + store.Put(blob1) + store.Put(blob2) + store.Close() + + // Mimic a blobpool with max blob count of 6 upgrading to a max blob count of 24. + for _, maxBlobs := range []int{6, 24} { + statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) + statedb.AddBalance(addr1, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(addr2, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) + statedb.AddBalance(addr3, uint256.NewInt(1_000_000_000), tracing.BalanceChangeUnspecified) + statedb.Commit(0, true, false) + + // Make custom chain config where the max blob count changes based on the loop variable. + zero := uint64(0) + config := ¶ms.ChainConfig{ + ChainID: big.NewInt(1), + LondonBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + CancunTime: &zero, + OsakaTime: &zero, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: ¶ms.BlobConfig{ + Target: maxBlobs / 2, + Max: maxBlobs, + UpdateFraction: params.DefaultCancunBlobConfig.UpdateFraction, + }, + Osaka: ¶ms.BlobConfig{ + Target: maxBlobs / 2, + Max: maxBlobs, + UpdateFraction: params.DefaultCancunBlobConfig.UpdateFraction, + }, + }, + } + chain := &testBlockChain{ + config: config, + basefee: uint256.NewInt(1050), + blobfee: uint256.NewInt(105), + statedb: statedb, + } + pool := New(Config{Datadir: storage}, chain, nil) + if err := pool.Init(1, chain.CurrentBlock(), newReserver()); err != nil { + t.Fatalf("failed to create blob pool: %v", err) + } + + // Try to add the big blob tx. In the initial iteration it should overflow + // the pool. On the subsequent iteration it should be accepted. + errs := pool.Add([]*types.Transaction{tx3}, true) + if _, ok := pool.index[addr3]; ok && maxBlobs == 6 { + t.Errorf("expected insert of oversized blob tx to fail: blobs=24, maxBlobs=%d, err=%v", maxBlobs, errs[0]) + } else if !ok && maxBlobs == 10 { + t.Errorf("expected insert of oversized blob tx to succeed: blobs=24, maxBlobs=%d, err=%v", maxBlobs, errs[0]) + } + + // Verify the regular two txs are always available. + if got := pool.Get(tx1.Hash()); got == nil { + t.Errorf("expected tx %s from %s in pool", tx1.Hash(), addr1) + } + if got := pool.Get(tx2.Hash()); got == nil { + t.Errorf("expected tx %s from %s in pool", tx2.Hash(), addr2) + } + + // Verify all the calculated pool internals. Interestingly, this is **not** + // a duplication of the above checks, this actually validates the verifier + // using the above already hard coded checks. + // + // Do not remove this, nor alter the above to be generic. + verifyPoolInternals(t, pool) + + pool.Close() + } +} + // TestBlobCountLimit tests the blobpool enforced limits on the max blob count. func TestBlobCountLimit(t *testing.T) { var ( @@ -1191,7 +1325,7 @@ func TestBlobCountLimit(t *testing.T) { // Check that first succeeds second fails. if errs[0] != nil { - t.Fatalf("expected tx with 7 blobs to succeed") + t.Fatalf("expected tx with 7 blobs to succeed, got %v", errs[0]) } if !errors.Is(errs[1], txpool.ErrTxBlobLimitExceeded) { t.Fatalf("expected tx with 8 blobs to fail, got: %v", errs[1]) @@ -1218,9 +1352,10 @@ func TestAdd(t *testing.T) { } // addtx is a helper sender/tx tuple to represent a new tx addition type addtx struct { - from string - tx *types.BlobTx - err error + from string + tx *types.BlobTx + err error + check func(*BlobPool, *types.Transaction) bool } tests := []struct { @@ -1237,6 +1372,7 @@ func TestAdd(t *testing.T) { "bob": {balance: 21100 + blobSize, nonce: 1}, "claire": {balance: 21100 + blobSize}, "dave": {balance: 21100 + blobSize, nonce: 1}, + "eve": {balance: 21100 + blobSize, nonce: 10}, // High nonce to test gapped acceptance }, adds: []addtx{ { // New account, no previous txs: accept nonce 0 @@ -1264,6 +1400,14 @@ func TestAdd(t *testing.T) { tx: makeUnsignedTx(2, 1, 1, 1), err: core.ErrNonceTooHigh, }, + { // Old account, 10 txs in chain: 0 pending: accept nonce 11 as gapped + from: "eve", + tx: makeUnsignedTx(11, 1, 1, 1), + err: nil, + check: func(pool *BlobPool, tx *types.Transaction) bool { + return pool.Status(tx.Hash()) == txpool.TxStatusQueued + }, + }, }, }, // Transactions from already pooled accounts should only be accepted if @@ -1620,19 +1764,32 @@ func TestAdd(t *testing.T) { // Add each transaction one by one, verifying the pool internals in between for j, add := range tt.adds { signed, _ := types.SignNewTx(keys[add.from], types.LatestSigner(params.MainnetChainConfig), add.tx) - if err := pool.add(signed); !errors.Is(err, add.err) { - t.Errorf("test %d, tx %d: adding transaction error mismatch: have %v, want %v", i, j, err, add.err) + if errs := pool.Add([]*types.Transaction{signed}, true); !errors.Is(errs[0], add.err) { + t.Errorf("test %d, tx %d: adding transaction error mismatch: have %v, want %v", i, j, errs[0], add.err) } if add.err == nil { - size, exist := pool.lookup.sizeOfTx(signed.Hash()) - if !exist { - t.Errorf("test %d, tx %d: failed to lookup transaction's size", i, j) + // first check if tx is in the pool (reorder queue or pending) + if !pool.Has(signed.Hash()) { + t.Errorf("test %d, tx %d: added transaction not found in pool", i, j) } - if size != signed.Size() { - t.Errorf("test %d, tx %d: transaction's size mismatches: have %v, want %v", - i, j, size, signed.Size()) + // if it is pending, check if size matches + if pool.Status(signed.Hash()) == txpool.TxStatusPending { + size, exist := pool.lookup.sizeOfTx(signed.Hash()) + if !exist { + t.Errorf("test %d, tx %d: failed to lookup transaction's size", i, j) + } + if size != signed.Size() { + t.Errorf("test %d, tx %d: transaction's size mismatches: have %v, want %v", + i, j, size, signed.Size()) + } } } + if add.check != nil { + if !add.check(pool, signed) { + t.Errorf("test %d, tx %d: custom check failed", i, j) + } + } + // Verify the pool internals after each addition verifyPoolInternals(t, pool) } verifyPoolInternals(t, pool) @@ -1750,10 +1907,10 @@ func TestGetBlobs(t *testing.T) { } cases := []struct { - start int - limit int - version byte - expErr bool + start int + limit int + fillRandom bool // Whether to randomly fill some of the requested blobs with unknowns + version byte // Blob sidecar version to request }{ { start: 0, limit: 6, @@ -1763,6 +1920,14 @@ func TestGetBlobs(t *testing.T) { start: 0, limit: 6, version: types.BlobSidecarVersion1, }, + { + start: 0, limit: 6, fillRandom: true, + version: types.BlobSidecarVersion0, + }, + { + start: 0, limit: 6, fillRandom: true, + version: types.BlobSidecarVersion1, + }, { start: 3, limit: 9, version: types.BlobSidecarVersion0, @@ -1771,6 +1936,14 @@ func TestGetBlobs(t *testing.T) { start: 3, limit: 9, version: types.BlobSidecarVersion1, }, + { + start: 3, limit: 9, fillRandom: true, + version: types.BlobSidecarVersion0, + }, + { + start: 3, limit: 9, fillRandom: true, + version: types.BlobSidecarVersion1, + }, { start: 3, limit: 15, version: types.BlobSidecarVersion0, @@ -1779,6 +1952,14 @@ func TestGetBlobs(t *testing.T) { start: 3, limit: 15, version: types.BlobSidecarVersion1, }, + { + start: 3, limit: 15, fillRandom: true, + version: types.BlobSidecarVersion0, + }, + { + start: 3, limit: 15, fillRandom: true, + version: types.BlobSidecarVersion1, + }, { start: 0, limit: 18, version: types.BlobSidecarVersion0, @@ -1788,58 +1969,84 @@ func TestGetBlobs(t *testing.T) { version: types.BlobSidecarVersion1, }, { - start: 18, limit: 20, + start: 0, limit: 18, fillRandom: true, version: types.BlobSidecarVersion0, - expErr: true, + }, + { + start: 0, limit: 18, fillRandom: true, + version: types.BlobSidecarVersion1, }, } for i, c := range cases { - var vhashes []common.Hash + var ( + vhashes []common.Hash + filled = make(map[int]struct{}) + ) + if c.fillRandom { + filled[len(vhashes)] = struct{}{} + vhashes = append(vhashes, testrand.Hash()) + } for j := c.start; j < c.limit; j++ { vhashes = append(vhashes, testBlobVHashes[j]) + if c.fillRandom && rand.Intn(2) == 0 { + filled[len(vhashes)] = struct{}{} + vhashes = append(vhashes, testrand.Hash()) + } + } + if c.fillRandom { + filled[len(vhashes)] = struct{}{} + vhashes = append(vhashes, testrand.Hash()) } blobs, _, proofs, err := pool.GetBlobs(vhashes, c.version) + if err != nil { + t.Errorf("Unexpected error for case %d, %v", i, err) + } - if c.expErr { - if err == nil { - t.Errorf("Unexpected return, want error for case %d", i) - } - } else { - if err != nil { - t.Errorf("Unexpected error for case %d, %v", i, err) - } - // Cross validate what we received vs what we wanted - length := c.limit - c.start - if len(blobs) != length || len(proofs) != length { - t.Errorf("retrieved blobs/proofs size mismatch: have %d/%d, want %d", len(blobs), len(proofs), length) + // Cross validate what we received vs what we wanted + length := c.limit - c.start + wantLen := length + len(filled) + if len(blobs) != wantLen || len(proofs) != wantLen { + t.Errorf("retrieved blobs/proofs size mismatch: have %d/%d, want %d", len(blobs), len(proofs), wantLen) + continue + } + + var unknown int + for j := 0; j < len(blobs); j++ { + testBlobIndex := c.start + j - unknown + if _, exist := filled[j]; exist { + if blobs[j] != nil || proofs[j] != nil { + t.Errorf("Unexpected blob and proof, item %d", j) + } + unknown++ continue } - for j := 0; j < len(blobs); j++ { - // If an item is missing, but shouldn't, error - if blobs[j] == nil || proofs[j] == nil { + // If an item is missing, but shouldn't, error + if blobs[j] == nil || proofs[j] == nil { + // This is only an error if there was no version mismatch + if (c.version == types.BlobSidecarVersion1 && 6 <= testBlobIndex && testBlobIndex < 12) || + (c.version == types.BlobSidecarVersion0 && (testBlobIndex < 6 || 12 <= testBlobIndex)) { t.Errorf("tracked blob retrieval failed: item %d, hash %x", j, vhashes[j]) - continue } - // Item retrieved, make sure the blob matches the expectation - if *blobs[j] != *testBlobs[c.start+j] { - t.Errorf("retrieved blob mismatch: item %d, hash %x", j, vhashes[j]) - continue + continue + } + // Item retrieved, make sure the blob matches the expectation + if *blobs[j] != *testBlobs[testBlobIndex] { + t.Errorf("retrieved blob mismatch: item %d, hash %x", j, vhashes[j]) + continue + } + // Item retrieved, make sure the proof matches the expectation + if c.version == types.BlobSidecarVersion0 { + if proofs[j][0] != testBlobProofs[testBlobIndex] { + t.Errorf("retrieved proof mismatch: item %d, hash %x", j, vhashes[j]) } - // Item retrieved, make sure the proof matches the expectation - if c.version == types.BlobSidecarVersion0 { - if proofs[j][0] != testBlobProofs[c.start+j] { - t.Errorf("retrieved proof mismatch: item %d, hash %x", j, vhashes[j]) - } - } else { - want, _ := kzg4844.ComputeCellProofs(blobs[j]) - if !reflect.DeepEqual(want, proofs[j]) { - t.Errorf("retrieved proof mismatch: item %d, hash %x", j, vhashes[j]) - } + } else { + want, _ := kzg4844.ComputeCellProofs(blobs[j]) + if !reflect.DeepEqual(want, proofs[j]) { + t.Errorf("retrieved proof mismatch: item %d, hash %x", j, vhashes[j]) } } } } - pool.Close() } @@ -1919,6 +2126,7 @@ func benchmarkPoolPending(b *testing.B, datacap uint64) { MinTip: uint256.NewInt(1), BaseFee: chain.basefee, BlobFee: chain.blobfee, + BlobTxs: true, }) if len(p) != int(capacity) { b.Fatalf("have %d want %d", len(p), capacity) diff --git a/core/txpool/blobpool/limbo.go b/core/txpool/blobpool/limbo.go index 5383b8062c..c68451f052 100644 --- a/core/txpool/blobpool/limbo.go +++ b/core/txpool/blobpool/limbo.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/billy" ) @@ -30,11 +31,11 @@ import ( // to which it belongs as well as the block number in which it was included for // finality eviction. type limboBlob struct { - TxHash common.Hash // Owner transaction's hash to support resurrecting reorged txs - Block uint64 // Block in which the blob transaction was included - Tx *types.Transaction `rlp:"omitempty"` // After this commitment the Tx field is optional, as the TxMeta contains the tx metadata. - TxMeta *blobTxMeta `rlp:"omitempty"` // Optional blob transaction metadata. - id uint64 // the billy id of limboBlob + TxHash common.Hash // Owner transaction's hash to support resurrecting reorged txs + Block uint64 // Block in which the blob transaction was included + Tx *types.Transaction + TxMeta *blobTxMeta `rlp:"omitempty"` // Optional blob transaction metadata. + id uint64 // the billy id of limboBlob } // limbo is a light, indexed database to temporarily store recently included @@ -46,10 +47,20 @@ type limbo struct { } // newLimbo opens and indexes a set of limboed blob transactions. -func newLimbo(datadir string, maxBlobsPerTransaction int) (*limbo, error) { +func newLimbo(config *params.ChainConfig, datadir string) (*limbo, error) { l := &limbo{ index: make(map[common.Hash]*limboBlob), } + + // Create new slotter for pre-Osaka blob configuration. + slotter := newSlotter(params.BlobTxMaxBlobs) + + // See if we need to migrate the limbo after fusaka. + slotter, err := tryMigrate(config, slotter, datadir) + if err != nil { + return nil, err + } + // Index all limboed blobs on disk and delete anything unprocessable var fails []uint64 index := func(id uint64, size uint32, data []byte) { @@ -57,13 +68,7 @@ func newLimbo(datadir string, maxBlobsPerTransaction int) (*limbo, error) { fails = append(fails, id) } } - store, err := billy.Open(billy.Options{Path: datadir, Repair: true}, func() (size uint32, done bool) { - // 8*6: Total size of uint64. - // 4: The size of uint32. - // 32*4: The max total size of big.Int. - // 32*(maxBlobsPerTransaction+2): The total size of hashes. - return 8*6 + 4 + 32*4 + 32*uint32(maxBlobsPerTransaction+2), true - }, index) + store, err := billy.Open(billy.Options{Path: datadir, Repair: true}, slotter, index) if err != nil { return nil, err } @@ -104,24 +109,12 @@ func (l *limbo) parseBlob(id uint64, data []byte) error { log.Error("Dropping duplicate blob limbo entry", "owner", item.TxHash, "id", id) return errors.New("duplicate blob") } - // Delete tx and set id. item.id = id l.index[item.TxHash] = item return nil } -// existsAndSet checks whether a blob transaction is already tracked by the limbo. -func (l *limbo) existsAndSet(meta *blobTxMeta) bool { - if item := l.index[meta.hash]; item != nil { - if item.TxMeta == nil { - item.TxMeta, item.Tx = meta, nil - } - return true - } - return false -} - // setTxMeta attempts to repair the limbo by re-encoding all transactions that are // currently in the limbo, but not yet stored in the database. This is useful // when the limbo is created from a previous state, and the transactions are not @@ -133,6 +126,7 @@ func (l *limbo) setTxMeta(store billy.Database) error { continue } tx := item.Tx + item.Tx = nil // Clear the in-memory tx // Transaction permitted into the pool from a nonce and cost perspective, // insert it into the database and update the indices blob, err := rlp.EncodeToBytes(tx) @@ -198,13 +192,13 @@ func (l *limbo) push(meta *blobTxMeta, block uint64) error { // pull retrieves a previously pushed set of blobs back from the limbo, removing // it at the same time. This method should be used when a previously included blob // transaction gets reorged out. -func (l *limbo) pull(txhash common.Hash) (*blobTxMeta, error) { +func (l *limbo) pull(tx common.Hash) (*blobTxMeta, error) { // If the blobs are not tracked by the limbo, there's not much to do. This // can happen for example if a blob transaction is mined without pushing it // into the network first. - item, ok := l.index[txhash] + item, ok := l.index[tx] if !ok { - log.Trace("Limbo cannot pull non-tracked blobs", "tx", txhash) + log.Trace("Limbo cannot pull non-tracked blobs", "tx", tx) return nil, errors.New("unseen blob transaction") } if err := l.drop(item.TxHash); err != nil { @@ -246,6 +240,24 @@ func (l *limbo) update(txhash common.Hash, block uint64) { log.Trace("Blob transaction updated in limbo", "tx", txhash, "old-block", item.Block, "new-block", block) } +// getAndDrop retrieves a blob item from the limbo store and deletes it both from +// the store and indices. +func (l *limbo) getAndDrop(id uint64) (*limboBlob, error) { + data, err := l.store.Get(id) + if err != nil { + return nil, err + } + item := new(limboBlob) + if err = rlp.DecodeBytes(data, item); err != nil { + return nil, err + } + delete(l.index, item.TxHash) + if err := l.store.Delete(id); err != nil { + return nil, err + } + return item, nil +} + // drop removes the blob metadata from the limbo. func (l *limbo) drop(txhash common.Hash) error { if item, ok := l.index[txhash]; ok { @@ -278,7 +290,7 @@ func (l *limbo) setAndIndex(meta *blobTxMeta, block uint64) error { if err != nil { return err } - // Delete tx and set id. + // Set the in-memory index item.id = id l.index[txhash] = item diff --git a/core/txpool/blobpool/slotter.go b/core/txpool/blobpool/slotter.go index 84ccc0f27b..3399361e55 100644 --- a/core/txpool/blobpool/slotter.go +++ b/core/txpool/blobpool/slotter.go @@ -16,6 +16,48 @@ package blobpool +import ( + "github.com/ethereum/go-ethereum/params" + "github.com/holiman/billy" +) + +// tryMigrate checks if the billy needs to be migrated and migrates if needed. +// Returns a slotter that can be used for the database. +func tryMigrate(config *params.ChainConfig, slotter billy.SlotSizeFn, datadir string) (billy.SlotSizeFn, error) { + // Check if we need to migrate our blob db to the new slotter. + if config.OsakaTime != nil { + // Open the store using the version slotter to see if any version has been + // written. + var version int + index := func(_ uint64, _ uint32, blob []byte) { + version = max(version, parseSlotterVersion(blob)) + } + store, err := billy.Open(billy.Options{Path: datadir}, newVersionSlotter(), index) + if err != nil { + return nil, err + } + store.Close() + + // If the version found is less than the currently configured store version, + // perform a migration then write the updated version of the store. + if version < storeVersion { + newSlotter := newSlotterEIP7594(params.BlobTxMaxBlobs) + if err := billy.Migrate(billy.Options{Path: datadir, Repair: true}, slotter, newSlotter); err != nil { + return nil, err + } + store, err = billy.Open(billy.Options{Path: datadir}, newVersionSlotter(), nil) + if err != nil { + return nil, err + } + writeSlotterVersion(store, storeVersion) + store.Close() + } + // Set the slotter to the format now that the Osaka is active. + slotter = newSlotterEIP7594(params.BlobTxMaxBlobs) + } + return slotter, nil +} + // newSlotter creates a helper method for the Billy datastore that returns the // individual shelf sizes used to store transactions in. // @@ -25,7 +67,7 @@ package blobpool // The slotter also creates a shelf for 0-blob transactions. Whilst those are not // allowed in the current protocol, having an empty shelf is not a relevant use // of resources, but it makes stress testing with junk transactions simpler. -func newSlotter(maxBlobsPerTransaction int) func() (uint32, bool) { +func newSlotter(maxBlobsPerTransaction int) billy.SlotSizeFn { slotsize := uint32(txAvgSize) slotsize -= uint32(blobSize) // underflows, it's ok, will overflow back in the first return @@ -36,3 +78,42 @@ func newSlotter(maxBlobsPerTransaction int) func() (uint32, bool) { return slotsize, finished } } + +// newSlotterEIP7594 creates a different slotter for EIP-7594 transactions. +// EIP-7594 (PeerDAS) changes the average transaction size which means the current +// static 4KB average size is not enough anymore. +// This slotter adds a dynamic overhead component to the slotter, which also +// captures the notion that blob transactions with more blobs are also more likely to +// to have more calldata. +func newSlotterEIP7594(maxBlobsPerTransaction int) billy.SlotSizeFn { + slotsize := uint32(txAvgSize) + slotsize -= uint32(blobSize) + txBlobOverhead // underflows, it's ok, will overflow back in the first return + + return func() (size uint32, done bool) { + slotsize += blobSize + txBlobOverhead + finished := slotsize > uint32(maxBlobsPerTransaction)*(blobSize+txBlobOverhead)+txMaxSize + + return slotsize, finished + } +} + +// newVersionSlotter creates a slotter with a single 8 byte shelf to store +// version metadata in. +func newVersionSlotter() billy.SlotSizeFn { + return func() (size uint32, done bool) { + return 8, true + } +} + +// parseSlotterVersion will parse the slotter's version from a given data blob. +func parseSlotterVersion(blob []byte) int { + if len(blob) > 0 { + return int(blob[0]) + } + return 0 +} + +// writeSlotterVersion writes the current slotter version into the store. +func writeSlotterVersion(store billy.Database, version int) { + store.Put([]byte{byte(version)}) +} diff --git a/core/txpool/blobpool/slotter_test.go b/core/txpool/blobpool/slotter_test.go index 8d46f47d2c..e4cf232f4e 100644 --- a/core/txpool/blobpool/slotter_test.go +++ b/core/txpool/blobpool/slotter_test.go @@ -16,7 +16,9 @@ package blobpool -import "testing" +import ( + "testing" +) // Tests that the slotter creates the expected database shelves. func TestNewSlotter(t *testing.T) { @@ -58,3 +60,44 @@ func TestNewSlotter(t *testing.T) { } } } + +// Tests that the slotter creates the expected database shelves. +func TestNewSlotterEIP7594(t *testing.T) { + // Generate the database shelve sizes + slotter := newSlotterEIP7594(6) + + var shelves []uint32 + for { + shelf, done := slotter() + shelves = append(shelves, shelf) + if done { + break + } + } + // Compare the database shelves to the expected ones + want := []uint32{ + 0*blobSize + 0*txBlobOverhead + txAvgSize, // 0 blob + some expected tx infos + 1*blobSize + 1*txBlobOverhead + txAvgSize, // 1 blob + some expected tx infos + 2*blobSize + 2*txBlobOverhead + txAvgSize, // 2 blob + some expected tx infos (could be fewer blobs and more tx data) + 3*blobSize + 3*txBlobOverhead + txAvgSize, // 3 blob + some expected tx infos (could be fewer blobs and more tx data) + 4*blobSize + 4*txBlobOverhead + txAvgSize, // 4 blob + some expected tx infos (could be fewer blobs and more tx data) + 5*blobSize + 5*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 6*blobSize + 6*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 7*blobSize + 7*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 8*blobSize + 8*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 9*blobSize + 9*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 10*blobSize + 10*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 11*blobSize + 11*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 12*blobSize + 12*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 13*blobSize + 13*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos < 4 blobs + max tx metadata size + 14*blobSize + 14*txBlobOverhead + txAvgSize, // 1-6 blobs + unexpectedly large tx infos >= 4 blobs + max tx metadata size + } + if len(shelves) != len(want) { + t.Errorf("shelves count mismatch: have %d, want %d", len(shelves), len(want)) + } + for i := 0; i < len(shelves) && i < len(want); i++ { + if shelves[i] != want[i] { + t.Errorf("shelf %d mismatch: have %d, want %d", i, shelves[i], want[i]) + } + } +} diff --git a/core/txpool/errors.go b/core/txpool/errors.go index 9bc435d67e..8285cbf10e 100644 --- a/core/txpool/errors.go +++ b/core/txpool/errors.go @@ -71,4 +71,7 @@ var ( // ErrInflightTxLimitReached is returned when the maximum number of in-flight // transactions is reached for specific accounts. ErrInflightTxLimitReached = errors.New("in-flight transaction limit reached for delegated accounts") + + // ErrKZGVerificationError is returned when a KZG proof was not verified correctly. + ErrKZGVerificationError = errors.New("KZG verification error") ) diff --git a/core/txpool/legacypool/legacypool.go b/core/txpool/legacypool/legacypool.go index 93a003c172..eb1fe23d5f 100644 --- a/core/txpool/legacypool/legacypool.go +++ b/core/txpool/legacypool/legacypool.go @@ -23,7 +23,6 @@ import ( "math" "math/big" "slices" - "sort" "sync" "sync/atomic" "time" @@ -115,6 +114,9 @@ var ( queuedGauge = metrics.NewRegisteredGauge("txpool/queued", nil) slotsGauge = metrics.NewRegisteredGauge("txpool/slots", nil) + pendingAddrsGauge = metrics.NewRegisteredGauge("txpool/pending/accounts", nil) + queuedAddrsGauge = metrics.NewRegisteredGauge("txpool/queued/accounts", nil) + reheapTimer = metrics.NewRegisteredTimer("txpool/reheap", nil) ) @@ -238,11 +240,10 @@ type LegacyPool struct { pendingNonces *noncer // Pending state tracking virtual nonces reserver txpool.Reserver // Address reserver to ensure exclusivity across subpools - pending map[common.Address]*list // All currently processable transactions - queue map[common.Address]*list // Queued but non-processable transactions - beats map[common.Address]time.Time // Last heartbeat from each known account - all *lookup // All transactions to allow lookups - priced *pricedList // All transactions sorted by price + pending map[common.Address]*list // All currently processable transactions + queue *queue + all *lookup // All transactions to allow lookups + priced *pricedList // All transactions sorted by price reqResetCh chan *txpoolResetRequest reqPromoteCh chan *accountSet @@ -266,14 +267,14 @@ func New(config Config, chain BlockChain) *LegacyPool { config = (&config).sanitize() // Create the transaction pool with its initial settings + signer := types.LatestSigner(chain.Config()) pool := &LegacyPool{ config: config, chain: chain, chainconfig: chain.Config(), - signer: types.LatestSigner(chain.Config()), + signer: signer, pending: make(map[common.Address]*list), - queue: make(map[common.Address]*list), - beats: make(map[common.Address]time.Time), + queue: newQueue(config, signer), all: newLookup(), reqResetCh: make(chan *txpoolResetRequest), reqPromoteCh: make(chan *accountSet), @@ -290,7 +291,12 @@ func New(config Config, chain BlockChain) *LegacyPool { // Filter returns whether the given transaction can be consumed by the legacy // pool, specifically, whether it is a Legacy, AccessList or Dynamic transaction. func (pool *LegacyPool) Filter(tx *types.Transaction) bool { - switch tx.Type() { + return pool.FilterType(tx.Type()) +} + +// FilterType returns whether the legacy pool supports the given transaction type. +func (pool *LegacyPool) FilterType(kind byte) bool { + switch kind { case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, types.SetCodeTxType: return true default: @@ -369,15 +375,8 @@ func (pool *LegacyPool) loop() { // Handle inactive account transaction eviction case <-evict.C: pool.mu.Lock() - for addr := range pool.queue { - // Any old enough should be removed - if time.Since(pool.beats[addr]) > pool.config.Lifetime { - list := pool.queue[addr].Flatten() - for _, tx := range list { - pool.removeTx(tx.Hash(), true, true) - } - queuedEvictionMeter.Mark(int64(len(list))) - } + for _, hash := range pool.queue.evictList() { + pool.removeTx(hash, true, true) } pool.mu.Unlock() } @@ -459,11 +458,7 @@ func (pool *LegacyPool) stats() (int, int) { for _, list := range pool.pending { pending += list.Len() } - queued := 0 - for _, list := range pool.queue { - queued += list.Len() - } - return pending, queued + return pending, pool.queue.stats() } // Content retrieves the data content of the transaction pool, returning all the @@ -476,10 +471,7 @@ func (pool *LegacyPool) Content() (map[common.Address][]*types.Transaction, map[ for addr, list := range pool.pending { pending[addr] = list.Flatten() } - queued := make(map[common.Address][]*types.Transaction, len(pool.queue)) - for addr, list := range pool.queue { - queued[addr] = list.Flatten() - } + queued := pool.queue.content() return pending, queued } @@ -493,10 +485,7 @@ func (pool *LegacyPool) ContentFrom(addr common.Address) ([]*types.Transaction, if list, ok := pool.pending[addr]; ok { pending = list.Flatten() } - var queued []*types.Transaction - if list, ok := pool.queue[addr]; ok { - queued = list.Flatten() - } + queued := pool.queue.contentFrom(addr) return pending, queued } @@ -508,32 +497,21 @@ func (pool *LegacyPool) ContentFrom(addr common.Address) ([]*types.Transaction, func (pool *LegacyPool) Pending(filter txpool.PendingFilter) map[common.Address][]*txpool.LazyTransaction { // If only blob transactions are requested, this pool is unsuitable as it // contains none, don't even bother. - if filter.OnlyBlobTxs { + if filter.BlobTxs { return nil } pool.mu.Lock() defer pool.mu.Unlock() - // Convert the new uint256.Int types to the old big.Int ones used by the legacy pool - var ( - minTipBig *big.Int - baseFeeBig *big.Int - ) - if filter.MinTip != nil { - minTipBig = filter.MinTip.ToBig() - } - if filter.BaseFee != nil { - baseFeeBig = filter.BaseFee.ToBig() - } pending := make(map[common.Address][]*txpool.LazyTransaction, len(pool.pending)) for addr, list := range pool.pending { txs := list.Flatten() // If the miner requests tip enforcement, cap the lists now - if minTipBig != nil || filter.GasLimitCap != 0 { + if filter.MinTip != nil || filter.GasLimitCap != 0 { for i, tx := range txs { - if minTipBig != nil { - if tx.EffectiveGasTipIntCmp(minTipBig, baseFeeBig) < 0 { + if filter.MinTip != nil { + if tx.EffectiveGasTipIntCmp(filter.MinTip, filter.BaseFee) < 0 { txs = txs[:i] break } @@ -655,7 +633,7 @@ func (pool *LegacyPool) validateAuth(tx *types.Transaction) error { if pending := pool.pending[auth]; pending != nil { count += pending.Len() } - if queue := pool.queue[auth]; queue != nil { + if queue, ok := pool.queue.get(auth); ok { count += queue.Len() } if count > 1 { @@ -702,7 +680,7 @@ func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) { // only by this subpool until all transactions are evicted var ( _, hasPending = pool.pending[from] - _, hasQueued = pool.queue[from] + _, hasQueued = pool.queue.get(from) ) if !hasPending && !hasQueued { if err := pool.reserver.Hold(from); err != nil { @@ -801,7 +779,7 @@ func (pool *LegacyPool) add(tx *types.Transaction) (replaced bool, err error) { log.Trace("Pooled new executable transaction", "hash", hash, "from", from, "to", tx.To()) // Successful promotion, bump the heartbeat - pool.beats[from] = time.Now() + pool.queue.bump(from) return old != nil, nil } // New transaction isn't replacing a pending one, push into queue @@ -826,7 +804,7 @@ func (pool *LegacyPool) isGapped(from common.Address, tx *types.Transaction) boo } // The transaction has a nonce gap with pending list, it's only considered // as executable if transactions in queue can fill up the nonce gap. - queue, ok := pool.queue[from] + queue, ok := pool.queue.get(from) if !ok { return true } @@ -842,25 +820,12 @@ func (pool *LegacyPool) isGapped(from common.Address, tx *types.Transaction) boo // // Note, this method assumes the pool lock is held! func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, addAll bool) (bool, error) { - // Try to insert the transaction into the future queue - from, _ := types.Sender(pool.signer, tx) // already validated - if pool.queue[from] == nil { - pool.queue[from] = newList(false) + replaced, err := pool.queue.add(tx) + if err != nil { + return false, err } - inserted, old := pool.queue[from].Add(tx, pool.config.PriceBump) - if !inserted { - // An older transaction was better, discard this - queuedDiscardMeter.Mark(1) - return false, txpool.ErrReplaceUnderpriced - } - // Discard any previous transaction and mark this - if old != nil { - pool.all.Remove(old.Hash()) - pool.priced.Removed(1) - queuedReplaceMeter.Mark(1) - } else { - // Nothing was replaced, bump the queued counter - queuedGauge.Inc(1) + if replaced != nil { + pool.removeTx(*replaced, true, true) } // If the transaction isn't in lookup set but it's expected to be there, // show the error log. @@ -871,11 +836,7 @@ func (pool *LegacyPool) enqueueTx(hash common.Hash, tx *types.Transaction, addAl pool.all.Add(tx) pool.priced.Put(tx) } - // If we never record the heartbeat, do it right now. - if _, exist := pool.beats[from]; !exist { - pool.beats[from] = time.Now() - } - return old != nil, nil + return replaced != nil, nil } // promoteTx adds a transaction to the pending (processable) list of transactions @@ -886,6 +847,7 @@ func (pool *LegacyPool) promoteTx(addr common.Address, hash common.Hash, tx *typ // Try to insert the transaction into the pending queue if pool.pending[addr] == nil { pool.pending[addr] = newList(true) + pendingAddrsGauge.Inc(1) } list := pool.pending[addr] @@ -910,7 +872,7 @@ func (pool *LegacyPool) promoteTx(addr common.Address, hash common.Hash, tx *typ pool.pendingNonces.set(addr, tx.Nonce()+1) // Successful promotion, bump the heartbeat - pool.beats[addr] = time.Now() + pool.queue.bump(addr) return true } @@ -995,17 +957,24 @@ func (pool *LegacyPool) Add(txs []*types.Transaction, sync bool) []error { // addTxsLocked attempts to queue a batch of transactions if they are valid. // The transaction pool lock must be held. +// Returns the error for each tx, and the set of accounts that might became promotable. func (pool *LegacyPool) addTxsLocked(txs []*types.Transaction) ([]error, *accountSet) { - dirty := newAccountSet(pool.signer) - errs := make([]error, len(txs)) + var ( + dirty = newAccountSet(pool.signer) + errs = make([]error, len(txs)) + valid int64 + ) for i, tx := range txs { replaced, err := pool.add(tx) errs[i] = err - if err == nil && !replaced { - dirty.addTx(tx) + if err == nil { + if !replaced { + dirty.addTx(tx) + } + valid++ } } - validTxMeter.Mark(int64(len(dirty.accounts))) + validTxMeter.Mark(valid) return errs, dirty } @@ -1023,7 +992,7 @@ func (pool *LegacyPool) Status(hash common.Hash) txpool.TxStatus { if txList := pool.pending[from]; txList != nil && txList.txs.items[tx.Nonce()] != nil { return txpool.TxStatusPending - } else if txList := pool.queue[from]; txList != nil && txList.txs.items[tx.Nonce()] != nil { + } else if txList, ok := pool.queue.get(from); ok && txList.txs.items[tx.Nonce()] != nil { return txpool.TxStatusQueued } return txpool.TxStatusUnknown @@ -1100,7 +1069,7 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo defer func() { var ( _, hasPending = pool.pending[addr] - _, hasQueued = pool.queue[addr] + _, hasQueued = pool.queue.get(addr) ) if !hasPending && !hasQueued { pool.reserver.Release(addr) @@ -1118,6 +1087,7 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo // If no more pending transactions are left, remove the list if pending.Empty() { delete(pool.pending, addr) + pendingAddrsGauge.Dec(1) } // Postpone any invalidated transactions for _, tx := range invalids { @@ -1132,16 +1102,7 @@ func (pool *LegacyPool) removeTx(hash common.Hash, outofbound bool, unreserve bo } } // Transaction is in the future queue - if future := pool.queue[addr]; future != nil { - if removed, _ := future.Remove(tx); removed { - // Reduce the queued counter - queuedGauge.Dec(1) - } - if future.Empty() { - delete(pool.queue, addr) - delete(pool.beats, addr) - } - } + pool.queue.remove(addr, tx) return 0 } @@ -1289,10 +1250,7 @@ func (pool *LegacyPool) runReorg(done chan struct{}, reset *txpoolResetRequest, } } // Reset needs promote for all addresses - promoteAddrs = make([]common.Address, 0, len(pool.queue)) - for addr := range pool.queue { - promoteAddrs = append(promoteAddrs, addr) - } + promoteAddrs = pool.queue.addresses() } // Check for pending transactions for every account that sent new ones promoted := pool.promoteExecutables(promoteAddrs) @@ -1446,60 +1404,29 @@ func (pool *LegacyPool) reset(oldHead, newHead *types.Header) { // future queue to the set of pending transactions. During this process, all // invalidated transactions (low nonce, low balance) are deleted. func (pool *LegacyPool) promoteExecutables(accounts []common.Address) []*types.Transaction { - // Track the promoted transactions to broadcast them at once - var promoted []*types.Transaction - - // Iterate over all accounts and promote any executable transactions gasLimit := pool.currentHead.Load().GasLimit - for _, addr := range accounts { - list := pool.queue[addr] - if list == nil { - continue // Just in case someone calls with a non existing account - } - // Drop all transactions that are deemed too old (low nonce) - forwards := list.Forward(pool.currentState.GetNonce(addr)) - for _, tx := range forwards { - pool.all.Remove(tx.Hash()) - } - log.Trace("Removed old queued transactions", "count", len(forwards)) - // Drop all transactions that are too costly (low balance or out of gas) - drops, _ := list.Filter(pool.currentState.GetBalance(addr), gasLimit) - for _, tx := range drops { - pool.all.Remove(tx.Hash()) - } - log.Trace("Removed unpayable queued transactions", "count", len(drops)) - queuedNofundsMeter.Mark(int64(len(drops))) + promotable, dropped, removedAddresses := pool.queue.promoteExecutables(accounts, gasLimit, pool.currentState, pool.pendingNonces) - // Gather all executable transactions and promote them - readies := list.Ready(pool.pendingNonces.get(addr)) - for _, tx := range readies { - hash := tx.Hash() - if pool.promoteTx(addr, hash, tx) { - promoted = append(promoted, tx) - } + // promote all promotable transactions + promoted := make([]*types.Transaction, 0, len(promotable)) + for _, tx := range promotable { + from, _ := pool.signer.Sender(tx) + if pool.promoteTx(from, tx.Hash(), tx) { + promoted = append(promoted, tx) } - log.Trace("Promoted queued transactions", "count", len(promoted)) - queuedGauge.Dec(int64(len(readies))) + } - // Drop all transactions over the allowed limit - var caps = list.Cap(int(pool.config.AccountQueue)) - for _, tx := range caps { - hash := tx.Hash() - pool.all.Remove(hash) - log.Trace("Removed cap-exceeding queued transaction", "hash", hash) - } - queuedRateLimitMeter.Mark(int64(len(caps))) - // Mark all the items dropped as removed - pool.priced.Removed(len(forwards) + len(drops) + len(caps)) - queuedGauge.Dec(int64(len(forwards) + len(drops) + len(caps))) + // remove all removable transactions + for _, hash := range dropped { + pool.all.Remove(hash) + } + pool.priced.Removed(len(dropped)) - // Delete the entire queue entry if it became empty. - if list.Empty() { - delete(pool.queue, addr) - delete(pool.beats, addr) - if _, ok := pool.pending[addr]; !ok { - pool.reserver.Release(addr) - } + // release all accounts that have no more transactions in the pool + for _, addr := range removedAddresses { + _, hasPending := pool.pending[addr] + if !hasPending { + pool.reserver.Release(addr) } } return promoted @@ -1589,43 +1516,18 @@ func (pool *LegacyPool) truncatePending() { // truncateQueue drops the oldest transactions in the queue if the pool is above the global queue limit. func (pool *LegacyPool) truncateQueue() { - queued := uint64(0) - for _, list := range pool.queue { - queued += uint64(list.Len()) - } - if queued <= pool.config.GlobalQueue { - return + removed, removedAddresses := pool.queue.truncate() + + // Remove all removable transactions from the lookup and global price list + for _, hash := range removed { + pool.all.Remove(hash) } + pool.priced.Removed(len(removed)) - // Sort all accounts with queued transactions by heartbeat - addresses := make(addressesByHeartbeat, 0, len(pool.queue)) - for addr := range pool.queue { - addresses = append(addresses, addressByHeartbeat{addr, pool.beats[addr]}) - } - sort.Sort(sort.Reverse(addresses)) - - // Drop transactions until the total is below the limit - for drop := queued - pool.config.GlobalQueue; drop > 0 && len(addresses) > 0; { - addr := addresses[len(addresses)-1] - list := pool.queue[addr.address] - - addresses = addresses[:len(addresses)-1] - - // Drop all transactions if they are less than the overflow - if size := uint64(list.Len()); size <= drop { - for _, tx := range list.Flatten() { - pool.removeTx(tx.Hash(), true, true) - } - drop -= size - queuedRateLimitMeter.Mark(int64(size)) - continue - } - // Otherwise drop only last few transactions - txs := list.Flatten() - for i := len(txs) - 1; i >= 0 && drop > 0; i-- { - pool.removeTx(txs[i].Hash(), true, true) - drop-- - queuedRateLimitMeter.Mark(1) + for _, addr := range removedAddresses { + _, hasPending := pool.pending[addr] + if !hasPending { + pool.reserver.Release(addr) } } } @@ -1683,25 +1585,14 @@ func (pool *LegacyPool) demoteUnexecutables() { // Delete the entire pending entry if it became empty. if list.Empty() { delete(pool.pending, addr) - if _, ok := pool.queue[addr]; !ok { + pendingAddrsGauge.Dec(1) + if _, ok := pool.queue.get(addr); !ok { pool.reserver.Release(addr) } } } } -// addressByHeartbeat is an account address tagged with its last activity timestamp. -type addressByHeartbeat struct { - address common.Address - heartbeat time.Time -} - -type addressesByHeartbeat []addressByHeartbeat - -func (a addressesByHeartbeat) Len() int { return len(a) } -func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } -func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } - // accountSet is simply a set of addresses to check for existence, and a signer // capable of deriving addresses from transactions. type accountSet struct { @@ -1942,18 +1833,25 @@ func (pool *LegacyPool) Clear() { // acquire the subpool lock until the transaction addition is completed. for addr := range pool.pending { - if _, ok := pool.queue[addr]; !ok { + if _, ok := pool.queue.get(addr); !ok { pool.reserver.Release(addr) } } - for addr := range pool.queue { + for _, addr := range pool.queue.addresses() { pool.reserver.Release(addr) } pool.all.Clear() pool.priced.Reheap() pool.pending = make(map[common.Address]*list) - pool.queue = make(map[common.Address]*list) + pool.queue = newQueue(pool.config, pool.signer) pool.pendingNonces = newNoncer(pool.currentState) + + // Reset gauges + pendingGauge.Update(0) + queuedGauge.Update(0) + slotsGauge.Update(0) + pendingAddrsGauge.Update(0) + queuedAddrsGauge.Update(0) } // HasPendingAuth returns a flag indicating whether there are pending diff --git a/core/txpool/legacypool/legacypool_test.go b/core/txpool/legacypool/legacypool_test.go index 1ba080b749..fb994d8208 100644 --- a/core/txpool/legacypool/legacypool_test.go +++ b/core/txpool/legacypool/legacypool_test.go @@ -466,8 +466,8 @@ func TestQueue(t *testing.T) { if _, ok := pool.pending[from].txs.items[tx.Nonce()]; ok { t.Error("expected transaction to be in tx pool") } - if len(pool.queue) > 0 { - t.Error("expected transaction queue to be empty. is", len(pool.queue)) + if len(pool.queue.queued) > 0 { + t.Error("expected transaction queue to be empty. is", len(pool.queue.queued)) } } @@ -492,8 +492,8 @@ func TestQueue2(t *testing.T) { if len(pool.pending) != 1 { t.Error("expected pending length to be 1, got", len(pool.pending)) } - if pool.queue[from].Len() != 2 { - t.Error("expected len(queue) == 2, got", pool.queue[from].Len()) + if list, _ := pool.queue.get(from); list.Len() != 2 { + t.Error("expected len(queue) == 2, got", list.Len()) } } @@ -639,8 +639,8 @@ func TestMissingNonce(t *testing.T) { if len(pool.pending) != 0 { t.Error("expected 0 pending transactions, got", len(pool.pending)) } - if pool.queue[addr].Len() != 1 { - t.Error("expected 1 queued transaction, got", pool.queue[addr].Len()) + if list, _ := pool.queue.get(addr); list.Len() != 1 { + t.Error("expected 1 queued transaction, got", list.Len()) } if pool.all.Count() != 1 { t.Error("expected 1 total transactions, got", pool.all.Count()) @@ -712,8 +712,8 @@ func TestDropping(t *testing.T) { if pool.pending[account].Len() != 3 { t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) } - if pool.queue[account].Len() != 3 { - t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) + if list, _ := pool.queue.get(account); list.Len() != 3 { + t.Errorf("queued transaction mismatch: have %d, want %d", list.Len(), 3) } if pool.all.Count() != 6 { t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) @@ -722,8 +722,8 @@ func TestDropping(t *testing.T) { if pool.pending[account].Len() != 3 { t.Errorf("pending transaction mismatch: have %d, want %d", pool.pending[account].Len(), 3) } - if pool.queue[account].Len() != 3 { - t.Errorf("queued transaction mismatch: have %d, want %d", pool.queue[account].Len(), 3) + if list, _ := pool.queue.get(account); list.Len() != 3 { + t.Errorf("queued transaction mismatch: have %d, want %d", list.Len(), 3) } if pool.all.Count() != 6 { t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), 6) @@ -741,13 +741,14 @@ func TestDropping(t *testing.T) { if _, ok := pool.pending[account].txs.items[tx2.Nonce()]; ok { t.Errorf("out-of-fund pending transaction present: %v", tx1) } - if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { + list, _ := pool.queue.get(account) + if _, ok := list.txs.items[tx10.Nonce()]; !ok { t.Errorf("funded queued transaction missing: %v", tx10) } - if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; !ok { + if _, ok := list.txs.items[tx11.Nonce()]; !ok { t.Errorf("funded queued transaction missing: %v", tx10) } - if _, ok := pool.queue[account].txs.items[tx12.Nonce()]; ok { + if _, ok := list.txs.items[tx12.Nonce()]; ok { t.Errorf("out-of-fund queued transaction present: %v", tx11) } if pool.all.Count() != 4 { @@ -763,10 +764,11 @@ func TestDropping(t *testing.T) { if _, ok := pool.pending[account].txs.items[tx1.Nonce()]; ok { t.Errorf("over-gased pending transaction present: %v", tx1) } - if _, ok := pool.queue[account].txs.items[tx10.Nonce()]; !ok { + list, _ = pool.queue.get(account) + if _, ok := list.txs.items[tx10.Nonce()]; !ok { t.Errorf("funded queued transaction missing: %v", tx10) } - if _, ok := pool.queue[account].txs.items[tx11.Nonce()]; ok { + if _, ok := list.txs.items[tx11.Nonce()]; ok { t.Errorf("over-gased queued transaction present: %v", tx11) } if pool.all.Count() != 2 { @@ -820,8 +822,8 @@ func TestPostponing(t *testing.T) { if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs)) } - if len(pool.queue) != 0 { - t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) + if len(pool.queue.addresses()) != 0 { + t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue.addresses()), 0) } if pool.all.Count() != len(txs) { t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) @@ -830,8 +832,8 @@ func TestPostponing(t *testing.T) { if pending := pool.pending[accs[0]].Len() + pool.pending[accs[1]].Len(); pending != len(txs) { t.Errorf("pending transaction mismatch: have %d, want %d", pending, len(txs)) } - if len(pool.queue) != 0 { - t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue), 0) + if len(pool.queue.addresses()) != 0 { + t.Errorf("queued accounts mismatch: have %d, want %d", len(pool.queue.addresses()), 0) } if pool.all.Count() != len(txs) { t.Errorf("total transaction mismatch: have %d, want %d", pool.all.Count(), len(txs)) @@ -847,7 +849,8 @@ func TestPostponing(t *testing.T) { if _, ok := pool.pending[accs[0]].txs.items[txs[0].Nonce()]; !ok { t.Errorf("tx %d: valid and funded transaction missing from pending pool: %v", 0, txs[0]) } - if _, ok := pool.queue[accs[0]].txs.items[txs[0].Nonce()]; ok { + list, _ := pool.queue.get(accs[0]) + if _, ok := list.txs.items[txs[0].Nonce()]; ok { t.Errorf("tx %d: valid and funded transaction present in future queue: %v", 0, txs[0]) } for i, tx := range txs[1:100] { @@ -855,14 +858,14 @@ func TestPostponing(t *testing.T) { if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok { t.Errorf("tx %d: valid but future transaction present in pending pool: %v", i+1, tx) } - if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; !ok { + if _, ok := list.txs.items[tx.Nonce()]; !ok { t.Errorf("tx %d: valid but future transaction missing from future queue: %v", i+1, tx) } } else { if _, ok := pool.pending[accs[0]].txs.items[tx.Nonce()]; ok { t.Errorf("tx %d: out-of-fund transaction present in pending pool: %v", i+1, tx) } - if _, ok := pool.queue[accs[0]].txs.items[tx.Nonce()]; ok { + if _, ok := list.txs.items[tx.Nonce()]; ok { t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", i+1, tx) } } @@ -872,13 +875,14 @@ func TestPostponing(t *testing.T) { if pool.pending[accs[1]] != nil { t.Errorf("invalidated account still has pending transactions") } + list, _ = pool.queue.get(accs[1]) for i, tx := range txs[100:] { if i%2 == 1 { - if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; !ok { + if _, ok := list.txs.items[tx.Nonce()]; !ok { t.Errorf("tx %d: valid but future transaction missing from future queue: %v", 100+i, tx) } } else { - if _, ok := pool.queue[accs[1]].txs.items[tx.Nonce()]; ok { + if _, ok := list.txs.items[tx.Nonce()]; ok { t.Errorf("tx %d: out-of-fund transaction present in future queue: %v", 100+i, tx) } } @@ -963,13 +967,14 @@ func TestQueueAccountLimiting(t *testing.T) { if len(pool.pending) != 0 { t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, len(pool.pending), 0) } + list, _ := pool.queue.get(account) if i <= testTxPoolConfig.AccountQueue { - if pool.queue[account].Len() != int(i) { - t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), i) + if list.Len() != int(i) { + t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, list.Len(), i) } } else { - if pool.queue[account].Len() != int(testTxPoolConfig.AccountQueue) { - t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, pool.queue[account].Len(), testTxPoolConfig.AccountQueue) + if list.Len() != int(testTxPoolConfig.AccountQueue) { + t.Errorf("tx %d: queue limit mismatch: have %d, want %d", i, list.Len(), testTxPoolConfig.AccountQueue) } } } @@ -1020,7 +1025,7 @@ func TestQueueGlobalLimiting(t *testing.T) { pool.addRemotesSync(txs) queued := 0 - for addr, list := range pool.queue { + for addr, list := range pool.queue.queued { if list.Len() > int(config.AccountQueue) { t.Errorf("addr %x: queued accounts overflown allowance: %d > %d", addr, list.Len(), config.AccountQueue) } @@ -1179,8 +1184,8 @@ func TestPendingLimiting(t *testing.T) { if pool.pending[account].Len() != int(i)+1 { t.Errorf("tx %d: pending pool size mismatch: have %d, want %d", i, pool.pending[account].Len(), i+1) } - if len(pool.queue) != 0 { - t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, pool.queue[account].Len(), 0) + if len(pool.queue.addresses()) != 0 { + t.Errorf("tx %d: queue size mismatch: have %d, want %d", i, len(pool.queue.addresses()), 0) } } if pool.all.Count() != int(testTxPoolConfig.AccountQueue+5) { @@ -2292,8 +2297,8 @@ func TestSetCodeTransactions(t *testing.T) { pending: 1, run: func(name string) { aa := common.Address{0xaa, 0xaa} - statedb.SetCode(addrA, append(types.DelegationPrefix, aa.Bytes()...)) - statedb.SetCode(aa, []byte{byte(vm.ADDRESS), byte(vm.PUSH0), byte(vm.SSTORE)}) + statedb.SetCode(addrA, append(types.DelegationPrefix, aa.Bytes()...), tracing.CodeChangeUnspecified) + statedb.SetCode(aa, []byte{byte(vm.ADDRESS), byte(vm.PUSH0), byte(vm.SSTORE)}, tracing.CodeChangeUnspecified) // Send gapped transaction, it should be rejected. if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1), keyA)); !errors.Is(err, ErrOutOfOrderTxFromDelegated) { @@ -2317,7 +2322,7 @@ func TestSetCodeTransactions(t *testing.T) { } // Reset the delegation, avoid leaking state into the other tests - statedb.SetCode(addrA, nil) + statedb.SetCode(addrA, nil, tracing.CodeChangeUnspecified) }, }, { @@ -2583,7 +2588,7 @@ func TestSetCodeTransactionsReorg(t *testing.T) { } // Simulate the chain moving blockchain.statedb.SetNonce(addrA, 1, tracing.NonceChangeAuthorization) - blockchain.statedb.SetCode(addrA, types.AddressToDelegation(auth.Address)) + blockchain.statedb.SetCode(addrA, types.AddressToDelegation(auth.Address), tracing.CodeChangeUnspecified) <-pool.requestReset(nil, nil) // Set an authorization for 0x00 auth, _ = types.SignSetCode(keyA, types.SetCodeAuthorization{ @@ -2601,7 +2606,7 @@ func TestSetCodeTransactionsReorg(t *testing.T) { } // Simulate the chain moving blockchain.statedb.SetNonce(addrA, 2, tracing.NonceChangeAuthorization) - blockchain.statedb.SetCode(addrA, nil) + blockchain.statedb.SetCode(addrA, nil, tracing.CodeChangeUnspecified) <-pool.requestReset(nil, nil) // Now send two transactions from addrA if err := pool.addRemoteSync(pricedTransaction(2, 100000, big.NewInt(1000), keyA)); err != nil { diff --git a/core/txpool/legacypool/list.go b/core/txpool/legacypool/list.go index 736c28ec4a..0c9f13c62f 100644 --- a/core/txpool/legacypool/list.go +++ b/core/txpool/legacypool/list.go @@ -323,15 +323,22 @@ func (l *list) Add(tx *types.Transaction, priceBump uint64) (bool, *types.Transa if tx.GasFeeCapIntCmp(thresholdFeeCap) < 0 || tx.GasTipCapIntCmp(thresholdTip) < 0 { return false, nil } - // Old is being replaced, subtract old cost - l.subTotalCost([]*types.Transaction{old}) } // Add new tx cost to totalcost cost, overflow := uint256.FromBig(tx.Cost()) if overflow { return false, nil } - l.totalcost.Add(l.totalcost, cost) + total, overflow := new(uint256.Int).AddOverflow(l.totalcost, cost) + if overflow { + return false, nil + } + l.totalcost = total + + // Old is being replaced, subtract old cost + if old != nil { + l.subTotalCost([]*types.Transaction{old}) + } // Otherwise overwrite the old transaction with the current one l.txs.Put(tx) @@ -475,7 +482,7 @@ func (l *list) subTotalCost(txs []*types.Transaction) { // then the heap is sorted based on the effective tip based on the given base fee. // If baseFee is nil then the sorting is based on gasFeeCap. type priceHeap struct { - baseFee *big.Int // heap should always be re-sorted after baseFee is changed + baseFee *uint256.Int // heap should always be re-sorted after baseFee is changed list []*types.Transaction } @@ -677,6 +684,10 @@ func (l *pricedList) Reheap() { // SetBaseFee updates the base fee and triggers a re-heap. Note that Removed is not // necessary to call right before SetBaseFee when processing a new block. func (l *pricedList) SetBaseFee(baseFee *big.Int) { - l.urgent.baseFee = baseFee + base := new(uint256.Int) + if baseFee != nil { + base.SetFromBig(baseFee) + } + l.urgent.baseFee = base l.Reheap() } diff --git a/core/txpool/legacypool/queue.go b/core/txpool/legacypool/queue.go new file mode 100644 index 0000000000..918a219ab6 --- /dev/null +++ b/core/txpool/legacypool/queue.go @@ -0,0 +1,278 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package legacypool + +import ( + "sort" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/txpool" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/log" +) + +// queue manages nonce-gapped transactions that have been validated but are +// not yet processable. +type queue struct { + config Config + signer types.Signer + queued map[common.Address]*list // Queued but non-processable transactions + beats map[common.Address]time.Time // Last heartbeat from each known account +} + +func newQueue(config Config, signer types.Signer) *queue { + return &queue{ + signer: signer, + config: config, + queued: make(map[common.Address]*list), + beats: make(map[common.Address]time.Time), + } +} + +// evictList returns the hashes of transactions that are old enough to be evicted. +func (q *queue) evictList() []common.Hash { + var removed []common.Hash + for addr, list := range q.queued { + if time.Since(q.beats[addr]) > q.config.Lifetime { + for _, tx := range list.Flatten() { + removed = append(removed, tx.Hash()) + } + } + } + queuedEvictionMeter.Mark(int64(len(removed))) + return removed +} + +func (q *queue) stats() int { + queued := 0 + for _, list := range q.queued { + queued += list.Len() + } + return queued +} + +func (q *queue) content() map[common.Address][]*types.Transaction { + queued := make(map[common.Address][]*types.Transaction, len(q.queued)) + for addr, list := range q.queued { + queued[addr] = list.Flatten() + } + return queued +} + +func (q *queue) contentFrom(addr common.Address) []*types.Transaction { + var queued []*types.Transaction + if list, ok := q.get(addr); ok { + queued = list.Flatten() + } + return queued +} + +func (q *queue) get(addr common.Address) (*list, bool) { + l, ok := q.queued[addr] + return l, ok +} + +func (q *queue) bump(addr common.Address) { + q.beats[addr] = time.Now() +} + +func (q *queue) addresses() []common.Address { + addrs := make([]common.Address, 0, len(q.queued)) + for addr := range q.queued { + addrs = append(addrs, addr) + } + return addrs +} + +func (q *queue) remove(addr common.Address, tx *types.Transaction) { + if future := q.queued[addr]; future != nil { + if txOld := future.txs.Get(tx.Nonce()); txOld != nil && txOld.Hash() != tx.Hash() { + // Edge case, a different transaction + // with the same nonce is in the queued, just ignore + return + } + if removed, _ := future.Remove(tx); removed { + // Reduce the queued counter + queuedGauge.Dec(1) + } + if future.Empty() { + delete(q.queued, addr) + delete(q.beats, addr) + queuedAddrsGauge.Dec(1) + } + } +} + +func (q *queue) add(tx *types.Transaction) (*common.Hash, error) { + // Try to insert the transaction into the future queue + from, _ := types.Sender(q.signer, tx) // already validated + if q.queued[from] == nil { + q.queued[from] = newList(false) + queuedAddrsGauge.Inc(1) + } + inserted, old := q.queued[from].Add(tx, q.config.PriceBump) + if !inserted { + // An older transaction was better, discard this + queuedDiscardMeter.Mark(1) + return nil, txpool.ErrReplaceUnderpriced + } + // If we never record the heartbeat, do it right now. + if _, exist := q.beats[from]; !exist { + q.beats[from] = time.Now() + } + if old == nil { + // Nothing was replaced, bump the queued counter + queuedGauge.Inc(1) + return nil, nil + } + h := old.Hash() + // Transaction was replaced, bump the replacement counter + queuedReplaceMeter.Mark(1) + return &h, nil +} + +// promoteExecutables iterates over all accounts with queued transactions, selecting +// for promotion any that are now executable. It also drops any transactions that are +// deemed too old (nonce too low) or too costly (insufficient funds or over gas limit). +// +// Returns three lists: +// - all transactions that were removed from the queue and selected for promotion; +// - all other transactions that were removed from the queue and dropped; +// - the list of addresses removed. +func (q *queue) promoteExecutables(accounts []common.Address, gasLimit uint64, currentState *state.StateDB, nonces *noncer) ([]*types.Transaction, []common.Hash, []common.Address) { + // Track the promotable transactions to broadcast them at once + var ( + promotable []*types.Transaction + dropped []common.Hash + removedAddresses []common.Address + ) + // Iterate over all accounts and promote any executable transactions + for _, addr := range accounts { + list := q.queued[addr] + if list == nil { + continue // Just in case someone calls with a non existing account + } + // Drop all transactions that are deemed too old (low nonce) + forwards := list.Forward(currentState.GetNonce(addr)) + for _, tx := range forwards { + dropped = append(dropped, tx.Hash()) + } + log.Trace("Removing old queued transactions", "count", len(forwards)) + + // Drop all transactions that are too costly (low balance or out of gas) + drops, _ := list.Filter(currentState.GetBalance(addr), gasLimit) + for _, tx := range drops { + dropped = append(dropped, tx.Hash()) + } + log.Trace("Removing unpayable queued transactions", "count", len(drops)) + queuedNofundsMeter.Mark(int64(len(drops))) + + // Gather all executable transactions and promote them + readies := list.Ready(nonces.get(addr)) + promotable = append(promotable, readies...) + log.Trace("Promoting queued transactions", "count", len(promotable)) + queuedGauge.Dec(int64(len(readies))) + + // Drop all transactions over the allowed limit + var caps = list.Cap(int(q.config.AccountQueue)) + for _, tx := range caps { + hash := tx.Hash() + dropped = append(dropped, hash) + log.Trace("Removing cap-exceeding queued transaction", "hash", hash) + } + queuedRateLimitMeter.Mark(int64(len(caps))) + + // Delete the entire queue entry if it became empty. + if list.Empty() { + delete(q.queued, addr) + delete(q.beats, addr) + queuedAddrsGauge.Dec(1) + removedAddresses = append(removedAddresses, addr) + } + } + queuedGauge.Dec(int64(len(dropped))) + return promotable, dropped, removedAddresses +} + +// truncate drops the oldest transactions from the queue until the total +// number is below the configured limit. Returns the hashes of all dropped +// transactions and the addresses of accounts that became empty due to +// the truncation. +func (q *queue) truncate() ([]common.Hash, []common.Address) { + queued := uint64(0) + for _, list := range q.queued { + queued += uint64(list.Len()) + } + if queued <= q.config.GlobalQueue { + return nil, nil + } + + // Sort all accounts with queued transactions by heartbeat + addresses := make(addressesByHeartbeat, 0, len(q.queued)) + for addr := range q.queued { + addresses = append(addresses, addressByHeartbeat{addr, q.beats[addr]}) + } + sort.Sort(sort.Reverse(addresses)) + + // Drop transactions until the total is below the limit + var ( + removed = make([]common.Hash, 0) + removedAddresses = make([]common.Address, 0) + ) + for drop := queued - q.config.GlobalQueue; drop > 0 && len(addresses) > 0; { + addr := addresses[len(addresses)-1] + list := q.queued[addr.address] + + addresses = addresses[:len(addresses)-1] + + // Drop all transactions if they are less than the overflow + if size := uint64(list.Len()); size <= drop { + for _, tx := range list.Flatten() { + q.remove(addr.address, tx) + removed = append(removed, tx.Hash()) + } + drop -= size + queuedRateLimitMeter.Mark(int64(size)) + removedAddresses = append(removedAddresses, addr.address) + continue + } + // Otherwise drop only last few transactions + txs := list.Flatten() + for i := len(txs) - 1; i >= 0 && drop > 0; i-- { + q.remove(addr.address, txs[i]) + removed = append(removed, txs[i].Hash()) + drop-- + queuedRateLimitMeter.Mark(1) + } + } + // No need to clear empty accounts, remove already does that + return removed, removedAddresses +} + +// addressByHeartbeat is an account address tagged with its last activity timestamp. +type addressByHeartbeat struct { + address common.Address + heartbeat time.Time +} + +type addressesByHeartbeat []addressByHeartbeat + +func (a addressesByHeartbeat) Len() int { return len(a) } +func (a addressesByHeartbeat) Less(i, j int) bool { return a[i].heartbeat.Before(a[j].heartbeat) } +func (a addressesByHeartbeat) Swap(i, j int) { a[i], a[j] = a[j], a[i] } diff --git a/core/txpool/locals/journal.go b/core/txpool/locals/journal.go index 46fd6de346..cd2be8a794 100644 --- a/core/txpool/locals/journal.go +++ b/core/txpool/locals/journal.go @@ -117,6 +117,25 @@ func (journal *journal) load(add func([]*types.Transaction) []error) error { return failure } +func (journal *journal) setupWriter() error { + if journal.writer != nil { + if err := journal.writer.Close(); err != nil { + return err + } + journal.writer = nil + } + + // Re-open the journal file for appending + // Use O_APPEND to ensure we always write to the end of the file + sink, err := os.OpenFile(journal.path, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644) + if err != nil { + return err + } + journal.writer = sink + + return nil +} + // insert adds the specified transaction to the local disk journal. func (journal *journal) insert(tx *types.Transaction) error { if journal.writer == nil { @@ -177,7 +196,6 @@ func (journal *journal) rotate(all map[common.Address]types.Transactions) error // close flushes the transaction journal contents to disk and closes the file. func (journal *journal) close() error { var err error - if journal.writer != nil { err = journal.writer.Close() journal.writer = nil diff --git a/core/txpool/locals/tx_tracker.go b/core/txpool/locals/tx_tracker.go index e08384ce71..bb178f175e 100644 --- a/core/txpool/locals/tx_tracker.go +++ b/core/txpool/locals/tx_tracker.go @@ -114,13 +114,14 @@ func (tracker *TxTracker) TrackAll(txs []*types.Transaction) { } // recheck checks and returns any transactions that needs to be resubmitted. -func (tracker *TxTracker) recheck(journalCheck bool) (resubmits []*types.Transaction, rejournal map[common.Address]types.Transactions) { +func (tracker *TxTracker) recheck(journalCheck bool) []*types.Transaction { tracker.mu.Lock() defer tracker.mu.Unlock() var ( numStales = 0 numOk = 0 + resubmits []*types.Transaction ) for sender, txs := range tracker.byAddr { // Wipe the stales @@ -141,7 +142,7 @@ func (tracker *TxTracker) recheck(journalCheck bool) (resubmits []*types.Transac } if journalCheck { // rejournal - rejournal = make(map[common.Address]types.Transactions) + rejournal := make(map[common.Address]types.Transactions) for _, tx := range tracker.all { addr, _ := types.Sender(tracker.signer, tx) rejournal[addr] = append(rejournal[addr], tx) @@ -153,10 +154,18 @@ func (tracker *TxTracker) recheck(journalCheck bool) (resubmits []*types.Transac return int(a.Nonce() - b.Nonce()) }) } + // Rejournal the tracker while holding the lock. No new transactions will + // be added to the old journal during this period, preventing any potential + // transaction loss. + if tracker.journal != nil { + if err := tracker.journal.rotate(rejournal); err != nil { + log.Warn("Transaction journal rotation failed", "err", err) + } + } } localGauge.Update(int64(len(tracker.all))) log.Debug("Tx tracker status", "need-resubmit", len(resubmits), "stale", numStales, "ok", numOk) - return resubmits, rejournal + return resubmits } // Start implements node.Lifecycle interface @@ -185,6 +194,12 @@ func (tracker *TxTracker) loop() { tracker.TrackAll(transactions) return nil }) + + // Setup the writer for the upcoming transactions + if err := tracker.journal.setupWriter(); err != nil { + log.Error("Failed to setup the journal writer", "err", err) + return + } defer tracker.journal.close() } var ( @@ -196,20 +211,15 @@ func (tracker *TxTracker) loop() { case <-tracker.shutdownCh: return case <-timer.C: - checkJournal := tracker.journal != nil && time.Since(lastJournal) > tracker.rejournal - resubmits, rejournal := tracker.recheck(checkJournal) + var rejournal bool + if tracker.journal != nil && time.Since(lastJournal) > tracker.rejournal { + rejournal, lastJournal = true, time.Now() + log.Debug("Rejournal the transaction tracker") + } + resubmits := tracker.recheck(rejournal) if len(resubmits) > 0 { tracker.pool.Add(resubmits, false) } - if checkJournal { - // Lock to prevent journal.rotate <-> journal.insert (via TrackAll) conflicts - tracker.mu.Lock() - lastJournal = time.Now() - if err := tracker.journal.rotate(rejournal); err != nil { - log.Warn("Transaction journal rotation failed", "err", err) - } - tracker.mu.Unlock() - } timer.Reset(recheckInterval) } } diff --git a/core/txpool/locals/tx_tracker_test.go b/core/txpool/locals/tx_tracker_test.go index 367fb6b6da..dde8754605 100644 --- a/core/txpool/locals/tx_tracker_test.go +++ b/core/txpool/locals/tx_tracker_test.go @@ -17,7 +17,11 @@ package locals import ( + "fmt" + "maps" "math/big" + "math/rand" + "path/filepath" "testing" "time" @@ -146,20 +150,59 @@ func TestResubmit(t *testing.T) { txsA := txs[:len(txs)/2] txsB := txs[len(txs)/2:] env.pool.Add(txsA, true) + pending, queued := env.pool.ContentFrom(address) if len(pending) != len(txsA) || len(queued) != 0 { t.Fatalf("Unexpected txpool content: %d, %d", len(pending), len(queued)) } env.tracker.TrackAll(txs) - resubmit, all := env.tracker.recheck(true) + resubmit := env.tracker.recheck(true) if len(resubmit) != len(txsB) { t.Fatalf("Unexpected transactions to resubmit, got: %d, want: %d", len(resubmit), len(txsB)) } - if len(all) == 0 || len(all[address]) == 0 { - t.Fatalf("Unexpected transactions being tracked, got: %d, want: %d", 0, len(txs)) - } - if len(all[address]) != len(txs) { - t.Fatalf("Unexpected transactions being tracked, got: %d, want: %d", len(all[address]), len(txs)) + env.tracker.mu.Lock() + allCopy := maps.Clone(env.tracker.all) + env.tracker.mu.Unlock() + + if len(allCopy) != len(txs) { + t.Fatalf("Unexpected transactions being tracked, got: %d, want: %d", len(allCopy), len(txs)) + } +} + +func TestJournal(t *testing.T) { + journalPath := filepath.Join(t.TempDir(), fmt.Sprintf("%d", rand.Int63())) + env := newTestEnv(t, 10, 0, journalPath) + defer env.close() + + env.tracker.Start() + defer env.tracker.Stop() + + txs := env.makeTxs(10) + txsA := txs[:len(txs)/2] + txsB := txs[len(txs)/2:] + env.pool.Add(txsA, true) + + pending, queued := env.pool.ContentFrom(address) + if len(pending) != len(txsA) || len(queued) != 0 { + t.Fatalf("Unexpected txpool content: %d, %d", len(pending), len(queued)) + } + env.tracker.TrackAll(txsA) + env.tracker.TrackAll(txsB) + env.tracker.recheck(true) // manually rejournal the tracker + + // Make sure all the transactions are properly journalled + trackerB := New(journalPath, time.Minute, gspec.Config, env.pool) + trackerB.journal.load(func(transactions []*types.Transaction) []error { + trackerB.TrackAll(transactions) + return nil + }) + + trackerB.mu.Lock() + allCopy := maps.Clone(trackerB.all) + trackerB.mu.Unlock() + + if len(allCopy) != len(txs) { + t.Fatalf("Unexpected transactions being tracked, got: %d, want: %d", len(allCopy), len(txs)) } } diff --git a/core/txpool/subpool.go b/core/txpool/subpool.go index f1f6056686..db099ddf98 100644 --- a/core/txpool/subpool.go +++ b/core/txpool/subpool.go @@ -78,8 +78,10 @@ type PendingFilter struct { BlobFee *uint256.Int // Minimum 4844 blobfee needed to include a blob transaction GasLimitCap uint64 // Maximum gas can be used for a single transaction execution (0 means no limit) - OnlyPlainTxs bool // Return only plain EVM transactions (peer-join announces, block space filling) - OnlyBlobTxs bool // Return only blob transactions (block blob-space filling) + // When BlobTxs true, return only blob transactions (block blob-space filling) + // when false, return only non-blob txs (peer-join announces, block space filling) + BlobTxs bool + BlobVersion byte // Blob tx version to include. 0 means pre-Osaka, 1 means Osaka and later } // TxMetadata denotes the metadata of a transaction. @@ -98,6 +100,9 @@ type SubPool interface { // to this particular subpool. Filter(tx *types.Transaction) bool + // FilterType returns whether the subpool supports the given transaction type. + FilterType(kind byte) bool + // Init sets the base parameters of the subpool, allowing it to load any saved // transactions from disk and also permitting internal maintenance routines to // start up. diff --git a/core/txpool/txpool.go b/core/txpool/txpool.go index b5470cd7fc..a314a83f1b 100644 --- a/core/txpool/txpool.go +++ b/core/txpool/txpool.go @@ -65,7 +65,6 @@ type BlockChain interface { type TxPool struct { subpools []SubPool // List of subpools for specialized transaction handling chain BlockChain - signer types.Signer stateLock sync.RWMutex // The lock for protecting state instance state *state.StateDB // Current state at the blockchain head @@ -98,7 +97,6 @@ func New(gasTip uint64, chain BlockChain, subpools []SubPool) (*TxPool, error) { pool := &TxPool{ subpools: subpools, chain: chain, - signer: types.LatestSigner(chain.Config()), state: statedb, quit: make(chan chan error), term: make(chan struct{}), @@ -491,3 +489,14 @@ func (p *TxPool) Clear() { subpool.Clear() } } + +// FilterType returns whether a transaction with the given type is supported +// (can be added) by the pool. +func (p *TxPool) FilterType(kind byte) bool { + for _, subpool := range p.subpools { + if subpool.FilterType(kind) { + return true + } + } + return false +} diff --git a/core/txpool/validation.go b/core/txpool/validation.go index d4f3401086..e0a333dfa5 100644 --- a/core/txpool/validation.go +++ b/core/txpool/validation.go @@ -22,7 +22,6 @@ import ( "math/big" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/misc/eip4844" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" @@ -117,6 +116,10 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types if _, err := types.Sender(signer, tx); err != nil { return fmt.Errorf("%w: %v", ErrInvalidSender, err) } + // Limit nonce to 2^64-1 per EIP-2681 + if tx.Nonce()+1 < tx.Nonce() { + return core.ErrNonceMax + } // Ensure the transaction has more gas than the bare minimum needed to cover // the transaction metadata intrGas, err := core.IntrinsicGas(tx.Data(), tx.AccessList(), tx.SetCodeAuthorizations(), tx.To() == nil, true, rules.IsIstanbul, rules.IsShanghai) @@ -127,7 +130,7 @@ func ValidateTransaction(tx *types.Transaction, head *types.Header, signer types return fmt.Errorf("%w: gas %v, minimum needed %v", core.ErrIntrinsicGas, tx.Gas(), intrGas) } // Ensure the transaction can cover floor data gas. - if opts.Config.IsPrague(head.Number, head.Time) { + if rules.IsPrague { floorDataGas, err := core.FloorDataGas(tx.Data()) if err != nil { return err @@ -157,6 +160,15 @@ func validateBlobTx(tx *types.Transaction, head *types.Header, opts *ValidationO if sidecar == nil { return errors.New("missing sidecar in blob transaction") } + // Ensure the sidecar is constructed with the correct version, consistent + // with the current fork. + version := types.BlobSidecarVersion0 + if opts.Config.IsOsaka(head.Number, head.Time) { + version = types.BlobSidecarVersion1 + } + if sidecar.Version != version { + return fmt.Errorf("unexpected sidecar version, want: %d, got: %d", version, sidecar.Version) + } // Ensure the blob fee cap satisfies the minimum blob gas price if tx.BlobGasFeeCapIntCmp(blobTxMinBlobGasPrice) < 0 { return fmt.Errorf("%w: blob fee cap %v, minimum needed %v", ErrTxGasPriceTooLow, tx.BlobGasFeeCap(), blobTxMinBlobGasPrice) @@ -167,9 +179,8 @@ func validateBlobTx(tx *types.Transaction, head *types.Header, opts *ValidationO if len(hashes) == 0 { return errors.New("blobless blob transaction") } - maxBlobs := eip4844.MaxBlobsPerBlock(opts.Config, head.Time) - if len(hashes) > maxBlobs { - return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), maxBlobs) + if len(hashes) > params.BlobTxMaxBlobs { + return fmt.Errorf("too many blobs in transaction: have %d, permitted %d", len(hashes), params.BlobTxMaxBlobs) } if len(sidecar.Blobs) != len(hashes) { return fmt.Errorf("invalid number of %d blobs compared to %d blob hashes", len(sidecar.Blobs), len(hashes)) @@ -178,35 +189,33 @@ func validateBlobTx(tx *types.Transaction, head *types.Header, opts *ValidationO return err } // Fork-specific sidecar checks, including proof verification. - if opts.Config.IsOsaka(head.Number, head.Time) { + if sidecar.Version == types.BlobSidecarVersion1 { return validateBlobSidecarOsaka(sidecar, hashes) + } else { + return validateBlobSidecarLegacy(sidecar, hashes) } - return validateBlobSidecarLegacy(sidecar, hashes) } func validateBlobSidecarLegacy(sidecar *types.BlobTxSidecar, hashes []common.Hash) error { - if sidecar.Version != types.BlobSidecarVersion0 { - return fmt.Errorf("invalid sidecar version pre-osaka: %v", sidecar.Version) - } if len(sidecar.Proofs) != len(hashes) { return fmt.Errorf("invalid number of %d blob proofs expected %d", len(sidecar.Proofs), len(hashes)) } for i := range sidecar.Blobs { if err := kzg4844.VerifyBlobProof(&sidecar.Blobs[i], sidecar.Commitments[i], sidecar.Proofs[i]); err != nil { - return fmt.Errorf("invalid blob %d: %v", i, err) + return fmt.Errorf("%w: invalid blob proof: %v", ErrKZGVerificationError, err) } } return nil } func validateBlobSidecarOsaka(sidecar *types.BlobTxSidecar, hashes []common.Hash) error { - if sidecar.Version != types.BlobSidecarVersion1 { - return fmt.Errorf("invalid sidecar version post-osaka: %v", sidecar.Version) - } if len(sidecar.Proofs) != len(hashes)*kzg4844.CellProofsPerBlob { return fmt.Errorf("invalid number of %d blob proofs expected %d", len(sidecar.Proofs), len(hashes)*kzg4844.CellProofsPerBlob) } - return kzg4844.VerifyCellProofs(sidecar.Blobs, sidecar.Commitments, sidecar.Proofs) + if err := kzg4844.VerifyCellProofs(sidecar.Blobs, sidecar.Commitments, sidecar.Proofs); err != nil { + return fmt.Errorf("%w: %v", ErrKZGVerificationError, err) + } + return nil } // ValidationOptionsWithState define certain differences between stateful transaction diff --git a/core/txpool/validation_test.go b/core/txpool/validation_test.go new file mode 100644 index 0000000000..3945b548c1 --- /dev/null +++ b/core/txpool/validation_test.go @@ -0,0 +1,115 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package txpool + +import ( + "crypto/ecdsa" + "errors" + "math" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" +) + +func TestValidateTransactionEIP2681(t *testing.T) { + key, err := crypto.GenerateKey() + if err != nil { + t.Fatal(err) + } + + head := &types.Header{ + Number: big.NewInt(1), + GasLimit: 5000000, + Time: 1, + Difficulty: big.NewInt(1), + } + + signer := types.LatestSigner(params.TestChainConfig) + + // Create validation options + opts := &ValidationOptions{ + Config: params.TestChainConfig, + Accept: 0xFF, // Accept all transaction types + MaxSize: 32 * 1024, + MaxBlobCount: 6, + MinTip: big.NewInt(0), + } + + tests := []struct { + name string + nonce uint64 + wantErr error + }{ + { + name: "normal nonce", + nonce: 42, + wantErr: nil, + }, + { + name: "max allowed nonce (2^64-2)", + nonce: math.MaxUint64 - 1, + wantErr: nil, + }, + { + name: "EIP-2681 nonce overflow (2^64-1)", + nonce: math.MaxUint64, + wantErr: core.ErrNonceMax, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + tx := createTestTransaction(key, tt.nonce) + err := ValidateTransaction(tx, head, signer, opts) + + if tt.wantErr == nil { + if err != nil { + t.Errorf("ValidateTransaction() error = %v, wantErr nil", err) + } + } else { + if err == nil { + t.Errorf("ValidateTransaction() error = nil, wantErr %v", tt.wantErr) + } else if !errors.Is(err, tt.wantErr) { + t.Errorf("ValidateTransaction() error = %v, wantErr %v", err, tt.wantErr) + } + } + }) + } +} + +// createTestTransaction creates a basic transaction for testing +func createTestTransaction(key *ecdsa.PrivateKey, nonce uint64) *types.Transaction { + to := common.HexToAddress("0x0000000000000000000000000000000000000001") + + txdata := &types.LegacyTx{ + Nonce: nonce, + To: &to, + Value: big.NewInt(1000), + Gas: 21000, + GasPrice: big.NewInt(1), + Data: nil, + } + + tx := types.NewTx(txdata) + signedTx, _ := types.SignTx(tx, types.HomesteadSigner{}, key) + return signedTx +} diff --git a/core/types/block.go b/core/types/block.go index da9614793a..c52c05a4c7 100644 --- a/core/types/block.go +++ b/core/types/block.go @@ -31,7 +31,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/rlp" - "github.com/ethereum/go-verkle" ) // A BlockNonce is a 64-bit hash which proves (combined with the @@ -61,13 +60,6 @@ func (n *BlockNonce) UnmarshalText(input []byte) error { return hexutil.UnmarshalFixedText("BlockNonce", input, n[:]) } -// ExecutionWitness represents the witness + proof used in a verkle context, -// to provide the ability to execute a block statelessly. -type ExecutionWitness struct { - StateDiff verkle.StateDiff `json:"stateDiff"` - VerkleProof *verkle.VerkleProof `json:"verkleProof"` -} - //go:generate go run github.com/fjl/gencodec -type Header -field-override headerMarshaling -out gen_header_json.go //go:generate go run ../../rlp/rlpgen -type Header -out gen_header_rlp.go @@ -209,11 +201,6 @@ type Block struct { transactions Transactions withdrawals Withdrawals - // witness is not an encoded part of the block body. - // It is held in Block in order for easy relaying to the places - // that process it. - witness *ExecutionWitness - // caches hash atomic.Pointer[common.Hash] size atomic.Uint64 @@ -240,7 +227,7 @@ type extblock struct { // // The receipt's bloom must already calculated for the block's bloom to be // correctly calculated. -func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher TrieHasher) *Block { +func NewBlock(header *Header, body *Body, receipts []*Receipt, hasher ListHasher) *Block { if body == nil { body = &Body{} } @@ -429,9 +416,6 @@ func (b *Block) BlobGasUsed() *uint64 { return blobGasUsed } -// ExecutionWitness returns the verkle execution witneess + proof for a block -func (b *Block) ExecutionWitness() *ExecutionWitness { return b.witness } - // Size returns the true RLP encoded storage size of the block, either by encoding // and returning it, or returning a previously cached value. func (b *Block) Size() uint64 { @@ -494,7 +478,6 @@ func (b *Block) WithSeal(header *Header) *Block { transactions: b.transactions, uncles: b.uncles, withdrawals: b.withdrawals, - witness: b.witness, } } @@ -506,7 +489,6 @@ func (b *Block) WithBody(body Body) *Block { transactions: slices.Clone(body.Transactions), uncles: make([]*Header, len(body.Uncles)), withdrawals: slices.Clone(body.Withdrawals), - witness: b.witness, } for i := range body.Uncles { block.uncles[i] = CopyHeader(body.Uncles[i]) @@ -514,16 +496,6 @@ func (b *Block) WithBody(body Body) *Block { return block } -func (b *Block) WithWitness(witness *ExecutionWitness) *Block { - return &Block{ - header: b.header, - transactions: b.transactions, - uncles: b.uncles, - withdrawals: b.withdrawals, - witness: witness, - } -} - // Hash returns the keccak256 hash of b's header. // The hash is computed on the first call and cached thereafter. func (b *Block) Hash() common.Hash { diff --git a/core/types/block_test.go b/core/types/block_test.go index 2130a2fcf3..5fa4756a50 100644 --- a/core/types/block_test.go +++ b/core/types/block_test.go @@ -263,9 +263,8 @@ var benchBuffer = bytes.NewBuffer(make([]byte, 0, 32000)) func BenchmarkEncodeBlock(b *testing.B) { block := makeBenchBlock() - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { benchBuffer.Reset() if err := rlp.Encode(benchBuffer, block); err != nil { b.Fatal(err) diff --git a/core/types/bloom9.go b/core/types/bloom9.go index 5a6e49c220..1d57e8e4bc 100644 --- a/core/types/bloom9.go +++ b/core/types/bloom9.go @@ -21,6 +21,7 @@ import ( "fmt" "math/big" + "github.com/ethereum/go-ethereum/common/bitutil" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/crypto" ) @@ -125,9 +126,7 @@ func MergeBloom(receipts Receipts) Bloom { for _, receipt := range receipts { if len(receipt.Logs) != 0 { bl := receipt.Bloom.Bytes() - for i := range bin { - bin[i] |= bl[i] - } + bitutil.ORBytes(bin[:], bin[:], bl) } } return bin diff --git a/core/types/bloom9_test.go b/core/types/bloom9_test.go index 07f6446a97..ceb6797e1f 100644 --- a/core/types/bloom9_test.go +++ b/core/types/bloom9_test.go @@ -78,7 +78,7 @@ func TestBloomExtensively(t *testing.T) { func BenchmarkBloom9(b *testing.B) { test := []byte("testestestest") - for i := 0; i < b.N; i++ { + for b.Loop() { Bloom9(test) } } @@ -86,7 +86,7 @@ func BenchmarkBloom9(b *testing.B) { func BenchmarkBloom9Lookup(b *testing.B) { toTest := []byte("testtest") bloom := new(Bloom) - for i := 0; i < b.N; i++ { + for b.Loop() { bloom.Test(toTest) } } @@ -128,7 +128,7 @@ func BenchmarkCreateBloom(b *testing.B) { } b.Run("small-createbloom", func(b *testing.B) { b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { for _, receipt := range rSmall { receipt.Bloom = CreateBloom(receipt) } @@ -144,7 +144,7 @@ func BenchmarkCreateBloom(b *testing.B) { }) b.Run("large-createbloom", func(b *testing.B) { b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { for _, receipt := range rLarge { receipt.Bloom = CreateBloom(receipt) } @@ -163,13 +163,11 @@ func BenchmarkCreateBloom(b *testing.B) { receipt.Bloom = CreateBloom(receipt) } b.ReportAllocs() - b.ResetTimer() var bl Bloom - for i := 0; i < b.N; i++ { + for b.Loop() { bl = MergeBloom(rSmall) } - b.StopTimer() var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") got := crypto.Keccak256Hash(bl.Bytes()) @@ -182,13 +180,11 @@ func BenchmarkCreateBloom(b *testing.B) { receipt.Bloom = CreateBloom(receipt) } b.ReportAllocs() - b.ResetTimer() var bl Bloom - for i := 0; i < b.N; i++ { + for b.Loop() { bl = MergeBloom(rLarge) } - b.StopTimer() var exp = common.HexToHash("c384c56ece49458a427c67b90fefe979ebf7104795be65dc398b280f24104949") got := crypto.Keccak256Hash(bl.Bytes()) diff --git a/core/types/hashes.go b/core/types/hashes.go index 05cfaeed74..22f1f946dc 100644 --- a/core/types/hashes.go +++ b/core/types/hashes.go @@ -45,4 +45,7 @@ var ( // EmptyVerkleHash is the known hash of an empty verkle trie. EmptyVerkleHash = common.Hash{} + + // EmptyBinaryHash is the known hash of an empty binary trie. + EmptyBinaryHash = common.Hash{} ) diff --git a/core/types/hashing.go b/core/types/hashing.go index 3cc22d50d1..98fe64e15a 100644 --- a/core/types/hashing.go +++ b/core/types/hashing.go @@ -27,7 +27,7 @@ import ( "github.com/ethereum/go-ethereum/rlp" ) -// hasherPool holds LegacyKeccak256 hashers for rlpHash. +// hasherPool holds LegacyKeccak256 buffer for rlpHash. var hasherPool = sync.Pool{ New: func() interface{} { return crypto.NewKeccakState() }, } @@ -75,11 +75,17 @@ func prefixedRlpHash(prefix byte, x interface{}) (h common.Hash) { return h } -// TrieHasher is the tool used to calculate the hash of derivable list. -// This is internal, do not use. -type TrieHasher interface { +// ListHasher defines the interface for computing the hash of a derivable list. +type ListHasher interface { + // Reset clears the internal state of the hasher, preparing it for reuse. Reset() - Update([]byte, []byte) error + + // Update inserts the given key-value pair into the hasher. + // The implementation must copy the provided slices, allowing the caller + // to safely modify them after the call returns. + Update(key []byte, value []byte) error + + // Hash computes and returns the final hash of all inserted key-value pairs. Hash() common.Hash } @@ -91,19 +97,20 @@ type DerivableList interface { EncodeIndex(int, *bytes.Buffer) } +// encodeForDerive encodes the element in the list at the position i into the buffer. func encodeForDerive(list DerivableList, i int, buf *bytes.Buffer) []byte { buf.Reset() list.EncodeIndex(i, buf) - // It's really unfortunate that we need to perform this copy. - // StackTrie holds onto the values until Hash is called, so the values - // written to it must not alias. - return common.CopyBytes(buf.Bytes()) + return buf.Bytes() } // DeriveSha creates the tree hashes of transactions, receipts, and withdrawals in a block header. -func DeriveSha(list DerivableList, hasher TrieHasher) common.Hash { +func DeriveSha(list DerivableList, hasher ListHasher) common.Hash { hasher.Reset() + // Allocate a buffer for value encoding. As the hasher is claimed that all + // supplied key value pairs will be copied by hasher and safe to reuse the + // encoding buffer. valueBuf := encodeBufferPool.Get().(*bytes.Buffer) defer encodeBufferPool.Put(valueBuf) diff --git a/core/types/hashing_test.go b/core/types/hashing_test.go index c846ecd0c5..a7153bf09a 100644 --- a/core/types/hashing_test.go +++ b/core/types/hashing_test.go @@ -26,12 +26,10 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/trie" - "github.com/ethereum/go-ethereum/triedb" ) func TestDeriveSha(t *testing.T) { @@ -40,7 +38,7 @@ func TestDeriveSha(t *testing.T) { t.Fatal(err) } for len(txs) < 1000 { - exp := types.DeriveSha(txs, trie.NewEmpty(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil))) + exp := types.DeriveSha(txs, trie.NewListHasher()) got := types.DeriveSha(txs, trie.NewStackTrie(nil)) if !bytes.Equal(got[:], exp[:]) { t.Fatalf("%d txs: got %x exp %x", len(txs), got, exp) @@ -76,31 +74,45 @@ func TestEIP2718DeriveSha(t *testing.T) { } } +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/core/types +// cpu: Apple M1 Pro +// BenchmarkDeriveSha200 +// BenchmarkDeriveSha200/std_trie +// BenchmarkDeriveSha200/std_trie-8 6754 174074 ns/op 80054 B/op 1926 allocs/op +// BenchmarkDeriveSha200/stack_trie +// BenchmarkDeriveSha200/stack_trie-8 7296 162675 ns/op 745 B/op 19 allocs/op func BenchmarkDeriveSha200(b *testing.B) { txs, err := genTxs(200) if err != nil { b.Fatal(err) } - var exp common.Hash - var got common.Hash + want := types.DeriveSha(txs, trie.NewListHasher()) + b.Run("std_trie", func(b *testing.B) { - b.ResetTimer() b.ReportAllocs() - for i := 0; i < b.N; i++ { - exp = types.DeriveSha(txs, trie.NewEmpty(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil))) + var have common.Hash + for b.Loop() { + have = types.DeriveSha(txs, trie.NewListHasher()) + } + if have != want { + b.Errorf("have %x want %x", have, want) } }) + st := trie.NewStackTrie(nil) b.Run("stack_trie", func(b *testing.B) { - b.ResetTimer() b.ReportAllocs() - for i := 0; i < b.N; i++ { - got = types.DeriveSha(txs, trie.NewStackTrie(nil)) + var have common.Hash + for b.Loop() { + st.Reset() + have = types.DeriveSha(txs, st) + } + if have != want { + b.Errorf("have %x want %x", have, want) } }) - if got != exp { - b.Errorf("got %x exp %x", got, exp) - } } func TestFuzzDeriveSha(t *testing.T) { @@ -108,7 +120,7 @@ func TestFuzzDeriveSha(t *testing.T) { rndSeed := mrand.Int() for i := 0; i < 10; i++ { seed := rndSeed + i - exp := types.DeriveSha(newDummy(i), trie.NewEmpty(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil))) + exp := types.DeriveSha(newDummy(i), trie.NewListHasher()) got := types.DeriveSha(newDummy(i), trie.NewStackTrie(nil)) if !bytes.Equal(got[:], exp[:]) { printList(t, newDummy(seed)) @@ -136,7 +148,7 @@ func TestDerivableList(t *testing.T) { }, } for i, tc := range tcs[1:] { - exp := types.DeriveSha(flatList(tc), trie.NewEmpty(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil))) + exp := types.DeriveSha(flatList(tc), trie.NewListHasher()) got := types.DeriveSha(flatList(tc), trie.NewStackTrie(nil)) if !bytes.Equal(got[:], exp[:]) { t.Fatalf("case %d: got %x exp %x", i, got, exp) diff --git a/core/types/transaction.go b/core/types/transaction.go index 733b6510f1..6af960b8c3 100644 --- a/core/types/transaction.go +++ b/core/types/transaction.go @@ -28,14 +28,15 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/rlp" + "github.com/holiman/uint256" ) var ( ErrInvalidSig = errors.New("invalid transaction v, r, s values") ErrUnexpectedProtection = errors.New("transaction type does not supported EIP-155 protected signatures") - ErrInvalidTxType = errors.New("transaction type not valid in this context") ErrTxTypeNotSupported = errors.New("transaction type not supported") ErrGasFeeCapTooLow = errors.New("fee cap less than base fee") + ErrUint256Overflow = errors.New("bigint overflow, too large for uint256") errShortTypedTx = errors.New("typed transaction too short") errInvalidYParity = errors.New("'yParity' field must be 0 or 1") errVYParityMismatch = errors.New("'v' and 'yParity' fields do not match") @@ -352,54 +353,66 @@ func (tx *Transaction) GasTipCapIntCmp(other *big.Int) int { } // EffectiveGasTip returns the effective miner gasTipCap for the given base fee. -// Note: if the effective gasTipCap is negative, this method returns both error -// the actual negative value, _and_ ErrGasFeeCapTooLow +// Note: if the effective gasTipCap would be negative, this method +// returns ErrGasFeeCapTooLow, and value is undefined. func (tx *Transaction) EffectiveGasTip(baseFee *big.Int) (*big.Int, error) { - dst := new(big.Int) - err := tx.calcEffectiveGasTip(dst, baseFee) - return dst, err + dst := new(uint256.Int) + base := new(uint256.Int) + if baseFee != nil { + if base.SetFromBig(baseFee) { + return nil, ErrUint256Overflow + } + } + err := tx.calcEffectiveGasTip(dst, base) + return dst.ToBig(), err } // calcEffectiveGasTip calculates the effective gas tip of the transaction and // saves the result to dst. -func (tx *Transaction) calcEffectiveGasTip(dst *big.Int, baseFee *big.Int) error { +func (tx *Transaction) calcEffectiveGasTip(dst *uint256.Int, baseFee *uint256.Int) error { if baseFee == nil { - dst.Set(tx.inner.gasTipCap()) + if dst.SetFromBig(tx.inner.gasTipCap()) { + return ErrUint256Overflow + } return nil } var err error - gasFeeCap := tx.inner.gasFeeCap() - if gasFeeCap.Cmp(baseFee) < 0 { + if dst.SetFromBig(tx.inner.gasFeeCap()) { + return ErrUint256Overflow + } + if dst.Cmp(baseFee) < 0 { err = ErrGasFeeCapTooLow } - dst.Sub(gasFeeCap, baseFee) - gasTipCap := tx.inner.gasTipCap() + dst.Sub(dst, baseFee) + gasTipCap := new(uint256.Int) + if gasTipCap.SetFromBig(tx.inner.gasTipCap()) { + return ErrUint256Overflow + } if gasTipCap.Cmp(dst) < 0 { dst.Set(gasTipCap) } return err } -// EffectiveGasTipCmp compares the effective gasTipCap of two transactions assuming the given base fee. -func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *big.Int) int { +func (tx *Transaction) EffectiveGasTipCmp(other *Transaction, baseFee *uint256.Int) int { if baseFee == nil { return tx.GasTipCapCmp(other) } // Use more efficient internal method. - txTip, otherTip := new(big.Int), new(big.Int) + txTip, otherTip := new(uint256.Int), new(uint256.Int) tx.calcEffectiveGasTip(txTip, baseFee) other.calcEffectiveGasTip(otherTip, baseFee) return txTip.Cmp(otherTip) } // EffectiveGasTipIntCmp compares the effective gasTipCap of a transaction to the given gasTipCap. -func (tx *Transaction) EffectiveGasTipIntCmp(other *big.Int, baseFee *big.Int) int { +func (tx *Transaction) EffectiveGasTipIntCmp(other *uint256.Int, baseFee *uint256.Int) int { if baseFee == nil { - return tx.GasTipCapIntCmp(other) + return tx.GasTipCapIntCmp(other.ToBig()) } - txTip := new(big.Int) + txTip := new(uint256.Int) tx.calcEffectiveGasTip(txTip, baseFee) return txTip.Cmp(other) } @@ -634,7 +647,7 @@ func TxDifference(a, b Transactions) Transactions { func HashDifference(a, b []common.Hash) []common.Hash { keep := make([]common.Hash, 0, len(a)) - remove := make(map[common.Hash]struct{}) + remove := make(map[common.Hash]struct{}, len(b)) for _, hash := range b { remove[hash] = struct{}{} } diff --git a/core/types/transaction_signing.go b/core/types/transaction_signing.go index 01aa67c6ba..5a624191cf 100644 --- a/core/types/transaction_signing.go +++ b/core/types/transaction_signing.go @@ -20,7 +20,6 @@ import ( "crypto/ecdsa" "errors" "fmt" - "maps" "math/big" "github.com/ethereum/go-ethereum/common" @@ -183,18 +182,31 @@ type Signer interface { // modernSigner is the signer implementation that handles non-legacy transaction types. // For legacy transactions, it defers to one of the legacy signers (frontier, homestead, eip155). type modernSigner struct { - txtypes map[byte]struct{} + txtypes txtypeSet chainID *big.Int legacy Signer } +// txtypeSet is a bitmap for transaction types. +type txtypeSet [2]uint64 + +func (v *txtypeSet) set(txType byte) { + v[txType/64] |= 1 << (txType % 64) +} + +func (v *txtypeSet) has(txType byte) bool { + if txType >= byte(len(v)*64) { + return false + } + return v[txType/64]&(1<<(txType%64)) != 0 +} + func newModernSigner(chainID *big.Int, fork forks.Fork) Signer { if chainID == nil || chainID.Sign() <= 0 { panic(fmt.Sprintf("invalid chainID %v", chainID)) } s := &modernSigner{ chainID: chainID, - txtypes: make(map[byte]struct{}, 4), } // configure legacy signer switch { @@ -205,19 +217,19 @@ func newModernSigner(chainID *big.Int, fork forks.Fork) Signer { default: s.legacy = FrontierSigner{} } - s.txtypes[LegacyTxType] = struct{}{} + s.txtypes.set(LegacyTxType) // configure tx types if fork >= forks.Berlin { - s.txtypes[AccessListTxType] = struct{}{} + s.txtypes.set(AccessListTxType) } if fork >= forks.London { - s.txtypes[DynamicFeeTxType] = struct{}{} + s.txtypes.set(DynamicFeeTxType) } if fork >= forks.Cancun { - s.txtypes[BlobTxType] = struct{}{} + s.txtypes.set(BlobTxType) } if fork >= forks.Prague { - s.txtypes[SetCodeTxType] = struct{}{} + s.txtypes.set(SetCodeTxType) } return s } @@ -228,7 +240,7 @@ func (s *modernSigner) ChainID() *big.Int { func (s *modernSigner) Equal(s2 Signer) bool { other, ok := s2.(*modernSigner) - return ok && s.chainID.Cmp(other.chainID) == 0 && maps.Equal(s.txtypes, other.txtypes) && s.legacy.Equal(other.legacy) + return ok && s.chainID.Cmp(other.chainID) == 0 && s.txtypes == other.txtypes && s.legacy.Equal(other.legacy) } func (s *modernSigner) Hash(tx *Transaction) common.Hash { @@ -236,8 +248,7 @@ func (s *modernSigner) Hash(tx *Transaction) common.Hash { } func (s *modernSigner) supportsType(txtype byte) bool { - _, ok := s.txtypes[txtype] - return ok + return s.txtypes.has(txtype) } func (s *modernSigner) Sender(tx *Transaction) (common.Address, error) { @@ -271,7 +282,10 @@ func (s *modernSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *bi if tx.inner.chainID().Sign() != 0 && tx.inner.chainID().Cmp(s.chainID) != 0 { return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.inner.chainID(), s.chainID) } - R, S, _ = decodeSignature(sig) + R, S, _, err = decodeSignature(sig) + if err != nil { + return nil, nil, nil, err + } V = big.NewInt(int64(sig[64])) return R, S, V, nil } @@ -362,7 +376,10 @@ func (s EIP155Signer) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big if tx.Type() != LegacyTxType { return nil, nil, nil, ErrTxTypeNotSupported } - R, S, V = decodeSignature(sig) + R, S, V, err = decodeSignature(sig) + if err != nil { + return nil, nil, nil, err + } if s.chainId.Sign() != 0 { V = big.NewInt(int64(sig[64] + 35)) V.Add(V, s.chainIdMul) @@ -431,8 +448,8 @@ func (fs FrontierSigner) SignatureValues(tx *Transaction, sig []byte) (r, s, v * if tx.Type() != LegacyTxType { return nil, nil, nil, ErrTxTypeNotSupported } - r, s, v = decodeSignature(sig) - return r, s, v, nil + r, s, v, err = decodeSignature(sig) + return r, s, v, err } // Hash returns the hash to be signed by the sender. @@ -448,14 +465,14 @@ func (fs FrontierSigner) Hash(tx *Transaction) common.Hash { }) } -func decodeSignature(sig []byte) (r, s, v *big.Int) { +func decodeSignature(sig []byte) (r, s, v *big.Int, err error) { if len(sig) != crypto.SignatureLength { - panic(fmt.Sprintf("wrong size for signature: got %d, want %d", len(sig), crypto.SignatureLength)) + return nil, nil, nil, fmt.Errorf("wrong size for signature: got %d, want %d", len(sig), crypto.SignatureLength) } r = new(big.Int).SetBytes(sig[:32]) s = new(big.Int).SetBytes(sig[32:64]) v = new(big.Int).SetBytes([]byte{sig[64] + 27}) - return r, s, v + return r, s, v, nil } func recoverPlain(sighash common.Hash, R, S, Vb *big.Int, homestead bool) (common.Address, error) { diff --git a/core/types/transaction_signing_test.go b/core/types/transaction_signing_test.go index b66577f7ed..252593e87b 100644 --- a/core/types/transaction_signing_test.go +++ b/core/types/transaction_signing_test.go @@ -25,6 +25,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/params/forks" "github.com/ethereum/go-ethereum/rlp" ) @@ -188,3 +189,39 @@ func createTestLegacyTxInner() *LegacyTx { Data: nil, } } + +func Benchmark_modernSigner_Equal(b *testing.B) { + signer1 := newModernSigner(big.NewInt(1), forks.Amsterdam) + signer2 := newModernSigner(big.NewInt(1), forks.Amsterdam) + + for b.Loop() { + if !signer1.Equal(signer2) { + b.Fatal("expected signers to be equal") + } + } +} + +func TestSignatureValuesError(t *testing.T) { + // 1. Setup a valid transaction + tx := NewTransaction(0, common.Address{}, big.NewInt(0), 0, big.NewInt(0), nil) + signer := HomesteadSigner{} + + // 2. Call WithSignature with invalid length sig (not 65 bytes) + invalidSig := make([]byte, 64) + + func() { + defer func() { + if r := recover(); r != nil { + t.Fatalf("Panicked for invalid signature length, expected error: %v", r) + } + }() + _, err := tx.WithSignature(signer, invalidSig) + if err == nil { + t.Fatal("Expected error for invalid signature length, got nil") + } else { + // This is just a sanity check to ensure we got an error, + // the exact error message is verified in unit tests elsewhere if needed. + t.Logf("Got expected error: %v", err) + } + }() +} diff --git a/core/types/transaction_test.go b/core/types/transaction_test.go index 7d5e2f058a..2d854ae345 100644 --- a/core/types/transaction_test.go +++ b/core/types/transaction_test.go @@ -31,6 +31,7 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" + "github.com/holiman/uint256" ) // The values in those tests are from the Transaction Tests @@ -590,7 +591,7 @@ func BenchmarkHash(b *testing.B) { GasTipCap: big.NewInt(500), GasFeeCap: big.NewInt(500), }) - for i := 0; i < b.N; i++ { + for b.Loop() { signer.Hash(tx) } } @@ -609,12 +610,12 @@ func BenchmarkEffectiveGasTip(b *testing.B) { Data: nil, } tx, _ := SignNewTx(key, signer, txdata) - baseFee := big.NewInt(1000000000) // 1 gwei + baseFee := uint256.NewInt(1000000000) // 1 gwei b.Run("Original", func(b *testing.B) { b.ReportAllocs() - for i := 0; i < b.N; i++ { - _, err := tx.EffectiveGasTip(baseFee) + for b.Loop() { + _, err := tx.EffectiveGasTip(baseFee.ToBig()) if err != nil { b.Fatal(err) } @@ -623,8 +624,8 @@ func BenchmarkEffectiveGasTip(b *testing.B) { b.Run("IntoMethod", func(b *testing.B) { b.ReportAllocs() - dst := new(big.Int) - for i := 0; i < b.N; i++ { + dst := new(uint256.Int) + for b.Loop() { err := tx.calcEffectiveGasTip(dst, baseFee) if err != nil { b.Fatal(err) @@ -634,9 +635,6 @@ func BenchmarkEffectiveGasTip(b *testing.B) { } func TestEffectiveGasTipInto(t *testing.T) { - signer := LatestSigner(params.TestChainConfig) - key, _ := crypto.GenerateKey() - testCases := []struct { tipCap int64 feeCap int64 @@ -652,8 +650,26 @@ func TestEffectiveGasTipInto(t *testing.T) { {tipCap: 50, feeCap: 100, baseFee: nil}, // nil base fee } + // original, non-allocation golfed version + orig := func(tx *Transaction, baseFee *big.Int) (*big.Int, error) { + if baseFee == nil { + return tx.GasTipCap(), nil + } + var err error + gasFeeCap := tx.GasFeeCap() + if gasFeeCap.Cmp(baseFee) < 0 { + err = ErrGasFeeCapTooLow + } + gasFeeCap = gasFeeCap.Sub(gasFeeCap, baseFee) + gasTipCap := tx.GasTipCap() + if gasTipCap.Cmp(gasFeeCap) < 0 { + return gasTipCap, err + } + return gasFeeCap, err + } + for i, tc := range testCases { - txdata := &DynamicFeeTx{ + tx := NewTx(&DynamicFeeTx{ ChainID: big.NewInt(1), Nonce: 0, GasTipCap: big.NewInt(tc.tipCap), @@ -662,27 +678,28 @@ func TestEffectiveGasTipInto(t *testing.T) { To: &common.Address{}, Value: big.NewInt(0), Data: nil, - } - tx, _ := SignNewTx(key, signer, txdata) + }) var baseFee *big.Int + var baseFee2 *uint256.Int if tc.baseFee != nil { baseFee = big.NewInt(*tc.baseFee) + baseFee2 = uint256.NewInt(uint64(*tc.baseFee)) } // Get result from original method - orig, origErr := tx.EffectiveGasTip(baseFee) + orig, origErr := orig(tx, baseFee) // Get result from new method - dst := new(big.Int) - newErr := tx.calcEffectiveGasTip(dst, baseFee) + dst := new(uint256.Int) + newErr := tx.calcEffectiveGasTip(dst, baseFee2) // Compare results if (origErr != nil) != (newErr != nil) { t.Fatalf("case %d: error mismatch: orig %v, new %v", i, origErr, newErr) } - if orig.Cmp(dst) != 0 { + if origErr == nil && orig.Cmp(dst.ToBig()) != 0 { t.Fatalf("case %d: result mismatch: orig %v, new %v", i, orig, dst) } } @@ -692,3 +709,28 @@ func TestEffectiveGasTipInto(t *testing.T) { func intPtr(i int64) *int64 { return &i } + +func BenchmarkEffectiveGasTipCmp(b *testing.B) { + signer := LatestSigner(params.TestChainConfig) + key, _ := crypto.GenerateKey() + txdata := &DynamicFeeTx{ + ChainID: big.NewInt(1), + Nonce: 0, + GasTipCap: big.NewInt(2000000000), + GasFeeCap: big.NewInt(3000000000), + Gas: 21000, + To: &common.Address{}, + Value: big.NewInt(0), + Data: nil, + } + tx, _ := SignNewTx(key, signer, txdata) + other, _ := SignNewTx(key, signer, txdata) + baseFee := uint256.NewInt(1000000000) // 1 gwei + + b.Run("Original", func(b *testing.B) { + b.ReportAllocs() + for b.Loop() { + tx.EffectiveGasTipCmp(other, baseFee) + } + }) +} diff --git a/core/types/tx_setcode.go b/core/types/tx_setcode.go index f2281d4ae7..9487c9cc81 100644 --- a/core/types/tx_setcode.go +++ b/core/types/tx_setcode.go @@ -94,7 +94,10 @@ func SignSetCode(prv *ecdsa.PrivateKey, auth SetCodeAuthorization) (SetCodeAutho if err != nil { return SetCodeAuthorization{}, err } - r, s, _ := decodeSignature(sig) + r, s, _, err := decodeSignature(sig) + if err != nil { + return SetCodeAuthorization{}, err + } return SetCodeAuthorization{ ChainID: auth.ChainID, Address: auth.Address, diff --git a/core/types/types_test.go b/core/types/types_test.go index 1fb386d5de..96d0444994 100644 --- a/core/types/types_test.go +++ b/core/types/types_test.go @@ -126,7 +126,7 @@ func benchRLP(b *testing.B, encode bool) { b.Run(tc.name, func(b *testing.B) { b.ReportAllocs() var null = &devnull{} - for i := 0; i < b.N; i++ { + for b.Loop() { rlp.Encode(null, tc.obj) } b.SetBytes(int64(null.len / b.N)) @@ -136,7 +136,7 @@ func benchRLP(b *testing.B, encode bool) { // Test decoding b.Run(tc.name, func(b *testing.B) { b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { if err := rlp.DecodeBytes(data, tc.obj); err != nil { b.Fatal(err) } diff --git a/core/verkle_witness_test.go b/core/verkle_witness_test.go deleted file mode 100644 index e200bf7f50..0000000000 --- a/core/verkle_witness_test.go +++ /dev/null @@ -1,1107 +0,0 @@ -// Copyright 2024 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package core - -import ( - "bytes" - "encoding/binary" - "encoding/hex" - "fmt" - "math/big" - "slices" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/consensus/beacon" - "github.com/ethereum/go-ethereum/consensus/ethash" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/state" - "github.com/ethereum/go-ethereum/core/tracing" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/core/vm" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie/utils" - "github.com/ethereum/go-ethereum/triedb" - "github.com/ethereum/go-verkle" - "github.com/holiman/uint256" -) - -var ( - testVerkleChainConfig = ¶ms.ChainConfig{ - ChainID: big.NewInt(1), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - Ethash: new(params.EthashConfig), - ShanghaiTime: u64(0), - VerkleTime: u64(0), - TerminalTotalDifficulty: common.Big0, - EnableVerkleAtGenesis: true, - BlobScheduleConfig: ¶ms.BlobScheduleConfig{ - Verkle: params.DefaultPragueBlobConfig, - }, - // TODO uncomment when proof generation is merged - // ProofInBlocks: true, - } - testKaustinenLikeChainConfig = ¶ms.ChainConfig{ - ChainID: big.NewInt(69420), - HomesteadBlock: big.NewInt(0), - EIP150Block: big.NewInt(0), - EIP155Block: big.NewInt(0), - EIP158Block: big.NewInt(0), - ByzantiumBlock: big.NewInt(0), - ConstantinopleBlock: big.NewInt(0), - PetersburgBlock: big.NewInt(0), - IstanbulBlock: big.NewInt(0), - MuirGlacierBlock: big.NewInt(0), - BerlinBlock: big.NewInt(0), - LondonBlock: big.NewInt(0), - Ethash: new(params.EthashConfig), - ShanghaiTime: u64(0), - VerkleTime: u64(0), - TerminalTotalDifficulty: common.Big0, - EnableVerkleAtGenesis: true, - BlobScheduleConfig: ¶ms.BlobScheduleConfig{ - Verkle: params.DefaultPragueBlobConfig, - }, - } -) - -func TestProcessVerkle(t *testing.T) { - var ( - code = common.FromHex(`6060604052600a8060106000396000f360606040526008565b00`) - intrinsicContractCreationGas, _ = IntrinsicGas(code, nil, nil, true, true, true, true) - // A contract creation that calls EXTCODECOPY in the constructor. Used to ensure that the witness - // will not contain that copied data. - // Source: https://gist.github.com/gballet/a23db1e1cb4ed105616b5920feb75985 - codeWithExtCodeCopy = common.FromHex(`0x60806040526040516100109061017b565b604051809103906000f08015801561002c573d6000803e3d6000fd5b506000806101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555034801561007857600080fd5b5060008067ffffffffffffffff8111156100955761009461024a565b5b6040519080825280601f01601f1916602001820160405280156100c75781602001600182028036833780820191505090505b50905060008060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690506020600083833c81610101906101e3565b60405161010d90610187565b61011791906101a3565b604051809103906000f080158015610133573d6000803e3d6000fd5b50600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550505061029b565b60d58061046783390190565b6102068061053c83390190565b61019d816101d9565b82525050565b60006020820190506101b86000830184610194565b92915050565b6000819050602082019050919050565b600081519050919050565b6000819050919050565b60006101ee826101ce565b826101f8846101be565b905061020381610279565b925060208210156102435761023e7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080261028e565b831692505b5050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600061028582516101d9565b80915050919050565b600082821b905092915050565b6101bd806102aa6000396000f3fe608060405234801561001057600080fd5b506004361061002b5760003560e01c8063f566852414610030575b600080fd5b61003861004e565b6040516100459190610146565b60405180910390f35b6000600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166381ca91d36040518163ffffffff1660e01b815260040160206040518083038186803b1580156100b857600080fd5b505afa1580156100cc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906100f0919061010a565b905090565b60008151905061010481610170565b92915050565b6000602082840312156101205761011f61016b565b5b600061012e848285016100f5565b91505092915050565b61014081610161565b82525050565b600060208201905061015b6000830184610137565b92915050565b6000819050919050565b600080fd5b61017981610161565b811461018457600080fd5b5056fea2646970667358221220a6a0e11af79f176f9c421b7b12f441356b25f6489b83d38cc828a701720b41f164736f6c63430008070033608060405234801561001057600080fd5b5060b68061001f6000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c8063ab5ed15014602d575b600080fd5b60336047565b604051603e9190605d565b60405180910390f35b60006001905090565b6057816076565b82525050565b6000602082019050607060008301846050565b92915050565b600081905091905056fea26469706673582212203a14eb0d5cd07c277d3e24912f110ddda3e553245a99afc4eeefb2fbae5327aa64736f6c63430008070033608060405234801561001057600080fd5b5060405161020638038061020683398181016040528101906100329190610063565b60018160001c6100429190610090565b60008190555050610145565b60008151905061005d8161012e565b92915050565b60006020828403121561007957610078610129565b5b60006100878482850161004e565b91505092915050565b600061009b826100f0565b91506100a6836100f0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156100db576100da6100fa565b5b828201905092915050565b6000819050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600080fd5b610137816100e6565b811461014257600080fd5b50565b60b3806101536000396000f3fe6080604052348015600f57600080fd5b506004361060285760003560e01c806381ca91d314602d575b600080fd5b60336047565b604051603e9190605a565b60405180910390f35b60005481565b6054816073565b82525050565b6000602082019050606d6000830184604d565b92915050565b600081905091905056fea26469706673582212209bff7098a2f526de1ad499866f27d6d0d6f17b74a413036d6063ca6a0998ca4264736f6c63430008070033`) - intrinsicCodeWithExtCodeCopyGas, _ = IntrinsicGas(codeWithExtCodeCopy, nil, nil, true, true, true, true) - signer = types.LatestSigner(testVerkleChainConfig) - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - bcdb = rawdb.NewMemoryDatabase() // Database for the blockchain - coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") - gspec = &Genesis{ - Config: testVerkleChainConfig, - Alloc: GenesisAlloc{ - coinbase: { - Balance: big.NewInt(1000000000000000000), // 1 ether - Nonce: 0, - }, - params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0}, - params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0}, - params.WithdrawalQueueAddress: {Nonce: 1, Code: params.WithdrawalQueueCode, Balance: common.Big0}, - params.ConsolidationQueueAddress: {Nonce: 1, Code: params.ConsolidationQueueCode, Balance: common.Big0}, - }, - } - ) - // Verkle trees use the snapshot, which must be enabled before the - // data is saved into the tree+database. - // genesis := gspec.MustCommit(bcdb, triedb) - options := DefaultConfig().WithStateScheme(rawdb.PathScheme) - options.SnapshotLimit = 0 - blockchain, _ := NewBlockChain(bcdb, gspec, beacon.New(ethash.NewFaker()), options) - defer blockchain.Stop() - - txCost1 := params.TxGas - txCost2 := params.TxGas - contractCreationCost := intrinsicContractCreationGas + - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* creation with value */ - 739 /* execution costs */ - codeWithExtCodeCopyGas := intrinsicCodeWithExtCodeCopyGas + - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (tx) */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at pc=0x20) */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */ - params.WitnessChunkReadCost + /* SLOAD in constructor */ - params.WitnessChunkWriteCost + /* SSTORE in constructor */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + params.WitnessBranchReadCost + params.WitnessBranchWriteCost + /* creation (CREATE at PC=0x121) */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #0 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #1 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #2 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #3 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #4 */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* code chunk #5 */ - params.WitnessChunkReadCost + /* SLOAD in constructor */ - params.WitnessChunkWriteCost + /* SSTORE in constructor */ - params.WitnessChunkReadCost + params.WitnessChunkWriteCost + /* write code hash for tx creation */ - 15*(params.WitnessChunkReadCost+params.WitnessChunkWriteCost) + /* code chunks #0..#14 */ - uint64(4844) /* execution costs */ - blockGasUsagesExpected := []uint64{ - txCost1*2 + txCost2, - txCost1*2 + txCost2 + contractCreationCost + codeWithExtCodeCopyGas, - } - _, _, chain, _, proofs, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { - gen.SetPoS() - - // TODO need to check that the tx cost provided is the exact amount used (no remaining left-over) - tx, _ := types.SignTx(types.NewTransaction(uint64(i)*3, common.Address{byte(i), 2, 3}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey) - gen.AddTx(tx) - tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+1, common.Address{}, big.NewInt(999), txCost1, big.NewInt(875000000), nil), signer, testKey) - gen.AddTx(tx) - tx, _ = types.SignTx(types.NewTransaction(uint64(i)*3+2, common.Address{}, big.NewInt(0), txCost2, big.NewInt(875000000), nil), signer, testKey) - gen.AddTx(tx) - - // Add two contract creations in block #2 - if i == 1 { - tx, _ = types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 6, - Value: big.NewInt(16), - Gas: 3000000, - GasPrice: big.NewInt(875000000), - Data: code, - }) - gen.AddTx(tx) - - tx, _ = types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 7, - Value: big.NewInt(0), - Gas: 3000000, - GasPrice: big.NewInt(875000000), - Data: codeWithExtCodeCopy, - }) - gen.AddTx(tx) - } - }) - - // Check proof for both blocks - err := verkle.Verify(proofs[0], gspec.ToBlock().Root().Bytes(), chain[0].Root().Bytes(), statediffs[0]) - if err != nil { - t.Fatal(err) - } - err = verkle.Verify(proofs[1], chain[0].Root().Bytes(), chain[1].Root().Bytes(), statediffs[1]) - if err != nil { - t.Fatal(err) - } - - t.Log("verified verkle proof, inserting blocks into the chain") - - for i, b := range chain { - fmt.Printf("%d %x\n", i, b.Root()) - } - endnum, err := blockchain.InsertChain(chain) - if err != nil { - t.Fatalf("block %d imported with error: %v", endnum, err) - } - - for i := range 2 { - b := blockchain.GetBlockByNumber(uint64(i) + 1) - if b == nil { - t.Fatalf("expected block %d to be present in chain", i+1) - } - if b.Hash() != chain[i].Hash() { - t.Fatalf("block #%d not found at expected height", b.NumberU64()) - } - if b.GasUsed() != blockGasUsagesExpected[i] { - t.Fatalf("expected block #%d txs to use %d, got %d\n", b.NumberU64(), blockGasUsagesExpected[i], b.GasUsed()) - } - } -} - -func TestProcessParentBlockHash(t *testing.T) { - // This test uses blocks where, - // block 1 parent hash is 0x0100.... - // block 2 parent hash is 0x0200.... - // etc - checkBlockHashes := func(statedb *state.StateDB, isVerkle bool) { - statedb.SetNonce(params.HistoryStorageAddress, 1, tracing.NonceChangeUnspecified) - statedb.SetCode(params.HistoryStorageAddress, params.HistoryStorageCode) - // Process n blocks, from 1 .. num - var num = 2 - for i := 1; i <= num; i++ { - header := &types.Header{ParentHash: common.Hash{byte(i)}, Number: big.NewInt(int64(i)), Difficulty: new(big.Int)} - chainConfig := params.MergedTestChainConfig - if isVerkle { - chainConfig = testVerkleChainConfig - } - vmContext := NewEVMBlockContext(header, nil, new(common.Address)) - evm := vm.NewEVM(vmContext, statedb, chainConfig, vm.Config{}) - ProcessParentBlockHash(header.ParentHash, evm) - } - // Read block hashes for block 0 .. num-1 - for i := 0; i < num; i++ { - have, want := getContractStoredBlockHash(statedb, uint64(i), isVerkle), common.Hash{byte(i + 1)} - if have != want { - t.Errorf("block %d, verkle=%v, have parent hash %v, want %v", i, isVerkle, have, want) - } - } - } - t.Run("MPT", func(t *testing.T) { - statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) - checkBlockHashes(statedb, false) - }) - t.Run("Verkle", func(t *testing.T) { - db := rawdb.NewMemoryDatabase() - cacheConfig := DefaultConfig().WithStateScheme(rawdb.PathScheme) - cacheConfig.SnapshotLimit = 0 - triedb := triedb.NewDatabase(db, cacheConfig.triedbConfig(true)) - statedb, _ := state.New(types.EmptyVerkleHash, state.NewDatabase(triedb, nil)) - checkBlockHashes(statedb, true) - }) -} - -// getContractStoredBlockHash is a utility method which reads the stored parent blockhash for block 'number' -func getContractStoredBlockHash(statedb *state.StateDB, number uint64, isVerkle bool) common.Hash { - ringIndex := number % params.HistoryServeWindow - var key common.Hash - binary.BigEndian.PutUint64(key[24:], ringIndex) - if isVerkle { - return statedb.GetState(params.HistoryStorageAddress, key) - } - return statedb.GetState(params.HistoryStorageAddress, key) -} - -// TestProcessVerkleInvalidContractCreation checks for several modes of contract creation failures -func TestProcessVerkleInvalidContractCreation(t *testing.T) { - var ( - account1 = common.HexToAddress("0x687704DB07e902e9A8B3754031D168D46E3D586e") - account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d") - gspec = verkleTestGenesis(testKaustinenLikeChainConfig) - ) - // slightly modify it to suit the live txs from the testnet - gspec.Alloc[account2] = types.Account{ - Balance: big.NewInt(1000000000000000000), // 1 ether - Nonce: 1, - } - - // Create two blocks that reproduce what is happening on kaustinen. - // - The first block contains two failing contract creation transactions, that - // write to storage before they revert. - // - // - The second block contains a single failing contract creation transaction, - // that fails right off the bat. - genesisH, _, chain, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { - gen.SetPoS() - - if i == 0 { - for _, rlpData := range []string{ - // SSTORE at slot 41 and reverts - "f8d48084479c2c18830186a08080b8806000602955bda3f9600060ca55600060695523b360006039551983576000601255b0620c2fde2c592ac2600060bc55e0ac6000606455a63e22600060e655eb607e605c5360a2605d5360c7605e53601d605f5360eb606053606b606153608e60625360816063536079606453601e60655360fc60665360b7606753608b60685383021e7ca0cc20c65a97d2e526b8ec0f4266e8b01bdcde43b9aeb59d8bfb44e8eb8119c109a07a8e751813ae1b2ce734960dbc39a4f954917d7822a2c5d1dca18b06c584131f", - // SSTORE at slot 133 and reverts - "02f8db83010f2c01843b9aca0084479c2c18830186a08080b88060006085553fad6000600a55600060565555600060b55506600060cf557f1b8b38183e7bd1bdfaa7123c5a4976e54cce0e42049d841411978fd3595e25c66019527f0538943712953cf08900aae40222a40b2d5a4ac8075ad8cf0870e2be307edbb96039527f9f3174ff85024747041ae7a611acffb987c513c088d90ab288aec080a0cd6ac65ce2cb0a912371f6b5a551ba8caffc22ec55ad4d3cb53de41d05eb77b6a02e0dfe8513dfa6ec7bfd7eda6f5c0dac21b39b982436045e128cec46cfd3f960", - // this one is a simple transfer that succeeds, necessary to get the correct nonce in the other block. - "f8e80184479c2c18830186a094bbbbde4ca27f83fc18aa108170547ff57675936a80b8807ff71f7c15faadb969a76a5f54a81a0117e1e743cb7f24e378eda28442ea4c6eb6604a527fb5409e5718d44e23bfffac926e5ea726067f772772e7e19446acba0c853f62f5606a526020608a536088608b536039608c536004608d5360af608e537f7f7675d9f210e0a61564e6d11e7cd75f5bc9009ac9f6b94a0fc63035441a83021e7ba04a4a172d81ebb02847829b76a387ac09749c8b65668083699abe20c887fb9efca07c5b1a990702ec7b31a5e8e3935cd9a77649f8c25a84131229e24ab61aec6093", - } { - var tx = new(types.Transaction) - if err := tx.UnmarshalBinary(common.Hex2Bytes(rlpData)); err != nil { - t.Fatal(err) - } - gen.AddTx(tx) - } - } else { - var tx = new(types.Transaction) - // immediately reverts - if err := tx.UnmarshalBinary(common.Hex2Bytes("01f8d683010f2c028443ad7d0e830186a08080b880b00e7fa3c849dce891cce5fae8a4c46cbb313d6aec0c0ffe7863e05fb7b22d4807674c6055527ffbfcb0938f3e18f7937aa8fa95d880afebd5c4cec0d85186095832d03c85cf8a60755260ab60955360cf6096536066609753606e60985360fa609953609e609a53608e609b536024609c5360f6609d536072609e5360a4609fc080a08fc6f7101f292ff1fb0de8ac69c2d320fbb23bfe61cf327173786ea5daee6e37a044c42d91838ef06646294bf4f9835588aee66243b16a66a2da37641fae4c045f")); err != nil { - t.Fatal(err) - } - gen.AddTx(tx) - } - }) - - tx1ContractAddress := crypto.CreateAddress(account1, 0) - tx1ContractStem := utils.GetTreeKey(tx1ContractAddress[:], uint256.NewInt(0), 105) - tx1ContractStem = tx1ContractStem[:31] - - tx2ContractAddress := crypto.CreateAddress(account2, 1) - tx2SlotKey := [32]byte{} - tx2SlotKey[31] = 133 - tx2ContractStem := utils.StorageSlotKey(tx2ContractAddress[:], tx2SlotKey[:]) - tx2ContractStem = tx2ContractStem[:31] - - eip2935Stem := utils.GetTreeKey(params.HistoryStorageAddress[:], uint256.NewInt(0), 0) - eip2935Stem = eip2935Stem[:31] - - // Check that the witness contains what we expect: a storage entry for each of the two contract - // creations that failed: one at 133 for the 2nd tx, and one at 105 for the first tx. - for _, stemStateDiff := range statediffs[0] { - // Check that the slot number 133, which is overflowing the account header, - // is present. Note that the offset of the 2nd group (first group after the - // header) is skipping the first 64 values, hence we still have an offset - // of 133, and not 133 - 64. - if bytes.Equal(stemStateDiff.Stem[:], tx2ContractStem[:]) { - for _, suffixDiff := range stemStateDiff.SuffixDiffs { - if suffixDiff.Suffix != 133 { - t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) - } - if suffixDiff.CurrentValue != nil { - t.Fatalf("invalid prestate value found for %x in block #1: %v != nil\n", stemStateDiff.Stem, suffixDiff.CurrentValue) - } - if suffixDiff.NewValue != nil { - t.Fatalf("invalid poststate value found for %x in block #1: %v != nil\n", stemStateDiff.Stem, suffixDiff.NewValue) - } - } - } else if bytes.Equal(stemStateDiff.Stem[:], tx1ContractStem) { - // For this contract creation, check that only the account header and storage slot 41 - // are found in the witness. - for _, suffixDiff := range stemStateDiff.SuffixDiffs { - if suffixDiff.Suffix != 105 && suffixDiff.Suffix != 0 && suffixDiff.Suffix != 1 { - t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) - } - } - } else if bytes.Equal(stemStateDiff.Stem[:], eip2935Stem) { - // Check the eip 2935 group of leaves. - // Check that only one leaf was accessed, and is present in the witness. - if len(stemStateDiff.SuffixDiffs) > 1 { - t.Fatalf("invalid suffix diff count found for BLOCKHASH contract: %d != 1", len(stemStateDiff.SuffixDiffs)) - } - // Check that this leaf is the first storage slot - if stemStateDiff.SuffixDiffs[0].Suffix != 64 { - t.Fatalf("invalid suffix diff value found for BLOCKHASH contract: %d != 64", stemStateDiff.SuffixDiffs[0].Suffix) - } - // check that the prestate value is nil and that the poststate value isn't. - if stemStateDiff.SuffixDiffs[0].CurrentValue != nil { - t.Fatalf("non-nil current value in BLOCKHASH contract insert: %x", stemStateDiff.SuffixDiffs[0].CurrentValue) - } - if stemStateDiff.SuffixDiffs[0].NewValue == nil { - t.Fatalf("nil new value in BLOCKHASH contract insert") - } - if *stemStateDiff.SuffixDiffs[0].NewValue != genesisH { - t.Fatalf("invalid BLOCKHASH value: %x != %x", *stemStateDiff.SuffixDiffs[0].NewValue, genesisH) - } - } else { - // For all other entries present in the witness, check that nothing beyond - // the account header was accessed. - for _, suffixDiff := range stemStateDiff.SuffixDiffs { - if suffixDiff.Suffix > 2 { - t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) - } - } - } - } - - // Check that no account has a value above 4 in the 2nd block as no storage nor - // code should make it to the witness. - for _, stemStateDiff := range statediffs[1] { - for _, suffixDiff := range stemStateDiff.SuffixDiffs { - if bytes.Equal(stemStateDiff.Stem[:], eip2935Stem) { - // BLOCKHASH contract stem - if len(stemStateDiff.SuffixDiffs) > 1 { - t.Fatalf("invalid suffix diff count found for BLOCKHASH contract at block #2: %d != 1", len(stemStateDiff.SuffixDiffs)) - } - if stemStateDiff.SuffixDiffs[0].Suffix != 65 { - t.Fatalf("invalid suffix diff value found for BLOCKHASH contract at block #2: %d != 65", stemStateDiff.SuffixDiffs[0].Suffix) - } - if stemStateDiff.SuffixDiffs[0].NewValue == nil { - t.Fatalf("missing post state value for BLOCKHASH contract at block #2") - } - if *stemStateDiff.SuffixDiffs[0].NewValue != chain[0].Hash() { - t.Fatalf("invalid post state value for BLOCKHASH contract at block #2: %x != %x", chain[0].Hash(), (*stemStateDiff.SuffixDiffs[0].NewValue)[:]) - } - } else if suffixDiff.Suffix > 4 { - t.Fatalf("invalid suffix diff found for %x in block #2: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) - } - } - } -} - -func verkleTestGenesis(config *params.ChainConfig) *Genesis { - var ( - coinbase = common.HexToAddress("0x71562b71999873DB5b286dF957af199Ec94617F7") - account1 = common.HexToAddress("0x687704DB07e902e9A8B3754031D168D46E3D586e") - account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d") - ) - return &Genesis{ - Config: config, - Alloc: GenesisAlloc{ - coinbase: GenesisAccount{ - Balance: big.NewInt(1000000000000000000), // 1 ether - Nonce: 0, - }, - account1: GenesisAccount{ - Balance: big.NewInt(1000000000000000000), // 1 ether - Nonce: 0, - }, - account2: GenesisAccount{ - Balance: big.NewInt(1000000000000000000), // 1 ether - Nonce: 3, - }, - params.BeaconRootsAddress: {Nonce: 1, Code: params.BeaconRootsCode, Balance: common.Big0}, - params.HistoryStorageAddress: {Nonce: 1, Code: params.HistoryStorageCode, Balance: common.Big0}, - params.WithdrawalQueueAddress: {Nonce: 1, Code: params.WithdrawalQueueCode, Balance: common.Big0}, - params.ConsolidationQueueAddress: {Nonce: 1, Code: params.ConsolidationQueueCode, Balance: common.Big0}, - }, - } -} - -// TestProcessVerkleContractWithEmptyCode checks that the witness contains all valid -// entries, if the initcode returns an empty code. -func TestProcessVerkleContractWithEmptyCode(t *testing.T) { - // The test txs were taken from a secondary testnet with chain id 69421 - config := *testKaustinenLikeChainConfig - config.ChainID.SetUint64(69421) - gspec := verkleTestGenesis(&config) - - genesisH, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { - gen.SetPoS() - var tx types.Transaction - // a transaction that does some PUSH1n but returns a 0-sized contract - txpayload := common.Hex2Bytes("02f8db83010f2d03843b9aca008444cf6a05830186a08080b8807fdfbbb59f2371a76485ce557fd0de00c298d3ede52a3eab56d35af674eb49ec5860335260826053536001605453604c60555360f3605653606060575360446058536096605953600c605a5360df605b5360f3605c5360fb605d53600c605e53609a605f53607f60605360fe606153603d60625360f4606353604b60645360cac001a0486b6dc55b8a311568b7239a2cae1d77e7446dba71df61eaafd53f73820a138fa010bd48a45e56133ac4c5645142c2ea48950d40eb35050e9510b6bad9e15c5865") - if err := tx.UnmarshalBinary(txpayload); err != nil { - t.Fatal(err) - } - gen.AddTx(&tx) - }) - - eip2935Stem := utils.GetTreeKey(params.HistoryStorageAddress[:], uint256.NewInt(0), 0) - eip2935Stem = eip2935Stem[:31] - - for _, stemStateDiff := range statediffs[0] { - // Handle the case of the history contract: make sure only the correct - // slots are added to the witness. - if bytes.Equal(stemStateDiff.Stem[:], eip2935Stem) { - // BLOCKHASH contract stem - if len(stemStateDiff.SuffixDiffs) > 1 { - t.Fatalf("invalid suffix diff count found for BLOCKHASH contract: %d != 1", len(stemStateDiff.SuffixDiffs)) - } - if stemStateDiff.SuffixDiffs[0].Suffix != 64 { - t.Fatalf("invalid suffix diff value found for BLOCKHASH contract: %d != 64", stemStateDiff.SuffixDiffs[0].Suffix) - } - // check that the "current value" is nil and that the new value isn't. - if stemStateDiff.SuffixDiffs[0].CurrentValue != nil { - t.Fatalf("non-nil current value in BLOCKHASH contract insert: %x", stemStateDiff.SuffixDiffs[0].CurrentValue) - } - if stemStateDiff.SuffixDiffs[0].NewValue == nil { - t.Fatalf("nil new value in BLOCKHASH contract insert") - } - if *stemStateDiff.SuffixDiffs[0].NewValue != genesisH { - t.Fatalf("invalid BLOCKHASH value: %x != %x", *stemStateDiff.SuffixDiffs[0].NewValue, genesisH) - } - } else { - for _, suffixDiff := range stemStateDiff.SuffixDiffs { - if suffixDiff.Suffix > 2 { - // if d8898012c484fb48610ecb7963886339207dab004bce968b007b616ffa18e0 shows up, it means that the PUSHn - // in the transaction above added entries into the witness, when they should not have since they are - // part of a contract deployment. - t.Fatalf("invalid suffix diff found for %x in block #1: %d\n", stemStateDiff.Stem, suffixDiff.Suffix) - } - } - } - } -} - -// TestProcessVerkleExtCodeHashOpcode verifies that calling EXTCODEHASH on another -// deployed contract, creates all the right entries in the witness. -func TestProcessVerkleExtCodeHashOpcode(t *testing.T) { - // The test txs were taken from a secondary testnet with chain id 69421 - config := *testKaustinenLikeChainConfig - config.ChainID.SetUint64(69421) - - var ( - signer = types.LatestSigner(&config) - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - gspec = verkleTestGenesis(&config) - ) - dummyContract := []byte{ - byte(vm.PUSH1), 2, - byte(vm.PUSH1), 12, - byte(vm.PUSH1), 0x00, - byte(vm.CODECOPY), - - byte(vm.PUSH1), 2, - byte(vm.PUSH1), 0x00, - byte(vm.RETURN), - - byte(vm.PUSH1), 42, - } - deployer := crypto.PubkeyToAddress(testKey.PublicKey) - dummyContractAddr := crypto.CreateAddress(deployer, 0) - - // contract that calls EXTCODEHASH on the dummy contract - extCodeHashContract := []byte{ - byte(vm.PUSH1), 22, - byte(vm.PUSH1), 12, - byte(vm.PUSH1), 0x00, - byte(vm.CODECOPY), - - byte(vm.PUSH1), 22, - byte(vm.PUSH1), 0x00, - byte(vm.RETURN), - - byte(vm.PUSH20), - 0x3a, 0x22, 0x0f, 0x35, 0x12, 0x52, 0x08, 0x9d, 0x38, 0x5b, 0x29, 0xbe, 0xca, 0x14, 0xe2, 0x7f, 0x20, 0x4c, 0x29, 0x6a, - byte(vm.EXTCODEHASH), - } - extCodeHashContractAddr := crypto.CreateAddress(deployer, 1) - - _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { - gen.SetPoS() - - if i == 0 { - // Create dummy contract. - tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, - Value: big.NewInt(0), - Gas: 100_000, - GasPrice: big.NewInt(875000000), - Data: dummyContract, - }) - gen.AddTx(tx) - - // Create contract with EXTCODEHASH opcode. - tx, _ = types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 1, - Value: big.NewInt(0), - Gas: 100_000, - GasPrice: big.NewInt(875000000), - Data: extCodeHashContract}) - gen.AddTx(tx) - } else { - tx, _ := types.SignTx(types.NewTransaction(2, extCodeHashContractAddr, big.NewInt(0), 100_000, big.NewInt(875000000), nil), signer, testKey) - gen.AddTx(tx) - } - }) - - contractKeccakTreeKey := utils.CodeHashKey(dummyContractAddr[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range statediffs[1] { - if bytes.Equal(stemStateDiff.Stem[:], contractKeccakTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatalf("no state diff found for stem") - } - - codeHashStateDiff := statediffs[1][stateDiffIdx].SuffixDiffs[0] - // Check location of code hash was accessed - if codeHashStateDiff.Suffix != utils.CodeHashLeafKey { - t.Fatalf("code hash invalid suffix") - } - // check the code hash wasn't present in the prestate, as - // the contract was deployed in this block. - if codeHashStateDiff.CurrentValue == nil { - t.Fatalf("codeHash.CurrentValue must not be empty") - } - // check the poststate value corresponds to the code hash - // of the deployed contract. - expCodeHash := crypto.Keccak256Hash(dummyContract[12:]) - if *codeHashStateDiff.CurrentValue != expCodeHash { - t.Fatalf("codeHash.CurrentValue unexpected code hash") - } - if codeHashStateDiff.NewValue != nil { - t.Fatalf("codeHash.NewValue must be nil") - } -} - -// TestProcessVerkleBalanceOpcode checks that calling balance -// on another contract will add the correct entries to the witness. -func TestProcessVerkleBalanceOpcode(t *testing.T) { - // The test txs were taken from a secondary testnet with chain id 69421 - config := *testKaustinenLikeChainConfig - config.ChainID.SetUint64(69421) - - var ( - signer = types.LatestSigner(&config) - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d") - gspec = verkleTestGenesis(&config) - ) - _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { - gen.SetPoS() - txData := slices.Concat( - []byte{byte(vm.PUSH20)}, - common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d").Bytes(), - []byte{byte(vm.BALANCE)}) - - tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, - Value: big.NewInt(0), - Gas: 100_000, - GasPrice: big.NewInt(875000000), - Data: txData}) - gen.AddTx(tx) - }) - - account2BalanceTreeKey := utils.BasicDataKey(account2[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range statediffs[0] { - if bytes.Equal(stemStateDiff.Stem[:], account2BalanceTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatalf("no state diff found for stem") - } - - var zero [32]byte - balanceStateDiff := statediffs[0][stateDiffIdx].SuffixDiffs[0] - if balanceStateDiff.Suffix != utils.BasicDataLeafKey { - t.Fatalf("invalid suffix diff") - } - // check the prestate balance wasn't 0 or missing - if balanceStateDiff.CurrentValue == nil || *balanceStateDiff.CurrentValue == zero { - t.Fatalf("invalid current value %v", *balanceStateDiff.CurrentValue) - } - // check that the poststate witness value for the balance is nil, - // meaning that it didn't get updated. - if balanceStateDiff.NewValue != nil { - t.Fatalf("invalid new value") - } -} - -// TestProcessVerkleSelfDestructInSeparateTx controls the contents of the witness after -// a non-eip6780-compliant selfdestruct occurs. -func TestProcessVerkleSelfDestructInSeparateTx(t *testing.T) { - // The test txs were taken from a secondary testnet with chain id 69421 - config := *testKaustinenLikeChainConfig - config.ChainID.SetUint64(69421) - - var ( - signer = types.LatestSigner(&config) - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d") - gspec = verkleTestGenesis(&config) - ) - - // runtime code: selfdestruct ( 0x6177843db3138ae69679A54b95cf345ED759450d ) - runtimeCode := slices.Concat( - []byte{byte(vm.PUSH20)}, - account2.Bytes(), - []byte{byte(vm.SELFDESTRUCT)}) - - //The goal of this test is to test SELFDESTRUCT that happens in a contract - // execution which is created in a previous transaction. - selfDestructContract := slices.Concat([]byte{ - byte(vm.PUSH1), byte(len(runtimeCode)), - byte(vm.PUSH1), 12, - byte(vm.PUSH1), 0x00, - byte(vm.CODECOPY), // Codecopy( to-offset: 0, code offset: 12, length: 22 ) - - byte(vm.PUSH1), byte(len(runtimeCode)), - byte(vm.PUSH1), 0x00, - byte(vm.RETURN), // Return ( 0 : len(runtimecode) - }, - runtimeCode) - - deployer := crypto.PubkeyToAddress(testKey.PublicKey) - contract := crypto.CreateAddress(deployer, 0) - - _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { - gen.SetPoS() - - if i == 0 { - // Create selfdestruct contract, sending 42 wei. - tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, - Value: big.NewInt(42), - Gas: 100_000, - GasPrice: big.NewInt(875000000), - Data: selfDestructContract, - }) - gen.AddTx(tx) - } else { - // Call it. - tx, _ := types.SignTx(types.NewTransaction(1, contract, big.NewInt(0), 100_000, big.NewInt(875000000), nil), signer, testKey) - gen.AddTx(tx) - } - }) - - var zero [32]byte - { // Check self-destructed contract in the witness - selfDestructContractTreeKey := utils.CodeHashKey(contract[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range statediffs[1] { - if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatalf("no state diff found for stem") - } - - balanceStateDiff := statediffs[1][stateDiffIdx].SuffixDiffs[0] - if balanceStateDiff.Suffix != utils.BasicDataLeafKey { - t.Fatalf("balance invalid suffix") - } - - // The original balance was 42. - var oldBalance [16]byte - oldBalance[15] = 42 - if !bytes.Equal((*balanceStateDiff.CurrentValue)[utils.BasicDataBalanceOffset:], oldBalance[:]) { - t.Fatalf("the pre-state balance before self-destruct must be %x, got %x", oldBalance, *balanceStateDiff.CurrentValue) - } - - // The new balance must be 0. - if !bytes.Equal((*balanceStateDiff.NewValue)[utils.BasicDataBalanceOffset:], zero[utils.BasicDataBalanceOffset:]) { - t.Fatalf("the post-state balance after self-destruct must be 0") - } - } - { // Check self-destructed target in the witness. - selfDestructTargetTreeKey := utils.CodeHashKey(account2[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range statediffs[1] { - if bytes.Equal(stemStateDiff.Stem[:], selfDestructTargetTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatalf("no state diff found for stem") - } - - balanceStateDiff := statediffs[1][stateDiffIdx].SuffixDiffs[0] - if balanceStateDiff.Suffix != utils.BasicDataLeafKey { - t.Fatalf("balance invalid suffix") - } - if balanceStateDiff.CurrentValue == nil { - t.Fatalf("codeHash.CurrentValue must not be empty") - } - if balanceStateDiff.NewValue == nil { - t.Fatalf("codeHash.NewValue must not be empty") - } - preStateBalance := binary.BigEndian.Uint64(balanceStateDiff.CurrentValue[utils.BasicDataBalanceOffset+8:]) - postStateBalance := binary.BigEndian.Uint64(balanceStateDiff.NewValue[utils.BasicDataBalanceOffset+8:]) - if postStateBalance-preStateBalance != 42 { - t.Fatalf("the post-state balance after self-destruct must be 42, got %d-%d=%d", postStateBalance, preStateBalance, postStateBalance-preStateBalance) - } - } -} - -// TestProcessVerkleSelfDestructInSeparateTx controls the contents of the witness after -// a eip6780-compliant selfdestruct occurs. -func TestProcessVerkleSelfDestructInSameTx(t *testing.T) { - // The test txs were taken from a secondary testnet with chain id 69421 - config := *testKaustinenLikeChainConfig - config.ChainID.SetUint64(69421) - - var ( - signer = types.LatestSigner(&config) - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - account2 = common.HexToAddress("0x6177843db3138ae69679A54b95cf345ED759450d") - gspec = verkleTestGenesis(&config) - ) - - // The goal of this test is to test SELFDESTRUCT that happens in a contract - // execution which is created in **the same** transaction sending the remaining - // balance to an external (i.e: not itself) account. - - selfDestructContract := slices.Concat( - []byte{byte(vm.PUSH20)}, - account2.Bytes(), - []byte{byte(vm.SELFDESTRUCT)}) - deployer := crypto.PubkeyToAddress(testKey.PublicKey) - contract := crypto.CreateAddress(deployer, 0) - - _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { - gen.SetPoS() - tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, - Value: big.NewInt(42), - Gas: 100_000, - GasPrice: big.NewInt(875000000), - Data: selfDestructContract, - }) - gen.AddTx(tx) - }) - - { // Check self-destructed contract in the witness - selfDestructContractTreeKey := utils.CodeHashKey(contract[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range statediffs[0] { - if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatalf("no state diff found for stem") - } - - balanceStateDiff := statediffs[0][stateDiffIdx].SuffixDiffs[0] - if balanceStateDiff.Suffix != utils.BasicDataLeafKey { - t.Fatalf("balance invalid suffix") - } - - if balanceStateDiff.CurrentValue != nil { - t.Fatalf("the pre-state balance before must be nil, since the contract didn't exist") - } - - if balanceStateDiff.NewValue != nil { - t.Fatalf("the post-state balance after self-destruct must be nil since the contract shouldn't be created at all") - } - } - { // Check self-destructed target in the witness. - selfDestructTargetTreeKey := utils.CodeHashKey(account2[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range statediffs[0] { - if bytes.Equal(stemStateDiff.Stem[:], selfDestructTargetTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatalf("no state diff found for stem") - } - - balanceStateDiff := statediffs[0][stateDiffIdx].SuffixDiffs[0] - if balanceStateDiff.Suffix != utils.BasicDataLeafKey { - t.Fatalf("balance invalid suffix") - } - if balanceStateDiff.CurrentValue == nil { - t.Fatalf("codeHash.CurrentValue must not be empty") - } - if balanceStateDiff.NewValue == nil { - t.Fatalf("codeHash.NewValue must not be empty") - } - preStateBalance := binary.BigEndian.Uint64(balanceStateDiff.CurrentValue[utils.BasicDataBalanceOffset+8:]) - postStateBalance := binary.BigEndian.Uint64(balanceStateDiff.NewValue[utils.BasicDataBalanceOffset+8:]) - if postStateBalance-preStateBalance != 42 { - t.Fatalf("the post-state balance after self-destruct must be 42. got %d", postStateBalance) - } - } -} - -// TestProcessVerkleSelfDestructInSeparateTxWithSelfBeneficiary checks the content of the witness -// if a selfdestruct occurs in a different tx than the one that created it, but the beneficiary -// is the selfdestructed account. -func TestProcessVerkleSelfDestructInSeparateTxWithSelfBeneficiary(t *testing.T) { - // The test txs were taken from a secondary testnet with chain id 69421 - config := *testKaustinenLikeChainConfig - config.ChainID.SetUint64(69421) - - var ( - signer = types.LatestSigner(&config) - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - gspec = verkleTestGenesis(&config) - ) - // The goal of this test is to test SELFDESTRUCT that happens in a contract - // execution which is created in a *previous* transaction sending the remaining - // balance to itself. - selfDestructContract := []byte{ - byte(vm.PUSH1), 2, // PUSH1 2 - byte(vm.PUSH1), 10, // PUSH1 12 - byte(vm.PUSH0), // PUSH0 - byte(vm.CODECOPY), // Codecopy ( to offset 0, code@offset: 10, length: 2) - - byte(vm.PUSH1), 22, - byte(vm.PUSH0), - byte(vm.RETURN), // RETURN( memory[0:2] ) - - // Deployed code - byte(vm.ADDRESS), - byte(vm.SELFDESTRUCT), - } - deployer := crypto.PubkeyToAddress(testKey.PublicKey) - contract := crypto.CreateAddress(deployer, 0) - - _, _, _, _, _, statediffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 2, func(i int, gen *BlockGen) { - gen.SetPoS() - if i == 0 { - // Create self-destruct contract, sending 42 wei. - tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, - Value: big.NewInt(42), - Gas: 100_000, - GasPrice: big.NewInt(875000000), - Data: selfDestructContract, - }) - gen.AddTx(tx) - } else { - // Call it. - tx, _ := types.SignTx(types.NewTransaction(1, contract, big.NewInt(0), 100_000, big.NewInt(875000000), nil), signer, testKey) - gen.AddTx(tx) - } - }) - - { - // Check self-destructed contract in the witness. - // The way 6780 is implemented today, it always SubBalance from the self-destructed contract, and AddBalance - // to the beneficiary. In this case both addresses are the same, thus this might be optimizable from a gas - // perspective. But until that happens, we need to honor this "balance reading" adding it to the witness. - - selfDestructContractTreeKey := utils.CodeHashKey(contract[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range statediffs[1] { - if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatal("no state diff found for stem") - } - - balanceStateDiff := statediffs[1][stateDiffIdx].SuffixDiffs[0] - if balanceStateDiff.Suffix != utils.BasicDataLeafKey { - t.Fatal("balance invalid suffix") - } - - // The original balance was 42. - var oldBalance [16]byte - oldBalance[15] = 42 - if !bytes.Equal((*balanceStateDiff.CurrentValue)[utils.BasicDataBalanceOffset:], oldBalance[:]) { - t.Fatal("the pre-state balance before self-destruct must be 42") - } - - // Note that the SubBalance+AddBalance net effect is a 0 change, so NewValue - // must be nil. - if balanceStateDiff.NewValue != nil { - t.Fatal("the post-state balance after self-destruct must be empty") - } - } -} - -// TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary checks the content of the witness -// if a selfdestruct occurs in the same tx as the one that created it, but the beneficiary -// is the selfdestructed account. -func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiary(t *testing.T) { - // The test txs were taken from a secondary testnet with chain id 69421 - config := *testKaustinenLikeChainConfig - config.ChainID.SetUint64(69421) - - var ( - signer = types.LatestSigner(&config) - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - gspec = verkleTestGenesis(&config) - deployer = crypto.PubkeyToAddress(testKey.PublicKey) - contract = crypto.CreateAddress(deployer, 0) - ) - - // The goal of this test is to test SELFDESTRUCT that happens while executing - // the init code of a contract creation, that occurs in **the same** transaction. - // The balance is sent to itself. - t.Logf("Contract: %v", contract.String()) - - selfDestructContract := []byte{byte(vm.ADDRESS), byte(vm.SELFDESTRUCT)} - - _, _, _, _, _, stateDiffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { - gen.SetPoS() - tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, - Value: big.NewInt(42), - Gas: 100_000, - GasPrice: big.NewInt(875000000), - Data: selfDestructContract, - }) - gen.AddTx(tx) - }) - stateDiff := stateDiffs[0] // state difference of block 1 - - { // Check self-destructed contract in the witness - selfDestructContractTreeKey := utils.CodeHashKey(contract[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range stateDiff { - if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatal("no state diff found for stem") - } - balanceStateDiff := stateDiff[stateDiffIdx].SuffixDiffs[0] - if balanceStateDiff.Suffix != utils.BasicDataLeafKey { - t.Fatal("balance invalid suffix") - } - if balanceStateDiff.CurrentValue != nil { - t.Fatal("the pre-state balance before must be nil, since the contract didn't exist") - } - // Ensure that the value is burnt, and therefore that the balance of the self-destructed - // contract isn't modified (it should remain missing from the state) - if balanceStateDiff.NewValue != nil { - t.Fatal("the post-state balance after self-destruct must be nil since the contract shouldn't be created at all") - } - } -} - -// TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiaryAndPrefundedAccount checks the -// content of the witness if a selfdestruct occurs in the same tx as the one that created it, -// it, but the beneficiary is the selfdestructed account. The difference with the test above, -// is that the created account is prefunded and so the final value should be 0. -func TestProcessVerkleSelfDestructInSameTxWithSelfBeneficiaryAndPrefundedAccount(t *testing.T) { - // The test txs were taken from a secondary testnet with chain id 69421 - config := *testKaustinenLikeChainConfig - config.ChainID.SetUint64(69421) - - var ( - signer = types.LatestSigner(&config) - testKey, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") - gspec = verkleTestGenesis(&config) - deployer = crypto.PubkeyToAddress(testKey.PublicKey) - contract = crypto.CreateAddress(deployer, 0) - ) - // Prefund the account, at an address that the contract will be deployed at, - // before it selfdestrucs. We can therefore check that the account itseld is - // NOT destroyed, which is what the current version of the spec requires. - // TODO(gballet) revisit after the spec has been modified. - gspec.Alloc[contract] = types.Account{ - Balance: big.NewInt(100), - } - - selfDestructContract := []byte{byte(vm.ADDRESS), byte(vm.SELFDESTRUCT)} - - _, _, _, _, _, stateDiffs := GenerateVerkleChainWithGenesis(gspec, beacon.New(ethash.NewFaker()), 1, func(i int, gen *BlockGen) { - gen.SetPoS() - tx, _ := types.SignNewTx(testKey, signer, &types.LegacyTx{Nonce: 0, - Value: big.NewInt(42), - Gas: 100_000, - GasPrice: big.NewInt(875000000), - Data: selfDestructContract, - }) - gen.AddTx(tx) - }) - stateDiff := stateDiffs[0] // state difference of block 1 - - { // Check self-destructed contract in the witness - selfDestructContractTreeKey := utils.CodeHashKey(contract[:]) - - var stateDiffIdx = -1 - for i, stemStateDiff := range stateDiff { - if bytes.Equal(stemStateDiff.Stem[:], selfDestructContractTreeKey[:31]) { - stateDiffIdx = i - break - } - } - if stateDiffIdx == -1 { - t.Fatal("no state diff found for stem") - } - balanceStateDiff := stateDiff[stateDiffIdx].SuffixDiffs[0] - if balanceStateDiff.Suffix != utils.BasicDataLeafKey { - t.Fatal("balance invalid suffix") - } - expected, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000064") - if balanceStateDiff.CurrentValue == nil || !bytes.Equal(balanceStateDiff.CurrentValue[:], expected) { - t.Fatalf("incorrect prestate balance: %x != %x", *balanceStateDiff.CurrentValue, expected) - } - // Ensure that the value is burnt, and therefore that the balance of the self-destructed - // contract isn't modified (it should remain missing from the state) - expected = make([]byte, 32) - if balanceStateDiff.NewValue == nil { - t.Fatal("incorrect nil poststate balance") - } - if !bytes.Equal(balanceStateDiff.NewValue[:], expected[:]) { - t.Fatalf("incorrect poststate balance: %x != %x", *balanceStateDiff.NewValue, expected[:]) - } - } -} diff --git a/core/vm/analysis_legacy_test.go b/core/vm/analysis_legacy_test.go index f84a4abc92..75d8a495fa 100644 --- a/core/vm/analysis_legacy_test.go +++ b/core/vm/analysis_legacy_test.go @@ -65,21 +65,17 @@ func BenchmarkJumpdestAnalysis_1200k(bench *testing.B) { // 1.4 ms code := make([]byte, analysisCodeSize) bench.SetBytes(analysisCodeSize) - bench.ResetTimer() - for i := 0; i < bench.N; i++ { + for bench.Loop() { codeBitmap(code) } - bench.StopTimer() } func BenchmarkJumpdestHashing_1200k(bench *testing.B) { // 4 ms code := make([]byte, analysisCodeSize) bench.SetBytes(analysisCodeSize) - bench.ResetTimer() - for i := 0; i < bench.N; i++ { + for bench.Loop() { crypto.Keccak256Hash(code) } - bench.StopTimer() } func BenchmarkJumpdestOpAnalysis(bench *testing.B) { @@ -91,8 +87,7 @@ func BenchmarkJumpdestOpAnalysis(bench *testing.B) { code[i] = byte(op) } bits := make(BitVec, len(code)/8+1+4) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { clear(bits) codeBitmapInternal(code, bits) } diff --git a/core/vm/common.go b/core/vm/common.go index 658803b820..2990f58972 100644 --- a/core/vm/common.go +++ b/core/vm/common.go @@ -84,12 +84,3 @@ func toWordSize(size uint64) uint64 { return (size + 31) / 32 } - -func allZero(b []byte) bool { - for _, byte := range b { - if byte != 0 { - return false - } - } - return true -} diff --git a/core/vm/contracts.go b/core/vm/contracts.go index 21307ff5ac..867746acc8 100644 --- a/core/vm/contracts.go +++ b/core/vm/contracts.go @@ -24,12 +24,15 @@ import ( "maps" "math" "math/big" + "math/bits" "github.com/consensys/gnark-crypto/ecc" bls12381 "github.com/consensys/gnark-crypto/ecc/bls12-381" "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" + patched_big "github.com/ethereum/go-bigmodexpfix/src/math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/bitutil" "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/blake2b" @@ -37,6 +40,7 @@ import ( "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/crypto/secp256r1" "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" "golang.org/x/crypto/ripemd160" ) @@ -46,6 +50,7 @@ import ( type PrecompiledContract interface { RequiredGas(input []byte) uint64 // RequiredPrice calculates the contract gas use Run(input []byte) ([]byte, error) // Run runs the precompiled contract + Name() string } // PrecompiledContracts contains the precompiled contracts supported at the given fork. @@ -289,16 +294,16 @@ func (c *ecrecover) Run(input []byte) ([]byte, error) { v := input[63] - 27 // tighter sig s values input homestead only apply to tx sigs - if !allZero(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) { + if bitutil.TestBytes(input[32:63]) || !crypto.ValidateSignatureValues(v, r, s, false) { return nil, nil } // We must make sure not to modify the 'input', so placing the 'v' along with // the signature needs to be done on a new allocation - sig := make([]byte, 65) - copy(sig, input[64:128]) + var sig [65]byte + copy(sig[:], input[64:128]) sig[64] = v // v needs to be at the end for libsecp256k1 - pubKey, err := crypto.Ecrecover(input[:32], sig) + pubKey, err := crypto.Ecrecover(input[:32], sig[:]) // make sure the public key is a valid one if err != nil { return nil, nil @@ -308,6 +313,10 @@ func (c *ecrecover) Run(input []byte) ([]byte, error) { return common.LeftPadBytes(crypto.Keccak256(pubKey[1:])[12:], 32), nil } +func (c *ecrecover) Name() string { + return "ECREC" +} + // SHA256 implemented as a native contract. type sha256hash struct{} @@ -323,6 +332,10 @@ func (c *sha256hash) Run(input []byte) ([]byte, error) { return h[:], nil } +func (c *sha256hash) Name() string { + return "SHA256" +} + // RIPEMD160 implemented as a native contract. type ripemd160hash struct{} @@ -339,6 +352,10 @@ func (c *ripemd160hash) Run(input []byte) ([]byte, error) { return common.LeftPadBytes(ripemd.Sum(nil), 32), nil } +func (c *ripemd160hash) Name() string { + return "RIPEMD160" +} + // data copy implemented as a native contract. type dataCopy struct{} @@ -353,6 +370,10 @@ func (c *dataCopy) Run(in []byte) ([]byte, error) { return common.CopyBytes(in), nil } +func (c *dataCopy) Name() string { + return "ID" +} + // bigModExp implements a native big integer exponential modular operation. type bigModExp struct { eip2565 bool @@ -360,21 +381,7 @@ type bigModExp struct { eip7883 bool } -var ( - big1 = big.NewInt(1) - big3 = big.NewInt(3) - big7 = big.NewInt(7) - big20 = big.NewInt(20) - big32 = big.NewInt(32) - big64 = big.NewInt(64) - big96 = big.NewInt(96) - big480 = big.NewInt(480) - big1024 = big.NewInt(1024) - big3072 = big.NewInt(3072) - big199680 = big.NewInt(199680) -) - -// modexpMultComplexity implements bigModexp multComplexity formula, as defined in EIP-198 +// byzantiumMultComplexity implements the bigModexp multComplexity formula, as defined in EIP-198. // // def mult_complexity(x): // if x <= 64: return x ** 2 @@ -382,146 +389,251 @@ var ( // else: return x ** 2 // 16 + 480 * x - 199680 // // where is x is max(length_of_MODULUS, length_of_BASE) -func modexpMultComplexity(x *big.Int) *big.Int { +// returns MaxUint64 if an overflow occurred. +func byzantiumMultComplexity(x uint64) uint64 { switch { - case x.Cmp(big64) <= 0: - x.Mul(x, x) // x ** 2 - case x.Cmp(big1024) <= 0: - // (x ** 2 // 4 ) + ( 96 * x - 3072) - x = new(big.Int).Add( - new(big.Int).Rsh(new(big.Int).Mul(x, x), 2), - new(big.Int).Sub(new(big.Int).Mul(big96, x), big3072), - ) + case x <= 64: + return x * x + case x <= 1024: + // x^2 / 4 + 96*x - 3072 + return x*x/4 + 96*x - 3072 + default: - // (x ** 2 // 16) + (480 * x - 199680) - x = new(big.Int).Add( - new(big.Int).Rsh(new(big.Int).Mul(x, x), 4), - new(big.Int).Sub(new(big.Int).Mul(big480, x), big199680), - ) + // For large x, use uint256 arithmetic to avoid overflow + // x^2 / 16 + 480*x - 199680 + + // xSqr = x^2 / 16 + carry, xSqr := bits.Mul64(x, x) + if carry != 0 { + return math.MaxUint64 + } + xSqr = xSqr >> 4 + + // Calculate 480 * x (can't overflow if x^2 didn't overflow) + x480 := x * 480 + // Calculate 480 * x - 199680 (will not underflow, since x > 1024) + x480 = x480 - 199680 + + // xSqr + x480 + sum, carry := bits.Add64(xSqr, x480, 0) + if carry != 0 { + return math.MaxUint64 + } + return sum + } +} + +// berlinMultComplexity implements the multiplication complexity formula for Berlin. +// +// def mult_complexity(x): +// +// ceiling(x/8)^2 +// +// where is x is max(length_of_MODULUS, length_of_BASE) +func berlinMultComplexity(x uint64) uint64 { + // x = (x + 7) / 8 + x, carry := bits.Add64(x, 7, 0) + if carry != 0 { + return math.MaxUint64 + } + x /= 8 + + // x^2 + carry, x = bits.Mul64(x, x) + if carry != 0 { + return math.MaxUint64 } return x } +// osakaMultComplexity implements the multiplication complexity formula for Osaka. +// +// For x <= 32: returns 16 +// For x > 32: returns 2 * ceiling(x/8)^2 +func osakaMultComplexity(x uint64) uint64 { + if x <= 32 { + return 16 + } + // For x > 32, return 2 * berlinMultComplexity(x) + result := berlinMultComplexity(x) + carry, result := bits.Mul64(result, 2) + if carry != 0 { + return math.MaxUint64 + } + return result +} + +// modexpIterationCount calculates the number of iterations for the modexp precompile. +// This is the adjusted exponent length used in gas calculation. +func modexpIterationCount(expLen uint64, expHead uint256.Int, multiplier uint64) uint64 { + var iterationCount uint64 + + // For large exponents (expLen > 32), add (expLen - 32) * multiplier + if expLen > 32 { + carry, count := bits.Mul64(expLen-32, multiplier) + if carry > 0 { + return math.MaxUint64 + } + iterationCount = count + } + // Add the MSB position - 1 if expHead is non-zero + if bitLen := expHead.BitLen(); bitLen > 0 { + count, carry := bits.Add64(iterationCount, uint64(bitLen-1), 0) + if carry > 0 { + return math.MaxUint64 + } + iterationCount = count + } + + return max(iterationCount, 1) +} + +// byzantiumModexpGas calculates the gas cost for the modexp precompile using Byzantium rules. +func byzantiumModexpGas(baseLen, expLen, modLen uint64, expHead uint256.Int) uint64 { + const ( + multiplier = 8 + divisor = 20 + ) + + maxLen := max(baseLen, modLen) + multComplexity := byzantiumMultComplexity(maxLen) + if multComplexity == math.MaxUint64 { + return math.MaxUint64 + } + iterationCount := modexpIterationCount(expLen, expHead, multiplier) + + // Calculate gas: (multComplexity * iterationCount) / divisor + carry, gas := bits.Mul64(iterationCount, multComplexity) + gas /= divisor + if carry != 0 { + return math.MaxUint64 + } + return gas +} + +// berlinModexpGas calculates the gas cost for the modexp precompile using Berlin rules. +func berlinModexpGas(baseLen, expLen, modLen uint64, expHead uint256.Int) uint64 { + const ( + multiplier = 8 + divisor = 3 + minGas = 200 + ) + + maxLen := max(baseLen, modLen) + multComplexity := berlinMultComplexity(maxLen) + if multComplexity == math.MaxUint64 { + return math.MaxUint64 + } + iterationCount := modexpIterationCount(expLen, expHead, multiplier) + + // Calculate gas: (multComplexity * iterationCount) / divisor + carry, gas := bits.Mul64(iterationCount, multComplexity) + gas /= divisor + if carry != 0 { + return math.MaxUint64 + } + return max(gas, minGas) +} + +// osakaModexpGas calculates the gas cost for the modexp precompile using Osaka rules. +func osakaModexpGas(baseLen, expLen, modLen uint64, expHead uint256.Int) uint64 { + const ( + multiplier = 16 + minGas = 500 + ) + + maxLen := max(baseLen, modLen) + multComplexity := osakaMultComplexity(maxLen) + if multComplexity == math.MaxUint64 { + return math.MaxUint64 + } + iterationCount := modexpIterationCount(expLen, expHead, multiplier) + + // Calculate gas: multComplexity * iterationCount + carry, gas := bits.Mul64(iterationCount, multComplexity) + if carry != 0 { + return math.MaxUint64 + } + return max(gas, minGas) +} + // RequiredGas returns the gas required to execute the pre-compiled contract. func (c *bigModExp) RequiredGas(input []byte) uint64 { - var ( - baseLen = new(big.Int).SetBytes(getData(input, 0, 32)) - expLen = new(big.Int).SetBytes(getData(input, 32, 32)) - modLen = new(big.Int).SetBytes(getData(input, 64, 32)) - ) + // Parse input lengths + baseLenBig := new(uint256.Int).SetBytes(getData(input, 0, 32)) + expLenBig := new(uint256.Int).SetBytes(getData(input, 32, 32)) + modLenBig := new(uint256.Int).SetBytes(getData(input, 64, 32)) + + // Convert to uint64, capping at max value + baseLen := baseLenBig.Uint64() + if !baseLenBig.IsUint64() { + baseLen = math.MaxUint64 + } + expLen := expLenBig.Uint64() + if !expLenBig.IsUint64() { + expLen = math.MaxUint64 + } + modLen := modLenBig.Uint64() + if !modLenBig.IsUint64() { + modLen = math.MaxUint64 + } + + // Skip the header if len(input) > 96 { input = input[96:] } else { input = input[:0] } + // Retrieve the head 32 bytes of exp for the adjusted exponent length - var expHead *big.Int - if big.NewInt(int64(len(input))).Cmp(baseLen) <= 0 { - expHead = new(big.Int) - } else { - if expLen.Cmp(big32) > 0 { - expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), 32)) + var expHead uint256.Int + if uint64(len(input)) > baseLen { + if expLen > 32 { + expHead.SetBytes(getData(input, baseLen, 32)) } else { - expHead = new(big.Int).SetBytes(getData(input, baseLen.Uint64(), expLen.Uint64())) + expHead.SetBytes(getData(input, baseLen, expLen)) } } - // Calculate the adjusted exponent length - var msb int - if bitlen := expHead.BitLen(); bitlen > 0 { - msb = bitlen - 1 - } - adjExpLen := new(big.Int) - if expLen.Cmp(big32) > 0 { - adjExpLen.Sub(expLen, big32) - if c.eip7883 { - adjExpLen.Lsh(adjExpLen, 4) - } else { - adjExpLen.Lsh(adjExpLen, 3) - } - } - adjExpLen.Add(adjExpLen, big.NewInt(int64(msb))) - // Calculate the gas cost of the operation - gas := new(big.Int) - if modLen.Cmp(baseLen) < 0 { - gas.Set(baseLen) + + // Choose the appropriate gas calculation based on the EIP flags + if c.eip7883 { + return osakaModexpGas(baseLen, expLen, modLen, expHead) + } else if c.eip2565 { + return berlinModexpGas(baseLen, expLen, modLen, expHead) } else { - gas.Set(modLen) + return byzantiumModexpGas(baseLen, expLen, modLen, expHead) } - - maxLenOver32 := gas.Cmp(big32) > 0 - if c.eip2565 { - // EIP-2565 (Berlin fork) has three changes: - // - // 1. Different multComplexity (inlined here) - // in EIP-2565 (https://eips.ethereum.org/EIPS/eip-2565): - // - // def mult_complexity(x): - // ceiling(x/8)^2 - // - // where is x is max(length_of_MODULUS, length_of_BASE) - gas.Add(gas, big7) - gas.Rsh(gas, 3) - gas.Mul(gas, gas) - - var minPrice uint64 = 200 - if c.eip7883 { - minPrice = 500 - if maxLenOver32 { - gas.Add(gas, gas) - } else { - gas = big.NewInt(16) - } - } - - if adjExpLen.Cmp(big1) > 0 { - gas.Mul(gas, adjExpLen) - } - // 2. Different divisor (`GQUADDIVISOR`) (3) - if !c.eip7883 { - gas.Div(gas, big3) - } - if gas.BitLen() > 64 { - return math.MaxUint64 - } - return max(minPrice, gas.Uint64()) - } - - // Pre-Berlin logic. - gas = modexpMultComplexity(gas) - if adjExpLen.Cmp(big1) > 0 { - gas.Mul(gas, adjExpLen) - } - gas.Div(gas, big20) - if gas.BitLen() > 64 { - return math.MaxUint64 - } - return gas.Uint64() } func (c *bigModExp) Run(input []byte) ([]byte, error) { var ( - baseLen = new(big.Int).SetBytes(getData(input, 0, 32)).Uint64() - expLen = new(big.Int).SetBytes(getData(input, 32, 32)).Uint64() - modLen = new(big.Int).SetBytes(getData(input, 64, 32)).Uint64() + baseLenBig = new(big.Int).SetBytes(getData(input, 0, 32)) + expLenBig = new(big.Int).SetBytes(getData(input, 32, 32)) + modLenBig = new(big.Int).SetBytes(getData(input, 64, 32)) + baseLen = baseLenBig.Uint64() + expLen = expLenBig.Uint64() + modLen = modLenBig.Uint64() + inputLenOverflow = max(baseLenBig.BitLen(), expLenBig.BitLen(), modLenBig.BitLen()) > 64 ) if len(input) > 96 { input = input[96:] } else { input = input[:0] } + + // enforce size cap for inputs + if c.eip7823 && (inputLenOverflow || max(baseLen, expLen, modLen) > 1024) { + return nil, errors.New("one or more of base/exponent/modulus length exceeded 1024 bytes") + } // Handle a special case when both the base and mod length is zero if baseLen == 0 && modLen == 0 { return []byte{}, nil } - // enforce size cap for inputs - if c.eip7823 && max(baseLen, expLen, modLen) > 1024 { - return nil, errors.New("one or more of base/exponent/modulus length exceeded 1024 bytes") - } // Retrieve the operands and execute the exponentiation var ( - base = new(big.Int).SetBytes(getData(input, 0, baseLen)) - exp = new(big.Int).SetBytes(getData(input, baseLen, expLen)) - mod = new(big.Int).SetBytes(getData(input, baseLen+expLen, modLen)) + base = new(patched_big.Int).SetBytes(getData(input, 0, baseLen)) + exp = new(patched_big.Int).SetBytes(getData(input, baseLen, expLen)) + mod = new(patched_big.Int).SetBytes(getData(input, baseLen+expLen, modLen)) v []byte ) switch { @@ -537,6 +649,10 @@ func (c *bigModExp) Run(input []byte) ([]byte, error) { return common.LeftPadBytes(v, int(modLen)), nil } +func (c *bigModExp) Name() string { + return "MODEXP" +} + // newCurvePoint unmarshals a binary blob into a bn256 elliptic curve point, // returning it, or an error if the point is invalid. func newCurvePoint(blob []byte) (*bn256.G1, error) { @@ -586,6 +702,10 @@ func (c *bn256AddIstanbul) Run(input []byte) ([]byte, error) { return runBn256Add(input) } +func (c *bn256AddIstanbul) Name() string { + return "BN254_ADD" +} + // bn256AddByzantium implements a native elliptic curve point addition // conforming to Byzantium consensus rules. type bn256AddByzantium struct{} @@ -599,6 +719,10 @@ func (c *bn256AddByzantium) Run(input []byte) ([]byte, error) { return runBn256Add(input) } +func (c *bn256AddByzantium) Name() string { + return "BN254_ADD" +} + // runBn256ScalarMul implements the Bn256ScalarMul precompile, referenced by // both Byzantium and Istanbul operations. func runBn256ScalarMul(input []byte) ([]byte, error) { @@ -624,6 +748,10 @@ func (c *bn256ScalarMulIstanbul) Run(input []byte) ([]byte, error) { return runBn256ScalarMul(input) } +func (c *bn256ScalarMulIstanbul) Name() string { + return "BN254_MUL" +} + // bn256ScalarMulByzantium implements a native elliptic curve scalar // multiplication conforming to Byzantium consensus rules. type bn256ScalarMulByzantium struct{} @@ -637,6 +765,10 @@ func (c *bn256ScalarMulByzantium) Run(input []byte) ([]byte, error) { return runBn256ScalarMul(input) } +func (c *bn256ScalarMulByzantium) Name() string { + return "BN254_MUL" +} + var ( // true32Byte is returned if the bn256 pairing check succeeds. true32Byte = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1} @@ -692,6 +824,10 @@ func (c *bn256PairingIstanbul) Run(input []byte) ([]byte, error) { return runBn256Pairing(input) } +func (c *bn256PairingIstanbul) Name() string { + return "BN254_PAIRING" +} + // bn256PairingByzantium implements a pairing pre-compile for the bn256 curve // conforming to Byzantium consensus rules. type bn256PairingByzantium struct{} @@ -705,6 +841,10 @@ func (c *bn256PairingByzantium) Run(input []byte) ([]byte, error) { return runBn256Pairing(input) } +func (c *bn256PairingByzantium) Name() string { + return "BN254_PAIRING" +} + type blake2F struct{} func (c *blake2F) RequiredGas(input []byte) uint64 { @@ -766,6 +906,10 @@ func (c *blake2F) Run(input []byte) ([]byte, error) { return output, nil } +func (c *blake2F) Name() string { + return "BLAKE2F" +} + var ( errBLS12381InvalidInputLength = errors.New("invalid input length") errBLS12381InvalidFieldElementTopBytes = errors.New("invalid field element top bytes") @@ -809,6 +953,10 @@ func (c *bls12381G1Add) Run(input []byte) ([]byte, error) { return encodePointG1(p0), nil } +func (c *bls12381G1Add) Name() string { + return "BLS12_G1ADD" +} + // bls12381G1MultiExp implements EIP-2537 G1MultiExp precompile. type bls12381G1MultiExp struct{} @@ -869,6 +1017,10 @@ func (c *bls12381G1MultiExp) Run(input []byte) ([]byte, error) { return encodePointG1(r), nil } +func (c *bls12381G1MultiExp) Name() string { + return "BLS12_G1MSM" +} + // bls12381G2Add implements EIP-2537 G2Add precompile. type bls12381G2Add struct{} @@ -906,6 +1058,10 @@ func (c *bls12381G2Add) Run(input []byte) ([]byte, error) { return encodePointG2(r), nil } +func (c *bls12381G2Add) Name() string { + return "BLS12_G2ADD" +} + // bls12381G2MultiExp implements EIP-2537 G2MultiExp precompile. type bls12381G2MultiExp struct{} @@ -966,6 +1122,10 @@ func (c *bls12381G2MultiExp) Run(input []byte) ([]byte, error) { return encodePointG2(r), nil } +func (c *bls12381G2MultiExp) Name() string { + return "BLS12_G2MSM" +} + // bls12381Pairing implements EIP-2537 Pairing precompile. type bls12381Pairing struct{} @@ -1029,6 +1189,10 @@ func (c *bls12381Pairing) Run(input []byte) ([]byte, error) { return out, nil } +func (c *bls12381Pairing) Name() string { + return "BLS12_PAIRING_CHECK" +} + func decodePointG1(in []byte) (*bls12381.G1Affine, error) { if len(in) != 128 { return nil, errors.New("invalid g1 point length") @@ -1147,6 +1311,10 @@ func (c *bls12381MapG1) Run(input []byte) ([]byte, error) { return encodePointG1(&r), nil } +func (c *bls12381MapG1) Name() string { + return "BLS12_MAP_FP_TO_G1" +} + // bls12381MapG2 implements EIP-2537 MapG2 precompile. type bls12381MapG2 struct{} @@ -1180,6 +1348,10 @@ func (c *bls12381MapG2) Run(input []byte) ([]byte, error) { return encodePointG2(&r), nil } +func (c *bls12381MapG2) Name() string { + return "BLS12_MAP_FP2_TO_G2" +} + // kzgPointEvaluation implements the EIP-4844 point evaluation precompile. type kzgPointEvaluation struct{} @@ -1236,6 +1408,10 @@ func (b *kzgPointEvaluation) Run(input []byte) ([]byte, error) { return common.Hex2Bytes(blobPrecompileReturnValue), nil } +func (b *kzgPointEvaluation) Name() string { + return "KZG_POINT_EVALUATION" +} + // kZGToVersionedHash implements kzg_to_versioned_hash from EIP-4844 func kZGToVersionedHash(kzg kzg4844.Commitment) common.Hash { h := sha256.Sum256(kzg[:]) @@ -1271,3 +1447,7 @@ func (c *p256Verify) Run(input []byte) ([]byte, error) { } return nil, nil } + +func (c *p256Verify) Name() string { + return "P256VERIFY" +} diff --git a/core/vm/contracts_test.go b/core/vm/contracts_test.go index da44e250e1..51bd7101ff 100644 --- a/core/vm/contracts_test.go +++ b/core/vm/contracts_test.go @@ -118,7 +118,7 @@ func testPrecompiled(addr string, test precompiledTest, t *testing.T) { func testPrecompiledOOG(addr string, test precompiledTest, t *testing.T) { p := allPrecompiles[common.HexToAddress(addr)] in := common.Hex2Bytes(test.Input) - gas := p.RequiredGas(in) - 1 + gas := test.Gas - 1 t.Run(fmt.Sprintf("%s-Gas=%d", test.Name, gas), func(t *testing.T) { _, _, err := RunPrecompiledContract(p, in, gas, nil) @@ -167,12 +167,10 @@ func benchmarkPrecompiled(addr string, test precompiledTest, bench *testing.B) { bench.Run(fmt.Sprintf("%s-Gas=%d", test.Name, reqGas), func(bench *testing.B) { bench.ReportAllocs() start := time.Now() - bench.ResetTimer() - for i := 0; i < bench.N; i++ { + for bench.Loop() { copy(data, in) res, _, err = RunPrecompiledContract(p, data, reqGas, nil) } - bench.StopTimer() elapsed := uint64(time.Since(start)) if elapsed < 1 { elapsed = 1 @@ -257,6 +255,30 @@ func TestPrecompiledModExpOOG(t *testing.T) { for _, test := range modexpTests { testPrecompiledOOG("05", test, t) } + modexpTestsEIP2565, err := loadJson("modexp_eip2565") + if err != nil { + t.Fatal(err) + } + for _, test := range modexpTestsEIP2565 { + testPrecompiledOOG("f5", test, t) + } + modexpTestsEIP7883, err := loadJson("modexp_eip7883") + if err != nil { + t.Fatal(err) + } + for _, test := range modexpTestsEIP7883 { + testPrecompiledOOG("f6", test, t) + } + gasCostTest := precompiledTest{ + Input: "000000000000000000000000000000000000000000000000000000000000082800000000000000000000000000000000000000000000000040000000000000090000000000000000000000000000000000000000000000000000000000000600000000adadadad00000000ff31ff00000006ffffffffffffffffffffffffffffffffffffffff0000000000000004ffffffffffffff0000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0000001000200fefffeff01000100000000000000ffff01000100ffffffff01000100ffffffff0000050001000100fefffdff02000300ff000000000000012b000000000000090000000000000000000000000000000000000000000000000000ffffff000000000200fffffeff00000001000000000001000200fefffeff010001000000000000000000423034000000000011006161ffbf640053004f00ff00fffffffffffffff3ff00000000000f00002dffffffffff0000000000000000000061999999999999999999999999899961ffffffff0100010000000000000000000000000600000000adadadad00000000ffff00000006fffffdffffffffffffffffffffffffffffffffff0000000000000004ffffffffffffff000000000000000000000000000000000000000098000000966375726c2f66000030000000000011006161ffbf640053004f002d00000000a200000000000000ff1818183fffffffff3a6e756c6c2c22223a6e7500006c2000000000002d2d0000000000000000000144ccef0100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000fdff000000ff00290001000009000000000000000000000000000000000000000000000000a50004ff2800000000000000000000000000000000000000000000000001000000000000090000000000000000000000030000000000000000002b00000000000000000600000000adadadad00000000ffff00000006ffffffffffffffffffffffffffffffffffffffff0000000000000004ffffffffffffff0000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212373800002d35373837346137346161610000000000000000d0d0d0d0d0d0d0d0002d3533321a1a000000d0d0d0d0d0d0d0d0d0d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121a1212121212121212000000000000000000000000d0d0d0d0d0d0d0d0002d3533321a1a0000000000000000000000003300000001000f5b00001100712c6eff9e61000000000061000000fbffff1a1a3a6e353900756c6c7d3b00000000009100002d35ff00600000000000000000002d3533321a1a1a1a3a6e353900756c6c7d3b000000000091373800002d3537383734613734616161d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121a1212121212121212000000000000000000000000d0d0d0d0d0d0d0d0002d3533321a1a0000000000000000000000003300000001000f5b00001100712c6eff9e61000000000061000000fbffff1a1a3a6e353900756c6c7d3b00000000009100002d35ff00600000000000000000002d3533321a1a1a1a3a6e353900756c6c7d3b000000000091373800002d353738373461373461616100000000000000000000000000000000000000000000000001000000000000090000000000000000000000030000000000000000002b00000000000000000600000000adadadad00000000ffff00000006ffffffffffffffffffffffffffffffffffffffff0000000000000004ffffffffffffff0000000000000000000000000000000000000000d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d01212121212121212121212121212121212121212121212121212121212121212121212121212121212121212373800002d35373837346137346161610000000000000000d0d0d0d0d0d0d0d0002d3533321a1a000000d0d0d0d0d0d0d0d0d0d0d0d0d0d000000000717a1a001a1a1a1a1a1a000000121212121212121212121212121212121212121212d0d0d0d012121212121212121212121212121212121212121212121212121212121212121212121212121212121212121212121a1212121212121212000000000000000000000000d0d0d0d0d0d0d0d0002d3533321a1a0000000000000000000000003300000001000f5b00001100712c6eff9e61000000000061000000fbffff1a1a3a6e353900756c6c7d3b00000000009100002d35ff00600000000000000000002d3533321a1a1a1a3a6e353900756c6c7d3b000000000091373800002d3537383734613734616161d0d0d0d0d000000000717a1a001a1a1a1a1a1a0000001212121212121212121212121212121212121212000000000000003300000001000f5b00001100712c6eff9e61000000000061000000fbffff1a1a3a6e353900756c6c7d3b00000000009100002d35ff00600000000000000000002d3533321a1a1a1a3a6e353900756c6c7d3b000000000091373800002d3537383734613734616161", + Expected: "000000000000000000000000000000000000000000000000", + Name: "oss_fuzz_gas_calc", + Gas: 18446744073709551615, + NoBenchmark: false, + } + testPrecompiledOOG("05", gasCostTest, t) + testPrecompiledOOG("f5", gasCostTest, t) + testPrecompiledOOG("f6", gasCostTest, t) } // Tests the sample inputs from the elliptic curve scalar multiplication EIP 213. diff --git a/core/vm/eips.go b/core/vm/eips.go index 10ca1fe9ab..dfcac4b930 100644 --- a/core/vm/eips.go +++ b/core/vm/eips.go @@ -42,6 +42,7 @@ var activators = map[int]func(*JumpTable){ 4762: enable4762, 7702: enable7702, 7939: enable7939, + 8024: enable8024, } // EnableEIP enables the given EIP on the config. @@ -294,7 +295,7 @@ func opBlobBaseFee(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { return nil, nil } -// opCLZ implements the CLZ opcode (count leading zero bytes) +// opCLZ implements the CLZ opcode (count leading zero bits) func opCLZ(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { x := scope.Stack.peek() x.SetUint64(256 - uint64(x.BitLen())) @@ -342,6 +343,28 @@ func enable6780(jt *JumpTable) { } } +// enable8024 applies EIP-8024 (DUPN, SWAPN, EXCHANGE) +func enable8024(jt *JumpTable) { + jt[DUPN] = &operation{ + execute: opDupN, + constantGas: GasFastestStep, + minStack: minStack(1, 0), + maxStack: maxStack(0, 1), + } + jt[SWAPN] = &operation{ + execute: opSwapN, + constantGas: GasFastestStep, + minStack: minStack(2, 0), + maxStack: maxStack(0, 0), + } + jt[EXCHANGE] = &operation{ + execute: opExchange, + constantGas: GasFastestStep, + minStack: minStack(2, 0), + maxStack: maxStack(0, 0), + } +} + func opExtCodeCopyEIP4762(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { var ( stack = scope.Stack diff --git a/core/vm/evm.go b/core/vm/evm.go index e360187f7b..25a3318c02 100644 --- a/core/vm/evm.go +++ b/core/vm/evm.go @@ -214,7 +214,7 @@ func (evm *EVM) SetJumpDestCache(jumpDests JumpDestCache) { // This is not threadsafe and should only be done very cautiously. func (evm *EVM) SetTxContext(txCtx TxContext) { if evm.chainRules.IsEIP4762 { - txCtx.AccessEvents = state.NewAccessEvents(evm.StateDB.PointCache()) + txCtx.AccessEvents = state.NewAccessEvents() } evm.TxContext = txCtx } @@ -601,7 +601,9 @@ func (evm *EVM) initNewContract(contract *Contract, address common.Address) ([]b } } - evm.StateDB.SetCode(address, ret) + if len(ret) > 0 { + evm.StateDB.SetCode(address, ret, tracing.CodeChangeContractCreation) + } return ret, nil } diff --git a/core/vm/gas_table.go b/core/vm/gas_table.go index c7c1274bf2..23a2cbbf4d 100644 --- a/core/vm/gas_table.go +++ b/core/vm/gas_table.go @@ -97,6 +97,9 @@ var ( ) func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + if evm.readOnly { + return 0, ErrWriteProtection + } var ( y, x = stack.Back(1), stack.Back(0) current, original = evm.StateDB.GetStateAndCommittedState(contract.Address(), x.Bytes32()) @@ -181,6 +184,9 @@ func gasSStore(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySi // (2.2.2.1.) If original value is 0, add SSTORE_SET_GAS - SLOAD_GAS to refund counter. // (2.2.2.2.) Otherwise, add SSTORE_RESET_GAS - SLOAD_GAS gas to refund counter. func gasSStoreEIP2200(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + if evm.readOnly { + return 0, ErrWriteProtection + } // If we fail the minimum gas availability invariant, fail (0) if contract.Gas <= params.SstoreSentryGasEIP2200 { return 0, errors.New("not enough gas for reentrancy sentry") @@ -374,6 +380,10 @@ func gasCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize transfersValue = !stack.Back(2).IsZero() address = common.Address(stack.Back(1).Bytes20()) ) + if evm.readOnly && transfersValue { + return 0, ErrWriteProtection + } + if evm.chainRules.IsEIP158 { if transfersValue && evm.StateDB.Empty(address) { gas += params.CallNewAccountGas @@ -462,6 +472,10 @@ func gasStaticCall(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memo } func gasSelfdestruct(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + if evm.readOnly { + return 0, ErrWriteProtection + } + var gas uint64 // EIP150 homestead gas reprice fork: if evm.chainRules.IsEIP150 { diff --git a/core/vm/gas_table_test.go b/core/vm/gas_table_test.go index cb6143c0b5..7fe76b0a63 100644 --- a/core/vm/gas_table_test.go +++ b/core/vm/gas_table_test.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" @@ -87,7 +88,7 @@ func TestEIP2200(t *testing.T) { statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.CreateAccount(address) - statedb.SetCode(address, hexutil.MustDecode(tt.input)) + statedb.SetCode(address, hexutil.MustDecode(tt.input), tracing.CodeChangeUnspecified) statedb.SetState(address, common.Hash{}, common.BytesToHash([]byte{tt.original})) statedb.Finalise(true) // Push the state into the "original" slot @@ -139,7 +140,7 @@ func TestCreateGas(t *testing.T) { address := common.BytesToAddress([]byte("contract")) statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.CreateAccount(address) - statedb.SetCode(address, hexutil.MustDecode(tt.code)) + statedb.SetCode(address, hexutil.MustDecode(tt.code), tracing.CodeChangeUnspecified) statedb.Finalise(true) vmctx := BlockContext{ CanTransfer: func(StateDB, common.Address, *uint256.Int) bool { return true }, diff --git a/core/vm/instructions.go b/core/vm/instructions.go index fffa65fd6a..baf6df8117 100644 --- a/core/vm/instructions.go +++ b/core/vm/instructions.go @@ -885,13 +885,24 @@ func opSelfdestruct(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { if evm.readOnly { return nil, ErrWriteProtection } - beneficiary := scope.Stack.pop() - balance := evm.StateDB.GetBalance(scope.Contract.Address()) - evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct) - evm.StateDB.SelfDestruct(scope.Contract.Address()) + var ( + this = scope.Contract.Address() + balance = evm.StateDB.GetBalance(this) + top = scope.Stack.pop() + beneficiary = common.Address(top.Bytes20()) + ) + // The funds are burned immediately if the beneficiary is the caller itself, + // in this case, the beneficiary's balance is not increased. + if this != beneficiary { + evm.StateDB.AddBalance(beneficiary, balance, tracing.BalanceIncreaseSelfdestruct) + } + // Clear any leftover funds for the account being destructed. + evm.StateDB.SubBalance(this, balance, tracing.BalanceDecreaseSelfdestruct) + evm.StateDB.SelfDestruct(this) + if tracer := evm.Config.Tracer; tracer != nil { if tracer.OnEnter != nil { - tracer.OnEnter(evm.depth, byte(SELFDESTRUCT), scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) + tracer.OnEnter(evm.depth, byte(SELFDESTRUCT), this, beneficiary, []byte{}, 0, balance.ToBig()) } if tracer.OnExit != nil { tracer.OnExit(evm.depth, []byte{}, 0, nil, false) @@ -904,14 +915,31 @@ func opSelfdestruct6780(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, erro if evm.readOnly { return nil, ErrWriteProtection } - beneficiary := scope.Stack.pop() - balance := evm.StateDB.GetBalance(scope.Contract.Address()) - evm.StateDB.SubBalance(scope.Contract.Address(), balance, tracing.BalanceDecreaseSelfdestruct) - evm.StateDB.AddBalance(beneficiary.Bytes20(), balance, tracing.BalanceIncreaseSelfdestruct) - evm.StateDB.SelfDestruct6780(scope.Contract.Address()) + var ( + this = scope.Contract.Address() + balance = evm.StateDB.GetBalance(this) + top = scope.Stack.pop() + beneficiary = common.Address(top.Bytes20()) + newContract = evm.StateDB.IsNewContract(this) + ) + // Contract is new and will actually be deleted. + if newContract { + if this != beneficiary { // Skip no-op transfer when self-destructing to self. + evm.StateDB.AddBalance(beneficiary, balance, tracing.BalanceIncreaseSelfdestruct) + } + evm.StateDB.SubBalance(this, balance, tracing.BalanceDecreaseSelfdestruct) + evm.StateDB.SelfDestruct(this) + } + + // Contract already exists, only do transfer if beneficiary is not self. + if !newContract && this != beneficiary { + evm.StateDB.SubBalance(this, balance, tracing.BalanceDecreaseSelfdestruct) + evm.StateDB.AddBalance(beneficiary, balance, tracing.BalanceIncreaseSelfdestruct) + } + if tracer := evm.Config.Tracer; tracer != nil { if tracer.OnEnter != nil { - tracer.OnEnter(evm.depth, byte(SELFDESTRUCT), scope.Contract.Address(), beneficiary.Bytes20(), []byte{}, 0, balance.ToBig()) + tracer.OnEnter(evm.depth, byte(SELFDESTRUCT), this, beneficiary, []byte{}, 0, balance.ToBig()) } if tracer.OnExit != nil { tracer.OnExit(evm.depth, []byte{}, 0, nil, false) @@ -920,6 +948,115 @@ func opSelfdestruct6780(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, erro return nil, errStopToken } +func decodeSingle(x byte) int { + if x <= 90 { + return int(x) + 17 + } + return int(x) - 20 +} + +func decodePair(x byte) (int, int) { + var k int + if x <= 79 { + k = int(x) + } else { + k = int(x) - 48 + } + q, r := k/16, k%16 + if q < r { + return q + 1, r + 1 + } + return r + 1, 29 - q +} + +func opDupN(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { + code := scope.Contract.Code + i := *pc + 1 + + // Ensure an immediate byte exists after DUPN + if i >= uint64(len(code)) { + return nil, &ErrInvalidOpCode{opcode: INVALID} + } + x := code[i] + + // This range is excluded to preserve compatibility with existing opcodes. + if x > 90 && x < 128 { + return nil, &ErrInvalidOpCode{opcode: OpCode(x)} + } + n := decodeSingle(x) + + // DUPN duplicates the n'th stack item, so the stack must contain at least n elements. + if scope.Stack.len() < n { + return nil, &ErrStackUnderflow{stackLen: scope.Stack.len(), required: n} + } + + //The n‘th stack item is duplicated at the top of the stack. + scope.Stack.push(scope.Stack.Back(n - 1)) + *pc += 1 + return nil, nil +} + +func opSwapN(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { + code := scope.Contract.Code + i := *pc + 1 + + // Ensure an immediate byte exists after SWAPN + if i >= uint64(len(code)) { + return nil, &ErrInvalidOpCode{opcode: INVALID} + } + x := code[i] + + // This range is excluded to preserve compatibility with existing opcodes. + if x > 90 && x < 128 { + return nil, &ErrInvalidOpCode{opcode: OpCode(x)} + } + n := decodeSingle(x) + + // SWAPN operates on the top and n+1 stack items, so the stack must contain at least n+1 elements. + if scope.Stack.len() < n+1 { + return nil, &ErrStackUnderflow{stackLen: scope.Stack.len(), required: n + 1} + } + + // The (n+1)‘th stack item is swapped with the top of the stack. + indexTop := scope.Stack.len() - 1 + indexN := scope.Stack.len() - 1 - n + scope.Stack.data[indexTop], scope.Stack.data[indexN] = scope.Stack.data[indexN], scope.Stack.data[indexTop] + *pc += 1 + return nil, nil +} + +func opExchange(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { + code := scope.Contract.Code + i := *pc + 1 + + // Ensure an immediate byte exists after EXCHANGE + if i >= uint64(len(code)) { + return nil, &ErrInvalidOpCode{opcode: INVALID} + } + x := code[i] + + // This range is excluded both to preserve compatibility with existing opcodes + // and to keep decode_pair’s 16-aligned arithmetic mapping valid (0–79, 128–255). + if x > 79 && x < 128 { + return nil, &ErrInvalidOpCode{opcode: OpCode(x)} + } + n, m := decodePair(x) + need := max(n, m) + 1 + + // EXCHANGE operates on the (n+1)'th and (m+1)'th stack items, + // so the stack must contain at least max(n, m)+1 elements. + if scope.Stack.len() < need { + return nil, &ErrStackUnderflow{stackLen: scope.Stack.len(), required: need} + } + + // The (n+1)‘th stack item is swapped with the (m+1)‘th stack item. + indexN := scope.Stack.len() - 1 - n + indexM := scope.Stack.len() - 1 - m + scope.Stack.data[indexN], scope.Stack.data[indexM] = scope.Stack.data[indexM], scope.Stack.data[indexN] + *pc += 1 + return nil, nil +} + // following functions are used by the instruction jump table // make log instruction function @@ -1003,9 +1140,9 @@ func makePush(size uint64, pushByteSize int) executionFunc { } // make dup instruction function -func makeDup(size int64) executionFunc { +func makeDup(size int) executionFunc { return func(pc *uint64, evm *EVM, scope *ScopeContext) ([]byte, error) { - scope.Stack.dup(int(size)) + scope.Stack.dup(size) return nil, nil } } diff --git a/core/vm/instructions_test.go b/core/vm/instructions_test.go index cd31829a7e..f38da7fb22 100644 --- a/core/vm/instructions_test.go +++ b/core/vm/instructions_test.go @@ -291,15 +291,13 @@ func opBenchmark(bench *testing.B, op executionFunc, args ...string) { intArgs[i] = new(uint256.Int).SetBytes(common.Hex2Bytes(arg)) } pc := uint64(0) - bench.ResetTimer() - for i := 0; i < bench.N; i++ { + for bench.Loop() { for _, arg := range intArgs { stack.push(arg) } op(&pc, evm, scope) stack.pop() } - bench.StopTimer() for i, arg := range args { want := new(uint256.Int).SetBytes(common.Hex2Bytes(arg)) @@ -551,8 +549,7 @@ func BenchmarkOpMstore(bench *testing.B) { memStart := new(uint256.Int) value := new(uint256.Int).SetUint64(0x1337) - bench.ResetTimer() - for i := 0; i < bench.N; i++ { + for bench.Loop() { stack.push(value) stack.push(memStart) opMstore(&pc, evm, &ScopeContext{mem, stack, nil}) @@ -609,8 +606,7 @@ func BenchmarkOpKeccak256(bench *testing.B) { pc := uint64(0) start := new(uint256.Int) - bench.ResetTimer() - for i := 0; i < bench.N; i++ { + for bench.Loop() { stack.push(uint256.NewInt(32)) stack.push(start) opKeccak256(&pc, evm, &ScopeContext{mem, stack, nil}) @@ -1012,3 +1008,168 @@ func TestOpCLZ(t *testing.T) { } } } + +func TestEIP8024_Execution(t *testing.T) { + evm := NewEVM(BlockContext{}, nil, params.TestChainConfig, Config{}) + + tests := []struct { + name string + codeHex string + wantErr bool + wantVals []uint64 + }{ + { + name: "DUPN", + codeHex: "60016000808080808080808080808080808080e600", + wantVals: []uint64{ + 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, + }, + }, + { + name: "SWAPN", + codeHex: "600160008080808080808080808080808080806002e700", + wantVals: []uint64{ + 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 2, + }, + }, + { + name: "EXCHANGE", + codeHex: "600060016002e801", + wantVals: []uint64{2, 0, 1}, + }, + { + name: "INVALID_SWAPN_LOW", + codeHex: "e75b", + wantErr: true, + }, + { + name: "JUMP over INVALID_DUPN", + codeHex: "600456e65b", + wantErr: false, + }, + // Additional test cases + { + name: "INVALID_DUPN_LOW", + codeHex: "e65b", + wantErr: true, + }, + { + name: "INVALID_EXCHANGE_LOW", + codeHex: "e850", + wantErr: true, + }, + { + name: "INVALID_DUPN_HIGH", + codeHex: "e67f", + wantErr: true, + }, + { + name: "INVALID_SWAPN_HIGH", + codeHex: "e77f", + wantErr: true, + }, + { + name: "INVALID_EXCHANGE_HIGH", + codeHex: "e87f", + wantErr: true, + }, + { + name: "UNDERFLOW_DUPN", + codeHex: "5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe600", // (n=17, need 17 items, have 16) + wantErr: true, + }, + { + name: "UNDERFLOW_SWAPN", + codeHex: "5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5f5fe700", // (n=17, need 18 items, have 17) + wantErr: true, + }, + { + name: "UNDERFLOW_EXCHANGE", + codeHex: "60016002e801", // (n,m)=(1,2), need 3 items, have 2 + wantErr: true, + }, + { + name: "MISSING_IMMEDIATE_DUPN", + codeHex: "e6", // no operand + wantErr: true, + }, + { + name: "MISSING_IMMEDIATE_SWAPN", + codeHex: "e7", // no operand + wantErr: true, + }, + { + name: "MISSING_IMMEDIATE_EXCHANGE", + codeHex: "e8", // no operand + wantErr: true, + }, + { + name: "PC_INCREMENT", + codeHex: "600060006000e80115", + wantVals: []uint64{1, 0, 0}, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + code := common.FromHex(tc.codeHex) + stack := newstack() + pc := uint64(0) + scope := &ScopeContext{Stack: stack, Contract: &Contract{Code: code}} + var err error + for pc < uint64(len(code)) && err == nil { + op := code[pc] + switch op { + case 0x00: + return + case 0x60: + _, err = opPush1(&pc, evm, scope) + case 0x80: + dup1 := makeDup(1) + _, err = dup1(&pc, evm, scope) + case 0x56: + _, err = opJump(&pc, evm, scope) + case 0x5b: + _, err = opJumpdest(&pc, evm, scope) + case 0x15: + _, err = opIszero(&pc, evm, scope) + case 0xe6: + _, err = opDupN(&pc, evm, scope) + case 0xe7: + _, err = opSwapN(&pc, evm, scope) + case 0xe8: + _, err = opExchange(&pc, evm, scope) + default: + err = &ErrInvalidOpCode{opcode: OpCode(op)} + } + pc++ + } + if tc.wantErr { + if err == nil { + t.Fatalf("expected error, got nil") + } + return + } + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + got := make([]uint64, 0, stack.len()) + for i := stack.len() - 1; i >= 0; i-- { + got = append(got, stack.data[i].Uint64()) + } + if len(got) != len(tc.wantVals) { + t.Fatalf("stack len=%d; want %d", len(got), len(tc.wantVals)) + } + for i := range got { + if got[i] != tc.wantVals[i] { + t.Fatalf("[%s] stack[%d]=%d; want %d\nstack=%v", + tc.name, i, got[i], tc.wantVals[i], got) + } + } + }) + } +} diff --git a/core/vm/interface.go b/core/vm/interface.go index 42a72db482..e285b18b0f 100644 --- a/core/vm/interface.go +++ b/core/vm/interface.go @@ -23,7 +23,6 @@ import ( "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" - "github.com/ethereum/go-ethereum/trie/utils" "github.com/holiman/uint256" ) @@ -43,7 +42,7 @@ type StateDB interface { GetCode(common.Address) []byte // SetCode sets the new code for the address, and returns the previous code, if any. - SetCode(common.Address, []byte) []byte + SetCode(common.Address, []byte, tracing.CodeChangeReason) []byte GetCodeSize(common.Address) int AddRefund(uint64) @@ -58,19 +57,17 @@ type StateDB interface { GetTransientState(addr common.Address, key common.Hash) common.Hash SetTransientState(addr common.Address, key, value common.Hash) - SelfDestruct(common.Address) uint256.Int + SelfDestruct(common.Address) HasSelfDestructed(common.Address) bool - // SelfDestruct6780 is post-EIP6780 selfdestruct, which means that it's a - // send-all-to-beneficiary, unless the contract was created in this same - // transaction, in which case it will be destructed. - // This method returns the prior balance, along with a boolean which is - // true iff the object was indeed destructed. - SelfDestruct6780(common.Address) (uint256.Int, bool) - // Exist reports whether the given account exists in state. // Notably this also returns true for self-destructed accounts within the current transaction. Exist(common.Address) bool + + // IsNewContract reports whether the contract at the given address was deployed + // during the current transaction. + IsNewContract(addr common.Address) bool + // Empty returns whether the given account is empty. Empty // is defined according to EIP161 (balance = nonce = code = 0). Empty(common.Address) bool @@ -84,9 +81,6 @@ type StateDB interface { // even if the feature/fork is not active yet AddSlotToAccessList(addr common.Address, slot common.Hash) - // PointCache returns the point cache used in computations - PointCache() *utils.PointCache - Prepare(rules params.Rules, sender, coinbase common.Address, dest *common.Address, precompiles []common.Address, txAccesses types.AccessList) RevertToSnapshot(int) diff --git a/core/vm/interpreter.go b/core/vm/interpreter.go index a0637a6800..52dbe83d86 100644 --- a/core/vm/interpreter.go +++ b/core/vm/interpreter.go @@ -33,6 +33,7 @@ type Config struct { ExtraEips []int // Additional EIPS that are to be enabled StatelessSelfValidation bool // Generate execution witnesses and self-check against them (testing purpose) + EnableWitnessStats bool // Whether trie access statistics collection is enabled } // ScopeContext contains the things that are per-call, such as stack and memory, diff --git a/core/vm/interpreter_test.go b/core/vm/interpreter_test.go index 8ed512316b..79531f78d2 100644 --- a/core/vm/interpreter_test.go +++ b/core/vm/interpreter_test.go @@ -24,6 +24,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/params" "github.com/holiman/uint256" @@ -45,7 +46,7 @@ func TestLoopInterrupt(t *testing.T) { for i, tt := range loopInterruptTests { statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) statedb.CreateAccount(address) - statedb.SetCode(address, common.Hex2Bytes(tt)) + statedb.SetCode(address, common.Hex2Bytes(tt), tracing.CodeChangeUnspecified) statedb.Finalise(true) evm := NewEVM(vmctx, statedb, params.AllEthashProtocolChanges, Config{}) @@ -89,8 +90,7 @@ func BenchmarkInterpreter(b *testing.B) { stack.push(uint256.NewInt(123)) stack.push(uint256.NewInt(123)) gasSStoreEIP3529 = makeGasSStoreFunc(params.SstoreClearsScheduleRefundEIP3529) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { gasSStoreEIP3529(evm, contract, stack, mem, 1234) } } diff --git a/core/vm/memory.go b/core/vm/memory.go index 5e11e83748..54bc2b2849 100644 --- a/core/vm/memory.go +++ b/core/vm/memory.go @@ -44,6 +44,7 @@ func (m *Memory) Free() { // To reduce peak allocation, return only smaller memory instances to the pool. const maxBufferSize = 16 << 10 if cap(m.store) <= maxBufferSize { + clear(m.store) m.store = m.store[:0] m.lastGasCost = 0 memoryPool.Put(m) @@ -76,10 +77,14 @@ func (m *Memory) Set32(offset uint64, val *uint256.Int) { val.PutUint256(m.store[offset:]) } -// Resize resizes the memory to size +// Resize grows the memory to the requested size. func (m *Memory) Resize(size uint64) { - if uint64(m.Len()) < size { - m.store = append(m.store, make([]byte, size-uint64(m.Len()))...) + if uint64(len(m.store)) < size { + if uint64(cap(m.store)) >= size { + m.store = m.store[:size] + } else { + m.store = append(m.store, make([]byte, size-uint64(len(m.store)))...) + } } } diff --git a/core/vm/memory_test.go b/core/vm/memory_test.go index 41389b729a..3890d18cb5 100644 --- a/core/vm/memory_test.go +++ b/core/vm/memory_test.go @@ -83,3 +83,10 @@ func TestMemoryCopy(t *testing.T) { } } } + +func BenchmarkResize(b *testing.B) { + memory := NewMemory() + for i := range b.N { + memory.Resize(uint64(i)) + } +} diff --git a/core/vm/operations_acl.go b/core/vm/operations_acl.go index 085b018e4c..ce394d9384 100644 --- a/core/vm/operations_acl.go +++ b/core/vm/operations_acl.go @@ -28,6 +28,9 @@ import ( func makeGasSStoreFunc(clearingRefund uint64) gasFunc { return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + if evm.readOnly { + return 0, ErrWriteProtection + } // If we fail the minimum gas availability invariant, fail (0) if contract.Gas <= params.SstoreSentryGasEIP2200 { return 0, errors.New("not enough gas for reentrancy sentry") @@ -226,10 +229,19 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { gas uint64 address = common.Address(stack.peek().Bytes20()) ) + if evm.readOnly { + return 0, ErrWriteProtection + } if !evm.StateDB.AddressInAccessList(address) { // If the caller cannot afford the cost, this change will be rolled back evm.StateDB.AddAddressToAccessList(address) gas = params.ColdAccountAccessCostEIP2929 + + // Terminate the gas measurement if the leftover gas is not sufficient, + // it can effectively prevent accessing the states in the following steps + if contract.Gas < gas { + return 0, ErrOutOfGas + } } // if empty and transfers value if evm.StateDB.Empty(address) && evm.StateDB.GetBalance(contract.Address()).Sign() != 0 { @@ -244,12 +256,24 @@ func makeSelfdestructGasFn(refundsEnabled bool) gasFunc { } var ( - gasCallEIP7702 = makeCallVariantGasCallEIP7702(gasCall) + innerGasCallEIP7702 = makeCallVariantGasCallEIP7702(gasCall) gasDelegateCallEIP7702 = makeCallVariantGasCallEIP7702(gasDelegateCall) gasStaticCallEIP7702 = makeCallVariantGasCallEIP7702(gasStaticCall) gasCallCodeEIP7702 = makeCallVariantGasCallEIP7702(gasCallCode) ) +func gasCallEIP7702(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { + // Return early if this call attempts to transfer value in a static context. + // Although it's checked in `gasCall`, EIP-7702 loads the target's code before + // to determine if it is resolving a delegation. This could incorrectly record + // the target in the block access list (BAL) if the call later fails. + transfersValue := !stack.Back(2).IsZero() + if evm.readOnly && transfersValue { + return 0, ErrWriteProtection + } + return innerGasCallEIP7702(evm, contract, stack, mem, memorySize) +} + func makeCallVariantGasCallEIP7702(oldCalculator gasFunc) gasFunc { return func(evm *EVM, contract *Contract, stack *Stack, mem *Memory, memorySize uint64) (uint64, error) { var ( diff --git a/core/vm/program/program.go b/core/vm/program/program.go index 5b9cfdcc5f..72cf6ff845 100644 --- a/core/vm/program/program.go +++ b/core/vm/program/program.go @@ -53,7 +53,7 @@ func (p *Program) add(op byte) *Program { return p } -// pushBig creates a PUSHX instruction and pushes the given val. +// doPush creates a PUSHX instruction and pushes the given val. // - If the val is nil, it pushes zero // - If the val is bigger than 32 bytes, it panics func (p *Program) doPush(val *uint256.Int) { diff --git a/core/vm/runtime/runtime.go b/core/vm/runtime/runtime.go index 9d984291f2..b40e99d047 100644 --- a/core/vm/runtime/runtime.go +++ b/core/vm/runtime/runtime.go @@ -22,6 +22,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" "github.com/ethereum/go-ethereum/crypto" @@ -139,7 +140,7 @@ func Execute(code, input []byte, cfg *Config) ([]byte, *state.StateDB, error) { cfg.State.Prepare(rules, cfg.Origin, cfg.Coinbase, &address, vm.ActivePrecompiles(rules), nil) cfg.State.CreateAccount(address) // set the receiver's (the executing contract) code for execution. - cfg.State.SetCode(address, code) + cfg.State.SetCode(address, code, tracing.CodeChangeUnspecified) // Call the code with the given configuration. ret, leftOverGas, err := vmenv.Call( cfg.Origin, diff --git a/core/vm/runtime/runtime_test.go b/core/vm/runtime/runtime_test.go index d75a5b0459..a001d81623 100644 --- a/core/vm/runtime/runtime_test.go +++ b/core/vm/runtime/runtime_test.go @@ -114,7 +114,7 @@ func TestCall(t *testing.T) { byte(vm.PUSH1), 32, byte(vm.PUSH1), 0, byte(vm.RETURN), - }) + }, tracing.CodeChangeUnspecified) ret, _, err := Call(address, nil, &Config{State: state}) if err != nil { @@ -150,8 +150,7 @@ func BenchmarkCall(b *testing.B) { b.Fatal(err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { for j := 0; j < 400; j++ { Execute(code, cpurchase, nil) Execute(code, creceived, nil) @@ -167,7 +166,7 @@ func benchmarkEVM_Create(bench *testing.B, code string) { ) statedb.CreateAccount(sender) - statedb.SetCode(receiver, common.FromHex(code)) + statedb.SetCode(receiver, common.FromHex(code), tracing.CodeChangeUnspecified) runtimeConfig := Config{ Origin: sender, State: statedb, @@ -190,11 +189,9 @@ func benchmarkEVM_Create(bench *testing.B, code string) { EVMConfig: vm.Config{}, } // Warm up the intpools and stuff - bench.ResetTimer() - for i := 0; i < bench.N; i++ { + for bench.Loop() { Call(receiver, []byte{}, &runtimeConfig) } - bench.StopTimer() } func BenchmarkEVM_CREATE_500(bench *testing.B) { @@ -232,9 +229,8 @@ func BenchmarkEVM_SWAP1(b *testing.B) { b.Run("10k", func(b *testing.B) { contractCode := swapContract(10_000) - state.SetCode(contractAddr, contractCode) - - for i := 0; i < b.N; i++ { + state.SetCode(contractAddr, contractCode, tracing.CodeChangeUnspecified) + for b.Loop() { _, _, err := Call(contractAddr, []byte{}, &Config{State: state}) if err != nil { b.Fatal(err) @@ -263,9 +259,8 @@ func BenchmarkEVM_RETURN(b *testing.B) { b.ReportAllocs() contractCode := returnContract(n) - state.SetCode(contractAddr, contractCode) - - for i := 0; i < b.N; i++ { + state.SetCode(contractAddr, contractCode, tracing.CodeChangeUnspecified) + for b.Loop() { ret, _, err := Call(contractAddr, []byte{}, &Config{State: state}) if err != nil { b.Fatal(err) @@ -317,6 +312,18 @@ func (d *dummyChain) Config() *params.ChainConfig { return nil } +func (d *dummyChain) CurrentHeader() *types.Header { + return nil +} + +func (d *dummyChain) GetHeaderByNumber(n uint64) *types.Header { + return d.GetHeader(common.Hash{}, n) +} + +func (d *dummyChain) GetHeaderByHash(h common.Hash) *types.Header { + return nil +} + // TestBlockhash tests the blockhash operation. It's a bit special, since it internally // requires access to a chain reader. func TestBlockhash(t *testing.T) { @@ -422,17 +429,17 @@ func benchmarkNonModifyingCode(gas uint64, code []byte, name string, tracerCode byte(vm.PUSH1), 0x00, byte(vm.PUSH1), 0x00, byte(vm.REVERT), - }) + }, tracing.CodeChangeUnspecified) } //cfg.State.CreateAccount(cfg.Origin) // set the receiver's (the executing contract) code for execution. - cfg.State.SetCode(destination, code) + cfg.State.SetCode(destination, code, tracing.CodeChangeUnspecified) Call(destination, nil, cfg) b.Run(name, func(b *testing.B) { b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { Call(destination, nil, cfg) } }) @@ -772,12 +779,12 @@ func TestRuntimeJSTracer(t *testing.T) { for i, jsTracer := range jsTracers { for j, tc := range tests { statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) - statedb.SetCode(main, tc.code) - statedb.SetCode(common.HexToAddress("0xbb"), calleeCode) - statedb.SetCode(common.HexToAddress("0xcc"), calleeCode) - statedb.SetCode(common.HexToAddress("0xdd"), calleeCode) - statedb.SetCode(common.HexToAddress("0xee"), calleeCode) - statedb.SetCode(common.HexToAddress("0xff"), suicideCode) + statedb.SetCode(main, tc.code, tracing.CodeChangeUnspecified) + statedb.SetCode(common.HexToAddress("0xbb"), calleeCode, tracing.CodeChangeUnspecified) + statedb.SetCode(common.HexToAddress("0xcc"), calleeCode, tracing.CodeChangeUnspecified) + statedb.SetCode(common.HexToAddress("0xdd"), calleeCode, tracing.CodeChangeUnspecified) + statedb.SetCode(common.HexToAddress("0xee"), calleeCode, tracing.CodeChangeUnspecified) + statedb.SetCode(common.HexToAddress("0xff"), suicideCode, tracing.CodeChangeUnspecified) tracer, err := tracers.DefaultDirectory.New(jsTracer, new(tracers.Context), nil, params.MergedTestChainConfig) if err != nil { @@ -862,8 +869,8 @@ func BenchmarkTracerStepVsCallFrame(b *testing.B) { // delegation designator incurs the correct amount of gas based on the tracer. func TestDelegatedAccountAccessCost(t *testing.T) { statedb, _ := state.New(types.EmptyRootHash, state.NewDatabaseForTesting()) - statedb.SetCode(common.HexToAddress("0xff"), types.AddressToDelegation(common.HexToAddress("0xaa"))) - statedb.SetCode(common.HexToAddress("0xaa"), program.New().Return(0, 0).Bytes()) + statedb.SetCode(common.HexToAddress("0xff"), types.AddressToDelegation(common.HexToAddress("0xaa")), tracing.CodeChangeUnspecified) + statedb.SetCode(common.HexToAddress("0xaa"), program.New().Return(0, 0).Bytes(), tracing.CodeChangeUnspecified) for i, tc := range []struct { code []byte diff --git a/core/vm/testdata/precompiles/modexp_eip2565.json b/core/vm/testdata/precompiles/modexp_eip2565.json index c55441439e..24455eeca7 100644 --- a/core/vm/testdata/precompiles/modexp_eip2565.json +++ b/core/vm/testdata/precompiles/modexp_eip2565.json @@ -117,5 +117,215 @@ "Name": "nagydani-5-pow0x10001", "Gas": 87381, "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000000cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000007d7d7d83828282348286877d7d827d407d797d7d7d7d7d7d7d7d7d7d7d5b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4000007d7d7d83828282348286877d7d82", + "Expected": "36a385a417859b5e178d3ab9", + "Name": "marius-1-even", + "Gas": 2057, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d80000000000000000000000000000000000000000000000000000000000000010ffffffffffffffff76ffffffffffffff1cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c76ec7c7c7c7ffffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7ffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c76ec7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7ffffffffff3f000000000000000000000000", + "Expected": "c3745de81615f80088ffffffffffffff", + "Name": "guido-1-even", + "Gas": 2298, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d80000000000000000000000000000000000000000000000000000000000000010e0060000a921212121212121ff0000212b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f00feffff212121212121ffffffff1fe1e0e0e01e1f1f169f1f1f1f490afcefffffffffffffffff82828282828282828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1fffffffffff0afceffffff7ffffffffff7c8282828282a1828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1fd11f1f1f1f1f1f1f1f1f1f1fffffffffffffffff21212121212121fb2121212121ffff1f1f1f1f1f1f1f1fffaf82828282828200ffff28ff2b21828200", + "Expected": "458ef0af2549d46d24c89079499479e1", + "Name": "guido-2-even", + "Gas": 2300, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000001e7000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002cb0193585a48e18aad777e9c1b54221a0f58140392e4f091cd5f42b2e8644a9384fbd58ae1edec2477ebf7edbf7c0a3f8bd21d1890ee87646feab3c47be716f842cc3da9b940af312dc54450a960e3fc0b86e56abddd154068e10571a96fff6259431632bc15695c6c8679057e66c2c25c127e97e64ee5de6ea1fc0a4a0e431343fed1daafa072c238a45841da86a9806680bc9f298411173210790359209cd454b5af7b4d5688b4403924e5f863d97e2c5349e1a04b54fcf385b1e9d7714bab8fbf5835f6ff9ed575e77dff7af5cbb641db5d537933bae1fa6555d6c12d6fb31ca27b57771f4aebfbe0bf95e8990c0108ffe7cbdaf370be52cf3ade594543af75ad9329d2d11a402270b5b9a6bf4b83307506e118fca4862749d04e916fc7a039f0d13f2a02e0eedb800199ec95df15b4ccd8669b52586879624d51219e72102fad810b5909b1e372ddf33888fb9beb09b416e4164966edbabd89e4a286be36277fc576ed519a15643dac602e92b63d0b9121f0491da5b16ef793a967f096d80b6c81ecaaffad7e3f06a4a5ac2796f1ed9f68e6a0fd5cf191f0c5c2eec338952ff8d31abc68bf760febeb57e088995ba1d7726a2fdd6d8ca28a181378b8b4ab699bfd4b696739bbf17a9eb2df6251143046137fdbbfacac312ebf67a67da9741b596000000000000419a2917c61722b0713d3b00a2f0e1dd5aebbbe09615de424700eea3c3020fe6e9ea5de9fa1ace781df28b21f746d2ab61d0da496e08473c90ff7dfe25b43bcde76f4bafb82e0975bea75f5a0591dba80ba2fff80a07d8853bea5be13ab326ba70c57b153acc646151948d1cf061ca31b02d4719fac710e7c723ca44f5b1737824b7ccc74ba5bff980aabdbf267621cafc3d6dcc29d0ca9c16839a92ed34de136da7900aa3ee43d21aa57498981124357cf0ca9b86f9a8d3f9c604ca00c726e48f7a9945021ea6dfff92d6b2d6514693169ca133e993541bfa4c4c191de806aa80c48109bcfc9901eccfdeb2395ab75fe63c67de900829d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "1194e971c875bb45f030316793bc6916343335b18670dfad7a4646fba99749b30283b78b818836de7400ff1a68ddad1a2dd850ec0f227441e2d4d13f5ee4b5d7a856db0a9ad1f86987e1f117d70f9e6a1a2b8d083fa82653aa16f1773b6deb2ed8a1f9e7f3a5db121c4a0c91cb954e2ec53e63422efe86c7984d79cd0e7b5e3eb8ca4980551d63f302c7d72500a84baf12c82fc7bd9b5c2ab8b9c33baf1df28b2031c58a8b2928a42c9f456e98874e22fe13cf17aa5915b11bb108b6ae40842d434604ccddcb4f64324c67b2dde32e6cd759d964f17d9cdf0046cd0ed3588e1fc4b88f67a5d4f3a870aad1cba89ead265d6ad327c8ea7ff54fe4b5e7dbe87c5c59c468543eab3675751111bfa1d6c51daf789d41dc21fd8ba9e05490f881a973a3c1567ff3129a49aa6658cf06f0a79530a7256ce5a07c2a77b4306383d538866bba376d90621c4f82d1f5f32304ee2b7170805d42418fc6967642e5648d8c64fe9c0fdff2d7c114a47add7767c8fccb8808de8c3c6e1a8880c05e16fafc1513fded8eba222dcaaa809bdb36999cc27ab8d0055009e9690e8a35b859df865dc510d25c7812d8eebbb35607ad595573f0fabd1b57970a2bc113ac6f0ca01e985032b9c2c139316ac099ed1632d2bc0fcc341343d303db2a9c3cf2ad572c6c43084b08d458bf822e92da16079f39cdb0dd10ef47f87ecae404117fc72660372cee9ea42266e7f8d973e7f6b09930ca5f96e04976bf23b9d356bbd2429597b04b7663e0e1a1228f4dfda3b854233e4888dc60c6886c1e0e8aec1705f681027b1e0b3017337557f107ef5cd272df5fd31dfec2bdffe163a8369895ffe124c0aa0ee00ca0fe1db4d5cf37b4af0e49bd73a89d88ced3d88f8e6f00d8e61ad09946d0e72cd3e25bc688a021a83758b5023daae7c269a6cbbd447aba5da7629b75801e1654ce85b8e21ccb9865654f8662e538625d75fea31000000000000000000000000000000000000000000000", + "Name": "guido-3-even", + "Gas": 5400, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000181000000000000000000000000000000000000000000000000000000000000000801ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2cffffffffffffffffffffffffffffffffffffffffffffffffffffffff3b10000000006c01ffffffffffffffffffffffffffffffffffffffffffffffdffffb97ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3bffffffffffffffffffffffffffffffffffffffffffffffffffffffffebafd93b37ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc5bb6affffffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2a", + "Expected": "0000000000000001", + "Name": "guido-4-even", + "Gas": 1026, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f2ee5f854d076701c8753d72779187e404f9b2fb705c495137d78551250314a463ef5a213fe22de1cea28d60f518364ff95fe0b73660793e3efcfbe31bda68aeccc21cc9477a6aea5df8cae73422b700c47e54d892691e099167e77befc94780a920ae4155769cd69c30626f054134b5f003772473f57f84837402df6d166e66303f01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c954b27ac388a17c8e9a7ba12a968f288f3308d6fe7bcdf28e685e9a2e00d8be1af19726b7662016d6404f9336493ad633777feb88c9d02a1d2428e566ac38f42c0bb66d2962ec349088ce0d03b35bf27f6114414ef558c87ad8e543754a352f7dffcaca429690688595ab1d1b349d9295b480a82f43ac5c9112fe40720545cc78501cd8b42f3605212fe06a835c9cbc0328e07e94aedb2ac11f6d6649e7fcd8c43", + "Expected": "120cf297dbe810911c7d060e109e03699ccefa00a257d296c5a14b4180776c5f7c0d7f1cd789c694807689729af267b53f00373f395dee264a3daba11fcac1fa8875aee0950acd8fa656f1fc58077a7549d794dd160506ecea1acc9c0cda13795749c94f9973b683ce2162866e8d6b5b1165a4c7fa4234964d394d6ec4e0113698b89d173e24a962dd7a41a1819b0fef188ef64e7ee264595dce0d76fbc3ba42d5de833b143c8744366effede8bc8197e8f747ff8cdbc0bf1a93560bec960ca9", + "Name": "marcin-1-base-heavy", + "Gas": 200, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000080001020304050607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0001020304050607", + "Expected": "0000000000000000", + "Name": "marcin-1-exp-heavy", + "Gas": 215, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000028e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c000102030405060701fffffff01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c950001020304050607", + "Expected": "1abce71dc2205cce4eb6934397a88136f94641342e283cbcd30e929e85605c6718ed67f475192ffd", + "Name": "marcin-1-balanced", + "Gas": 200, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000019800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000198e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f2ee5f854d076701c8753d72779187e404f9b2fb705c495137d78551250314a463ef5a213fe22de1cea28d60f518364ff95fe0b73660793e3efcfbe31bda68aeccc21cc9477a6aea5df8cae73422b700c47e54d892691e099167e77befc94780a920ae4155769cd69c30626f054134b5f003772473f57f84837402df6d166e663c29021b0e084f7dc16f6ec88cc597f1aea9f8e0b9501e0f7a546805d2a20eeda0bf080aeb3ed7ea6f9174d804bd242f0b31ff1ea24800344abb580cd87f61ca75a013a87733553966400242399dee3760877fead2cd87287747155e47a854acb50fe07922f57ae3b4553201bfd7c11aca85e1541f91db8e62dca9c418dc5feae086c9487350539c884510044efce5e3f2aaffca4215c12b9044506375097fecd9b22e2ef46f01f1af8aff742aebf96bdcaf55a341600971dc62555376b9e98a8000102030405060708090a0b0c0d0e0f101112131415161703f01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c954b27ac388a17c8e9a7ba12a968f288f3308d6fe7bcdf28e685e9a2e00d8be1af19726b7662016d6404f9336493ad633777feb88c9d02a1d2428e566ac38f42c0bb66d2962ec349088ce0d03b35bf27f6114414ef558c87ad8e543754a352f7dffcaca429690688595ab1d1b349d9295b480a82f43ac5c9112fe40720545cc78501cd8b42f3605212fe06a835c9cbc0328e07e94aedb2ac11f6d6649e7fcd8c43ddce2bd0cdc6c22c4dcd345735040d5bfe3f09b7c61362089f728e2222db96cab2f2c2ccf43574f9e119f4860fd0f1b6036a43ad9db8a428ea09a4ee385112f3fe9c6656ea2cec604cbb5a9227526653bfa7035e4ae80010b1ba16a76608d5dde0a62bc019e9047b5ec05b1005fd017366130a4ba555e7be654561ee3f539c93cb2c9988fca71bf0ad9c4a426b924641a28e1e4adb93609bfa5b2bc81714cbba1110208b86d7b87be28bdf63a62e33ae81dbcc43de9192bd192c40e85faab539000102030405060708090a0b0c0d0e0f1011121314151617", + "Expected": "817d05c4d540ace3f250fd082e2deb8c2097410fcfe4ce40862cfa015b7f62a7bb72ec1af2915cad66294447b45d177fe759eb80370b0dbd3c0e1c448d54db81eadc11e40c19e394d066a5c019c443798a98d4afd116fc220593d42fbf191b6af0ae75410badb641187ba24a0b968f742a75e2822853f137151d9ea972fd1f36b7c7cc4e71355ecf50648aec094b864cfae9316c0a7be3ddb8ab2d0050b2a029ee956c2366d49430c8f889f29ab514aea8e5b8dec40ba1b49432e30aee32ec45e96dd548205a79d8f8f918eed46acb2115c59086b1011b1d2b093cea723535c3d95efc8e51a7da43b80586d69eb7f213dfb06f7a8e789a9472392bd224411b50f8ca6f2862bcd63431912d1ff99c8d76408245da9e4bea649f0eb930b32922f2d0a345a206160be44d418f1a6c74bd49c4618392ef9350b264a461dfc684c7343211e27675b027054f1cb3d4a5b1a066d3a3ea2eed9caf13251d8be936818f15274e8e3d7539b7c5f216cef327a270fd2a886fbf679c163fb5806249f2c74da5ee0e3ffe9ad1fde2634b29b35da6da6d184ab6ae70199229", + "Name": "marcin-2-base-heavy", + "Gas": 867, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000010000102030405060708090a0b0c0d0e0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000102030405060708090a0b0c0d0e0f", + "Expected": "00000000000000000000000000000000", + "Name": "marcin-2-exp-heavy", + "Gas": 852, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000038e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c000102030405060708090a0b0c0d0e0f10111213141516172bfffffffffffffff01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c95000102030405060708090a0b0c0d0e0f1011121314151617", + "Expected": "86bef3367fc7117c8a6b825cadebe80f3e94c321dda73e9e240b98188a1d5c071c60a195097c8d1fb85ce03a2e1b6964846edee5aa2c3f46", + "Name": "marcin-2-balanced", + "Gas": 996, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244cfffffffffffffffffffffffffffffffff01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c95", + "Expected": "4004762c491606a5132134da6086284f74cc8e14b08f18b90fc09f31bca3d78f", + "Name": "marcin-3-base-heavy", + "Gas": 677, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000018000102030405060708090a0b0c0d0e0f1011121314151617ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000102030405060708090a0b0c0d0e0f1011121314151617", + "Expected": "000000000000000000000000000000000000000000000000", + "Name": "marcin-3-exp-heavy", + "Gas": 765, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c95", + "Expected": "2d3feee20d394af68dd6744b86a8aca6a4a0b7f01bbcd3c3eec768245ca6acee", + "Name": "marcin-3-balanced", + "Gas": 1360, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000000800ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffff", + "Name": "mod-8-exp-648", + "Gas": 215, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000800ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffff", + "Name": "mod-8-exp-896", + "Gas": 298, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-32", + "Gas": 200, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-36", + "Gas": 200, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-40", + "Gas": 208, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-64", + "Gas": 336, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-65", + "Gas": 341, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-128", + "Gas": 677, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "02fd01000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03feffffffffff", + "Name": "mod-256-exp-2", + "Gas": 341, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000001080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010800ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff00", + "Expected": "0100fefffffffffffff710f80000000006f108000000000000feffffffffffff0100fefffffffffffef90ff80000000105f008ffffffffff02fdffffffffffff0100feffffffffff00f80ff80000010101f407fffffffd06fc0000000000fd020000feffffffff00fff80ff8000101fa08f207fffffb0afa0000000001fb03000000feffffff00fffff80ff80102f80405f207fff90ef80000000002f90400000000feffff00fffffff80ff903f6050005f207f712f60000000003f7050000000000feff00fffffffff810fcf406000005f1fd16f40000000004f506000000000000fe00fffffffffff915ea0700000005e522f20000000005f306ffffffffffffffffffffffffff", + "Name": "mod-264-exp-2", + "Gas": 363, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000040000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02feffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-1024-exp-2", + "Gas": 5461, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000008ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "2a02d5f86c2375ff", + "Name": "pawel-1-exp-heavy", + "Gas": 298, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000010ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "823ef7dc60d6d9616756c48f69b7c4ff", + "Name": "pawel-2-exp-heavy", + "Gas": 425, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000018ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "c817dd5aa60a41948eed409706c2aa97be3000d4da0261ff", + "Name": "pawel-3-exp-heavy", + "Gas": 501, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000020ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "2defaca0137d6edacbbd5d36d6ed70cbf8a998ffb19fc270d45a18d37e0f35ff", + "Name": "pawel-4-exp-heavy", + "Gas": 506, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000017bffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffe", + "Expected": "200f14de1d474710c1c979920452e0ffc2ac6f618afba5", + "Name": "mod_vul_pawel_3_exp_8", + "Gas": 200, + "NoBenchmark": false } ] \ No newline at end of file diff --git a/core/vm/testdata/precompiles/modexp_eip7883.json b/core/vm/testdata/precompiles/modexp_eip7883.json index 85e9ad1849..fb3169d148 100644 --- a/core/vm/testdata/precompiles/modexp_eip7883.json +++ b/core/vm/testdata/precompiles/modexp_eip7883.json @@ -103,5 +103,215 @@ "Name": "nagydani-5-pow0x10001", "Gas": 524288, "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000c1000000000000000000000000000000000000000000000000000000000000000cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe000007d7d7d83828282348286877d7d827d407d797d7d7d7d7d7d7d7d7d7d7d5b00000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000021000000000000000000000000000000000000000000000000000000000000000cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff4000007d7d7d83828282348286877d7d82", + "Expected": "36a385a417859b5e178d3ab9", + "Name": "marius-1-even", + "Gas": 45296, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d80000000000000000000000000000000000000000000000000000000000000010ffffffffffffffff76ffffffffffffff1cffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c76ec7c7c7c7ffffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7ffffffffffffc7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c76ec7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7c7ffffffffff3f000000000000000000000000", + "Expected": "c3745de81615f80088ffffffffffffff", + "Name": "guido-1-even", + "Gas": 51136, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000d80000000000000000000000000000000000000000000000000000000000000010e0060000a921212121212121ff0000212b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f00feffff212121212121ffffffff1fe1e0e0e01e1f1f169f1f1f1f490afcefffffffffffffffff82828282828282828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1f1fffffffffff0afceffffff7ffffffffff7c8282828282a1828282828282828282828282828200ffff28ff2b212121ffff1f1f1f1f1f1fd11f1f1f1f1f1f1f1f1f1f1fffffffffffffffff21212121212121fb2121212121ffff1f1f1f1f1f1f1f1fffaf82828282828200ffff28ff2b21828200", + "Expected": "458ef0af2549d46d24c89079499479e1", + "Name": "guido-2-even", + "Gas": 51152, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000001e7000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002cb0193585a48e18aad777e9c1b54221a0f58140392e4f091cd5f42b2e8644a9384fbd58ae1edec2477ebf7edbf7c0a3f8bd21d1890ee87646feab3c47be716f842cc3da9b940af312dc54450a960e3fc0b86e56abddd154068e10571a96fff6259431632bc15695c6c8679057e66c2c25c127e97e64ee5de6ea1fc0a4a0e431343fed1daafa072c238a45841da86a9806680bc9f298411173210790359209cd454b5af7b4d5688b4403924e5f863d97e2c5349e1a04b54fcf385b1e9d7714bab8fbf5835f6ff9ed575e77dff7af5cbb641db5d537933bae1fa6555d6c12d6fb31ca27b57771f4aebfbe0bf95e8990c0108ffe7cbdaf370be52cf3ade594543af75ad9329d2d11a402270b5b9a6bf4b83307506e118fca4862749d04e916fc7a039f0d13f2a02e0eedb800199ec95df15b4ccd8669b52586879624d51219e72102fad810b5909b1e372ddf33888fb9beb09b416e4164966edbabd89e4a286be36277fc576ed519a15643dac602e92b63d0b9121f0491da5b16ef793a967f096d80b6c81ecaaffad7e3f06a4a5ac2796f1ed9f68e6a0fd5cf191f0c5c2eec338952ff8d31abc68bf760febeb57e088995ba1d7726a2fdd6d8ca28a181378b8b4ab699bfd4b696739bbf17a9eb2df6251143046137fdbbfacac312ebf67a67da9741b596000000000000419a2917c61722b0713d3b00a2f0e1dd5aebbbe09615de424700eea3c3020fe6e9ea5de9fa1ace781df28b21f746d2ab61d0da496e08473c90ff7dfe25b43bcde76f4bafb82e0975bea75f5a0591dba80ba2fff80a07d8853bea5be13ab326ba70c57b153acc646151948d1cf061ca31b02d4719fac710e7c723ca44f5b1737824b7ccc74ba5bff980aabdbf267621cafc3d6dcc29d0ca9c16839a92ed34de136da7900aa3ee43d21aa57498981124357cf0ca9b86f9a8d3f9c604ca00c726e48f7a9945021ea6dfff92d6b2d6514693169ca133e993541bfa4c4c191de806aa80c48109bcfc9901eccfdeb2395ab75fe63c67de900829d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "Expected": "1194e971c875bb45f030316793bc6916343335b18670dfad7a4646fba99749b30283b78b818836de7400ff1a68ddad1a2dd850ec0f227441e2d4d13f5ee4b5d7a856db0a9ad1f86987e1f117d70f9e6a1a2b8d083fa82653aa16f1773b6deb2ed8a1f9e7f3a5db121c4a0c91cb954e2ec53e63422efe86c7984d79cd0e7b5e3eb8ca4980551d63f302c7d72500a84baf12c82fc7bd9b5c2ab8b9c33baf1df28b2031c58a8b2928a42c9f456e98874e22fe13cf17aa5915b11bb108b6ae40842d434604ccddcb4f64324c67b2dde32e6cd759d964f17d9cdf0046cd0ed3588e1fc4b88f67a5d4f3a870aad1cba89ead265d6ad327c8ea7ff54fe4b5e7dbe87c5c59c468543eab3675751111bfa1d6c51daf789d41dc21fd8ba9e05490f881a973a3c1567ff3129a49aa6658cf06f0a79530a7256ce5a07c2a77b4306383d538866bba376d90621c4f82d1f5f32304ee2b7170805d42418fc6967642e5648d8c64fe9c0fdff2d7c114a47add7767c8fccb8808de8c3c6e1a8880c05e16fafc1513fded8eba222dcaaa809bdb36999cc27ab8d0055009e9690e8a35b859df865dc510d25c7812d8eebbb35607ad595573f0fabd1b57970a2bc113ac6f0ca01e985032b9c2c139316ac099ed1632d2bc0fcc341343d303db2a9c3cf2ad572c6c43084b08d458bf822e92da16079f39cdb0dd10ef47f87ecae404117fc72660372cee9ea42266e7f8d973e7f6b09930ca5f96e04976bf23b9d356bbd2429597b04b7663e0e1a1228f4dfda3b854233e4888dc60c6886c1e0e8aec1705f681027b1e0b3017337557f107ef5cd272df5fd31dfec2bdffe163a8369895ffe124c0aa0ee00ca0fe1db4d5cf37b4af0e49bd73a89d88ced3d88f8e6f00d8e61ad09946d0e72cd3e25bc688a021a83758b5023daae7c269a6cbbd447aba5da7629b75801e1654ce85b8e21ccb9865654f8662e538625d75fea31000000000000000000000000000000000000000000000", + "Name": "guido-3-even", + "Gas": 32400, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000181000000000000000000000000000000000000000000000000000000000000000801ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2cffffffffffffffffffffffffffffffffffffffffffffffffffffffff3b10000000006c01ffffffffffffffffffffffffffffffffffffffffffffffdffffb97ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff3bffffffffffffffffffffffffffffffffffffffffffffffffffffffffebafd93b37ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc5bb6affffffff3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff2a", + "Expected": "0000000000000001", + "Name": "guido-4-even", + "Gas": 94448, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000c0e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f2ee5f854d076701c8753d72779187e404f9b2fb705c495137d78551250314a463ef5a213fe22de1cea28d60f518364ff95fe0b73660793e3efcfbe31bda68aeccc21cc9477a6aea5df8cae73422b700c47e54d892691e099167e77befc94780a920ae4155769cd69c30626f054134b5f003772473f57f84837402df6d166e66303f01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c954b27ac388a17c8e9a7ba12a968f288f3308d6fe7bcdf28e685e9a2e00d8be1af19726b7662016d6404f9336493ad633777feb88c9d02a1d2428e566ac38f42c0bb66d2962ec349088ce0d03b35bf27f6114414ef558c87ad8e543754a352f7dffcaca429690688595ab1d1b349d9295b480a82f43ac5c9112fe40720545cc78501cd8b42f3605212fe06a835c9cbc0328e07e94aedb2ac11f6d6649e7fcd8c43", + "Expected": "120cf297dbe810911c7d060e109e03699ccefa00a257d296c5a14b4180776c5f7c0d7f1cd789c694807689729af267b53f00373f395dee264a3daba11fcac1fa8875aee0950acd8fa656f1fc58077a7549d794dd160506ecea1acc9c0cda13795749c94f9973b683ce2162866e8d6b5b1165a4c7fa4234964d394d6ec4e0113698b89d173e24a962dd7a41a1819b0fef188ef64e7ee264595dce0d76fbc3ba42d5de833b143c8744366effede8bc8197e8f747ff8cdbc0bf1a93560bec960ca9", + "Name": "marcin-1-base-heavy", + "Gas": 1152, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000005100000000000000000000000000000000000000000000000000000000000000080001020304050607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0001020304050607", + "Expected": "0000000000000000", + "Name": "marcin-1-exp-heavy", + "Gas": 16624, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000002800000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000028e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c000102030405060701fffffff01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c950001020304050607", + "Expected": "1abce71dc2205cce4eb6934397a88136f94641342e283cbcd30e929e85605c6718ed67f475192ffd", + "Name": "marcin-1-balanced", + "Gas": 1200, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000019800000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000198e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c51f81bcdfc324a0dff2b5bec9d92e21cbebc4d5e29d3a3d30de3e03fbeab8d7f2ee5f854d076701c8753d72779187e404f9b2fb705c495137d78551250314a463ef5a213fe22de1cea28d60f518364ff95fe0b73660793e3efcfbe31bda68aeccc21cc9477a6aea5df8cae73422b700c47e54d892691e099167e77befc94780a920ae4155769cd69c30626f054134b5f003772473f57f84837402df6d166e663c29021b0e084f7dc16f6ec88cc597f1aea9f8e0b9501e0f7a546805d2a20eeda0bf080aeb3ed7ea6f9174d804bd242f0b31ff1ea24800344abb580cd87f61ca75a013a87733553966400242399dee3760877fead2cd87287747155e47a854acb50fe07922f57ae3b4553201bfd7c11aca85e1541f91db8e62dca9c418dc5feae086c9487350539c884510044efce5e3f2aaffca4215c12b9044506375097fecd9b22e2ef46f01f1af8aff742aebf96bdcaf55a341600971dc62555376b9e98a8000102030405060708090a0b0c0d0e0f101112131415161703f01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c954b27ac388a17c8e9a7ba12a968f288f3308d6fe7bcdf28e685e9a2e00d8be1af19726b7662016d6404f9336493ad633777feb88c9d02a1d2428e566ac38f42c0bb66d2962ec349088ce0d03b35bf27f6114414ef558c87ad8e543754a352f7dffcaca429690688595ab1d1b349d9295b480a82f43ac5c9112fe40720545cc78501cd8b42f3605212fe06a835c9cbc0328e07e94aedb2ac11f6d6649e7fcd8c43ddce2bd0cdc6c22c4dcd345735040d5bfe3f09b7c61362089f728e2222db96cab2f2c2ccf43574f9e119f4860fd0f1b6036a43ad9db8a428ea09a4ee385112f3fe9c6656ea2cec604cbb5a9227526653bfa7035e4ae80010b1ba16a76608d5dde0a62bc019e9047b5ec05b1005fd017366130a4ba555e7be654561ee3f539c93cb2c9988fca71bf0ad9c4a426b924641a28e1e4adb93609bfa5b2bc81714cbba1110208b86d7b87be28bdf63a62e33ae81dbcc43de9192bd192c40e85faab539000102030405060708090a0b0c0d0e0f1011121314151617", + "Expected": "817d05c4d540ace3f250fd082e2deb8c2097410fcfe4ce40862cfa015b7f62a7bb72ec1af2915cad66294447b45d177fe759eb80370b0dbd3c0e1c448d54db81eadc11e40c19e394d066a5c019c443798a98d4afd116fc220593d42fbf191b6af0ae75410badb641187ba24a0b968f742a75e2822853f137151d9ea972fd1f36b7c7cc4e71355ecf50648aec094b864cfae9316c0a7be3ddb8ab2d0050b2a029ee956c2366d49430c8f889f29ab514aea8e5b8dec40ba1b49432e30aee32ec45e96dd548205a79d8f8f918eed46acb2115c59086b1011b1d2b093cea723535c3d95efc8e51a7da43b80586d69eb7f213dfb06f7a8e789a9472392bd224411b50f8ca6f2862bcd63431912d1ff99c8d76408245da9e4bea649f0eb930b32922f2d0a345a206160be44d418f1a6c74bd49c4618392ef9350b264a461dfc684c7343211e27675b027054f1cb3d4a5b1a066d3a3ea2eed9caf13251d8be936818f15274e8e3d7539b7c5f216cef327a270fd2a886fbf679c163fb5806249f2c74da5ee0e3ffe9ad1fde2634b29b35da6da6d184ab6ae70199229", + "Name": "marcin-2-base-heavy", + "Gas": 5202, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000500000000000000000000000000000000000000000000000000000000000000010000102030405060708090a0b0c0d0e0fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000102030405060708090a0b0c0d0e0f", + "Expected": "00000000000000000000000000000000", + "Name": "marcin-2-exp-heavy", + "Gas": 16368, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000003800000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000038e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244c000102030405060708090a0b0c0d0e0f10111213141516172bfffffffffffffff01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c95000102030405060708090a0b0c0d0e0f1011121314151617", + "Expected": "86bef3367fc7117c8a6b825cadebe80f3e94c321dda73e9e240b98188a1d5c071c60a195097c8d1fb85ce03a2e1b6964846edee5aa2c3f46", + "Name": "marcin-2-balanced", + "Gas": 5978, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244cfffffffffffffffffffffffffffffffff01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c95", + "Expected": "4004762c491606a5132134da6086284f74cc8e14b08f18b90fc09f31bca3d78f", + "Name": "marcin-3-base-heavy", + "Gas": 2032, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000018000102030405060708090a0b0c0d0e0f1011121314151617ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000102030405060708090a0b0c0d0e0f1011121314151617", + "Expected": "000000000000000000000000000000000000000000000000", + "Name": "marcin-3-exp-heavy", + "Gas": 4080, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000020e8e77626586f73b955364c7b4bbf0bb7f7685ebd40e852b164633a4acbd3244cfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01681d2220bfea4bb888a5543db8c0916274ddb1ea93b144c042c01d8164c95", + "Expected": "2d3feee20d394af68dd6744b86a8aca6a4a0b7f01bbcd3c3eec768245ca6acee", + "Name": "marcin-3-balanced", + "Gas": 4080, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000051000000000000000000000000000000000000000000000000000000000000000800ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffff", + "Name": "mod-8-exp-648", + "Gas": 16624, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000070000000000000000000000000000000000000000000000000000000000000000800ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffff", + "Name": "mod-8-exp-896", + "Gas": 24560, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-32", + "Gas": 500, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0dffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-36", + "Gas": 560, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000005000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-40", + "Gas": 624, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-64", + "Gas": 1008, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000009000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-65", + "Gas": 1024, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-32-exp-128", + "Gas": 2032, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "02fd01000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03ff0000000000000000000000000000000000000000000000fefffffffffffd03feffffffffff", + "Name": "mod-256-exp-2", + "Gas": 2048, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000001080000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000010800ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffff00", + "Expected": "0100fefffffffffffff710f80000000006f108000000000000feffffffffffff0100fefffffffffffef90ff80000000105f008ffffffffff02fdffffffffffff0100feffffffffff00f80ff80000010101f407fffffffd06fc0000000000fd020000feffffffff00fff80ff8000101fa08f207fffffb0afa0000000001fb03000000feffffff00fffff80ff80102f80405f207fff90ef80000000002f90400000000feffff00fffffff80ff903f6050005f207f712f60000000003f7050000000000feff00fffffffff810fcf406000005f1fd16f40000000004f506000000000000fe00fffffffffff915ea0700000005e522f20000000005f306ffffffffffffffffffffffffff", + "Name": "mod-264-exp-2", + "Gas": 2178, + "NoBenchmark": false + }, + { + "Input": "00000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000040000ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00", + "Expected": "00fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02fefffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe02feffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Name": "mod-1024-exp-2", + "Gas": 32768, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000700000000000000000000000000000000000000000000000000000000000000008ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "2a02d5f86c2375ff", + "Name": "pawel-1-exp-heavy", + "Gas": 24560, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000280000000000000000000000000000000000000000000000000000000000000010ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "823ef7dc60d6d9616756c48f69b7c4ff", + "Name": "pawel-2-exp-heavy", + "Gas": 6128, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001800000000000000000000000000000000000000000000000000000000000000150000000000000000000000000000000000000000000000000000000000000018ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "c817dd5aa60a41948eed409706c2aa97be3000d4da0261ff", + "Name": "pawel-3-exp-heavy", + "Gas": 2672, + "NoBenchmark": false + }, + { + "Input": "0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000000000020ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "Expected": "2defaca0137d6edacbbd5d36d6ed70cbf8a998ffb19fc270d45a18d37e0f35ff", + "Name": "pawel-4-exp-heavy", + "Gas": 1520, + "NoBenchmark": false + }, + { + "Input": "000000000000000000000000000000000000000000000000000000000000001700000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000017bffffffffffffffffffffffffffffffffffffffffffffbffffffffffffffffff7ffffffffffffffffffffffffffffffffffffffffffe", + "Expected": "200f14de1d474710c1c979920452e0ffc2ac6f618afba5", + "Name": "mod_vul_pawel_3_exp_8", + "Gas": 1008, + "NoBenchmark": false } ] diff --git a/crypto/blake2b/blake2b.go b/crypto/blake2b/blake2b.go index c24a88b99d..e00ee2e6d2 100644 --- a/crypto/blake2b/blake2b.go +++ b/crypto/blake2b/blake2b.go @@ -302,7 +302,7 @@ func appendUint64(b []byte, x uint64) []byte { return append(b, a[:]...) } -//nolint:unused,deadcode +//nolint:unused func appendUint32(b []byte, x uint32) []byte { var a [4]byte binary.BigEndian.PutUint32(a[:], x) @@ -314,7 +314,7 @@ func consumeUint64(b []byte) ([]byte, uint64) { return b[8:], x } -//nolint:unused,deadcode +//nolint:unused func consumeUint32(b []byte) ([]byte, uint32) { x := binary.BigEndian.Uint32(b) return b[4:], x diff --git a/crypto/blake2b/blake2b_generic.go b/crypto/blake2b/blake2b_generic.go index 61e678fdf5..4d3f69d292 100644 --- a/crypto/blake2b/blake2b_generic.go +++ b/crypto/blake2b/blake2b_generic.go @@ -25,7 +25,7 @@ var precomputed = [10][16]byte{ {10, 8, 7, 1, 2, 4, 6, 5, 15, 9, 3, 13, 11, 14, 12, 0}, } -// nolint:unused,deadcode +// nolint:unused func hashBlocksGeneric(h *[8]uint64, c *[2]uint64, flag uint64, blocks []byte) { var m [16]uint64 c0, c1 := c[0], c[1] diff --git a/crypto/blake2b/blake2b_test.go b/crypto/blake2b/blake2b_test.go index 9d24444a27..8f210445fc 100644 --- a/crypto/blake2b/blake2b_test.go +++ b/crypto/blake2b/blake2b_test.go @@ -303,8 +303,7 @@ func benchmarkSum(b *testing.B, size int, sse4, avx, avx2 bool) { data := make([]byte, size) b.SetBytes(int64(size)) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { Sum512(data) } } @@ -319,8 +318,7 @@ func benchmarkWrite(b *testing.B, size int, sse4, avx, avx2 bool) { data := make([]byte, size) h, _ := New512(nil) b.SetBytes(int64(size)) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { h.Write(data) } } diff --git a/crypto/bn256/bn256_fast.go b/crypto/bn256/bn256_fast.go index e3c9b60518..93a2eef879 100644 --- a/crypto/bn256/bn256_fast.go +++ b/crypto/bn256/bn256_fast.go @@ -9,18 +9,18 @@ package bn256 import ( - bn256cf "github.com/ethereum/go-ethereum/crypto/bn256/cloudflare" + gnark "github.com/ethereum/go-ethereum/crypto/bn256/gnark" ) // G1 is an abstract cyclic group. The zero value is suitable for use as the // output of an operation, but cannot be used as an input. -type G1 = bn256cf.G1 +type G1 = gnark.G1 // G2 is an abstract cyclic group. The zero value is suitable for use as the // output of an operation, but cannot be used as an input. -type G2 = bn256cf.G2 +type G2 = gnark.G2 // PairingCheck calculates the Optimal Ate pairing for a set of points. func PairingCheck(a []*G1, b []*G2) bool { - return bn256cf.PairingCheck(a, b) + return gnark.PairingCheck(a, b) } diff --git a/crypto/bn256/cloudflare/gfp_decl.go b/crypto/bn256/cloudflare/gfp_decl.go index 1954d14a4a..b7dd1a8aac 100644 --- a/crypto/bn256/cloudflare/gfp_decl.go +++ b/crypto/bn256/cloudflare/gfp_decl.go @@ -10,7 +10,7 @@ import ( "golang.org/x/sys/cpu" ) -//nolint:varcheck,unused,deadcode +//nolint:unused var hasBMI2 = cpu.X86.HasBMI2 //go:noescape diff --git a/crypto/bn256/gnark/g1.go b/crypto/bn256/gnark/g1.go index 59e04cb247..bb758c3580 100644 --- a/crypto/bn256/gnark/g1.go +++ b/crypto/bn256/gnark/g1.go @@ -5,6 +5,7 @@ import ( "math/big" "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/ethereum/go-ethereum/common/bitutil" ) // G1 is the affine representation of a G1 group element. @@ -43,7 +44,7 @@ func (g *G1) Unmarshal(buf []byte) (int, error) { return 0, errors.New("invalid G1 point size") } - if allZeroes(buf[:64]) { + if !bitutil.TestBytes(buf[:64]) { // point at infinity g.inner.X.SetZero() g.inner.Y.SetZero() @@ -82,12 +83,3 @@ func (p *G1) Marshal() []byte { return output } - -func allZeroes(buf []byte) bool { - for i := range buf { - if buf[i] != 0 { - return false - } - } - return true -} diff --git a/crypto/bn256/gnark/g2.go b/crypto/bn256/gnark/g2.go index 48a797e5a7..87ad88b9f1 100644 --- a/crypto/bn256/gnark/g2.go +++ b/crypto/bn256/gnark/g2.go @@ -4,6 +4,7 @@ import ( "errors" "github.com/consensys/gnark-crypto/ecc/bn254" + "github.com/ethereum/go-ethereum/common/bitutil" ) // G2 is the affine representation of a G2 group element. @@ -31,7 +32,7 @@ func (g *G2) Unmarshal(buf []byte) (int, error) { return 0, errors.New("invalid G2 point size") } - if allZeroes(buf[:128]) { + if !bitutil.TestBytes(buf[:128]) { // point at infinity g.inner.X.A0.SetZero() g.inner.X.A1.SetZero() diff --git a/crypto/crypto.go b/crypto/crypto.go index 09596c05ce..db6b6ee071 100644 --- a/crypto/crypto.go +++ b/crypto/crypto.go @@ -28,12 +28,10 @@ import ( "io" "math/big" "os" - "sync" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/math" "github.com/ethereum/go-ethereum/rlp" - "golang.org/x/crypto/sha3" ) // SignatureLength indicates the byte length required to carry a signature with recovery id. @@ -69,17 +67,6 @@ type KeccakState interface { Read([]byte) (int, error) } -// NewKeccakState creates a new KeccakState -func NewKeccakState() KeccakState { - return sha3.NewLegacyKeccak256().(KeccakState) -} - -var hasherPool = sync.Pool{ - New: func() any { - return sha3.NewLegacyKeccak256().(KeccakState) - }, -} - // HashData hashes the provided data using the KeccakState and returns a 32 byte hash func HashData(kh KeccakState, data []byte) (h common.Hash) { kh.Reset() @@ -88,41 +75,6 @@ func HashData(kh KeccakState, data []byte) (h common.Hash) { return h } -// Keccak256 calculates and returns the Keccak256 hash of the input data. -func Keccak256(data ...[]byte) []byte { - b := make([]byte, 32) - d := hasherPool.Get().(KeccakState) - d.Reset() - for _, b := range data { - d.Write(b) - } - d.Read(b) - hasherPool.Put(d) - return b -} - -// Keccak256Hash calculates and returns the Keccak256 hash of the input data, -// converting it to an internal Hash data structure. -func Keccak256Hash(data ...[]byte) (h common.Hash) { - d := hasherPool.Get().(KeccakState) - d.Reset() - for _, b := range data { - d.Write(b) - } - d.Read(h[:]) - hasherPool.Put(d) - return h -} - -// Keccak512 calculates and returns the Keccak512 hash of the input data. -func Keccak512(data ...[]byte) []byte { - d := sha3.NewLegacyKeccak512() - for _, b := range data { - d.Write(b) - } - return d.Sum(nil) -} - // CreateAddress creates an ethereum address given the bytes and the nonce func CreateAddress(b common.Address, nonce uint64) common.Address { data, _ := rlp.EncodeToBytes([]interface{}{b, nonce}) diff --git a/crypto/crypto_test.go b/crypto/crypto_test.go index e620d6ee3a..d803ab27c5 100644 --- a/crypto/crypto_test.go +++ b/crypto/crypto_test.go @@ -60,7 +60,7 @@ func TestToECDSAErrors(t *testing.T) { func BenchmarkSha3(b *testing.B) { a := []byte("hello world") - for i := 0; i < b.N; i++ { + for b.Loop() { Keccak256(a) } } @@ -310,7 +310,7 @@ func BenchmarkKeccak256Hash(b *testing.B) { rand.Read(input[:]) b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { Keccak256Hash(input[:]) } } @@ -329,7 +329,7 @@ func BenchmarkHashData(b *testing.B) { rand.Read(input[:]) b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { HashData(buffer, input[:]) } } diff --git a/crypto/ecies/ecies.go b/crypto/ecies/ecies.go index 76f934c72d..9a892781f4 100644 --- a/crypto/ecies/ecies.go +++ b/crypto/ecies/ecies.go @@ -290,7 +290,7 @@ func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) { switch c[0] { case 2, 3, 4: rLen = (prv.PublicKey.Curve.Params().BitSize + 7) / 4 - if len(c) < (rLen + hLen + 1) { + if len(c) < (rLen + hLen + params.BlockSize) { return nil, ErrInvalidMessage } default: diff --git a/crypto/ecies/ecies_test.go b/crypto/ecies/ecies_test.go index e3da71010e..e822db2783 100644 --- a/crypto/ecies/ecies_test.go +++ b/crypto/ecies/ecies_test.go @@ -164,7 +164,7 @@ func TestTooBigSharedKey(t *testing.T) { // Benchmark the generation of P256 keys. func BenchmarkGenerateKeyP256(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { if _, err := GenerateKey(rand.Reader, elliptic.P256(), nil); err != nil { b.Fatal(err) } @@ -177,8 +177,7 @@ func BenchmarkGenSharedKeyP256(b *testing.B) { if err != nil { b.Fatal(err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { _, err := prv.GenerateShared(&prv.PublicKey, 16, 16) if err != nil { b.Fatal(err) @@ -192,8 +191,7 @@ func BenchmarkGenSharedKeyS256(b *testing.B) { if err != nil { b.Fatal(err) } - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { _, err := prv.GenerateShared(&prv.PublicKey, 16, 16) if err != nil { b.Fatal(err) diff --git a/crypto/keccak.go b/crypto/keccak.go new file mode 100644 index 0000000000..0ad79a63c1 --- /dev/null +++ b/crypto/keccak.go @@ -0,0 +1,63 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +//go:build !ziren + +package crypto + +import ( + "sync" + + "github.com/ethereum/go-ethereum/common" + "golang.org/x/crypto/sha3" +) + +// NewKeccakState creates a new KeccakState +func NewKeccakState() KeccakState { + return sha3.NewLegacyKeccak256().(KeccakState) +} + +var hasherPool = sync.Pool{ + New: func() any { + return sha3.NewLegacyKeccak256().(KeccakState) + }, +} + +// Keccak256 calculates and returns the Keccak256 hash of the input data. +func Keccak256(data ...[]byte) []byte { + b := make([]byte, 32) + d := hasherPool.Get().(KeccakState) + d.Reset() + for _, b := range data { + d.Write(b) + } + d.Read(b) + hasherPool.Put(d) + return b +} + +// Keccak256Hash calculates and returns the Keccak256 hash of the input data, +// converting it to an internal Hash data structure. +func Keccak256Hash(data ...[]byte) (h common.Hash) { + d := hasherPool.Get().(KeccakState) + d.Reset() + for _, b := range data { + d.Write(b) + } + d.Read(h[:]) + hasherPool.Put(d) + return h +} diff --git a/crypto/keccak_ziren.go b/crypto/keccak_ziren.go new file mode 100644 index 0000000000..8e967c6dbf --- /dev/null +++ b/crypto/keccak_ziren.go @@ -0,0 +1,122 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +//go:build ziren + +package crypto + +import ( + "github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime" + "github.com/ethereum/go-ethereum/common" +) + +// zirenKeccakState implements the KeccakState interface using the Ziren zkvm_runtime. +// It accumulates data written to it and uses the zkvm's Keccak256 system call for hashing. +type zirenKeccakState struct { + buf []byte // accumulated data + result []byte // cached result + dirty bool // whether new data has been written since last hash +} + +func newZirenKeccakState() KeccakState { + return &zirenKeccakState{ + buf: make([]byte, 0, 512), // pre-allocate reasonable capacity + } +} + +func (s *zirenKeccakState) Write(p []byte) (n int, err error) { + s.buf = append(s.buf, p...) + s.dirty = true + return len(p), nil +} + +func (s *zirenKeccakState) Sum(b []byte) []byte { + s.computeHashIfNeeded() + return append(b, s.result...) +} + +func (s *zirenKeccakState) Reset() { + s.buf = s.buf[:0] + s.result = nil + s.dirty = false +} + +func (s *zirenKeccakState) Size() int { + return 32 +} + +func (s *zirenKeccakState) BlockSize() int { + return 136 // Keccak256 rate +} + +func (s *zirenKeccakState) Read(p []byte) (n int, err error) { + s.computeHashIfNeeded() + + if len(p) == 0 { + return 0, nil + } + + // After computeHashIfNeeded(), s.result is always a 32-byte slice + n = copy(p, s.result) + return n, nil +} + +func (s *zirenKeccakState) computeHashIfNeeded() { + if s.dirty || s.result == nil { + // Use the zkvm_runtime Keccak256 which uses SyscallKeccakSponge + hashArray := zkvm_runtime.Keccak256(s.buf) + s.result = hashArray[:] + s.dirty = false + } +} + +// NewKeccakState creates a new KeccakState +// This uses a Ziren-optimized implementation that leverages the zkvm_runtime.Keccak256 system call. +func NewKeccakState() KeccakState { + return newZirenKeccakState() +} + +// Keccak256 calculates and returns the Keccak256 hash using the Ziren zkvm_runtime implementation. +func Keccak256(data ...[]byte) []byte { + // For multiple data chunks, concatenate them + if len(data) == 0 { + result := zkvm_runtime.Keccak256(nil) + return result[:] + } + if len(data) == 1 { + result := zkvm_runtime.Keccak256(data[0]) + return result[:] + } + + // Concatenate multiple data chunks + var totalLen int + for _, d := range data { + totalLen += len(d) + } + + combined := make([]byte, 0, totalLen) + for _, d := range data { + combined = append(combined, d...) + } + + result := zkvm_runtime.Keccak256(combined) + return result[:] +} + +// Keccak256Hash calculates and returns the Keccak256 hash as a Hash using the Ziren zkvm_runtime implementation. +func Keccak256Hash(data ...[]byte) common.Hash { + return common.Hash(Keccak256(data...)) +} diff --git a/crypto/kzg4844/kzg4844.go b/crypto/kzg4844/kzg4844.go index 9da2386368..3ccc204838 100644 --- a/crypto/kzg4844/kzg4844.go +++ b/crypto/kzg4844/kzg4844.go @@ -34,10 +34,10 @@ var ( blobT = reflect.TypeFor[Blob]() commitmentT = reflect.TypeFor[Commitment]() proofT = reflect.TypeFor[Proof]() - - CellProofsPerBlob = 128 ) +const CellProofsPerBlob = 128 + // Blob represents a 4844 data blob. type Blob [131072]byte diff --git a/crypto/kzg4844/kzg4844_ckzg_cgo.go b/crypto/kzg4844/kzg4844_ckzg_cgo.go index b215b19928..46509674b6 100644 --- a/crypto/kzg4844/kzg4844_ckzg_cgo.go +++ b/crypto/kzg4844/kzg4844_ckzg_cgo.go @@ -150,7 +150,7 @@ func ckzgComputeCellProofs(blob *Blob) ([]Proof, error) { return p, nil } -// ckzgVerifyCellProofs verifies that the blob data corresponds to the provided commitment. +// ckzgVerifyCellProofBatch verifies that the blob data corresponds to the provided commitment. func ckzgVerifyCellProofBatch(blobs []Blob, commitments []Commitment, cellProofs []Proof) error { ckzgIniter.Do(ckzgInit) var ( diff --git a/crypto/kzg4844/kzg4844_gokzg.go b/crypto/kzg4844/kzg4844_gokzg.go index 82ec8379d4..e9676ff1b8 100644 --- a/crypto/kzg4844/kzg4844_gokzg.go +++ b/crypto/kzg4844/kzg4844_gokzg.go @@ -115,7 +115,7 @@ func gokzgComputeCellProofs(blob *Blob) ([]Proof, error) { return p, nil } -// gokzgVerifyCellProofs verifies that the blob data corresponds to the provided commitment. +// gokzgVerifyCellProofBatch verifies that the blob data corresponds to the provided commitment. func gokzgVerifyCellProofBatch(blobs []Blob, commitments []Commitment, cellProofs []Proof) error { gokzgIniter.Do(gokzgInit) diff --git a/crypto/kzg4844/kzg4844_test.go b/crypto/kzg4844/kzg4844_test.go index 7e73efd850..743a277199 100644 --- a/crypto/kzg4844/kzg4844_test.go +++ b/crypto/kzg4844/kzg4844_test.go @@ -105,8 +105,7 @@ func benchmarkBlobToCommitment(b *testing.B, ckzg bool) { blob := randBlob() - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { BlobToCommitment(blob) } } @@ -125,8 +124,7 @@ func benchmarkComputeProof(b *testing.B, ckzg bool) { point = randFieldElement() ) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { ComputeProof(blob, point) } } @@ -147,8 +145,7 @@ func benchmarkVerifyProof(b *testing.B, ckzg bool) { proof, claim, _ = ComputeProof(blob, point) ) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { VerifyProof(commitment, point, claim, proof) } } @@ -167,8 +164,7 @@ func benchmarkComputeBlobProof(b *testing.B, ckzg bool) { commitment, _ = BlobToCommitment(blob) ) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { ComputeBlobProof(blob, commitment) } } @@ -188,8 +184,7 @@ func benchmarkVerifyBlobProof(b *testing.B, ckzg bool) { proof, _ = ComputeBlobProof(blob, commitment) ) - b.ResetTimer() - for i := 0; i < b.N; i++ { + for b.Loop() { VerifyBlobProof(blob, commitment, proof) } } @@ -230,3 +225,31 @@ func testKZGCells(t *testing.T, ckzg bool) { t.Fatalf("failed to verify KZG proof at point: %v", err) } } + +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/crypto/kzg4844 +// cpu: Apple M1 Pro +// BenchmarkGOKZGComputeCellProofs +// BenchmarkGOKZGComputeCellProofs-8 8 139012286 ns/op +func BenchmarkGOKZGComputeCellProofs(b *testing.B) { benchmarkComputeCellProofs(b, false) } +func BenchmarkCKZGComputeCellProofs(b *testing.B) { benchmarkComputeCellProofs(b, true) } + +func benchmarkComputeCellProofs(b *testing.B, ckzg bool) { + if ckzg && !ckzgAvailable { + b.Skip("CKZG unavailable in this test build") + } + defer func(old bool) { useCKZG.Store(old) }(useCKZG.Load()) + useCKZG.Store(ckzg) + + blob := randBlob() + _, _ = ComputeCellProofs(blob) // for kzg initialization + b.ResetTimer() + + for b.Loop() { + _, err := ComputeCellProofs(blob) + if err != nil { + b.Fatalf("failed to create KZG proof at point: %v", err) + } + } +} diff --git a/crypto/secp256k1/curve.go b/crypto/secp256k1/curve.go index 85ba885d6f..b82b147e3c 100644 --- a/crypto/secp256k1/curve.go +++ b/crypto/secp256k1/curve.go @@ -35,29 +35,10 @@ package secp256k1 import ( "crypto/elliptic" "math/big" -) -const ( - // number of bits in a big.Word - wordBits = 32 << (uint64(^big.Word(0)) >> 63) - // number of bytes in a big.Word - wordBytes = wordBits / 8 + "github.com/ethereum/go-ethereum/common/math" ) -// readBits encodes the absolute value of bigint as big-endian bytes. Callers -// must ensure that buf has enough space. If buf is too short the result will -// be incomplete. -func readBits(bigint *big.Int, buf []byte) { - i := len(buf) - for _, d := range bigint.Bits() { - for j := 0; j < wordBytes && i > 0; j++ { - i-- - buf[i] = byte(d) - d >>= 8 - } - } -} - // This code is from https://github.com/ThePiachu/GoBit and implements // several Koblitz elliptic curves over prime fields. // @@ -257,8 +238,8 @@ func (bitCurve *BitCurve) Marshal(x, y *big.Int) []byte { byteLen := (bitCurve.BitSize + 7) >> 3 ret := make([]byte, 1+2*byteLen) ret[0] = 4 // uncompressed point flag - readBits(x, ret[1:1+byteLen]) - readBits(y, ret[1+byteLen:]) + math.ReadBits(x, ret[1:1+byteLen]) + math.ReadBits(y, ret[1+byteLen:]) return ret } diff --git a/crypto/secp256k1/scalar_mult_cgo.go b/crypto/secp256k1/scalar_mult_cgo.go index d11c11faf8..b16c13f7e2 100644 --- a/crypto/secp256k1/scalar_mult_cgo.go +++ b/crypto/secp256k1/scalar_mult_cgo.go @@ -10,6 +10,8 @@ package secp256k1 import ( "math/big" "unsafe" + + "github.com/ethereum/go-ethereum/common/math" ) /* @@ -34,8 +36,8 @@ func (bitCurve *BitCurve) ScalarMult(Bx, By *big.Int, scalar []byte) (*big.Int, // Do the multiplication in C, updating point. point := make([]byte, 64) - readBits(Bx, point[:32]) - readBits(By, point[32:]) + math.ReadBits(Bx, point[:32]) + math.ReadBits(By, point[32:]) pointPtr := (*C.uchar)(unsafe.Pointer(&point[0])) scalarPtr := (*C.uchar)(unsafe.Pointer(&scalar[0])) diff --git a/crypto/secp256k1/secp256_test.go b/crypto/secp256k1/secp256_test.go index 4827cc5b25..c7485bca08 100644 --- a/crypto/secp256k1/secp256_test.go +++ b/crypto/secp256k1/secp256_test.go @@ -221,9 +221,7 @@ func TestRecoverSanity(t *testing.T) { func BenchmarkSign(b *testing.B) { _, seckey := generateKeyPair() msg := csprngEntropy(32) - b.ResetTimer() - - for i := 0; i < b.N; i++ { + for b.Loop() { Sign(msg, seckey) } } @@ -232,9 +230,7 @@ func BenchmarkRecover(b *testing.B) { msg := csprngEntropy(32) _, seckey := generateKeyPair() sig, _ := Sign(msg, seckey) - b.ResetTimer() - - for i := 0; i < b.N; i++ { + for b.Loop() { RecoverPubkey(msg, sig) } } diff --git a/crypto/signature_nocgo.go b/crypto/signature_nocgo.go index d76127c258..9dce1057fa 100644 --- a/crypto/signature_nocgo.go +++ b/crypto/signature_nocgo.go @@ -43,6 +43,9 @@ func sigToPub(hash, sig []byte) (*secp256k1.PublicKey, error) { if len(sig) != SignatureLength { return nil, errors.New("invalid signature") } + if len(hash) != DigestLength { + return nil, fmt.Errorf("hash is required to be exactly %d bytes (%d)", DigestLength, len(hash)) + } // Convert to secp256k1 input format with 'recovery id' v at the beginning. btcsig := make([]byte, SignatureLength) btcsig[0] = sig[RecoveryIDOffset] + 27 @@ -76,8 +79,8 @@ func SigToPub(hash, sig []byte) (*ecdsa.PublicKey, error) { // // The produced signature is in the [R || S || V] format where V is 0 or 1. func Sign(hash []byte, prv *ecdsa.PrivateKey) ([]byte, error) { - if len(hash) != 32 { - return nil, fmt.Errorf("hash is required to be exactly 32 bytes (%d)", len(hash)) + if len(hash) != DigestLength { + return nil, fmt.Errorf("hash is required to be exactly %d bytes (%d)", DigestLength, len(hash)) } if prv.Curve != S256() { return nil, errors.New("private key curve is not secp256k1") diff --git a/crypto/signature_test.go b/crypto/signature_test.go index 74d683b507..b1f2960254 100644 --- a/crypto/signature_test.go +++ b/crypto/signature_test.go @@ -135,7 +135,7 @@ func TestPubkeyRandom(t *testing.T) { } func BenchmarkEcrecoverSignature(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { if _, err := Ecrecover(testmsg, testsig); err != nil { b.Fatal("ecrecover error", err) } @@ -144,7 +144,7 @@ func BenchmarkEcrecoverSignature(b *testing.B) { func BenchmarkVerifySignature(b *testing.B) { sig := testsig[:len(testsig)-1] // remove recovery id - for i := 0; i < b.N; i++ { + for b.Loop() { if !VerifySignature(testpubkey, testmsg, sig) { b.Fatal("verify error") } @@ -152,7 +152,7 @@ func BenchmarkVerifySignature(b *testing.B) { } func BenchmarkDecompressPubkey(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { if _, err := DecompressPubkey(testpubkeyc); err != nil { b.Fatal(err) } diff --git a/crypto/signify/signify_fuzz.go b/crypto/signify/signify_fuzz.go index 239a2134df..d11125c697 100644 --- a/crypto/signify/signify_fuzz.go +++ b/crypto/signify/signify_fuzz.go @@ -56,7 +56,7 @@ func Fuzz(data []byte) int { fmt.Printf("untrusted: %v\n", untrustedComment) fmt.Printf("trusted: %v\n", trustedComment) - err = SignifySignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, untrustedComment, trustedComment) + err = SignFile(tmpFile.Name(), tmpFile.Name()+".sig", testSecKey, untrustedComment, trustedComment) if err != nil { panic(err) } @@ -68,7 +68,7 @@ func Fuzz(data []byte) int { signify = path } - _, err := exec.LookPath(signify) + _, err = exec.LookPath(signify) if err != nil { panic(err) } diff --git a/eth/api_backend.go b/eth/api_backend.go index 3ae73e78af..3f826b7861 100644 --- a/eth/api_backend.go +++ b/eth/api_backend.go @@ -315,6 +315,11 @@ func (b *EthAPIBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) e return b.eth.BlockChain().SubscribeChainHeadEvent(ch) } +// SubscribeNewPayloadEvent registers a subscription for NewPayloadEvent. +func (b *EthAPIBackend) SubscribeNewPayloadEvent(ch chan<- core.NewPayloadEvent) event.Subscription { + return b.eth.BlockChain().SubscribeNewPayloadEvent(ch) +} + func (b *EthAPIBackend) SubscribeLogsEvent(ch chan<- []*types.Log) event.Subscription { return b.eth.BlockChain().SubscribeLogsEvent(ch) } @@ -486,3 +491,11 @@ func (b *EthAPIBackend) StateAtBlock(ctx context.Context, block *types.Block, re func (b *EthAPIBackend) StateAtTransaction(ctx context.Context, block *types.Block, txIndex int, reexec uint64) (*types.Transaction, vm.BlockContext, *state.StateDB, tracers.StateReleaseFunc, error) { return b.eth.stateAtTransaction(ctx, block, txIndex, reexec) } + +func (b *EthAPIBackend) RPCTxSyncDefaultTimeout() time.Duration { + return b.eth.config.TxSyncDefaultTimeout +} + +func (b *EthAPIBackend) RPCTxSyncMaxTimeout() time.Duration { + return b.eth.config.TxSyncMaxTimeout +} diff --git a/eth/api_backend_test.go b/eth/api_backend_test.go index d0718ede1c..aa0539511b 100644 --- a/eth/api_backend_test.go +++ b/eth/api_backend_test.go @@ -20,6 +20,7 @@ import ( "context" "crypto/ecdsa" "errors" + "math" "math/big" "testing" "time" @@ -130,6 +131,27 @@ func TestSendTx(t *testing.T) { testSendTx(t, true) } +func TestSendTxEIP2681(t *testing.T) { + b := initBackend(false) + + // Test EIP-2681: nonce overflow should be rejected + tx := makeTx(uint64(math.MaxUint64), nil, nil, key) // max uint64 nonce + err := b.SendTx(context.Background(), tx) + if err == nil { + t.Fatal("Expected EIP-2681 nonce overflow error, but transaction was accepted") + } + if !errors.Is(err, core.ErrNonceMax) { + t.Errorf("Expected core.ErrNonceMax, got: %v", err) + } + + // Test normal case: should succeed + normalTx := makeTx(0, nil, nil, key) + err = b.SendTx(context.Background(), normalTx) + if err != nil { + t.Errorf("Normal transaction should succeed, got error: %v", err) + } +} + func testSendTx(t *testing.T, withLocal bool) { b := initBackend(withLocal) diff --git a/eth/api_debug.go b/eth/api_debug.go index 188dee11aa..db1b842e90 100644 --- a/eth/api_debug.go +++ b/eth/api_debug.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/stateless" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/internal/ethapi" @@ -443,3 +444,85 @@ func (api *DebugAPI) GetTrieFlushInterval() (string, error) { } return api.eth.blockchain.GetTrieFlushInterval().String(), nil } + +// StateSize returns the current state size statistics from the state size tracker. +// Returns an error if the state size tracker is not initialized or if stats are not ready. +func (api *DebugAPI) StateSize(blockHashOrNumber *rpc.BlockNumberOrHash) (interface{}, error) { + sizer := api.eth.blockchain.StateSizer() + if sizer == nil { + return nil, errors.New("state size tracker is not enabled") + } + var ( + err error + stats *state.SizeStats + ) + if blockHashOrNumber == nil { + stats, err = sizer.Query(nil) + } else { + header, herr := api.eth.APIBackend.HeaderByNumberOrHash(context.Background(), *blockHashOrNumber) + if herr != nil || header == nil { + return nil, fmt.Errorf("block %s is unknown", blockHashOrNumber) + } + stats, err = sizer.Query(&header.Root) + } + if err != nil { + return nil, err + } + if stats == nil { + var s string + if blockHashOrNumber == nil { + s = "chain head" + } else { + s = blockHashOrNumber.String() + } + return nil, fmt.Errorf("state size of %s is not available", s) + } + return map[string]interface{}{ + "stateRoot": stats.StateRoot, + "blockNumber": hexutil.Uint64(stats.BlockNumber), + "accounts": hexutil.Uint64(stats.Accounts), + "accountBytes": hexutil.Uint64(stats.AccountBytes), + "storages": hexutil.Uint64(stats.Storages), + "storageBytes": hexutil.Uint64(stats.StorageBytes), + "accountTrienodes": hexutil.Uint64(stats.AccountTrienodes), + "accountTrienodeBytes": hexutil.Uint64(stats.AccountTrienodeBytes), + "storageTrienodes": hexutil.Uint64(stats.StorageTrienodes), + "storageTrienodeBytes": hexutil.Uint64(stats.StorageTrienodeBytes), + "contractCodes": hexutil.Uint64(stats.ContractCodes), + "contractCodeBytes": hexutil.Uint64(stats.ContractCodeBytes), + }, nil +} + +func (api *DebugAPI) ExecutionWitness(bn rpc.BlockNumber) (*stateless.ExtWitness, error) { + bc := api.eth.blockchain + block, err := api.eth.APIBackend.BlockByNumber(context.Background(), bn) + if err != nil { + return &stateless.ExtWitness{}, fmt.Errorf("block number %v not found", bn) + } + parent := bc.GetHeader(block.ParentHash(), block.NumberU64()-1) + if parent == nil { + return &stateless.ExtWitness{}, fmt.Errorf("block number %v found, but parent missing", bn) + } + result, err := bc.ProcessBlock(parent.Root, block, false, true) + if err != nil { + return nil, err + } + return result.Witness().ToExtWitness(), nil +} + +func (api *DebugAPI) ExecutionWitnessByHash(hash common.Hash) (*stateless.ExtWitness, error) { + bc := api.eth.blockchain + block := bc.GetBlockByHash(hash) + if block == nil { + return &stateless.ExtWitness{}, fmt.Errorf("block hash %x not found", hash) + } + parent := bc.GetHeader(block.ParentHash(), block.NumberU64()-1) + if parent == nil { + return &stateless.ExtWitness{}, fmt.Errorf("block number %x found, but parent missing", hash) + } + result, err := bc.ProcessBlock(parent.Root, block, false, true) + if err != nil { + return nil, err + } + return result.Witness().ToExtWitness(), nil +} diff --git a/eth/backend.go b/eth/backend.go index 7616ec9d31..aed1542aeb 100644 --- a/eth/backend.go +++ b/eth/backend.go @@ -222,25 +222,31 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { } var ( options = &core.BlockChainConfig{ - TrieCleanLimit: config.TrieCleanCache, - NoPrefetch: config.NoPrefetch, - TrieDirtyLimit: config.TrieDirtyCache, - ArchiveMode: config.NoPruning, - TrieTimeLimit: config.TrieTimeout, - SnapshotLimit: config.SnapshotCache, - Preimages: config.Preimages, - StateHistory: config.StateHistory, - StateScheme: scheme, - ChainHistoryMode: config.HistoryMode, - TxLookupLimit: int64(min(config.TransactionHistory, math.MaxInt64)), + TrieCleanLimit: config.TrieCleanCache, + NoPrefetch: config.NoPrefetch, + TrieDirtyLimit: config.TrieDirtyCache, + ArchiveMode: config.NoPruning, + TrieTimeLimit: config.TrieTimeout, + SnapshotLimit: config.SnapshotCache, + Preimages: config.Preimages, + StateHistory: config.StateHistory, + TrienodeHistory: config.TrienodeHistory, + NodeFullValueCheckpoint: config.NodeFullValueCheckpoint, + StateScheme: scheme, + ChainHistoryMode: config.HistoryMode, + TxLookupLimit: int64(min(config.TransactionHistory, math.MaxInt64)), VmConfig: vm.Config{ EnablePreimageRecording: config.EnablePreimageRecording, + EnableWitnessStats: config.EnableWitnessStats, + StatelessSelfValidation: config.StatelessSelfValidation, }, // Enables file journaling for the trie database. The journal files will be stored // within the data directory. The corresponding paths will be either: // - DATADIR/triedb/merkle.journal // - DATADIR/triedb/verkle.journal TrieJournalDirectory: stack.ResolvePath("triedb"), + StateSizeTracking: config.EnableStateSizeTracking, + SlowBlockThreshold: config.SlowBlockThreshold, } ) if config.VMTrace != "" { @@ -259,6 +265,12 @@ func New(stack *node.Node, config *ethconfig.Config) (*Ethereum, error) { if config.OverrideOsaka != nil { overrides.OverrideOsaka = config.OverrideOsaka } + if config.OverrideBPO1 != nil { + overrides.OverrideBPO1 = config.OverrideBPO1 + } + if config.OverrideBPO2 != nil { + overrides.OverrideBPO2 = config.OverrideBPO2 + } if config.OverrideVerkle != nil { overrides.OverrideVerkle = config.OverrideVerkle } @@ -582,29 +594,3 @@ func (s *Ethereum) Stop() error { return nil } - -// SyncMode retrieves the current sync mode, either explicitly set, or derived -// from the chain status. -func (s *Ethereum) SyncMode() ethconfig.SyncMode { - // If we're in snap sync mode, return that directly - if s.handler.snapSync.Load() { - return ethconfig.SnapSync - } - // We are probably in full sync, but we might have rewound to before the - // snap sync pivot, check if we should re-enable snap sync. - head := s.blockchain.CurrentBlock() - if pivot := rawdb.ReadLastPivotNumber(s.chainDb); pivot != nil { - if head.Number.Uint64() < *pivot { - return ethconfig.SnapSync - } - } - // We are in a full sync, but the associated head state is missing. To complete - // the head state, forcefully rerun the snap sync. Note it doesn't mean the - // persistent state is corrupted, just mismatch with the head block. - if !s.blockchain.HasState(head.Root) { - log.Info("Reenabled snap sync as chain is stateless") - return ethconfig.SnapSync - } - // Nope, we're really full syncing - return ethconfig.FullSync -} diff --git a/eth/catalyst/api.go b/eth/catalyst/api.go index 038328d9ba..e6ecf4ff6a 100644 --- a/eth/catalyst/api.go +++ b/eth/catalyst/api.go @@ -20,21 +20,23 @@ package catalyst import ( "errors" "fmt" + "reflect" "strconv" "sync" "sync/atomic" "time" + "unicode" "github.com/ethereum/go-ethereum/beacon/engine" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/internal/version" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/node" "github.com/ethereum/go-ethereum/params" @@ -45,7 +47,6 @@ import ( // Register adds the engine API to the full node. func Register(stack *node.Node, backend *eth.Ethereum) error { - log.Warn("Engine API enabled", "protocol", "eth") stack.RegisterAPIs([]rpc.API{ { Namespace: "engine", @@ -80,55 +81,6 @@ const ( beaconUpdateWarnFrequency = 5 * time.Minute ) -// All methods provided over the engine endpoint. -var caps = []string{ - "engine_forkchoiceUpdatedV1", - "engine_forkchoiceUpdatedV2", - "engine_forkchoiceUpdatedV3", - "engine_forkchoiceUpdatedWithWitnessV1", - "engine_forkchoiceUpdatedWithWitnessV2", - "engine_forkchoiceUpdatedWithWitnessV3", - "engine_exchangeTransitionConfigurationV1", - "engine_getPayloadV1", - "engine_getPayloadV2", - "engine_getPayloadV3", - "engine_getPayloadV4", - "engine_getPayloadV5", - "engine_getBlobsV1", - "engine_getBlobsV2", - "engine_newPayloadV1", - "engine_newPayloadV2", - "engine_newPayloadV3", - "engine_newPayloadV4", - "engine_newPayloadWithWitnessV1", - "engine_newPayloadWithWitnessV2", - "engine_newPayloadWithWitnessV3", - "engine_newPayloadWithWitnessV4", - "engine_executeStatelessPayloadV1", - "engine_executeStatelessPayloadV2", - "engine_executeStatelessPayloadV3", - "engine_executeStatelessPayloadV4", - "engine_getPayloadBodiesByHashV1", - "engine_getPayloadBodiesByHashV2", - "engine_getPayloadBodiesByRangeV1", - "engine_getPayloadBodiesByRangeV2", - "engine_getClientVersionV1", -} - -var ( - // Number of blobs requested via getBlobsV2 - getBlobsRequestedCounter = metrics.NewRegisteredCounter("engine/getblobs/requested", nil) - - // Number of blobs requested via getBlobsV2 that are present in the blobpool - getBlobsAvailableCounter = metrics.NewRegisteredCounter("engine/getblobs/available", nil) - - // Number of times getBlobsV2 responded with “hit” - getBlobsV2RequestHit = metrics.NewRegisteredCounter("engine/getblobs/hit", nil) - - // Number of times getBlobsV2 responded with “miss” - getBlobsV2RequestMiss = metrics.NewRegisteredCounter("engine/getblobs/miss", nil) -) - type ConsensusAPI struct { eth *eth.Ethereum @@ -171,6 +123,9 @@ type ConsensusAPI struct { // NewConsensusAPI creates a new consensus api for the given backend. // The underlying blockchain needs to have a valid terminal total difficulty set. +// +// This function creates a long-lived object with an attached background thread. +// For testing or other short-term use cases, please use newConsensusAPIWithoutHeartbeat. func NewConsensusAPI(eth *eth.Ethereum) *ConsensusAPI { api := newConsensusAPIWithoutHeartbeat(eth) go api.heartbeat() @@ -197,9 +152,6 @@ func newConsensusAPIWithoutHeartbeat(eth *eth.Ethereum) *ConsensusAPI { // // We try to set our blockchain to the headBlock. // -// If the method is called with an empty head block: we return success, which can be used -// to check if the engine API is enabled. -// // If the total difficulty was not reached: we return INVALID. // // If the finalizedBlockHash is set: we check if we have the finalizedBlockHash in our db, @@ -246,8 +198,8 @@ func (api *ConsensusAPI) ForkchoiceUpdatedV3(update engine.ForkchoiceStateV1, pa return engine.STATUS_INVALID, attributesErr("missing withdrawals") case params.BeaconRoot == nil: return engine.STATUS_INVALID, attributesErr("missing beacon root") - case !api.checkFork(params.Timestamp, forks.Cancun, forks.Prague, forks.Osaka): - return engine.STATUS_INVALID, unsupportedForkErr("fcuV3 must only be called for cancun or prague payloads") + case !api.checkFork(params.Timestamp, forks.Cancun, forks.Prague, forks.Osaka, forks.BPO1, forks.BPO2, forks.BPO3, forks.BPO4, forks.BPO5): + return engine.STATUS_INVALID, unsupportedForkErr("fcuV3 must only be called for cancun/prague/osaka payloads") } } // TODO(matt): the spec requires that fcu is applied when called on a valid @@ -307,7 +259,7 @@ func (api *ConsensusAPI) forkchoiceUpdated(update engine.ForkchoiceStateV1, payl } } log.Info("Forkchoice requested sync to new head", context...) - if err := api.eth.Downloader().BeaconSync(api.eth.SyncMode(), header, finalized); err != nil { + if err := api.eth.Downloader().BeaconSync(header, finalized); err != nil { return engine.STATUS_SYNCING, err } return engine.STATUS_SYNCING, nil @@ -439,10 +391,12 @@ func (api *ConsensusAPI) ExchangeTransitionConfigurationV1(config engine.Transit // GetPayloadV1 returns a cached payload by id. func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.ExecutableData, error) { - if !payloadID.Is(engine.PayloadV1) { - return nil, engine.UnsupportedFork - } - data, err := api.getPayload(payloadID, false) + data, err := api.getPayload( + payloadID, + false, + []engine.PayloadVersion{engine.PayloadV1}, + nil, + ) if err != nil { return nil, err } @@ -451,47 +405,104 @@ func (api *ConsensusAPI) GetPayloadV1(payloadID engine.PayloadID) (*engine.Execu // GetPayloadV2 returns a cached payload by id. func (api *ConsensusAPI) GetPayloadV2(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) { - if !payloadID.Is(engine.PayloadV1, engine.PayloadV2) { - return nil, engine.UnsupportedFork - } - return api.getPayload(payloadID, false) + return api.getPayload( + payloadID, + false, + []engine.PayloadVersion{engine.PayloadV1, engine.PayloadV2}, + []forks.Fork{forks.Shanghai}, + ) } -// GetPayloadV3 returns a cached payload by id. +// GetPayloadV3 returns a cached payload by id. This endpoint should only +// be used for the Cancun fork. func (api *ConsensusAPI) GetPayloadV3(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) { - if !payloadID.Is(engine.PayloadV3) { - return nil, engine.UnsupportedFork - } - return api.getPayload(payloadID, false) + return api.getPayload( + payloadID, + false, + []engine.PayloadVersion{engine.PayloadV3}, + []forks.Fork{forks.Cancun}, + ) } -// GetPayloadV4 returns a cached payload by id. +// GetPayloadV4 returns a cached payload by id. This endpoint should only +// be used for the Prague fork. func (api *ConsensusAPI) GetPayloadV4(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) { - if !payloadID.Is(engine.PayloadV3) { - return nil, engine.UnsupportedFork - } - return api.getPayload(payloadID, false) + return api.getPayload( + payloadID, + false, + []engine.PayloadVersion{engine.PayloadV3}, + []forks.Fork{forks.Prague}, + ) } -// GetPayloadV5 returns a cached payload by id. +// GetPayloadV5 returns a cached payload by id. This endpoint should only +// be used after the Osaka fork. +// +// This method follows the same specification as engine_getPayloadV4 with +// changes of returning BlobsBundleV2 with BlobSidecar version 1. func (api *ConsensusAPI) GetPayloadV5(payloadID engine.PayloadID) (*engine.ExecutionPayloadEnvelope, error) { - if !payloadID.Is(engine.PayloadV3) { - return nil, engine.UnsupportedFork - } - return api.getPayload(payloadID, false) + return api.getPayload( + payloadID, + false, + []engine.PayloadVersion{engine.PayloadV3}, + []forks.Fork{ + forks.Osaka, + forks.BPO1, + forks.BPO2, + forks.BPO3, + forks.BPO4, + forks.BPO5, + }) } -func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool) (*engine.ExecutionPayloadEnvelope, error) { +// getPayload will retrieve the specified payload and verify it conforms to the +// endpoint's allowed payload versions and forks. +// +// Note passing nil `forks`, `versions` disables the respective check. +func (api *ConsensusAPI) getPayload(payloadID engine.PayloadID, full bool, versions []engine.PayloadVersion, forks []forks.Fork) (*engine.ExecutionPayloadEnvelope, error) { log.Trace("Engine API request received", "method", "GetPayload", "id", payloadID) + if versions != nil && !payloadID.Is(versions...) { + return nil, engine.UnsupportedFork + } data := api.localBlocks.get(payloadID, full) if data == nil { return nil, engine.UnknownPayload } + if forks != nil && !api.checkFork(data.ExecutionPayload.Timestamp, forks...) { + return nil, engine.UnsupportedFork + } + return data, nil } // GetBlobsV1 returns a blob from the transaction pool. +// +// Specification: +// +// Given an array of blob versioned hashes client software MUST respond with an +// array of BlobAndProofV1 objects with matching versioned hashes, respecting the +// order of versioned hashes in the input array. +// +// Client software MUST place responses in the order given in the request, using +// null for any missing blobs. For instance: +// +// if the request is [A_versioned_hash, B_versioned_hash, C_versioned_hash] and +// client software has data for blobs A and C, but doesn't have data for B, the +// response MUST be [A, null, C]. +// +// Client software MUST support request sizes of at least 128 blob versioned hashes. +// The client MUST return -38004: Too large request error if the number of requested +// blobs is too large. +// +// Client software MAY return an array of all null entries if syncing or otherwise +// unable to serve blob pool data. func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProofV1, error) { + // Reject the request if Osaka has been activated. + // follow https://github.com/ethereum/execution-apis/blob/main/src/engine/osaka.md#cancun-api + head := api.eth.BlockChain().CurrentHeader() + if !api.checkFork(head.Time, forks.Cancun, forks.Prague) { + return nil, unsupportedForkErr("engine_getBlobsV1 is only available at Cancun/Prague fork") + } if len(hashes) > 128 { return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes))) } @@ -501,6 +512,10 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo } res := make([]*engine.BlobAndProofV1, len(hashes)) for i := 0; i < len(blobs); i++ { + // Skip the non-existing blob + if blobs[i] == nil { + continue + } res[i] = &engine.BlobAndProofV1{ Blob: blobs[i][:], Proof: proofs[i][0][:], @@ -510,7 +525,52 @@ func (api *ConsensusAPI) GetBlobsV1(hashes []common.Hash) ([]*engine.BlobAndProo } // GetBlobsV2 returns a blob from the transaction pool. +// +// Specification: +// Refer to the specification for engine_getBlobsV1 with changes of the following: +// +// Given an array of blob versioned hashes client software MUST respond with an +// array of BlobAndProofV2 objects with matching versioned hashes, respecting +// the order of versioned hashes in the input array. +// +// Client software MUST return null in case of any missing or older version blobs. +// For instance, +// +// - if the request is [A_versioned_hash, B_versioned_hash, C_versioned_hash] and +// client software has data for blobs A and C, but doesn't have data for B, the +// response MUST be null. +// +// - if the request is [A_versioned_hash_for_blob_with_blob_proof], the response +// MUST be null as well. +// +// Client software MUST support request sizes of at least 128 blob versioned +// hashes. The client MUST return -38004: Too large request error if the number +// of requested blobs is too large. +// +// Client software MUST return null if syncing or otherwise unable to serve +// blob pool data. func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProofV2, error) { + head := api.eth.BlockChain().CurrentHeader() + if api.config().LatestFork(head.Time) < forks.Osaka { + return nil, nil + } + return api.getBlobs(hashes, true) +} + +// GetBlobsV3 returns a set of blobs from the transaction pool. Same as +// GetBlobsV2, except will return partial responses in case there is a missing +// blob. +func (api *ConsensusAPI) GetBlobsV3(hashes []common.Hash) ([]*engine.BlobAndProofV2, error) { + head := api.eth.BlockChain().CurrentHeader() + if api.config().LatestFork(head.Time) < forks.Osaka { + return nil, nil + } + return api.getBlobs(hashes, false) +} + +// getBlobs returns all available blobs. In v2, partial responses are not allowed, +// while v3 supports partial responses. +func (api *ConsensusAPI) getBlobs(hashes []common.Hash, v2 bool) ([]*engine.BlobAndProofV2, error) { if len(hashes) > 128 { return nil, engine.TooLargeRequest.With(fmt.Errorf("requested blob count too large: %v", len(hashes))) } @@ -518,19 +578,30 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo getBlobsRequestedCounter.Inc(int64(len(hashes))) getBlobsAvailableCounter.Inc(int64(available)) - // Optimization: check first if all blobs are available, if not, return empty response - if available != len(hashes) { - getBlobsV2RequestMiss.Inc(1) + // Short circuit if partial response is not allowed + if v2 && available != len(hashes) { + getBlobsRequestMiss.Inc(1) return nil, nil } - getBlobsV2RequestHit.Inc(1) - + // Retrieve blobs from the pool. This operation is expensive and may involve + // heavy disk I/O. blobs, _, proofs, err := api.eth.BlobTxPool().GetBlobs(hashes, types.BlobSidecarVersion1) if err != nil { return nil, engine.InvalidParams.With(err) } + // Validate the blobs from the pool and assemble the response res := make([]*engine.BlobAndProofV2, len(hashes)) - for i := 0; i < len(blobs); i++ { + for i := range blobs { + // The blob has been evicted since the last AvailableBlobs call. + // Return null if partial response is not allowed. + if blobs[i] == nil { + if !v2 { + continue + } else { + getBlobsRequestMiss.Inc(1) + return nil, nil + } + } var cellProofs []hexutil.Bytes for _, proof := range proofs[i] { cellProofs = append(cellProofs, proof[:]) @@ -540,6 +611,13 @@ func (api *ConsensusAPI) GetBlobsV2(hashes []common.Hash) ([]*engine.BlobAndProo CellProofs: cellProofs, } } + if len(res) == len(hashes) { + getBlobsRequestCompleteHit.Inc(1) + } else if len(res) > 0 { + getBlobsRequestPartialHit.Inc(1) + } else { + getBlobsRequestMiss.Inc(1) + } return res, nil } @@ -609,8 +687,8 @@ func (api *ConsensusAPI) NewPayloadV4(params engine.ExecutableData, versionedHas return invalidStatus, paramsErr("nil beaconRoot post-cancun") case executionRequests == nil: return invalidStatus, paramsErr("nil executionRequests post-prague") - case !api.checkFork(params.Timestamp, forks.Prague, forks.Osaka): - return invalidStatus, unsupportedForkErr("newPayloadV4 must only be called for prague payloads") + case !api.checkFork(params.Timestamp, forks.Prague, forks.Osaka, forks.BPO1, forks.BPO2, forks.BPO3, forks.BPO4, forks.BPO5): + return invalidStatus, unsupportedForkErr("newPayloadV4 must only be called for prague/osaka payloads") } requests := convertRequests(executionRequests) if err := validateRequests(requests); err != nil { @@ -694,14 +772,14 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe return api.delayPayloadImport(block), nil } if block.Time() <= parent.Time() { - log.Warn("Invalid timestamp", "parent", block.Time(), "block", block.Time()) + log.Warn("Invalid timestamp", "parent", parent.Time(), "block", block.Time()) return api.invalid(errors.New("invalid timestamp"), parent.Header()), nil } // Another corner case: if the node is in snap sync mode, but the CL client // tries to make it import a block. That should be denied as pushing something // into the database directly will conflict with the assumptions of snap sync // that it has an empty db that it can fill itself. - if api.eth.SyncMode() != ethconfig.FullSync { + if api.eth.Downloader().ConfigSyncMode() == ethconfig.SnapSync { return api.delayPayloadImport(block), nil } if !api.eth.BlockChain().HasBlockAndState(block.ParentHash(), block.NumberU64()-1) { @@ -710,7 +788,9 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe return engine.PayloadStatusV1{Status: engine.ACCEPTED}, nil } log.Trace("Inserting block without sethead", "hash", block.Hash(), "number", block.Number()) + start := time.Now() proofs, err := api.eth.BlockChain().InsertBlockWithoutSetHead(block, witness) + processingTime := time.Since(start) if err != nil { log.Warn("NewPayload: inserting block failed", "error", err) @@ -723,6 +803,13 @@ func (api *ConsensusAPI) newPayload(params engine.ExecutableData, versionedHashe } hash := block.Hash() + // Emit NewPayloadEvent for ethstats reporting + api.eth.BlockChain().SendNewPayloadEvent(core.NewPayloadEvent{ + Hash: hash, + Number: block.NumberU64(), + ProcessingTime: processingTime, + }) + // If witness collection was requested, inject that into the result too var ow *hexutil.Bytes if proofs != nil { @@ -749,16 +836,16 @@ func (api *ConsensusAPI) delayPayloadImport(block *types.Block) engine.PayloadSt // Although we don't want to trigger a sync, if there is one already in // progress, try to extend it with the current payload request to relieve // some strain from the forkchoice update. - err := api.eth.Downloader().BeaconExtend(api.eth.SyncMode(), block.Header()) + err := api.eth.Downloader().BeaconExtend(block.Header()) if err == nil { log.Debug("Payload accepted for sync extension", "number", block.NumberU64(), "hash", block.Hash()) return engine.PayloadStatusV1{Status: engine.SYNCING} } // Either no beacon sync was started yet, or it rejected the delivered - // payload as non-integratable on top of the existing sync. We'll just + // payload as non-integrate on top of the existing sync. We'll just // have to rely on the beacon client to forcefully update the head with // a forkchoice update request. - if api.eth.SyncMode() == ethconfig.FullSync { + if api.eth.Downloader().ConfigSyncMode() == ethconfig.FullSync { // In full sync mode, failure to import a well-formed block can only mean // that the parent state is missing and the syncer rejected extending the // current cycle with the new payload. @@ -853,8 +940,6 @@ func (api *ConsensusAPI) invalid(err error, latestValid *types.Header) engine.Pa // heartbeat loops indefinitely, and checks if there have been beacon client updates // received in the last while. If not - or if they but strange ones - it warns the // user that something might be off with their consensus node. -// -// TODO(karalabe): Spin this goroutine down somehow func (api *ConsensusAPI) heartbeat() { // Sleep a bit on startup since there's obviously no beacon client yet // attached, so no need to print scary warnings to the user. @@ -916,6 +1001,15 @@ func (api *ConsensusAPI) checkFork(timestamp uint64, forks ...forks.Fork) bool { // ExchangeCapabilities returns the current methods provided by this node. func (api *ConsensusAPI) ExchangeCapabilities([]string) []string { + valueT := reflect.TypeOf(api) + caps := make([]string, 0, valueT.NumMethod()) + for i := 0; i < valueT.NumMethod(); i++ { + name := []rune(valueT.Method(i).Name) + if string(name) == "ExchangeCapabilities" { + continue + } + caps = append(caps, "engine_"+string(unicode.ToLower(name[0]))+string(name[1:])) + } return caps } diff --git a/eth/catalyst/api_test.go b/eth/catalyst/api_test.go index ad377113b5..4d7246d4ed 100644 --- a/eth/catalyst/api_test.go +++ b/eth/catalyst/api_test.go @@ -19,7 +19,9 @@ package catalyst import ( "bytes" "context" + "crypto/ecdsa" crand "crypto/rand" + "crypto/sha256" "errors" "fmt" "math/big" @@ -40,6 +42,7 @@ import ( "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/internal/testrand" "github.com/ethereum/go-ethereum/internal/version" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/node" @@ -47,6 +50,7 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/trie" + "github.com/holiman/uint256" ) var ( @@ -112,7 +116,7 @@ func TestEth2AssembleBlock(t *testing.T) { n, ethservice := startEthService(t, genesis, blocks) defer n.Close() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) signer := types.NewEIP155Signer(ethservice.BlockChain().Config().ChainID) tx, err := types.SignTx(types.NewTransaction(uint64(10), blocks[9].Coinbase(), big.NewInt(1000), params.TxGas, big.NewInt(params.InitialBaseFee), nil), signer, testKey) if err != nil { @@ -151,7 +155,7 @@ func TestEth2AssembleBlockWithAnotherBlocksTxs(t *testing.T) { n, ethservice := startEthService(t, genesis, blocks[:9]) defer n.Close() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) // Put the 10th block's tx in the pool and produce a new block txs := blocks[9].Transactions() @@ -173,7 +177,7 @@ func TestEth2PrepareAndGetPayload(t *testing.T) { n, ethservice := startEthService(t, genesis, blocks[:9]) defer n.Close() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) // Put the 10th block's tx in the pool and produce a new block txs := blocks[9].Transactions() @@ -199,7 +203,7 @@ func TestEth2PrepareAndGetPayload(t *testing.T) { BeaconRoot: blockParams.BeaconRoot, Version: engine.PayloadV1, }).Id() - execData, err := api.getPayload(payloadID, true) + execData, err := api.getPayload(payloadID, true, nil, nil) if err != nil { t.Fatalf("error getting payload, err=%v", err) } @@ -238,8 +242,9 @@ func TestInvalidPayloadTimestamp(t *testing.T) { genesis, preMergeBlocks := generateMergeChain(10, false) n, ethservice := startEthService(t, genesis, preMergeBlocks) defer n.Close() + var ( - api = NewConsensusAPI(ethservice) + api = newConsensusAPIWithoutHeartbeat(ethservice) parent = ethservice.BlockChain().CurrentBlock() ) tests := []struct { @@ -281,7 +286,7 @@ func TestEth2NewBlock(t *testing.T) { defer n.Close() var ( - api = NewConsensusAPI(ethservice) + api = newConsensusAPIWithoutHeartbeat(ethservice) parent = preMergeBlocks[len(preMergeBlocks)-1] // This EVM code generates a log when the contract is created. @@ -421,7 +426,7 @@ func TestEth2DeepReorg(t *testing.T) { } // startEthService creates a full node instance for testing. -func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block) (*node.Node, *eth.Ethereum) { +func startEthService(t testing.TB, genesis *core.Genesis, blocks []*types.Block) (*node.Node, *eth.Ethereum) { t.Helper() n, err := node.New(&node.Config{ @@ -434,8 +439,14 @@ func startEthService(t *testing.T, genesis *core.Genesis, blocks []*types.Block) t.Fatal("can't create node:", err) } - mcfg := miner.DefaultConfig - ethcfg := ðconfig.Config{Genesis: genesis, SyncMode: ethconfig.FullSync, TrieTimeout: time.Minute, TrieDirtyCache: 256, TrieCleanCache: 256, Miner: mcfg} + ethcfg := ðconfig.Config{ + Genesis: genesis, + SyncMode: ethconfig.FullSync, + TrieTimeout: time.Minute, + TrieDirtyCache: 256, + TrieCleanCache: 256, + Miner: miner.DefaultConfig, + } ethservice, err := eth.New(n, ethcfg) if err != nil { t.Fatal("can't create eth service:", err) @@ -459,6 +470,7 @@ func TestFullAPI(t *testing.T) { genesis, preMergeBlocks := generateMergeChain(10, false) n, ethservice := startEthService(t, genesis, preMergeBlocks) defer n.Close() + var ( parent = ethservice.BlockChain().CurrentBlock() // This EVM code generates a log when the contract is created. @@ -476,7 +488,7 @@ func TestFullAPI(t *testing.T) { } func setupBlocks(t *testing.T, ethservice *eth.Ethereum, n int, parent *types.Header, callback func(parent *types.Header), withdrawals [][]*types.Withdrawal, beaconRoots []common.Hash) []*types.Header { - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) var blocks []*types.Header for i := 0; i < n; i++ { callback(parent) @@ -524,7 +536,7 @@ func TestExchangeTransitionConfig(t *testing.T) { defer n.Close() // invalid ttd - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) config := engine.TransitionConfigurationV1{ TerminalTotalDifficulty: (*hexutil.Big)(big.NewInt(0)), TerminalBlockHash: common.Hash{}, @@ -585,7 +597,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) { defer n.Close() var ( - api = NewConsensusAPI(ethservice) + api = newConsensusAPIWithoutHeartbeat(ethservice) parent = ethservice.BlockChain().CurrentBlock() signer = types.LatestSigner(ethservice.BlockChain().Config()) // This EVM code generates a log when the contract is created. @@ -624,7 +636,7 @@ func TestNewPayloadOnInvalidChain(t *testing.T) { t.Fatalf("error preparing payload, invalid status: %v", resp.PayloadStatus.Status) } // give the payload some time to be built - if payload, err = api.getPayload(*resp.PayloadID, true); err != nil { + if payload, err = api.getPayload(*resp.PayloadID, true, nil, nil); err != nil { t.Fatalf("can't get payload: %v", err) } if len(payload.ExecutionPayload.Transactions) > 0 { @@ -688,7 +700,7 @@ func TestEmptyBlocks(t *testing.T) { defer n.Close() commonAncestor := ethservice.BlockChain().CurrentBlock() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) // Setup 10 blocks on the canonical chain setupBlocks(t, ethservice, 10, commonAncestor, func(parent *types.Header) {}, nil, nil) @@ -814,8 +826,8 @@ func TestTrickRemoteBlockCache(t *testing.T) { } nodeA.Server().AddPeer(nodeB.Server().Self()) nodeB.Server().AddPeer(nodeA.Server().Self()) - apiA := NewConsensusAPI(ethserviceA) - apiB := NewConsensusAPI(ethserviceB) + apiA := newConsensusAPIWithoutHeartbeat(ethserviceA) + apiB := newConsensusAPIWithoutHeartbeat(ethserviceB) commonAncestor := ethserviceA.BlockChain().CurrentBlock() @@ -872,7 +884,7 @@ func TestInvalidBloom(t *testing.T) { defer n.Close() commonAncestor := ethservice.BlockChain().CurrentBlock() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) // Setup 10 blocks on the canonical chain setupBlocks(t, ethservice, 10, commonAncestor, func(parent *types.Header) {}, nil, nil) @@ -898,7 +910,7 @@ func TestSimultaneousNewBlock(t *testing.T) { defer n.Close() var ( - api = NewConsensusAPI(ethservice) + api = newConsensusAPIWithoutHeartbeat(ethservice) parent = preMergeBlocks[len(preMergeBlocks)-1] ) for i := 0; i < 10; i++ { @@ -988,7 +1000,7 @@ func TestWithdrawals(t *testing.T) { n, ethservice := startEthService(t, genesis, blocks) defer n.Close() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) // 10: Build Shanghai block with no withdrawals. parent := ethservice.BlockChain().CurrentHeader() @@ -1105,7 +1117,7 @@ func TestNilWithdrawals(t *testing.T) { n, ethservice := startEthService(t, genesis, blocks) defer n.Close() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) parent := ethservice.BlockChain().CurrentHeader() aa := common.Address{0xaa} @@ -1207,7 +1219,7 @@ func TestNilWithdrawals(t *testing.T) { Random: test.blockParams.Random, Version: payloadVersion, }).Id() - execData, err := api.GetPayloadV2(payloadID) + execData, err := api.getPayload(payloadID, false, nil, nil) if err != nil { t.Fatalf("error getting payload, err=%v", err) } @@ -1301,7 +1313,7 @@ func allBodies(blocks []*types.Block) []*types.Body { func TestGetBlockBodiesByHash(t *testing.T) { node, eth, blocks := setupBodies(t) - api := NewConsensusAPI(eth) + api := newConsensusAPIWithoutHeartbeat(eth) defer node.Close() tests := []struct { @@ -1357,7 +1369,7 @@ func TestGetBlockBodiesByHash(t *testing.T) { func TestGetBlockBodiesByRange(t *testing.T) { node, eth, blocks := setupBodies(t) - api := NewConsensusAPI(eth) + api := newConsensusAPIWithoutHeartbeat(eth) defer node.Close() tests := []struct { @@ -1438,7 +1450,7 @@ func TestGetBlockBodiesByRange(t *testing.T) { func TestGetBlockBodiesByRangeInvalidParams(t *testing.T) { node, eth, _ := setupBodies(t) - api := NewConsensusAPI(eth) + api := newConsensusAPIWithoutHeartbeat(eth) defer node.Close() tests := []struct { start hexutil.Uint64 @@ -1550,7 +1562,7 @@ func TestParentBeaconBlockRoot(t *testing.T) { n, ethservice := startEthService(t, genesis, blocks) defer n.Close() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) // 11: Build Shanghai block with no withdrawals. parent := ethservice.BlockChain().CurrentHeader() @@ -1633,7 +1645,7 @@ func TestWitnessCreationAndConsumption(t *testing.T) { n, ethservice := startEthService(t, genesis, blocks[:9]) defer n.Close() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) // Put the 10th block's tx in the pool and produce a new block txs := blocks[9].Transactions() @@ -1662,7 +1674,7 @@ func TestWitnessCreationAndConsumption(t *testing.T) { BeaconRoot: blockParams.BeaconRoot, Version: engine.PayloadV3, }).Id() - envelope, err := api.getPayload(payloadID, true) + envelope, err := api.getPayload(payloadID, true, nil, nil) if err != nil { t.Fatalf("error getting payload, err=%v", err) } @@ -1725,7 +1737,7 @@ func TestGetClientVersion(t *testing.T) { n, ethservice := startEthService(t, genesis, preMergeBlocks) defer n.Close() - api := NewConsensusAPI(ethservice) + api := newConsensusAPIWithoutHeartbeat(ethservice) info := engine.ClientVersionV1{ Code: "TT", Name: "test", @@ -1799,3 +1811,298 @@ func TestValidateRequests(t *testing.T) { }) } } + +var ( + testBlobs []*kzg4844.Blob + testBlobCommits []kzg4844.Commitment + testBlobProofs []kzg4844.Proof + testBlobCellProofs [][]kzg4844.Proof + testBlobVHashes [][32]byte +) + +func init() { + for i := 0; i < 6; i++ { + testBlob := &kzg4844.Blob{byte(i)} + testBlobs = append(testBlobs, testBlob) + + testBlobCommit, _ := kzg4844.BlobToCommitment(testBlob) + testBlobCommits = append(testBlobCommits, testBlobCommit) + + testBlobProof, _ := kzg4844.ComputeBlobProof(testBlob, testBlobCommit) + testBlobProofs = append(testBlobProofs, testBlobProof) + + testBlobCellProof, _ := kzg4844.ComputeCellProofs(testBlob) + testBlobCellProofs = append(testBlobCellProofs, testBlobCellProof) + + testBlobVHash := kzg4844.CalcBlobHashV1(sha256.New(), &testBlobCommit) + testBlobVHashes = append(testBlobVHashes, testBlobVHash) + } +} + +// makeMultiBlobTx is a utility method to construct a random blob tx with +// certain number of blobs in its sidecar. +func makeMultiBlobTx(chainConfig *params.ChainConfig, nonce uint64, blobCount int, blobOffset int, key *ecdsa.PrivateKey, version byte) *types.Transaction { + var ( + blobs []kzg4844.Blob + blobHashes []common.Hash + commitments []kzg4844.Commitment + proofs []kzg4844.Proof + ) + for i := 0; i < blobCount; i++ { + blobs = append(blobs, *testBlobs[blobOffset+i]) + commitments = append(commitments, testBlobCommits[blobOffset+i]) + if version == types.BlobSidecarVersion0 { + proofs = append(proofs, testBlobProofs[blobOffset+i]) + } else { + cellProofs, _ := kzg4844.ComputeCellProofs(testBlobs[blobOffset+i]) + proofs = append(proofs, cellProofs...) + } + blobHashes = append(blobHashes, testBlobVHashes[blobOffset+i]) + } + blobtx := &types.BlobTx{ + ChainID: uint256.MustFromBig(chainConfig.ChainID), + Nonce: nonce, + GasTipCap: uint256.NewInt(1), + GasFeeCap: uint256.NewInt(1000), + Gas: 21000, + BlobFeeCap: uint256.NewInt(1000), + BlobHashes: blobHashes, + Value: uint256.NewInt(100), + Sidecar: types.NewBlobTxSidecar(version, blobs, commitments, proofs), + } + return types.MustSignNewTx(key, types.LatestSigner(chainConfig), blobtx) +} + +func newGetBlobEnv(t testing.TB, version byte) (*node.Node, *ConsensusAPI) { + var ( + // Create a database pre-initialize with a genesis block + config = *params.MergedTestChainConfig + + key1, _ = crypto.GenerateKey() + key2, _ = crypto.GenerateKey() + key3, _ = crypto.GenerateKey() + + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + addr2 = crypto.PubkeyToAddress(key2.PublicKey) + addr3 = crypto.PubkeyToAddress(key3.PublicKey) + ) + // Disable Osaka fork for GetBlobsV1 + if version == 0 { + config.OsakaTime = nil + } + gspec := &core.Genesis{ + Config: &config, + Alloc: types.GenesisAlloc{ + testAddr: {Balance: testBalance}, + addr1: {Balance: testBalance}, + addr2: {Balance: testBalance}, + addr3: {Balance: testBalance}, + }, + Difficulty: common.Big0, + } + n, ethServ := startEthService(t, gspec, nil) + + // fill blob txs into the pool + tx1 := makeMultiBlobTx(&config, 0, 2, 0, key1, version) // blob[0, 2) + tx2 := makeMultiBlobTx(&config, 0, 2, 2, key2, version) // blob[2, 4) + tx3 := makeMultiBlobTx(&config, 0, 2, 4, key3, version) // blob[4, 6) + ethServ.TxPool().Add([]*types.Transaction{tx1, tx2, tx3}, true) + + api := newConsensusAPIWithoutHeartbeat(ethServ) + return n, api +} + +func TestGetBlobsV1(t *testing.T) { + n, api := newGetBlobEnv(t, 0) + defer n.Close() + + suites := []struct { + start int + limit int + fillRandom bool + }{ + { + start: 0, limit: 1, + }, + { + start: 0, limit: 1, fillRandom: true, + }, + { + start: 0, limit: 2, + }, + { + start: 0, limit: 2, fillRandom: true, + }, + { + start: 1, limit: 3, + }, + { + start: 1, limit: 3, fillRandom: true, + }, + { + start: 0, limit: 6, + }, + { + start: 0, limit: 6, fillRandom: true, + }, + { + start: 1, limit: 5, + }, + { + start: 1, limit: 5, fillRandom: true, + }, + } + for i, suite := range suites { + // Fill the request for retrieving blobs + var ( + vhashes []common.Hash + expect []*engine.BlobAndProofV1 + ) + // fill missing blob at the beginning + if suite.fillRandom { + vhashes = append(vhashes, testrand.Hash()) + expect = append(expect, nil) + } + for j := suite.start; j < suite.limit; j++ { + vhashes = append(vhashes, testBlobVHashes[j]) + expect = append(expect, &engine.BlobAndProofV1{ + Blob: testBlobs[j][:], + Proof: testBlobProofs[j][:], + }) + + // fill missing blobs in the middle + if suite.fillRandom && rand.Intn(2) == 0 { + vhashes = append(vhashes, testrand.Hash()) + expect = append(expect, nil) + } + } + // fill missing blobs at the end + if suite.fillRandom { + vhashes = append(vhashes, testrand.Hash()) + expect = append(expect, nil) + } + result, err := api.GetBlobsV1(vhashes) + if err != nil { + t.Errorf("Unexpected error for case %d, %v", i, err) + } + if !reflect.DeepEqual(result, expect) { + t.Fatalf("Unexpected result for case %d", i) + } + } +} + +func TestGetBlobsV1AfterOsakaFork(t *testing.T) { + genesis := &core.Genesis{ + Config: params.MergedTestChainConfig, + Alloc: types.GenesisAlloc{testAddr: {Balance: testBalance}}, + Difficulty: common.Big0, + Timestamp: 1, // Timestamp > 0 to ensure Osaka fork is active + } + n, ethServ := startEthService(t, genesis, nil) + defer n.Close() + + var engineErr *engine.EngineAPIError + api := newConsensusAPIWithoutHeartbeat(ethServ) + _, err := api.GetBlobsV1([]common.Hash{testrand.Hash()}) + if !errors.As(err, &engineErr) { + t.Fatalf("Unexpected error: %T", err) + } else { + if engineErr.ErrorCode() != -38005 { + t.Fatalf("Expected error code -38005, got %d", engineErr.ErrorCode()) + } + if engineErr.Error() != "Unsupported fork" { + t.Fatalf("Expected error message 'Unsupported fork', got '%s'", engineErr.Error()) + } + } +} + +func TestGetBlobsV2And3(t *testing.T) { + n, api := newGetBlobEnv(t, 1) + defer n.Close() + + suites := []struct { + start int + limit int + fillRandom bool + }{ + { + start: 0, limit: 1, + }, + { + start: 0, limit: 2, + }, + { + start: 1, limit: 3, + }, + { + start: 0, limit: 6, + }, + { + start: 1, limit: 5, + }, + { + start: 0, limit: 6, fillRandom: true, + }, + } + for i, suite := range suites { + runGetBlobs(t, api.GetBlobsV2, suite.start, suite.limit, suite.fillRandom, false, fmt.Sprintf("GetBlobsV2 suite=%d", i)) + runGetBlobs(t, api.GetBlobsV3, suite.start, suite.limit, suite.fillRandom, true, fmt.Sprintf("GetBlobsV3 suite=%d %v", i, suite)) + } +} + +// Benchmark GetBlobsV2 internals +// Note that this is not an RPC-level benchmark, so JSON-RPC overhead is not included. +func BenchmarkGetBlobsV2(b *testing.B) { + n, api := newGetBlobEnv(b, 1) + defer n.Close() + + // for blobs in [1, 2, 4, 6], print string and run benchmark + for _, blobs := range []int{1, 2, 4, 6} { + name := fmt.Sprintf("blobs=%d", blobs) + b.Run(name, func(b *testing.B) { + for b.Loop() { + runGetBlobs(b, api.GetBlobsV2, 0, blobs, false, false, name) + } + }) + } +} + +type getBlobsFn func(hashes []common.Hash) ([]*engine.BlobAndProofV2, error) + +func runGetBlobs(t testing.TB, getBlobs getBlobsFn, start, limit int, fillRandom bool, expectPartialResponse bool, name string) { + // Fill the request for retrieving blobs + var ( + vhashes []common.Hash + expect []*engine.BlobAndProofV2 + ) + for j := start; j < limit; j++ { + vhashes = append(vhashes, testBlobVHashes[j]) + var cellProofs []hexutil.Bytes + for _, proof := range testBlobCellProofs[j] { + cellProofs = append(cellProofs, proof[:]) + } + expect = append(expect, &engine.BlobAndProofV2{ + Blob: testBlobs[j][:], + CellProofs: cellProofs, + }) + } + // fill missing blob + if fillRandom { + vhashes = append(vhashes, testrand.Hash()) + } + result, err := getBlobs(vhashes) + if err != nil { + t.Errorf("Unexpected error for case %s, %v", name, err) + } + if fillRandom { + if expectPartialResponse { + expect = append(expect, nil) + } else { + // Nil is expected if getBlobs can not return a partial response + expect = nil + } + } + if !reflect.DeepEqual(result, expect) { + t.Fatalf("Unexpected result for case %s", name) + } +} diff --git a/eth/catalyst/metrics.go b/eth/catalyst/metrics.go new file mode 100644 index 0000000000..01a24191b0 --- /dev/null +++ b/eth/catalyst/metrics.go @@ -0,0 +1,37 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package catalyst + +import "github.com/ethereum/go-ethereum/metrics" + +var ( + // Number of blobs requested via getBlobsV2 + getBlobsRequestedCounter = metrics.NewRegisteredCounter("engine/getblobs/requested", nil) + + // Number of blobs requested via getBlobsV2 that are present in the blobpool + getBlobsAvailableCounter = metrics.NewRegisteredCounter("engine/getblobs/available", nil) + + // Number of times getBlobsV2/V3 responded with all blobs + getBlobsRequestCompleteHit = metrics.NewRegisteredCounter("engine/getblobs/hit", nil) + + // Number of times getBlobsV2/V3 responded with no blobs. V2 will return no + // blobs if it doesn't have all the blobs (all or nothing). + getBlobsRequestMiss = metrics.NewRegisteredCounter("engine/getblobs/miss", nil) + + // Number of times getBlobsV3 responded with some, but not all, blobs + getBlobsRequestPartialHit = metrics.NewRegisteredCounter("engine/getblobs/partial", nil) +) diff --git a/eth/catalyst/simulated_beacon.go b/eth/catalyst/simulated_beacon.go index 0642d6a1ad..92f9798e71 100644 --- a/eth/catalyst/simulated_beacon.go +++ b/eth/catalyst/simulated_beacon.go @@ -100,7 +100,7 @@ type SimulatedBeacon struct { func payloadVersion(config *params.ChainConfig, time uint64) engine.PayloadVersion { switch config.LatestFork(time) { - case forks.Prague, forks.Cancun: + case forks.BPO5, forks.BPO4, forks.BPO3, forks.BPO2, forks.BPO1, forks.Osaka, forks.Prague, forks.Cancun: return engine.PayloadV3 case forks.Paris, forks.Shanghai: return engine.PayloadV2 @@ -214,7 +214,7 @@ func (c *SimulatedBeacon) sealBlock(withdrawals []*types.Withdrawal, timestamp u return nil } - envelope, err := c.engineAPI.getPayload(*fcResponse.PayloadID, true) + envelope, err := c.engineAPI.getPayload(*fcResponse.PayloadID, true, nil, nil) if err != nil { return err } @@ -280,9 +280,8 @@ func (c *SimulatedBeacon) loop() { case <-timer.C: if err := c.sealBlock(c.withdrawals.pop(10), uint64(time.Now().Unix())); err != nil { log.Warn("Error performing sealing work", "err", err) - } else { - timer.Reset(time.Second * time.Duration(c.period)) } + timer.Reset(time.Second * time.Duration(c.period)) } } } diff --git a/eth/catalyst/witness.go b/eth/catalyst/witness.go index 703f1b0881..0df612a695 100644 --- a/eth/catalyst/witness.go +++ b/eth/catalyst/witness.go @@ -73,8 +73,8 @@ func (api *ConsensusAPI) ForkchoiceUpdatedWithWitnessV3(update engine.Forkchoice return engine.STATUS_INVALID, attributesErr("missing withdrawals") case params.BeaconRoot == nil: return engine.STATUS_INVALID, attributesErr("missing beacon root") - case !api.checkFork(params.Timestamp, forks.Cancun, forks.Prague): - return engine.STATUS_INVALID, unsupportedForkErr("fcuV3 must only be called for cancun or prague payloads") + case !api.checkFork(params.Timestamp, forks.Cancun, forks.Prague, forks.Osaka, forks.BPO1, forks.BPO2, forks.BPO3, forks.BPO4, forks.BPO5): + return engine.STATUS_INVALID, unsupportedForkErr("fcuV3 must only be called for cancun/prague/osaka payloads") } } // TODO(matt): the spec requires that fcu is applied when called on a valid @@ -151,8 +151,8 @@ func (api *ConsensusAPI) NewPayloadWithWitnessV4(params engine.ExecutableData, v return invalidStatus, paramsErr("nil beaconRoot post-cancun") case executionRequests == nil: return invalidStatus, paramsErr("nil executionRequests post-prague") - case !api.checkFork(params.Timestamp, forks.Prague): - return invalidStatus, unsupportedForkErr("newPayloadV4 must only be called for prague payloads") + case !api.checkFork(params.Timestamp, forks.Prague, forks.Osaka, forks.BPO1, forks.BPO2, forks.BPO3, forks.BPO4, forks.BPO5): + return invalidStatus, unsupportedForkErr("newPayloadV4 must only be called for prague/osaka payloads") } requests := convertRequests(executionRequests) if err := validateRequests(requests); err != nil { @@ -228,8 +228,8 @@ func (api *ConsensusAPI) ExecuteStatelessPayloadV4(params engine.ExecutableData, return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil beaconRoot post-cancun") case executionRequests == nil: return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, paramsErr("nil executionRequests post-prague") - case !api.checkFork(params.Timestamp, forks.Prague, forks.Osaka): - return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, unsupportedForkErr("newPayloadV4 must only be called for prague payloads") + case !api.checkFork(params.Timestamp, forks.Prague, forks.Osaka, forks.BPO1, forks.BPO2, forks.BPO3, forks.BPO4, forks.BPO5): + return engine.StatelessPayloadStatusV1{Status: engine.INVALID}, unsupportedForkErr("newPayloadV4 must only be called for prague/osaka payloads") } requests := convertRequests(executionRequests) if err := validateRequests(requests); err != nil { diff --git a/eth/downloader/beacondevsync.go b/eth/downloader/beacondevsync.go index 7b30684133..52e43f86b4 100644 --- a/eth/downloader/beacondevsync.go +++ b/eth/downloader/beacondevsync.go @@ -33,14 +33,14 @@ import ( // Note, this must not be used in live code. If the forkchcoice endpoint where // to use this instead of giving us the payload first, then essentially nobody // in the network would have the block yet that we'd attempt to retrieve. -func (d *Downloader) BeaconDevSync(mode SyncMode, header *types.Header) error { +func (d *Downloader) BeaconDevSync(header *types.Header) error { // Be very loud that this code should not be used in a live node log.Warn("----------------------------------") log.Warn("Beacon syncing with hash as target", "number", header.Number, "hash", header.Hash()) log.Warn("This is unhealthy for a live node!") log.Warn("This is incompatible with the consensus layer!") log.Warn("----------------------------------") - return d.BeaconSync(mode, header, header) + return d.BeaconSync(header, header) } // GetHeader tries to retrieve the header with a given hash from a random peer. @@ -52,7 +52,8 @@ func (d *Downloader) GetHeader(hash common.Hash) (*types.Header, error) { for _, peer := range d.peers.peers { if peer == nil { - return nil, errors.New("could not find peer") + log.Warn("Encountered nil peer while retrieving sync target", "hash", hash) + continue } // Found a peer, attempt to retrieve the header whilst blocking and // retry if it fails for whatever reason diff --git a/eth/downloader/beaconsync.go b/eth/downloader/beaconsync.go index 12b74a1ba9..914e1dfada 100644 --- a/eth/downloader/beaconsync.go +++ b/eth/downloader/beaconsync.go @@ -34,10 +34,8 @@ import ( // directed by the skeleton sync's head/tail events. type beaconBackfiller struct { downloader *Downloader // Downloader to direct via this callback implementation - syncMode SyncMode // Sync mode to use for backfilling the skeleton chains success func() // Callback to run on successful sync cycle completion filling bool // Flag whether the downloader is backfilling or not - filled *types.Header // Last header filled by the last terminated sync loop started chan struct{} // Notification channel whether the downloader inited lock sync.Mutex // Mutex protecting the sync lock } @@ -57,12 +55,15 @@ func (b *beaconBackfiller) suspend() *types.Header { // If no filling is running, don't waste cycles b.lock.Lock() filling := b.filling - filled := b.filled started := b.started b.lock.Unlock() if !filling { - return filled // Return the filled header on the previous sync completion + // Sync cycle was inactive, retrieve and return the latest snap block + // as the filled header. + log.Debug("Backfiller was inactive") + + return b.downloader.blockchain.CurrentSnapBlock() } // A previous filling should be running, though it may happen that it hasn't // yet started (being done on a new goroutine). Many concurrent beacon head @@ -74,9 +75,9 @@ func (b *beaconBackfiller) suspend() *types.Header { // Now that we're sure the downloader successfully started up, we can cancel // it safely without running the risk of data races. b.downloader.Cancel() + log.Debug("Backfiller has been suspended") // Sync cycle was just terminated, retrieve and return the last filled header. - // Can't use `filled` as that contains a stale value from before cancellation. return b.downloader.blockchain.CurrentSnapBlock() } @@ -87,12 +88,11 @@ func (b *beaconBackfiller) resume() { // If a previous filling cycle is still running, just ignore this start // request. // TODO(karalabe): We should make this channel driven b.lock.Unlock() + log.Debug("Backfiller is running") return } b.filling = true - b.filled = nil b.started = make(chan struct{}) - mode := b.syncMode b.lock.Unlock() // Start the backfilling on its own thread since the downloader does not have @@ -102,42 +102,22 @@ func (b *beaconBackfiller) resume() { defer func() { b.lock.Lock() b.filling = false - b.filled = b.downloader.blockchain.CurrentSnapBlock() b.lock.Unlock() }() // If the downloader fails, report an error as in beacon chain mode there // should be no errors as long as the chain we're syncing to is valid. - if err := b.downloader.synchronise(mode, b.started); err != nil { + if err := b.downloader.synchronise(b.started); err != nil { log.Error("Beacon backfilling failed", "err", err) return } // Synchronization succeeded. Since this happens async, notify the outer - // context to disable snap syncing and enable transaction propagation. + // context to enable transaction propagation. if b.success != nil { b.success() } + log.Debug("Backfilling completed") }() -} - -// setMode updates the sync mode from the current one to the requested one. If -// there's an active sync in progress, it will be cancelled and restarted. -func (b *beaconBackfiller) setMode(mode SyncMode) { - // Update the old sync mode and track if it was changed - b.lock.Lock() - oldMode := b.syncMode - updated := oldMode != mode - filling := b.filling - b.syncMode = mode - b.lock.Unlock() - - // If the sync mode was changed mid-sync, restart. This should never ever - // really happen, we just handle it to detect programming errors. - if !updated || !filling { - return - } - log.Error("Downloader sync mode changed mid-run", "old", oldMode.String(), "new", mode.String()) - b.suspend() - b.resume() + log.Debug("Backfilling started") } // SetBadBlockCallback sets the callback to run when a bad block is hit by the @@ -153,8 +133,8 @@ func (d *Downloader) SetBadBlockCallback(onBadBlock badBlockFn) { // // Internally backfilling and state sync is done the same way, but the header // retrieval and scheduling is replaced. -func (d *Downloader) BeaconSync(mode SyncMode, head *types.Header, final *types.Header) error { - return d.beaconSync(mode, head, final, true) +func (d *Downloader) BeaconSync(head *types.Header, final *types.Header) error { + return d.beaconSync(head, final, true) } // BeaconExtend is an optimistic version of BeaconSync, where an attempt is made @@ -163,8 +143,8 @@ func (d *Downloader) BeaconSync(mode SyncMode, head *types.Header, final *types. // // This is useful if a beacon client is feeding us large chunks of payloads to run, // but is not setting the head after each. -func (d *Downloader) BeaconExtend(mode SyncMode, head *types.Header) error { - return d.beaconSync(mode, head, nil, false) +func (d *Downloader) BeaconExtend(head *types.Header) error { + return d.beaconSync(head, nil, false) } // beaconSync is the post-merge version of the chain synchronization, where the @@ -173,20 +153,9 @@ func (d *Downloader) BeaconExtend(mode SyncMode, head *types.Header) error { // // Internally backfilling and state sync is done the same way, but the header // retrieval and scheduling is replaced. -func (d *Downloader) beaconSync(mode SyncMode, head *types.Header, final *types.Header, force bool) error { - // When the downloader starts a sync cycle, it needs to be aware of the sync - // mode to use (full, snap). To keep the skeleton chain oblivious, inject the - // mode into the backfiller directly. - // - // Super crazy dangerous type cast. Should be fine (TM), we're only using a - // different backfiller implementation for skeleton tests. - d.skeleton.filler.(*beaconBackfiller).setMode(mode) - +func (d *Downloader) beaconSync(head *types.Header, final *types.Header, force bool) error { // Signal the skeleton sync to switch to a new head, however it wants - if err := d.skeleton.Sync(head, final, force); err != nil { - return err - } - return nil + return d.skeleton.Sync(head, final, force) } // findBeaconAncestor tries to locate the common ancestor link of the local chain @@ -217,6 +186,8 @@ func (d *Downloader) findBeaconAncestor() (uint64, error) { log.Error("Failed to retrieve beacon bounds", "err", err) return 0, err } + log.Debug("Searching beacon ancestor", "local", number, "beaconhead", beaconHead.Number, "beacontail", beaconTail.Number) + var linked bool switch d.getMode() { case ethconfig.FullSync: @@ -270,6 +241,7 @@ func (d *Downloader) findBeaconAncestor() (uint64, error) { } start = check } + log.Debug("Found beacon ancestor", "number", start) return start, nil } diff --git a/eth/downloader/downloader.go b/eth/downloader/downloader.go index 09837a3045..caeb3d64dd 100644 --- a/eth/downloader/downloader.go +++ b/eth/downloader/downloader.go @@ -97,8 +97,9 @@ type headerTask struct { } type Downloader struct { - mode atomic.Uint32 // Synchronisation mode defining the strategy used (per sync cycle), use d.getMode() to get the SyncMode - mux *event.TypeMux // Event multiplexer to announce sync operation events + mode atomic.Uint32 // Synchronisation mode defining the strategy used (per sync cycle), use d.getMode() to get the SyncMode + moder *syncModer // Sync mode management, deliver the appropriate sync mode choice for each cycle + mux *event.TypeMux // Event multiplexer to announce sync operation events queue *queue // Scheduler for selecting the hashes to download peers *peerSet // Set of active peers from which download can proceed @@ -165,6 +166,9 @@ type BlockChain interface { // HasHeader verifies a header's presence in the local chain. HasHeader(common.Hash, uint64) bool + // HasState checks if state trie is fully present in the database or not. + HasState(root common.Hash) bool + // GetHeaderByHash retrieves a header from the local chain. GetHeaderByHash(common.Hash) *types.Header @@ -189,8 +193,12 @@ type BlockChain interface { // CurrentSnapBlock retrieves the head snap block from the local chain. CurrentSnapBlock() *types.Header - // SnapSyncCommitHead directly commits the head block to a certain entity. - SnapSyncCommitHead(common.Hash) error + // SnapSyncStart explicitly notifies the chain that snap sync is scheduled and + // marks chain mutations as disallowed. + SnapSyncStart() error + + // SnapSyncComplete directly commits the head block to a certain entity. + SnapSyncComplete(common.Hash) error // InsertHeadersBeforeCutoff inserts a batch of headers before the configured // chain cutoff into the ancient store. @@ -221,10 +229,11 @@ type BlockChain interface { } // New creates a new downloader to fetch hashes and blocks from remote peers. -func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, dropPeer peerDropFn, success func()) *Downloader { +func New(stateDb ethdb.Database, mode ethconfig.SyncMode, mux *event.TypeMux, chain BlockChain, dropPeer peerDropFn, success func()) *Downloader { cutoffNumber, cutoffHash := chain.HistoryPruningCutoff() dl := &Downloader{ stateDB: stateDb, + moder: newSyncModer(mode, chain, stateDb), mux: mux, queue: newQueue(blockCacheMaxItems, blockCacheInitialItems), peers: newPeerSet(), @@ -239,7 +248,7 @@ func New(stateDb ethdb.Database, mux *event.TypeMux, chain BlockChain, dropPeer syncStartBlock: chain.CurrentSnapBlock().Number.Uint64(), } // Create the post-merge skeleton syncer and start the process - dl.skeleton = newSkeleton(stateDb, dl.peers, dropPeer, newBeaconBackfiller(dl, success)) + dl.skeleton = newSkeleton(stateDb, dl.peers, dropPeer, newBeaconBackfiller(dl, success), chain) go dl.stateFetcher() return dl @@ -331,7 +340,7 @@ func (d *Downloader) UnregisterPeer(id string) error { // synchronise will select the peer and use it for synchronising. If an empty string is given // it will use the best peer possible and synchronize if its TD is higher than our own. If any of the // checks fail an error will be returned. This method is synchronous -func (d *Downloader) synchronise(mode SyncMode, beaconPing chan struct{}) error { +func (d *Downloader) synchronise(beaconPing chan struct{}) (err error) { // The beacon header syncer is async. It will start this synchronization and // will continue doing other tasks. However, if synchronization needs to be // cancelled, the syncer needs to know if we reached the startup point (and @@ -356,21 +365,21 @@ func (d *Downloader) synchronise(mode SyncMode, beaconPing chan struct{}) error if d.notified.CompareAndSwap(false, true) { log.Info("Block synchronisation started") } - if mode == ethconfig.SnapSync { - // Snap sync will directly modify the persistent state, making the entire - // trie database unusable until the state is fully synced. To prevent any - // subsequent state reads, explicitly disable the trie database and state - // syncer is responsible to address and correct any state missing. - if d.blockchain.TrieDB().Scheme() == rawdb.PathScheme { - if err := d.blockchain.TrieDB().Disable(); err != nil { - return err - } + + // Obtain the synchronized used in this cycle + mode := d.moder.get(true) + defer func() { + if err == nil && mode == ethconfig.SnapSync { + d.moder.disableSnap() + log.Info("Disabled snap-sync after the initial sync cycle") } - // Snap sync uses the snapshot namespace to store potentially flaky data until - // sync completely heals and finishes. Pause snapshot maintenance in the mean- - // time to prevent access. - if snapshots := d.blockchain.Snapshots(); snapshots != nil { // Only nil in tests - snapshots.Disable() + }() + + // Disable chain mutations when snap sync is selected, ensuring the + // downloader is the sole mutator. + if mode == ethconfig.SnapSync { + if err := d.blockchain.SnapSyncStart(); err != nil { + return err } } // Reset the queue, peer set and wake channels to clean any internal leftover state @@ -399,6 +408,7 @@ func (d *Downloader) synchronise(mode SyncMode, beaconPing chan struct{}) error // Atomically set the requested sync mode d.mode.Store(uint32(mode)) + defer d.mode.Store(0) if beaconPing != nil { close(beaconPing) @@ -406,10 +416,17 @@ func (d *Downloader) synchronise(mode SyncMode, beaconPing chan struct{}) error return d.syncToHead() } +// getMode returns the sync mode used within current cycle. func (d *Downloader) getMode() SyncMode { return SyncMode(d.mode.Load()) } +// ConfigSyncMode returns the sync mode configured for the node. +// The actual running sync mode can differ from this. +func (d *Downloader) ConfigSyncMode() SyncMode { + return d.moder.get(false) +} + // syncToHead starts a block synchronization based on the hash chain from // the specified head hash. func (d *Downloader) syncToHead() (err error) { @@ -1066,7 +1083,7 @@ func (d *Downloader) commitPivotBlock(result *fetchResult) error { if _, err := d.blockchain.InsertReceiptChain([]*types.Block{block}, []rlp.RawValue{result.Receipts}, d.ancientLimit); err != nil { return err } - if err := d.blockchain.SnapSyncCommitHead(block.Hash()); err != nil { + if err := d.blockchain.SnapSyncComplete(block.Hash()); err != nil { return err } d.committed.Store(true) diff --git a/eth/downloader/downloader_test.go b/eth/downloader/downloader_test.go index c1a31d6e1c..7fa2522a3d 100644 --- a/eth/downloader/downloader_test.go +++ b/eth/downloader/downloader_test.go @@ -30,6 +30,7 @@ import ( "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" "github.com/ethereum/go-ethereum/event" @@ -49,12 +50,12 @@ type downloadTester struct { } // newTester creates a new downloader test mocker. -func newTester(t *testing.T) *downloadTester { - return newTesterWithNotification(t, nil) +func newTester(t *testing.T, mode ethconfig.SyncMode) *downloadTester { + return newTesterWithNotification(t, mode, nil) } // newTesterWithNotification creates a new downloader test mocker. -func newTesterWithNotification(t *testing.T, success func()) *downloadTester { +func newTesterWithNotification(t *testing.T, mode ethconfig.SyncMode, success func()) *downloadTester { db, err := rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{}) if err != nil { panic(err) @@ -75,7 +76,7 @@ func newTesterWithNotification(t *testing.T, success func()) *downloadTester { chain: chain, peers: make(map[string]*downloadTesterPeer), } - tester.downloader = New(db, new(event.TypeMux), tester.chain, tester.dropPeer, success) + tester.downloader = New(db, mode, new(event.TypeMux), tester.chain, tester.dropPeer, success) return tester } @@ -393,7 +394,7 @@ func TestCanonicalSynchronisation68Snap(t *testing.T) { testCanonSync(t, eth.ETH func testCanonSync(t *testing.T, protocol uint, mode SyncMode) { success := make(chan struct{}) - tester := newTesterWithNotification(t, func() { + tester := newTesterWithNotification(t, mode, func() { close(success) }) defer tester.terminate() @@ -403,7 +404,7 @@ func testCanonSync(t *testing.T, protocol uint, mode SyncMode) { tester.newPeer("peer", protocol, chain.blocks[1:]) // Synchronise with the peer and make sure all relevant data was retrieved - if err := tester.downloader.BeaconSync(mode, chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { + if err := tester.downloader.BeaconSync(chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { t.Fatalf("failed to beacon-sync chain: %v", err) } select { @@ -420,7 +421,7 @@ func TestThrottling68Full(t *testing.T) { testThrottling(t, eth.ETH68, FullSync) func TestThrottling68Snap(t *testing.T) { testThrottling(t, eth.ETH68, SnapSync) } func testThrottling(t *testing.T, protocol uint, mode SyncMode) { - tester := newTester(t) + tester := newTester(t, mode) defer tester.terminate() // Create a long block chain to download and the tester @@ -437,7 +438,7 @@ func testThrottling(t *testing.T, protocol uint, mode SyncMode) { // Start a synchronisation concurrently errc := make(chan error, 1) go func() { - errc <- tester.downloader.BeaconSync(mode, testChainBase.blocks[len(testChainBase.blocks)-1].Header(), nil) + errc <- tester.downloader.BeaconSync(testChainBase.blocks[len(testChainBase.blocks)-1].Header(), nil) }() // Iteratively take some blocks, always checking the retrieval count for { @@ -502,7 +503,7 @@ func testCancel(t *testing.T, protocol uint, mode SyncMode) { success := func() { close(complete) } - tester := newTesterWithNotification(t, success) + tester := newTesterWithNotification(t, mode, success) defer tester.terminate() chain := testChainBase.shorten(MaxHeaderFetch) @@ -514,7 +515,7 @@ func testCancel(t *testing.T, protocol uint, mode SyncMode) { t.Errorf("download queue not idle") } // Synchronise with the peer, but cancel afterwards - if err := tester.downloader.BeaconSync(mode, chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { + if err := tester.downloader.BeaconSync(chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } <-complete @@ -534,7 +535,7 @@ func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) { success := func() { close(complete) } - tester := newTesterWithNotification(t, success) + tester := newTesterWithNotification(t, mode, success) defer tester.terminate() // Create a small enough block chain to download @@ -543,7 +544,7 @@ func testMultiProtoSync(t *testing.T, protocol uint, mode SyncMode) { // Create peers of every type tester.newPeer("peer 68", eth.ETH68, chain.blocks[1:]) - if err := tester.downloader.BeaconSync(mode, chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { + if err := tester.downloader.BeaconSync(chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { t.Fatalf("failed to start beacon sync: %v", err) } select { @@ -570,7 +571,7 @@ func TestEmptyShortCircuit68Snap(t *testing.T) { testEmptyShortCircuit(t, eth.ET func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) { success := make(chan struct{}) - tester := newTesterWithNotification(t, func() { + tester := newTesterWithNotification(t, mode, func() { close(success) }) defer tester.terminate() @@ -588,7 +589,7 @@ func testEmptyShortCircuit(t *testing.T, protocol uint, mode SyncMode) { receiptsHave.Add(int32(len(headers))) } - if err := tester.downloader.BeaconSync(mode, chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { + if err := tester.downloader.BeaconSync(chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { t.Fatalf("failed to synchronise blocks: %v", err) } select { @@ -650,7 +651,7 @@ func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) { for _, c := range cases { t.Run(c.name, func(t *testing.T) { success := make(chan struct{}) - tester := newTesterWithNotification(t, func() { + tester := newTesterWithNotification(t, mode, func() { close(success) }) defer tester.terminate() @@ -662,7 +663,7 @@ func testBeaconSync(t *testing.T, protocol uint, mode SyncMode) { if c.local > 0 { tester.chain.InsertChain(chain.blocks[1 : c.local+1]) } - if err := tester.downloader.BeaconSync(mode, chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { + if err := tester.downloader.BeaconSync(chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { t.Fatalf("Failed to beacon sync chain %v %v", c.name, err) } select { @@ -685,7 +686,7 @@ func TestSyncProgress68Snap(t *testing.T) { testSyncProgress(t, eth.ETH68, SnapS func testSyncProgress(t *testing.T, protocol uint, mode SyncMode) { success := make(chan struct{}) - tester := newTesterWithNotification(t, func() { + tester := newTesterWithNotification(t, mode, func() { success <- struct{}{} }) defer tester.terminate() @@ -700,7 +701,7 @@ func testSyncProgress(t *testing.T, protocol uint, mode SyncMode) { faultyPeer.withholdBodies[header.Hash()] = struct{}{} } - if err := tester.downloader.BeaconSync(mode, chain.blocks[len(chain.blocks)/2-1].Header(), nil); err != nil { + if err := tester.downloader.BeaconSync(chain.blocks[len(chain.blocks)/2-1].Header(), nil); err != nil { t.Fatalf("failed to beacon-sync chain: %v", err) } select { @@ -716,7 +717,7 @@ func testSyncProgress(t *testing.T, protocol uint, mode SyncMode) { // Synchronise all the blocks and check continuation progress tester.newPeer("peer-full", protocol, chain.blocks[1:]) - if err := tester.downloader.BeaconSync(mode, chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { + if err := tester.downloader.BeaconSync(chain.blocks[len(chain.blocks)-1].Header(), nil); err != nil { t.Fatalf("failed to beacon-sync chain: %v", err) } startingBlock := uint64(len(chain.blocks)/2 - 1) diff --git a/eth/downloader/queue.go b/eth/downloader/queue.go index 9fe169d5f7..76a14345e5 100644 --- a/eth/downloader/queue.go +++ b/eth/downloader/queue.go @@ -418,7 +418,7 @@ func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common skip := make([]*types.Header, 0) progress := false throttled := false - for proc := 0; len(send) < count && !taskQueue.Empty(); proc++ { + for len(send) < count && !taskQueue.Empty() { // the task queue will pop items in order, so the highest prio block // is also the lowest block number. header, _ := taskQueue.Peek() @@ -433,7 +433,6 @@ func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common taskQueue.PopItem() progress = true delete(taskPool, header.Hash()) - proc = proc - 1 log.Error("Fetch reservation already delivered", "number", header.Number.Uint64()) continue } @@ -455,7 +454,6 @@ func (q *queue) reserveHeaders(p *peerConnection, count int, taskPool map[common // If it's a noop, we can skip this task delete(taskPool, header.Hash()) taskQueue.PopItem() - proc = proc - 1 progress = true continue } diff --git a/eth/downloader/queue_test.go b/eth/downloader/queue_test.go index 854acf3d8f..ca71a769de 100644 --- a/eth/downloader/queue_test.go +++ b/eth/downloader/queue_test.go @@ -36,13 +36,13 @@ import ( ) // makeChain creates a chain of n blocks starting at and including parent. -// the returned hash chain is ordered head->parent. In addition, every 3rd block -// contains a transaction and every 5th an uncle to allow testing correct block -// reassembly. +// The returned hash chain is ordered head->parent. +// If empty is false, every second block (i%2==0) contains one transaction. +// No uncles are added. func makeChain(n int, seed byte, parent *types.Block, empty bool) ([]*types.Block, []types.Receipts) { blocks, receipts := core.GenerateChain(params.TestChainConfig, parent, ethash.NewFaker(), testDB, n, func(i int, block *core.BlockGen) { block.SetCoinbase(common.Address{seed}) - // Add one tx to every secondblock + // Add one tx to every second block if !empty && i%2 == 0 { signer := types.MakeSigner(params.TestChainConfig, block.Number(), block.Timestamp()) tx, err := types.SignTx(types.NewTransaction(block.TxNonce(testAddress), common.Address{seed}, big.NewInt(1000), params.TxGas, block.BaseFee(), nil), signer, testKey) @@ -351,6 +351,7 @@ func XTestDelivery(t *testing.T) { } } }() + wg.Add(1) go func() { defer wg.Done() // reserve receiptfetch diff --git a/eth/downloader/skeleton.go b/eth/downloader/skeleton.go index 2cf9c4672b..e693bfc066 100644 --- a/eth/downloader/skeleton.go +++ b/eth/downloader/skeleton.go @@ -64,6 +64,12 @@ var errSyncMerged = errors.New("sync merged") // should abort and restart with the new state. var errSyncReorged = errors.New("sync reorged") +// errSyncTrimmed is an internal helper error to signal that the local chain +// has been trimmed (e.g, via debug_setHead explicitly) and the skeleton chain +// is no longer linked with the local chain. In this case, the skeleton sync +// should be re-scheduled again. +var errSyncTrimmed = errors.New("sync trimmed") + // errTerminated is returned if the sync mechanism was terminated for this run of // the process. This is usually the case when Geth is shutting down and some events // might still be propagating. @@ -201,6 +207,7 @@ type backfiller interface { type skeleton struct { db ethdb.Database // Database backing the skeleton filler backfiller // Chain syncer suspended/resumed by head events + chain chainReader // Underlying block chain peers *peerSet // Set of peers we can sync from idles map[string]*peerConnection // Set of idle peers in the current sync cycle @@ -225,12 +232,19 @@ type skeleton struct { syncStarting func() // callback triggered after a sync cycle is inited but before started } +// chainReader wraps the method to retrieve the head of the local chain. +type chainReader interface { + // CurrentSnapBlock retrieves the head snap block from the local chain. + CurrentSnapBlock() *types.Header +} + // newSkeleton creates a new sync skeleton that tracks a potentially dangling // header chain until it's linked into an existing set of blocks. -func newSkeleton(db ethdb.Database, peers *peerSet, drop peerDropFn, filler backfiller) *skeleton { +func newSkeleton(db ethdb.Database, peers *peerSet, drop peerDropFn, filler backfiller, chain chainReader) *skeleton { sk := &skeleton{ db: db, filler: filler, + chain: chain, peers: peers, drop: drop, requests: make(map[uint64]*headerRequest), @@ -296,6 +310,11 @@ func (s *skeleton) startup() { // head to force a cleanup. head = newhead + case err == errSyncTrimmed: + // The skeleton chain is not linked with the local chain anymore, + // restart the sync. + head = nil + case err == errTerminated: // Sync was requested to be terminated from within, stop and // return (no need to pass a message, was already done internally) @@ -343,6 +362,29 @@ func (s *skeleton) Sync(head *types.Header, final *types.Header, force bool) err } } +// linked returns the flag indicating whether the skeleton has been linked with +// the local chain. +func (s *skeleton) linked(number uint64, hash common.Hash) bool { + linked := rawdb.HasHeader(s.db, hash, number) && + rawdb.HasBody(s.db, hash, number) && + rawdb.HasReceipts(s.db, hash, number) + + // Ensure the skeleton chain links to the local chain below the chain head. + // This accounts for edge cases where leftover chain segments above the head + // may still link to the skeleton chain. In such cases, synchronization is + // likely to fail due to potentially missing segments in the middle. + // + // You can try to produce the edge case by these steps: + // - sync the chain + // - debug.setHead(`0x1`) + // - kill the geth process (the chain segment will be left with chain head rewound) + // - restart + if s.chain.CurrentSnapBlock() != nil { + linked = linked && s.chain.CurrentSnapBlock().Number.Uint64() >= number + } + return linked +} + // sync is the internal version of Sync that executes a single sync cycle, either // until some termination condition is reached, or until the current cycle merges // with a previously aborted run. @@ -367,10 +409,7 @@ func (s *skeleton) sync(head *types.Header) (*types.Header, error) { // If the sync is already done, resume the backfiller. When the loop stops, // terminate the backfiller too. - linked := len(s.progress.Subchains) == 1 && - rawdb.HasHeader(s.db, s.progress.Subchains[0].Next, s.scratchHead) && - rawdb.HasBody(s.db, s.progress.Subchains[0].Next, s.scratchHead) && - rawdb.HasReceipts(s.db, s.progress.Subchains[0].Next, s.scratchHead) + linked := len(s.progress.Subchains) == 1 && s.linked(s.scratchHead, s.progress.Subchains[0].Next) if linked { s.filler.resume() } @@ -486,7 +525,17 @@ func (s *skeleton) sync(head *types.Header) (*types.Header, error) { // is still running, it will pick it up. If it already terminated, // a new cycle needs to be spun up. if linked { - s.filler.resume() + if len(s.progress.Subchains) == 1 && s.linked(s.scratchHead, s.progress.Subchains[0].Next) { + // The skeleton chain has been extended and is still linked with the local + // chain, try to re-schedule the backfiller if it's already terminated. + s.filler.resume() + } else { + // The skeleton chain is no longer linked to the local chain for some reason + // (e.g. debug_setHead was used to trim the local chain). Re-schedule the + // skeleton sync to fill the chain gap. + log.Warn("Local chain has been trimmed", "tailnumber", s.scratchHead, "tailhash", s.progress.Subchains[0].Next) + return nil, errSyncTrimmed + } } case req := <-requestFails: @@ -649,9 +698,19 @@ func (s *skeleton) processNewHead(head *types.Header, final *types.Header) error // Not a noop / double head announce, abort with a reorg return fmt.Errorf("%w, tail: %d, head: %d, newHead: %d", errChainReorged, lastchain.Tail, lastchain.Head, number) } + // Terminate the sync if the chain head is gapped if lastchain.Head+1 < number { return fmt.Errorf("%w, head: %d, newHead: %d", errChainGapped, lastchain.Head, number) } + // Ignore the duplicated beacon header announcement + if lastchain.Head == number { + local := rawdb.ReadSkeletonHeader(s.db, number) + if local != nil && local.Hash() == head.Hash() { + log.Debug("Ignored the identical beacon header", "number", number, "hash", local.Hash()) + return nil + } + } + // Terminate the sync if the chain head is forked if parent := rawdb.ReadSkeletonHeader(s.db, number-1); parent.Hash() != head.ParentHash { return fmt.Errorf("%w, ancestor: %d, hash: %s, want: %s", errChainForked, number-1, parent.Hash(), head.ParentHash) } @@ -669,6 +728,7 @@ func (s *skeleton) processNewHead(head *types.Header, final *types.Header) error if err := batch.Write(); err != nil { log.Crit("Failed to write skeleton sync status", "err", err) } + log.Debug("Extended beacon header chain", "number", head.Number, "hash", head.Hash()) return nil } @@ -909,6 +969,45 @@ func (s *skeleton) revertRequest(req *headerRequest) { s.scratchOwners[(s.scratchHead-req.head)/requestHeaders] = "" } +// mergeSubchains is invoked once certain beacon headers have been persisted locally +// and the subchains should be merged in case there are some overlaps between. An +// indicator will be returned if the last subchain is merged with previous subchain. +func (s *skeleton) mergeSubchains() bool { + // If the subchain extended into the next subchain, we need to handle + // the overlap. Since there could be many overlaps, do this in a loop. + var merged bool + for len(s.progress.Subchains) > 1 && s.progress.Subchains[1].Head >= s.progress.Subchains[0].Tail { + // Extract some stats from the second subchain + head := s.progress.Subchains[1].Head + tail := s.progress.Subchains[1].Tail + next := s.progress.Subchains[1].Next + + // Since we just overwrote part of the next subchain, we need to trim + // its head independent of matching or mismatching content + if s.progress.Subchains[1].Tail >= s.progress.Subchains[0].Tail { + // Fully overwritten, get rid of the subchain as a whole + log.Debug("Previous subchain fully overwritten", "head", head, "tail", tail, "next", next) + s.progress.Subchains = append(s.progress.Subchains[:1], s.progress.Subchains[2:]...) + continue + } else { + // Partially overwritten, trim the head to the overwritten size + log.Debug("Previous subchain partially overwritten", "head", head, "tail", tail, "next", next) + s.progress.Subchains[1].Head = s.progress.Subchains[0].Tail - 1 + } + // If the old subchain is an extension of the new one, merge the two + // and let the skeleton syncer restart (to clean internal state) + if rawdb.ReadSkeletonHeader(s.db, s.progress.Subchains[1].Head).Hash() == s.progress.Subchains[0].Next { + log.Debug("Previous subchain merged", "head", head, "tail", tail, "next", next) + s.progress.Subchains[0].Tail = s.progress.Subchains[1].Tail + s.progress.Subchains[0].Next = s.progress.Subchains[1].Next + + s.progress.Subchains = append(s.progress.Subchains[:1], s.progress.Subchains[2:]...) + merged = true + } + } + return merged +} + func (s *skeleton) processResponse(res *headerResponse) (linked bool, merged bool) { res.peer.log.Trace("Processing header response", "head", res.headers[0].Number, "hash", res.headers[0].Hash(), "count", len(res.headers)) @@ -982,10 +1081,9 @@ func (s *skeleton) processResponse(res *headerResponse) (linked bool, merged boo // processing is done, so it's just one more "needless" check. // // The weird cascading checks are done to minimize the database reads. - linked = rawdb.HasHeader(s.db, header.ParentHash, header.Number.Uint64()-1) && - rawdb.HasBody(s.db, header.ParentHash, header.Number.Uint64()-1) && - rawdb.HasReceipts(s.db, header.ParentHash, header.Number.Uint64()-1) + linked = s.linked(header.Number.Uint64()-1, header.ParentHash) if linked { + log.Debug("Primary subchain linked", "number", header.Number.Uint64()-1, "hash", header.ParentHash) break } } @@ -999,6 +1097,9 @@ func (s *skeleton) processResponse(res *headerResponse) (linked bool, merged boo // If the beacon chain was linked to the local chain, completely swap out // all internal progress and abort header synchronization. if linked { + // Merge all overlapped subchains beforehand + s.mergeSubchains() + // Linking into the local chain should also mean that there are no // leftover subchains, but in the case of importing the blocks via // the engine API, we will not push the subchains forward. This will @@ -1056,41 +1157,10 @@ func (s *skeleton) processResponse(res *headerResponse) (linked bool, merged boo s.scratchHead -= uint64(consumed) - // If the subchain extended into the next subchain, we need to handle - // the overlap. Since there could be many overlaps (come on), do this - // in a loop. - for len(s.progress.Subchains) > 1 && s.progress.Subchains[1].Head >= s.progress.Subchains[0].Tail { - // Extract some stats from the second subchain - head := s.progress.Subchains[1].Head - tail := s.progress.Subchains[1].Tail - next := s.progress.Subchains[1].Next - - // Since we just overwrote part of the next subchain, we need to trim - // its head independent of matching or mismatching content - if s.progress.Subchains[1].Tail >= s.progress.Subchains[0].Tail { - // Fully overwritten, get rid of the subchain as a whole - log.Debug("Previous subchain fully overwritten", "head", head, "tail", tail, "next", next) - s.progress.Subchains = append(s.progress.Subchains[:1], s.progress.Subchains[2:]...) - continue - } else { - // Partially overwritten, trim the head to the overwritten size - log.Debug("Previous subchain partially overwritten", "head", head, "tail", tail, "next", next) - s.progress.Subchains[1].Head = s.progress.Subchains[0].Tail - 1 - } - // If the old subchain is an extension of the new one, merge the two - // and let the skeleton syncer restart (to clean internal state) - if rawdb.ReadSkeletonHeader(s.db, s.progress.Subchains[1].Head).Hash() == s.progress.Subchains[0].Next { - log.Debug("Previous subchain merged", "head", head, "tail", tail, "next", next) - s.progress.Subchains[0].Tail = s.progress.Subchains[1].Tail - s.progress.Subchains[0].Next = s.progress.Subchains[1].Next - - s.progress.Subchains = append(s.progress.Subchains[:1], s.progress.Subchains[2:]...) - merged = true - } - } // If subchains were merged, all further available headers in the scratch // space are invalid since we skipped ahead. Stop processing the scratch // space to avoid dropping peers thinking they delivered invalid data. + merged = s.mergeSubchains() if merged { break } @@ -1121,15 +1191,17 @@ func (s *skeleton) processResponse(res *headerResponse) (linked bool, merged boo // due to the downloader backfilling past the tracked tail. func (s *skeleton) cleanStales(filled *types.Header) error { number := filled.Number.Uint64() - log.Trace("Cleaning stale beacon headers", "filled", number, "hash", filled.Hash()) + log.Debug("Cleaning stale beacon headers", "filled", number, "hash", filled.Hash()) - // If the filled header is below the linked subchain, something's corrupted - // internally. Report and error and refuse to do anything. + // If the filled header is below the subchain, it means the skeleton is not + // linked with local chain yet, don't bother to do cleanup. if number+1 < s.progress.Subchains[0].Tail { - return fmt.Errorf("filled header below beacon header tail: %d < %d", number, s.progress.Subchains[0].Tail) + log.Debug("filled header below beacon header tail", "filled", number, "tail", s.progress.Subchains[0].Tail) + return nil } // If nothing in subchain is filled, don't bother to do cleanup. if number+1 == s.progress.Subchains[0].Tail { + log.Debug("Skeleton chain not yet consumed", "filled", number, "hash", filled.Hash(), "tail", s.progress.Subchains[0].Tail) return nil } // If the latest fill was on a different subchain, it means the backfiller @@ -1206,6 +1278,7 @@ func (s *skeleton) cleanStales(filled *types.Header) error { if err := batch.Write(); err != nil { log.Crit("Failed to write beacon trim data", "err", err) } + log.Debug("Cleaned stale beacon headers", "start", start, "end", end) return nil } diff --git a/eth/downloader/skeleton_test.go b/eth/downloader/skeleton_test.go index 4aa97cf1f7..5c54b4b5c2 100644 --- a/eth/downloader/skeleton_test.go +++ b/eth/downloader/skeleton_test.go @@ -20,6 +20,7 @@ import ( "encoding/json" "errors" "fmt" + "math" "math/big" "sync/atomic" "testing" @@ -71,6 +72,12 @@ func (hf *hookedBackfiller) resume() { } } +type fakeChainReader struct{} + +func (fc *fakeChainReader) CurrentSnapBlock() *types.Header { + return &types.Header{Number: big.NewInt(math.MaxInt64)} +} + // skeletonTestPeer is a mock peer that can only serve header requests from a // pre-perated header chain (which may be arbitrarily wrong for testing). // @@ -369,7 +376,7 @@ func TestSkeletonSyncInit(t *testing.T) { // Create a skeleton sync and run a cycle wait := make(chan struct{}) - skeleton := newSkeleton(db, newPeerSet(), nil, newHookedBackfiller()) + skeleton := newSkeleton(db, newPeerSet(), nil, newHookedBackfiller(), &fakeChainReader{}) skeleton.syncStarting = func() { close(wait) } skeleton.Sync(tt.head, nil, true) @@ -472,7 +479,7 @@ func TestSkeletonSyncExtend(t *testing.T) { // Create a skeleton sync and run a cycle wait := make(chan struct{}) - skeleton := newSkeleton(db, newPeerSet(), nil, newHookedBackfiller()) + skeleton := newSkeleton(db, newPeerSet(), nil, newHookedBackfiller(), &fakeChainReader{}) skeleton.syncStarting = func() { close(wait) } skeleton.Sync(tt.head, nil, true) @@ -885,7 +892,7 @@ func TestSkeletonSyncRetrievals(t *testing.T) { } } // Create a skeleton sync and run a cycle - skeleton := newSkeleton(db, peerset, drop, filler) + skeleton := newSkeleton(db, peerset, drop, filler, &fakeChainReader{}) skeleton.Sync(tt.head, nil, true) // Wait a bit (bleah) for the initial sync loop to go to idle. This might diff --git a/eth/downloader/syncmode.go b/eth/downloader/syncmode.go new file mode 100644 index 0000000000..036119ce3d --- /dev/null +++ b/eth/downloader/syncmode.go @@ -0,0 +1,115 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package downloader + +import ( + "sync" + + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" +) + +// syncModer is responsible for managing the downloader's sync mode. It takes the +// user's preference at startup and then determines the appropriate sync mode +// based on the current chain status. +type syncModer struct { + mode ethconfig.SyncMode + chain BlockChain + disk ethdb.KeyValueReader + lock sync.Mutex +} + +func newSyncModer(mode ethconfig.SyncMode, chain BlockChain, disk ethdb.KeyValueReader) *syncModer { + if mode == ethconfig.FullSync { + // The database seems empty as the current block is the genesis. Yet the snap + // block is ahead, so snap sync was enabled for this node at a certain point. + // The scenarios where this can happen is + // * if the user manually (or via a bad block) rolled back a snap sync node + // below the sync point. + // * the last snap sync is not finished while user specifies a full sync this + // time. But we don't have any recent state for full sync. + // In these cases however it's safe to reenable snap sync. + fullBlock, snapBlock := chain.CurrentBlock(), chain.CurrentSnapBlock() + if fullBlock.Number.Uint64() == 0 && snapBlock.Number.Uint64() > 0 { + mode = ethconfig.SnapSync + log.Warn("Switching from full-sync to snap-sync", "reason", "snap-sync incomplete") + } else if !chain.HasState(fullBlock.Root) { + mode = ethconfig.SnapSync + log.Warn("Switching from full-sync to snap-sync", "reason", "head state missing") + } else { + // Grant the full sync mode + log.Info("Enabled full-sync", "head", fullBlock.Number, "hash", fullBlock.Hash()) + } + } else { + head := chain.CurrentBlock() + if head.Number.Uint64() > 0 && chain.HasState(head.Root) { + mode = ethconfig.FullSync + log.Info("Switching from snap-sync to full-sync", "reason", "snap-sync complete") + } else { + // If snap sync was requested and our database is empty, grant it + log.Info("Enabled snap-sync", "head", head.Number, "hash", head.Hash()) + } + } + return &syncModer{ + mode: mode, + chain: chain, + disk: disk, + } +} + +// get retrieves the current sync mode, either explicitly set, or derived +// from the chain status. +func (m *syncModer) get(report bool) ethconfig.SyncMode { + m.lock.Lock() + defer m.lock.Unlock() + + // If we're in snap sync mode, return that directly + if m.mode == ethconfig.SnapSync { + return ethconfig.SnapSync + } + logger := log.Debug + if report { + logger = log.Info + } + // We are probably in full sync, but we might have rewound to before the + // snap sync pivot, check if we should re-enable snap sync. + head := m.chain.CurrentBlock() + if pivot := rawdb.ReadLastPivotNumber(m.disk); pivot != nil { + if head.Number.Uint64() < *pivot { + logger("Reenabled snap-sync as chain is lagging behind the pivot", "head", head.Number, "pivot", pivot) + return ethconfig.SnapSync + } + } + // We are in a full sync, but the associated head state is missing. To complete + // the head state, forcefully rerun the snap sync. Note it doesn't mean the + // persistent state is corrupted, just mismatch with the head block. + if !m.chain.HasState(head.Root) { + logger("Reenabled snap-sync as chain is stateless") + return ethconfig.SnapSync + } + // Nope, we're really full syncing + return ethconfig.FullSync +} + +// disableSnap disables the snap sync mode, usually it's called after a successful snap sync. +func (m *syncModer) disableSnap() { + m.lock.Lock() + m.mode = ethconfig.FullSync + m.lock.Unlock() +} diff --git a/eth/dropper.go b/eth/dropper.go index 51f2a7a95a..dada5d07c0 100644 --- a/eth/dropper.go +++ b/eth/dropper.go @@ -145,6 +145,9 @@ func randomDuration(min, max time.Duration) time.Duration { if min > max { panic("min duration must be less than or equal to max duration") } + if min == max { + return min + } return time.Duration(mrand.Int63n(int64(max-min)) + int64(min)) } diff --git a/eth/ethconfig/config.go b/eth/ethconfig/config.go index 82c3c500a7..e58c4b884a 100644 --- a/eth/ethconfig/config.go +++ b/eth/ethconfig/config.go @@ -35,6 +35,7 @@ import ( "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/triedb/pathdb" ) // FullNodeGPO contains default gasprice oracle settings for full node. @@ -49,26 +50,33 @@ var FullNodeGPO = gasprice.Config{ // Defaults contains default settings for use on the Ethereum main net. var Defaults = Config{ - HistoryMode: history.KeepAll, - SyncMode: SnapSync, - NetworkId: 0, // enable auto configuration of networkID == chainID - TxLookupLimit: 2350000, - TransactionHistory: 2350000, - LogHistory: 2350000, - StateHistory: params.FullImmutabilityThreshold, - DatabaseCache: 512, - TrieCleanCache: 154, - TrieDirtyCache: 256, - TrieTimeout: 60 * time.Minute, - SnapshotCache: 102, - FilterLogCacheSize: 32, - Miner: miner.DefaultConfig, - TxPool: legacypool.DefaultConfig, - BlobPool: blobpool.DefaultConfig, - RPCGasCap: 50000000, - RPCEVMTimeout: 5 * time.Second, - GPO: FullNodeGPO, - RPCTxFeeCap: 1, // 1 ether + HistoryMode: history.KeepAll, + SyncMode: SnapSync, + NetworkId: 0, // enable auto configuration of networkID == chainID + TxLookupLimit: 2350000, + TransactionHistory: 2350000, + LogHistory: 2350000, + StateHistory: pathdb.Defaults.StateHistory, + TrienodeHistory: pathdb.Defaults.TrienodeHistory, + NodeFullValueCheckpoint: pathdb.Defaults.FullValueCheckpoint, + DatabaseCache: 512, + TrieCleanCache: 154, + TrieDirtyCache: 256, + TrieTimeout: 60 * time.Minute, + SnapshotCache: 102, + FilterLogCacheSize: 32, + LogQueryLimit: 1000, + Miner: miner.DefaultConfig, + TxPool: legacypool.DefaultConfig, + BlobPool: blobpool.DefaultConfig, + RPCGasCap: 50000000, + RPCEVMTimeout: 5 * time.Second, + GPO: FullNodeGPO, + RPCTxFeeCap: 1, // 1 ether + TxSyncDefaultTimeout: 20 * time.Second, + TxSyncMaxTimeout: 1 * time.Minute, + SlowBlockThreshold: time.Second * 2, + RangeLimit: 0, } //go:generate go run github.com/fjl/gencodec -type Config -formats toml -out gen_config.go @@ -104,6 +112,13 @@ type Config struct { LogNoHistory bool `toml:",omitempty"` // No log search index is maintained. LogExportCheckpoints string // export log index checkpoints to file StateHistory uint64 `toml:",omitempty"` // The maximum number of blocks from head whose state histories are reserved. + TrienodeHistory int64 `toml:",omitempty"` // Number of blocks from the chain head for which trienode histories are retained + + // The frequency of full-value encoding. For example, a value of 16 means + // that, on average, for a given trie node across its 16 consecutive historical + // versions, only one version is stored in full format, while the others + // are stored in diff mode for storage compression. + NodeFullValueCheckpoint uint32 `toml:",omitempty"` // State scheme represents the scheme used to store ethereum states and trie // nodes on top. It can be 'hash', 'path', or none which means use the scheme @@ -115,6 +130,10 @@ type Config struct { // presence of these blocks for every new peer connection. RequiredBlocks map[uint64]common.Hash `toml:"-"` + // SlowBlockThreshold is the block execution speed threshold (Mgas/s) + // below which detailed statistics are logged. + SlowBlockThreshold time.Duration `toml:",omitempty"` + // Database options SkipBcVersionCheck bool `toml:"-"` DatabaseHandles int `toml:"-"` @@ -131,6 +150,10 @@ type Config struct { // This is the number of blocks for which logs will be cached in the filter system. FilterLogCacheSize int + // This is the maximum number of addresses or topics allowed in filter criteria + // for eth_getLogs. + LogQueryLimit int + // Mining options Miner miner.Config @@ -144,6 +167,15 @@ type Config struct { // Enables tracking of SHA3 preimages in the VM EnablePreimageRecording bool + // Enables collection of witness trie access statistics + EnableWitnessStats bool + + // Generate execution witnesses and self-check against them (testing purpose) + StatelessSelfValidation bool + + // Enables tracking of state size + EnableStateSizeTracking bool + // Enables VM tracing VMTrace string VMTraceJsonConfig string @@ -161,8 +193,21 @@ type Config struct { // OverrideOsaka (TODO: remove after the fork) OverrideOsaka *uint64 `toml:",omitempty"` + // OverrideBPO1 (TODO: remove after the fork) + OverrideBPO1 *uint64 `toml:",omitempty"` + + // OverrideBPO2 (TODO: remove after the fork) + OverrideBPO2 *uint64 `toml:",omitempty"` + // OverrideVerkle (TODO: remove after the fork) OverrideVerkle *uint64 `toml:",omitempty"` + + // EIP-7966: eth_sendRawTransactionSync timeouts + TxSyncDefaultTimeout time.Duration `toml:",omitempty"` + TxSyncMaxTimeout time.Duration `toml:",omitempty"` + + // RangeLimit restricts the maximum range (end - start) for range queries. + RangeLimit uint64 `toml:",omitempty"` } // CreateConsensusEngine creates a consensus engine for the given chain config. diff --git a/eth/ethconfig/gen_config.go b/eth/ethconfig/gen_config.go index 0a188ba23c..6f94a409e5 100644 --- a/eth/ethconfig/gen_config.go +++ b/eth/ethconfig/gen_config.go @@ -31,8 +31,11 @@ func (c Config) MarshalTOML() (interface{}, error) { LogNoHistory bool `toml:",omitempty"` LogExportCheckpoints string StateHistory uint64 `toml:",omitempty"` + TrienodeHistory int64 `toml:",omitempty"` + NodeFullValueCheckpoint uint32 `toml:",omitempty"` StateScheme string `toml:",omitempty"` RequiredBlocks map[uint64]common.Hash `toml:"-"` + SlowBlockThreshold time.Duration `toml:",omitempty"` SkipBcVersionCheck bool `toml:"-"` DatabaseHandles int `toml:"-"` DatabaseCache int @@ -44,18 +47,27 @@ func (c Config) MarshalTOML() (interface{}, error) { SnapshotCache int Preimages bool FilterLogCacheSize int + LogQueryLimit int Miner miner.Config TxPool legacypool.Config BlobPool blobpool.Config GPO gasprice.Config EnablePreimageRecording bool + EnableWitnessStats bool + StatelessSelfValidation bool + EnableStateSizeTracking bool VMTrace string VMTraceJsonConfig string RPCGasCap uint64 RPCEVMTimeout time.Duration RPCTxFeeCap float64 - OverrideOsaka *uint64 `toml:",omitempty"` - OverrideVerkle *uint64 `toml:",omitempty"` + OverrideOsaka *uint64 `toml:",omitempty"` + OverrideBPO1 *uint64 `toml:",omitempty"` + OverrideBPO2 *uint64 `toml:",omitempty"` + OverrideVerkle *uint64 `toml:",omitempty"` + TxSyncDefaultTimeout time.Duration `toml:",omitempty"` + TxSyncMaxTimeout time.Duration `toml:",omitempty"` + RangeLimit uint64 `toml:",omitempty"` } var enc Config enc.Genesis = c.Genesis @@ -72,8 +84,11 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.LogNoHistory = c.LogNoHistory enc.LogExportCheckpoints = c.LogExportCheckpoints enc.StateHistory = c.StateHistory + enc.TrienodeHistory = c.TrienodeHistory + enc.NodeFullValueCheckpoint = c.NodeFullValueCheckpoint enc.StateScheme = c.StateScheme enc.RequiredBlocks = c.RequiredBlocks + enc.SlowBlockThreshold = c.SlowBlockThreshold enc.SkipBcVersionCheck = c.SkipBcVersionCheck enc.DatabaseHandles = c.DatabaseHandles enc.DatabaseCache = c.DatabaseCache @@ -85,18 +100,27 @@ func (c Config) MarshalTOML() (interface{}, error) { enc.SnapshotCache = c.SnapshotCache enc.Preimages = c.Preimages enc.FilterLogCacheSize = c.FilterLogCacheSize + enc.LogQueryLimit = c.LogQueryLimit enc.Miner = c.Miner enc.TxPool = c.TxPool enc.BlobPool = c.BlobPool enc.GPO = c.GPO enc.EnablePreimageRecording = c.EnablePreimageRecording + enc.EnableWitnessStats = c.EnableWitnessStats + enc.StatelessSelfValidation = c.StatelessSelfValidation + enc.EnableStateSizeTracking = c.EnableStateSizeTracking enc.VMTrace = c.VMTrace enc.VMTraceJsonConfig = c.VMTraceJsonConfig enc.RPCGasCap = c.RPCGasCap enc.RPCEVMTimeout = c.RPCEVMTimeout enc.RPCTxFeeCap = c.RPCTxFeeCap enc.OverrideOsaka = c.OverrideOsaka + enc.OverrideBPO1 = c.OverrideBPO1 + enc.OverrideBPO2 = c.OverrideBPO2 enc.OverrideVerkle = c.OverrideVerkle + enc.TxSyncDefaultTimeout = c.TxSyncDefaultTimeout + enc.TxSyncMaxTimeout = c.TxSyncMaxTimeout + enc.RangeLimit = c.RangeLimit return &enc, nil } @@ -117,8 +141,11 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { LogNoHistory *bool `toml:",omitempty"` LogExportCheckpoints *string StateHistory *uint64 `toml:",omitempty"` + TrienodeHistory *int64 `toml:",omitempty"` + NodeFullValueCheckpoint *uint32 `toml:",omitempty"` StateScheme *string `toml:",omitempty"` RequiredBlocks map[uint64]common.Hash `toml:"-"` + SlowBlockThreshold *time.Duration `toml:",omitempty"` SkipBcVersionCheck *bool `toml:"-"` DatabaseHandles *int `toml:"-"` DatabaseCache *int @@ -130,18 +157,27 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { SnapshotCache *int Preimages *bool FilterLogCacheSize *int + LogQueryLimit *int Miner *miner.Config TxPool *legacypool.Config BlobPool *blobpool.Config GPO *gasprice.Config EnablePreimageRecording *bool + EnableWitnessStats *bool + StatelessSelfValidation *bool + EnableStateSizeTracking *bool VMTrace *string VMTraceJsonConfig *string RPCGasCap *uint64 RPCEVMTimeout *time.Duration RPCTxFeeCap *float64 - OverrideOsaka *uint64 `toml:",omitempty"` - OverrideVerkle *uint64 `toml:",omitempty"` + OverrideOsaka *uint64 `toml:",omitempty"` + OverrideBPO1 *uint64 `toml:",omitempty"` + OverrideBPO2 *uint64 `toml:",omitempty"` + OverrideVerkle *uint64 `toml:",omitempty"` + TxSyncDefaultTimeout *time.Duration `toml:",omitempty"` + TxSyncMaxTimeout *time.Duration `toml:",omitempty"` + RangeLimit *uint64 `toml:",omitempty"` } var dec Config if err := unmarshal(&dec); err != nil { @@ -189,12 +225,21 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.StateHistory != nil { c.StateHistory = *dec.StateHistory } + if dec.TrienodeHistory != nil { + c.TrienodeHistory = *dec.TrienodeHistory + } + if dec.NodeFullValueCheckpoint != nil { + c.NodeFullValueCheckpoint = *dec.NodeFullValueCheckpoint + } if dec.StateScheme != nil { c.StateScheme = *dec.StateScheme } if dec.RequiredBlocks != nil { c.RequiredBlocks = dec.RequiredBlocks } + if dec.SlowBlockThreshold != nil { + c.SlowBlockThreshold = *dec.SlowBlockThreshold + } if dec.SkipBcVersionCheck != nil { c.SkipBcVersionCheck = *dec.SkipBcVersionCheck } @@ -228,6 +273,9 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.FilterLogCacheSize != nil { c.FilterLogCacheSize = *dec.FilterLogCacheSize } + if dec.LogQueryLimit != nil { + c.LogQueryLimit = *dec.LogQueryLimit + } if dec.Miner != nil { c.Miner = *dec.Miner } @@ -243,6 +291,15 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.EnablePreimageRecording != nil { c.EnablePreimageRecording = *dec.EnablePreimageRecording } + if dec.EnableWitnessStats != nil { + c.EnableWitnessStats = *dec.EnableWitnessStats + } + if dec.StatelessSelfValidation != nil { + c.StatelessSelfValidation = *dec.StatelessSelfValidation + } + if dec.EnableStateSizeTracking != nil { + c.EnableStateSizeTracking = *dec.EnableStateSizeTracking + } if dec.VMTrace != nil { c.VMTrace = *dec.VMTrace } @@ -261,8 +318,23 @@ func (c *Config) UnmarshalTOML(unmarshal func(interface{}) error) error { if dec.OverrideOsaka != nil { c.OverrideOsaka = dec.OverrideOsaka } + if dec.OverrideBPO1 != nil { + c.OverrideBPO1 = dec.OverrideBPO1 + } + if dec.OverrideBPO2 != nil { + c.OverrideBPO2 = dec.OverrideBPO2 + } if dec.OverrideVerkle != nil { c.OverrideVerkle = dec.OverrideVerkle } + if dec.TxSyncDefaultTimeout != nil { + c.TxSyncDefaultTimeout = *dec.TxSyncDefaultTimeout + } + if dec.TxSyncMaxTimeout != nil { + c.TxSyncMaxTimeout = *dec.TxSyncMaxTimeout + } + if dec.RangeLimit != nil { + c.RangeLimit = *dec.RangeLimit + } return nil } diff --git a/eth/fetcher/metrics.go b/eth/fetcher/metrics.go new file mode 100644 index 0000000000..fd1678dd30 --- /dev/null +++ b/eth/fetcher/metrics.go @@ -0,0 +1,59 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see 25% of the deliveries in any batch, sleep a bit. - if otherreject > addTxsBatchSize/4 { + if otherreject > int64((len(batch)+3)/4) { + log.Debug("Peer delivering stale or invalid transactions", "peer", peer, "rejected", otherreject) time.Sleep(200 * time.Millisecond) - log.Debug("Peer delivering stale transactions", "peer", peer, "rejected", otherreject) + } + // If we encountered a protocol violation, disconnect this peer. + if violation != nil { + break } } select { - case f.cleanup <- &txDelivery{origin: peer, hashes: added, metas: metas, direct: direct}: + case f.cleanup <- &txDelivery{origin: peer, hashes: added, metas: metas, direct: direct, violation: violation}: return nil case <-f.quit: return errTerminated @@ -635,6 +629,7 @@ func (f *TxFetcher) loop() { } // Keep track of the request as dangling, but never expire f.requests[peer].hashes = nil + txFetcherSlowPeers.Inc(1) } } // Schedule a new transaction retrieval @@ -728,6 +723,10 @@ func (f *TxFetcher) loop() { log.Warn("Unexpected transaction delivery", "peer", delivery.origin) break } + if req.hashes == nil { + txFetcherSlowPeers.Dec(1) + txFetcherSlowWait.Update(time.Duration(f.clock.Now() - req.time).Nanoseconds()) + } delete(f.requests, delivery.origin) // Anything not delivered should be re-scheduled (with or without @@ -771,6 +770,11 @@ func (f *TxFetcher) loop() { // Something was delivered, try to reschedule requests f.scheduleFetches(timeoutTimer, timeoutTrigger, nil) // Partial delivery may enable others to deliver too } + // If we encountered a protocol violation, disconnect the peer + if delivery.violation != nil { + log.Warn("Disconnect peer for protocol violation", "peer", delivery.origin, "error", delivery.violation) + f.dropPeer(delivery.origin) + } case drop := <-f.drop: // A peer was dropped, remove all traces of it @@ -807,6 +811,10 @@ func (f *TxFetcher) loop() { } delete(f.fetching, hash) } + if request.hashes == nil { + txFetcherSlowPeers.Dec(1) + txFetcherSlowWait.Update(time.Duration(f.clock.Now() - request.time).Nanoseconds()) + } delete(f.requests, drop.peer) } // Clean up general announcement tracking @@ -816,6 +824,10 @@ func (f *TxFetcher) loop() { if len(f.announced[hash]) == 0 { delete(f.announced, hash) } + delete(f.alternates[hash], drop.peer) + if len(f.alternates[hash]) == 0 { + delete(f.alternates, hash) + } } delete(f.announces, drop.peer) } @@ -879,7 +891,7 @@ func (f *TxFetcher) rescheduleWait(timer *mclock.Timer, trigger chan struct{}) { // This method is a bit "flaky" "by design". In theory the timeout timer only ever // should be rescheduled if some request is pending. In practice, a timeout will // cause the timer to be rescheduled every 5 secs (until the peer comes through or -// disconnects). This is a limitation of the fetcher code because we don't trac +// disconnects). This is a limitation of the fetcher code because we don't track // pending requests and timed out requests separately. Without double tracking, if // we simply didn't reschedule the timer on all-timeout then the timer would never // be set again since len(request) > 0 => something's running. diff --git a/eth/fetcher/tx_fetcher_test.go b/eth/fetcher/tx_fetcher_test.go index 0f05a1c995..87fbe9f38c 100644 --- a/eth/fetcher/tx_fetcher_test.go +++ b/eth/fetcher/tx_fetcher_test.go @@ -17,6 +17,7 @@ package fetcher import ( + "crypto/sha256" "errors" "math/big" "math/rand" @@ -28,7 +29,10 @@ import ( "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/crypto/kzg4844" "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" ) var ( @@ -83,6 +87,19 @@ type txFetcherTest struct { steps []interface{} } +// newTestTxFetcher creates a tx fetcher with noop callbacks, simulated clock, +// and deterministic randomness. +func newTestTxFetcher() *TxFetcher { + return NewTxFetcher( + func(common.Hash, byte) error { return nil }, + func(txs []*types.Transaction) []error { + return make([]error, len(txs)) + }, + func(string, []common.Hash) error { return nil }, + nil, + ) +} + // Tests that transaction announcements with associated metadata are added to a // waitlist, and none of them are scheduled for retrieval until the wait expires. // @@ -91,14 +108,7 @@ type txFetcherTest struct { // with all the useless extra fields. func TestTransactionFetcherWaiting(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Initial announcement to get something into the waitlist doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 222}}, @@ -293,14 +303,7 @@ func TestTransactionFetcherWaiting(t *testing.T) { // already scheduled. func TestTransactionFetcherSkipWaiting(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Push an initial announcement through to the scheduled stage doTxNotify{ @@ -383,14 +386,7 @@ func TestTransactionFetcherSkipWaiting(t *testing.T) { // and subsequent announces block or get allotted to someone else. func TestTransactionFetcherSingletonRequesting(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Push an initial announcement through to the scheduled stage doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 222}}, @@ -489,15 +485,12 @@ func TestTransactionFetcherFailedRescheduling(t *testing.T) { proceed := make(chan struct{}) testTransactionFetcherParallel(t, txFetcherTest{ init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(origin string, hashes []common.Hash) error { - <-proceed - return errors.New("peer disconnected") - }, - nil, - ) + f := newTestTxFetcher() + f.fetchTxs = func(origin string, hashes []common.Hash) error { + <-proceed + return errors.New("peer disconnected") + } + return f }, steps: []interface{}{ // Push an initial announcement through to the scheduled stage @@ -572,16 +565,7 @@ func TestTransactionFetcherFailedRescheduling(t *testing.T) { // are cleaned up. func TestTransactionFetcherCleanup(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Push an initial announcement through to the scheduled stage doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, @@ -616,16 +600,7 @@ func TestTransactionFetcherCleanup(t *testing.T) { // this was a bug)). func TestTransactionFetcherCleanupEmpty(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Push an initial announcement through to the scheduled stage doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, @@ -659,16 +634,7 @@ func TestTransactionFetcherCleanupEmpty(t *testing.T) { // different peer, or self if they are after the cutoff point. func TestTransactionFetcherMissingRescheduling(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Push an initial announcement through to the scheduled stage doTxNotify{peer: "A", @@ -720,16 +686,7 @@ func TestTransactionFetcherMissingRescheduling(t *testing.T) { // delivered, the peer gets properly cleaned out from the internal state. func TestTransactionFetcherMissingCleanup(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Push an initial announcement through to the scheduled stage doTxNotify{peer: "A", @@ -769,16 +726,7 @@ func TestTransactionFetcherMissingCleanup(t *testing.T) { // Tests that transaction broadcasts properly clean up announcements. func TestTransactionFetcherBroadcasts(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Set up three transactions to be in different stats, waiting, queued and fetching doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, @@ -825,14 +773,7 @@ func TestTransactionFetcherBroadcasts(t *testing.T) { // Tests that the waiting list timers properly reset and reschedule. func TestTransactionFetcherWaitTimerResets(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, isWaiting(map[string][]announce{ @@ -895,16 +836,7 @@ func TestTransactionFetcherWaitTimerResets(t *testing.T) { // out and be re-scheduled for someone else. func TestTransactionFetcherTimeoutRescheduling(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Push an initial announcement through to the scheduled stage doTxNotify{ @@ -973,14 +905,7 @@ func TestTransactionFetcherTimeoutRescheduling(t *testing.T) { // Tests that the fetching timeout timers properly reset and reschedule. func TestTransactionFetcherTimeoutTimerResets(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, doWait{time: txArriveTimeout, step: true}, @@ -1051,14 +976,7 @@ func TestTransactionFetcherRateLimiting(t *testing.T) { }) } testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Announce all the transactions, wait a bit and ensure only a small // percentage gets requested @@ -1081,14 +999,7 @@ func TestTransactionFetcherRateLimiting(t *testing.T) { // be requested at a time, to keep the responses below a reasonable level. func TestTransactionFetcherBandwidthLimiting(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Announce mid size transactions from A to verify that multiple // ones can be piled into a single request. @@ -1198,14 +1109,7 @@ func TestTransactionFetcherDoSProtection(t *testing.T) { }) } testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Announce half of the transaction and wait for them to be scheduled doTxNotify{peer: "A", hashes: hashesA[:maxTxAnnounces/2], types: typesA[:maxTxAnnounces/2], sizes: sizesA[:maxTxAnnounces/2]}, @@ -1266,24 +1170,21 @@ func TestTransactionFetcherDoSProtection(t *testing.T) { func TestTransactionFetcherUnderpricedDedup(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - errs := make([]error, len(txs)) - for i := 0; i < len(errs); i++ { - if i%3 == 0 { - errs[i] = txpool.ErrUnderpriced - } else if i%3 == 1 { - errs[i] = txpool.ErrReplaceUnderpriced - } else { - errs[i] = txpool.ErrTxGasPriceTooLow - } + f := newTestTxFetcher() + f.addTxs = func(txs []*types.Transaction) []error { + errs := make([]error, len(txs)) + for i := 0; i < len(errs); i++ { + if i%3 == 0 { + errs[i] = txpool.ErrUnderpriced + } else if i%3 == 1 { + errs[i] = txpool.ErrReplaceUnderpriced + } else { + errs[i] = txpool.ErrTxGasPriceTooLow } - return errs - }, - func(string, []common.Hash) error { return nil }, - nil, - ) + } + return errs + } + return f }, steps: []interface{}{ // Deliver a transaction through the fetcher, but reject as underpriced @@ -1367,18 +1268,15 @@ func TestTransactionFetcherUnderpricedDoSProtection(t *testing.T) { } testTransactionFetcher(t, txFetcherTest{ init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - errs := make([]error, len(txs)) - for i := 0; i < len(errs); i++ { - errs[i] = txpool.ErrUnderpriced - } - return errs - }, - func(string, []common.Hash) error { return nil }, - nil, - ) + f := newTestTxFetcher() + f.addTxs = func(txs []*types.Transaction) []error { + errs := make([]error, len(txs)) + for i := 0; i < len(errs); i++ { + errs[i] = txpool.ErrUnderpriced + } + return errs + } + return f }, steps: append(steps, []interface{}{ // The preparation of the test has already been done in `steps`, add the last check @@ -1398,16 +1296,7 @@ func TestTransactionFetcherUnderpricedDoSProtection(t *testing.T) { // Tests that unexpected deliveries don't corrupt the internal state. func TestTransactionFetcherOutOfBoundDeliveries(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Deliver something out of the blue isWaiting(nil), @@ -1457,16 +1346,7 @@ func TestTransactionFetcherOutOfBoundDeliveries(t *testing.T) { // live or dangling stages. func TestTransactionFetcherDrop(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Set up a few hashes into various stages doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, @@ -1531,16 +1411,7 @@ func TestTransactionFetcherDrop(t *testing.T) { // available peer. func TestTransactionFetcherDropRescheduling(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Set up a few hashes into various stages doTxNotify{peer: "A", hashes: []common.Hash{{0x01}}, types: []byte{types.LegacyTxType}, sizes: []uint32{111}}, @@ -1578,14 +1449,9 @@ func TestInvalidAnnounceMetadata(t *testing.T) { drop := make(chan string, 2) testTransactionFetcherParallel(t, txFetcherTest{ init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - func(peer string) { drop <- peer }, - ) + f := newTestTxFetcher() + f.dropPeer = func(peer string) { drop <- peer } + return f }, steps: []interface{}{ // Initial announcement to get something into the waitlist @@ -1660,16 +1526,7 @@ func TestInvalidAnnounceMetadata(t *testing.T) { // announced one. func TestTransactionFetcherFuzzCrash01(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Get a transaction into fetching mode and make it dangling with a broadcast doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, @@ -1688,16 +1545,7 @@ func TestTransactionFetcherFuzzCrash01(t *testing.T) { // concurrently announced one. func TestTransactionFetcherFuzzCrash02(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Get a transaction into fetching mode and make it dangling with a broadcast doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, @@ -1718,16 +1566,7 @@ func TestTransactionFetcherFuzzCrash02(t *testing.T) { // with a concurrent notify. func TestTransactionFetcherFuzzCrash03(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Get a transaction into fetching mode and make it dangling with a broadcast doTxNotify{ @@ -1758,17 +1597,12 @@ func TestTransactionFetcherFuzzCrash04(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - func(txs []*types.Transaction) []error { - return make([]error, len(txs)) - }, - func(string, []common.Hash) error { - <-proceed - return errors.New("peer disconnected") - }, - nil, - ) + f := newTestTxFetcher() + f.fetchTxs = func(string, []common.Hash) error { + <-proceed + return errors.New("peer disconnected") + } + return f }, steps: []interface{}{ // Get a transaction into fetching mode and make it dangling with a broadcast @@ -1792,14 +1626,7 @@ func TestTransactionFetcherFuzzCrash04(t *testing.T) { // once they are announced in the network. func TestBlobTransactionAnnounce(t *testing.T) { testTransactionFetcherParallel(t, txFetcherTest{ - init: func() *TxFetcher { - return NewTxFetcher( - func(common.Hash) bool { return false }, - nil, - func(string, []common.Hash) error { return nil }, - nil, - ) - }, + init: newTestTxFetcher, steps: []interface{}{ // Initial announcement to get something into the waitlist doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{types.LegacyTxType, types.LegacyTxType}, sizes: []uint32{111, 222}}, @@ -1858,6 +1685,175 @@ func TestBlobTransactionAnnounce(t *testing.T) { }) } +func TestTransactionFetcherDropAlternates(t *testing.T) { + testTransactionFetcherParallel(t, txFetcherTest{ + init: newTestTxFetcher, + steps: []interface{}{ + doTxNotify{peer: "A", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, + doWait{time: txArriveTimeout, step: true}, + doTxNotify{peer: "B", hashes: []common.Hash{testTxsHashes[0]}, types: []byte{testTxs[0].Type()}, sizes: []uint32{uint32(testTxs[0].Size())}}, + + isScheduled{ + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + }, + "B": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + }, + }, + fetching: map[string][]common.Hash{ + "A": {testTxsHashes[0]}, + }, + }, + doDrop("B"), + + isScheduled{ + tracking: map[string][]announce{ + "A": { + {testTxsHashes[0], testTxs[0].Type(), uint32(testTxs[0].Size())}, + }, + }, + fetching: map[string][]common.Hash{ + "A": {testTxsHashes[0]}, + }, + }, + doDrop("A"), + isScheduled{ + tracking: nil, fetching: nil, + }, + }, + }) +} + +func TestTransactionFetcherWrongMetadata(t *testing.T) { + testTransactionFetcherParallel(t, txFetcherTest{ + init: func() *TxFetcher { + f := newTestTxFetcher() + f.validateMeta = func(name common.Hash, kind byte) error { + switch kind { + case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, types.BlobTxType, types.SetCodeTxType: + return nil + } + return types.ErrTxTypeNotSupported + } + return f + }, + steps: []interface{}{ + doTxNotify{peer: "A", hashes: []common.Hash{{0x01}, {0x02}}, types: []byte{0xff, types.LegacyTxType}, sizes: []uint32{111, 222}}, + isWaiting(map[string][]announce{ + "A": { + {common.Hash{0x02}, types.LegacyTxType, 222}, + }, + }), + }, + }) +} + +func makeInvalidBlobTx() *types.Transaction { + key, _ := crypto.GenerateKey() + blob := &kzg4844.Blob{byte(0xa)} + commitment, _ := kzg4844.BlobToCommitment(blob) + blobHash := kzg4844.CalcBlobHashV1(sha256.New(), &commitment) + cellProof, _ := kzg4844.ComputeCellProofs(blob) + + // Mutate the cell proof + cellProof[0][0] = 0x0 + + blobtx := &types.BlobTx{ + ChainID: uint256.MustFromBig(params.MainnetChainConfig.ChainID), + Nonce: 0, + GasTipCap: uint256.NewInt(100), + GasFeeCap: uint256.NewInt(200), + Gas: 21000, + BlobFeeCap: uint256.NewInt(200), + BlobHashes: []common.Hash{blobHash}, + Value: uint256.NewInt(100), + Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion1, []kzg4844.Blob{*blob}, []kzg4844.Commitment{commitment}, cellProof), + } + return types.MustSignNewTx(key, types.LatestSigner(params.MainnetChainConfig), blobtx) +} + +// This test ensures that the peer will be disconnected for protocol violation +// and all its internal traces should be removed properly. +func TestTransactionProtocolViolation(t *testing.T) { + //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) + + var ( + badTx = makeInvalidBlobTx() + drop = make(chan struct{}, 1) + ) + testTransactionFetcherParallel(t, txFetcherTest{ + init: func() *TxFetcher { + f := newTestTxFetcher() + f.addTxs = func(txs []*types.Transaction) []error { + var errs []error + for range txs { + errs = append(errs, txpool.ErrKZGVerificationError) + } + return errs + } + f.dropPeer = func(string) { drop <- struct{}{} } + return f + }, + steps: []interface{}{ + // Initial announcement to get something into the waitlist + doTxNotify{ + peer: "A", + hashes: []common.Hash{testTxs[0].Hash(), badTx.Hash(), testTxs[1].Hash()}, + types: []byte{types.LegacyTxType, types.BlobTxType, types.LegacyTxType}, + sizes: []uint32{uint32(testTxs[0].Size()), uint32(badTx.Size()), uint32(testTxs[1].Size())}, + }, + isWaiting(map[string][]announce{ + "A": { + {testTxs[0].Hash(), types.LegacyTxType, uint32(testTxs[0].Size())}, + {badTx.Hash(), types.BlobTxType, uint32(badTx.Size())}, + {testTxs[1].Hash(), types.LegacyTxType, uint32(testTxs[1].Size())}, + }, + }), + doWait{time: 0, step: true}, // zero time, but the blob fetching should be scheduled + + isWaiting(map[string][]announce{ + "A": { + {testTxs[0].Hash(), types.LegacyTxType, uint32(testTxs[0].Size())}, + {testTxs[1].Hash(), types.LegacyTxType, uint32(testTxs[1].Size())}, + }, + }), + isScheduled{ + tracking: map[string][]announce{ + "A": { + {badTx.Hash(), types.BlobTxType, uint32(badTx.Size())}, + }, + }, + fetching: map[string][]common.Hash{ + "A": {badTx.Hash()}, + }, + }, + + doTxEnqueue{ + peer: "A", + txs: []*types.Transaction{badTx}, + direct: true, + }, + // Some internal traces are left and will be cleaned by a following drop + // operation. + isWaiting(map[string][]announce{ + "A": { + {testTxs[0].Hash(), types.LegacyTxType, uint32(testTxs[0].Size())}, + {testTxs[1].Hash(), types.LegacyTxType, uint32(testTxs[1].Size())}, + }, + }), + isScheduled{}, + doFunc(func() { <-drop }), + + // Simulate the drop operation emitted by the server + doDrop("A"), + isWaiting(nil), + isScheduled{nil, nil, nil}, + }, + }) +} + func testTransactionFetcherParallel(t *testing.T, tt txFetcherTest) { t.Parallel() testTransactionFetcher(t, tt) @@ -2195,7 +2191,7 @@ func TestTransactionForgotten(t *testing.T) { } fetcher := NewTxFetcherForTests( - func(common.Hash) bool { return false }, + func(common.Hash, byte) error { return nil }, func(txs []*types.Transaction) []error { errs := make([]error, len(txs)) for i := 0; i < len(errs); i++ { diff --git a/eth/filters/api.go b/eth/filters/api.go index c929810a12..f4bed35b26 100644 --- a/eth/filters/api.go +++ b/eth/filters/api.go @@ -35,23 +35,36 @@ import ( ) var ( - errInvalidTopic = errors.New("invalid topic(s)") - errFilterNotFound = errors.New("filter not found") - errInvalidBlockRange = errors.New("invalid block range params") + errInvalidTopic = invalidParamsErr("invalid topic(s)") + errInvalidBlockRange = invalidParamsErr("invalid block range params") + errBlockRangeIntoFuture = invalidParamsErr("block range extends beyond current head block") + errBlockHashWithRange = invalidParamsErr("can't specify fromBlock/toBlock with blockHash") + errPendingLogsUnsupported = invalidParamsErr("pending logs are not supported") errUnknownBlock = errors.New("unknown block") - errBlockHashWithRange = errors.New("can't specify fromBlock/toBlock with blockHash") - errPendingLogsUnsupported = errors.New("pending logs are not supported") + errFilterNotFound = errors.New("filter not found") errExceedMaxTopics = errors.New("exceed max topics") - errExceedMaxAddresses = errors.New("exceed max addresses") + errExceedLogQueryLimit = errors.New("exceed max addresses or topics per search position") + errExceedMaxTxHashes = errors.New("exceed max number of transaction hashes allowed per transactionReceipts subscription") ) +type invalidParamsError struct { + err error +} + +func (e invalidParamsError) Error() string { return e.err.Error() } +func (e invalidParamsError) ErrorCode() int { return -32602 } + +func invalidParamsErr(format string, args ...any) error { + return invalidParamsError{fmt.Errorf(format, args...)} +} + const ( - // The maximum number of addresses allowed in a filter criteria - maxAddresses = 1000 // The maximum number of topic criteria allowed, vm.LOG4 - vm.LOG0 maxTopics = 4 // The maximum number of allowed topics within a topic criteria maxSubTopics = 1000 + // The maximum number of transaction hash criteria allowed in a single subscription + maxTxHashes = 200 ) // filter is a helper struct that holds meta information over the filter type @@ -70,20 +83,24 @@ type filter struct { // FilterAPI offers support to create and manage filters. This will allow external clients to retrieve various // information related to the Ethereum protocol such as blocks, transactions and logs. type FilterAPI struct { - sys *FilterSystem - events *EventSystem - filtersMu sync.Mutex - filters map[rpc.ID]*filter - timeout time.Duration + sys *FilterSystem + events *EventSystem + filtersMu sync.Mutex + filters map[rpc.ID]*filter + timeout time.Duration + logQueryLimit int + rangeLimit uint64 } // NewFilterAPI returns a new FilterAPI instance. func NewFilterAPI(system *FilterSystem) *FilterAPI { api := &FilterAPI{ - sys: system, - events: NewEventSystem(system), - filters: make(map[rpc.ID]*filter), - timeout: system.cfg.Timeout, + sys: system, + events: NewEventSystem(system), + filters: make(map[rpc.ID]*filter), + timeout: system.cfg.Timeout, + logQueryLimit: system.cfg.LogQueryLimit, + rangeLimit: system.cfg.RangeLimit, } go api.timeoutLoop(system.cfg.Timeout) @@ -140,6 +157,7 @@ func (api *FilterAPI) NewPendingTransactionFilter(fullTx *bool) rpc.ID { api.filtersMu.Unlock() go func() { + defer pendingTxSub.Unsubscribe() for { select { case pTx := <-pendingTxs: @@ -214,6 +232,7 @@ func (api *FilterAPI) NewBlockFilter() rpc.ID { api.filtersMu.Unlock() go func() { + defer headerSub.Unsubscribe() for { select { case h := <-headers: @@ -295,6 +314,83 @@ func (api *FilterAPI) Logs(ctx context.Context, crit FilterCriteria) (*rpc.Subsc return rpcSub, nil } +// TransactionReceiptsQuery defines criteria for transaction receipts subscription. +// Same as ethereum.TransactionReceiptsQuery but with UnmarshalJSON() method. +type TransactionReceiptsQuery ethereum.TransactionReceiptsQuery + +// UnmarshalJSON sets *args fields with given data. +func (args *TransactionReceiptsQuery) UnmarshalJSON(data []byte) error { + type input struct { + TransactionHashes []common.Hash `json:"transactionHashes"` + } + + var raw input + if err := json.Unmarshal(data, &raw); err != nil { + return err + } + + args.TransactionHashes = raw.TransactionHashes + return nil +} + +// TransactionReceipts creates a subscription that fires transaction receipts when transactions are included in blocks. +func (api *FilterAPI) TransactionReceipts(ctx context.Context, filter *TransactionReceiptsQuery) (*rpc.Subscription, error) { + notifier, supported := rpc.NotifierFromContext(ctx) + if !supported { + return &rpc.Subscription{}, rpc.ErrNotificationsUnsupported + } + + // Validate transaction hashes limit + if filter != nil && len(filter.TransactionHashes) > maxTxHashes { + return nil, errExceedMaxTxHashes + } + + var ( + rpcSub = notifier.CreateSubscription() + matchedReceipts = make(chan []*ReceiptWithTx) + txHashes []common.Hash + ) + + if filter != nil { + txHashes = filter.TransactionHashes + } + + receiptsSub := api.events.SubscribeTransactionReceipts(txHashes, matchedReceipts) + + go func() { + defer receiptsSub.Unsubscribe() + + signer := types.LatestSigner(api.sys.backend.ChainConfig()) + + for { + select { + case receiptsWithTxs := <-matchedReceipts: + if len(receiptsWithTxs) > 0 { + // Convert to the same format as eth_getTransactionReceipt + marshaledReceipts := make([]map[string]interface{}, len(receiptsWithTxs)) + for i, receiptWithTx := range receiptsWithTxs { + marshaledReceipts[i] = ethapi.MarshalReceipt( + receiptWithTx.Receipt, + receiptWithTx.Receipt.BlockHash, + receiptWithTx.Receipt.BlockNumber.Uint64(), + signer, + receiptWithTx.Transaction, + int(receiptWithTx.Receipt.TransactionIndex), + ) + } + + // Send a batch of tx receipts in one notification + notifier.Notify(rpcSub.ID, marshaledReceipts) + } + case <-rpcSub.Err(): + return + } + } + }() + + return rpcSub, nil +} + // FilterCriteria represents a request to create a new filter. // Same as ethereum.FilterQuery but with UnmarshalJSON() method. type FilterCriteria ethereum.FilterQuery @@ -322,6 +418,7 @@ func (api *FilterAPI) NewFilter(crit FilterCriteria) (rpc.ID, error) { api.filtersMu.Unlock() go func() { + defer logsSub.Unsubscribe() for { select { case l := <-logs: @@ -347,8 +444,15 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type if len(crit.Topics) > maxTopics { return nil, errExceedMaxTopics } - if len(crit.Addresses) > maxAddresses { - return nil, errExceedMaxAddresses + if api.logQueryLimit != 0 { + if len(crit.Addresses) > api.logQueryLimit { + return nil, errExceedLogQueryLimit + } + for _, topics := range crit.Topics { + if len(topics) > api.logQueryLimit { + return nil, errExceedLogQueryLimit + } + } } var filter *Filter @@ -377,7 +481,7 @@ func (api *FilterAPI) GetLogs(ctx context.Context, crit FilterCriteria) ([]*type return nil, &history.PrunedHistoryError{} } // Construct the range filter - filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics) + filter = api.sys.NewRangeFilter(begin, end, crit.Addresses, crit.Topics, api.rangeLimit) } // Run the filter and return all the logs @@ -429,7 +533,7 @@ func (api *FilterAPI) GetFilterLogs(ctx context.Context, id rpc.ID) ([]*types.Lo end = f.crit.ToBlock.Int64() } // Construct the range filter - filter = api.sys.NewRangeFilter(begin, end, f.crit.Addresses, f.crit.Topics) + filter = api.sys.NewRangeFilter(begin, end, f.crit.Addresses, f.crit.Topics, api.rangeLimit) } // Run the filter and return all the logs logs, err := filter.Logs(ctx) @@ -545,9 +649,6 @@ func (args *FilterCriteria) UnmarshalJSON(data []byte) error { // raw.Address can contain a single address or an array of addresses switch rawAddr := raw.Addresses.(type) { case []interface{}: - if len(rawAddr) > maxAddresses { - return errExceedMaxAddresses - } for i, addr := range rawAddr { if strAddr, ok := addr.(string); ok { addr, err := decodeAddress(strAddr) diff --git a/eth/filters/api_test.go b/eth/filters/api_test.go index 2eb3ee97b3..822bc826f6 100644 --- a/eth/filters/api_test.go +++ b/eth/filters/api_test.go @@ -19,7 +19,6 @@ package filters import ( "encoding/json" "fmt" - "strings" "testing" "github.com/ethereum/go-ethereum/common" @@ -183,15 +182,4 @@ func TestUnmarshalJSONNewFilterArgs(t *testing.T) { if len(test7.Topics[2]) != 0 { t.Fatalf("expected 0 topics, got %d topics", len(test7.Topics[2])) } - - // multiple address exceeding max - var test8 FilterCriteria - addresses := make([]string, maxAddresses+1) - for i := 0; i < maxAddresses+1; i++ { - addresses[i] = fmt.Sprintf(`"%s"`, common.HexToAddress(fmt.Sprintf("0x%x", i)).Hex()) - } - vector = fmt.Sprintf(`{"address": [%s]}`, strings.Join(addresses, ", ")) - if err := json.Unmarshal([]byte(vector), &test8); err != errExceedMaxAddresses { - t.Fatal("expected errExceedMaxAddresses, got", err) - } } diff --git a/eth/filters/filter.go b/eth/filters/filter.go index 1a9918d0ee..9915f28128 100644 --- a/eth/filters/filter.go +++ b/eth/filters/filter.go @@ -19,12 +19,14 @@ package filters import ( "context" "errors" + "fmt" "math" "math/big" "slices" "time" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/history" "github.com/ethereum/go-ethereum/core/types" @@ -43,15 +45,17 @@ type Filter struct { begin, end int64 // Range interval if filtering multiple blocks rangeLogsTestHook chan rangeLogsTestEvent + rangeLimit uint64 } // NewRangeFilter creates a new filter which uses a bloom filter on blocks to // figure out whether a particular block is interesting or not. -func (sys *FilterSystem) NewRangeFilter(begin, end int64, addresses []common.Address, topics [][]common.Hash) *Filter { +func (sys *FilterSystem) NewRangeFilter(begin, end int64, addresses []common.Address, topics [][]common.Hash, rangeLimit uint64) *Filter { // Create a generic filter and convert it into a range filter filter := newFilter(sys, addresses, topics) filter.begin = begin filter.end = end + filter.rangeLimit = rangeLimit return filter } @@ -142,6 +146,9 @@ func (f *Filter) Logs(ctx context.Context) ([]*types.Log, error) { if err != nil { return nil, err } + if f.rangeLimit != 0 && (end-begin) > f.rangeLimit { + return nil, fmt.Errorf("exceed maximum block range: %d", f.rangeLimit) + } return f.rangeLogs(ctx, begin, end) } @@ -220,9 +227,12 @@ func (s *searchSession) updateChainView() error { if lastBlock == math.MaxUint64 { lastBlock = head } - if firstBlock > lastBlock || lastBlock > head { + if firstBlock > lastBlock { return errInvalidBlockRange } + if lastBlock > head { + return errBlockRangeIntoFuture + } s.searchRange = common.NewRange(firstBlock, lastBlock+1-firstBlock) // Trim existing match set in case a reorg may have invalidated some results @@ -490,7 +500,7 @@ func (f *Filter) checkMatches(ctx context.Context, header *types.Header) ([]*typ // filterLogs creates a slice of logs matching the given criteria. func filterLogs(logs []*types.Log, fromBlock, toBlock *big.Int, addresses []common.Address, topics [][]common.Hash) []*types.Log { - var check = func(log *types.Log) bool { + check := func(log *types.Log) bool { if fromBlock != nil && fromBlock.Int64() >= 0 && fromBlock.Uint64() > log.BlockNumber { return false } @@ -551,3 +561,52 @@ func bloomFilter(bloom types.Bloom, addresses []common.Address, topics [][]commo } return true } + +// ReceiptWithTx contains a receipt and its corresponding transaction +type ReceiptWithTx struct { + Receipt *types.Receipt + Transaction *types.Transaction +} + +// filterReceipts returns the receipts matching the given criteria +// In addition to returning receipts, it also returns the corresponding transactions. +// This is because receipts only contain low-level data, while user-facing data +// may require additional information from the Transaction. +func filterReceipts(txHashes map[common.Hash]struct{}, ev core.ChainEvent) []*ReceiptWithTx { + var ret []*ReceiptWithTx + + receipts := ev.Receipts + txs := ev.Transactions + + if len(receipts) != len(txs) { + log.Warn("Receipts and transactions length mismatch", "receipts", len(receipts), "transactions", len(txs)) + return ret + } + + if len(txHashes) == 0 { + // No filter, send all receipts with their transactions. + ret = make([]*ReceiptWithTx, len(receipts)) + for i, receipt := range receipts { + ret[i] = &ReceiptWithTx{ + Receipt: receipt, + Transaction: txs[i], + } + } + } else { + for i, receipt := range receipts { + if _, ok := txHashes[receipt.TxHash]; ok { + ret = append(ret, &ReceiptWithTx{ + Receipt: receipt, + Transaction: txs[i], + }) + + // Early exit if all receipts are found + if len(ret) == len(txHashes) { + break + } + } + } + } + + return ret +} diff --git a/eth/filters/filter_system.go b/eth/filters/filter_system.go index 751cd417e8..1f92c4e36f 100644 --- a/eth/filters/filter_system.go +++ b/eth/filters/filter_system.go @@ -41,8 +41,10 @@ import ( // Config represents the configuration of the filter system. type Config struct { - LogCacheSize int // maximum number of cached blocks (default: 32) - Timeout time.Duration // how long filters stay active (default: 5min) + LogCacheSize int // maximum number of cached blocks (default: 32) + Timeout time.Duration // how long filters stay active (default: 5min) + LogQueryLimit int // maximum number of addresses allowed in filter criteria (default: 1000) + RangeLimit uint64 // maximum block range allowed in filter criteria (default: 0) } func (cfg Config) withDefaults() Config { @@ -157,6 +159,8 @@ const ( PendingTransactionsSubscription // BlocksSubscription queries hashes for blocks that are imported BlocksSubscription + // TransactionReceiptsSubscription queries for transaction receipts when transactions are included in blocks + TransactionReceiptsSubscription // LastIndexSubscription keeps track of the last index LastIndexSubscription ) @@ -181,8 +185,10 @@ type subscription struct { logs chan []*types.Log txs chan []*types.Transaction headers chan *types.Header - installed chan struct{} // closed when the filter is installed - err chan error // closed when the filter is uninstalled + receipts chan []*ReceiptWithTx + txHashes map[common.Hash]struct{} // contains transaction hashes for transactionReceipts subscription filtering + installed chan struct{} // closed when the filter is installed + err chan error // closed when the filter is uninstalled } // EventSystem creates subscriptions, processes events and broadcasts them to the @@ -267,6 +273,7 @@ func (sub *Subscription) Unsubscribe() { case <-sub.f.logs: case <-sub.f.txs: case <-sub.f.headers: + case <-sub.f.receipts: } } @@ -291,8 +298,15 @@ func (es *EventSystem) SubscribeLogs(crit ethereum.FilterQuery, logs chan []*typ if len(crit.Topics) > maxTopics { return nil, errExceedMaxTopics } - if len(crit.Addresses) > maxAddresses { - return nil, errExceedMaxAddresses + if es.sys.cfg.LogQueryLimit != 0 { + if len(crit.Addresses) > es.sys.cfg.LogQueryLimit { + return nil, errExceedLogQueryLimit + } + for _, topics := range crit.Topics { + if len(topics) > es.sys.cfg.LogQueryLimit { + return nil, errExceedLogQueryLimit + } + } } var from, to rpc.BlockNumber if crit.FromBlock == nil { @@ -345,6 +359,7 @@ func (es *EventSystem) subscribeLogs(crit ethereum.FilterQuery, logs chan []*typ logs: logs, txs: make(chan []*types.Transaction), headers: make(chan *types.Header), + receipts: make(chan []*ReceiptWithTx), installed: make(chan struct{}), err: make(chan error), } @@ -361,6 +376,7 @@ func (es *EventSystem) SubscribeNewHeads(headers chan *types.Header) *Subscripti logs: make(chan []*types.Log), txs: make(chan []*types.Transaction), headers: headers, + receipts: make(chan []*ReceiptWithTx), installed: make(chan struct{}), err: make(chan error), } @@ -377,6 +393,30 @@ func (es *EventSystem) SubscribePendingTxs(txs chan []*types.Transaction) *Subsc logs: make(chan []*types.Log), txs: txs, headers: make(chan *types.Header), + receipts: make(chan []*ReceiptWithTx), + installed: make(chan struct{}), + err: make(chan error), + } + return es.subscribe(sub) +} + +// SubscribeTransactionReceipts creates a subscription that writes transaction receipts for +// transactions when they are included in blocks. If txHashes is provided, only receipts +// for those specific transaction hashes will be delivered. +func (es *EventSystem) SubscribeTransactionReceipts(txHashes []common.Hash, receipts chan []*ReceiptWithTx) *Subscription { + hashSet := make(map[common.Hash]struct{}, len(txHashes)) + for _, h := range txHashes { + hashSet[h] = struct{}{} + } + sub := &subscription{ + id: rpc.NewID(), + typ: TransactionReceiptsSubscription, + created: time.Now(), + logs: make(chan []*types.Log), + txs: make(chan []*types.Transaction), + headers: make(chan *types.Header), + receipts: receipts, + txHashes: hashSet, installed: make(chan struct{}), err: make(chan error), } @@ -407,6 +447,14 @@ func (es *EventSystem) handleChainEvent(filters filterIndex, ev core.ChainEvent) for _, f := range filters[BlocksSubscription] { f.headers <- ev.Header } + + // Handle transaction receipts subscriptions when a new block is added + for _, f := range filters[TransactionReceiptsSubscription] { + matchedReceipts := filterReceipts(f.txHashes, ev) + if len(matchedReceipts) > 0 { + f.receipts <- matchedReceipts + } + } } // eventLoop (un)installs filters and processes mux events. diff --git a/eth/filters/filter_system_test.go b/eth/filters/filter_system_test.go index 013c1ae527..6f97d5b664 100644 --- a/eth/filters/filter_system_test.go +++ b/eth/filters/filter_system_test.go @@ -31,11 +31,13 @@ import ( "github.com/ethereum/go-ethereum/core/filtermaps" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/internal/ethapi" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/triedb" ) type testBackend struct { @@ -424,7 +426,7 @@ func TestInvalidLogFilterCreation(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - _, sys = newTestFilterSystem(db, Config{}) + _, sys = newTestFilterSystem(db, Config{LogQueryLimit: 1000}) api = NewFilterAPI(sys) ) @@ -435,7 +437,7 @@ func TestInvalidLogFilterCreation(t *testing.T) { 1: {FromBlock: big.NewInt(rpc.PendingBlockNumber.Int64()), ToBlock: big.NewInt(100)}, 2: {FromBlock: big.NewInt(rpc.LatestBlockNumber.Int64()), ToBlock: big.NewInt(100)}, 3: {Topics: [][]common.Hash{{}, {}, {}, {}, {}}}, - 4: {Addresses: make([]common.Address, maxAddresses+1)}, + 4: {Addresses: make([]common.Address, api.logQueryLimit+1)}, } for i, test := range testCases { @@ -455,7 +457,7 @@ func TestInvalidGetLogsRequest(t *testing.T) { BaseFee: big.NewInt(params.InitialBaseFee), } db, blocks, _ = core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 10, func(i int, gen *core.BlockGen) {}) - _, sys = newTestFilterSystem(db, Config{}) + _, sys = newTestFilterSystem(db, Config{LogQueryLimit: 10}) api = NewFilterAPI(sys) blockHash = blocks[0].Hash() unknownBlockHash = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111") @@ -500,8 +502,8 @@ func TestInvalidGetLogsRequest(t *testing.T) { err: errExceedMaxTopics, }, { - f: FilterCriteria{BlockHash: &blockHash, Addresses: make([]common.Address, maxAddresses+1)}, - err: errExceedMaxAddresses, + f: FilterCriteria{BlockHash: &blockHash, Addresses: make([]common.Address, api.logQueryLimit+1)}, + err: errExceedLogQueryLimit, }, } @@ -528,6 +530,92 @@ func TestInvalidGetRangeLogsRequest(t *testing.T) { } } +// TestExceedLogQueryLimit tests getLogs with too many addresses or topics +func TestExceedLogQueryLimit(t *testing.T) { + t.Parallel() + + // Test with custom config (LogQueryLimit = 5 for easier testing) + var ( + db = rawdb.NewMemoryDatabase() + backend, sys = newTestFilterSystem(db, Config{LogQueryLimit: 5}) + api = NewFilterAPI(sys) + gspec = &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{}, + BaseFee: big.NewInt(params.InitialBaseFee), + } + ) + + _, err := gspec.Commit(db, triedb.NewDatabase(db, nil), nil) + if err != nil { + t.Fatal(err) + } + chain, _ := core.GenerateChain(gspec.Config, gspec.ToBlock(), ethash.NewFaker(), db, 1000, func(i int, gen *core.BlockGen) {}) + + options := core.DefaultConfig().WithStateScheme(rawdb.HashScheme) + options.TxLookupLimit = 0 // index all txs + bc, err := core.NewBlockChain(db, gspec, ethash.NewFaker(), options) + if err != nil { + t.Fatal(err) + } + _, err = bc.InsertChain(chain[:600]) + if err != nil { + t.Fatal(err) + } + + backend.startFilterMaps(200, false, filtermaps.RangeTestParams) + defer backend.stopFilterMaps() + + addresses := make([]common.Address, 6) + for i := range addresses { + addresses[i] = common.HexToAddress("0x1234567890123456789012345678901234567890") + } + + topics := make([]common.Hash, 6) + for i := range topics { + topics[i] = common.HexToHash("0x123456789012345678901234567890123456789001234567890012345678901234") + } + + // Test that 5 addresses do not result in error + // Add FromBlock and ToBlock to make it similar to other invalid tests + if _, err := api.GetLogs(context.Background(), FilterCriteria{ + FromBlock: big.NewInt(0), + ToBlock: big.NewInt(100), + Addresses: addresses[:5], + }); err != nil { + t.Errorf("Expected GetLogs with 5 addresses to return with no error, got: %v", err) + } + + // Test that 6 addresses fails with correct error + if _, err := api.GetLogs(context.Background(), FilterCriteria{ + FromBlock: big.NewInt(0), + ToBlock: big.NewInt(100), + Addresses: addresses, + }); err != errExceedLogQueryLimit { + t.Errorf("Expected GetLogs with 6 addresses to return errExceedLogQueryLimit, got: %v", err) + } + + // Test that 5 topics at one position do not result in error + if _, err := api.GetLogs(context.Background(), FilterCriteria{ + FromBlock: big.NewInt(0), + ToBlock: big.NewInt(100), + Addresses: addresses[:1], + Topics: [][]common.Hash{topics[:5]}, + }); err != nil { + t.Errorf("Expected GetLogs with 5 topics at one position to return with no error, got: %v", err) + } + + // Test that 6 topics at one position fails with correct error + if _, err := api.GetLogs(context.Background(), FilterCriteria{ + FromBlock: big.NewInt(0), + ToBlock: big.NewInt(100), + Addresses: addresses[:1], + Topics: [][]common.Hash{topics}, + }); err != errExceedLogQueryLimit { + t.Errorf("Expected GetLogs with 6 topics at one position to return errExceedLogQueryLimit, got: %v", err) + } +} + // TestLogFilter tests whether log filters match the correct logs that are posted to the event feed. func TestLogFilter(t *testing.T) { t.Parallel() @@ -694,3 +782,143 @@ func TestPendingTxFilterDeadlock(t *testing.T) { } } } + +// TestTransactionReceiptsSubscription tests the transaction receipts subscription functionality +func TestTransactionReceiptsSubscription(t *testing.T) { + t.Parallel() + + const txNum = 5 + + // Setup test environment + var ( + db = rawdb.NewMemoryDatabase() + backend, sys = newTestFilterSystem(db, Config{}) + api = NewFilterAPI(sys) + key1, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + addr1 = crypto.PubkeyToAddress(key1.PublicKey) + signer = types.NewLondonSigner(big.NewInt(1)) + genesis = &core.Genesis{ + Alloc: types.GenesisAlloc{addr1: {Balance: big.NewInt(1000000000000000000)}}, // 1 ETH + Config: params.TestChainConfig, + BaseFee: big.NewInt(params.InitialBaseFee), + } + _, chain, _ = core.GenerateChainWithGenesis(genesis, ethash.NewFaker(), 1, func(i int, gen *core.BlockGen) { + // Add transactions to the block + for j := 0; j < txNum; j++ { + toAddr := common.HexToAddress("0xb794f5ea0ba39494ce83a213fffba74279579268") + tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{ + Nonce: uint64(j), + GasPrice: gen.BaseFee(), + Gas: 21000, + To: &toAddr, + Value: big.NewInt(1000), + Data: nil, + }), signer, key1) + gen.AddTx(tx) + } + }) + ) + + // Insert the blocks into the chain + blockchain, err := core.NewBlockChain(db, genesis, ethash.NewFaker(), nil) + if err != nil { + t.Fatalf("failed to create tester chain: %v", err) + } + if n, err := blockchain.InsertChain(chain); err != nil { + t.Fatalf("block %d: failed to insert into chain: %v", n, err) + } + + // Prepare test data + receipts := blockchain.GetReceiptsByHash(chain[0].Hash()) + if receipts == nil { + t.Fatalf("failed to get receipts") + } + + chainEvent := core.ChainEvent{ + Header: chain[0].Header(), + Receipts: receipts, + Transactions: chain[0].Transactions(), + } + + txHashes := make([]common.Hash, txNum) + for i := 0; i < txNum; i++ { + txHashes[i] = chain[0].Transactions()[i].Hash() + } + + testCases := []struct { + name string + filterTxHashes []common.Hash + expectedReceiptTxHashes []common.Hash + expectError bool + }{ + { + name: "no filter - should return all receipts", + filterTxHashes: nil, + expectedReceiptTxHashes: txHashes, + expectError: false, + }, + { + name: "single tx hash filter", + filterTxHashes: []common.Hash{txHashes[0]}, + expectedReceiptTxHashes: []common.Hash{txHashes[0]}, + expectError: false, + }, + { + name: "multiple tx hashes filter", + filterTxHashes: []common.Hash{txHashes[0], txHashes[1], txHashes[2]}, + expectedReceiptTxHashes: []common.Hash{txHashes[0], txHashes[1], txHashes[2]}, + expectError: false, + }, + } + + // Run test cases + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + receiptsChan := make(chan []*ReceiptWithTx) + sub := api.events.SubscribeTransactionReceipts(tc.filterTxHashes, receiptsChan) + + // Send chain event + backend.chainFeed.Send(chainEvent) + + // Wait for receipts + timeout := time.After(1 * time.Second) + var receivedReceipts []*types.Receipt + for { + select { + case receiptsWithTx := <-receiptsChan: + for _, receiptWithTx := range receiptsWithTx { + receivedReceipts = append(receivedReceipts, receiptWithTx.Receipt) + } + case <-timeout: + t.Fatalf("timeout waiting for receipts") + } + if len(receivedReceipts) >= len(tc.expectedReceiptTxHashes) { + break + } + } + + // Verify receipt count + if len(receivedReceipts) != len(tc.expectedReceiptTxHashes) { + t.Errorf("Expected %d receipts, got %d", len(tc.expectedReceiptTxHashes), len(receivedReceipts)) + } + + // Verify specific transaction hashes are present + if tc.expectedReceiptTxHashes != nil { + receivedHashes := make(map[common.Hash]bool) + for _, receipt := range receivedReceipts { + receivedHashes[receipt.TxHash] = true + } + + for _, expectedHash := range tc.expectedReceiptTxHashes { + if !receivedHashes[expectedHash] { + t.Errorf("Expected receipt for tx %x not found", expectedHash) + } + } + } + + // Cleanup + sub.Unsubscribe() + <-sub.Err() + }) + } +} diff --git a/eth/filters/filter_test.go b/eth/filters/filter_test.go index e99b2f6caa..63727200f7 100644 --- a/eth/filters/filter_test.go +++ b/eth/filters/filter_test.go @@ -109,11 +109,8 @@ func benchmarkFilters(b *testing.B, history uint64, noHistory bool) { backend.startFilterMaps(history, noHistory, filtermaps.DefaultParams) defer backend.stopFilterMaps() - b.ResetTimer() - - filter := sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{addr1, addr2, addr3, addr4}, nil) - - for i := 0; i < b.N; i++ { + filter := sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{addr1, addr2, addr3, addr4}, nil, 0) + for b.Loop() { filter.begin = 0 logs, _ := filter.Logs(context.Background()) if len(logs) != 4 { @@ -208,7 +205,7 @@ func testFilters(t *testing.T, history uint64, noHistory bool) { // Hack: GenerateChainWithGenesis creates a new db. // Commit the genesis manually and use GenerateChain. - _, err = gspec.Commit(db, triedb.NewDatabase(db, nil)) + _, err = gspec.Commit(db, triedb.NewDatabase(db, nil), nil) if err != nil { t.Fatal(err) } @@ -320,70 +317,70 @@ func testFilters(t *testing.T, history uint64, noHistory bool) { want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","blockTimestamp":"0x1e","logIndex":"0x0","removed":false}]`, }, { - f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}), + f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{contract}, [][]common.Hash{{hash1, hash2, hash3, hash4}}, 0), want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","blockTimestamp":"0x14","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","blockTimestamp":"0x1e","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","blockTimestamp":"0x2710","logIndex":"0x0","removed":false}]`, }, { - f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}), + f: sys.NewRangeFilter(900, 999, []common.Address{contract}, [][]common.Hash{{hash3}}, 0), }, { - f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}), + f: sys.NewRangeFilter(990, int64(rpc.LatestBlockNumber), []common.Address{contract2}, [][]common.Hash{{hash3}}, 0), want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","blockTimestamp":"0x2706","logIndex":"0x0","removed":false}]`, }, { - f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}), + f: sys.NewRangeFilter(1, 10, []common.Address{contract}, [][]common.Hash{{hash2}, {hash1}}, 0), want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","blockTimestamp":"0x1e","logIndex":"0x0","removed":false}]`, }, { - f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}), + f: sys.NewRangeFilter(1, 10, nil, [][]common.Hash{{hash1, hash2}}, 0), want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xa8028c655b6423204c8edfbc339f57b042d6bec2b6a61145d76b7c08b4cccd42","transactionIndex":"0x0","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","blockTimestamp":"0x14","logIndex":"0x0","removed":false},{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x2","transactionHash":"0xdba3e2ea9a7d690b722d70ee605fd67ba4c00d1d3aecd5cf187a7b92ad8eb3df","transactionIndex":"0x1","blockHash":"0x24417bb49ce44cfad65da68f33b510bf2a129c0d89ccf06acb6958b8585ccf34","blockTimestamp":"0x14","logIndex":"0x1","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696332","0x0000000000000000000000000000000000000000000000000000746f70696331"],"data":"0x","blockNumber":"0x3","transactionHash":"0xdefe471992a07a02acdfbe33edaae22fbb86d7d3cec3f1b8e4e77702fb3acc1d","transactionIndex":"0x0","blockHash":"0x7a7556792ca7d37882882e2b001fe14833eaf81c2c7f865c9c771ec37a024f6b","blockTimestamp":"0x1e","logIndex":"0x0","removed":false}]`, }, { - f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}), + f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}}, 0), }, { - f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil), + f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), []common.Address{common.BytesToAddress([]byte("failmenow"))}, nil, 0), }, { - f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}), + f: sys.NewRangeFilter(0, int64(rpc.LatestBlockNumber), nil, [][]common.Hash{{common.BytesToHash([]byte("fail"))}, {hash1}}, 0), }, { - f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, 0), want: `[{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","blockTimestamp":"0x2710","logIndex":"0x0","removed":false}]`, }, { - f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, 0), want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","blockTimestamp":"0x2706","logIndex":"0x0","removed":false},{"address":"0xfe00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696334"],"data":"0x","blockNumber":"0x3e8","transactionHash":"0x9a87842100a638dfa5da8842b4beda691d2fd77b0c84b57f24ecfa9fb208f747","transactionIndex":"0x0","blockHash":"0xb360bad5265261c075ece02d3bf0e39498a6a76310482cdfd90588748e6c5ee0","blockTimestamp":"0x2710","logIndex":"0x0","removed":false}]`, }, { - f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.FinalizedBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil, 0), want: `[{"address":"0xff00000000000000000000000000000000000000","topics":["0x0000000000000000000000000000000000000000000000000000746f70696333"],"data":"0x","blockNumber":"0x3e7","transactionHash":"0x53e3675800c6908424b61b35a44e51ca4c73ca603e58a65b32c67968b4f42200","transactionIndex":"0x0","blockHash":"0x2e4620a2b426b0612ec6cad9603f466723edaed87f98c9137405dd4f7a2409ff","blockTimestamp":"0x2706","logIndex":"0x0","removed":false}]`, }, { - f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.FinalizedBlockNumber), nil, nil, 0), }, { - f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, 0), err: "safe header not found", }, { - f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.SafeBlockNumber), int64(rpc.SafeBlockNumber), nil, nil, 0), err: "safe header not found", }, { - f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.SafeBlockNumber), nil, nil, 0), err: "safe header not found", }, { - f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, 0), err: errPendingLogsUnsupported.Error(), }, { - f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.LatestBlockNumber), int64(rpc.PendingBlockNumber), nil, nil, 0), err: errPendingLogsUnsupported.Error(), }, { - f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil), + f: sys.NewRangeFilter(int64(rpc.PendingBlockNumber), int64(rpc.LatestBlockNumber), nil, nil, 0), err: errPendingLogsUnsupported.Error(), }, } { @@ -406,7 +403,7 @@ func testFilters(t *testing.T, history uint64, noHistory bool) { } t.Run("timeout", func(t *testing.T) { - f := sys.NewRangeFilter(0, rpc.LatestBlockNumber.Int64(), nil, nil) + f := sys.NewRangeFilter(0, rpc.LatestBlockNumber.Int64(), nil, nil, 0) ctx, cancel := context.WithDeadline(context.Background(), time.Now().Add(-time.Hour)) defer cancel() _, err := f.Logs(ctx) @@ -429,7 +426,7 @@ func TestRangeLogs(t *testing.T) { BaseFee: big.NewInt(params.InitialBaseFee), } ) - _, err := gspec.Commit(db, triedb.NewDatabase(db, nil)) + _, err := gspec.Commit(db, triedb.NewDatabase(db, nil), nil) if err != nil { t.Fatal(err) } @@ -467,7 +464,7 @@ func TestRangeLogs(t *testing.T) { newFilter := func(begin, end int64) { testCase++ event = 0 - filter = sys.NewRangeFilter(begin, end, addresses, nil) + filter = sys.NewRangeFilter(begin, end, addresses, nil, 0) filter.rangeLogsTestHook = make(chan rangeLogsTestEvent) go func(filter *Filter) { filter.Logs(context.Background()) @@ -604,3 +601,39 @@ func TestRangeLogs(t *testing.T) { expEvent(rangeLogsTestReorg, 400, 901) expEvent(rangeLogsTestDone, 0, 0) } + +func TestRangeLimit(t *testing.T) { + db := rawdb.NewMemoryDatabase() + backend, sys := newTestFilterSystem(db, Config{}) + defer db.Close() + + gspec := &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{}, + BaseFee: big.NewInt(params.InitialBaseFee), + } + _, err := gspec.Commit(db, triedb.NewDatabase(db, nil), nil) + if err != nil { + t.Fatal(err) + } + chain, _ := core.GenerateChain(gspec.Config, gspec.ToBlock(), ethash.NewFaker(), db, 10, func(i int, gen *core.BlockGen) {}) + options := core.DefaultConfig().WithStateScheme(rawdb.HashScheme) + options.TxLookupLimit = 0 + bc, err := core.NewBlockChain(db, gspec, ethash.NewFaker(), options) + if err != nil { + t.Fatal(err) + } + _, err = bc.InsertChain(chain) + if err != nil { + t.Fatal(err) + } + backend.startFilterMaps(0, false, filtermaps.DefaultParams) + defer backend.stopFilterMaps() + + // Set rangeLimit to 5, but request a range of 9 (end - begin = 9, from 0 to 9) + filter := sys.NewRangeFilter(0, 9, nil, nil, 5) + _, err = filter.Logs(context.Background()) + if err == nil || !strings.Contains(err.Error(), "exceed maximum block range") { + t.Fatalf("expected range limit error, got %v", err) + } +} diff --git a/eth/handler.go b/eth/handler.go index 033a44b3bb..46634cae88 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -17,21 +17,22 @@ package eth import ( + "cmp" + crand "crypto/rand" "errors" "maps" "math" - "math/big" "slices" "sync" "sync/atomic" "time" + "github.com/dchest/siphash" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/core/txpool" "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/downloader" "github.com/ethereum/go-ethereum/eth/ethconfig" "github.com/ethereum/go-ethereum/eth/fetcher" @@ -91,6 +92,9 @@ type txPool interface { // can decide whether to receive notifications only for newly seen transactions // or also for reorged out ones. SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bool) event.Subscription + + // FilterType returns whether the given tx type is supported by the txPool. + FilterType(kind byte) bool } // handlerConfig is the collection of initialization parameters to create a full @@ -110,18 +114,17 @@ type handlerConfig struct { type handler struct { nodeID enode.ID networkID uint64 - - snapSync atomic.Bool // Flag whether snap sync is enabled (gets disabled if we already have blocks) - synced atomic.Bool // Flag whether we're considered synchronised (enables transaction processing) + synced atomic.Bool // Flag whether we're considered synchronised (enables transaction processing) database ethdb.Database txpool txPool chain *core.BlockChain maxPeers int - downloader *downloader.Downloader - txFetcher *fetcher.TxFetcher - peers *peerSet + downloader *downloader.Downloader + txFetcher *fetcher.TxFetcher + peers *peerSet + txBroadcastKey [16]byte eventMux *event.TypeMux txsCh chan core.NewTxsEvent @@ -153,46 +156,19 @@ func newHandler(config *handlerConfig) (*handler, error) { txpool: config.TxPool, chain: config.Chain, peers: newPeerSet(), + txBroadcastKey: newBroadcastChoiceKey(), requiredBlocks: config.RequiredBlocks, quitSync: make(chan struct{}), handlerDoneCh: make(chan struct{}), handlerStartCh: make(chan struct{}), } - if config.Sync == ethconfig.FullSync { - // The database seems empty as the current block is the genesis. Yet the snap - // block is ahead, so snap sync was enabled for this node at a certain point. - // The scenarios where this can happen is - // * if the user manually (or via a bad block) rolled back a snap sync node - // below the sync point. - // * the last snap sync is not finished while user specifies a full sync this - // time. But we don't have any recent state for full sync. - // In these cases however it's safe to reenable snap sync. - fullBlock, snapBlock := h.chain.CurrentBlock(), h.chain.CurrentSnapBlock() - if fullBlock.Number.Uint64() == 0 && snapBlock.Number.Uint64() > 0 { - h.snapSync.Store(true) - log.Warn("Switch sync mode from full sync to snap sync", "reason", "snap sync incomplete") - } else if !h.chain.HasState(fullBlock.Root) { - h.snapSync.Store(true) - log.Warn("Switch sync mode from full sync to snap sync", "reason", "head state missing") - } - } else { - head := h.chain.CurrentBlock() - if head.Number.Uint64() > 0 && h.chain.HasState(head.Root) { - // Print warning log if database is not empty to run snap sync. - log.Warn("Switch sync mode from snap sync to full sync", "reason", "snap sync complete") - } else { - // If snap sync was requested and our database is empty, grant it - h.snapSync.Store(true) - log.Info("Enabled snap sync", "head", head.Number, "hash", head.Hash()) - } - } + // Construct the downloader (long sync) + h.downloader = downloader.New(config.Database, config.Sync, h.eventMux, h.chain, h.removePeer, h.enableSyncedFeatures) + // If snap sync is requested but snapshots are disabled, fail loudly - if h.snapSync.Load() && (config.Chain.Snapshots() == nil && config.Chain.TrieDB().Scheme() == rawdb.HashScheme) { + if h.downloader.ConfigSyncMode() == ethconfig.SnapSync && (config.Chain.Snapshots() == nil && config.Chain.TrieDB().Scheme() == rawdb.HashScheme) { return nil, errors.New("snap sync not supported with snapshots disabled") } - // Construct the downloader (long sync) - h.downloader = downloader.New(config.Database, h.eventMux, h.chain, h.removePeer, h.enableSyncedFeatures) - fetchTx := func(peer string, hashes []common.Hash) error { p := h.peers.peer(peer) if p == nil { @@ -203,7 +179,18 @@ func newHandler(config *handlerConfig) (*handler, error) { addTxs := func(txs []*types.Transaction) []error { return h.txpool.Add(txs, false) } - h.txFetcher = fetcher.NewTxFetcher(h.txpool.Has, addTxs, fetchTx, h.removePeer) + + validateMeta := func(tx common.Hash, kind byte) error { + if h.txpool.Has(tx) { + return txpool.ErrAlreadyKnown + } + if !h.txpool.FilterType(kind) { + return types.ErrTxTypeNotSupported + } + return nil + } + + h.txFetcher = fetcher.NewTxFetcher(validateMeta, addTxs, fetchTx, h.removePeer) return h, nil } @@ -265,7 +252,7 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { return err } reject := false // reserved peer slots - if h.snapSync.Load() { + if h.downloader.ConfigSyncMode() == ethconfig.SnapSync { if snap == nil { // If we are running snap-sync, we want to reserve roughly half the peer // slots for peers supporting the snap protocol. @@ -352,6 +339,8 @@ func (h *handler) runEthPeer(peer *eth.Peer, handler eth.Handler) error { case <-timeout.C: peer.Log().Warn("Required block challenge timed out, dropping", "addr", peer.RemoteAddr(), "type", peer.Name()) h.removePeer(peer.ID()) + case <-dead: + // Peer handler terminated, abort all goroutines } }(number, hash, req) } @@ -478,58 +467,40 @@ func (h *handler) BroadcastTransactions(txs types.Transactions) { txset = make(map[*ethPeer][]common.Hash) // Set peer->hash to transfer directly annos = make(map[*ethPeer][]common.Hash) // Set peer->hash to announce - ) - // Broadcast transactions to a batch of peers not knowing about it - direct := big.NewInt(int64(math.Sqrt(float64(h.peers.len())))) // Approximate number of peers to broadcast to - if direct.BitLen() == 0 { - direct = big.NewInt(1) - } - total := new(big.Int).Exp(direct, big.NewInt(2), nil) // Stabilise total peer count a bit based on sqrt peers - var ( - signer = types.LatestSigner(h.chain.Config()) // Don't care about chain status, we just need *a* sender - hasher = crypto.NewKeccakState() - hash = make([]byte, 32) + signer = types.LatestSigner(h.chain.Config()) + choice = newBroadcastChoice(h.nodeID, h.txBroadcastKey) + peers = h.peers.all() ) + for _, tx := range txs { - var maybeDirect bool + var directSet map[*ethPeer]struct{} switch { case tx.Type() == types.BlobTxType: blobTxs++ case tx.Size() > txMaxBroadcastSize: largeTxs++ default: - maybeDirect = true + // Get transaction sender address. Here we can ignore any error + // since we're just interested in any value. + txSender, _ := types.Sender(signer, tx) + directSet = choice.choosePeers(peers, txSender) } - // Send the transaction (if it's small enough) directly to a subset of - // the peers that have not received it yet, ensuring that the flow of - // transactions is grouped by account to (try and) avoid nonce gaps. - // - // To do this, we hash the local enode IW with together with a peer's - // enode ID together with the transaction sender and broadcast if - // `sha(self, peer, sender) mod peers < sqrt(peers)`. - for _, peer := range h.peers.peersWithoutTransaction(tx.Hash()) { - var broadcast bool - if maybeDirect { - hasher.Reset() - hasher.Write(h.nodeID.Bytes()) - hasher.Write(peer.Node().ID().Bytes()) - from, _ := types.Sender(signer, tx) // Ignore error, we only use the addr as a propagation target splitter - hasher.Write(from.Bytes()) - - hasher.Read(hash) - if new(big.Int).Mod(new(big.Int).SetBytes(hash), total).Cmp(direct) < 0 { - broadcast = true - } + for _, peer := range peers { + if peer.KnownTransaction(tx.Hash()) { + continue } - if broadcast { + if _, ok := directSet[peer]; ok { + // Send direct. txset[peer] = append(txset[peer], tx.Hash()) } else { + // Send announcement. annos[peer] = append(annos[peer], tx.Hash()) } } } + for peer, hashes := range txset { directCount += len(hashes) peer.AsyncSendTransactions(hashes) @@ -538,7 +509,7 @@ func (h *handler) BroadcastTransactions(txs types.Transactions) { annCount += len(hashes) peer.AsyncSendPooledTransactionHashes(hashes) } - log.Debug("Distributed transactions", "plaintxs", len(txs)-blobTxs-largeTxs, "blobtxs", blobTxs, "largetxs", largeTxs, + log.Trace("Distributed transactions", "plaintxs", len(txs)-blobTxs-largeTxs, "blobtxs", blobTxs, "largetxs", largeTxs, "bcastpeers", len(txset), "bcastcount", directCount, "annpeers", len(annos), "anncount", annCount) } @@ -558,15 +529,7 @@ func (h *handler) txBroadcastLoop() { // enableSyncedFeatures enables the post-sync functionalities when the initial // sync is finished. func (h *handler) enableSyncedFeatures() { - // Mark the local node as synced. h.synced.Store(true) - - // If we were running snap sync and it finished, disable doing another - // round on next sync cycle - if h.snapSync.Load() { - log.Info("Snap sync complete, auto disabling") - h.snapSync.Store(false) - } } // blockRangeState holds the state of the block range update broadcasting mechanism. @@ -592,7 +555,7 @@ func newBlockRangeState(chain *core.BlockChain, typeMux *event.TypeMux) *blockRa return st } -// blockRangeBroadcastLoop announces changes in locally-available block range to peers. +// blockRangeLoop announces changes in locally-available block range to peers. // The range to announce is the range that is available in the store, so it's not just // about imported blocks. func (h *handler) blockRangeLoop(st *blockRangeState) { @@ -604,7 +567,7 @@ func (h *handler) blockRangeLoop(st *blockRangeState) { if ev == nil { continue } - if _, ok := ev.Data.(downloader.StartEvent); ok && h.snapSync.Load() { + if _, ok := ev.Data.(downloader.StartEvent); ok && h.downloader.ConfigSyncMode() == ethconfig.SnapSync { h.blockRangeWhileSnapSyncing(st) } case <-st.headCh: @@ -694,3 +657,62 @@ func (st *blockRangeState) stop() { func (st *blockRangeState) currentRange() eth.BlockRangeUpdatePacket { return *st.next.Load() } + +// broadcastChoice implements a deterministic random choice of peers. This is designed +// specifically for choosing which peer receives a direct broadcast of a transaction. +// +// The choice is made based on the involved p2p node IDs and the transaction sender, +// ensuring that the flow of transactions is grouped by account to (try and) avoid nonce +// gaps. +type broadcastChoice struct { + self enode.ID + key [16]byte + buffer map[*ethPeer]struct{} + tmp []broadcastPeer +} + +type broadcastPeer struct { + p *ethPeer + score uint64 +} + +func newBroadcastChoiceKey() (k [16]byte) { + crand.Read(k[:]) + return k +} + +func newBroadcastChoice(self enode.ID, key [16]byte) *broadcastChoice { + return &broadcastChoice{ + self: self, + key: key, + buffer: make(map[*ethPeer]struct{}), + } +} + +// choosePeers selects the peers that will receive a direct transaction broadcast message. +// Note the return value will only stay valid until the next call to choosePeers. +func (bc *broadcastChoice) choosePeers(peers []*ethPeer, txSender common.Address) map[*ethPeer]struct{} { + // Compute randomized scores. + bc.tmp = slices.Grow(bc.tmp[:0], len(peers))[:len(peers)] + hash := siphash.New(bc.key[:]) + for i, peer := range peers { + hash.Reset() + hash.Write(bc.self[:]) + hash.Write(peer.Peer.Peer.ID().Bytes()) + hash.Write(txSender[:]) + bc.tmp[i] = broadcastPeer{peer, hash.Sum64()} + } + + // Sort by score. + slices.SortFunc(bc.tmp, func(a, b broadcastPeer) int { + return cmp.Compare(a.score, b.score) + }) + + // Take top n. + clear(bc.buffer) + n := int(math.Ceil(math.Sqrt(float64(len(bc.tmp))))) + for i := range n { + bc.buffer[bc.tmp[i].p] = struct{}{} + } + return bc.buffer +} diff --git a/eth/handler_eth_test.go b/eth/handler_eth_test.go index 058a0d5949..1343cae03e 100644 --- a/eth/handler_eth_test.go +++ b/eth/handler_eth_test.go @@ -232,7 +232,7 @@ func testRecvTransactions(t *testing.T, protocol uint) { t.Parallel() // Create a message handler, configure it to accept transactions and watch them - handler := newTestHandler() + handler := newTestHandler(ethconfig.FullSync) defer handler.close() handler.handler.synced.Store(true) // mark synced to accept transactions @@ -284,7 +284,7 @@ func testSendTransactions(t *testing.T, protocol uint) { t.Parallel() // Create a message handler and fill the pool with big transactions - handler := newTestHandler() + handler := newTestHandler(ethconfig.FullSync) defer handler.close() insert := make([]*types.Transaction, 100) @@ -365,13 +365,12 @@ func testTransactionPropagation(t *testing.T, protocol uint) { // Create a source handler to send transactions from and a number of sinks // to receive them. We need multiple sinks since a one-to-one peering would // broadcast all transactions without announcement. - source := newTestHandler() - source.handler.snapSync.Store(false) // Avoid requiring snap, otherwise some will be dropped below + source := newTestHandler(ethconfig.FullSync) defer source.close() sinks := make([]*testHandler, 10) for i := 0; i < len(sinks); i++ { - sinks[i] = newTestHandler() + sinks[i] = newTestHandler(ethconfig.FullSync) defer sinks[i].close() sinks[i].handler.synced.Store(true) // mark synced to accept transactions diff --git a/eth/handler_test.go b/eth/handler_test.go index d0da098430..3470452980 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -17,9 +17,12 @@ package eth import ( + "maps" "math/big" + "math/rand" "sort" "sync" + "testing" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/consensus/ethash" @@ -29,8 +32,11 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth/ethconfig" + "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" + "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/p2p/enode" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/holiman/uint256" @@ -157,6 +163,15 @@ func (p *testTxPool) SubscribeTransactions(ch chan<- core.NewTxsEvent, reorgs bo return p.txFeed.Subscribe(ch) } +// FilterType should check whether the pool supports the given type of transactions. +func (p *testTxPool) FilterType(kind byte) bool { + switch kind { + case types.LegacyTxType, types.AccessListTxType, types.DynamicFeeTxType, types.BlobTxType, types.SetCodeTxType: + return true + } + return false +} + // testHandler is a live implementation of the Ethereum protocol handler, just // preinitialized with some sane testing defaults and the transaction pool mocked // out. @@ -168,13 +183,13 @@ type testHandler struct { } // newTestHandler creates a new handler for testing purposes with no blocks. -func newTestHandler() *testHandler { - return newTestHandlerWithBlocks(0) +func newTestHandler(mode ethconfig.SyncMode) *testHandler { + return newTestHandlerWithBlocks(0, mode) } // newTestHandlerWithBlocks creates a new handler for testing purposes, with a // given number of initial blocks. -func newTestHandlerWithBlocks(blocks int) *testHandler { +func newTestHandlerWithBlocks(blocks int, mode ethconfig.SyncMode) *testHandler { // Create a database pre-initialize with a genesis block db := rawdb.NewMemoryDatabase() gspec := &core.Genesis{ @@ -194,7 +209,7 @@ func newTestHandlerWithBlocks(blocks int) *testHandler { Chain: chain, TxPool: txpool, Network: 1, - Sync: ethconfig.SnapSync, + Sync: mode, BloomCache: 1, }) handler.Start(1000) @@ -212,3 +227,102 @@ func (b *testHandler) close() { b.handler.Stop() b.chain.Stop() } + +func TestBroadcastChoice(t *testing.T) { + self := enode.HexID("1111111111111111111111111111111111111111111111111111111111111111") + choice49 := newBroadcastChoice(self, [16]byte{1}) + choice50 := newBroadcastChoice(self, [16]byte{1}) + + // Create test peers and random tx sender addresses. + rand := rand.New(rand.NewSource(33)) + txsenders := make([]common.Address, 400) + for i := range txsenders { + rand.Read(txsenders[i][:]) + } + peers := createTestPeers(rand, 50) + defer closePeers(peers) + + // Evaluate choice49 first. + expectedCount := 7 // sqrt(49) + var chosen49 = make([]map[*ethPeer]struct{}, len(txsenders)) + for i, txSender := range txsenders { + set := choice49.choosePeers(peers[:49], txSender) + chosen49[i] = maps.Clone(set) + + // Sanity check choices. Here we check that the function selects different peers + // for different transaction senders. + if len(set) != expectedCount { + t.Fatalf("choice49 produced wrong count %d, want %d", len(set), expectedCount) + } + if i > 0 && maps.Equal(set, chosen49[i-1]) { + t.Errorf("choice49 for tx %d is equal to tx %d", i, i-1) + } + } + + // Evaluate choice50 for the same peers and transactions. It should always yield more + // peers than choice49, and the chosen set should be a superset of choice49's. + for i, txSender := range txsenders { + set := choice50.choosePeers(peers[:50], txSender) + if len(set) < len(chosen49[i]) { + t.Errorf("for tx %d, choice50 has less peers than choice49", i) + } + for p := range chosen49[i] { + if _, ok := set[p]; !ok { + t.Errorf("for tx %d, choice50 did not choose peer %v, but choice49 did", i, p.ID()) + } + } + } +} + +func BenchmarkBroadcastChoice(b *testing.B) { + b.Run("50", func(b *testing.B) { + benchmarkBroadcastChoice(b, 50) + }) + b.Run("200", func(b *testing.B) { + benchmarkBroadcastChoice(b, 200) + }) + b.Run("500", func(b *testing.B) { + benchmarkBroadcastChoice(b, 500) + }) +} + +// This measures the overhead of sending one transaction to N peers. +func benchmarkBroadcastChoice(b *testing.B, npeers int) { + rand := rand.New(rand.NewSource(33)) + peers := createTestPeers(rand, npeers) + defer closePeers(peers) + + txsenders := make([]common.Address, b.N) + for i := range txsenders { + rand.Read(txsenders[i][:]) + } + + self := enode.HexID("1111111111111111111111111111111111111111111111111111111111111111") + choice := newBroadcastChoice(self, [16]byte{1}) + + b.ResetTimer() + for i := range b.N { + set := choice.choosePeers(peers, txsenders[i]) + if len(set) == 0 { + b.Fatal("empty result") + } + } +} + +func createTestPeers(rand *rand.Rand, n int) []*ethPeer { + peers := make([]*ethPeer, n) + for i := range peers { + var id enode.ID + rand.Read(id[:]) + p2pPeer := p2p.NewPeer(id, "test", nil) + ep := eth.NewPeer(eth.ETH69, p2pPeer, nil, nil) + peers[i] = ðPeer{Peer: ep} + } + return peers +} + +func closePeers(peers []*ethPeer) { + for _, p := range peers { + p.Close() + } +} diff --git a/eth/peerset.go b/eth/peerset.go index 6b0aff226c..e6f623f90c 100644 --- a/eth/peerset.go +++ b/eth/peerset.go @@ -19,9 +19,10 @@ package eth import ( "errors" "fmt" + "maps" + "slices" "sync" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/eth/protocols/eth" "github.com/ethereum/go-ethereum/eth/protocols/snap" "github.com/ethereum/go-ethereum/p2p" @@ -191,19 +192,12 @@ func (ps *peerSet) peer(id string) *ethPeer { return ps.peers[id] } -// peersWithoutTransaction retrieves a list of peers that do not have a given -// transaction in their set of known hashes. -func (ps *peerSet) peersWithoutTransaction(hash common.Hash) []*ethPeer { +// all returns all current peers. +func (ps *peerSet) all() []*ethPeer { ps.lock.RLock() defer ps.lock.RUnlock() - list := make([]*ethPeer, 0, len(ps.peers)) - for _, p := range ps.peers { - if !p.KnownTransaction(hash) { - list = append(list, p) - } - } - return list + return slices.Collect(maps.Values(ps.peers)) } // len returns if the current number of `eth` peers in the set. Since the `snap` diff --git a/eth/protocols/eth/handlers.go b/eth/protocols/eth/handlers.go index 15ad048bcf..aad3353d88 100644 --- a/eth/protocols/eth/handlers.go +++ b/eth/protocols/eth/handlers.go @@ -494,12 +494,19 @@ func handleTransactions(backend Backend, msg Decoder, peer *Peer) error { if err := msg.Decode(&txs); err != nil { return err } + // Duplicate transactions are not allowed + seen := make(map[common.Hash]struct{}) for i, tx := range txs { // Validate and mark the remote transaction if tx == nil { return fmt.Errorf("Transactions: transaction %d is nil", i) } - peer.markTransaction(tx.Hash()) + hash := tx.Hash() + if _, exists := seen[hash]; exists { + return fmt.Errorf("Transactions: multiple copies of the same hash %v", hash) + } + seen[hash] = struct{}{} + peer.markTransaction(hash) } return backend.Handle(peer, &txs) } @@ -514,12 +521,19 @@ func handlePooledTransactions(backend Backend, msg Decoder, peer *Peer) error { if err := msg.Decode(&txs); err != nil { return err } + // Duplicate transactions are not allowed + seen := make(map[common.Hash]struct{}) for i, tx := range txs.PooledTransactionsResponse { // Validate and mark the remote transaction if tx == nil { return fmt.Errorf("PooledTransactions: transaction %d is nil", i) } - peer.markTransaction(tx.Hash()) + hash := tx.Hash() + if _, exists := seen[hash]; exists { + return fmt.Errorf("PooledTransactions: multiple copies of the same hash %v", hash) + } + seen[hash] = struct{}{} + peer.markTransaction(hash) } requestTracker.Fulfil(peer.id, peer.version, PooledTransactionsMsg, txs.RequestId) diff --git a/eth/protocols/eth/handshake.go b/eth/protocols/eth/handshake.go index 824e49fb2b..bb3d1b8eb4 100644 --- a/eth/protocols/eth/handshake.go +++ b/eth/protocols/eth/handshake.go @@ -22,7 +22,6 @@ import ( "time" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/p2p" @@ -36,7 +35,7 @@ const ( // Handshake executes the eth protocol handshake, negotiating version number, // network IDs, difficulties, head and genesis blocks. -func (p *Peer) Handshake(networkID uint64, chain *core.BlockChain, rangeMsg BlockRangeUpdatePacket) error { +func (p *Peer) Handshake(networkID uint64, chain forkid.Blockchain, rangeMsg BlockRangeUpdatePacket) error { switch p.version { case ETH69: return p.handshake69(networkID, chain, rangeMsg) @@ -47,10 +46,10 @@ func (p *Peer) Handshake(networkID uint64, chain *core.BlockChain, rangeMsg Bloc } } -func (p *Peer) handshake68(networkID uint64, chain *core.BlockChain) error { +func (p *Peer) handshake68(networkID uint64, chain forkid.Blockchain) error { var ( genesis = chain.Genesis() - latest = chain.CurrentBlock() + latest = chain.CurrentHeader() forkID = forkid.NewID(chain.Config(), genesis, latest.Number.Uint64(), latest.Time) forkFilter = forkid.NewFilter(chain) ) @@ -92,10 +91,10 @@ func (p *Peer) readStatus68(networkID uint64, status *StatusPacket68, genesis co return nil } -func (p *Peer) handshake69(networkID uint64, chain *core.BlockChain, rangeMsg BlockRangeUpdatePacket) error { +func (p *Peer) handshake69(networkID uint64, chain forkid.Blockchain, rangeMsg BlockRangeUpdatePacket) error { var ( genesis = chain.Genesis() - latest = chain.CurrentBlock() + latest = chain.CurrentHeader() forkID = forkid.NewID(chain.Config(), genesis, latest.Number.Uint64(), latest.Time) forkFilter = forkid.NewFilter(chain) ) diff --git a/eth/protocols/eth/peer.go b/eth/protocols/eth/peer.go index 40c54a3570..df20c672c0 100644 --- a/eth/protocols/eth/peer.go +++ b/eth/protocols/eth/peer.go @@ -341,7 +341,7 @@ func (p *Peer) RequestReceipts(hashes []common.Hash, sink chan *Response) (*Requ // RequestTxs fetches a batch of transactions from a remote node. func (p *Peer) RequestTxs(hashes []common.Hash) error { - p.Log().Debug("Fetching batch of transactions", "count", len(hashes)) + p.Log().Trace("Fetching batch of transactions", "count", len(hashes)) id := rand.Uint64() requestTracker.Track(p.id, p.version, GetPooledTransactionsMsg, PooledTransactionsMsg, id) diff --git a/eth/protocols/snap/gentrie_test.go b/eth/protocols/snap/gentrie_test.go index 2da4f3c866..5998840b52 100644 --- a/eth/protocols/snap/gentrie_test.go +++ b/eth/protocols/snap/gentrie_test.go @@ -239,7 +239,6 @@ func TestPartialGentree(t *testing.T) { {1, len(entries) - 1}, // no left {2, len(entries) - 1}, // no left {2, len(entries) - 2}, // no left and right - {2, len(entries) - 2}, // no left and right {len(entries) / 2, len(entries) / 2}, // single {0, 0}, // single first {len(entries) - 1, len(entries) - 1}, // single last @@ -348,7 +347,6 @@ func TestGentreeDanglingClearing(t *testing.T) { {1, len(entries) - 1}, // no left {2, len(entries) - 1}, // no left {2, len(entries) - 2}, // no left and right - {2, len(entries) - 2}, // no left and right {len(entries) / 2, len(entries) / 2}, // single {0, 0}, // single first {len(entries) - 1, len(entries) - 1}, // single last diff --git a/eth/protocols/snap/range.go b/eth/protocols/snap/range.go index 8c98c71d50..f32cca8d23 100644 --- a/eth/protocols/snap/range.go +++ b/eth/protocols/snap/range.go @@ -74,8 +74,11 @@ func (r *hashRange) End() common.Hash { // incHash returns the next hash, in lexicographical order (a.k.a plus one) func incHash(h common.Hash) common.Hash { - var a uint256.Int - a.SetBytes32(h[:]) - a.AddUint64(&a, 1) - return common.Hash(a.Bytes32()) + for i := len(h) - 1; i >= 0; i-- { + h[i]++ + if h[i] != 0 { + break + } + } + return h } diff --git a/eth/protocols/snap/sync_test.go b/eth/protocols/snap/sync_test.go index d599e7ecc3..713b358ff8 100644 --- a/eth/protocols/snap/sync_test.go +++ b/eth/protocols/snap/sync_test.go @@ -106,13 +106,13 @@ func BenchmarkHashing(b *testing.B) { } b.Run("old", func(b *testing.B) { b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { old() } }) b.Run("new", func(b *testing.B) { b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { new() } }) @@ -597,7 +597,6 @@ func testSyncBloatedProof(t *testing.T, scheme string) { proof := trienode.NewProofSet() if err := t.accountTrie.Prove(origin[:], proof); err != nil { t.logger.Error("Could not prove origin", "origin", origin, "error", err) - t.logger.Error("Could not prove origin", "origin", origin, "error", err) } // The bloat: add proof of every single element for _, entry := range t.accountValues { diff --git a/eth/sync.go b/eth/sync.go index 61f2b2b376..ddae8443a3 100644 --- a/eth/sync.go +++ b/eth/sync.go @@ -25,7 +25,7 @@ import ( // syncTransactions starts sending all currently pending transactions to the given peer. func (h *handler) syncTransactions(p *eth.Peer) { var hashes []common.Hash - for _, batch := range h.txpool.Pending(txpool.PendingFilter{OnlyPlainTxs: true}) { + for _, batch := range h.txpool.Pending(txpool.PendingFilter{BlobTxs: false}) { for _, tx := range batch { hashes = append(hashes, tx.Hash) } diff --git a/eth/sync_test.go b/eth/sync_test.go index cad3a4732e..509b836f82 100644 --- a/eth/sync_test.go +++ b/eth/sync_test.go @@ -36,17 +36,11 @@ func testSnapSyncDisabling(t *testing.T, ethVer uint, snapVer uint) { t.Parallel() // Create an empty handler and ensure it's in snap sync mode - empty := newTestHandler() - if !empty.handler.snapSync.Load() { - t.Fatalf("snap sync disabled on pristine blockchain") - } + empty := newTestHandler(ethconfig.SnapSync) defer empty.close() // Create a full handler and ensure snap sync ends up disabled - full := newTestHandlerWithBlocks(1024) - if full.handler.snapSync.Load() { - t.Fatalf("snap sync not disabled on non-empty blockchain") - } + full := newTestHandlerWithBlocks(1024, ethconfig.SnapSync) defer full.close() // Sync up the two handlers via both `eth` and `snap` @@ -85,12 +79,20 @@ func testSnapSyncDisabling(t *testing.T, ethVer uint, snapVer uint) { time.Sleep(250 * time.Millisecond) // Check that snap sync was disabled - if err := empty.handler.downloader.BeaconSync(ethconfig.SnapSync, full.chain.CurrentBlock(), nil); err != nil { + if err := empty.handler.downloader.BeaconSync(full.chain.CurrentBlock(), nil); err != nil { t.Fatal("sync failed:", err) } - time.Sleep(time.Second * 5) // Downloader internally has to wait a timer (3s) to be expired before exiting - - if empty.handler.snapSync.Load() { - t.Fatalf("snap sync not disabled after successful synchronisation") + // Downloader internally has to wait for a timer (3s) to be expired before + // exiting. Poll after to determine if sync is disabled. + time.Sleep(time.Second * 3) + for timeout := time.After(time.Second); ; { + select { + case <-timeout: + t.Fatalf("snap sync not disabled after successful synchronisation") + case <-time.After(100 * time.Millisecond): + if empty.handler.downloader.ConfigSyncMode() == ethconfig.FullSync { + return + } + } } } diff --git a/eth/syncer/syncer.go b/eth/syncer/syncer.go index 5c4d2401e9..c0d54b953b 100644 --- a/eth/syncer/syncer.go +++ b/eth/syncer/syncer.go @@ -22,6 +22,7 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/beacon/params" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" @@ -89,6 +90,7 @@ func (s *Syncer) run() { target *types.Header ticker = time.NewTicker(time.Second * 5) ) + defer ticker.Stop() for { select { case req := <-s.request: @@ -99,7 +101,7 @@ func (s *Syncer) run() { ) for { if retries >= 10 { - req.errc <- fmt.Errorf("sync target is not avaibale, %x", req.hash) + req.errc <- fmt.Errorf("sync target is not available, %x", req.hash) break } select { @@ -128,17 +130,43 @@ func (s *Syncer) run() { break } if resync { - req.errc <- s.backend.Downloader().BeaconDevSync(ethconfig.FullSync, target) + if mode := s.backend.Downloader().ConfigSyncMode(); mode != ethconfig.FullSync { + req.errc <- fmt.Errorf("unsupported syncmode %v, please relaunch geth with --syncmode full", mode) + } else { + req.errc <- s.backend.Downloader().BeaconDevSync(target) + } } case <-ticker.C: - if target == nil || !s.exitWhenSynced { + if target == nil { continue } - if block := s.backend.BlockChain().GetBlockByHash(target.Hash()); block != nil { - log.Info("Sync target reached", "number", block.NumberU64(), "hash", block.Hash()) - go s.stack.Close() // async since we need to close ourselves - return + + // Terminate the node if the target has been reached + if s.exitWhenSynced { + if block := s.backend.BlockChain().GetBlockByHash(target.Hash()); block != nil { + log.Info("Sync target reached", "number", block.NumberU64(), "hash", block.Hash()) + go s.stack.Close() // async since we need to close ourselves + return + } + } + + // Set the finalized and safe markers relative to the current head. + // The finalized marker is set two epochs behind the target, + // and the safe marker is set one epoch behind the target. + head := s.backend.BlockChain().CurrentHeader() + if head == nil { + continue + } + if header := s.backend.BlockChain().GetHeaderByNumber(head.Number.Uint64() - params.EpochLength*2); header != nil { + if final := s.backend.BlockChain().CurrentFinalBlock(); final == nil || final.Number.Cmp(header.Number) < 0 { + s.backend.BlockChain().SetFinalized(header) + } + } + if header := s.backend.BlockChain().GetHeaderByNumber(head.Number.Uint64() - params.EpochLength); header != nil { + if safe := s.backend.BlockChain().CurrentSafeBlock(); safe == nil || safe.Number.Cmp(header.Number) < 0 { + s.backend.BlockChain().SetSafe(header) + } } case <-s.closed: diff --git a/eth/tracers/api.go b/eth/tracers/api.go index b50a532b60..5f2f16627a 100644 --- a/eth/tracers/api.go +++ b/eth/tracers/api.go @@ -80,6 +80,7 @@ type StateReleaseFunc func() type Backend interface { HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) + CurrentHeader() *types.Header BlockByHash(ctx context.Context, hash common.Hash) (*types.Block, error) BlockByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Block, error) GetCanonicalTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) @@ -958,7 +959,7 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc // Apply the customization rules if required. if config != nil { - if config.BlockOverrides != nil && config.BlockOverrides.Number.ToInt().Uint64() == h.Number.Uint64()+1 { + if config.BlockOverrides != nil && config.BlockOverrides.Number != nil && config.BlockOverrides.Number.ToInt().Uint64() == h.Number.Uint64()+1 { // Overriding the block number to n+1 is a common way for wallets to // simulate transactions, however without the following fix, a contract // can assert it is being simulated by checking if blockhash(n) == 0x0 and @@ -984,8 +985,8 @@ func (api *API) TraceCall(ctx context.Context, args ethapi.TransactionArgs, bloc return nil, err } var ( - msg = args.ToMessage(blockContext.BaseFee, true, true) - tx = args.ToTransaction(types.LegacyTxType) + msg = args.ToMessage(blockContext.BaseFee, true) + tx = args.ToTransaction(types.DynamicFeeTxType) traceConfig *TraceConfig ) // Lower the basefee to 0 to avoid breaking EVM diff --git a/eth/tracers/api_test.go b/eth/tracers/api_test.go index 7ed2a5936e..609c3f4d8b 100644 --- a/eth/tracers/api_test.go +++ b/eth/tracers/api_test.go @@ -142,6 +142,10 @@ func (b *testBackend) ChainDb() ethdb.Database { return b.chaindb } +func (b *testBackend) CurrentHeader() *types.Header { + return b.chain.CurrentHeader() +} + // teardown releases the associated resources. func (b *testBackend) teardown() { b.chain.Stop() @@ -467,6 +471,20 @@ func TestTraceCall(t *testing.T) { {"pc":0,"op":"NUMBER","gas":24946984,"gasCost":2,"depth":1,"stack":[]}, {"pc":1,"op":"STOP","gas":24946982,"gasCost":0,"depth":1,"stack":["0x1337"]}]}`, }, + // Tests issue #33014 where accessing nil block number override panics. + { + blockNumber: rpc.BlockNumber(0), + call: ethapi.TransactionArgs{ + From: &accounts[0].addr, + To: &accounts[1].addr, + Value: (*hexutil.Big)(big.NewInt(1000)), + }, + config: &TraceCallConfig{ + BlockOverrides: &override.BlockOverrides{}, + }, + expectErr: nil, + expect: `{"gas":21000,"failed":false,"returnValue":"0x","structLogs":[]}`, + }, } for i, testspec := range testSuite { result, err := api.TraceCall(context.Background(), testspec.call, rpc.BlockNumberOrHash{BlockNumber: &testspec.blockNumber}, testspec.config) @@ -527,7 +545,7 @@ func TestTraceTransaction(t *testing.T) { b.AddTx(tx) target = tx.Hash() }) - defer backend.chain.Stop() + defer backend.teardown() api := NewAPI(backend) result, err := api.TraceTransaction(context.Background(), target, nil) if err != nil { @@ -584,7 +602,7 @@ func TestTraceBlock(t *testing.T) { b.AddTx(tx) txHash = tx.Hash() }) - defer backend.chain.Stop() + defer backend.teardown() api := NewAPI(backend) var testSuite = []struct { @@ -681,7 +699,7 @@ func TestTracingWithOverrides(t *testing.T) { signer, accounts[0].key) b.AddTx(tx) }) - defer backend.chain.Stop() + defer backend.teardown() api := NewAPI(backend) randomAccounts := newAccounts(3) type res struct { @@ -1105,6 +1123,7 @@ func TestTraceChain(t *testing.T) { nonce += 1 } }) + defer backend.teardown() backend.refHook = func() { ref.Add(1) } backend.relHook = func() { rel.Add(1) } api := NewAPI(backend) @@ -1212,7 +1231,7 @@ func TestTraceBlockWithBasefee(t *testing.T) { txHash = tx.Hash() baseFee.Set(b.BaseFee()) }) - defer backend.chain.Stop() + defer backend.teardown() api := NewAPI(backend) var testSuite = []struct { @@ -1298,7 +1317,7 @@ func TestStandardTraceBlockToFile(t *testing.T) { b.AddTx(tx) txHashs = append(txHashs, tx.Hash()) }) - defer backend.chain.Stop() + defer backend.teardown() var testSuite = []struct { blockNumber rpc.BlockNumber diff --git a/eth/tracers/internal/tracetest/calltrace_test.go b/eth/tracers/internal/tracetest/calltrace_test.go index 70da34f427..ba0706c598 100644 --- a/eth/tracers/internal/tracetest/calltrace_test.go +++ b/eth/tracers/internal/tracetest/calltrace_test.go @@ -211,11 +211,9 @@ func benchTracer(tracerName string, test *callTracerTest, b *testing.B) { defer state.Close() b.ReportAllocs() - b.ResetTimer() evm := vm.NewEVM(context, state.StateDB, test.Genesis.Config, vm.Config{}) - - for i := 0; i < b.N; i++ { + for b.Loop() { snap := state.StateDB.Snapshot() tracer, err := tracers.DefaultDirectory.New(tracerName, new(tracers.Context), nil, test.Genesis.Config) if err != nil { @@ -321,7 +319,7 @@ func TestInternals(t *testing.T) { byte(vm.LOG0), }, tracer: mkTracer("prestateTracer", nil), - want: fmt.Sprintf(`{"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex), + want: fmt.Sprintf(`{"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600164ffffffffff60016000f560ff6000a0","codeHash":"0x27be17a236425a9b513d736c4bb84eca4505a15564cae640e85558cf4d7ff7bb"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex), }, { // CREATE2 which requires padding memory by prestate tracer @@ -340,7 +338,7 @@ func TestInternals(t *testing.T) { byte(vm.LOG0), }, tracer: mkTracer("prestateTracer", nil), - want: fmt.Sprintf(`{"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600160ff60016000f560ff6000a0"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex), + want: fmt.Sprintf(`{"0x00000000000000000000000000000000deadbeef":{"balance":"0x0","code":"0x6001600052600160ff60016000f560ff6000a0","codeHash":"0x5544040a7fd107ba8164108904724a38fb9c664daae88a5cc53580841e648edf"},"%s":{"balance":"0x1c6bf52634000"}}`, originHex), }, } { t.Run(tc.name, func(t *testing.T) { diff --git a/eth/tracers/internal/tracetest/flat_calltrace_test.go b/eth/tracers/internal/tracetest/flat_calltrace_test.go index d1fa44e9d8..1882ef315e 100644 --- a/eth/tracers/internal/tracetest/flat_calltrace_test.go +++ b/eth/tracers/internal/tracetest/flat_calltrace_test.go @@ -201,7 +201,7 @@ func BenchmarkFlatCallTracer(b *testing.B) { for _, file := range files { filename := strings.TrimPrefix(file, "testdata/call_tracer_flat/") b.Run(camel(strings.TrimSuffix(filename, ".json")), func(b *testing.B) { - for n := 0; n < b.N; n++ { + for b.Loop() { err := flatCallTracerTestRunner("flatCallTracer", filename, "call_tracer_flat", b) if err != nil { b.Fatal(err) diff --git a/eth/tracers/internal/tracetest/prestate_test.go b/eth/tracers/internal/tracetest/prestate_test.go index 29c2834ba2..456d962c69 100644 --- a/eth/tracers/internal/tracetest/prestate_test.go +++ b/eth/tracers/internal/tracetest/prestate_test.go @@ -109,6 +109,9 @@ func testPrestateTracer(tracerName string, dirPath string, t *testing.T) { if err != nil { t.Fatalf("failed to execute transaction: %v", err) } + if vmRet.Failed() { + t.Logf("(warn) transaction failed: %v", vmRet.Err) + } tracer.OnTxEnd(&types.Receipt{GasUsed: vmRet.UsedGas}, nil) // Retrieve the trace result and compare against the expected res, err := tracer.GetResult() diff --git a/eth/tracers/internal/tracetest/selfdestruct_state_test.go b/eth/tracers/internal/tracetest/selfdestruct_state_test.go new file mode 100644 index 0000000000..2c714b6dce --- /dev/null +++ b/eth/tracers/internal/tracetest/selfdestruct_state_test.go @@ -0,0 +1,653 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package tracetest + +import ( + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/consensus" + "github.com/ethereum/go-ethereum/consensus/beacon" + "github.com/ethereum/go-ethereum/consensus/ethash" + "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/core/state" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/params" +) + +// accountState represents the expected final state of an account +type accountState struct { + Balance *big.Int + Nonce uint64 + Code []byte + Exists bool +} + +// selfdestructStateTracer tracks state changes during selfdestruct operations +type selfdestructStateTracer struct { + env *tracing.VMContext + accounts map[common.Address]*accountState +} + +func newSelfdestructStateTracer() *selfdestructStateTracer { + return &selfdestructStateTracer{ + accounts: make(map[common.Address]*accountState), + } +} + +func (t *selfdestructStateTracer) OnTxStart(env *tracing.VMContext, tx *types.Transaction, from common.Address) { + t.env = env +} + +func (t *selfdestructStateTracer) OnTxEnd(receipt *types.Receipt, err error) { + // Nothing to do +} + +func (t *selfdestructStateTracer) getOrCreateAccount(addr common.Address) *accountState { + if acc, ok := t.accounts[addr]; ok { + return acc + } + + // Initialize with current state from statedb + acc := &accountState{ + Balance: t.env.StateDB.GetBalance(addr).ToBig(), + Nonce: t.env.StateDB.GetNonce(addr), + Code: t.env.StateDB.GetCode(addr), + Exists: t.env.StateDB.Exist(addr), + } + t.accounts[addr] = acc + return acc +} + +func (t *selfdestructStateTracer) OnBalanceChange(addr common.Address, prev, new *big.Int, reason tracing.BalanceChangeReason) { + acc := t.getOrCreateAccount(addr) + acc.Balance = new +} + +func (t *selfdestructStateTracer) OnNonceChangeV2(addr common.Address, prev, new uint64, reason tracing.NonceChangeReason) { + acc := t.getOrCreateAccount(addr) + acc.Nonce = new + + // If this is a selfdestruct nonce change, mark account as not existing + if reason == tracing.NonceChangeSelfdestruct { + acc.Exists = false + } +} + +func (t *selfdestructStateTracer) OnCodeChangeV2(addr common.Address, prevCodeHash common.Hash, prevCode []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) { + acc := t.getOrCreateAccount(addr) + acc.Code = code + + // If this is a selfdestruct code change, mark account as not existing + if reason == tracing.CodeChangeSelfDestruct { + acc.Exists = false + } +} + +func (t *selfdestructStateTracer) Hooks() *tracing.Hooks { + return &tracing.Hooks{ + OnTxStart: t.OnTxStart, + OnTxEnd: t.OnTxEnd, + OnBalanceChange: t.OnBalanceChange, + OnNonceChangeV2: t.OnNonceChangeV2, + OnCodeChangeV2: t.OnCodeChangeV2, + } +} + +func (t *selfdestructStateTracer) Accounts() map[common.Address]*accountState { + return t.accounts +} + +// verifyAccountState compares actual and expected account state and reports any mismatches +func verifyAccountState(t *testing.T, addr common.Address, actual, expected *accountState) { + if actual.Balance.Cmp(expected.Balance) != 0 { + t.Errorf("address %s: balance mismatch: have %s, want %s", + addr.Hex(), actual.Balance, expected.Balance) + } + if actual.Nonce != expected.Nonce { + t.Errorf("address %s: nonce mismatch: have %d, want %d", + addr.Hex(), actual.Nonce, expected.Nonce) + } + if len(actual.Code) != len(expected.Code) { + t.Errorf("address %s: code length mismatch: have %d, want %d", + addr.Hex(), len(actual.Code), len(expected.Code)) + } + if actual.Exists != expected.Exists { + t.Errorf("address %s: exists mismatch: have %v, want %v", + addr.Hex(), actual.Exists, expected.Exists) + } +} + +// setupTestBlockchain creates a blockchain with the given genesis and transaction, +// returns the blockchain, the first block, and a statedb at genesis for testing +func setupTestBlockchain(t *testing.T, genesis *core.Genesis, tx *types.Transaction, useBeacon bool) (*core.BlockChain, *types.Block, *state.StateDB) { + var engine consensus.Engine + if useBeacon { + engine = beacon.New(ethash.NewFaker()) + } else { + engine = ethash.NewFaker() + } + + _, blocks, _ := core.GenerateChainWithGenesis(genesis, engine, 1, func(i int, b *core.BlockGen) { + b.AddTx(tx) + }) + db := rawdb.NewMemoryDatabase() + blockchain, err := core.NewBlockChain(db, genesis, engine, nil) + if err != nil { + t.Fatalf("failed to create blockchain: %v", err) + } + if _, err := blockchain.InsertChain(blocks); err != nil { + t.Fatalf("failed to insert chain: %v", err) + } + genesisBlock := blockchain.GetBlockByNumber(0) + if genesisBlock == nil { + t.Fatalf("failed to get genesis block") + } + statedb, err := blockchain.StateAt(genesisBlock.Root()) + if err != nil { + t.Fatalf("failed to get state: %v", err) + } + + return blockchain, blocks[0], statedb +} + +func TestSelfdestructStateTracer(t *testing.T) { + t.Parallel() + + const ( + // Gas limit high enough for all test scenarios (factory creation + multiple calls) + testGasLimit = 500000 + + // Common balance amounts used across tests + testBalanceInitial = 100 // Initial balance for contracts being tested + testBalanceSent = 50 // Amount sent back in sendback tests + testBalanceFactory = 200 // Factory needs extra balance for contract creation + ) + + // Helper to create *big.Int for wei amounts + wei := func(amount int64) *big.Int { + return big.NewInt(amount) + } + + // Test account (transaction sender) + var ( + key, _ = crypto.HexToECDSA("b71c71a67e1177ad4e901695e1b4b9ee17ae16c6668d313eac2f96dbcda3f291") + caller = crypto.PubkeyToAddress(key.PublicKey) + ) + + // Simple selfdestruct test contracts + var ( + contract = common.HexToAddress("0x00000000000000000000000000000000000000bb") + recipient = common.HexToAddress("0x00000000000000000000000000000000000000cc") + ) + // Build selfdestruct code: PUSH20 SELFDESTRUCT + selfdestructCode := []byte{byte(vm.PUSH20)} + selfdestructCode = append(selfdestructCode, recipient.Bytes()...) + selfdestructCode = append(selfdestructCode, byte(vm.SELFDESTRUCT)) + + // Factory test contracts (create-and-destroy pattern) + var ( + factory = common.HexToAddress("0x00000000000000000000000000000000000000ff") + ) + // Factory code: creates a contract with 100 wei and calls it to trigger selfdestruct back to factory + // See selfdestruct_test_contracts/factory.yul for source + // Runtime bytecode compiled with: solc --strict-assembly --evm-version paris factory.yul --bin + // (Using paris to avoid PUSH0 opcode which is not available pre-Shanghai) + var ( + factoryCode = common.Hex2Bytes("6a6133ff6000526002601ef360a81b600052600080808080600b816064f05af100") + createdContractAddr = crypto.CreateAddress(factory, 0) // Address where factory creates the contract + ) + + // Sendback test contracts (A→B→A pattern) + // For the refund test: Coordinator calls A, then B + // A selfdestructs to B, B sends funds back to A + var ( + contractA = common.HexToAddress("0x00000000000000000000000000000000000000aa") + contractB = common.HexToAddress("0x00000000000000000000000000000000000000bb") + coordinator = common.HexToAddress("0x00000000000000000000000000000000000000cc") + ) + // Contract A: if msg.value > 0, accept funds; else selfdestruct to B + // See selfdestruct_test_contracts/contractA.yul for source + // Runtime bytecode compiled with: solc --strict-assembly --evm-version paris contractA.yul --bin + contractACode := common.Hex2Bytes("60003411600a5760bbff5b00") + + // Contract B: sends 50 wei back to contract A + // See selfdestruct_test_contracts/contractB.yul for source + // Runtime bytecode compiled with: solc --strict-assembly --evm-version paris contractB.yul --bin + contractBCode := common.Hex2Bytes("6000808080603260aa5af100") + + // Coordinator: calls A (A selfdestructs to B), then calls B (B sends funds to A) + // See selfdestruct_test_contracts/coordinator.yul for source + // Runtime bytecode compiled with: solc --strict-assembly --evm-version paris coordinator.yul --bin + coordinatorCode := common.Hex2Bytes("60008080808060aa818080808060bb955af1505af100") + + // Factory for create-and-refund test: creates A with 100 wei, calls A, calls B + // See selfdestruct_test_contracts/factoryRefund.yul for source + // Runtime bytecode compiled with: solc --strict-assembly --evm-version paris factoryRefund.yul --bin + var ( + factoryRefund = common.HexToAddress("0x00000000000000000000000000000000000000dd") + factoryRefundCode = common.Hex2Bytes("60008080808060bb78600c600d600039600c6000f3fe60003411600a5760bbff5b0082528180808080601960076064f05af1505af100") + createdContractAddrA = crypto.CreateAddress(factoryRefund, 0) // Address where factory creates contract A + ) + + // Self-destruct-to-self test contracts + var ( + contractSelfDestruct = common.HexToAddress("0x00000000000000000000000000000000000000aa") + coordinatorSendAfter = common.HexToAddress("0x00000000000000000000000000000000000000ee") + ) + // Contract that selfdestructs to self + // See selfdestruct_test_contracts/contractSelfDestruct.yul + contractSelfDestructCode := common.Hex2Bytes("30ff") + + // Coordinator: calls contract (triggers selfdestruct to self), stores balance, sends 50 wei, stores balance again + // See selfdestruct_test_contracts/coordinatorSendAfter.yul + coordinatorSendAfterCode := common.Hex2Bytes("60aa600080808080855af150803160005560008080806032855af1503160015500") + + // Factory with balance checking: creates contract, calls it, checks balances + // See selfdestruct_test_contracts/factorySelfDestructBalanceCheck.yul + var ( + factorySelfDestructBalanceCheck = common.HexToAddress("0x00000000000000000000000000000000000000fd") + factorySelfDestructBalanceCheckCode = common.Hex2Bytes("6e6002600d60003960026000f3fe30ff600052600f60116064f0600080808080855af150803160005560008080806032855af1503160015500") + createdContractAddrSelfBalanceCheck = crypto.CreateAddress(factorySelfDestructBalanceCheck, 0) + ) + + tests := []struct { + name string + description string + targetContract common.Address + genesis *core.Genesis + useBeacon bool + expectedResults map[common.Address]accountState + expectedStorage map[common.Address]map[uint64]*big.Int + }{ + { + name: "pre_6780_existing", + description: "Pre-EIP-6780: Existing contract selfdestructs to recipient. Contract should be destroyed and balance transferred.", + targetContract: contract, + genesis: &core.Genesis{ + Config: params.AllEthashProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + contract: { + Balance: wei(testBalanceInitial), + Code: selfdestructCode, + }, + }, + }, + useBeacon: false, + expectedResults: map[common.Address]accountState{ + contract: { + Balance: wei(0), + Nonce: 0, + Code: []byte{}, + Exists: false, + }, + recipient: { + Balance: wei(testBalanceInitial), // Received contract's balance + Nonce: 0, + Code: []byte{}, + Exists: true, + }, + }, + }, + { + name: "post_6780_existing", + description: "Post-EIP-6780: Existing contract selfdestructs to recipient. Balance transferred but contract NOT destroyed (code/storage remain).", + targetContract: contract, + genesis: &core.Genesis{ + Config: params.AllDevChainProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + contract: { + Balance: wei(testBalanceInitial), + Code: selfdestructCode, + }, + }, + }, + useBeacon: true, + expectedResults: map[common.Address]accountState{ + contract: { + Balance: wei(0), + Nonce: 0, + Code: selfdestructCode, + Exists: true, + }, + recipient: { + Balance: wei(testBalanceInitial), + Nonce: 0, + Code: []byte{}, + Exists: true, + }, + }, + }, + { + name: "pre_6780_create_destroy", + description: "Pre-EIP-6780: Factory creates contract with 100 wei, contract selfdestructs back to factory. Contract destroyed, factory gets refund.", + targetContract: factory, + genesis: &core.Genesis{ + Config: params.AllEthashProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + factory: { + Balance: wei(testBalanceFactory), + Code: factoryCode, + }, + }, + }, + useBeacon: false, + expectedResults: map[common.Address]accountState{ + factory: { + Balance: wei(testBalanceFactory), + Nonce: 1, + Code: factoryCode, + Exists: true, + }, + createdContractAddr: { + Balance: wei(0), + Nonce: 0, + Code: []byte{}, + Exists: false, + }, + }, + }, + { + name: "post_6780_create_destroy", + description: "Post-EIP-6780: Factory creates contract with 100 wei, contract selfdestructs back to factory. Contract destroyed (EIP-6780 exception for same-tx creation).", + targetContract: factory, + genesis: &core.Genesis{ + Config: params.AllDevChainProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + factory: { + Balance: wei(testBalanceFactory), + Code: factoryCode, + }, + }, + }, + useBeacon: true, + expectedResults: map[common.Address]accountState{ + factory: { + Balance: wei(testBalanceFactory), + Nonce: 1, + Code: factoryCode, + Exists: true, + }, + createdContractAddr: { + Balance: wei(0), + Nonce: 0, + Code: []byte{}, + Exists: false, + }, + }, + }, + { + name: "pre_6780_sendback", + description: "Pre-EIP-6780: Contract A selfdestructs sending funds to B, then B sends funds back to A's address. Funds sent to destroyed address are burnt.", + targetContract: coordinator, + genesis: &core.Genesis{ + Config: params.AllEthashProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + contractA: { + Balance: wei(testBalanceInitial), + Code: contractACode, + }, + contractB: { + Balance: wei(0), + Code: contractBCode, + }, + coordinator: { + Code: coordinatorCode, + }, + }, + }, + useBeacon: false, + expectedResults: map[common.Address]accountState{ + contractA: { + Balance: wei(0), + Nonce: 0, + Code: []byte{}, + Exists: false, + }, + contractB: { + // 100 received - 50 sent back + Balance: wei(testBalanceSent), + Nonce: 0, + Code: contractBCode, + Exists: true, + }, + }, + }, + { + name: "post_6780_existing_sendback", + description: "Post-EIP-6780: Existing contract A selfdestructs to B, then B sends funds back to A. Funds are NOT burnt (A still exists post-6780).", + targetContract: coordinator, + genesis: &core.Genesis{ + Config: params.AllDevChainProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + contractA: { + Balance: wei(testBalanceInitial), + Code: contractACode, + }, + contractB: { + Balance: wei(0), + Code: contractBCode, + }, + coordinator: { + Code: coordinatorCode, + }, + }, + }, + useBeacon: true, + expectedResults: map[common.Address]accountState{ + contractA: { + Balance: wei(testBalanceSent), + Nonce: 0, + Code: contractACode, + Exists: true, + }, + contractB: { + Balance: wei(testBalanceSent), + Nonce: 0, + Code: contractBCode, + Exists: true, + }, + }, + }, + { + name: "post_6780_create_destroy_sendback", + description: "Post-EIP-6780: Factory creates A, A selfdestructs to B, B sends funds back to A. Funds are burnt (A was destroyed via EIP-6780 exception).", + targetContract: factoryRefund, + genesis: &core.Genesis{ + Config: params.AllDevChainProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + contractB: { + Balance: wei(0), + Code: contractBCode, + }, + factoryRefund: { + Balance: wei(testBalanceFactory), + Code: factoryRefundCode, + }, + }, + }, + useBeacon: true, + expectedResults: map[common.Address]accountState{ + createdContractAddrA: { + // Funds sent back are burnt! + Balance: wei(0), + Nonce: 0, + Code: []byte{}, + Exists: false, + }, + contractB: { + Balance: wei(testBalanceSent), + Nonce: 0, + Code: contractBCode, + Exists: true, + }, + }, + }, + { + name: "post_6780_existing_to_self", + description: "Post-EIP-6780: Pre-existing contract selfdestructs to itself. Balance NOT burnt (selfdestruct-to-self is no-op for existing contracts).", + targetContract: coordinatorSendAfter, + genesis: &core.Genesis{ + Config: params.AllDevChainProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + contractSelfDestruct: { + Balance: wei(testBalanceInitial), + Code: contractSelfDestructCode, + }, + coordinatorSendAfter: { + Balance: wei(testBalanceInitial), + Code: coordinatorSendAfterCode, + }, + }, + }, + useBeacon: true, + expectedResults: map[common.Address]accountState{ + contractSelfDestruct: { + Balance: wei(150), + Nonce: 0, + Code: contractSelfDestructCode, + Exists: true, + }, + coordinatorSendAfter: { + Balance: wei(testBalanceSent), + Nonce: 0, + Code: coordinatorSendAfterCode, + Exists: true, + }, + }, + expectedStorage: map[common.Address]map[uint64]*big.Int{ + coordinatorSendAfter: { + 0: wei(testBalanceInitial), + 1: wei(150), + }, + }, + }, + { + name: "post_6780_create_destroy_to_self", + description: "Post-EIP-6780: Factory creates contract, contract selfdestructs to itself. Balance IS burnt and contract destroyed (EIP-6780 exception for same-tx creation).", + targetContract: factorySelfDestructBalanceCheck, + genesis: &core.Genesis{ + Config: params.AllDevChainProtocolChanges, + Alloc: types.GenesisAlloc{ + caller: {Balance: big.NewInt(params.Ether)}, + factorySelfDestructBalanceCheck: { + Balance: wei(testBalanceFactory), + Code: factorySelfDestructBalanceCheckCode, + }, + }, + }, + useBeacon: true, + expectedResults: map[common.Address]accountState{ + createdContractAddrSelfBalanceCheck: { + Balance: wei(0), + Nonce: 0, + Code: []byte{}, + Exists: false, + }, + factorySelfDestructBalanceCheck: { + Balance: wei(testBalanceSent), + Nonce: 1, + Code: factorySelfDestructBalanceCheckCode, + Exists: true, + }, + }, + expectedStorage: map[common.Address]map[uint64]*big.Int{ + factorySelfDestructBalanceCheck: { + 0: wei(0), + 1: wei(0), + }, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + t.Parallel() + + var ( + signer = types.HomesteadSigner{} + tx *types.Transaction + err error + ) + + tx, err = types.SignTx(types.NewTx(&types.LegacyTx{ + Nonce: 0, + To: &tt.targetContract, + Value: big.NewInt(0), + Gas: testGasLimit, + GasPrice: big.NewInt(params.InitialBaseFee * 2), + Data: nil, + }), signer, key) + if err != nil { + t.Fatalf("failed to sign transaction: %v", err) + } + + blockchain, block, statedb := setupTestBlockchain(t, tt.genesis, tx, tt.useBeacon) + defer blockchain.Stop() + + tracer := newSelfdestructStateTracer() + hookedState := state.NewHookedState(statedb, tracer.Hooks()) + msg, err := core.TransactionToMessage(tx, signer, nil) + if err != nil { + t.Fatalf("failed to prepare transaction for tracing: %v", err) + } + context := core.NewEVMBlockContext(block.Header(), blockchain, nil) + evm := vm.NewEVM(context, hookedState, tt.genesis.Config, vm.Config{Tracer: tracer.Hooks()}) + usedGas := uint64(0) + _, err = core.ApplyTransactionWithEVM(msg, new(core.GasPool).AddGas(tx.Gas()), statedb, block.Number(), block.Hash(), block.Time(), tx, &usedGas, evm) + if err != nil { + t.Fatalf("failed to execute transaction: %v", err) + } + + results := tracer.Accounts() + + // Verify storage + for addr, expectedSlots := range tt.expectedStorage { + for slot, expectedValue := range expectedSlots { + actualValue := statedb.GetState(addr, common.BigToHash(big.NewInt(int64(slot)))) + if actualValue.Big().Cmp(expectedValue) != 0 { + t.Errorf("address %s slot %d: storage mismatch: have %s, want %s", + addr.Hex(), slot, actualValue.Big(), expectedValue) + } + } + } + + // Verify results + for addr, expected := range tt.expectedResults { + actual, ok := results[addr] + if !ok { + t.Errorf("address %s missing from results", addr.Hex()) + continue + } + verifyAccountState(t, addr, actual, &expected) + } + }) + } +} diff --git a/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractA.yul b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractA.yul new file mode 100644 index 0000000000..109551f26e --- /dev/null +++ b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractA.yul @@ -0,0 +1,18 @@ +object "ContractA" { + code { + datacopy(0, dataoffset("Runtime"), datasize("Runtime")) + return(0, datasize("Runtime")) + } + object "Runtime" { + code { + // If receiving funds (msg.value > 0), just accept them and return + if gt(callvalue(), 0) { + stop() + } + + // Otherwise, selfdestruct to B (transfers balance immediately, then stops execution) + let contractB := 0x00000000000000000000000000000000000000bb + selfdestruct(contractB) + } + } +} diff --git a/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractB.yul b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractB.yul new file mode 100644 index 0000000000..c737355fb6 --- /dev/null +++ b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractB.yul @@ -0,0 +1,14 @@ +object "ContractB" { + code { + datacopy(0, dataoffset("Runtime"), datasize("Runtime")) + return(0, datasize("Runtime")) + } + object "Runtime" { + code { + // Send 50 wei back to contract A + let contractA := 0x00000000000000000000000000000000000000aa + let success := call(gas(), contractA, 50, 0, 0, 0, 0) + stop() + } + } +} diff --git a/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractSelfDestruct.yul b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractSelfDestruct.yul new file mode 100644 index 0000000000..73884c5dd4 --- /dev/null +++ b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/contractSelfDestruct.yul @@ -0,0 +1,12 @@ +object "ContractSelfDestruct" { + code { + datacopy(0, dataoffset("Runtime"), datasize("Runtime")) + return(0, datasize("Runtime")) + } + object "Runtime" { + code { + // Simply selfdestruct to self + selfdestruct(address()) + } + } +} diff --git a/eth/tracers/internal/tracetest/selfdestruct_test_contracts/coordinator.yul b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/coordinator.yul new file mode 100644 index 0000000000..54bd5c08f3 --- /dev/null +++ b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/coordinator.yul @@ -0,0 +1,20 @@ +object "Coordinator" { + code { + datacopy(0, dataoffset("Runtime"), datasize("Runtime")) + return(0, datasize("Runtime")) + } + object "Runtime" { + code { + let contractA := 0x00000000000000000000000000000000000000aa + let contractB := 0x00000000000000000000000000000000000000bb + + // First, call A (A will selfdestruct to B) + pop(call(gas(), contractA, 0, 0, 0, 0, 0)) + + // Then, call B (B will send funds back to A) + pop(call(gas(), contractB, 0, 0, 0, 0, 0)) + + stop() + } + } +} diff --git a/eth/tracers/internal/tracetest/selfdestruct_test_contracts/coordinatorSendAfter.yul b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/coordinatorSendAfter.yul new file mode 100644 index 0000000000..9473d1f3ef --- /dev/null +++ b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/coordinatorSendAfter.yul @@ -0,0 +1,27 @@ +object "CoordinatorSendAfter" { + code { + datacopy(0, dataoffset("Runtime"), datasize("Runtime")) + return(0, datasize("Runtime")) + } + object "Runtime" { + code { + let contractAddr := 0x00000000000000000000000000000000000000aa + + // Call contract (triggers selfdestruct to self, burning its balance) + pop(call(gas(), contractAddr, 0, 0, 0, 0, 0)) + + // Check contract's balance immediately after selfdestruct + // Store in slot 0 to verify it's 0 (proving immediate burn) + sstore(0, balance(contractAddr)) + + // Send 50 wei to the contract (after it selfdestructed) + pop(call(gas(), contractAddr, 50, 0, 0, 0, 0)) + + // Check balance again after sending funds + // Store in slot 1 to verify it's 50 (new funds not burnt) + sstore(1, balance(contractAddr)) + + stop() + } + } +} diff --git a/eth/tracers/internal/tracetest/selfdestruct_test_contracts/factoryRefund.yul b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/factoryRefund.yul new file mode 100644 index 0000000000..f52a46fcc3 --- /dev/null +++ b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/factoryRefund.yul @@ -0,0 +1,28 @@ +object "FactoryRefund" { + code { + datacopy(0, dataoffset("Runtime"), datasize("Runtime")) + return(0, datasize("Runtime")) + } + object "Runtime" { + code { + let contractB := 0x00000000000000000000000000000000000000bb + + // Store the deploy bytecode for contract A in memory + // Full deploy bytecode from: solc --strict-assembly --evm-version paris contractA.yul --bin + // Including the 0xfe separator: 600c600d600039600c6000f3fe60003411600a5760bbff5b00 + // That's 25 bytes, padded to 32 bytes with 7 zero bytes at the front + mstore(0, 0x0000000000000000000000000000600c600d600039600c6000f3fe60003411600a5760bbff5b00) + + // CREATE contract A with 100 wei, using 25 bytes starting at position 7 + let contractA := create(100, 7, 25) + + // Call contract A (triggers selfdestruct to B) + pop(call(gas(), contractA, 0, 0, 0, 0, 0)) + + // Call contract B (B sends 50 wei back to A) + pop(call(gas(), contractB, 0, 0, 0, 0, 0)) + + stop() + } + } +} diff --git a/eth/tracers/internal/tracetest/selfdestruct_test_contracts/factorySelfDestructBalanceCheck.yul b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/factorySelfDestructBalanceCheck.yul new file mode 100644 index 0000000000..46f4628419 --- /dev/null +++ b/eth/tracers/internal/tracetest/selfdestruct_test_contracts/factorySelfDestructBalanceCheck.yul @@ -0,0 +1,35 @@ +object "FactorySelfDestructBalanceCheck" { + code { + datacopy(0, dataoffset("Runtime"), datasize("Runtime")) + return(0, datasize("Runtime")) + } + object "Runtime" { + code { + // Get the full deploy bytecode for ContractSelfDestruct + // Compiled with: solc --strict-assembly --evm-version paris contractSelfDestruct.yul --bin + // Full bytecode: 6002600d60003960026000f3fe30ff + // That's 15 bytes total, padded to 32 bytes with 17 zero bytes at front + mstore(0, 0x0000000000000000000000000000000000000000006002600d60003960026000f3fe30ff) + + // CREATE contract with 100 wei, using deploy bytecode + // The bytecode is 15 bytes, starts at position 17 in the 32-byte word + let contractAddr := create(100, 17, 15) + + // Call the created contract (triggers selfdestruct to self) + pop(call(gas(), contractAddr, 0, 0, 0, 0, 0)) + + // Check contract's balance immediately after selfdestruct + // Store in slot 0 to verify it's 0 (proving immediate burn) + sstore(0, balance(contractAddr)) + + // Send 50 wei to the contract (after it selfdestructed) + pop(call(gas(), contractAddr, 50, 0, 0, 0, 0)) + + // Check balance again after sending funds + // Store in slot 1 to verify it's 0 (funds sent to destroyed contract are burnt) + sstore(1, balance(contractAddr)) + + stop() + } + } +} diff --git a/eth/tracers/internal/tracetest/supply_test.go b/eth/tracers/internal/tracetest/supply_test.go index 8aedc9d564..2b5a8212aa 100644 --- a/eth/tracers/internal/tracetest/supply_test.go +++ b/eth/tracers/internal/tracetest/supply_test.go @@ -77,7 +77,7 @@ func TestSupplyOmittedFields(t *testing.T) { out, _, err := testSupplyTracer(t, gspec, func(b *core.BlockGen) { b.SetPoS() - }) + }, 1) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -120,7 +120,7 @@ func TestSupplyGenesisAlloc(t *testing.T) { ParentHash: common.HexToHash("0x0000000000000000000000000000000000000000000000000000000000000000"), } - out, _, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc) + out, _, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc, 1) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -148,7 +148,55 @@ func TestSupplyRewards(t *testing.T) { ParentHash: common.HexToHash("0xadeda0a83e337b6c073e3f0e9a17531a04009b397a9588c093b628f21b8bc5a3"), } - out, _, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc) + out, _, err := testSupplyTracer(t, gspec, emptyBlockGenerationFunc, 1) + if err != nil { + t.Fatalf("failed to test supply tracer: %v", err) + } + + actual := out[expected.Number] + + compareAsJSON(t, expected, actual) +} + +func TestSupplyRewardsWithUncle(t *testing.T) { + var ( + config = *params.AllEthashProtocolChanges + + gspec = &core.Genesis{ + Config: &config, + } + ) + + // Base reward for the miner + baseReward := ethash.ConstantinopleBlockReward.ToBig() + // Miner reward for uncle inclusion is 1/32 of the base reward + uncleInclusionReward := new(big.Int).Rsh(baseReward, 5) + // Uncle miner reward for an uncle that is 1 block behind is 7/8 of the base reward + uncleReward := big.NewInt(7) + uncleReward.Mul(uncleReward, baseReward).Rsh(uncleReward, 3) + + totalReward := baseReward.Add(baseReward, uncleInclusionReward).Add(baseReward, uncleReward) + + expected := supplyInfo{ + Issuance: &supplyInfoIssuance{ + Reward: (*hexutil.Big)(totalReward), + }, + Number: 3, + Hash: common.HexToHash("0x0737d31f8671c18d32b5143833cfa600e4264df62324c9de569668c6de9eed6d"), + ParentHash: common.HexToHash("0x45af6557df87719cb3c7e6f8a98b61508ea74a797733191aececb4c2ec802447"), + } + + // Generate a new chain where block 3 includes an uncle + uncleGenerationFunc := func(b *core.BlockGen) { + if b.Number().Uint64() == 3 { + prevBlock := b.PrevBlock(1) // Block 2 + uncle := types.CopyHeader(prevBlock.Header()) + uncle.Extra = []byte("uncle!") + b.AddUncle(uncle) + } + } + + out, _, err := testSupplyTracer(t, gspec, uncleGenerationFunc, 3) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -195,7 +243,7 @@ func TestSupplyEip1559Burn(t *testing.T) { b.AddTx(tx) } - out, chain, err := testSupplyTracer(t, gspec, eip1559BlockGenerationFunc) + out, chain, err := testSupplyTracer(t, gspec, eip1559BlockGenerationFunc, 1) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -238,7 +286,7 @@ func TestSupplyWithdrawals(t *testing.T) { }) } - out, chain, err := testSupplyTracer(t, gspec, withdrawalsBlockGenerationFunc) + out, chain, err := testSupplyTracer(t, gspec, withdrawalsBlockGenerationFunc, 1) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -318,7 +366,7 @@ func TestSupplySelfdestruct(t *testing.T) { } // 1. Test pre Cancun - preCancunOutput, preCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + preCancunOutput, preCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc, 1) if err != nil { t.Fatalf("Pre-cancun failed to test supply tracer: %v", err) } @@ -360,7 +408,7 @@ func TestSupplySelfdestruct(t *testing.T) { gspec.Config.CancunTime = &cancunTime gspec.Config.BlobScheduleConfig = params.DefaultBlobSchedule - postCancunOutput, postCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + postCancunOutput, postCancunChain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc, 1) if err != nil { t.Fatalf("Post-cancun failed to test supply tracer: %v", err) } @@ -500,7 +548,7 @@ func TestSupplySelfdestructItselfAndRevert(t *testing.T) { b.AddTx(tx) } - output, chain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc) + output, chain, err := testSupplyTracer(t, gspec, testBlockGenerationFunc, 1) if err != nil { t.Fatalf("failed to test supply tracer: %v", err) } @@ -542,7 +590,7 @@ func TestSupplySelfdestructItselfAndRevert(t *testing.T) { compareAsJSON(t, expected, actual) } -func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockGen)) ([]supplyInfo, *core.BlockChain, error) { +func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(b *core.BlockGen), numBlocks int) ([]supplyInfo, *core.BlockChain, error) { engine := beacon.New(ethash.NewFaker()) traceOutputPath := filepath.ToSlash(t.TempDir()) @@ -562,7 +610,7 @@ func testSupplyTracer(t *testing.T, genesis *core.Genesis, gen func(*core.BlockG } defer chain.Stop() - _, blocks, _ := core.GenerateChainWithGenesis(genesis, engine, 1, func(i int, b *core.BlockGen) { + _, blocks, _ := core.GenerateChainWithGenesis(genesis, engine, numBlocks, func(i int, b *core.BlockGen) { b.SetCoinbase(common.Address{1}) gen(b) }) diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/7702_delegate.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/7702_delegate.json index 14874dcc07..a86c289c3f 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/7702_delegate.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/7702_delegate.json @@ -67,26 +67,23 @@ }, "config": { "chainId": 1, - "homesteadBlock": 1150000, - "daoForkBlock": 1920000, - "daoForkSupport": true, - "eip150Block": 2463000, - "eip155Block": 2675000, - "eip158Block": 2675000, - "byzantiumBlock": 4370000, - "constantinopleBlock": 7280000, - "petersburgBlock": 7280000, - "istanbulBlock": 9069000, - "muirGlacierBlock": 9200000, - "berlinBlock": 12244000, - "londonBlock": 12965000, - "arrowGlacierBlock": 13773000, - "grayGlacierBlock": 15050000, - "shanghaiTime": 1681338455, - "cancunTime": 1710338135, - "pragueTime": 1746612311, - "terminalTotalDifficulty": 58750000000000000000000, - "depositContractAddress": "0x00000000219ab540356cbb839cbe05303d7705fa", + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "muirGlacierBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "arrowGlacierBlock": 0, + "grayGlacierBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "pragueTime": 0, + "terminalTotalDifficulty": 0, "ethash": {}, "blobSchedule": { "cancun": { @@ -113,23 +110,58 @@ "input": "0x04f8ec0182075f830f424084714d24d7830493e09417816e9a858b161c3e37016d139cf618056cacd480a000000000000000000000000000000000000000000000000316580c3ab7e66cc4c0f85ef85c0194b684710e6d5914ad6e64493de2a3c424cc43e970823dc101a02f15ba55009fcd3682cd0f9c9645dd94e616f9a969ba3f1a5a2d871f9fe0f2b4a053c332a83312d0b17dd4c16eeb15b1ff5223398b14e0a55c70762e8f3972b7a580a02aceec9737d2a211c79aff3dbd4bf44a5cdabbdd6bbe19ff346a89d94d61914aa062e92842bfe7d2f3ff785c594c70fafafcb180fb32a774de1b92c588be8cd87b", "result": { "0x17816e9a858b161c3e37016d139cf618056cacd4": { - "balance": "0x0", - "code": "0xef0100b684710e6d5914ad6e64493de2a3c424cc43e970", - "nonce": 15809 + "balance": "0x0", + "code": "0xef0100b684710e6d5914ad6e64493de2a3c424cc43e970", + "codeHash":"0xca4cab497827c53a640924e1f7ebb69c3280f8ce8cef2d1d2f9a3707def2a856", + "nonce": 15809 + }, + "0x236501327e701692a281934230af0b6be8df3353": { + "balance": "0x0", + "code": "0x6080604052600a600c565b005b60186014601a565b605e565b565b600060597f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc5473ffffffffffffffffffffffffffffffffffffffff1690565b905090565b3660008037600080366000845af43d6000803e808015607c573d6000f35b3d6000fdfea26469706673582212200b737106e31d6abde738d261a4c4f12fcdfac5141ebc6ab5ffe4cf6e1630aaed64736f6c63430008140033", + "codeHash": "0x297bbcbd2b9ae035f750536c62603b5b7240c69b04fe22eec21cf6fcbb61179f", + "nonce": 1, + "storage": { + "0x078d9cc432fb3eab476f678ef9a73d8ca570f23897c68eb99b2721ebf46e5a9e": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000bdb50eff425fb2b1b67fea21b8420eeb6d99ccc0", + "0x5555c0547520ec9521cc3134a71677625cdeb6accbb330321dcaf2cbc22c1fe9": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x84fdd52031be5dc8bcfa0ffd090a0bf85ef922e1fa9d026be0cf5716edafb4db": "0x0000000000000000000000000000000000000000007b74591c97f086c1057bee", + "0x8c854b3845c254f768d5435bc89fa04fb52bd2f72a1cf4370b962cf104ecd5fc": "0x0000000000000000000000000000000000000000000000000000000000000000", + "0xc45aef11733ee3a84cf02368a8b99ca24b1e3bfc2f5f532a1a2439aa077d2843": "0x000000000000000000000000000000000000000000000738cda8f7729a2a8a1e", + "0xda699a88dd51ba5e1d66c40fd985a4ad1511875941c3dd2936300679d596ab7b": "0x0000000000000000000000000000000000000000000000000000000000000000" + } }, "0x4838b106fce9647bdf1e7877bf73ce8b0bad5f97": { - "balance": "0x8c2e6837fe7fb165", - "nonce": 1874580 + "balance": "0x8c2e6837fe7fb165", + "nonce": 1874580 }, "0xb684710e6d5914ad6e64493de2a3c424cc43e970": { - "balance": "0x0", - "code": "0x60806040525f4711156100b6575f3273ffffffffffffffffffffffffffffffffffffffff16476040516100319061048b565b5f6040518083038185875af1925050503d805f811461006b576040519150601f19603f3d011682016040523d82523d5f602084013e610070565b606091505b50509050806100b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100ab906104f9565b60405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80166001336100da9190610563565b73ffffffffffffffffffffffffffffffffffffffff161115610131576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610128906105f4565b60405180910390fd5b73b9df4a9ba45917e71d664d51462d46926e4798e873ffffffffffffffffffffffffffffffffffffffff166001336101699190610563565b73ffffffffffffffffffffffffffffffffffffffff160361045c575f8036906101929190610631565b5f1c90505f73cda6461f1a30c618373f5790a83e1569fb685cba73ffffffffffffffffffffffffffffffffffffffff16631f3a71ba306040518263ffffffff1660e01b81526004016101e491906106af565b602060405180830381865afa1580156101ff573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061022391906106ff565b90508181106104595773cda6461f1a30c618373f5790a83e1569fb685cba73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb5f836040518363ffffffff1660e01b815260040161027b929190610739565b6020604051808303815f875af1158015610297573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102bb9190610795565b6102fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102f1906104f9565b60405180910390fd5b5f73236501327e701692a281934230af0b6be8df335373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161034891906106af565b602060405180830381865afa158015610363573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061038791906106ff565b905073236501327e701692a281934230af0b6be8df335373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb32836040518363ffffffff1660e01b81526004016103d8929190610739565b6020604051808303815f875af11580156103f4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104189190610795565b610457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161044e9061080a565b60405180910390fd5b505b50505b005b5f81905092915050565b50565b5f6104765f8361045e565b915061048182610468565b5f82019050919050565b5f6104958261046b565b9150819050919050565b5f82825260208201905092915050565b7f5472616e73666572206661696c656400000000000000000000000000000000005f82015250565b5f6104e3600f8361049f565b91506104ee826104af565b602082019050919050565b5f6020820190508181035f830152610510816104d7565b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61056d82610517565b915061057883610517565b9250828201905073ffffffffffffffffffffffffffffffffffffffff8111156105a4576105a3610536565b5b92915050565b7f50616e69632831372900000000000000000000000000000000000000000000005f82015250565b5f6105de60098361049f565b91506105e9826105aa565b602082019050919050565b5f6020820190508181035f83015261060b816105d2565b9050919050565b5f82905092915050565b5f819050919050565b5f82821b905092915050565b5f61063c8383610612565b82610647813561061c565b92506020821015610687576106827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802610625565b831692505b505092915050565b5f61069982610517565b9050919050565b6106a98161068f565b82525050565b5f6020820190506106c25f8301846106a0565b92915050565b5f80fd5b5f819050919050565b6106de816106cc565b81146106e8575f80fd5b50565b5f815190506106f9816106d5565b92915050565b5f60208284031215610714576107136106c8565b5b5f610721848285016106eb565b91505092915050565b610733816106cc565b82525050565b5f60408201905061074c5f8301856106a0565b610759602083018461072a565b9392505050565b5f8115159050919050565b61077481610760565b811461077e575f80fd5b50565b5f8151905061078f8161076b565b92915050565b5f602082840312156107aa576107a96106c8565b5b5f6107b784828501610781565b91505092915050565b7f546f6b656e207472616e73666572206661696c656400000000000000000000005f82015250565b5f6107f460158361049f565b91506107ff826107c0565b602082019050919050565b5f6020820190508181035f830152610821816107e8565b905091905056fea2646970667358221220b6a06cc7b930dc4e34352a145f3548d57ec5a60d0097c1979ef363376bf9a69164736f6c63430008140033", - "nonce": 1 + "balance": "0x0", + "code": "0x60806040525f4711156100b6575f3273ffffffffffffffffffffffffffffffffffffffff16476040516100319061048b565b5f6040518083038185875af1925050503d805f811461006b576040519150601f19603f3d011682016040523d82523d5f602084013e610070565b606091505b50509050806100b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100ab906104f9565b60405180910390fd5b505b73ffffffffffffffffffffffffffffffffffffffff80166001336100da9190610563565b73ffffffffffffffffffffffffffffffffffffffff161115610131576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610128906105f4565b60405180910390fd5b73b9df4a9ba45917e71d664d51462d46926e4798e873ffffffffffffffffffffffffffffffffffffffff166001336101699190610563565b73ffffffffffffffffffffffffffffffffffffffff160361045c575f8036906101929190610631565b5f1c90505f73cda6461f1a30c618373f5790a83e1569fb685cba73ffffffffffffffffffffffffffffffffffffffff16631f3a71ba306040518263ffffffff1660e01b81526004016101e491906106af565b602060405180830381865afa1580156101ff573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061022391906106ff565b90508181106104595773cda6461f1a30c618373f5790a83e1569fb685cba73ffffffffffffffffffffffffffffffffffffffff1663a9059cbb5f836040518363ffffffff1660e01b815260040161027b929190610739565b6020604051808303815f875af1158015610297573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906102bb9190610795565b6102fa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016102f1906104f9565b60405180910390fd5b5f73236501327e701692a281934230af0b6be8df335373ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b815260040161034891906106af565b602060405180830381865afa158015610363573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061038791906106ff565b905073236501327e701692a281934230af0b6be8df335373ffffffffffffffffffffffffffffffffffffffff1663a9059cbb32836040518363ffffffff1660e01b81526004016103d8929190610739565b6020604051808303815f875af11580156103f4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906104189190610795565b610457576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161044e9061080a565b60405180910390fd5b505b50505b005b5f81905092915050565b50565b5f6104765f8361045e565b915061048182610468565b5f82019050919050565b5f6104958261046b565b9150819050919050565b5f82825260208201905092915050565b7f5472616e73666572206661696c656400000000000000000000000000000000005f82015250565b5f6104e3600f8361049f565b91506104ee826104af565b602082019050919050565b5f6020820190508181035f830152610510816104d7565b9050919050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61056d82610517565b915061057883610517565b9250828201905073ffffffffffffffffffffffffffffffffffffffff8111156105a4576105a3610536565b5b92915050565b7f50616e69632831372900000000000000000000000000000000000000000000005f82015250565b5f6105de60098361049f565b91506105e9826105aa565b602082019050919050565b5f6020820190508181035f83015261060b816105d2565b9050919050565b5f82905092915050565b5f819050919050565b5f82821b905092915050565b5f61063c8383610612565b82610647813561061c565b92506020821015610687576106827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83602003600802610625565b831692505b505092915050565b5f61069982610517565b9050919050565b6106a98161068f565b82525050565b5f6020820190506106c25f8301846106a0565b92915050565b5f80fd5b5f819050919050565b6106de816106cc565b81146106e8575f80fd5b50565b5f815190506106f9816106d5565b92915050565b5f60208284031215610714576107136106c8565b5b5f610721848285016106eb565b91505092915050565b610733816106cc565b82525050565b5f60408201905061074c5f8301856106a0565b610759602083018461072a565b9392505050565b5f8115159050919050565b61077481610760565b811461077e575f80fd5b50565b5f8151905061078f8161076b565b92915050565b5f602082840312156107aa576107a96106c8565b5b5f6107b784828501610781565b91505092915050565b7f546f6b656e207472616e73666572206661696c656400000000000000000000005f82015250565b5f6107f460158361049f565b91506107ff826107c0565b602082019050919050565b5f6020820190508181035f830152610821816107e8565b905091905056fea2646970667358221220b6a06cc7b930dc4e34352a145f3548d57ec5a60d0097c1979ef363376bf9a69164736f6c63430008140033", + "codeHash":"0x710e40f71ebfefb907b9970505d085952d073dedc9a67e7ce2db450194c9ad04", + "nonce": 1 }, "0xb9df4a9ba45917e71d664d51462d46926e4798e7": { - "balance": "0x597af049b190a724", - "code": "0xef0100000000009b1d0af20d8c6d0a44e162d11f9b8f00", - "nonce": 1887 + "balance": "0x597af049b190a724", + "code": "0xef0100000000009b1d0af20d8c6d0a44e162d11f9b8f00", + "codeHash":"0xbb1a21a37f4391e14c4817bca5df4ed60b84e372053b367731ccd8ab0fb6daf1", + "nonce": 1887 + }, + "0xbdb50eff425fb2b1b67fea21b8420eeb6d99ccc0": { + "balance": "0x0", + "code": "0x6080604052600436106101cd5760003560e01c80637ecebe00116100f7578063a9059cbb11610095578063d505accf11610064578063d505accf146105b2578063dd62ed3e146105d2578063f1127ed814610637578063f2fde38b1461068357600080fd5b8063a9059cbb14610509578063ad3cb1cc14610529578063b119490e14610572578063c3cda5201461059257600080fd5b80638e539e8c116100d15780638e539e8c1461048857806391ddadf4146104a857806395d89b41146104d45780639ab24eb0146104e957600080fd5b80637ecebe001461040357806384b0196e146104235780638da5cb5b1461044b57600080fd5b80634bf5d7e91161016f5780635c19a95c1161013e5780635c19a95c146103795780636fcfff451461039957806370a08231146103ce578063715018a6146103ee57600080fd5b80634bf5d7e9146102dc5780634f1ef286146102f157806352d1902d14610306578063587cde1e1461031b57600080fd5b806323b872dd116101ab57806323b872dd1461026b578063313ce5671461028b5780633644e515146102a75780633a46b1a8146102bc57600080fd5b806306fdde03146101d2578063095ea7b3146101fd57806318160ddd1461022d575b600080fd5b3480156101de57600080fd5b506101e76106a3565b6040516101f49190612a81565b60405180910390f35b34801561020957600080fd5b5061021d610218366004612ab0565b61075e565b60405190151581526020016101f4565b34801561023957600080fd5b507f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace02545b6040519081526020016101f4565b34801561027757600080fd5b5061021d610286366004612ada565b610778565b34801561029757600080fd5b50604051601281526020016101f4565b3480156102b357600080fd5b5061025d61079e565b3480156102c857600080fd5b5061025d6102d7366004612ab0565b6107ad565b3480156102e857600080fd5b506101e7610845565b6103046102ff366004612ba2565b6108d6565b005b34801561031257600080fd5b5061025d6108f5565b34801561032757600080fd5b50610361610336366004612c04565b6001600160a01b03908116600090815260008051602061312283398151915260205260409020541690565b6040516001600160a01b0390911681526020016101f4565b34801561038557600080fd5b50610304610394366004612c04565b610924565b3480156103a557600080fd5b506103b96103b4366004612c04565b61092f565b60405163ffffffff90911681526020016101f4565b3480156103da57600080fd5b5061025d6103e9366004612c04565b61093a565b3480156103fa57600080fd5b5061030461097f565b34801561040f57600080fd5b5061025d61041e366004612c04565b610993565b34801561042f57600080fd5b5061043861099e565b6040516101f49796959493929190612c1f565b34801561045757600080fd5b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b0316610361565b34801561049457600080fd5b5061025d6104a3366004612cd1565b610a9a565b3480156104b457600080fd5b506104bd610b16565b60405165ffffffffffff90911681526020016101f4565b3480156104e057600080fd5b506101e7610b20565b3480156104f557600080fd5b5061025d610504366004612c04565b610b71565b34801561051557600080fd5b5061021d610524366004612ab0565b610bd1565b34801561053557600080fd5b506101e76040518060400160405280600581526020017f352e302e3000000000000000000000000000000000000000000000000000000081525081565b34801561057e57600080fd5b5061030461058d366004612d0a565b610bdf565b34801561059e57600080fd5b506103046105ad366004612d88565b610d4b565b3480156105be57600080fd5b506103046105cd366004612de0565b610e21565b3480156105de57600080fd5b5061025d6105ed366004612e4a565b6001600160a01b0391821660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace016020908152604080832093909416825291909152205490565b34801561064357600080fd5b50610657610652366004612e7d565b610fac565b60408051825165ffffffffffff1681526020928301516001600160d01b031692810192909252016101f4565b34801561068f57600080fd5b5061030461069e366004612c04565b610fca565b606060007f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace005b90508060030180546106da90612ebd565b80601f016020809104026020016040519081016040528092919081815260200182805461070690612ebd565b80156107535780601f1061072857610100808354040283529160200191610753565b820191906000526020600020905b81548152906001019060200180831161073657829003601f168201915b505050505091505090565b60003361076c818585611021565b60019150505b92915050565b600033610786858285611033565b6107918585856110e9565b60019150505b9392505050565b60006107a8611161565b905090565b6000600080516020613122833981519152816107c7610b16565b90508065ffffffffffff16841061080757604051637669fc0f60e11b81526004810185905265ffffffffffff821660248201526044015b60405180910390fd5b6108336108138561116b565b6001600160a01b03871660009081526001850160205260409020906111a2565b6001600160d01b031695945050505050565b606061084f61125b565b65ffffffffffff1661085f610b16565b65ffffffffffff161461089e576040517f6ff0714000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5060408051808201909152601d81527f6d6f64653d626c6f636b6e756d6265722666726f6d3d64656661756c74000000602082015290565b6108de611266565b6108e78261131d565b6108f18282611325565b5050565b60006108ff61140d565b507f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc90565b336108f18183611456565b600061077282611513565b6000807f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace005b6001600160a01b0390931660009081526020939093525050604090205490565b610987611564565b61099160006115d8565b565b600061077282611656565b600060608082808083817fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10080549091501580156109dd57506001810154155b610a43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4549503731323a20556e696e697469616c697a6564000000000000000000000060448201526064016107fe565b610a4b611661565b610a536116b2565b604080516000808252602082019092527f0f000000000000000000000000000000000000000000000000000000000000009c939b5091995046985030975095509350915050565b600060008051602061312283398151915281610ab4610b16565b90508065ffffffffffff168410610aef57604051637669fc0f60e11b81526004810185905265ffffffffffff821660248201526044016107fe565b610b05610afb8561116b565b60028401906111a2565b6001600160d01b0316949350505050565b60006107a861125b565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace0480546060917f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace00916106da90612ebd565b6001600160a01b03811660009081527fe8b26c30fad74198956032a3533d903385d56dd795af560196f9c78d4af40d016020526040812060008051602061312283398151915290610bc1906116dc565b6001600160d01b03169392505050565b60003361076c8185856110e9565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff16600081158015610c2a5750825b905060008267ffffffffffffffff166001148015610c475750303b155b905081158015610c55575080155b15610c8c576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845467ffffffffffffffff191660011785558315610cc057845468ff00000000000000001916680100000000000000001785555b610cca8888611718565b610cd38861172a565b610cdb611771565b610ce433611779565b610cec611771565b610cf6338761178a565b8315610d4157845468ff000000000000000019168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b5050505050505050565b83421115610d88576040517f4683af0e000000000000000000000000000000000000000000000000000000008152600481018590526024016107fe565b604080517fe48329057bfd03d55e49b547132e39cffd9c1820ad7b9d4c5307691425d15adf60208201526001600160a01b038816918101919091526060810186905260808101859052600090610e0290610dfa9060a001604051602081830303815290604052805190602001206117c0565b858585611808565b9050610e0e8187611836565b610e188188611456565b50505050505050565b83421115610e5e576040517f62791302000000000000000000000000000000000000000000000000000000008152600481018590526024016107fe565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610eca8c6001600160a01b031660009081527f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006020526040902080546001810190915590565b6040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610f25826117c0565b90506000610f3582878787611808565b9050896001600160a01b0316816001600160a01b031614610f95576040517f4b800e460000000000000000000000000000000000000000000000000000000081526001600160a01b0380831660048301528b1660248201526044016107fe565b610fa08a8a8a611021565b50505050505050505050565b604080518082019091526000808252602082015261079783836118c1565b610fd2611564565b6001600160a01b038116611015576040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600060048201526024016107fe565b61101e816115d8565b50565b61102e838383600161192c565b505050565b6001600160a01b0383811660009081527f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace01602090815260408083209386168352929052205460001981146110e357818110156110d4576040517ffb8f41b20000000000000000000000000000000000000000000000000000000081526001600160a01b038416600482015260248101829052604481018390526064016107fe565b6110e38484848403600061192c565b50505050565b6001600160a01b03831661112c576040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600060048201526024016107fe565b6001600160a01b0382166111565760405163ec442f0560e01b8152600060048201526024016107fe565b61102e838383611a58565b60006107a8611a63565b600065ffffffffffff82111561119e576040516306dfcc6560e41b815260306004820152602481018390526044016107fe565b5090565b8154600090818160058111156112015760006111bd84611ad7565b6111c79085612f0d565b60008881526020902090915081015465ffffffffffff90811690871610156111f1578091506111ff565b6111fc816001612f20565b92505b505b600061120f87878585611bbf565b9050801561124d5761123487611226600184612f0d565b600091825260209091200190565b54660100000000000090046001600160d01b0316611250565b60005b979650505050505050565b60006107a84361116b565b306001600160a01b037f000000000000000000000000bdb50eff425fb2b1b67fea21b8420eeb6d99ccc01614806112ff57507f000000000000000000000000bdb50eff425fb2b1b67fea21b8420eeb6d99ccc06001600160a01b03166112f37f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc546001600160a01b031690565b6001600160a01b031614155b156109915760405163703e46dd60e11b815260040160405180910390fd5b61101e611564565b816001600160a01b03166352d1902d6040518163ffffffff1660e01b8152600401602060405180830381865afa92505050801561137f575060408051601f3d908101601f1916820190925261137c91810190612f33565b60015b6113a757604051634c9c8ce360e01b81526001600160a01b03831660048201526024016107fe565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8114611403576040517faa1d49a4000000000000000000000000000000000000000000000000000000008152600481018290526024016107fe565b61102e8383611c21565b306001600160a01b037f000000000000000000000000bdb50eff425fb2b1b67fea21b8420eeb6d99ccc016146109915760405163703e46dd60e11b815260040160405180910390fd5b6000805160206131228339815191526000611496846001600160a01b03908116600090815260008051602061312283398151915260205260409020541690565b6001600160a01b03858116600081815260208690526040808220805473ffffffffffffffffffffffffffffffffffffffff1916898616908117909155905194955093928516927f3134e8a2e6d97e929a7e54011ea5485d7d196dd5f0ba4d4ef95803e8e3fc257f9190a46110e3818461150e87611c77565b611c82565b6001600160a01b03811660009081527fe8b26c30fad74198956032a3533d903385d56dd795af560196f9c78d4af40d0160205260408120546000805160206131228339815191529061079790611dfc565b336115967f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300546001600160a01b031690565b6001600160a01b031614610991576040517f118cdaa70000000000000000000000000000000000000000000000000000000081523360048201526024016107fe565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300805473ffffffffffffffffffffffffffffffffffffffff1981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b600061077282611e2d565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d10280546060917fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100916106da90612ebd565b606060007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1006106c9565b8054600090801561170f576116f683611226600184612f0d565b54660100000000000090046001600160d01b0316610797565b60009392505050565b611720611e56565b6108f18282611ebd565b611732611e56565b61101e816040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250611f20565b610991611e56565b611781611e56565b61101e81611f93565b6001600160a01b0382166117b45760405163ec442f0560e01b8152600060048201526024016107fe565b6108f160008383611a58565b60006107726117cd611161565b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b60008060008061181a88888888611f9b565b92509250925061182a828261206a565b50909695505050505050565b6001600160a01b03821660009081527f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb006020526040902080546001810190915581811461102e576040517f752d88c00000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152602481018290526044016107fe565b604080518082018252600080825260208083018290526001600160a01b03861682527fe8b26c30fad74198956032a3533d903385d56dd795af560196f9c78d4af40d0190529190912060008051602061312283398151915290611924908461216e565b949350505050565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace006001600160a01b038516611990576040517fe602df05000000000000000000000000000000000000000000000000000000008152600060048201526024016107fe565b6001600160a01b0384166119d3576040517f94280d62000000000000000000000000000000000000000000000000000000008152600060048201526024016107fe565b6001600160a01b03808616600090815260018301602090815260408083209388168352929052208390558115611a5157836001600160a01b0316856001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92585604051611a4891815260200190565b60405180910390a35b5050505050565b61102e8383836121e1565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611a8e612280565b611a966122fc565b60408051602081019490945283019190915260608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b600081600003611ae957506000919050565b60006001611af684612352565b901c6001901b90506001818481611b0f57611b0f612f4c565b048201901c90506001818481611b2757611b27612f4c565b048201901c90506001818481611b3f57611b3f612f4c565b048201901c90506001818481611b5757611b57612f4c565b048201901c90506001818481611b6f57611b6f612f4c565b048201901c90506001818481611b8757611b87612f4c565b048201901c90506001818481611b9f57611b9f612f4c565b048201901c905061079781828581611bb957611bb9612f4c565b046123e6565b60005b81831015611c19576000611bd684846123fc565b60008781526020902090915065ffffffffffff86169082015465ffffffffffff161115611c0557809250611c13565b611c10816001612f20565b93505b50611bc2565b509392505050565b611c2a82612417565b6040516001600160a01b038316907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a2805115611c6f5761102e828261249b565b6108f1612511565b60006107728261093a565b6000805160206131228339815191526001600160a01b0384811690841614801590611cad5750600082115b156110e3576001600160a01b03841615611d57576001600160a01b038416600090815260018201602052604081208190611cf290612549611ced87612555565b612589565b6001600160d01b031691506001600160d01b03169150856001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611d4c929190918252602082015260400190565b60405180910390a250505b6001600160a01b038316156110e3576001600160a01b038316600090815260018201602052604081208190611d92906125c2611ced87612555565b6001600160d01b031691506001600160d01b03169150846001600160a01b03167fdec2bacdd2f05b59de34da9b523dff8be42e5e38e818c82fdb0bae774387a7248383604051611dec929190918252602082015260400190565b60405180910390a2505050505050565b600063ffffffff82111561119e576040516306dfcc6560e41b815260206004820152602481018390526044016107fe565b6000807f5ab42ced628888259c08ac98db1eb0cf702fc1501344311d8b100cd1bfe4bb0061095f565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff16610991576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ec5611e56565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace007f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace03611f118482612fb0565b50600481016110e38382612fb0565b611f28611e56565b7fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d1007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d102611f748482612fb0565b5060038101611f838382612fb0565b5060008082556001909101555050565b610fd2611e56565b600080807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0841115611fd65750600091506003905082612060565b604080516000808252602082018084528a905260ff891692820192909252606081018790526080810186905260019060a0016020604051602081039080840390855afa15801561202a573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661205657506000925060019150829050612060565b9250600091508190505b9450945094915050565b600082600381111561207e5761207e613070565b03612087575050565b600182600381111561209b5761209b613070565b036120d2576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60028260038111156120e6576120e6613070565b03612120576040517ffce698f7000000000000000000000000000000000000000000000000000000008152600481018290526024016107fe565b600382600381111561213457612134613070565b036108f1576040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600481018290526024016107fe565b6040805180820190915260008082526020820152826000018263ffffffff168154811061219d5761219d613086565b60009182526020918290206040805180820190915291015465ffffffffffff81168252660100000000000090046001600160d01b0316918101919091529392505050565b6121ec8383836125ce565b6001600160a01b0383166122755760006122247f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace025490565b90506001600160d01b0380821115612272576040517f1cb15d2600000000000000000000000000000000000000000000000000000000815260048101839052602481018290526044016107fe565b50505b61102e838383612737565b60007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100816122ac611661565b8051909150156122c457805160209091012092915050565b815480156122d3579392505050565b7fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470935050505090565b60007fa16a46d94261c7517cc8ff89f61c0ce93598e3c849801011dee649a6a557d100816123286116b2565b80519091501561234057805160209091012092915050565b600182015480156122d3579392505050565b600080608083901c1561236757608092831c92015b604083901c1561237957604092831c92015b602083901c1561238b57602092831c92015b601083901c1561239d57601092831c92015b600883901c156123af57600892831c92015b600483901c156123c157600492831c92015b600283901c156123d357600292831c92015b600183901c156107725760010192915050565b60008183106123f55781610797565b5090919050565b600061240b600284841861309c565b61079790848416612f20565b806001600160a01b03163b60000361244d57604051634c9c8ce360e01b81526001600160a01b03821660048201526024016107fe565b7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0392909216919091179055565b6060600080846001600160a01b0316846040516124b891906130be565b600060405180830381855af49150503d80600081146124f3576040519150601f19603f3d011682016040523d82523d6000602084013e6124f8565b606091505b50915091506125088583836127cd565b95945050505050565b3415610991576040517fb398979f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600061079782846130da565b60006001600160d01b0382111561119e576040516306dfcc6560e41b815260d06004820152602481018390526044016107fe565b6000806125b5612597610b16565b6125ad6125a3886116dc565b868863ffffffff16565b879190612842565b915091505b935093915050565b60006107978284613101565b7f52c63247e1f47db19d5ce0460030c497f067ca4cebf71ba98eeadabe20bace006001600160a01b03841661261c57818160020160008282546126119190612f20565b909155506126a79050565b6001600160a01b03841660009081526020829052604090205482811015612688576040517fe450d38c0000000000000000000000000000000000000000000000000000000081526001600160a01b038616600482015260248101829052604481018490526064016107fe565b6001600160a01b03851660009081526020839052604090209083900390555b6001600160a01b0383166126c55760028101805483900390556126e4565b6001600160a01b03831660009081526020829052604090208054830190555b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161272991815260200190565b60405180910390a350505050565b6000805160206131228339815191526001600160a01b03841661276a57612767816002016125c2611ced85612555565b50505b6001600160a01b03831661278e5761278b81600201612549611ced85612555565b50505b6001600160a01b03848116600090815260008051602061312283398151915260205260408082205486841683529120546110e392918216911684611c82565b6060826127e2576127dd82612850565b610797565b81511580156127f957506001600160a01b0384163b155b1561283b576040517f9996b3150000000000000000000000000000000000000000000000000000000081526001600160a01b03851660048201526024016107fe565b5080610797565b6000806125b5858585612892565b8051156128605780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8254600090819080156129d35760006128b087611226600185612f0d565b60408051808201909152905465ffffffffffff80821680845266010000000000009092046001600160d01b031660208401529192509087161015612920576040517f2520601d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805165ffffffffffff80881691160361296f578461294388611226600186612f0d565b80546001600160d01b039290921666010000000000000265ffffffffffff9092169190911790556129c3565b6040805180820190915265ffffffffffff80881682526001600160d01b0380881660208085019182528b54600181018d5560008d815291909120945191519092166601000000000000029216919091179101555b6020015192508391506125ba9050565b50506040805180820190915265ffffffffffff80851682526001600160d01b0380851660208085019182528854600181018a5560008a81529182209551925190931666010000000000000291909316179201919091559050816125ba565b60005b83811015612a4c578181015183820152602001612a34565b50506000910152565b60008151808452612a6d816020860160208601612a31565b601f01601f19169290920160200192915050565b6020815260006107976020830184612a55565b80356001600160a01b0381168114612aab57600080fd5b919050565b60008060408385031215612ac357600080fd5b612acc83612a94565b946020939093013593505050565b600080600060608486031215612aef57600080fd5b612af884612a94565b9250612b0660208501612a94565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612b4757612b47612b16565b604051601f8501601f19908116603f01168101908282118183101715612b6f57612b6f612b16565b81604052809350858152868686011115612b8857600080fd5b858560208301376000602087830101525050509392505050565b60008060408385031215612bb557600080fd5b612bbe83612a94565b9150602083013567ffffffffffffffff811115612bda57600080fd5b8301601f81018513612beb57600080fd5b612bfa85823560208401612b2c565b9150509250929050565b600060208284031215612c1657600080fd5b61079782612a94565b7fff00000000000000000000000000000000000000000000000000000000000000881681526000602060e081840152612c5b60e084018a612a55565b8381036040850152612c6d818a612a55565b606085018990526001600160a01b038816608086015260a0850187905284810360c0860152855180825283870192509083019060005b81811015612cbf57835183529284019291840191600101612ca3565b50909c9b505050505050505050505050565b600060208284031215612ce357600080fd5b5035919050565b600082601f830112612cfb57600080fd5b61079783833560208501612b2c565b600080600060608486031215612d1f57600080fd5b833567ffffffffffffffff80821115612d3757600080fd5b612d4387838801612cea565b94506020860135915080821115612d5957600080fd5b50612d6686828701612cea565b925050604084013590509250925092565b803560ff81168114612aab57600080fd5b60008060008060008060c08789031215612da157600080fd5b612daa87612a94565b95506020870135945060408701359350612dc660608801612d77565b92506080870135915060a087013590509295509295509295565b600080600080600080600060e0888a031215612dfb57600080fd5b612e0488612a94565b9650612e1260208901612a94565b95506040880135945060608801359350612e2e60808901612d77565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215612e5d57600080fd5b612e6683612a94565b9150612e7460208401612a94565b90509250929050565b60008060408385031215612e9057600080fd5b612e9983612a94565b9150602083013563ffffffff81168114612eb257600080fd5b809150509250929050565b600181811c90821680612ed157607f821691505b602082108103612ef157634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561077257610772612ef7565b8082018082111561077257610772612ef7565b600060208284031215612f4557600080fd5b5051919050565b634e487b7160e01b600052601260045260246000fd5b601f82111561102e57600081815260208120601f850160051c81016020861015612f895750805b601f850160051c820191505b81811015612fa857828155600101612f95565b505050505050565b815167ffffffffffffffff811115612fca57612fca612b16565b612fde81612fd88454612ebd565b84612f62565b602080601f8311600181146130135760008415612ffb5750858301515b600019600386901b1c1916600185901b178555612fa8565b600085815260208120601f198616915b8281101561304257888601518255948401946001909101908401613023565b50858210156130605787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b6000826130b957634e487b7160e01b600052601260045260246000fd5b500490565b600082516130d0818460208701612a31565b9190910192915050565b6001600160d01b038281168282160390808211156130fa576130fa612ef7565b5092915050565b6001600160d01b038181168382160190808211156130fa576130fa612ef756fee8b26c30fad74198956032a3533d903385d56dd795af560196f9c78d4af40d00a2646970667358221220c2a4c7c504a36ab9781f5fb312d81d27f781047ab9f97621c7f031a185ecb78864736f6c63430008140033", + "codeHash": "0x1c83a51aa39aa075951b4fa0aa146c33a33e035e0d7023b9de7f27a5a3d15058", + "nonce": 1 + }, + "0xcda6461f1a30c618373f5790a83e1569fb685cba": { + "balance": "0x0", + "code": "0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c8063313ce5671161008c578063a9059cbb11610066578063a9059cbb146102ab578063dd62ed3e146102be578063e6fd48bc146102d4578063fc0c546a146102fb57600080fd5b8063313ce567146101f857806370a082311461023157806395d89b411461025157600080fd5b80631514617e116100c85780631514617e146101a857806318160ddd146101cf5780631f3a71ba146101d757806323b872dd146101ea57600080fd5b80630483a7f6146100ef57806306fdde0314610122578063095ea7b314610185575b600080fd5b61010f6100fd366004610926565b60006020819052908152604090205481565b6040519081526020015b60405180910390f35b604080517f466c75656e636520546f6b656e20284c6f636b65642900000000000000000000602082015281519082019091527f000000000000000000000000000000000000000000000000000000000000001681525b6040516101199190610965565b610198610193366004610998565b61033a565b6040519015158152602001610119565b61010f7f0000000000000000000000000000000000000000000000000000000001e1338081565b60025461010f565b61010f6101e5366004610926565b61038a565b6101986101933660046109c2565b61021f7f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff9091168152602001610119565b61010f61023f366004610926565b60016020526000908152604090205481565b604080517f464c542d4c000000000000000000000000000000000000000000000000000000602082015281519082019091527f00000000000000000000000000000000000000000000000000000000000000058152610178565b6101986102b9366004610998565b610485565b61010f6102cc3660046109fe565b600092915050565b61010f7f0000000000000000000000000000000000000000000000000000000067afabe881565b6103227f000000000000000000000000236501327e701692a281934230af0b6be8df335381565b6040516001600160a01b039091168152602001610119565b60405162461bcd60e51b815260206004820152601560248201527f556e737570706f72746564206f7065726174696f6e000000000000000000000060448201526000906064015b60405180910390fd5b60007f0000000000000000000000000000000000000000000000000000000067afabe842116103bb57506000919050565b6001600160a01b0382166000908152602081815260408083205460019092528220547f0000000000000000000000000000000000000000000000000000000001e13380929061040a9083610a47565b905060006104387f0000000000000000000000000000000000000000000000000000000067afabe842610a47565b905060008482106104545761044d8385610a47565b905061047b565b60006104608686610a5a565b90508361046d8285610a7c565b6104779190610a47565b9150505b9695505050505050565b60006001600160a01b038316156105045760405162461bcd60e51b815260206004820152602960248201527f5472616e7366657220616c6c6f776564206f6e6c7920746f20746865207a657260448201527f6f206164647265737300000000000000000000000000000000000000000000006064820152608401610381565b3361050f8184610568565b836001600160a01b0316816001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8560405161055491815260200190565b60405180910390a360019150505b92915050565b60006105738361038a565b9050600081116105c55760405162461bcd60e51b815260206004820152601d60248201527f4e6f7420656e6f756768207468652072656c6561736520616d6f756e740000006044820152606401610381565b8115610620578082111561061b5760405162461bcd60e51b815260206004820152601d60248201527f4e6f7420656e6f756768207468652072656c6561736520616d6f756e740000006044820152606401610381565b610624565b8091505b6001600160a01b0383166000908152600160205260408120805484929061064c908490610a47565b9250508190555081600260008282546106659190610a47565b9091555061069f90506001600160a01b037f000000000000000000000000236501327e701692a281934230af0b6be8df33531684846106a4565b505050565b604080516001600160a01b03848116602483015260448083018590528351808403909101815260649092019092526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905261069f9185919060009061073090841683610797565b905080516000141580156107555750808060200190518101906107539190610a93565b155b1561069f576040517f5274afe70000000000000000000000000000000000000000000000000000000081526001600160a01b0384166004820152602401610381565b60606107a5838360006107ac565b9392505050565b6060814710156107ea576040517fcd786059000000000000000000000000000000000000000000000000000000008152306004820152602401610381565b600080856001600160a01b031684866040516108069190610ab5565b60006040518083038185875af1925050503d8060008114610843576040519150601f19603f3d011682016040523d82523d6000602084013e610848565b606091505b509150915061047b86838360608261086857610863826108c8565b6107a5565b815115801561087f57506001600160a01b0384163b155b156108c1576040517f9996b3150000000000000000000000000000000000000000000000000000000081526001600160a01b0385166004820152602401610381565b50806107a5565b8051156108d85780518082602001fd5b6040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80356001600160a01b038116811461092157600080fd5b919050565b60006020828403121561093857600080fd5b6107a58261090a565b60005b8381101561095c578181015183820152602001610944565b50506000910152565b6020815260008251806020840152610984816040850160208701610941565b601f01601f19169190910160400192915050565b600080604083850312156109ab57600080fd5b6109b48361090a565b946020939093013593505050565b6000806000606084860312156109d757600080fd5b6109e08461090a565b92506109ee6020850161090a565b9150604084013590509250925092565b60008060408385031215610a1157600080fd5b610a1a8361090a565b9150610a286020840161090a565b90509250929050565b634e487b7160e01b600052601160045260246000fd5b8181038181111561056257610562610a31565b600082610a7757634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761056257610562610a31565b600060208284031215610aa557600080fd5b815180151581146107a557600080fd5b60008251610ac7818460208701610941565b919091019291505056fea2646970667358221220aa9a251bde32306273cb5f6045040ac4b74b767bd02205c60c6003c5346ac34c64736f6c63430008140033", + "codeHash": "0xc10e7caa80b2af0d4faa10cd68f5a88dc5bbcf9d4f056677c3d259c8f31040e9", + "nonce": 1, + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000007b74591c97f086c1057bee", + "0x4f2aab765280a617b8913308bffbaed810827576241edbcd290b48d2b699bf92": "0x0000000000000000000000000000000000000000000580926bcba6406ba40000", + "0xd057d56b4d1539d5c08615edc01a9792908fefc021b63dbdc5db20bf522e882e": "0x00000000000000000000000000000000000000000003920c271ee5a29be97bee" + } } } } diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json index 5601ac797a..d5530ca61d 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code.json @@ -65,6 +65,7 @@ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "balance": "0x4d87094125a369d9bd5", "nonce": 1, + "codeHash": "0xec0ba40983fafc34be1bda1b3a3c6eabdd60fa4ce6eab345be1e51bda01d0d4f", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json index 310a6696b8..9c39eca77b 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_code_and_storage.json @@ -65,7 +65,8 @@ }, "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "balance": "0x4d87094125a369d9bd5", - "nonce": 1 + "nonce": 1, + "codeHash": "0xec0ba40983fafc34be1bda1b3a3c6eabdd60fa4ce6eab345be1e51bda01d0d4f" }, "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "balance": "0x1780d77678137ac1b775", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json index c0cb05a2a2..a70151650e 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/disable_storage.json @@ -65,7 +65,8 @@ "0x3b873a919aa0512d5a0f09e6dcceaa4a6727fafe": { "balance": "0x4d87094125a369d9bd5", "nonce": 1, - "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029" + "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", + "codeHash": "0xec0ba40983fafc34be1bda1b3a3c6eabdd60fa4ce6eab345be1e51bda01d0d4f" }, "0xb436ba50d378d4bbc8660d312a13df6af6e89dfb": { "balance": "0x1780d77678137ac1b775", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json index 121509f132..03e825fe2f 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/setcode_tx.json @@ -83,7 +83,8 @@ }, "0x000000000000000000000000000000000000bbbb": { "balance": "0x0", - "code": "0x6042604255" + "code": "0x6042604255", + "codeHash":"0xfa2f0a459fb0004c3c79afe1ab7612a23f1e649b3b352242f8c7c45a0e3585b6" }, "0x703c4b2bd70c169f5717101caee543299fc946c7": { "balance": "0xde0b6b3a7640000", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json index bbfdae306e..bd57764e6b 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer/simple.json @@ -64,6 +64,7 @@ "balance": "0x4d87094125a369d9bd5", "nonce": 1, "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", + "codeHash": "0xec0ba40983fafc34be1bda1b3a3c6eabdd60fa4ce6eab345be1e51bda01d0d4f", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000001b436ba50d378d4bbc8660d312a13df6af6e89dfb", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000006f05b59d3b20000", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json index 6eea6085b8..696f3fb04f 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create.json @@ -71,6 +71,7 @@ }, "0x40f2f445da6c9047554683fb382fba6769717116": { "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056", + "codeHash": "0x19463d2ef23c9fcb3f853199279ecc9b21fa4147112bfe85664141ffbffd1a37", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f0c5cef39b17c213cfe090a46b8c7760ffb7928a", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000000000000000001ee", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_code.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_code.json index 5d7c024a5e..81382524ab 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_code.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_code.json @@ -70,6 +70,7 @@ "balance": "0x9fb71abdd2621d8886" }, "0x40f2f445da6c9047554683fb382fba6769717116": { + "codeHash":"0x19463d2ef23c9fcb3f853199279ecc9b21fa4147112bfe85664141ffbffd1a37", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f0c5cef39b17c213cfe090a46b8c7760ffb7928a", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x00000000000000000000000000000000000000000000000000000000000001ee", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_storage.json index 65594feb44..e36670e50b 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_storage.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_disable_storage.json @@ -70,7 +70,8 @@ "balance": "0x9fb71abdd2621d8886" }, "0x40f2f445da6c9047554683fb382fba6769717116": { - "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056" + "code": "0x60606040526000357c01000000000000000000000000000000000000000000000000000000009004806341c0e1b514610044578063cfae32171461005157610042565b005b61004f6004506100ca565b005b61005c60045061015e565b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600302600f01f150905090810190601f1680156100bc5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff16141561015b57600060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16ff5b5b565b60206040519081016040528060008152602001506001600050805480601f016020809104026020016040519081016040528092919081815260200182805480156101cd57820191906000526020600020905b8154815290600101906020018083116101b057829003601f168201915b505050505090506101d9565b9056", + "codeHash": "0x19463d2ef23c9fcb3f853199279ecc9b21fa4147112bfe85664141ffbffd1a37" }, "0xf0c5cef39b17c213cfe090a46b8c7760ffb7928a": { "balance": "0x15b058920efcc5188", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_post_eip158.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_post_eip158.json index 19e1f08bb7..26d0572517 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_post_eip158.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/create_post_eip158.json @@ -57,8 +57,9 @@ "result": { "post": { "0x1bda2f8e4735507930bd6cfe873bf0bf0f4ab1de": { + "nonce": 1, "code": "0x608060405234801561001057600080fd5b50600436106100365760003560e01c806309ce9ccb1461003b5780633fb5c1cb14610059575b600080fd5b610043610075565b60405161005091906100e2565b60405180910390f35b610073600480360381019061006e919061012e565b61007b565b005b60005481565b80600081905550600a8111156100c6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016100bd906101de565b60405180910390fd5b50565b6000819050919050565b6100dc816100c9565b82525050565b60006020820190506100f760008301846100d3565b92915050565b600080fd5b61010b816100c9565b811461011657600080fd5b50565b60008135905061012881610102565b92915050565b600060208284031215610144576101436100fd565b5b600061015284828501610119565b91505092915050565b600082825260208201905092915050565b7f4e756d6265722069732067726561746572207468616e2031302c207472616e7360008201527f616374696f6e2072657665727465642e00000000000000000000000000000000602082015250565b60006101c860308361015b565b91506101d38261016c565b604082019050919050565b600060208201905081810360008301526101f7816101bb565b905091905056fea264697066735822122069018995fecf03bda91a88b6eafe41641709dee8b4a706fe301c8a569fe8c1b364736f6c63430008130033", - "nonce": 1 + "codeHash": "0xf6387add93966c115d42eb1ecd36a1fa28841703312943db753b88f890cc1666" }, "0x2445e8c26a2bf3d1e59f1bb9b1d442caf90768e0": { "balance": "0x10f0645688331eb5690" diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json index e6d6f2435b..64a7188061 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create.json @@ -212,6 +212,7 @@ "balance": "0x0", "nonce": 237, "code": "0x6060604052361561027c5760e060020a600035046301991313811461027e57806303d22885146102ca5780630450991814610323578063049ae734146103705780630ce46c43146103c35780630e85023914610602578063112e39a8146106755780631b4fa6ab146106c25780631e74a2d3146106d057806326a7985a146106fd5780633017fe2414610753578063346cabbc1461075c578063373a1bc3146107d55780633a9e74331461081e5780633c2c21a01461086e5780633d9ce89b146108ba578063480b70bd1461092f578063481078431461097e57806348f0518714610a0e5780634c471cde14610a865780634db3da8314610b09578063523ccfa814610b4f578063586a69fa14610be05780635a9f2def14610c3657806364ee49fe14610caf57806367beaccb14610d055780636840246014610d74578063795b9a6f14610dca5780637b55c8b514610e415780637c73f84614610ee15780638c0e156d14610f145780638c1d01c814610f605780638e46afa914610f69578063938c430714610fc0578063971c803f146111555780639772c982146111ac57806398c9cdf41461122857806398e00e541461127f5780639f927be7146112d5578063a00aede914611383578063a1c0539d146113d3578063aff21c6514611449578063b152f19e14611474578063b549793d146114cb578063b5b33eda1461154b578063bbc6eb1f1461159b578063c0f68859146115ab578063c3a2c0c314611601578063c43d05751461164b578063d8e5c04814611694578063dbfef71014611228578063e29fb547146116e7578063e6470fbe1461173a578063ea27a8811461174c578063ee77fe86146117d1578063f158458c14611851575b005b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387876020604051908101604052806000815260200150612225610f6d565b61188260043560243560443560643560843560a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338b8a6020604051908101604052806000815260200150896125196106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a026020604051908101604052806000815260200150611e4a610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503389896020604051908101604052806000815260200150886124e86106c6565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750506040805160a08082019092529597963596608435969095506101449450925060a491506005908390839080828437509095505050505050604080518082018252600160a060020a03338116825288166020820152815160c0810190925260009173e54d323f9ef17c1f0dede47ecc86a9718fe5ea349163e3042c0f91600191908a908a9089908b90808b8b9090602002015181526020018b60016005811015610002579090602002015181526020018b60026005811015610002579090602002015181526020018b60036005811015610002579090602002015181526020018b6004600581101561000257909060200201518152602001348152602001506040518860e060020a02815260040180888152602001876002602002808383829060006004602084601f0104600f02600301f150905001868152602001806020018560ff1681526020018461ffff168152602001836006602002808383829060006004602084601f0104600f02600301f1509050018281038252868181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156105d25780820380516001836020036101000a031916815260200191505b509850505050505050505060206040518083038160008760325a03f2156100025750506040515191506124cd9050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808787611e64610f6d565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611d28610f6d565b61189f5b6000611bf8611159565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881600060005054611a9561159f565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346326a7985a6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b760075b90565b604080516020606435600481810135601f8101849004840285018401909552848452611882948135946024803595604435956084949201919081908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160013389898861224b610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386866020604051908101604052806000815260200150611e64610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333896020604051908101604052806000815260200150886123bc6106c6565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387866020604051908101604052806000815260200150611f8d610f6d565b60408051602060248035600481810135601f810185900485028601850190965285855261188295813595919460449492939092019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808888612225610f6d565b611882600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503388886020604051908101604052806000815260200150612388610f6d565b611882600435604080517fc4144b2600000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163c4144b26916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437509496505093359350505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133888888612238610f6d565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a43560c435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338b8b8b896126536106c6565b611882600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333866020604051908101604052806000815260200150611e4a610f6d565b6118b76004355b604080517fed5bd7ea00000000000000000000000000000000000000000000000000000000815260016004820152600160a060020a03831660248201529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163ed5bd7ea916044818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b61189f600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463586a69fa6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f81018590048502860185019096528585526118829581359591946044949293909201918190840183828082843750949650509335935050606435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808989612388610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a896020604051908101604052806000815260200150886124d76106c6565b6040805160206004803580820135601f8101849004840285018401909552848452611882949193602493909291840191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808587611e4a610f6d565b61188260043560243560443560643560843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050338a8a60206040519081016040528060008152602001508961262d6106c6565b604080516020606435600481810135601f810184900484028501840190955284845261188294813594602480359560443595608494920191908190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338888876120c7610f6d565b604080516020604435600481810135601f81018490048402850184019095528484526118829481359460248035959394606494929391019181908401838280828437505060408051608080820190925295979635969561010495509350608492508591508390839080828437509095505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989898961263a6106c6565b6118b7600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881858585611ba361122c565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001600050333388602060405190810160405280600081526020015061236e610f6d565b6118b760005481565b6118c95b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea34638e46afa96040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a43560c43560e43561010435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338e8e8d8f8e8e8e8e8e346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156111195780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519b9a5050505050505050505050565b61189f5b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463971c803f6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650509335935050608435915050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338989896123a2610f6d565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398c9cdf46040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346398e00e546040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600435604080517fe6ce3a6a000000000000000000000000000000000000000000000000000000008152600160048201527f3e3d0000000000000000000000000000000000000000000000000000000000006024820152604481018390529051600091737c1eb207c07e7ab13cf245585bd03d0fa478d0349163e6ce3a6a916064818101926020929091908290030181878760325a03f215610002575050604051519150611b409050565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503385600060e060020a0260206040519081016040528060008152602001506121ef610f6d565b604080516020604435600481810135601f8101849004840285018401909552848452611882948135946024803595939460649492939101918190840183828082843750949650505050505050600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338787876120b5610f6d565b6118b7600435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88183611b4561159f565b6118b75b600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463b152f19e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b60408051602060248035600481810135601f8101859004850286018501909652858552611882958135959194604494929390920191819084018382808284375094965050933593505060643591505060843560a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600133808b8b8961262d6106c6565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503386600060e060020a026020604051908101604052806000815260200150612200610f6d565b6118b75b60005460649004610759565b6118b7600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463c0f688596040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506107599050565b611882600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333600060e060020a026020604051908101604052806000815260200150611bff610f6d565b611882600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503333876020604051908101604052806000815260200150612200610f6d565b611882600435602435604435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e41160016000503387600060e060020a026020604051908101604052806000815260200150612213610f6d565b611882600435602435604435606435608435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e411600160005033338a60206040519081016040528060008152602001508961250c6106c6565b61027c6000600060006118e033610b56565b6118b7600435602435604435606435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a881868686866040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b949350505050565b604080516020604435600481810135601f810184900484028501840190955284845261188294813594602480359593946064949293910191819084018382808284375094965050933593505060843591505060a435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea346350d4e4116001338a8a8a886124fa6106c6565b6118b7600435602435600073e54d323f9ef17c1f0dede47ecc86a9718fe5ea3463ea27a88184846000611b4f61122c565b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b60408051918252519081900360200190f35b6040805160ff929092168252519081900360200190f35b15611a905733925082600160a060020a031663c6502da86040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040805180517fc6803622000000000000000000000000000000000000000000000000000000008252915191945063c680362291600482810192602092919082900301816000876161da5a03f11561000257505060405151905080156119d1575082600160a060020a031663d379be236040518160e060020a0281526004018090506020604051808303816000876161da5a03f11561000257505060405151600160a060020a03166000141590505b80156119dd5750600082115b80156119ec5750600054600190115b15611a90578183600160a060020a031663830953ab6040518160e060020a0281526004018090506020604051808303816000876161da5a03f1156100025750506040515160640291909104915050604281118015611a4d5750600054829011155b15611a675760008054612710612711909102049055611a90565b602181108015611a7a5750600054829010155b15611a90576000805461271061270f9091020490555b505050565b6000611a9f61122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b919050565b6000611af261122c565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b6040518560e060020a0281526004018085815260200184815260200183815260200182815260200194505050505060206040518083038160008760325a03f215610002575050604051519150505b9392505050565b9050610759565b611c076106c6565b6000611c11611478565b611c1961122c565b600054611c2461159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611cf25780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506107599050565b611d306106c6565b60008b611d3b61122c565b600054611d4661159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611e145780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b409050565b611e526106c6565b6000611e5c611478565b611d3b61122c565b611e6c6106c6565b6000611e76611478565b611e7e61122c565b600054611e8961159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015611f575780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611b9d9050565b611f956106c6565b8b611f9e611478565b611fa661122c565b600054611fb161159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561207f5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150611bf19050565b6120bd6106c6565b6000611f9e611478565b6120cf6106c6565b8b6120d8611478565b6120e061122c565b6000546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156121b95780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f2156100025750506040515191506117c99050565b6121f76106c6565b8b611e76611478565b6122086106c6565b60008b611e7e61122c565b61221b6106c6565b8a8c611fa661122c565b61222d6106c6565b60008b611fa661122c565b6122406106c6565b60008b6120e061122c565b6122536106c6565b8c8b61225d61122c565b60005461226861159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156123365780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f21561000257505060405151979650505050505050565b6123766106c6565b60008c8c600060005054611fb161159f565b6123906106c6565b60008c8c6000600050546120eb61159f565b6123aa6106c6565b60008c8c60006000505461226861159f565b60008d8d6000600050546120eb61159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f16801561249c5780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519150505b9695505050505050565b8e8d8d6000600050546123ce61159f565b60008d8d60006000505461226861159f565b60008d8d6000600050546123ce61159f565b60008e8e8d61226861159f565b8f8e8e8d61252561159f565b346040518e60e060020a028152600401808e81526020018d600160a060020a031681526020018c600160a060020a031681526020018b8152602001806020018a60ff1681526020018961ffff16815260200188815260200187815260200186815260200185815260200184815260200183815260200182810382528b8181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f1680156125f35780820380516001836020036101000a031916815260200191505b509e50505050505050505050505050505060206040518083038160008760325a03f215610002575050604051519998505050505050505050565b60008e8e8d6123ce61159f565b8a5160208c015160408d015160608e015161226861159f565b60008e8e8d61252561159f56", + "codeHash": "0x461e17b7ae561793f22843985fc6866a3395c1fcee8ebf2d7ed5f293aec1b473", "storage": { "0x26cba0705aade77fa0f9275b68d01fb71206a44abd3a4f5a838f7241efbc8abf": "0x00000000000000000000000042e69cd0a17ae9992f9ad93d136c4bb0d95e3230", "0x49f03a2c2f4fd666a32141fb324283b6f84a1d07b5fa435669fdb55766aef715": "0x000000000000000000000000d7b0e93fa8386b17fb5d1cf934076203dcc122f3", @@ -226,11 +227,13 @@ }, "0x741467b251fca923d6229c4b439078b55dca233b": { "balance": "0x29c613529e8218f8", - "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256" + "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256", + "codeHash": "0x7678943ba1f399d76abe8e77b6f899c193f72aaefb5c4bd47fffb63c7f57ad9e" }, "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": { "balance": "0xd7a58f5b73b4b6c4", "code": "0x606060405236156100985760e060020a60003504633896002781146100e15780633defb962146100ea5780633f4be8891461010c5780634136aa351461011f5780634a420138146101a057806369c1a7121461028c5780638129fc1c146102955780638da5cb5b146102a6578063ae45850b146102b8578063af3309d8146102cc578063ea8a1af0146102d5578063ead50da3146102f4575b610308671bc16d674ec8000030600160a060020a03163110156100df57600554604051600160a060020a03918216916000913091909116319082818181858883f150505050505b565b61030a60005481565b610308671bc16d674ec8000030600160a060020a031631101561040f576100df565b61031c600454600160a060020a03165b90565b61030a5b600080548190118015610199575060408051600480547f0a16697a0000000000000000000000000000000000000000000000000000000083529251600160a060020a039390931692630a16697a928083019260209291829003018187876161da5a03f1156100025750506040515160ff01431090505b905061011c565b6103085b600354600554604080517f8c0e156d0000000000000000000000000000000000000000000000000000000081527f3defb96200000000000000000000000000000000000000000000000000000000600482015260a060020a90920461ffff1643016024830152621e8480604483015251600092600160a060020a031691638c0e156d916729a2241af62c000091606481810192602092909190829003018185886185025a03f1156100025750506040515192600160a060020a0384161491506102899050576004805473ffffffffffffffffffffffffffffffffffffffff1916821790555b50565b61030a60015481565b61030860008054146103f2576100df565b61031c600554600160a060020a031681565b61031c600354600160a060020a031661011c565b61030a60025481565b610308600554600160a060020a03908116339091161461035157610002565b61033960055460a060020a900461ffff1681565b005b60408051918252519081900360200190f35b60408051600160a060020a03929092168252519081900360200190f35b6040805161ffff929092168252519081900360200190f35b6004546000600160a060020a03919091163111156103c75760408051600480547fea8a1af00000000000000000000000000000000000000000000000000000000083529251600160a060020a03939093169263ea8a1af0928083019260009291829003018183876161da5a03f115610002575050505b600554604051600160a060020a03918216916000913091909116319082818181858883f15050505050565b426000556100df6101a4565b600280546001908101909155429055565b600454600160a060020a03908116339091161461042b576100df565b610433610123565b151561043e576100df565b6103fe6101a456", + "codeHash": "0xd1255e5eabbe40c6e18c87b2ed2acf8157356103d1ca1df617f7b52811edefc4", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000056d0009b", "0x0000000000000000000000000000000000000000000000000000000000000002": "0x000000000000000000000000000000000000000000000000000000000000008b", @@ -253,6 +256,7 @@ "0x651913977e8140c323997fce5e03c19e0015eebf": { "balance": "0x29a2241af62c0000", "code": "0x606060405236156101a05760e060020a60003504630924120081146101c25780630a16697a146101cf5780630fd1f94e146101d8578063137c638b1461022e57806321835af61461023b57806324032866146102545780632f95b833146102d65780633017fe24146102e55780633233c686146102ef57806337f4c00e146102fa5780634500054f146103055780634e417a98146103785780634e71d92d146103e15780634f059a43146103f35780636146195414610451578063625cc4651461046157806367ce940d1461046a5780637d298ee314610477578063830953ab146104f9578063938b5f321461050457806395ee122114610516578063974654f41461052a578063a06db7dc14610535578063a9d2293d14610541578063ae45850b14610597578063b0f07e44146105a9578063c19d93fb146105cb578063c6502da81461062e578063c680362214610637578063ca94692d1461064a578063cc3471af14610673578063d379be23146106c9578063d62457f6146106e3578063ea8a1af0146106ee578063f5562753146107f3578063f6b4dfb414610854575b610868600080548190600160a060020a03908116339091161461087a57610994565b610868600b5460ff165b90565b610868600d5481565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630fd1f94e6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6108685b62012cc86101cc565b61086860043560008160001415610dc65750600161084f565b6108686004356024356000731deeda36e15ec9e80f3d7414d67a4803ae45fc80630bd295e6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f215610002575050604051519150505b92915050565b61099860085461ffff166101cc565b61086860026101cc565b610868600a546101cc565b6108686006546101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a09431546003600050336040518360e060020a0281526004018083815260200182600160a060020a031681526020019250505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b6109af60408051602081810183526000825282516004805460026001821615610100026000190190911604601f81018490048402830184019095528482529293909291830182828015610a7d5780601f10610a5257610100808354040283529160200191610a7d565b61086860006000600180610b7b6105cf565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753436040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1d6000600480610c986105cf565b61086860025481565b6108685b620186a06101cc565b6108686004356024355b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a1873db6600360005085856040518460e060020a0281526004018084815260200183600160a060020a03168152602001828152602001935050505060206040518083038160008760325a03f2156100025750506040515191506102d09050565b6108686009546101cc565b610a1f600c54600160a060020a031681565b610868600b5462010000900460ff166101cc565b6108686007546101cc565b610a3c600e5460ff1681565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063a9d2293d6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600054600160a060020a031681565b610868600080548190600160a060020a039081163390911614610a8957610994565b6108685b6000731deeda36e15ec9e80f3d7414d67a4803ae45fc80635054d98a60036000506040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b61086860015481565b610868600b54610100900460ff166101cc565b61086860035474010000000000000000000000000000000000000000900460e060020a026101cc565b6108686000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063cc3471af6040518160e060020a02815260040180905060206040518083038160008760325a03f2156100025750506040515191506101cc9050565b610a1f600854620100009004600160a060020a03166101cc565b6108686005546101cc565b610a1d604080517fa09431540000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc809163a0943154916044808301926020929190829003018160008760325a03f215610002575050604051511590506107f157604080517f7e9265620000000000000000000000000000000000000000000000000000000081526003600482015233600160a060020a031660248201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091637e9265629160448083019260009291908290030181838760325a03f215610002575050505b565b6108686004356000731deeda36e15ec9e80f3d7414d67a4803ae45fc8063f5562753836040518260e060020a0281526004018082815260200191505060206040518083038160008760325a03f215610002575050604051519150505b919050565b610a1f600354600160a060020a03166101cc565b60408051918252519081900360200190f35b60045460006002600183161561010002600019019092169190910411156108a45760009150610994565b6108ac6105cf565b9050600081141580156108c0575060018114155b80156108cd575060028114155b156108db5760009150610994565b600480546000828152602060026001841615610100026000190190931692909204601f908101929092047f8a35acfbc15ff81a39ae7d344fd709f28e8600b4aa8c65c6b64bfe7fe36bd19b9081019236929083901061095d5782800160ff198235161785555b5061098d9291505b808211156109945760008155600101610949565b82800160010185558215610941579182015b8281111561094157823582600050559160200191906001019061096f565b5050600191505b5090565b6040805161ffff9092168252519081900360200190f35b60405180806020018281038252838181518152602001915080519060200190808383829060006004602084601f0104600f02600301f150905090810190601f168015610a0f5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b005b60408051600160a060020a03929092168252519081900360200190f35b6040805160ff9092168252519081900360200190f35b820191906000526020600020905b815481529060010190602001808311610a6057829003601f168201915b505050505090506101cc565b6004546000600260018316156101000260001901909216919091041115610ab35760009150610994565b610abb6105cf565b905060008114158015610acf575060018114155b8015610adc575060028114155b15610aea5760009150610994565b604080517f7c0278fc000000000000000000000000000000000000000000000000000000008152600360048201818152602483019384523660448401819052731deeda36e15ec9e80f3d7414d67a4803ae45fc8094637c0278fc946000939190606401848480828437820191505094505050505060006040518083038160008760325a03f215610002575050505090565b1415610c8557604080516001547f0fee183d0000000000000000000000000000000000000000000000000000000082526003600483015233600160a060020a0316602483015234604483015260648201529051731deeda36e15ec9e80f3d7414d67a4803ae45fc8091630fee183d916084828101926020929190829003018160008760325a03f21561000257505060405151925050811515610c8a577389efe605e9ecbe22849cd85d5449cc946c26f8f36312c82bcc33346040518360e060020a0281526004018083600160a060020a031681526020018281526020019250505060206040518083038160008760325a03f2156100025750506040515115159050610c8a57610002565b505090565b81925050610994565b505b50565b1415610c93575a9150610cab3383610481565b1515610cb75750610c95565b731deeda36e15ec9e80f3d7414d67a4803ae45fc8063da46be0a60038433610cdd61046e565b610ce5610232565b6040518660e060020a0281526004018086815260200185815260200184600160a060020a031681526020018381526020018281526020019550505050505060006040518083038160008760325a03f21561000257505050610c933360408051600080547fc17e6817000000000000000000000000000000000000000000000000000000008352600160a060020a03908116600484015230163160248301529151731deeda36e15ec9e80f3d7414d67a4803ae45fc809263c17e68179260448082019360209390928390039091019082908760325a03f2156100025750505050565b30600160a060020a031660405180807f5f5f6469672875696e7432353629000000000000000000000000000000000000815260200150600e019050604051809103902060e060020a8091040260e060020a9004600184036040518260e060020a0281526004018082815260200191505060006040518083038160008760325a03f292505050151561084f5761000256", + "codeHash": "0x7678943ba1f399d76abe8e77b6f899c193f72aaefb5c4bd47fffb63c7f57ad9e", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000007dd677b54fc954824a7bc49bd26cbdfa12c75adf", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000011f8119429ed3a", diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create_disable_code_and_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create_disable_code_and_storage.json index 96c93e7cf8..9b6b7577f9 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create_disable_code_and_storage.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/inner_create_disable_code_and_storage.json @@ -211,13 +211,16 @@ }, "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": { "balance": "0x0", - "nonce": 237 + "nonce": 237, + "codeHash":"0x461e17b7ae561793f22843985fc6866a3395c1fcee8ebf2d7ed5f293aec1b473" }, "0x741467b251fca923d6229c4b439078b55dca233b": { - "balance": "0x29c613529e8218f8" + "balance": "0x29c613529e8218f8", + "codeHash":"0x7678943ba1f399d76abe8e77b6f899c193f72aaefb5c4bd47fffb63c7f57ad9e" }, "0x7dd677b54fc954824a7bc49bd26cbdfa12c75adf": { - "balance": "0xd7a58f5b73b4b6c4" + "balance": "0xd7a58f5b73b4b6c4", + "codeHash":"0xd1255e5eabbe40c6e18c87b2ed2acf8157356103d1ca1df617f7b52811edefc4" }, "0xb834e3edfc1a927bdcecb67a9d0eccbd752a5bb3": { "balance": "0xffe9b09a5c474dca", @@ -233,7 +236,8 @@ "balance": "0x98e2b02f14529b1eb2" }, "0x651913977e8140c323997fce5e03c19e0015eebf": { - "balance": "0x29a2241af62c0000" + "balance": "0x29a2241af62c0000", + "codeHash":"0x7678943ba1f399d76abe8e77b6f899c193f72aaefb5c4bd47fffb63c7f57ad9e" }, "0x6c8f2a135f6ed072de4503bd7c4999a1a17f824b": { "nonce": 238 diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json index be4981b8b8..c97e16bce5 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple.json @@ -68,6 +68,7 @@ "balance": "0x4d87094125a369d9bd5", "nonce": 1, "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", + "codeHash": "0xec0ba40983fafc34be1bda1b3a3c6eabdd60fa4ce6eab345be1e51bda01d0d4f", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" } diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json index 502149de43..9041901790 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/simple_disable_code_and_storage.json @@ -67,6 +67,7 @@ "balance": "0x4d87094125a369d9bd5", "nonce": 1, "code": "0x606060405236156100935763ffffffff60e060020a60003504166311ee8382811461009c57806313af4035146100be5780631f5e8f4c146100ee57806324daddc5146101125780634921a91a1461013b57806363e4bff414610157578063764978f91461017f578063893d20e8146101a1578063ba40aaa1146101cd578063cebc9a82146101f4578063e177246e14610216575b61009a5b5b565b005b34156100a457fe5b6100ac61023d565b60408051918252519081900360200190f35b34156100c657fe5b6100da600160a060020a0360043516610244565b604080519115158252519081900360200190f35b34156100f657fe5b6100da610307565b604080519115158252519081900360200190f35b341561011a57fe5b6100da6004351515610318565b604080519115158252519081900360200190f35b6100da6103d6565b604080519115158252519081900360200190f35b6100da600160a060020a0360043516610420565b604080519115158252519081900360200190f35b341561018757fe5b6100ac61046c565b60408051918252519081900360200190f35b34156101a957fe5b6101b1610473565b60408051600160a060020a039092168252519081900360200190f35b34156101d557fe5b6100da600435610483565b604080519115158252519081900360200190f35b34156101fc57fe5b6100ac61050d565b60408051918252519081900360200190f35b341561021e57fe5b6100da600435610514565b604080519115158252519081900360200190f35b6003545b90565b60006000610250610473565b600160a060020a031633600160a060020a03161415156102705760006000fd5b600160a060020a03831615156102865760006000fd5b50600054600160a060020a0390811690831681146102fb57604051600160a060020a0380851691908316907ffcf23a92150d56e85e3a3d33b357493246e55783095eb6a733eb8439ffc752c890600090a360008054600160a060020a031916600160a060020a03851617905560019150610300565b600091505b5b50919050565b60005460a060020a900460ff165b90565b60006000610324610473565b600160a060020a031633600160a060020a03161415156103445760006000fd5b5060005460a060020a900460ff16801515831515146102fb576000546040805160a060020a90920460ff1615158252841515602083015280517fe6cd46a119083b86efc6884b970bfa30c1708f53ba57b86716f15b2f4551a9539281900390910190a16000805460a060020a60ff02191660a060020a8515150217905560019150610300565b600091505b5b50919050565b60006103e0610307565b801561040557506103ef610473565b600160a060020a031633600160a060020a031614155b156104105760006000fd5b610419336105a0565b90505b5b90565b600061042a610307565b801561044f5750610439610473565b600160a060020a031633600160a060020a031614155b1561045a5760006000fd5b610463826105a0565b90505b5b919050565b6001545b90565b600054600160a060020a03165b90565b6000600061048f610473565b600160a060020a031633600160a060020a03161415156104af5760006000fd5b506001548281146102fb57604080518281526020810185905281517f79a3746dde45672c9e8ab3644b8bb9c399a103da2dc94b56ba09777330a83509929181900390910190a160018381559150610300565b600091505b5b50919050565b6002545b90565b60006000610520610473565b600160a060020a031633600160a060020a03161415156105405760006000fd5b506002548281146102fb57604080518281526020810185905281517ff6991a728965fedd6e927fdf16bdad42d8995970b4b31b8a2bf88767516e2494929181900390910190a1600283905560019150610300565b600091505b5b50919050565b60006000426105ad61023d565b116102fb576105c46105bd61050d565b4201610652565b6105cc61046c565b604051909150600160a060020a038416908290600081818185876187965a03f1925050501561063d57604080518281529051600160a060020a038516917f9bca65ce52fdef8a470977b51f247a2295123a4807dfa9e502edf0d30722da3b919081900360200190a260019150610300565b6102fb42610652565b5b600091505b50919050565b60038190555b505600a165627a7a72305820f3c973c8b7ed1f62000b6701bd5b708469e19d0f1d73fde378a56c07fd0b19090029", + "codeHash": "0xec0ba40983fafc34be1bda1b3a3c6eabdd60fa4ce6eab345be1e51bda01d0d4f", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000003": "0x000000000000000000000000000000000000000000000000000000005a37b834" } diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json index 3f07146871..23ac6852d9 100644 --- a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide.json @@ -79,6 +79,7 @@ "0x2861bf89b6c640c79040d357c1e9513693ef5d3f": { "balance": "0x0", "code": "0x606060405236156100825760e060020a600035046312055e8f8114610084578063185061da146100b157806322beb9b9146100d5578063245a03ec146101865780633fa4f245146102a657806341c0e1b5146102af578063890eba68146102cb578063b29f0835146102de578063d6b4485914610308578063dd012a15146103b9575b005b6001805474ff0000000000000000000000000000000000000000191660a060020a60043502179055610082565b6100826001805475ff00000000000000000000000000000000000000000019169055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527fb29f0835000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b6100826004356024356001547fb0f07e440000000000000000000000000000000000000000000000000000000060609081526064839052600160a060020a039091169063b0f07e449060849060009060248183876161da5a03f150604080516001547f73657449742875696e74323536290000000000000000000000000000000000008252825191829003600e018220878352835192839003602001832060e060020a6352afbc33028452600160a060020a03308116600486015260e060020a9283900490920260248501526044840152438901606484015260a060020a820460ff1694830194909452600060a483018190529251931694506352afbc33935060c48181019391829003018183876161da5a03f115610002575050505050565b6103c460025481565b61008260005433600160a060020a039081169116146103ce575b565b6103c460015460a860020a900460ff1681565b6100826001805475ff000000000000000000000000000000000000000000191660a860020a179055565b61008260043560015460e060020a6352afbc3302606090815230600160a060020a039081166064527f185061da000000000000000000000000000000000000000000000000000000006084527fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a47060a45243840160c490815260ff60a060020a85041660e452600061010481905291909316926352afbc339261012492918183876161da5a03f1156100025750505050565b600435600255610082565b6060908152602090f35b6001547f6ff96d17000000000000000000000000000000000000000000000000000000006060908152600160a060020a0330811660645290911690632e1a7d4d908290636ff96d17906084906020906024816000876161da5a03f1156100025750506040805180517f2e1a7d4d0000000000000000000000000000000000000000000000000000000082526004820152905160248281019350600092829003018183876161da5a03f115610002575050600054600160a060020a03169050ff", + "codeHash": "0xad3e5642a709b936c0eafdd1fbca08a9f5f5089ff2008efeee3eed3f110d83d3", "storage": { "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000d3cda913deb6f67967b99d67acdfa1712c293601", "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000ff30c9e568f133adce1f1ea91e189613223fc461b9" diff --git a/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide_cancun.json b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide_cancun.json new file mode 100644 index 0000000000..cdabe66913 --- /dev/null +++ b/eth/tracers/internal/tracetest/testdata/prestate_tracer_with_diff_mode/suicide_cancun.json @@ -0,0 +1,101 @@ +{ + "context": { + "difficulty": "0", + "gasLimit": "8000000", + "miner": "0x0000000000000000000000000000000000000000", + "number": "1", + "timestamp": "1000", + "baseFeePerGas": "7" + }, + "genesis": { + "alloc": { + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x10000000000000000", + "nonce": "0", + "code": "0x", + "storage": {} + }, + "0x1111111111111111111111111111111111111111": { + "balance": "0x0", + "nonce": "0", + "code": "0x", + "storage": {} + }, + "0x2222222222222222222222222222222222222222": { + "balance": "0xde0b6b3a7640000", + "nonce": "1", + "code": "0x6099600155731111111111111111111111111111111111111111ff", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000000000000000000000000000000000000000abcd", + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000001234" + } + } + }, + "config": { + "chainId": 1, + "homesteadBlock": 0, + "eip150Block": 0, + "eip155Block": 0, + "eip158Block": 0, + "byzantiumBlock": 0, + "constantinopleBlock": 0, + "petersburgBlock": 0, + "istanbulBlock": 0, + "berlinBlock": 0, + "londonBlock": 0, + "mergeNetsplitBlock": 0, + "shanghaiTime": 0, + "cancunTime": 0, + "terminalTotalDifficulty": 0, + "terminalTotalDifficultyPassed": true + }, + "difficulty": "0", + "extraData": "0x", + "gasLimit": "8000000", + "hash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "miner": "0x0000000000000000000000000000000000000000", + "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", + "nonce": "0x0000000000000000", + "number": "0", + "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", + "timestamp": "0" + }, + "input": "0xf860800a830186a094222222222222222222222222222222222222222280801ba0c4829400221936e8016721406f84b4710ead5608f15c785a3cedc20a7aebaab2a033e8e6e12cc432098b5ce8a409691f977867249073a3fc7804e8676c4d159475", + "tracerConfig": { + "diffMode": true + }, + "result": { + "pre": { + "0x2222222222222222222222222222222222222222": { + "balance": "0xde0b6b3a7640000", + "nonce": 1, + "code": "0x6099600155731111111111111111111111111111111111111111ff", + "codeHash": "0x701bdb1d43777a9304905a100f758955d130e09c8e86d97e3f6becccdc001048", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x000000000000000000000000000000000000000000000000000000000000abcd" + } + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0x10000000000000000" + } + }, + "post": { + "0x0000000000000000000000000000000000000000": { + "balance": "0x2aed3" + }, + "0x1111111111111111111111111111111111111111": { + "balance": "0xde0b6b3a7640000" + }, + "0x2222222222222222222222222222222222222222": { + "balance": "0x0", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000001": "0x0000000000000000000000000000000000000000000000000000000000000099" + } + }, + "0xa94f5374fce5edbc8e2a8697c15331677e6ebf0b": { + "balance": "0xfffffffffff70e96", + "nonce": 1 + } + } + } +} diff --git a/eth/tracers/live/supply.go b/eth/tracers/live/supply.go index bae7445cb4..ad3b9cbae3 100644 --- a/eth/tracers/live/supply.go +++ b/eth/tracers/live/supply.go @@ -199,8 +199,7 @@ func (s *supplyTracer) onBalanceChange(a common.Address, prevBalance, newBalance // NOTE: don't handle "BalanceIncreaseGenesisBalance" because it is handled in OnGenesisBlock switch reason { - case tracing.BalanceIncreaseRewardMineUncle: - case tracing.BalanceIncreaseRewardMineBlock: + case tracing.BalanceIncreaseRewardMineBlock, tracing.BalanceIncreaseRewardMineUncle: s.delta.Issuance.Reward.Add(s.delta.Issuance.Reward, diff) case tracing.BalanceIncreaseWithdrawal: s.delta.Issuance.Withdrawals.Add(s.delta.Issuance.Withdrawals, diff) diff --git a/eth/tracers/logger/logger.go b/eth/tracers/logger/logger.go index 824a5e0c3e..67e07f78d0 100644 --- a/eth/tracers/logger/logger.go +++ b/eth/tracers/logger/logger.go @@ -94,8 +94,8 @@ func (s *StructLog) ErrorString() string { return "" } -// WriteTo writes the human-readable log data into the supplied writer. -func (s *StructLog) WriteTo(writer io.Writer) { +// Write writes the human-readable log data into the supplied writer. +func (s *StructLog) Write(writer io.Writer) { fmt.Fprintf(writer, "%-16spc=%08d gas=%v cost=%v", s.Op, s.Pc, s.Gas, s.GasCost) if s.Err != nil { fmt.Fprintf(writer, " ERROR: %v", s.Err) @@ -324,7 +324,7 @@ func (l *StructLogger) OnOpcode(pc uint64, opcode byte, gas, cost uint64, scope l.logs = append(l.logs, entry) return } - log.WriteTo(l.writer) + log.Write(l.writer) } // OnExit is called a call frame finishes processing. @@ -405,7 +405,7 @@ func (l *StructLogger) Output() []byte { return l.output } // @deprecated func WriteTrace(writer io.Writer, logs []StructLog) { for _, log := range logs { - log.WriteTo(writer) + log.Write(writer) } } diff --git a/eth/tracers/native/erc7562.go b/eth/tracers/native/erc7562.go index 3ab98c7132..34e202f667 100644 --- a/eth/tracers/native/erc7562.go +++ b/eth/tracers/native/erc7562.go @@ -513,7 +513,7 @@ func defaultIgnoredOpcodes() []hexutil.Uint64 { ignored := make([]hexutil.Uint64, 0, 64) // Allow all PUSHx, DUPx and SWAPx opcodes as they have sequential codes - for op := vm.PUSH0; op < vm.SWAP16; op++ { + for op := vm.PUSH0; op <= vm.SWAP16; op++ { ignored = append(ignored, hexutil.Uint64(op)) } diff --git a/eth/tracers/native/gen_account_json.go b/eth/tracers/native/gen_account_json.go index 4c39cbc38c..5fec2648b7 100644 --- a/eth/tracers/native/gen_account_json.go +++ b/eth/tracers/native/gen_account_json.go @@ -15,14 +15,16 @@ var _ = (*accountMarshaling)(nil) // MarshalJSON marshals as JSON. func (a account) MarshalJSON() ([]byte, error) { type account struct { - Balance *hexutil.Big `json:"balance,omitempty"` - Code hexutil.Bytes `json:"code,omitempty"` - Nonce uint64 `json:"nonce,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + Balance *hexutil.Big `json:"balance,omitempty"` + Code hexutil.Bytes `json:"code,omitempty"` + CodeHash *common.Hash `json:"codeHash,omitempty"` + Nonce uint64 `json:"nonce,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` } var enc account enc.Balance = (*hexutil.Big)(a.Balance) enc.Code = a.Code + enc.CodeHash = a.CodeHash enc.Nonce = a.Nonce enc.Storage = a.Storage return json.Marshal(&enc) @@ -31,10 +33,11 @@ func (a account) MarshalJSON() ([]byte, error) { // UnmarshalJSON unmarshals from JSON. func (a *account) UnmarshalJSON(input []byte) error { type account struct { - Balance *hexutil.Big `json:"balance,omitempty"` - Code *hexutil.Bytes `json:"code,omitempty"` - Nonce *uint64 `json:"nonce,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + Balance *hexutil.Big `json:"balance,omitempty"` + Code *hexutil.Bytes `json:"code,omitempty"` + CodeHash *common.Hash `json:"codeHash,omitempty"` + Nonce *uint64 `json:"nonce,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` } var dec account if err := json.Unmarshal(input, &dec); err != nil { @@ -46,6 +49,9 @@ func (a *account) UnmarshalJSON(input []byte) error { if dec.Code != nil { a.Code = *dec.Code } + if dec.CodeHash != nil { + a.CodeHash = dec.CodeHash + } if dec.Nonce != nil { a.Nonce = *dec.Nonce } diff --git a/eth/tracers/native/keccak256_preimage.go b/eth/tracers/native/keccak256_preimage.go new file mode 100644 index 0000000000..0c2b7e6e32 --- /dev/null +++ b/eth/tracers/native/keccak256_preimage.go @@ -0,0 +1,86 @@ +package native + +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/eth/tracers/internal" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +func init() { + tracers.DefaultDirectory.Register("keccak256PreimageTracer", newKeccak256PreimageTracer, false) +} + +// keccak256PreimageTracer is a native tracer that collects preimages of all KECCAK256 operations. +// This tracer is particularly useful for analyzing smart contract execution patterns, +// especially when debugging storage access in Solidity mappings and dynamic arrays. +type keccak256PreimageTracer struct { + computedHashes map[common.Hash]hexutil.Bytes +} + +// newKeccak256PreimageTracer returns a new keccak256PreimageTracer instance. +func newKeccak256PreimageTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) { + t := &keccak256PreimageTracer{ + computedHashes: make(map[common.Hash]hexutil.Bytes), + } + return &tracers.Tracer{ + Hooks: &tracing.Hooks{ + OnOpcode: t.OnOpcode, + }, + GetResult: t.GetResult, + }, nil +} + +func (t *keccak256PreimageTracer) OnOpcode(pc uint64, op byte, gas, cost uint64, scope tracing.OpContext, rData []byte, depth int, err error) { + if op == byte(vm.KECCAK256) { + sd := scope.StackData() + // it turns out that sometimes the stack is empty, evm will fail in this case, but we should not panic here + if len(sd) < 2 { + return + } + + dataOffset := internal.StackBack(sd, 0).Uint64() + dataLength := internal.StackBack(sd, 1).Uint64() + preimage, err := internal.GetMemoryCopyPadded(scope.MemoryData(), int64(dataOffset), int64(dataLength)) + if err != nil { + log.Warn("keccak256PreimageTracer: failed to copy keccak preimage from memory", "err", err) + return + } + + hash := crypto.Keccak256(preimage) + + t.computedHashes[common.Hash(hash)] = hexutil.Bytes(preimage) + } +} + +// GetResult returns the collected keccak256 preimages as a JSON object mapping hashes to preimages. +func (t *keccak256PreimageTracer) GetResult() (json.RawMessage, error) { + msg, err := json.Marshal(t.computedHashes) + if err != nil { + return nil, err + } + return msg, nil +} diff --git a/eth/tracers/native/keccak256_preimage_test.go b/eth/tracers/native/keccak256_preimage_test.go new file mode 100644 index 0000000000..b54b0cc238 --- /dev/null +++ b/eth/tracers/native/keccak256_preimage_test.go @@ -0,0 +1,442 @@ +// Copyright 2021 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package native_test + +import ( + "encoding/json" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/tracing" + "github.com/ethereum/go-ethereum/core/vm" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth/tracers" + "github.com/ethereum/go-ethereum/params" + "github.com/holiman/uint256" + "github.com/stretchr/testify/require" +) + +// mockOpContext implements tracing.OpContext for testing +type mockOpContext struct { + memory []byte + stack []uint256.Int +} + +// Ensure mockOpContext implements tracing.OpContext +var _ tracing.OpContext = (*mockOpContext)(nil) + +func (m *mockOpContext) MemoryData() []byte { + return m.memory +} + +func (m *mockOpContext) StackData() []uint256.Int { + return m.stack +} + +func (m *mockOpContext) Address() common.Address { + return common.Address{} +} + +func (m *mockOpContext) Caller() common.Address { + return common.Address{} +} + +func (m *mockOpContext) CallValue() *uint256.Int { + return uint256.NewInt(0) +} + +func (m *mockOpContext) CallInput() []byte { + return []byte{} +} + +func (m *mockOpContext) ContractCode() []byte { + return []byte{} +} + +func TestKeccak256PreimageTracerCreation(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + require.NotNil(t, tracer) + require.NotNil(t, tracer.Hooks) + require.NotNil(t, tracer.Hooks.OnOpcode) + require.NotNil(t, tracer.GetResult) +} + +func TestKeccak256PreimageTracerInitialResult(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + require.Empty(t, hashes) +} + +func TestKeccak256PreimageTracerSingleKeccak(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + // Test data: "hello world" + testData := []byte("hello world") + memory := make([]byte, 32) + copy(memory, testData) + + // Create stack with offset=0, length=11 + stack := []uint256.Int{ + *uint256.NewInt(11), // length (stack[1]) + *uint256.NewInt(0), // offset (stack[0]) + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // Call OnOpcode with KECCAK256 + tracer.OnOpcode(0, byte(vm.KECCAK256), 0, 0, mockScope, nil, 0, nil) + + // Get result + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + + // Verify the hash and preimage + expectedHash := crypto.Keccak256Hash(testData) + require.Len(t, hashes, 1) + require.Contains(t, hashes, expectedHash) + require.Equal(t, hexutil.Bytes(testData), hashes[expectedHash]) +} + +func TestKeccak256PreimageTracerMultipleKeccak(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + testCases := []struct { + name string + data []byte + }{ + {"empty", []byte{}}, + {"hello", []byte("hello")}, + {"world", []byte("world")}, + {"long_data", make([]byte, 100)}, + } + + // Initialize long_data with some pattern + for i := range testCases[3].data { + testCases[3].data[i] = byte(i % 256) + } + + expectedHashes := make(map[common.Hash]hexutil.Bytes) + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + memory := make([]byte, max(len(tc.data), 1)) + copy(memory, tc.data) + + stack := []uint256.Int{ + *uint256.NewInt(uint64(len(tc.data))), // length + *uint256.NewInt(0), // offset + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // Call OnOpcode with KECCAK256 + tracer.OnOpcode(0, byte(vm.KECCAK256), 0, 0, mockScope, nil, 0, nil) + + expectedHash := crypto.Keccak256Hash(tc.data) + expectedHashes[expectedHash] = hexutil.Bytes(tc.data) + }) + } + + // Get final result + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + + require.Equal(t, expectedHashes, hashes) +} + +func TestKeccak256PreimageTracerNonKeccakOpcodes(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + testData := []byte("should not be recorded") + memory := make([]byte, 32) + copy(memory, testData) + + stack := []uint256.Int{ + *uint256.NewInt(uint64(len(testData))), + *uint256.NewInt(0), + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // Test various non-KECCAK256 opcodes + nonKeccakOpcodes := []vm.OpCode{ + vm.ADD, vm.MUL, vm.SUB, vm.DIV, vm.SDIV, vm.MOD, vm.SMOD, + vm.ADDMOD, vm.MULMOD, vm.EXP, vm.SIGNEXTEND, vm.SLOAD, + vm.SSTORE, vm.MLOAD, vm.MSTORE, vm.CALL, vm.RETURN, + } + + for _, opcode := range nonKeccakOpcodes { + tracer.OnOpcode(0, byte(opcode), 0, 0, mockScope, nil, 0, nil) + } + + // Get result - should be empty + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + require.Empty(t, hashes) +} + +func TestKeccak256PreimageTracerMemoryOffset(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + // Test data at different memory offset + prefix := []byte("prefix_data_") + testData := []byte("target_data") + memory := make([]byte, len(prefix)+len(testData)+10) + copy(memory, prefix) + copy(memory[len(prefix):], testData) + + // Stack: offset=len(prefix), length=len(testData) + stack := []uint256.Int{ + *uint256.NewInt(uint64(len(testData))), // length + *uint256.NewInt(uint64(len(prefix))), // offset + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // Call OnOpcode with KECCAK256 + tracer.OnOpcode(0, byte(vm.KECCAK256), 0, 0, mockScope, nil, 0, nil) + + // Get result + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + + // Verify the hash matches the target data, not the prefix + expectedHash := crypto.Keccak256Hash(testData) + require.Len(t, hashes, 1) + require.Contains(t, hashes, expectedHash) + require.Equal(t, hexutil.Bytes(testData), hashes[expectedHash]) +} + +func TestKeccak256PreimageTracerMemoryPadding(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + // Test data that extends beyond memory bounds (should be zero-padded) + testData := []byte("short") + memory := make([]byte, len(testData)) + copy(memory, testData) + + // Request more data than available in memory + requestedLength := len(testData) + 5 + stack := []uint256.Int{ + *uint256.NewInt(uint64(requestedLength)), // length > memory size + *uint256.NewInt(0), // offset + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // Call OnOpcode with KECCAK256 + tracer.OnOpcode(0, byte(vm.KECCAK256), 0, 0, mockScope, nil, 0, nil) + + // Get result + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + + // Verify the hash includes zero padding + expectedData := make([]byte, requestedLength) + copy(expectedData, testData) + // Rest is zero-padded by default + + expectedHash := crypto.Keccak256Hash(expectedData) + require.Len(t, hashes, 1) + require.Contains(t, hashes, expectedHash) + require.Equal(t, hexutil.Bytes(expectedData), hashes[expectedHash]) +} + +func TestKeccak256PreimageTracerDuplicateHashes(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + testData := []byte("duplicate_test") + memory := make([]byte, len(testData)) + copy(memory, testData) + + stack := []uint256.Int{ + *uint256.NewInt(uint64(len(testData))), + *uint256.NewInt(0), + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // Call OnOpcode with KECCAK256 multiple times with same data + for i := 0; i < 3; i++ { + tracer.OnOpcode(0, byte(vm.KECCAK256), 0, 0, mockScope, nil, 0, nil) + } + + // Get result + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + + // Should only have one entry (duplicates overwrite) + expectedHash := crypto.Keccak256Hash(testData) + require.Len(t, hashes, 1) + require.Contains(t, hashes, expectedHash) + require.Equal(t, hexutil.Bytes(testData), hashes[expectedHash]) +} + +func TestKeccak256PreimageTracerWithExecutionError(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + testData := []byte("error_test") + memory := make([]byte, len(testData)) + copy(memory, testData) + + stack := []uint256.Int{ + *uint256.NewInt(uint64(len(testData))), + *uint256.NewInt(0), + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // Call OnOpcode with KECCAK256 and an execution error + tracer.OnOpcode(0, byte(vm.KECCAK256), 0, 0, mockScope, nil, 0, vm.ErrOutOfGas) + + // Get result - should still record the hash even with execution error + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + + expectedHash := crypto.Keccak256Hash(testData) + require.Len(t, hashes, 1) + require.Contains(t, hashes, expectedHash) + require.Equal(t, hexutil.Bytes(testData), hashes[expectedHash]) +} + +func TestKeccak256PreimageTracerInsufficientStack(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + // Test with insufficient stack items (should cause panic, but we test it doesn't crash) + testData := []byte("test") + memory := make([]byte, len(testData)) + copy(memory, testData) + + // Stack with only one item (need 2 for KECCAK256) + stack := []uint256.Int{ + *uint256.NewInt(0), // only offset, missing length + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // This should not panic due to insufficient stack + tracer.OnOpcode(0, byte(vm.KECCAK256), 0, 0, mockScope, nil, 0, nil) +} + +func TestKeccak256PreimageTracerLargeData(t *testing.T) { + tracer, err := tracers.DefaultDirectory.New("keccak256PreimageTracer", &tracers.Context{}, nil, params.MainnetChainConfig) + require.NoError(t, err) + + // Test with large data + largeData := make([]byte, 1024) + for i := range largeData { + largeData[i] = byte(i % 256) + } + + memory := make([]byte, len(largeData)) + copy(memory, largeData) + + stack := []uint256.Int{ + *uint256.NewInt(uint64(len(largeData))), + *uint256.NewInt(0), + } + + mockScope := &mockOpContext{ + memory: memory, + stack: stack, + } + + // Call OnOpcode with KECCAK256 + tracer.OnOpcode(0, byte(vm.KECCAK256), 0, 0, mockScope, nil, 0, nil) + + // Get result + result, err := tracer.GetResult() + require.NoError(t, err) + + var hashes map[common.Hash]hexutil.Bytes + err = json.Unmarshal(result, &hashes) + require.NoError(t, err) + + expectedHash := crypto.Keccak256Hash(largeData) + require.Len(t, hashes, 1) + require.Contains(t, hashes, expectedHash) + require.Equal(t, hexutil.Bytes(largeData), hashes[expectedHash]) +} diff --git a/eth/tracers/native/mux.go b/eth/tracers/native/mux.go index 77ab254568..37fc64f3f5 100644 --- a/eth/tracers/native/mux.go +++ b/eth/tracers/native/mux.go @@ -156,6 +156,14 @@ func (t *muxTracer) OnCodeChange(a common.Address, prevCodeHash common.Hash, pre } } +func (t *muxTracer) OnCodeChangeV2(a common.Address, prevCodeHash common.Hash, prev []byte, codeHash common.Hash, code []byte, reason tracing.CodeChangeReason) { + for _, t := range t.tracers { + if t.OnCodeChangeV2 != nil { + t.OnCodeChangeV2(a, prevCodeHash, prev, codeHash, code, reason) + } + } +} + func (t *muxTracer) OnStorageChange(a common.Address, k, prev, new common.Hash) { for _, t := range t.tracers { if t.OnStorageChange != nil { diff --git a/eth/tracers/native/prestate.go b/eth/tracers/native/prestate.go index 57c66ae327..159a91b310 100644 --- a/eth/tracers/native/prestate.go +++ b/eth/tracers/native/prestate.go @@ -44,11 +44,12 @@ func init() { type stateMap = map[common.Address]*account type account struct { - Balance *big.Int `json:"balance,omitempty"` - Code []byte `json:"code,omitempty"` - Nonce uint64 `json:"nonce,omitempty"` - Storage map[common.Hash]common.Hash `json:"storage,omitempty"` - empty bool + Balance *big.Int `json:"balance,omitempty"` + Code []byte `json:"code,omitempty"` + CodeHash *common.Hash `json:"codeHash,omitempty"` + Nonce uint64 `json:"nonce,omitempty"` + Storage map[common.Hash]common.Hash `json:"storage,omitempty"` + empty bool } func (a *account) exists() bool { @@ -65,7 +66,7 @@ type prestateTracer struct { pre stateMap post stateMap to common.Address - config prestateTracerConfig + config PrestateTracerConfig chainConfig *params.ChainConfig interrupt atomic.Bool // Atomic flag to signal execution interruption reason error // Textual reason for the interruption @@ -73,7 +74,7 @@ type prestateTracer struct { deleted map[common.Address]bool } -type prestateTracerConfig struct { +type PrestateTracerConfig struct { DiffMode bool `json:"diffMode"` // If true, this tracer will return state modifications DisableCode bool `json:"disableCode"` // If true, this tracer will not return the contract code DisableStorage bool `json:"disableStorage"` // If true, this tracer will not return the contract storage @@ -81,7 +82,7 @@ type prestateTracerConfig struct { } func newPrestateTracer(ctx *tracers.Context, cfg json.RawMessage, chainConfig *params.ChainConfig) (*tracers.Tracer, error) { - var config prestateTracerConfig + var config PrestateTracerConfig if err := json.Unmarshal(cfg, &config); err != nil { return nil, err } @@ -130,7 +131,15 @@ func (t *prestateTracer) OnOpcode(pc uint64, opcode byte, gas, cost uint64, scop addr := common.Address(stackData[stackLen-1].Bytes20()) t.lookupAccount(addr) if op == vm.SELFDESTRUCT { - t.deleted[caller] = true + if t.chainConfig.IsCancun(t.env.BlockNumber, t.env.Time) { + // EIP-6780: only delete if created in same transaction + if t.created[caller] { + t.deleted[caller] = true + } + } else { + // Pre-EIP-6780: always delete + t.deleted[caller] = true + } } case stackLen >= 5 && (op == vm.DELEGATECALL || op == vm.CALL || op == vm.STATICCALL || op == vm.CALLCODE): addr := common.Address(stackData[stackLen-2].Bytes20()) @@ -247,6 +256,7 @@ func (t *prestateTracer) processDiffState() { postAccount := &account{Storage: make(map[common.Hash]common.Hash)} newBalance := t.env.StateDB.GetBalance(addr).ToBig() newNonce := t.env.StateDB.GetNonce(addr) + newCodeHash := t.env.StateDB.GetCodeHash(addr) if newBalance.Cmp(t.pre[addr].Balance) != 0 { modified = true @@ -256,6 +266,19 @@ func (t *prestateTracer) processDiffState() { modified = true postAccount.Nonce = newNonce } + prevCodeHash := common.Hash{} + if t.pre[addr].CodeHash != nil { + prevCodeHash = *t.pre[addr].CodeHash + } + // Empty code hashes are excluded from the prestate. Normalize + // the empty code hash to a zero hash to make it comparable. + if newCodeHash == types.EmptyCodeHash { + newCodeHash = common.Hash{} + } + if newCodeHash != prevCodeHash { + modified = true + postAccount.CodeHash = &newCodeHash + } if !t.config.DisableCode { newCode := t.env.StateDB.GetCode(addr) if !bytes.Equal(newCode, t.pre[addr].Code) { @@ -305,6 +328,11 @@ func (t *prestateTracer) lookupAccount(addr common.Address) { Nonce: t.env.StateDB.GetNonce(addr), Code: t.env.StateDB.GetCode(addr), } + codeHash := t.env.StateDB.GetCodeHash(addr) + // If the code is empty, we don't need to store it in the prestate. + if codeHash != (common.Hash{}) && codeHash != types.EmptyCodeHash { + acc.CodeHash = &codeHash + } if !acc.exists() { acc.empty = true } diff --git a/eth/tracers/tracers_test.go b/eth/tracers/tracers_test.go index a72dbf6ee6..06edeaf698 100644 --- a/eth/tracers/tracers_test.go +++ b/eth/tracers/tracers_test.go @@ -84,10 +84,8 @@ func BenchmarkTransactionTraceV2(b *testing.B) { if err != nil { b.Fatalf("failed to prepare transaction for tracing: %v", err) } - b.ResetTimer() b.ReportAllocs() - - for i := 0; i < b.N; i++ { + for b.Loop() { tracer := logger.NewStructLogger(&logger.Config{}).Hooks() tracer.OnTxStart(evm.GetVMContext(), tx, msg.From) evm.Config.Tracer = tracer diff --git a/ethclient/ethclient.go b/ethclient/ethclient.go index 1195929f7d..6f2fb5ebc8 100644 --- a/ethclient/ethclient.go +++ b/ethclient/ethclient.go @@ -23,6 +23,7 @@ import ( "errors" "fmt" "math/big" + "time" "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/common" @@ -123,7 +124,7 @@ func (ec *Client) PeerCount(ctx context.Context) (uint64, error) { // BlockReceipts returns the receipts of a given block number or hash. func (ec *Client) BlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]*types.Receipt, error) { var r []*types.Receipt - err := ec.c.CallContext(ctx, &r, "eth_getBlockReceipts", blockNrOrHash.String()) + err := ec.c.CallContext(ctx, &r, "eth_getBlockReceipts", blockNrOrHash) if err == nil && r == nil { return nil, ethereum.NotFound } @@ -350,6 +351,15 @@ func (ec *Client) TransactionReceipt(ctx context.Context, txHash common.Hash) (* return r, err } +// SubscribeTransactionReceipts subscribes to notifications about transaction receipts. +func (ec *Client) SubscribeTransactionReceipts(ctx context.Context, q *ethereum.TransactionReceiptsQuery, ch chan<- []*types.Receipt) (ethereum.Subscription, error) { + sub, err := ec.c.EthSubscribe(ctx, ch, "transactionReceipts", q) + if err != nil { + return nil, err + } + return sub, nil +} + // SyncProgress retrieves the current progress of the sync algorithm. If there's // no sync currently running, it returns nil. func (ec *Client) SyncProgress(ctx context.Context) (*ethereum.SyncProgress, error) { @@ -487,9 +497,12 @@ func (ec *Client) SubscribeFilterLogs(ctx context.Context, q ethereum.FilterQuer } func toFilterArg(q ethereum.FilterQuery) (interface{}, error) { - arg := map[string]interface{}{ - "address": q.Addresses, - "topics": q.Topics, + arg := map[string]interface{}{} + if q.Addresses != nil { + arg["address"] = q.Addresses + } + if q.Topics != nil { + arg["topics"] = q.Topics } if q.BlockHash != nil { arg["blockHash"] = *q.BlockHash @@ -696,6 +709,39 @@ func (ec *Client) SendTransaction(ctx context.Context, tx *types.Transaction) er return ec.c.CallContext(ctx, nil, "eth_sendRawTransaction", hexutil.Encode(data)) } +// SendTransactionSync submits a signed tx and waits for a receipt (or until +// the optional timeout elapses on the server side). If timeout == 0, the server +// uses its default. +func (ec *Client) SendTransactionSync( + ctx context.Context, + tx *types.Transaction, + timeout *time.Duration, +) (*types.Receipt, error) { + raw, err := tx.MarshalBinary() + if err != nil { + return nil, err + } + return ec.SendRawTransactionSync(ctx, raw, timeout) +} + +func (ec *Client) SendRawTransactionSync( + ctx context.Context, + rawTx []byte, + timeout *time.Duration, +) (*types.Receipt, error) { + var ms *hexutil.Uint64 + if timeout != nil { + if d := hexutil.Uint64(timeout.Milliseconds()); d > 0 { + ms = &d + } + } + var receipt types.Receipt + if err := ec.c.CallContext(ctx, &receipt, "eth_sendRawTransactionSync", hexutil.Bytes(rawTx), ms); err != nil { + return nil, err + } + return &receipt, nil +} + // RevertErrorData returns the 'revert reason' data of a contract call. // // This can be used with CallContract and EstimateGas, and only when the server is Geth. @@ -819,3 +865,89 @@ func (p *rpcProgress) toSyncProgress() *ethereum.SyncProgress { StateIndexRemaining: uint64(p.StateIndexRemaining), } } + +// SimulateOptions represents the options for eth_simulateV1. +type SimulateOptions struct { + BlockStateCalls []SimulateBlock `json:"blockStateCalls"` + TraceTransfers bool `json:"traceTransfers"` + Validation bool `json:"validation"` + ReturnFullTransactions bool `json:"returnFullTransactions"` +} + +// SimulateBlock represents a batch of calls to be simulated. +type SimulateBlock struct { + BlockOverrides *ethereum.BlockOverrides `json:"blockOverrides,omitempty"` + StateOverrides map[common.Address]ethereum.OverrideAccount `json:"stateOverrides,omitempty"` + Calls []ethereum.CallMsg `json:"calls"` +} + +// MarshalJSON implements json.Marshaler for SimulateBlock. +func (s SimulateBlock) MarshalJSON() ([]byte, error) { + type Alias struct { + BlockOverrides *ethereum.BlockOverrides `json:"blockOverrides,omitempty"` + StateOverrides map[common.Address]ethereum.OverrideAccount `json:"stateOverrides,omitempty"` + Calls []interface{} `json:"calls"` + } + calls := make([]interface{}, len(s.Calls)) + for i, call := range s.Calls { + calls[i] = toCallArg(call) + } + return json.Marshal(Alias{ + BlockOverrides: s.BlockOverrides, + StateOverrides: s.StateOverrides, + Calls: calls, + }) +} + +//go:generate go run github.com/fjl/gencodec -type SimulateCallResult -field-override simulateCallResultMarshaling -out gen_simulate_call_result.go + +// SimulateCallResult is the result of a simulated call. +type SimulateCallResult struct { + ReturnValue []byte `json:"returnData"` + Logs []*types.Log `json:"logs"` + GasUsed uint64 `json:"gasUsed"` + Status uint64 `json:"status"` + Error *CallError `json:"error,omitempty"` +} + +type simulateCallResultMarshaling struct { + ReturnValue hexutil.Bytes + GasUsed hexutil.Uint64 + Status hexutil.Uint64 +} + +// CallError represents an error from a simulated call. +type CallError struct { + Code int `json:"code"` + Message string `json:"message"` + Data string `json:"data,omitempty"` +} + +//go:generate go run github.com/fjl/gencodec -type SimulateBlockResult -field-override simulateBlockResultMarshaling -out gen_simulate_block_result.go + +// SimulateBlockResult represents the result of a simulated block. +type SimulateBlockResult struct { + Number *big.Int `json:"number"` + Hash common.Hash `json:"hash"` + Timestamp uint64 `json:"timestamp"` + GasLimit uint64 `json:"gasLimit"` + GasUsed uint64 `json:"gasUsed"` + FeeRecipient common.Address `json:"miner"` + BaseFeePerGas *big.Int `json:"baseFeePerGas,omitempty"` + Calls []SimulateCallResult `json:"calls"` +} + +type simulateBlockResultMarshaling struct { + Number *hexutil.Big + Timestamp hexutil.Uint64 + GasLimit hexutil.Uint64 + GasUsed hexutil.Uint64 + BaseFeePerGas *hexutil.Big +} + +// SimulateV1 executes transactions on top of a base state. +func (ec *Client) SimulateV1(ctx context.Context, opts SimulateOptions, blockNrOrHash *rpc.BlockNumberOrHash) ([]SimulateBlockResult, error) { + var result []SimulateBlockResult + err := ec.c.CallContext(ctx, &result, "eth_simulateV1", opts, blockNrOrHash) + return result, err +} diff --git a/ethclient/ethclient_test.go b/ethclient/ethclient_test.go index 8e70177944..f9e761e412 100644 --- a/ethclient/ethclient_test.go +++ b/ethclient/ethclient_test.go @@ -110,6 +110,12 @@ func newTestBackend(config *node.Config) (*node.Node, []*types.Block, error) { if err != nil { return nil, nil, fmt.Errorf("can't create new ethereum service: %v", err) } + // Ensure tx pool starts the background operation + txPool := ethservice.TxPool() + if err = txPool.Sync(); err != nil { + return nil, nil, fmt.Errorf("can't sync transaction pool: %v", err) + } + // Import the test chain. if err := n.Start(); err != nil { return nil, nil, fmt.Errorf("can't start test node: %v", err) @@ -506,8 +512,9 @@ func testAtFunctions(t *testing.T, client *rpc.Client) { } // send a transaction for some interesting pending status - // and wait for the transaction to be included in the pending block - sendTransaction(ec) + if err := sendTransaction(ec); err != nil { + t.Fatalf("unexpected error: %v", err) + } // wait for the transaction to be included in the pending block for { @@ -680,6 +687,49 @@ func testTransactionSender(t *testing.T, client *rpc.Client) { } } +func TestBlockReceiptsPreservesCanonicalFlag(t *testing.T) { + srv := rpc.NewServer() + service := &blockReceiptsTestService{calls: make(chan rpc.BlockNumberOrHash, 1)} + if err := srv.RegisterName("eth", service); err != nil { + t.Fatalf("failed to register service: %v", err) + } + defer srv.Stop() + + client := rpc.DialInProc(srv) + defer client.Close() + + ec := ethclient.NewClient(client) + defer ec.Close() + + hash := common.HexToHash("0x01") + ref := rpc.BlockNumberOrHashWithHash(hash, true) + + if _, err := ec.BlockReceipts(context.Background(), ref); err != nil { + t.Fatalf("BlockReceipts returned error: %v", err) + } + + select { + case call := <-service.calls: + if call.BlockHash == nil || *call.BlockHash != hash { + t.Fatalf("unexpected block hash: got %v, want %v", call.BlockHash, hash) + } + if !call.RequireCanonical { + t.Fatalf("requireCanonical flag was lost: %+v", call) + } + default: + t.Fatal("service was not called") + } +} + +type blockReceiptsTestService struct { + calls chan rpc.BlockNumberOrHash +} + +func (s *blockReceiptsTestService) GetBlockReceipts(ctx context.Context, block rpc.BlockNumberOrHash) ([]*types.Receipt, error) { + s.calls <- block + return []*types.Receipt{}, nil +} + func newCanceledContext() context.Context { ctx, cancel := context.WithCancel(context.Background()) cancel() @@ -747,3 +797,250 @@ func ExampleRevertErrorData() { // revert: 08c379a00000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000a75736572206572726f72 // message: user error } + +func TestSimulateV1(t *testing.T) { + backend, _, err := newTestBackend(nil) + if err != nil { + t.Fatalf("Failed to create test backend: %v", err) + } + defer backend.Close() + + client := ethclient.NewClient(backend.Attach()) + defer client.Close() + + ctx := context.Background() + + // Get current base fee + header, err := client.HeaderByNumber(ctx, nil) + if err != nil { + t.Fatalf("Failed to get header: %v", err) + } + + // Simple test: transfer ETH from one account to another + from := testAddr + to := common.HexToAddress("0x0000000000000000000000000000000000000001") + value := big.NewInt(100) + gas := uint64(100000) + maxFeePerGas := new(big.Int).Mul(header.BaseFee, big.NewInt(2)) + + opts := ethclient.SimulateOptions{ + BlockStateCalls: []ethclient.SimulateBlock{ + { + Calls: []ethereum.CallMsg{ + { + From: from, + To: &to, + Value: value, + Gas: gas, + GasFeeCap: maxFeePerGas, + }, + }, + }, + }, + Validation: true, + } + + results, err := client.SimulateV1(ctx, opts, nil) + if err != nil { + t.Fatalf("SimulateV1 failed: %v", err) + } + + if len(results) != 1 { + t.Fatalf("expected 1 block result, got %d", len(results)) + } + + if len(results[0].Calls) != 1 { + t.Fatalf("expected 1 call result, got %d", len(results[0].Calls)) + } + + // Check that the transaction succeeded + if results[0].Calls[0].Status != 1 { + t.Errorf("expected status 1 (success), got %d", results[0].Calls[0].Status) + } + + if results[0].Calls[0].Error != nil { + t.Errorf("expected no error, got %v", results[0].Calls[0].Error) + } +} + +func TestSimulateV1WithBlockOverrides(t *testing.T) { + backend, _, err := newTestBackend(nil) + if err != nil { + t.Fatalf("Failed to create test backend: %v", err) + } + defer backend.Close() + + client := ethclient.NewClient(backend.Attach()) + defer client.Close() + + ctx := context.Background() + + // Get current base fee + header, err := client.HeaderByNumber(ctx, nil) + if err != nil { + t.Fatalf("Failed to get header: %v", err) + } + + from := testAddr + to := common.HexToAddress("0x0000000000000000000000000000000000000001") + value := big.NewInt(100) + gas := uint64(100000) + maxFeePerGas := new(big.Int).Mul(header.BaseFee, big.NewInt(2)) + + // Override timestamp only + timestamp := uint64(1234567890) + + opts := ethclient.SimulateOptions{ + BlockStateCalls: []ethclient.SimulateBlock{ + { + BlockOverrides: ðereum.BlockOverrides{ + Time: timestamp, + }, + Calls: []ethereum.CallMsg{ + { + From: from, + To: &to, + Value: value, + Gas: gas, + GasFeeCap: maxFeePerGas, + }, + }, + }, + }, + Validation: true, + } + + results, err := client.SimulateV1(ctx, opts, nil) + if err != nil { + t.Fatalf("SimulateV1 with block overrides failed: %v", err) + } + + if len(results) != 1 { + t.Fatalf("expected 1 block result, got %d", len(results)) + } + + // Verify the timestamp was overridden + if results[0].Timestamp != timestamp { + t.Errorf("expected timestamp %d, got %d", timestamp, results[0].Timestamp) + } +} + +func TestSimulateV1WithStateOverrides(t *testing.T) { + backend, _, err := newTestBackend(nil) + if err != nil { + t.Fatalf("Failed to create test backend: %v", err) + } + defer backend.Close() + + client := ethclient.NewClient(backend.Attach()) + defer client.Close() + + ctx := context.Background() + + // Get current base fee + header, err := client.HeaderByNumber(ctx, nil) + if err != nil { + t.Fatalf("Failed to get header: %v", err) + } + + from := testAddr + to := common.HexToAddress("0x0000000000000000000000000000000000000001") + value := big.NewInt(1000000000000000000) // 1 ETH + gas := uint64(100000) + maxFeePerGas := new(big.Int).Mul(header.BaseFee, big.NewInt(2)) + + // Override the balance of the 'from' address + balanceStr := "1000000000000000000000" + balance := new(big.Int) + balance.SetString(balanceStr, 10) + + stateOverrides := map[common.Address]ethereum.OverrideAccount{ + from: { + Balance: balance, + }, + } + + opts := ethclient.SimulateOptions{ + BlockStateCalls: []ethclient.SimulateBlock{ + { + StateOverrides: stateOverrides, + Calls: []ethereum.CallMsg{ + { + From: from, + To: &to, + Value: value, + Gas: gas, + GasFeeCap: maxFeePerGas, + }, + }, + }, + }, + Validation: true, + } + + results, err := client.SimulateV1(ctx, opts, nil) + if err != nil { + t.Fatalf("SimulateV1 with state overrides failed: %v", err) + } + + if len(results) != 1 { + t.Fatalf("expected 1 block result, got %d", len(results)) + } + + if results[0].Calls[0].Status != 1 { + t.Errorf("expected status 1 (success), got %d", results[0].Calls[0].Status) + } +} + +func TestSimulateV1WithBlockNumberOrHash(t *testing.T) { + backend, _, err := newTestBackend(nil) + if err != nil { + t.Fatalf("Failed to create test backend: %v", err) + } + defer backend.Close() + + client := ethclient.NewClient(backend.Attach()) + defer client.Close() + + ctx := context.Background() + + // Get current base fee + header, err := client.HeaderByNumber(ctx, nil) + if err != nil { + t.Fatalf("Failed to get header: %v", err) + } + + from := testAddr + to := common.HexToAddress("0x0000000000000000000000000000000000000001") + value := big.NewInt(100) + gas := uint64(100000) + maxFeePerGas := new(big.Int).Mul(header.BaseFee, big.NewInt(2)) + + opts := ethclient.SimulateOptions{ + BlockStateCalls: []ethclient.SimulateBlock{ + { + Calls: []ethereum.CallMsg{ + { + From: from, + To: &to, + Value: value, + Gas: gas, + GasFeeCap: maxFeePerGas, + }, + }, + }, + }, + Validation: true, + } + + // Simulate on the latest block + latest := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) + results, err := client.SimulateV1(ctx, opts, &latest) + if err != nil { + t.Fatalf("SimulateV1 with latest block failed: %v", err) + } + + if len(results) != 1 { + t.Fatalf("expected 1 block result, got %d", len(results)) + } +} diff --git a/ethclient/gen_simulate_block_result.go b/ethclient/gen_simulate_block_result.go new file mode 100644 index 0000000000..b8cd6ebf2f --- /dev/null +++ b/ethclient/gen_simulate_block_result.go @@ -0,0 +1,80 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package ethclient + +import ( + "encoding/json" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" +) + +var _ = (*simulateBlockResultMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (s SimulateBlockResult) MarshalJSON() ([]byte, error) { + type SimulateBlockResult struct { + Number *hexutil.Big `json:"number"` + Hash common.Hash `json:"hash"` + Timestamp hexutil.Uint64 `json:"timestamp"` + GasLimit hexutil.Uint64 `json:"gasLimit"` + GasUsed hexutil.Uint64 `json:"gasUsed"` + FeeRecipient common.Address `json:"miner"` + BaseFeePerGas *hexutil.Big `json:"baseFeePerGas,omitempty"` + Calls []SimulateCallResult `json:"calls"` + } + var enc SimulateBlockResult + enc.Number = (*hexutil.Big)(s.Number) + enc.Hash = s.Hash + enc.Timestamp = hexutil.Uint64(s.Timestamp) + enc.GasLimit = hexutil.Uint64(s.GasLimit) + enc.GasUsed = hexutil.Uint64(s.GasUsed) + enc.FeeRecipient = s.FeeRecipient + enc.BaseFeePerGas = (*hexutil.Big)(s.BaseFeePerGas) + enc.Calls = s.Calls + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (s *SimulateBlockResult) UnmarshalJSON(input []byte) error { + type SimulateBlockResult struct { + Number *hexutil.Big `json:"number"` + Hash *common.Hash `json:"hash"` + Timestamp *hexutil.Uint64 `json:"timestamp"` + GasLimit *hexutil.Uint64 `json:"gasLimit"` + GasUsed *hexutil.Uint64 `json:"gasUsed"` + FeeRecipient *common.Address `json:"miner"` + BaseFeePerGas *hexutil.Big `json:"baseFeePerGas,omitempty"` + Calls []SimulateCallResult `json:"calls"` + } + var dec SimulateBlockResult + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.Number != nil { + s.Number = (*big.Int)(dec.Number) + } + if dec.Hash != nil { + s.Hash = *dec.Hash + } + if dec.Timestamp != nil { + s.Timestamp = uint64(*dec.Timestamp) + } + if dec.GasLimit != nil { + s.GasLimit = uint64(*dec.GasLimit) + } + if dec.GasUsed != nil { + s.GasUsed = uint64(*dec.GasUsed) + } + if dec.FeeRecipient != nil { + s.FeeRecipient = *dec.FeeRecipient + } + if dec.BaseFeePerGas != nil { + s.BaseFeePerGas = (*big.Int)(dec.BaseFeePerGas) + } + if dec.Calls != nil { + s.Calls = dec.Calls + } + return nil +} diff --git a/ethclient/gen_simulate_call_result.go b/ethclient/gen_simulate_call_result.go new file mode 100644 index 0000000000..55e14cd697 --- /dev/null +++ b/ethclient/gen_simulate_call_result.go @@ -0,0 +1,61 @@ +// Code generated by github.com/fjl/gencodec. DO NOT EDIT. + +package ethclient + +import ( + "encoding/json" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" +) + +var _ = (*simulateCallResultMarshaling)(nil) + +// MarshalJSON marshals as JSON. +func (s SimulateCallResult) MarshalJSON() ([]byte, error) { + type SimulateCallResult struct { + ReturnValue hexutil.Bytes `json:"returnData"` + Logs []*types.Log `json:"logs"` + GasUsed hexutil.Uint64 `json:"gasUsed"` + Status hexutil.Uint64 `json:"status"` + Error *CallError `json:"error,omitempty"` + } + var enc SimulateCallResult + enc.ReturnValue = s.ReturnValue + enc.Logs = s.Logs + enc.GasUsed = hexutil.Uint64(s.GasUsed) + enc.Status = hexutil.Uint64(s.Status) + enc.Error = s.Error + return json.Marshal(&enc) +} + +// UnmarshalJSON unmarshals from JSON. +func (s *SimulateCallResult) UnmarshalJSON(input []byte) error { + type SimulateCallResult struct { + ReturnValue *hexutil.Bytes `json:"returnData"` + Logs []*types.Log `json:"logs"` + GasUsed *hexutil.Uint64 `json:"gasUsed"` + Status *hexutil.Uint64 `json:"status"` + Error *CallError `json:"error,omitempty"` + } + var dec SimulateCallResult + if err := json.Unmarshal(input, &dec); err != nil { + return err + } + if dec.ReturnValue != nil { + s.ReturnValue = *dec.ReturnValue + } + if dec.Logs != nil { + s.Logs = dec.Logs + } + if dec.GasUsed != nil { + s.GasUsed = uint64(*dec.GasUsed) + } + if dec.Status != nil { + s.Status = uint64(*dec.Status) + } + if dec.Error != nil { + s.Error = dec.Error + } + return nil +} diff --git a/ethclient/gethclient/gethclient.go b/ethclient/gethclient/gethclient.go index d030878e54..c2013bca2c 100644 --- a/ethclient/gethclient/gethclient.go +++ b/ethclient/gethclient/gethclient.go @@ -19,7 +19,6 @@ package gethclient import ( "context" - "encoding/json" "fmt" "math/big" "runtime" @@ -105,7 +104,10 @@ func (ec *Client) GetProof(ctx context.Context, account common.Address, keys []s var res accountResult err := ec.c.CallContext(ctx, &res, "eth_getProof", account, keys, toBlockNumArg(blockNumber)) - // Turn hexutils back to normal datatypes + if err != nil { + return nil, err + } + // Turn hexutils back to normal data types storageResults := make([]StorageResult, 0, len(res.StorageProof)) for _, st := range res.StorageProof { storageResults = append(storageResults, StorageResult{ @@ -123,7 +125,7 @@ func (ec *Client) GetProof(ctx context.Context, account common.Address, keys []s StorageHash: res.StorageHash, StorageProof: storageResults, } - return &result, err + return &result, nil } // CallContract executes a message call transaction, which is directly executed in the VM @@ -209,7 +211,7 @@ func (ec *Client) SubscribePendingTransactions(ctx context.Context, ch chan<- co // and returns them as a JSON object. func (ec *Client) TraceTransaction(ctx context.Context, hash common.Hash, config *tracers.TraceConfig) (any, error) { var result any - err := ec.c.CallContext(ctx, &result, "debug_traceTransaction", hash.Hex(), config) + err := ec.c.CallContext(ctx, &result, "debug_traceTransaction", hash, config) if err != nil { return nil, err } @@ -280,97 +282,8 @@ func toCallArg(msg ethereum.CallMsg) interface{} { return arg } -// OverrideAccount specifies the state of an account to be overridden. -type OverrideAccount struct { - // Nonce sets nonce of the account. Note: the nonce override will only - // be applied when it is set to a non-zero value. - Nonce uint64 +// OverrideAccount is an alias for ethereum.OverrideAccount. +type OverrideAccount = ethereum.OverrideAccount - // Code sets the contract code. The override will be applied - // when the code is non-nil, i.e. setting empty code is possible - // using an empty slice. - Code []byte - - // Balance sets the account balance. - Balance *big.Int - - // State sets the complete storage. The override will be applied - // when the given map is non-nil. Using an empty map wipes the - // entire contract storage during the call. - State map[common.Hash]common.Hash - - // StateDiff allows overriding individual storage slots. - StateDiff map[common.Hash]common.Hash -} - -func (a OverrideAccount) MarshalJSON() ([]byte, error) { - type acc struct { - Nonce hexutil.Uint64 `json:"nonce,omitempty"` - Code string `json:"code,omitempty"` - Balance *hexutil.Big `json:"balance,omitempty"` - State interface{} `json:"state,omitempty"` - StateDiff map[common.Hash]common.Hash `json:"stateDiff,omitempty"` - } - - output := acc{ - Nonce: hexutil.Uint64(a.Nonce), - Balance: (*hexutil.Big)(a.Balance), - StateDiff: a.StateDiff, - } - if a.Code != nil { - output.Code = hexutil.Encode(a.Code) - } - if a.State != nil { - output.State = a.State - } - return json.Marshal(output) -} - -// BlockOverrides specifies the set of header fields to override. -type BlockOverrides struct { - // Number overrides the block number. - Number *big.Int - // Difficulty overrides the block difficulty. - Difficulty *big.Int - // Time overrides the block timestamp. Time is applied only when - // it is non-zero. - Time uint64 - // GasLimit overrides the block gas limit. GasLimit is applied only when - // it is non-zero. - GasLimit uint64 - // Coinbase overrides the block coinbase. Coinbase is applied only when - // it is different from the zero address. - Coinbase common.Address - // Random overrides the block extra data which feeds into the RANDOM opcode. - // Random is applied only when it is a non-zero hash. - Random common.Hash - // BaseFee overrides the block base fee. - BaseFee *big.Int -} - -func (o BlockOverrides) MarshalJSON() ([]byte, error) { - type override struct { - Number *hexutil.Big `json:"number,omitempty"` - Difficulty *hexutil.Big `json:"difficulty,omitempty"` - Time hexutil.Uint64 `json:"time,omitempty"` - GasLimit hexutil.Uint64 `json:"gasLimit,omitempty"` - Coinbase *common.Address `json:"feeRecipient,omitempty"` - Random *common.Hash `json:"prevRandao,omitempty"` - BaseFee *hexutil.Big `json:"baseFeePerGas,omitempty"` - } - - output := override{ - Number: (*hexutil.Big)(o.Number), - Difficulty: (*hexutil.Big)(o.Difficulty), - Time: hexutil.Uint64(o.Time), - GasLimit: hexutil.Uint64(o.GasLimit), - BaseFee: (*hexutil.Big)(o.BaseFee), - } - if o.Coinbase != (common.Address{}) { - output.Coinbase = &o.Coinbase - } - if o.Random != (common.Hash{}) { - output.Random = &o.Random - } - return json.Marshal(output) -} +// BlockOverrides is an alias for ethereum.BlockOverrides. +type BlockOverrides = ethereum.BlockOverrides diff --git a/ethclient/types_test.go b/ethclient/types_test.go index 02f9f21758..dcb9a579b7 100644 --- a/ethclient/types_test.go +++ b/ethclient/types_test.go @@ -41,6 +41,18 @@ func TestToFilterArg(t *testing.T) { output interface{} err error }{ + { + "without addresses", + ethereum.FilterQuery{ + FromBlock: big.NewInt(1), + ToBlock: big.NewInt(2), + }, + map[string]interface{}{ + "fromBlock": "0x1", + "toBlock": "0x2", + }, + nil, + }, { "without BlockHash", ethereum.FilterQuery{ diff --git a/ethdb/database.go b/ethdb/database.go index e665a84a61..534fcad4fc 100644 --- a/ethdb/database.go +++ b/ethdb/database.go @@ -121,6 +121,10 @@ type AncientReaderOp interface { // - if maxBytes is not specified, 'count' items will be returned if they are present AncientRange(kind string, start, count, maxBytes uint64) ([][]byte, error) + // AncientBytes retrieves the value segment of the element specified by the id + // and value offsets. + AncientBytes(kind string, id, offset, length uint64) ([]byte, error) + // Ancients returns the ancient item numbers in the ancient store. Ancients() (uint64, error) diff --git a/ethdb/leveldb/leveldb.go b/ethdb/leveldb/leveldb.go index 8e1bb86fec..b6c93907b1 100644 --- a/ethdb/leveldb/leveldb.go +++ b/ethdb/leveldb/leveldb.go @@ -233,6 +233,9 @@ func (db *Database) DeleteRange(start, end []byte) error { return err } } + if err := it.Error(); err != nil { + return err + } return batch.Write() } diff --git a/ethdb/pebble/pebble.go b/ethdb/pebble/pebble.go index 2370d4654f..800559ab4b 100644 --- a/ethdb/pebble/pebble.go +++ b/ethdb/pebble/pebble.go @@ -205,8 +205,8 @@ func New(file string, cache int, handles int, namespace string, readonly bool) ( // limit unchanged allows writes to be flushed more smoothly. This helps // avoid compaction spikes and mitigates write stalls caused by heavy // compaction workloads. - memTableLimit := 4 - memTableSize := cache * 1024 * 1024 / 2 / memTableLimit + memTableNumber := 4 + memTableSize := cache * 1024 * 1024 / 2 / memTableNumber // The memory table size is currently capped at maxMemTableSize-1 due to a // known bug in the pebble where maxMemTableSize is not recognized as a @@ -218,9 +218,10 @@ func New(file string, cache int, handles int, namespace string, readonly bool) ( memTableSize = maxMemTableSize - 1 } db := &Database{ - fn: file, - log: logger, - quitChan: make(chan chan error), + fn: file, + log: logger, + quitChan: make(chan chan error), + namespace: namespace, // Use asynchronous write mode by default. Otherwise, the overhead of frequent fsync // operations can be significant, especially on platforms with slow fsync performance @@ -242,12 +243,16 @@ func New(file string, cache int, handles int, namespace string, readonly bool) ( // Note, there may have more than two memory tables in the system. MemTableSize: uint64(memTableSize), - // MemTableStopWritesThreshold places a hard limit on the size + // MemTableStopWritesThreshold places a hard limit on the number // of the existent MemTables(including the frozen one). + // // Note, this must be the number of tables not the size of all memtables // according to https://github.com/cockroachdb/pebble/blob/master/options.go#L738-L742 // and to https://github.com/cockroachdb/pebble/blob/master/db.go#L1892-L1903. - MemTableStopWritesThreshold: memTableLimit, + // + // MemTableStopWritesThreshold is set to twice the maximum number of + // allowed memtables to accommodate temporary spikes. + MemTableStopWritesThreshold: memTableNumber * 2, // The default compaction concurrency(1 thread), // Here use all available CPUs for faster compaction. @@ -262,7 +267,9 @@ func New(file string, cache int, handles int, namespace string, readonly bool) ( {TargetFileSize: 16 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)}, {TargetFileSize: 32 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)}, {TargetFileSize: 64 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)}, - {TargetFileSize: 128 * 1024 * 1024, FilterPolicy: bloom.FilterPolicy(10)}, + + // Pebble doesn't use the Bloom filter at level6 for read efficiency. + {TargetFileSize: 128 * 1024 * 1024}, }, ReadOnly: readonly, EventListener: &pebble.EventListener{ @@ -293,9 +300,15 @@ func New(file string, cache int, handles int, namespace string, readonly bool) ( // debt will be less than 1GB, but with more frequent compactions scheduled. L0CompactionThreshold: 2, } - // Disable seek compaction explicitly. Check https://github.com/ethereum/go-ethereum/pull/20130 - // for more details. - opt.Experimental.ReadSamplingMultiplier = -1 + // These two settings define the conditions under which compaction concurrency + // is increased. Specifically, one additional compaction job will be enabled when: + // - there is one more overlapping sub-level0; + // - there is an additional 512 MB of compaction debt; + // + // The maximum concurrency is still capped by MaxConcurrentCompactions, but with + // these settings compactions can scale up more readily. + opt.Experimental.L0CompactionConcurrency = 1 + opt.Experimental.CompactionDebtConcurrency = 1 << 28 // 256MB // Open the db and recover any potential corruptions innerDB, err := pebble.Open(file, opt) diff --git a/ethdb/remotedb/remotedb.go b/ethdb/remotedb/remotedb.go index 7fe154ea95..0d0d854fe4 100644 --- a/ethdb/remotedb/remotedb.go +++ b/ethdb/remotedb/remotedb.go @@ -140,6 +140,10 @@ func (db *Database) Close() error { return nil } +func (db *Database) AncientBytes(kind string, id, offset, length uint64) ([]byte, error) { + panic("not supported") +} + func New(client *rpc.Client) ethdb.Database { if client == nil { return nil diff --git a/ethstats/ethstats.go b/ethstats/ethstats.go index b6191baa12..c17e225165 100644 --- a/ethstats/ethstats.go +++ b/ethstats/ethstats.go @@ -63,6 +63,7 @@ const ( type backend interface { SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription SubscribeNewTxsEvent(ch chan<- core.NewTxsEvent) event.Subscription + SubscribeNewPayloadEvent(ch chan<- core.NewPayloadEvent) event.Subscription CurrentHeader() *types.Header HeaderByNumber(ctx context.Context, number rpc.BlockNumber) (*types.Header, error) Stats() (pending int, queued int) @@ -92,8 +93,9 @@ type Service struct { pongCh chan struct{} // Pong notifications are fed into this channel histCh chan []uint64 // History request block numbers are fed into this channel - headSub event.Subscription - txSub event.Subscription + headSub event.Subscription + txSub event.Subscription + newPayloadSub event.Subscription } // connWrapper is a wrapper to prevent concurrent-write or concurrent-read on the @@ -198,7 +200,9 @@ func (s *Service) Start() error { s.headSub = s.backend.SubscribeChainHeadEvent(chainHeadCh) txEventCh := make(chan core.NewTxsEvent, txChanSize) s.txSub = s.backend.SubscribeNewTxsEvent(txEventCh) - go s.loop(chainHeadCh, txEventCh) + newPayloadCh := make(chan core.NewPayloadEvent, chainHeadChanSize) + s.newPayloadSub = s.backend.SubscribeNewPayloadEvent(newPayloadCh) + go s.loop(chainHeadCh, txEventCh, newPayloadCh) log.Info("Stats daemon started") return nil @@ -208,18 +212,20 @@ func (s *Service) Start() error { func (s *Service) Stop() error { s.headSub.Unsubscribe() s.txSub.Unsubscribe() + s.newPayloadSub.Unsubscribe() log.Info("Stats daemon stopped") return nil } // loop keeps trying to connect to the netstats server, reporting chain events // until termination. -func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core.NewTxsEvent) { +func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core.NewTxsEvent, newPayloadCh chan core.NewPayloadEvent) { // Start a goroutine that exhausts the subscriptions to avoid events piling up var ( - quitCh = make(chan struct{}) - headCh = make(chan *types.Header, 1) - txCh = make(chan struct{}, 1) + quitCh = make(chan struct{}) + headCh = make(chan *types.Header, 1) + txCh = make(chan struct{}, 1) + newPayloadEvCh = make(chan core.NewPayloadEvent, 1) ) go func() { var lastTx mclock.AbsTime @@ -246,11 +252,20 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core default: } + // Notify of new payload events, but drop if too frequent + case ev := <-newPayloadCh: + select { + case newPayloadEvCh <- ev: + default: + } + // node stopped case <-s.txSub.Err(): break HandleLoop case <-s.headSub.Err(): break HandleLoop + case <-s.newPayloadSub.Err(): + break HandleLoop } } close(quitCh) @@ -336,6 +351,10 @@ func (s *Service) loop(chainHeadCh chan core.ChainHeadEvent, txEventCh chan core if err = s.reportPending(conn); err != nil { log.Warn("Post-block transaction stats report failed", "err", err) } + case ev := <-newPayloadEvCh: + if err = s.reportNewPayload(conn, ev); err != nil { + log.Warn("New payload stats report failed", "err", err) + } case <-txCh: if err = s.reportPending(conn); err != nil { log.Warn("Transaction stats report failed", "err", err) @@ -600,6 +619,33 @@ func (s uncleStats) MarshalJSON() ([]byte, error) { return []byte("[]"), nil } +// newPayloadStats is the information to report about new payload events. +type newPayloadStats struct { + Number uint64 `json:"number"` + Hash common.Hash `json:"hash"` + ProcessingTime uint64 `json:"processingTime"` // nanoseconds +} + +// reportNewPayload reports a new payload event to the stats server. +func (s *Service) reportNewPayload(conn *connWrapper, ev core.NewPayloadEvent) error { + details := &newPayloadStats{ + Number: ev.Number, + Hash: ev.Hash, + ProcessingTime: uint64(ev.ProcessingTime.Nanoseconds()), + } + + log.Trace("Sending new payload to ethstats", "number", details.Number, "hash", details.Hash) + + stats := map[string]interface{}{ + "id": s.node, + "block": details, + } + report := map[string][]interface{}{ + "emit": {"block_new_payload", stats}, + } + return conn.WriteJSON(report) +} + // reportBlock retrieves the current chain head and reports it to the stats server. func (s *Service) reportBlock(conn *connWrapper, header *types.Header) error { // Gather the block details from the header or block chain diff --git a/go.mod b/go.mod index 363d7d3dfb..306b08ff1a 100644 --- a/go.mod +++ b/go.mod @@ -1,11 +1,11 @@ module github.com/ethereum/go-ethereum -go 1.23.0 +go 1.24.0 require ( github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 github.com/Microsoft/go-winio v0.6.2 - github.com/VictoriaMetrics/fastcache v1.12.2 + github.com/VictoriaMetrics/fastcache v1.13.0 github.com/aws/aws-sdk-go-v2 v1.21.2 github.com/aws/aws-sdk-go-v2/config v1.18.45 github.com/aws/aws-sdk-go-v2/credentials v1.13.43 @@ -13,30 +13,29 @@ require ( github.com/cespare/cp v0.1.0 github.com/cloudflare/cloudflare-go v0.114.0 github.com/cockroachdb/pebble v1.1.5 - github.com/consensys/gnark-crypto v0.18.0 - github.com/crate-crypto/go-eth-kzg v1.3.0 - github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a + github.com/consensys/gnark-crypto v0.18.1 + github.com/crate-crypto/go-eth-kzg v1.4.0 github.com/davecgh/go-spew v1.1.1 + github.com/dchest/siphash v1.2.3 github.com/deckarep/golang-set/v2 v2.6.0 github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 github.com/donovanhide/eventsource v0.0.0-20210830082556-c59027999da0 github.com/dop251/goja v0.0.0-20230605162241-28ee0ee714f3 - github.com/ethereum/c-kzg-4844/v2 v2.1.0 - github.com/ethereum/go-verkle v0.2.2 + github.com/ethereum/c-kzg-4844/v2 v2.1.5 + github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab github.com/fatih/color v1.16.0 github.com/ferranbt/fastssz v0.1.4 - github.com/fjl/gencodec v0.1.0 github.com/fsnotify/fsnotify v1.6.0 github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff github.com/gofrs/flock v0.12.1 github.com/golang-jwt/jwt/v4 v4.5.2 - github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb + github.com/golang/snappy v1.0.0 github.com/google/gofuzz v1.2.0 - github.com/google/uuid v1.3.0 + github.com/google/uuid v1.6.0 github.com/gorilla/websocket v1.4.2 github.com/graph-gophers/graphql-go v1.3.0 github.com/hashicorp/go-bexpr v0.1.10 - github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 + github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db github.com/holiman/bloomfilter/v2 v2.0.3 github.com/holiman/uint256 v1.3.2 github.com/huin/goupnp v1.3.0 @@ -49,7 +48,6 @@ require ( github.com/mattn/go-colorable v0.1.13 github.com/mattn/go-isatty v0.0.20 github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 - github.com/olekukonko/tablewriter v0.0.5 github.com/peterh/liner v1.1.1-0.20190123174540-a2c9a5303de7 github.com/pion/stun/v2 v2.0.0 github.com/protolambda/bls12-381-util v0.1.0 @@ -58,16 +56,19 @@ require ( github.com/rs/cors v1.7.0 github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible github.com/status-im/keycard-go v0.2.0 - github.com/stretchr/testify v1.10.0 - github.com/supranational/blst v0.3.14 + github.com/stretchr/testify v1.11.1 + github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 github.com/urfave/cli/v2 v2.27.5 + go.opentelemetry.io/otel v1.39.0 + go.opentelemetry.io/otel/sdk v1.39.0 + go.opentelemetry.io/otel/trace v1.39.0 go.uber.org/automaxprocs v1.5.2 go.uber.org/goleak v1.3.0 golang.org/x/crypto v0.36.0 golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df golang.org/x/sync v0.12.0 - golang.org/x/sys v0.31.0 + golang.org/x/sys v0.39.0 golang.org/x/text v0.23.0 golang.org/x/time v0.9.0 golang.org/x/tools v0.29.0 @@ -76,10 +77,18 @@ require ( gopkg.in/yaml.v3 v3.0.1 ) +require ( + github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + go.opentelemetry.io/auto/sdk v1.2.1 // indirect + go.opentelemetry.io/otel/metric v1.39.0 // indirect +) + require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.7.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/internal v1.3.0 // indirect github.com/DataDog/zstd v1.4.5 // indirect + github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 github.com/StackExchange/wmi v1.2.1 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.13 // indirect github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.43 // indirect @@ -102,6 +111,7 @@ require ( github.com/deepmap/oapi-codegen v1.6.0 // indirect github.com/dlclark/regexp2 v1.7.0 // indirect github.com/emicklei/dot v1.6.2 // indirect + github.com/fjl/gencodec v0.1.0 // indirect github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61 // indirect github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect @@ -111,10 +121,12 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/pprof v0.0.0-20230207041349-798e818bf904 // indirect + github.com/grafana/pyroscope-go v1.2.7 + github.com/grafana/pyroscope-go/godeltaprof v0.1.9 // indirect github.com/influxdata/line-protocol v0.0.0-20200327222509-2487e7298839 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/kilic/bls12-381 v0.1.0 // indirect - github.com/klauspost/compress v1.16.0 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.0.9 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect @@ -136,7 +148,7 @@ require ( github.com/prometheus/common v0.42.0 // indirect github.com/prometheus/procfs v0.9.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.12.0 // indirect + github.com/rogpeppe/go-internal v1.14.1 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect @@ -145,3 +157,9 @@ require ( golang.org/x/net v0.38.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) + +tool ( + github.com/fjl/gencodec + golang.org/x/tools/cmd/stringer + google.golang.org/protobuf/cmd/protoc-gen-go +) diff --git a/go.sum b/go.sum index 099d432ba4..dad819e09d 100644 --- a/go.sum +++ b/go.sum @@ -14,10 +14,12 @@ github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6 h1:1zYrtlhrZ6/b6SAjLSfKzWtdgqK0U+HtH/VcBWh1BaU= +github.com/ProjectZKM/Ziren/crates/go-runtime/zkvm_runtime v0.0.0-20251001021608-1fe7b43fc4d6/go.mod h1:ioLG6R+5bUSO1oeGSDxOV3FADARuMoytZCSX6MEMQkI= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= -github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= -github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= +github.com/VictoriaMetrics/fastcache v1.13.0 h1:AW4mheMR5Vd9FkAPUv+NH6Nhw+fmbTMGMsNAoA/+4G0= +github.com/VictoriaMetrics/fastcache v1.13.0/go.mod h1:hHXhl4DA2fTL2HTZDJFXWgW0LNjo6B+4aj2Wmng3TjU= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156 h1:eMwmnE/GDgah4HI848JfFxHt+iPb26b4zyfspmqY0/8= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/aws/aws-sdk-go-v2 v1.21.2 h1:+LXZ0sgo8quN9UOKXXzAWRT3FWd4NxeXWOZom9pE7GA= @@ -52,7 +54,6 @@ github.com/bits-and-blooms/bitset v1.20.0 h1:2F+rfL86jE2d/bmw7OhqUg2Sj/1rURkBn3M github.com/bits-and-blooms/bitset v1.20.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/cespare/cp v0.1.0 h1:SE+dxFebS7Iik5LK0tsi1k9ZCxEaFX4AjQmoyA+1dJk= github.com/cespare/cp v0.1.0/go.mod h1:SOGHArjBr4JWaSDEVpWpo/hNg6RoKrls6Oh40hiwW+s= -github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= @@ -74,19 +75,19 @@ github.com/cockroachdb/redact v1.1.5 h1:u1PMllDkdFfPWaNGMyLD1+so+aq3uUItthCFqzwP github.com/cockroachdb/redact v1.1.5/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 h1:zuQyyAKVxetITBuuhv3BI9cMrmStnpT18zmgmTxunpo= github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06/go.mod h1:7nc4anLGjupUW/PeY5qiNYsdNXj7zopG+eqsS7To5IQ= -github.com/consensys/gnark-crypto v0.18.0 h1:vIye/FqI50VeAr0B3dx+YjeIvmc3LWz4yEfbWBpTUf0= -github.com/consensys/gnark-crypto v0.18.0/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= +github.com/consensys/gnark-crypto v0.18.1 h1:RyLV6UhPRoYYzaFnPQA4qK3DyuDgkTgskDdoGqFt3fI= +github.com/consensys/gnark-crypto v0.18.1/go.mod h1:L3mXGFTe1ZN+RSJ+CLjUt9x7PNdx8ubaYfDROyp2Z8c= github.com/cpuguy83/go-md2man/v2 v2.0.5 h1:ZtcqGrnekaHpVLArFSe4HK5DoKx1T0rq2DwVB0alcyc= github.com/cpuguy83/go-md2man/v2 v2.0.5/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/crate-crypto/go-eth-kzg v1.3.0 h1:05GrhASN9kDAidaFJOda6A4BEvgvuXbazXg/0E3OOdI= -github.com/crate-crypto/go-eth-kzg v1.3.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= -github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a h1:W8mUrRp6NOVl3J+MYp5kPMoUZPp7aOYHtaua31lwRHg= -github.com/crate-crypto/go-ipa v0.0.0-20240724233137-53bbb0ceb27a/go.mod h1:sTwzHBvIzm2RfVCGNEBZgRyjwK40bVoun3ZnGOCafNM= +github.com/crate-crypto/go-eth-kzg v1.4.0 h1:WzDGjHk4gFg6YzV0rJOAsTK4z3Qkz5jd4RE3DAvPFkg= +github.com/crate-crypto/go-eth-kzg v1.4.0/go.mod h1:J9/u5sWfznSObptgfa92Jq8rTswn6ahQWEuiLHOjCUI= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/cyberdelia/templates v0.0.0-20141128023046-ca7fffd4298c/go.mod h1:GyV+0YP4qX0UQ7r2MoYZ+AvYDp12OF5yg4q8rGnyNh4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dchest/siphash v1.2.3 h1:QXwFc8cFOR2dSa/gE6o/HokBMWtLUaNDVd+22aKHeEA= +github.com/dchest/siphash v1.2.3/go.mod h1:0NvQU092bT0ipiFN++/rXm69QG9tVxLAlQHIXMPAkHc= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= @@ -110,10 +111,10 @@ github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA github.com/dop251/goja_nodejs v0.0.0-20211022123610-8dd9abb0616d/go.mod h1:DngW8aVqWbuLRMHItjPUyqdj+HWPvnQe8V8y1nDpIbM= github.com/emicklei/dot v1.6.2 h1:08GN+DD79cy/tzN6uLCT84+2Wk9u+wvqP+Hkx/dIR8A= github.com/emicklei/dot v1.6.2/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= -github.com/ethereum/c-kzg-4844/v2 v2.1.0 h1:gQropX9YFBhl3g4HYhwE70zq3IHFRgbbNPw0Shwzf5w= -github.com/ethereum/c-kzg-4844/v2 v2.1.0/go.mod h1:TC48kOKjJKPbN7C++qIgt0TJzZ70QznYR7Ob+WXl57E= -github.com/ethereum/go-verkle v0.2.2 h1:I2W0WjnrFUIzzVPwm8ykY+7pL2d4VhlsePn4j7cnFk8= -github.com/ethereum/go-verkle v0.2.2/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= +github.com/ethereum/c-kzg-4844/v2 v2.1.5 h1:aVtoLK5xwJ6c5RiqO8g8ptJ5KU+2Hdquf6G3aXiHh5s= +github.com/ethereum/c-kzg-4844/v2 v2.1.5/go.mod h1:u59hRTTah4Co6i9fDWtiCjTrblJv0UwsqZKCc0GfgUs= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab h1:rvv6MJhy07IMfEKuARQ9TKojGqLVNxQajaXEp/BoqSk= +github.com/ethereum/go-bigmodexpfix v0.0.0-20250911101455-f9e208c548ab/go.mod h1:IuLm4IsPipXKF7CW5Lzf68PIbZ5yl7FFd74l/E0o9A8= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/ferranbt/fastssz v0.1.4 h1:OCDB+dYDEQDvAgtAGnTSidK1Pe2tW3nFV40XyMkTeDY= @@ -135,6 +136,11 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA= github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= +github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= @@ -161,33 +167,37 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= -github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golangci/lint-1 v0.0.0-20181222135242-d2cdd8c08219/go.mod h1:/X8TswGSh1pIozq4ZwCfxS0WA5JGXguxk94ar/4c87Y= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/pprof v0.0.0-20230207041349-798e818bf904 h1:4/hN5RUoecvl+RmJRE2YxKWtnnQls6rQjjW5oV7qg2U= github.com/google/pprof v0.0.0-20230207041349-798e818bf904/go.mod h1:uglQLonpP8qtYCYyzA+8c/9qtqgA3qsXGYqCPKARAFg= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/pyroscope-go v1.2.7 h1:VWBBlqxjyR0Cwk2W6UrE8CdcdD80GOFNutj0Kb1T8ac= +github.com/grafana/pyroscope-go v1.2.7/go.mod h1:o/bpSLiJYYP6HQtvcoVKiE9s5RiNgjYTj1DhiddP2Pc= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9 h1:c1Us8i6eSmkW+Ez05d3co8kasnuOY813tbMN8i/a3Og= +github.com/grafana/pyroscope-go/godeltaprof v0.1.9/go.mod h1:2+l7K7twW49Ct4wFluZD3tZ6e0SjanjcUUBPVD/UuGU= github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/hashicorp/go-bexpr v0.1.10 h1:9kuI5PFotCboP3dkDYFr/wi0gg0QVbSNz5oFRpxn4uE= github.com/hashicorp/go-bexpr v0.1.10/go.mod h1:oxlubA2vC/gFVfX1A6JGp7ls7uCDlfJn732ehYYg+g0= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4 h1:X4egAf/gcS1zATw6wn4Ej8vjuVGxeHdan+bRb2ebyv4= -github.com/holiman/billy v0.0.0-20240216141850-2abb0c79d3c4/go.mod h1:5GuXa7vkL8u9FkFuWdVvfR5ix8hRB7DbOAaYULamFpc= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db h1:IZUYC/xb3giYwBLMnr8d0TGTzPKFGNTCGgGLoyeX330= +github.com/holiman/billy v0.0.0-20250707135307-f2f9b9aae7db/go.mod h1:xTEYN9KCHxuYHs+NmrmzFcnvHMzLLNiGFafCb1n3Mfg= github.com/holiman/bloomfilter/v2 v2.0.3 h1:73e0e/V0tCydx14a0SCYS/EWCxgwLZ18CZcZKVu0fao= github.com/holiman/bloomfilter/v2 v2.0.3/go.mod h1:zpoh+gs7qcpqrHr3dB55AMiJwo0iURXE7ZOP9L9hSkA= github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= @@ -217,8 +227,8 @@ github.com/kilic/bls12-381 v0.1.0 h1:encrdjqKMEvabVQ7qYOKu1OvhqpK4s47wDYtNiPtlp4 github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.16.0 h1:iULayQNOReoYUe+1qtKOqw9CwJv3aNQu8ivo7lw1HU4= -github.com/klauspost/compress v1.16.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= @@ -252,7 +262,6 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= @@ -269,8 +278,6 @@ github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416 h1:shk/vn9oCoOTmwcou github.com/naoina/toml v0.1.2-0.20170918210437-9fafd6967416/go.mod h1:NBIhNtsFMo3G2szEBne+bO4gS192HuIYRqfvOWb4i1E= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= -github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= @@ -324,8 +331,8 @@ github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= -github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= +github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= @@ -337,6 +344,8 @@ github.com/status-im/keycard-go v0.2.0/go.mod h1:wlp8ZLbsmrF6g6WjugPAx+IzoLrkdf9 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= @@ -345,10 +354,10 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= -github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= -github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/supranational/blst v0.3.14 h1:xNMoHRJOTwMn63ip6qoWJ2Ymgvj7E2b9jY2FAwY+qRo= -github.com/supranational/blst v0.3.14/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= +github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= +github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe h1:nbdqkIGOGfUAD54q1s2YBcBz/WcsxCO9HUQ4aGV5hUw= +github.com/supranational/blst v0.3.16-0.20250831170142-f48500c1fdbe/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7/go.mod h1:q4W45IWZaF22tdD+VEXcAWRA037jwmWEB5VWYORlTpc= github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU= @@ -365,6 +374,18 @@ github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1/go.mod h1:Ohn+xnUBi github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= +go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= +go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48= +go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8= +go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0= +go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs= +go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18= +go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE= +go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8= +go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew= +go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI= +go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA= go.uber.org/automaxprocs v1.5.2 h1:2LxUOGiR3O6tw8ui5sZa2LAaHnsviZdVOUZw4fvbnME= go.uber.org/automaxprocs v1.5.2/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= @@ -446,9 +467,8 @@ golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik= -golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk= +golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= diff --git a/graphql/graphql.go b/graphql/graphql.go index 0b2a77a3c4..f5eec210a5 100644 --- a/graphql/graphql.go +++ b/graphql/graphql.go @@ -272,7 +272,7 @@ func (t *Transaction) GasPrice(ctx context.Context) hexutil.Big { return hexutil.Big{} } switch tx.Type() { - case types.DynamicFeeTxType: + case types.DynamicFeeTxType, types.BlobTxType, types.SetCodeTxType: if block != nil { if baseFee, _ := block.BaseFeePerGas(ctx); baseFee != nil { // price = min(gasTipCap + baseFee, gasFeeCap) @@ -575,6 +575,9 @@ func (t *Transaction) getLogs(ctx context.Context, hash common.Hash) (*[]*Log, e func (t *Transaction) Type(ctx context.Context) *hexutil.Uint64 { tx, _ := t.resolve(ctx) + if tx == nil { + return nil + } txType := hexutil.Uint64(tx.Type()) return &txType } @@ -704,6 +707,9 @@ func (b *Block) resolveHeader(ctx context.Context) (*types.Header, error) { if err != nil { return nil, err } + if b.header == nil { + return nil, nil + } if b.hash == (common.Hash{}) { b.hash = b.header.Hash() } @@ -1427,7 +1433,7 @@ func (r *Resolver) Logs(ctx context.Context, args struct{ Filter FilterCriteria topics = *args.Filter.Topics } // Construct the range filter - filter := r.filterSystem.NewRangeFilter(begin, end, addresses, topics) + filter := r.filterSystem.NewRangeFilter(begin, end, addresses, topics, 0) return runFilter(ctx, r, filter) } diff --git a/graphql/graphql_test.go b/graphql/graphql_test.go index 0f6ba10b90..ca864d5fb2 100644 --- a/graphql/graphql_test.go +++ b/graphql/graphql_test.go @@ -430,6 +430,40 @@ func TestWithdrawals(t *testing.T) { } } +// TestGraphQLMaxDepth ensures that queries exceeding the configured maximum depth +// are rejected to prevent resource exhaustion from deeply nested operations. +func TestGraphQLMaxDepth(t *testing.T) { + stack := createNode(t) + defer stack.Close() + + h, err := newHandler(stack, nil, nil, []string{}, []string{}) + if err != nil { + t.Fatalf("could not create graphql service: %v", err) + } + + var b strings.Builder + for i := 0; i < maxQueryDepth+1; i++ { + b.WriteString("ommers{") + } + b.WriteString("number") + for i := 0; i < maxQueryDepth+1; i++ { + b.WriteString("}") + } + query := fmt.Sprintf("{block{%s}}", b.String()) + + res := h.Schema.Exec(context.Background(), query, "", nil) + var found bool + for _, err := range res.Errors { + if err.Rule == "MaxDepthExceeded" { + found = true + break + } + } + if !found { + t.Fatalf("expected max depth exceeded error, got %v", res.Errors) + } +} + func createNode(t *testing.T) *node.Node { stack, err := node.New(&node.Config{ HTTPHost: "127.0.0.1", diff --git a/graphql/service.go b/graphql/service.go index 584165bdb8..9381a51da6 100644 --- a/graphql/service.go +++ b/graphql/service.go @@ -32,6 +32,9 @@ import ( gqlErrors "github.com/graph-gophers/graphql-go/errors" ) +// maxQueryDepth limits the maximum field nesting depth allowed in GraphQL queries. +const maxQueryDepth = 20 + type handler struct { Schema *graphql.Schema } @@ -116,7 +119,7 @@ func New(stack *node.Node, backend ethapi.Backend, filterSystem *filters.FilterS func newHandler(stack *node.Node, backend ethapi.Backend, filterSystem *filters.FilterSystem, cors, vhosts []string) (*handler, error) { q := Resolver{backend, filterSystem} - s, err := graphql.ParseSchema(schema, &q) + s, err := graphql.ParseSchema(schema, &q, graphql.MaxDepth(maxQueryDepth)) if err != nil { return nil, err } diff --git a/interfaces.go b/interfaces.go index be5b970851..21d42c6d34 100644 --- a/interfaces.go +++ b/interfaces.go @@ -19,10 +19,12 @@ package ethereum import ( "context" + "encoding/json" "errors" "math/big" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" ) @@ -62,6 +64,13 @@ type ChainReader interface { SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (Subscription, error) } +// TransactionReceiptsQuery defines criteria for transaction receipts subscription. +// If TransactionHashes is empty, receipts for all transactions included in new blocks will be delivered. +// Otherwise, only receipts for the specified transactions will be delivered. +type TransactionReceiptsQuery struct { + TransactionHashes []common.Hash +} + // TransactionReader provides access to past transactions and their receipts. // Implementations may impose arbitrary restrictions on the transactions and receipts that // can be retrieved. Historic transactions may not be available. @@ -81,6 +90,11 @@ type TransactionReader interface { // transaction may not be included in the current canonical chain even if a receipt // exists. TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error) + // SubscribeTransactionReceipts subscribes to notifications about transaction receipts. + // The receipts are delivered in batches when transactions are included in blocks. + // If q is nil or has empty TransactionHashes, all receipts from new blocks will be delivered. + // Otherwise, only receipts for the specified transaction hashes will be delivered. + SubscribeTransactionReceipts(ctx context.Context, q *TransactionReceiptsQuery, ch chan<- []*types.Receipt) (Subscription, error) } // ChainStateReader wraps access to the state trie of the canonical blockchain. Note that @@ -281,3 +295,98 @@ type BlockNumberReader interface { type ChainIDReader interface { ChainID(ctx context.Context) (*big.Int, error) } + +// OverrideAccount specifies the state of an account to be overridden. +type OverrideAccount struct { + // Nonce sets nonce of the account. Note: the nonce override will only + // be applied when it is set to a non-zero value. + Nonce uint64 + + // Code sets the contract code. The override will be applied + // when the code is non-nil, i.e. setting empty code is possible + // using an empty slice. + Code []byte + + // Balance sets the account balance. + Balance *big.Int + + // State sets the complete storage. The override will be applied + // when the given map is non-nil. Using an empty map wipes the + // entire contract storage during the call. + State map[common.Hash]common.Hash + + // StateDiff allows overriding individual storage slots. + StateDiff map[common.Hash]common.Hash +} + +func (a OverrideAccount) MarshalJSON() ([]byte, error) { + type acc struct { + Nonce hexutil.Uint64 `json:"nonce,omitempty"` + Code string `json:"code,omitempty"` + Balance *hexutil.Big `json:"balance,omitempty"` + State interface{} `json:"state,omitempty"` + StateDiff map[common.Hash]common.Hash `json:"stateDiff,omitempty"` + } + + output := acc{ + Nonce: hexutil.Uint64(a.Nonce), + Balance: (*hexutil.Big)(a.Balance), + StateDiff: a.StateDiff, + } + if a.Code != nil { + output.Code = hexutil.Encode(a.Code) + } + if a.State != nil { + output.State = a.State + } + return json.Marshal(output) +} + +// BlockOverrides specifies the set of header fields to override. +type BlockOverrides struct { + // Number overrides the block number. + Number *big.Int + // Difficulty overrides the block difficulty. + Difficulty *big.Int + // Time overrides the block timestamp. Time is applied only when + // it is non-zero. + Time uint64 + // GasLimit overrides the block gas limit. GasLimit is applied only when + // it is non-zero. + GasLimit uint64 + // Coinbase overrides the block coinbase. Coinbase is applied only when + // it is different from the zero address. + Coinbase common.Address + // Random overrides the block extra data which feeds into the RANDOM opcode. + // Random is applied only when it is a non-zero hash. + Random common.Hash + // BaseFee overrides the block base fee. + BaseFee *big.Int +} + +func (o BlockOverrides) MarshalJSON() ([]byte, error) { + type override struct { + Number *hexutil.Big `json:"number,omitempty"` + Difficulty *hexutil.Big `json:"difficulty,omitempty"` + Time hexutil.Uint64 `json:"time,omitempty"` + GasLimit hexutil.Uint64 `json:"gasLimit,omitempty"` + Coinbase *common.Address `json:"feeRecipient,omitempty"` + Random *common.Hash `json:"prevRandao,omitempty"` + BaseFee *hexutil.Big `json:"baseFeePerGas,omitempty"` + } + + output := override{ + Number: (*hexutil.Big)(o.Number), + Difficulty: (*hexutil.Big)(o.Difficulty), + Time: hexutil.Uint64(o.Time), + GasLimit: hexutil.Uint64(o.GasLimit), + BaseFee: (*hexutil.Big)(o.BaseFee), + } + if o.Coinbase != (common.Address{}) { + output.Coinbase = &o.Coinbase + } + if o.Random != (common.Hash{}) { + output.Random = &o.Random + } + return json.Marshal(output) +} diff --git a/internal/blocktest/test_hash.go b/internal/blocktest/test_hash.go index 4d2b077e89..b3e7098e2b 100644 --- a/internal/blocktest/test_hash.go +++ b/internal/blocktest/test_hash.go @@ -23,6 +23,7 @@ package blocktest import ( + "bytes" "hash" "github.com/ethereum/go-ethereum/common" @@ -48,8 +49,8 @@ func (h *testHasher) Reset() { // Update updates the hash state with the given key and value. func (h *testHasher) Update(key, val []byte) error { - h.hasher.Write(key) - h.hasher.Write(val) + h.hasher.Write(bytes.Clone(key)) + h.hasher.Write(bytes.Clone(val)) return nil } diff --git a/internal/build/file.go b/internal/build/file.go index 2d8c993f36..b7c00eb842 100644 --- a/internal/build/file.go +++ b/internal/build/file.go @@ -21,46 +21,21 @@ import ( "io" "os" "path/filepath" - "sort" - "strings" + "slices" ) -// FileExist checks if a file exists at path. -func FileExist(path string) bool { - _, err := os.Stat(path) - if err != nil && os.IsNotExist(err) { - return false - } - return true -} - -// HashFiles iterates the provided set of files, computing the hash of each. -func HashFiles(files []string) (map[string][32]byte, error) { - res := make(map[string][32]byte) - for _, filePath := range files { - f, err := os.OpenFile(filePath, os.O_RDONLY, 0666) - if err != nil { - return nil, err - } - hasher := sha256.New() - if _, err := io.Copy(hasher, f); err != nil { - return nil, err - } - res[filePath] = [32]byte(hasher.Sum(nil)) - } - return res, nil -} - // HashFolder iterates all files under the given directory, computing the hash // of each. -func HashFolder(folder string, exlude []string) (map[string][32]byte, error) { +func HashFolder(folder string, excludes []string) (map[string][32]byte, error) { res := make(map[string][32]byte) err := filepath.WalkDir(folder, func(path string, d os.DirEntry, _ error) error { // Skip anything that's exluded or not a regular file - for _, skip := range exlude { - if strings.HasPrefix(path, filepath.FromSlash(skip)) { + // Skip anything that's excluded or not a regular file + if slices.Contains(excludes, path) { + if d.IsDir() { return filepath.SkipDir } + return nil } if !d.Type().IsRegular() { return nil @@ -97,6 +72,6 @@ func DiffHashes(a map[string][32]byte, b map[string][32]byte) []string { updates = append(updates, file) } } - sort.Strings(updates) + slices.Sort(updates) return updates } diff --git a/internal/build/util.go b/internal/build/util.go index aee8bf0fc8..6e6632c750 100644 --- a/internal/build/util.go +++ b/internal/build/util.go @@ -21,8 +21,6 @@ import ( "bytes" "flag" "fmt" - "go/parser" - "go/token" "io" "log" "os" @@ -39,6 +37,9 @@ var DryRunFlag = flag.Bool("n", false, "dry run, don't execute commands") // MustRun executes the given command and exits the host process for // any error. func MustRun(cmd *exec.Cmd) { + if cmd.Dir != "" && cmd.Dir != "." { + fmt.Printf("(in %s) ", cmd.Dir) + } fmt.Println(">>>", printArgs(cmd.Args)) if !*DryRunFlag { cmd.Stderr = os.Stderr @@ -71,6 +72,13 @@ func MustRunCommand(cmd string, args ...string) { // printed while it runs. This is useful for CI builds where the process will be stopped // when there is no output. func MustRunCommandWithOutput(cmd string, args ...string) { + MustRunWithOutput(exec.Command(cmd, args...)) +} + +// MustRunWithOutput runs the given command, and ensures that some output will be printed +// while it runs. This is useful for CI builds where the process will be stopped when +// there is no output. +func MustRunWithOutput(cmd *exec.Cmd) { interval := time.NewTicker(time.Minute) done := make(chan struct{}) defer interval.Stop() @@ -85,7 +93,7 @@ func MustRunCommandWithOutput(cmd string, args ...string) { } } }() - MustRun(exec.Command(cmd, args...)) + MustRun(cmd) } var warnedAboutGit bool @@ -209,28 +217,18 @@ func UploadSFTP(identityFile, host, dir string, files []string) error { // FindMainPackages finds all 'main' packages in the given directory and returns their // package paths. -func FindMainPackages(dir string) []string { - var commands []string - cmds, err := os.ReadDir(dir) +func FindMainPackages(tc *GoToolchain, pattern string) []string { + list := tc.Go("list", "-f", `{{if eq .Name "main"}}{{.ImportPath}}{{end}}`, pattern) + output, err := list.Output() if err != nil { - log.Fatal(err) + log.Fatal("go list failed:", err) } - for _, cmd := range cmds { - pkgdir := filepath.Join(dir, cmd.Name()) - if !cmd.IsDir() { - continue - } - pkgs, err := parser.ParseDir(token.NewFileSet(), pkgdir, nil, parser.PackageClauseOnly) - if err != nil { - log.Fatal(err) - } - for name := range pkgs { - if name == "main" { - path := "./" + filepath.ToSlash(pkgdir) - commands = append(commands, path) - break - } + var result []string + for l := range bytes.Lines(output) { + l = bytes.TrimSpace(l) + if len(l) > 0 { + result = append(result, string(l)) } } - return commands + return result } diff --git a/internal/debug/api.go b/internal/debug/api.go index 1bac36e908..5a2781cc77 100644 --- a/internal/debug/api.go +++ b/internal/debug/api.go @@ -252,7 +252,7 @@ func (*HandlerT) SetGCPercent(v int) int { // - Geth also allocates memory off-heap, particularly for fastCache and Pebble, // which can be non-trivial (a few gigabytes by default). func (*HandlerT) SetMemoryLimit(limit int64) int64 { - log.Info("Setting memory limit", "size", common.PrettyDuration(limit)) + log.Info("Setting memory limit", "size", common.StorageSize(limit)) return debug.SetMemoryLimit(limit) } diff --git a/internal/debug/flags.go b/internal/debug/flags.go index 30b0ddb3be..b4e55c46c1 100644 --- a/internal/debug/flags.go +++ b/internal/debug/flags.go @@ -162,6 +162,11 @@ var Flags = []cli.Flag{ blockprofilerateFlag, cpuprofileFlag, traceFlag, + pyroscopeFlag, + pyroscopeServerFlag, + pyroscopeAuthUsernameFlag, + pyroscopeAuthPasswordFlag, + pyroscopeTagsFlag, } var ( @@ -298,6 +303,14 @@ func Setup(ctx *cli.Context) error { // It cannot be imported because it will cause a cyclical dependency. StartPProf(address, !ctx.IsSet("metrics.addr")) } + + // Pyroscope profiling + if ctx.Bool(pyroscopeFlag.Name) { + if err := startPyroscope(ctx); err != nil { + return err + } + } + if len(logFile) > 0 || rotation { log.Info("Logging configured", context...) } @@ -321,6 +334,7 @@ func StartPProf(address string, withMetrics bool) { // Exit stops all running profiles, flushing their output to the // respective file. func Exit() { + stopPyroscope() Handler.StopCPUProfile() Handler.StopGoTrace() if logOutputFile != nil { diff --git a/internal/debug/pyroscope.go b/internal/debug/pyroscope.go new file mode 100644 index 0000000000..d0804cb891 --- /dev/null +++ b/internal/debug/pyroscope.go @@ -0,0 +1,134 @@ +// Copyright 2026 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package debug + +import ( + "fmt" + "strings" + + "github.com/ethereum/go-ethereum/internal/flags" + "github.com/ethereum/go-ethereum/log" + "github.com/grafana/pyroscope-go" + "github.com/urfave/cli/v2" +) + +var ( + pyroscopeFlag = &cli.BoolFlag{ + Name: "pyroscope", + Usage: "Enable Pyroscope profiling", + Value: false, + Category: flags.LoggingCategory, + } + pyroscopeServerFlag = &cli.StringFlag{ + Name: "pyroscope.server", + Usage: "Pyroscope server URL to push profiling data to", + Value: "http://localhost:4040", + Category: flags.LoggingCategory, + } + pyroscopeAuthUsernameFlag = &cli.StringFlag{ + Name: "pyroscope.username", + Usage: "Pyroscope basic authentication username", + Value: "", + Category: flags.LoggingCategory, + } + pyroscopeAuthPasswordFlag = &cli.StringFlag{ + Name: "pyroscope.password", + Usage: "Pyroscope basic authentication password", + Value: "", + Category: flags.LoggingCategory, + } + pyroscopeTagsFlag = &cli.StringFlag{ + Name: "pyroscope.tags", + Usage: "Comma separated list of key=value tags to add to profiling data", + Value: "", + Category: flags.LoggingCategory, + } +) + +// This holds the globally-configured Pyroscope instance. +var pyroscopeProfiler *pyroscope.Profiler + +func startPyroscope(ctx *cli.Context) error { + server := ctx.String(pyroscopeServerFlag.Name) + authUsername := ctx.String(pyroscopeAuthUsernameFlag.Name) + authPassword := ctx.String(pyroscopeAuthPasswordFlag.Name) + + rawTags := ctx.String(pyroscopeTagsFlag.Name) + tags := make(map[string]string) + for tag := range strings.SplitSeq(rawTags, ",") { + tag = strings.TrimSpace(tag) + if tag == "" { + continue + } + k, v, _ := strings.Cut(tag, "=") + tags[k] = v + } + + config := pyroscope.Config{ + ApplicationName: "geth", + ServerAddress: server, + BasicAuthUser: authUsername, + BasicAuthPassword: authPassword, + Logger: &pyroscopeLogger{Logger: log.Root()}, + Tags: tags, + ProfileTypes: []pyroscope.ProfileType{ + // Enabling all profile types + pyroscope.ProfileCPU, + pyroscope.ProfileAllocObjects, + pyroscope.ProfileAllocSpace, + pyroscope.ProfileInuseObjects, + pyroscope.ProfileInuseSpace, + pyroscope.ProfileGoroutines, + pyroscope.ProfileMutexCount, + pyroscope.ProfileMutexDuration, + pyroscope.ProfileBlockCount, + pyroscope.ProfileBlockDuration, + }, + } + + profiler, err := pyroscope.Start(config) + if err != nil { + return err + } + pyroscopeProfiler = profiler + log.Info("Enabled Pyroscope") + return nil +} + +func stopPyroscope() { + if pyroscopeProfiler != nil { + pyroscopeProfiler.Stop() + pyroscopeProfiler = nil + } +} + +// Small wrapper for log.Logger to satisfy pyroscope.Logger interface +type pyroscopeLogger struct { + Logger log.Logger +} + +func (l *pyroscopeLogger) Infof(format string, v ...any) { + l.Logger.Info(fmt.Sprintf("Pyroscope: "+format, v...)) +} + +func (l *pyroscopeLogger) Debugf(format string, v ...any) { + l.Logger.Debug(fmt.Sprintf("Pyroscope: "+format, v...)) +} + +func (l *pyroscopeLogger) Errorf(format string, v ...any) { + l.Logger.Error(fmt.Sprintf("Pyroscope: "+format, v...)) +} diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 51b6ca3c44..b0a79295f5 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -34,6 +34,7 @@ import ( "github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus/misc/eip1559" "github.com/ethereum/go-ethereum/core" + "github.com/ethereum/go-ethereum/core/forkid" "github.com/ethereum/go-ethereum/core/state" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/vm" @@ -46,7 +47,6 @@ import ( "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/trie" ) // estimateGasErrorRatio is the amount of overestimation eth_estimateGas is @@ -54,6 +54,7 @@ import ( const estimateGasErrorRatio = 0.015 var errBlobTxNotSupported = errors.New("signing blob transactions not supported") +var errSubClosed = errors.New("chain subscription closed") // EthereumAPI provides an API to access Ethereum related information. type EthereumAPI struct { @@ -184,6 +185,15 @@ func NewTxPoolAPI(b Backend) *TxPoolAPI { return &TxPoolAPI{b} } +// flattenTxs builds the RPC transaction map keyed by nonce for a set of pool txs. +func flattenTxs(txs types.Transactions, header *types.Header, cfg *params.ChainConfig) map[string]*RPCTransaction { + dump := make(map[string]*RPCTransaction, len(txs)) + for _, tx := range txs { + dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, header, cfg) + } + return dump +} + // Content returns the transactions contained within the transaction pool. func (api *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction { pending, queue := api.b.TxPoolContent() @@ -194,19 +204,11 @@ func (api *TxPoolAPI) Content() map[string]map[string]map[string]*RPCTransaction curHeader := api.b.CurrentHeader() // Flatten the pending transactions for account, txs := range pending { - dump := make(map[string]*RPCTransaction, len(txs)) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig()) - } - content["pending"][account.Hex()] = dump + content["pending"][account.Hex()] = flattenTxs(txs, curHeader, api.b.ChainConfig()) } // Flatten the queued transactions for account, txs := range queue { - dump := make(map[string]*RPCTransaction, len(txs)) - for _, tx := range txs { - dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig()) - } - content["queued"][account.Hex()] = dump + content["queued"][account.Hex()] = flattenTxs(txs, curHeader, api.b.ChainConfig()) } return content } @@ -218,18 +220,10 @@ func (api *TxPoolAPI) ContentFrom(addr common.Address) map[string]map[string]*RP curHeader := api.b.CurrentHeader() // Build the pending transactions - dump := make(map[string]*RPCTransaction, len(pending)) - for _, tx := range pending { - dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig()) - } - content["pending"] = dump + content["pending"] = flattenTxs(pending, curHeader, api.b.ChainConfig()) // Build the queued transactions - dump = make(map[string]*RPCTransaction, len(queue)) - for _, tx := range queue { - dump[fmt.Sprintf("%d", tx.Nonce())] = NewRPCPendingTransaction(tx, curHeader, api.b.ChainConfig()) - } - content["queued"] = dump + content["queued"] = flattenTxs(queue, curHeader, api.b.ChainConfig()) return content } @@ -372,9 +366,9 @@ func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, // Deserialize all keys. This prevents state access on invalid input. for i, hexKey := range storageKeys { var err error - keys[i], keyLengths[i], err = decodeHash(hexKey) + keys[i], keyLengths[i], err = decodeStorageKey(hexKey) if err != nil { - return nil, err + return nil, &invalidParamsError{fmt.Sprintf("%v: %q", err, hexKey)} } } statedb, header, err := api.b.StateAndHeaderByNumberOrHash(ctx, blockNrOrHash) @@ -387,8 +381,7 @@ func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, if len(keys) > 0 { var storageTrie state.Trie if storageRoot != types.EmptyRootHash && storageRoot != (common.Hash{}) { - id := trie.StorageTrieID(header.Root, crypto.Keccak256Hash(address.Bytes()), storageRoot) - st, err := trie.NewStateTrie(id, statedb.Database().TrieDB()) + st, err := statedb.Database().OpenStorageTrie(header.Root, address, storageRoot, nil) if err != nil { return nil, err } @@ -419,7 +412,7 @@ func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, } } // Create the accountProof. - tr, err := trie.NewStateTrie(trie.StateTrieID(header.Root), statedb.Database().TrieDB()) + tr, err := statedb.Database().OpenTrie(header.Root) if err != nil { return nil, err } @@ -439,30 +432,31 @@ func (api *BlockChainAPI) GetProof(ctx context.Context, address common.Address, }, statedb.Error() } -// decodeHash parses a hex-encoded 32-byte hash. The input may optionally -// be prefixed by 0x and can have a byte length up to 32. -func decodeHash(s string) (h common.Hash, inputLength int, err error) { +// decodeStorageKey parses a hex-encoded 32-byte hash. +// For legacy compatibility reasons, we parse these keys leniently, +// with the 0x prefix being optional. +func decodeStorageKey(s string) (h common.Hash, inputLength int, err error) { if strings.HasPrefix(s, "0x") || strings.HasPrefix(s, "0X") { s = s[2:] } if (len(s) & 1) > 0 { s = "0" + s } + if len(s) > 64 { + return common.Hash{}, len(s) / 2, errors.New("storage key too long (want at most 32 bytes)") + } b, err := hex.DecodeString(s) if err != nil { - return common.Hash{}, 0, errors.New("hex string invalid") - } - if len(b) > 32 { - return common.Hash{}, len(b), errors.New("hex string too long, want at most 32 bytes") + return common.Hash{}, 0, errors.New("invalid hex in storage key") } return common.BytesToHash(b), len(b), nil } // GetHeaderByNumber returns the requested canonical block header. -// - When blockNr is -1 the chain pending header is returned. -// - When blockNr is -2 the chain latest header is returned. -// - When blockNr is -3 the chain finalized header is returned. -// - When blockNr is -4 the chain safe header is returned. +// - When number is -1 the chain pending header is returned. +// - When number is -2 the chain latest header is returned. +// - When number is -3 the chain finalized header is returned. +// - When number is -4 the chain safe header is returned. func (api *BlockChainAPI) GetHeaderByNumber(ctx context.Context, number rpc.BlockNumber) (map[string]interface{}, error) { header, err := api.b.HeaderByNumber(ctx, number) if header != nil && err == nil { @@ -488,10 +482,10 @@ func (api *BlockChainAPI) GetHeaderByHash(ctx context.Context, hash common.Hash) } // GetBlockByNumber returns the requested canonical block. -// - When blockNr is -1 the chain pending block is returned. -// - When blockNr is -2 the chain latest block is returned. -// - When blockNr is -3 the chain finalized block is returned. -// - When blockNr is -4 the chain safe block is returned. +// - When number is -1 the chain pending block is returned. +// - When number is -2 the chain latest block is returned. +// - When number is -3 the chain finalized block is returned. +// - When number is -4 the chain safe block is returned. // - When fullTx is true all transactions in the block are returned, otherwise // only the transaction hash is returned. func (api *BlockChainAPI) GetBlockByNumber(ctx context.Context, number rpc.BlockNumber, fullTx bool) (map[string]interface{}, error) { @@ -587,9 +581,9 @@ func (api *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Addre if state == nil || err != nil { return nil, err } - key, _, err := decodeHash(hexKey) + key, _, err := decodeStorageKey(hexKey) if err != nil { - return nil, fmt.Errorf("unable to decode storage key: %s", err) + return nil, &invalidParamsError{fmt.Sprintf("%v: %q", err, hexKey)} } res := state.GetState(address, key) return res[:], state.Error() @@ -597,27 +591,37 @@ func (api *BlockChainAPI) GetStorageAt(ctx context.Context, address common.Addre // GetBlockReceipts returns the block receipts for the given block hash or number or tag. func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rpc.BlockNumberOrHash) ([]map[string]interface{}, error) { - block, err := api.b.BlockByNumberOrHash(ctx, blockNrOrHash) - if block == nil || err != nil { - return nil, err - } - receipts, err := api.b.GetReceipts(ctx, block.Hash()) - if err != nil { - return nil, err + var ( + err error + block *types.Block + receipts types.Receipts + ) + if blockNr, ok := blockNrOrHash.Number(); ok && blockNr == rpc.PendingBlockNumber { + block, receipts, _ = api.b.Pending() + if block == nil { + return nil, errors.New("pending receipts is not available") + } + } else { + block, err = api.b.BlockByNumberOrHash(ctx, blockNrOrHash) + if block == nil || err != nil { + return nil, err + } + receipts, err = api.b.GetReceipts(ctx, block.Hash()) + if err != nil { + return nil, err + } } txs := block.Transactions() if len(txs) != len(receipts) { return nil, fmt.Errorf("receipts length mismatch: %d vs %d", len(txs), len(receipts)) } - // Derive the sender. signer := types.MakeSigner(api.b.ChainConfig(), block.Number(), block.Time()) result := make([]map[string]interface{}, len(receipts)) for i, receipt := range receipts { - result[i] = marshalReceipt(receipt, block.Hash(), block.NumberU64(), signer, txs[i], i) + result[i] = MarshalReceipt(receipt, block.Hash(), block.NumberU64(), signer, txs[i], i) } - return result, nil } @@ -625,6 +629,8 @@ func (api *BlockChainAPI) GetBlockReceipts(ctx context.Context, blockNrOrHash rp type ChainContextBackend interface { Engine() consensus.Engine HeaderByNumber(context.Context, rpc.BlockNumber) (*types.Header, error) + HeaderByHash(context.Context, common.Hash) (*types.Header, error) + CurrentHeader() *types.Header ChainConfig() *params.ChainConfig } @@ -658,6 +664,20 @@ func (context *ChainContext) Config() *params.ChainConfig { return context.b.ChainConfig() } +func (context *ChainContext) CurrentHeader() *types.Header { + return context.b.CurrentHeader() +} + +func (context *ChainContext) GetHeaderByNumber(number uint64) *types.Header { + header, _ := context.b.HeaderByNumber(context.ctx, rpc.BlockNumber(number)) + return header +} + +func (context *ChainContext) GetHeaderByHash(hash common.Hash) *types.Header { + header, _ := context.b.HeaderByHash(context.ctx, hash) + return header +} + func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, overrides *override.StateOverride, blockOverrides *override.BlockOverrides, timeout time.Duration, globalGasCap uint64) (*core.ExecutionResult, error) { blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) if blockOverrides != nil { @@ -688,15 +708,15 @@ func doCall(ctx context.Context, b Backend, args TransactionArgs, state *state.S } else { gp.AddGas(globalGasCap) } - return applyMessage(ctx, b, args, state, header, timeout, gp, &blockCtx, &vm.Config{NoBaseFee: true}, precompiles, true) + return applyMessage(ctx, b, args, state, header, timeout, gp, &blockCtx, &vm.Config{NoBaseFee: true}, precompiles) } -func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, timeout time.Duration, gp *core.GasPool, blockContext *vm.BlockContext, vmConfig *vm.Config, precompiles vm.PrecompiledContracts, skipChecks bool) (*core.ExecutionResult, error) { +func applyMessage(ctx context.Context, b Backend, args TransactionArgs, state *state.StateDB, header *types.Header, timeout time.Duration, gp *core.GasPool, blockContext *vm.BlockContext, vmConfig *vm.Config, precompiles vm.PrecompiledContracts) (*core.ExecutionResult, error) { // Get a new instance of the EVM. if err := args.CallDefaults(gp.Gas(), blockContext.BaseFee, b.ChainConfig().ChainID); err != nil { return nil, err } - msg := args.ToMessage(header.BaseFee, skipChecks, skipChecks) + msg := args.ToMessage(header.BaseFee, true) // Lower the basefee to 0 to avoid breaking EVM // invariants (basefee < feecap). if msg.GasPrice.Sign() == 0 { @@ -819,7 +839,15 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr if state == nil || err != nil { return 0, err } - if err := overrides.Apply(state, nil); err != nil { + blockCtx := core.NewEVMBlockContext(header, NewChainContext(ctx, b), nil) + if blockOverrides != nil { + if err := blockOverrides.Apply(&blockCtx); err != nil { + return 0, err + } + } + rules := b.ChainConfig().Rules(blockCtx.BlockNumber, blockCtx.Random != nil, blockCtx.Time) + precompiles := vm.ActivePrecompiledContracts(rules) + if err := overrides.Apply(state, precompiles); err != nil { return 0, err } // Construct the gas estimator option from the user input @@ -839,7 +867,7 @@ func DoEstimateGas(ctx context.Context, b Backend, args TransactionArgs, blockNr if err := args.CallDefaults(gasCap, header.BaseFee, b.ChainConfig().ChainID); err != nil { return 0, err } - call := args.ToMessage(header.BaseFee, true, true) + call := args.ToMessage(header.BaseFee, true) // Run the gas estimation and wrap any revertals into a custom return estimate, revert, err := gasestimator.Estimate(ctx, call, opts, gasCap) @@ -1135,6 +1163,71 @@ func (api *BlockChainAPI) CreateAccessList(ctx context.Context, args Transaction return result, nil } +type config struct { + ActivationTime uint64 `json:"activationTime"` + BlobSchedule *params.BlobConfig `json:"blobSchedule"` + ChainId *hexutil.Big `json:"chainId"` + ForkId hexutil.Bytes `json:"forkId"` + Precompiles map[string]common.Address `json:"precompiles"` + SystemContracts map[string]common.Address `json:"systemContracts"` +} + +type configResponse struct { + Current *config `json:"current"` + Next *config `json:"next"` + Last *config `json:"last"` +} + +// Config implements the EIP-7910 eth_config method. +func (api *BlockChainAPI) Config(ctx context.Context) (*configResponse, error) { + genesis, err := api.b.HeaderByNumber(ctx, 0) + if err != nil { + return nil, fmt.Errorf("unable to load genesis: %w", err) + } + assemble := func(c *params.ChainConfig, ts *uint64) *config { + if ts == nil { + return nil + } + t := *ts + + var ( + rules = c.Rules(c.LondonBlock, true, t) + precompiles = make(map[string]common.Address) + ) + for addr, c := range vm.ActivePrecompiledContracts(rules) { + precompiles[c.Name()] = addr + } + // Activation time is required. If a fork is activated at genesis the value 0 is used + activationTime := t + if genesis.Time >= t { + activationTime = 0 + } + forkid := forkid.NewID(c, types.NewBlockWithHeader(genesis), ^uint64(0), t).Hash + return &config{ + ActivationTime: activationTime, + BlobSchedule: c.BlobConfig(c.LatestFork(t)), + ChainId: (*hexutil.Big)(c.ChainID), + ForkId: forkid[:], + Precompiles: precompiles, + SystemContracts: c.ActiveSystemContracts(t), + } + } + var ( + c = api.b.ChainConfig() + t = api.b.CurrentHeader().Time + ) + resp := configResponse{ + Next: assemble(c, c.Timestamp(c.LatestFork(t)+1)), + Current: assemble(c, c.Timestamp(c.LatestFork(t))), + Last: assemble(c, c.Timestamp(c.LatestFork(^uint64(0)))), + } + // Nil out last if no future-fork is configured. + if resp.Next == nil { + resp.Last = nil + } + return &resp, nil +} + // AccessList creates an access list for the given transaction. // If the accesslist creation fails an error is returned. // If the transaction itself fails, an vmErr is returned. @@ -1217,7 +1310,7 @@ func AccessList(ctx context.Context, b Backend, blockNrOrHash rpc.BlockNumberOrH statedb := db.Copy() // Set the accesslist to the last al args.AccessList = &accessList - msg := args.ToMessage(header.BaseFee, true, true) + msg := args.ToMessage(header.BaseFee, true) // Apply the transaction with the access list tracer tracer := logger.NewAccessListTracer(accessList, addressesToExclude) @@ -1388,11 +1481,11 @@ func (api *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash commo return nil, err } // Derive the sender. - return marshalReceipt(receipt, blockHash, blockNumber, api.signer, tx, int(index)), nil + return MarshalReceipt(receipt, blockHash, blockNumber, api.signer, tx, int(index)), nil } -// marshalReceipt marshals a transaction receipt into a JSON object. -func marshalReceipt(receipt *types.Receipt, blockHash common.Hash, blockNumber uint64, signer types.Signer, tx *types.Transaction, txIndex int) map[string]interface{} { +// MarshalReceipt marshals a transaction receipt into a JSON object. +func MarshalReceipt(receipt *types.Receipt, blockHash common.Hash, blockNumber uint64, signer types.Signer, tx *types.Transaction, txIndex int) map[string]interface{} { from, _ := types.Sender(signer, tx) fields := map[string]interface{}{ @@ -1479,6 +1572,8 @@ func SubmitTransaction(ctx context.Context, b Backend, tx *types.Transaction) (c // SendTransaction creates a transaction for the given argument, sign it and submit it to the // transaction pool. +// +// This API is not capable for submitting blob transaction with sidecar. func (api *TransactionAPI) SendTransaction(ctx context.Context, args TransactionArgs) (common.Hash, error) { // Look up the wallet containing the requested signer account := accounts.Account{Address: args.from()} @@ -1499,11 +1594,11 @@ func (api *TransactionAPI) SendTransaction(ctx context.Context, args Transaction } // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, api.b, false); err != nil { + if err := args.setDefaults(ctx, api.b, sidecarConfig{}); err != nil { return common.Hash{}, err } // Assemble the transaction and sign with the wallet - tx := args.ToTransaction(types.LegacyTxType) + tx := args.ToTransaction(types.DynamicFeeTxType) signed, err := wallet.SignTx(account, tx, api.b.ChainConfig().ChainID) if err != nil { @@ -1516,14 +1611,16 @@ func (api *TransactionAPI) SendTransaction(ctx context.Context, args Transaction // on a given unsigned transaction, and returns it to the caller for further // processing (signing + broadcast). func (api *TransactionAPI) FillTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { - args.blobSidecarAllowed = true - // Set some sanity defaults and terminate on failure - if err := args.setDefaults(ctx, api.b, false); err != nil { + config := sidecarConfig{ + blobSidecarAllowed: true, + blobSidecarVersion: api.currentBlobSidecarVersion(), + } + if err := args.setDefaults(ctx, api.b, config); err != nil { return nil, err } // Assemble the transaction and obtain rlp - tx := args.ToTransaction(types.LegacyTxType) + tx := args.ToTransaction(types.DynamicFeeTxType) data, err := tx.MarshalBinary() if err != nil { return nil, err @@ -1531,6 +1628,14 @@ func (api *TransactionAPI) FillTransaction(ctx context.Context, args Transaction return &SignTransactionResult{data, tx}, nil } +func (api *TransactionAPI) currentBlobSidecarVersion() byte { + h := api.b.CurrentHeader() + if api.b.ChainConfig().IsOsaka(h.Number, h.Time) { + return types.BlobSidecarVersion1 + } + return types.BlobSidecarVersion0 +} + // SendRawTransaction will add the signed transaction to the transaction pool. // The sender is responsible for signing the transaction and using the correct nonce. func (api *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) { @@ -1538,9 +1643,119 @@ func (api *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil if err := tx.UnmarshalBinary(input); err != nil { return common.Hash{}, err } + + // Convert legacy blob transaction proofs. + // TODO: remove in go-ethereum v1.17.x + if sc := tx.BlobTxSidecar(); sc != nil { + exp := api.currentBlobSidecarVersion() + if sc.Version == types.BlobSidecarVersion0 && exp == types.BlobSidecarVersion1 { + if err := sc.ToV1(); err != nil { + return common.Hash{}, fmt.Errorf("blob sidecar conversion failed: %v", err) + } + tx = tx.WithBlobTxSidecar(sc) + } + } + return SubmitTransaction(ctx, api.b, tx) } +// SendRawTransactionSync will add the signed transaction to the transaction pool +// and wait until the transaction has been included in a block and return the receipt, or the timeout. +func (api *TransactionAPI) SendRawTransactionSync(ctx context.Context, input hexutil.Bytes, timeoutMs *hexutil.Uint64) (map[string]interface{}, error) { + tx := new(types.Transaction) + if err := tx.UnmarshalBinary(input); err != nil { + return nil, err + } + + // Convert legacy blob transaction proofs. + // TODO: remove in go-ethereum v1.17.x + if sc := tx.BlobTxSidecar(); sc != nil { + exp := api.currentBlobSidecarVersion() + if sc.Version == types.BlobSidecarVersion0 && exp == types.BlobSidecarVersion1 { + if err := sc.ToV1(); err != nil { + return nil, fmt.Errorf("blob sidecar conversion failed: %v", err) + } + tx = tx.WithBlobTxSidecar(sc) + } + } + + ch := make(chan core.ChainEvent, 128) + sub := api.b.SubscribeChainEvent(ch) + defer sub.Unsubscribe() + + hash, err := SubmitTransaction(ctx, api.b, tx) + if err != nil { + return nil, err + } + + var ( + maxTimeout = api.b.RPCTxSyncMaxTimeout() + defaultTimeout = api.b.RPCTxSyncDefaultTimeout() + timeout = defaultTimeout + ) + if timeoutMs != nil && *timeoutMs > 0 { + req := time.Duration(*timeoutMs) * time.Millisecond + if req > maxTimeout { + timeout = maxTimeout + } else { + timeout = req + } + } + receiptCtx, cancel := context.WithTimeout(ctx, timeout) + defer cancel() + + // Fast path. + if r, err := api.GetTransactionReceipt(receiptCtx, hash); err == nil && r != nil { + return r, nil + } + + // Monitor the receipts + for { + select { + case <-receiptCtx.Done(): + // If server-side wait window elapsed, return the structured timeout. + if errors.Is(receiptCtx.Err(), context.DeadlineExceeded) { + return nil, &txSyncTimeoutError{ + msg: fmt.Sprintf("The transaction was added to the transaction pool but wasn't processed in %v", timeout), + hash: hash, + } + } + return nil, receiptCtx.Err() + + case err, ok := <-sub.Err(): + if !ok { + return nil, errSubClosed + } + return nil, err + + case ev, ok := <-ch: + if !ok { + return nil, errSubClosed + } + rs, txs := ev.Receipts, ev.Transactions + if len(rs) == 0 || len(rs) != len(txs) { + continue + } + for i := range rs { + if rs[i].TxHash == hash { + if rs[i].BlockNumber != nil && rs[i].BlockHash != (common.Hash{}) { + signer := types.LatestSigner(api.b.ChainConfig()) + return MarshalReceipt( + rs[i], + rs[i].BlockHash, + rs[i].BlockNumber.Uint64(), + signer, + txs[i], + int(rs[i].TransactionIndex), + ), nil + } + return api.GetTransactionReceipt(receiptCtx, hash) + } + } + } + } +} + // Sign calculates an ECDSA signature for: // keccak256("\x19Ethereum Signed Message:\n" + len(message) + message). // @@ -1576,8 +1791,6 @@ type SignTransactionResult struct { // The node needs to have the private key of the account corresponding with // the given from address and it needs to be unlocked. func (api *TransactionAPI) SignTransaction(ctx context.Context, args TransactionArgs) (*SignTransactionResult, error) { - args.blobSidecarAllowed = true - if args.Gas == nil { return nil, errors.New("gas not specified") } @@ -1587,11 +1800,23 @@ func (api *TransactionAPI) SignTransaction(ctx context.Context, args Transaction if args.Nonce == nil { return nil, errors.New("nonce not specified") } - if err := args.setDefaults(ctx, api.b, false); err != nil { + sidecarVersion := types.BlobSidecarVersion0 + if len(args.Blobs) > 0 { + h := api.b.CurrentHeader() + if api.b.ChainConfig().IsOsaka(h.Number, h.Time) { + sidecarVersion = types.BlobSidecarVersion1 + } + } + + config := sidecarConfig{ + blobSidecarAllowed: true, + blobSidecarVersion: sidecarVersion, + } + if err := args.setDefaults(ctx, api.b, config); err != nil { return nil, err } // Before actually sign the transaction, ensure the transaction fee is reasonable. - tx := args.ToTransaction(types.LegacyTxType) + tx := args.ToTransaction(types.DynamicFeeTxType) if err := checkTxFee(tx.GasPrice(), tx.Gas(), api.b.RPCTxFeeCap()); err != nil { return nil, err } @@ -1603,7 +1828,7 @@ func (api *TransactionAPI) SignTransaction(ctx context.Context, args Transaction // no longer retains the blobs, only the blob hashes. In this step, we need // to put back the blob(s). if args.IsEIP4844() { - signed = signed.WithBlobTxSidecar(types.NewBlobTxSidecar(types.BlobSidecarVersion0, args.Blobs, args.Commitments, args.Proofs)) + signed = signed.WithBlobTxSidecar(types.NewBlobTxSidecar(sidecarVersion, args.Blobs, args.Commitments, args.Proofs)) } data, err := signed.MarshalBinary() if err != nil { @@ -1638,14 +1863,16 @@ func (api *TransactionAPI) PendingTransactions() ([]*RPCTransaction, error) { // Resend accepts an existing transaction and a new gas price and limit. It will remove // the given transaction from the pool and reinsert it with the new gas price and limit. +// +// This API is not capable for submitting blob transaction with sidecar. func (api *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, gasPrice *hexutil.Big, gasLimit *hexutil.Uint64) (common.Hash, error) { if sendArgs.Nonce == nil { return common.Hash{}, errors.New("missing transaction nonce in transaction spec") } - if err := sendArgs.setDefaults(ctx, api.b, false); err != nil { + if err := sendArgs.setDefaults(ctx, api.b, sidecarConfig{}); err != nil { return common.Hash{}, err } - matchTx := sendArgs.ToTransaction(types.LegacyTxType) + matchTx := sendArgs.ToTransaction(types.DynamicFeeTxType) // Before replacing the old transaction, ensure the _new_ transaction fee is reasonable. price := matchTx.GasPrice() @@ -1675,7 +1902,7 @@ func (api *TransactionAPI) Resend(ctx context.Context, sendArgs TransactionArgs, if gasLimit != nil && *gasLimit != 0 { sendArgs.Gas = gasLimit } - signedTx, err := api.sign(sendArgs.from(), sendArgs.ToTransaction(types.LegacyTxType)) + signedTx, err := api.sign(sendArgs.from(), sendArgs.ToTransaction(types.DynamicFeeTxType)) if err != nil { return common.Hash{}, err } diff --git a/internal/ethapi/api_test.go b/internal/ethapi/api_test.go index de6d1d5e06..aaa002b5ec 100644 --- a/internal/ethapi/api_test.go +++ b/internal/ethapi/api_test.go @@ -34,11 +34,9 @@ import ( "testing" "time" - "github.com/ethereum/go-ethereum/accounts/abi" - "github.com/ethereum/go-ethereum/internal/ethapi/override" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/accounts/abi" "github.com/ethereum/go-ethereum/accounts/keystore" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -56,6 +54,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/internal/blocktest" + "github.com/ethereum/go-ethereum/internal/ethapi/override" "github.com/ethereum/go-ethereum/params" "github.com/ethereum/go-ethereum/rpc" "github.com/holiman/uint256" @@ -434,11 +433,26 @@ func newTestAccountManager(t *testing.T) (*accounts.Manager, accounts.Account) { } type testBackend struct { - db ethdb.Database - chain *core.BlockChain - pending *types.Block - accman *accounts.Manager - acc accounts.Account + db ethdb.Database + chain *core.BlockChain + accman *accounts.Manager + acc accounts.Account + + pending *types.Block + pendingReceipts types.Receipts + + chainFeed *event.Feed + autoMine bool + + sentTx *types.Transaction + sentTxHash common.Hash + + syncDefaultTimeout time.Duration + syncMaxTimeout time.Duration +} + +func fakeBlockHash(txh common.Hash) common.Hash { + return crypto.Keccak256Hash([]byte("testblock"), txh.Bytes()) } func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.Engine, generator func(i int, b *core.BlockGen)) *testBackend { @@ -449,24 +463,27 @@ func newTestBackend(t *testing.T, n int, gspec *core.Genesis, engine consensus.E gspec.Alloc[acc.Address] = types.Account{Balance: big.NewInt(params.Ether)} // Generate blocks for testing - db, blocks, _ := core.GenerateChainWithGenesis(gspec, engine, n, generator) + db, blocks, receipts := core.GenerateChainWithGenesis(gspec, engine, n+1, generator) chain, err := core.NewBlockChain(db, gspec, engine, options) if err != nil { t.Fatalf("failed to create tester chain: %v", err) } - if n, err := chain.InsertChain(blocks); err != nil { + if n, err := chain.InsertChain(blocks[:n]); err != nil { t.Fatalf("block %d: failed to insert into chain: %v", n, err) } - - backend := &testBackend{db: db, chain: chain, accman: accman, acc: acc} + backend := &testBackend{ + db: db, + chain: chain, + accman: accman, + acc: acc, + pending: blocks[n], + pendingReceipts: receipts[n], + chainFeed: new(event.Feed), + } return backend } -func (b *testBackend) setPendingBlock(block *types.Block) { - b.pending = block -} - func (b testBackend) SyncProgress(ctx context.Context) ethereum.SyncProgress { return ethereum.SyncProgress{} } @@ -558,7 +575,13 @@ func (b testBackend) StateAndHeaderByNumberOrHash(ctx context.Context, blockNrOr } panic("only implemented for number") } -func (b testBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { panic("implement me") } +func (b testBackend) Pending() (*types.Block, types.Receipts, *state.StateDB) { + block := b.pending + if block == nil { + return nil, nil, nil + } + return block, b.pendingReceipts, nil +} func (b testBackend) GetReceipts(ctx context.Context, hash common.Hash) (types.Receipts, error) { header, err := b.HeaderByHash(ctx, hash) if header == nil || err != nil { @@ -578,19 +601,64 @@ func (b testBackend) GetEVM(ctx context.Context, state *state.StateDB, header *t return vm.NewEVM(context, state, b.chain.Config(), *vmConfig) } func (b testBackend) SubscribeChainEvent(ch chan<- core.ChainEvent) event.Subscription { - panic("implement me") + return b.chainFeed.Subscribe(ch) } func (b testBackend) SubscribeChainHeadEvent(ch chan<- core.ChainHeadEvent) event.Subscription { panic("implement me") } -func (b testBackend) SendTx(ctx context.Context, signedTx *types.Transaction) error { - panic("implement me") +func (b *testBackend) SendTx(ctx context.Context, tx *types.Transaction) error { + b.sentTx = tx + b.sentTxHash = tx.Hash() + + if b.autoMine { + // Synthesize a "mined" receipt at head+1 + num := b.chain.CurrentHeader().Number.Uint64() + 1 + receipt := &types.Receipt{ + TxHash: tx.Hash(), + Status: types.ReceiptStatusSuccessful, + BlockHash: fakeBlockHash(tx.Hash()), + BlockNumber: new(big.Int).SetUint64(num), + TransactionIndex: 0, + CumulativeGasUsed: 21000, + GasUsed: 21000, + } + // Broadcast a ChainEvent that includes the receipts and txs + b.chainFeed.Send(core.ChainEvent{ + Header: &types.Header{ + Number: new(big.Int).SetUint64(num), + }, + Receipts: types.Receipts{receipt}, + Transactions: types.Transactions{tx}, + }) + } + return nil } -func (b testBackend) GetCanonicalTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) { +func (b *testBackend) GetCanonicalTransaction(txHash common.Hash) (bool, *types.Transaction, common.Hash, uint64, uint64) { + // Treat the auto-mined tx as canonically placed at head+1. + if b.autoMine && txHash == b.sentTxHash { + num := b.chain.CurrentHeader().Number.Uint64() + 1 + return true, b.sentTx, fakeBlockHash(txHash), num, 0 + } tx, blockHash, blockNumber, index := rawdb.ReadCanonicalTransaction(b.db, txHash) return tx != nil, tx, blockHash, blockNumber, index } -func (b testBackend) GetCanonicalReceipt(tx *types.Transaction, blockHash common.Hash, blockNumber, blockIndex uint64) (*types.Receipt, error) { +func (b *testBackend) GetCanonicalReceipt(tx *types.Transaction, blockHash common.Hash, blockNumber, blockIndex uint64) (*types.Receipt, error) { + if b.autoMine && tx != nil && tx.Hash() == b.sentTxHash && + blockHash == fakeBlockHash(tx.Hash()) && + blockIndex == 0 && + blockNumber == b.chain.CurrentHeader().Number.Uint64()+1 { + return &types.Receipt{ + Type: tx.Type(), + Status: types.ReceiptStatusSuccessful, + CumulativeGasUsed: 21000, + GasUsed: 21000, + EffectiveGasPrice: big.NewInt(1), + BlockHash: blockHash, + BlockNumber: new(big.Int).SetUint64(blockNumber), + TransactionIndex: 0, + TxHash: tx.Hash(), + }, nil + } return b.chain.GetCanonicalReceipt(tx, blockHash, blockNumber, blockIndex) } func (b testBackend) TxIndexDone() bool { @@ -1318,10 +1386,11 @@ func TestSimulateV1(t *testing.T) { validation = true ) type log struct { - Address common.Address `json:"address"` - Topics []common.Hash `json:"topics"` - Data hexutil.Bytes `json:"data"` - BlockNumber hexutil.Uint64 `json:"blockNumber"` + Address common.Address `json:"address"` + Topics []common.Hash `json:"topics"` + Data hexutil.Bytes `json:"data"` + BlockNumber hexutil.Uint64 `json:"blockNumber"` + BlockTimestamp hexutil.Uint64 `json:"blockTimestamp"` // Skip txHash //TxHash common.Hash `json:"transactionHash" gencodec:"required"` TxIndex hexutil.Uint `json:"transactionIndex"` @@ -1668,10 +1737,11 @@ func TestSimulateV1(t *testing.T) { Calls: []callRes{{ ReturnValue: "0x", Logs: []log{{ - Address: randomAccounts[2].addr, - Topics: []common.Hash{common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")}, - BlockNumber: hexutil.Uint64(11), - Data: hexutil.Bytes{}, + Address: randomAccounts[2].addr, + Topics: []common.Hash{common.HexToHash("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")}, + BlockNumber: hexutil.Uint64(11), + BlockTimestamp: hexutil.Uint64(0x70), + Data: hexutil.Bytes{}, }}, GasUsed: "0x5508", Status: "0x1", @@ -1844,8 +1914,9 @@ func TestSimulateV1(t *testing.T) { addressToHash(accounts[0].addr), addressToHash(randomAccounts[0].addr), }, - Data: hexutil.Bytes(common.BigToHash(big.NewInt(50)).Bytes()), - BlockNumber: hexutil.Uint64(11), + Data: hexutil.Bytes(common.BigToHash(big.NewInt(50)).Bytes()), + BlockNumber: hexutil.Uint64(11), + BlockTimestamp: hexutil.Uint64(0x70), }, { Address: transferAddress, Topics: []common.Hash{ @@ -1853,9 +1924,10 @@ func TestSimulateV1(t *testing.T) { addressToHash(randomAccounts[0].addr), addressToHash(fixedAccount.addr), }, - Data: hexutil.Bytes(common.BigToHash(big.NewInt(100)).Bytes()), - BlockNumber: hexutil.Uint64(11), - Index: hexutil.Uint(1), + Data: hexutil.Bytes(common.BigToHash(big.NewInt(100)).Bytes()), + BlockNumber: hexutil.Uint64(11), + BlockTimestamp: hexutil.Uint64(0x70), + Index: hexutil.Uint(1), }}, Status: "0x1", }}, @@ -2661,19 +2733,53 @@ func TestSendBlobTransaction(t *testing.T) { func TestFillBlobTransaction(t *testing.T) { t.Parallel() + + testFillBlobTransaction(t, false) + testFillBlobTransaction(t, true) +} + +func testFillBlobTransaction(t *testing.T, osaka bool) { // Initialize test accounts + config := *params.MergedTestChainConfig + if !osaka { + config.OsakaTime = nil + } var ( key, _ = crypto.HexToECDSA("8a1f9a8f95be41cd7ccb6168179afb4504aefe388d1e14474d32c45c72ce7b7a") to = crypto.PubkeyToAddress(key.PublicKey) genesis = &core.Genesis{ - Config: params.MergedTestChainConfig, + Config: &config, Alloc: types.GenesisAlloc{}, } - emptyBlob = new(kzg4844.Blob) - emptyBlobs = []kzg4844.Blob{*emptyBlob} - emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob) - emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit) - emptyBlobHash common.Hash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit) + emptyBlob = new(kzg4844.Blob) + emptyBlobs = []kzg4844.Blob{*emptyBlob} + emptyBlobCommit, _ = kzg4844.BlobToCommitment(emptyBlob) + emptyBlobProof, _ = kzg4844.ComputeBlobProof(emptyBlob, emptyBlobCommit) + emptyBlobCellProofs, _ = kzg4844.ComputeCellProofs(emptyBlob) + emptyBlobHash common.Hash = kzg4844.CalcBlobHashV1(sha256.New(), &emptyBlobCommit) + + fillEmptyKZGProofs = func(blobs int) []kzg4844.Proof { + if osaka { + return make([]kzg4844.Proof, blobs*kzg4844.CellProofsPerBlob) + } + return make([]kzg4844.Proof, blobs) + } + expectSidecar = func() *types.BlobTxSidecar { + if osaka { + return types.NewBlobTxSidecar( + types.BlobSidecarVersion1, + emptyBlobs, + []kzg4844.Commitment{emptyBlobCommit}, + emptyBlobCellProofs, + ) + } + return types.NewBlobTxSidecar( + types.BlobSidecarVersion0, + emptyBlobs, + []kzg4844.Commitment{emptyBlobCommit}, + []kzg4844.Proof{emptyBlobProof}, + ) + } ) b := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) { b.SetPoS() @@ -2733,7 +2839,7 @@ func TestFillBlobTransaction(t *testing.T) { Commitments: []kzg4844.Commitment{{}, {}}, Proofs: []kzg4844.Proof{{}}, }, - err: `number of blobs and proofs mismatch (have=1, want=2)`, + err: fmt.Sprintf(`number of blobs and proofs mismatch (have=1, want=%d)`, len(fillEmptyKZGProofs(2))), }, { name: "TestInvalidProofVerification", @@ -2743,7 +2849,7 @@ func TestFillBlobTransaction(t *testing.T) { Value: (*hexutil.Big)(big.NewInt(1)), Blobs: []kzg4844.Blob{{}, {}}, Commitments: []kzg4844.Commitment{{}, {}}, - Proofs: []kzg4844.Proof{{}, {}}, + Proofs: fillEmptyKZGProofs(2), }, err: `failed to verify blob proof: short buffer`, }, @@ -2759,7 +2865,7 @@ func TestFillBlobTransaction(t *testing.T) { }, want: &result{ Hashes: []common.Hash{emptyBlobHash}, - Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, emptyBlobs, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof}), + Sidecar: expectSidecar(), }, }, { @@ -2775,7 +2881,7 @@ func TestFillBlobTransaction(t *testing.T) { }, want: &result{ Hashes: []common.Hash{emptyBlobHash}, - Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, emptyBlobs, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof}), + Sidecar: expectSidecar(), }, }, { @@ -2801,7 +2907,7 @@ func TestFillBlobTransaction(t *testing.T) { }, want: &result{ Hashes: []common.Hash{emptyBlobHash}, - Sidecar: types.NewBlobTxSidecar(types.BlobSidecarVersion0, emptyBlobs, []kzg4844.Commitment{emptyBlobCommit}, []kzg4844.Proof{emptyBlobProof}), + Sidecar: expectSidecar(), }, }, } @@ -3141,21 +3247,6 @@ func TestRPCGetBlockOrHeader(t *testing.T) { } genBlocks = 10 signer = types.HomesteadSigner{} - tx = types.NewTx(&types.LegacyTx{ - Nonce: 11, - GasPrice: big.NewInt(11111), - Gas: 1111, - To: &acc2Addr, - Value: big.NewInt(111), - Data: []byte{0x11, 0x11, 0x11}, - }) - withdrawal = &types.Withdrawal{ - Index: 0, - Validator: 1, - Address: common.Address{0x12, 0x34}, - Amount: 10, - } - pending = types.NewBlock(&types.Header{Number: big.NewInt(11), Time: 42}, &types.Body{Transactions: types.Transactions{tx}, Withdrawals: types.Withdrawals{withdrawal}}, nil, blocktest.NewHasher()) ) backend := newTestBackend(t, genBlocks, genesis, ethash.NewFaker(), func(i int, b *core.BlockGen) { // Transfer from account[0] to account[1] @@ -3164,7 +3255,6 @@ func TestRPCGetBlockOrHeader(t *testing.T) { tx, _ := types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &acc2Addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), signer, acc1Key) b.AddTx(tx) }) - backend.setPendingBlock(pending) api := NewBlockChainAPI(backend) blockHashes := make([]common.Hash, genBlocks+1) ctx := context.Background() @@ -3175,7 +3265,7 @@ func TestRPCGetBlockOrHeader(t *testing.T) { } blockHashes[i] = header.Hash() } - pendingHash := pending.Hash() + pendingHash := backend.pending.Hash() var testSuite = []struct { blockNumber rpc.BlockNumber @@ -3406,7 +3496,7 @@ func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Ha }, } signer = types.LatestSignerForChainID(params.TestChainConfig.ChainID) - txHashes = make([]common.Hash, genBlocks) + txHashes = make([]common.Hash, 0, genBlocks) ) backend := newTestBackend(t, genBlocks, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) { @@ -3416,9 +3506,6 @@ func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Ha ) b.SetPoS() switch i { - case 0: - // transfer 1000wei - tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &acc2Addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), types.HomesteadSigner{}, acc1Key) case 1: // create contract tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: nil, Gas: 53100, GasPrice: b.BaseFee(), Data: common.FromHex("0x60806040")}), signer, acc1Key) @@ -3455,13 +3542,16 @@ func setupReceiptBackend(t *testing.T, genBlocks int) (*testBackend, []common.Ha BlobHashes: []common.Hash{{1}}, Value: new(uint256.Int), }), signer, acc1Key) + default: + // transfer 1000wei + tx, err = types.SignTx(types.NewTx(&types.LegacyTx{Nonce: uint64(i), To: &acc2Addr, Value: big.NewInt(1000), Gas: params.TxGas, GasPrice: b.BaseFee(), Data: nil}), types.HomesteadSigner{}, acc1Key) } if err != nil { t.Errorf("failed to sign tx: %v", err) } if tx != nil { b.AddTx(tx) - txHashes[i] = tx.Hash() + txHashes = append(txHashes, tx.Hash()) } }) return backend, txHashes @@ -3577,6 +3667,11 @@ func TestRPCGetBlockReceipts(t *testing.T) { test: rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber), file: "tag-latest", }, + // 3. pending tag + { + test: rpc.BlockNumberOrHashWithNumber(rpc.PendingBlockNumber), + file: "tag-pending", + }, // 4. block with legacy transfer tx(hash) { test: rpc.BlockNumberOrHashWithHash(blockHashes[1], false), @@ -3714,8 +3809,8 @@ func TestCreateAccessListWithStateOverrides(t *testing.T) { if err != nil { t.Fatalf("Failed to create access list: %v", err) } - if err != nil || result == nil { - t.Fatalf("Failed to create access list: %v", err) + if result == nil { + t.Fatalf("Failed to create access list: result is nil") } require.NotNil(t, result.Accesslist) @@ -3726,3 +3821,236 @@ func TestCreateAccessListWithStateOverrides(t *testing.T) { }} require.Equal(t, expected, result.Accesslist) } + +func TestEstimateGasWithMovePrecompile(t *testing.T) { + t.Parallel() + // Initialize test accounts + var ( + accounts = newAccounts(2) + genesis = &core.Genesis{ + Config: params.MergedTestChainConfig, + Alloc: types.GenesisAlloc{ + accounts[0].addr: {Balance: big.NewInt(params.Ether)}, + }, + } + ) + backend := newTestBackend(t, 1, genesis, beacon.New(ethash.NewFaker()), func(i int, b *core.BlockGen) { + b.SetPoS() + }) + api := NewBlockChainAPI(backend) + // Move SHA256 precompile (0x2) to a new address (0x100) + // and estimate gas for calling the moved precompile. + var ( + sha256Addr = common.BytesToAddress([]byte{0x2}) + newSha256Addr = common.BytesToAddress([]byte{0x10, 0}) + sha256Input = hexutil.Bytes([]byte("hello")) + args = TransactionArgs{ + From: &accounts[0].addr, + To: &newSha256Addr, + Data: &sha256Input, + } + overrides = &override.StateOverride{ + sha256Addr: override.OverrideAccount{ + MovePrecompileTo: &newSha256Addr, + }, + } + ) + gas, err := api.EstimateGas(context.Background(), args, nil, overrides, nil) + if err != nil { + t.Fatalf("EstimateGas failed: %v", err) + } + if gas != 21366 { + t.Fatalf("mismatched gas: %d, want 21366", gas) + } +} + +func TestEIP7910Config(t *testing.T) { + var ( + newUint64 = func(val uint64) *uint64 { return &val } + // Define a snapshot of the current Hoodi config (only Prague scheduled) so that future forks do not + // cause this test to fail. + config = ¶ms.ChainConfig{ + ChainID: big.NewInt(560048), + HomesteadBlock: big.NewInt(0), + DAOForkBlock: nil, + DAOForkSupport: true, + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: nil, + GrayGlacierBlock: nil, + TerminalTotalDifficulty: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + ShanghaiTime: newUint64(0), + CancunTime: newUint64(0), + PragueTime: newUint64(1742999832), + DepositContractAddress: common.HexToAddress("0x00000000219ab540356cBB839Cbe05303d7705Fa"), + Ethash: new(params.EthashConfig), + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + }, + } + ) + gspec := core.DefaultHoodiGenesisBlock() + gspec.Config = config + + var testSuite = []struct { + time uint64 + file string + }{ + { + time: 0, + file: "next-and-last", + }, + { + time: *gspec.Config.PragueTime, + file: "current", + }, + } + + for i, tt := range testSuite { + backend := configTimeBackend{nil, gspec, tt.time} + api := NewBlockChainAPI(backend) + result, err := api.Config(context.Background()) + if err != nil { + t.Errorf("test %d: want no error, have %v", i, err) + continue + } + testRPCResponseWithFile(t, i, result, "eth_config", tt.file) + } +} + +type configTimeBackend struct { + *testBackend + genesis *core.Genesis + time uint64 +} + +func (b configTimeBackend) ChainConfig() *params.ChainConfig { + return b.genesis.Config +} + +func (b configTimeBackend) HeaderByNumber(_ context.Context, n rpc.BlockNumber) (*types.Header, error) { + if n == 0 { + return b.genesis.ToBlock().Header(), nil + } + panic("not implemented") +} + +func (b configTimeBackend) CurrentHeader() *types.Header { + return &types.Header{Time: b.time} +} + +func (b *testBackend) RPCTxSyncDefaultTimeout() time.Duration { + if b.syncDefaultTimeout != 0 { + return b.syncDefaultTimeout + } + return 2 * time.Second +} +func (b *testBackend) RPCTxSyncMaxTimeout() time.Duration { + if b.syncMaxTimeout != 0 { + return b.syncMaxTimeout + } + return 5 * time.Minute +} +func (b *backendMock) RPCTxSyncDefaultTimeout() time.Duration { return 2 * time.Second } +func (b *backendMock) RPCTxSyncMaxTimeout() time.Duration { return 5 * time.Minute } + +func makeSignedRaw(t *testing.T, api *TransactionAPI, from, to common.Address, value *big.Int) (hexutil.Bytes, *types.Transaction) { + t.Helper() + + fillRes, err := api.FillTransaction(context.Background(), TransactionArgs{ + From: &from, + To: &to, + Value: (*hexutil.Big)(value), + }) + if err != nil { + t.Fatalf("FillTransaction failed: %v", err) + } + signRes, err := api.SignTransaction(context.Background(), argsFromTransaction(fillRes.Tx, from)) + if err != nil { + t.Fatalf("SignTransaction failed: %v", err) + } + return signRes.Raw, signRes.Tx +} + +// makeSelfSignedRaw is a convenience for a 0-ETH self-transfer. +func makeSelfSignedRaw(t *testing.T, api *TransactionAPI, addr common.Address) (hexutil.Bytes, *types.Transaction) { + return makeSignedRaw(t, api, addr, addr, big.NewInt(0)) +} + +func TestSendRawTransactionSync_Success(t *testing.T) { + t.Parallel() + genesis := &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{}, + } + b := newTestBackend(t, 0, genesis, ethash.NewFaker(), nil) + b.autoMine = true // immediately “mines” the tx in-memory + + api := NewTransactionAPI(b, new(AddrLocker)) + + raw, _ := makeSelfSignedRaw(t, api, b.acc.Address) + + receipt, err := api.SendRawTransactionSync(context.Background(), raw, nil) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if receipt == nil { + t.Fatalf("expected non-nil receipt") + } + if _, ok := receipt["blockNumber"]; !ok { + t.Fatalf("expected blockNumber in receipt, got %#v", receipt) + } +} + +func TestSendRawTransactionSync_Timeout(t *testing.T) { + t.Parallel() + + genesis := &core.Genesis{ + Config: params.TestChainConfig, + Alloc: types.GenesisAlloc{}, + } + b := newTestBackend(t, 0, genesis, ethash.NewFaker(), nil) + b.autoMine = false // don't mine, should time out + + api := NewTransactionAPI(b, new(AddrLocker)) + + raw, _ := makeSelfSignedRaw(t, api, b.acc.Address) + + timeout := hexutil.Uint64(200) // 200ms + receipt, err := api.SendRawTransactionSync(context.Background(), raw, &timeout) + + if receipt != nil { + t.Fatalf("expected nil receipt, got %#v", receipt) + } + if err == nil { + t.Fatalf("expected timeout error, got nil") + } + // assert error shape & data (hash) + var de interface { + ErrorCode() int + ErrorData() interface{} + } + if !errors.As(err, &de) { + t.Fatalf("expected data error with code/data, got %T %v", err, err) + } + if de.ErrorCode() != errCodeTxSyncTimeout { + t.Fatalf("expected code %d, got %d", errCodeTxSyncTimeout, de.ErrorCode()) + } + tx := new(types.Transaction) + if e := tx.UnmarshalBinary(raw); e != nil { + t.Fatal(e) + } + if got, want := de.ErrorData(), tx.Hash().Hex(); got != want { + t.Fatalf("expected ErrorData=%s, got %v", want, got) + } +} diff --git a/internal/ethapi/backend.go b/internal/ethapi/backend.go index f709a1fcdc..af3d592b82 100644 --- a/internal/ethapi/backend.go +++ b/internal/ethapi/backend.go @@ -53,6 +53,8 @@ type Backend interface { RPCEVMTimeout() time.Duration // global timeout for eth_call over rpc: DoS protection RPCTxFeeCap() float64 // global tx fee cap for all transaction related APIs UnprotectedAllowed() bool // allows only for EIP155 transactions. + RPCTxSyncDefaultTimeout() time.Duration + RPCTxSyncMaxTimeout() time.Duration // Blockchain API SetHead(number uint64) diff --git a/internal/ethapi/errors.go b/internal/ethapi/errors.go index 154938fa0e..30711a0167 100644 --- a/internal/ethapi/errors.go +++ b/internal/ethapi/errors.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/ethereum/go-ethereum/accounts/abi" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/vm" @@ -33,6 +34,11 @@ type revertError struct { reason string // revert reason hex encoded } +type txSyncTimeoutError struct { + msg string + hash common.Hash +} + // ErrorCode returns the JSON error code for a revert. // See: https://ethereum.org/en/developers/docs/apis/json-rpc/#error-codes func (e *revertError) ErrorCode() int { @@ -108,6 +114,7 @@ const ( errCodeInvalidParams = -32602 errCodeReverted = -32000 errCodeVMError = -32015 + errCodeTxSyncTimeout = 4 ) func txValidationError(err error) *invalidTxError { @@ -168,3 +175,7 @@ type blockGasLimitReachedError struct{ message string } func (e *blockGasLimitReachedError) Error() string { return e.message } func (e *blockGasLimitReachedError) ErrorCode() int { return errCodeBlockGasLimitReached } + +func (e *txSyncTimeoutError) Error() string { return e.msg } +func (e *txSyncTimeoutError) ErrorCode() int { return errCodeTxSyncTimeout } +func (e *txSyncTimeoutError) ErrorData() interface{} { return e.hash.Hex() } diff --git a/internal/ethapi/logtracer.go b/internal/ethapi/logtracer.go index 456aa93736..54d2d653ea 100644 --- a/internal/ethapi/logtracer.go +++ b/internal/ethapi/logtracer.go @@ -53,15 +53,17 @@ type tracer struct { count int traceTransfers bool blockNumber uint64 + blockTimestamp uint64 blockHash common.Hash txHash common.Hash txIdx uint } -func newTracer(traceTransfers bool, blockNumber uint64, blockHash, txHash common.Hash, txIndex uint) *tracer { +func newTracer(traceTransfers bool, blockNumber uint64, blockTimestamp uint64, blockHash, txHash common.Hash, txIndex uint) *tracer { return &tracer{ traceTransfers: traceTransfers, blockNumber: blockNumber, + blockTimestamp: blockTimestamp, blockHash: blockHash, txHash: txHash, txIdx: txIndex, @@ -115,14 +117,15 @@ func (t *tracer) onLog(log *types.Log) { func (t *tracer) captureLog(address common.Address, topics []common.Hash, data []byte) { t.logs[len(t.logs)-1] = append(t.logs[len(t.logs)-1], &types.Log{ - Address: address, - Topics: topics, - Data: data, - BlockNumber: t.blockNumber, - BlockHash: t.blockHash, - TxHash: t.txHash, - TxIndex: t.txIdx, - Index: uint(t.count), + Address: address, + Topics: topics, + Data: data, + BlockNumber: t.blockNumber, + BlockTimestamp: t.blockTimestamp, + BlockHash: t.blockHash, + TxHash: t.txHash, + TxIndex: t.txIdx, + Index: uint(t.count), }) t.count++ } diff --git a/internal/ethapi/override/override.go b/internal/ethapi/override/override.go index 0bcf3c444d..9d57a78651 100644 --- a/internal/ethapi/override/override.go +++ b/internal/ethapi/override/override.go @@ -91,7 +91,7 @@ func (diff *StateOverride) Apply(statedb *state.StateDB, precompiles vm.Precompi } // Override account(contract) code. if account.Code != nil { - statedb.SetCode(addr, *account.Code) + statedb.SetCode(addr, *account.Code, tracing.CodeChangeUnspecified) } // Override account balance. if account.Balance != nil { diff --git a/internal/ethapi/override/override_test.go b/internal/ethapi/override/override_test.go index 41b4f2c253..6feafaac75 100644 --- a/internal/ethapi/override/override_test.go +++ b/internal/ethapi/override/override_test.go @@ -31,14 +31,14 @@ import ( type precompileContract struct{} -func (p *precompileContract) Name() string { - panic("implement me") -} - func (p *precompileContract) RequiredGas(input []byte) uint64 { return 0 } func (p *precompileContract) Run(input []byte) ([]byte, error) { return nil, nil } +func (p *precompileContract) Name() string { + panic("implement me") +} + func TestStateOverrideMovePrecompile(t *testing.T) { db := state.NewDatabase(triedb.NewDatabase(rawdb.NewMemoryDatabase(), nil), nil) statedb, err := state.New(types.EmptyRootHash, db) diff --git a/internal/ethapi/simulate.go b/internal/ethapi/simulate.go index 362536bcb5..3c08061313 100644 --- a/internal/ethapi/simulate.go +++ b/internal/ethapi/simulate.go @@ -233,7 +233,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, if block.BlockOverrides.BlobBaseFee != nil { blockContext.BlobBaseFee = block.BlockOverrides.BlobBaseFee.ToInt() } - precompiles := sim.activePrecompiles(sim.base) + precompiles := sim.activePrecompiles(header) // State overrides are applied prior to execution of a block if err := block.StateOverrides.Apply(sim.state, precompiles); err != nil { return nil, nil, nil, err @@ -244,7 +244,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, callResults = make([]simCallResult, len(block.Calls)) receipts = make([]*types.Receipt, len(block.Calls)) // Block hash will be repaired after execution. - tracer = newTracer(sim.traceTransfers, blockContext.BlockNumber.Uint64(), common.Hash{}, common.Hash{}, 0) + tracer = newTracer(sim.traceTransfers, blockContext.BlockNumber.Uint64(), blockContext.Time, common.Hash{}, common.Hash{}, 0) vmConfig = &vm.Config{ NoBaseFee: !sim.validate, Tracer: tracer.Hooks(), @@ -287,7 +287,7 @@ func (sim *simulator) processBlock(ctx context.Context, block *simBlock, header, tracer.reset(txHash, uint(i)) sim.state.SetTxContext(txHash, i) // EoA check is always skipped, even in validation mode. - msg := call.ToMessage(header.BaseFee, !sim.validate, true) + msg := call.ToMessage(header.BaseFee, !sim.validate) result, err := applyMessageWithEVM(ctx, evm, msg, timeout, sim.gp) if err != nil { txErr := txValidationError(err) @@ -377,7 +377,7 @@ func (sim *simulator) sanitizeCall(call *TransactionArgs, state vm.StateDB, head call.Gas = (*hexutil.Uint64)(&remaining) } if *gasUsed+uint64(*call.Gas) > blockContext.GasLimit { - return &blockGasLimitReachedError{fmt.Sprintf("block gas limit reached: %d >= %d", gasUsed, blockContext.GasLimit)} + return &blockGasLimitReachedError{fmt.Sprintf("block gas limit reached: %d >= %d", *gasUsed, blockContext.GasLimit)} } if err := call.CallDefaults(sim.gp.Gas(), header.BaseFee, sim.chainConfig.ChainID); err != nil { return err @@ -474,22 +474,30 @@ func (sim *simulator) makeHeaders(blocks []simBlock) ([]*types.Header, error) { overrides := block.BlockOverrides var withdrawalsHash *common.Hash - if sim.chainConfig.IsShanghai(overrides.Number.ToInt(), (uint64)(*overrides.Time)) { + number := overrides.Number.ToInt() + timestamp := (uint64)(*overrides.Time) + if sim.chainConfig.IsShanghai(number, timestamp) { withdrawalsHash = &types.EmptyWithdrawalsHash } var parentBeaconRoot *common.Hash - if sim.chainConfig.IsCancun(overrides.Number.ToInt(), (uint64)(*overrides.Time)) { + if sim.chainConfig.IsCancun(number, timestamp) { parentBeaconRoot = &common.Hash{} if overrides.BeaconRoot != nil { parentBeaconRoot = overrides.BeaconRoot } } + // Set difficulty to zero if the given block is post-merge. Without this, all post-merge hardforks would remain inactive. + // For example, calling eth_simulateV1(..., blockParameter: 0x0) on hoodi network will cause all blocks to have a difficulty of 1 and be treated as pre-merge. + difficulty := header.Difficulty + if sim.chainConfig.IsPostMerge(number.Uint64(), timestamp) { + difficulty = big.NewInt(0) + } header = overrides.MakeHeader(&types.Header{ UncleHash: types.EmptyUncleHash, ReceiptHash: types.EmptyReceiptsHash, TxHash: types.EmptyTxsHash, Coinbase: header.Coinbase, - Difficulty: header.Difficulty, + Difficulty: difficulty, GasLimit: header.GasLimit, WithdrawalsHash: withdrawalsHash, ParentBeaconRoot: parentBeaconRoot, @@ -533,3 +541,23 @@ func (b *simBackend) HeaderByNumber(ctx context.Context, number rpc.BlockNumber) func (b *simBackend) ChainConfig() *params.ChainConfig { return b.b.ChainConfig() } + +func (b *simBackend) HeaderByHash(ctx context.Context, hash common.Hash) (*types.Header, error) { + if b.base.Hash() == hash { + return b.base, nil + } + if header, err := b.b.HeaderByHash(ctx, hash); err == nil { + return header, nil + } + // Check simulated headers + for _, header := range b.headers { + if header.Hash() == hash { + return header, nil + } + } + return nil, errors.New("header not found") +} + +func (b *simBackend) CurrentHeader() *types.Header { + return b.b.CurrentHeader() +} diff --git a/internal/ethapi/testdata/eth_config-current.json b/internal/ethapi/testdata/eth_config-current.json new file mode 100644 index 0000000000..0597c23e39 --- /dev/null +++ b/internal/ethapi/testdata/eth_config-current.json @@ -0,0 +1,40 @@ +{ + "current": { + "activationTime": 1742999832, + "blobSchedule": { + "target": 6, + "max": 9, + "baseFeeUpdateFraction": 5007716 + }, + "chainId": "0x88bb0", + "forkId": "0x0929e24e", + "precompiles": { + "BLAKE2F": "0x0000000000000000000000000000000000000009", + "BLS12_G1ADD": "0x000000000000000000000000000000000000000b", + "BLS12_G1MSM": "0x000000000000000000000000000000000000000c", + "BLS12_G2ADD": "0x000000000000000000000000000000000000000d", + "BLS12_G2MSM": "0x000000000000000000000000000000000000000e", + "BLS12_MAP_FP2_TO_G2": "0x0000000000000000000000000000000000000011", + "BLS12_MAP_FP_TO_G1": "0x0000000000000000000000000000000000000010", + "BLS12_PAIRING_CHECK": "0x000000000000000000000000000000000000000f", + "BN254_ADD": "0x0000000000000000000000000000000000000006", + "BN254_MUL": "0x0000000000000000000000000000000000000007", + "BN254_PAIRING": "0x0000000000000000000000000000000000000008", + "ECREC": "0x0000000000000000000000000000000000000001", + "ID": "0x0000000000000000000000000000000000000004", + "KZG_POINT_EVALUATION": "0x000000000000000000000000000000000000000a", + "MODEXP": "0x0000000000000000000000000000000000000005", + "RIPEMD160": "0x0000000000000000000000000000000000000003", + "SHA256": "0x0000000000000000000000000000000000000002" + }, + "systemContracts": { + "BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02", + "CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS": "0x0000bbddc7ce488642fb579f8b00f3a590007251", + "DEPOSIT_CONTRACT_ADDRESS": "0x00000000219ab540356cbb839cbe05303d7705fa", + "HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935", + "WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS": "0x00000961ef480eb55e80d19ad83579a64c007002" + } + }, + "next": null, + "last": null +} diff --git a/internal/ethapi/testdata/eth_config-next-and-last.json b/internal/ethapi/testdata/eth_config-next-and-last.json new file mode 100644 index 0000000000..81869ba174 --- /dev/null +++ b/internal/ethapi/testdata/eth_config-next-and-last.json @@ -0,0 +1,99 @@ +{ + "current": { + "activationTime": 0, + "blobSchedule": { + "baseFeeUpdateFraction": 3338477, + "max": 6, + "target": 3 + }, + "chainId": "0x88bb0", + "forkId": "0xbef71d30", + "precompiles": { + "BLAKE2F": "0x0000000000000000000000000000000000000009", + "BN254_ADD": "0x0000000000000000000000000000000000000006", + "BN254_MUL": "0x0000000000000000000000000000000000000007", + "BN254_PAIRING": "0x0000000000000000000000000000000000000008", + "ECREC": "0x0000000000000000000000000000000000000001", + "ID": "0x0000000000000000000000000000000000000004", + "KZG_POINT_EVALUATION": "0x000000000000000000000000000000000000000a", + "MODEXP": "0x0000000000000000000000000000000000000005", + "RIPEMD160": "0x0000000000000000000000000000000000000003", + "SHA256": "0x0000000000000000000000000000000000000002" + }, + "systemContracts": { + "BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02" + } + }, + "next": { + "activationTime": 1742999832, + "blobSchedule": { + "baseFeeUpdateFraction": 5007716, + "max": 9, + "target": 6 + }, + "chainId": "0x88bb0", + "forkId": "0x0929e24e", + "precompiles": { + "BLAKE2F": "0x0000000000000000000000000000000000000009", + "BLS12_G1ADD": "0x000000000000000000000000000000000000000b", + "BLS12_G1MSM": "0x000000000000000000000000000000000000000c", + "BLS12_G2ADD": "0x000000000000000000000000000000000000000d", + "BLS12_G2MSM": "0x000000000000000000000000000000000000000e", + "BLS12_MAP_FP2_TO_G2": "0x0000000000000000000000000000000000000011", + "BLS12_MAP_FP_TO_G1": "0x0000000000000000000000000000000000000010", + "BLS12_PAIRING_CHECK": "0x000000000000000000000000000000000000000f", + "BN254_ADD": "0x0000000000000000000000000000000000000006", + "BN254_MUL": "0x0000000000000000000000000000000000000007", + "BN254_PAIRING": "0x0000000000000000000000000000000000000008", + "ECREC": "0x0000000000000000000000000000000000000001", + "ID": "0x0000000000000000000000000000000000000004", + "KZG_POINT_EVALUATION": "0x000000000000000000000000000000000000000a", + "MODEXP": "0x0000000000000000000000000000000000000005", + "RIPEMD160": "0x0000000000000000000000000000000000000003", + "SHA256": "0x0000000000000000000000000000000000000002" + }, + "systemContracts": { + "BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02", + "CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS": "0x0000bbddc7ce488642fb579f8b00f3a590007251", + "DEPOSIT_CONTRACT_ADDRESS": "0x00000000219ab540356cbb839cbe05303d7705fa", + "HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935", + "WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS": "0x00000961ef480eb55e80d19ad83579a64c007002" + } + }, + "last": { + "activationTime": 1742999832, + "blobSchedule": { + "baseFeeUpdateFraction": 5007716, + "max": 9, + "target": 6 + }, + "chainId": "0x88bb0", + "forkId": "0x0929e24e", + "precompiles": { + "BLAKE2F": "0x0000000000000000000000000000000000000009", + "BLS12_G1ADD": "0x000000000000000000000000000000000000000b", + "BLS12_G1MSM": "0x000000000000000000000000000000000000000c", + "BLS12_G2ADD": "0x000000000000000000000000000000000000000d", + "BLS12_G2MSM": "0x000000000000000000000000000000000000000e", + "BLS12_MAP_FP2_TO_G2": "0x0000000000000000000000000000000000000011", + "BLS12_MAP_FP_TO_G1": "0x0000000000000000000000000000000000000010", + "BLS12_PAIRING_CHECK": "0x000000000000000000000000000000000000000f", + "BN254_ADD": "0x0000000000000000000000000000000000000006", + "BN254_MUL": "0x0000000000000000000000000000000000000007", + "BN254_PAIRING": "0x0000000000000000000000000000000000000008", + "ECREC": "0x0000000000000000000000000000000000000001", + "ID": "0x0000000000000000000000000000000000000004", + "KZG_POINT_EVALUATION": "0x000000000000000000000000000000000000000a", + "MODEXP": "0x0000000000000000000000000000000000000005", + "RIPEMD160": "0x0000000000000000000000000000000000000003", + "SHA256": "0x0000000000000000000000000000000000000002" + }, + "systemContracts": { + "BEACON_ROOTS_ADDRESS": "0x000f3df6d732807ef1319fb7b8bb8522d0beac02", + "CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS": "0x0000bbddc7ce488642fb579f8b00f3a590007251", + "DEPOSIT_CONTRACT_ADDRESS": "0x00000000219ab540356cbb839cbe05303d7705fa", + "HISTORY_STORAGE_ADDRESS": "0x0000f90827f1c53a10cb7a02335b175320002935", + "WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS": "0x00000961ef480eb55e80d19ad83579a64c007002" + } + } +} diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json index 60f18bc114..2e323dcfe7 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending-fullTx.json @@ -1,49 +1,40 @@ { - "difficulty": "0x0", + "baseFeePerGas": "0xde56ab3", + "difficulty": "0x20000", "extraData": "0x", - "gasLimit": "0x0", - "gasUsed": "0x0", + "gasLimit": "0x47e7c4", + "gasUsed": "0x5208", "hash": null, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": null, "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": null, "number": "0xb", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "parentHash": "0xa063415a5020f1569fae73ecb0d37bc5649ebe86d59e764a389eb37814bd42cb", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x256", - "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x2a", + "size": "0x26a", + "stateRoot": "0xce0e05397e548614a5b93254662174329466f8f4b1b391eb36fec9a7a591e58e", + "timestamp": "0x6e", "transactions": [ { - "blockHash": "0x6cebd9f966ea686f44b981685e3f0eacea28591a7a86d7fbbe521a86e9f81165", + "blockHash": "0xfda6c7cb7a3a712e0c424909a7724cab0448e89e286617fa8d5fd27f63f28bd2", "blockNumber": "0xb", - "from": "0x0000000000000000000000000000000000000000", - "gas": "0x457", - "gasPrice": "0x2b67", - "hash": "0x4afee081df5dff7a025964032871f7d4ba4d21baf5f6376a2f4a9f79fc506298", - "input": "0x111111", - "nonce": "0xb", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gas": "0x5208", + "gasPrice": "0xde56ab3", + "hash": "0xd773fbb47ec87b1a958ac16430943ddf2797ecae2b33fe7b16ddb334e30325ed", + "input": "0x", + "nonce": "0xa", "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", "transactionIndex": "0x0", - "value": "0x6f", + "value": "0x3e8", "type": "0x0", - "chainId": "0x7fffffffffffffee", - "v": "0x0", - "r": "0x0", - "s": "0x0" + "v": "0x1c", + "r": "0xfa029dacd66238d20cd649fe3b323bb458d2cfa4af7db0ff4f6b3e1039bc320a", + "s": "0x52fb4d45c1d623f2f05508bae063a4728761d762ae45b8b0908ffea546f3d95e" } ], - "transactionsRoot": "0x98d9f6dd0aa479c0fb448f2627e9f1964aca699fccab8f6e95861547a4699e37", - "uncles": [], - "withdrawals": [ - { - "index": "0x0", - "validatorIndex": "0x1", - "address": "0x1234000000000000000000000000000000000000", - "amount": "0xa" - } - ], - "withdrawalsRoot": "0x73d756269cdfc22e7e17a3548e36f42f750ca06d7e3cd98d1b6d0eb5add9dc84" + "transactionsRoot": "0x59abb8ec0655f66e66450d1502618bc64022ae2d2950fa471eec6e8da2846264", + "uncles": [] } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json index dda2d93213..3254482cd9 100644 --- a/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json +++ b/internal/ethapi/testdata/eth_getBlockByNumber-tag-pending.json @@ -1,32 +1,24 @@ { - "difficulty": "0x0", + "baseFeePerGas": "0xde56ab3", + "difficulty": "0x20000", "extraData": "0x", - "gasLimit": "0x0", - "gasUsed": "0x0", + "gasLimit": "0x47e7c4", + "gasUsed": "0x5208", "hash": null, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": null, "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": null, "number": "0xb", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "parentHash": "0xa063415a5020f1569fae73ecb0d37bc5649ebe86d59e764a389eb37814bd42cb", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "size": "0x256", - "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x2a", + "size": "0x26a", + "stateRoot": "0xce0e05397e548614a5b93254662174329466f8f4b1b391eb36fec9a7a591e58e", + "timestamp": "0x6e", "transactions": [ - "0x4afee081df5dff7a025964032871f7d4ba4d21baf5f6376a2f4a9f79fc506298" + "0xd773fbb47ec87b1a958ac16430943ddf2797ecae2b33fe7b16ddb334e30325ed" ], - "transactionsRoot": "0x98d9f6dd0aa479c0fb448f2627e9f1964aca699fccab8f6e95861547a4699e37", - "uncles": [], - "withdrawals": [ - { - "index": "0x0", - "validatorIndex": "0x1", - "address": "0x1234000000000000000000000000000000000000", - "amount": "0xa" - } - ], - "withdrawalsRoot": "0x73d756269cdfc22e7e17a3548e36f42f750ca06d7e3cd98d1b6d0eb5add9dc84" + "transactionsRoot": "0x59abb8ec0655f66e66450d1502618bc64022ae2d2950fa471eec6e8da2846264", + "uncles": [] } \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getBlockReceipts-tag-pending.json b/internal/ethapi/testdata/eth_getBlockReceipts-tag-pending.json new file mode 100644 index 0000000000..75f9f3ad99 --- /dev/null +++ b/internal/ethapi/testdata/eth_getBlockReceipts-tag-pending.json @@ -0,0 +1,18 @@ +[ + { + "blockHash": "0xc74cf882395ec92eec3673d93a57f9a3bf1a5e696fae3e52f252059af62756c8", + "blockNumber": "0x7", + "contractAddress": null, + "cumulativeGasUsed": "0x5208", + "effectiveGasPrice": "0x17b07ddf", + "from": "0x703c4b2bd70c169f5717101caee543299fc946c7", + "gasUsed": "0x5208", + "logs": [], + "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", + "status": "0x1", + "to": "0x0d3ab14bbad3d99f4203bd7a11acb94882050e7e", + "transactionHash": "0xa7eeffe8111539a8f9725eb4d49e341efa1287d33190300adab220929daa5fac", + "transactionIndex": "0x0", + "type": "0x0" + } +] \ No newline at end of file diff --git a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json index 289ff5fece..e4121824ef 100644 --- a/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json +++ b/internal/ethapi/testdata/eth_getHeaderByNumber-tag-pending.json @@ -1,19 +1,19 @@ { - "difficulty": "0x0", + "baseFeePerGas": "0xde56ab3", + "difficulty": "0x20000", "extraData": "0x", - "gasLimit": "0x0", - "gasUsed": "0x0", + "gasLimit": "0x47e7c4", + "gasUsed": "0x5208", "hash": null, "logsBloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "miner": null, "mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000", "nonce": null, "number": "0xb", - "parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000", - "receiptsRoot": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "parentHash": "0xa063415a5020f1569fae73ecb0d37bc5649ebe86d59e764a389eb37814bd42cb", + "receiptsRoot": "0x056b23fbba480696b65fe5a59b8f2148a1299103c4f57df839233af2cf4ca2d2", "sha3Uncles": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347", - "stateRoot": "0x0000000000000000000000000000000000000000000000000000000000000000", - "timestamp": "0x2a", - "transactionsRoot": "0x98d9f6dd0aa479c0fb448f2627e9f1964aca699fccab8f6e95861547a4699e37", - "withdrawalsRoot": "0x73d756269cdfc22e7e17a3548e36f42f750ca06d7e3cd98d1b6d0eb5add9dc84" + "stateRoot": "0xce0e05397e548614a5b93254662174329466f8f4b1b391eb36fec9a7a591e58e", + "timestamp": "0x6e", + "transactionsRoot": "0x59abb8ec0655f66e66450d1502618bc64022ae2d2950fa471eec6e8da2846264" } \ No newline at end of file diff --git a/internal/ethapi/transaction_args.go b/internal/ethapi/transaction_args.go index 6b094721e4..23aa8e5947 100644 --- a/internal/ethapi/transaction_args.go +++ b/internal/ethapi/transaction_args.go @@ -70,9 +70,6 @@ type TransactionArgs struct { // For SetCodeTxType AuthorizationList []types.SetCodeAuthorization `json:"authorizationList"` - - // This configures whether blobs are allowed to be passed. - blobSidecarAllowed bool } // from retrieves the transaction sender address. @@ -94,9 +91,17 @@ func (args *TransactionArgs) data() []byte { return nil } +// sidecarConfig defines the options for deriving missing fields of transactions. +type sidecarConfig struct { + // This configures whether blobs are allowed to be passed and + // the associated sidecar version should be attached. + blobSidecarAllowed bool + blobSidecarVersion byte +} + // setDefaults fills in default values for unspecified tx fields. -func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGasEstimation bool) error { - if err := args.setBlobTxSidecar(ctx); err != nil { +func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, config sidecarConfig) error { + if err := args.setBlobTxSidecar(ctx, config); err != nil { return err } if err := args.setFeeDefaults(ctx, b, b.CurrentHeader()); err != nil { @@ -119,11 +124,10 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas // BlobTx fields if args.BlobHashes != nil && len(args.BlobHashes) == 0 { - return errors.New(`need at least 1 blob for a blob transaction`) + return errors.New("need at least 1 blob for a blob transaction") } - maxBlobs := eip4844.MaxBlobsPerBlock(b.ChainConfig(), b.CurrentHeader().Time) - if args.BlobHashes != nil && len(args.BlobHashes) > maxBlobs { - return fmt.Errorf(`too many blobs in transaction (have=%d, max=%d)`, len(args.BlobHashes), maxBlobs) + if args.BlobHashes != nil && len(args.BlobHashes) > params.BlobTxMaxBlobs { + return fmt.Errorf("too many blobs in transaction (have=%d, max=%d)", len(args.BlobHashes), params.BlobTxMaxBlobs) } // create check @@ -137,36 +141,28 @@ func (args *TransactionArgs) setDefaults(ctx context.Context, b Backend, skipGas } if args.Gas == nil { - if skipGasEstimation { // Skip gas usage estimation if a precise gas limit is not critical, e.g., in non-transaction calls. - gas := hexutil.Uint64(b.RPCGasCap()) - if gas == 0 { - gas = hexutil.Uint64(math.MaxUint64 / 2) - } - args.Gas = &gas - } else { // Estimate the gas usage otherwise. - // These fields are immutable during the estimation, safe to - // pass the pointer directly. - data := args.data() - callArgs := TransactionArgs{ - From: args.From, - To: args.To, - GasPrice: args.GasPrice, - MaxFeePerGas: args.MaxFeePerGas, - MaxPriorityFeePerGas: args.MaxPriorityFeePerGas, - Value: args.Value, - Data: (*hexutil.Bytes)(&data), - AccessList: args.AccessList, - BlobFeeCap: args.BlobFeeCap, - BlobHashes: args.BlobHashes, - } - latestBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) - estimated, err := DoEstimateGas(ctx, b, callArgs, latestBlockNr, nil, nil, b.RPCGasCap()) - if err != nil { - return err - } - args.Gas = &estimated - log.Trace("Estimate gas usage automatically", "gas", args.Gas) + // These fields are immutable during the estimation, safe to + // pass the pointer directly. + data := args.data() + callArgs := TransactionArgs{ + From: args.From, + To: args.To, + GasPrice: args.GasPrice, + MaxFeePerGas: args.MaxFeePerGas, + MaxPriorityFeePerGas: args.MaxPriorityFeePerGas, + Value: args.Value, + Data: (*hexutil.Bytes)(&data), + AccessList: args.AccessList, + BlobFeeCap: args.BlobFeeCap, + BlobHashes: args.BlobHashes, } + latestBlockNr := rpc.BlockNumberOrHashWithNumber(rpc.LatestBlockNumber) + estimated, err := DoEstimateGas(ctx, b, callArgs, latestBlockNr, nil, nil, b.RPCGasCap()) + if err != nil { + return err + } + args.Gas = &estimated + log.Trace("Estimated gas usage automatically", "gas", args.Gas) } // If chain id is provided, ensure it matches the local chain id. Otherwise, set the local @@ -283,18 +279,17 @@ func (args *TransactionArgs) setLondonFeeDefaults(ctx context.Context, head *typ } // setBlobTxSidecar adds the blob tx -func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context) error { +func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context, config sidecarConfig) error { // No blobs, we're done. if args.Blobs == nil { return nil } // Passing blobs is not allowed in all contexts, only in specific methods. - if !args.blobSidecarAllowed { + if !config.blobSidecarAllowed { return errors.New(`"blobs" is not supported for this RPC method`) } - n := len(args.Blobs) // Assume user provides either only blobs (w/o hashes), or // blobs together with commitments and proofs. if args.Commitments == nil && args.Proofs != nil { @@ -303,43 +298,77 @@ func (args *TransactionArgs) setBlobTxSidecar(ctx context.Context) error { return errors.New(`blob commitments provided while proofs were not`) } - // len(blobs) == len(commitments) == len(proofs) == len(hashes) - if args.Commitments != nil && len(args.Commitments) != n { - return fmt.Errorf("number of blobs and commitments mismatch (have=%d, want=%d)", len(args.Commitments), n) - } - if args.Proofs != nil && len(args.Proofs) != n { - return fmt.Errorf("number of blobs and proofs mismatch (have=%d, want=%d)", len(args.Proofs), n) - } + // len(blobs) == len(commitments) == len(hashes) + n := len(args.Blobs) if args.BlobHashes != nil && len(args.BlobHashes) != n { return fmt.Errorf("number of blobs and hashes mismatch (have=%d, want=%d)", len(args.BlobHashes), n) } + if args.Commitments != nil && len(args.Commitments) != n { + return fmt.Errorf("number of blobs and commitments mismatch (have=%d, want=%d)", len(args.Commitments), n) + } + // if V0: len(blobs) == len(proofs) + // if V1: len(blobs) == len(proofs) * 128 + proofLen := n + if config.blobSidecarVersion == types.BlobSidecarVersion1 { + proofLen = n * kzg4844.CellProofsPerBlob + } + if args.Proofs != nil && len(args.Proofs) != proofLen { + if len(args.Proofs) != n { + return fmt.Errorf("number of blobs and proofs mismatch (have=%d, want=%d)", len(args.Proofs), proofLen) + } + // Unset the commitments and proofs, as they may be submitted in the legacy format + log.Debug("Unset legacy commitments and proofs", "blobs", n, "proofs", len(args.Proofs)) + args.Commitments, args.Proofs = nil, nil + } + + // Generate commitments and proofs if they are missing, or validate them if they + // are provided. if args.Commitments == nil { - // Generate commitment and proof. - commitments := make([]kzg4844.Commitment, n) - proofs := make([]kzg4844.Proof, n) + var ( + commitments = make([]kzg4844.Commitment, n) + proofs = make([]kzg4844.Proof, 0, proofLen) + ) for i, b := range args.Blobs { c, err := kzg4844.BlobToCommitment(&b) if err != nil { return fmt.Errorf("blobs[%d]: error computing commitment: %v", i, err) } commitments[i] = c - p, err := kzg4844.ComputeBlobProof(&b, c) - if err != nil { - return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err) + + switch config.blobSidecarVersion { + case types.BlobSidecarVersion0: + p, err := kzg4844.ComputeBlobProof(&b, c) + if err != nil { + return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err) + } + proofs = append(proofs, p) + case types.BlobSidecarVersion1: + ps, err := kzg4844.ComputeCellProofs(&b) + if err != nil { + return fmt.Errorf("blobs[%d]: error computing proof: %v", i, err) + } + proofs = append(proofs, ps...) } - proofs[i] = p } args.Commitments = commitments args.Proofs = proofs } else { - for i, b := range args.Blobs { - if err := kzg4844.VerifyBlobProof(&b, args.Commitments[i], args.Proofs[i]); err != nil { + switch config.blobSidecarVersion { + case types.BlobSidecarVersion0: + for i, b := range args.Blobs { + if err := kzg4844.VerifyBlobProof(&b, args.Commitments[i], args.Proofs[i]); err != nil { + return fmt.Errorf("failed to verify blob proof: %v", err) + } + } + case types.BlobSidecarVersion1: + if err := kzg4844.VerifyCellProofs(args.Blobs, args.Commitments, args.Proofs); err != nil { return fmt.Errorf("failed to verify blob proof: %v", err) } } } + // Generate blob hashes if they are missing, or validate them if they are provided. hashes := make([]common.Hash, n) hasher := sha256.New() for i, c := range args.Commitments { @@ -414,7 +443,7 @@ func (args *TransactionArgs) CallDefaults(globalGasCap uint64, baseFee *big.Int, // core evm. This method is used in calls and traces that do not require a real // live transaction. // Assumes that fields are not nil, i.e. setDefaults or CallDefaults has been called. -func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck, skipEoACheck bool) *core.Message { +func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck bool) *core.Message { var ( gasPrice *big.Int gasFeeCap *big.Int @@ -462,7 +491,7 @@ func (args *TransactionArgs) ToMessage(baseFee *big.Int, skipNonceCheck, skipEoA BlobHashes: args.BlobHashes, SetCodeAuthorizations: args.AuthorizationList, SkipNonceChecks: skipNonceCheck, - SkipFromEOACheck: skipEoACheck, + SkipTransactionChecks: true, } } @@ -527,8 +556,11 @@ func (args *TransactionArgs) ToTransaction(defaultType int) *types.Transaction { BlobFeeCap: uint256.MustFromBig((*big.Int)(args.BlobFeeCap)), } if args.Blobs != nil { - // TODO(rjl493456442, marius) support V1 - data.(*types.BlobTx).Sidecar = types.NewBlobTxSidecar(types.BlobSidecarVersion0, args.Blobs, args.Commitments, args.Proofs) + version := types.BlobSidecarVersion0 + if len(args.Proofs) == len(args.Blobs)*kzg4844.CellProofsPerBlob { + version = types.BlobSidecarVersion1 + } + data.(*types.BlobTx).Sidecar = types.NewBlobTxSidecar(version, args.Blobs, args.Commitments, args.Proofs) } case types.DynamicFeeTxType: diff --git a/internal/flags/helpers.go b/internal/flags/helpers.go index fc84ae85da..e6a6966d9f 100644 --- a/internal/flags/helpers.go +++ b/internal/flags/helpers.go @@ -40,7 +40,7 @@ func NewApp(usage string) *cli.App { app.EnableBashCompletion = true app.Version = version.WithCommit(git.Commit, git.Date) app.Usage = usage - app.Copyright = "Copyright 2013-2025 The go-ethereum Authors" + app.Copyright = "Copyright 2013-2026 The go-ethereum Authors" app.Before = func(ctx *cli.Context) error { MigrateGlobalFlags(ctx) return nil diff --git a/internal/jsre/jsre.go b/internal/jsre/jsre.go index 0dfeae8e1b..4512115f16 100644 --- a/internal/jsre/jsre.go +++ b/internal/jsre/jsre.go @@ -201,7 +201,7 @@ loop: if !isFunc { panic(re.vm.ToValue("js error: timer/timeout callback is not a function")) } - call(goja.Null(), timer.call.Arguments...) + call(goja.Null(), timer.call.Arguments[2:]...) _, inreg := registry[timer] // when clearInterval is called from within the callback don't reset it if timer.interval && inreg { diff --git a/internal/telemetry/telemetry.go b/internal/telemetry/telemetry.go new file mode 100644 index 0000000000..6bd16da66c --- /dev/null +++ b/internal/telemetry/telemetry.go @@ -0,0 +1,104 @@ +// Copyright 2026 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package telemetry + +import ( + "context" + "fmt" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + semconv "go.opentelemetry.io/otel/semconv/v1.38.0" + "go.opentelemetry.io/otel/trace" +) + +// Attribute is an alias for attribute.KeyValue. +type Attribute = attribute.KeyValue + +// StringAttribute creates an attribute with a string value. +func StringAttribute(key, val string) Attribute { + return attribute.String(key, val) +} + +// Int64Attribute creates an attribute with an int64 value. +func Int64Attribute(key string, val int64) Attribute { + return attribute.Int64(key, val) +} + +// BoolAttribute creates an attribute with a bool value. +func BoolAttribute(key string, val bool) Attribute { + return attribute.Bool(key, val) +} + +// StartSpan creates a SpanKind=INTERNAL span. +func StartSpan(ctx context.Context, spanName string, attributes ...Attribute) (context.Context, trace.Span, func(error)) { + return StartSpanWithTracer(ctx, otel.Tracer(""), spanName, attributes...) +} + +// StartSpanWithTracer requires a tracer to be passed in and creates a SpanKind=INTERNAL span. +func StartSpanWithTracer(ctx context.Context, tracer trace.Tracer, name string, attributes ...Attribute) (context.Context, trace.Span, func(error)) { + return startSpan(ctx, tracer, trace.SpanKindInternal, name, attributes...) +} + +// RPCInfo contains information about the RPC request. +type RPCInfo struct { + System string + Service string + Method string + RequestID string +} + +// StartServerSpan creates a SpanKind=SERVER span at the JSON-RPC boundary. +// The span name is formatted as $rpcSystem.$rpcService/$rpcMethod +// (e.g. "jsonrpc.engine/newPayloadV4") which follows the Open Telemetry +// semantic convensions: https://opentelemetry.io/docs/specs/semconv/rpc/rpc-spans/#span-name. +func StartServerSpan(ctx context.Context, tracer trace.Tracer, rpc RPCInfo, others ...Attribute) (context.Context, func(error)) { + var ( + name = fmt.Sprintf("%s.%s/%s", rpc.System, rpc.Service, rpc.Method) + attributes = append([]Attribute{ + semconv.RPCSystemKey.String(rpc.System), + semconv.RPCServiceKey.String(rpc.Service), + semconv.RPCMethodKey.String(rpc.Method), + semconv.RPCJSONRPCRequestID(rpc.RequestID), + }, + others..., + ) + ) + ctx, _, end := startSpan(ctx, tracer, trace.SpanKindServer, name, attributes...) + return ctx, end +} + +// startSpan creates a span with the given kind. +func startSpan(ctx context.Context, tracer trace.Tracer, kind trace.SpanKind, spanName string, attributes ...Attribute) (context.Context, trace.Span, func(error)) { + ctx, span := tracer.Start(ctx, spanName, trace.WithSpanKind(kind)) + if len(attributes) > 0 { + span.SetAttributes(attributes...) + } + return ctx, span, endSpan(span) +} + +// endSpan ends the span and handles error recording. +func endSpan(span trace.Span) func(error) { + return func(err error) { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, err.Error()) + } + span.End() + } +} diff --git a/internal/web3ext/web3ext.go b/internal/web3ext/web3ext.go index d7f37a79ee..0aedffe230 100644 --- a/internal/web3ext/web3ext.go +++ b/internal/web3ext/web3ext.go @@ -217,11 +217,6 @@ web3._extend({ call: 'debug_setHead', params: 1 }), - new web3._extend.Method({ - name: 'seedHash', - call: 'debug_seedHash', - params: 1 - }), new web3._extend.Method({ name: 'dumpBlock', call: 'debug_dumpBlock', @@ -473,6 +468,12 @@ web3._extend({ call: 'debug_sync', params: 1 }), + new web3._extend.Method({ + name: 'stateSize', + call: 'debug_stateSize', + params: 1, + inputFormatter: [null], + }), ], properties: [] }); @@ -600,6 +601,11 @@ web3._extend({ call: 'eth_getBlockReceipts', params: 1, }), + new web3._extend.Method({ + name: 'config', + call: 'eth_config', + params: 0, + }) ], properties: [ new web3._extend.Property({ diff --git a/log/format_test.go b/log/format_test.go index d4c1df4abc..bb740ceb84 100644 --- a/log/format_test.go +++ b/log/format_test.go @@ -10,7 +10,7 @@ var sink []byte func BenchmarkPrettyInt64Logfmt(b *testing.B) { buf := make([]byte, 100) b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { sink = appendInt64(buf, rand.Int63()) } } @@ -18,7 +18,7 @@ func BenchmarkPrettyInt64Logfmt(b *testing.B) { func BenchmarkPrettyUint64Logfmt(b *testing.B) { buf := make([]byte, 100) b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { sink = appendUint64(buf, rand.Uint64(), false) } } diff --git a/log/logger_test.go b/log/logger_test.go index 3ec6d2e19c..dae8497204 100644 --- a/log/logger_test.go +++ b/log/logger_test.go @@ -70,9 +70,10 @@ func TestJSONHandler(t *testing.T) { func BenchmarkTraceLogging(b *testing.B) { SetDefault(NewLogger(NewTerminalHandler(io.Discard, true))) - b.ResetTimer() - for i := 0; i < b.N; i++ { + i := 0 + for b.Loop() { Trace("a message", "v", i) + i++ } } @@ -99,8 +100,8 @@ func benchmarkLogger(b *testing.B, l Logger) { err = errors.New("oh nooes it's crap") ) b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { + i := 0 + for b.Loop() { l.Info("This is a message", "foo", int16(i), "bytes", bb, @@ -109,8 +110,8 @@ func benchmarkLogger(b *testing.B, l Logger) { "bigint", bigint, "nilbig", nilbig, "err", err) + i++ } - b.StopTimer() } func TestLoggerOutput(t *testing.T) { @@ -161,18 +162,18 @@ const termTimeFormat = "01-02|15:04:05.000" func BenchmarkAppendFormat(b *testing.B) { var now = time.Now() b.Run("fmt time.Format", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { fmt.Fprintf(io.Discard, "%s", now.Format(termTimeFormat)) } }) b.Run("time.AppendFormat", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { now.AppendFormat(nil, termTimeFormat) } }) var buf = new(bytes.Buffer) b.Run("time.Custom", func(b *testing.B) { - for i := 0; i < b.N; i++ { + for b.Loop() { writeTimeTermFormat(buf, now) buf.Reset() } diff --git a/metrics/cputime_nop.go b/metrics/cputime_nop.go index 465d88c4d2..a6285ec10a 100644 --- a/metrics/cputime_nop.go +++ b/metrics/cputime_nop.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build windows || js -// +build windows js +//go:build windows || js || tinygo +// +build windows js tinygo package metrics diff --git a/metrics/cputime_unix.go b/metrics/cputime_unix.go index a44bf80876..5db38b16a2 100644 --- a/metrics/cputime_unix.go +++ b/metrics/cputime_unix.go @@ -14,8 +14,8 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . -//go:build !windows && !js && !wasip1 -// +build !windows,!js,!wasip1 +//go:build !windows && !js && !wasip1 && !tinygo +// +build !windows,!js,!wasip1,!tinygo package metrics diff --git a/metrics/runtimehistogram.go b/metrics/runtimehistogram.go index 0ab8914602..efbed498af 100644 --- a/metrics/runtimehistogram.go +++ b/metrics/runtimehistogram.go @@ -204,7 +204,7 @@ func (h *runtimeHistogramSnapshot) Percentiles(ps []float64) []float64 { thresholds := make([]float64, len(ps)) indexes := make([]int, len(ps)) for i, percentile := range ps { - thresholds[i] = count * math.Max(0, math.Min(1.0, percentile)) + thresholds[i] = count * max(0, min(1.0, percentile)) indexes[i] = i } sort.Sort(floatsAscendingKeepingIndex{thresholds, indexes}) diff --git a/miner/miner.go b/miner/miner.go index ddfe0dcf26..ee890b5e54 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -48,11 +48,12 @@ type Config struct { GasCeil uint64 // Target gas ceiling for mined blocks. GasPrice *big.Int // Minimum gas price for mining a transaction Recommit time.Duration // The time interval for miner to re-create mining work. + MaxBlobsPerBlock int // Maximum number of blobs per block (0 for unset uses protocol default) } // DefaultConfig contains default settings for miner. var DefaultConfig = Config{ - GasCeil: 45_000_000, + GasCeil: 60_000_000, GasPrice: big.NewInt(params.GWei / 1000), // The default recommit time is chosen as two seconds since @@ -144,10 +145,10 @@ func (miner *Miner) getPending() *newPayloadResult { header := miner.chain.CurrentHeader() miner.pendingMu.Lock() defer miner.pendingMu.Unlock() + if cached := miner.pending.resolve(header.Hash()); cached != nil { return cached } - var ( timestamp = uint64(time.Now().Unix()) withdrawal types.Withdrawals diff --git a/miner/worker.go b/miner/worker.go index ee31a65359..45d7073ed7 100644 --- a/miner/worker.go +++ b/miner/worker.go @@ -43,6 +43,16 @@ var ( errBlockInterruptedByTimeout = errors.New("timeout while building block") ) +// maxBlobsPerBlock returns the maximum number of blobs per block. +// Users can specify the maximum number of blobs per block if necessary. +func (miner *Miner) maxBlobsPerBlock(time uint64) int { + maxBlobs := eip4844.MaxBlobsPerBlock(miner.chainConfig, time) + if miner.config.MaxBlobsPerBlock != 0 { + maxBlobs = miner.config.MaxBlobsPerBlock + } + return maxBlobs +} + // environment is the worker's current environment and holds all // information of the sealing block generation. type environment struct { @@ -271,7 +281,7 @@ func (miner *Miner) makeEnv(parent *types.Header, header *types.Header, coinbase if err != nil { return nil, err } - state.StartPrefetcher("miner", bundle) + state.StartPrefetcher("miner", bundle, nil) } // Note the passed coinbase may be different with header.Coinbase. return &environment{ @@ -309,7 +319,7 @@ func (miner *Miner) commitBlobTransaction(env *environment, tx *types.Transactio // isn't really a better place right now. The blob gas limit is checked at block validation time // and not during execution. This means core.ApplyTransaction will not return an error if the // tx has too many blobs. So we have to explicitly check it here. - maxBlobs := eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time) + maxBlobs := miner.maxBlobsPerBlock(env.header.Time) if env.blobs+len(sc.Blobs) > maxBlobs { return errors.New("max data blobs reached") } @@ -344,7 +354,6 @@ func (miner *Miner) applyTransaction(env *environment, tx *types.Transaction) (* func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *transactionsByPriceAndNonce, interrupt *atomic.Int32) error { var ( - isOsaka = miner.chainConfig.IsOsaka(env.header.Number, env.header.Time) isCancun = miner.chainConfig.IsCancun(env.header.Number, env.header.Time) gasLimit = env.header.GasLimit ) @@ -365,7 +374,7 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran } // If we don't have enough blob space for any further blob transactions, // skip that list altogether - if !blobTxs.Empty() && env.blobs >= eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time) { + if !blobTxs.Empty() && env.blobs >= miner.maxBlobsPerBlock(env.header.Time) { log.Trace("Not enough blob space for further blob transactions") blobTxs.Clear() // Fall though to pick up any plain txs @@ -404,7 +413,7 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran // blobs or not, however the max check panics when called on a chain without // a defined schedule, so we need to verify it's safe to call. if isCancun { - left := eip4844.MaxBlobsPerBlock(miner.chainConfig, env.header.Time) - env.blobs + left := miner.maxBlobsPerBlock(env.header.Time) - env.blobs if left < int(ltx.BlobGas/params.BlobTxBlobGasPerBlob) { log.Trace("Not enough blob space left for transaction", "hash", ltx.Hash, "left", left, "needed", ltx.BlobGas/params.BlobTxBlobGasPerBlob) txs.Pop() @@ -425,21 +434,6 @@ func (miner *Miner) commitTransactions(env *environment, plainTxs, blobTxs *tran if !env.txFitsSize(tx) { break } - - // Make sure all transactions after osaka have cell proofs - if isOsaka { - if sidecar := tx.BlobTxSidecar(); sidecar != nil { - if sidecar.Version == types.BlobSidecarVersion0 { - log.Info("Including blob tx with v0 sidecar, recomputing proofs", "hash", ltx.Hash) - if err := sidecar.ToV1(); err != nil { - txs.Pop() - log.Warn("Failed to recompute cell proofs", "hash", ltx.Hash, "err", err) - continue - } - } - } - } - // Error may be ignored here. The error has already been checked // during transaction acceptance in the transaction pool. from, _ := types.Sender(env.signer, tx) @@ -497,10 +491,15 @@ func (miner *Miner) fillTransactions(interrupt *atomic.Int32, env *environment) if miner.chainConfig.IsOsaka(env.header.Number, env.header.Time) { filter.GasLimitCap = params.MaxTxGas } - filter.OnlyPlainTxs, filter.OnlyBlobTxs = true, false + filter.BlobTxs = false pendingPlainTxs := miner.txpool.Pending(filter) - filter.OnlyPlainTxs, filter.OnlyBlobTxs = false, true + filter.BlobTxs = true + if miner.chainConfig.IsOsaka(env.header.Number, env.header.Time) { + filter.BlobVersion = types.BlobSidecarVersion1 + } else { + filter.BlobVersion = types.BlobSidecarVersion0 + } pendingBlobTxs := miner.txpool.Pending(filter) // Split the pending transactions into locals and remotes. @@ -543,7 +542,6 @@ func totalFees(block *types.Block, receipts []*types.Receipt) *big.Int { for i, tx := range block.Transactions() { minerFee, _ := tx.EffectiveGasTip(block.BaseFee()) feesWei.Add(feesWei, new(big.Int).Mul(new(big.Int).SetUint64(receipts[i].GasUsed), minerFee)) - // TODO (MariusVanDerWijden) add blob fees } return feesWei } diff --git a/node/api.go b/node/api.go index 33dfb3a1cc..e5dda5ac4d 100644 --- a/node/api.go +++ b/node/api.go @@ -191,7 +191,7 @@ func (api *adminAPI) StartHTTP(host *string, port *int, cors *string, apis *stri } if vhosts != nil { config.Vhosts = nil - for _, vhost := range strings.Split(*host, ",") { + for _, vhost := range strings.Split(*vhosts, ",") { config.Vhosts = append(config.Vhosts, strings.TrimSpace(vhost)) } } diff --git a/node/defaults.go b/node/defaults.go index 307d9e186a..403a7f88a3 100644 --- a/node/defaults.go +++ b/node/defaults.go @@ -22,6 +22,7 @@ import ( "path/filepath" "runtime" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/p2p/nat" "github.com/ethereum/go-ethereum/rpc" @@ -68,9 +69,11 @@ var DefaultConfig = Config{ BatchResponseMaxSize: 25 * 1000 * 1000, GraphQLVirtualHosts: []string{"localhost"}, P2P: p2p.Config{ - ListenAddr: ":30303", - MaxPeers: 50, - NAT: nat.Any(), + ListenAddr: ":30303", + MaxPeers: 50, + NAT: nat.Any(), + DiscoveryV4: true, + DiscoveryV5: true, }, DBEngine: "", // Use whatever exists, will default to Pebble if non-existent and supported } @@ -90,7 +93,7 @@ func DefaultDataDir() string { // is non-empty, use it, otherwise DTRT and check %LOCALAPPDATA%. fallback := filepath.Join(home, "AppData", "Roaming", "Ethereum") appdata := windowsAppData() - if appdata == "" || isNonEmptyDir(fallback) { + if appdata == "" || common.IsNonEmptyDir(fallback) { return fallback } return filepath.Join(appdata, "Ethereum") @@ -113,16 +116,6 @@ func windowsAppData() string { return v } -func isNonEmptyDir(dir string) bool { - f, err := os.Open(dir) - if err != nil { - return false - } - names, _ := f.Readdir(1) - f.Close() - return len(names) > 0 -} - func homeDir() string { if home := os.Getenv("HOME"); home != "" { return home diff --git a/node/errors.go b/node/errors.go index 67547bf691..f9188f8d99 100644 --- a/node/errors.go +++ b/node/errors.go @@ -24,10 +24,9 @@ import ( ) var ( - ErrDatadirUsed = errors.New("datadir already used by another process") - ErrNodeStopped = errors.New("node not started") - ErrNodeRunning = errors.New("node already running") - ErrServiceUnknown = errors.New("unknown service") + ErrDatadirUsed = errors.New("datadir already used by another process") + ErrNodeStopped = errors.New("node not started") + ErrNodeRunning = errors.New("node already running") datadirInUseErrnos = map[uint]bool{11: true, 32: true, 35: true} ) diff --git a/node/node.go b/node/node.go index 62b5abc34b..f9ebb243b0 100644 --- a/node/node.go +++ b/node/node.go @@ -696,7 +696,7 @@ func (n *Node) EventMux() *event.TypeMux { return n.eventmux } -// OpenDatabase opens an existing database with the given name (or creates one if no +// OpenDatabaseWithOptions opens an existing database with the given name (or creates one if no // previous can be found) from within the node's instance directory. If the node has no // data directory, an in-memory database is returned. func (n *Node) OpenDatabaseWithOptions(name string, opt DatabaseOptions) (ethdb.Database, error) { diff --git a/node/rpcstack.go b/node/rpcstack.go index 655f7db9e4..a1cc832f9f 100644 --- a/node/rpcstack.go +++ b/node/rpcstack.go @@ -500,7 +500,7 @@ func (w *gzipResponseWriter) init() { hdr := w.resp.Header() length := hdr.Get("content-length") if len(length) > 0 { - if n, err := strconv.ParseUint(length, 10, 64); err != nil { + if n, err := strconv.ParseUint(length, 10, 64); err == nil { w.hasLength = true w.contentLength = n } diff --git a/oss-fuzz.sh b/oss-fuzz.sh index 020b6fee27..bd87665125 100644 --- a/oss-fuzz.sh +++ b/oss-fuzz.sh @@ -64,7 +64,7 @@ function compile_fuzzer() { go get github.com/holiman/gofuzz-shim/testing if [[ $SANITIZER == *coverage* ]]; then - coverbuild $path $function $fuzzer $coverpkg + coverbuild $path $function $fuzzer else gofuzz-shim --func $function --package $package -f $file -o $fuzzer.a $CXX $CXXFLAGS $LIB_FUZZING_ENGINE $fuzzer.a -o $OUT/$fuzzer diff --git a/p2p/config.go b/p2p/config.go index 68a9c0bb5f..17607a1f88 100644 --- a/p2p/config.go +++ b/p2p/config.go @@ -35,8 +35,7 @@ type Config struct { // This field must be set to a valid secp256k1 private key. PrivateKey *ecdsa.PrivateKey `toml:"-"` - // MaxPeers is the maximum number of peers that can be - // connected. It must be greater than zero. + // MaxPeers is the maximum number of peers that can be connected. MaxPeers int // MaxPendingPeers is the maximum number of peers that can be pending in the diff --git a/p2p/discover/lookup.go b/p2p/discover/lookup.go index 09808b71e0..416256fb36 100644 --- a/p2p/discover/lookup.go +++ b/p2p/discover/lookup.go @@ -27,6 +27,7 @@ import ( // lookup performs a network search for nodes close to the given target. It approaches the // target by querying nodes that are closer to it on each iteration. The given target does // not need to be an actual node identifier. +// lookup on an empty table will return immediately with no nodes. type lookup struct { tab *Table queryfunc queryFunc @@ -49,11 +50,15 @@ func newLookup(ctx context.Context, tab *Table, target enode.ID, q queryFunc) *l result: nodesByDistance{target: target}, replyCh: make(chan []*enode.Node, alpha), cancelCh: ctx.Done(), - queries: -1, } // Don't query further if we hit ourself. // Unlikely to happen often in practice. it.asked[tab.self().ID()] = true + it.seen[tab.self().ID()] = true + + // Initialize the lookup with nodes from table. + closest := it.tab.findnodeByID(it.result.target, bucketSize, false) + it.addNodes(closest.entries) return it } @@ -64,22 +69,19 @@ func (it *lookup) run() []*enode.Node { return it.result.entries } +func (it *lookup) empty() bool { + return len(it.replyBuffer) == 0 +} + // advance advances the lookup until any new nodes have been found. // It returns false when the lookup has ended. func (it *lookup) advance() bool { for it.startQueries() { select { case nodes := <-it.replyCh: - it.replyBuffer = it.replyBuffer[:0] - for _, n := range nodes { - if n != nil && !it.seen[n.ID()] { - it.seen[n.ID()] = true - it.result.push(n, bucketSize) - it.replyBuffer = append(it.replyBuffer, n) - } - } it.queries-- - if len(it.replyBuffer) > 0 { + it.addNodes(nodes) + if !it.empty() { return true } case <-it.cancelCh: @@ -89,6 +91,17 @@ func (it *lookup) advance() bool { return false } +func (it *lookup) addNodes(nodes []*enode.Node) { + it.replyBuffer = it.replyBuffer[:0] + for _, n := range nodes { + if n != nil && !it.seen[n.ID()] { + it.seen[n.ID()] = true + it.result.push(n, bucketSize) + it.replyBuffer = append(it.replyBuffer, n) + } + } +} + func (it *lookup) shutdown() { for it.queries > 0 { <-it.replyCh @@ -103,20 +116,6 @@ func (it *lookup) startQueries() bool { return false } - // The first query returns nodes from the local table. - if it.queries == -1 { - closest := it.tab.findnodeByID(it.result.target, bucketSize, false) - // Avoid finishing the lookup too quickly if table is empty. It'd be better to wait - // for the table to fill in this case, but there is no good mechanism for that - // yet. - if len(closest.entries) == 0 { - it.slowdown() - } - it.queries = 1 - it.replyCh <- closest.entries - return true - } - // Ask the closest nodes that we haven't asked yet. for i := 0; i < len(it.result.entries) && it.queries < alpha; i++ { n := it.result.entries[i] @@ -130,15 +129,6 @@ func (it *lookup) startQueries() bool { return it.queries > 0 } -func (it *lookup) slowdown() { - sleep := time.NewTimer(1 * time.Second) - defer sleep.Stop() - select { - case <-sleep.C: - case <-it.tab.closeReq: - } -} - func (it *lookup) query(n *enode.Node, reply chan<- []*enode.Node) { r, err := it.queryfunc(n) if !errors.Is(err, errClosed) { // avoid recording failures on shutdown. @@ -153,12 +143,17 @@ func (it *lookup) query(n *enode.Node, reply chan<- []*enode.Node) { // lookupIterator performs lookup operations and iterates over all seen nodes. // When a lookup finishes, a new one is created through nextLookup. +// LookupIterator waits for table initialization and triggers a table refresh +// when necessary. + type lookupIterator struct { - buffer []*enode.Node - nextLookup lookupFunc - ctx context.Context - cancel func() - lookup *lookup + buffer []*enode.Node + nextLookup lookupFunc + ctx context.Context + cancel func() + lookup *lookup + tabRefreshing <-chan struct{} + lastLookup time.Time } type lookupFunc func(ctx context.Context) *lookup @@ -182,6 +177,7 @@ func (it *lookupIterator) Next() bool { if len(it.buffer) > 0 { it.buffer = it.buffer[1:] } + // Advance the lookup to refill the buffer. for len(it.buffer) == 0 { if it.ctx.Err() != nil { @@ -190,18 +186,78 @@ func (it *lookupIterator) Next() bool { return false } if it.lookup == nil { + // Ensure enough time has passed between lookup creations. + it.slowdown() + it.lookup = it.nextLookup(it.ctx) + if it.lookup.empty() { + // If the lookup is empty right after creation, it means the local table + // is in a degraded state, and we need to wait for it to fill again. + it.lookupFailed(it.lookup.tab, 1*time.Minute) + it.lookup = nil + continue + } + // Yield the initial nodes from the iterator before advancing the lookup. + it.buffer = it.lookup.replyBuffer continue } - if !it.lookup.advance() { - it.lookup = nil - continue - } + + newNodes := it.lookup.advance() it.buffer = it.lookup.replyBuffer + if !newNodes { + it.lookup = nil + } } return true } +// lookupFailed handles failed lookup attempts. This can be called when the table has +// exited, or when it runs out of nodes. +func (it *lookupIterator) lookupFailed(tab *Table, timeout time.Duration) { + tout, cancel := context.WithTimeout(it.ctx, timeout) + defer cancel() + + // Wait for Table initialization to complete, in case it is still in progress. + select { + case <-tab.initDone: + case <-tout.Done(): + return + } + + // Wait for ongoing refresh operation, or trigger one. + if it.tabRefreshing == nil { + it.tabRefreshing = tab.refresh() + } + select { + case <-it.tabRefreshing: + it.tabRefreshing = nil + case <-tout.Done(): + return + } + + // Wait for the table to fill. + tab.waitForNodes(tout, 1) +} + +// slowdown applies a delay between creating lookups. This exists to prevent hot-spinning +// in some test environments where lookups don't yield any results. +func (it *lookupIterator) slowdown() { + const minInterval = 1 * time.Second + + now := time.Now() + diff := now.Sub(it.lastLookup) + it.lastLookup = now + if diff > minInterval { + return + } + wait := time.NewTimer(diff) + defer wait.Stop() + select { + case <-wait.C: + case <-it.ctx.Done(): + } +} + // Close ends the iterator. func (it *lookupIterator) Close() { it.cancel() diff --git a/p2p/discover/table.go b/p2p/discover/table.go index b6c35aaaa9..e5b2c7c8c5 100644 --- a/p2p/discover/table.go +++ b/p2p/discover/table.go @@ -32,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/mclock" + "github.com/ethereum/go-ethereum/event" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/metrics" "github.com/ethereum/go-ethereum/p2p/enode" @@ -53,9 +54,8 @@ const ( bucketIPLimit, bucketSubnet = 2, 24 // at most 2 addresses from the same /24 tableIPLimit, tableSubnet = 10, 24 - seedMinTableTime = 5 * time.Minute - seedCount = 30 - seedMaxAge = 5 * 24 * time.Hour + seedCount = 30 + seedMaxAge = 5 * 24 * time.Hour ) // Table is the 'node table', a Kademlia-like index of neighbor nodes. The table keeps @@ -84,6 +84,7 @@ type Table struct { closeReq chan struct{} closed chan struct{} + nodeFeed event.FeedOf[*enode.Node] nodeAddedHook func(*bucket, *tableNode) nodeRemovedHook func(*bucket, *tableNode) } @@ -567,6 +568,8 @@ func (tab *Table) nodeAdded(b *bucket, n *tableNode) { } n.addedToBucket = time.Now() tab.revalidation.nodeAdded(tab, n) + + tab.nodeFeed.Send(n.Node) if tab.nodeAddedHook != nil { tab.nodeAddedHook(b, n) } @@ -702,3 +705,38 @@ func (tab *Table) deleteNode(n *enode.Node) { b := tab.bucket(n.ID()) tab.deleteInBucket(b, n.ID()) } + +// waitForNodes blocks until the table contains at least n nodes. +func (tab *Table) waitForNodes(ctx context.Context, n int) error { + getlength := func() (count int) { + for _, b := range &tab.buckets { + count += len(b.entries) + } + return count + } + + var ch chan *enode.Node + for { + tab.mutex.Lock() + if getlength() >= n { + tab.mutex.Unlock() + return nil + } + if ch == nil { + // Init subscription. + ch = make(chan *enode.Node) + sub := tab.nodeFeed.Subscribe(ch) + defer sub.Unsubscribe() + } + tab.mutex.Unlock() + + // Wait for a node add event. + select { + case <-ch: + case <-ctx.Done(): + return ctx.Err() + case <-tab.closeReq: + return errClosed + } + } +} diff --git a/p2p/discover/v4_udp_test.go b/p2p/discover/v4_udp_test.go index 1af31f4f1b..287f0c34fa 100644 --- a/p2p/discover/v4_udp_test.go +++ b/p2p/discover/v4_udp_test.go @@ -24,10 +24,12 @@ import ( "errors" "fmt" "io" + "maps" "math/rand" "net" "net/netip" "reflect" + "slices" "sync" "testing" "time" @@ -509,18 +511,26 @@ func TestUDPv4_smallNetConvergence(t *testing.T) { // they have all found each other. status := make(chan error, len(nodes)) for i := range nodes { - node := nodes[i] + self := nodes[i] go func() { - found := make(map[enode.ID]bool, len(nodes)) - it := node.RandomNodes() + missing := make(map[enode.ID]bool, len(nodes)) + for _, n := range nodes { + if n.Self().ID() == self.Self().ID() { + continue // skip self + } + missing[n.Self().ID()] = true + } + + it := self.RandomNodes() for it.Next() { - found[it.Node().ID()] = true - if len(found) == len(nodes) { + delete(missing, it.Node().ID()) + if len(missing) == 0 { status <- nil return } } - status <- fmt.Errorf("node %s didn't find all nodes", node.Self().ID().TerminalString()) + missingIDs := slices.Collect(maps.Keys(missing)) + status <- fmt.Errorf("node %s didn't find all nodes, missing %v", self.Self().ID().TerminalString(), missingIDs) }() } @@ -537,7 +547,6 @@ func TestUDPv4_smallNetConvergence(t *testing.T) { received++ if err != nil { t.Error("ERROR:", err) - return } } } @@ -566,6 +575,13 @@ func startLocalhostV4(t *testing.T, cfg Config) *UDPv4 { if err != nil { t.Fatal(err) } + + // Wait for bootstrap to complete. + select { + case <-udp.tab.initDone: + case <-time.After(5 * time.Second): + t.Fatalf("timed out waiting for table initialization") + } return udp } diff --git a/p2p/discover/v5_udp.go b/p2p/discover/v5_udp.go index 9679f5c61a..c13032e1af 100644 --- a/p2p/discover/v5_udp.go +++ b/p2p/discover/v5_udp.go @@ -328,12 +328,6 @@ func (t *UDPv5) TalkRequestToID(id enode.ID, addr netip.AddrPort, protocol strin // RandomNodes returns an iterator that finds random nodes in the DHT. func (t *UDPv5) RandomNodes() enode.Iterator { - if t.tab.len() == 0 { - // All nodes were dropped, refresh. The very first query will hit this - // case and run the bootstrapping logic. - <-t.tab.refresh() - } - return newLookupIterator(t.closeCtx, t.newRandomLookup) } diff --git a/p2p/discover/v5_udp_test.go b/p2p/discover/v5_udp_test.go index 3a384aab12..6abe20d7a4 100644 --- a/p2p/discover/v5_udp_test.go +++ b/p2p/discover/v5_udp_test.go @@ -378,9 +378,93 @@ func TestUDPv5_findnodeCall(t *testing.T) { if !reflect.DeepEqual(response, nodes) { t.Fatalf("wrong nodes in response") } +} - // TODO: check invalid IPs - // TODO: check invalid/unsigned record +// BadIdentityScheme mocks an identity scheme not supported by the test node. +type BadIdentityScheme struct{} + +func (s BadIdentityScheme) Verify(r *enr.Record, sig []byte) error { return nil } +func (s BadIdentityScheme) NodeAddr(r *enr.Record) []byte { + var id enode.ID + r.Load(enr.WithEntry("badaddr", &id)) + return id[:] +} + +// This test covers invalid NODES responses for the FINDNODE call in a single table-driven test. +func TestUDPv5_findnodeCall_InvalidNodes(t *testing.T) { + t.Parallel() + test := newUDPV5Test(t) + defer test.close() + + for i, tt := range []struct { + name string + ip enr.Entry + port enr.Entry + sign func(r *enr.Record, id enode.ID) *enode.Node + }{ + { + name: "invalid ip (unspecified 0.0.0.0)", + ip: enr.IP(net.IPv4zero), + }, + { + name: "invalid udp port (<=1024)", + port: enr.UDP(1024), + }, + { + name: "invalid record, no signature", + sign: func(r *enr.Record, id enode.ID) *enode.Node { + r.Set(enr.ID("bad")) + r.Set(enr.WithEntry("badaddr", id)) + r.SetSig(BadIdentityScheme{}, []byte{}) + n, _ := enode.New(BadIdentityScheme{}, r) + return n + }, + }, + } { + t.Run(tt.name, func(t *testing.T) { + // Build ENR node for test. + var ( + distance = 230 + remote = test.getNode(test.remotekey, test.remoteaddr).Node() + id = idAtDistance(remote.ID(), distance) + r enr.Record + ) + r.Set(enr.IP(intIP(i))) + if tt.ip != nil { + r.Set(tt.ip) + } + r.Set(enr.UDP(30303)) + if tt.port != nil { + r.Set(tt.port) + } + r = *enode.SignNull(&r, id).Record() + if tt.sign != nil { + r = *tt.sign(&r, id).Record() + } + + // Launch findnode request. + var ( + done = make(chan error, 1) + got []*enode.Node + ) + go func() { + var err error + got, err = test.udp.Findnode(remote, []uint{uint(distance)}) + done <- err + }() + + // Handle request. + test.waitPacketOut(func(p *v5wire.Findnode, _ netip.AddrPort, _ v5wire.Nonce) { + test.packetIn(&v5wire.Nodes{ReqID: p.ReqID, RespCount: 1, Nodes: []*enr.Record{&r}}) + }) + if err := <-done; err != nil { + t.Fatalf("unexpected error: %v", err) + } + if len(got) != 0 { + t.Fatalf("expected 0 nodes, got %d", len(got)) + } + }) + } } // This test checks that pending calls are re-sent when a handshake happens. diff --git a/p2p/discover/v5wire/encoding.go b/p2p/discover/v5wire/encoding.go index ec5ef8a261..d6a30a17ca 100644 --- a/p2p/discover/v5wire/encoding.go +++ b/p2p/discover/v5wire/encoding.go @@ -27,6 +27,7 @@ import ( "errors" "fmt" "hash" + "slices" "github.com/ethereum/go-ethereum/common/mclock" "github.com/ethereum/go-ethereum/p2p/enode" @@ -222,7 +223,7 @@ func (c *Codec) Encode(id enode.ID, addr string, packet Packet, challenge *Whoar // Store sent WHOAREYOU challenges. if challenge, ok := packet.(*Whoareyou); ok { - challenge.ChallengeData = bytesCopy(&c.buf) + challenge.ChallengeData = slices.Clone(c.buf.Bytes()) enc, err := c.EncodeRaw(id, head, msgData) if err != nil { return nil, Nonce{}, err @@ -325,7 +326,6 @@ func (c *Codec) encodeWhoareyou(toID enode.ID, packet *Whoareyou) (Header, error // Create header. head := c.makeHeader(toID, flagWhoareyou, 0) - head.AuthData = bytesCopy(&c.buf) head.Nonce = packet.Nonce // Encode auth data. @@ -430,7 +430,7 @@ func (c *Codec) encodeMessageHeader(toID enode.ID, s *session) (Header, error) { auth := messageAuthData{SrcID: c.localnode.ID()} c.buf.Reset() binary.Write(&c.buf, binary.BigEndian, &auth) - head.AuthData = bytesCopy(&c.buf) + head.AuthData = slices.Clone(c.buf.Bytes()) head.Nonce = nonce return head, err } @@ -686,9 +686,3 @@ func (h *Header) mask(destID enode.ID) cipher.Stream { } return cipher.NewCTR(block, h.IV[:]) } - -func bytesCopy(r *bytes.Buffer) []byte { - b := make([]byte, r.Len()) - copy(b, r.Bytes()) - return b -} diff --git a/p2p/discover/v5wire/encoding_test.go b/p2p/discover/v5wire/encoding_test.go index 2304d0f132..5774cb3d8c 100644 --- a/p2p/discover/v5wire/encoding_test.go +++ b/p2p/discover/v5wire/encoding_test.go @@ -477,10 +477,9 @@ func BenchmarkV5_DecodeHandshakePingSecp256k1(b *testing.B) { b.Fatal("can't encode handshake packet") } challenge.Node = nil // force ENR signature verification in decoder - b.ResetTimer() input := make([]byte, len(enc)) - for i := 0; i < b.N; i++ { + for b.Loop() { copy(input, enc) net.nodeB.c.sc.storeSentHandshake(idA, "", challenge) _, _, _, err := net.nodeB.c.Decode(input, "") @@ -507,10 +506,9 @@ func BenchmarkV5_DecodePing(b *testing.B) { if err != nil { b.Fatalf("can't encode: %v", err) } - b.ResetTimer() input := make([]byte, len(enc)) - for i := 0; i < b.N; i++ { + for b.Loop() { copy(input, enc) _, _, packet, _ := net.nodeB.c.Decode(input, addrB) if _, ok := packet.(*Ping); !ok { diff --git a/p2p/enode/iter.go b/p2p/enode/iter.go index f8f79a9436..54c2fc7258 100644 --- a/p2p/enode/iter.go +++ b/p2p/enode/iter.go @@ -38,7 +38,7 @@ type SourceIterator interface { NodeSource() string // source of current node } -// WithSource attaches a 'source name' to an iterator. +// WithSourceName attaches a 'source name' to an iterator. func WithSourceName(name string, it Iterator) SourceIterator { return sourceIter{it, name} } @@ -174,11 +174,12 @@ type AsyncFilterFunc func(context.Context, *Node) *Node // AsyncFilter creates an iterator which checks nodes in parallel. // The 'check' function is called on multiple goroutines to filter each node // from the upstream iterator. When check returns nil, the node will be skipped. -// It can also return a new node to be returned by the iterator instead of the . +// It can also return a new node to be returned by the iterator instead of the +// original one. func AsyncFilter(it Iterator, check AsyncFilterFunc, workers int) Iterator { f := &asyncFilterIter{ it: ensureSourceIter(it), - slots: make(chan struct{}, workers+1), + slots: make(chan struct{}, workers+1), // extra 1 slot to make sure all the goroutines can be completed passed: make(chan iteratorItem), } for range cap(f.slots) { @@ -193,6 +194,9 @@ func AsyncFilter(it Iterator, check AsyncFilterFunc, workers int) Iterator { return case <-f.slots: } + defer func() { + f.slots <- struct{}{} // the iterator has ended + }() // read from the iterator and start checking nodes in parallel // when a node is checked, it will be sent to the passed channel // and the slot will be released @@ -201,7 +205,11 @@ func AsyncFilter(it Iterator, check AsyncFilterFunc, workers int) Iterator { nodeSource := f.it.NodeSource() // check the node async, in a separate goroutine - <-f.slots + select { + case <-ctx.Done(): + return + case <-f.slots: + } go func() { if nn := check(ctx, node); nn != nil { item := iteratorItem{nn, nodeSource} @@ -213,8 +221,6 @@ func AsyncFilter(it Iterator, check AsyncFilterFunc, workers int) Iterator { f.slots <- struct{}{} }() } - // the iterator has ended - f.slots <- struct{}{} }() return f diff --git a/p2p/enode/iter_test.go b/p2p/enode/iter_test.go index 577f9c2825..922e1cde19 100644 --- a/p2p/enode/iter_test.go +++ b/p2p/enode/iter_test.go @@ -45,7 +45,7 @@ func TestReadNodesCycle(t *testing.T) { nodes := ReadNodes(iter, 10) checkNodes(t, nodes, 3) if iter.count != 10 { - t.Fatalf("%d calls to Next, want %d", iter.count, 100) + t.Fatalf("%d calls to Next, want %d", iter.count, 10) } } diff --git a/p2p/enode/localnode.go b/p2p/enode/localnode.go index d8fa6a9202..6425560b02 100644 --- a/p2p/enode/localnode.go +++ b/p2p/enode/localnode.go @@ -305,12 +305,3 @@ func (ln *LocalNode) bumpSeq() { ln.seq++ ln.db.storeLocalSeq(ln.id, ln.seq) } - -// nowMilliseconds gives the current timestamp at millisecond precision. -func nowMilliseconds() uint64 { - ns := time.Now().UnixNano() - if ns < 0 { - return 0 - } - return uint64(ns / 1000 / 1000) -} diff --git a/p2p/enode/localnode_test.go b/p2p/enode/localnode_test.go index 86b962a74e..5ddc302d65 100644 --- a/p2p/enode/localnode_test.go +++ b/p2p/enode/localnode_test.go @@ -21,6 +21,7 @@ import ( "net" "net/netip" "testing" + "time" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/p2p/enr" @@ -53,7 +54,7 @@ func TestLocalNode(t *testing.T) { // This test checks that the sequence number is persisted between restarts. func TestLocalNodeSeqPersist(t *testing.T) { - timestamp := nowMilliseconds() + timestamp := uint64(time.Now().UnixMilli()) ln, db := newLocalNodeForTesting() defer db.Close() diff --git a/p2p/enode/node.go b/p2p/enode/node.go index d6f2ac7ff5..dafde51d6a 100644 --- a/p2p/enode/node.go +++ b/p2p/enode/node.go @@ -19,6 +19,7 @@ package enode import ( "crypto/ecdsa" "encoding/base64" + "encoding/binary" "encoding/hex" "errors" "fmt" @@ -358,9 +359,10 @@ func ParseID(in string) (ID, error) { // Returns -1 if a is closer to target, 1 if b is closer to target // and 0 if they are equal. func DistCmp(target, a, b ID) int { - for i := range target { - da := a[i] ^ target[i] - db := b[i] ^ target[i] + for i := 0; i < len(target); i += 8 { + tn := binary.BigEndian.Uint64(target[i : i+8]) + da := tn ^ binary.BigEndian.Uint64(a[i:i+8]) + db := tn ^ binary.BigEndian.Uint64(b[i:i+8]) if da > db { return 1 } else if da < db { @@ -373,12 +375,14 @@ func DistCmp(target, a, b ID) int { // LogDist returns the logarithmic distance between a and b, log2(a ^ b). func LogDist(a, b ID) int { lz := 0 - for i := range a { - x := a[i] ^ b[i] + for i := 0; i < len(a); i += 8 { + ai := binary.BigEndian.Uint64(a[i : i+8]) + bi := binary.BigEndian.Uint64(b[i : i+8]) + x := ai ^ bi if x == 0 { - lz += 8 + lz += 64 } else { - lz += bits.LeadingZeros8(x) + lz += bits.LeadingZeros64(x) break } } diff --git a/p2p/enode/node_test.go b/p2p/enode/node_test.go index e9fe631f34..51bc4ebe15 100644 --- a/p2p/enode/node_test.go +++ b/p2p/enode/node_test.go @@ -368,6 +368,16 @@ func TestID_distcmpEqual(t *testing.T) { } } +func BenchmarkDistCmp(b *testing.B) { + base := ID{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + aID := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0} + bID := ID{15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 1} + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = DistCmp(base, aID, bID) + } +} + func TestID_logdist(t *testing.T) { logdistBig := func(a, b ID) int { abig, bbig := new(big.Int).SetBytes(a[:]), new(big.Int).SetBytes(b[:]) @@ -378,6 +388,28 @@ func TestID_logdist(t *testing.T) { } } +func makeIDs() (ID, ID) { + var a, b ID + size := len(a) + // last byte differs + for i := 0; i < size-1; i++ { + a[i] = 0xAA + b[i] = 0xAA + } + a[size-1] = 0xAA + b[size-1] = 0xAB + return a, b +} + +// Benchmark LogDist +func BenchmarkLogDist(b *testing.B) { + aID, bID := makeIDs() // 256-bit ID + b.ResetTimer() + for i := 0; i < b.N; i++ { + _ = LogDist(aID, bID) + } +} + // The random tests is likely to miss the case where a and b are equal, // this test checks it explicitly. func TestID_logdistEqual(t *testing.T) { diff --git a/p2p/enode/nodedb.go b/p2p/enode/nodedb.go index 51e554e68a..2cd211e2c2 100644 --- a/p2p/enode/nodedb.go +++ b/p2p/enode/nodedb.go @@ -434,7 +434,7 @@ func (db *DB) localSeq(id ID) uint64 { if seq := db.fetchUint64(localItemKey(id, dbLocalSeq)); seq > 0 { return seq } - return nowMilliseconds() + return uint64(time.Now().UnixMilli()) } // storeLocalSeq stores the local record sequence counter. diff --git a/p2p/msgrate/msgrate.go b/p2p/msgrate/msgrate.go index de1a3177db..7702256ed4 100644 --- a/p2p/msgrate/msgrate.go +++ b/p2p/msgrate/msgrate.go @@ -171,8 +171,7 @@ func (t *Tracker) Capacity(kind uint64, targetRTT time.Duration) int { // roundCapacity gives the integer value of a capacity. // The result fits int32, and is guaranteed to be positive. func roundCapacity(cap float64) int { - const maxInt32 = float64(1<<31 - 1) - return int(math.Min(maxInt32, math.Max(1, math.Ceil(cap)))) + return int(min(math.MaxInt32, max(1, math.Ceil(cap)))) } // Update modifies the peer's capacity values for a specific data type with a new diff --git a/p2p/nat/natupnp.go b/p2p/nat/natupnp.go index d79677db55..b9570e561f 100644 --- a/p2p/nat/natupnp.go +++ b/p2p/nat/natupnp.go @@ -107,30 +107,30 @@ func (n *upnp) addAnyPortMapping(protocol string, extport, intport int, ip net.I }) } // For IGDv1 and v1 services we should first try to add with extport. + var lastErr error for i := 0; i < retryCount+1; i++ { - err := n.withRateLimit(func() error { + lastErr = n.withRateLimit(func() error { return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) }) - if err == nil { + if lastErr == nil { return uint16(extport), nil } - log.Debug("Failed to add port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", err) + log.Debug("Failed to add port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", lastErr) } // If above fails, we retry with a random port. // We retry several times because of possible port conflicts. - var err error for i := 0; i < randomCount; i++ { extport = n.randomPort() - err := n.withRateLimit(func() error { + lastErr = n.withRateLimit(func() error { return n.client.AddPortMapping("", uint16(extport), protocol, uint16(intport), ip.String(), true, desc, lifetimeS) }) - if err == nil { + if lastErr == nil { return uint16(extport), nil } - log.Debug("Failed to add random port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", err) + log.Debug("Failed to add random port mapping", "protocol", protocol, "extport", extport, "intport", intport, "err", lastErr) } - return 0, err + return 0, lastErr } func (n *upnp) randomPort() int { diff --git a/p2p/netutil/net_test.go b/p2p/netutil/net_test.go index 569c7ac454..8c810f494f 100644 --- a/p2p/netutil/net_test.go +++ b/p2p/netutil/net_test.go @@ -187,7 +187,7 @@ func TestCheckRelayIP(t *testing.T) { func BenchmarkCheckRelayIP(b *testing.B) { sender := parseIP("23.55.1.242") addr := parseIP("23.55.1.2") - for i := 0; i < b.N; i++ { + for b.Loop() { CheckRelayIP(sender, addr) } } diff --git a/p2p/peer.go b/p2p/peer.go index 9a0a750ac8..5521889f30 100644 --- a/p2p/peer.go +++ b/p2p/peer.go @@ -173,7 +173,6 @@ func (p *Peer) Fullname() string { // Caps returns the capabilities (supported subprotocols) of the remote peer. func (p *Peer) Caps() []Cap { - // TODO: maybe return copy return p.rw.caps } diff --git a/p2p/rlpx/rlpx.go b/p2p/rlpx/rlpx.go index c074534d4d..0dc4ecbe2d 100644 --- a/p2p/rlpx/rlpx.go +++ b/p2p/rlpx/rlpx.go @@ -24,6 +24,7 @@ import ( "crypto/ecdsa" "crypto/hmac" "crypto/rand" + "crypto/subtle" "encoding/binary" "errors" "fmt" @@ -33,7 +34,6 @@ import ( "net" "time" - "github.com/ethereum/go-ethereum/common/bitutil" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/crypto/ecies" "github.com/ethereum/go-ethereum/rlp" @@ -677,6 +677,6 @@ func exportPubkey(pub *ecies.PublicKey) []byte { func xor(one, other []byte) (xor []byte) { xor = make([]byte, len(one)) - bitutil.XORBytes(xor, one, other) + subtle.XORBytes(xor, one, other) return xor } diff --git a/p2p/rlpx/rlpx_test.go b/p2p/rlpx/rlpx_test.go index 27d51546e7..a02c1dc2cc 100644 --- a/p2p/rlpx/rlpx_test.go +++ b/p2p/rlpx/rlpx_test.go @@ -369,8 +369,7 @@ func TestHandshakeForwardCompatibility(t *testing.T) { func BenchmarkHandshakeRead(b *testing.B) { var input = unhex(eip8HandshakeAuthTests[0].input) - - for i := 0; i < b.N; i++ { + for b.Loop() { var ( h handshakeState r = bytes.NewReader(input) @@ -427,7 +426,7 @@ func BenchmarkThroughput(b *testing.B) { // Read N messages. b.SetBytes(int64(len(msgdata))) b.ReportAllocs() - for i := 0; i < b.N; i++ { + for b.Loop() { _, _, _, err := conn2.Read() if err != nil { b.Fatal("read error:", err) diff --git a/p2p/server.go b/p2p/server.go index 1f859089af..10c855f1c4 100644 --- a/p2p/server.go +++ b/p2p/server.go @@ -490,6 +490,11 @@ func (srv *Server) setupDiscovery() error { } srv.discv5, err = discover.ListenV5(sconn, srv.localnode, cfg) if err != nil { + // Clean up v4 if v5 setup fails. + if srv.discv4 != nil { + srv.discv4.Close() + srv.discv4 = nil + } return err } } @@ -813,7 +818,9 @@ func (srv *Server) listenLoop() { time.Sleep(time.Millisecond * 200) continue } else if err != nil { - srv.log.Debug("Read error", "err", err) + if !errors.Is(err, net.ErrClosed) { + srv.log.Debug("Read error", "err", err) + } slots <- struct{}{} return } diff --git a/p2p/server_test.go b/p2p/server_test.go index d42926cf4c..7bc7379099 100644 --- a/p2p/server_test.go +++ b/p2p/server_test.go @@ -579,6 +579,33 @@ func TestServerInboundThrottle(t *testing.T) { } } +func TestServerDiscoveryV5FailureRollsBackV4(t *testing.T) { + badBootstrap := enode.NewV4(&newkey().PublicKey, net.ParseIP("127.0.0.1"), 30303, 0) // invalid V5 of a V4 node + srv := &Server{ + Config: Config{ + PrivateKey: newkey(), + ListenAddr: "", + DiscAddr: "127.0.0.1:0", + MaxPeers: 5, + DiscoveryV4: true, + DiscoveryV5: true, + BootstrapNodesV5: []*enode.Node{badBootstrap}, + Logger: testlog.Logger(t, log.LvlTrace), + }, + } + err := srv.Start() + if err == nil { + t.Fatal("expected discovery v5 startup failure") + } + if !strings.Contains(err.Error(), "bad bootstrap node") { + t.Fatalf("unexpected error: %v", err) + } + if srv.DiscoveryV4() != nil { + t.Fatal("discovery v4 not cleaned after failure") + } + srv.Stop() +} + func listenFakeAddr(network, laddr string, remoteAddr net.Addr) (net.Listener, error) { l, err := net.Listen(network, laddr) if err == nil { diff --git a/p2p/tracker/tracker.go b/p2p/tracker/tracker.go index 5b72eb2b88..a1cf6f1119 100644 --- a/p2p/tracker/tracker.go +++ b/p2p/tracker/tracker.go @@ -185,9 +185,10 @@ func (t *Tracker) Fulfil(peer string, version uint, code uint64, id uint64) { return } // Everything matches, mark the request serviced and meter it + wasHead := req.expire.Prev() == nil t.expire.Remove(req.expire) delete(t.pending, id) - if req.expire.Prev() == nil { + if wasHead { if t.wake.Stop() { t.schedule() } diff --git a/params/config.go b/params/config.go index 85619bbe22..c5dfad1cd3 100644 --- a/params/config.go +++ b/params/config.go @@ -61,11 +61,17 @@ var ( ShanghaiTime: newUint64(1681338455), CancunTime: newUint64(1710338135), PragueTime: newUint64(1746612311), + OsakaTime: newUint64(1764798551), + BPO1Time: newUint64(1765290071), + BPO2Time: newUint64(1767747671), DepositContractAddress: common.HexToAddress("0x00000000219ab540356cbb839cbe05303d7705fa"), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfig, + Osaka: DefaultOsakaBlobConfig, + BPO1: DefaultBPO1BlobConfig, + BPO2: DefaultBPO2BlobConfig, }, } // HoleskyChainConfig contains the chain parameters to run a node on the Holesky test network. @@ -91,11 +97,17 @@ var ( ShanghaiTime: newUint64(1696000704), CancunTime: newUint64(1707305664), PragueTime: newUint64(1740434112), + OsakaTime: newUint64(1759308480), + BPO1Time: newUint64(1759800000), + BPO2Time: newUint64(1760389824), DepositContractAddress: common.HexToAddress("0x4242424242424242424242424242424242424242"), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfig, + Osaka: DefaultOsakaBlobConfig, + BPO1: DefaultBPO1BlobConfig, + BPO2: DefaultBPO2BlobConfig, }, } // SepoliaChainConfig contains the chain parameters to run a node on the Sepolia test network. @@ -121,11 +133,17 @@ var ( ShanghaiTime: newUint64(1677557088), CancunTime: newUint64(1706655072), PragueTime: newUint64(1741159776), + OsakaTime: newUint64(1760427360), + BPO1Time: newUint64(1761017184), + BPO2Time: newUint64(1761607008), DepositContractAddress: common.HexToAddress("0x7f02c3e3c98b133055b8b348b2ac625669ed295d"), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfig, + Osaka: DefaultOsakaBlobConfig, + BPO1: DefaultBPO1BlobConfig, + BPO2: DefaultBPO2BlobConfig, }, } // HoodiChainConfig contains the chain parameters to run a node on the Hoodi test network. @@ -151,11 +169,17 @@ var ( ShanghaiTime: newUint64(0), CancunTime: newUint64(0), PragueTime: newUint64(1742999832), + OsakaTime: newUint64(1761677592), + BPO1Time: newUint64(1762365720), + BPO2Time: newUint64(1762955544), DepositContractAddress: common.HexToAddress("0x00000000219ab540356cBB839Cbe05303d7705Fa"), Ethash: new(EthashConfig), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfig, + Osaka: DefaultOsakaBlobConfig, + BPO1: DefaultBPO1BlobConfig, + BPO2: DefaultBPO2BlobConfig, }, } // AllEthashProtocolChanges contains every protocol change (EIPs) introduced @@ -207,9 +231,11 @@ var ( CancunTime: newUint64(0), TerminalTotalDifficulty: big.NewInt(0), PragueTime: newUint64(0), + OsakaTime: newUint64(0), BlobScheduleConfig: &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, Prague: DefaultPragueBlobConfig, + Osaka: DefaultOsakaBlobConfig, }, } @@ -359,6 +385,30 @@ var ( Max: 9, UpdateFraction: 5007716, } + // DefaultBPO1BlobConfig is the default blob configuration for the BPO1 fork. + DefaultBPO1BlobConfig = &BlobConfig{ + Target: 10, + Max: 15, + UpdateFraction: 8346193, + } + // DefaultBPO2BlobConfig is the default blob configuration for the BPO2 fork. + DefaultBPO2BlobConfig = &BlobConfig{ + Target: 14, + Max: 21, + UpdateFraction: 11684671, + } + // DefaultBPO3BlobConfig is the default blob configuration for the BPO3 fork. + DefaultBPO3BlobConfig = &BlobConfig{ + Target: 21, + Max: 32, + UpdateFraction: 20609697, + } + // DefaultBPO4BlobConfig is the default blob configuration for the BPO4 fork. + DefaultBPO4BlobConfig = &BlobConfig{ + Target: 14, + Max: 21, + UpdateFraction: 13739630, + } // DefaultBlobSchedule is the latest configured blob schedule for Ethereum mainnet. DefaultBlobSchedule = &BlobScheduleConfig{ Cancun: DefaultCancunBlobConfig, @@ -406,16 +456,17 @@ type ChainConfig struct { // Fork scheduling was switched from blocks to timestamps here - ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) - CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) - PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) - OsakaTime *uint64 `json:"osakaTime,omitempty"` // Osaka switch time (nil = no fork, 0 = already on osaka) - VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle) - BPO1Time *uint64 `json:"bpo1Time,omitempty"` // BPO1 switch time (nil = no fork, 0 = already on bpo1) - BPO2Time *uint64 `json:"bpo2Time,omitempty"` // BPO2 switch time (nil = no fork, 0 = already on bpo2) - BPO3Time *uint64 `json:"bpo3Time,omitempty"` // BPO3 switch time (nil = no fork, 0 = already on bpo3) - BPO4Time *uint64 `json:"bpo4Time,omitempty"` // BPO4 switch time (nil = no fork, 0 = already on bpo4) - BPO5Time *uint64 `json:"bpo5Time,omitempty"` // BPO5 switch time (nil = no fork, 0 = already on bpo5) + ShanghaiTime *uint64 `json:"shanghaiTime,omitempty"` // Shanghai switch time (nil = no fork, 0 = already on shanghai) + CancunTime *uint64 `json:"cancunTime,omitempty"` // Cancun switch time (nil = no fork, 0 = already on cancun) + PragueTime *uint64 `json:"pragueTime,omitempty"` // Prague switch time (nil = no fork, 0 = already on prague) + OsakaTime *uint64 `json:"osakaTime,omitempty"` // Osaka switch time (nil = no fork, 0 = already on osaka) + BPO1Time *uint64 `json:"bpo1Time,omitempty"` // BPO1 switch time (nil = no fork, 0 = already on bpo1) + BPO2Time *uint64 `json:"bpo2Time,omitempty"` // BPO2 switch time (nil = no fork, 0 = already on bpo2) + BPO3Time *uint64 `json:"bpo3Time,omitempty"` // BPO3 switch time (nil = no fork, 0 = already on bpo3) + BPO4Time *uint64 `json:"bpo4Time,omitempty"` // BPO4 switch time (nil = no fork, 0 = already on bpo4) + BPO5Time *uint64 `json:"bpo5Time,omitempty"` // BPO5 switch time (nil = no fork, 0 = already on bpo5) + AmsterdamTime *uint64 `json:"amsterdamTime,omitempty"` // Amsterdam switch time (nil = no fork, 0 = already on amsterdam) + VerkleTime *uint64 `json:"verkleTime,omitempty"` // Verkle switch time (nil = no fork, 0 = already on verkle) // TerminalTotalDifficulty is the amount of total difficulty reached by // the network that triggers the consensus upgrade. @@ -461,6 +512,96 @@ func (c CliqueConfig) String() string { return fmt.Sprintf("clique(period: %d, epoch: %d)", c.Period, c.Epoch) } +// String implements the fmt.Stringer interface, returning a string representation +// of ChainConfig. +func (c *ChainConfig) String() string { + result := fmt.Sprintf("ChainConfig{ChainID: %v", c.ChainID) + + // Add block-based forks + if c.HomesteadBlock != nil { + result += fmt.Sprintf(", HomesteadBlock: %v", c.HomesteadBlock) + } + if c.DAOForkBlock != nil { + result += fmt.Sprintf(", DAOForkBlock: %v", c.DAOForkBlock) + } + if c.EIP150Block != nil { + result += fmt.Sprintf(", EIP150Block: %v", c.EIP150Block) + } + if c.EIP155Block != nil { + result += fmt.Sprintf(", EIP155Block: %v", c.EIP155Block) + } + if c.EIP158Block != nil { + result += fmt.Sprintf(", EIP158Block: %v", c.EIP158Block) + } + if c.ByzantiumBlock != nil { + result += fmt.Sprintf(", ByzantiumBlock: %v", c.ByzantiumBlock) + } + if c.ConstantinopleBlock != nil { + result += fmt.Sprintf(", ConstantinopleBlock: %v", c.ConstantinopleBlock) + } + if c.PetersburgBlock != nil { + result += fmt.Sprintf(", PetersburgBlock: %v", c.PetersburgBlock) + } + if c.IstanbulBlock != nil { + result += fmt.Sprintf(", IstanbulBlock: %v", c.IstanbulBlock) + } + if c.MuirGlacierBlock != nil { + result += fmt.Sprintf(", MuirGlacierBlock: %v", c.MuirGlacierBlock) + } + if c.BerlinBlock != nil { + result += fmt.Sprintf(", BerlinBlock: %v", c.BerlinBlock) + } + if c.LondonBlock != nil { + result += fmt.Sprintf(", LondonBlock: %v", c.LondonBlock) + } + if c.ArrowGlacierBlock != nil { + result += fmt.Sprintf(", ArrowGlacierBlock: %v", c.ArrowGlacierBlock) + } + if c.GrayGlacierBlock != nil { + result += fmt.Sprintf(", GrayGlacierBlock: %v", c.GrayGlacierBlock) + } + if c.MergeNetsplitBlock != nil { + result += fmt.Sprintf(", MergeNetsplitBlock: %v", c.MergeNetsplitBlock) + } + + // Add timestamp-based forks + if c.ShanghaiTime != nil { + result += fmt.Sprintf(", ShanghaiTime: %v", *c.ShanghaiTime) + } + if c.CancunTime != nil { + result += fmt.Sprintf(", CancunTime: %v", *c.CancunTime) + } + if c.PragueTime != nil { + result += fmt.Sprintf(", PragueTime: %v", *c.PragueTime) + } + if c.OsakaTime != nil { + result += fmt.Sprintf(", OsakaTime: %v", *c.OsakaTime) + } + if c.BPO1Time != nil { + result += fmt.Sprintf(", BPO1Time: %v", *c.BPO1Time) + } + if c.BPO2Time != nil { + result += fmt.Sprintf(", BPO2Time: %v", *c.BPO2Time) + } + if c.BPO3Time != nil { + result += fmt.Sprintf(", BPO3Time: %v", *c.BPO3Time) + } + if c.BPO4Time != nil { + result += fmt.Sprintf(", BPO4Time: %v", *c.BPO4Time) + } + if c.BPO5Time != nil { + result += fmt.Sprintf(", BPO5Time: %v", *c.BPO5Time) + } + if c.AmsterdamTime != nil { + result += fmt.Sprintf(", AmsterdamTime: %v", *c.AmsterdamTime) + } + if c.VerkleTime != nil { + result += fmt.Sprintf(", VerkleTime: %v", *c.VerkleTime) + } + result += "}" + return result +} + // Description returns a human-readable description of ChainConfig. func (c *ChainConfig) Description() string { var banner string @@ -485,34 +626,32 @@ func (c *ChainConfig) Description() string { // makes sense for mainnet should be optional at printing to avoid bloating // the output for testnets and private networks. banner += "Pre-Merge hard forks (block based):\n" - banner += fmt.Sprintf(" - Homestead: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/homestead.md)\n", c.HomesteadBlock) + banner += fmt.Sprintf(" - Homestead: #%-8v\n", c.HomesteadBlock) if c.DAOForkBlock != nil { - banner += fmt.Sprintf(" - DAO Fork: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/dao-fork.md)\n", c.DAOForkBlock) + banner += fmt.Sprintf(" - DAO Fork: #%-8v\n", c.DAOForkBlock) } - banner += fmt.Sprintf(" - Tangerine Whistle (EIP 150): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/tangerine-whistle.md)\n", c.EIP150Block) - banner += fmt.Sprintf(" - Spurious Dragon/1 (EIP 155): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.EIP155Block) - banner += fmt.Sprintf(" - Spurious Dragon/2 (EIP 158): #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/spurious-dragon.md)\n", c.EIP155Block) - banner += fmt.Sprintf(" - Byzantium: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/byzantium.md)\n", c.ByzantiumBlock) - banner += fmt.Sprintf(" - Constantinople: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/constantinople.md)\n", c.ConstantinopleBlock) - banner += fmt.Sprintf(" - Petersburg: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/petersburg.md)\n", c.PetersburgBlock) - banner += fmt.Sprintf(" - Istanbul: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/istanbul.md)\n", c.IstanbulBlock) + banner += fmt.Sprintf(" - Tangerine Whistle (EIP 150): #%-8v\n", c.EIP150Block) + banner += fmt.Sprintf(" - Spurious Dragon/1 (EIP 155): #%-8v\n", c.EIP155Block) + banner += fmt.Sprintf(" - Spurious Dragon/2 (EIP 158): #%-8v\n", c.EIP158Block) + banner += fmt.Sprintf(" - Byzantium: #%-8v\n", c.ByzantiumBlock) + banner += fmt.Sprintf(" - Constantinople: #%-8v\n", c.ConstantinopleBlock) + banner += fmt.Sprintf(" - Petersburg: #%-8v\n", c.PetersburgBlock) + banner += fmt.Sprintf(" - Istanbul: #%-8v\n", c.IstanbulBlock) if c.MuirGlacierBlock != nil { - banner += fmt.Sprintf(" - Muir Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/muir-glacier.md)\n", c.MuirGlacierBlock) + banner += fmt.Sprintf(" - Muir Glacier: #%-8v\n", c.MuirGlacierBlock) } - banner += fmt.Sprintf(" - Berlin: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/berlin.md)\n", c.BerlinBlock) - banner += fmt.Sprintf(" - London: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/london.md)\n", c.LondonBlock) + banner += fmt.Sprintf(" - Berlin: #%-8v\n", c.BerlinBlock) + banner += fmt.Sprintf(" - London: #%-8v\n", c.LondonBlock) if c.ArrowGlacierBlock != nil { - banner += fmt.Sprintf(" - Arrow Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/arrow-glacier.md)\n", c.ArrowGlacierBlock) + banner += fmt.Sprintf(" - Arrow Glacier: #%-8v\n", c.ArrowGlacierBlock) } if c.GrayGlacierBlock != nil { - banner += fmt.Sprintf(" - Gray Glacier: #%-8v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/gray-glacier.md)\n", c.GrayGlacierBlock) + banner += fmt.Sprintf(" - Gray Glacier: #%-8v\n", c.GrayGlacierBlock) } banner += "\n" // Add a special section for the merge as it's non-obvious banner += "Merge configured:\n" - banner += " - Hard-fork specification: https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/paris.md\n" - banner += " - Network known to be merged\n" banner += fmt.Sprintf(" - Total terminal difficulty: %v\n", c.TerminalTotalDifficulty) if c.MergeNetsplitBlock != nil { banner += fmt.Sprintf(" - Merge netsplit block: #%-8v\n", c.MergeNetsplitBlock) @@ -522,35 +661,39 @@ func (c *ChainConfig) Description() string { // Create a list of forks post-merge banner += "Post-Merge hard forks (timestamp based):\n" if c.ShanghaiTime != nil { - banner += fmt.Sprintf(" - Shanghai: @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/shanghai.md)\n", *c.ShanghaiTime) + banner += fmt.Sprintf(" - Shanghai: @%-10v\n", *c.ShanghaiTime) } if c.CancunTime != nil { - banner += fmt.Sprintf(" - Cancun: @%-10v (https://github.com/ethereum/execution-specs/blob/master/network-upgrades/mainnet-upgrades/cancun.md)\n", *c.CancunTime) + banner += fmt.Sprintf(" - Cancun: @%-10v blob: (%s)\n", *c.CancunTime, c.BlobScheduleConfig.Cancun) } if c.PragueTime != nil { - banner += fmt.Sprintf(" - Prague: @%-10v\n", *c.PragueTime) + banner += fmt.Sprintf(" - Prague: @%-10v blob: (%s)\n", *c.PragueTime, c.BlobScheduleConfig.Prague) } if c.OsakaTime != nil { - banner += fmt.Sprintf(" - Osaka: @%-10v\n", *c.OsakaTime) - } - if c.VerkleTime != nil { - banner += fmt.Sprintf(" - Verkle: @%-10v\n", *c.VerkleTime) + banner += fmt.Sprintf(" - Osaka: @%-10v blob: (%s)\n", *c.OsakaTime, c.BlobScheduleConfig.Osaka) } if c.BPO1Time != nil { - banner += fmt.Sprintf(" - BPO1: @%-10v\n", *c.BPO1Time) + banner += fmt.Sprintf(" - BPO1: @%-10v blob: (%s)\n", *c.BPO1Time, c.BlobScheduleConfig.BPO1) } if c.BPO2Time != nil { - banner += fmt.Sprintf(" - BPO2: @%-10v\n", *c.BPO2Time) + banner += fmt.Sprintf(" - BPO2: @%-10v blob: (%s)\n", *c.BPO2Time, c.BlobScheduleConfig.BPO2) } if c.BPO3Time != nil { - banner += fmt.Sprintf(" - BPO3: @%-10v\n", *c.BPO3Time) + banner += fmt.Sprintf(" - BPO3: @%-10v blob: (%s)\n", *c.BPO3Time, c.BlobScheduleConfig.BPO3) } if c.BPO4Time != nil { - banner += fmt.Sprintf(" - BPO4: @%-10v\n", *c.BPO4Time) + banner += fmt.Sprintf(" - BPO4: @%-10v blob: (%s)\n", *c.BPO4Time, c.BlobScheduleConfig.BPO4) } if c.BPO5Time != nil { - banner += fmt.Sprintf(" - BPO5: @%-10v\n", *c.BPO5Time) + banner += fmt.Sprintf(" - BPO5: @%-10v blob: (%s)\n", *c.BPO5Time, c.BlobScheduleConfig.BPO5) } + if c.AmsterdamTime != nil { + banner += fmt.Sprintf(" - Amsterdam: @%-10v blob: (%s)\n", *c.AmsterdamTime, c.BlobScheduleConfig.Amsterdam) + } + if c.VerkleTime != nil { + banner += fmt.Sprintf(" - Verkle: @%-10v blob: (%s)\n", *c.VerkleTime, c.BlobScheduleConfig.Verkle) + } + banner += fmt.Sprintf("\nAll fork specifications can be found at https://ethereum.github.io/execution-specs/src/ethereum/forks/\n") return banner } @@ -561,17 +704,26 @@ type BlobConfig struct { UpdateFraction uint64 `json:"baseFeeUpdateFraction"` } +// String implement fmt.Stringer, returning string format blob config. +func (bc *BlobConfig) String() string { + if bc == nil { + return "nil" + } + return fmt.Sprintf("target: %d, max: %d, fraction: %d", bc.Target, bc.Max, bc.UpdateFraction) +} + // BlobScheduleConfig determines target and max number of blobs allow per fork. type BlobScheduleConfig struct { - Cancun *BlobConfig `json:"cancun,omitempty"` - Prague *BlobConfig `json:"prague,omitempty"` - Osaka *BlobConfig `json:"osaka,omitempty"` - Verkle *BlobConfig `json:"verkle,omitempty"` - BPO1 *BlobConfig `json:"bpo1,omitempty"` - BPO2 *BlobConfig `json:"bpo2,omitempty"` - BPO3 *BlobConfig `json:"bpo3,omitempty"` - BPO4 *BlobConfig `json:"bpo4,omitempty"` - BPO5 *BlobConfig `json:"bpo5,omitempty"` + Cancun *BlobConfig `json:"cancun,omitempty"` + Prague *BlobConfig `json:"prague,omitempty"` + Osaka *BlobConfig `json:"osaka,omitempty"` + Verkle *BlobConfig `json:"verkle,omitempty"` + BPO1 *BlobConfig `json:"bpo1,omitempty"` + BPO2 *BlobConfig `json:"bpo2,omitempty"` + BPO3 *BlobConfig `json:"bpo3,omitempty"` + BPO4 *BlobConfig `json:"bpo4,omitempty"` + BPO5 *BlobConfig `json:"bpo5,omitempty"` + Amsterdam *BlobConfig `json:"amsterdam,omitempty"` } // IsHomestead returns whether num is either equal to the homestead block or greater. @@ -654,6 +806,16 @@ func (c *ChainConfig) IsTerminalPoWBlock(parentTotalDiff *big.Int, totalDiff *bi return parentTotalDiff.Cmp(c.TerminalTotalDifficulty) < 0 && totalDiff.Cmp(c.TerminalTotalDifficulty) >= 0 } +// IsPostMerge reports whether the given block number is assumed to be post-merge. +// Here we check the MergeNetsplitBlock to allow configuring networks with a PoW or +// PoA chain for unit testing purposes. +func (c *ChainConfig) IsPostMerge(blockNum uint64, timestamp uint64) bool { + mergedAtGenesis := c.TerminalTotalDifficulty != nil && c.TerminalTotalDifficulty.Sign() == 0 + return mergedAtGenesis || + c.MergeNetsplitBlock != nil && blockNum >= c.MergeNetsplitBlock.Uint64() || + c.ShanghaiTime != nil && timestamp >= *c.ShanghaiTime +} + // IsShanghai returns whether time is either equal to the Shanghai fork time or greater. func (c *ChainConfig) IsShanghai(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.ShanghaiTime, time) @@ -674,11 +836,6 @@ func (c *ChainConfig) IsOsaka(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.OsakaTime, time) } -// IsVerkle returns whether time is either equal to the Verkle fork time or greater. -func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { - return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time) -} - // IsBPO1 returns whether time is either equal to the BPO1 fork time or greater. func (c *ChainConfig) IsBPO1(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.BPO1Time, time) @@ -704,6 +861,16 @@ func (c *ChainConfig) IsBPO5(num *big.Int, time uint64) bool { return c.IsLondon(num) && isTimestampForked(c.BPO5Time, time) } +// IsAmsterdam returns whether time is either equal to the Amsterdam fork time or greater. +func (c *ChainConfig) IsAmsterdam(num *big.Int, time uint64) bool { + return c.IsLondon(num) && isTimestampForked(c.AmsterdamTime, time) +} + +// IsVerkle returns whether time is either equal to the Verkle fork time or greater. +func (c *ChainConfig) IsVerkle(num *big.Int, time uint64) bool { + return c.IsLondon(num) && isTimestampForked(c.VerkleTime, time) +} + // IsVerkleGenesis checks whether the verkle fork is activated at the genesis block. // // Verkle mode is considered enabled if the verkle fork time is configured, @@ -784,6 +951,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "bpo3", timestamp: c.BPO3Time, optional: true}, {name: "bpo4", timestamp: c.BPO4Time, optional: true}, {name: "bpo5", timestamp: c.BPO5Time, optional: true}, + {name: "amsterdam", timestamp: c.AmsterdamTime, optional: true}, } { if lastFork.name != "" { switch { @@ -838,6 +1006,7 @@ func (c *ChainConfig) CheckConfigForkOrder() error { {name: "bpo3", timestamp: c.BPO3Time, config: bsc.BPO3}, {name: "bpo4", timestamp: c.BPO4Time, config: bsc.BPO4}, {name: "bpo5", timestamp: c.BPO5Time, config: bsc.BPO5}, + {name: "amsterdam", timestamp: c.AmsterdamTime, config: bsc.Amsterdam}, } { if cur.config != nil { if err := cur.config.validate(); err != nil { @@ -953,6 +1122,9 @@ func (c *ChainConfig) checkCompatible(newcfg *ChainConfig, headNumber *big.Int, if isForkTimestampIncompatible(c.BPO5Time, newcfg.BPO5Time, headTimestamp) { return newTimestampCompatError("BPO5 fork timestamp", c.BPO5Time, newcfg.BPO5Time) } + if isForkTimestampIncompatible(c.AmsterdamTime, newcfg.AmsterdamTime, headTimestamp) { + return newTimestampCompatError("Amsterdam fork timestamp", c.AmsterdamTime, newcfg.AmsterdamTime) + } return nil } @@ -972,6 +1144,18 @@ func (c *ChainConfig) LatestFork(time uint64) forks.Fork { london := c.LondonBlock switch { + case c.IsAmsterdam(london, time): + return forks.Amsterdam + case c.IsBPO5(london, time): + return forks.BPO5 + case c.IsBPO4(london, time): + return forks.BPO4 + case c.IsBPO3(london, time): + return forks.BPO3 + case c.IsBPO2(london, time): + return forks.BPO2 + case c.IsBPO1(london, time): + return forks.BPO1 case c.IsOsaka(london, time): return forks.Osaka case c.IsPrague(london, time): @@ -985,10 +1169,64 @@ func (c *ChainConfig) LatestFork(time uint64) forks.Fork { } } +// BlobConfig returns the blob config associated with the provided fork. +func (c *ChainConfig) BlobConfig(fork forks.Fork) *BlobConfig { + switch fork { + case forks.BPO5: + return c.BlobScheduleConfig.BPO5 + case forks.BPO4: + return c.BlobScheduleConfig.BPO4 + case forks.BPO3: + return c.BlobScheduleConfig.BPO3 + case forks.BPO2: + return c.BlobScheduleConfig.BPO2 + case forks.BPO1: + return c.BlobScheduleConfig.BPO1 + case forks.Osaka: + return c.BlobScheduleConfig.Osaka + case forks.Prague: + return c.BlobScheduleConfig.Prague + case forks.Cancun: + return c.BlobScheduleConfig.Cancun + default: + return nil + } +} + +// ActiveSystemContracts returns the currently active system contracts at the +// given timestamp. +func (c *ChainConfig) ActiveSystemContracts(time uint64) map[string]common.Address { + fork := c.LatestFork(time) + active := make(map[string]common.Address) + if fork >= forks.Osaka { + // no new system contracts + } + if fork >= forks.Prague { + active["CONSOLIDATION_REQUEST_PREDEPLOY_ADDRESS"] = ConsolidationQueueAddress + active["DEPOSIT_CONTRACT_ADDRESS"] = c.DepositContractAddress + active["HISTORY_STORAGE_ADDRESS"] = HistoryStorageAddress + active["WITHDRAWAL_REQUEST_PREDEPLOY_ADDRESS"] = WithdrawalQueueAddress + } + if fork >= forks.Cancun { + active["BEACON_ROOTS_ADDRESS"] = BeaconRootsAddress + } + return active +} + // Timestamp returns the timestamp associated with the fork or returns nil if // the fork isn't defined or isn't a time-based fork. func (c *ChainConfig) Timestamp(fork forks.Fork) *uint64 { switch { + case fork == forks.BPO5: + return c.BPO5Time + case fork == forks.BPO4: + return c.BPO4Time + case fork == forks.BPO3: + return c.BPO3Time + case fork == forks.BPO2: + return c.BPO2Time + case fork == forks.BPO1: + return c.BPO1Time case fork == forks.Osaka: return c.OsakaTime case fork == forks.Prague: @@ -1143,7 +1381,7 @@ type Rules struct { IsByzantium, IsConstantinople, IsPetersburg, IsIstanbul bool IsBerlin, IsLondon bool IsMerge, IsShanghai, IsCancun, IsPrague, IsOsaka bool - IsVerkle bool + IsAmsterdam, IsVerkle bool } // Rules ensures c's ChainID is not nil. @@ -1173,6 +1411,7 @@ func (c *ChainConfig) Rules(num *big.Int, isMerge bool, timestamp uint64) Rules IsCancun: isMerge && c.IsCancun(num, timestamp), IsPrague: isMerge && c.IsPrague(num, timestamp), IsOsaka: isMerge && c.IsOsaka(num, timestamp), + IsAmsterdam: isMerge && c.IsAmsterdam(num, timestamp), IsVerkle: isVerkle, IsEIP4762: isVerkle, } diff --git a/params/forks/forks.go b/params/forks/forks.go index 5c9612a625..641d59434b 100644 --- a/params/forks/forks.go +++ b/params/forks/forks.go @@ -40,6 +40,12 @@ const ( Cancun Prague Osaka + BPO1 + BPO2 + BPO3 + BPO4 + BPO5 + Amsterdam ) // String implements fmt.Stringer. @@ -72,4 +78,10 @@ var forkToString = map[Fork]string{ Cancun: "Cancun", Prague: "Prague", Osaka: "Osaka", + BPO1: "BPO1", + BPO2: "BPO2", + BPO3: "BPO3", + BPO4: "BPO4", + BPO5: "BPO5", + Amsterdam: "Amsterdam", } diff --git a/params/protocol_params.go b/params/protocol_params.go index 2ec3a5c249..bb506af015 100644 --- a/params/protocol_params.go +++ b/params/protocol_params.go @@ -32,7 +32,7 @@ const ( MaximumExtraDataSize uint64 = 32 // Maximum size extra data may be after Genesis. ExpByteGas uint64 = 10 // Times ceil(log256(exponent)) for the EXP instruction. - SloadGas uint64 = 50 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. + SloadGas uint64 = 50 // CallValueTransferGas uint64 = 9000 // Paid for CALL when the value transfer is non-zero. CallNewAccountGas uint64 = 25000 // Paid for CALL when the destination address didn't exist prior. TxGas uint64 = 21000 // Per transaction not creating a contract. NOTE: Not payable on data of calls between transactions. @@ -82,7 +82,7 @@ const ( CallCreateDepth uint64 = 1024 // Maximum depth of call/create stack. ExpGas uint64 = 10 // Once per EXP instruction LogGas uint64 = 375 // Per LOG* operation. - CopyGas uint64 = 3 // + CopyGas uint64 = 3 // Multiplied by the number of 32-byte words that are copied (round up) for any *COPY operation and added. StackLimit uint64 = 1024 // Maximum size of VM stack allowed. TierStepGas uint64 = 0 // Once per operation, for a selection of them. LogTopicGas uint64 = 375 // Multiplied by the * of the LOG*, per LOG transaction. e.g. LOG0 incurs 0 * c_txLogTopicGas, LOG4 incurs 4 * c_txLogTopicGas. @@ -180,7 +180,7 @@ const ( BlobTxMaxBlobs = 6 BlobBaseCost = 1 << 13 // Base execution gas cost for a blob. - HistoryServeWindow = 8192 // Number of blocks to serve historical block hashes for, EIP-2935. + HistoryServeWindow = 8191 // Number of blocks to serve historical block hashes for, EIP-2935. MaxBlockSize = 8_388_608 // maximum size of an RLP-encoded block ) diff --git a/rlp/decode.go b/rlp/decode.go index 5a06f35ec0..19074072fb 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -371,7 +371,7 @@ func decodeByteArray(s *Stream, val reflect.Value) error { if err != nil { return err } - slice := byteArrayBytes(val, val.Len()) + slice := val.Bytes() switch kind { case Byte: if len(slice) == 0 { diff --git a/rlp/decode_test.go b/rlp/decode_test.go index 3e492188e8..4b3a322873 100644 --- a/rlp/decode_test.go +++ b/rlp/decode_test.go @@ -350,7 +350,7 @@ func TestDecodeErrors(t *testing.T) { } if err := Decode(r, new(uint)); err != io.EOF { - t.Errorf("Decode(r, new(int)) error mismatch, got %q, want %q", err, io.EOF) + t.Errorf("Decode(r, new(uint)) error mismatch, got %q, want %q", err, io.EOF) } } diff --git a/rlp/encbuffer.go b/rlp/encbuffer.go index 8d3a3b2293..61d8bd059c 100644 --- a/rlp/encbuffer.go +++ b/rlp/encbuffer.go @@ -23,6 +23,7 @@ import ( "reflect" "sync" + "github.com/ethereum/go-ethereum/common/math" "github.com/holiman/uint256" ) @@ -145,9 +146,6 @@ func (buf *encBuffer) writeString(s string) { buf.writeBytes([]byte(s)) } -// wordBytes is the number of bytes in a big.Word -const wordBytes = (32 << (uint64(^big.Word(0)) >> 63)) / 8 - // writeBigInt writes i as an integer. func (buf *encBuffer) writeBigInt(i *big.Int) { bitlen := i.BitLen() @@ -161,15 +159,8 @@ func (buf *encBuffer) writeBigInt(i *big.Int) { length := ((bitlen + 7) & -8) >> 3 buf.encodeStringHeader(length) buf.str = append(buf.str, make([]byte, length)...) - index := length bytesBuf := buf.str[len(buf.str)-length:] - for _, d := range i.Bits() { - for j := 0; j < wordBytes && index > 0; j++ { - index-- - bytesBuf[index] = byte(d) - d >>= 8 - } - } + math.ReadBits(i, bytesBuf) } // writeUint256 writes z as an integer. diff --git a/rlp/encode.go b/rlp/encode.go index 623932a90b..ed99275739 100644 --- a/rlp/encode.go +++ b/rlp/encode.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "math/big" + "math/bits" "reflect" "github.com/ethereum/go-ethereum/rlp/internal/rlpstruct" @@ -239,7 +240,6 @@ func makeByteArrayWriter(typ reflect.Type) writer { case 1: return writeLengthOneByteArray default: - length := typ.Len() return func(val reflect.Value, w *encBuffer) error { if !val.CanAddr() { // Getting the byte slice of val requires it to be addressable. Make it @@ -248,7 +248,7 @@ func makeByteArrayWriter(typ reflect.Type) writer { copy.Set(val) val = copy } - slice := byteArrayBytes(val, length) + slice := val.Bytes() w.encodeStringHeader(len(slice)) w.str = append(w.str, slice...) return nil @@ -487,9 +487,8 @@ func putint(b []byte, i uint64) (size int) { // intsize computes the minimum number of bytes required to store i. func intsize(i uint64) (size int) { - for size = 1; ; size++ { - if i >>= 8; i == 0 { - return size - } + if i == 0 { + return 1 } + return (bits.Len64(i) + 7) / 8 } diff --git a/rlp/encode_test.go b/rlp/encode_test.go index 314958eb56..e63ea319b4 100644 --- a/rlp/encode_test.go +++ b/rlp/encode_test.go @@ -317,7 +317,6 @@ var encTests = []encTest{ {val: &optionalAndTailField{A: 1}, output: "C101"}, {val: &optionalAndTailField{A: 1, B: 2}, output: "C20102"}, {val: &optionalAndTailField{A: 1, Tail: []uint{5, 6}}, output: "C401800506"}, - {val: &optionalAndTailField{A: 1, Tail: []uint{5, 6}}, output: "C401800506"}, {val: &optionalBigIntField{A: 1}, output: "C101"}, {val: &optionalPtrField{A: 1}, output: "C101"}, {val: &optionalPtrFieldNil{A: 1}, output: "C101"}, diff --git a/rlp/iterator.go b/rlp/iterator.go index 95bd3f2582..05567fa05b 100644 --- a/rlp/iterator.go +++ b/rlp/iterator.go @@ -37,15 +37,24 @@ func NewListIterator(data RawValue) (*listIterator, error) { return it, nil } -// Next forwards the iterator one step, returns true if it was not at end yet +// Next forwards the iterator one step. +// Returns true if there is a next item or an error occurred on this step (check Err()). +// On parse error, the iterator is marked finished and subsequent calls return false. func (it *listIterator) Next() bool { if len(it.data) == 0 { return false } _, t, c, err := readKind(it.data) + if err != nil { + it.next = nil + it.err = err + // Mark iteration as finished to avoid potential infinite loops on subsequent Next calls. + it.data = nil + return true + } it.next = it.data[:t+c] it.data = it.data[t+c:] - it.err = err + it.err = nil return true } diff --git a/rlp/raw.go b/rlp/raw.go index cec90346a1..f284da3f6d 100644 --- a/rlp/raw.go +++ b/rlp/raw.go @@ -152,6 +152,45 @@ func CountValues(b []byte) (int, error) { return i, nil } +// SplitListValues extracts the raw elements from the list RLP-encoding blob. +// +// Note: the returned slice must not be modified, as it shares the same +// backing array as the original slice. It's acceptable to deep-copy the elements +// out if necessary, but let's stick with this approach for less allocation +// overhead. +func SplitListValues(b []byte) ([][]byte, error) { + b, _, err := SplitList(b) + if err != nil { + return nil, err + } + n, err := CountValues(b) + if err != nil { + return nil, err + } + var elements = make([][]byte, 0, n) + + for len(b) > 0 { + _, tagsize, size, err := readKind(b) + if err != nil { + return nil, err + } + elements = append(elements, b[:tagsize+size]) + b = b[tagsize+size:] + } + return elements, nil +} + +// MergeListValues takes a list of raw elements and rlp-encodes them as list. +func MergeListValues(elems [][]byte) ([]byte, error) { + w := NewEncoderBuffer(nil) + offset := w.List() + for _, elem := range elems { + w.Write(elem) + } + w.ListEnd(offset) + return w.ToBytes(), nil +} + func readKind(buf []byte) (k Kind, tagsize, contentsize uint64, err error) { if len(buf) == 0 { return 0, 0, 0, io.ErrUnexpectedEOF diff --git a/rlp/raw_test.go b/rlp/raw_test.go index 7b3255eca3..2ed77b384c 100644 --- a/rlp/raw_test.go +++ b/rlp/raw_test.go @@ -336,3 +336,269 @@ func TestBytesSize(t *testing.T) { } } } + +func TestSplitListValues(t *testing.T) { + tests := []struct { + name string + input string // hex-encoded RLP list + want []string // hex-encoded expected elements + wantErr error + }{ + { + name: "empty list", + input: "C0", + want: []string{}, + }, + { + name: "single byte element", + input: "C101", + want: []string{"01"}, + }, + { + name: "single empty string", + input: "C180", + want: []string{"80"}, + }, + { + name: "two byte elements", + input: "C20102", + want: []string{"01", "02"}, + }, + { + name: "three elements", + input: "C3010203", + want: []string{"01", "02", "03"}, + }, + { + name: "mixed size elements", + input: "C80182020283030303", + want: []string{"01", "820202", "83030303"}, + }, + { + name: "string elements", + input: "C88363617483646F67", + want: []string{"83636174", "83646F67"}, // cat,dog + }, + { + name: "nested list element", + input: "C4C3010203", // [[1,2,3]] + want: []string{"C3010203"}, // [1,2,3] + }, + { + name: "multiple nested lists", + input: "C6C20102C20304", // [[1,2],[3,4]] + want: []string{"C20102", "C20304"}, // [1,2], [3,4] + }, + { + name: "large list", + input: "C6010203040506", + want: []string{"01", "02", "03", "04", "05", "06"}, + }, + { + name: "list with empty strings", + input: "C3808080", + want: []string{"80", "80", "80"}, + }, + // Error cases + { + name: "single byte", + input: "01", + wantErr: ErrExpectedList, + }, + { + name: "string", + input: "83636174", + wantErr: ErrExpectedList, + }, + { + name: "empty input", + input: "", + wantErr: io.ErrUnexpectedEOF, + }, + { + name: "invalid list - value too large", + input: "C60102030405", + wantErr: ErrValueTooLarge, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := SplitListValues(unhex(tt.input)) + if !errors.Is(err, tt.wantErr) { + t.Errorf("SplitListValues() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err != nil { + return + } + if len(got) != len(tt.want) { + t.Errorf("SplitListValues() got %d elements, want %d", len(got), len(tt.want)) + return + } + for i, elem := range got { + want := unhex(tt.want[i]) + if !bytes.Equal(elem, want) { + t.Errorf("SplitListValues() element[%d] = %x, want %x", i, elem, want) + } + } + }) + } +} + +func TestMergeListValues(t *testing.T) { + tests := []struct { + name string + elems []string // hex-encoded RLP elements + want string // hex-encoded expected result + wantErr error + }{ + { + name: "empty list", + elems: []string{}, + want: "C0", + }, + { + name: "single byte element", + elems: []string{"01"}, + want: "C101", + }, + { + name: "single empty string", + elems: []string{"80"}, + want: "C180", + }, + { + name: "two byte elements", + elems: []string{"01", "02"}, + want: "C20102", + }, + { + name: "three elements", + elems: []string{"01", "02", "03"}, + want: "C3010203", + }, + { + name: "mixed size elements", + elems: []string{"01", "820202", "83030303"}, + want: "C80182020283030303", + }, + { + name: "string elements", + elems: []string{"83636174", "83646F67"}, // cat, dog + want: "C88363617483646F67", + }, + { + name: "nested list element", + elems: []string{"C20102", "03"}, // [[1, 2], 3] + want: "C4C2010203", + }, + { + name: "multiple nested lists", + elems: []string{"C20102", "C3030405"}, // [[1,2],[3,4,5]], + want: "C7C20102C3030405", + }, + { + name: "large list", + elems: []string{"01", "02", "03", "04", "05", "06"}, + want: "C6010203040506", + }, + { + name: "list with empty strings", + elems: []string{"80", "80", "80"}, + want: "C3808080", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + elems := make([][]byte, len(tt.elems)) + for i, s := range tt.elems { + elems[i] = unhex(s) + } + got, err := MergeListValues(elems) + if !errors.Is(err, tt.wantErr) { + t.Errorf("MergeListValues() error = %v, wantErr %v", err, tt.wantErr) + return + } + if err != nil { + return + } + want := unhex(tt.want) + if !bytes.Equal(got, want) { + t.Errorf("MergeListValues() = %x, want %x", got, want) + } + }) + } +} + +func TestSplitMergeList(t *testing.T) { + tests := []struct { + name string + input string // hex-encoded RLP list + }{ + { + name: "empty list", + input: "C0", + }, + { + name: "single byte element", + input: "C101", + }, + { + name: "two byte elements", + input: "C20102", + }, + { + name: "three elements", + input: "C3010203", + }, + { + name: "mixed size elements", + input: "C80182020283030303", + }, + { + name: "string elements", + input: "C88363617483646F67", // [cat, dog] + }, + { + name: "nested list element", + input: "C4C2010203", // [[1,2],3] + }, + { + name: "multiple nested lists", + input: "C6C20102C20304", // [[1,2],[3,4]] + }, + { + name: "large list", + input: "C6010203040506", // [1,2,3,4,5,6] + }, + { + name: "list with empty strings", + input: "C3808080", // ["", "", ""] + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + original := unhex(tt.input) + + // Split the list + elements, err := SplitListValues(original) + if err != nil { + t.Fatalf("SplitListValues() error = %v", err) + } + + // Merge back + merged, err := MergeListValues(elements) + if err != nil { + t.Fatalf("MergeListValues() error = %v", err) + } + + // The merged result should match the original + if !bytes.Equal(merged, original) { + t.Errorf("Round trip failed: original = %x, merged = %x", original, merged) + } + }) + } +} diff --git a/rpc/client.go b/rpc/client.go index ba7e43eb5c..8d81503d59 100644 --- a/rpc/client.go +++ b/rpc/client.go @@ -32,7 +32,6 @@ import ( ) var ( - ErrBadResult = errors.New("bad result in JSON-RPC response") ErrClientQuit = errors.New("client is closed") ErrNoResult = errors.New("JSON-RPC response has no result") ErrMissingBatchResponse = errors.New("response batch did not contain a response to this call") @@ -120,7 +119,7 @@ func (c *Client) newClientConn(conn ServerCodec) *clientConn { ctx := context.Background() ctx = context.WithValue(ctx, clientContextKey{}, c) ctx = context.WithValue(ctx, peerInfoContextKey{}, conn.peerInfo()) - handler := newHandler(ctx, conn, c.idgen, c.services, c.batchItemLimit, c.batchResponseMaxSize) + handler := newHandler(ctx, conn, c.idgen, c.services, c.batchItemLimit, c.batchResponseMaxSize, nil) return &clientConn{conn, handler} } diff --git a/rpc/client_test.go b/rpc/client_test.go index 6c1a4f8f6c..03a3410537 100644 --- a/rpc/client_test.go +++ b/rpc/client_test.go @@ -973,7 +973,7 @@ func (l *flakeyListener) Accept() (net.Conn, error) { c, err := l.Listener.Accept() if err == nil { - timeout := time.Duration(rand.Int63n(int64(l.maxKillTimeout))) + timeout := max(time.Millisecond*10, time.Duration(rand.Int63n(int64(l.maxKillTimeout)))) time.AfterFunc(timeout, func() { log.Debug(fmt.Sprintf("killing conn %v after %v", c.LocalAddr(), timeout)) c.Close() diff --git a/rpc/handler.go b/rpc/handler.go index 45558d5821..4ac3a26df1 100644 --- a/rpc/handler.go +++ b/rpc/handler.go @@ -28,7 +28,10 @@ import ( "sync" "time" + "github.com/ethereum/go-ethereum/internal/telemetry" "github.com/ethereum/go-ethereum/log" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/trace" ) // handler handles JSON-RPC messages. There is one handler per connection. Note that @@ -65,6 +68,7 @@ type handler struct { allowSubscribe bool batchRequestLimit int batchResponseMaxSize int + tracerProvider trace.TracerProvider subLock sync.Mutex serverSubs map[ID]*Subscription @@ -73,9 +77,10 @@ type handler struct { type callProc struct { ctx context.Context notifiers []*Notifier + isBatch bool } -func newHandler(connCtx context.Context, conn jsonWriter, idgen func() ID, reg *serviceRegistry, batchRequestLimit, batchResponseMaxSize int) *handler { +func newHandler(connCtx context.Context, conn jsonWriter, idgen func() ID, reg *serviceRegistry, batchRequestLimit, batchResponseMaxSize int, tracerProvider trace.TracerProvider) *handler { rootCtx, cancelRoot := context.WithCancel(connCtx) h := &handler{ reg: reg, @@ -90,6 +95,7 @@ func newHandler(connCtx context.Context, conn jsonWriter, idgen func() ID, reg * log: log.Root(), batchRequestLimit: batchRequestLimit, batchResponseMaxSize: batchResponseMaxSize, + tracerProvider: tracerProvider, } if conn.remoteAddr() != "" { h.log = h.log.New("conn", conn.remoteAddr()) @@ -197,6 +203,7 @@ func (h *handler) handleBatch(msgs []*jsonrpcMessage) { // Process calls on a goroutine because they may block indefinitely: h.startCallProc(func(cp *callProc) { + cp.isBatch = true var ( timer *time.Timer cancel context.CancelFunc @@ -497,40 +504,65 @@ func (h *handler) handleCall(cp *callProc, msg *jsonrpcMessage) *jsonrpcMessage if msg.isSubscribe() { return h.handleSubscribe(cp, msg) } - var callb *callback if msg.isUnsubscribe() { - callb = h.unsubscribeCb - } else { - // Check method name length - if len(msg.Method) > maxMethodNameLength { - return msg.errorResponse(&invalidRequestError{fmt.Sprintf("method name too long: %d > %d", len(msg.Method), maxMethodNameLength)}) + args, err := parsePositionalArguments(msg.Params, h.unsubscribeCb.argTypes) + if err != nil { + return msg.errorResponse(&invalidParamsError{err.Error()}) } - callb = h.reg.callback(msg.Method) + return h.runMethod(cp.ctx, msg, h.unsubscribeCb, args) } + + // Check method name length + if len(msg.Method) > maxMethodNameLength { + return msg.errorResponse(&invalidRequestError{fmt.Sprintf("method name too long: %d > %d", len(msg.Method), maxMethodNameLength)}) + } + callb, service, method := h.reg.callback(msg.Method) + + // If the method is not found, return an error. if callb == nil { return msg.errorResponse(&methodNotFoundError{method: msg.Method}) } + // Start root span for the request. + var err error + rpcInfo := telemetry.RPCInfo{ + System: "jsonrpc", + Service: service, + Method: method, + RequestID: string(msg.ID), + } + attrib := []telemetry.Attribute{ + telemetry.BoolAttribute("rpc.batch", cp.isBatch), + } + ctx, spanEnd := telemetry.StartServerSpan(cp.ctx, h.tracer(), rpcInfo, attrib...) + defer spanEnd(err) + + // Start tracing span before parsing arguments. + _, _, pSpanEnd := telemetry.StartSpanWithTracer(ctx, h.tracer(), "rpc.parsePositionalArguments") args, err := parsePositionalArguments(msg.Params, callb.argTypes) + pSpanEnd(err) if err != nil { return msg.errorResponse(&invalidParamsError{err.Error()}) } start := time.Now() - answer := h.runMethod(cp.ctx, msg, callb, args) + + // Start tracing span before running the method. + rctx, _, rSpanEnd := telemetry.StartSpanWithTracer(ctx, h.tracer(), "rpc.runMethod") + answer := h.runMethod(rctx, msg, callb, args) + if answer.Error != nil { + err = errors.New(answer.Error.Message) + } + rSpanEnd(err) // Collect the statistics for RPC calls if metrics is enabled. - // We only care about pure rpc call. Filter out subscription. - if callb != h.unsubscribeCb { - rpcRequestGauge.Inc(1) - if answer.Error != nil { - failedRequestGauge.Inc(1) - } else { - successfulRequestGauge.Inc(1) - } - rpcServingTimer.UpdateSince(start) - updateServeTimeHistogram(msg.Method, answer.Error == nil, time.Since(start)) + rpcRequestGauge.Inc(1) + if answer.Error != nil { + failedRequestGauge.Inc(1) + } else { + successfulRequestGauge.Inc(1) } - + rpcServingTimer.UpdateSince(start) + updateServeTimeHistogram(msg.Method, answer.Error == nil, time.Since(start)) return answer } @@ -568,17 +600,33 @@ func (h *handler) handleSubscribe(cp *callProc, msg *jsonrpcMessage) *jsonrpcMes n := &Notifier{h: h, namespace: namespace} cp.notifiers = append(cp.notifiers, n) ctx := context.WithValue(cp.ctx, notifierKey{}, n) - return h.runMethod(ctx, msg, callb, args) } +// tracer returns the OpenTelemetry Tracer for RPC call tracing. +func (h *handler) tracer() trace.Tracer { + if h.tracerProvider == nil { + // Default to global TracerProvider if none is set. + // Note: If no TracerProvider is set, the default is a no-op TracerProvider. + // See https://pkg.go.dev/go.opentelemetry.io/otel#GetTracerProvider + return otel.Tracer("") + } + return h.tracerProvider.Tracer("") +} + // runMethod runs the Go callback for an RPC method. -func (h *handler) runMethod(ctx context.Context, msg *jsonrpcMessage, callb *callback, args []reflect.Value) *jsonrpcMessage { +func (h *handler) runMethod(ctx context.Context, msg *jsonrpcMessage, callb *callback, args []reflect.Value, attributes ...telemetry.Attribute) *jsonrpcMessage { result, err := callb.call(ctx, msg.Method, args) if err != nil { return msg.errorResponse(err) } - return msg.response(result) + _, _, spanEnd := telemetry.StartSpanWithTracer(ctx, h.tracer(), "rpc.encodeJSONResponse", attributes...) + response := msg.response(result) + if response.Error != nil { + err = errors.New(response.Error.Message) + } + spanEnd(err) + return response } // unsubscribe is the callback function for all *_unsubscribe calls. @@ -612,8 +660,11 @@ type limitedBuffer struct { } func (buf *limitedBuffer) Write(data []byte) (int, error) { - avail := max(buf.limit, len(buf.output)) - if len(data) < avail { + avail := buf.limit - len(buf.output) + if avail <= 0 { + return 0, errTruncatedOutput + } + if len(data) <= avail { buf.output = append(buf.output, data...) return len(data), nil } diff --git a/rpc/http.go b/rpc/http.go index f4b99429ef..55f0abfa72 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -30,6 +30,9 @@ import ( "strconv" "sync" "time" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/propagation" ) const ( @@ -168,13 +171,21 @@ func newClientTransportHTTP(endpoint string, cfg *clientConfig) reconnectFunc { } } +// cleanlyCloseBody avoids sending unnecessary RST_STREAM and PING frames by +// ensuring the whole body is read before being closed. +// See https://blog.cloudflare.com/go-and-enhance-your-calm/#reading-bodies-in-go-can-be-unintuitive +func cleanlyCloseBody(body io.ReadCloser) error { + io.Copy(io.Discard, body) + return body.Close() +} + func (c *Client) sendHTTP(ctx context.Context, op *requestOp, msg interface{}) error { hc := c.writeConn.(*httpConn) respBody, err := hc.doRequest(ctx, msg) if err != nil { return err } - defer respBody.Close() + defer cleanlyCloseBody(respBody) var resp jsonrpcMessage batch := [1]*jsonrpcMessage{&resp} @@ -191,7 +202,7 @@ func (c *Client) sendBatchHTTP(ctx context.Context, op *requestOp, msgs []*jsonr if err != nil { return err } - defer respBody.Close() + defer cleanlyCloseBody(respBody) var respmsgs []*jsonrpcMessage if err := json.NewDecoder(respBody).Decode(&respmsgs); err != nil { @@ -236,7 +247,7 @@ func (hc *httpConn) doRequest(ctx context.Context, msg interface{}) (io.ReadClos if _, err := buf.ReadFrom(resp.Body); err == nil { body = buf.Bytes() } - resp.Body.Close() + cleanlyCloseBody(resp.Body) return nil, HTTPError{ Status: resp.Status, StatusCode: resp.StatusCode, @@ -326,6 +337,9 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() ctx = context.WithValue(ctx, peerInfoContextKey{}, connInfo) + // Extract trace context from incoming headers. + ctx = otel.GetTextMapPropagator().Extract(ctx, propagation.HeaderCarrier(r.Header)) + // All checks passed, create a codec that reads directly from the request body // until EOF, writes the response to w, and orders the server to process a // single request. diff --git a/rpc/http_test.go b/rpc/http_test.go index 6c268b6292..15ddd59bd0 100644 --- a/rpc/http_test.go +++ b/rpc/http_test.go @@ -106,7 +106,7 @@ func confirmHTTPRequestYieldsStatusCode(t *testing.T, method, contentType, body if err != nil { t.Fatalf("request failed: %v", err) } - resp.Body.Close() + cleanlyCloseBody(resp.Body) confirmStatusCode(t, resp.StatusCode, expectedStatusCode) } diff --git a/rpc/server.go b/rpc/server.go index 42b59f8f6f..94d4a3e13e 100644 --- a/rpc/server.go +++ b/rpc/server.go @@ -25,6 +25,7 @@ import ( "sync/atomic" "github.com/ethereum/go-ethereum/log" + "go.opentelemetry.io/otel/trace" ) const MetadataApi = "rpc" @@ -54,14 +55,18 @@ type Server struct { batchItemLimit int batchResponseLimit int httpBodyLimit int + wsReadLimit int64 + tracerProvider trace.TracerProvider } // NewServer creates a new server instance with no registered handlers. func NewServer() *Server { server := &Server{ - idgen: randomIDGenerator(), - codecs: make(map[ServerCodec]struct{}), - httpBodyLimit: defaultBodyLimit, + idgen: randomIDGenerator(), + codecs: make(map[ServerCodec]struct{}), + httpBodyLimit: defaultBodyLimit, + wsReadLimit: wsDefaultReadLimit, + tracerProvider: nil, } server.run.Store(true) // Register the default service providing meta information about the RPC service such @@ -89,6 +94,13 @@ func (s *Server) SetHTTPBodyLimit(limit int) { s.httpBodyLimit = limit } +// SetWebsocketReadLimit sets the limit for max message size for Websocket requests. +// +// This method should be called before processing any requests via Websocket server. +func (s *Server) SetWebsocketReadLimit(limit int64) { + s.wsReadLimit = limit +} + // RegisterName creates a service for the given receiver type under the given name. When no // methods on the given receiver match the criteria to be either an RPC method or a // subscription an error is returned. Otherwise a new service is created and added to the @@ -120,6 +132,15 @@ func (s *Server) ServeCodec(codec ServerCodec, options CodecOption) { c.Close() } +// setTracerProvider configures the OpenTelemetry TracerProvider for RPC call tracing. +// Note: This method (and the TracerProvider field in the Server/Handler struct) is +// primarily intended for testing. In particular, it allows tests to configure an +// isolated TracerProvider without changing the global provider, avoiding +// interference between tests running in parallel. +func (s *Server) setTracerProvider(tp trace.TracerProvider) { + s.tracerProvider = tp +} + func (s *Server) trackCodec(codec ServerCodec) bool { s.mutex.Lock() defer s.mutex.Unlock() @@ -147,7 +168,7 @@ func (s *Server) serveSingleRequest(ctx context.Context, codec ServerCodec) { return } - h := newHandler(ctx, codec, s.idgen, &s.services, s.batchItemLimit, s.batchResponseLimit) + h := newHandler(ctx, codec, s.idgen, &s.services, s.batchItemLimit, s.batchResponseLimit, s.tracerProvider) h.allowSubscribe = false defer h.close(io.EOF, nil) diff --git a/rpc/server_test.go b/rpc/server_test.go index 9ee545d81a..8334d4e80d 100644 --- a/rpc/server_test.go +++ b/rpc/server_test.go @@ -19,13 +19,18 @@ package rpc import ( "bufio" "bytes" + "context" + "errors" "io" "net" + "net/http/httptest" "os" "path/filepath" "strings" "testing" "time" + + "github.com/gorilla/websocket" ) func TestServerRegisterName(t *testing.T) { @@ -202,3 +207,87 @@ func TestServerBatchResponseSizeLimit(t *testing.T) { } } } + +func TestServerWebsocketReadLimit(t *testing.T) { + t.Parallel() + + // Test different read limits + testCases := []struct { + name string + readLimit int64 + testSize int + shouldFail bool + }{ + { + name: "limit with small request - should succeed", + readLimit: 4096, // generous limit to comfortably allow JSON overhead + testSize: 256, // reasonably small payload + shouldFail: false, + }, + { + name: "limit with large request - should fail", + readLimit: 256, // tight limit to trigger server-side read limit + testSize: 1024, // payload that will exceed the limit including JSON overhead + shouldFail: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + // Create server and set read limits + srv := newTestServer() + srv.SetWebsocketReadLimit(tc.readLimit) + defer srv.Stop() + + // Start HTTP server with WebSocket handler + httpsrv := httptest.NewServer(srv.WebsocketHandler([]string{"*"})) + defer httpsrv.Close() + + wsURL := "ws:" + strings.TrimPrefix(httpsrv.URL, "http:") + + // Connect WebSocket client + client, err := DialOptions(context.Background(), wsURL) + if err != nil { + t.Fatalf("can't dial: %v", err) + } + defer client.Close() + + // Create large request data - this is what will be limited + largeString := strings.Repeat("A", tc.testSize) + + // Send the large string as a parameter in the request + var result echoResult + err = client.Call(&result, "test_echo", largeString, 42, &echoArgs{S: "test"}) + + if tc.shouldFail { + // Expecting an error due to read limit exceeded + if err == nil { + t.Fatalf("expected error for request size %d with limit %d, but got none", tc.testSize, tc.readLimit) + } + // Be tolerant about the exact error surfaced by gorilla/websocket. + // Prefer a CloseError with code 1009, but accept ErrReadLimit or an error string containing 1009/message too big. + var cerr *websocket.CloseError + if errors.As(err, &cerr) { + if cerr.Code != websocket.CloseMessageTooBig { + t.Fatalf("unexpected websocket close code: have %d want %d (err=%v)", cerr.Code, websocket.CloseMessageTooBig, err) + } + } else if !errors.Is(err, websocket.ErrReadLimit) && + !strings.Contains(strings.ToLower(err.Error()), "1009") && + !strings.Contains(strings.ToLower(err.Error()), "message too big") && + !strings.Contains(strings.ToLower(err.Error()), "connection reset by peer") { + // Not the error we expect from exceeding the message size limit. + t.Fatalf("unexpected error for read limit violation: %v", err) + } + } else { + // Expecting success + if err != nil { + t.Fatalf("unexpected error for request size %d with limit %d: %v", tc.testSize, tc.readLimit, err) + } + // Verify the response is correct - the echo should return our string + if result.String != largeString { + t.Fatalf("expected echo result to match input") + } + } + }) + } +} diff --git a/rpc/service.go b/rpc/service.go index 0f62d7eb7c..8462a5a59a 100644 --- a/rpc/service.go +++ b/rpc/service.go @@ -92,14 +92,14 @@ func (r *serviceRegistry) registerName(name string, rcvr interface{}) error { } // callback returns the callback corresponding to the given RPC method name. -func (r *serviceRegistry) callback(method string) *callback { +func (r *serviceRegistry) callback(method string) (cb *callback, service, methodName string) { before, after, found := strings.Cut(method, serviceMethodSeparator) if !found { - return nil + return nil, "", "" } r.mu.Lock() defer r.mu.Unlock() - return r.services[before].callbacks[after] + return r.services[before].callbacks[after], before, after } // subscription returns a subscription callback in the given service. diff --git a/rpc/tracing_test.go b/rpc/tracing_test.go new file mode 100644 index 0000000000..f32a647e6f --- /dev/null +++ b/rpc/tracing_test.go @@ -0,0 +1,224 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package rpc + +import ( + "context" + "net/http/httptest" + "testing" + + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/propagation" + sdktrace "go.opentelemetry.io/otel/sdk/trace" + "go.opentelemetry.io/otel/sdk/trace/tracetest" +) + +// attributeMap converts a slice of attributes to a map. +func attributeMap(attrs []attribute.KeyValue) map[string]string { + m := make(map[string]string) + for _, a := range attrs { + switch a.Value.Type() { + case attribute.STRING: + m[string(a.Key)] = a.Value.AsString() + case attribute.BOOL: + if a.Value.AsBool() { + m[string(a.Key)] = "true" + } else { + m[string(a.Key)] = "false" + } + default: + m[string(a.Key)] = a.Value.Emit() + } + } + return m +} + +// newTracingServer creates a new server with tracing enabled. +func newTracingServer(t *testing.T) (*Server, *sdktrace.TracerProvider, *tracetest.InMemoryExporter) { + t.Helper() + exporter := tracetest.NewInMemoryExporter() + tp := sdktrace.NewTracerProvider(sdktrace.WithSyncer(exporter)) + t.Cleanup(func() { _ = tp.Shutdown(context.Background()) }) + server := newTestServer() + server.setTracerProvider(tp) + t.Cleanup(server.Stop) + return server, tp, exporter +} + +// TestTracingHTTP verifies that RPC spans are emitted when processing HTTP requests. +func TestTracingHTTP(t *testing.T) { + // Not parallel: this test modifies the global otel TextMapPropagator. + + // Set up a propagator to extract W3C Trace Context headers. + originalPropagator := otel.GetTextMapPropagator() + otel.SetTextMapPropagator(propagation.TraceContext{}) + t.Cleanup(func() { otel.SetTextMapPropagator(originalPropagator) }) + + server, tracer, exporter := newTracingServer(t) + httpsrv := httptest.NewServer(server) + t.Cleanup(httpsrv.Close) + + // Define the expected trace and span IDs for context propagation. + const ( + traceID = "4bf92f3577b34da6a3ce929d0e0e4736" + parentSpanID = "00f067aa0ba902b7" + traceparent = "00-" + traceID + "-" + parentSpanID + "-01" + ) + + client, err := DialHTTP(httpsrv.URL) + if err != nil { + t.Fatalf("failed to dial: %v", err) + } + t.Cleanup(client.Close) + + // Set trace context headers. + client.SetHeader("traceparent", traceparent) + + // Make a successful RPC call. + var result echoResult + if err := client.Call(&result, "test_echo", "hello", 42, &echoArgs{S: "world"}); err != nil { + t.Fatalf("RPC call failed: %v", err) + } + + // Flush and verify that we emitted the expected span. + if err := tracer.ForceFlush(context.Background()); err != nil { + t.Fatalf("failed to flush: %v", err) + } + spans := exporter.GetSpans() + if len(spans) == 0 { + t.Fatal("no spans were emitted") + } + var rpcSpan *tracetest.SpanStub + for i := range spans { + if spans[i].Name == "jsonrpc.test/echo" { + rpcSpan = &spans[i] + break + } + } + if rpcSpan == nil { + t.Fatalf("jsonrpc.test/echo span not found") + } + + // Verify span attributes. + attrs := attributeMap(rpcSpan.Attributes) + if attrs["rpc.system"] != "jsonrpc" { + t.Errorf("expected rpc.system=jsonrpc, got %v", attrs["rpc.system"]) + } + if attrs["rpc.service"] != "test" { + t.Errorf("expected rpc.service=test, got %v", attrs["rpc.service"]) + } + if attrs["rpc.method"] != "echo" { + t.Errorf("expected rpc.method=echo, got %v", attrs["rpc.method"]) + } + if _, ok := attrs["rpc.jsonrpc.request_id"]; !ok { + t.Errorf("expected rpc.jsonrpc.request_id attribute to be set") + } + + // Verify the span's parent matches the traceparent header values. + if got := rpcSpan.Parent.TraceID().String(); got != traceID { + t.Errorf("parent trace ID mismatch: got %s, want %s", got, traceID) + } + if got := rpcSpan.Parent.SpanID().String(); got != parentSpanID { + t.Errorf("parent span ID mismatch: got %s, want %s", got, parentSpanID) + } + if !rpcSpan.Parent.IsRemote() { + t.Error("expected parent span context to be marked as remote") + } +} + +// TestTracingBatchHTTP verifies that RPC spans are emitted for batched JSON-RPC calls over HTTP. +func TestTracingBatchHTTP(t *testing.T) { + t.Parallel() + server, tracer, exporter := newTracingServer(t) + httpsrv := httptest.NewServer(server) + t.Cleanup(httpsrv.Close) + client, err := DialHTTP(httpsrv.URL) + if err != nil { + t.Fatalf("failed to dial: %v", err) + } + t.Cleanup(client.Close) + + // Make a successful batch RPC call. + batch := []BatchElem{ + { + Method: "test_echo", + Args: []any{"hello", 42, &echoArgs{S: "world"}}, + Result: new(echoResult), + }, + { + Method: "test_echo", + Args: []any{"your", 7, &echoArgs{S: "mom"}}, + Result: new(echoResult), + }, + } + if err := client.BatchCall(batch); err != nil { + t.Fatalf("batch RPC call failed: %v", err) + } + + // Flush and verify we emitted spans for each batch element. + if err := tracer.ForceFlush(context.Background()); err != nil { + t.Fatalf("failed to flush: %v", err) + } + spans := exporter.GetSpans() + if len(spans) == 0 { + t.Fatal("no spans were emitted") + } + var found int + for i := range spans { + if spans[i].Name == "jsonrpc.test/echo" { + attrs := attributeMap(spans[i].Attributes) + if attrs["rpc.system"] == "jsonrpc" && + attrs["rpc.service"] == "test" && + attrs["rpc.method"] == "echo" && + attrs["rpc.batch"] == "true" { + found++ + } + } + } + if found != len(batch) { + t.Fatalf("expected %d matching batch spans, got %d", len(batch), found) + } +} + +// TestTracingSubscribeUnsubscribe verifies that subscribe and unsubscribe calls +// do not emit any spans. +// Note: This works because client.newClientConn() passes nil as the tracer provider. +func TestTracingSubscribeUnsubscribe(t *testing.T) { + t.Parallel() + server, tracer, exporter := newTracingServer(t) + client := DialInProc(server) + t.Cleanup(client.Close) + + // Subscribe to notifications. + sub, err := client.Subscribe(context.Background(), "nftest", make(chan int), "someSubscription", 1, 1) + if err != nil { + t.Fatalf("subscribe failed: %v", err) + } + + // Unsubscribe. + sub.Unsubscribe() + + // Flush and check that no spans were emitted. + if err := tracer.ForceFlush(context.Background()); err != nil { + t.Fatalf("failed to flush: %v", err) + } + spans := exporter.GetSpans() + if len(spans) != 0 { + t.Errorf("expected no spans for subscribe/unsubscribe, got %d", len(spans)) + } +} diff --git a/rpc/websocket.go b/rpc/websocket.go index 9f67caf859..543ff617ba 100644 --- a/rpc/websocket.go +++ b/rpc/websocket.go @@ -60,7 +60,7 @@ func (s *Server) WebsocketHandler(allowedOrigins []string) http.Handler { log.Debug("WebSocket upgrade failed", "err", err) return } - codec := newWebsocketCodec(conn, r.Host, r.Header, wsDefaultReadLimit) + codec := newWebsocketCodec(conn, r.Host, r.Header, s.wsReadLimit) s.ServeCodec(codec, 0) }) } diff --git a/rpc/websocket_test.go b/rpc/websocket_test.go index a8d8624900..3b7d5a9da0 100644 --- a/rpc/websocket_test.go +++ b/rpc/websocket_test.go @@ -121,56 +121,49 @@ func TestWebsocketLargeRead(t *testing.T) { srv = newTestServer() httpsrv = httptest.NewServer(srv.WebsocketHandler([]string{"*"})) wsURL = "ws:" + strings.TrimPrefix(httpsrv.URL, "http:") + buffer = 64 ) defer srv.Stop() defer httpsrv.Close() - testLimit := func(limit *int64) { - opts := []ClientOption{} - expLimit := int64(wsDefaultReadLimit) - if limit != nil && *limit >= 0 { - opts = append(opts, WithWebsocketMessageSizeLimit(*limit)) - if *limit > 0 { - expLimit = *limit // 0 means infinite + for _, tt := range []struct { + size int + limit int + err bool + }{ + {200, 200, false}, // Small, successful request and limit + {2048, 1024, true}, // Normal, failed request + {wsDefaultReadLimit + buffer, 0, false}, // Large, successful request, infinite limit + } { + func() { + if tt.limit != 0 { + // Some buffer is added to the limit to account for JSON encoding. It's + // skipped when the limit is zero since the intention is for the limit + // to be infinite. + tt.limit += buffer } - } - client, err := DialOptions(context.Background(), wsURL, opts...) - if err != nil { - t.Fatalf("can't dial: %v", err) - } - defer client.Close() - // Remove some bytes for json encoding overhead. - underLimit := int(expLimit - 128) - overLimit := expLimit + 1 - if expLimit == wsDefaultReadLimit { - // No point trying the full 32MB in tests. Just sanity-check that - // it's not obviously limited. - underLimit = 1024 - overLimit = -1 - } - var res string - // Check under limit - if err = client.Call(&res, "test_repeat", "A", underLimit); err != nil { - t.Fatalf("unexpected error with limit %d: %v", expLimit, err) - } - if len(res) != underLimit || strings.Count(res, "A") != underLimit { - t.Fatal("incorrect data") - } - // Check over limit - if overLimit > 0 { - err = client.Call(&res, "test_repeat", "A", expLimit+1) - if err == nil || err != websocket.ErrReadLimit { - t.Fatalf("wrong error with limit %d: %v expecting %v", expLimit, err, websocket.ErrReadLimit) + opts := []ClientOption{WithWebsocketMessageSizeLimit(int64(tt.limit))} + client, err := DialOptions(context.Background(), wsURL, opts...) + if err != nil { + t.Fatalf("failed to dial test server: %v", err) } - } - } - ptr := func(v int64) *int64 { return &v } + defer client.Close() - testLimit(ptr(-1)) // Should be ignored (use default) - testLimit(ptr(0)) // Should be ignored (use default) - testLimit(nil) // Should be ignored (use default) - testLimit(ptr(200)) - testLimit(ptr(wsDefaultReadLimit * 2)) + var res string + err = client.Call(&res, "test_repeat", "A", tt.size) + if tt.err && err == nil { + t.Fatalf("expected error, got none") + } + if !tt.err { + if err != nil { + t.Fatalf("unexpected error with limit %d: %v", tt.limit, err) + } + if strings.Count(res, "A") != tt.size { + t.Fatal("incorrect data") + } + } + }() + } } func TestWebsocketPeerInfo(t *testing.T) { diff --git a/signer/core/api_test.go b/signer/core/api_test.go index 69229dadaf..ed4fdc5096 100644 --- a/signer/core/api_test.go +++ b/signer/core/api_test.go @@ -18,7 +18,6 @@ package core_test import ( "bytes" - "context" "fmt" "math/big" "os" @@ -97,12 +96,12 @@ func (ui *headlessUi) ApproveNewAccount(request *core.NewAccountRequest) (core.N } func (ui *headlessUi) ShowError(message string) { - //stdout is used by communication + // stdout is used by communication fmt.Fprintln(os.Stderr, message) } func (ui *headlessUi) ShowInfo(message string) { - //stdout is used by communication + // stdout is used by communication fmt.Fprintln(os.Stderr, message) } @@ -128,7 +127,7 @@ func setup(t *testing.T) (*core.SignerAPI, *headlessUi) { func createAccount(ui *headlessUi, api *core.SignerAPI, t *testing.T) { ui.approveCh <- "Y" ui.inputCh <- "a_long_password" - _, err := api.New(context.Background()) + _, err := api.New(t.Context()) if err != nil { t.Fatal(err) } @@ -143,7 +142,7 @@ func failCreateAccountWithPassword(ui *headlessUi, api *core.SignerAPI, password ui.inputCh <- password ui.inputCh <- password - addr, err := api.New(context.Background()) + addr, err := api.New(t.Context()) if err == nil { t.Fatal("Should have returned an error") } @@ -154,7 +153,7 @@ func failCreateAccountWithPassword(ui *headlessUi, api *core.SignerAPI, password func failCreateAccount(ui *headlessUi, api *core.SignerAPI, t *testing.T) { ui.approveCh <- "N" - addr, err := api.New(context.Background()) + addr, err := api.New(t.Context()) if err != core.ErrRequestDenied { t.Fatal(err) } @@ -165,7 +164,7 @@ func failCreateAccount(ui *headlessUi, api *core.SignerAPI, t *testing.T) { func list(ui *headlessUi, api *core.SignerAPI, t *testing.T) ([]common.Address, error) { ui.approveCh <- "A" - return api.List(context.Background()) + return api.List(t.Context()) } func TestNewAcc(t *testing.T) { @@ -199,7 +198,7 @@ func TestNewAcc(t *testing.T) { // Testing listing: // Listing one Account control.approveCh <- "1" - list, err := api.List(context.Background()) + list, err := api.List(t.Context()) if err != nil { t.Fatal(err) } @@ -208,7 +207,7 @@ func TestNewAcc(t *testing.T) { } // Listing denied control.approveCh <- "Nope" - list, err = api.List(context.Background()) + list, err = api.List(t.Context()) if len(list) != 0 { t.Fatalf("List should be empty") } @@ -246,7 +245,7 @@ func TestSignTx(t *testing.T) { api, control := setup(t) createAccount(control, api, t) control.approveCh <- "A" - list, err = api.List(context.Background()) + list, err = api.List(t.Context()) if err != nil { t.Fatal(err) } @@ -260,15 +259,15 @@ func TestSignTx(t *testing.T) { control.approveCh <- "Y" control.inputCh <- "wrongpassword" - res, err = api.SignTransaction(context.Background(), tx, &methodSig) + res, err = api.SignTransaction(t.Context(), tx, &methodSig) if res != nil { t.Errorf("Expected nil-response, got %v", res) } if err != keystore.ErrDecrypt { - t.Errorf("Expected ErrLocked! %v", err) + t.Errorf("Expected ErrDecrypt! %v", err) } control.approveCh <- "No way" - res, err = api.SignTransaction(context.Background(), tx, &methodSig) + res, err = api.SignTransaction(t.Context(), tx, &methodSig) if res != nil { t.Errorf("Expected nil-response, got %v", res) } @@ -278,22 +277,21 @@ func TestSignTx(t *testing.T) { // Sign with correct password control.approveCh <- "Y" control.inputCh <- "a_long_password" - res, err = api.SignTransaction(context.Background(), tx, &methodSig) - + res, err = api.SignTransaction(t.Context(), tx, &methodSig) if err != nil { t.Fatal(err) } parsedTx := &types.Transaction{} rlp.DecodeBytes(res.Raw, parsedTx) - //The tx should NOT be modified by the UI + // The tx should NOT be modified by the UI if parsedTx.Value().Cmp(tx.Value.ToInt()) != 0 { t.Errorf("Expected value to be unchanged, expected %v got %v", tx.Value, parsedTx.Value()) } control.approveCh <- "Y" control.inputCh <- "a_long_password" - res2, err = api.SignTransaction(context.Background(), tx, &methodSig) + res2, err = api.SignTransaction(t.Context(), tx, &methodSig) if err != nil { t.Fatal(err) } @@ -301,20 +299,20 @@ func TestSignTx(t *testing.T) { t.Error("Expected tx to be unmodified by UI") } - //The tx is modified by the UI + // The tx is modified by the UI control.approveCh <- "M" control.inputCh <- "a_long_password" - res2, err = api.SignTransaction(context.Background(), tx, &methodSig) + res2, err = api.SignTransaction(t.Context(), tx, &methodSig) if err != nil { t.Fatal(err) } parsedTx2 := &types.Transaction{} - rlp.DecodeBytes(res.Raw, parsedTx2) + rlp.DecodeBytes(res2.Raw, parsedTx2) - //The tx should be modified by the UI - if parsedTx2.Value().Cmp(tx.Value.ToInt()) != 0 { - t.Errorf("Expected value to be unchanged, got %v", parsedTx.Value()) + // The tx should be modified by the UI + if parsedTx2.Value().Cmp(tx.Value.ToInt()) == 0 { + t.Errorf("Expected value to be changed, got %v", parsedTx2.Value()) } if bytes.Equal(res.Raw, res2.Raw) { t.Error("Expected tx to be modified by UI") diff --git a/signer/core/apitypes/types.go b/signer/core/apitypes/types.go index dcbd04867c..9034e7e9ca 100644 --- a/signer/core/apitypes/types.go +++ b/signer/core/apitypes/types.go @@ -167,8 +167,11 @@ func (args *SendTxArgs) ToTransaction() (*types.Transaction, error) { BlobFeeCap: uint256.MustFromBig((*big.Int)(args.BlobFeeCap)), } if args.Blobs != nil { - // TODO(rjl493456442, marius) support V1 - data.(*types.BlobTx).Sidecar = types.NewBlobTxSidecar(types.BlobSidecarVersion0, args.Blobs, args.Commitments, args.Proofs) + version := types.BlobSidecarVersion0 + if len(args.Proofs) == len(args.Blobs)*kzg4844.CellProofsPerBlob { + version = types.BlobSidecarVersion1 + } + data.(*types.BlobTx).Sidecar = types.NewBlobTxSidecar(version, args.Blobs, args.Commitments, args.Proofs) } case args.MaxFeePerGas != nil: diff --git a/signer/core/signed_data_test.go b/signer/core/signed_data_test.go index 001f6b6838..8455aaf9c5 100644 --- a/signer/core/signed_data_test.go +++ b/signer/core/signed_data_test.go @@ -202,7 +202,7 @@ func TestSignData(t *testing.T) { t.Errorf("Expected nil-data, got %x", signature) } if err != keystore.ErrDecrypt { - t.Errorf("Expected ErrLocked! '%v'", err) + t.Errorf("Expected ErrDecrypt! '%v'", err) } control.approveCh <- "No way" signature, err = api.SignData(context.Background(), apitypes.TextPlain.Mime, a, hexutil.Encode([]byte("EHLO world"))) diff --git a/tests/block_test.go b/tests/block_test.go index 91d9f2e653..c718b304b6 100644 --- a/tests/block_test.go +++ b/tests/block_test.go @@ -81,8 +81,9 @@ func TestExecutionSpecBlocktests(t *testing.T) { } bt := new(testMatcher) - bt.skipLoad(".*prague/eip7251_consolidations/contract_deployment/system_contract_deployment.json") - bt.skipLoad(".*prague/eip7002_el_triggerable_withdrawals/contract_deployment/system_contract_deployment.json") + // These tests require us to handle scenarios where a system contract is not deployed at a fork + bt.skipLoad(".*prague/eip7251_consolidations/test_system_contract_deployment.json") + bt.skipLoad(".*prague/eip7002_el_triggerable_withdrawals/test_system_contract_deployment.json") bt.walk(t, executionSpecBlockchainTestDir, func(t *testing.T, name string, test *BlockTest) { execBlockTest(t, bt, test) diff --git a/tests/block_test_util.go b/tests/block_test_util.go index 3b88753b1c..4f6ab65c1a 100644 --- a/tests/block_test_util.go +++ b/tests/block_test_util.go @@ -116,27 +116,29 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *t if !ok { return UnsupportedForkError{t.json.Network} } + // import pre accounts & construct test genesis block & state root + // Commit genesis state var ( + gspec = t.genesis(config) db = rawdb.NewMemoryDatabase() tconf = &triedb.Config{ Preimages: true, + IsVerkle: gspec.Config.VerkleTime != nil && *gspec.Config.VerkleTime <= gspec.Timestamp, } ) - if scheme == rawdb.PathScheme { + if scheme == rawdb.PathScheme || tconf.IsVerkle { tconf.PathDB = pathdb.Defaults } else { tconf.HashDB = hashdb.Defaults } - // Commit genesis state - gspec := t.genesis(config) // if ttd is not specified, set an arbitrary huge value if gspec.Config.TerminalTotalDifficulty == nil { gspec.Config.TerminalTotalDifficulty = big.NewInt(stdmath.MaxInt64) } triedb := triedb.NewDatabase(db, tconf) - gblock, err := gspec.Commit(db, triedb) + gblock, err := gspec.Commit(db, triedb, nil) if err != nil { return err } @@ -202,6 +204,11 @@ func (t *BlockTest) Run(snapshotter bool, scheme string, witness bool, tracer *t return t.validateImportedHeaders(chain, validBlocks) } +// Network returns the network/fork name for this test. +func (t *BlockTest) Network() string { + return t.json.Network +} + func (t *BlockTest) genesis(config *params.ChainConfig) *core.Genesis { return &core.Genesis{ Config: config, @@ -259,7 +266,7 @@ func (t *BlockTest) insertBlocks(blockchain *core.BlockChain) ([]btBlock, error) } if b.BlockHeader == nil { if data, err := json.MarshalIndent(cb.Header(), "", " "); err == nil { - fmt.Fprintf(os.Stderr, "block (index %d) insertion should have failed due to: %v:\n%v\n", + fmt.Fprintf(os.Stdout, "block (index %d) insertion should have failed due to: %v:\n%v\n", bi, b.ExpectException, string(data)) } return nil, fmt.Errorf("block (index %d) insertion should have failed due to: %v", diff --git a/tests/fuzzers/rangeproof/rangeproof-fuzzer.go b/tests/fuzzers/rangeproof/rangeproof-fuzzer.go index 4d94d31c0c..c60c9cb6e6 100644 --- a/tests/fuzzers/rangeproof/rangeproof-fuzzer.go +++ b/tests/fuzzers/rangeproof/rangeproof-fuzzer.go @@ -32,7 +32,6 @@ import ( type kv struct { k, v []byte - t bool } type fuzzer struct { @@ -62,8 +61,8 @@ func (f *fuzzer) randomTrie(n int) (*trie.Trie, map[string]*kv) { size := f.readInt() // Fill it with some fluff for i := byte(0); i < byte(size); i++ { - value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}, false} - value2 := &kv{common.LeftPadBytes([]byte{i + 10}, 32), []byte{i}, false} + value := &kv{common.LeftPadBytes([]byte{i}, 32), []byte{i}} + value2 := &kv{common.LeftPadBytes([]byte{i + 10}, 32), []byte{i}} trie.MustUpdate(value.k, value.v) trie.MustUpdate(value2.k, value2.v) vals[string(value.k)] = value @@ -76,7 +75,7 @@ func (f *fuzzer) randomTrie(n int) (*trie.Trie, map[string]*kv) { for i := 0; i < n; i++ { k := f.randBytes(32) v := f.randBytes(20) - value := &kv{k, v, false} + value := &kv{k, v} trie.MustUpdate(k, v) vals[string(k)] = value if f.exhausted { diff --git a/tests/fuzzers/txfetcher/txfetcher_fuzzer.go b/tests/fuzzers/txfetcher/txfetcher_fuzzer.go index c136253a62..3baff33dcc 100644 --- a/tests/fuzzers/txfetcher/txfetcher_fuzzer.go +++ b/tests/fuzzers/txfetcher/txfetcher_fuzzer.go @@ -78,7 +78,7 @@ func fuzz(input []byte) int { rand := rand.New(rand.NewSource(0x3a29)) // Same used in package tests!!! f := fetcher.NewTxFetcherForTests( - func(common.Hash) bool { return false }, + func(common.Hash, byte) error { return nil }, func(txs []*types.Transaction) []error { return make([]error, len(txs)) }, diff --git a/tests/init.go b/tests/init.go index a8bc424fa2..d10b47986c 100644 --- a/tests/init.go +++ b/tests/init.go @@ -464,6 +464,293 @@ var Forks = map[string]*params.ChainConfig{ Osaka: params.DefaultOsakaBlobConfig, }, }, + "BPO1": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + OsakaTime: u64(0), + BPO1Time: u64(0), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: bpo1BlobConfig, + }, + }, + "OsakaToBPO1AtTime15k": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + OsakaTime: u64(0), + BPO1Time: u64(15_000), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: bpo1BlobConfig, + }, + }, + "BPO2": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + OsakaTime: u64(0), + BPO1Time: u64(0), + BPO2Time: u64(0), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: bpo1BlobConfig, + BPO2: bpo2BlobConfig, + }, + }, + "BPO1ToBPO2AtTime15k": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + OsakaTime: u64(0), + BPO1Time: u64(0), + BPO2Time: u64(15_000), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: bpo1BlobConfig, + BPO2: bpo2BlobConfig, + }, + }, + "BPO3": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + OsakaTime: u64(0), + BPO1Time: u64(0), + BPO2Time: u64(0), + BPO3Time: u64(0), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: bpo1BlobConfig, + BPO2: bpo2BlobConfig, + BPO3: params.DefaultBPO3BlobConfig, + }, + }, + "BPO2ToBPO3AtTime15k": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + OsakaTime: u64(0), + BPO1Time: u64(0), + BPO2Time: u64(0), + BPO3Time: u64(15_000), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: bpo1BlobConfig, + BPO2: bpo2BlobConfig, + BPO3: params.DefaultBPO3BlobConfig, + }, + }, + "BPO4": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + OsakaTime: u64(0), + BPO1Time: u64(0), + BPO2Time: u64(0), + BPO3Time: u64(0), + BPO4Time: u64(0), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: bpo1BlobConfig, + BPO2: bpo2BlobConfig, + BPO3: params.DefaultBPO3BlobConfig, + BPO4: params.DefaultBPO4BlobConfig, + }, + }, + "BPO3ToBPO4AtTime15k": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + CancunTime: u64(0), + PragueTime: u64(0), + OsakaTime: u64(0), + BPO1Time: u64(0), + BPO2Time: u64(0), + BPO3Time: u64(0), + BPO4Time: u64(15_000), + DepositContractAddress: params.MainnetChainConfig.DepositContractAddress, + BlobScheduleConfig: ¶ms.BlobScheduleConfig{ + Cancun: params.DefaultCancunBlobConfig, + Prague: params.DefaultPragueBlobConfig, + Osaka: params.DefaultOsakaBlobConfig, + BPO1: bpo1BlobConfig, + BPO2: bpo2BlobConfig, + BPO3: params.DefaultBPO3BlobConfig, + BPO4: params.DefaultBPO4BlobConfig, + }, + }, + "Verkle": { + ChainID: big.NewInt(1), + HomesteadBlock: big.NewInt(0), + EIP150Block: big.NewInt(0), + EIP155Block: big.NewInt(0), + EIP158Block: big.NewInt(0), + ByzantiumBlock: big.NewInt(0), + ConstantinopleBlock: big.NewInt(0), + PetersburgBlock: big.NewInt(0), + IstanbulBlock: big.NewInt(0), + MuirGlacierBlock: big.NewInt(0), + BerlinBlock: big.NewInt(0), + LondonBlock: big.NewInt(0), + ArrowGlacierBlock: big.NewInt(0), + MergeNetsplitBlock: big.NewInt(0), + TerminalTotalDifficulty: big.NewInt(0), + ShanghaiTime: u64(0), + VerkleTime: u64(0), + }, +} + +var bpo1BlobConfig = ¶ms.BlobConfig{ + Target: 9, + Max: 14, + UpdateFraction: 8832827, +} + +var bpo2BlobConfig = ¶ms.BlobConfig{ + Target: 14, + Max: 21, + UpdateFraction: 13739630, } // AvailableForks returns the set of defined fork names diff --git a/tests/state_test.go b/tests/state_test.go index 301bc3a7a9..f80bda4372 100644 --- a/tests/state_test.go +++ b/tests/state_test.go @@ -156,8 +156,8 @@ func execStateTest(t *testing.T, st *testMatcher, test *StateTest) { withTrace(t, test.gasLimit(subtest), func(vmconfig vm.Config) error { var result error test.Run(subtest, vmconfig, true, rawdb.PathScheme, func(err error, state *StateTestState) { - if state.Snapshots != nil && state.StateDB != nil { - if _, err := state.Snapshots.Journal(state.StateDB.IntermediateRoot(false)); err != nil { + if state.TrieDB != nil && state.StateDB != nil { + if err := state.TrieDB.Journal(state.StateDB.IntermediateRoot(false)); err != nil { result = err return } diff --git a/tests/state_test_util.go b/tests/state_test_util.go index a22e470ad8..3c1df35157 100644 --- a/tests/state_test_util.go +++ b/tests/state_test_util.go @@ -234,6 +234,20 @@ func (t *StateTest) Run(subtest StateSubtest, vmconfig vm.Config, snapshotter bo if err != nil { // Here, an error exists but it was expected. // We do not check the post state or logs. + // However, if the test defines a post state root, we should check it. + // In case of an error, the state is reverted to the snapshot, so we need to + // recalculate the root. + post := t.json.Post[subtest.Fork][subtest.Index] + if post.Root != (common.UnprefixedHash{}) { + config, _, err := GetChainConfig(subtest.Fork) + if err != nil { + return fmt.Errorf("failed to get chain config: %w", err) + } + root = st.StateDB.IntermediateRoot(config.IsEIP158(new(big.Int).SetUint64(t.json.Env.Number))) + if root != common.Hash(post.Root) { + return fmt.Errorf("post-state root does not match the pre-state root, indicates an error in the test: got %x, want %x", root, post.Root) + } + } return nil } post := t.json.Post[subtest.Fork][subtest.Index] @@ -511,7 +525,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo sdb := state.NewDatabase(triedb, nil) statedb, _ := state.New(types.EmptyRootHash, sdb) for addr, a := range accounts { - statedb.SetCode(addr, a.Code) + statedb.SetCode(addr, a.Code, tracing.CodeChangeUnspecified) statedb.SetNonce(addr, a.Nonce, tracing.NonceChangeUnspecified) statedb.SetBalance(addr, uint256.MustFromBig(a.Balance), tracing.BalanceChangeUnspecified) for k, v := range a.Storage { @@ -523,7 +537,7 @@ func MakePreState(db ethdb.Database, accounts types.GenesisAlloc, snapshotter bo // If snapshot is requested, initialize the snapshotter and use it in state. var snaps *snapshot.Tree - if snapshotter { + if snapshotter && scheme == rawdb.HashScheme { snapconfig := snapshot.Config{ CacheSize: 1, Recovery: false, @@ -559,3 +573,6 @@ type dummyChain struct { func (d *dummyChain) Engine() consensus.Engine { return nil } func (d *dummyChain) GetHeader(h common.Hash, n uint64) *types.Header { return nil } func (d *dummyChain) Config() *params.ChainConfig { return d.config } +func (d *dummyChain) CurrentHeader() *types.Header { return nil } +func (d *dummyChain) GetHeaderByNumber(n uint64) *types.Header { return nil } +func (d *dummyChain) GetHeaderByHash(h common.Hash) *types.Header { return nil } diff --git a/tests/transaction_test.go b/tests/transaction_test.go index 6260df0f3f..73ee3aa16a 100644 --- a/tests/transaction_test.go +++ b/tests/transaction_test.go @@ -70,7 +70,7 @@ func TestExecutionSpecTransaction(t *testing.T) { st := new(testMatcher) // Emptiness of authorization list is only validated during the tx precheck - st.skipLoad("^prague/eip7702_set_code_tx/invalid_tx/empty_authorization_list.json") + st.skipLoad("^prague/eip7702_set_code_tx/test_empty_authorization_list.json") st.walk(t, executionSpecTransactionTestDir, func(t *testing.T, name string, test *TransactionTest) { if err := st.checkFailure(t, test.Run()); err != nil { diff --git a/trie/bintrie/binary_node.go b/trie/bintrie/binary_node.go new file mode 100644 index 0000000000..690489b2aa --- /dev/null +++ b/trie/bintrie/binary_node.go @@ -0,0 +1,139 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "errors" + + "github.com/ethereum/go-ethereum/common" +) + +type ( + NodeFlushFn func([]byte, BinaryNode) + NodeResolverFn func([]byte, common.Hash) ([]byte, error) +) + +// zero is the zero value for a 32-byte array. +var zero [32]byte + +const ( + StemNodeWidth = 256 // Number of child per leaf node + StemSize = 31 // Number of bytes to travel before reaching a group of leaves + NodeTypeBytes = 1 // Size of node type prefix in serialization + HashSize = 32 // Size of a hash in bytes + BitmapSize = 32 // Size of the bitmap in a stem node +) + +const ( + nodeTypeStem = iota + 1 // Stem node, contains a stem and a bitmap of values + nodeTypeInternal +) + +// BinaryNode is an interface for a binary trie node. +type BinaryNode interface { + Get([]byte, NodeResolverFn) ([]byte, error) + Insert([]byte, []byte, NodeResolverFn, int) (BinaryNode, error) + Copy() BinaryNode + Hash() common.Hash + GetValuesAtStem([]byte, NodeResolverFn) ([][]byte, error) + InsertValuesAtStem([]byte, [][]byte, NodeResolverFn, int) (BinaryNode, error) + CollectNodes([]byte, NodeFlushFn) error + + toDot(parent, path string) string + GetHeight() int +} + +// SerializeNode serializes a binary trie node into a byte slice. +func SerializeNode(node BinaryNode) []byte { + switch n := (node).(type) { + case *InternalNode: + // InternalNode: 1 byte type + 32 bytes left hash + 32 bytes right hash + var serialized [NodeTypeBytes + HashSize + HashSize]byte + serialized[0] = nodeTypeInternal + copy(serialized[1:33], n.left.Hash().Bytes()) + copy(serialized[33:65], n.right.Hash().Bytes()) + return serialized[:] + case *StemNode: + // StemNode: 1 byte type + 31 bytes stem + 32 bytes bitmap + 256*32 bytes values + var serialized [NodeTypeBytes + StemSize + BitmapSize + StemNodeWidth*HashSize]byte + serialized[0] = nodeTypeStem + copy(serialized[NodeTypeBytes:NodeTypeBytes+StemSize], n.Stem) + bitmap := serialized[NodeTypeBytes+StemSize : NodeTypeBytes+StemSize+BitmapSize] + offset := NodeTypeBytes + StemSize + BitmapSize + for i, v := range n.Values { + if v != nil { + bitmap[i/8] |= 1 << (7 - (i % 8)) + copy(serialized[offset:offset+HashSize], v) + offset += HashSize + } + } + // Only return the actual data, not the entire array + return serialized[:offset] + default: + panic("invalid node type") + } +} + +var invalidSerializedLength = errors.New("invalid serialized node length") + +// DeserializeNode deserializes a binary trie node from a byte slice. +func DeserializeNode(serialized []byte, depth int) (BinaryNode, error) { + if len(serialized) == 0 { + return Empty{}, nil + } + + switch serialized[0] { + case nodeTypeInternal: + if len(serialized) != 65 { + return nil, invalidSerializedLength + } + return &InternalNode{ + depth: depth, + left: HashedNode(common.BytesToHash(serialized[1:33])), + right: HashedNode(common.BytesToHash(serialized[33:65])), + }, nil + case nodeTypeStem: + if len(serialized) < 64 { + return nil, invalidSerializedLength + } + var values [StemNodeWidth][]byte + bitmap := serialized[NodeTypeBytes+StemSize : NodeTypeBytes+StemSize+BitmapSize] + offset := NodeTypeBytes + StemSize + BitmapSize + + for i := range StemNodeWidth { + if bitmap[i/8]>>(7-(i%8))&1 == 1 { + if len(serialized) < offset+HashSize { + return nil, invalidSerializedLength + } + values[i] = serialized[offset : offset+HashSize] + offset += HashSize + } + } + return &StemNode{ + Stem: serialized[NodeTypeBytes : NodeTypeBytes+StemSize], + Values: values[:], + depth: depth, + }, nil + default: + return nil, errors.New("invalid node type") + } +} + +// ToDot converts the binary trie to a DOT language representation. Useful for debugging. +func ToDot(root BinaryNode) string { + return root.toDot("", "") +} diff --git a/trie/bintrie/binary_node_test.go b/trie/bintrie/binary_node_test.go new file mode 100644 index 0000000000..242743ba53 --- /dev/null +++ b/trie/bintrie/binary_node_test.go @@ -0,0 +1,252 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +// TestSerializeDeserializeInternalNode tests serialization and deserialization of InternalNode +func TestSerializeDeserializeInternalNode(t *testing.T) { + // Create an internal node with two hashed children + leftHash := common.HexToHash("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef") + rightHash := common.HexToHash("0xfedcba0987654321fedcba0987654321fedcba0987654321fedcba0987654321") + + node := &InternalNode{ + depth: 5, + left: HashedNode(leftHash), + right: HashedNode(rightHash), + } + + // Serialize the node + serialized := SerializeNode(node) + + // Check the serialized format + if serialized[0] != nodeTypeInternal { + t.Errorf("Expected type byte to be %d, got %d", nodeTypeInternal, serialized[0]) + } + + if len(serialized) != 65 { + t.Errorf("Expected serialized length to be 65, got %d", len(serialized)) + } + + // Deserialize the node + deserialized, err := DeserializeNode(serialized, 5) + if err != nil { + t.Fatalf("Failed to deserialize node: %v", err) + } + + // Check that it's an internal node + internalNode, ok := deserialized.(*InternalNode) + if !ok { + t.Fatalf("Expected InternalNode, got %T", deserialized) + } + + // Check the depth + if internalNode.depth != 5 { + t.Errorf("Expected depth 5, got %d", internalNode.depth) + } + + // Check the left and right hashes + if internalNode.left.Hash() != leftHash { + t.Errorf("Left hash mismatch: expected %x, got %x", leftHash, internalNode.left.Hash()) + } + + if internalNode.right.Hash() != rightHash { + t.Errorf("Right hash mismatch: expected %x, got %x", rightHash, internalNode.right.Hash()) + } +} + +// TestSerializeDeserializeStemNode tests serialization and deserialization of StemNode +func TestSerializeDeserializeStemNode(t *testing.T) { + // Create a stem node with some values + stem := make([]byte, StemSize) + for i := range stem { + stem[i] = byte(i) + } + + var values [StemNodeWidth][]byte + // Add some values at different indices + values[0] = common.HexToHash("0x0101010101010101010101010101010101010101010101010101010101010101").Bytes() + values[10] = common.HexToHash("0x0202020202020202020202020202020202020202020202020202020202020202").Bytes() + values[255] = common.HexToHash("0x0303030303030303030303030303030303030303030303030303030303030303").Bytes() + + node := &StemNode{ + Stem: stem, + Values: values[:], + depth: 10, + } + + // Serialize the node + serialized := SerializeNode(node) + + // Check the serialized format + if serialized[0] != nodeTypeStem { + t.Errorf("Expected type byte to be %d, got %d", nodeTypeStem, serialized[0]) + } + + // Check the stem is correctly serialized + if !bytes.Equal(serialized[1:1+StemSize], stem) { + t.Errorf("Stem mismatch in serialized data") + } + + // Deserialize the node + deserialized, err := DeserializeNode(serialized, 10) + if err != nil { + t.Fatalf("Failed to deserialize node: %v", err) + } + + // Check that it's a stem node + stemNode, ok := deserialized.(*StemNode) + if !ok { + t.Fatalf("Expected StemNode, got %T", deserialized) + } + + // Check the stem + if !bytes.Equal(stemNode.Stem, stem) { + t.Errorf("Stem mismatch after deserialization") + } + + // Check the values + if !bytes.Equal(stemNode.Values[0], values[0]) { + t.Errorf("Value at index 0 mismatch") + } + if !bytes.Equal(stemNode.Values[10], values[10]) { + t.Errorf("Value at index 10 mismatch") + } + if !bytes.Equal(stemNode.Values[255], values[255]) { + t.Errorf("Value at index 255 mismatch") + } + + // Check that other values are nil + for i := range StemNodeWidth { + if i == 0 || i == 10 || i == 255 { + continue + } + if stemNode.Values[i] != nil { + t.Errorf("Expected nil value at index %d, got %x", i, stemNode.Values[i]) + } + } +} + +// TestDeserializeEmptyNode tests deserialization of empty node +func TestDeserializeEmptyNode(t *testing.T) { + // Empty byte slice should deserialize to Empty node + deserialized, err := DeserializeNode([]byte{}, 0) + if err != nil { + t.Fatalf("Failed to deserialize empty node: %v", err) + } + + _, ok := deserialized.(Empty) + if !ok { + t.Fatalf("Expected Empty node, got %T", deserialized) + } +} + +// TestDeserializeInvalidType tests deserialization with invalid type byte +func TestDeserializeInvalidType(t *testing.T) { + // Create invalid serialized data with unknown type byte + invalidData := []byte{99, 0, 0, 0} // Type byte 99 is invalid + + _, err := DeserializeNode(invalidData, 0) + if err == nil { + t.Fatal("Expected error for invalid type byte, got nil") + } +} + +// TestDeserializeInvalidLength tests deserialization with invalid data length +func TestDeserializeInvalidLength(t *testing.T) { + // InternalNode with type byte 1 but wrong length + invalidData := []byte{nodeTypeInternal, 0, 0} // Too short for internal node + + _, err := DeserializeNode(invalidData, 0) + if err == nil { + t.Fatal("Expected error for invalid data length, got nil") + } + + if err.Error() != "invalid serialized node length" { + t.Errorf("Expected 'invalid serialized node length' error, got: %v", err) + } +} + +// TestKeyToPath tests the keyToPath function +func TestKeyToPath(t *testing.T) { + tests := []struct { + name string + depth int + key []byte + expected []byte + wantErr bool + }{ + { + name: "depth 0", + depth: 0, + key: []byte{0x80}, // 10000000 in binary + expected: []byte{1}, + wantErr: false, + }, + { + name: "depth 7", + depth: 7, + key: []byte{0xFF}, // 11111111 in binary + expected: []byte{1, 1, 1, 1, 1, 1, 1, 1}, + wantErr: false, + }, + { + name: "depth crossing byte boundary", + depth: 10, + key: []byte{0xFF, 0x00}, // 11111111 00000000 in binary + expected: []byte{1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0}, + wantErr: false, + }, + { + name: "max valid depth", + depth: StemSize * 8, + key: make([]byte, HashSize), + expected: make([]byte, StemSize*8+1), + wantErr: false, + }, + { + name: "depth too large", + depth: StemSize*8 + 1, + key: make([]byte, HashSize), + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + path, err := keyToPath(tt.depth, tt.key) + if tt.wantErr { + if err == nil { + t.Errorf("Expected error for depth %d, got nil", tt.depth) + } + return + } + if err != nil { + t.Errorf("Unexpected error: %v", err) + return + } + if !bytes.Equal(path, tt.expected) { + t.Errorf("Path mismatch: expected %v, got %v", tt.expected, path) + } + }) + } +} diff --git a/trie/bintrie/empty.go b/trie/bintrie/empty.go new file mode 100644 index 0000000000..7cfe373b35 --- /dev/null +++ b/trie/bintrie/empty.go @@ -0,0 +1,72 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "slices" + + "github.com/ethereum/go-ethereum/common" +) + +type Empty struct{} + +func (e Empty) Get(_ []byte, _ NodeResolverFn) ([]byte, error) { + return nil, nil +} + +func (e Empty) Insert(key []byte, value []byte, _ NodeResolverFn, depth int) (BinaryNode, error) { + var values [256][]byte + values[key[31]] = value + return &StemNode{ + Stem: slices.Clone(key[:31]), + Values: values[:], + depth: depth, + }, nil +} + +func (e Empty) Copy() BinaryNode { + return Empty{} +} + +func (e Empty) Hash() common.Hash { + return common.Hash{} +} + +func (e Empty) GetValuesAtStem(_ []byte, _ NodeResolverFn) ([][]byte, error) { + var values [256][]byte + return values[:], nil +} + +func (e Empty) InsertValuesAtStem(key []byte, values [][]byte, _ NodeResolverFn, depth int) (BinaryNode, error) { + return &StemNode{ + Stem: slices.Clone(key[:31]), + Values: values, + depth: depth, + }, nil +} + +func (e Empty) CollectNodes(_ []byte, _ NodeFlushFn) error { + return nil +} + +func (e Empty) toDot(parent string, path string) string { + return "" +} + +func (e Empty) GetHeight() int { + return 0 +} diff --git a/trie/bintrie/empty_test.go b/trie/bintrie/empty_test.go new file mode 100644 index 0000000000..574ae1830b --- /dev/null +++ b/trie/bintrie/empty_test.go @@ -0,0 +1,222 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +// TestEmptyGet tests the Get method +func TestEmptyGet(t *testing.T) { + node := Empty{} + + key := make([]byte, 32) + value, err := node.Get(key, nil) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + if value != nil { + t.Errorf("Expected nil value from empty node, got %x", value) + } +} + +// TestEmptyInsert tests the Insert method +func TestEmptyInsert(t *testing.T) { + node := Empty{} + + key := make([]byte, 32) + key[0] = 0x12 + key[31] = 0x34 + value := common.HexToHash("0xabcd").Bytes() + + newNode, err := node.Insert(key, value, nil, 0) + if err != nil { + t.Fatalf("Failed to insert: %v", err) + } + + // Should create a StemNode + stemNode, ok := newNode.(*StemNode) + if !ok { + t.Fatalf("Expected StemNode, got %T", newNode) + } + + // Check the stem (first 31 bytes of key) + if !bytes.Equal(stemNode.Stem, key[:31]) { + t.Errorf("Stem mismatch: expected %x, got %x", key[:31], stemNode.Stem) + } + + // Check the value at the correct index (last byte of key) + if !bytes.Equal(stemNode.Values[key[31]], value) { + t.Errorf("Value mismatch at index %d: expected %x, got %x", key[31], value, stemNode.Values[key[31]]) + } + + // Check that other values are nil + for i := 0; i < 256; i++ { + if i != int(key[31]) && stemNode.Values[i] != nil { + t.Errorf("Expected nil value at index %d, got %x", i, stemNode.Values[i]) + } + } +} + +// TestEmptyCopy tests the Copy method +func TestEmptyCopy(t *testing.T) { + node := Empty{} + + copied := node.Copy() + copiedEmpty, ok := copied.(Empty) + if !ok { + t.Fatalf("Expected Empty, got %T", copied) + } + + // Both should be empty + if node != copiedEmpty { + // Empty is a zero-value struct, so copies should be equal + t.Errorf("Empty nodes should be equal") + } +} + +// TestEmptyHash tests the Hash method +func TestEmptyHash(t *testing.T) { + node := Empty{} + + hash := node.Hash() + + // Empty node should have zero hash + if hash != (common.Hash{}) { + t.Errorf("Expected zero hash for empty node, got %x", hash) + } +} + +// TestEmptyGetValuesAtStem tests the GetValuesAtStem method +func TestEmptyGetValuesAtStem(t *testing.T) { + node := Empty{} + + stem := make([]byte, 31) + values, err := node.GetValuesAtStem(stem, nil) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // Should return an array of 256 nil values + if len(values) != 256 { + t.Errorf("Expected 256 values, got %d", len(values)) + } + + for i, v := range values { + if v != nil { + t.Errorf("Expected nil value at index %d, got %x", i, v) + } + } +} + +// TestEmptyInsertValuesAtStem tests the InsertValuesAtStem method +func TestEmptyInsertValuesAtStem(t *testing.T) { + node := Empty{} + + stem := make([]byte, 31) + stem[0] = 0x42 + + var values [256][]byte + values[0] = common.HexToHash("0x0101").Bytes() + values[10] = common.HexToHash("0x0202").Bytes() + values[255] = common.HexToHash("0x0303").Bytes() + + newNode, err := node.InsertValuesAtStem(stem, values[:], nil, 5) + if err != nil { + t.Fatalf("Failed to insert values: %v", err) + } + + // Should create a StemNode + stemNode, ok := newNode.(*StemNode) + if !ok { + t.Fatalf("Expected StemNode, got %T", newNode) + } + + // Check the stem + if !bytes.Equal(stemNode.Stem, stem) { + t.Errorf("Stem mismatch: expected %x, got %x", stem, stemNode.Stem) + } + + // Check the depth + if stemNode.depth != 5 { + t.Errorf("Depth mismatch: expected 5, got %d", stemNode.depth) + } + + // Check the values + if !bytes.Equal(stemNode.Values[0], values[0]) { + t.Error("Value at index 0 mismatch") + } + if !bytes.Equal(stemNode.Values[10], values[10]) { + t.Error("Value at index 10 mismatch") + } + if !bytes.Equal(stemNode.Values[255], values[255]) { + t.Error("Value at index 255 mismatch") + } + + // Check that values is the same slice (not a copy) + if &stemNode.Values[0] != &values[0] { + t.Error("Expected values to be the same slice reference") + } +} + +// TestEmptyCollectNodes tests the CollectNodes method +func TestEmptyCollectNodes(t *testing.T) { + node := Empty{} + + var collected []BinaryNode + flushFn := func(path []byte, n BinaryNode) { + collected = append(collected, n) + } + + err := node.CollectNodes([]byte{0, 1, 0}, flushFn) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } + + // Should not collect anything for empty node + if len(collected) != 0 { + t.Errorf("Expected no collected nodes for empty, got %d", len(collected)) + } +} + +// TestEmptyToDot tests the toDot method +func TestEmptyToDot(t *testing.T) { + node := Empty{} + + dot := node.toDot("parent", "010") + + // Should return empty string for empty node + if dot != "" { + t.Errorf("Expected empty string for empty node toDot, got %s", dot) + } +} + +// TestEmptyGetHeight tests the GetHeight method +func TestEmptyGetHeight(t *testing.T) { + node := Empty{} + + height := node.GetHeight() + + // Empty node should have height 0 + if height != 0 { + t.Errorf("Expected height 0 for empty node, got %d", height) + } +} diff --git a/trie/bintrie/hashed_node.go b/trie/bintrie/hashed_node.go new file mode 100644 index 0000000000..e4d8c2e7ac --- /dev/null +++ b/trie/bintrie/hashed_node.go @@ -0,0 +1,90 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" +) + +type HashedNode common.Hash + +func (h HashedNode) Get(_ []byte, _ NodeResolverFn) ([]byte, error) { + panic("not implemented") // TODO: Implement +} + +func (h HashedNode) Insert(key []byte, value []byte, resolver NodeResolverFn, depth int) (BinaryNode, error) { + return nil, errors.New("insert not implemented for hashed node") +} + +func (h HashedNode) Copy() BinaryNode { + nh := common.Hash(h) + return HashedNode(nh) +} + +func (h HashedNode) Hash() common.Hash { + return common.Hash(h) +} + +func (h HashedNode) GetValuesAtStem(_ []byte, _ NodeResolverFn) ([][]byte, error) { + return nil, errors.New("attempted to get values from an unresolved node") +} + +func (h HashedNode) InsertValuesAtStem(stem []byte, values [][]byte, resolver NodeResolverFn, depth int) (BinaryNode, error) { + // Step 1: Generate the path for this node's position in the tree + path, err := keyToPath(depth, stem) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem path generation error: %w", err) + } + + if resolver == nil { + return nil, errors.New("InsertValuesAtStem resolve error: resolver is nil") + } + + // Step 2: Resolve the hashed node to get the actual node data + data, err := resolver(path, common.Hash(h)) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem resolve error: %w", err) + } + + // Step 3: Deserialize the resolved data into a concrete node + node, err := DeserializeNode(data, depth) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem node deserialization error: %w", err) + } + + // Step 4: Call InsertValuesAtStem on the resolved concrete node + return node.InsertValuesAtStem(stem, values, resolver, depth) +} + +func (h HashedNode) toDot(parent string, path string) string { + me := fmt.Sprintf("hash%s", path) + ret := fmt.Sprintf("%s [label=\"%x\"]\n", me, h) + ret = fmt.Sprintf("%s %s -> %s\n", ret, parent, me) + return ret +} + +func (h HashedNode) CollectNodes([]byte, NodeFlushFn) error { + // HashedNodes are already persisted in the database and don't need to be collected. + return nil +} + +func (h HashedNode) GetHeight() int { + panic("tried to get the height of a hashed node, this is a bug") +} diff --git a/trie/bintrie/hashed_node_test.go b/trie/bintrie/hashed_node_test.go new file mode 100644 index 0000000000..f9e6984888 --- /dev/null +++ b/trie/bintrie/hashed_node_test.go @@ -0,0 +1,197 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +// TestHashedNodeHash tests the Hash method +func TestHashedNodeHash(t *testing.T) { + hash := common.HexToHash("0x1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef") + node := HashedNode(hash) + + // Hash should return the stored hash + if node.Hash() != hash { + t.Errorf("Hash mismatch: expected %x, got %x", hash, node.Hash()) + } +} + +// TestHashedNodeCopy tests the Copy method +func TestHashedNodeCopy(t *testing.T) { + hash := common.HexToHash("0xabcdef") + node := HashedNode(hash) + + copied := node.Copy() + copiedHash, ok := copied.(HashedNode) + if !ok { + t.Fatalf("Expected HashedNode, got %T", copied) + } + + // Hash should be the same + if common.Hash(copiedHash) != hash { + t.Errorf("Hash mismatch after copy: expected %x, got %x", hash, copiedHash) + } + + // But should be a different object + if &node == &copiedHash { + t.Error("Copy returned same object reference") + } +} + +// TestHashedNodeInsert tests that Insert returns an error +func TestHashedNodeInsert(t *testing.T) { + node := HashedNode(common.HexToHash("0x1234")) + + key := make([]byte, HashSize) + value := make([]byte, HashSize) + + _, err := node.Insert(key, value, nil, 0) + if err == nil { + t.Fatal("Expected error for Insert on HashedNode") + } + + if err.Error() != "insert not implemented for hashed node" { + t.Errorf("Unexpected error message: %v", err) + } +} + +// TestHashedNodeGetValuesAtStem tests that GetValuesAtStem returns an error +func TestHashedNodeGetValuesAtStem(t *testing.T) { + node := HashedNode(common.HexToHash("0x1234")) + + stem := make([]byte, StemSize) + _, err := node.GetValuesAtStem(stem, nil) + if err == nil { + t.Fatal("Expected error for GetValuesAtStem on HashedNode") + } + + if err.Error() != "attempted to get values from an unresolved node" { + t.Errorf("Unexpected error message: %v", err) + } +} + +// TestHashedNodeInsertValuesAtStem tests that InsertValuesAtStem returns an error +func TestHashedNodeInsertValuesAtStem(t *testing.T) { + node := HashedNode(common.HexToHash("0x1234")) + + stem := make([]byte, StemSize) + values := make([][]byte, StemNodeWidth) + + // Test 1: nil resolver should return an error + _, err := node.InsertValuesAtStem(stem, values, nil, 0) + if err == nil { + t.Fatal("Expected error for InsertValuesAtStem on HashedNode with nil resolver") + } + + if err.Error() != "InsertValuesAtStem resolve error: resolver is nil" { + t.Errorf("Unexpected error message: %v", err) + } + + // Test 2: mock resolver returning invalid data should return deserialization error + mockResolver := func(path []byte, hash common.Hash) ([]byte, error) { + // Return invalid/nonsense data that cannot be deserialized + return []byte{0xff, 0xff, 0xff}, nil + } + + _, err = node.InsertValuesAtStem(stem, values, mockResolver, 0) + if err == nil { + t.Fatal("Expected error for InsertValuesAtStem on HashedNode with invalid resolver data") + } + + expectedPrefix := "InsertValuesAtStem node deserialization error:" + if len(err.Error()) < len(expectedPrefix) || err.Error()[:len(expectedPrefix)] != expectedPrefix { + t.Errorf("Expected deserialization error, got: %v", err) + } + + // Test 3: mock resolver returning valid serialized node should succeed + stem = make([]byte, StemSize) + stem[0] = 0xaa + var originalValues [StemNodeWidth][]byte + originalValues[0] = common.HexToHash("0x1111111111111111111111111111111111111111111111111111111111111111").Bytes() + originalValues[1] = common.HexToHash("0x2222222222222222222222222222222222222222222222222222222222222222").Bytes() + + originalNode := &StemNode{ + Stem: stem, + Values: originalValues[:], + depth: 0, + } + + // Serialize the node + serialized := SerializeNode(originalNode) + + // Create a mock resolver that returns the serialized node + validResolver := func(path []byte, hash common.Hash) ([]byte, error) { + return serialized, nil + } + + var newValues [StemNodeWidth][]byte + newValues[2] = common.HexToHash("0x3333333333333333333333333333333333333333333333333333333333333333").Bytes() + + resolvedNode, err := node.InsertValuesAtStem(stem, newValues[:], validResolver, 0) + if err != nil { + t.Fatalf("Expected successful resolution and insertion, got error: %v", err) + } + + resultStem, ok := resolvedNode.(*StemNode) + if !ok { + t.Fatalf("Expected resolved node to be *StemNode, got %T", resolvedNode) + } + + if !bytes.Equal(resultStem.Stem, stem) { + t.Errorf("Stem mismatch: expected %x, got %x", stem, resultStem.Stem) + } + + // Verify the original values are preserved + if !bytes.Equal(resultStem.Values[0], originalValues[0]) { + t.Errorf("Original value at index 0 not preserved: expected %x, got %x", originalValues[0], resultStem.Values[0]) + } + if !bytes.Equal(resultStem.Values[1], originalValues[1]) { + t.Errorf("Original value at index 1 not preserved: expected %x, got %x", originalValues[1], resultStem.Values[1]) + } + + // Verify the new value was inserted + if !bytes.Equal(resultStem.Values[2], newValues[2]) { + t.Errorf("New value at index 2 not inserted correctly: expected %x, got %x", newValues[2], resultStem.Values[2]) + } +} + +// TestHashedNodeToDot tests the toDot method for visualization +func TestHashedNodeToDot(t *testing.T) { + hash := common.HexToHash("0x1234") + node := HashedNode(hash) + + dot := node.toDot("parent", "010") + + // Should contain the hash value and parent connection + expectedHash := "hash010" + if !contains(dot, expectedHash) { + t.Errorf("Expected dot output to contain %s", expectedHash) + } + + if !contains(dot, "parent -> hash010") { + t.Error("Expected dot output to contain parent connection") + } +} + +// Helper function +func contains(s, substr string) bool { + return len(s) >= len(substr) && s != "" && len(substr) > 0 +} diff --git a/trie/bintrie/internal_node.go b/trie/bintrie/internal_node.go new file mode 100644 index 0000000000..0a7bece521 --- /dev/null +++ b/trie/bintrie/internal_node.go @@ -0,0 +1,241 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "crypto/sha256" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" +) + +func keyToPath(depth int, key []byte) ([]byte, error) { + if depth > 31*8 { + return nil, errors.New("node too deep") + } + path := make([]byte, 0, depth+1) + for i := range depth + 1 { + bit := key[i/8] >> (7 - (i % 8)) & 1 + path = append(path, bit) + } + return path, nil +} + +// InternalNode is a binary trie internal node. +type InternalNode struct { + left, right BinaryNode + depth int +} + +// GetValuesAtStem retrieves the group of values located at the given stem key. +func (bt *InternalNode) GetValuesAtStem(stem []byte, resolver NodeResolverFn) ([][]byte, error) { + if bt.depth > 31*8 { + return nil, errors.New("node too deep") + } + + bit := stem[bt.depth/8] >> (7 - (bt.depth % 8)) & 1 + if bit == 0 { + if hn, ok := bt.left.(HashedNode); ok { + path, err := keyToPath(bt.depth, stem) + if err != nil { + return nil, fmt.Errorf("GetValuesAtStem resolve error: %w", err) + } + data, err := resolver(path, common.Hash(hn)) + if err != nil { + return nil, fmt.Errorf("GetValuesAtStem resolve error: %w", err) + } + node, err := DeserializeNode(data, bt.depth+1) + if err != nil { + return nil, fmt.Errorf("GetValuesAtStem node deserialization error: %w", err) + } + bt.left = node + } + return bt.left.GetValuesAtStem(stem, resolver) + } + + if hn, ok := bt.right.(HashedNode); ok { + path, err := keyToPath(bt.depth, stem) + if err != nil { + return nil, fmt.Errorf("GetValuesAtStem resolve error: %w", err) + } + data, err := resolver(path, common.Hash(hn)) + if err != nil { + return nil, fmt.Errorf("GetValuesAtStem resolve error: %w", err) + } + node, err := DeserializeNode(data, bt.depth+1) + if err != nil { + return nil, fmt.Errorf("GetValuesAtStem node deserialization error: %w", err) + } + bt.right = node + } + return bt.right.GetValuesAtStem(stem, resolver) +} + +// Get retrieves the value for the given key. +func (bt *InternalNode) Get(key []byte, resolver NodeResolverFn) ([]byte, error) { + values, err := bt.GetValuesAtStem(key[:31], resolver) + if err != nil { + return nil, fmt.Errorf("get error: %w", err) + } + if values == nil { + return nil, nil + } + return values[key[31]], nil +} + +// Insert inserts a new key-value pair into the trie. +func (bt *InternalNode) Insert(key []byte, value []byte, resolver NodeResolverFn, depth int) (BinaryNode, error) { + var values [256][]byte + values[key[31]] = value + return bt.InsertValuesAtStem(key[:31], values[:], resolver, depth) +} + +// Copy creates a deep copy of the node. +func (bt *InternalNode) Copy() BinaryNode { + return &InternalNode{ + left: bt.left.Copy(), + right: bt.right.Copy(), + depth: bt.depth, + } +} + +// Hash returns the hash of the node. +func (bt *InternalNode) Hash() common.Hash { + h := sha256.New() + if bt.left != nil { + h.Write(bt.left.Hash().Bytes()) + } else { + h.Write(zero[:]) + } + if bt.right != nil { + h.Write(bt.right.Hash().Bytes()) + } else { + h.Write(zero[:]) + } + return common.BytesToHash(h.Sum(nil)) +} + +// InsertValuesAtStem inserts a full value group at the given stem in the internal node. +// Already-existing values will be overwritten. +func (bt *InternalNode) InsertValuesAtStem(stem []byte, values [][]byte, resolver NodeResolverFn, depth int) (BinaryNode, error) { + var err error + bit := stem[bt.depth/8] >> (7 - (bt.depth % 8)) & 1 + if bit == 0 { + if bt.left == nil { + bt.left = Empty{} + } + + if hn, ok := bt.left.(HashedNode); ok { + path, err := keyToPath(bt.depth, stem) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem resolve error: %w", err) + } + data, err := resolver(path, common.Hash(hn)) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem resolve error: %w", err) + } + node, err := DeserializeNode(data, bt.depth+1) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem node deserialization error: %w", err) + } + bt.left = node + } + + bt.left, err = bt.left.InsertValuesAtStem(stem, values, resolver, depth+1) + return bt, err + } + + if bt.right == nil { + bt.right = Empty{} + } + + if hn, ok := bt.right.(HashedNode); ok { + path, err := keyToPath(bt.depth, stem) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem resolve error: %w", err) + } + data, err := resolver(path, common.Hash(hn)) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem resolve error: %w", err) + } + node, err := DeserializeNode(data, bt.depth+1) + if err != nil { + return nil, fmt.Errorf("InsertValuesAtStem node deserialization error: %w", err) + } + bt.right = node + } + + bt.right, err = bt.right.InsertValuesAtStem(stem, values, resolver, depth+1) + return bt, err +} + +// CollectNodes collects all child nodes at a given path, and flushes it +// into the provided node collector. +func (bt *InternalNode) CollectNodes(path []byte, flushfn NodeFlushFn) error { + if bt.left != nil { + var p [256]byte + copy(p[:], path) + childpath := p[:len(path)] + childpath = append(childpath, 0) + if err := bt.left.CollectNodes(childpath, flushfn); err != nil { + return err + } + } + if bt.right != nil { + var p [256]byte + copy(p[:], path) + childpath := p[:len(path)] + childpath = append(childpath, 1) + if err := bt.right.CollectNodes(childpath, flushfn); err != nil { + return err + } + } + flushfn(path, bt) + return nil +} + +// GetHeight returns the height of the node. +func (bt *InternalNode) GetHeight() int { + var ( + leftHeight int + rightHeight int + ) + if bt.left != nil { + leftHeight = bt.left.GetHeight() + } + if bt.right != nil { + rightHeight = bt.right.GetHeight() + } + return 1 + max(leftHeight, rightHeight) +} + +func (bt *InternalNode) toDot(parent, path string) string { + me := fmt.Sprintf("internal%s", path) + ret := fmt.Sprintf("%s [label=\"I: %x\"]\n", me, bt.Hash()) + if len(parent) > 0 { + ret = fmt.Sprintf("%s %s -> %s\n", ret, parent, me) + } + + if bt.left != nil { + ret = fmt.Sprintf("%s%s", ret, bt.left.toDot(me, fmt.Sprintf("%s%02x", path, 0))) + } + if bt.right != nil { + ret = fmt.Sprintf("%s%s", ret, bt.right.toDot(me, fmt.Sprintf("%s%02x", path, 1))) + } + return ret +} diff --git a/trie/bintrie/internal_node_test.go b/trie/bintrie/internal_node_test.go new file mode 100644 index 0000000000..158d8b7147 --- /dev/null +++ b/trie/bintrie/internal_node_test.go @@ -0,0 +1,458 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "bytes" + "errors" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +// TestInternalNodeGet tests the Get method +func TestInternalNodeGet(t *testing.T) { + // Create a simple tree structure + leftStem := make([]byte, 31) + rightStem := make([]byte, 31) + rightStem[0] = 0x80 // First bit is 1 + + var leftValues, rightValues [256][]byte + leftValues[0] = common.HexToHash("0x0101").Bytes() + rightValues[0] = common.HexToHash("0x0202").Bytes() + + node := &InternalNode{ + depth: 0, + left: &StemNode{ + Stem: leftStem, + Values: leftValues[:], + depth: 1, + }, + right: &StemNode{ + Stem: rightStem, + Values: rightValues[:], + depth: 1, + }, + } + + // Get value from left subtree + leftKey := make([]byte, 32) + leftKey[31] = 0 + value, err := node.Get(leftKey, nil) + if err != nil { + t.Fatalf("Failed to get left value: %v", err) + } + if !bytes.Equal(value, leftValues[0]) { + t.Errorf("Left value mismatch: expected %x, got %x", leftValues[0], value) + } + + // Get value from right subtree + rightKey := make([]byte, 32) + rightKey[0] = 0x80 + rightKey[31] = 0 + value, err = node.Get(rightKey, nil) + if err != nil { + t.Fatalf("Failed to get right value: %v", err) + } + if !bytes.Equal(value, rightValues[0]) { + t.Errorf("Right value mismatch: expected %x, got %x", rightValues[0], value) + } +} + +// TestInternalNodeGetWithResolver tests Get with HashedNode resolution +func TestInternalNodeGetWithResolver(t *testing.T) { + // Create an internal node with a hashed child + hashedChild := HashedNode(common.HexToHash("0x1234")) + + node := &InternalNode{ + depth: 0, + left: hashedChild, + right: Empty{}, + } + + // Mock resolver that returns a stem node + resolver := func(path []byte, hash common.Hash) ([]byte, error) { + if hash == common.Hash(hashedChild) { + stem := make([]byte, 31) + var values [256][]byte + values[5] = common.HexToHash("0xabcd").Bytes() + stemNode := &StemNode{ + Stem: stem, + Values: values[:], + depth: 1, + } + return SerializeNode(stemNode), nil + } + return nil, errors.New("node not found") + } + + // Get value through the hashed node + key := make([]byte, 32) + key[31] = 5 + value, err := node.Get(key, resolver) + if err != nil { + t.Fatalf("Failed to get value: %v", err) + } + + expectedValue := common.HexToHash("0xabcd").Bytes() + if !bytes.Equal(value, expectedValue) { + t.Errorf("Value mismatch: expected %x, got %x", expectedValue, value) + } +} + +// TestInternalNodeInsert tests the Insert method +func TestInternalNodeInsert(t *testing.T) { + // Start with an internal node with empty children + node := &InternalNode{ + depth: 0, + left: Empty{}, + right: Empty{}, + } + + // Insert a value into the left subtree + leftKey := make([]byte, 32) + leftKey[31] = 10 + leftValue := common.HexToHash("0x0101").Bytes() + + newNode, err := node.Insert(leftKey, leftValue, nil, 0) + if err != nil { + t.Fatalf("Failed to insert: %v", err) + } + + internalNode, ok := newNode.(*InternalNode) + if !ok { + t.Fatalf("Expected InternalNode, got %T", newNode) + } + + // Check that left child is now a StemNode + leftStem, ok := internalNode.left.(*StemNode) + if !ok { + t.Fatalf("Expected left child to be StemNode, got %T", internalNode.left) + } + + // Check the inserted value + if !bytes.Equal(leftStem.Values[10], leftValue) { + t.Errorf("Value mismatch: expected %x, got %x", leftValue, leftStem.Values[10]) + } + + // Right child should still be Empty + _, ok = internalNode.right.(Empty) + if !ok { + t.Errorf("Expected right child to remain Empty, got %T", internalNode.right) + } +} + +// TestInternalNodeCopy tests the Copy method +func TestInternalNodeCopy(t *testing.T) { + // Create an internal node with stem children + leftStem := &StemNode{ + Stem: make([]byte, 31), + Values: make([][]byte, 256), + depth: 1, + } + leftStem.Values[0] = common.HexToHash("0x0101").Bytes() + + rightStem := &StemNode{ + Stem: make([]byte, 31), + Values: make([][]byte, 256), + depth: 1, + } + rightStem.Stem[0] = 0x80 + rightStem.Values[0] = common.HexToHash("0x0202").Bytes() + + node := &InternalNode{ + depth: 0, + left: leftStem, + right: rightStem, + } + + // Create a copy + copied := node.Copy() + copiedInternal, ok := copied.(*InternalNode) + if !ok { + t.Fatalf("Expected InternalNode, got %T", copied) + } + + // Check depth + if copiedInternal.depth != node.depth { + t.Errorf("Depth mismatch: expected %d, got %d", node.depth, copiedInternal.depth) + } + + // Check that children are copied + copiedLeft, ok := copiedInternal.left.(*StemNode) + if !ok { + t.Fatalf("Expected left child to be StemNode, got %T", copiedInternal.left) + } + + copiedRight, ok := copiedInternal.right.(*StemNode) + if !ok { + t.Fatalf("Expected right child to be StemNode, got %T", copiedInternal.right) + } + + // Verify deep copy (children should be different objects) + if copiedLeft == leftStem { + t.Error("Left child not properly copied") + } + if copiedRight == rightStem { + t.Error("Right child not properly copied") + } + + // But values should be equal + if !bytes.Equal(copiedLeft.Values[0], leftStem.Values[0]) { + t.Error("Left child value mismatch after copy") + } + if !bytes.Equal(copiedRight.Values[0], rightStem.Values[0]) { + t.Error("Right child value mismatch after copy") + } +} + +// TestInternalNodeHash tests the Hash method +func TestInternalNodeHash(t *testing.T) { + // Create an internal node + node := &InternalNode{ + depth: 0, + left: HashedNode(common.HexToHash("0x1111")), + right: HashedNode(common.HexToHash("0x2222")), + } + + hash1 := node.Hash() + + // Hash should be deterministic + hash2 := node.Hash() + if hash1 != hash2 { + t.Errorf("Hash not deterministic: %x != %x", hash1, hash2) + } + + // Changing a child should change the hash + node.left = HashedNode(common.HexToHash("0x3333")) + hash3 := node.Hash() + if hash1 == hash3 { + t.Error("Hash didn't change after modifying left child") + } + + // Test with nil children (should use zero hash) + nodeWithNil := &InternalNode{ + depth: 0, + left: nil, + right: HashedNode(common.HexToHash("0x4444")), + } + hashWithNil := nodeWithNil.Hash() + if hashWithNil == (common.Hash{}) { + t.Error("Hash shouldn't be zero even with nil child") + } +} + +// TestInternalNodeGetValuesAtStem tests GetValuesAtStem method +func TestInternalNodeGetValuesAtStem(t *testing.T) { + // Create a tree with values at different stems + leftStem := make([]byte, 31) + rightStem := make([]byte, 31) + rightStem[0] = 0x80 + + var leftValues, rightValues [256][]byte + leftValues[0] = common.HexToHash("0x0101").Bytes() + leftValues[10] = common.HexToHash("0x0102").Bytes() + rightValues[0] = common.HexToHash("0x0201").Bytes() + rightValues[20] = common.HexToHash("0x0202").Bytes() + + node := &InternalNode{ + depth: 0, + left: &StemNode{ + Stem: leftStem, + Values: leftValues[:], + depth: 1, + }, + right: &StemNode{ + Stem: rightStem, + Values: rightValues[:], + depth: 1, + }, + } + + // Get values from left stem + values, err := node.GetValuesAtStem(leftStem, nil) + if err != nil { + t.Fatalf("Failed to get left values: %v", err) + } + if !bytes.Equal(values[0], leftValues[0]) { + t.Error("Left value at index 0 mismatch") + } + if !bytes.Equal(values[10], leftValues[10]) { + t.Error("Left value at index 10 mismatch") + } + + // Get values from right stem + values, err = node.GetValuesAtStem(rightStem, nil) + if err != nil { + t.Fatalf("Failed to get right values: %v", err) + } + if !bytes.Equal(values[0], rightValues[0]) { + t.Error("Right value at index 0 mismatch") + } + if !bytes.Equal(values[20], rightValues[20]) { + t.Error("Right value at index 20 mismatch") + } +} + +// TestInternalNodeInsertValuesAtStem tests InsertValuesAtStem method +func TestInternalNodeInsertValuesAtStem(t *testing.T) { + // Start with an internal node with empty children + node := &InternalNode{ + depth: 0, + left: Empty{}, + right: Empty{}, + } + + // Insert values at a stem in the left subtree + stem := make([]byte, 31) + var values [256][]byte + values[5] = common.HexToHash("0x0505").Bytes() + values[10] = common.HexToHash("0x1010").Bytes() + + newNode, err := node.InsertValuesAtStem(stem, values[:], nil, 0) + if err != nil { + t.Fatalf("Failed to insert values: %v", err) + } + + internalNode, ok := newNode.(*InternalNode) + if !ok { + t.Fatalf("Expected InternalNode, got %T", newNode) + } + + // Check that left child is now a StemNode with the values + leftStem, ok := internalNode.left.(*StemNode) + if !ok { + t.Fatalf("Expected left child to be StemNode, got %T", internalNode.left) + } + + if !bytes.Equal(leftStem.Values[5], values[5]) { + t.Error("Value at index 5 mismatch") + } + if !bytes.Equal(leftStem.Values[10], values[10]) { + t.Error("Value at index 10 mismatch") + } +} + +// TestInternalNodeCollectNodes tests CollectNodes method +func TestInternalNodeCollectNodes(t *testing.T) { + // Create an internal node with two stem children + leftStem := &StemNode{ + Stem: make([]byte, 31), + Values: make([][]byte, 256), + depth: 1, + } + + rightStem := &StemNode{ + Stem: make([]byte, 31), + Values: make([][]byte, 256), + depth: 1, + } + rightStem.Stem[0] = 0x80 + + node := &InternalNode{ + depth: 0, + left: leftStem, + right: rightStem, + } + + var collectedPaths [][]byte + var collectedNodes []BinaryNode + + flushFn := func(path []byte, n BinaryNode) { + pathCopy := make([]byte, len(path)) + copy(pathCopy, path) + collectedPaths = append(collectedPaths, pathCopy) + collectedNodes = append(collectedNodes, n) + } + + err := node.CollectNodes([]byte{1}, flushFn) + if err != nil { + t.Fatalf("Failed to collect nodes: %v", err) + } + + // Should have collected 3 nodes: left stem, right stem, and the internal node itself + if len(collectedNodes) != 3 { + t.Errorf("Expected 3 collected nodes, got %d", len(collectedNodes)) + } + + // Check paths + expectedPaths := [][]byte{ + {1, 0}, // left child + {1, 1}, // right child + {1}, // internal node itself + } + + for i, expectedPath := range expectedPaths { + if !bytes.Equal(collectedPaths[i], expectedPath) { + t.Errorf("Path %d mismatch: expected %v, got %v", i, expectedPath, collectedPaths[i]) + } + } +} + +// TestInternalNodeGetHeight tests GetHeight method +func TestInternalNodeGetHeight(t *testing.T) { + // Create a tree with different heights + // Left subtree: depth 2 (internal -> stem) + // Right subtree: depth 1 (stem) + leftInternal := &InternalNode{ + depth: 1, + left: &StemNode{ + Stem: make([]byte, 31), + Values: make([][]byte, 256), + depth: 2, + }, + right: Empty{}, + } + + rightStem := &StemNode{ + Stem: make([]byte, 31), + Values: make([][]byte, 256), + depth: 1, + } + + node := &InternalNode{ + depth: 0, + left: leftInternal, + right: rightStem, + } + + height := node.GetHeight() + // Height should be max(left height, right height) + 1 + // Left height: 2, Right height: 1, so total: 3 + if height != 3 { + t.Errorf("Expected height 3, got %d", height) + } +} + +// TestInternalNodeDepthTooLarge tests handling of excessive depth +func TestInternalNodeDepthTooLarge(t *testing.T) { + // Create an internal node at max depth + node := &InternalNode{ + depth: 31*8 + 1, + left: Empty{}, + right: Empty{}, + } + + stem := make([]byte, 31) + _, err := node.GetValuesAtStem(stem, nil) + if err == nil { + t.Fatal("Expected error for excessive depth") + } + if err.Error() != "node too deep" { + t.Errorf("Expected 'node too deep' error, got: %v", err) + } +} diff --git a/trie/bintrie/iterator.go b/trie/bintrie/iterator.go new file mode 100644 index 0000000000..9b863ed1e3 --- /dev/null +++ b/trie/bintrie/iterator.go @@ -0,0 +1,288 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "errors" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/trie" +) + +var errIteratorEnd = errors.New("end of iteration") + +type binaryNodeIteratorState struct { + Node BinaryNode + Index int +} + +type binaryNodeIterator struct { + trie *BinaryTrie + current BinaryNode + lastErr error + + stack []binaryNodeIteratorState +} + +func newBinaryNodeIterator(t *BinaryTrie, _ []byte) (trie.NodeIterator, error) { + if t.Hash() == zero { + return &binaryNodeIterator{trie: t, lastErr: errIteratorEnd}, nil + } + it := &binaryNodeIterator{trie: t, current: t.root} + // it.err = it.seek(start) + return it, nil +} + +// Next moves the iterator to the next node. If the parameter is false, any child +// nodes will be skipped. +func (it *binaryNodeIterator) Next(descend bool) bool { + if it.lastErr == errIteratorEnd { + it.lastErr = errIteratorEnd + return false + } + + if len(it.stack) == 0 { + it.stack = append(it.stack, binaryNodeIteratorState{Node: it.trie.root}) + it.current = it.trie.root + + return true + } + + switch node := it.current.(type) { + case *InternalNode: + // index: 0 = nothing visited, 1=left visited, 2=right visited + context := &it.stack[len(it.stack)-1] + + // recurse into both children + if context.Index == 0 { + if _, isempty := node.left.(Empty); node.left != nil && !isempty { + it.stack = append(it.stack, binaryNodeIteratorState{Node: node.left}) + it.current = node.left + return it.Next(descend) + } + + context.Index++ + } + + if context.Index == 1 { + if _, isempty := node.right.(Empty); node.right != nil && !isempty { + it.stack = append(it.stack, binaryNodeIteratorState{Node: node.right}) + it.current = node.right + return it.Next(descend) + } + + context.Index++ + } + + // Reached the end of this node, go back to the parent, if + // this isn't root. + if len(it.stack) == 1 { + it.lastErr = errIteratorEnd + return false + } + it.stack = it.stack[:len(it.stack)-1] + it.current = it.stack[len(it.stack)-1].Node + it.stack[len(it.stack)-1].Index++ + return it.Next(descend) + case *StemNode: + // Look for the next non-empty value + for i := it.stack[len(it.stack)-1].Index; i < 256; i++ { + if node.Values[i] != nil { + it.stack[len(it.stack)-1].Index = i + 1 + return true + } + } + + // go back to parent to get the next leaf + // Check if we're at the root before popping + if len(it.stack) == 1 { + it.lastErr = errIteratorEnd + return false + } + it.stack = it.stack[:len(it.stack)-1] + it.current = it.stack[len(it.stack)-1].Node + it.stack[len(it.stack)-1].Index++ + return it.Next(descend) + case HashedNode: + // resolve the node + data, err := it.trie.nodeResolver(it.Path(), common.Hash(node)) + if err != nil { + panic(err) + } + it.current, err = DeserializeNode(data, len(it.stack)-1) + if err != nil { + panic(err) + } + + // update the stack and parent with the resolved node + it.stack[len(it.stack)-1].Node = it.current + parent := &it.stack[len(it.stack)-2] + if parent.Index == 0 { + parent.Node.(*InternalNode).left = it.current + } else { + parent.Node.(*InternalNode).right = it.current + } + return it.Next(descend) + case Empty: + // do nothing + return false + default: + panic("invalid node type") + } +} + +// Error returns the error status of the iterator. +func (it *binaryNodeIterator) Error() error { + if it.lastErr == errIteratorEnd { + return nil + } + return it.lastErr +} + +// Hash returns the hash of the current node. +func (it *binaryNodeIterator) Hash() common.Hash { + return it.current.Hash() +} + +// Parent returns the hash of the parent of the current node. The hash may be the one +// grandparent if the immediate parent is an internal node with no hash. +func (it *binaryNodeIterator) Parent() common.Hash { + return it.stack[len(it.stack)-1].Node.Hash() +} + +// Path returns the hex-encoded path to the current node. +// Callers must not retain references to the return value after calling Next. +// For leaf nodes, the last element of the path is the 'terminator symbol' 0x10. +func (it *binaryNodeIterator) Path() []byte { + if it.Leaf() { + return it.LeafKey() + } + var path []byte + for i, state := range it.stack { + // skip the last byte + if i >= len(it.stack)-1 { + break + } + path = append(path, byte(state.Index)) + } + return path +} + +// NodeBlob returns the serialized bytes of the current node. +func (it *binaryNodeIterator) NodeBlob() []byte { + return SerializeNode(it.current) +} + +// Leaf returns true iff the current node is a leaf node. +// In a Binary Trie, a StemNode contains up to 256 leaf values. +// The iterator is only considered to be "at a leaf" when it's positioned +// at a specific non-nil value within the StemNode, not just at the StemNode itself. +func (it *binaryNodeIterator) Leaf() bool { + sn, ok := it.current.(*StemNode) + if !ok { + return false + } + + // Check if we have a valid stack position + if len(it.stack) == 0 { + return false + } + + // The Index in the stack state points to the NEXT position after the current value. + // So if Index is 0, we haven't started iterating through the values yet. + // If Index is 5, we're currently at value[4] (the 5th value, 0-indexed). + idx := it.stack[len(it.stack)-1].Index + if idx == 0 || idx > 256 { + return false + } + + // Check if there's actually a value at the current position + currentValueIndex := idx - 1 + return sn.Values[currentValueIndex] != nil +} + +// LeafKey returns the key of the leaf. The method panics if the iterator is not +// positioned at a leaf. Callers must not retain references to the value after +// calling Next. +func (it *binaryNodeIterator) LeafKey() []byte { + leaf, ok := it.current.(*StemNode) + if !ok { + panic("Leaf() called on an binary node iterator not at a leaf location") + } + return leaf.Key(it.stack[len(it.stack)-1].Index - 1) +} + +// LeafBlob returns the content of the leaf. The method panics if the iterator +// is not positioned at a leaf. Callers must not retain references to the value +// after calling Next. +func (it *binaryNodeIterator) LeafBlob() []byte { + leaf, ok := it.current.(*StemNode) + if !ok { + panic("LeafBlob() called on an binary node iterator not at a leaf location") + } + return leaf.Values[it.stack[len(it.stack)-1].Index-1] +} + +// LeafProof returns the Merkle proof of the leaf. The method panics if the +// iterator is not positioned at a leaf. Callers must not retain references +// to the value after calling Next. +func (it *binaryNodeIterator) LeafProof() [][]byte { + sn, ok := it.current.(*StemNode) + if !ok { + panic("LeafProof() called on an binary node iterator not at a leaf location") + } + + proof := make([][]byte, 0, len(it.stack)+StemNodeWidth) + + // Build proof by walking up the stack and collecting sibling hashes + for i := range it.stack[:len(it.stack)-2] { + state := it.stack[i] + internalNode := state.Node.(*InternalNode) // should panic if the node isn't an InternalNode + + // Add the sibling hash to the proof + if state.Index == 0 { + // We came from left, so include right sibling + proof = append(proof, internalNode.right.Hash().Bytes()) + } else { + // We came from right, so include left sibling + proof = append(proof, internalNode.left.Hash().Bytes()) + } + } + + // Add the stem and siblings + proof = append(proof, sn.Stem) + for _, v := range sn.Values { + proof = append(proof, v) + } + + return proof +} + +// AddResolver sets an intermediate database to use for looking up trie nodes +// before reaching into the real persistent layer. +// +// This is not required for normal operation, rather is an optimization for +// cases where trie nodes can be recovered from some external mechanism without +// reading from disk. In those cases, this resolver allows short circuiting +// accesses and returning them from memory. +// +// Before adding a similar mechanism to any other place in Geth, consider +// making trie.Database an interface and wrapping at that level. It's a huge +// refactor, but it could be worth it if another occurrence arises. +func (it *binaryNodeIterator) AddResolver(trie.NodeResolver) { + // Not implemented, but should not panic +} diff --git a/trie/bintrie/key_encoding.go b/trie/bintrie/key_encoding.go new file mode 100644 index 0000000000..5a93fcde9a --- /dev/null +++ b/trie/bintrie/key_encoding.go @@ -0,0 +1,129 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "bytes" + "crypto/sha256" + + "github.com/ethereum/go-ethereum/common" + "github.com/holiman/uint256" +) + +const ( + BasicDataLeafKey = 0 + CodeHashLeafKey = 1 + BasicDataCodeSizeOffset = 5 + BasicDataNonceOffset = 8 + BasicDataBalanceOffset = 16 +) + +var ( + zeroInt = uint256.NewInt(0) + zeroHash = common.Hash{} + verkleNodeWidthLog2 = 8 + headerStorageOffset = uint256.NewInt(64) + codeOffset = uint256.NewInt(128) + codeStorageDelta = uint256.NewInt(0).Sub(codeOffset, headerStorageOffset) + mainStorageOffsetLshVerkleNodeWidth = new(uint256.Int).Lsh(uint256.NewInt(1), 248-uint(verkleNodeWidthLog2)) + CodeOffset = uint256.NewInt(128) + VerkleNodeWidth = uint256.NewInt(256) + HeaderStorageOffset = uint256.NewInt(64) + VerkleNodeWidthLog2 = 8 +) + +func GetBinaryTreeKey(addr common.Address, key []byte) []byte { + hasher := sha256.New() + hasher.Write(zeroHash[:12]) + hasher.Write(addr[:]) + hasher.Write(key[:31]) + k := hasher.Sum(nil) + k[31] = key[31] + return k +} + +func GetBinaryTreeKeyBasicData(addr common.Address) []byte { + var k [32]byte + k[31] = BasicDataLeafKey + return GetBinaryTreeKey(addr, k[:]) +} + +func GetBinaryTreeKeyCodeHash(addr common.Address) []byte { + var k [32]byte + k[31] = CodeHashLeafKey + return GetBinaryTreeKey(addr, k[:]) +} + +func GetBinaryTreeKeyStorageSlot(address common.Address, key []byte) []byte { + var k [32]byte + + // Case when the key belongs to the account header + if bytes.Equal(key[:31], zeroHash[:31]) && key[31] < 64 { + k[31] = 64 + key[31] + return GetBinaryTreeKey(address, k[:]) + } + + // Set the main storage offset + // note that the first 64 bytes of the main offset storage + // are unreachable, which is consistent with the spec and + // what verkle does. + k[0] = 1 // 1 << 248 + copy(k[1:], key[:31]) + k[31] = key[31] + + return GetBinaryTreeKey(address, k[:]) +} + +func GetBinaryTreeKeyCodeChunk(address common.Address, chunknr *uint256.Int) []byte { + chunkOffset := new(uint256.Int).Add(codeOffset, chunknr).Bytes() + return GetBinaryTreeKey(address, chunkOffset) +} + +func StorageIndex(storageKey []byte) (*uint256.Int, byte) { + // If the storage slot is in the header, we need to add the header offset. + var key uint256.Int + key.SetBytes(storageKey) + if key.Cmp(codeStorageDelta) < 0 { + // This addition is always safe; it can't ever overflow since pos. + +package bintrie + +import ( + "bytes" + "crypto/sha256" + "errors" + "fmt" + "slices" + + "github.com/ethereum/go-ethereum/common" +) + +// StemNode represents a group of `NodeWith` values sharing the same stem. +type StemNode struct { + Stem []byte // Stem path to get to StemNodeWidth values + Values [][]byte // All values, indexed by the last byte of the key. + depth int // Depth of the node +} + +// Get retrieves the value for the given key. +func (bt *StemNode) Get(key []byte, _ NodeResolverFn) ([]byte, error) { + panic("this should not be called directly") +} + +// Insert inserts a new key-value pair into the node. +func (bt *StemNode) Insert(key []byte, value []byte, _ NodeResolverFn, depth int) (BinaryNode, error) { + if !bytes.Equal(bt.Stem, key[:StemSize]) { + bitStem := bt.Stem[bt.depth/8] >> (7 - (bt.depth % 8)) & 1 + + n := &InternalNode{depth: bt.depth} + bt.depth++ + var child, other *BinaryNode + if bitStem == 0 { + n.left = bt + child = &n.left + other = &n.right + } else { + n.right = bt + child = &n.right + other = &n.left + } + + bitKey := key[n.depth/8] >> (7 - (n.depth % 8)) & 1 + if bitKey == bitStem { + var err error + *child, err = (*child).Insert(key, value, nil, depth+1) + if err != nil { + return n, fmt.Errorf("insert error: %w", err) + } + *other = Empty{} + } else { + var values [StemNodeWidth][]byte + values[key[StemSize]] = value + *other = &StemNode{ + Stem: slices.Clone(key[:StemSize]), + Values: values[:], + depth: depth + 1, + } + } + return n, nil + } + if len(value) != HashSize { + return bt, errors.New("invalid insertion: value length") + } + bt.Values[key[StemSize]] = value + return bt, nil +} + +// Copy creates a deep copy of the node. +func (bt *StemNode) Copy() BinaryNode { + var values [StemNodeWidth][]byte + for i, v := range bt.Values { + values[i] = slices.Clone(v) + } + return &StemNode{ + Stem: slices.Clone(bt.Stem), + Values: values[:], + depth: bt.depth, + } +} + +// GetHeight returns the height of the node. +func (bt *StemNode) GetHeight() int { + return 1 +} + +// Hash returns the hash of the node. +func (bt *StemNode) Hash() common.Hash { + var data [StemNodeWidth]common.Hash + for i, v := range bt.Values { + if v != nil { + h := sha256.Sum256(v) + data[i] = common.BytesToHash(h[:]) + } + } + + h := sha256.New() + for level := 1; level <= 8; level++ { + for i := range StemNodeWidth / (1 << level) { + h.Reset() + + if data[i*2] == (common.Hash{}) && data[i*2+1] == (common.Hash{}) { + data[i] = common.Hash{} + continue + } + + h.Write(data[i*2][:]) + h.Write(data[i*2+1][:]) + data[i] = common.Hash(h.Sum(nil)) + } + } + + h.Reset() + h.Write(bt.Stem) + h.Write([]byte{0}) + h.Write(data[0][:]) + return common.BytesToHash(h.Sum(nil)) +} + +// CollectNodes collects all child nodes at a given path, and flushes it +// into the provided node collector. +func (bt *StemNode) CollectNodes(path []byte, flush NodeFlushFn) error { + flush(path, bt) + return nil +} + +// GetValuesAtStem retrieves the group of values located at the given stem key. +func (bt *StemNode) GetValuesAtStem(stem []byte, _ NodeResolverFn) ([][]byte, error) { + if !bytes.Equal(bt.Stem, stem) { + return nil, nil + } + return bt.Values[:], nil +} + +// InsertValuesAtStem inserts a full value group at the given stem in the internal node. +// Already-existing values will be overwritten. +func (bt *StemNode) InsertValuesAtStem(key []byte, values [][]byte, _ NodeResolverFn, depth int) (BinaryNode, error) { + if !bytes.Equal(bt.Stem, key[:StemSize]) { + bitStem := bt.Stem[bt.depth/8] >> (7 - (bt.depth % 8)) & 1 + + n := &InternalNode{depth: bt.depth} + bt.depth++ + var child, other *BinaryNode + if bitStem == 0 { + n.left = bt + child = &n.left + other = &n.right + } else { + n.right = bt + child = &n.right + other = &n.left + } + + bitKey := key[n.depth/8] >> (7 - (n.depth % 8)) & 1 + if bitKey == bitStem { + var err error + *child, err = (*child).InsertValuesAtStem(key, values, nil, depth+1) + if err != nil { + return n, fmt.Errorf("insert error: %w", err) + } + *other = Empty{} + } else { + *other = &StemNode{ + Stem: slices.Clone(key[:StemSize]), + Values: values, + depth: n.depth + 1, + } + } + return n, nil + } + + // same stem, just merge the two value lists + for i, v := range values { + if v != nil { + bt.Values[i] = v + } + } + return bt, nil +} + +func (bt *StemNode) toDot(parent, path string) string { + me := fmt.Sprintf("stem%s", path) + ret := fmt.Sprintf("%s [label=\"stem=%x c=%x\"]\n", me, bt.Stem, bt.Hash()) + ret = fmt.Sprintf("%s %s -> %s\n", ret, parent, me) + for i, v := range bt.Values { + if v != nil { + ret = fmt.Sprintf("%s%s%x [label=\"%x\"]\n", ret, me, i, v) + ret = fmt.Sprintf("%s%s -> %s%x\n", ret, me, me, i) + } + } + return ret +} + +// Key returns the full key for the given index. +func (bt *StemNode) Key(i int) []byte { + var ret [HashSize]byte + copy(ret[:], bt.Stem) + ret[StemSize] = byte(i) + return ret[:] +} diff --git a/trie/bintrie/stem_node_test.go b/trie/bintrie/stem_node_test.go new file mode 100644 index 0000000000..d8d6844427 --- /dev/null +++ b/trie/bintrie/stem_node_test.go @@ -0,0 +1,369 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "bytes" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +// TestStemNodeInsertSameStem tests inserting values with the same stem +func TestStemNodeInsertSameStem(t *testing.T) { + stem := make([]byte, 31) + for i := range stem { + stem[i] = byte(i) + } + + var values [256][]byte + values[0] = common.HexToHash("0x0101").Bytes() + + node := &StemNode{ + Stem: stem, + Values: values[:], + depth: 0, + } + + // Insert another value with the same stem but different last byte + key := make([]byte, 32) + copy(key[:31], stem) + key[31] = 10 + value := common.HexToHash("0x0202").Bytes() + + newNode, err := node.Insert(key, value, nil, 0) + if err != nil { + t.Fatalf("Failed to insert: %v", err) + } + + // Should still be a StemNode + stemNode, ok := newNode.(*StemNode) + if !ok { + t.Fatalf("Expected StemNode, got %T", newNode) + } + + // Check that both values are present + if !bytes.Equal(stemNode.Values[0], values[0]) { + t.Errorf("Value at index 0 mismatch") + } + if !bytes.Equal(stemNode.Values[10], value) { + t.Errorf("Value at index 10 mismatch") + } +} + +// TestStemNodeInsertDifferentStem tests inserting values with different stems +func TestStemNodeInsertDifferentStem(t *testing.T) { + stem1 := make([]byte, 31) + for i := range stem1 { + stem1[i] = 0x00 + } + + var values [256][]byte + values[0] = common.HexToHash("0x0101").Bytes() + + node := &StemNode{ + Stem: stem1, + Values: values[:], + depth: 0, + } + + // Insert with a different stem (first bit different) + key := make([]byte, 32) + key[0] = 0x80 // First bit is 1 instead of 0 + value := common.HexToHash("0x0202").Bytes() + + newNode, err := node.Insert(key, value, nil, 0) + if err != nil { + t.Fatalf("Failed to insert: %v", err) + } + + // Should now be an InternalNode + internalNode, ok := newNode.(*InternalNode) + if !ok { + t.Fatalf("Expected InternalNode, got %T", newNode) + } + + // Check depth + if internalNode.depth != 0 { + t.Errorf("Expected depth 0, got %d", internalNode.depth) + } + + // Original stem should be on the left (bit 0) + leftStem, ok := internalNode.left.(*StemNode) + if !ok { + t.Fatalf("Expected left child to be StemNode, got %T", internalNode.left) + } + if !bytes.Equal(leftStem.Stem, stem1) { + t.Errorf("Left stem mismatch") + } + + // New stem should be on the right (bit 1) + rightStem, ok := internalNode.right.(*StemNode) + if !ok { + t.Fatalf("Expected right child to be StemNode, got %T", internalNode.right) + } + if !bytes.Equal(rightStem.Stem, key[:31]) { + t.Errorf("Right stem mismatch") + } +} + +// TestStemNodeInsertInvalidValueLength tests inserting value with invalid length +func TestStemNodeInsertInvalidValueLength(t *testing.T) { + stem := make([]byte, 31) + var values [256][]byte + + node := &StemNode{ + Stem: stem, + Values: values[:], + depth: 0, + } + + // Try to insert value with wrong length + key := make([]byte, 32) + copy(key[:31], stem) + invalidValue := []byte{1, 2, 3} // Not 32 bytes + + _, err := node.Insert(key, invalidValue, nil, 0) + if err == nil { + t.Fatal("Expected error for invalid value length") + } + + if err.Error() != "invalid insertion: value length" { + t.Errorf("Expected 'invalid insertion: value length' error, got: %v", err) + } +} + +// TestStemNodeCopy tests the Copy method +func TestStemNodeCopy(t *testing.T) { + stem := make([]byte, 31) + for i := range stem { + stem[i] = byte(i) + } + + var values [256][]byte + values[0] = common.HexToHash("0x0101").Bytes() + values[255] = common.HexToHash("0x0202").Bytes() + + node := &StemNode{ + Stem: stem, + Values: values[:], + depth: 10, + } + + // Create a copy + copied := node.Copy() + copiedStem, ok := copied.(*StemNode) + if !ok { + t.Fatalf("Expected StemNode, got %T", copied) + } + + // Check that values are equal but not the same slice + if !bytes.Equal(copiedStem.Stem, node.Stem) { + t.Errorf("Stem mismatch after copy") + } + if &copiedStem.Stem[0] == &node.Stem[0] { + t.Error("Stem slice not properly cloned") + } + + // Check values + if !bytes.Equal(copiedStem.Values[0], node.Values[0]) { + t.Errorf("Value at index 0 mismatch after copy") + } + if !bytes.Equal(copiedStem.Values[255], node.Values[255]) { + t.Errorf("Value at index 255 mismatch after copy") + } + + // Check that value slices are cloned + if copiedStem.Values[0] != nil && &copiedStem.Values[0][0] == &node.Values[0][0] { + t.Error("Value slice not properly cloned") + } + + // Check depth + if copiedStem.depth != node.depth { + t.Errorf("Depth mismatch: expected %d, got %d", node.depth, copiedStem.depth) + } +} + +// TestStemNodeHash tests the Hash method +func TestStemNodeHash(t *testing.T) { + stem := make([]byte, 31) + var values [256][]byte + values[0] = common.HexToHash("0x0101").Bytes() + + node := &StemNode{ + Stem: stem, + Values: values[:], + depth: 0, + } + + hash1 := node.Hash() + + // Hash should be deterministic + hash2 := node.Hash() + if hash1 != hash2 { + t.Errorf("Hash not deterministic: %x != %x", hash1, hash2) + } + + // Changing a value should change the hash + node.Values[1] = common.HexToHash("0x0202").Bytes() + hash3 := node.Hash() + if hash1 == hash3 { + t.Error("Hash didn't change after modifying values") + } +} + +// TestStemNodeGetValuesAtStem tests GetValuesAtStem method +func TestStemNodeGetValuesAtStem(t *testing.T) { + stem := make([]byte, 31) + for i := range stem { + stem[i] = byte(i) + } + + var values [256][]byte + values[0] = common.HexToHash("0x0101").Bytes() + values[10] = common.HexToHash("0x0202").Bytes() + values[255] = common.HexToHash("0x0303").Bytes() + + node := &StemNode{ + Stem: stem, + Values: values[:], + depth: 0, + } + + // GetValuesAtStem with matching stem + retrievedValues, err := node.GetValuesAtStem(stem, nil) + if err != nil { + t.Fatalf("Failed to get values: %v", err) + } + + // Check that all values match + for i := range 256 { + if !bytes.Equal(retrievedValues[i], values[i]) { + t.Errorf("Value mismatch at index %d", i) + } + } + + // GetValuesAtStem with different stem should return nil + differentStem := make([]byte, 31) + differentStem[0] = 0xFF + + shouldBeNil, err := node.GetValuesAtStem(differentStem, nil) + if err != nil { + t.Fatalf("Failed to get values with different stem: %v", err) + } + + if shouldBeNil != nil { + t.Error("Expected nil for different stem, got non-nil") + } +} + +// TestStemNodeInsertValuesAtStem tests InsertValuesAtStem method +func TestStemNodeInsertValuesAtStem(t *testing.T) { + stem := make([]byte, 31) + var values [256][]byte + values[0] = common.HexToHash("0x0101").Bytes() + + node := &StemNode{ + Stem: stem, + Values: values[:], + depth: 0, + } + + // Insert new values at the same stem + var newValues [256][]byte + newValues[1] = common.HexToHash("0x0202").Bytes() + newValues[2] = common.HexToHash("0x0303").Bytes() + + newNode, err := node.InsertValuesAtStem(stem, newValues[:], nil, 0) + if err != nil { + t.Fatalf("Failed to insert values: %v", err) + } + + stemNode, ok := newNode.(*StemNode) + if !ok { + t.Fatalf("Expected StemNode, got %T", newNode) + } + + // Check that all values are present + if !bytes.Equal(stemNode.Values[0], values[0]) { + t.Error("Original value at index 0 missing") + } + if !bytes.Equal(stemNode.Values[1], newValues[1]) { + t.Error("New value at index 1 missing") + } + if !bytes.Equal(stemNode.Values[2], newValues[2]) { + t.Error("New value at index 2 missing") + } +} + +// TestStemNodeGetHeight tests GetHeight method +func TestStemNodeGetHeight(t *testing.T) { + node := &StemNode{ + Stem: make([]byte, 31), + Values: make([][]byte, 256), + depth: 0, + } + + height := node.GetHeight() + if height != 1 { + t.Errorf("Expected height 1, got %d", height) + } +} + +// TestStemNodeCollectNodes tests CollectNodes method +func TestStemNodeCollectNodes(t *testing.T) { + stem := make([]byte, 31) + var values [256][]byte + values[0] = common.HexToHash("0x0101").Bytes() + + node := &StemNode{ + Stem: stem, + Values: values[:], + depth: 0, + } + + var collectedPaths [][]byte + var collectedNodes []BinaryNode + + flushFn := func(path []byte, n BinaryNode) { + // Make a copy of the path + pathCopy := make([]byte, len(path)) + copy(pathCopy, path) + collectedPaths = append(collectedPaths, pathCopy) + collectedNodes = append(collectedNodes, n) + } + + err := node.CollectNodes([]byte{0, 1, 0}, flushFn) + if err != nil { + t.Fatalf("Failed to collect nodes: %v", err) + } + + // Should have collected one node (itself) + if len(collectedNodes) != 1 { + t.Errorf("Expected 1 collected node, got %d", len(collectedNodes)) + } + + // Check that the collected node is the same + if collectedNodes[0] != node { + t.Error("Collected node doesn't match original") + } + + // Check the path + if !bytes.Equal(collectedPaths[0], []byte{0, 1, 0}) { + t.Errorf("Path mismatch: expected [0, 1, 0], got %v", collectedPaths[0]) + } +} diff --git a/trie/bintrie/trie.go b/trie/bintrie/trie.go new file mode 100644 index 0000000000..c082d57bdf --- /dev/null +++ b/trie/bintrie/trie.go @@ -0,0 +1,428 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/trienode" + "github.com/ethereum/go-ethereum/triedb/database" + "github.com/holiman/uint256" +) + +var errInvalidRootType = errors.New("invalid root type") + +// ChunkedCode represents a sequence of HashSize-byte chunks of code (StemSize bytes of which +// are actual code, and NodeTypeBytes byte is the pushdata offset). +type ChunkedCode []byte + +// Copy the values here so as to avoid an import cycle +const ( + PUSH1 = byte(0x60) + PUSH32 = byte(0x7f) +) + +// ChunkifyCode generates the chunked version of an array representing EVM bytecode +// according to EIP-7864 specification. +// +// The code is divided into HashSize-byte chunks, where each chunk contains: +// - Byte 0: Metadata byte indicating the number of leading bytes that are PUSHDATA (0-StemSize) +// - Bytes 1-StemSize: Actual code bytes +// +// This format enables stateless clients to validate jump destinations within a chunk +// without requiring additional context. When a PUSH instruction's data spans multiple +// chunks, the metadata byte tells us how many bytes at the start of the chunk are +// part of the previous chunk's PUSH instruction data. +// +// For example: +// - If a chunk starts with regular code: metadata byte = 0 +// - If a PUSH32 instruction starts at byte 30 of chunk N: +// - Chunk N: normal, contains PUSH32 opcode + 1 byte of data +// - Chunk N+1: metadata = StemSize (entire chunk is PUSH data) +// - Chunk N+2: metadata = 1 (first byte is PUSH data, then normal code resumes) +// +// This chunking approach ensures that jump destination validity can be determined +// by examining only the chunk containing the potential JUMPDEST, making it ideal +// for stateless execution and verkle/binary tries. +// +// Reference: https://eips.ethereum.org/EIPS/eip-7864 +func ChunkifyCode(code []byte) ChunkedCode { + var ( + chunkOffset = 0 // offset in the chunk + chunkCount = len(code) / StemSize + codeOffset = 0 // offset in the code + ) + if len(code)%StemSize != 0 { + chunkCount++ + } + chunks := make([]byte, chunkCount*HashSize) + for i := 0; i < chunkCount; i++ { + // number of bytes to copy, StemSize unless the end of the code has been reached. + end := min(len(code), StemSize*(i+1)) + copy(chunks[i*HashSize+1:], code[StemSize*i:end]) // copy the code itself + + // chunk offset = taken from the last chunk. + if chunkOffset > StemSize { + // skip offset calculation if push data covers the whole chunk + chunks[i*HashSize] = StemSize + chunkOffset = 1 + continue + } + chunks[HashSize*i] = byte(chunkOffset) + chunkOffset = 0 + + // Check each instruction and update the offset it should be 0 unless + // a PUSH-N overflows. + for ; codeOffset < end; codeOffset++ { + if code[codeOffset] >= PUSH1 && code[codeOffset] <= PUSH32 { + codeOffset += int(code[codeOffset] - PUSH1 + 1) + if codeOffset+1 >= StemSize*(i+1) { + codeOffset++ + chunkOffset = codeOffset - StemSize*(i+1) + break + } + } + } + } + return chunks +} + +// NewBinaryNode creates a new empty binary trie +func NewBinaryNode() BinaryNode { + return Empty{} +} + +// BinaryTrie is the implementation of https://eips.ethereum.org/EIPS/eip-7864. +type BinaryTrie struct { + root BinaryNode + reader *trie.Reader + tracer *trie.PrevalueTracer +} + +// ToDot converts the binary trie to a DOT language representation. Useful for debugging. +func (t *BinaryTrie) ToDot() string { + t.root.Hash() + return ToDot(t.root) +} + +// NewBinaryTrie creates a new binary trie. +func NewBinaryTrie(root common.Hash, db database.NodeDatabase) (*BinaryTrie, error) { + reader, err := trie.NewReader(root, common.Hash{}, db) + if err != nil { + return nil, err + } + t := &BinaryTrie{ + root: NewBinaryNode(), + reader: reader, + tracer: trie.NewPrevalueTracer(), + } + // Parse the root node if it's not empty + if root != types.EmptyBinaryHash && root != types.EmptyRootHash { + blob, err := t.nodeResolver(nil, root) + if err != nil { + return nil, err + } + node, err := DeserializeNode(blob, 0) + if err != nil { + return nil, err + } + t.root = node + } + return t, nil +} + +// nodeResolver is a node resolver that reads nodes from the flatdb. +func (t *BinaryTrie) nodeResolver(path []byte, hash common.Hash) ([]byte, error) { + // empty nodes will be serialized as common.Hash{}, so capture + // this special use case. + if hash == (common.Hash{}) { + return nil, nil // empty node + } + blob, err := t.reader.Node(path, hash) + if err != nil { + return nil, err + } + t.tracer.Put(path, blob) + return blob, nil +} + +// GetKey returns the sha3 preimage of a hashed key that was previously used +// to store a value. +func (t *BinaryTrie) GetKey(key []byte) []byte { + return key +} + +// GetWithHashedKey returns the value, assuming that the key has already +// been hashed. +func (t *BinaryTrie) GetWithHashedKey(key []byte) ([]byte, error) { + return t.root.Get(key, t.nodeResolver) +} + +// GetAccount returns the account information for the given address. +func (t *BinaryTrie) GetAccount(addr common.Address) (*types.StateAccount, error) { + var ( + values [][]byte + err error + acc = &types.StateAccount{} + key = GetBinaryTreeKey(addr, zero[:]) + ) + switch r := t.root.(type) { + case *InternalNode: + values, err = r.GetValuesAtStem(key[:StemSize], t.nodeResolver) + case *StemNode: + values = r.Values + case Empty: + return nil, nil + default: + // This will cover HashedNode but that should be fine since the + // root node should always be resolved. + return nil, errInvalidRootType + } + if err != nil { + return nil, fmt.Errorf("GetAccount (%x) error: %v", addr, err) + } + + // The following code is required for the MPT->Binary conversion. + // An account can be partially migrated, where storage slots were moved to the binary + // but not yet the account. This means some account information as (header) storage slots + // are in the binary trie but basic account information must be read in the base tree (MPT). + // TODO: we can simplify this logic depending if the conversion is in progress or finished. + emptyAccount := true + for i := 0; values != nil && i <= CodeHashLeafKey && emptyAccount; i++ { + emptyAccount = emptyAccount && values[i] == nil + } + if emptyAccount { + return nil, nil + } + + // If the account has been deleted, then values[10] will be 0 and not nil. If it has + // been recreated after that, then its code keccak will NOT be 0. So return `nil` if + // the nonce, and values[10], and code keccak is 0. + if bytes.Equal(values[BasicDataLeafKey], zero[:]) && len(values) > 10 && len(values[10]) > 0 && bytes.Equal(values[CodeHashLeafKey], zero[:]) { + return nil, nil + } + + acc.Nonce = binary.BigEndian.Uint64(values[BasicDataLeafKey][BasicDataNonceOffset:]) + var balance [16]byte + copy(balance[:], values[BasicDataLeafKey][BasicDataBalanceOffset:]) + acc.Balance = new(uint256.Int).SetBytes(balance[:]) + acc.CodeHash = values[CodeHashLeafKey] + + return acc, nil +} + +// GetStorage returns the value for key stored in the trie. The value bytes must +// not be modified by the caller. If a node was not found in the database, a +// trie.MissingNodeError is returned. +func (t *BinaryTrie) GetStorage(addr common.Address, key []byte) ([]byte, error) { + return t.root.Get(GetBinaryTreeKey(addr, key), t.nodeResolver) +} + +// UpdateAccount updates the account information for the given address. +func (t *BinaryTrie) UpdateAccount(addr common.Address, acc *types.StateAccount, codeLen int) error { + var ( + err error + basicData [HashSize]byte + values = make([][]byte, StemNodeWidth) + stem = GetBinaryTreeKey(addr, zero[:]) + ) + binary.BigEndian.PutUint32(basicData[BasicDataCodeSizeOffset-1:], uint32(codeLen)) + binary.BigEndian.PutUint64(basicData[BasicDataNonceOffset:], acc.Nonce) + + // Because the balance is a max of 16 bytes, truncate + // the extra values. This happens in devmode, where + // 0xff**HashSize is allocated to the developer account. + balanceBytes := acc.Balance.Bytes() + // TODO: reduce the size of the allocation in devmode, then panic instead + // of truncating. + if len(balanceBytes) > 16 { + balanceBytes = balanceBytes[16:] + } + copy(basicData[HashSize-len(balanceBytes):], balanceBytes[:]) + values[BasicDataLeafKey] = basicData[:] + values[CodeHashLeafKey] = acc.CodeHash[:] + + t.root, err = t.root.InsertValuesAtStem(stem, values, t.nodeResolver, 0) + return err +} + +// UpdateStem updates the values for the given stem key. +func (t *BinaryTrie) UpdateStem(key []byte, values [][]byte) error { + var err error + t.root, err = t.root.InsertValuesAtStem(key, values, t.nodeResolver, 0) + return err +} + +// UpdateStorage associates key with value in the trie. If value has length zero, any +// existing value is deleted from the trie. The value bytes must not be modified +// by the caller while they are stored in the trie. If a node was not found in the +// database, a trie.MissingNodeError is returned. +func (t *BinaryTrie) UpdateStorage(address common.Address, key, value []byte) error { + k := GetBinaryTreeKeyStorageSlot(address, key) + var v [HashSize]byte + if len(value) >= HashSize { + copy(v[:], value[:HashSize]) + } else { + copy(v[HashSize-len(value):], value[:]) + } + root, err := t.root.Insert(k, v[:], t.nodeResolver, 0) + if err != nil { + return fmt.Errorf("UpdateStorage (%x) error: %v", address, err) + } + t.root = root + return nil +} + +// DeleteAccount is a no-op as it is disabled in stateless. +func (t *BinaryTrie) DeleteAccount(addr common.Address) error { + return nil +} + +// DeleteStorage removes any existing value for key from the trie. If a node was not +// found in the database, a trie.MissingNodeError is returned. +func (t *BinaryTrie) DeleteStorage(addr common.Address, key []byte) error { + k := GetBinaryTreeKey(addr, key) + var zero [HashSize]byte + root, err := t.root.Insert(k, zero[:], t.nodeResolver, 0) + if err != nil { + return fmt.Errorf("DeleteStorage (%x) error: %v", addr, err) + } + t.root = root + return nil +} + +// Hash returns the root hash of the trie. It does not write to the database and +// can be used even if the trie doesn't have one. +func (t *BinaryTrie) Hash() common.Hash { + return t.root.Hash() +} + +// Commit writes all nodes to the trie's memory database, tracking the internal +// and external (for account tries) references. +func (t *BinaryTrie) Commit(_ bool) (common.Hash, *trienode.NodeSet) { + nodeset := trienode.NewNodeSet(common.Hash{}) + + // The root can be any type of BinaryNode (InternalNode, StemNode, etc.) + err := t.root.CollectNodes(nil, func(path []byte, node BinaryNode) { + serialized := SerializeNode(node) + nodeset.AddNode(path, trienode.NewNodeWithPrev(node.Hash(), serialized, t.tracer.Get(path))) + }) + if err != nil { + panic(fmt.Errorf("CollectNodes failed: %v", err)) + } + // Serialize root commitment form + return t.Hash(), nodeset +} + +// NodeIterator returns an iterator that returns nodes of the trie. Iteration +// starts at the key after the given start key. +func (t *BinaryTrie) NodeIterator(startKey []byte) (trie.NodeIterator, error) { + return newBinaryNodeIterator(t, nil) +} + +// Prove constructs a Merkle proof for key. The result contains all encoded nodes +// on the path to the value at key. The value itself is also included in the last +// node and can be retrieved by verifying the proof. +// +// If the trie does not contain a value for key, the returned proof contains all +// nodes of the longest existing prefix of the key (at least the root), ending +// with the node that proves the absence of the key. +func (t *BinaryTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { + panic("not implemented") +} + +// Copy creates a deep copy of the trie. +func (t *BinaryTrie) Copy() *BinaryTrie { + return &BinaryTrie{ + root: t.root.Copy(), + reader: t.reader, + tracer: t.tracer.Copy(), + } +} + +// IsVerkle returns true if the trie is a Verkle tree. +func (t *BinaryTrie) IsVerkle() bool { + // TODO @gballet This is technically NOT a verkle tree, but it has the same + // behavior and basic structure, so for all intents and purposes, it can be + // treated as such. Rename this when verkle gets removed. + return true +} + +// UpdateContractCode updates the contract code into the trie. +// +// Note: the basic data leaf needs to have been previously created for this to work +func (t *BinaryTrie) UpdateContractCode(addr common.Address, codeHash common.Hash, code []byte) error { + var ( + chunks = ChunkifyCode(code) + values [][]byte + key []byte + err error + ) + for i, chunknr := 0, uint64(0); i < len(chunks); i, chunknr = i+HashSize, chunknr+1 { + groupOffset := (chunknr + 128) % StemNodeWidth + if groupOffset == 0 /* start of new group */ || chunknr == 0 /* first chunk in header group */ { + values = make([][]byte, StemNodeWidth) + var offset [HashSize]byte + binary.LittleEndian.PutUint64(offset[24:], chunknr+128) + key = GetBinaryTreeKey(addr, offset[:]) + } + values[groupOffset] = chunks[i : i+HashSize] + + if groupOffset == StemNodeWidth-1 || len(chunks)-i <= HashSize { + err = t.UpdateStem(key[:StemSize], values) + + if err != nil { + return fmt.Errorf("UpdateContractCode (addr=%x) error: %w", addr[:], err) + } + } + } + return nil +} + +// PrefetchAccount attempts to resolve specific accounts from the database +// to accelerate subsequent trie operations. +func (t *BinaryTrie) PrefetchAccount(addresses []common.Address) error { + for _, addr := range addresses { + if _, err := t.GetAccount(addr); err != nil { + return err + } + } + return nil +} + +// PrefetchStorage attempts to resolve specific storage slots from the database +// to accelerate subsequent trie operations. +func (t *BinaryTrie) PrefetchStorage(addr common.Address, keys [][]byte) error { + for _, key := range keys { + if _, err := t.GetStorage(addr, key); err != nil { + return err + } + } + return nil +} + +// Witness returns a set containing all trie nodes that have been accessed. +func (t *BinaryTrie) Witness() map[string][]byte { + panic("not implemented") +} diff --git a/trie/bintrie/trie_test.go b/trie/bintrie/trie_test.go new file mode 100644 index 0000000000..ca02cfaa1f --- /dev/null +++ b/trie/bintrie/trie_test.go @@ -0,0 +1,197 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package bintrie + +import ( + "bytes" + "encoding/binary" + "testing" + + "github.com/ethereum/go-ethereum/common" +) + +var ( + zeroKey = [HashSize]byte{} + oneKey = common.HexToHash("0101010101010101010101010101010101010101010101010101010101010101") + twoKey = common.HexToHash("0202020202020202020202020202020202020202020202020202020202020202") + threeKey = common.HexToHash("0303030303030303030303030303030303030303030303030303030303030303") + fourKey = common.HexToHash("0404040404040404040404040404040404040404040404040404040404040404") + ffKey = common.HexToHash("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff") +) + +func TestSingleEntry(t *testing.T) { + tree := NewBinaryNode() + tree, err := tree.Insert(zeroKey[:], oneKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + if tree.GetHeight() != 1 { + t.Fatal("invalid depth") + } + expected := common.HexToHash("aab1060e04cb4f5dc6f697ae93156a95714debbf77d54238766adc5709282b6f") + got := tree.Hash() + if got != expected { + t.Fatalf("invalid tree root, got %x, want %x", got, expected) + } +} + +func TestTwoEntriesDiffFirstBit(t *testing.T) { + var err error + tree := NewBinaryNode() + tree, err = tree.Insert(zeroKey[:], oneKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + tree, err = tree.Insert(common.HexToHash("8000000000000000000000000000000000000000000000000000000000000000").Bytes(), twoKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + if tree.GetHeight() != 2 { + t.Fatal("invalid height") + } + if tree.Hash() != common.HexToHash("dfc69c94013a8b3c65395625a719a87534a7cfd38719251ad8c8ea7fe79f065e") { + t.Fatal("invalid tree root") + } +} + +func TestOneStemColocatedValues(t *testing.T) { + var err error + tree := NewBinaryNode() + tree, err = tree.Insert(common.HexToHash("0000000000000000000000000000000000000000000000000000000000000003").Bytes(), oneKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + tree, err = tree.Insert(common.HexToHash("0000000000000000000000000000000000000000000000000000000000000004").Bytes(), twoKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + tree, err = tree.Insert(common.HexToHash("0000000000000000000000000000000000000000000000000000000000000009").Bytes(), threeKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + tree, err = tree.Insert(common.HexToHash("00000000000000000000000000000000000000000000000000000000000000FF").Bytes(), fourKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + if tree.GetHeight() != 1 { + t.Fatal("invalid height") + } +} + +func TestTwoStemColocatedValues(t *testing.T) { + var err error + tree := NewBinaryNode() + // stem: 0...0 + tree, err = tree.Insert(common.HexToHash("0000000000000000000000000000000000000000000000000000000000000003").Bytes(), oneKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + tree, err = tree.Insert(common.HexToHash("0000000000000000000000000000000000000000000000000000000000000004").Bytes(), twoKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + // stem: 10...0 + tree, err = tree.Insert(common.HexToHash("8000000000000000000000000000000000000000000000000000000000000003").Bytes(), oneKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + tree, err = tree.Insert(common.HexToHash("8000000000000000000000000000000000000000000000000000000000000004").Bytes(), twoKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + if tree.GetHeight() != 2 { + t.Fatal("invalid height") + } +} + +func TestTwoKeysMatchFirst42Bits(t *testing.T) { + var err error + tree := NewBinaryNode() + // key1 and key 2 have the same prefix of 42 bits (b0*42+b1+b1) and differ after. + key1 := common.HexToHash("0000000000C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0C0").Bytes() + key2 := common.HexToHash("0000000000E00000000000000000000000000000000000000000000000000000").Bytes() + tree, err = tree.Insert(key1, oneKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + tree, err = tree.Insert(key2, twoKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + if tree.GetHeight() != 1+42+1 { + t.Fatal("invalid height") + } +} +func TestInsertDuplicateKey(t *testing.T) { + var err error + tree := NewBinaryNode() + tree, err = tree.Insert(oneKey[:], oneKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + tree, err = tree.Insert(oneKey[:], twoKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + if tree.GetHeight() != 1 { + t.Fatal("invalid height") + } + // Verify that the value is updated + if !bytes.Equal(tree.(*StemNode).Values[1], twoKey[:]) { + t.Fatal("invalid height") + } +} +func TestLargeNumberOfEntries(t *testing.T) { + var err error + tree := NewBinaryNode() + for i := range StemNodeWidth { + var key [HashSize]byte + key[0] = byte(i) + tree, err = tree.Insert(key[:], ffKey[:], nil, 0) + if err != nil { + t.Fatal(err) + } + } + height := tree.GetHeight() + if height != 1+8 { + t.Fatalf("invalid height, wanted %d, got %d", 1+8, height) + } +} + +func TestMerkleizeMultipleEntries(t *testing.T) { + var err error + tree := NewBinaryNode() + keys := [][]byte{ + zeroKey[:], + common.HexToHash("8000000000000000000000000000000000000000000000000000000000000000").Bytes(), + common.HexToHash("0100000000000000000000000000000000000000000000000000000000000000").Bytes(), + common.HexToHash("8100000000000000000000000000000000000000000000000000000000000000").Bytes(), + } + for i, key := range keys { + var v [HashSize]byte + binary.LittleEndian.PutUint64(v[:8], uint64(i)) + tree, err = tree.Insert(key, v[:], nil, 0) + if err != nil { + t.Fatal(err) + } + } + got := tree.Hash() + expected := common.HexToHash("9317155862f7a3867660ddd0966ff799a3d16aa4df1e70a7516eaa4a675191b5") + if got != expected { + t.Fatalf("invalid root, expected=%x, got = %x", expected, got) + } +} diff --git a/trie/bytepool.go b/trie/bytepool.go index 4f9c5672fd..31be7ae749 100644 --- a/trie/bytepool.go +++ b/trie/bytepool.go @@ -32,8 +32,8 @@ func newBytesPool(sliceCap, nitems int) *bytesPool { } } -// Get returns a slice. Safe for concurrent use. -func (bp *bytesPool) Get() []byte { +// get returns a slice. Safe for concurrent use. +func (bp *bytesPool) get() []byte { select { case b := <-bp.c: return b @@ -42,18 +42,18 @@ func (bp *bytesPool) Get() []byte { } } -// GetWithSize returns a slice with specified byte slice size. -func (bp *bytesPool) GetWithSize(s int) []byte { - b := bp.Get() +// getWithSize returns a slice with specified byte slice size. +func (bp *bytesPool) getWithSize(s int) []byte { + b := bp.get() if cap(b) < s { return make([]byte, s) } return b[:s] } -// Put returns a slice to the pool. Safe for concurrent use. This method +// put returns a slice to the pool. Safe for concurrent use. This method // will ignore slices that are too small or too large (>3x the cap) -func (bp *bytesPool) Put(b []byte) { +func (bp *bytesPool) put(b []byte) { if c := cap(b); c < bp.w || c > 3*bp.w { return } @@ -62,3 +62,40 @@ func (bp *bytesPool) Put(b []byte) { default: } } + +// unsafeBytesPool is a pool for byte slices. It is not safe for concurrent use. +type unsafeBytesPool struct { + items [][]byte + w int +} + +// newUnsafeBytesPool creates a new unsafeBytesPool. The sliceCap sets the +// capacity of newly allocated slices, and the nitems determines how many +// items the pool will hold, at maximum. +func newUnsafeBytesPool(sliceCap, nitems int) *unsafeBytesPool { + return &unsafeBytesPool{ + items: make([][]byte, 0, nitems), + w: sliceCap, + } +} + +// Get returns a slice with pre-allocated space. +func (bp *unsafeBytesPool) get() []byte { + if len(bp.items) > 0 { + last := bp.items[len(bp.items)-1] + bp.items = bp.items[:len(bp.items)-1] + return last + } + return make([]byte, 0, bp.w) +} + +// put returns a slice to the pool. This method will ignore slices that are +// too small or too large (>3x the cap) +func (bp *unsafeBytesPool) put(b []byte) { + if c := cap(b); c < bp.w || c > 3*bp.w { + return + } + if len(bp.items) < cap(bp.items) { + bp.items = append(bp.items, b) + } +} diff --git a/trie/committer.go b/trie/committer.go index 0939a07abb..2a2142e0ff 100644 --- a/trie/committer.go +++ b/trie/committer.go @@ -29,12 +29,12 @@ import ( // insertion order. type committer struct { nodes *trienode.NodeSet - tracer *tracer + tracer *PrevalueTracer collectLeaf bool } // newCommitter creates a new committer or picks one from the pool. -func newCommitter(nodeset *trienode.NodeSet, tracer *tracer, collectLeaf bool) *committer { +func newCommitter(nodeset *trienode.NodeSet, tracer *PrevalueTracer, collectLeaf bool) *committer { return &committer{ nodes: nodeset, tracer: tracer, @@ -110,14 +110,16 @@ func (c *committer) commitChildren(path []byte, n *fullNode, parallel bool) { } else { wg.Add(1) go func(index int) { + defer wg.Done() + p := append(path, byte(index)) childSet := trienode.NewNodeSet(c.nodes.Owner) childCommitter := newCommitter(childSet, c.tracer, c.collectLeaf) n.Children[index] = childCommitter.commit(p, child, false) + nodesMu.Lock() - c.nodes.MergeSet(childSet) + c.nodes.MergeDisjoint(childSet) nodesMu.Unlock() - wg.Done() }(i) } } @@ -140,15 +142,15 @@ func (c *committer) store(path []byte, n node) node { // The node is embedded in its parent, in other words, this node // will not be stored in the database independently, mark it as // deleted only if the node was existent in database before. - _, ok := c.tracer.accessList[string(path)] - if ok { - c.nodes.AddNode(path, trienode.NewDeleted()) + origin := c.tracer.Get(path) + if len(origin) != 0 { + c.nodes.AddNode(path, trienode.NewDeletedWithPrev(origin)) } return n } // Collect the dirty node to nodeset for return. nhash := common.BytesToHash(hash) - c.nodes.AddNode(path, trienode.New(nhash, nodeToBytes(n))) + c.nodes.AddNode(path, trienode.NewNodeWithPrev(nhash, nodeToBytes(n), c.tracer.Get(path))) // Collect the corresponding leaf node if it's required. We don't check // full node since it's impossible to store value in fullNode. The key diff --git a/trie/iterator.go b/trie/iterator.go index e6fedf2430..3d3191ffba 100644 --- a/trie/iterator.go +++ b/trie/iterator.go @@ -405,7 +405,7 @@ func (it *nodeIterator) resolveHash(hash hashNode, path []byte) (node, error) { // loaded blob will be tracked, while it's not required here since // all loaded nodes won't be linked to trie at all and track nodes // may lead to out-of-memory issue. - blob, err := it.trie.reader.node(path, common.BytesToHash(hash)) + blob, err := it.trie.reader.Node(path, common.BytesToHash(hash)) if err != nil { return nil, err } @@ -426,7 +426,7 @@ func (it *nodeIterator) resolveBlob(hash hashNode, path []byte) ([]byte, error) // loaded blob will be tracked, while it's not required here since // all loaded nodes won't be linked to trie at all and track nodes // may lead to out-of-memory issue. - return it.trie.reader.node(path, common.BytesToHash(hash)) + return it.trie.reader.Node(path, common.BytesToHash(hash)) } func (st *nodeIteratorState) resolve(it *nodeIterator, path []byte) error { @@ -836,3 +836,91 @@ func (it *unionIterator) Error() error { } return nil } + +// subTreeIterator wraps nodeIterator to traverse a trie within a predefined +// start and limit range. +type subtreeIterator struct { + NodeIterator + + stopPath []byte // Precomputed hex path for stopKey (without terminator), nil means no limit + exhausted bool // Flag whether the iterator has been exhausted +} + +// newSubtreeIterator creates an iterator that only traverses nodes within a subtree +// defined by the given startKey and stopKey. This supports general range iteration +// where startKey is inclusive and stopKey is exclusive. +// +// The iterator will only visit nodes whose keys k satisfy: startKey <= k < stopKey, +// where comparisons are performed in lexicographic order of byte keys (internally +// implemented via hex-nibble path comparisons for efficiency). +// +// If startKey is nil, iteration starts from the beginning. If stopKey is nil, +// iteration continues to the end of the trie. +func newSubtreeIterator(trie *Trie, startKey, stopKey []byte) (NodeIterator, error) { + it, err := trie.NodeIterator(startKey) + if err != nil { + return nil, err + } + if startKey == nil && stopKey == nil { + return it, nil + } + // Precompute nibble paths for efficient comparison + var stopPath []byte + if stopKey != nil { + stopPath = keybytesToHex(stopKey) + if hasTerm(stopPath) { + stopPath = stopPath[:len(stopPath)-1] + } + } + return &subtreeIterator{ + NodeIterator: it, + stopPath: stopPath, + }, nil +} + +// nextKey returns the next possible key after the given prefix. +// For example, "abc" -> "abd", "ab\xff" -> "ac", etc. +func nextKey(prefix []byte) []byte { + if len(prefix) == 0 { + return nil + } + // Make a copy to avoid modifying the original + next := make([]byte, len(prefix)) + copy(next, prefix) + + // Increment the last byte that isn't 0xff + for i := len(next) - 1; i >= 0; i-- { + if next[i] < 0xff { + next[i]++ + return next + } + // If it's 0xff, we need to carry over + // Trim trailing 0xff bytes + next = next[:i] + } + // If all bytes were 0xff, return nil (no upper bound) + return nil +} + +// newPrefixIterator creates an iterator that only traverses nodes with the given prefix. +// This ensures that only keys starting with the prefix are visited. +func newPrefixIterator(trie *Trie, prefix []byte) (NodeIterator, error) { + return newSubtreeIterator(trie, prefix, nextKey(prefix)) +} + +// Next moves the iterator to the next node. If the parameter is false, any child +// nodes will be skipped. +func (it *subtreeIterator) Next(descend bool) bool { + if it.exhausted { + return false + } + if !it.NodeIterator.Next(descend) { + it.exhausted = true + return false + } + if it.stopPath != nil && reachedPath(it.NodeIterator.Path(), it.stopPath) { + it.exhausted = true + return false + } + return true +} diff --git a/trie/iterator_test.go b/trie/iterator_test.go index 74a1aa378c..3e0ef126be 100644 --- a/trie/iterator_test.go +++ b/trie/iterator_test.go @@ -19,7 +19,9 @@ package trie import ( "bytes" "fmt" + "maps" "math/rand" + "slices" "testing" "github.com/ethereum/go-ethereum/common" @@ -624,6 +626,540 @@ func isTrieNode(scheme string, key, val []byte) (bool, []byte, common.Hash) { return true, path, hash } +func TestSubtreeIterator(t *testing.T) { + var ( + db = newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) + tr = NewEmpty(db) + ) + vals := []struct{ k, v string }{ + {"do", "verb"}, + {"dog", "puppy"}, + {"doge", "coin"}, + {"dog\xff", "value6"}, + {"dog\xff\xff", "value7"}, + {"horse", "stallion"}, + {"house", "building"}, + {"houses", "multiple"}, + {"xyz", "value"}, + {"xyz\xff", "value"}, + {"xyz\xff\xff", "value"}, + } + all := make(map[string]string) + for _, val := range vals { + all[val.k] = val.v + tr.MustUpdate([]byte(val.k), []byte(val.v)) + } + root, nodes := tr.Commit(false) + db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) + + allNodes := make(map[string][]byte) + tr, _ = New(TrieID(root), db) + it, err := tr.NodeIterator(nil) + if err != nil { + t.Fatal(err) + } + for it.Next(true) { + allNodes[string(it.Path())] = it.NodeBlob() + } + allKeys := slices.Collect(maps.Keys(all)) + + suites := []struct { + start []byte + end []byte + expected []string + }{ + // entire key range + { + start: nil, + end: nil, + expected: allKeys, + }, + { + start: nil, + end: bytes.Repeat([]byte{0xff}, 32), + expected: allKeys, + }, + { + start: bytes.Repeat([]byte{0x0}, 32), + end: bytes.Repeat([]byte{0xff}, 32), + expected: allKeys, + }, + // key range with start + { + start: []byte("do"), + end: nil, + expected: allKeys, + }, + { + start: []byte("doe"), + end: nil, + expected: allKeys[1:], + }, + { + start: []byte("dog"), + end: nil, + expected: allKeys[1:], + }, + { + start: []byte("doge"), + end: nil, + expected: allKeys[2:], + }, + { + start: []byte("dog\xff"), + end: nil, + expected: allKeys[3:], + }, + { + start: []byte("dog\xff\xff"), + end: nil, + expected: allKeys[4:], + }, + { + start: []byte("dog\xff\xff\xff"), + end: nil, + expected: allKeys[5:], + }, + // key range with limit + { + start: nil, + end: []byte("xyz"), + expected: allKeys[:len(allKeys)-3], + }, + { + start: nil, + end: []byte("xyz\xff"), + expected: allKeys[:len(allKeys)-2], + }, + { + start: nil, + end: []byte("xyz\xff\xff"), + expected: allKeys[:len(allKeys)-1], + }, + { + start: nil, + end: []byte("xyz\xff\xff\xff"), + expected: allKeys, + }, + } + for _, suite := range suites { + // We need to re-open the trie from the committed state + tr, _ = New(TrieID(root), db) + it, err := newSubtreeIterator(tr, suite.start, suite.end) + if err != nil { + t.Fatal(err) + } + + found := make(map[string]string) + for it.Next(true) { + if it.Leaf() { + found[string(it.LeafKey())] = string(it.LeafBlob()) + } + } + if len(found) != len(suite.expected) { + t.Errorf("wrong number of values: got %d, want %d", len(found), len(suite.expected)) + } + for k, v := range found { + if all[k] != v { + t.Errorf("wrong value for %s: got %s, want %s", k, found[k], all[k]) + } + } + + expectedNodes := make(map[string][]byte) + for path, blob := range allNodes { + if suite.start != nil { + hexStart := keybytesToHex(suite.start) + hexStart = hexStart[:len(hexStart)-1] + if !reachedPath([]byte(path), hexStart) { + continue + } + } + if suite.end != nil { + hexEnd := keybytesToHex(suite.end) + hexEnd = hexEnd[:len(hexEnd)-1] + if reachedPath([]byte(path), hexEnd) { + continue + } + } + expectedNodes[path] = bytes.Clone(blob) + } + + // Compare the result yield from the subtree iterator + var ( + subCount int + subIt, _ = newSubtreeIterator(tr, suite.start, suite.end) + ) + for subIt.Next(true) { + blob, ok := expectedNodes[string(subIt.Path())] + if !ok { + t.Errorf("Unexpected node iterated, path: %v", subIt.Path()) + } + subCount++ + + if !bytes.Equal(blob, subIt.NodeBlob()) { + t.Errorf("Unexpected node blob, path: %v, want: %v, got: %v", subIt.Path(), blob, subIt.NodeBlob()) + } + } + if subCount != len(expectedNodes) { + t.Errorf("Unexpected node being iterated, want: %d, got: %d", len(expectedNodes), subCount) + } + } +} + +func TestPrefixIterator(t *testing.T) { + // Create a new trie + trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) + + // Insert test data + testData := map[string]string{ + "key1": "value1", + "key2": "value2", + "key10": "value10", + "key11": "value11", + "different": "value_different", + } + + for key, value := range testData { + trie.Update([]byte(key), []byte(value)) + } + + // Test prefix iteration for "key1" prefix + prefix := []byte("key1") + iter, err := trie.NodeIteratorWithPrefix(prefix) + if err != nil { + t.Fatalf("Failed to create prefix iterator: %v", err) + } + + var foundKeys [][]byte + for iter.Next(true) { + if iter.Leaf() { + foundKeys = append(foundKeys, iter.LeafKey()) + } + } + + if err := iter.Error(); err != nil { + t.Fatalf("Iterator error: %v", err) + } + + // Verify only keys starting with "key1" were found + expectedCount := 3 // "key1", "key10", "key11" + if len(foundKeys) != expectedCount { + t.Errorf("Expected %d keys, found %d", expectedCount, len(foundKeys)) + } + + for _, key := range foundKeys { + keyStr := string(key) + if !bytes.HasPrefix(key, prefix) { + t.Errorf("Found key %s doesn't have prefix %s", keyStr, string(prefix)) + } + } +} + +func TestPrefixIteratorVsFullIterator(t *testing.T) { + // Create a new trie with more structured data + trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) + + // Insert structured test data + testData := map[string]string{ + "aaa": "value_aaa", + "aab": "value_aab", + "aba": "value_aba", + "bbb": "value_bbb", + } + + for key, value := range testData { + trie.Update([]byte(key), []byte(value)) + } + + // Test that prefix iterator stops at boundary + prefix := []byte("aa") + prefixIter, err := trie.NodeIteratorWithPrefix(prefix) + if err != nil { + t.Fatalf("Failed to create prefix iterator: %v", err) + } + + var prefixKeys [][]byte + for prefixIter.Next(true) { + if prefixIter.Leaf() { + prefixKeys = append(prefixKeys, prefixIter.LeafKey()) + } + } + + // Should only find "aaa" and "aab", not "aba" or "bbb" + if len(prefixKeys) != 2 { + t.Errorf("Expected 2 keys with prefix 'aa', found %d", len(prefixKeys)) + } + + // Verify no keys outside prefix were found + for _, key := range prefixKeys { + if !bytes.HasPrefix(key, prefix) { + t.Errorf("Prefix iterator returned key %s outside prefix %s", string(key), string(prefix)) + } + } +} + +func TestEmptyPrefixIterator(t *testing.T) { + // Test with empty trie + trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) + + iter, err := trie.NodeIteratorWithPrefix([]byte("nonexistent")) + if err != nil { + t.Fatalf("Failed to create iterator: %v", err) + } + + if iter.Next(true) { + t.Error("Expected no results from empty trie") + } +} + +// TestPrefixIteratorEdgeCases tests various edge cases for prefix iteration +func TestPrefixIteratorEdgeCases(t *testing.T) { + // Create a trie with test data + trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) + testData := map[string]string{ + "abc": "value1", + "abcd": "value2", + "abce": "value3", + "abd": "value4", + "dog": "value5", + "dog\xff": "value6", // Test with 0xff byte + "dog\xff\xff": "value7", // Multiple 0xff bytes + } + for key, value := range testData { + trie.Update([]byte(key), []byte(value)) + } + + // Test 1: Prefix not present in trie + t.Run("NonexistentPrefix", func(t *testing.T) { + iter, err := trie.NodeIteratorWithPrefix([]byte("xyz")) + if err != nil { + t.Fatalf("Failed to create iterator: %v", err) + } + count := 0 + for iter.Next(true) { + if iter.Leaf() { + count++ + } + } + if count != 0 { + t.Errorf("Expected 0 results for nonexistent prefix, got %d", count) + } + }) + + // Test 2: Prefix exactly equals an existing key + t.Run("ExactKeyPrefix", func(t *testing.T) { + iter, err := trie.NodeIteratorWithPrefix([]byte("abc")) + if err != nil { + t.Fatalf("Failed to create iterator: %v", err) + } + found := make(map[string]bool) + for iter.Next(true) { + if iter.Leaf() { + found[string(iter.LeafKey())] = true + } + } + // Should find "abc", "abcd", "abce" but not "abd" + if !found["abc"] || !found["abcd"] || !found["abce"] { + t.Errorf("Missing expected keys: got %v", found) + } + if found["abd"] { + t.Errorf("Found unexpected key 'abd' with prefix 'abc'") + } + }) + + // Test 3: Prefix with trailing 0xff + t.Run("TrailingFFPrefix", func(t *testing.T) { + iter, err := trie.NodeIteratorWithPrefix([]byte("dog\xff")) + if err != nil { + t.Fatalf("Failed to create iterator: %v", err) + } + found := make(map[string]bool) + for iter.Next(true) { + if iter.Leaf() { + found[string(iter.LeafKey())] = true + } + } + // Should find "dog\xff" and "dog\xff\xff" + if !found["dog\xff"] || !found["dog\xff\xff"] { + t.Errorf("Missing expected keys with 0xff: got %v", found) + } + if found["dog"] { + t.Errorf("Found unexpected key 'dog' with prefix 'dog\\xff'") + } + }) + + // Test 4: All 0xff case (edge case for nextKey) + t.Run("AllFFPrefix", func(t *testing.T) { + // Add a key with all 0xff bytes + allFF := []byte{0xff, 0xff} + trie.Update(allFF, []byte("all_ff_value")) + trie.Update(append(allFF, 0x00), []byte("all_ff_plus")) + + iter, err := trie.NodeIteratorWithPrefix(allFF) + if err != nil { + t.Fatalf("Failed to create iterator: %v", err) + } + count := 0 + for iter.Next(true) { + if iter.Leaf() { + count++ + } + } + // Should find exactly the two keys with the all-0xff prefix + if count != 2 { + t.Errorf("Expected 2 results for all-0xff prefix, got %d", count) + } + }) + + // Test 5: Empty prefix (should iterate entire trie) + t.Run("EmptyPrefix", func(t *testing.T) { + iter, err := trie.NodeIteratorWithPrefix([]byte{}) + if err != nil { + t.Fatalf("Failed to create iterator: %v", err) + } + count := 0 + for iter.Next(true) { + if iter.Leaf() { + count++ + } + } + // Should find all keys in the trie + expectedCount := len(testData) + 2 // +2 for the extra keys added in test 4 + if count != expectedCount { + t.Errorf("Expected %d results for empty prefix, got %d", expectedCount, count) + } + }) +} + +// TestGeneralRangeIteration tests NewSubtreeIterator with arbitrary start/stop ranges +func TestGeneralRangeIteration(t *testing.T) { + // Create a trie with test data + trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) + testData := map[string]string{ + "apple": "fruit1", + "apricot": "fruit2", + "banana": "fruit3", + "cherry": "fruit4", + "date": "fruit5", + "fig": "fruit6", + "grape": "fruit7", + } + for key, value := range testData { + trie.Update([]byte(key), []byte(value)) + } + + // Test range iteration from "banana" to "fig" (exclusive) + t.Run("RangeIteration", func(t *testing.T) { + iter, _ := newSubtreeIterator(trie, []byte("banana"), []byte("fig")) + found := make(map[string]bool) + for iter.Next(true) { + if iter.Leaf() { + found[string(iter.LeafKey())] = true + } + } + // Should find "banana", "cherry", "date" but not "fig" + if !found["banana"] || !found["cherry"] || !found["date"] { + t.Errorf("Missing expected keys in range: got %v", found) + } + if found["apple"] || found["apricot"] || found["fig"] || found["grape"] { + t.Errorf("Found unexpected keys outside range: got %v", found) + } + }) + + // Test with nil stopKey (iterate to end) + t.Run("NilStopKey", func(t *testing.T) { + iter, _ := newSubtreeIterator(trie, []byte("date"), nil) + found := make(map[string]bool) + for iter.Next(true) { + if iter.Leaf() { + found[string(iter.LeafKey())] = true + } + } + // Should find "date", "fig", "grape" + if !found["date"] || !found["fig"] || !found["grape"] { + t.Errorf("Missing expected keys from 'date' to end: got %v", found) + } + if found["apple"] || found["banana"] || found["cherry"] { + t.Errorf("Found unexpected keys before 'date': got %v", found) + } + }) + + // Test with nil startKey (iterate from beginning) + t.Run("NilStartKey", func(t *testing.T) { + iter, _ := newSubtreeIterator(trie, nil, []byte("cherry")) + found := make(map[string]bool) + for iter.Next(true) { + if iter.Leaf() { + found[string(iter.LeafKey())] = true + } + } + // Should find "apple", "apricot", "banana" but not "cherry" or later + if !found["apple"] || !found["apricot"] || !found["banana"] { + t.Errorf("Missing expected keys before 'cherry': got %v", found) + } + if found["cherry"] || found["date"] || found["fig"] || found["grape"] { + t.Errorf("Found unexpected keys at or after 'cherry': got %v", found) + } + }) +} + +// TestPrefixIteratorWithDescend tests prefix iteration with descend=false +func TestPrefixIteratorWithDescend(t *testing.T) { + // Create a trie with nested structure + trie := NewEmpty(newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme)) + testData := map[string]string{ + "a": "value_a", + "a/b": "value_ab", + "a/b/c": "value_abc", + "a/b/d": "value_abd", + "a/e": "value_ae", + "b": "value_b", + } + for key, value := range testData { + trie.Update([]byte(key), []byte(value)) + } + + // Test skipping subtrees with descend=false + t.Run("SkipSubtrees", func(t *testing.T) { + iter, err := trie.NodeIteratorWithPrefix([]byte("a")) + if err != nil { + t.Fatalf("Failed to create iterator: %v", err) + } + + // Count nodes at each level + nodesVisited := 0 + leafsFound := make(map[string]bool) + + // First call with descend=true to enter the "a" subtree + if !iter.Next(true) { + t.Fatal("Expected to find at least one node") + } + nodesVisited++ + + // Continue iteration, sometimes with descend=false + descendPattern := []bool{false, true, false, true, true} + for i := 0; iter.Next(descendPattern[i%len(descendPattern)]); i++ { + nodesVisited++ + if iter.Leaf() { + leafsFound[string(iter.LeafKey())] = true + } + } + + // We should still respect the prefix boundary even when skipping + prefix := []byte("a") + for key := range leafsFound { + if !bytes.HasPrefix([]byte(key), prefix) { + t.Errorf("Found key outside prefix when using descend=false: %s", key) + } + } + + // Should not have found "b" even if we skip some subtrees + if leafsFound["b"] { + t.Error("Iterator leaked outside prefix boundary with descend=false") + } + }) +} + func BenchmarkIterator(b *testing.B) { diskDb, srcDb, tr, _ := makeTestTrie(rawdb.HashScheme) root := tr.Hash() diff --git a/trie/list_hasher.go b/trie/list_hasher.go new file mode 100644 index 0000000000..8f334f9901 --- /dev/null +++ b/trie/list_hasher.go @@ -0,0 +1,56 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package trie + +import ( + "bytes" + + "github.com/ethereum/go-ethereum/common" +) + +// ListHasher is a wrapper of the Merkle-Patricia-Trie, which implements +// types.ListHasher. Compared to a Trie instance, the Update method of this +// type always deep-copies its input slices. +// +// This implementation is very inefficient in terms of memory allocation, +// compared with StackTrie. It exists only for correctness comparison purposes. +type ListHasher struct { + tr *Trie +} + +// NewListHasher initializes the list hasher. +func NewListHasher() *ListHasher { + return &ListHasher{ + tr: NewEmpty(nil), + } +} + +// Reset clears the internal state prepares the ListHasher for reuse. +func (h *ListHasher) Reset() { + h.tr.reset() +} + +// Update inserts a key-value pair into the trie. +func (h *ListHasher) Update(key []byte, value []byte) error { + key, value = bytes.Clone(key), bytes.Clone(value) + return h.tr.Update(key, value) +} + +// Hash computes the root hash of all inserted key-value pairs. +func (h *ListHasher) Hash() common.Hash { + return h.tr.Hash() +} diff --git a/trie/node.go b/trie/node.go index 74fac4fd4e..3f14f07d63 100644 --- a/trie/node.go +++ b/trie/node.go @@ -17,6 +17,7 @@ package trie import ( + "bytes" "fmt" "io" "strings" @@ -242,6 +243,74 @@ func decodeRef(buf []byte) (node, []byte, error) { } } +// decodeNodeElements parses the RLP encoding of a trie node and returns all the +// elements in raw byte format. +// +// For full node, it returns a slice of 17 elements; +// For short node, it returns a slice of 2 elements; +func decodeNodeElements(buf []byte) ([][]byte, error) { + if len(buf) == 0 { + return nil, io.ErrUnexpectedEOF + } + return rlp.SplitListValues(buf) +} + +// encodeNodeElements encodes the provided node elements into a rlp list. +func encodeNodeElements(elements [][]byte) ([]byte, error) { + if len(elements) != 2 && len(elements) != 17 { + return nil, fmt.Errorf("invalid number of elements: %d", len(elements)) + } + return rlp.MergeListValues(elements) +} + +// NodeDifference accepts two RLP-encoding nodes and figures out the difference +// between them. +// +// An error is returned if any of the provided blob is nil, or the type of nodes +// are different. +func NodeDifference(oldvalue []byte, newvalue []byte) (int, []int, [][]byte, error) { + oldElems, err := decodeNodeElements(oldvalue) + if err != nil { + return 0, nil, nil, err + } + newElems, err := decodeNodeElements(newvalue) + if err != nil { + return 0, nil, nil, err + } + if len(oldElems) != len(newElems) { + return 0, nil, nil, fmt.Errorf("different node type, old elements: %d, new elements: %d", len(oldElems), len(newElems)) + } + var ( + indices = make([]int, 0, len(oldElems)) + diff = make([][]byte, 0, len(oldElems)) + ) + for i := 0; i < len(oldElems); i++ { + if !bytes.Equal(oldElems[i], newElems[i]) { + indices = append(indices, i) + diff = append(diff, oldElems[i]) + } + } + return len(oldElems), indices, diff, nil +} + +// ReassembleNode accepts a RLP-encoding node along with a set of mutations, +// applying the modification diffs according to the indices and re-assemble. +func ReassembleNode(blob []byte, mutations [][][]byte, indices [][]int) ([]byte, error) { + if len(mutations) == 0 && len(indices) == 0 { + return blob, nil + } + elements, err := decodeNodeElements(blob) + if err != nil { + return nil, err + } + for i := 0; i < len(mutations); i++ { + for j, pos := range indices[i] { + elements[pos] = mutations[i][j] + } + } + return encodeNodeElements(elements) +} + // wraps a decoding error with information about the path to the // invalid child node (for debugging encoding issues). type decodeError struct { diff --git a/trie/node_test.go b/trie/node_test.go index 9b8b33748f..875f6e38dc 100644 --- a/trie/node_test.go +++ b/trie/node_test.go @@ -18,9 +18,12 @@ package trie import ( "bytes" + "math/rand" + "reflect" "testing" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testrand" "github.com/ethereum/go-ethereum/rlp" ) @@ -94,6 +97,286 @@ func TestDecodeFullNode(t *testing.T) { } } +func makeTestLeafNode(small bool) []byte { + l := leafNodeEncoder{} + l.Key = hexToCompact(keybytesToHex(testrand.Bytes(10))) + if small { + l.Val = testrand.Bytes(10) + } else { + l.Val = testrand.Bytes(32) + } + buf := rlp.NewEncoderBuffer(nil) + l.encode(buf) + return buf.ToBytes() +} + +func makeTestFullNode(small bool) []byte { + n := fullnodeEncoder{} + for i := 0; i < 16; i++ { + switch rand.Intn(3) { + case 0: + // write nil + case 1: + // write hash + n.Children[i] = testrand.Bytes(32) + case 2: + // write embedded node + n.Children[i] = makeTestLeafNode(small) + } + } + n.Children[16] = testrand.Bytes(32) // value + buf := rlp.NewEncoderBuffer(nil) + n.encode(buf) + return buf.ToBytes() +} + +func TestEncodeDecodeNodeElements(t *testing.T) { + var nodes [][]byte + nodes = append(nodes, makeTestFullNode(true)) + nodes = append(nodes, makeTestFullNode(false)) + nodes = append(nodes, makeTestLeafNode(true)) + nodes = append(nodes, makeTestLeafNode(false)) + + for _, blob := range nodes { + elements, err := decodeNodeElements(blob) + if err != nil { + t.Fatalf("Failed to decode node elements: %v", err) + } + enc, err := encodeNodeElements(elements) + if err != nil { + t.Fatalf("Failed to encode node elements: %v", err) + } + if !bytes.Equal(enc, blob) { + t.Fatalf("Unexpected encoded node element, want: %v, got: %v", blob, enc) + } + } +} + +func makeTestLeafNodePair() ([]byte, []byte, [][]byte, []int) { + var ( + na = leafNodeEncoder{} + nb = leafNodeEncoder{} + ) + key := keybytesToHex(testrand.Bytes(10)) + na.Key = hexToCompact(key) + nb.Key = hexToCompact(key) + + valA := testrand.Bytes(32) + valB := testrand.Bytes(32) + na.Val = valA + nb.Val = valB + + bufa, bufb := rlp.NewEncoderBuffer(nil), rlp.NewEncoderBuffer(nil) + na.encode(bufa) + nb.encode(bufb) + diff, _ := rlp.EncodeToBytes(valA) + return bufa.ToBytes(), bufb.ToBytes(), [][]byte{diff}, []int{1} +} + +func makeTestFullNodePair() ([]byte, []byte, [][]byte, []int) { + var ( + na = fullnodeEncoder{} + nb = fullnodeEncoder{} + indices []int + values [][]byte + ) + for i := 0; i < 16; i++ { + switch rand.Intn(3) { + case 0: + // write nil + case 1: + // write same + var child []byte + if rand.Intn(2) == 0 { + child = testrand.Bytes(32) // hashnode + } else { + child = makeTestLeafNode(true) // embedded node + } + na.Children[i] = child + nb.Children[i] = child + case 2: + // write different + var ( + va []byte + diff []byte + ) + rnd := rand.Intn(3) + if rnd == 0 { + va = testrand.Bytes(32) // hashnode + diff, _ = rlp.EncodeToBytes(va) + } else if rnd == 1 { + va = makeTestLeafNode(true) // embedded node + diff = va + } else { + va = nil + diff = rlp.EmptyString + } + vb := testrand.Bytes(32) // hashnode + na.Children[i] = va + nb.Children[i] = vb + + indices = append(indices, i) + values = append(values, diff) + } + } + na.Children[16] = nil + nb.Children[16] = nil + + bufa, bufb := rlp.NewEncoderBuffer(nil), rlp.NewEncoderBuffer(nil) + na.encode(bufa) + nb.encode(bufb) + return bufa.ToBytes(), bufb.ToBytes(), values, indices +} + +func TestNodeDifference(t *testing.T) { + type testsuite struct { + old []byte + new []byte + expErr bool + expIndices []int + expValues [][]byte + } + var tests = []testsuite{ + // Invalid node data + { + old: nil, new: nil, expErr: true, + }, + { + old: testrand.Bytes(32), new: nil, expErr: true, + }, + { + old: nil, new: testrand.Bytes(32), expErr: true, + }, + { + old: testrand.Bytes(32), new: testrand.Bytes(32), expErr: true, + }, + // Different node type + { + old: makeTestLeafNode(true), new: makeTestFullNode(true), expErr: true, + }, + } + for range 10 { + va, vb, elements, indices := makeTestLeafNodePair() + tests = append(tests, testsuite{ + old: va, + new: vb, + expErr: false, + expIndices: indices, + expValues: elements, + }) + } + for range 10 { + va, vb, elements, indices := makeTestFullNodePair() + tests = append(tests, testsuite{ + old: va, + new: vb, + expErr: false, + expIndices: indices, + expValues: elements, + }) + } + + for _, test := range tests { + _, indices, values, err := NodeDifference(test.old, test.new) + if test.expErr && err == nil { + t.Fatal("Expect error, got nil") + } + if !test.expErr && err != nil { + t.Fatalf("Unexpect error, %v", err) + } + if err == nil { + if !reflect.DeepEqual(indices, test.expIndices) { + t.Fatalf("Unexpected indices, want: %v, got: %v", test.expIndices, indices) + } + if !reflect.DeepEqual(values, test.expValues) { + t.Fatalf("Unexpected values, want: %v, got: %v", test.expValues, values) + } + } + } +} + +func TestReassembleFullNode(t *testing.T) { + var fn fullnodeEncoder + for i := 0; i < 16; i++ { + if rand.Intn(2) == 0 { + fn.Children[i] = testrand.Bytes(32) + } + } + buf := rlp.NewEncoderBuffer(nil) + fn.encode(buf) + enc := buf.ToBytes() + + // Generate a list of diffs + var ( + values [][][]byte + indices [][]int + ) + for i := 0; i < 10; i++ { + var ( + pos = make(map[int]struct{}) + poslist []int + valuelist [][]byte + ) + for j := 0; j < 3; j++ { + p := rand.Intn(16) + if _, ok := pos[p]; ok { + continue + } + pos[p] = struct{}{} + + nh := testrand.Bytes(32) + diff, _ := rlp.EncodeToBytes(nh) + poslist = append(poslist, p) + valuelist = append(valuelist, diff) + fn.Children[p] = nh + } + values = append(values, valuelist) + indices = append(indices, poslist) + } + reassembled, err := ReassembleNode(enc, values, indices) + if err != nil { + t.Fatalf("Failed to re-assemble full node %v", err) + } + buf2 := rlp.NewEncoderBuffer(nil) + fn.encode(buf2) + enc2 := buf2.ToBytes() + if !reflect.DeepEqual(enc2, reassembled) { + t.Fatalf("Unexpeted reassembled node") + } +} + +func TestReassembleShortNode(t *testing.T) { + var ln leafNodeEncoder + ln.Key = hexToCompact(keybytesToHex(testrand.Bytes(10))) + ln.Val = testrand.Bytes(10) + buf := rlp.NewEncoderBuffer(nil) + ln.encode(buf) + enc := buf.ToBytes() + + // Generate a list of diffs + var ( + values [][][]byte + indices [][]int + ) + for i := 0; i < 10; i++ { + val := testrand.Bytes(10) + ln.Val = val + diff, _ := rlp.EncodeToBytes(val) + values = append(values, [][]byte{diff}) + indices = append(indices, []int{1}) + } + reassembled, err := ReassembleNode(enc, values, indices) + if err != nil { + t.Fatalf("Failed to re-assemble full node %v", err) + } + buf2 := rlp.NewEncoderBuffer(nil) + ln.encode(buf2) + enc2 := buf2.ToBytes() + if !reflect.DeepEqual(enc2, reassembled) { + t.Fatalf("Unexpeted reassembled node") + } +} + // goos: darwin // goarch: arm64 // pkg: github.com/ethereum/go-ethereum/trie diff --git a/trie/proof.go b/trie/proof.go index 53b7acc30c..1a06ed5d5e 100644 --- a/trie/proof.go +++ b/trie/proof.go @@ -69,7 +69,7 @@ func (t *Trie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { // loaded blob will be tracked, while it's not required here since // all loaded nodes won't be linked to trie at all and track nodes // may lead to out-of-memory issue. - blob, err := t.reader.node(prefix, common.BytesToHash(n)) + blob, err := t.reader.Node(prefix, common.BytesToHash(n)) if err != nil { log.Error("Unhandled trie error in Trie.Prove", "err", err) return err @@ -567,7 +567,12 @@ func VerifyRangeProof(rootHash common.Hash, firstKey []byte, keys [][]byte, valu } // Rebuild the trie with the leaf stream, the shape of trie // should be same with the original one. - tr := &Trie{root: root, reader: newEmptyReader(), tracer: newTracer()} + tr := &Trie{ + root: root, + reader: newEmptyReader(), + opTracer: newOpTracer(), + prevalueTracer: NewPrevalueTracer(), + } if empty { tr.root = nil } diff --git a/trie/proof_test.go b/trie/proof_test.go index b3c9dd753c..40c49f358b 100644 --- a/trie/proof_test.go +++ b/trie/proof_test.go @@ -109,7 +109,7 @@ func TestOneElementProof(t *testing.T) { t.Fatalf("prover %d: failed to verify proof: %v\nraw proof: %x", i, err, proof) } if !bytes.Equal(val, []byte("v")) { - t.Fatalf("prover %d: verified value mismatch: have %x, want 'k'", i, val) + t.Fatalf("prover %d: verified value mismatch: have %x, want 'v'", i, val) } } } diff --git a/trie/secure_trie.go b/trie/secure_trie.go index 0424ecb6e5..7c7bd184bf 100644 --- a/trie/secure_trie.go +++ b/trie/secure_trie.go @@ -105,19 +105,6 @@ func (t *StateTrie) MustGet(key []byte) []byte { return t.trie.MustGet(crypto.Keccak256(key)) } -// GetStorage attempts to retrieve a storage slot with provided account address -// and slot key. The value bytes must not be modified by the caller. -// If the specified storage slot is not in the trie, nil will be returned. -// If a trie node is not found in the database, a MissingNodeError is returned. -func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) { - enc, err := t.trie.Get(crypto.Keccak256(key)) - if err != nil || len(enc) == 0 { - return nil, err - } - _, content, _, err := rlp.Split(enc) - return content, err -} - // GetAccount attempts to retrieve an account with provided account address. // If the specified account is not in the trie, nil will be returned. // If a trie node is not found in the database, a MissingNodeError is returned. @@ -144,6 +131,39 @@ func (t *StateTrie) GetAccountByHash(addrHash common.Hash) (*types.StateAccount, return ret, err } +// PrefetchAccount attempts to resolve specific accounts from the database +// to accelerate subsequent trie operations. +func (t *StateTrie) PrefetchAccount(addresses []common.Address) error { + var keys [][]byte + for _, addr := range addresses { + keys = append(keys, crypto.Keccak256(addr.Bytes())) + } + return t.trie.Prefetch(keys) +} + +// GetStorage attempts to retrieve a storage slot with provided account address +// and slot key. The value bytes must not be modified by the caller. +// If the specified storage slot is not in the trie, nil will be returned. +// If a trie node is not found in the database, a MissingNodeError is returned. +func (t *StateTrie) GetStorage(_ common.Address, key []byte) ([]byte, error) { + enc, err := t.trie.Get(crypto.Keccak256(key)) + if err != nil || len(enc) == 0 { + return nil, err + } + _, content, _, err := rlp.Split(enc) + return content, err +} + +// PrefetchStorage attempts to resolve specific storage slots from the database +// to accelerate subsequent trie operations. +func (t *StateTrie) PrefetchStorage(_ common.Address, keys [][]byte) error { + var keylist [][]byte + for _, key := range keys { + keylist = append(keylist, crypto.Keccak256(key)) + } + return t.trie.Prefetch(keylist) +} + // GetNode attempts to retrieve a trie node by compact-encoded path. It is not // possible to use keybyte-encoding as the path might contain odd nibbles. // If the specified trie node is not in the trie, nil will be returned. @@ -253,7 +273,7 @@ func (t *StateTrie) GetKey(shaKey []byte) []byte { } // Witness returns a set containing all trie nodes that have been accessed. -func (t *StateTrie) Witness() map[string]struct{} { +func (t *StateTrie) Witness() map[string][]byte { return t.trie.Witness() } diff --git a/trie/stacktrie.go b/trie/stacktrie.go index 2b7366c3c5..18fe1eea78 100644 --- a/trie/stacktrie.go +++ b/trie/stacktrie.go @@ -28,7 +28,7 @@ import ( var ( stPool = sync.Pool{New: func() any { return new(stNode) }} bPool = newBytesPool(32, 100) - _ = types.TrieHasher((*StackTrie)(nil)) + _ = types.ListHasher((*StackTrie)(nil)) ) // OnTrieNode is a callback method invoked when a trie node is committed @@ -50,6 +50,7 @@ type StackTrie struct { onTrieNode OnTrieNode kBuf []byte // buf space used for hex-key during insertions pBuf []byte // buf space used for path during insertions + vPool *unsafeBytesPool } // NewStackTrie allocates and initializes an empty trie. The committed nodes @@ -61,6 +62,7 @@ func NewStackTrie(onTrieNode OnTrieNode) *StackTrie { onTrieNode: onTrieNode, kBuf: make([]byte, 64), pBuf: make([]byte, 64), + vPool: newUnsafeBytesPool(300, 20), } } @@ -74,6 +76,9 @@ func (t *StackTrie) grow(key []byte) { } // Update inserts a (key, value) pair into the stack trie. +// +// Note the supplied key value pair is copied and managed internally, +// they are safe to be modified after this method returns. func (t *StackTrie) Update(key, value []byte) error { if len(value) == 0 { return errors.New("trying to insert empty (deletion)") @@ -88,7 +93,14 @@ func (t *StackTrie) Update(key, value []byte) error { } else { t.last = append(t.last[:0], k...) // reuse key slice } - t.insert(t.root, k, value, t.pBuf[:0]) + vBuf := t.vPool.get() + if cap(vBuf) < len(value) { + vBuf = common.CopyBytes(value) + } else { + vBuf = vBuf[:len(value)] + copy(vBuf, value) + } + t.insert(t.root, k, vBuf, t.pBuf[:0]) return nil } @@ -108,14 +120,16 @@ func (t *StackTrie) TrieKey(key []byte) []byte { // stNode represents a node within a StackTrie type stNode struct { typ uint8 // node type (as in branch, ext, leaf) - key []byte // key chunk covered by this (leaf|ext) node - val []byte // value contained by this node if it's a leaf - children [16]*stNode // list of children (for branch and exts) + key []byte // exclusive owned key chunk covered by this (leaf|ext) node + val []byte // exclusive owned value contained by this node (leaf: value; hash: hash) + children [16]*stNode // list of children (for branch and ext) } -// newLeaf constructs a leaf node with provided node key and value. The key -// will be deep-copied in the function and safe to modify afterwards, but -// value is not. +// newLeaf constructs a leaf node with provided node key and value. +// +// The key is deep-copied within the function, so it can be safely modified +// afterwards. The value is retained directly without copying, as it is +// exclusively owned by the stackTrie. func newLeaf(key, val []byte) *stNode { st := stPool.Get().(*stNode) st.typ = leafNode @@ -146,9 +160,9 @@ const ( func (n *stNode) reset() *stNode { if n.typ == hashedNode { // On hashnodes, we 'own' the val: it is guaranteed to be not held - // by external caller. Hence, when we arrive here, we can put it back - // into the pool - bPool.Put(n.val) + // by external caller. Hence, when we arrive here, we can put it + // back into the pool + bPool.put(n.val) } n.key = n.key[:0] n.val = nil @@ -172,11 +186,6 @@ func (n *stNode) getDiffIndex(key []byte) int { } // Helper function to that inserts a (key, value) pair into the trie. -// -// - The key is not retained by this method, but always copied if needed. -// - The value is retained by this method, as long as the leaf that it represents -// remains unhashed. However: it is never modified. -// - The path is not retained by this method. func (t *StackTrie) insert(st *stNode, key, value []byte, path []byte) { switch st.typ { case branchNode: /* Branch */ @@ -235,16 +244,14 @@ func (t *StackTrie) insert(st *stNode, key, value []byte, path []byte) { } var p *stNode if diffidx == 0 { - // the break is on the first byte, so - // the current node is converted into - // a branch node. + // the break is on the first byte, so the current node + // is converted into a branch node. st.children[0] = nil - p = st st.typ = branchNode + p = st } else { - // the common prefix is at least one byte - // long, insert a new intermediate branch - // node. + // the common prefix is at least one byte long, insert + // a new intermediate branch node. st.children[0] = stPool.Get().(*stNode) st.children[0].typ = branchNode p = st.children[0] @@ -280,8 +287,8 @@ func (t *StackTrie) insert(st *stNode, key, value []byte, path []byte) { if diffidx == 0 { // Convert current leaf into a branch st.typ = branchNode - p = st st.children[0] = nil + p = st } else { // Convert current node into an ext, // and insert a child branch node. @@ -307,9 +314,7 @@ func (t *StackTrie) insert(st *stNode, key, value []byte, path []byte) { st.val = nil case emptyNode: /* Empty */ - st.typ = leafNode - st.key = append(st.key, key...) // deep-copy the key as it's volatile - st.val = value + *st = *newLeaf(key, value) case hashedNode: panic("trying to insert into hash") @@ -393,18 +398,23 @@ func (t *StackTrie) hash(st *stNode, path []byte) { st.typ = hashedNode st.key = st.key[:0] - st.val = nil // Release reference to potentially externally held slice. + // Release reference to value slice which is exclusively owned + // by stackTrie itself. + if cap(st.val) > 0 && t.vPool != nil { + t.vPool.put(st.val) + } + st.val = nil // Skip committing the non-root node if the size is smaller than 32 bytes // as tiny nodes are always embedded in their parent except root node. if len(blob) < 32 && len(path) > 0 { - st.val = bPool.GetWithSize(len(blob)) + st.val = bPool.getWithSize(len(blob)) copy(st.val, blob) return } // Write the hash to the 'val'. We allocate a new val here to not mutate // input values. - st.val = bPool.GetWithSize(32) + st.val = bPool.getWithSize(32) t.h.hashDataTo(st.val, blob) // Invoke the callback it's provided. Notably, the path and blob slices are diff --git a/trie/sync.go b/trie/sync.go index 8d0ce6901c..404d67f154 100644 --- a/trie/sync.go +++ b/trie/sync.go @@ -19,6 +19,7 @@ package trie import ( "errors" "fmt" + "slices" "sync" "github.com/ethereum/go-ethereum/common" @@ -553,7 +554,7 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { } children = []childNode{{ node: node.Val, - path: append(append([]byte(nil), req.path...), key...), + path: slices.Concat(req.path, key), }} // Mark all internal nodes between shortNode and its **in disk** // child as invalid. This is essential in the case of path mode @@ -595,7 +596,7 @@ func (s *Sync) children(req *nodeRequest, object node) ([]*nodeRequest, error) { if node.Children[i] != nil { children = append(children, childNode{ node: node.Children[i], - path: append(append([]byte(nil), req.path...), byte(i)), + path: append(slices.Clone(req.path), byte(i)), }) } } diff --git a/trie/tracer.go b/trie/tracer.go index 90b9666f0b..04122d1384 100644 --- a/trie/tracer.go +++ b/trie/tracer.go @@ -18,14 +18,13 @@ package trie import ( "maps" - - "github.com/ethereum/go-ethereum/common" + "sync" ) -// tracer tracks the changes of trie nodes. During the trie operations, +// opTracer tracks the changes of trie nodes. During the trie operations, // some nodes can be deleted from the trie, while these deleted nodes // won't be captured by trie.Hasher or trie.Committer. Thus, these deleted -// nodes won't be removed from the disk at all. Tracer is an auxiliary tool +// nodes won't be removed from the disk at all. opTracer is an auxiliary tool // used to track all insert and delete operations of trie and capture all // deleted nodes eventually. // @@ -35,38 +34,25 @@ import ( // This tool can track all of them no matter the node is embedded in its // parent or not, but valueNode is never tracked. // -// Besides, it's also used for recording the original value of the nodes -// when they are resolved from the disk. The pre-value of the nodes will -// be used to construct trie history in the future. -// -// Note tracer is not thread-safe, callers should be responsible for handling +// Note opTracer is not thread-safe, callers should be responsible for handling // the concurrency issues by themselves. -type tracer struct { - inserts map[string]struct{} - deletes map[string]struct{} - accessList map[string][]byte +type opTracer struct { + inserts map[string]struct{} + deletes map[string]struct{} } -// newTracer initializes the tracer for capturing trie changes. -func newTracer() *tracer { - return &tracer{ - inserts: make(map[string]struct{}), - deletes: make(map[string]struct{}), - accessList: make(map[string][]byte), +// newOpTracer initializes the tracer for capturing trie changes. +func newOpTracer() *opTracer { + return &opTracer{ + inserts: make(map[string]struct{}), + deletes: make(map[string]struct{}), } } -// onRead tracks the newly loaded trie node and caches the rlp-encoded -// blob internally. Don't change the value outside of function since -// it's not deep-copied. -func (t *tracer) onRead(path []byte, val []byte) { - t.accessList[string(path)] = val -} - // onInsert tracks the newly inserted trie node. If it's already // in the deletion set (resurrected node), then just wipe it from // the deletion set as it's "untouched". -func (t *tracer) onInsert(path []byte) { +func (t *opTracer) onInsert(path []byte) { if _, present := t.deletes[string(path)]; present { delete(t.deletes, string(path)) return @@ -77,7 +63,7 @@ func (t *tracer) onInsert(path []byte) { // onDelete tracks the newly deleted trie node. If it's already // in the addition set, then just wipe it from the addition set // as it's untouched. -func (t *tracer) onDelete(path []byte) { +func (t *opTracer) onDelete(path []byte) { if _, present := t.inserts[string(path)]; present { delete(t.inserts, string(path)) return @@ -86,37 +72,101 @@ func (t *tracer) onDelete(path []byte) { } // reset clears the content tracked by tracer. -func (t *tracer) reset() { - t.inserts = make(map[string]struct{}) - t.deletes = make(map[string]struct{}) - t.accessList = make(map[string][]byte) +func (t *opTracer) reset() { + clear(t.inserts) + clear(t.deletes) } // copy returns a deep copied tracer instance. -func (t *tracer) copy() *tracer { - accessList := make(map[string][]byte, len(t.accessList)) - for path, blob := range t.accessList { - accessList[path] = common.CopyBytes(blob) - } - return &tracer{ - inserts: maps.Clone(t.inserts), - deletes: maps.Clone(t.deletes), - accessList: accessList, +func (t *opTracer) copy() *opTracer { + return &opTracer{ + inserts: maps.Clone(t.inserts), + deletes: maps.Clone(t.deletes), } } -// deletedNodes returns a list of node paths which are deleted from the trie. -func (t *tracer) deletedNodes() []string { - var paths []string +// deletedList returns a list of node paths which are deleted from the trie. +func (t *opTracer) deletedList() [][]byte { + paths := make([][]byte, 0, len(t.deletes)) for path := range t.deletes { - // It's possible a few deleted nodes were embedded - // in their parent before, the deletions can be no - // effect by deleting nothing, filter them out. - _, ok := t.accessList[path] - if !ok { - continue - } - paths = append(paths, path) + paths = append(paths, []byte(path)) } return paths } + +// PrevalueTracer tracks the original values of resolved trie nodes. Cached trie +// node values are expected to be immutable. A zero-size node value is treated as +// non-existent and should not occur in practice. +// +// Note PrevalueTracer is thread-safe. +type PrevalueTracer struct { + data map[string][]byte + lock sync.RWMutex +} + +// NewPrevalueTracer initializes the tracer for capturing resolved trie nodes. +func NewPrevalueTracer() *PrevalueTracer { + return &PrevalueTracer{ + data: make(map[string][]byte), + } +} + +// Put tracks the newly loaded trie node and caches its RLP-encoded +// blob internally. Do not modify the value outside this function, +// as it is not deep-copied. +func (t *PrevalueTracer) Put(path []byte, val []byte) { + t.lock.Lock() + defer t.lock.Unlock() + + t.data[string(path)] = val +} + +// Get returns the cached trie node value. If the node is not found, nil will +// be returned. +func (t *PrevalueTracer) Get(path []byte) []byte { + t.lock.RLock() + defer t.lock.RUnlock() + + return t.data[string(path)] +} + +// HasList returns a list of flags indicating whether the corresponding trie nodes +// specified by the path exist in the trie. +func (t *PrevalueTracer) HasList(list [][]byte) []bool { + t.lock.RLock() + defer t.lock.RUnlock() + + exists := make([]bool, 0, len(list)) + for _, path := range list { + _, ok := t.data[string(path)] + exists = append(exists, ok) + } + return exists +} + +// Values returns a list of values of the cached trie nodes. +func (t *PrevalueTracer) Values() map[string][]byte { + t.lock.RLock() + defer t.lock.RUnlock() + + return maps.Clone(t.data) +} + +// Reset resets the cached content in the prevalueTracer. +func (t *PrevalueTracer) Reset() { + t.lock.Lock() + defer t.lock.Unlock() + + clear(t.data) +} + +// Copy returns a copied prevalueTracer instance. +func (t *PrevalueTracer) Copy() *PrevalueTracer { + t.lock.RLock() + defer t.lock.RUnlock() + + // Shadow clone is used, as the cached trie node values are immutable + return &PrevalueTracer{ + data: maps.Clone(t.data), + } +} diff --git a/trie/tracer_test.go b/trie/tracer_test.go index 852a706021..695570fd0d 100644 --- a/trie/tracer_test.go +++ b/trie/tracer_test.go @@ -52,15 +52,15 @@ var ( } ) -func TestTrieTracer(t *testing.T) { - testTrieTracer(t, tiny) - testTrieTracer(t, nonAligned) - testTrieTracer(t, standard) +func TestTrieOpTracer(t *testing.T) { + testTrieOpTracer(t, tiny) + testTrieOpTracer(t, nonAligned) + testTrieOpTracer(t, standard) } // Tests if the trie diffs are tracked correctly. Tracer should capture // all non-leaf dirty nodes, no matter the node is embedded or not. -func testTrieTracer(t *testing.T, vals []struct{ k, v string }) { +func testTrieOpTracer(t *testing.T, vals []struct{ k, v string }) { db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) trie := NewEmpty(db) @@ -68,8 +68,8 @@ func testTrieTracer(t *testing.T, vals []struct{ k, v string }) { for _, val := range vals { trie.MustUpdate([]byte(val.k), []byte(val.v)) } - insertSet := copySet(trie.tracer.inserts) // copy before commit - deleteSet := copySet(trie.tracer.deletes) // copy before commit + insertSet := copySet(trie.opTracer.inserts) // copy before commit + deleteSet := copySet(trie.opTracer.deletes) // copy before commit root, nodes := trie.Commit(false) db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) @@ -86,7 +86,7 @@ func testTrieTracer(t *testing.T, vals []struct{ k, v string }) { for _, val := range vals { trie.MustDelete([]byte(val.k)) } - insertSet, deleteSet = copySet(trie.tracer.inserts), copySet(trie.tracer.deletes) + insertSet, deleteSet = copySet(trie.opTracer.inserts), copySet(trie.opTracer.deletes) if !compareSet(insertSet, nil) { t.Fatal("Unexpected insertion set") } @@ -97,13 +97,13 @@ func testTrieTracer(t *testing.T, vals []struct{ k, v string }) { // Test that after inserting a new batch of nodes and deleting them immediately, // the trie tracer should be cleared normally as no operation happened. -func TestTrieTracerNoop(t *testing.T) { - testTrieTracerNoop(t, tiny) - testTrieTracerNoop(t, nonAligned) - testTrieTracerNoop(t, standard) +func TestTrieOpTracerNoop(t *testing.T) { + testTrieOpTracerNoop(t, tiny) + testTrieOpTracerNoop(t, nonAligned) + testTrieOpTracerNoop(t, standard) } -func testTrieTracerNoop(t *testing.T, vals []struct{ k, v string }) { +func testTrieOpTracerNoop(t *testing.T, vals []struct{ k, v string }) { db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) trie := NewEmpty(db) for _, val := range vals { @@ -112,22 +112,22 @@ func testTrieTracerNoop(t *testing.T, vals []struct{ k, v string }) { for _, val := range vals { trie.MustDelete([]byte(val.k)) } - if len(trie.tracer.inserts) != 0 { + if len(trie.opTracer.inserts) != 0 { t.Fatal("Unexpected insertion set") } - if len(trie.tracer.deletes) != 0 { + if len(trie.opTracer.deletes) != 0 { t.Fatal("Unexpected deletion set") } } -// Tests if the accessList is correctly tracked. -func TestAccessList(t *testing.T) { - testAccessList(t, tiny) - testAccessList(t, nonAligned) - testAccessList(t, standard) +// Tests if the original value of trie nodes are correctly tracked. +func TestPrevalueTracer(t *testing.T) { + testPrevalueTracer(t, tiny) + testPrevalueTracer(t, nonAligned) + testPrevalueTracer(t, standard) } -func testAccessList(t *testing.T, vals []struct{ k, v string }) { +func testPrevalueTracer(t *testing.T, vals []struct{ k, v string }) { var ( db = newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) trie = NewEmpty(db) @@ -210,7 +210,7 @@ func testAccessList(t *testing.T, vals []struct{ k, v string }) { } // Tests origin values won't be tracked in Iterator or Prover -func TestAccessListLeak(t *testing.T) { +func TestPrevalueTracerLeak(t *testing.T) { var ( db = newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) trie = NewEmpty(db) @@ -249,9 +249,9 @@ func TestAccessListLeak(t *testing.T) { } for _, c := range cases { trie, _ = New(TrieID(root), db) - n1 := len(trie.tracer.accessList) + n1 := len(trie.prevalueTracer.data) c.op(trie) - n2 := len(trie.tracer.accessList) + n2 := len(trie.prevalueTracer.data) if n1 != n2 { t.Fatalf("AccessList is leaked, prev %d after %d", n1, n2) diff --git a/trie/transitiontrie/transition.go b/trie/transitiontrie/transition.go new file mode 100644 index 0000000000..4c73022082 --- /dev/null +++ b/trie/transitiontrie/transition.go @@ -0,0 +1,237 @@ +// Copyright 2025 go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package transitiontrie + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/trie" + "github.com/ethereum/go-ethereum/trie/bintrie" + "github.com/ethereum/go-ethereum/trie/trienode" +) + +// TransitionTrie is a trie that implements a façade design pattern, presenting +// a single interface to the old MPT trie and the new verkle/binary trie. Reads +// first from the overlay trie, and falls back to the base trie if the key isn't +// found. All writes go to the overlay trie. +type TransitionTrie struct { + overlay *bintrie.BinaryTrie + base *trie.SecureTrie + storage bool +} + +// NewTransitionTrie creates a new TransitionTrie. +// Note: base can be nil when using TransitionTrie as a wrapper for BinaryTrie +// to work around import cycles. This is a temporary hack that should be +// refactored in future PRs (see core/state/reader.go for details). +func NewTransitionTrie(base *trie.SecureTrie, overlay *bintrie.BinaryTrie, st bool) *TransitionTrie { + return &TransitionTrie{ + overlay: overlay, + base: base, + storage: st, + } +} + +// Base returns the base trie. +func (t *TransitionTrie) Base() *trie.SecureTrie { + return t.base +} + +// Overlay returns the overlay trie. +func (t *TransitionTrie) Overlay() *bintrie.BinaryTrie { + return t.overlay +} + +// GetKey returns the sha3 preimage of a hashed key that was previously used +// to store a value. +func (t *TransitionTrie) GetKey(key []byte) []byte { + if key := t.overlay.GetKey(key); key != nil { + return key + } + if t.base != nil { + return t.base.GetKey(key) + } + return nil +} + +// GetStorage returns the value for key stored in the trie. The value bytes must +// not be modified by the caller. +func (t *TransitionTrie) GetStorage(addr common.Address, key []byte) ([]byte, error) { + val, err := t.overlay.GetStorage(addr, key) + if err != nil { + return nil, fmt.Errorf("get storage from overlay: %s", err) + } + if len(val) != 0 { + return val, nil + } + if t.base != nil { + // TODO also insert value into overlay + return t.base.GetStorage(addr, key) + } + return nil, nil +} + +// PrefetchStorage attempts to resolve specific storage slots from the database +// to accelerate subsequent trie operations. +func (t *TransitionTrie) PrefetchStorage(addr common.Address, keys [][]byte) error { + for _, key := range keys { + if _, err := t.GetStorage(addr, key); err != nil { + return err + } + } + return nil +} + +// GetAccount abstract an account read from the trie. +func (t *TransitionTrie) GetAccount(address common.Address) (*types.StateAccount, error) { + data, err := t.overlay.GetAccount(address) + if err != nil { + // Post cancun, no indicator needs to be used to indicate that + // an account was deleted in the overlay tree. If an error is + // returned, then it's a genuine error, and not an indicator + // that a tombstone was found. + return nil, err + } + if data != nil { + return data, nil + } + if t.base != nil { + return t.base.GetAccount(address) + } + return nil, nil +} + +// PrefetchAccount attempts to resolve specific accounts from the database +// to accelerate subsequent trie operations. +func (t *TransitionTrie) PrefetchAccount(addresses []common.Address) error { + for _, addr := range addresses { + if _, err := t.GetAccount(addr); err != nil { + return err + } + } + return nil +} + +// UpdateStorage associates key with value in the trie. If value has length zero, any +// existing value is deleted from the trie. The value bytes must not be modified +// by the caller while they are stored in the trie. +func (t *TransitionTrie) UpdateStorage(address common.Address, key []byte, value []byte) error { + var v []byte + if len(value) >= 32 { + v = value[:32] + } else { + var val [32]byte + copy(val[32-len(value):], value[:]) + v = val[:] + } + return t.overlay.UpdateStorage(address, key, v) +} + +// UpdateAccount abstract an account write to the trie. +func (t *TransitionTrie) UpdateAccount(addr common.Address, account *types.StateAccount, codeLen int) error { + // NOTE: before the rebase, this was saving the state root, so that OpenStorageTrie + // could still work during a replay. This is no longer needed, as OpenStorageTrie + // only needs to know what the account trie does now. + return t.overlay.UpdateAccount(addr, account, codeLen) +} + +// DeleteStorage removes any existing value for key from the trie. If a node was not +// found in the database, a trie.MissingNodeError is returned. +func (t *TransitionTrie) DeleteStorage(addr common.Address, key []byte) error { + return t.overlay.DeleteStorage(addr, key) +} + +// DeleteAccount abstracts an account deletion from the trie. +func (t *TransitionTrie) DeleteAccount(key common.Address) error { + return t.overlay.DeleteAccount(key) +} + +// Hash returns the root hash of the trie. It does not write to the database and +// can be used even if the trie doesn't have one. +func (t *TransitionTrie) Hash() common.Hash { + return t.overlay.Hash() +} + +// Commit collects all dirty nodes in the trie and replace them with the +// corresponding node hash. All collected nodes(including dirty leaves if +// collectLeaf is true) will be encapsulated into a nodeset for return. +// The returned nodeset can be nil if the trie is clean(nothing to commit). +// Once the trie is committed, it's not usable anymore. A new trie must +// be created with new root and updated trie database for following usage +func (t *TransitionTrie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) { + // Just return if the trie is a storage trie: otherwise, + // the overlay trie will be committed as many times as + // there are storage tries. This would kill performance. + if t.storage { + return common.Hash{}, nil + } + return t.overlay.Commit(collectLeaf) +} + +// NodeIterator returns an iterator that returns nodes of the trie. Iteration +// starts at the key after the given start key. +func (t *TransitionTrie) NodeIterator(startKey []byte) (trie.NodeIterator, error) { + panic("not implemented") // TODO: Implement +} + +// Prove constructs a Merkle proof for key. The result contains all encoded nodes +// on the path to the value at key. The value itself is also included in the last +// node and can be retrieved by verifying the proof. +// +// If the trie does not contain a value for key, the returned proof contains all +// nodes of the longest existing prefix of the key (at least the root), ending +// with the node that proves the absence of the key. +func (t *TransitionTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { + panic("not implemented") // TODO: Implement +} + +// IsVerkle returns true if the trie is verkle-tree based +func (t *TransitionTrie) IsVerkle() bool { + // For all intents and purposes, the calling code should treat this as a verkle trie + return true +} + +// UpdateStem updates a group of values, given the stem they are using. If +// a value already exists, it is overwritten. +// TODO: This is Verkle-specific and requires access to private fields. +// Not currently used in the codebase. +func (t *TransitionTrie) UpdateStem(key []byte, values [][]byte) error { + panic("UpdateStem is not implemented for TransitionTrie") +} + +// Copy creates a deep copy of the transition trie. +func (t *TransitionTrie) Copy() *TransitionTrie { + return &TransitionTrie{ + overlay: t.overlay.Copy(), + // base in immutable, so there is no need to copy it + base: t.base, + storage: t.storage, + } +} + +// UpdateContractCode updates the contract code for the given address. +func (t *TransitionTrie) UpdateContractCode(addr common.Address, codeHash common.Hash, code []byte) error { + return t.overlay.UpdateContractCode(addr, codeHash, code) +} + +// Witness returns a set containing all trie nodes that have been accessed. +func (t *TransitionTrie) Witness() map[string][]byte { + panic("not implemented") +} diff --git a/trie/trie.go b/trie/trie.go index 222bf8b1f0..1ef2c2f1a6 100644 --- a/trie/trie.go +++ b/trie/trie.go @@ -21,12 +21,14 @@ import ( "bytes" "errors" "fmt" + "slices" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/ethereum/go-ethereum/triedb/database" + "golang.org/x/sync/errgroup" ) // Trie represents a Merkle Patricia Trie. Use New to create a trie that operates @@ -53,10 +55,11 @@ type Trie struct { uncommitted int // reader is the handler trie can retrieve nodes from. - reader *trieReader + reader *Reader - // tracer is the tool to track the trie changes. - tracer *tracer + // Various tracers for capturing the modifications to trie + opTracer *opTracer + prevalueTracer *PrevalueTracer } // newFlag returns the cache flag value for a newly created node. @@ -67,13 +70,14 @@ func (t *Trie) newFlag() nodeFlag { // Copy returns a copy of Trie. func (t *Trie) Copy() *Trie { return &Trie{ - root: copyNode(t.root), - owner: t.owner, - committed: t.committed, - unhashed: t.unhashed, - uncommitted: t.uncommitted, - reader: t.reader, - tracer: t.tracer.copy(), + root: copyNode(t.root), + owner: t.owner, + committed: t.committed, + unhashed: t.unhashed, + uncommitted: t.uncommitted, + reader: t.reader, + opTracer: t.opTracer.copy(), + prevalueTracer: t.prevalueTracer.Copy(), } } @@ -84,14 +88,15 @@ func (t *Trie) Copy() *Trie { // empty, otherwise, the root node must be present in database or returns // a MissingNodeError if not. func New(id *ID, db database.NodeDatabase) (*Trie, error) { - reader, err := newTrieReader(id.StateRoot, id.Owner, db) + reader, err := NewReader(id.StateRoot, id.Owner, db) if err != nil { return nil, err } trie := &Trie{ - owner: id.Owner, - reader: reader, - tracer: newTracer(), + owner: id.Owner, + reader: reader, + opTracer: newOpTracer(), + prevalueTracer: NewPrevalueTracer(), } if id.Root != (common.Hash{}) && id.Root != types.EmptyRootHash { rootnode, err := trie.resolveAndTrack(id.Root[:], nil) @@ -129,6 +134,34 @@ func (t *Trie) NodeIterator(start []byte) (NodeIterator, error) { return newNodeIterator(t, start), nil } +// NodeIteratorWithPrefix returns an iterator that returns nodes of the trie +// whose leaf keys start with the given prefix. Iteration includes all keys +// where prefix <= k < nextKey(prefix), effectively returning only keys that +// have the prefix. The iteration stops once it would encounter a key that +// doesn't start with the prefix. +// +// For example, with prefix "dog", the iterator will return "dog", "dogcat", +// "dogfish" but not "dot" or "fog". An empty prefix iterates the entire trie. +func (t *Trie) NodeIteratorWithPrefix(prefix []byte) (NodeIterator, error) { + // Short circuit if the trie is already committed and not usable. + if t.committed { + return nil, ErrCommitted + } + // Use the dedicated prefix iterator which handles prefix checking correctly + return newPrefixIterator(t, prefix) +} + +// NodeIteratorWithRange returns an iterator over trie nodes whose leaf keys +// fall within the specified range. It includes all keys where start <= k < end. +// Iteration stops once a key beyond the end boundary is encountered. +func (t *Trie) NodeIteratorWithRange(start, end []byte) (NodeIterator, error) { + // Short circuit if the trie is already committed and not usable. + if t.committed { + return nil, ErrCommitted + } + return newSubtreeIterator(t, start, end) +} + // MustGet is a wrapper of Get and will omit any encountered error but just // print out an error message. func (t *Trie) MustGet(key []byte) []byte { @@ -190,6 +223,51 @@ func (t *Trie) get(origNode node, key []byte, pos int) (value []byte, newnode no } } +// Prefetch attempts to resolve the leaves and intermediate trie nodes +// specified by the key list in parallel. The results are silently +// discarded to simplify the function. +func (t *Trie) Prefetch(keylist [][]byte) error { + // Short circuit if the trie is already committed and not usable. + if t.committed { + return ErrCommitted + } + // Resolve the trie nodes sequentially if there are not too many + // trie nodes in the trie. + fn, ok := t.root.(*fullNode) + if !ok || len(keylist) < 16 { + for _, key := range keylist { + _, err := t.Get(key) + if err != nil { + return err + } + } + return nil + } + var ( + keys = make(map[byte][][]byte) + eg errgroup.Group + ) + for _, key := range keylist { + hkey := keybytesToHex(key) + keys[hkey[0]] = append(keys[hkey[0]], hkey) + } + for pos, ks := range keys { + eg.Go(func() error { + for _, k := range ks { + _, newnode, didResolve, err := t.get(fn.Children[pos], k, 1) + if err == nil && didResolve { + fn.Children[pos] = newnode + } + if err != nil { + return err + } + } + return nil + }) + } + return eg.Wait() +} + // MustGetNode is a wrapper of GetNode and will omit any encountered error but // just print out an error message. func (t *Trie) MustGetNode(path []byte) ([]byte, int) { @@ -239,7 +317,7 @@ func (t *Trie) getNode(origNode node, path []byte, pos int) (item []byte, newnod if hash == nil { return nil, origNode, 0, errors.New("non-consensus node") } - blob, err := t.reader.node(path, common.BytesToHash(hash)) + blob, err := t.reader.Node(path, common.BytesToHash(hash)) return blob, origNode, 1, err } // Path still needs to be traversed, descend into children @@ -361,7 +439,7 @@ func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error // New branch node is created as a child of the original short node. // Track the newly inserted node in the tracer. The node identifier // passed is the path from the root node. - t.tracer.onInsert(append(prefix, key[:matchlen]...)) + t.opTracer.onInsert(append(prefix, key[:matchlen]...)) // Replace it with a short node leading up to the branch. return true, &shortNode{key[:matchlen], branch, t.newFlag()}, nil @@ -379,7 +457,7 @@ func (t *Trie) insert(n node, prefix, key []byte, value node) (bool, node, error // New short node is created and track it in the tracer. The node identifier // passed is the path from the root node. Note the valueNode won't be tracked // since it's always embedded in its parent. - t.tracer.onInsert(prefix) + t.opTracer.onInsert(prefix) return true, &shortNode{key, value, t.newFlag()}, nil @@ -444,7 +522,7 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { // The matched short node is deleted entirely and track // it in the deletion set. The same the valueNode doesn't // need to be tracked at all since it's always embedded. - t.tracer.onDelete(prefix) + t.opTracer.onDelete(prefix) return true, nil, nil // remove n entirely for whole matches } @@ -460,7 +538,7 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { case *shortNode: // The child shortNode is merged into its parent, track // is deleted as well. - t.tracer.onDelete(append(prefix, n.Key...)) + t.opTracer.onDelete(append(prefix, n.Key...)) // Deleting from the subtrie reduced it to another // short node. Merge the nodes to avoid creating a @@ -468,7 +546,7 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { // always creates a new slice) instead of append to // avoid modifying n.Key since it might be shared with // other nodes. - return true, &shortNode{concat(n.Key, child.Key...), child.Val, t.newFlag()}, nil + return true, &shortNode{slices.Concat(n.Key, child.Key), child.Val, t.newFlag()}, nil default: return true, &shortNode{n.Key, child, t.newFlag()}, nil } @@ -525,7 +603,7 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { // Replace the entire full node with the short node. // Mark the original short node as deleted since the // value is embedded into the parent now. - t.tracer.onDelete(append(prefix, byte(pos))) + t.opTracer.onDelete(append(prefix, byte(pos))) k := append([]byte{byte(pos)}, cnode.Key...) return true, &shortNode{k, cnode.Val, t.newFlag()}, nil @@ -563,13 +641,6 @@ func (t *Trie) delete(n node, prefix, key []byte) (bool, node, error) { } } -func concat(s1 []byte, s2 ...byte) []byte { - r := make([]byte, len(s1)+len(s2)) - copy(r, s1) - copy(r[len(s1):], s2) - return r -} - // copyNode deep-copies the supplied node along with its children recursively. func copyNode(n node) node { switch n := (n).(type) { @@ -612,17 +683,35 @@ func (t *Trie) resolve(n node, prefix []byte) (node, error) { // node's original value. The rlp-encoded blob is preferred to be loaded from // database because it's easy to decode node while complex to encode node to blob. func (t *Trie) resolveAndTrack(n hashNode, prefix []byte) (node, error) { - blob, err := t.reader.node(prefix, common.BytesToHash(n)) + blob, err := t.reader.Node(prefix, common.BytesToHash(n)) if err != nil { return nil, err } - t.tracer.onRead(prefix, blob) + t.prevalueTracer.Put(prefix, blob) // The returned node blob won't be changed afterward. No need to // deep-copy the slice. return decodeNodeUnsafe(n, blob) } +// deletedNodes returns a list of node paths, referring the nodes being deleted +// from the trie. It's possible a few deleted nodes were embedded in their parent +// before, the deletions can be no effect by deleting nothing, filter them out. +func (t *Trie) deletedNodes() [][]byte { + var ( + pos int + list = t.opTracer.deletedList() + flags = t.prevalueTracer.HasList(list) + ) + for i := 0; i < len(list); i++ { + if flags[i] { + list[pos] = list[i] + pos++ + } + } + return list[:pos] // trim to the new length +} + // Hash returns the root hash of the trie. It does not write to the // database and can be used even if the trie doesn't have one. func (t *Trie) Hash() common.Hash { @@ -644,13 +733,13 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) { // (b) The trie was non-empty and all nodes are dropped => return // the node set includes all deleted nodes if t.root == nil { - paths := t.tracer.deletedNodes() + paths := t.deletedNodes() if len(paths) == 0 { return types.EmptyRootHash, nil // case (a) } nodes := trienode.NewNodeSet(t.owner) for _, path := range paths { - nodes.AddNode([]byte(path), trienode.NewDeleted()) + nodes.AddNode(path, trienode.NewDeletedWithPrev(t.prevalueTracer.Get(path))) } return types.EmptyRootHash, nodes // case (b) } @@ -667,11 +756,11 @@ func (t *Trie) Commit(collectLeaf bool) (common.Hash, *trienode.NodeSet) { return rootHash, nil } nodes := trienode.NewNodeSet(t.owner) - for _, path := range t.tracer.deletedNodes() { - nodes.AddNode([]byte(path), trienode.NewDeleted()) + for _, path := range t.deletedNodes() { + nodes.AddNode(path, trienode.NewDeletedWithPrev(t.prevalueTracer.Get(path))) } // If the number of changes is below 100, we let one thread handle it - t.root = newCommitter(nodes, t.tracer, collectLeaf).Commit(t.root, t.uncommitted > 100) + t.root = newCommitter(nodes, t.prevalueTracer, collectLeaf).Commit(t.root, t.uncommitted > 100) t.uncommitted = 0 return rootHash, nodes } @@ -691,23 +780,17 @@ func (t *Trie) hashRoot() []byte { } // Witness returns a set containing all trie nodes that have been accessed. -func (t *Trie) Witness() map[string]struct{} { - if len(t.tracer.accessList) == 0 { - return nil - } - witness := make(map[string]struct{}, len(t.tracer.accessList)) - for _, node := range t.tracer.accessList { - witness[string(node)] = struct{}{} - } - return witness +func (t *Trie) Witness() map[string][]byte { + return t.prevalueTracer.Values() } -// Reset drops the referenced root node and cleans all internal state. -func (t *Trie) Reset() { +// reset drops the referenced root node and cleans all internal state. +func (t *Trie) reset() { t.root = nil t.owner = common.Hash{} t.unhashed = 0 t.uncommitted = 0 - t.tracer.reset() + t.opTracer.reset() + t.prevalueTracer.Reset() t.committed = false } diff --git a/trie/trie_reader.go b/trie/trie_reader.go index a42cdb0cf9..42fe4d72c7 100644 --- a/trie/trie_reader.go +++ b/trie/trie_reader.go @@ -22,39 +22,39 @@ import ( "github.com/ethereum/go-ethereum/triedb/database" ) -// trieReader is a wrapper of the underlying node reader. It's not safe +// Reader is a wrapper of the underlying database reader. It's not safe // for concurrent usage. -type trieReader struct { +type Reader struct { owner common.Hash reader database.NodeReader banned map[string]struct{} // Marker to prevent node from being accessed, for tests } -// newTrieReader initializes the trie reader with the given node reader. -func newTrieReader(stateRoot, owner common.Hash, db database.NodeDatabase) (*trieReader, error) { +// NewReader initializes the trie reader with the given database reader. +func NewReader(stateRoot, owner common.Hash, db database.NodeDatabase) (*Reader, error) { if stateRoot == (common.Hash{}) || stateRoot == types.EmptyRootHash { - return &trieReader{owner: owner}, nil + return &Reader{owner: owner}, nil } reader, err := db.NodeReader(stateRoot) if err != nil { return nil, &MissingNodeError{Owner: owner, NodeHash: stateRoot, err: err} } - return &trieReader{owner: owner, reader: reader}, nil + return &Reader{owner: owner, reader: reader}, nil } // newEmptyReader initializes the pure in-memory reader. All read operations // should be forbidden and returns the MissingNodeError. -func newEmptyReader() *trieReader { - return &trieReader{} +func newEmptyReader() *Reader { + return &Reader{} } -// node retrieves the rlp-encoded trie node with the provided trie node +// Node retrieves the rlp-encoded trie node with the provided trie node // information. An MissingNodeError will be returned in case the node is // not found or any error is encountered. // // Don't modify the returned byte slice since it's not deep-copied and // still be referenced by database. -func (r *trieReader) node(path []byte, hash common.Hash) ([]byte, error) { +func (r *Reader) Node(path []byte, hash common.Hash) ([]byte, error) { // Perform the logics in tests for preventing trie node access. if r.banned != nil { if _, ok := r.banned[string(path)]; ok { diff --git a/trie/trie_test.go b/trie/trie_test.go index edd85677fe..b8b8edb33e 100644 --- a/trie/trie_test.go +++ b/trie/trie_test.go @@ -326,7 +326,7 @@ func TestReplication(t *testing.T) { updateString(trie2, val.k, val.v) } if trie2.Hash() != hash { - t.Errorf("root failure. expected %x got %x", hash, hash) + t.Errorf("root failure. expected %x got %x", hash, trie2.Hash()) } } @@ -449,35 +449,35 @@ func verifyAccessList(old *Trie, new *Trie, set *trienode.NodeSet) error { if !ok || n.IsDeleted() { return errors.New("expect new node") } - //if len(n.Prev) > 0 { - // return errors.New("unexpected origin value") - //} + if len(set.Origins[path]) > 0 { + return errors.New("unexpected origin value") + } } // Check deletion set - for path := range deletes { + for path, blob := range deletes { n, ok := set.Nodes[path] if !ok || !n.IsDeleted() { return errors.New("expect deleted node") } - //if len(n.Prev) == 0 { - // return errors.New("expect origin value") - //} - //if !bytes.Equal(n.Prev, blob) { - // return errors.New("invalid origin value") - //} + if len(set.Origins[path]) == 0 { + return errors.New("expect origin value") + } + if !bytes.Equal(set.Origins[path], blob) { + return errors.New("invalid origin value") + } } // Check update set - for path := range updates { + for path, blob := range updates { n, ok := set.Nodes[path] if !ok || n.IsDeleted() { return errors.New("expect updated node") } - //if len(n.Prev) == 0 { - // return errors.New("expect origin value") - //} - //if !bytes.Equal(n.Prev, blob) { - // return errors.New("invalid origin value") - //} + if len(set.Origins[path]) == 0 { + return errors.New("expect origin value") + } + if !bytes.Equal(set.Origins[path], blob) { + return errors.New("invalid origin value") + } } return nil } @@ -595,18 +595,18 @@ func runRandTest(rt randTest) error { deleteExp[path] = struct{}{} } } - if len(insertExp) != len(tr.tracer.inserts) { + if len(insertExp) != len(tr.opTracer.inserts) { rt[i].err = errors.New("insert set mismatch") } - if len(deleteExp) != len(tr.tracer.deletes) { + if len(deleteExp) != len(tr.opTracer.deletes) { rt[i].err = errors.New("delete set mismatch") } - for insert := range tr.tracer.inserts { + for insert := range tr.opTracer.inserts { if _, present := insertExp[insert]; !present { rt[i].err = errors.New("missing inserted node") } } - for del := range tr.tracer.deletes { + for del := range tr.opTracer.deletes { if _, present := deleteExp[del]; !present { rt[i].err = errors.New("missing deleted node") } @@ -1499,3 +1499,83 @@ func testTrieCopyNewTrie(t *testing.T, entries []kv) { t.Errorf("Hash mismatch: old %v, new %v", hash, tr.Hash()) } } + +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/trie +// cpu: Apple M1 Pro +// BenchmarkTriePrefetch +// BenchmarkTriePrefetch-8 9961 100706 ns/op +func BenchmarkTriePrefetch(b *testing.B) { + db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) + tr := NewEmpty(db) + vals := make(map[string]*kv) + for i := 0; i < 3000; i++ { + value := &kv{ + k: randBytes(32), + v: randBytes(20), + t: false, + } + tr.MustUpdate(value.k, value.v) + vals[string(value.k)] = value + } + root, nodes := tr.Commit(false) + db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) + b.ResetTimer() + + for i := 0; i < b.N; i++ { + tr, err := New(TrieID(root), db) + if err != nil { + b.Fatalf("Failed to open the trie") + } + var keys [][]byte + for k := range vals { + keys = append(keys, []byte(k)) + if len(keys) > 64 { + break + } + } + tr.Prefetch(keys) + } +} + +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/trie +// cpu: Apple M1 Pro +// BenchmarkTrieSeqPrefetch +// BenchmarkTrieSeqPrefetch-8 12879 96710 ns/op +func BenchmarkTrieSeqPrefetch(b *testing.B) { + db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.HashScheme) + tr := NewEmpty(db) + vals := make(map[string]*kv) + for i := 0; i < 3000; i++ { + value := &kv{ + k: randBytes(32), + v: randBytes(20), + t: false, + } + tr.MustUpdate(value.k, value.v) + vals[string(value.k)] = value + } + root, nodes := tr.Commit(false) + db.Update(root, types.EmptyRootHash, trienode.NewWithNodeSet(nodes)) + b.ResetTimer() + + for i := 0; i < b.N; i++ { + tr, err := New(TrieID(root), db) + if err != nil { + b.Fatalf("Failed to open the trie") + } + var keys [][]byte + for k := range vals { + keys = append(keys, []byte(k)) + if len(keys) > 64 { + break + } + } + for _, k := range keys { + tr.Get(k) + } + } +} diff --git a/trie/trienode/node.go b/trie/trienode/node.go index b09ec66374..228a64f04c 100644 --- a/trie/trienode/node.go +++ b/trie/trienode/node.go @@ -51,6 +51,35 @@ func New(hash common.Hash, blob []byte) *Node { // NewDeleted constructs a node which is deleted. func NewDeleted() *Node { return New(common.Hash{}, nil) } +// NodeWithPrev is a wrapper over Node by tracking the original value of node. +type NodeWithPrev struct { + *Node + Prev []byte // Nil means the node was not existent +} + +// NewNodeWithPrev constructs a node with the additional original value. +func NewNodeWithPrev(hash common.Hash, blob []byte, prev []byte) *NodeWithPrev { + return &NodeWithPrev{ + Node: &Node{ + Hash: hash, + Blob: blob, + }, + Prev: prev, + } +} + +// NewDeletedWithPrev constructs a node which is deleted with the additional +// original value. +func NewDeletedWithPrev(prev []byte) *NodeWithPrev { + return &NodeWithPrev{ + Node: &Node{ + Hash: common.Hash{}, + Blob: nil, + }, + Prev: prev, + } +} + // leaf represents a trie leaf node type leaf struct { Blob []byte // raw blob of leaf @@ -63,6 +92,8 @@ type NodeSet struct { Owner common.Hash Leaves []*leaf Nodes map[string]*Node + Origins map[string][]byte + updates int // the count of updated and inserted nodes deletes int // the count of deleted nodes } @@ -71,8 +102,9 @@ type NodeSet struct { // the owning account address hash for storage tries. func NewNodeSet(owner common.Hash) *NodeSet { return &NodeSet{ - Owner: owner, - Nodes: make(map[string]*Node), + Owner: owner, + Nodes: make(map[string]*Node), + Origins: make(map[string][]byte), } } @@ -91,22 +123,25 @@ func (set *NodeSet) ForEachWithOrder(callback func(path string, n *Node)) { } // AddNode adds the provided node into set. -func (set *NodeSet) AddNode(path []byte, n *Node) { +func (set *NodeSet) AddNode(path []byte, n *NodeWithPrev) { if n.IsDeleted() { set.deletes += 1 } else { set.updates += 1 } - set.Nodes[string(path)] = n + key := string(path) + set.Nodes[key] = n.Node + set.Origins[key] = n.Prev } -// MergeSet merges this 'set' with 'other'. It assumes that the sets are disjoint, +// MergeDisjoint merges this 'set' with 'other'. It assumes that the sets are disjoint, // and thus does not deduplicate data (count deletes, dedup leaves etc). -func (set *NodeSet) MergeSet(other *NodeSet) error { +func (set *NodeSet) MergeDisjoint(other *NodeSet) error { if set.Owner != other.Owner { return fmt.Errorf("nodesets belong to different owner are not mergeable %x-%x", set.Owner, other.Owner) } maps.Copy(set.Nodes, other.Nodes) + maps.Copy(set.Origins, other.Origins) set.deletes += other.deletes set.updates += other.updates @@ -117,12 +152,13 @@ func (set *NodeSet) MergeSet(other *NodeSet) error { return nil } -// Merge adds a set of nodes into the set. -func (set *NodeSet) Merge(owner common.Hash, nodes map[string]*Node) error { - if set.Owner != owner { - return fmt.Errorf("nodesets belong to different owner are not mergeable %x-%x", set.Owner, owner) +// Merge adds a set of nodes to the current set. It assumes the sets may overlap, +// so deduplication is performed. +func (set *NodeSet) Merge(other *NodeSet) error { + if set.Owner != other.Owner { + return fmt.Errorf("nodesets belong to different owner are not mergeable %x-%x", set.Owner, other.Owner) } - for path, node := range nodes { + for path, node := range other.Nodes { prev, ok := set.Nodes[path] if ok { // overwrite happens, revoke the counter @@ -137,8 +173,17 @@ func (set *NodeSet) Merge(owner common.Hash, nodes map[string]*Node) error { } else { set.updates += 1 } - set.Nodes[path] = node + set.Nodes[path] = node // overwrite the node with new value + + // Add the original value only if it was previously non-existent. + // If multiple mutations are made to the same node, the first one + // is considered the true original value. + if _, exist := set.Origins[path]; !exist { + set.Origins[path] = other.Origins[path] + } } + // TODO leaves are not aggregated, as they are not used in storage tries. + // TODO(rjl493456442) deprecate the leaves along with the legacy hash mode. return nil } @@ -169,11 +214,16 @@ func (set *NodeSet) Summary() string { for path, n := range set.Nodes { // Deletion if n.IsDeleted() { - fmt.Fprintf(out, " [-]: %x\n", path) + fmt.Fprintf(out, " [-]: %x prev: %x\n", path, set.Origins[path]) continue } - // Insertion or update - fmt.Fprintf(out, " [+/*]: %x -> %v \n", path, n.Hash) + // Insertion + if len(set.Origins[path]) == 0 { + fmt.Fprintf(out, " [+]: %x -> %v\n", path, n.Hash) + continue + } + // Update + fmt.Fprintf(out, " [*]: %x -> %v prev: %x\n", path, n.Hash, set.Origins[path]) } for _, n := range set.Leaves { fmt.Fprintf(out, "[leaf]: %v\n", n) @@ -203,17 +253,30 @@ func NewWithNodeSet(set *NodeSet) *MergedNodeSet { func (set *MergedNodeSet) Merge(other *NodeSet) error { subset, present := set.Sets[other.Owner] if present { - return subset.Merge(other.Owner, other.Nodes) + return subset.Merge(other) } set.Sets[other.Owner] = other return nil } -// Flatten returns a two-dimensional map for internal nodes. -func (set *MergedNodeSet) Flatten() map[common.Hash]map[string]*Node { +// Nodes returns a two-dimensional map for internal nodes. +func (set *MergedNodeSet) Nodes() map[common.Hash]map[string]*Node { nodes := make(map[common.Hash]map[string]*Node, len(set.Sets)) for owner, set := range set.Sets { nodes[owner] = set.Nodes } return nodes } + +// NodeAndOrigins returns a two-dimensional map for internal nodes along with +// their original values. +func (set *MergedNodeSet) NodeAndOrigins() (map[common.Hash]map[string]*Node, map[common.Hash]map[string][]byte) { + var ( + nodes = make(map[common.Hash]map[string]*Node, len(set.Sets)) + origins = make(map[common.Hash]map[string][]byte, len(set.Sets)) + ) + for owner, set := range set.Sets { + nodes[owner], origins[owner] = set.Nodes, set.Origins + } + return nodes, origins +} diff --git a/trie/trienode/node_test.go b/trie/trienode/node_test.go index bcb3a2202b..332b6f1776 100644 --- a/trie/trienode/node_test.go +++ b/trie/trienode/node_test.go @@ -17,13 +17,100 @@ package trienode import ( + "bytes" "crypto/rand" + "maps" + "reflect" + "slices" "testing" + "github.com/davecgh/go-spew/spew" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testrand" ) +func makeTestSet(owner common.Hash, n int, paths [][]byte) *NodeSet { + set := NewNodeSet(owner) + for i := 0; i < n*3/4; i++ { + path := testrand.Bytes(10) + blob := testrand.Bytes(100) + set.AddNode(path, NewNodeWithPrev(crypto.Keccak256Hash(blob), blob, testrand.Bytes(100))) + } + for i := 0; i < n/4; i++ { + path := testrand.Bytes(10) + set.AddNode(path, NewDeletedWithPrev(testrand.Bytes(100))) + } + for i := 0; i < len(paths); i++ { + if i%3 == 0 { + set.AddNode(paths[i], NewDeletedWithPrev(testrand.Bytes(100))) + } else { + blob := testrand.Bytes(100) + set.AddNode(paths[i], NewNodeWithPrev(crypto.Keccak256Hash(blob), blob, testrand.Bytes(100))) + } + } + return set +} + +func copyNodeSet(set *NodeSet) *NodeSet { + cpy := &NodeSet{ + Owner: set.Owner, + Leaves: slices.Clone(set.Leaves), + updates: set.updates, + deletes: set.deletes, + Nodes: maps.Clone(set.Nodes), + Origins: maps.Clone(set.Origins), + } + return cpy +} + +func TestNodeSetMerge(t *testing.T) { + var shared [][]byte + for i := 0; i < 2; i++ { + shared = append(shared, testrand.Bytes(10)) + } + owner := testrand.Hash() + setA := makeTestSet(owner, 20, shared) + cpyA := copyNodeSet(setA) + + setB := makeTestSet(owner, 20, shared) + setA.Merge(setB) + + for path, node := range setA.Nodes { + nA, inA := cpyA.Nodes[path] + nB, inB := setB.Nodes[path] + + switch { + case inA && inB: + origin := setA.Origins[path] + if !bytes.Equal(origin, cpyA.Origins[path]) { + t.Errorf("Unexpected origin, path %v: want: %v, got: %v", []byte(path), cpyA.Origins[path], origin) + } + if !reflect.DeepEqual(node, nB) { + t.Errorf("Unexpected node, path %v: want: %v, got: %v", []byte(path), spew.Sdump(nB), spew.Sdump(node)) + } + case !inA && inB: + origin := setA.Origins[path] + if !bytes.Equal(origin, setB.Origins[path]) { + t.Errorf("Unexpected origin, path %v: want: %v, got: %v", []byte(path), setB.Origins[path], origin) + } + if !reflect.DeepEqual(node, nB) { + t.Errorf("Unexpected node, path %v: want: %v, got: %v", []byte(path), spew.Sdump(nB), spew.Sdump(node)) + } + case inA && !inB: + origin := setA.Origins[path] + if !bytes.Equal(origin, cpyA.Origins[path]) { + t.Errorf("Unexpected origin, path %v: want: %v, got: %v", []byte(path), cpyA.Origins[path], origin) + } + if !reflect.DeepEqual(node, nA) { + t.Errorf("Unexpected node, path %v: want: %v, got: %v", []byte(path), spew.Sdump(nA), spew.Sdump(node)) + } + default: + t.Errorf("Unexpected node, %v", []byte(path)) + } + } +} + func BenchmarkMerge(b *testing.B) { b.Run("1K", func(b *testing.B) { benchmarkMerge(b, 1000) @@ -42,7 +129,7 @@ func benchmarkMerge(b *testing.B, count int) { blob := make([]byte, 32) rand.Read(blob) hash := crypto.Keccak256Hash(blob) - s.AddNode(path, New(hash, blob)) + s.AddNode(path, NewNodeWithPrev(hash, blob, nil)) } for i := 0; i < count; i++ { // Random path of 4 nibbles @@ -53,9 +140,9 @@ func benchmarkMerge(b *testing.B, count int) { for i := 0; i < b.N; i++ { // Store set x into a backup z := NewNodeSet(common.Hash{}) - z.Merge(common.Hash{}, x.Nodes) + z.Merge(x) // Merge y into x - x.Merge(common.Hash{}, y.Nodes) + x.Merge(y) x = z } } diff --git a/trie/utils/verkle.go b/trie/utils/verkle.go deleted file mode 100644 index dea210c046..0000000000 --- a/trie/utils/verkle.go +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package utils - -import ( - "encoding/binary" - "sync" - - "github.com/crate-crypto/go-ipa/bandersnatch/fr" - "github.com/ethereum/go-ethereum/common/lru" - "github.com/ethereum/go-ethereum/metrics" - "github.com/ethereum/go-verkle" - "github.com/holiman/uint256" -) - -const ( - BasicDataLeafKey = 0 - CodeHashLeafKey = 1 - - BasicDataVersionOffset = 0 - BasicDataCodeSizeOffset = 5 - BasicDataNonceOffset = 8 - BasicDataBalanceOffset = 16 -) - -var ( - zero = uint256.NewInt(0) - verkleNodeWidthLog2 = 8 - headerStorageOffset = uint256.NewInt(64) - codeOffset = uint256.NewInt(128) - verkleNodeWidth = uint256.NewInt(256) - codeStorageDelta = uint256.NewInt(0).Sub(codeOffset, headerStorageOffset) - mainStorageOffsetLshVerkleNodeWidth = new(uint256.Int).Lsh(uint256.NewInt(1), 248-uint(verkleNodeWidthLog2)) - - index0Point *verkle.Point // pre-computed commitment of polynomial [2+256*64] - - // cacheHitGauge is the metric to track how many cache hit occurred. - cacheHitGauge = metrics.NewRegisteredGauge("trie/verkle/cache/hit", nil) - - // cacheMissGauge is the metric to track how many cache miss occurred. - cacheMissGauge = metrics.NewRegisteredGauge("trie/verkle/cache/miss", nil) -) - -func init() { - // The byte array is the Marshalled output of the point computed as such: - // - // var ( - // config = verkle.GetConfig() - // fr verkle.Fr - // ) - // verkle.FromLEBytes(&fr, []byte{2, 64}) - // point := config.CommitToPoly([]verkle.Fr{fr}, 1) - index0Point = new(verkle.Point) - err := index0Point.SetBytes([]byte{34, 25, 109, 242, 193, 5, 144, 224, 76, 52, 189, 92, 197, 126, 9, 145, 27, 152, 199, 130, 165, 3, 210, 27, 193, 131, 142, 28, 110, 26, 16, 191}) - if err != nil { - panic(err) - } -} - -// PointCache is the LRU cache for storing evaluated address commitment. -type PointCache struct { - lru lru.BasicLRU[string, *verkle.Point] - lock sync.RWMutex -} - -// NewPointCache returns the cache with specified size. -func NewPointCache(maxItems int) *PointCache { - return &PointCache{ - lru: lru.NewBasicLRU[string, *verkle.Point](maxItems), - } -} - -// Get returns the cached commitment for the specified address, or computing -// it on the flight. -func (c *PointCache) Get(addr []byte) *verkle.Point { - c.lock.Lock() - defer c.lock.Unlock() - - p, ok := c.lru.Get(string(addr)) - if ok { - cacheHitGauge.Inc(1) - return p - } - cacheMissGauge.Inc(1) - p = evaluateAddressPoint(addr) - c.lru.Add(string(addr), p) - return p -} - -// GetStem returns the first 31 bytes of the tree key as the tree stem. It only -// works for the account metadata whose treeIndex is 0. -func (c *PointCache) GetStem(addr []byte) []byte { - p := c.Get(addr) - return pointToHash(p, 0)[:31] -} - -// GetTreeKey performs both the work of the spec's get_tree_key function, and that -// of pedersen_hash: it builds the polynomial in pedersen_hash without having to -// create a mostly zero-filled buffer and "type cast" it to a 128-long 16-byte -// array. Since at most the first 5 coefficients of the polynomial will be non-zero, -// these 5 coefficients are created directly. -func GetTreeKey(address []byte, treeIndex *uint256.Int, subIndex byte) []byte { - if len(address) < 32 { - var aligned [32]byte - address = append(aligned[:32-len(address)], address...) - } - // poly = [2+256*64, address_le_low, address_le_high, tree_index_le_low, tree_index_le_high] - var poly [5]fr.Element - - // 32-byte address, interpreted as two little endian - // 16-byte numbers. - verkle.FromLEBytes(&poly[1], address[:16]) - verkle.FromLEBytes(&poly[2], address[16:]) - - // treeIndex must be interpreted as a 32-byte aligned little-endian integer. - // e.g: if treeIndex is 0xAABBCC, we need the byte representation to be 0xCCBBAA00...00. - // poly[3] = LE({CC,BB,AA,00...0}) (16 bytes), poly[4]=LE({00,00,...}) (16 bytes). - // - // To avoid unnecessary endianness conversions for go-ipa, we do some trick: - // - poly[3]'s byte representation is the same as the *top* 16 bytes (trieIndexBytes[16:]) of - // 32-byte aligned big-endian representation (BE({00,...,AA,BB,CC})). - // - poly[4]'s byte representation is the same as the *low* 16 bytes (trieIndexBytes[:16]) of - // the 32-byte aligned big-endian representation (BE({00,00,...}). - trieIndexBytes := treeIndex.Bytes32() - verkle.FromBytes(&poly[3], trieIndexBytes[16:]) - verkle.FromBytes(&poly[4], trieIndexBytes[:16]) - - cfg := verkle.GetConfig() - ret := cfg.CommitToPoly(poly[:], 0) - - // add a constant point corresponding to poly[0]=[2+256*64]. - ret.Add(ret, index0Point) - - return pointToHash(ret, subIndex) -} - -// GetTreeKeyWithEvaluatedAddress is basically identical to GetTreeKey, the only -// difference is a part of polynomial is already evaluated. -// -// Specifically, poly = [2+256*64, address_le_low, address_le_high] is already -// evaluated. -func GetTreeKeyWithEvaluatedAddress(evaluated *verkle.Point, treeIndex *uint256.Int, subIndex byte) []byte { - var poly [5]fr.Element - - // little-endian, 32-byte aligned treeIndex - var index [32]byte - for i := 0; i < len(treeIndex); i++ { - binary.LittleEndian.PutUint64(index[i*8:(i+1)*8], treeIndex[i]) - } - verkle.FromLEBytes(&poly[3], index[:16]) - verkle.FromLEBytes(&poly[4], index[16:]) - - cfg := verkle.GetConfig() - ret := cfg.CommitToPoly(poly[:], 0) - - // add the pre-evaluated address - ret.Add(ret, evaluated) - - return pointToHash(ret, subIndex) -} - -// BasicDataKey returns the verkle tree key of the basic data field for -// the specified account. -func BasicDataKey(address []byte) []byte { - return GetTreeKey(address, zero, BasicDataLeafKey) -} - -// CodeHashKey returns the verkle tree key of the code hash field for -// the specified account. -func CodeHashKey(address []byte) []byte { - return GetTreeKey(address, zero, CodeHashLeafKey) -} - -func codeChunkIndex(chunk *uint256.Int) (*uint256.Int, byte) { - var ( - chunkOffset = new(uint256.Int).Add(codeOffset, chunk) - treeIndex, subIndexMod = new(uint256.Int).DivMod(chunkOffset, verkleNodeWidth, new(uint256.Int)) - ) - return treeIndex, byte(subIndexMod.Uint64()) -} - -// CodeChunkKey returns the verkle tree key of the code chunk for the -// specified account. -func CodeChunkKey(address []byte, chunk *uint256.Int) []byte { - treeIndex, subIndex := codeChunkIndex(chunk) - return GetTreeKey(address, treeIndex, subIndex) -} - -func StorageIndex(storageKey []byte) (*uint256.Int, byte) { - // If the storage slot is in the header, we need to add the header offset. - var key uint256.Int - key.SetBytes(storageKey) - if key.Cmp(codeStorageDelta) < 0 { - // This addition is always safe; it can't ever overflow since pos. - -package utils - -import ( - "bytes" - "testing" - - "github.com/ethereum/go-verkle" - "github.com/holiman/uint256" -) - -func TestTreeKey(t *testing.T) { - var ( - address = []byte{0x01} - addressEval = evaluateAddressPoint(address) - smallIndex = uint256.NewInt(1) - largeIndex = uint256.NewInt(10000) - smallStorage = []byte{0x1} - largeStorage = bytes.Repeat([]byte{0xff}, 16) - ) - if !bytes.Equal(BasicDataKey(address), BasicDataKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched basic data key") - } - if !bytes.Equal(CodeHashKey(address), CodeHashKeyWithEvaluatedAddress(addressEval)) { - t.Fatal("Unmatched code hash key") - } - if !bytes.Equal(CodeChunkKey(address, smallIndex), CodeChunkKeyWithEvaluatedAddress(addressEval, smallIndex)) { - t.Fatal("Unmatched code chunk key") - } - if !bytes.Equal(CodeChunkKey(address, largeIndex), CodeChunkKeyWithEvaluatedAddress(addressEval, largeIndex)) { - t.Fatal("Unmatched code chunk key") - } - if !bytes.Equal(StorageSlotKey(address, smallStorage), StorageSlotKeyWithEvaluatedAddress(addressEval, smallStorage)) { - t.Fatal("Unmatched storage slot key") - } - if !bytes.Equal(StorageSlotKey(address, largeStorage), StorageSlotKeyWithEvaluatedAddress(addressEval, largeStorage)) { - t.Fatal("Unmatched storage slot key") - } -} - -// goos: darwin -// goarch: amd64 -// pkg: github.com/ethereum/go-ethereum/trie/utils -// cpu: VirtualApple @ 2.50GHz -// BenchmarkTreeKey -// BenchmarkTreeKey-8 398731 2961 ns/op 32 B/op 1 allocs/op -func BenchmarkTreeKey(b *testing.B) { - // Initialize the IPA settings which can be pretty expensive. - verkle.GetConfig() - - b.ReportAllocs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - BasicDataKey([]byte{0x01}) - } -} - -// goos: darwin -// goarch: amd64 -// pkg: github.com/ethereum/go-ethereum/trie/utils -// cpu: VirtualApple @ 2.50GHz -// BenchmarkTreeKeyWithEvaluation -// BenchmarkTreeKeyWithEvaluation-8 513855 2324 ns/op 32 B/op 1 allocs/op -func BenchmarkTreeKeyWithEvaluation(b *testing.B) { - // Initialize the IPA settings which can be pretty expensive. - verkle.GetConfig() - - addr := []byte{0x01} - eval := evaluateAddressPoint(addr) - - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - BasicDataKeyWithEvaluatedAddress(eval) - } -} - -// goos: darwin -// goarch: amd64 -// pkg: github.com/ethereum/go-ethereum/trie/utils -// cpu: VirtualApple @ 2.50GHz -// BenchmarkStorageKey -// BenchmarkStorageKey-8 230516 4584 ns/op 96 B/op 3 allocs/op -func BenchmarkStorageKey(b *testing.B) { - // Initialize the IPA settings which can be pretty expensive. - verkle.GetConfig() - - b.ReportAllocs() - b.ResetTimer() - - for i := 0; i < b.N; i++ { - StorageSlotKey([]byte{0x01}, bytes.Repeat([]byte{0xff}, 32)) - } -} - -// goos: darwin -// goarch: amd64 -// pkg: github.com/ethereum/go-ethereum/trie/utils -// cpu: VirtualApple @ 2.50GHz -// BenchmarkStorageKeyWithEvaluation -// BenchmarkStorageKeyWithEvaluation-8 320125 3753 ns/op 96 B/op 3 allocs/op -func BenchmarkStorageKeyWithEvaluation(b *testing.B) { - // Initialize the IPA settings which can be pretty expensive. - verkle.GetConfig() - - addr := []byte{0x01} - eval := evaluateAddressPoint(addr) - - b.ReportAllocs() - b.ResetTimer() - for i := 0; i < b.N; i++ { - StorageSlotKeyWithEvaluatedAddress(eval, bytes.Repeat([]byte{0xff}, 32)) - } -} diff --git a/trie/verkle.go b/trie/verkle.go deleted file mode 100644 index 015b8f6590..0000000000 --- a/trie/verkle.go +++ /dev/null @@ -1,430 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "encoding/binary" - "errors" - "fmt" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethdb" - "github.com/ethereum/go-ethereum/trie/trienode" - "github.com/ethereum/go-ethereum/trie/utils" - "github.com/ethereum/go-ethereum/triedb/database" - "github.com/ethereum/go-verkle" - "github.com/holiman/uint256" -) - -var ( - errInvalidRootType = errors.New("invalid node type for root") -) - -// VerkleTrie is a wrapper around VerkleNode that implements the trie.Trie -// interface so that Verkle trees can be reused verbatim. -type VerkleTrie struct { - root verkle.VerkleNode - cache *utils.PointCache - reader *trieReader -} - -// NewVerkleTrie constructs a verkle tree based on the specified root hash. -func NewVerkleTrie(root common.Hash, db database.NodeDatabase, cache *utils.PointCache) (*VerkleTrie, error) { - reader, err := newTrieReader(root, common.Hash{}, db) - if err != nil { - return nil, err - } - // Parse the root verkle node if it's not empty. - node := verkle.New() - if root != types.EmptyVerkleHash && root != types.EmptyRootHash { - blob, err := reader.node(nil, common.Hash{}) - if err != nil { - return nil, err - } - node, err = verkle.ParseNode(blob, 0) - if err != nil { - return nil, err - } - } - return &VerkleTrie{ - root: node, - cache: cache, - reader: reader, - }, nil -} - -func (t *VerkleTrie) FlatdbNodeResolver(path []byte) ([]byte, error) { - return t.reader.node(path, common.Hash{}) -} - -// GetKey returns the sha3 preimage of a hashed key that was previously used -// to store a value. -func (t *VerkleTrie) GetKey(key []byte) []byte { - return key -} - -// GetAccount implements state.Trie, retrieving the account with the specified -// account address. If the specified account is not in the verkle tree, nil will -// be returned. If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) GetAccount(addr common.Address) (*types.StateAccount, error) { - var ( - acc = &types.StateAccount{} - values [][]byte - err error - ) - switch n := t.root.(type) { - case *verkle.InternalNode: - values, err = n.GetValuesAtStem(t.cache.GetStem(addr[:]), t.nodeResolver) - if err != nil { - return nil, fmt.Errorf("GetAccount (%x) error: %v", addr, err) - } - default: - return nil, errInvalidRootType - } - if values == nil { - return nil, nil - } - basicData := values[utils.BasicDataLeafKey] - acc.Nonce = binary.BigEndian.Uint64(basicData[utils.BasicDataNonceOffset:]) - acc.Balance = new(uint256.Int).SetBytes(basicData[utils.BasicDataBalanceOffset : utils.BasicDataBalanceOffset+16]) - acc.CodeHash = values[utils.CodeHashLeafKey] - - // TODO account.Root is leave as empty. How should we handle the legacy account? - return acc, nil -} - -// GetStorage implements state.Trie, retrieving the storage slot with the specified -// account address and storage key. If the specified slot is not in the verkle tree, -// nil will be returned. If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) GetStorage(addr common.Address, key []byte) ([]byte, error) { - k := utils.StorageSlotKeyWithEvaluatedAddress(t.cache.Get(addr.Bytes()), key) - val, err := t.root.Get(k, t.nodeResolver) - if err != nil { - return nil, err - } - return common.TrimLeftZeroes(val), nil -} - -// UpdateAccount implements state.Trie, writing the provided account into the tree. -// If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) UpdateAccount(addr common.Address, acc *types.StateAccount, codeLen int) error { - var ( - err error - basicData [32]byte - values = make([][]byte, verkle.NodeWidth) - stem = t.cache.GetStem(addr[:]) - ) - - // Code size is encoded in BasicData as a 3-byte big-endian integer. Spare bytes are present - // before the code size to support bigger integers in the future. PutUint32(...) requires - // 4 bytes, so we need to shift the offset 1 byte to the left. - binary.BigEndian.PutUint32(basicData[utils.BasicDataCodeSizeOffset-1:], uint32(codeLen)) - binary.BigEndian.PutUint64(basicData[utils.BasicDataNonceOffset:], acc.Nonce) - if acc.Balance.ByteLen() > 16 { - panic("balance too large") - } - acc.Balance.WriteToSlice(basicData[utils.BasicDataBalanceOffset : utils.BasicDataBalanceOffset+16]) - values[utils.BasicDataLeafKey] = basicData[:] - values[utils.CodeHashLeafKey] = acc.CodeHash[:] - - switch root := t.root.(type) { - case *verkle.InternalNode: - err = root.InsertValuesAtStem(stem, values, t.nodeResolver) - default: - return errInvalidRootType - } - if err != nil { - return fmt.Errorf("UpdateAccount (%x) error: %v", addr, err) - } - - return nil -} - -// UpdateStorage implements state.Trie, writing the provided storage slot into -// the tree. If the tree is corrupted, an error will be returned. -func (t *VerkleTrie) UpdateStorage(address common.Address, key, value []byte) error { - // Left padding the slot value to 32 bytes. - var v [32]byte - if len(value) >= 32 { - copy(v[:], value[:32]) - } else { - copy(v[32-len(value):], value[:]) - } - k := utils.StorageSlotKeyWithEvaluatedAddress(t.cache.Get(address.Bytes()), key) - return t.root.Insert(k, v[:], t.nodeResolver) -} - -// DeleteAccount leaves the account untouched, as no account deletion can happen -// in verkle. -// There is a special corner case, in which an account that is prefunded, CREATE2-d -// and then SELFDESTRUCT-d should see its funds drained. EIP161 says that account -// should be removed, but this is verboten by the verkle spec. This contains a -// workaround in which the method checks for this corner case, and if so, overwrites -// the balance with 0. This will be removed once the spec has been clarified. -func (t *VerkleTrie) DeleteAccount(addr common.Address) error { - k := utils.BasicDataKeyWithEvaluatedAddress(t.cache.Get(addr.Bytes())) - values, err := t.root.(*verkle.InternalNode).GetValuesAtStem(k, t.nodeResolver) - if err != nil { - return fmt.Errorf("Error getting data at %x in delete: %w", k, err) - } - var prefunded bool - for i, v := range values { - switch i { - case 0: - prefunded = len(v) == 32 - case 1: - prefunded = len(v) == 32 && bytes.Equal(v, types.EmptyCodeHash[:]) - default: - prefunded = v == nil - } - if !prefunded { - break - } - } - if prefunded { - t.root.Insert(k, common.Hash{}.Bytes(), t.nodeResolver) - } - return nil -} - -// RollBackAccount removes the account info + code from the tree, unlike DeleteAccount -// that will overwrite it with 0s. The first 64 storage slots are also removed. -func (t *VerkleTrie) RollBackAccount(addr common.Address) error { - var ( - evaluatedAddr = t.cache.Get(addr.Bytes()) - basicDataKey = utils.BasicDataKeyWithEvaluatedAddress(evaluatedAddr) - ) - basicDataBytes, err := t.root.Get(basicDataKey, t.nodeResolver) - if err != nil { - return fmt.Errorf("rollback: error finding code size: %w", err) - } - if len(basicDataBytes) == 0 { - return errors.New("rollback: basic data is not existent") - } - // The code size is encoded in BasicData as a 3-byte big-endian integer. Spare bytes are present - // before the code size to support bigger integers in the future. - // LittleEndian.Uint32(...) expects 4-bytes, so we need to shift the offset 1-byte to the left. - codeSize := binary.BigEndian.Uint32(basicDataBytes[utils.BasicDataCodeSizeOffset-1:]) - - // Delete the account header + first 64 slots + first 128 code chunks - _, err = t.root.(*verkle.InternalNode).DeleteAtStem(basicDataKey[:31], t.nodeResolver) - if err != nil { - return fmt.Errorf("error rolling back account header: %w", err) - } - - // Delete all further code - for i, chunknr := uint64(31*128), uint64(128); i < uint64(codeSize); i, chunknr = i+31*256, chunknr+256 { - // evaluate group key at the start of a new group - offset := uint256.NewInt(chunknr) - key := utils.CodeChunkKeyWithEvaluatedAddress(evaluatedAddr, offset) - - if _, err = t.root.(*verkle.InternalNode).DeleteAtStem(key[:], t.nodeResolver); err != nil { - return fmt.Errorf("error deleting code chunk stem (addr=%x, offset=%d) error: %w", addr[:], offset, err) - } - } - return nil -} - -// DeleteStorage implements state.Trie, deleting the specified storage slot from -// the trie. If the storage slot was not existent in the trie, no error will be -// returned. If the trie is corrupted, an error will be returned. -func (t *VerkleTrie) DeleteStorage(addr common.Address, key []byte) error { - var zero [32]byte - k := utils.StorageSlotKeyWithEvaluatedAddress(t.cache.Get(addr.Bytes()), key) - return t.root.Insert(k, zero[:], t.nodeResolver) -} - -// Hash returns the root hash of the tree. It does not write to the database and -// can be used even if the tree doesn't have one. -func (t *VerkleTrie) Hash() common.Hash { - return t.root.Commit().Bytes() -} - -// Commit writes all nodes to the tree's memory database. -func (t *VerkleTrie) Commit(_ bool) (common.Hash, *trienode.NodeSet) { - root := t.root.(*verkle.InternalNode) - nodes, err := root.BatchSerialize() - if err != nil { - // Error return from this function indicates error in the code logic - // of BatchSerialize, and we fail catastrophically if this is the case. - panic(fmt.Errorf("BatchSerialize failed: %v", err)) - } - nodeset := trienode.NewNodeSet(common.Hash{}) - for _, node := range nodes { - // Hash parameter is not used in pathdb - nodeset.AddNode(node.Path, trienode.New(common.Hash{}, node.SerializedBytes)) - } - // Serialize root commitment form - return t.Hash(), nodeset -} - -// NodeIterator implements state.Trie, returning an iterator that returns -// nodes of the trie. Iteration starts at the key after the given start key. -// -// TODO(gballet, rjl493456442) implement it. -func (t *VerkleTrie) NodeIterator(startKey []byte) (NodeIterator, error) { - panic("not implemented") -} - -// Prove implements state.Trie, constructing a Merkle proof for key. The result -// contains all encoded nodes on the path to the value at key. The value itself -// is also included in the last node and can be retrieved by verifying the proof. -// -// If the trie does not contain a value for key, the returned proof contains all -// nodes of the longest existing prefix of the key (at least the root), ending -// with the node that proves the absence of the key. -// -// TODO(gballet, rjl493456442) implement it. -func (t *VerkleTrie) Prove(key []byte, proofDb ethdb.KeyValueWriter) error { - panic("not implemented") -} - -// Copy returns a deep-copied verkle tree. -func (t *VerkleTrie) Copy() *VerkleTrie { - return &VerkleTrie{ - root: t.root.Copy(), - cache: t.cache, - reader: t.reader, - } -} - -// IsVerkle indicates if the trie is a Verkle trie. -func (t *VerkleTrie) IsVerkle() bool { - return true -} - -// Proof builds and returns the verkle multiproof for keys, built against -// the pre tree. The post tree is passed in order to add the post values -// to that proof. -func (t *VerkleTrie) Proof(posttrie *VerkleTrie, keys [][]byte) (*verkle.VerkleProof, verkle.StateDiff, error) { - var postroot verkle.VerkleNode - if posttrie != nil { - postroot = posttrie.root - } - proof, _, _, _, err := verkle.MakeVerkleMultiProof(t.root, postroot, keys, t.FlatdbNodeResolver) - if err != nil { - return nil, nil, err - } - p, kvps, err := verkle.SerializeProof(proof) - if err != nil { - return nil, nil, err - } - return p, kvps, nil -} - -// ChunkedCode represents a sequence of 32-bytes chunks of code (31 bytes of which -// are actual code, and 1 byte is the pushdata offset). -type ChunkedCode []byte - -// Copy the values here so as to avoid an import cycle -const ( - PUSH1 = byte(0x60) - PUSH32 = byte(0x7f) -) - -// ChunkifyCode generates the chunked version of an array representing EVM bytecode -func ChunkifyCode(code []byte) ChunkedCode { - var ( - chunkOffset = 0 // offset in the chunk - chunkCount = len(code) / 31 - codeOffset = 0 // offset in the code - ) - if len(code)%31 != 0 { - chunkCount++ - } - chunks := make([]byte, chunkCount*32) - for i := 0; i < chunkCount; i++ { - // number of bytes to copy, 31 unless the end of the code has been reached. - end := 31 * (i + 1) - if len(code) < end { - end = len(code) - } - copy(chunks[i*32+1:], code[31*i:end]) // copy the code itself - - // chunk offset = taken from the last chunk. - if chunkOffset > 31 { - // skip offset calculation if push data covers the whole chunk - chunks[i*32] = 31 - chunkOffset = 1 - continue - } - chunks[32*i] = byte(chunkOffset) - chunkOffset = 0 - - // Check each instruction and update the offset it should be 0 unless - // a PUSH-N overflows. - for ; codeOffset < end; codeOffset++ { - if code[codeOffset] >= PUSH1 && code[codeOffset] <= PUSH32 { - codeOffset += int(code[codeOffset] - PUSH1 + 1) - if codeOffset+1 >= 31*(i+1) { - codeOffset++ - chunkOffset = codeOffset - 31*(i+1) - break - } - } - } - } - return chunks -} - -// UpdateContractCode implements state.Trie, writing the provided contract code -// into the trie. -// Note that the code-size *must* be already saved by a previous UpdateAccount call. -func (t *VerkleTrie) UpdateContractCode(addr common.Address, codeHash common.Hash, code []byte) error { - var ( - chunks = ChunkifyCode(code) - values [][]byte - key []byte - err error - ) - for i, chunknr := 0, uint64(0); i < len(chunks); i, chunknr = i+32, chunknr+1 { - groupOffset := (chunknr + 128) % 256 - if groupOffset == 0 /* start of new group */ || chunknr == 0 /* first chunk in header group */ { - values = make([][]byte, verkle.NodeWidth) - key = utils.CodeChunkKeyWithEvaluatedAddress(t.cache.Get(addr.Bytes()), uint256.NewInt(chunknr)) - } - values[groupOffset] = chunks[i : i+32] - - if groupOffset == 255 || len(chunks)-i <= 32 { - switch root := t.root.(type) { - case *verkle.InternalNode: - err = root.InsertValuesAtStem(key[:31], values, t.nodeResolver) - if err != nil { - return fmt.Errorf("UpdateContractCode (addr=%x) error: %w", addr[:], err) - } - default: - return errInvalidRootType - } - } - } - return nil -} - -func (t *VerkleTrie) ToDot() string { - return verkle.ToDot(t.root) -} - -func (t *VerkleTrie) nodeResolver(path []byte) ([]byte, error) { - return t.reader.node(path, common.Hash{}) -} - -// Witness returns a set containing all trie nodes that have been accessed. -func (t *VerkleTrie) Witness() map[string]struct{} { - panic("not implemented") -} diff --git a/trie/verkle_test.go b/trie/verkle_test.go deleted file mode 100644 index f31ab02df9..0000000000 --- a/trie/verkle_test.go +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2023 The go-ethereum Authors -// This file is part of the go-ethereum library. -// -// The go-ethereum library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The go-ethereum library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . - -package trie - -import ( - "bytes" - "reflect" - "testing" - - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/trie/utils" - "github.com/holiman/uint256" -) - -var ( - accounts = map[common.Address]*types.StateAccount{ - {1}: { - Nonce: 100, - Balance: uint256.NewInt(100), - CodeHash: common.Hash{0x1}.Bytes(), - }, - {2}: { - Nonce: 200, - Balance: uint256.NewInt(200), - CodeHash: common.Hash{0x2}.Bytes(), - }, - } - storages = map[common.Address]map[common.Hash][]byte{ - {1}: { - common.Hash{10}: []byte{10}, - common.Hash{11}: []byte{11}, - common.MaxHash: []byte{0xff}, - }, - {2}: { - common.Hash{20}: []byte{20}, - common.Hash{21}: []byte{21}, - common.MaxHash: []byte{0xff}, - }, - } -) - -func TestVerkleTreeReadWrite(t *testing.T) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.PathScheme) - tr, _ := NewVerkleTrie(types.EmptyVerkleHash, db, utils.NewPointCache(100)) - - for addr, acct := range accounts { - if err := tr.UpdateAccount(addr, acct, 0); err != nil { - t.Fatalf("Failed to update account, %v", err) - } - for key, val := range storages[addr] { - if err := tr.UpdateStorage(addr, key.Bytes(), val); err != nil { - t.Fatalf("Failed to update account, %v", err) - } - } - } - - for addr, acct := range accounts { - stored, err := tr.GetAccount(addr) - if err != nil { - t.Fatalf("Failed to get account, %v", err) - } - if !reflect.DeepEqual(stored, acct) { - t.Fatal("account is not matched") - } - for key, val := range storages[addr] { - stored, err := tr.GetStorage(addr, key.Bytes()) - if err != nil { - t.Fatalf("Failed to get storage, %v", err) - } - if !bytes.Equal(stored, val) { - t.Fatal("storage is not matched") - } - } - } -} - -func TestVerkleRollBack(t *testing.T) { - db := newTestDatabase(rawdb.NewMemoryDatabase(), rawdb.PathScheme) - tr, _ := NewVerkleTrie(types.EmptyVerkleHash, db, utils.NewPointCache(100)) - - for addr, acct := range accounts { - // create more than 128 chunks of code - code := make([]byte, 129*32) - for i := 0; i < len(code); i += 2 { - code[i] = 0x60 - code[i+1] = byte(i % 256) - } - if err := tr.UpdateAccount(addr, acct, len(code)); err != nil { - t.Fatalf("Failed to update account, %v", err) - } - for key, val := range storages[addr] { - if err := tr.UpdateStorage(addr, key.Bytes(), val); err != nil { - t.Fatalf("Failed to update account, %v", err) - } - } - hash := crypto.Keccak256Hash(code) - if err := tr.UpdateContractCode(addr, hash, code); err != nil { - t.Fatalf("Failed to update contract, %v", err) - } - } - - // Check that things were created - for addr, acct := range accounts { - stored, err := tr.GetAccount(addr) - if err != nil { - t.Fatalf("Failed to get account, %v", err) - } - if !reflect.DeepEqual(stored, acct) { - t.Fatal("account is not matched") - } - for key, val := range storages[addr] { - stored, err := tr.GetStorage(addr, key.Bytes()) - if err != nil { - t.Fatalf("Failed to get storage, %v", err) - } - if !bytes.Equal(stored, val) { - t.Fatal("storage is not matched") - } - } - } - - // ensure there is some code in the 2nd group of the 1st account - keyOf2ndGroup := utils.CodeChunkKeyWithEvaluatedAddress(tr.cache.Get(common.Address{1}.Bytes()), uint256.NewInt(128)) - chunk, err := tr.root.Get(keyOf2ndGroup, nil) - if err != nil { - t.Fatalf("Failed to get account, %v", err) - } - if len(chunk) == 0 { - t.Fatal("account was not created ") - } - - // Rollback first account and check that it is gone - addr1 := common.Address{1} - err = tr.RollBackAccount(addr1) - if err != nil { - t.Fatalf("error rolling back address 1: %v", err) - } - - // ensure the account is gone - stored, err := tr.GetAccount(addr1) - if err != nil { - t.Fatalf("Failed to get account, %v", err) - } - if stored != nil { - t.Fatal("account was not deleted") - } - - // ensure that the last code chunk is also gone from the tree - chunk, err = tr.root.Get(keyOf2ndGroup, nil) - if err != nil { - t.Fatalf("Failed to get account, %v", err) - } - if len(chunk) != 0 { - t.Fatal("account was not deleted") - } -} diff --git a/triedb/database.go b/triedb/database.go index e2f4334d6e..e7e47bb91a 100644 --- a/triedb/database.go +++ b/triedb/database.go @@ -129,8 +129,8 @@ func (db *Database) StateReader(blockRoot common.Hash) (database.StateReader, er return db.backend.StateReader(blockRoot) } -// HistoricReader constructs a reader for accessing the requested historic state. -func (db *Database) HistoricReader(root common.Hash) (*pathdb.HistoricalStateReader, error) { +// HistoricStateReader constructs a reader for accessing the requested historic state. +func (db *Database) HistoricStateReader(root common.Hash) (*pathdb.HistoricalStateReader, error) { pdb, ok := db.backend.(*pathdb.Database) if !ok { return nil, errors.New("not supported") @@ -138,6 +138,15 @@ func (db *Database) HistoricReader(root common.Hash) (*pathdb.HistoricalStateRea return pdb.HistoricReader(root) } +// HistoricNodeReader constructs a reader for accessing the historical trie node. +func (db *Database) HistoricNodeReader(root common.Hash) (*pathdb.HistoricalNodeReader, error) { + pdb, ok := db.backend.(*pathdb.Database) + if !ok { + return nil, errors.New("not supported") + } + return pdb.HistoricNodeReader(root) +} + // Update performs a state transition by committing dirty nodes contained in the // given set in order to update state from the specified parent to the specified // root. The held pre-images accumulated up to this point will be flushed in case @@ -375,3 +384,12 @@ func (db *Database) IsVerkle() bool { func (db *Database) Disk() ethdb.Database { return db.disk } + +// SnapshotCompleted returns the indicator if the snapshot is completed. +func (db *Database) SnapshotCompleted() bool { + pdb, ok := db.backend.(*pathdb.Database) + if !ok { + return false + } + return pdb.SnapshotCompleted() +} diff --git a/triedb/pathdb/buffer.go b/triedb/pathdb/buffer.go index 138962110f..853e1090b3 100644 --- a/triedb/pathdb/buffer.go +++ b/triedb/pathdb/buffer.go @@ -132,7 +132,7 @@ func (b *buffer) size() uint64 { // flush persists the in-memory dirty trie node into the disk if the configured // memory threshold is reached. Note, all data must be written atomically. -func (b *buffer) flush(root common.Hash, db ethdb.KeyValueStore, freezer ethdb.AncientWriter, progress []byte, nodesCache, statesCache *fastcache.Cache, id uint64, postFlush func()) { +func (b *buffer) flush(root common.Hash, db ethdb.KeyValueStore, freezers []ethdb.AncientWriter, progress []byte, nodesCache, statesCache *fastcache.Cache, id uint64, postFlush func()) { if b.done != nil { panic("duplicated flush operation") } @@ -165,11 +165,9 @@ func (b *buffer) flush(root common.Hash, db ethdb.KeyValueStore, freezer ethdb.A // // This step is crucial to guarantee that the corresponding state history remains // available for state rollback. - if freezer != nil { - if err := freezer.SyncAncient(); err != nil { - b.flushErr = err - return - } + if err := syncHistory(freezers...); err != nil { + b.flushErr = err + return } nodes := b.nodes.write(batch, nodesCache) accounts, slots := b.states.write(batch, progress, statesCache) diff --git a/triedb/pathdb/config.go b/triedb/pathdb/config.go new file mode 100644 index 0000000000..c236b34333 --- /dev/null +++ b/triedb/pathdb/config.go @@ -0,0 +1,161 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pathdb + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/params" +) + +const ( + // defaultTrieCleanSize is the default memory allowance of clean trie cache. + defaultTrieCleanSize = 16 * 1024 * 1024 + + // defaultStateCleanSize is the default memory allowance of clean state cache. + defaultStateCleanSize = 16 * 1024 * 1024 + + // maxBufferSize is the maximum memory allowance of node buffer. + // Too large buffer will cause the system to pause for a long + // time when write happens. Also, the largest batch that pebble can + // support is 4GB, node will panic if batch size exceeds this limit. + maxBufferSize = 256 * 1024 * 1024 + + // defaultBufferSize is the default memory allowance of node buffer + // that aggregates the writes from above until it's flushed into the + // disk. It's meant to be used once the initial sync is finished. + // Do not increase the buffer size arbitrarily, otherwise the system + // pause time will increase when the database writes happen. + defaultBufferSize = 64 * 1024 * 1024 + + // maxFullValueCheckpoint defines the maximum allowed encoding frequency (1/16) + // for storing nodes in full format. With this setting, a node may be written + // to the trienode history as a full value at the specified frequency. + // + // Note that the frequency is not strict: the actual decision is probabilistic. + // Only the overall long-term full-value encoding rate is enforced. + // + // Values beyond this limit are considered ineffective, as the trienode history + // is already well compressed. Increasing it further will only degrade read + // performance linearly. + maxFullValueCheckpoint = 16 + + // defaultFullValueCheckpoint defines the default full-value encoding frequency + // (1/8) for storing nodes in full format. With this setting, nodes may be + // written to the trienode history as full values at the specified rate. + // + // This strikes a balance between effective compression of the trienode history + // and acceptable read performance. + defaultFullValueCheckpoint = 8 +) + +var ( + // maxDiffLayers is the maximum diff layers allowed in the layer tree. + maxDiffLayers = 128 +) + +// Defaults contains default settings for Ethereum mainnet. +var Defaults = &Config{ + StateHistory: params.FullImmutabilityThreshold, + TrienodeHistory: -1, + FullValueCheckpoint: defaultFullValueCheckpoint, + EnableStateIndexing: false, + TrieCleanSize: defaultTrieCleanSize, + StateCleanSize: defaultStateCleanSize, + WriteBufferSize: defaultBufferSize, +} + +// ReadOnly is the config in order to open database in read only mode. +var ReadOnly = &Config{ + ReadOnly: true, + TrienodeHistory: -1, + TrieCleanSize: defaultTrieCleanSize, + StateCleanSize: defaultStateCleanSize, + FullValueCheckpoint: defaultFullValueCheckpoint, +} + +// Config contains the settings for database. +type Config struct { + TrieCleanSize int // Maximum memory allowance (in bytes) for caching clean trie data + StateCleanSize int // Maximum memory allowance (in bytes) for caching clean state data + WriteBufferSize int // Maximum memory allowance (in bytes) for write buffer + ReadOnly bool // Flag whether the database is opened in read only mode + JournalDirectory string // Absolute path of journal directory (null means the journal data is persisted in key-value store) + + // Historical state configurations + StateHistory uint64 // Number of recent blocks to maintain state history for, 0: full chain + TrienodeHistory int64 // Number of recent blocks to maintain trienode history for, 0: full chain, negative: disable + EnableStateIndexing bool // Whether to enable state history indexing for external state access + FullValueCheckpoint uint32 // The rate at which trie nodes are encoded in full-value format + + // Testing configurations + SnapshotNoBuild bool // Flag Whether the state generation is disabled + NoAsyncFlush bool // Flag whether the background buffer flushing is disabled + NoAsyncGeneration bool // Flag whether the background generation is disabled +} + +// sanitize checks the provided user configurations and changes anything that's +// unreasonable or unworkable. +func (c *Config) sanitize() *Config { + conf := *c + if conf.WriteBufferSize > maxBufferSize { + log.Warn("Sanitizing invalid node buffer size", "provided", common.StorageSize(conf.WriteBufferSize), "updated", common.StorageSize(maxBufferSize)) + conf.WriteBufferSize = maxBufferSize + } + if conf.FullValueCheckpoint > maxFullValueCheckpoint { + log.Warn("Sanitizing trienode history full value checkpoint", "provided", conf.FullValueCheckpoint, "updated", maxFullValueCheckpoint) + conf.FullValueCheckpoint = maxFullValueCheckpoint + } + if conf.FullValueCheckpoint == 0 { + conf.FullValueCheckpoint = 1 + log.Info("Disabling diff mode trie node history encoding") + } + return &conf +} + +// fields returns a list of attributes of config for printing. +func (c *Config) fields() []interface{} { + var list []interface{} + if c.ReadOnly { + list = append(list, "readonly", true) + } + list = append(list, "triecache", common.StorageSize(c.TrieCleanSize)) + list = append(list, "statecache", common.StorageSize(c.StateCleanSize)) + list = append(list, "buffer", common.StorageSize(c.WriteBufferSize)) + + if c.StateHistory == 0 { + list = append(list, "state-history", "entire chain") + } else { + list = append(list, "state-history", fmt.Sprintf("last %d blocks", c.StateHistory)) + } + if c.TrienodeHistory >= 0 { + if c.TrienodeHistory == 0 { + list = append(list, "trie-history", "entire chain") + } else { + list = append(list, "trie-history", fmt.Sprintf("last %d blocks", c.TrienodeHistory)) + } + } + if c.EnableStateIndexing { + list = append(list, "index-history", true) + } + if c.JournalDirectory != "" { + list = append(list, "journal-dir", c.JournalDirectory) + } + return list +} diff --git a/triedb/pathdb/database.go b/triedb/pathdb/database.go index e323a7449e..f7c0ba1398 100644 --- a/triedb/pathdb/database.go +++ b/triedb/pathdb/database.go @@ -31,35 +31,8 @@ import ( "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" - "github.com/ethereum/go-ethereum/params" + "github.com/ethereum/go-ethereum/trie/bintrie" "github.com/ethereum/go-ethereum/trie/trienode" - "github.com/ethereum/go-verkle" -) - -const ( - // defaultTrieCleanSize is the default memory allowance of clean trie cache. - defaultTrieCleanSize = 16 * 1024 * 1024 - - // defaultStateCleanSize is the default memory allowance of clean state cache. - defaultStateCleanSize = 16 * 1024 * 1024 - - // maxBufferSize is the maximum memory allowance of node buffer. - // Too large buffer will cause the system to pause for a long - // time when write happens. Also, the largest batch that pebble can - // support is 4GB, node will panic if batch size exceeds this limit. - maxBufferSize = 256 * 1024 * 1024 - - // defaultBufferSize is the default memory allowance of node buffer - // that aggregates the writes from above until it's flushed into the - // disk. It's meant to be used once the initial sync is finished. - // Do not increase the buffer size arbitrarily, otherwise the system - // pause time will increase when the database writes happen. - defaultBufferSize = 64 * 1024 * 1024 -) - -var ( - // maxDiffLayers is the maximum diff layers allowed in the layer tree. - maxDiffLayers = 128 ) // layer is the interface implemented by all state layers which includes some @@ -105,7 +78,7 @@ type layer interface { // the provided dirty trie nodes along with the state change set. // // Note, the maps are retained by the method to avoid copying everything. - update(root common.Hash, id uint64, block uint64, nodes *nodeSet, states *StateSetWithOrigin) *diffLayer + update(root common.Hash, id uint64, block uint64, nodes *nodeSetWithOrigin, states *StateSetWithOrigin) *diffLayer // journal commits an entire diff hierarchy to disk into a single journal entry. // This is meant to be used during shutdown to persist the layer without @@ -113,68 +86,6 @@ type layer interface { journal(w io.Writer) error } -// Config contains the settings for database. -type Config struct { - StateHistory uint64 // Number of recent blocks to maintain state history for - EnableStateIndexing bool // Whether to enable state history indexing for external state access - TrieCleanSize int // Maximum memory allowance (in bytes) for caching clean trie nodes - StateCleanSize int // Maximum memory allowance (in bytes) for caching clean state data - WriteBufferSize int // Maximum memory allowance (in bytes) for write buffer - ReadOnly bool // Flag whether the database is opened in read only mode - JournalDirectory string // Absolute path of journal directory (null means the journal data is persisted in key-value store) - - // Testing configurations - SnapshotNoBuild bool // Flag Whether the state generation is allowed - NoAsyncFlush bool // Flag whether the background buffer flushing is allowed - NoAsyncGeneration bool // Flag whether the background generation is allowed -} - -// sanitize checks the provided user configurations and changes anything that's -// unreasonable or unworkable. -func (c *Config) sanitize() *Config { - conf := *c - if conf.WriteBufferSize > maxBufferSize { - log.Warn("Sanitizing invalid node buffer size", "provided", common.StorageSize(conf.WriteBufferSize), "updated", common.StorageSize(maxBufferSize)) - conf.WriteBufferSize = maxBufferSize - } - return &conf -} - -// fields returns a list of attributes of config for printing. -func (c *Config) fields() []interface{} { - var list []interface{} - if c.ReadOnly { - list = append(list, "readonly", true) - } - if c.SnapshotNoBuild { - list = append(list, "snapshot", false) - } - list = append(list, "triecache", common.StorageSize(c.TrieCleanSize)) - list = append(list, "statecache", common.StorageSize(c.StateCleanSize)) - list = append(list, "buffer", common.StorageSize(c.WriteBufferSize)) - - if c.StateHistory == 0 { - list = append(list, "history", "entire chain") - } else { - list = append(list, "history", fmt.Sprintf("last %d blocks", c.StateHistory)) - } - if c.JournalDirectory != "" { - list = append(list, "journal-dir", c.JournalDirectory) - } - return list -} - -// Defaults contains default settings for Ethereum mainnet. -var Defaults = &Config{ - StateHistory: params.FullImmutabilityThreshold, - TrieCleanSize: defaultTrieCleanSize, - StateCleanSize: defaultStateCleanSize, - WriteBufferSize: defaultBufferSize, -} - -// ReadOnly is the config in order to open database in read only mode. -var ReadOnly = &Config{ReadOnly: true} - // nodeHasher is the function to compute the hash of supplied node blob. type nodeHasher func([]byte) (common.Hash, error) @@ -186,16 +97,16 @@ func merkleNodeHasher(blob []byte) (common.Hash, error) { return crypto.Keccak256Hash(blob), nil } -// verkleNodeHasher computes the hash of the given verkle node. -func verkleNodeHasher(blob []byte) (common.Hash, error) { +// binaryNodeHasher computes the hash of the given verkle node. +func binaryNodeHasher(blob []byte) (common.Hash, error) { if len(blob) == 0 { return types.EmptyVerkleHash, nil } - n, err := verkle.ParseNode(blob, 0) + n, err := bintrie.DeserializeNode(blob, 0) if err != nil { return common.Hash{}, err } - return n.Commit().Bytes(), nil + return n.Hash(), nil } // Database is a multiple-layered structure for maintaining in-memory states @@ -219,12 +130,17 @@ type Database struct { isVerkle bool // Flag if database is used for verkle tree hasher nodeHasher // Trie node hasher - config *Config // Configuration for database - diskdb ethdb.Database // Persistent storage for matured trie nodes - tree *layerTree // The group for all known layers - freezer ethdb.ResettableAncientStore // Freezer for storing trie histories, nil possible in tests - lock sync.RWMutex // Lock to prevent mutations from happening at the same time - indexer *historyIndexer // History indexer + config *Config // Configuration for database + diskdb ethdb.Database // Persistent storage for matured trie nodes + tree *layerTree // The group for all known layers + + stateFreezer ethdb.ResettableAncientStore // Freezer for storing state histories, nil possible in tests + stateIndexer *historyIndexer // History indexer historical state data, nil possible + + trienodeFreezer ethdb.ResettableAncientStore // Freezer for storing trienode histories, nil possible in tests + trienodeIndexer *historyIndexer // History indexer for historical trienode data + + lock sync.RWMutex // Lock to prevent mutations from happening at the same time } // New attempts to load an already existing layer from a persistent key-value @@ -250,17 +166,20 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { // compress the shared key prefix. if isVerkle { db.diskdb = rawdb.NewTable(diskdb, string(rawdb.VerklePrefix)) - db.hasher = verkleNodeHasher + db.hasher = binaryNodeHasher } // Construct the layer tree by resolving the in-disk singleton state // and in-memory layer journal. db.tree = newLayerTree(db.loadLayers()) - // Repair the state history, which might not be aligned with the state - // in the key-value store due to an unclean shutdown. - if err := db.repairHistory(); err != nil { - log.Crit("Failed to repair state history", "err", err) + // Repair the history, which might not be aligned with the persistent + // state in the key-value store due to an unclean shutdown. + states, trienodes, err := repairHistory(db.diskdb, isVerkle, db.config.ReadOnly, db.tree.bottom().stateID(), db.config.TrienodeHistory >= 0) + if err != nil { + log.Crit("Failed to repair history", "err", err) } + db.stateFreezer, db.trienodeFreezer = states, trienodes + // Disable database in case node is still in the initial state sync stage. if rawdb.ReadSnapSyncStatusFlag(diskdb) == rawdb.StateSyncRunning && !db.readOnly { if err := db.Disable(); err != nil { @@ -274,11 +193,8 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { if err := db.setStateGenerator(); err != nil { log.Crit("Failed to setup the generator", "err", err) } - // TODO (rjl493456442) disable the background indexing in read-only mode - if db.freezer != nil && db.config.EnableStateIndexing { - db.indexer = newHistoryIndexer(db.diskdb, db.freezer, db.tree.bottom().stateID()) - log.Info("Enabled state history indexing") - } + db.setHistoryIndexer() + fields := config.fields() if db.isVerkle { fields = append(fields, "verkle", true) @@ -287,58 +203,28 @@ func New(diskdb ethdb.Database, config *Config, isVerkle bool) *Database { return db } -// repairHistory truncates leftover state history objects, which may occur due -// to an unclean shutdown or other unexpected reasons. -func (db *Database) repairHistory() error { - // Open the freezer for state history. This mechanism ensures that - // only one database instance can be opened at a time to prevent - // accidental mutation. - ancient, err := db.diskdb.AncientDatadir() - if err != nil { - // TODO error out if ancient store is disabled. A tons of unit tests - // disable the ancient store thus the error here will immediately fail - // all of them. Fix the tests first. - return nil +// setHistoryIndexer initializes the indexers for both state history and +// trienode history if available. Note that this function may be called while +// existing indexers are still running, so they must be closed beforehand. +func (db *Database) setHistoryIndexer() { + // TODO (rjl493456442) disable the background indexing in read-only mode + if !db.config.EnableStateIndexing { + return } - freezer, err := rawdb.NewStateFreezer(ancient, db.isVerkle, db.readOnly) - if err != nil { - log.Crit("Failed to open state history freezer", "err", err) - } - db.freezer = freezer - - // Reset the entire state histories if the trie database is not initialized - // yet. This action is necessary because these state histories are not - // expected to exist without an initialized trie database. - id := db.tree.bottom().stateID() - if id == 0 { - frozen, err := db.freezer.Ancients() - if err != nil { - log.Crit("Failed to retrieve head of state history", "err", err) + if db.stateFreezer != nil { + if db.stateIndexer != nil { + db.stateIndexer.close() } - if frozen != 0 { - // TODO(rjl493456442) would be better to group them into a batch. - // - // Purge all state history indexing data first - rawdb.DeleteStateHistoryIndexMetadata(db.diskdb) - rawdb.DeleteStateHistoryIndex(db.diskdb) - err := db.freezer.Reset() - if err != nil { - log.Crit("Failed to reset state histories", "err", err) - } - log.Info("Truncated extraneous state history") + db.stateIndexer = newHistoryIndexer(db.diskdb, db.stateFreezer, db.tree.bottom().stateID(), typeStateHistory) + log.Info("Enabled state history indexing") + } + if db.trienodeFreezer != nil { + if db.trienodeIndexer != nil { + db.trienodeIndexer.close() } - return nil + db.trienodeIndexer = newHistoryIndexer(db.diskdb, db.trienodeFreezer, db.tree.bottom().stateID(), typeTrienodeHistory) + log.Info("Enabled trienode history indexing") } - // Truncate the extra state histories above in freezer in case it's not - // aligned with the disk layer. It might happen after a unclean shutdown. - pruned, err := truncateFromHead(db.diskdb, db.freezer, id) - if err != nil { - log.Crit("Failed to truncate extra state histories", "err", err) - } - if pruned != 0 { - log.Warn("Truncated extra state histories", "number", pruned) - } - return nil } // setStateGenerator loads the state generation progress marker and potentially @@ -419,7 +305,13 @@ func (db *Database) Update(root common.Hash, parentRoot common.Hash, block uint6 if err := db.modifyAllowed(); err != nil { return err } - if err := db.tree.add(root, parentRoot, block, nodes, states); err != nil { + var nodesWithOrigins *nodeSetWithOrigin + if db.config.TrienodeHistory >= 0 { + nodesWithOrigins = NewNodeSetWithOrigin(nodes.NodeAndOrigins()) + } else { + nodesWithOrigins = NewNodeSetWithOrigin(nodes.Nodes(), nil) + } + if err := db.tree.add(root, parentRoot, block, nodesWithOrigins, states); err != nil { return err } // Keep 128 diff layers in the memory, persistent layer is 129th. @@ -507,16 +399,9 @@ func (db *Database) Enable(root common.Hash) error { // all root->id mappings should be removed as well. Since // mappings can be huge and might take a while to clear // them, just leave them in disk and wait for overwriting. - if db.freezer != nil { - // TODO(rjl493456442) would be better to group them into a batch. - // - // Purge all state history indexing data first - rawdb.DeleteStateHistoryIndexMetadata(db.diskdb) - rawdb.DeleteStateHistoryIndex(db.diskdb) - if err := db.freezer.Reset(); err != nil { - return err - } - } + purgeHistory(db.stateFreezer, db.diskdb, typeStateHistory) + purgeHistory(db.trienodeFreezer, db.diskdb, typeTrienodeHistory) + // Re-enable the database as the final step. db.waitSync = false rawdb.WriteSnapSyncStatusFlag(db.diskdb, rawdb.StateSyncFinished) @@ -529,11 +414,8 @@ func (db *Database) Enable(root common.Hash) error { // To ensure the history indexer always matches the current state, we must: // 1. Close any existing indexer // 2. Re-initialize the indexer so it starts indexing from the new state root. - if db.indexer != nil && db.freezer != nil && db.config.EnableStateIndexing { - db.indexer.close() - db.indexer = newHistoryIndexer(db.diskdb, db.freezer, db.tree.bottom().stateID()) - log.Info("Re-enabled state history indexing") - } + db.setHistoryIndexer() + log.Info("Rebuilt trie database", "root", root) return nil } @@ -551,7 +433,7 @@ func (db *Database) Recover(root common.Hash) error { if err := db.modifyAllowed(); err != nil { return err } - if db.freezer == nil { + if db.stateFreezer == nil { return errors.New("state rollback is non-supported") } // Short circuit if the target state is not recoverable @@ -564,7 +446,7 @@ func (db *Database) Recover(root common.Hash) error { dl = db.tree.bottom() ) for dl.rootHash() != root { - h, err := readHistory(db.freezer, dl.stateID()) + h, err := readStateHistory(db.stateFreezer, dl.stateID()) if err != nil { return err } @@ -585,10 +467,16 @@ func (db *Database) Recover(root common.Hash) error { if err := db.diskdb.SyncKeyValue(); err != nil { return err } - _, err := truncateFromHead(db.diskdb, db.freezer, dl.stateID()) + _, err := truncateFromHead(db.stateFreezer, typeStateHistory, dl.stateID()) if err != nil { return err } + if db.trienodeFreezer != nil { + _, err = truncateFromHead(db.trienodeFreezer, typeTrienodeHistory, dl.stateID()) + if err != nil { + return err + } + } log.Debug("Recovered state", "root", root, "elapsed", common.PrettyDuration(time.Since(start))) return nil } @@ -610,15 +498,15 @@ func (db *Database) Recoverable(root common.Hash) bool { return false } // This is a temporary workaround for the unavailability of the freezer in - // dev mode. As a consequence, the Pathdb loses the ability for deep reorg + // dev mode. As a consequence, the database loses the ability for deep reorg // in certain cases. // TODO(rjl493456442): Implement the in-memory ancient store. - if db.freezer == nil { + if db.stateFreezer == nil { return false } // Ensure the requested state is a canonical state and all state - // histories in range [id+1, disklayer.ID] are present and complete. - return checkHistories(db.freezer, *id+1, dl.stateID()-*id, func(m *meta) error { + // histories in range [id+1, dl.ID] are present and complete. + return checkStateHistories(db.stateFreezer, *id+1, dl.stateID()-*id, func(m *meta) error { if m.parent != root { return errors.New("unexpected state history") } @@ -646,14 +534,24 @@ func (db *Database) Close() error { dl.resetCache() // release the memory held by clean cache // Terminate the background state history indexer - if db.indexer != nil { - db.indexer.close() + if db.stateIndexer != nil { + db.stateIndexer.close() + } + if db.trienodeIndexer != nil { + db.trienodeIndexer.close() } // Close the attached state history freezer. - if db.freezer == nil { - return nil + if db.stateFreezer != nil { + if err := db.stateFreezer.Close(); err != nil { + return err + } } - return db.freezer.Close() + if db.trienodeFreezer != nil { + if err := db.trienodeFreezer.Close(); err != nil { + return err + } + } + return nil } // Size returns the current storage size of the memory cache in front of the @@ -704,7 +602,7 @@ func (db *Database) journalPath() string { // End: State ID of the last history for the query. 0 implies the last available // object is selected as the ending point. Note end is included in the query. func (db *Database) AccountHistory(address common.Address, start, end uint64) (*HistoryStats, error) { - return accountHistory(db.freezer, address, start, end) + return accountHistory(db.stateFreezer, address, start, end) } // StorageHistory inspects the storage history within the specified range. @@ -717,22 +615,22 @@ func (db *Database) AccountHistory(address common.Address, start, end uint64) (* // // Note, slot refers to the hash of the raw slot key. func (db *Database) StorageHistory(address common.Address, slot common.Hash, start uint64, end uint64) (*HistoryStats, error) { - return storageHistory(db.freezer, address, slot, start, end) + return storageHistory(db.stateFreezer, address, slot, start, end) } // HistoryRange returns the block numbers associated with earliest and latest // state history in the local store. func (db *Database) HistoryRange() (uint64, uint64, error) { - return historyRange(db.freezer) + return historyRange(db.stateFreezer) } // IndexProgress returns the indexing progress made so far. It provides the // number of states that remain unindexed. func (db *Database) IndexProgress() (uint64, error) { - if db.indexer == nil { + if db.stateIndexer == nil { return 0, nil } - return db.indexer.progress() + return db.stateIndexer.progress() } // AccountIterator creates a new account iterator for the specified root hash and @@ -764,3 +662,14 @@ func (db *Database) StorageIterator(root common.Hash, account common.Hash, seek } return newFastStorageIterator(db, root, account, seek) } + +// SnapshotCompleted returns the flag indicating if the snapshot generation is completed. +func (db *Database) SnapshotCompleted() bool { + db.lock.RLock() + wait := db.waitSync + db.lock.RUnlock() + if wait { + return false + } + return db.tree.bottom().genComplete() +} diff --git a/triedb/pathdb/database_test.go b/triedb/pathdb/database_test.go index e9a1850ee0..2d1819d08f 100644 --- a/triedb/pathdb/database_test.go +++ b/triedb/pathdb/database_test.go @@ -36,9 +36,10 @@ import ( "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" "github.com/holiman/uint256" + "golang.org/x/exp/maps" ) -func updateTrie(db *Database, stateRoot common.Hash, addrHash common.Hash, root common.Hash, dirties map[common.Hash][]byte) (common.Hash, *trienode.NodeSet) { +func updateTrie(db *Database, stateRoot common.Hash, addrHash common.Hash, root common.Hash, entries map[common.Hash][]byte) (common.Hash, *trienode.NodeSet) { var id *trie.ID if addrHash == (common.Hash{}) { id = trie.StateTrieID(stateRoot) @@ -49,13 +50,17 @@ func updateTrie(db *Database, stateRoot common.Hash, addrHash common.Hash, root if err != nil { panic(fmt.Errorf("failed to load trie, err: %w", err)) } - for key, val := range dirties { + var deletes []common.Hash + for key, val := range entries { if len(val) == 0 { - tr.Delete(key.Bytes()) + deletes = append(deletes, key) } else { tr.Update(key.Bytes(), val) } } + for _, key := range deletes { + tr.Delete(key.Bytes()) + } return tr.Commit(false) } @@ -72,16 +77,18 @@ const ( createAccountOp int = iota modifyAccountOp deleteAccountOp + resurrectAccountOp opLen ) +// genctx carries the generation context used within a single state transition. type genctx struct { stateRoot common.Hash accounts map[common.Hash][]byte // Keyed by the hash of account address storages map[common.Hash]map[common.Hash][]byte // Keyed by the hash of account address and the hash of storage key accountOrigin map[common.Address][]byte // Keyed by the account address storageOrigin map[common.Address]map[common.Hash][]byte // Keyed by the account address and the hash of storage key - nodes *trienode.MergedNodeSet + nodes *trienode.MergedNodeSet // Trie nodes produced from the state transition } func newCtx(stateRoot common.Hash) *genctx { @@ -114,6 +121,8 @@ func (ctx *genctx) storageOriginSet(rawStorageKey bool, t *tester) map[common.Ad type tester struct { db *Database roots []common.Hash + nodes []*trienode.MergedNodeSet + states []*StateSetWithOrigin preimages map[common.Hash][]byte // current state set @@ -123,20 +132,57 @@ type tester struct { // state snapshots snapAccounts map[common.Hash]map[common.Hash][]byte // Keyed by the hash of account address snapStorages map[common.Hash]map[common.Hash]map[common.Hash][]byte // Keyed by the hash of account address and the hash of storage key + + // trienode snapshots + snapNodes map[common.Hash]*trienode.MergedNodeSet } -func newTester(t *testing.T, historyLimit uint64, isVerkle bool, layers int, enableIndex bool, journalDir string) *tester { +// testerConfig holds configuration parameters for running a test scenario. +type testerConfig struct { + stateHistory uint64 // Number of historical states to retain + layers int // Number of state transitions to generate for + enableIndex bool // Enable state history indexing or not + journalDir string // Directory path for persisting journal files + isVerkle bool // Enables Verkle trie mode if true + + writeBuffer *int // Optional, the size of memory allocated for write buffer + trieCache *int // Optional, the size of memory allocated for trie cache + stateCache *int // Optional, the size of memory allocated for state cache +} + +func (c *testerConfig) trieCacheSize() int { + if c.trieCache != nil { + return *c.trieCache + } + return 256 * 1024 +} + +func (c *testerConfig) stateCacheSize() int { + if c.stateCache != nil { + return *c.stateCache + } + return 256 * 1024 +} + +func (c *testerConfig) writeBufferSize() int { + if c.writeBuffer != nil { + return *c.writeBuffer + } + return 256 * 1024 +} + +func newTester(t *testing.T, config *testerConfig) *tester { var ( disk, _ = rawdb.Open(rawdb.NewMemoryDatabase(), rawdb.OpenOptions{Ancient: t.TempDir()}) db = New(disk, &Config{ - StateHistory: historyLimit, - EnableStateIndexing: enableIndex, - TrieCleanSize: 256 * 1024, - StateCleanSize: 256 * 1024, - WriteBufferSize: 256 * 1024, + StateHistory: config.stateHistory, + EnableStateIndexing: config.enableIndex, + TrieCleanSize: config.trieCacheSize(), + StateCleanSize: config.stateCacheSize(), + WriteBufferSize: config.writeBufferSize(), NoAsyncFlush: true, - JournalDirectory: journalDir, - }, isVerkle) + JournalDirectory: config.journalDir, + }, config.isVerkle) obj = &tester{ db: db, @@ -145,9 +191,10 @@ func newTester(t *testing.T, historyLimit uint64, isVerkle bool, layers int, ena storages: make(map[common.Hash]map[common.Hash][]byte), snapAccounts: make(map[common.Hash]map[common.Hash][]byte), snapStorages: make(map[common.Hash]map[common.Hash]map[common.Hash][]byte), + snapNodes: make(map[common.Hash]*trienode.MergedNodeSet), } ) - for i := 0; i < layers; i++ { + for i := 0; i < config.layers; i++ { var parent = types.EmptyRootHash if len(obj.roots) != 0 { parent = obj.roots[len(obj.roots)-1] @@ -158,6 +205,8 @@ func newTester(t *testing.T, historyLimit uint64, isVerkle bool, layers int, ena panic(fmt.Errorf("failed to update state changes, err: %w", err)) } obj.roots = append(obj.roots, root) + obj.nodes = append(obj.nodes, nodes) + obj.states = append(obj.states, states) } return obj } @@ -181,6 +230,8 @@ func (t *tester) extend(layers int) { panic(fmt.Errorf("failed to update state changes, err: %w", err)) } t.roots = append(t.roots, root) + t.nodes = append(t.nodes, nodes) + t.states = append(t.states, states) } } @@ -270,10 +321,53 @@ func (t *tester) clearStorage(ctx *genctx, addr common.Address, root common.Hash return root } +func (t *tester) resurrectStorage(ctx *genctx, addr common.Address, old map[common.Hash][]byte) common.Hash { + var ( + addrHash = crypto.Keccak256Hash(addr.Bytes()) + storage = make(map[common.Hash][]byte) + origin = make(map[common.Hash][]byte) + ) + for i := 0; i < 3; i++ { + v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32))) + key := testrand.Bytes(32) + hash := crypto.Keccak256Hash(key) + t.preimages[hash] = key + + storage[hash] = v + origin[hash] = nil + } + var cnt int + for khash := range old { + cnt += 1 + v, _ := rlp.EncodeToBytes(common.TrimLeftZeroes(testrand.Bytes(32))) + + storage[khash] = v + origin[khash] = old[khash] + if cnt >= 3 { + break + } + } + root, set := updateTrie(t.db, ctx.stateRoot, addrHash, types.EmptyRootHash, storage) + + maps.Copy(ctx.storages[addrHash], storage) + if ctx.storageOrigin[addr] == nil { + ctx.storageOrigin[addr] = make(map[common.Hash][]byte) + } + for k, v := range origin { + if _, exists := ctx.storageOrigin[addr][k]; !exists { + ctx.storageOrigin[addr][k] = v + } + } + ctx.nodes.Merge(set) + return root +} + func (t *tester) generate(parent common.Hash, rawStorageKey bool) (common.Hash, *trienode.MergedNodeSet, *StateSetWithOrigin) { var ( - ctx = newCtx(parent) - dirties = make(map[common.Hash]struct{}) + ctx = newCtx(parent) + dirties = make(map[common.Hash]struct{}) + deleted = make(map[common.Address]struct{}) + resurrect = make(map[common.Address]struct{}) ) for i := 0; i < 20; i++ { // Start with account creation always @@ -336,6 +430,7 @@ func (t *tester) generate(parent common.Hash, rawStorageKey bool) (common.Hash, continue } dirties[addrHash] = struct{}{} + deleted[addr] = struct{}{} acct, _ := types.FullAccount(account) if acct.Root != types.EmptyRootHash { @@ -343,6 +438,25 @@ func (t *tester) generate(parent common.Hash, rawStorageKey bool) (common.Hash, } ctx.accounts[addrHash] = nil ctx.accountOrigin[addr] = account + + case resurrectAccountOp: + if len(deleted) == 0 { + continue + } + addresses := maps.Keys(deleted) + addr := addresses[rand.Intn(len(addresses))] + if _, exist := resurrect[addr]; exist { + continue + } + resurrect[addr] = struct{}{} + + addrHash := crypto.Keccak256Hash(addr.Bytes()) + root := t.resurrectStorage(ctx, addr, t.storages[addrHash]) + ctx.accounts[addrHash] = types.SlimAccountRLP(generateAccount(root)) + if _, exist := ctx.accountOrigin[addr]; !exist { + ctx.accountOrigin[addr] = nil + } + t.preimages[addrHash] = addr.Bytes() } } root, set := updateTrie(t.db, parent, common.Hash{}, parent, ctx.accounts) @@ -351,6 +465,7 @@ func (t *tester) generate(parent common.Hash, rawStorageKey bool) (common.Hash, // Save state snapshot before commit t.snapAccounts[parent] = copyAccounts(t.accounts) t.snapStorages[parent] = copyStorages(t.storages) + t.snapNodes[parent] = ctx.nodes // Commit all changes to live state set for addrHash, account := range ctx.accounts { @@ -426,7 +541,7 @@ func (t *tester) verifyHistory() error { for i, root := range t.roots { // The state history related to the state above disk layer should not exist. if i > bottom { - _, err := readHistory(t.db.freezer, uint64(i+1)) + _, err := readStateHistory(t.db.stateFreezer, uint64(i+1)) if err == nil { return errors.New("unexpected state history") } @@ -434,7 +549,7 @@ func (t *tester) verifyHistory() error { } // The state history related to the state below or equal to the disk layer // should exist. - obj, err := readHistory(t.db.freezer, uint64(i+1)) + obj, err := readStateHistory(t.db.stateFreezer, uint64(i+1)) if err != nil { return err } @@ -470,8 +585,7 @@ func TestDatabaseRollback(t *testing.T) { maxDiffLayers = 128 }() - // Verify state histories - tester := newTester(t, 0, false, 32, false, "") + tester := newTester(t, &testerConfig{layers: 32}) defer tester.release() if err := tester.verifyHistory(); err != nil { @@ -505,7 +619,7 @@ func TestDatabaseRecoverable(t *testing.T) { }() var ( - tester = newTester(t, 0, false, 12, false, "") + tester = newTester(t, &testerConfig{layers: 12}) index = tester.bottomIndex() ) defer tester.release() @@ -526,7 +640,7 @@ func TestDatabaseRecoverable(t *testing.T) { // Layers below current disk layer are recoverable {tester.roots[index-1], true}, - // Disklayer itself is not recoverable, since it's + // Disk layer itself is not recoverable, since it's // available for accessing. {tester.roots[index], false}, @@ -542,6 +656,59 @@ func TestDatabaseRecoverable(t *testing.T) { } } +func TestExecuteRollback(t *testing.T) { + // Redefine the diff layer depth allowance for faster testing. + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + + tester := newTester(t, &testerConfig{layers: 32}) + defer tester.release() + + // Revert database from top to bottom + for i := tester.bottomIndex(); i >= 0; i-- { + dl := tester.db.tree.bottom() + h, err := readStateHistory(tester.db.stateFreezer, dl.stateID()) + if err != nil { + t.Fatalf("Failed to read history, err: %v", err) + } + nodes, err := apply(tester.db, h.meta.parent, h.meta.root, h.meta.version == stateHistoryV1, h.accounts, h.storages) + if err != nil { + t.Fatalf("Failed to apply history, err: %v", err) + } + + // Verify the produced node set, ensuring they are aligned with the + // tracked dirty nodes. + want := tester.snapNodes[h.meta.parent] + if len(nodes) != len(want.Sets) { + t.Fatalf("Unexpected node sets, want: %d, got: %d", len(want.Sets), len(nodes)) + } + for owner, setA := range nodes { + setB, ok := want.Sets[owner] + if !ok { + t.Fatalf("Excessive nodeset, %x", owner) + } + if len(setA) != len(setB.Origins) { + t.Fatalf("Unexpected origins, want: %d, got: %d", len(setA), len(setB.Origins)) + } + for k, nA := range setA { + nB, ok := setB.Origins[k] + if !ok { + t.Fatalf("Excessive node, %v", []byte(k)) + } + if !bytes.Equal(nA.Blob, nB) { + t.Fatalf("Unexpected node value, want: %v, got: %v", nA.Blob, nB) + } + } + } + + if err := tester.db.Recover(h.meta.parent); err != nil { + t.Fatalf("Failed to recover db, err: %v", err) + } + } +} + func TestDisable(t *testing.T) { // Redefine the diff layer depth allowance for faster testing. maxDiffLayers = 4 @@ -549,7 +716,7 @@ func TestDisable(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0, false, 32, false, "") + tester := newTester(t, &testerConfig{layers: 32}) defer tester.release() stored := crypto.Keccak256Hash(rawdb.ReadAccountTrieNode(tester.db.diskdb, nil)) @@ -563,12 +730,8 @@ func TestDisable(t *testing.T) { t.Fatalf("Failed to activate database: %v", err) } - // Ensure journal is deleted from disk - if blob := rawdb.ReadTrieJournal(tester.db.diskdb); len(blob) != 0 { - t.Fatal("Failed to clean journal") - } // Ensure all trie histories are removed - n, err := tester.db.freezer.Ancients() + n, err := tester.db.stateFreezer.Ancients() if err != nil { t.Fatal("Failed to clean state history") } @@ -591,7 +754,7 @@ func TestCommit(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 0, false, 12, false, "") + tester := newTester(t, &testerConfig{layers: 12}) defer tester.release() if err := tester.db.Commit(tester.lastHash(), false); err != nil { @@ -626,7 +789,7 @@ func testJournal(t *testing.T, journalDir string) { maxDiffLayers = 128 }() - tester := newTester(t, 0, false, 12, false, journalDir) + tester := newTester(t, &testerConfig{layers: 12, journalDir: journalDir}) defer tester.release() if err := tester.db.Journal(tester.lastHash()); err != nil { @@ -673,7 +836,7 @@ func testCorruptedJournal(t *testing.T, journalDir string, modifyFn func(databas maxDiffLayers = 128 }() - tester := newTester(t, 0, false, 12, false, journalDir) + tester := newTester(t, &testerConfig{layers: 12, journalDir: journalDir}) defer tester.release() if err := tester.db.Journal(tester.lastHash()); err != nil { @@ -718,13 +881,13 @@ func TestTailTruncateHistory(t *testing.T) { maxDiffLayers = 128 }() - tester := newTester(t, 10, false, 12, false, "") + tester := newTester(t, &testerConfig{layers: 12, stateHistory: 10}) defer tester.release() tester.db.Close() tester.db = New(tester.db.diskdb, &Config{StateHistory: 10}, false) - head, err := tester.db.freezer.Ancients() + head, err := tester.db.stateFreezer.Ancients() if err != nil { t.Fatalf("Failed to obtain freezer head") } @@ -754,3 +917,107 @@ func copyStorages(set map[common.Hash]map[common.Hash][]byte) map[common.Hash]ma } return copied } + +func TestDatabaseIndexRecovery(t *testing.T) { + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + + //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) + writeBuffer := 512 * 1024 + config := &testerConfig{ + layers: 64, + enableIndex: true, + writeBuffer: &writeBuffer, + } + env := newTester(t, config) + defer env.release() + + // Ensure the buffer in disk layer is not empty + var ( + bRoot = env.db.tree.bottom().rootHash() + dRoot = crypto.Keccak256Hash(rawdb.ReadAccountTrieNode(env.db.diskdb, nil)) + ) + for dRoot == bRoot { + env.extend(1) + + bRoot = env.db.tree.bottom().rootHash() + dRoot = crypto.Keccak256Hash(rawdb.ReadAccountTrieNode(env.db.diskdb, nil)) + } + waitIndexing(env.db) + + var ( + dIndex int + roots = env.roots + hr = newStateHistoryReader(env.db.diskdb, env.db.stateFreezer) + ) + for i, root := range roots { + if root == dRoot { + dIndex = i + } + if root == bRoot { + break + } + if err := checkHistoricalState(env, root, uint64(i+1), hr); err != nil { + t.Fatal(err) + } + } + + // Terminate the database and mutate the journal, it's for simulating + // the unclean shutdown + env.db.Journal(env.lastHash()) + env.db.Close() + + // Mutate the journal in disk, it should be regarded as invalid + blob := rawdb.ReadTrieJournal(env.db.diskdb) + blob[0] = 0xa + rawdb.WriteTrieJournal(env.db.diskdb, blob) + + // Reload the database, the extra state histories should be removed + env.db = New(env.db.diskdb, env.db.config, false) + + for i := range roots { + _, err := readStateHistory(env.db.stateFreezer, uint64(i+1)) + if i <= dIndex && err != nil { + t.Fatalf("State history is not found, %d", i) + } + if i > dIndex && err == nil { + t.Fatalf("Unexpected state history found, %d", i) + } + } + remain, err := env.db.IndexProgress() + if err != nil { + t.Fatalf("Failed to obtain the progress, %v", err) + } + if remain == 0 { + t.Fatalf("Unexpected progress remain, %d", remain) + } + + // Apply new states on top, ensuring state indexing can respond correctly + for i := dIndex + 1; i < len(roots); i++ { + if err := env.db.Update(roots[i], roots[i-1], uint64(i), env.nodes[i], env.states[i]); err != nil { + panic(fmt.Errorf("failed to update state changes, err: %w", err)) + } + } + remain, err = env.db.IndexProgress() + if err != nil { + t.Fatalf("Failed to obtain the progress, %v", err) + } + if remain != 0 { + t.Fatalf("Unexpected progress remain, %d", remain) + } + waitIndexing(env.db) + + // Ensure the truncated state histories become accessible + bRoot = env.db.tree.bottom().rootHash() + hr = newStateHistoryReader(env.db.diskdb, env.db.stateFreezer) + for i, root := range roots { + if root == bRoot { + break + } + if err := checkHistoricalState(env, root, uint64(i+1), hr); err != nil { + t.Fatal(err) + } + } +} diff --git a/triedb/pathdb/difflayer.go b/triedb/pathdb/difflayer.go index ac05b4a0fb..ae523c979c 100644 --- a/triedb/pathdb/difflayer.go +++ b/triedb/pathdb/difflayer.go @@ -34,7 +34,7 @@ type diffLayer struct { root common.Hash // Root hash to which this layer diff belongs to id uint64 // Corresponding state id block uint64 // Associated block number - nodes *nodeSet // Cached trie nodes indexed by owner and path + nodes *nodeSetWithOrigin // Cached trie nodes indexed by owner and path states *StateSetWithOrigin // Associated state changes along with origin value parent layer // Parent layer modified by this one, never nil, **can be changed** @@ -42,7 +42,7 @@ type diffLayer struct { } // newDiffLayer creates a new diff layer on top of an existing layer. -func newDiffLayer(parent layer, root common.Hash, id uint64, block uint64, nodes *nodeSet, states *StateSetWithOrigin) *diffLayer { +func newDiffLayer(parent layer, root common.Hash, id uint64, block uint64, nodes *nodeSetWithOrigin, states *StateSetWithOrigin) *diffLayer { dl := &diffLayer{ root: root, id: id, @@ -151,7 +151,7 @@ func (dl *diffLayer) storage(accountHash, storageHash common.Hash, depth int) ([ // update implements the layer interface, creating a new layer on top of the // existing layer tree with the specified data items. -func (dl *diffLayer) update(root common.Hash, id uint64, block uint64, nodes *nodeSet, states *StateSetWithOrigin) *diffLayer { +func (dl *diffLayer) update(root common.Hash, id uint64, block uint64, nodes *nodeSetWithOrigin, states *StateSetWithOrigin) *diffLayer { return newDiffLayer(dl, root, id, block, nodes, states) } diff --git a/triedb/pathdb/difflayer_test.go b/triedb/pathdb/difflayer_test.go index 83ed833486..0484fd9644 100644 --- a/triedb/pathdb/difflayer_test.go +++ b/triedb/pathdb/difflayer_test.go @@ -76,7 +76,7 @@ func benchmarkSearch(b *testing.B, depth int, total int) { nblob = common.CopyBytes(blob) } } - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return newDiffLayer(parent, common.Hash{}, 0, 0, NewNodeSetWithOrigin(nodes, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) } var layer layer layer = emptyLayer() @@ -118,7 +118,7 @@ func BenchmarkPersist(b *testing.B) { ) nodes[common.Hash{}][string(path)] = node } - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return newDiffLayer(parent, common.Hash{}, 0, 0, NewNodeSetWithOrigin(nodes, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) } for i := 0; i < b.N; i++ { b.StopTimer() @@ -156,7 +156,7 @@ func BenchmarkJournal(b *testing.B) { ) nodes[common.Hash{}][string(path)] = node } - return newDiffLayer(parent, common.Hash{}, 0, 0, newNodeSet(nodes), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + return newDiffLayer(parent, common.Hash{}, 0, 0, NewNodeSetWithOrigin(nodes, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) } var layer layer layer = emptyLayer() diff --git a/triedb/pathdb/disklayer.go b/triedb/pathdb/disklayer.go index 06f0a7285f..911959dfa9 100644 --- a/triedb/pathdb/disklayer.go +++ b/triedb/pathdb/disklayer.go @@ -26,6 +26,7 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" ) @@ -275,7 +276,7 @@ func (dl *diskLayer) storage(accountHash, storageHash common.Hash, depth int) ([ // If the layer is being generated, ensure the requested storage slot // has already been covered by the generator. - key := append(accountHash[:], storageHash[:]...) + key := storageKeySlice(accountHash, storageHash) marker := dl.genMarker() if marker != nil && bytes.Compare(key, marker) > 0 { return nil, errNotCoveredYet @@ -319,10 +320,98 @@ func (dl *diskLayer) storage(accountHash, storageHash common.Hash, depth int) ([ // update implements the layer interface, returning a new diff layer on top // with the given state set. -func (dl *diskLayer) update(root common.Hash, id uint64, block uint64, nodes *nodeSet, states *StateSetWithOrigin) *diffLayer { +func (dl *diskLayer) update(root common.Hash, id uint64, block uint64, nodes *nodeSetWithOrigin, states *StateSetWithOrigin) *diffLayer { return newDiffLayer(dl, root, id, block, nodes, states) } +// writeHistory stores the specified history and indexes if indexing is +// permitted. +// +// What's more, this function also returns a flag indicating whether the +// buffer flushing is required, ensuring the persistent state ID is always +// greater than or equal to the first history ID. +func (dl *diskLayer) writeHistory(typ historyType, diff *diffLayer) (bool, error) { + var ( + limit uint64 + freezer ethdb.AncientStore + indexer *historyIndexer + writeFunc func(writer ethdb.AncientWriter, dl *diffLayer) error + ) + switch typ { + case typeStateHistory: + freezer = dl.db.stateFreezer + indexer = dl.db.stateIndexer + writeFunc = writeStateHistory + limit = dl.db.config.StateHistory + case typeTrienodeHistory: + freezer = dl.db.trienodeFreezer + indexer = dl.db.trienodeIndexer + writeFunc = func(writer ethdb.AncientWriter, diff *diffLayer) error { + return writeTrienodeHistory(writer, diff, dl.db.config.FullValueCheckpoint) + } + // Skip the history commit if the trienode history is not permitted + if dl.db.config.TrienodeHistory < 0 { + return false, nil + } + limit = uint64(dl.db.config.TrienodeHistory) + default: + panic(fmt.Sprintf("unknown history type: %v", typ)) + } + // Short circuit if the history freezer is nil + if freezer == nil { + return false, nil + } + // Bail out with an error if writing the state history fails. + // This can happen, for example, if the device is full. + err := writeFunc(freezer, diff) + if err != nil { + return false, err + } + // Notify the history indexer for newly created history + if indexer != nil { + if err := indexer.extend(diff.stateID()); err != nil { + return false, err + } + } + // Determine if the persisted history object has exceeded the + // configured limitation. + if limit == 0 { + return false, nil + } + tail, err := freezer.Tail() + if err != nil { + return false, err + } // firstID = tail+1 + + // length = diff.stateID()-firstID+1 = diff.stateID()-tail + if diff.stateID()-tail <= limit { + return false, nil + } + newFirst := diff.stateID() - limit + 1 // the id of first history **after truncation** + + // In a rare case where the ID of the first history object (after tail + // truncation) exceeds the persisted state ID, we must take corrective + // steps: + // + // - Skip tail truncation temporarily, avoid the scenario that associated + // history of persistent state is removed + // + // - Force a commit of the cached dirty states into persistent state + // + // These measures ensure the persisted state ID always remains greater + // than or equal to the first history ID. + if persistentID := rawdb.ReadPersistentStateID(dl.db.diskdb); persistentID < newFirst { + log.Debug("Skip tail truncation", "type", typ, "persistentID", persistentID, "tailID", tail+1, "headID", diff.stateID(), "limit", limit) + return true, nil + } + pruned, err := truncateFromTail(freezer, typ, newFirst-1) + if err != nil { + return false, err + } + log.Debug("Pruned history", "type", typ, "items", pruned, "tailid", newFirst) + return false, nil +} + // commit merges the given bottom-most diff layer into the node buffer // and returns a newly constructed disk layer. Note the current disk // layer must be tagged as stale first to prevent re-access. @@ -333,35 +422,22 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { // Construct and store the state history first. If crash happens after storing // the state history but without flushing the corresponding states(journal), // the stored state history will be truncated from head in the next restart. - var ( - overflow bool - oldest uint64 - ) - if dl.db.freezer != nil { - // Bail out with an error if writing the state history fails. - // This can happen, for example, if the device is full. - err := writeHistory(dl.db.freezer, bottom) - if err != nil { - return nil, err - } - // Determine if the persisted history object has exceeded the configured - // limitation, set the overflow as true if so. - tail, err := dl.db.freezer.Tail() - if err != nil { - return nil, err - } - limit := dl.db.config.StateHistory - if limit != 0 && bottom.stateID()-tail > limit { - overflow = true - oldest = bottom.stateID() - limit + 1 // track the id of history **after truncation** - } - // Notify the state history indexer for newly created history - if dl.db.indexer != nil { - if err := dl.db.indexer.extend(bottom.stateID()); err != nil { - return nil, err - } - } + flushA, err := dl.writeHistory(typeStateHistory, bottom) + if err != nil { + return nil, err } + // Construct and store the trienode history first. If crash happens after + // storing the trienode history but without flushing the corresponding + // states(journal), the stored trienode history will be truncated from head + // in the next restart. + flushB, err := dl.writeHistory(typeTrienodeHistory, bottom) + if err != nil { + return nil, err + } + // Since the state history and trienode history may be configured with different + // lengths, the buffer will be flushed once either of them meets its threshold. + flush := flushA || flushB + // Mark the diskLayer as stale before applying any mutations on top. dl.stale = true @@ -373,21 +449,13 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { } rawdb.WriteStateID(dl.db.diskdb, bottom.rootHash(), bottom.stateID()) - // In a unique scenario where the ID of the oldest history object (after tail - // truncation) surpasses the persisted state ID, we take the necessary action - // of forcibly committing the cached dirty states to ensure that the persisted - // state ID remains higher. - persistedID := rawdb.ReadPersistentStateID(dl.db.diskdb) - if !force && persistedID < oldest { - force = true - } // Merge the trie nodes and flat states of the bottom-most diff layer into the // buffer as the combined layer. - combined := dl.buffer.commit(bottom.nodes, bottom.states.stateSet) + combined := dl.buffer.commit(bottom.nodes.nodeSet, bottom.states.stateSet) // Terminate the background state snapshot generation before mutating the // persistent state. - if combined.full() || force { + if combined.full() || force || flush { // Wait until the previous frozen buffer is fully flushed if dl.frozen != nil { if err := dl.frozen.waitFlush(); err != nil { @@ -418,7 +486,7 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { // Freeze the live buffer and schedule background flushing dl.frozen = combined - dl.frozen.flush(bottom.root, dl.db.diskdb, dl.db.freezer, progress, dl.nodes, dl.states, bottom.stateID(), func() { + dl.frozen.flush(bottom.root, dl.db.diskdb, []ethdb.AncientWriter{dl.db.stateFreezer, dl.db.trienodeFreezer}, progress, dl.nodes, dl.states, bottom.stateID(), func() { // Resume the background generation if it's not completed yet. // The generator is assumed to be available if the progress is // not nil. @@ -431,8 +499,8 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { } }) // Block until the frozen buffer is fully flushed out if the async flushing - // is not allowed, or if the oldest history surpasses the persisted state ID. - if dl.db.config.NoAsyncFlush || persistedID < oldest { + // is not allowed. + if dl.db.config.NoAsyncFlush { if err := dl.frozen.waitFlush(); err != nil { return nil, err } @@ -445,20 +513,11 @@ func (dl *diskLayer) commit(bottom *diffLayer, force bool) (*diskLayer, error) { if dl.generator != nil { ndl.setGenerator(dl.generator) } - // To remove outdated history objects from the end, we set the 'tail' parameter - // to 'oldest-1' due to the offset between the freezer index and the history ID. - if overflow { - pruned, err := truncateFromTail(ndl.db.diskdb, ndl.db.freezer, oldest-1) - if err != nil { - return nil, err - } - log.Debug("Pruned state history", "items", pruned, "tailid", oldest) - } return ndl, nil } // revert applies the given state history and return a reverted disk layer. -func (dl *diskLayer) revert(h *history) (*diskLayer, error) { +func (dl *diskLayer) revert(h *stateHistory) (*diskLayer, error) { start := time.Now() if h.meta.root != dl.rootHash() { return nil, errUnexpectedHistory @@ -483,9 +542,14 @@ func (dl *diskLayer) revert(h *history) (*diskLayer, error) { dl.stale = true - // Unindex the corresponding state history - if dl.db.indexer != nil { - if err := dl.db.indexer.shorten(dl.id); err != nil { + // Unindex the corresponding history + if dl.db.stateIndexer != nil { + if err := dl.db.stateIndexer.shorten(dl.id); err != nil { + return nil, err + } + } + if dl.db.trienodeIndexer != nil { + if err := dl.db.trienodeIndexer.shorten(dl.id); err != nil { return nil, err } } diff --git a/triedb/pathdb/execute.go b/triedb/pathdb/execute.go index aa4bd8b44b..4c1cafec12 100644 --- a/triedb/pathdb/execute.go +++ b/triedb/pathdb/execute.go @@ -59,13 +59,19 @@ func apply(db database.NodeDatabase, prevRoot common.Hash, postRoot common.Hash, rawStorageKey: rawStorageKey, nodes: trienode.NewMergedNodeSet(), } + var deletes []common.Address for addr, account := range accounts { - var err error if len(account) == 0 { - err = deleteAccount(ctx, db, addr) + deletes = append(deletes, addr) } else { - err = updateAccount(ctx, db, addr) + err := updateAccount(ctx, db, addr) + if err != nil { + return nil, fmt.Errorf("failed to revert state, err: %w", err) + } } + } + for _, addr := range deletes { + err := deleteAccount(ctx, db, addr) if err != nil { return nil, fmt.Errorf("failed to revert state, err: %w", err) } @@ -77,7 +83,7 @@ func apply(db database.NodeDatabase, prevRoot common.Hash, postRoot common.Hash, if err := ctx.nodes.Merge(result); err != nil { return nil, err } - return ctx.nodes.Flatten(), nil + return ctx.nodes.Nodes(), nil } // updateAccount the account was present in prev-state, and may or may not @@ -108,17 +114,23 @@ func updateAccount(ctx *context, db database.NodeDatabase, addr common.Address) if err != nil { return err } + var deletes []common.Hash for key, val := range ctx.storages[addr] { tkey := key if ctx.rawStorageKey { tkey = crypto.Keccak256Hash(key.Bytes()) } - var err error if len(val) == 0 { - err = st.Delete(tkey.Bytes()) + deletes = append(deletes, tkey) } else { - err = st.Update(tkey.Bytes(), val) + err := st.Update(tkey.Bytes(), val) + if err != nil { + return err + } } + } + for _, tkey := range deletes { + err := st.Delete(tkey.Bytes()) if err != nil { return err } diff --git a/triedb/pathdb/flush.go b/triedb/pathdb/flush.go index 6563dbccff..4f816cf6a6 100644 --- a/triedb/pathdb/flush.go +++ b/triedb/pathdb/flush.go @@ -116,15 +116,16 @@ func writeStates(batch ethdb.Batch, genMarker []byte, accountData map[common.Has continue } slots += 1 + key := storageKeySlice(addrHash, storageHash) if len(blob) == 0 { rawdb.DeleteStorageSnapshot(batch, addrHash, storageHash) if clean != nil { - clean.Set(append(addrHash[:], storageHash[:]...), nil) + clean.Set(key, nil) } } else { rawdb.WriteStorageSnapshot(batch, addrHash, storageHash, blob) if clean != nil { - clean.Set(append(addrHash[:], storageHash[:]...), blob) + clean.Set(key, blob) } } } diff --git a/triedb/pathdb/generate.go b/triedb/pathdb/generate.go index 2efbbbb4e1..d3d26fff26 100644 --- a/triedb/pathdb/generate.go +++ b/triedb/pathdb/generate.go @@ -148,6 +148,7 @@ func (g *generator) stop() { g.abort <- ch <-ch g.running = false + log.Debug("Snapshot generation has been terminated") } // completed returns the flag indicating if the whole generation is done. diff --git a/triedb/pathdb/history.go b/triedb/pathdb/history.go index 47f224170d..820c3c03bf 100644 --- a/triedb/pathdb/history.go +++ b/triedb/pathdb/history.go @@ -1,4 +1,4 @@ -// Copyright 2023 The go-ethereum Authors +// Copyright 2025 The go-ethereum Authors // This file is part of the go-ethereum library. // // The go-ethereum library is free software: you can redistribute it and/or modify @@ -12,592 +12,263 @@ // GNU Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public License -// along with the go-ethereum library. If not, see . +// along with the go-ethereum library. If not, see | State 1 |---->| ... |---->| State n | -// +------------+ +---------+ +---------+ +---------+ -// -// +-----------+ +------+ +-----------+ -// | History 1 |----> | ... |---->| History n | -// +-----------+ +------+ +-----------+ -// -// # Rollback -// -// If the system wants to roll back to a previous state n, it needs to ensure -// all history objects from n+1 up to the current disk layer are existent. The -// history objects are applied to the state in reverse order, starting from the -// current disk layer. +// historyType represents the category of historical data. +type historyType uint8 const ( - accountIndexSize = common.AddressLength + 13 // The length of encoded account index - slotIndexSize = common.HashLength + 5 // The length of encoded slot index - historyMetaSize = 9 + 2*common.HashLength // The length of encoded history meta + // typeStateHistory indicates history data related to account or storage changes. + typeStateHistory historyType = 0 - stateHistoryV0 = uint8(0) // initial version of state history structure - stateHistoryV1 = uint8(1) // use the storage slot raw key as the identifier instead of the key hash - historyVersion = stateHistoryV1 // the default state history version + // typeTrienodeHistory indicates history data related to trie node changes. + typeTrienodeHistory historyType = 1 ) -// Each state history entry is consisted of five elements: -// -// # metadata -// This object contains a few meta fields, such as the associated state root, -// block number, version tag and so on. This object may contain an extra -// accountHash list which means the storage changes belong to these accounts -// are not complete due to large contract destruction. The incomplete history -// can not be used for rollback and serving archive state request. -// -// # account index -// This object contains some index information of account. For example, offset -// and length indicate the location of the data belonging to the account. Besides, -// storageOffset and storageSlots indicate the storage modification location -// belonging to the account. -// -// The size of each account index is *fixed*, and all indexes are sorted -// lexicographically. Thus binary search can be performed to quickly locate a -// specific account. -// -// # account data -// Account data is a concatenated byte stream composed of all account data. -// The account data can be solved by the offset and length info indicated -// by corresponding account index. -// -// fixed size -// ^ ^ -// / \ -// +-----------------+-----------------+----------------+-----------------+ -// | Account index 1 | Account index 2 | ... | Account index N | -// +-----------------+-----------------+----------------+-----------------+ -// | -// | length -// offset |----------------+ -// v v -// +----------------+----------------+----------------+----------------+ -// | Account data 1 | Account data 2 | ... | Account data N | -// +----------------+----------------+----------------+----------------+ -// -// # storage index -// This object is similar with account index. It's also fixed size and contains -// the location info of storage slot data. -// -// # storage data -// Storage data is a concatenated byte stream composed of all storage slot data. -// The storage slot data can be solved by the location info indicated by -// corresponding account index and storage slot index. -// -// fixed size -// ^ ^ -// / \ -// +-----------------+-----------------+----------------+-----------------+ -// | Account index 1 | Account index 2 | ... | Account index N | -// +-----------------+-----------------+----------------+-----------------+ -// | -// | storage slots -// storage offset |-----------------------------------------------------+ -// v v -// +-----------------+-----------------+-----------------+ -// | storage index 1 | storage index 2 | storage index 3 | -// +-----------------+-----------------+-----------------+ -// | length -// offset |-------------+ -// v v -// +-------------+ -// | slot data 1 | -// +-------------+ - -// accountIndex describes the metadata belonging to an account. -type accountIndex struct { - address common.Address // The address of account - length uint8 // The length of account data, size limited by 255 - offset uint32 // The offset of item in account data table - storageOffset uint32 // The offset of storage index in storage index table - storageSlots uint32 // The number of mutated storage slots belonging to the account -} - -// encode packs account index into byte stream. -func (i *accountIndex) encode() []byte { - var buf [accountIndexSize]byte - copy(buf[:], i.address.Bytes()) - buf[common.AddressLength] = i.length - binary.BigEndian.PutUint32(buf[common.AddressLength+1:], i.offset) - binary.BigEndian.PutUint32(buf[common.AddressLength+5:], i.storageOffset) - binary.BigEndian.PutUint32(buf[common.AddressLength+9:], i.storageSlots) - return buf[:] -} - -// decode unpacks account index from byte stream. -func (i *accountIndex) decode(blob []byte) { - i.address = common.BytesToAddress(blob[:common.AddressLength]) - i.length = blob[common.AddressLength] - i.offset = binary.BigEndian.Uint32(blob[common.AddressLength+1:]) - i.storageOffset = binary.BigEndian.Uint32(blob[common.AddressLength+5:]) - i.storageSlots = binary.BigEndian.Uint32(blob[common.AddressLength+9:]) -} - -// slotIndex describes the metadata belonging to a storage slot. -type slotIndex struct { - // the identifier of the storage slot. Specifically - // in v0, it's the hash of the raw storage slot key (32 bytes); - // in v1, it's the raw storage slot key (32 bytes); - id common.Hash - length uint8 // The length of storage slot, up to 32 bytes defined in protocol - offset uint32 // The offset of item in storage slot data table -} - -// encode packs slot index into byte stream. -func (i *slotIndex) encode() []byte { - var buf [slotIndexSize]byte - copy(buf[:common.HashLength], i.id.Bytes()) - buf[common.HashLength] = i.length - binary.BigEndian.PutUint32(buf[common.HashLength+1:], i.offset) - return buf[:] -} - -// decode unpack slot index from the byte stream. -func (i *slotIndex) decode(blob []byte) { - i.id = common.BytesToHash(blob[:common.HashLength]) - i.length = blob[common.HashLength] - i.offset = binary.BigEndian.Uint32(blob[common.HashLength+1:]) -} - -// meta describes the meta data of state history object. -type meta struct { - version uint8 // version tag of history object - parent common.Hash // prev-state root before the state transition - root common.Hash // post-state root after the state transition - block uint64 // associated block number -} - -// encode packs the meta object into byte stream. -func (m *meta) encode() []byte { - buf := make([]byte, historyMetaSize) - buf[0] = m.version - copy(buf[1:1+common.HashLength], m.parent.Bytes()) - copy(buf[1+common.HashLength:1+2*common.HashLength], m.root.Bytes()) - binary.BigEndian.PutUint64(buf[1+2*common.HashLength:historyMetaSize], m.block) - return buf[:] -} - -// decode unpacks the meta object from byte stream. -func (m *meta) decode(blob []byte) error { - if len(blob) < 1 { - return errors.New("no version tag") - } - switch blob[0] { - case stateHistoryV0, stateHistoryV1: - if len(blob) != historyMetaSize { - return fmt.Errorf("invalid state history meta, len: %d", len(blob)) - } - m.version = blob[0] - m.parent = common.BytesToHash(blob[1 : 1+common.HashLength]) - m.root = common.BytesToHash(blob[1+common.HashLength : 1+2*common.HashLength]) - m.block = binary.BigEndian.Uint64(blob[1+2*common.HashLength : historyMetaSize]) - return nil +// String returns the string format representation. +func (h historyType) String() string { + switch h { + case typeStateHistory: + return "state" + case typeTrienodeHistory: + return "trienode" default: - return fmt.Errorf("unknown version %d", blob[0]) + return fmt.Sprintf("unknown type: %d", h) } } -// history represents a set of state changes belong to a block along with -// the metadata including the state roots involved in the state transition. -// State history objects in disk are linked with each other by a unique id -// (8-bytes integer), the oldest state history object can be pruned on demand -// in order to control the storage size. -type history struct { - meta *meta // Meta data of history - accounts map[common.Address][]byte // Account data keyed by its address hash - accountList []common.Address // Sorted account hash list - storages map[common.Address]map[common.Hash][]byte // Storage data keyed by its address hash and slot hash - storageList map[common.Address][]common.Hash // Sorted slot hash list -} +// elementType represents the category of state element. +type elementType uint8 -// newHistory constructs the state history object with provided state change set. -func newHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *history { - var ( - accountList = slices.SortedFunc(maps.Keys(accounts), common.Address.Cmp) - storageList = make(map[common.Address][]common.Hash) - ) - for addr, slots := range storages { - storageList[addr] = slices.SortedFunc(maps.Keys(slots), common.Hash.Cmp) - } - version := historyVersion - if !rawStorageKey { - version = stateHistoryV0 - } - return &history{ - meta: &meta{ - version: version, - parent: parent, - root: root, - block: block, - }, - accounts: accounts, - accountList: accountList, - storages: storages, - storageList: storageList, +const ( + typeAccount elementType = 0 // represents the account data + typeStorage elementType = 1 // represents the storage slot data + typeTrienode elementType = 2 // represents the trie node data +) + +// String returns the string format representation. +func (e elementType) String() string { + switch e { + case typeAccount: + return "account" + case typeStorage: + return "storage" + case typeTrienode: + return "trienode" + default: + return fmt.Sprintf("unknown element type: %d", e) } } -// stateSet returns the state set, keyed by the hash of the account address -// and the hash of the storage slot key. -func (h *history) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) { - var ( - accounts = make(map[common.Hash][]byte) - storages = make(map[common.Hash]map[common.Hash][]byte) - ) - for addr, blob := range h.accounts { - addrHash := crypto.Keccak256Hash(addr.Bytes()) - accounts[addrHash] = blob - - storage, exist := h.storages[addr] - if !exist { - continue - } - if h.meta.version == stateHistoryV0 { - storages[addrHash] = storage - } else { - subset := make(map[common.Hash][]byte) - for key, slot := range storage { - subset[crypto.Keccak256Hash(key.Bytes())] = slot - } - storages[addrHash] = subset - } +// toHistoryType maps an element type to its corresponding history type. +func toHistoryType(typ elementType) historyType { + if typ == typeAccount || typ == typeStorage { + return typeStateHistory } - return accounts, storages + if typ == typeTrienode { + return typeTrienodeHistory + } + panic(fmt.Sprintf("unknown element type %v", typ)) } -// encode serializes the state history and returns four byte streams represent -// concatenated account/storage data, account/storage indexes respectively. -func (h *history) encode() ([]byte, []byte, []byte, []byte) { - var ( - slotNumber uint32 // the number of processed slots - accountData []byte // the buffer for concatenated account data - storageData []byte // the buffer for concatenated storage data - accountIndexes []byte // the buffer for concatenated account index - storageIndexes []byte // the buffer for concatenated storage index - ) - for _, addr := range h.accountList { - accIndex := accountIndex{ - address: addr, - length: uint8(len(h.accounts[addr])), - offset: uint32(len(accountData)), - } - slots, exist := h.storages[addr] - if exist { - // Encode storage slots in order - for _, slotHash := range h.storageList[addr] { - sIndex := slotIndex{ - id: slotHash, - length: uint8(len(slots[slotHash])), - offset: uint32(len(storageData)), - } - storageData = append(storageData, slots[slotHash]...) - storageIndexes = append(storageIndexes, sIndex.encode()...) - } - // Fill up the storage meta in account index - accIndex.storageOffset = slotNumber - accIndex.storageSlots = uint32(len(slots)) - slotNumber += uint32(len(slots)) - } - accountData = append(accountData, h.accounts[addr]...) - accountIndexes = append(accountIndexes, accIndex.encode()...) - } - return accountData, storageData, accountIndexes, storageIndexes +// stateIdent represents the identifier of a state element, which can be +// an account, a storage slot or a trienode. +type stateIdent struct { + typ elementType + + // The hash of the account address. This is used instead of the raw account + // address is to align the traversal order with the Merkle-Patricia-Trie. + addressHash common.Hash + + // The hash of the storage slot key. This is used instead of the raw slot key + // because, in legacy state histories (prior to the Cancun fork), the slot + // identifier is the hash of the key, and the original key (preimage) cannot + // be recovered. To maintain backward compatibility, the key hash is used. + // + // Meanwhile, using the storage key hash also preserve the traversal order + // with Merkle-Patricia-Trie. + // + // This field is null if the identifier refers to an account or a trie node. + storageHash common.Hash + + // The trie node path within the trie. + // + // This field is null if the identifier refers to an account or a storage slot. + // String type is chosen to make stateIdent comparable. + path string } -// decoder wraps the byte streams for decoding with extra meta fields. -type decoder struct { - accountData []byte // the buffer for concatenated account data - storageData []byte // the buffer for concatenated storage data - accountIndexes []byte // the buffer for concatenated account index - storageIndexes []byte // the buffer for concatenated storage index - - lastAccount *common.Address // the address of last resolved account - lastAccountRead uint32 // the read-cursor position of account data - lastSlotIndexRead uint32 // the read-cursor position of storage slot index - lastSlotDataRead uint32 // the read-cursor position of storage slot data +// String returns the string format state identifier. +func (ident stateIdent) String() string { + if ident.typ == typeAccount { + return ident.addressHash.Hex() + } + if ident.typ == typeStorage { + return ident.addressHash.Hex() + ident.storageHash.Hex() + } + return ident.addressHash.Hex() + ident.path } -// verify validates the provided byte streams for decoding state history. A few -// checks will be performed to quickly detect data corruption. The byte stream -// is regarded as corrupted if: -// -// - account indexes buffer is empty(empty state set is invalid) -// - account indexes/storage indexer buffer is not aligned -// -// note, these situations are allowed: -// -// - empty account data: all accounts were not present -// - empty storage set: no slots are modified -func (r *decoder) verify() error { - if len(r.accountIndexes)%accountIndexSize != 0 || len(r.accountIndexes) == 0 { - return fmt.Errorf("invalid account index, len: %d", len(r.accountIndexes)) +func (ident stateIdent) bloomSize() int { + if ident.typ == typeAccount { + return 0 } - if len(r.storageIndexes)%slotIndexSize != 0 { - return fmt.Errorf("invalid storage index, len: %d", len(r.storageIndexes)) + if ident.typ == typeStorage { + return 0 } + scheme := accountIndexScheme + if ident.addressHash != (common.Hash{}) { + scheme = storageIndexScheme + } + return scheme.getBitmapSize(len(ident.path)) +} + +// newAccountIdent constructs a state identifier for an account. +func newAccountIdent(addressHash common.Hash) stateIdent { + return stateIdent{ + typ: typeAccount, + addressHash: addressHash, + } +} + +// newStorageIdent constructs a state identifier for a storage slot. +// The address denotes the address hash of the associated account; +// the storageHash denotes the hash of the raw storage slot key; +func newStorageIdent(addressHash common.Hash, storageHash common.Hash) stateIdent { + return stateIdent{ + typ: typeStorage, + addressHash: addressHash, + storageHash: storageHash, + } +} + +// newTrienodeIdent constructs a state identifier for a trie node. +// The address denotes the address hash of the associated account; +// the path denotes the path of the node within the trie; +func newTrienodeIdent(addressHash common.Hash, path string) stateIdent { + return stateIdent{ + typ: typeTrienode, + addressHash: addressHash, + path: path, + } +} + +// stateIdentQuery is the extension of stateIdent by adding the raw storage key. +type stateIdentQuery struct { + stateIdent + + address common.Address + storageKey common.Hash +} + +// newAccountIdentQuery constructs a state identifier for an account. +func newAccountIdentQuery(address common.Address, addressHash common.Hash) stateIdentQuery { + return stateIdentQuery{ + stateIdent: newAccountIdent(addressHash), + address: address, + } +} + +// newStorageIdentQuery constructs a state identifier for a storage slot. +// the address denotes the address of the associated account; +// the addressHash denotes the address hash of the associated account; +// the storageKey denotes the raw storage slot key; +// the storageHash denotes the hash of the raw storage slot key; +func newStorageIdentQuery(address common.Address, addressHash common.Hash, storageKey common.Hash, storageHash common.Hash) stateIdentQuery { + return stateIdentQuery{ + stateIdent: newStorageIdent(addressHash, storageHash), + address: address, + storageKey: storageKey, + } +} + +// indexElem defines the element for indexing. +type indexElem interface { + key() stateIdent + ext() []uint16 +} + +type accountIndexElem struct { + addressHash common.Hash +} + +func (a accountIndexElem) key() stateIdent { + return stateIdent{ + typ: typeAccount, + addressHash: a.addressHash, + } +} + +func (a accountIndexElem) ext() []uint16 { return nil } -// readAccount parses the account from the byte stream with specified position. -func (r *decoder) readAccount(pos int) (accountIndex, []byte, error) { - // Decode account index from the index byte stream. - var index accountIndex - if (pos+1)*accountIndexSize > len(r.accountIndexes) { - return accountIndex{}, nil, errors.New("account data buffer is corrupted") - } - index.decode(r.accountIndexes[pos*accountIndexSize : (pos+1)*accountIndexSize]) - - // Perform validation before parsing account data, ensure - // - account is sorted in order in byte stream - // - account data is strictly encoded with no gap inside - // - account data is not out-of-slice - if r.lastAccount != nil { // zero address is possible - if bytes.Compare(r.lastAccount.Bytes(), index.address.Bytes()) >= 0 { - return accountIndex{}, nil, errors.New("account is not in order") - } - } - if index.offset != r.lastAccountRead { - return accountIndex{}, nil, errors.New("account data buffer is gaped") - } - last := index.offset + uint32(index.length) - if uint32(len(r.accountData)) < last { - return accountIndex{}, nil, errors.New("account data buffer is corrupted") - } - data := r.accountData[index.offset:last] - - r.lastAccount = &index.address - r.lastAccountRead = last - - return index, data, nil +type storageIndexElem struct { + addressHash common.Hash + storageHash common.Hash } -// readStorage parses the storage slots from the byte stream with specified account. -func (r *decoder) readStorage(accIndex accountIndex) ([]common.Hash, map[common.Hash][]byte, error) { - var ( - last *common.Hash - count = int(accIndex.storageSlots) - list = make([]common.Hash, 0, count) - storage = make(map[common.Hash][]byte, count) - ) - for j := 0; j < count; j++ { - var ( - index slotIndex - start = (accIndex.storageOffset + uint32(j)) * uint32(slotIndexSize) - end = (accIndex.storageOffset + uint32(j+1)) * uint32(slotIndexSize) - ) - // Perform validation before parsing storage slot data, ensure - // - slot index is not out-of-slice - // - slot data is not out-of-slice - // - slot is sorted in order in byte stream - // - slot indexes is strictly encoded with no gap inside - // - slot data is strictly encoded with no gap inside - if start != r.lastSlotIndexRead { - return nil, nil, errors.New("storage index buffer is gapped") - } - if uint32(len(r.storageIndexes)) < end { - return nil, nil, errors.New("storage index buffer is corrupted") - } - index.decode(r.storageIndexes[start:end]) - - if last != nil { - if bytes.Compare(last.Bytes(), index.id.Bytes()) >= 0 { - return nil, nil, fmt.Errorf("storage slot is not in order, last: %x, current: %x", *last, index.id) - } - } - if index.offset != r.lastSlotDataRead { - return nil, nil, errors.New("storage data buffer is gapped") - } - sEnd := index.offset + uint32(index.length) - if uint32(len(r.storageData)) < sEnd { - return nil, nil, errors.New("storage data buffer is corrupted") - } - storage[index.id] = r.storageData[r.lastSlotDataRead:sEnd] - list = append(list, index.id) - - last = &index.id - r.lastSlotIndexRead = end - r.lastSlotDataRead = sEnd +func (a storageIndexElem) key() stateIdent { + return stateIdent{ + typ: typeStorage, + addressHash: a.addressHash, + storageHash: a.storageHash, } - return list, storage, nil } -// decode deserializes the account and storage data from the provided byte stream. -func (h *history) decode(accountData, storageData, accountIndexes, storageIndexes []byte) error { - var ( - count = len(accountIndexes) / accountIndexSize - accounts = make(map[common.Address][]byte, count) - storages = make(map[common.Address]map[common.Hash][]byte) - accountList = make([]common.Address, 0, count) - storageList = make(map[common.Address][]common.Hash) - - r = &decoder{ - accountData: accountData, - storageData: storageData, - accountIndexes: accountIndexes, - storageIndexes: storageIndexes, - } - ) - if err := r.verify(); err != nil { - return err - } - for i := 0; i < count; i++ { - // Resolve account first - accIndex, accData, err := r.readAccount(i) - if err != nil { - return err - } - accounts[accIndex.address] = accData - accountList = append(accountList, accIndex.address) - - // Resolve storage slots - slotList, slotData, err := r.readStorage(accIndex) - if err != nil { - return err - } - if len(slotList) > 0 { - storageList[accIndex.address] = slotList - storages[accIndex.address] = slotData - } - } - h.accounts = accounts - h.accountList = accountList - h.storages = storages - h.storageList = storageList +func (a storageIndexElem) ext() []uint16 { return nil } -// readHistory reads and decodes the state history object by the given id. -func readHistory(reader ethdb.AncientReader, id uint64) (*history, error) { - mData, accountIndexes, storageIndexes, accountData, storageData, err := rawdb.ReadStateHistory(reader, id) - if err != nil { - return nil, err - } - var m meta - if err := m.decode(mData); err != nil { - return nil, err - } - h := history{meta: &m} - if err := h.decode(accountData, storageData, accountIndexes, storageIndexes); err != nil { - return nil, err - } - return &h, nil +type trienodeIndexElem struct { + owner common.Hash + path string + data []uint16 } -// readHistories reads and decodes a list of state histories with the specific -// history range. -func readHistories(freezer ethdb.AncientReader, start uint64, count uint64) ([]*history, error) { - var histories []*history - metaList, aIndexList, sIndexList, aDataList, sDataList, err := rawdb.ReadStateHistoryList(freezer, start, count) - if err != nil { - return nil, err +func (a trienodeIndexElem) key() stateIdent { + return stateIdent{ + typ: typeTrienode, + addressHash: a.owner, + path: a.path, } - for i := 0; i < len(metaList); i++ { - var m meta - if err := m.decode(metaList[i]); err != nil { - return nil, err - } - h := history{meta: &m} - if err := h.decode(aDataList[i], sDataList[i], aIndexList[i], sIndexList[i]); err != nil { - return nil, err - } - histories = append(histories, &h) - } - return histories, nil } -// writeHistory persists the state history with the provided state set. -func writeHistory(writer ethdb.AncientWriter, dl *diffLayer) error { - // Short circuit if state set is not available. - if dl.states == nil { - return errors.New("state change set is not available") - } - var ( - start = time.Now() - history = newHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states.accountOrigin, dl.states.storageOrigin, dl.states.rawStorageKey) - ) - accountData, storageData, accountIndex, storageIndex := history.encode() - dataSize := common.StorageSize(len(accountData) + len(storageData)) - indexSize := common.StorageSize(len(accountIndex) + len(storageIndex)) - - // Write history data into five freezer table respectively. - if err := rawdb.WriteStateHistory(writer, dl.stateID(), history.meta.encode(), accountIndex, storageIndex, accountData, storageData); err != nil { - return err - } - historyDataBytesMeter.Mark(int64(dataSize)) - historyIndexBytesMeter.Mark(int64(indexSize)) - historyBuildTimeMeter.UpdateSince(start) - log.Debug("Stored state history", "id", dl.stateID(), "block", dl.block, "data", dataSize, "index", indexSize, "elapsed", common.PrettyDuration(time.Since(start))) - - return nil +func (a trienodeIndexElem) ext() []uint16 { + return a.data } -// checkHistories retrieves a batch of meta objects with the specified range -// and performs the callback on each item. -func checkHistories(reader ethdb.AncientReader, start, count uint64, check func(*meta) error) error { - for count > 0 { - number := count - if number > 10000 { - number = 10000 // split the big read into small chunks - } - blobs, err := rawdb.ReadStateHistoryMetaList(reader, start, number) - if err != nil { - return err - } - for _, blob := range blobs { - var dec meta - if err := dec.decode(blob); err != nil { - return err - } - if err := check(&dec); err != nil { - return err - } - } - count -= uint64(len(blobs)) - start += uint64(len(blobs)) - } - return nil +// history defines the interface of historical data, shared by stateHistory +// and trienodeHistory. +type history interface { + // typ returns the historical data type held in the history. + typ() historyType + + // forEach returns an iterator to traverse the state entries in the history. + forEach() iter.Seq[indexElem] } -// truncateFromHead removes the extra state histories from the head with the given -// parameters. It returns the number of items removed from the head. -func truncateFromHead(db ethdb.Batcher, store ethdb.AncientStore, nhead uint64) (int, error) { +var ( + errHeadTruncationOutOfRange = errors.New("history head truncation out of range") + errTailTruncationOutOfRange = errors.New("history tail truncation out of range") +) + +// truncateFromHead removes excess elements from the head of the freezer based +// on the given parameters. It returns the number of items that were removed. +func truncateFromHead(store ethdb.AncientStore, typ historyType, nhead uint64) (int, error) { ohead, err := store.Ancients() if err != nil { return 0, err @@ -606,40 +277,28 @@ func truncateFromHead(db ethdb.Batcher, store ethdb.AncientStore, nhead uint64) if err != nil { return 0, err } - // Ensure that the truncation target falls within the specified range. + // Ensure that the truncation target falls within the valid range. if ohead < nhead || nhead < otail { - return 0, fmt.Errorf("out of range, tail: %d, head: %d, target: %d", otail, ohead, nhead) + return 0, fmt.Errorf("%w, %s, tail: %d, head: %d, target: %d", errHeadTruncationOutOfRange, typ, otail, ohead, nhead) } // Short circuit if nothing to truncate. if ohead == nhead { return 0, nil } - // Load the meta objects in range [nhead+1, ohead] - blobs, err := rawdb.ReadStateHistoryMetaList(store, nhead+1, ohead-nhead) - if err != nil { - return 0, err - } - batch := db.NewBatch() - for _, blob := range blobs { - var m meta - if err := m.decode(blob); err != nil { - return 0, err - } - rawdb.DeleteStateID(batch, m.root) - } - if err := batch.Write(); err != nil { - return 0, err - } + log.Info("Truncating from head", "type", typ.String(), "ohead", ohead, "tail", otail, "nhead", nhead) + ohead, err = store.TruncateHead(nhead) if err != nil { return 0, err } + // Associated root->id mappings are left in the database and wait + // for overwriting. return int(ohead - nhead), nil } -// truncateFromTail removes the extra state histories from the tail with the given -// parameters. It returns the number of items removed from the tail. -func truncateFromTail(db ethdb.Batcher, store ethdb.AncientStore, ntail uint64) (int, error) { +// truncateFromTail removes excess elements from the end of the freezer based +// on the given parameters. It returns the number of items that were removed. +func truncateFromTail(store ethdb.AncientStore, typ historyType, ntail uint64) (int, error) { ohead, err := store.Ancients() if err != nil { return 0, err @@ -648,33 +307,148 @@ func truncateFromTail(db ethdb.Batcher, store ethdb.AncientStore, ntail uint64) if err != nil { return 0, err } - // Ensure that the truncation target falls within the specified range. + // Ensure that the truncation target falls within the valid range. if otail > ntail || ntail > ohead { - return 0, fmt.Errorf("out of range, tail: %d, head: %d, target: %d", otail, ohead, ntail) + return 0, fmt.Errorf("%w, %s, tail: %d, head: %d, target: %d", errTailTruncationOutOfRange, typ, otail, ohead, ntail) } // Short circuit if nothing to truncate. if otail == ntail { return 0, nil } - // Load the meta objects in range [otail+1, ntail] - blobs, err := rawdb.ReadStateHistoryMetaList(store, otail+1, ntail-otail) - if err != nil { - return 0, err - } - batch := db.NewBatch() - for _, blob := range blobs { - var m meta - if err := m.decode(blob); err != nil { - return 0, err - } - rawdb.DeleteStateID(batch, m.root) - } - if err := batch.Write(); err != nil { - return 0, err - } otail, err = store.TruncateTail(ntail) if err != nil { return 0, err } + // Associated root->id mappings are left in the database. return int(ntail - otail), nil } + +// purgeHistory resets the history and also purges the associated index data. +func purgeHistory(store ethdb.ResettableAncientStore, disk ethdb.KeyValueStore, typ historyType) { + if store == nil { + return + } + frozen, err := store.Ancients() + if err != nil { + log.Crit("Failed to retrieve head of history", "type", typ, "err", err) + } + if frozen == 0 { + return + } + // Purge all state history indexing data first + batch := disk.NewBatch() + if typ == typeStateHistory { + rawdb.DeleteStateHistoryIndexMetadata(batch) + rawdb.DeleteStateHistoryIndexes(batch) + } else { + rawdb.DeleteTrienodeHistoryIndexMetadata(batch) + rawdb.DeleteTrienodeHistoryIndexes(batch) + } + if err := batch.Write(); err != nil { + log.Crit("Failed to purge history index", "type", typ, "err", err) + } + if err := store.Reset(); err != nil { + log.Crit("Failed to reset history", "type", typ, "err", err) + } + log.Info("Truncated extraneous history", "type", typ) +} + +// syncHistory explicitly sync the provided history stores. +func syncHistory(stores ...ethdb.AncientWriter) error { + for _, store := range stores { + if store == nil { + continue + } + if err := store.SyncAncient(); err != nil { + return err + } + } + return nil +} + +// repairHistory truncates any leftover history objects in either the state +// history or the trienode history, which may occur due to an unclean shutdown +// or other unexpected events. +// +// Additionally, this mechanism ensures that the state history and trienode +// history remain aligned. Since the trienode history is optional and not +// required by regular users, a gap between the trienode history and the +// persistent state may appear if the trienode history was disabled during the +// previous run. This process detects and resolves such gaps, preventing +// unexpected panics. +func repairHistory(db ethdb.Database, isVerkle bool, readOnly bool, stateID uint64, enableTrienode bool) (ethdb.ResettableAncientStore, ethdb.ResettableAncientStore, error) { + ancient, err := db.AncientDatadir() + if err != nil { + // TODO error out if ancient store is disabled. A tons of unit tests + // disable the ancient store thus the error here will immediately fail + // all of them. Fix the tests first. + return nil, nil, nil + } + // State history is mandatory as it is the key component that ensures + // resilience to deep reorgs. + states, err := rawdb.NewStateFreezer(ancient, isVerkle, readOnly) + if err != nil { + log.Crit("Failed to open state history freezer", "err", err) + } + + // Trienode history is optional and only required for building archive + // node with state proofs. + var trienodes ethdb.ResettableAncientStore + if enableTrienode { + trienodes, err = rawdb.NewTrienodeFreezer(ancient, isVerkle, readOnly) + if err != nil { + log.Crit("Failed to open trienode history freezer", "err", err) + } + } + + // Reset the both histories if the trie database is not initialized yet. + // This action is necessary because these histories are not expected + // to exist without an initialized trie database. + if stateID == 0 { + purgeHistory(states, db, typeStateHistory) + purgeHistory(trienodes, db, typeTrienodeHistory) + return states, trienodes, nil + } + // Truncate excessive history entries in either the state history or + // the trienode history, ensuring both histories remain aligned with + // the state. + head, err := states.Ancients() + if err != nil { + return nil, nil, err + } + if stateID > head { + return nil, nil, fmt.Errorf("gap between state [#%d] and state history [#%d]", stateID, head) + } + if trienodes != nil { + th, err := trienodes.Ancients() + if err != nil { + return nil, nil, err + } + if stateID > th { + return nil, nil, fmt.Errorf("gap between state [#%d] and trienode history [#%d]", stateID, th) + } + if th != head { + log.Info("Histories are not aligned with each other", "state", head, "trienode", th) + head = min(head, th) + } + } + head = min(head, stateID) + + // Truncate the extra history elements above in freezer in case it's not + // aligned with the state. It might happen after an unclean shutdown. + truncate := func(store ethdb.AncientStore, typ historyType, nhead uint64) { + if store == nil { + return + } + pruned, err := truncateFromHead(store, typ, nhead) + if err != nil { + log.Crit("Failed to truncate extra histories", "typ", typ, "err", err) + } + if pruned != 0 { + log.Warn("Truncated extra histories", "typ", typ, "number", pruned) + } + } + truncate(states, typeStateHistory, head) + truncate(trienodes, typeTrienodeHistory, head) + return states, trienodes, nil +} diff --git a/triedb/pathdb/history_index.go b/triedb/pathdb/history_index.go index e781a898e1..0c5eb8db21 100644 --- a/triedb/pathdb/history_index.go +++ b/triedb/pathdb/history_index.go @@ -20,28 +20,33 @@ import ( "errors" "fmt" "math" - "sort" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" ) -// parseIndex parses the index data with the supplied byte stream. The index data -// is a list of fixed-sized metadata. Empty metadata is regarded as invalid. -func parseIndex(blob []byte) ([]*indexBlockDesc, error) { +// parseIndex parses the index data from the provided byte stream. The index data +// is a sequence of fixed-size metadata entries, and any empty metadata entry is +// considered invalid. +// +// Each metadata entry consists of two components: the indexBlockDesc and an +// optional extension bitmap. The bitmap length may vary across different categories, +// but must remain consistent within the same category. +func parseIndex(blob []byte, bitmapSize int) ([]*indexBlockDesc, error) { if len(blob) == 0 { return nil, errors.New("empty state history index") } - if len(blob)%indexBlockDescSize != 0 { - return nil, fmt.Errorf("corrupted state index, len: %d", len(blob)) + size := indexBlockDescSize + bitmapSize + if len(blob)%size != 0 { + return nil, fmt.Errorf("corrupted state index, len: %d, bitmap size: %d", len(blob), bitmapSize) } var ( lastID uint32 descList []*indexBlockDesc ) - for i := 0; i < len(blob)/indexBlockDescSize; i++ { + for i := 0; i < len(blob)/size; i++ { var desc indexBlockDesc - desc.decode(blob[i*indexBlockDescSize : (i+1)*indexBlockDescSize]) + desc.decode(blob[i*size : (i+1)*size]) if desc.empty() { return nil, errors.New("empty state history index block") } @@ -70,38 +75,35 @@ func parseIndex(blob []byte) ([]*indexBlockDesc, error) { // indexReader is the structure to look up the state history index records // associated with the specific state element. type indexReader struct { - db ethdb.KeyValueReader - descList []*indexBlockDesc - readers map[uint32]*blockReader - state stateIdent + db ethdb.KeyValueReader + descList []*indexBlockDesc + readers map[uint32]*blockReader + state stateIdent + bitmapSize int } // loadIndexData loads the index data associated with the specified state. -func loadIndexData(db ethdb.KeyValueReader, state stateIdent) ([]*indexBlockDesc, error) { - var blob []byte - if state.account { - blob = rawdb.ReadAccountHistoryIndex(db, state.addressHash) - } else { - blob = rawdb.ReadStorageHistoryIndex(db, state.addressHash, state.storageHash) - } +func loadIndexData(db ethdb.KeyValueReader, state stateIdent, bitmapSize int) ([]*indexBlockDesc, error) { + blob := readStateIndex(state, db) if len(blob) == 0 { return nil, nil } - return parseIndex(blob) + return parseIndex(blob, bitmapSize) } // newIndexReader constructs a index reader for the specified state. Reader with // empty data is allowed. -func newIndexReader(db ethdb.KeyValueReader, state stateIdent) (*indexReader, error) { - descList, err := loadIndexData(db, state) +func newIndexReader(db ethdb.KeyValueReader, state stateIdent, bitmapSize int) (*indexReader, error) { + descList, err := loadIndexData(db, state, bitmapSize) if err != nil { return nil, err } return &indexReader{ - descList: descList, - readers: make(map[uint32]*blockReader), - db: db, - state: state, + descList: descList, + readers: make(map[uint32]*blockReader), + db: db, + state: state, + bitmapSize: bitmapSize, }, nil } @@ -112,11 +114,9 @@ func (r *indexReader) refresh() error { // may have been modified by additional elements written to the disk. if len(r.descList) != 0 { last := r.descList[len(r.descList)-1] - if !last.full() { - delete(r.readers, last.id) - } + delete(r.readers, last.id) } - descList, err := loadIndexData(r.db, r.state) + descList, err := loadIndexData(r.db, r.state, r.bitmapSize) if err != nil { return err } @@ -127,34 +127,15 @@ func (r *indexReader) refresh() error { // readGreaterThan locates the first element that is greater than the specified // id. If no such element is found, MaxUint64 is returned. func (r *indexReader) readGreaterThan(id uint64) (uint64, error) { - index := sort.Search(len(r.descList), func(i int) bool { - return id < r.descList[i].max - }) - if index == len(r.descList) { + it := r.newIterator(nil) + found := it.SeekGT(id) + if err := it.Error(); err != nil { + return 0, err + } + if !found { return math.MaxUint64, nil } - desc := r.descList[index] - - br, ok := r.readers[desc.id] - if !ok { - var ( - err error - blob []byte - ) - if r.state.account { - blob = rawdb.ReadAccountHistoryIndexBlock(r.db, r.state.addressHash, desc.id) - } else { - blob = rawdb.ReadStorageHistoryIndexBlock(r.db, r.state.addressHash, r.state.storageHash, desc.id) - } - br, err = newBlockReader(blob) - if err != nil { - return 0, err - } - r.readers[desc.id] = br - } - // The supplied ID is not greater than block.max, ensuring that an element - // satisfying the condition can be found. - return br.readGreaterThan(id) + return it.ID(), nil } // indexWriter is responsible for writing index data for a specific state (either @@ -164,69 +145,75 @@ func (r *indexReader) readGreaterThan(id uint64) (uint64, error) { // history ids) is stored in these second-layer index blocks, which are size // limited. type indexWriter struct { - descList []*indexBlockDesc // The list of index block descriptions - bw *blockWriter // The live index block writer - frozen []*blockWriter // The finalized index block writers, waiting for flush - lastID uint64 // The ID of the latest tracked history - state stateIdent - db ethdb.KeyValueReader + descList []*indexBlockDesc // The list of index block descriptions + bw *blockWriter // The live index block writer + frozen []*blockWriter // The finalized index block writers, waiting for flush + lastID uint64 // The ID of the latest tracked history + state stateIdent // The identifier of the state being indexed + bitmapSize int // The size of optional extension bitmap + db ethdb.KeyValueReader } -// newIndexWriter constructs the index writer for the specified state. -func newIndexWriter(db ethdb.KeyValueReader, state stateIdent) (*indexWriter, error) { - var blob []byte - if state.account { - blob = rawdb.ReadAccountHistoryIndex(db, state.addressHash) - } else { - blob = rawdb.ReadStorageHistoryIndex(db, state.addressHash, state.storageHash) - } +// newIndexWriter constructs the index writer for the specified state. Additionally, +// it takes an integer as the limit and prunes all existing elements above that ID. +// It's essential as the recovery mechanism after unclean shutdown during the history +// indexing. +func newIndexWriter(db ethdb.KeyValueReader, state stateIdent, limit uint64, bitmapSize int) (*indexWriter, error) { + blob := readStateIndex(state, db) if len(blob) == 0 { - desc := newIndexBlockDesc(0) - bw, _ := newBlockWriter(nil, desc) + desc := newIndexBlockDesc(0, bitmapSize) + bw, _ := newBlockWriter(nil, desc, 0 /* useless if the block is empty */, bitmapSize != 0) return &indexWriter{ - descList: []*indexBlockDesc{desc}, - bw: bw, - state: state, - db: db, + descList: []*indexBlockDesc{desc}, + bw: bw, + state: state, + db: db, + bitmapSize: bitmapSize, }, nil } - descList, err := parseIndex(blob) + descList, err := parseIndex(blob, bitmapSize) if err != nil { return nil, err } - var ( - indexBlock []byte - lastDesc = descList[len(descList)-1] - ) - if state.account { - indexBlock = rawdb.ReadAccountHistoryIndexBlock(db, state.addressHash, lastDesc.id) - } else { - indexBlock = rawdb.ReadStorageHistoryIndexBlock(db, state.addressHash, state.storageHash, lastDesc.id) + // Trim trailing blocks whose elements all exceed the limit. + for i := len(descList) - 1; i > 0 && descList[i].max > limit; i-- { + // The previous block has the elements that exceed the limit, + // therefore the current block can be entirely dropped. + if descList[i-1].max >= limit { + descList = descList[:i] + } } - bw, err := newBlockWriter(indexBlock, lastDesc) + // Take the last block for appending new elements + lastDesc := descList[len(descList)-1] + indexBlock := readStateIndexBlock(state, db, lastDesc.id) + + // Construct the writer for the last block. All elements in this block + // that exceed the limit will be truncated. + bw, err := newBlockWriter(indexBlock, lastDesc, limit, bitmapSize != 0) if err != nil { return nil, err } return &indexWriter{ - descList: descList, - lastID: lastDesc.max, - bw: bw, - state: state, - db: db, + descList: descList, + lastID: bw.last(), + bw: bw, + state: state, + db: db, + bitmapSize: bitmapSize, }, nil } // append adds the new element into the index writer. -func (w *indexWriter) append(id uint64) error { +func (w *indexWriter) append(id uint64, ext []uint16) error { if id <= w.lastID { return fmt.Errorf("append element out of order, last: %d, this: %d", w.lastID, id) } - if w.bw.full() { + if w.bw.estimateFull(ext) { if err := w.rotate(); err != nil { return err } } - if err := w.bw.append(id); err != nil { + if err := w.bw.append(id, ext); err != nil { return err } w.lastID = id @@ -239,10 +226,10 @@ func (w *indexWriter) append(id uint64) error { func (w *indexWriter) rotate() error { var ( err error - desc = newIndexBlockDesc(w.bw.desc.id + 1) + desc = newIndexBlockDesc(w.bw.desc.id+1, w.bitmapSize) ) w.frozen = append(w.frozen, w.bw) - w.bw, err = newBlockWriter(nil, desc) + w.bw, err = newBlockWriter(nil, desc, 0 /* useless if the block is empty */, w.bitmapSize != 0) if err != nil { return err } @@ -270,82 +257,78 @@ func (w *indexWriter) finish(batch ethdb.Batch) { return // nothing to commit } for _, bw := range writers { - if w.state.account { - rawdb.WriteAccountHistoryIndexBlock(batch, w.state.addressHash, bw.desc.id, bw.finish()) - } else { - rawdb.WriteStorageHistoryIndexBlock(batch, w.state.addressHash, w.state.storageHash, bw.desc.id, bw.finish()) - } + writeStateIndexBlock(w.state, batch, bw.desc.id, bw.finish()) } w.frozen = nil // release all the frozen writers - buf := make([]byte, 0, indexBlockDescSize*len(descList)) + size := indexBlockDescSize + w.bitmapSize + buf := make([]byte, 0, size*len(descList)) for _, desc := range descList { buf = append(buf, desc.encode()...) } - if w.state.account { - rawdb.WriteAccountHistoryIndex(batch, w.state.addressHash, buf) - } else { - rawdb.WriteStorageHistoryIndex(batch, w.state.addressHash, w.state.storageHash, buf) - } + writeStateIndex(w.state, batch, buf) } // indexDeleter is responsible for deleting index data for a specific state. type indexDeleter struct { - descList []*indexBlockDesc // The list of index block descriptions - bw *blockWriter // The live index block writer - dropped []uint32 // The list of index block id waiting for deleting - lastID uint64 // The ID of the latest tracked history - state stateIdent - db ethdb.KeyValueReader + descList []*indexBlockDesc // The list of index block descriptions + bw *blockWriter // The live index block writer + dropped []uint32 // The list of index block id waiting for deleting + lastID uint64 // The ID of the latest tracked history + state stateIdent // The identifier of the state being indexed + bitmapSize int // The size of optional extension bitmap + db ethdb.KeyValueReader } // newIndexDeleter constructs the index deleter for the specified state. -func newIndexDeleter(db ethdb.KeyValueReader, state stateIdent) (*indexDeleter, error) { - var blob []byte - if state.account { - blob = rawdb.ReadAccountHistoryIndex(db, state.addressHash) - } else { - blob = rawdb.ReadStorageHistoryIndex(db, state.addressHash, state.storageHash) - } +func newIndexDeleter(db ethdb.KeyValueReader, state stateIdent, limit uint64, bitmapSize int) (*indexDeleter, error) { + blob := readStateIndex(state, db) if len(blob) == 0 { // TODO(rjl493456442) we can probably return an error here, // deleter with no data is meaningless. - desc := newIndexBlockDesc(0) - bw, _ := newBlockWriter(nil, desc) + desc := newIndexBlockDesc(0, bitmapSize) + bw, _ := newBlockWriter(nil, desc, 0 /* useless if the block is empty */, bitmapSize != 0) return &indexDeleter{ - descList: []*indexBlockDesc{desc}, - bw: bw, - state: state, - db: db, + descList: []*indexBlockDesc{desc}, + bw: bw, + state: state, + bitmapSize: bitmapSize, + db: db, }, nil } - descList, err := parseIndex(blob) + descList, err := parseIndex(blob, bitmapSize) if err != nil { return nil, err } - var ( - indexBlock []byte - lastDesc = descList[len(descList)-1] - ) - if state.account { - indexBlock = rawdb.ReadAccountHistoryIndexBlock(db, state.addressHash, lastDesc.id) - } else { - indexBlock = rawdb.ReadStorageHistoryIndexBlock(db, state.addressHash, state.storageHash, lastDesc.id) + // Trim trailing blocks whose elements all exceed the limit. + for i := len(descList) - 1; i > 0 && descList[i].max > limit; i-- { + // The previous block has the elements that exceed the limit, + // therefore the current block can be entirely dropped. + if descList[i-1].max >= limit { + descList = descList[:i] + } } - bw, err := newBlockWriter(indexBlock, lastDesc) + // Take the block for deleting element from + lastDesc := descList[len(descList)-1] + indexBlock := readStateIndexBlock(state, db, lastDesc.id) + + // Construct the writer for the last block. All elements in this block + // that exceed the limit will be truncated. + bw, err := newBlockWriter(indexBlock, lastDesc, limit, bitmapSize != 0) if err != nil { return nil, err } return &indexDeleter{ - descList: descList, - lastID: lastDesc.max, - bw: bw, - state: state, - db: db, + descList: descList, + lastID: bw.last(), + bw: bw, + state: state, + bitmapSize: bitmapSize, + db: db, }, nil } -// empty returns an flag indicating whether the state index is empty. +// empty returns whether the state index is empty. func (d *indexDeleter) empty() bool { return d.bw.empty() && len(d.descList) == 1 } @@ -376,16 +359,9 @@ func (d *indexDeleter) pop(id uint64) error { d.descList = d.descList[:len(d.descList)-1] // Open the previous block writer for deleting - var ( - indexBlock []byte - lastDesc = d.descList[len(d.descList)-1] - ) - if d.state.account { - indexBlock = rawdb.ReadAccountHistoryIndexBlock(d.db, d.state.addressHash, lastDesc.id) - } else { - indexBlock = rawdb.ReadStorageHistoryIndexBlock(d.db, d.state.addressHash, d.state.storageHash, lastDesc.id) - } - bw, err := newBlockWriter(indexBlock, lastDesc) + lastDesc := d.descList[len(d.descList)-1] + indexBlock := readStateIndexBlock(d.state, d.db, lastDesc.id) + bw, err := newBlockWriter(indexBlock, lastDesc, lastDesc.max, d.bitmapSize != 0) if err != nil { return err } @@ -399,38 +375,113 @@ func (d *indexDeleter) pop(id uint64) error { // This function is safe to be called multiple times. func (d *indexDeleter) finish(batch ethdb.Batch) { for _, id := range d.dropped { - if d.state.account { - rawdb.DeleteAccountHistoryIndexBlock(batch, d.state.addressHash, id) - } else { - rawdb.DeleteStorageHistoryIndexBlock(batch, d.state.addressHash, d.state.storageHash, id) - } + deleteStateIndexBlock(d.state, batch, id) } d.dropped = nil // Flush the content of last block writer, regardless it's dirty or not if !d.bw.empty() { - if d.state.account { - rawdb.WriteAccountHistoryIndexBlock(batch, d.state.addressHash, d.bw.desc.id, d.bw.finish()) - } else { - rawdb.WriteStorageHistoryIndexBlock(batch, d.state.addressHash, d.state.storageHash, d.bw.desc.id, d.bw.finish()) - } + writeStateIndexBlock(d.state, batch, d.bw.desc.id, d.bw.finish()) } // Flush the index metadata into the supplied batch if d.empty() { - if d.state.account { - rawdb.DeleteAccountHistoryIndex(batch, d.state.addressHash) - } else { - rawdb.DeleteStorageHistoryIndex(batch, d.state.addressHash, d.state.storageHash) - } + deleteStateIndex(d.state, batch) } else { - buf := make([]byte, 0, indexBlockDescSize*len(d.descList)) + size := indexBlockDescSize + d.bitmapSize + buf := make([]byte, 0, size*len(d.descList)) for _, desc := range d.descList { buf = append(buf, desc.encode()...) } - if d.state.account { - rawdb.WriteAccountHistoryIndex(batch, d.state.addressHash, buf) - } else { - rawdb.WriteStorageHistoryIndex(batch, d.state.addressHash, d.state.storageHash, buf) - } + writeStateIndex(d.state, batch, buf) + } +} + +// readStateIndex retrieves the index metadata for the given state identifier. +// This function is shared by accounts and storage slots. +func readStateIndex(ident stateIdent, db ethdb.KeyValueReader) []byte { + switch ident.typ { + case typeAccount: + return rawdb.ReadAccountHistoryIndex(db, ident.addressHash) + case typeStorage: + return rawdb.ReadStorageHistoryIndex(db, ident.addressHash, ident.storageHash) + case typeTrienode: + return rawdb.ReadTrienodeHistoryIndex(db, ident.addressHash, []byte(ident.path)) + default: + panic(fmt.Errorf("unknown type: %v", ident.typ)) + } +} + +// writeStateIndex writes the provided index metadata into database with the +// given state identifier. This function is shared by accounts and storage slots. +func writeStateIndex(ident stateIdent, db ethdb.KeyValueWriter, data []byte) { + switch ident.typ { + case typeAccount: + rawdb.WriteAccountHistoryIndex(db, ident.addressHash, data) + case typeStorage: + rawdb.WriteStorageHistoryIndex(db, ident.addressHash, ident.storageHash, data) + case typeTrienode: + rawdb.WriteTrienodeHistoryIndex(db, ident.addressHash, []byte(ident.path), data) + default: + panic(fmt.Errorf("unknown type: %v", ident.typ)) + } +} + +// deleteStateIndex removes the index metadata for the given state identifier. +// This function is shared by accounts and storage slots. +func deleteStateIndex(ident stateIdent, db ethdb.KeyValueWriter) { + switch ident.typ { + case typeAccount: + rawdb.DeleteAccountHistoryIndex(db, ident.addressHash) + case typeStorage: + rawdb.DeleteStorageHistoryIndex(db, ident.addressHash, ident.storageHash) + case typeTrienode: + rawdb.DeleteTrienodeHistoryIndex(db, ident.addressHash, []byte(ident.path)) + default: + panic(fmt.Errorf("unknown type: %v", ident.typ)) + } +} + +// readStateIndexBlock retrieves the index block for the given state identifier +// and block ID. This function is shared by accounts and storage slots. +func readStateIndexBlock(ident stateIdent, db ethdb.KeyValueReader, id uint32) []byte { + switch ident.typ { + case typeAccount: + return rawdb.ReadAccountHistoryIndexBlock(db, ident.addressHash, id) + case typeStorage: + return rawdb.ReadStorageHistoryIndexBlock(db, ident.addressHash, ident.storageHash, id) + case typeTrienode: + return rawdb.ReadTrienodeHistoryIndexBlock(db, ident.addressHash, []byte(ident.path), id) + default: + panic(fmt.Errorf("unknown type: %v", ident.typ)) + } +} + +// writeStateIndexBlock writes the provided index block into database with the +// given state identifier. This function is shared by accounts and storage slots. +func writeStateIndexBlock(ident stateIdent, db ethdb.KeyValueWriter, id uint32, data []byte) { + switch ident.typ { + case typeAccount: + rawdb.WriteAccountHistoryIndexBlock(db, ident.addressHash, id, data) + case typeStorage: + rawdb.WriteStorageHistoryIndexBlock(db, ident.addressHash, ident.storageHash, id, data) + case typeTrienode: + rawdb.WriteTrienodeHistoryIndexBlock(db, ident.addressHash, []byte(ident.path), id, data) + default: + panic(fmt.Errorf("unknown type: %v", ident.typ)) + } +} + +// deleteStateIndexBlock removes the index block from database with the given +// state identifier. This function is shared by accounts and storage slots. +func deleteStateIndexBlock(ident stateIdent, db ethdb.KeyValueWriter, id uint32) { + switch ident.typ { + case typeAccount: + rawdb.DeleteAccountHistoryIndexBlock(db, ident.addressHash, id) + case typeStorage: + rawdb.DeleteStorageHistoryIndexBlock(db, ident.addressHash, ident.storageHash, id) + case typeTrienode: + rawdb.DeleteTrienodeHistoryIndexBlock(db, ident.addressHash, []byte(ident.path), id) + default: + panic(fmt.Errorf("unknown type: %v", ident.typ)) } } diff --git a/triedb/pathdb/history_index_block.go b/triedb/pathdb/history_index_block.go index 7648b99226..fd43d81b78 100644 --- a/triedb/pathdb/history_index_block.go +++ b/triedb/pathdb/history_index_block.go @@ -17,31 +17,37 @@ package pathdb import ( + "bytes" "encoding/binary" "errors" "fmt" "math" - "sort" + + "github.com/ethereum/go-ethereum/log" ) const ( - indexBlockDescSize = 14 // The size of index block descriptor - indexBlockEntriesCap = 4096 // The maximum number of entries can be grouped in a block - indexBlockRestartLen = 256 // The restart interval length of index block - historyIndexBatch = 1_000_000 // The number of state history indexes for constructing or deleting as batch + indexBlockDescSize = 14 // The size of index block descriptor + indexBlockMaxSize = 4096 // The maximum size of a single index block + indexBlockRestartLen = 256 // The restart interval length of index block ) // indexBlockDesc represents a descriptor for an index block, which contains a // list of state mutation records associated with a specific state (either an // account or a storage slot). type indexBlockDesc struct { - max uint64 // The maximum state ID retained within the block - entries uint16 // The number of state mutation records retained within the block - id uint32 // The id of the index block + max uint64 // The maximum state ID retained within the block + entries uint16 // The number of state mutation records retained within the block + id uint32 // The id of the index block + extBitmap []byte // Optional fixed-size bitmap for the included extension elements } -func newIndexBlockDesc(id uint32) *indexBlockDesc { - return &indexBlockDesc{id: id} +func newIndexBlockDesc(id uint32, bitmapSize int) *indexBlockDesc { + var bitmap []byte + if bitmapSize > 0 { + bitmap = make([]byte, bitmapSize) + } + return &indexBlockDesc{id: id, extBitmap: bitmap} } // empty indicates whether the block is empty with no element retained. @@ -49,26 +55,33 @@ func (d *indexBlockDesc) empty() bool { return d.entries == 0 } -// full indicates whether the number of elements in the block exceeds the -// preconfigured limit. -func (d *indexBlockDesc) full() bool { - return d.entries >= indexBlockEntriesCap -} - // encode packs index block descriptor into byte stream. func (d *indexBlockDesc) encode() []byte { - var buf [indexBlockDescSize]byte + buf := make([]byte, indexBlockDescSize+len(d.extBitmap)) binary.BigEndian.PutUint64(buf[0:8], d.max) binary.BigEndian.PutUint16(buf[8:10], d.entries) binary.BigEndian.PutUint32(buf[10:14], d.id) + copy(buf[indexBlockDescSize:], d.extBitmap) return buf[:] } -// decode unpacks index block descriptor from byte stream. +// decode unpacks index block descriptor from byte stream. It's safe to mutate +// the provided byte stream after the function call. func (d *indexBlockDesc) decode(blob []byte) { d.max = binary.BigEndian.Uint64(blob[:8]) d.entries = binary.BigEndian.Uint16(blob[8:10]) d.id = binary.BigEndian.Uint32(blob[10:14]) + d.extBitmap = bytes.Clone(blob[indexBlockDescSize:]) +} + +// copy returns a deep-copied object. +func (d *indexBlockDesc) copy() *indexBlockDesc { + return &indexBlockDesc{ + max: d.max, + entries: d.entries, + id: d.id, + extBitmap: bytes.Clone(d.extBitmap), + } } // parseIndexBlock parses the index block with the supplied byte stream. @@ -96,20 +109,38 @@ func (d *indexBlockDesc) decode(blob []byte) { // A uint16 can cover offsets in the range [0, 65536), which is more than enough // to store 4096 integers. // -// Each chunk begins with the full value of the first integer, followed by -// subsequent integers representing the differences between the current value -// and the preceding one. Integers are encoded with variable-size for best -// storage efficiency. Each chunk can be illustrated as below. +// Each chunk begins with a full integer value for the first element, followed +// by subsequent integers encoded as differences (deltas) from their preceding +// values. All integers use variable-length encoding for optimal space efficiency. // -// Restart ---> +----------------+ -// | Full integer | -// +----------------+ -// | Diff with prev | -// +----------------+ -// | ... | -// +----------------+ -// | Diff with prev | -// +----------------+ +// In the updated format, each element in the chunk may optionally include an +// "extension" section. If an extension is present, it starts with a var-size +// integer indicating the length of the remaining extension payload, followed by +// that many bytes. If no extension is present, the element format is identical +// to the original version (i.e., only the integer or delta value is encoded). +// +// In the trienode history index, the extension field contains the list of +// trie node IDs that fall within this range. For the given state transition, +// these IDs represent the specific nodes in this range that were mutated. +// +// Whether an element includes an extension is determined by the block reader +// based on the specification. Conceptually, a chunk is structured as: +// +// Restart ---> +----------------+ +// | Full integer | +// +----------------+ +// | (Extension?) | +// +----------------+ +// | Diff with prev | +// +----------------+ +// | (Extension?) | +// +----------------+ +// | ... | +// +----------------+ +// | Diff with prev | +// +----------------+ +// | (Extension?) | +// +----------------+ // // Empty index block is regarded as invalid. func parseIndexBlock(blob []byte) ([]uint16, []byte, error) { @@ -147,104 +178,98 @@ func parseIndexBlock(blob []byte) ([]uint16, []byte, error) { type blockReader struct { restarts []uint16 data []byte + hasExt bool } // newBlockReader constructs the block reader with the supplied block data. -func newBlockReader(blob []byte) (*blockReader, error) { +func newBlockReader(blob []byte, hasExt bool) (*blockReader, error) { restarts, data, err := parseIndexBlock(blob) if err != nil { return nil, err } return &blockReader{ restarts: restarts, - data: data, // safe to own the slice + data: data, // safe to own the slice + hasExt: hasExt, // flag whether extension should be resolved }, nil } // readGreaterThan locates the first element in the block that is greater than // the specified value. If no such element is found, MaxUint64 is returned. func (br *blockReader) readGreaterThan(id uint64) (uint64, error) { - var err error - index := sort.Search(len(br.restarts), func(i int) bool { - item, n := binary.Uvarint(br.data[br.restarts[i]:]) - if n <= 0 { - err = fmt.Errorf("failed to decode item at restart %d", br.restarts[i]) - } - return item > id - }) - if err != nil { + it := br.newIterator(nil) + found := it.SeekGT(id) + if err := it.Error(); err != nil { return 0, err } - if index == 0 { - item, _ := binary.Uvarint(br.data[br.restarts[0]:]) - return item, nil - } - var ( - start int - limit int - result uint64 - ) - if index == len(br.restarts) { - // The element being searched falls within the last restart section, - // there is no guarantee such element can be found. - start = int(br.restarts[len(br.restarts)-1]) - limit = len(br.data) - } else { - // The element being searched falls within the non-last restart section, - // such element can be found for sure. - start = int(br.restarts[index-1]) - limit = int(br.restarts[index]) - } - pos := start - for pos < limit { - x, n := binary.Uvarint(br.data[pos:]) - if pos == start { - result = x - } else { - result += x - } - if result > id { - return result, nil - } - pos += n - } - // The element which is greater than specified id is not found. - if index == len(br.restarts) { + if !found { return math.MaxUint64, nil } - // The element which is the first one greater than the specified id - // is exactly the one located at the restart point. - item, _ := binary.Uvarint(br.data[br.restarts[index]:]) - return item, nil + return it.ID(), nil } type blockWriter struct { desc *indexBlockDesc // Descriptor of the block restarts []uint16 // Offsets into the data slice, marking the start of each section data []byte // Aggregated encoded data slice + hasExt bool // Flag whether the extension field for each element exists } -func newBlockWriter(blob []byte, desc *indexBlockDesc) (*blockWriter, error) { +// newBlockWriter constructs a block writer. In addition to the existing data +// and block description, it takes an element ID and prunes all existing elements +// above that ID. It's essential as the recovery mechanism after unclean shutdown +// during the history indexing. +func newBlockWriter(blob []byte, desc *indexBlockDesc, limit uint64, hasExt bool) (*blockWriter, error) { if len(blob) == 0 { return &blockWriter{ - desc: desc, - data: make([]byte, 0, 1024), + desc: desc, + data: make([]byte, 0, 1024), + hasExt: hasExt, }, nil } restarts, data, err := parseIndexBlock(blob) if err != nil { return nil, err } - return &blockWriter{ + writer := &blockWriter{ desc: desc, restarts: restarts, data: data, // safe to own the slice - }, nil + hasExt: hasExt, + } + var trimmed int + for !writer.empty() && writer.last() > limit { + if err := writer.pop(writer.last()); err != nil { + return nil, err + } + trimmed += 1 + } + if trimmed > 0 { + log.Debug("Truncated extraneous elements", "count", trimmed, "limit", limit) + } + return writer, nil +} + +// setBitmap applies the given extension elements into the bitmap. +func (b *blockWriter) setBitmap(ext []uint16) { + for _, n := range ext { + // Node ID zero is intentionally filtered out. Any element in this range + // can indicate that the sub-tree's root node was mutated, so storing zero + // is redundant and saves one byte for bitmap. + if n != 0 { + setBit(b.desc.extBitmap, int(n-1)) + } + } } // append adds a new element to the block. The new element must be greater than // the previous one. The provided ID is assumed to always be greater than 0. -func (b *blockWriter) append(id uint64) error { +// +// ext refers to the optional extension field attached to the appended element. +// This extension mechanism is used by trie-node history and represents a list of +// trie node IDs that fall within the range covered by the index element +// (typically corresponding to a sub-trie in trie-node history). +func (b *blockWriter) append(id uint64, ext []uint16) error { if id == 0 { return errors.New("invalid zero id") } @@ -271,13 +296,29 @@ func (b *blockWriter) append(id uint64) error { // element. b.data = binary.AppendUvarint(b.data, id-b.desc.max) } + // Extension validation + if (len(ext) == 0) != !b.hasExt { + if len(ext) == 0 { + return errors.New("missing extension") + } + return errors.New("unexpected extension") + } + // Append the extension if it is not nil. The extension is prefixed with a + // length indicator, and the block reader MUST understand this scheme and + // decode the extension accordingly. + if len(ext) > 0 { + b.setBitmap(ext) + enc := encodeIDs(ext) + b.data = binary.AppendUvarint(b.data, uint64(len(enc))) + b.data = append(b.data, enc...) + } b.desc.entries++ b.desc.max = id return nil } // scanSection traverses the specified section and terminates if fn returns true. -func (b *blockWriter) scanSection(section int, fn func(uint64, int) bool) { +func (b *blockWriter) scanSection(section int, fn func(uint64, int, []uint16) bool) error { var ( value uint64 start = int(b.restarts[section]) @@ -296,27 +337,47 @@ func (b *blockWriter) scanSection(section int, fn func(uint64, int) bool) { } else { value += x } - if fn(value, pos) { - return + // Resolve the extension if exists + var ( + err error + ext []uint16 + extLen int + ) + if b.hasExt { + l, ln := binary.Uvarint(b.data[pos+n:]) + extLen = ln + int(l) + ext, err = decodeIDs(b.data[pos+n+ln : pos+n+extLen]) } + if err != nil { + return err + } + if fn(value, pos, ext) { + return nil + } + // Shift to next position pos += n + pos += extLen } + return nil } // sectionLast returns the last element in the specified section. -func (b *blockWriter) sectionLast(section int) uint64 { +func (b *blockWriter) sectionLast(section int) (uint64, error) { var n uint64 - b.scanSection(section, func(v uint64, _ int) bool { + if err := b.scanSection(section, func(v uint64, _ int, _ []uint16) bool { n = v return false - }) - return n + }); err != nil { + return 0, err + } + return n, nil } // sectionSearch looks up the specified value in the given section, // the position and the preceding value will be returned if found. -func (b *blockWriter) sectionSearch(section int, n uint64) (found bool, prev uint64, pos int) { - b.scanSection(section, func(v uint64, p int) bool { +// It assumes that the preceding element exists in the section. +func (b *blockWriter) sectionSearch(section int, n uint64) (found bool, prev uint64, pos int, err error) { + if err := b.scanSection(section, func(v uint64, p int, _ []uint16) bool { if n == v { pos = p found = true @@ -324,8 +385,24 @@ func (b *blockWriter) sectionSearch(section int, n uint64) (found bool, prev uin } prev = v return false // continue iteration - }) - return found, prev, pos + }); err != nil { + return false, 0, 0, err + } + return found, prev, pos, nil +} + +// rebuildBitmap scans the entire block and rebuilds the bitmap. +func (b *blockWriter) rebuildBitmap() error { + clear(b.desc.extBitmap) + for i := 0; i < len(b.restarts); i++ { + if err := b.scanSection(i, func(v uint64, p int, ext []uint16) bool { + b.setBitmap(ext) + return false // continue iteration + }); err != nil { + return err + } + } + return nil } // pop removes the last element from the block. The assumption is held that block @@ -339,9 +416,9 @@ func (b *blockWriter) pop(id uint64) error { } // If there is only one entry left, the entire block should be reset if b.desc.entries == 1 { - //b.desc.min = 0 b.desc.max = 0 b.desc.entries = 0 + clear(b.desc.extBitmap) b.restarts = nil b.data = b.data[:0] return nil @@ -351,28 +428,45 @@ func (b *blockWriter) pop(id uint64) error { if b.desc.entries%indexBlockRestartLen == 1 { b.data = b.data[:b.restarts[len(b.restarts)-1]] b.restarts = b.restarts[:len(b.restarts)-1] - b.desc.max = b.sectionLast(len(b.restarts) - 1) + last, err := b.sectionLast(len(b.restarts) - 1) + if err != nil { + return err + } + b.desc.max = last b.desc.entries -= 1 - return nil + return b.rebuildBitmap() } // Look up the element preceding the one to be popped, in order to update // the maximum element in the block. - found, prev, pos := b.sectionSearch(len(b.restarts)-1, id) + found, prev, pos, err := b.sectionSearch(len(b.restarts)-1, id) + if err != nil { + return err + } if !found { return fmt.Errorf("pop element is not found, last: %d, this: %d", b.desc.max, id) } b.desc.max = prev b.data = b.data[:pos] b.desc.entries -= 1 - return nil + return b.rebuildBitmap() } func (b *blockWriter) empty() bool { return b.desc.empty() } -func (b *blockWriter) full() bool { - return b.desc.full() +func (b *blockWriter) estimateFull(ext []uint16) bool { + size := 8 + 2*len(ext) + return len(b.data)+size > indexBlockMaxSize +} + +// last returns the last element in the block. It should only be called when +// writer is not empty, otherwise the returned data is meaningless. +func (b *blockWriter) last() uint64 { + if b.empty() { + return 0 + } + return b.desc.max } // finish finalizes the index block encoding by appending the encoded restart points diff --git a/triedb/pathdb/history_index_block_test.go b/triedb/pathdb/history_index_block_test.go index c251cea2ec..923ae29348 100644 --- a/triedb/pathdb/history_index_block_test.go +++ b/triedb/pathdb/history_index_block_test.go @@ -17,6 +17,7 @@ package pathdb import ( + "bytes" "math" "math/rand" "slices" @@ -24,16 +25,36 @@ import ( "testing" ) +func randomExt(bitmapSize int, n int) []uint16 { + if bitmapSize == 0 { + return nil + } + var ( + limit = bitmapSize * 8 + extList []uint16 + ) + for i := 0; i < n; i++ { + extList = append(extList, uint16(rand.Intn(limit+1))) + } + return extList +} + func TestBlockReaderBasic(t *testing.T) { + testBlockReaderBasic(t, 0) + testBlockReaderBasic(t, 2) + testBlockReaderBasic(t, 34) +} + +func testBlockReaderBasic(t *testing.T, bitmapSize int) { elements := []uint64{ 1, 5, 10, 11, 20, } - bw, _ := newBlockWriter(nil, newIndexBlockDesc(0)) + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, bitmapSize), 0, bitmapSize != 0) for i := 0; i < len(elements); i++ { - bw.append(elements[i]) + bw.append(elements[i], randomExt(bitmapSize, 5)) } - br, err := newBlockReader(bw.finish()) + br, err := newBlockReader(bw.finish(), bitmapSize != 0) if err != nil { t.Fatalf("Failed to construct the block reader, %v", err) } @@ -60,18 +81,24 @@ func TestBlockReaderBasic(t *testing.T) { } func TestBlockReaderLarge(t *testing.T) { + testBlockReaderLarge(t, 0) + testBlockReaderLarge(t, 2) + testBlockReaderLarge(t, 34) +} + +func testBlockReaderLarge(t *testing.T, bitmapSize int) { var elements []uint64 for i := 0; i < 1000; i++ { elements = append(elements, rand.Uint64()) } slices.Sort(elements) - bw, _ := newBlockWriter(nil, newIndexBlockDesc(0)) + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, bitmapSize), 0, bitmapSize != 0) for i := 0; i < len(elements); i++ { - bw.append(elements[i]) + bw.append(elements[i], randomExt(bitmapSize, 5)) } - br, err := newBlockReader(bw.finish()) + br, err := newBlockReader(bw.finish(), bitmapSize != 0) if err != nil { t.Fatalf("Failed to construct the block reader, %v", err) } @@ -95,34 +122,91 @@ func TestBlockReaderLarge(t *testing.T) { } func TestBlockWriterBasic(t *testing.T) { - bw, _ := newBlockWriter(nil, newIndexBlockDesc(0)) + testBlockWriteBasic(t, 0) + testBlockWriteBasic(t, 2) + testBlockWriteBasic(t, 34) +} + +func testBlockWriteBasic(t *testing.T, bitmapSize int) { + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, bitmapSize), 0, bitmapSize != 0) if !bw.empty() { t.Fatal("expected empty block") } - bw.append(2) - if err := bw.append(1); err == nil { + bw.append(2, randomExt(bitmapSize, 5)) + if err := bw.append(1, randomExt(bitmapSize, 5)); err == nil { t.Fatal("out-of-order insertion is not expected") } + var maxElem uint64 for i := 0; i < 10; i++ { - bw.append(uint64(i + 3)) + bw.append(uint64(i+3), randomExt(bitmapSize, 5)) + maxElem = uint64(i + 3) } - bw, err := newBlockWriter(bw.finish(), newIndexBlockDesc(0)) + bw, err := newBlockWriter(bw.finish(), newIndexBlockDesc(0, bitmapSize), maxElem, bitmapSize != 0) if err != nil { t.Fatalf("Failed to construct the block writer, %v", err) } for i := 0; i < 10; i++ { - if err := bw.append(uint64(i + 100)); err != nil { + if err := bw.append(uint64(i+100), randomExt(bitmapSize, 5)); err != nil { t.Fatalf("Failed to append value %d: %v", i, err) } } bw.finish() } +func TestBlockWriterWithLimit(t *testing.T) { + testBlockWriterWithLimit(t, 0) + testBlockWriterWithLimit(t, 2) + testBlockWriterWithLimit(t, 34) +} + +func testBlockWriterWithLimit(t *testing.T, bitmapSize int) { + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, bitmapSize), 0, bitmapSize != 0) + + var bitmaps [][]byte + for i := 0; i < indexBlockRestartLen+2; i++ { + bw.append(uint64(i+1), randomExt(bitmapSize, 5)) + bitmaps = append(bitmaps, bytes.Clone(bw.desc.extBitmap)) + } + for i := 0; i < indexBlockRestartLen+2; i++ { + limit := uint64(i + 1) + + desc := bw.desc.copy() + block, err := newBlockWriter(bytes.Clone(bw.finish()), desc, limit, bitmapSize != 0) + if err != nil { + t.Fatalf("Failed to construct the block writer, %v", err) + } + if block.desc.max != limit { + t.Fatalf("Test %d, unexpected max value, got %d, want %d", i, block.desc.max, limit) + } + if !bytes.Equal(desc.extBitmap, bitmaps[i]) { + t.Fatalf("Test %d, unexpected bitmap, got: %v, want: %v", i, block.desc.extBitmap, bitmaps[i]) + } + + // Re-fill the elements + var maxElem uint64 + for elem := limit + 1; elem < indexBlockRestartLen+4; elem++ { + if err := block.append(elem, randomExt(bitmapSize, 5)); err != nil { + t.Fatalf("Failed to append value %d: %v", elem, err) + } + maxElem = elem + } + if block.desc.max != maxElem { + t.Fatalf("Test %d, unexpected max value, got %d, want %d", i, block.desc.max, maxElem) + } + } +} + func TestBlockWriterDelete(t *testing.T) { - bw, _ := newBlockWriter(nil, newIndexBlockDesc(0)) + testBlockWriterDelete(t, 0) + testBlockWriterDelete(t, 2) + testBlockWriterDelete(t, 34) +} + +func testBlockWriterDelete(t *testing.T, bitmapSize int) { + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, bitmapSize), 0, bitmapSize != 0) for i := 0; i < 10; i++ { - bw.append(uint64(i + 1)) + bw.append(uint64(i+1), randomExt(bitmapSize, 5)) } // Pop unknown id, the request should be rejected if err := bw.pop(100); err == nil { @@ -144,12 +228,18 @@ func TestBlockWriterDelete(t *testing.T) { } func TestBlcokWriterDeleteWithData(t *testing.T) { + testBlcokWriterDeleteWithData(t, 0) + testBlcokWriterDeleteWithData(t, 2) + testBlcokWriterDeleteWithData(t, 34) +} + +func testBlcokWriterDeleteWithData(t *testing.T, bitmapSize int) { elements := []uint64{ 1, 5, 10, 11, 20, } - bw, _ := newBlockWriter(nil, newIndexBlockDesc(0)) + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, bitmapSize), 0, bitmapSize != 0) for i := 0; i < len(elements); i++ { - bw.append(elements[i]) + bw.append(elements[i], randomExt(bitmapSize, 5)) } // Re-construct the block writer with data @@ -158,7 +248,10 @@ func TestBlcokWriterDeleteWithData(t *testing.T) { max: 20, entries: 5, } - bw, err := newBlockWriter(bw.finish(), desc) + if bitmapSize > 0 { + desc.extBitmap = make([]byte, bitmapSize) + } + bw, err := newBlockWriter(bw.finish(), desc, elements[len(elements)-1], bitmapSize != 0) if err != nil { t.Fatalf("Failed to construct block writer %v", err) } @@ -169,7 +262,7 @@ func TestBlcokWriterDeleteWithData(t *testing.T) { newTail := elements[i-1] // Ensure the element can still be queried with no issue - br, err := newBlockReader(bw.finish()) + br, err := newBlockReader(bw.finish(), bitmapSize != 0) if err != nil { t.Fatalf("Failed to construct the block reader, %v", err) } @@ -201,26 +294,60 @@ func TestBlcokWriterDeleteWithData(t *testing.T) { } func TestCorruptedIndexBlock(t *testing.T) { - bw, _ := newBlockWriter(nil, newIndexBlockDesc(0)) + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, 0), 0, false) + + var maxElem uint64 for i := 0; i < 10; i++ { - bw.append(uint64(i + 1)) + bw.append(uint64(i+1), nil) + maxElem = uint64(i + 1) } buf := bw.finish() // Mutate the buffer manually buf[len(buf)-1]++ - _, err := newBlockWriter(buf, newIndexBlockDesc(0)) + _, err := newBlockWriter(buf, newIndexBlockDesc(0, 0), maxElem, false) if err == nil { t.Fatal("Corrupted index block data is not detected") } } // BenchmarkParseIndexBlock benchmarks the performance of parseIndexBlock. +// +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/triedb/pathdb +// cpu: Apple M1 Pro +// BenchmarkParseIndexBlock +// BenchmarkParseIndexBlock-8 35829495 34.16 ns/op func BenchmarkParseIndexBlock(b *testing.B) { // Generate a realistic index block blob - bw, _ := newBlockWriter(nil, newIndexBlockDesc(0)) + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, 0), 0, false) for i := 0; i < 4096; i++ { - bw.append(uint64(i * 2)) + bw.append(uint64(i*2), nil) + } + blob := bw.finish() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + _, _, err := parseIndexBlock(blob) + if err != nil { + b.Fatalf("parseIndexBlock failed: %v", err) + } + } +} + +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/triedb/pathdb +// cpu: Apple M1 Pro +// BenchmarkParseIndexBlockWithExt +// BenchmarkParseIndexBlockWithExt-8 35773242 33.72 ns/op +func BenchmarkParseIndexBlockWithExt(b *testing.B) { + // Generate a realistic index block blob + bw, _ := newBlockWriter(nil, newIndexBlockDesc(0, 34), 0, true) + for i := 0; i < 4096; i++ { + id, ext := uint64(i*2), randomExt(34, 3) + bw.append(id, ext) } blob := bw.finish() @@ -234,19 +361,58 @@ func BenchmarkParseIndexBlock(b *testing.B) { } // BenchmarkBlockWriterAppend benchmarks the performance of indexblock.writer +// +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/triedb/pathdb +// cpu: Apple M1 Pro +// BenchmarkBlockWriterAppend +// BenchmarkBlockWriterAppend-8 293611083 4.113 ns/op 3 B/op 0 allocs/op func BenchmarkBlockWriterAppend(b *testing.B) { b.ReportAllocs() b.ResetTimer() - desc := newIndexBlockDesc(0) - writer, _ := newBlockWriter(nil, desc) + var blockID uint32 + desc := newIndexBlockDesc(blockID, 0) + writer, _ := newBlockWriter(nil, desc, 0, false) for i := 0; i < b.N; i++ { - if writer.full() { - desc = newIndexBlockDesc(0) - writer, _ = newBlockWriter(nil, desc) + if writer.estimateFull(nil) { + blockID += 1 + desc = newIndexBlockDesc(blockID, 0) + writer, _ = newBlockWriter(nil, desc, 0, false) } - if err := writer.append(writer.desc.max + 1); err != nil { + if err := writer.append(writer.desc.max+1, nil); err != nil { + b.Error(err) + } + } +} + +// goos: darwin +// goarch: arm64 +// pkg: github.com/ethereum/go-ethereum/triedb/pathdb +// cpu: Apple M1 Pro +// BenchmarkBlockWriterAppendWithExt +// BenchmarkBlockWriterAppendWithExt-8 11123844 103.6 ns/op 42 B/op 2 allocs/op +func BenchmarkBlockWriterAppendWithExt(b *testing.B) { + b.ReportAllocs() + b.ResetTimer() + + var ( + bitmapSize = 34 + blockID uint32 + ) + desc := newIndexBlockDesc(blockID, bitmapSize) + writer, _ := newBlockWriter(nil, desc, 0, true) + + for i := 0; i < b.N; i++ { + ext := randomExt(bitmapSize, 3) + if writer.estimateFull(ext) { + blockID += 1 + desc = newIndexBlockDesc(blockID, bitmapSize) + writer, _ = newBlockWriter(nil, desc, 0, true) + } + if err := writer.append(writer.desc.max+1, ext); err != nil { b.Error(err) } } diff --git a/triedb/pathdb/history_index_iterator.go b/triedb/pathdb/history_index_iterator.go new file mode 100644 index 0000000000..e4aca24f5d --- /dev/null +++ b/triedb/pathdb/history_index_iterator.go @@ -0,0 +1,656 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see = bitmapElementThresholdTwoLevels { + return false, fmt.Errorf("invalid extension filter %d for 2 bytes bitmap", id) + } + return isBitSet(bitmap, n), nil + case bitmapBytesThreeLevels: + // Bitmap for 3-level trie with at most 16+16*16 elements inside + if n >= bitmapElementThresholdThreeLevels { + return false, fmt.Errorf("invalid extension filter %d for 34 bytes bitmap", id) + } else if n >= bitmapElementThresholdTwoLevels { + return isBitSet(bitmap, n), nil + } else { + // Check the element itself first + if isBitSet(bitmap, n) { + return true, nil + } + // Check descendants: the presence of any descendant implicitly + // represents a mutation of its ancestor. + return bitmap[2+2*n] != 0 || bitmap[3+2*n] != 0, nil + } + default: + return false, fmt.Errorf("unsupported bitmap size %d", len(bitmap)) + } +} + +// blockIterator is the iterator to traverse the indices within a single block. +type blockIterator struct { + // immutable fields + data []byte // Reference to the data segment within the block reader + restarts []uint16 // Offsets pointing to the restart sections within the data + hasExt bool // Flag whether the extension is included in the data + + // Optional extension filter + filter *extFilter // Filters index entries based on the extension field. + + // mutable fields + id uint64 // ID of the element at the iterators current position + ext []byte // Extension field of the element at the iterators current position + dataPtr int // Current read position within the data slice + restartPtr int // Index of the restart section where the iterator is currently positioned + exhausted bool // Flag whether the iterator has been exhausted + err error // Accumulated error during the traversal +} + +func (br *blockReader) newIterator(filter *extFilter) *blockIterator { + it := &blockIterator{ + data: br.data, // hold the slice directly with no deep copy + restarts: br.restarts, // hold the slice directly with no deep copy + hasExt: br.hasExt, // flag whether the extension should be resolved + filter: filter, // optional extension filter + } + it.reset() + return it +} + +func (it *blockIterator) set(dataPtr int, restartPtr int, id uint64, ext []byte) { + it.id = id + it.ext = ext + + it.dataPtr = dataPtr + it.restartPtr = restartPtr + it.exhausted = dataPtr == len(it.data) +} + +func (it *blockIterator) setErr(err error) { + if it.err != nil { + return + } + it.err = err +} + +func (it *blockIterator) reset() { + it.id = 0 + it.ext = nil + + it.dataPtr = -1 + it.restartPtr = -1 + it.exhausted = false + it.err = nil + + // Mark the iterator as exhausted if the associated index block is empty + if len(it.data) == 0 || len(it.restarts) == 0 { + it.exhausted = true + } +} + +func (it *blockIterator) resolveExt(pos int) ([]byte, int, error) { + if !it.hasExt { + return nil, 0, nil + } + length, n := binary.Uvarint(it.data[pos:]) + if n <= 0 { + return nil, 0, fmt.Errorf("too short for extension, pos: %d, datalen: %d", pos, len(it.data)) + } + if len(it.data[pos+n:]) < int(length) { + return nil, 0, fmt.Errorf("too short for extension, pos: %d, length: %d, datalen: %d", pos, length, len(it.data)) + } + return it.data[pos+n : pos+n+int(length)], n + int(length), nil +} + +// seekGT moves the iterator to the first element whose id is greater than the +// given number. It returns whether such element exists. +// +// Note, this operation will unset the exhausted status and subsequent traversal +// is allowed. +func (it *blockIterator) seekGT(id uint64) bool { + if it.err != nil { + return false + } + var err error + index := sort.Search(len(it.restarts), func(i int) bool { + item, n := binary.Uvarint(it.data[it.restarts[i]:]) + if n <= 0 { + err = fmt.Errorf("failed to decode item at restart %d", it.restarts[i]) + } + return item > id + }) + if err != nil { + it.setErr(err) + return false + } + if index == 0 { + pos := int(it.restarts[0]) + item, n := binary.Uvarint(it.data[pos:]) + if n <= 0 { + it.setErr(fmt.Errorf("failed to decode item at pos %d", it.restarts[0])) + return false + } + pos = pos + n + + ext, shift, err := it.resolveExt(pos) + if err != nil { + it.setErr(err) + return false + } + it.set(pos+shift, 0, item, ext) + return true + } + var ( + start int + limit int + restartIndex int // The restart section being searched below + ) + if index == len(it.restarts) { + // The element being searched falls within the last restart section, + // there is no guarantee such element can be found. + start = int(it.restarts[len(it.restarts)-1]) + limit = len(it.data) + restartIndex = len(it.restarts) - 1 + } else { + // The element being searched falls within the non-last restart section, + // such element can be found for sure. + start = int(it.restarts[index-1]) + limit = int(it.restarts[index]) + restartIndex = index - 1 + } + var ( + result uint64 + pos = start + ) + for pos < limit { + x, n := binary.Uvarint(it.data[pos:]) + if n <= 0 { + it.setErr(fmt.Errorf("failed to decode item at pos %d", pos)) + return false + } + if pos == start { + result = x + } else { + result += x + } + pos += n + + ext, shift, err := it.resolveExt(pos) + if err != nil { + it.setErr(err) + return false + } + pos += shift + + if result > id { + if pos == limit { + it.set(pos, restartIndex+1, result, ext) + } else { + it.set(pos, restartIndex, result, ext) + } + return true + } + } + // The element which is greater than specified id is not found. + if index == len(it.restarts) { + it.reset() + return false + } + // The element which is the first one greater than the specified id + // is exactly the one located at the restart point. + pos = int(it.restarts[index]) + item, n := binary.Uvarint(it.data[pos:]) + if n <= 0 { + it.setErr(fmt.Errorf("failed to decode item at pos %d", it.restarts[index])) + return false + } + pos = pos + n + + ext, shift, err := it.resolveExt(pos) + if err != nil { + it.setErr(err) + return false + } + it.set(pos+shift, index, item, ext) + return true +} + +// SeekGT implements HistoryIndexIterator, is the wrapper of the seekGT with +// optional extension filter logic applied. +func (it *blockIterator) SeekGT(id uint64) bool { + if !it.seekGT(id) { + return false + } + if it.filter == nil { + return true + } + for { + found, err := it.filter.exists(it.ext) + if err != nil { + it.setErr(err) + return false + } + if found { + break + } + if !it.next() { + return false + } + } + return true +} + +func (it *blockIterator) init() { + if it.dataPtr != -1 { + return + } + it.dataPtr = 0 + it.restartPtr = 0 +} + +// next moves the iterator to the next element. If the iterator has been exhausted, +// and boolean with false should be returned. +func (it *blockIterator) next() bool { + if it.exhausted || it.err != nil { + return false + } + it.init() + + // Decode the next element pointed by the iterator + v, n := binary.Uvarint(it.data[it.dataPtr:]) + if n <= 0 { + it.setErr(fmt.Errorf("failed to decode item at pos %d", it.dataPtr)) + return false + } + var val uint64 + if it.dataPtr == int(it.restarts[it.restartPtr]) { + val = v + } else { + val = it.id + v + } + + // Decode the extension field + ext, shift, err := it.resolveExt(it.dataPtr + n) + if err != nil { + it.setErr(err) + return false + } + + // Move to the next restart section if the data pointer crosses the boundary + nextRestartPtr := it.restartPtr + if it.restartPtr < len(it.restarts)-1 && it.dataPtr+n+shift == int(it.restarts[it.restartPtr+1]) { + nextRestartPtr = it.restartPtr + 1 + } + it.set(it.dataPtr+n+shift, nextRestartPtr, val, ext) + + return true +} + +// Next implements the HistoryIndexIterator, moving the iterator to the next +// element. It's a wrapper of next with optional extension filter logic applied. +func (it *blockIterator) Next() bool { + if !it.next() { + return false + } + if it.filter == nil { + return true + } + for { + found, err := it.filter.exists(it.ext) + if err != nil { + it.setErr(err) + return false + } + if found { + break + } + if !it.next() { + return false + } + } + return true +} + +// ID implements HistoryIndexIterator, returning the id of the element where the +// iterator is positioned at. +func (it *blockIterator) ID() uint64 { + return it.id +} + +// Error implements HistoryIndexIterator, returning any accumulated error. +// Exhausting all the elements is not considered to be an error. +func (it *blockIterator) Error() error { return it.err } + +// indexIterator is an iterator to traverse the history indices belonging to the +// specific state entry. +type indexIterator struct { + // immutable fields + descList []*indexBlockDesc + reader *indexReader + + // Optional extension filter + filter *extFilter + + // mutable fields + blockIt *blockIterator + blockPtr int + exhausted bool + err error +} + +// newBlockIter initializes the block iterator with the specified block ID. +func (r *indexReader) newBlockIter(id uint32, filter *extFilter) (*blockIterator, error) { + br, ok := r.readers[id] + if !ok { + var err error + br, err = newBlockReader(readStateIndexBlock(r.state, r.db, id), r.bitmapSize != 0) + if err != nil { + return nil, err + } + r.readers[id] = br + } + return br.newIterator(filter), nil +} + +// newIterator initializes the index iterator with the specified extension filter. +func (r *indexReader) newIterator(filter *extFilter) *indexIterator { + it := &indexIterator{ + descList: r.descList, + reader: r, + filter: filter, + } + it.reset() + return it +} + +func (it *indexIterator) setErr(err error) { + if it.err != nil { + return + } + it.err = err +} + +func (it *indexIterator) reset() { + it.blockIt = nil + it.blockPtr = -1 + it.exhausted = false + it.err = nil + + if len(it.descList) == 0 { + it.exhausted = true + } +} + +func (it *indexIterator) open(blockPtr int) error { + blockIt, err := it.reader.newBlockIter(it.descList[blockPtr].id, it.filter) + if err != nil { + return err + } + it.blockIt = blockIt + it.blockPtr = blockPtr + return nil +} + +func (it *indexIterator) applyFilter(index int) (int, error) { + if it.filter == nil { + return index, nil + } + for index < len(it.descList) { + found, err := it.filter.contains(it.descList[index].extBitmap) + if err != nil { + return 0, err + } + if found { + break + } + index++ + } + return index, nil +} + +// SeekGT moves the iterator to the first element whose id is greater than the +// given number. It returns whether such element exists. +// +// Note, this operation will unset the exhausted status and subsequent traversal +// is allowed. +func (it *indexIterator) SeekGT(id uint64) bool { + if it.err != nil { + return false + } + index := sort.Search(len(it.descList), func(i int) bool { + return id < it.descList[i].max + }) + index, err := it.applyFilter(index) + if err != nil { + it.setErr(err) + return false + } + if index == len(it.descList) { + return false + } + it.exhausted = false + + if it.blockIt == nil || it.blockPtr != index { + if err := it.open(index); err != nil { + it.setErr(err) + return false + } + } + // Terminate if the element which is greater than the id can be found in the + // last block; otherwise move to the next block. It may happen that all the + // target elements in this block are all less than id. + if it.blockIt.SeekGT(id) { + return true + } + return it.Next() +} + +func (it *indexIterator) init() error { + if it.blockIt != nil { + return nil + } + return it.open(0) +} + +// Next implements the HistoryIndexIterator, moving the iterator to the next +// element. If the iterator has been exhausted, and boolean with false should +// be returned. +func (it *indexIterator) Next() bool { + if it.exhausted || it.err != nil { + return false + } + if err := it.init(); err != nil { + it.setErr(err) + return false + } + if it.blockIt.Next() { + return true + } + it.blockPtr++ + + index, err := it.applyFilter(it.blockPtr) + if err != nil { + it.setErr(err) + return false + } + it.blockPtr = index + + if it.blockPtr == len(it.descList) { + it.exhausted = true + return false + } + if err := it.open(it.blockPtr); err != nil { + it.setErr(err) + return false + } + return it.blockIt.Next() +} + +// Error implements HistoryIndexIterator, returning any accumulated error. +// Exhausting all the elements is not considered to be an error. +func (it *indexIterator) Error() error { + if it.err != nil { + return it.err + } + if it.blockIt != nil { + return it.blockIt.Error() + } + return nil +} + +// ID implements HistoryIndexIterator, returning the id of the element where the +// iterator is positioned at. +func (it *indexIterator) ID() uint64 { + return it.blockIt.ID() +} + +// seqIter provides a simple iterator over a contiguous sequence of +// unsigned integers, ending at end (end is included). +type seqIter struct { + cur uint64 // current position + end uint64 // iteration stops at end-1 + done bool // true when iteration is exhausted +} + +func newSeqIter(last uint64) *seqIter { + return &seqIter{end: last + 1} +} + +// SeekGT positions the iterator at the smallest element > id. +// Returns false if no such element exists. +func (it *seqIter) SeekGT(id uint64) bool { + if id+1 >= it.end { + it.done = true + return false + } + it.cur = id + 1 + it.done = false + return true +} + +// Next advances the iterator. Returns false if exhausted. +func (it *seqIter) Next() bool { + if it.done { + return false + } + if it.cur+1 < it.end { + it.cur++ + return true + } + // this was the last element + it.done = true + return false +} + +// ID returns the id of the element where the iterator is positioned at. +func (it *seqIter) ID() uint64 { return it.cur } + +// Error returns any accumulated error. Exhausting all the elements is not +// considered to be an error. +func (it *seqIter) Error() error { return nil } diff --git a/triedb/pathdb/history_index_iterator_test.go b/triedb/pathdb/history_index_iterator_test.go new file mode 100644 index 0000000000..a11fd17666 --- /dev/null +++ b/triedb/pathdb/history_index_iterator_test.go @@ -0,0 +1,361 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see 0 { + filter = &filters[rand.Intn(len(filters))] + } else { + filter = nil + } + + var input uint64 + if rand.Intn(2) == 0 { + input = elements[rand.Intn(len(elements))] + } else { + input = uint64(rand.Uint32()) + } + + index := sort.Search(len(elements), func(i int) bool { + return elements[i] > input + }) + for index < len(elements) { + if checkExt(filter, ext[index]) { + break + } + index++ + } + + var ( + exp bool + expVal uint64 + remains []uint64 + ) + if index == len(elements) { + exp = false + } else { + exp = true + expVal = elements[index] + + index++ + for index < len(elements) { + if checkExt(filter, ext[index]) { + remains = append(remains, elements[index]) + } + index++ + } + } + + it := newIter(filter) + if err := checkSeekGT(it, input, exp, expVal); err != nil { + t.Fatal(err) + } + if exp { + if err := checkNext(it, remains); err != nil { + t.Fatal(err) + } + } + } +} + +func verifyTraversal(t *testing.T, elements []uint64, ext [][]uint16, newIter func(filter *extFilter) HistoryIndexIterator) { + set := make(map[extFilter]bool) + for _, extList := range ext { + for _, f := range extList { + set[extFilter(f)] = true + } + } + filters := slices.Collect(maps.Keys(set)) + + for i := 0; i < 16; i++ { + var filter *extFilter + if len(filters) > 0 { + filter = &filters[rand.Intn(len(filters))] + } else { + filter = nil + } + it := newIter(filter) + + var ( + pos int + exp []uint64 + ) + for pos < len(elements) { + if checkExt(filter, ext[pos]) { + exp = append(exp, elements[pos]) + } + pos++ + } + if err := checkNext(it, exp); err != nil { + t.Fatal(err) + } + } +} + +func TestBlockIteratorSeekGT(t *testing.T) { + for _, size := range []int{0, 2, 34} { + for _, n := range []int{1, indexBlockRestartLen, 3 * indexBlockRestartLen} { + data, elements, ext := makeTestIndexBlock(n, size) + + verifySeekGT(t, elements, ext, func(filter *extFilter) HistoryIndexIterator { + br, err := newBlockReader(data, size != 0) + if err != nil { + t.Fatalf("Failed to open the block for reading, %v", err) + } + return br.newIterator(filter) + }) + } + } +} + +func TestIndexIteratorSeekGT(t *testing.T) { + ident := newAccountIdent(common.Hash{0x1}) + + for _, size := range []int{0, 2, 34} { + for _, n := range []int{1, 4096, 3 * 4096} { + db := rawdb.NewMemoryDatabase() + elements, ext := makeTestIndexBlocks(db, ident, n, size) + + verifySeekGT(t, elements, ext, func(filter *extFilter) HistoryIndexIterator { + ir, err := newIndexReader(db, ident, size) + if err != nil { + t.Fatalf("Failed to open the index reader, %v", err) + } + return ir.newIterator(filter) + }) + } + } +} + +func TestBlockIteratorTraversal(t *testing.T) { + /* 0-size index block is not allowed + + data, elements := makeTestIndexBlock(0) + testBlockIterator(t, data, elements) + */ + + for _, size := range []int{0, 2, 34} { + for _, n := range []int{1, indexBlockRestartLen, 3 * indexBlockRestartLen} { + data, elements, ext := makeTestIndexBlock(n, size) + + verifyTraversal(t, elements, ext, func(filter *extFilter) HistoryIndexIterator { + br, err := newBlockReader(data, size != 0) + if err != nil { + t.Fatalf("Failed to open the block for reading, %v", err) + } + return br.newIterator(filter) + }) + } + } +} + +func TestIndexIteratorTraversal(t *testing.T) { + ident := newAccountIdent(common.Hash{0x1}) + + for _, size := range []int{0, 2, 34} { + for _, n := range []int{1, 4096, 3 * 4096} { + db := rawdb.NewMemoryDatabase() + elements, ext := makeTestIndexBlocks(db, ident, n, size) + + verifyTraversal(t, elements, ext, func(filter *extFilter) HistoryIndexIterator { + ir, err := newIndexReader(db, ident, size) + if err != nil { + t.Fatalf("Failed to open the index reader, %v", err) + } + return ir.newIterator(filter) + }) + } + } +} + +func TestSeqIterBasicIteration(t *testing.T) { + it := newSeqIter(5) // iterates over [1..5] + it.SeekGT(0) + + var ( + got []uint64 + expected = []uint64{1, 2, 3, 4, 5} + ) + got = append(got, it.ID()) + for it.Next() { + got = append(got, it.ID()) + } + if len(got) != len(expected) { + t.Fatalf("iteration length mismatch: got %v, expected %v", got, expected) + } + for i := range expected { + if got[i] != expected[i] { + t.Fatalf("element mismatch at %d: got %d, expected %d", i, got[i], expected[i]) + } + } +} + +func TestSeqIterSeekGT(t *testing.T) { + it := newSeqIter(5) + + tests := []struct { + input uint64 + ok bool + expected uint64 + }{ + {0, true, 1}, + {1, true, 2}, + {4, true, 5}, + {5, false, 0}, // 6 is out of range + } + for _, tt := range tests { + ok := it.SeekGT(tt.input) + if ok != tt.ok { + t.Fatalf("SeekGT(%d) ok mismatch: got %v, expected %v", tt.input, ok, tt.ok) + } + if ok && it.ID() != tt.expected { + t.Fatalf("SeekGT(%d) positioned at %d, expected %d", tt.input, it.ID(), tt.expected) + } + } +} diff --git a/triedb/pathdb/history_index_test.go b/triedb/pathdb/history_index_test.go index 7b24b86fd6..2644db46b5 100644 --- a/triedb/pathdb/history_index_test.go +++ b/triedb/pathdb/history_index_test.go @@ -29,19 +29,25 @@ import ( ) func TestIndexReaderBasic(t *testing.T) { + testIndexReaderBasic(t, 0) + testIndexReaderBasic(t, 2) + testIndexReaderBasic(t, 34) +} + +func testIndexReaderBasic(t *testing.T, bitmapSize int) { elements := []uint64{ 1, 5, 10, 11, 20, } db := rawdb.NewMemoryDatabase() - bw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa})) + bw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}), 0, bitmapSize) for i := 0; i < len(elements); i++ { - bw.append(elements[i]) + bw.append(elements[i], randomExt(bitmapSize, 5)) } batch := db.NewBatch() bw.finish(batch) batch.Write() - br, err := newIndexReader(db, newAccountIdent(common.Hash{0xa})) + br, err := newIndexReader(db, newAccountIdent(common.Hash{0xa}), bitmapSize) if err != nil { t.Fatalf("Failed to construct the index reader, %v", err) } @@ -68,22 +74,28 @@ func TestIndexReaderBasic(t *testing.T) { } func TestIndexReaderLarge(t *testing.T) { + testIndexReaderLarge(t, 0) + testIndexReaderLarge(t, 2) + testIndexReaderLarge(t, 34) +} + +func testIndexReaderLarge(t *testing.T, bitmapSize int) { var elements []uint64 - for i := 0; i < 10*indexBlockEntriesCap; i++ { + for i := 0; i < 10*4096; i++ { elements = append(elements, rand.Uint64()) } slices.Sort(elements) db := rawdb.NewMemoryDatabase() - bw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa})) + bw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}), 0, bitmapSize) for i := 0; i < len(elements); i++ { - bw.append(elements[i]) + bw.append(elements[i], randomExt(bitmapSize, 5)) } batch := db.NewBatch() bw.finish(batch) batch.Write() - br, err := newIndexReader(db, newAccountIdent(common.Hash{0xa})) + br, err := newIndexReader(db, newAccountIdent(common.Hash{0xa}), bitmapSize) if err != nil { t.Fatalf("Failed to construct the index reader, %v", err) } @@ -107,7 +119,7 @@ func TestIndexReaderLarge(t *testing.T) { } func TestEmptyIndexReader(t *testing.T) { - br, err := newIndexReader(rawdb.NewMemoryDatabase(), newAccountIdent(common.Hash{0xa})) + br, err := newIndexReader(rawdb.NewMemoryDatabase(), newAccountIdent(common.Hash{0xa}), 0) if err != nil { t.Fatalf("Failed to construct the index reader, %v", err) } @@ -121,57 +133,150 @@ func TestEmptyIndexReader(t *testing.T) { } func TestIndexWriterBasic(t *testing.T) { + testIndexWriterBasic(t, 0) + testIndexWriterBasic(t, 2) + testIndexWriterBasic(t, 34) +} + +func testIndexWriterBasic(t *testing.T, bitmapSize int) { db := rawdb.NewMemoryDatabase() - iw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa})) - iw.append(2) - if err := iw.append(1); err == nil { + iw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}), 0, bitmapSize) + iw.append(2, randomExt(bitmapSize, 5)) + if err := iw.append(1, randomExt(bitmapSize, 5)); err == nil { t.Fatal("out-of-order insertion is not expected") } + var maxElem uint64 for i := 0; i < 10; i++ { - iw.append(uint64(i + 3)) + iw.append(uint64(i+3), randomExt(bitmapSize, 5)) + maxElem = uint64(i + 3) } batch := db.NewBatch() iw.finish(batch) batch.Write() - iw, err := newIndexWriter(db, newAccountIdent(common.Hash{0xa})) + iw, err := newIndexWriter(db, newAccountIdent(common.Hash{0xa}), maxElem, bitmapSize) if err != nil { t.Fatalf("Failed to construct the block writer, %v", err) } for i := 0; i < 10; i++ { - if err := iw.append(uint64(i + 100)); err != nil { + if err := iw.append(uint64(i+100), randomExt(bitmapSize, 5)); err != nil { t.Fatalf("Failed to append item, %v", err) } } iw.finish(db.NewBatch()) } -func TestIndexWriterDelete(t *testing.T) { +func TestIndexWriterWithLimit(t *testing.T) { + testIndexWriterWithLimit(t, 0) + testIndexWriterWithLimit(t, 2) + testIndexWriterWithLimit(t, 34) +} + +func testIndexWriterWithLimit(t *testing.T, bitmapSize int) { db := rawdb.NewMemoryDatabase() - iw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa})) - for i := 0; i < indexBlockEntriesCap*4; i++ { - iw.append(uint64(i + 1)) + iw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}), 0, bitmapSize) + + // 200 iterations (with around 50 bytes extension) is enough to cross + // the block boundary (4096 bytes) + for i := 0; i < 200; i++ { + iw.append(uint64(i+1), randomExt(bitmapSize, 50)) + } + batch := db.NewBatch() + iw.finish(batch) + batch.Write() + + for i := 0; i < 200; i++ { + limit := uint64(i + 1) + iw, err := newIndexWriter(db, newAccountIdent(common.Hash{0xa}), limit, bitmapSize) + if err != nil { + t.Fatalf("Failed to construct the index writer, %v", err) + } + if iw.lastID != limit { + t.Fatalf("Test %d, unexpected max value, got %d, want %d", i, iw.lastID, limit) + } + // Re-fill the elements + var maxElem uint64 + for elem := limit + 1; elem < 500; elem++ { + if err := iw.append(elem, randomExt(bitmapSize, 5)); err != nil { + t.Fatalf("Failed to append value %d: %v", elem, err) + } + maxElem = elem + } + if iw.lastID != maxElem { + t.Fatalf("Test %d, unexpected max value, got %d, want %d", i, iw.lastID, maxElem) + } + } +} + +func TestIndexDeleterBasic(t *testing.T) { + testIndexDeleterBasic(t, 0) + testIndexDeleterBasic(t, 2) + testIndexDeleterBasic(t, 34) +} + +func testIndexDeleterBasic(t *testing.T, bitmapSize int) { + db := rawdb.NewMemoryDatabase() + iw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}), 0, bitmapSize) + + // 200 iterations (with around 50 bytes extension) is enough to cross + // the block boundary (4096 bytes) + var maxElem uint64 + for i := 0; i < 200; i++ { + iw.append(uint64(i+1), randomExt(bitmapSize, 50)) + maxElem = uint64(i + 1) } batch := db.NewBatch() iw.finish(batch) batch.Write() // Delete unknown id, the request should be rejected - id, _ := newIndexDeleter(db, newAccountIdent(common.Hash{0xa})) - if err := id.pop(indexBlockEntriesCap * 5); err == nil { + id, _ := newIndexDeleter(db, newAccountIdent(common.Hash{0xa}), maxElem, bitmapSize) + if err := id.pop(500); err == nil { t.Fatal("Expect error to occur for unknown id") } - for i := indexBlockEntriesCap * 4; i >= 1; i-- { + for i := 200; i >= 1; i-- { if err := id.pop(uint64(i)); err != nil { t.Fatalf("Unexpected error for element popping, %v", err) } if id.lastID != uint64(i-1) { t.Fatalf("Unexpected lastID, want: %d, got: %d", uint64(i-1), iw.lastID) } - if rand.Intn(10) == 0 { - batch := db.NewBatch() - id.finish(batch) - batch.Write() + } +} + +func TestIndexDeleterWithLimit(t *testing.T) { + testIndexDeleterWithLimit(t, 0) + testIndexDeleterWithLimit(t, 2) + testIndexDeleterWithLimit(t, 34) +} + +func testIndexDeleterWithLimit(t *testing.T, bitmapSize int) { + db := rawdb.NewMemoryDatabase() + iw, _ := newIndexWriter(db, newAccountIdent(common.Hash{0xa}), 0, bitmapSize) + + // 200 iterations (with around 50 bytes extension) is enough to cross + // the block boundary (4096 bytes) + for i := 0; i < 200; i++ { + iw.append(uint64(i+1), randomExt(bitmapSize, 50)) + } + batch := db.NewBatch() + iw.finish(batch) + batch.Write() + + for i := 0; i < 200; i++ { + limit := uint64(i + 1) + id, err := newIndexDeleter(db, newAccountIdent(common.Hash{0xa}), limit, bitmapSize) + if err != nil { + t.Fatalf("Failed to construct the index writer, %v", err) + } + if id.lastID != limit { + t.Fatalf("Test %d, unexpected max value, got %d, want %d", i, iw.lastID, limit) + } + // Keep removing elements + for elem := id.lastID; elem > 0; elem-- { + if err := id.pop(elem); err != nil { + t.Fatalf("Failed to pop value %d: %v", elem, err) + } } } } @@ -179,8 +284,8 @@ func TestIndexWriterDelete(t *testing.T) { func TestBatchIndexerWrite(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - batch = newBatchIndexer(db, false) - histories = makeHistories(10) + batch = newBatchIndexer(db, false, typeStateHistory) + histories = makeStateHistories(10) ) for i, h := range histories { if err := batch.process(h, uint64(i+1)); err != nil { @@ -190,7 +295,7 @@ func TestBatchIndexerWrite(t *testing.T) { if err := batch.finish(true); err != nil { t.Fatalf("Failed to finish batch indexer, %v", err) } - metadata := loadIndexMetadata(db) + metadata := loadIndexMetadata(db, typeStateHistory) if metadata == nil || metadata.Last != uint64(10) { t.Fatal("Unexpected index position") } @@ -212,7 +317,7 @@ func TestBatchIndexerWrite(t *testing.T) { } } for addrHash, indexes := range accounts { - ir, _ := newIndexReader(db, newAccountIdent(addrHash)) + ir, _ := newIndexReader(db, newAccountIdent(addrHash), 0) for i := 0; i < len(indexes)-1; i++ { n, err := ir.readGreaterThan(indexes[i]) if err != nil { @@ -232,7 +337,7 @@ func TestBatchIndexerWrite(t *testing.T) { } for addrHash, slots := range storages { for slotHash, indexes := range slots { - ir, _ := newIndexReader(db, newStorageIdent(addrHash, slotHash)) + ir, _ := newIndexReader(db, newStorageIdent(addrHash, slotHash), 0) for i := 0; i < len(indexes)-1; i++ { n, err := ir.readGreaterThan(indexes[i]) if err != nil { @@ -256,8 +361,8 @@ func TestBatchIndexerWrite(t *testing.T) { func TestBatchIndexerDelete(t *testing.T) { var ( db = rawdb.NewMemoryDatabase() - bw = newBatchIndexer(db, false) - histories = makeHistories(10) + bw = newBatchIndexer(db, false, typeStateHistory) + histories = makeStateHistories(10) ) // Index histories for i, h := range histories { @@ -270,7 +375,7 @@ func TestBatchIndexerDelete(t *testing.T) { } // Unindex histories - bd := newBatchIndexer(db, true) + bd := newBatchIndexer(db, true, typeStateHistory) for i := len(histories) - 1; i >= 0; i-- { if err := bd.process(histories[i], uint64(i+1)); err != nil { t.Fatalf("Failed to process history, %v", err) @@ -280,7 +385,7 @@ func TestBatchIndexerDelete(t *testing.T) { t.Fatalf("Failed to finish batch indexer, %v", err) } - metadata := loadIndexMetadata(db) + metadata := loadIndexMetadata(db, typeStateHistory) if metadata != nil { t.Fatal("Unexpected index position") } diff --git a/triedb/pathdb/history_indexer.go b/triedb/pathdb/history_indexer.go index 054d43e946..c987b380ed 100644 --- a/triedb/pathdb/history_indexer.go +++ b/triedb/pathdb/history_indexer.go @@ -26,7 +26,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" @@ -35,19 +34,45 @@ import ( const ( // The batch size for reading state histories - historyReadBatch = 1000 + historyReadBatch = 1000 + historyIndexBatch = 8 * 1024 * 1024 // The number of state history indexes for constructing or deleting as batch - stateIndexV0 = uint8(0) // initial version of state index structure - stateIndexVersion = stateIndexV0 // the current state index version + stateHistoryIndexV0 = uint8(0) // initial version of state index structure + stateHistoryIndexVersion = stateHistoryIndexV0 // the current state index version + trienodeHistoryIndexV0 = uint8(0) // initial version of trienode index structure + trienodeHistoryIndexVersion = trienodeHistoryIndexV0 // the current trienode index version ) +// indexVersion returns the latest index version for the given history type. +// It panics if the history type is unknown. +func indexVersion(typ historyType) uint8 { + switch typ { + case typeStateHistory: + return stateHistoryIndexVersion + case typeTrienodeHistory: + return trienodeHistoryIndexVersion + default: + panic(fmt.Errorf("unknown history type: %d", typ)) + } +} + +// indexMetadata describes the metadata of the historical data index. type indexMetadata struct { Version uint8 Last uint64 } -func loadIndexMetadata(db ethdb.KeyValueReader) *indexMetadata { - blob := rawdb.ReadStateHistoryIndexMetadata(db) +// loadIndexMetadata reads the metadata of the specific history index. +func loadIndexMetadata(db ethdb.KeyValueReader, typ historyType) *indexMetadata { + var blob []byte + switch typ { + case typeStateHistory: + blob = rawdb.ReadStateHistoryIndexMetadata(db) + case typeTrienodeHistory: + blob = rawdb.ReadTrienodeHistoryIndexMetadata(db) + default: + panic(fmt.Errorf("unknown history type %d", typ)) + } if len(blob) == 0 { return nil } @@ -59,181 +84,185 @@ func loadIndexMetadata(db ethdb.KeyValueReader) *indexMetadata { return &m } -func storeIndexMetadata(db ethdb.KeyValueWriter, last uint64) { - var m indexMetadata - m.Version = stateIndexVersion - m.Last = last +// storeIndexMetadata stores the metadata of the specific history index. +func storeIndexMetadata(db ethdb.KeyValueWriter, typ historyType, last uint64) { + m := indexMetadata{ + Version: indexVersion(typ), + Last: last, + } blob, err := rlp.EncodeToBytes(m) if err != nil { - log.Crit("Failed to encode index metadata", "err", err) + panic(fmt.Errorf("fail to encode index metadata, %v", err)) } - rawdb.WriteStateHistoryIndexMetadata(db, blob) + switch typ { + case typeStateHistory: + rawdb.WriteStateHistoryIndexMetadata(db, blob) + case typeTrienodeHistory: + rawdb.WriteTrienodeHistoryIndexMetadata(db, blob) + default: + panic(fmt.Errorf("unknown history type %d", typ)) + } + log.Debug("Written index metadata", "type", typ, "last", last) } -// batchIndexer is a structure designed to perform batch indexing or unindexing -// of state histories atomically. +// deleteIndexMetadata deletes the metadata of the specific history index. +func deleteIndexMetadata(db ethdb.KeyValueWriter, typ historyType) { + switch typ { + case typeStateHistory: + rawdb.DeleteStateHistoryIndexMetadata(db) + case typeTrienodeHistory: + rawdb.DeleteTrienodeHistoryIndexMetadata(db) + default: + panic(fmt.Errorf("unknown history type %d", typ)) + } + log.Debug("Deleted index metadata", "type", typ) +} + +// batchIndexer is responsible for performing batch indexing or unindexing +// of historical data (e.g., state or trie node changes) atomically. type batchIndexer struct { - accounts map[common.Hash][]uint64 // History ID list, Keyed by the hash of account address - storages map[common.Hash]map[common.Hash][]uint64 // History ID list, Keyed by the hash of account address and the hash of raw storage key - counter int // The counter of processed states - delete bool // Index or unindex mode - lastID uint64 // The ID of latest processed history - db ethdb.KeyValueStore + index map[stateIdent][]uint64 // List of history IDs for tracked state entry + ext map[stateIdent][][]uint16 // List of extension for each state element + pending int // Number of entries processed in the current batch. + delete bool // Operation mode: true for unindex, false for index. + lastID uint64 // ID of the most recently processed history. + typ historyType // Type of history being processed (e.g., state or trienode). + db ethdb.KeyValueStore // Key-value database used to store or delete index data. } // newBatchIndexer constructs the batch indexer with the supplied mode. -func newBatchIndexer(db ethdb.KeyValueStore, delete bool) *batchIndexer { +func newBatchIndexer(db ethdb.KeyValueStore, delete bool, typ historyType) *batchIndexer { return &batchIndexer{ - accounts: make(map[common.Hash][]uint64), - storages: make(map[common.Hash]map[common.Hash][]uint64), - delete: delete, - db: db, + index: make(map[stateIdent][]uint64), + ext: make(map[stateIdent][][]uint16), + delete: delete, + typ: typ, + db: db, } } -// process iterates through the accounts and their associated storage slots in the -// state history, tracking the mapping between state and history IDs. -func (b *batchIndexer) process(h *history, historyID uint64) error { - for _, address := range h.accountList { - addrHash := crypto.Keccak256Hash(address.Bytes()) - b.counter += 1 - b.accounts[addrHash] = append(b.accounts[addrHash], historyID) - - for _, slotKey := range h.storageList[address] { - b.counter += 1 - if _, ok := b.storages[addrHash]; !ok { - b.storages[addrHash] = make(map[common.Hash][]uint64) - } - // The hash of the storage slot key is used as the identifier because the - // legacy history does not include the raw storage key, therefore, the - // conversion from storage key to hash is necessary for non-v0 histories. - slotHash := slotKey - if h.meta.version != stateHistoryV0 { - slotHash = crypto.Keccak256Hash(slotKey.Bytes()) - } - b.storages[addrHash][slotHash] = append(b.storages[addrHash][slotHash], historyID) - } +// process traverses the state entries within the provided history and tracks the mutation +// records for them. +func (b *batchIndexer) process(h history, id uint64) error { + for elem := range h.forEach() { + key := elem.key() + b.index[key] = append(b.index[key], id) + b.ext[key] = append(b.ext[key], elem.ext()) + b.pending++ } - b.lastID = historyID + b.lastID = id + return b.finish(false) } // finish writes the accumulated state indexes into the disk if either the // memory limitation is reached or it's requested forcibly. func (b *batchIndexer) finish(force bool) error { - if b.counter == 0 { + if b.pending == 0 { return nil } - if !force && b.counter < historyIndexBatch { + if !force && b.pending < historyIndexBatch { return nil } var ( - batch = b.db.NewBatch() - batchMu sync.RWMutex - storages int - start = time.Now() - eg errgroup.Group + start = time.Now() + eg errgroup.Group + + batch = b.db.NewBatchWithSize(ethdb.IdealBatchSize) + batchSize int + batchMu sync.RWMutex + + writeBatch = func(fn func(batch ethdb.Batch)) error { + batchMu.Lock() + defer batchMu.Unlock() + + fn(batch) + if batch.ValueSize() >= ethdb.IdealBatchSize { + batchSize += batch.ValueSize() + if err := batch.Write(); err != nil { + return err + } + batch.Reset() + } + return nil + } ) eg.SetLimit(runtime.NumCPU()) - for addrHash, idList := range b.accounts { + var indexed uint64 + if metadata := loadIndexMetadata(b.db, b.typ); metadata != nil { + indexed = metadata.Last + } + for ident, list := range b.index { + ext := b.ext[ident] eg.Go(func() error { if !b.delete { - iw, err := newIndexWriter(b.db, newAccountIdent(addrHash)) + iw, err := newIndexWriter(b.db, ident, indexed, ident.bloomSize()) if err != nil { return err } - for _, n := range idList { - if err := iw.append(n); err != nil { + for i, n := range list { + if err := iw.append(n, ext[i]); err != nil { return err } } - batchMu.Lock() - iw.finish(batch) - batchMu.Unlock() + return writeBatch(func(batch ethdb.Batch) { + iw.finish(batch) + }) } else { - id, err := newIndexDeleter(b.db, newAccountIdent(addrHash)) + id, err := newIndexDeleter(b.db, ident, indexed, ident.bloomSize()) if err != nil { return err } - for _, n := range idList { + for _, n := range list { if err := id.pop(n); err != nil { return err } } - batchMu.Lock() - id.finish(batch) - batchMu.Unlock() - } - return nil - }) - } - for addrHash, slots := range b.storages { - storages += len(slots) - for storageHash, idList := range slots { - eg.Go(func() error { - if !b.delete { - iw, err := newIndexWriter(b.db, newStorageIdent(addrHash, storageHash)) - if err != nil { - return err - } - for _, n := range idList { - if err := iw.append(n); err != nil { - return err - } - } - batchMu.Lock() - iw.finish(batch) - batchMu.Unlock() - } else { - id, err := newIndexDeleter(b.db, newStorageIdent(addrHash, storageHash)) - if err != nil { - return err - } - for _, n := range idList { - if err := id.pop(n); err != nil { - return err - } - } - batchMu.Lock() + return writeBatch(func(batch ethdb.Batch) { id.finish(batch) - batchMu.Unlock() - } - return nil - }) - } + }) + } + }) } if err := eg.Wait(); err != nil { return err } // Update the position of last indexed state history if !b.delete { - storeIndexMetadata(batch, b.lastID) + storeIndexMetadata(batch, b.typ, b.lastID) } else { if b.lastID == 1 { - rawdb.DeleteStateHistoryIndexMetadata(batch) + deleteIndexMetadata(batch, b.typ) } else { - storeIndexMetadata(batch, b.lastID-1) + storeIndexMetadata(batch, b.typ, b.lastID-1) } } + batchSize += batch.ValueSize() + if err := batch.Write(); err != nil { return err } - log.Debug("Committed batch indexer", "accounts", len(b.accounts), "storages", storages, "records", b.counter, "elapsed", common.PrettyDuration(time.Since(start))) - b.counter = 0 - b.accounts = make(map[common.Hash][]uint64) - b.storages = make(map[common.Hash]map[common.Hash][]uint64) + log.Debug("Committed batch indexer", "type", b.typ, "entries", len(b.index), "records", b.pending, "size", common.StorageSize(batchSize), "elapsed", common.PrettyDuration(time.Since(start))) + + b.pending = 0 + clear(b.index) + clear(b.ext) return nil } // indexSingle processes the state history with the specified ID for indexing. -func indexSingle(historyID uint64, db ethdb.KeyValueStore, freezer ethdb.AncientReader) error { +func indexSingle(historyID uint64, db ethdb.KeyValueStore, freezer ethdb.AncientReader, typ historyType) error { start := time.Now() defer func() { - indexHistoryTimer.UpdateSince(start) + if typ == typeStateHistory { + stateIndexHistoryTimer.UpdateSince(start) + } else if typ == typeTrienodeHistory { + trienodeIndexHistoryTimer.UpdateSince(start) + } }() - metadata := loadIndexMetadata(db) + metadata := loadIndexMetadata(db, typ) if metadata == nil || metadata.Last+1 != historyID { last := "null" if metadata != nil { @@ -241,29 +270,41 @@ func indexSingle(historyID uint64, db ethdb.KeyValueStore, freezer ethdb.Ancient } return fmt.Errorf("history indexing is out of order, last: %s, requested: %d", last, historyID) } - h, err := readHistory(freezer, historyID) + var ( + err error + h history + b = newBatchIndexer(db, false, typ) + ) + if typ == typeStateHistory { + h, err = readStateHistory(freezer, historyID) + } else { + h, err = readTrienodeHistory(freezer, historyID) + } if err != nil { return err } - b := newBatchIndexer(db, false) if err := b.process(h, historyID); err != nil { return err } if err := b.finish(true); err != nil { return err } - log.Debug("Indexed state history", "id", historyID, "elapsed", common.PrettyDuration(time.Since(start))) + log.Debug("Indexed history", "type", typ, "id", historyID, "elapsed", common.PrettyDuration(time.Since(start))) return nil } // unindexSingle processes the state history with the specified ID for unindexing. -func unindexSingle(historyID uint64, db ethdb.KeyValueStore, freezer ethdb.AncientReader) error { +func unindexSingle(historyID uint64, db ethdb.KeyValueStore, freezer ethdb.AncientReader, typ historyType) error { start := time.Now() defer func() { - unindexHistoryTimer.UpdateSince(start) + if typ == typeStateHistory { + stateUnindexHistoryTimer.UpdateSince(start) + } else if typ == typeTrienodeHistory { + trienodeUnindexHistoryTimer.UpdateSince(start) + } }() - metadata := loadIndexMetadata(db) + metadata := loadIndexMetadata(db, typ) if metadata == nil || metadata.Last != historyID { last := "null" if metadata != nil { @@ -271,18 +312,26 @@ func unindexSingle(historyID uint64, db ethdb.KeyValueStore, freezer ethdb.Ancie } return fmt.Errorf("history unindexing is out of order, last: %s, requested: %d", last, historyID) } - h, err := readHistory(freezer, historyID) + var ( + err error + h history + ) + b := newBatchIndexer(db, true, typ) + if typ == typeStateHistory { + h, err = readStateHistory(freezer, historyID) + } else { + h, err = readTrienodeHistory(freezer, historyID) + } if err != nil { return err } - b := newBatchIndexer(db, true) if err := b.process(h, historyID); err != nil { return err } if err := b.finish(true); err != nil { return err } - log.Debug("Unindexed state history", "id", historyID, "elapsed", common.PrettyDuration(time.Since(start))) + log.Debug("Unindexed history", "type", typ, "id", historyID, "elapsed", common.PrettyDuration(time.Since(start))) return nil } @@ -305,6 +354,8 @@ type indexIniter struct { interrupt chan *interruptSignal done chan struct{} closed chan struct{} + typ historyType + log log.Logger // Contextual logger with the history type injected // indexing progress indexed atomic.Uint64 // the id of latest indexed state @@ -313,24 +364,33 @@ type indexIniter struct { wg sync.WaitGroup } -func newIndexIniter(disk ethdb.KeyValueStore, freezer ethdb.AncientStore, lastID uint64) *indexIniter { +func newIndexIniter(disk ethdb.KeyValueStore, freezer ethdb.AncientStore, typ historyType, lastID uint64) *indexIniter { initer := &indexIniter{ disk: disk, freezer: freezer, interrupt: make(chan *interruptSignal), done: make(chan struct{}), closed: make(chan struct{}), + typ: typ, + log: log.New("type", typ.String()), } // Load indexing progress + var recover bool initer.last.Store(lastID) - metadata := loadIndexMetadata(disk) + metadata := loadIndexMetadata(disk, typ) if metadata != nil { initer.indexed.Store(metadata.Last) + recover = metadata.Last > lastID } // Launch background indexer initer.wg.Add(1) - go initer.run(lastID) + if recover { + log.Info("History indexer is recovering", "history", lastID, "indexed", metadata.Last) + go initer.recover(lastID) + } else { + go initer.run(lastID) + } return initer } @@ -364,8 +424,8 @@ func (i *indexIniter) remain() uint64 { default: last, indexed := i.last.Load(), i.indexed.Load() if last < indexed { - log.Error("Invalid state indexing range", "last", last, "indexed", indexed) - return 0 + i.log.Warn("State indexer is in recovery", "indexed", indexed, "last", last) + return indexed - last } return last - indexed } @@ -382,7 +442,7 @@ func (i *indexIniter) run(lastID uint64) { // checkDone indicates whether all requested state histories // have been fully indexed. checkDone = func() bool { - metadata := loadIndexMetadata(i.disk) + metadata := loadIndexMetadata(i.disk, i.typ) return metadata != nil && metadata.Last == lastID } ) @@ -404,7 +464,7 @@ func (i *indexIniter) run(lastID uint64) { if newLastID == lastID+1 { lastID = newLastID signal.result <- nil - log.Debug("Extended state history range", "last", lastID) + i.log.Debug("Extended history range", "last", lastID) continue } // The index limit is shortened by one, interrupt the current background @@ -415,14 +475,14 @@ func (i *indexIniter) run(lastID uint64) { // If all state histories, including the one to be reverted, have // been fully indexed, unindex it here and shut down the initializer. if checkDone() { - log.Info("Truncate the extra history", "id", lastID) - if err := unindexSingle(lastID, i.disk, i.freezer); err != nil { + i.log.Info("Truncate the extra history", "id", lastID) + if err := unindexSingle(lastID, i.disk, i.freezer, i.typ); err != nil { signal.result <- err return } close(i.done) signal.result <- nil - log.Info("State histories have been fully indexed", "last", lastID-1) + i.log.Info("Histories have been fully indexed", "last", lastID-1) return } // Adjust the indexing target and relaunch the process @@ -431,12 +491,12 @@ func (i *indexIniter) run(lastID uint64) { done, interrupt = make(chan struct{}), new(atomic.Int32) go i.index(done, interrupt, lastID) - log.Debug("Shortened state history range", "last", lastID) + i.log.Debug("Shortened history range", "last", lastID) case <-done: if checkDone() { close(i.done) - log.Info("State histories have been fully indexed", "last", lastID) + i.log.Info("Histories have been fully indexed", "last", lastID) return } // Relaunch the background runner if some tasks are left @@ -445,7 +505,7 @@ func (i *indexIniter) run(lastID uint64) { case <-i.closed: interrupt.Store(1) - log.Info("Waiting background history index initer to exit") + i.log.Info("Waiting background history index initer to exit") <-done if checkDone() { @@ -465,14 +525,14 @@ func (i *indexIniter) next() (uint64, error) { tailID := tail + 1 // compute the id of the oldest history // Start indexing from scratch if nothing has been indexed - metadata := loadIndexMetadata(i.disk) + metadata := loadIndexMetadata(i.disk, i.typ) if metadata == nil { - log.Debug("Initialize state history indexing from scratch", "id", tailID) + i.log.Debug("Initialize history indexing from scratch", "id", tailID) return tailID, nil } // Resume indexing from the last interrupted position if metadata.Last+1 >= tailID { - log.Debug("Resume state history indexing", "id", metadata.Last+1, "tail", tailID) + i.log.Debug("Resume history indexing", "id", metadata.Last+1, "tail", tailID) return metadata.Last + 1, nil } // History has been shortened without indexing. Discard the gapped segment @@ -480,7 +540,7 @@ func (i *indexIniter) next() (uint64, error) { // // The missing indexes corresponding to the gapped histories won't be visible. // It's fine to leave them unindexed. - log.Info("History gap detected, discard old segment", "oldHead", metadata.Last, "newHead", tailID) + i.log.Info("History gap detected, discard old segment", "oldHead", metadata.Last, "newHead", tailID) return tailID, nil } @@ -489,7 +549,7 @@ func (i *indexIniter) index(done chan struct{}, interrupt *atomic.Int32, lastID beginID, err := i.next() if err != nil { - log.Error("Failed to find next state history for indexing", "err", err) + i.log.Error("Failed to find next history for indexing", "err", err) return } // All available state histories have been indexed, and the last indexed one @@ -504,36 +564,47 @@ func (i *indexIniter) index(done chan struct{}, interrupt *atomic.Int32, lastID // // This step is essential to avoid spinning up indexing thread // endlessly until a history object is produced. - storeIndexMetadata(i.disk, 0) - log.Info("Initialized history indexing flag") + storeIndexMetadata(i.disk, i.typ, 0) + i.log.Info("Initialized history indexing flag") } else { - log.Debug("State history is fully indexed", "last", lastID) + i.log.Debug("History is fully indexed", "last", lastID) } return } - log.Info("Start history indexing", "beginID", beginID, "lastID", lastID) + i.log.Info("Start history indexing", "beginID", beginID, "lastID", lastID) var ( current = beginID start = time.Now() logged = time.Now() - batch = newBatchIndexer(i.disk, false) + batch = newBatchIndexer(i.disk, false, i.typ) ) for current <= lastID { count := lastID - current + 1 if count > historyReadBatch { count = historyReadBatch } - histories, err := readHistories(i.freezer, current, count) - if err != nil { - // The history read might fall if the history is truncated from - // head due to revert operation. - log.Error("Failed to read history for indexing", "current", current, "count", count, "err", err) - return + var histories []history + if i.typ == typeStateHistory { + histories, err = readStateHistories(i.freezer, current, count) + if err != nil { + // The history read might fall if the history is truncated from + // head due to revert operation. + i.log.Error("Failed to read history for indexing", "current", current, "count", count, "err", err) + return + } + } else { + histories, err = readTrienodeHistories(i.freezer, current, count) + if err != nil { + // The history read might fall if the history is truncated from + // head due to revert operation. + i.log.Error("Failed to read history for indexing", "current", current, "count", count, "err", err) + return + } } for _, h := range histories { if err := batch.process(h, current); err != nil { - log.Error("Failed to index history", "err", err) + i.log.Error("Failed to index history", "err", err) return } current += 1 @@ -543,13 +614,11 @@ func (i *indexIniter) index(done chan struct{}, interrupt *atomic.Int32, lastID logged = time.Now() var ( - left = lastID - current + 1 - done = current - beginID - speed = done/uint64(time.Since(start)/time.Millisecond+1) + 1 // +1s to avoid division by zero + left = lastID - current + 1 + done = current - beginID ) - // Override the ETA if larger than the largest until now - eta := time.Duration(left/speed) * time.Millisecond - log.Info("Indexing state history", "processed", done, "left", left, "elapsed", common.PrettyDuration(time.Since(start)), "eta", common.PrettyDuration(eta)) + eta := common.CalculateETA(done, left, time.Since(start)) + i.log.Info("Indexing history", "processed", done, "left", left, "elapsed", common.PrettyDuration(time.Since(start)), "eta", common.PrettyDuration(eta)) } } i.indexed.Store(current - 1) // update indexing progress @@ -558,7 +627,7 @@ func (i *indexIniter) index(done chan struct{}, interrupt *atomic.Int32, lastID if interrupt != nil { if signal := interrupt.Load(); signal != 0 { if err := batch.finish(true); err != nil { - log.Error("Failed to flush index", "err", err) + i.log.Error("Failed to flush index", "err", err) } log.Info("State indexing interrupted") return @@ -566,9 +635,52 @@ func (i *indexIniter) index(done chan struct{}, interrupt *atomic.Int32, lastID } } if err := batch.finish(true); err != nil { - log.Error("Failed to flush index", "err", err) + i.log.Error("Failed to flush index", "err", err) + } + i.log.Info("Indexed history", "from", beginID, "to", lastID, "elapsed", common.PrettyDuration(time.Since(start))) +} + +// recover handles unclean shutdown recovery. After an unclean shutdown, any +// extra histories are typically truncated, while the corresponding history index +// entries may still have been written. Ideally, we would unindex these histories +// in reverse order, but there is no guarantee that the required histories will +// still be available. +// +// As a workaround, indexIniter waits until the missing histories are regenerated +// by chain recovery, under the assumption that the recovered histories will be +// identical to the lost ones. Fork-awareness should be added in the future to +// correctly handle histories affected by reorgs. +func (i *indexIniter) recover(lastID uint64) { + defer i.wg.Done() + + for { + select { + case signal := <-i.interrupt: + newLastID := signal.newLastID + if newLastID != lastID+1 && newLastID != lastID-1 { + signal.result <- fmt.Errorf("invalid history id, last: %d, got: %d", lastID, newLastID) + continue + } + + // Update the last indexed flag + lastID = newLastID + signal.result <- nil + i.last.Store(newLastID) + i.log.Debug("Updated history index flag", "last", lastID) + + // Terminate the recovery routine once the histories are fully aligned + // with the index data, indicating that index initialization is complete. + metadata := loadIndexMetadata(i.disk, i.typ) + if metadata != nil && metadata.Last == lastID { + close(i.done) + i.log.Info("History indexer is recovered", "last", lastID) + return + } + + case <-i.closed: + return + } } - log.Info("Indexed state history", "from", beginID, "to", lastID, "elapsed", common.PrettyDuration(time.Since(start))) } // historyIndexer manages the indexing and unindexing of state histories, @@ -583,38 +695,62 @@ func (i *indexIniter) index(done chan struct{}, interrupt *atomic.Int32, lastID // state history. type historyIndexer struct { initer *indexIniter + typ historyType disk ethdb.KeyValueStore freezer ethdb.AncientStore } // checkVersion checks whether the index data in the database matches the version. -func checkVersion(disk ethdb.KeyValueStore) { - blob := rawdb.ReadStateHistoryIndexMetadata(disk) +func checkVersion(disk ethdb.KeyValueStore, typ historyType) { + var blob []byte + if typ == typeStateHistory { + blob = rawdb.ReadStateHistoryIndexMetadata(disk) + } else if typ == typeTrienodeHistory { + blob = rawdb.ReadTrienodeHistoryIndexMetadata(disk) + } else { + panic(fmt.Errorf("unknown history type: %v", typ)) + } + // Short circuit if metadata is not found, re-index is required + // from scratch. if len(blob) == 0 { return } + // Short circuit if the metadata is found and the version is matched + ver := stateHistoryIndexVersion + if typ == typeTrienodeHistory { + ver = trienodeHistoryIndexVersion + } var m indexMetadata err := rlp.DecodeBytes(blob, &m) - if err == nil && m.Version == stateIndexVersion { + if err == nil && m.Version == ver { return } - // TODO(rjl493456442) would be better to group them into a batch. - rawdb.DeleteStateHistoryIndexMetadata(disk) - rawdb.DeleteStateHistoryIndex(disk) - + // Version is not matched, prune the existing data and re-index from scratch + batch := disk.NewBatch() + if typ == typeStateHistory { + rawdb.DeleteStateHistoryIndexMetadata(batch) + rawdb.DeleteStateHistoryIndexes(batch) + } else { + rawdb.DeleteTrienodeHistoryIndexMetadata(batch) + rawdb.DeleteTrienodeHistoryIndexes(batch) + } + if err := batch.Write(); err != nil { + log.Crit("Failed to purge history index", "type", typ, "err", err) + } version := "unknown" if err == nil { version = fmt.Sprintf("%d", m.Version) } - log.Info("Cleaned up obsolete state history index", "version", version, "want", stateIndexVersion) + log.Info("Cleaned up obsolete history index", "type", typ, "version", version, "want", version) } // newHistoryIndexer constructs the history indexer and launches the background // initer to complete the indexing of any remaining state histories. -func newHistoryIndexer(disk ethdb.KeyValueStore, freezer ethdb.AncientStore, lastHistoryID uint64) *historyIndexer { - checkVersion(disk) +func newHistoryIndexer(disk ethdb.KeyValueStore, freezer ethdb.AncientStore, lastHistoryID uint64, typ historyType) *historyIndexer { + checkVersion(disk, typ) return &historyIndexer{ - initer: newIndexIniter(disk, freezer, lastHistoryID), + initer: newIndexIniter(disk, freezer, typ, lastHistoryID), + typ: typ, disk: disk, freezer: freezer, } @@ -642,7 +778,7 @@ func (i *historyIndexer) extend(historyID uint64) error { case <-i.initer.closed: return errors.New("indexer is closed") case <-i.initer.done: - return indexSingle(historyID, i.disk, i.freezer) + return indexSingle(historyID, i.disk, i.freezer, i.typ) case i.initer.interrupt <- signal: return <-signal.result } @@ -659,7 +795,7 @@ func (i *historyIndexer) shorten(historyID uint64) error { case <-i.initer.closed: return errors.New("indexer is closed") case <-i.initer.done: - return unindexSingle(historyID, i.disk, i.freezer) + return unindexSingle(historyID, i.disk, i.freezer, i.typ) case i.initer.interrupt <- signal: return <-signal.result } diff --git a/triedb/pathdb/history_indexer_test.go b/triedb/pathdb/history_indexer_test.go index abfcafc945..f333d18d8b 100644 --- a/triedb/pathdb/history_indexer_test.go +++ b/triedb/pathdb/history_indexer_test.go @@ -32,13 +32,13 @@ func TestHistoryIndexerShortenDeadlock(t *testing.T) { freezer, _ := rawdb.NewStateFreezer(t.TempDir(), false, false) defer freezer.Close() - histories := makeHistories(100) + histories := makeStateHistories(100) for i, h := range histories { accountData, storageData, accountIndex, storageIndex := h.encode() rawdb.WriteStateHistory(freezer, uint64(i+1), h.meta.encode(), accountIndex, storageIndex, accountData, storageData) } // As a workaround, assign a future block to keep the initer running indefinitely - indexer := newHistoryIndexer(db, freezer, 200) + indexer := newHistoryIndexer(db, freezer, 200, typeStateHistory) defer indexer.close() done := make(chan error, 1) diff --git a/triedb/pathdb/history_inspect.go b/triedb/pathdb/history_inspect.go index 9458e2478b..74b8bb8df2 100644 --- a/triedb/pathdb/history_inspect.go +++ b/triedb/pathdb/history_inspect.go @@ -50,18 +50,18 @@ func sanitizeRange(start, end uint64, freezer ethdb.AncientReader) (uint64, uint if err != nil { return 0, 0, err } - last := head - 1 + last := head if end != 0 && end < last { last = end } // Make sure the range is valid - if first >= last { + if first > last { return 0, 0, fmt.Errorf("range is invalid, first: %d, last: %d", first, last) } return first, last, nil } -func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory func(*history, *HistoryStats)) (*HistoryStats, error) { +func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory func(*stateHistory, *HistoryStats)) (*HistoryStats, error) { var ( stats = &HistoryStats{} init = time.Now() @@ -74,7 +74,7 @@ func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory fu for id := start; id <= end; id += 1 { // The entire history object is decoded, although it's unnecessary for // account inspection. TODO(rjl493456442) optimization is worthwhile. - h, err := readHistory(freezer, id) + h, err := readStateHistory(freezer, id) if err != nil { return nil, err } @@ -98,7 +98,7 @@ func inspectHistory(freezer ethdb.AncientReader, start, end uint64, onHistory fu // accountHistory inspects the account history within the range. func accountHistory(freezer ethdb.AncientReader, address common.Address, start, end uint64) (*HistoryStats, error) { - return inspectHistory(freezer, start, end, func(h *history, stats *HistoryStats) { + return inspectHistory(freezer, start, end, func(h *stateHistory, stats *HistoryStats) { blob, exists := h.accounts[address] if !exists { return @@ -111,7 +111,7 @@ func accountHistory(freezer ethdb.AncientReader, address common.Address, start, // storageHistory inspects the storage history within the range. func storageHistory(freezer ethdb.AncientReader, address common.Address, slot common.Hash, start uint64, end uint64) (*HistoryStats, error) { slotHash := crypto.Keccak256Hash(slot.Bytes()) - return inspectHistory(freezer, start, end, func(h *history, stats *HistoryStats) { + return inspectHistory(freezer, start, end, func(h *stateHistory, stats *HistoryStats) { slots, exists := h.storages[address] if !exists { return @@ -143,13 +143,13 @@ func historyRange(freezer ethdb.AncientReader) (uint64, uint64, error) { if err != nil { return 0, 0, err } - last := head - 1 + last := head - fh, err := readHistory(freezer, first) + fh, err := readStateHistory(freezer, first) if err != nil { return 0, 0, err } - lh, err := readHistory(freezer, last) + lh, err := readStateHistory(freezer, last) if err != nil { return 0, 0, err } diff --git a/triedb/pathdb/history_reader.go b/triedb/pathdb/history_reader.go index d0ecdf035f..a2644c8fd4 100644 --- a/triedb/pathdb/history_reader.go +++ b/triedb/pathdb/history_reader.go @@ -22,95 +22,19 @@ import ( "errors" "fmt" "math" + "slices" "sort" + "sync" + "sync/atomic" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" + "github.com/ethereum/go-ethereum/rlp" + "golang.org/x/sync/errgroup" ) -// stateIdent represents the identifier of a state element, which can be -// either an account or a storage slot. -type stateIdent struct { - account bool - - // The hash of the account address. This is used instead of the raw account - // address is to align the traversal order with the Merkle-Patricia-Trie. - addressHash common.Hash - - // The hash of the storage slot key. This is used instead of the raw slot key - // because, in legacy state histories (prior to the Cancun fork), the slot - // identifier is the hash of the key, and the original key (preimage) cannot - // be recovered. To maintain backward compatibility, the key hash is used. - // - // Meanwhile, using the storage key hash also preserve the traversal order - // with Merkle-Patricia-Trie. - // - // This field is null if the identifier refers to account data. - storageHash common.Hash -} - -// String returns the string format state identifier. -func (ident stateIdent) String() string { - if ident.account { - return ident.addressHash.Hex() - } - return ident.addressHash.Hex() + ident.storageHash.Hex() -} - -// newAccountIdent constructs a state identifier for an account. -func newAccountIdent(addressHash common.Hash) stateIdent { - return stateIdent{ - account: true, - addressHash: addressHash, - } -} - -// newStorageIdent constructs a state identifier for a storage slot. -// The address denotes the address of the associated account; -// the storageHash denotes the hash of the raw storage slot key; -func newStorageIdent(addressHash common.Hash, storageHash common.Hash) stateIdent { - return stateIdent{ - addressHash: addressHash, - storageHash: storageHash, - } -} - -// stateIdentQuery is the extension of stateIdent by adding the raw storage key. -type stateIdentQuery struct { - stateIdent - - address common.Address - storageKey common.Hash -} - -// newAccountIdentQuery constructs a state identifier for an account. -func newAccountIdentQuery(address common.Address, addressHash common.Hash) stateIdentQuery { - return stateIdentQuery{ - stateIdent: stateIdent{ - account: true, - addressHash: addressHash, - }, - address: address, - } -} - -// newStorageIdentQuery constructs a state identifier for a storage slot. -// the address denotes the address of the associated account; -// the addressHash denotes the address hash of the associated account; -// the storageKey denotes the raw storage slot key; -// the storageHash denotes the hash of the raw storage slot key; -func newStorageIdentQuery(address common.Address, addressHash common.Hash, storageKey common.Hash, storageHash common.Hash) stateIdentQuery { - return stateIdentQuery{ - stateIdent: stateIdent{ - addressHash: addressHash, - storageHash: storageHash, - }, - address: address, - storageKey: storageKey, - } -} - // indexReaderWithLimitTag is a wrapper around indexReader that includes an // additional index position. This position represents the ID of the last // indexed state history at the time the reader was created, implying that @@ -122,8 +46,8 @@ type indexReaderWithLimitTag struct { } // newIndexReaderWithLimitTag constructs a index reader with indexing position. -func newIndexReaderWithLimitTag(db ethdb.KeyValueReader, state stateIdent, limit uint64) (*indexReaderWithLimitTag, error) { - r, err := newIndexReader(db, state) +func newIndexReaderWithLimitTag(db ethdb.KeyValueReader, state stateIdent, limit uint64, bitmapSize int) (*indexReaderWithLimitTag, error) { + r, err := newIndexReader(db, state, bitmapSize) if err != nil { return nil, err } @@ -169,7 +93,7 @@ func (r *indexReaderWithLimitTag) readGreaterThan(id uint64, lastID uint64) (uin // Given that it's very unlikely to occur and users try to perform historical // state queries while reverting the states at the same time. Simply returning // an error should be sufficient for now. - metadata := loadIndexMetadata(r.db) + metadata := loadIndexMetadata(r.db, toHistoryType(r.reader.state.typ)) if metadata == nil || metadata.Last < lastID { return 0, errors.New("state history hasn't been indexed yet") } @@ -181,16 +105,17 @@ func (r *indexReaderWithLimitTag) readGreaterThan(id uint64, lastID uint64) (uin return r.reader.readGreaterThan(id) } -// historyReader is the structure to access historic state data. -type historyReader struct { +// stateHistoryReader is the structure to access historic state data. +type stateHistoryReader struct { disk ethdb.KeyValueReader freezer ethdb.AncientReader readers map[string]*indexReaderWithLimitTag } -// newHistoryReader constructs the history reader with the supplied db. -func newHistoryReader(disk ethdb.KeyValueReader, freezer ethdb.AncientReader) *historyReader { - return &historyReader{ +// newStateHistoryReader constructs the history reader with the supplied db +// for accessing historical states. +func newStateHistoryReader(disk ethdb.KeyValueReader, freezer ethdb.AncientReader) *stateHistoryReader { + return &stateHistoryReader{ disk: disk, freezer: freezer, readers: make(map[string]*indexReaderWithLimitTag), @@ -199,7 +124,7 @@ func newHistoryReader(disk ethdb.KeyValueReader, freezer ethdb.AncientReader) *h // readAccountMetadata resolves the account metadata within the specified // state history. -func (r *historyReader) readAccountMetadata(address common.Address, historyID uint64) ([]byte, error) { +func (r *stateHistoryReader) readAccountMetadata(address common.Address, historyID uint64) ([]byte, error) { blob := rawdb.ReadStateAccountIndex(r.freezer, historyID) if len(blob) == 0 { return nil, fmt.Errorf("account index is truncated, historyID: %d", historyID) @@ -225,26 +150,18 @@ func (r *historyReader) readAccountMetadata(address common.Address, historyID ui // readStorageMetadata resolves the storage slot metadata within the specified // state history. -func (r *historyReader) readStorageMetadata(storageKey common.Hash, storageHash common.Hash, historyID uint64, slotOffset, slotNumber int) ([]byte, error) { - // TODO(rj493456442) optimize it with partial read - blob := rawdb.ReadStateStorageIndex(r.freezer, historyID) - if len(blob) == 0 { - return nil, fmt.Errorf("storage index is truncated, historyID: %d", historyID) +func (r *stateHistoryReader) readStorageMetadata(storageKey common.Hash, storageHash common.Hash, historyID uint64, slotOffset, slotNumber int) ([]byte, error) { + data, err := rawdb.ReadStateStorageIndex(r.freezer, historyID, slotIndexSize*slotOffset, slotIndexSize*slotNumber) + if err != nil { + msg := fmt.Sprintf("id: %d, slot-offset: %d, slot-length: %d", historyID, slotOffset, slotNumber) + return nil, fmt.Errorf("storage indices corrupted, %s, %w", msg, err) } - if len(blob)%slotIndexSize != 0 { - return nil, fmt.Errorf("storage indices is corrupted, historyID: %d, size: %d", historyID, len(blob)) - } - if slotIndexSize*(slotOffset+slotNumber) > len(blob) { - return nil, fmt.Errorf("storage indices is truncated, historyID: %d, size: %d, offset: %d, length: %d", historyID, len(blob), slotOffset, slotNumber) - } - subSlice := blob[slotIndexSize*slotOffset : slotIndexSize*(slotOffset+slotNumber)] - // TODO(rj493456442) get rid of the metadata resolution var ( m meta target common.Hash ) - blob = rawdb.ReadStateHistoryMeta(r.freezer, historyID) + blob := rawdb.ReadStateHistoryMeta(r.freezer, historyID) if err := m.decode(blob); err != nil { return nil, err } @@ -254,21 +171,21 @@ func (r *historyReader) readStorageMetadata(storageKey common.Hash, storageHash target = storageKey } pos := sort.Search(slotNumber, func(i int) bool { - slotID := subSlice[slotIndexSize*i : slotIndexSize*i+common.HashLength] + slotID := data[slotIndexSize*i : slotIndexSize*i+common.HashLength] return bytes.Compare(slotID, target.Bytes()) >= 0 }) if pos == slotNumber { return nil, fmt.Errorf("storage metadata is not found, slot key: %#x, historyID: %d", storageKey, historyID) } offset := slotIndexSize * pos - if target != common.BytesToHash(subSlice[offset:offset+common.HashLength]) { + if target != common.BytesToHash(data[offset:offset+common.HashLength]) { return nil, fmt.Errorf("storage metadata is not found, slot key: %#x, historyID: %d", storageKey, historyID) } - return subSlice[offset : slotIndexSize*(pos+1)], nil + return data[offset : slotIndexSize*(pos+1)], nil } // readAccount retrieves the account data from the specified state history. -func (r *historyReader) readAccount(address common.Address, historyID uint64) ([]byte, error) { +func (r *stateHistoryReader) readAccount(address common.Address, historyID uint64) ([]byte, error) { metadata, err := r.readAccountMetadata(address, historyID) if err != nil { return nil, err @@ -276,16 +193,15 @@ func (r *historyReader) readAccount(address common.Address, historyID uint64) ([ length := int(metadata[common.AddressLength]) // one byte for account data length offset := int(binary.BigEndian.Uint32(metadata[common.AddressLength+1 : common.AddressLength+5])) // four bytes for the account data offset - // TODO(rj493456442) optimize it with partial read - data := rawdb.ReadStateAccountHistory(r.freezer, historyID) - if len(data) < length+offset { + data, err := rawdb.ReadStateAccountHistory(r.freezer, historyID, offset, length) + if err != nil { return nil, fmt.Errorf("account data is truncated, address: %#x, historyID: %d, size: %d, offset: %d, len: %d", address, historyID, len(data), offset, length) } - return data[offset : offset+length], nil + return data, nil } // readStorage retrieves the storage slot data from the specified state history. -func (r *historyReader) readStorage(address common.Address, storageKey common.Hash, storageHash common.Hash, historyID uint64) ([]byte, error) { +func (r *stateHistoryReader) readStorage(address common.Address, storageKey common.Hash, storageHash common.Hash, historyID uint64) ([]byte, error) { metadata, err := r.readAccountMetadata(address, historyID) if err != nil { return nil, err @@ -304,46 +220,27 @@ func (r *historyReader) readStorage(address common.Address, storageKey common.Ha length := int(slotMetadata[common.HashLength]) // one byte for slot data length offset := int(binary.BigEndian.Uint32(slotMetadata[common.HashLength+1 : common.HashLength+5])) // four bytes for slot data offset - // TODO(rj493456442) optimize it with partial read - data := rawdb.ReadStateStorageHistory(r.freezer, historyID) - if len(data) < offset+length { + data, err := rawdb.ReadStateStorageHistory(r.freezer, historyID, offset, length) + if err != nil { return nil, fmt.Errorf("storage data is truncated, address: %#x, key: %#x, historyID: %d, size: %d, offset: %d, len: %d", address, storageKey, historyID, len(data), offset, length) } - return data[offset : offset+length], nil + return data, nil } // read retrieves the state element data associated with the stateID. // stateID: represents the ID of the state of the specified version; // lastID: represents the ID of the latest/newest state history; // latestValue: represents the state value at the current disk layer with ID == lastID; -func (r *historyReader) read(state stateIdentQuery, stateID uint64, lastID uint64, latestValue []byte) ([]byte, error) { - tail, err := r.freezer.Tail() +func (r *stateHistoryReader) read(state stateIdentQuery, stateID uint64, lastID uint64, latestValue []byte) ([]byte, error) { + lastIndexed, err := checkStateAvail(state.stateIdent, typeStateHistory, r.freezer, stateID, lastID, r.disk) if err != nil { return nil, err } - // stateID == tail is allowed, as the first history object preserved - // is tail+1 - if stateID < tail { - return nil, errors.New("historical state has been pruned") - } - - // To serve the request, all state histories from stateID+1 to lastID - // must be indexed. It's not supposed to happen unless system is very - // wrong. - metadata := loadIndexMetadata(r.disk) - if metadata == nil || metadata.Last < lastID { - indexed := "null" - if metadata != nil { - indexed = fmt.Sprintf("%d", metadata.Last) - } - return nil, fmt.Errorf("state history is not fully indexed, requested: %d, indexed: %s", stateID, indexed) - } - // Construct the index reader to locate the corresponding history for // state retrieval ir, ok := r.readers[state.String()] if !ok { - ir, err = newIndexReaderWithLimitTag(r.disk, state.stateIdent, metadata.Last) + ir, err = newIndexReaderWithLimitTag(r.disk, state.stateIdent, lastIndexed, 0) if err != nil { return nil, err } @@ -363,8 +260,234 @@ func (r *historyReader) read(state stateIdentQuery, stateID uint64, lastID uint6 // that the associated state histories are no longer available due to a rollback. // Such truncation should be captured by the state resolver below, rather than returning // invalid data. - if state.account { + if state.typ == typeAccount { return r.readAccount(state.address, historyID) } return r.readStorage(state.address, state.storageKey, state.storageHash, historyID) } + +// trienodeReader is the structure to access historical trienode data. +type trienodeReader struct { + disk ethdb.KeyValueReader + freezer ethdb.AncientReader + readConcurrency int // The concurrency used to load trie node data from history +} + +// newTrienodeReader constructs the history reader with the supplied db +// for accessing historical trie nodes. +func newTrienodeReader(disk ethdb.KeyValueReader, freezer ethdb.AncientReader, readConcurrency int) *trienodeReader { + return &trienodeReader{ + disk: disk, + freezer: freezer, + readConcurrency: readConcurrency, + } +} + +// readTrienode retrieves the trienode data from the specified trienode history. +func (r *trienodeReader) readTrienode(addrHash common.Hash, path string, historyID uint64) ([]byte, error) { + tr, err := newTrienodeHistoryReader(historyID, r.freezer) + if err != nil { + return nil, err + } + return tr.read(addrHash, path) +} + +// assembleNode takes a complete node value as the base and applies a list of +// mutation records to assemble the final node value accordingly. +func assembleNode(blob []byte, elements [][][]byte, indices [][]int) ([]byte, error) { + if len(elements) == 0 && len(indices) == 0 { + return blob, nil + } + children, err := rlp.SplitListValues(blob) + if err != nil { + return nil, err + } + for i := 0; i < len(elements); i++ { + for j, pos := range indices[i] { + children[pos] = elements[i][j] + } + } + return rlp.MergeListValues(children) +} + +type resultQueue struct { + data [][]byte + lock sync.Mutex +} + +func newResultQueue(size int) *resultQueue { + return &resultQueue{ + data: make([][]byte, size, size*2), + } +} + +func (q *resultQueue) set(data []byte, pos int) { + q.lock.Lock() + defer q.lock.Unlock() + + if pos >= len(q.data) { + newSize := pos + 1 + if cap(q.data) < newSize { + newData := make([][]byte, newSize, newSize*2) + copy(newData, q.data) + q.data = newData + } + q.data = q.data[:newSize] + } + q.data[pos] = data +} + +func (r *trienodeReader) readOptimized(state stateIdent, it HistoryIndexIterator, latestValue []byte) ([]byte, error) { + var ( + elements [][][]byte + indices [][]int + blob = latestValue + + eg errgroup.Group + seq int + term atomic.Bool + queue = newResultQueue(r.readConcurrency * 2) + ) + eg.SetLimit(r.readConcurrency) + + for { + id, pos := it.ID(), seq + seq += 1 + + eg.Go(func() error { + // In optimistic readahead mode, it is theoretically possible to encounter a + // NotFound error, where the trie node does not actually exist and the iterator + // reports a false-positive mutation record. Terminate the iterator if so, as + // all the necessary data (checkpoints and all diffs) required has already been + // fetching. + data, err := r.readTrienode(state.addressHash, state.path, id) + if err != nil { + term.Store(true) + log.Debug("Failed to read the trienode", "err", err) + return nil + } + full, _, err := decodeNodeFull(data) + if err != nil { + term.Store(true) + return err + } + if full { + term.Store(true) + } + queue.set(data, pos) + return nil + }) + if term.Load() || !it.Next() { + break + } + } + if err := eg.Wait(); err != nil { + return nil, err + } + if err := it.Error(); err != nil { + return nil, err + } + for i := 0; i < seq; i++ { + isComplete, fullBlob, err := decodeNodeFull(queue.data[i]) + if err != nil { + return nil, err + } + // Terminate the loop is the node with full value has been found + if isComplete { + blob = fullBlob + break + } + // Decode the partial encoded node and keep iterating the node history + // until the node with full value being reached. + element, index, err := decodeNodeCompressed(queue.data[i]) + if err != nil { + return nil, err + } + elements, indices = append(elements, element), append(indices, index) + } + slices.Reverse(elements) + slices.Reverse(indices) + return assembleNode(blob, elements, indices) +} + +// read retrieves the trie node data associated with the stateID. +// stateID: represents the ID of the state of the specified version; +// lastID: represents the ID of the latest/newest trie node history; +// latestValue: represents the trie node value at the current disk layer with ID == lastID; +func (r *trienodeReader) read(state stateIdent, stateID uint64, lastID uint64, latestValue []byte) ([]byte, error) { + _, err := checkStateAvail(state, typeTrienodeHistory, r.freezer, stateID, lastID, r.disk) + if err != nil { + return nil, err + } + // Construct the index iterator to traverse the trienode history + var ( + scheme *indexScheme + it HistoryIndexIterator + ) + if state.addressHash == (common.Hash{}) { + scheme = accountIndexScheme + } else { + scheme = storageIndexScheme + } + if state.addressHash == (common.Hash{}) && state.path == "" { + it = newSeqIter(lastID) + } else { + chunkID, nodeID := scheme.splitPathLast(state.path) + + queryIdent := state + queryIdent.path = chunkID + ir, err := newIndexReader(r.disk, queryIdent, scheme.getBitmapSize(len(chunkID))) + if err != nil { + return nil, err + } + filter := extFilter(nodeID) + it = ir.newIterator(&filter) + } + // Move the iterator to the first element whose id is greater than + // the given number. + found := it.SeekGT(stateID) + if err := it.Error(); err != nil { + return nil, err + } + // The state was not found in the trie node histories, as it has not been + // modified since stateID. Use the data from the associated disk layer + // instead (full value node as always) + if !found { + return latestValue, nil + } + return r.readOptimized(state, it, latestValue) +} + +// checkStateAvail determines whether the requested historical state is available +// for accessing. What's more, it also returns the ID of the latest indexed history +// entry for subsequent usage. +// +// TODO(rjl493456442) it's really expensive to perform the check for every state +// retrieval, please rework this later. +func checkStateAvail(state stateIdent, exptyp historyType, freezer ethdb.AncientReader, stateID uint64, lastID uint64, db ethdb.KeyValueReader) (uint64, error) { + if toHistoryType(state.typ) != exptyp { + return 0, fmt.Errorf("unsupported history type: %d, want: %v", toHistoryType(state.typ), exptyp) + } + // firstID = tail+1 + tail, err := freezer.Tail() + if err != nil { + return 0, err + } + // stateID+1 == firstID is allowed, as all the subsequent history entries + // are present with no gap inside. + if stateID < tail { + return 0, fmt.Errorf("historical state has been pruned, first: %d, state: %d", tail+1, stateID) + } + // To serve the request, all history entries from stateID+1 to lastID + // must be indexed. It's not supposed to happen unless system is very + // wrong. + metadata := loadIndexMetadata(db, exptyp) + if metadata == nil || metadata.Last < lastID { + indexed := "null" + if metadata != nil { + indexed = fmt.Sprintf("%d", metadata.Last) + } + return 0, fmt.Errorf("history is not fully indexed, requested: %d, indexed: %s", stateID, indexed) + } + return metadata.Last, nil +} diff --git a/triedb/pathdb/history_reader_test.go b/triedb/pathdb/history_reader_test.go index 4eb93fb9c9..b69fba68cb 100644 --- a/triedb/pathdb/history_reader_test.go +++ b/triedb/pathdb/history_reader_test.go @@ -24,11 +24,12 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/internal/testrand" ) func waitIndexing(db *Database) { for { - metadata := loadIndexMetadata(db.diskdb) + metadata := loadIndexMetadata(db.diskdb, typeStateHistory) if metadata != nil && metadata.Last >= db.tree.bottom().stateID() { return } @@ -36,11 +37,29 @@ func waitIndexing(db *Database) { } } -func checkHistoricState(env *tester, root common.Hash, hr *historyReader) error { - // Short circuit if the historical state is no longer available - if rawdb.ReadStateID(env.db.diskdb, root) == nil { +func stateAvail(id uint64, env *tester) bool { + if env.db.config.StateHistory == 0 { + return true + } + dl := env.db.tree.bottom() + if dl.stateID() <= env.db.config.StateHistory { + return true + } + firstID := dl.stateID() - env.db.config.StateHistory + 1 + + return id+1 >= firstID +} + +func checkHistoricalState(env *tester, root common.Hash, id uint64, hr *stateHistoryReader) error { + if !stateAvail(id, env) { return nil } + + // Short circuit if the historical state is no longer available + if rawdb.ReadStateID(env.db.diskdb, root) == nil { + return fmt.Errorf("state not found %d %x", id, root) + } + var ( dl = env.db.tree.bottom() stateID = rawdb.ReadStateID(env.db.diskdb, root) @@ -124,22 +143,27 @@ func testHistoryReader(t *testing.T, historyLimit uint64) { defer func() { maxDiffLayers = 128 }() - //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) - env := newTester(t, historyLimit, false, 64, true, "") + //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) + config := &testerConfig{ + stateHistory: historyLimit, + layers: 64, + enableIndex: true, + } + env := newTester(t, config) defer env.release() waitIndexing(env.db) var ( roots = env.roots - dRoot = env.db.tree.bottom().rootHash() - hr = newHistoryReader(env.db.diskdb, env.db.freezer) + dl = env.db.tree.bottom() + hr = newStateHistoryReader(env.db.diskdb, env.db.stateFreezer) ) - for _, root := range roots { - if root == dRoot { + for i, root := range roots { + if root == dl.rootHash() { break } - if err := checkHistoricState(env, root, hr); err != nil { + if err := checkHistoricalState(env, root, uint64(i+1), hr); err != nil { t.Fatal(err) } } @@ -148,12 +172,46 @@ func testHistoryReader(t *testing.T, historyLimit uint64) { env.extend(4) waitIndexing(env.db) - for _, root := range roots { - if root == dRoot { + for i, root := range roots { + if root == dl.rootHash() { break } - if err := checkHistoricState(env, root, hr); err != nil { + if err := checkHistoricalState(env, root, uint64(i+1), hr); err != nil { t.Fatal(err) } } } + +func TestHistoricalStateReader(t *testing.T) { + maxDiffLayers = 4 + defer func() { + maxDiffLayers = 128 + }() + + //log.SetDefault(log.NewLogger(log.NewTerminalHandlerWithLevel(os.Stderr, log.LevelDebug, true))) + config := &testerConfig{ + stateHistory: 0, + layers: 64, + enableIndex: true, + } + env := newTester(t, config) + defer env.release() + waitIndexing(env.db) + + // non-canonical state + fakeRoot := testrand.Hash() + rawdb.WriteStateID(env.db.diskdb, fakeRoot, 10) + + _, err := env.db.HistoricReader(fakeRoot) + if err == nil { + t.Fatal("expected error") + } + t.Log(err) + + // canonical state + realRoot := env.roots[9] + _, err = env.db.HistoricReader(realRoot) + if err != nil { + t.Fatalf("Unexpected error: %v", err) + } +} diff --git a/triedb/pathdb/history_state.go b/triedb/pathdb/history_state.go new file mode 100644 index 0000000000..23428b1a54 --- /dev/null +++ b/triedb/pathdb/history_state.go @@ -0,0 +1,641 @@ +// Copyright 2023 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pathdb + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "iter" + "maps" + "slices" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" +) + +// State history records the state changes involved in executing a block. The +// state can be reverted to the previous version by applying the associated +// history object (state reverse diff). State history objects are kept to +// guarantee that the system can perform state rollbacks in case of deep reorg. +// +// Each state transition will generate a state history object. Note that not +// every block has a corresponding state history object. If a block performs +// no state changes whatsoever, no state is created for it. Each state history +// will have a sequentially increasing number acting as its unique identifier. +// +// The state history is written to disk (ancient store) when the corresponding +// diff layer is merged into the disk layer. At the same time, system can prune +// the oldest histories according to config. +// +// Disk State +// ^ +// | +// +------------+ +---------+ +---------+ +---------+ +// | Init State |---->| State 1 |---->| ... |---->| State n | +// +------------+ +---------+ +---------+ +---------+ +// +// +-----------+ +------+ +-----------+ +// | History 1 |----> | ... |---->| History n | +// +-----------+ +------+ +-----------+ +// +// # Rollback +// +// If the system wants to roll back to a previous state n, it needs to ensure +// all history objects from n+1 up to the current disk layer are existent. The +// history objects are applied to the state in reverse order, starting from the +// current disk layer. + +const ( + accountIndexSize = common.AddressLength + 13 // The length of encoded account index + slotIndexSize = common.HashLength + 5 // The length of encoded slot index + historyMetaSize = 9 + 2*common.HashLength // The length of encoded history meta + + stateHistoryV0 = uint8(0) // initial version of state history structure + stateHistoryV1 = uint8(1) // use the storage slot raw key as the identifier instead of the key hash + historyVersion = stateHistoryV1 // the default state history version +) + +// Each state history entry is consisted of five elements: +// +// # metadata +// This object contains a few meta fields, such as the associated state root, +// block number, version tag and so on. This object may contain an extra +// accountHash list which means the storage changes belong to these accounts +// are not complete due to large contract destruction. The incomplete history +// can not be used for rollback and serving archive state request. +// +// # account index +// This object contains some index information of account. For example, offset +// and length indicate the location of the data belonging to the account. Besides, +// storageOffset and storageSlots indicate the storage modification location +// belonging to the account. +// +// The size of each account index is *fixed*, and all indexes are sorted +// lexicographically. Thus binary search can be performed to quickly locate a +// specific account. +// +// # account data +// Account data is a concatenated byte stream composed of all account data. +// The account data can be solved by the offset and length info indicated +// by corresponding account index. +// +// fixed size +// ^ ^ +// / \ +// +-----------------+-----------------+----------------+-----------------+ +// | Account index 1 | Account index 2 | ... | Account index N | +// +-----------------+-----------------+----------------+-----------------+ +// | +// | length +// offset |----------------+ +// v v +// +----------------+----------------+----------------+----------------+ +// | Account data 1 | Account data 2 | ... | Account data N | +// +----------------+----------------+----------------+----------------+ +// +// # storage index +// This object is similar with account index. It's also fixed size and contains +// the location info of storage slot data. +// +// # storage data +// Storage data is a concatenated byte stream composed of all storage slot data. +// The storage slot data can be solved by the location info indicated by +// corresponding account index and storage slot index. +// +// fixed size +// ^ ^ +// / \ +// +-----------------+-----------------+----------------+-----------------+ +// | Account index 1 | Account index 2 | ... | Account index N | +// +-----------------+-----------------+----------------+-----------------+ +// | +// | storage slots +// storage offset |-----------------------------------------------------+ +// v v +// +-----------------+-----------------+-----------------+ +// | storage index 1 | storage index 2 | storage index 3 | +// +-----------------+-----------------+-----------------+ +// | length +// offset |-------------+ +// v v +// +-------------+ +// | slot data 1 | +// +-------------+ + +// accountIndex describes the metadata belonging to an account. +type accountIndex struct { + address common.Address // The address of account + length uint8 // The length of account data, size limited by 255 + offset uint32 // The offset of item in account data table + storageOffset uint32 // The offset of storage index in storage index table + storageSlots uint32 // The number of mutated storage slots belonging to the account +} + +// encode packs account index into byte stream. +func (i *accountIndex) encode() []byte { + var buf [accountIndexSize]byte + copy(buf[:], i.address.Bytes()) + buf[common.AddressLength] = i.length + binary.BigEndian.PutUint32(buf[common.AddressLength+1:], i.offset) + binary.BigEndian.PutUint32(buf[common.AddressLength+5:], i.storageOffset) + binary.BigEndian.PutUint32(buf[common.AddressLength+9:], i.storageSlots) + return buf[:] +} + +// decode unpacks account index from byte stream. +func (i *accountIndex) decode(blob []byte) { + i.address = common.BytesToAddress(blob[:common.AddressLength]) + i.length = blob[common.AddressLength] + i.offset = binary.BigEndian.Uint32(blob[common.AddressLength+1:]) + i.storageOffset = binary.BigEndian.Uint32(blob[common.AddressLength+5:]) + i.storageSlots = binary.BigEndian.Uint32(blob[common.AddressLength+9:]) +} + +// slotIndex describes the metadata belonging to a storage slot. +type slotIndex struct { + // the identifier of the storage slot. Specifically + // in v0, it's the hash of the raw storage slot key (32 bytes); + // in v1, it's the raw storage slot key (32 bytes); + id common.Hash + length uint8 // The length of storage slot, up to 32 bytes defined in protocol + offset uint32 // The offset of item in storage slot data table +} + +// encode packs slot index into byte stream. +func (i *slotIndex) encode() []byte { + var buf [slotIndexSize]byte + copy(buf[:common.HashLength], i.id.Bytes()) + buf[common.HashLength] = i.length + binary.BigEndian.PutUint32(buf[common.HashLength+1:], i.offset) + return buf[:] +} + +// decode unpack slot index from the byte stream. +func (i *slotIndex) decode(blob []byte) { + i.id = common.BytesToHash(blob[:common.HashLength]) + i.length = blob[common.HashLength] + i.offset = binary.BigEndian.Uint32(blob[common.HashLength+1:]) +} + +// meta describes the meta data of state history object. +type meta struct { + version uint8 // version tag of history object + parent common.Hash // prev-state root before the state transition + root common.Hash // post-state root after the state transition + block uint64 // associated block number +} + +// encode packs the meta object into byte stream. +func (m *meta) encode() []byte { + buf := make([]byte, historyMetaSize) + buf[0] = m.version + copy(buf[1:1+common.HashLength], m.parent.Bytes()) + copy(buf[1+common.HashLength:1+2*common.HashLength], m.root.Bytes()) + binary.BigEndian.PutUint64(buf[1+2*common.HashLength:historyMetaSize], m.block) + return buf[:] +} + +// decode unpacks the meta object from byte stream. +func (m *meta) decode(blob []byte) error { + if len(blob) < 1 { + return errors.New("no version tag") + } + switch blob[0] { + case stateHistoryV0, stateHistoryV1: + if len(blob) != historyMetaSize { + return fmt.Errorf("invalid state history meta, len: %d", len(blob)) + } + m.version = blob[0] + m.parent = common.BytesToHash(blob[1 : 1+common.HashLength]) + m.root = common.BytesToHash(blob[1+common.HashLength : 1+2*common.HashLength]) + m.block = binary.BigEndian.Uint64(blob[1+2*common.HashLength : historyMetaSize]) + return nil + default: + return fmt.Errorf("unknown version %d", blob[0]) + } +} + +// stateHistory represents a set of state changes belong to a block along with +// the metadata including the state roots involved in the state transition. +// +// State history objects in disk are linked with each other by a unique id +// (8-bytes integer), the oldest state history object can be pruned on demand +// in order to control the storage size. +type stateHistory struct { + meta *meta // Meta data of history + accounts map[common.Address][]byte // Account data keyed by its address hash + accountList []common.Address // Sorted account hash list + storages map[common.Address]map[common.Hash][]byte // Storage data keyed by its address hash and slot hash + storageList map[common.Address][]common.Hash // Sorted slot hash list +} + +// newStateHistory constructs the state history object with provided states. +func newStateHistory(root common.Hash, parent common.Hash, block uint64, accounts map[common.Address][]byte, storages map[common.Address]map[common.Hash][]byte, rawStorageKey bool) *stateHistory { + var ( + accountList = slices.SortedFunc(maps.Keys(accounts), common.Address.Cmp) + storageList = make(map[common.Address][]common.Hash) + ) + for addr, slots := range storages { + storageList[addr] = slices.SortedFunc(maps.Keys(slots), common.Hash.Cmp) + } + version := historyVersion + if !rawStorageKey { + version = stateHistoryV0 + } + return &stateHistory{ + meta: &meta{ + version: version, + parent: parent, + root: root, + block: block, + }, + accounts: accounts, + accountList: accountList, + storages: storages, + storageList: storageList, + } +} + +// typ implements the history interface, returning the historical data type held. +func (h *stateHistory) typ() historyType { + return typeStateHistory +} + +// forEach implements the history interface, returning an iterator to traverse the +// state entries in the history. +func (h *stateHistory) forEach() iter.Seq[indexElem] { + return func(yield func(indexElem) bool) { + for _, addr := range h.accountList { + addrHash := crypto.Keccak256Hash(addr.Bytes()) + if !yield(accountIndexElem{addrHash}) { + return + } + for _, slotKey := range h.storageList[addr] { + // The hash of the storage slot key is used as the identifier because the + // legacy history does not include the raw storage key, therefore, the + // conversion from storage key to hash is necessary for non-v0 histories. + slotHash := slotKey + if h.meta.version != stateHistoryV0 { + slotHash = crypto.Keccak256Hash(slotKey.Bytes()) + } + if !yield(storageIndexElem{addrHash, slotHash}) { + return + } + } + } + } +} + +// stateSet returns the state set, keyed by the hash of the account address +// and the hash of the storage slot key. +func (h *stateHistory) stateSet() (map[common.Hash][]byte, map[common.Hash]map[common.Hash][]byte) { + var ( + accounts = make(map[common.Hash][]byte) + storages = make(map[common.Hash]map[common.Hash][]byte) + ) + for addr, blob := range h.accounts { + addrHash := crypto.Keccak256Hash(addr.Bytes()) + accounts[addrHash] = blob + + storage, exist := h.storages[addr] + if !exist { + continue + } + if h.meta.version == stateHistoryV0 { + storages[addrHash] = storage + } else { + subset := make(map[common.Hash][]byte) + for key, slot := range storage { + subset[crypto.Keccak256Hash(key.Bytes())] = slot + } + storages[addrHash] = subset + } + } + return accounts, storages +} + +// encode serializes the state history and returns four byte streams represent +// concatenated account/storage data, account/storage indexes respectively. +func (h *stateHistory) encode() ([]byte, []byte, []byte, []byte) { + var ( + slotNumber uint32 // the number of processed slots + accountData []byte // the buffer for concatenated account data + storageData []byte // the buffer for concatenated storage data + accountIndexes []byte // the buffer for concatenated account index + storageIndexes []byte // the buffer for concatenated storage index + ) + for _, addr := range h.accountList { + accIndex := accountIndex{ + address: addr, + length: uint8(len(h.accounts[addr])), + offset: uint32(len(accountData)), + } + slots, exist := h.storages[addr] + if exist { + // Encode storage slots in order + for _, slotHash := range h.storageList[addr] { + sIndex := slotIndex{ + id: slotHash, + length: uint8(len(slots[slotHash])), + offset: uint32(len(storageData)), + } + storageData = append(storageData, slots[slotHash]...) + storageIndexes = append(storageIndexes, sIndex.encode()...) + } + // Fill up the storage meta in account index + accIndex.storageOffset = slotNumber + accIndex.storageSlots = uint32(len(slots)) + slotNumber += uint32(len(slots)) + } + accountData = append(accountData, h.accounts[addr]...) + accountIndexes = append(accountIndexes, accIndex.encode()...) + } + return accountData, storageData, accountIndexes, storageIndexes +} + +// decoder wraps the byte streams for decoding with extra meta fields. +type decoder struct { + accountData []byte // the buffer for concatenated account data + storageData []byte // the buffer for concatenated storage data + accountIndexes []byte // the buffer for concatenated account index + storageIndexes []byte // the buffer for concatenated storage index + + lastAccount *common.Address // the address of last resolved account + lastAccountRead uint32 // the read-cursor position of account data + lastSlotIndexRead uint32 // the read-cursor position of storage slot index + lastSlotDataRead uint32 // the read-cursor position of storage slot data +} + +// verify validates the provided byte streams for decoding state history. A few +// checks will be performed to quickly detect data corruption. The byte stream +// is regarded as corrupted if: +// +// - account indexes buffer is empty(empty state set is invalid) +// - account indexes/storage indexer buffer is not aligned +// +// note, these situations are allowed: +// +// - empty account data: all accounts were not present +// - empty storage set: no slots are modified +func (r *decoder) verify() error { + if len(r.accountIndexes)%accountIndexSize != 0 || len(r.accountIndexes) == 0 { + return fmt.Errorf("invalid account index, len: %d", len(r.accountIndexes)) + } + if len(r.storageIndexes)%slotIndexSize != 0 { + return fmt.Errorf("invalid storage index, len: %d", len(r.storageIndexes)) + } + return nil +} + +// readAccount parses the account from the byte stream with specified position. +func (r *decoder) readAccount(pos int) (accountIndex, []byte, error) { + // Decode account index from the index byte stream. + var index accountIndex + if (pos+1)*accountIndexSize > len(r.accountIndexes) { + return accountIndex{}, nil, errors.New("account data buffer is corrupted") + } + index.decode(r.accountIndexes[pos*accountIndexSize : (pos+1)*accountIndexSize]) + + // Perform validation before parsing account data, ensure + // - account is sorted in order in byte stream + // - account data is strictly encoded with no gap inside + // - account data is not out-of-slice + if r.lastAccount != nil { // zero address is possible + if bytes.Compare(r.lastAccount.Bytes(), index.address.Bytes()) >= 0 { + return accountIndex{}, nil, errors.New("account is not in order") + } + } + if index.offset != r.lastAccountRead { + return accountIndex{}, nil, errors.New("account data buffer is gaped") + } + last := index.offset + uint32(index.length) + if uint32(len(r.accountData)) < last { + return accountIndex{}, nil, errors.New("account data buffer is corrupted") + } + data := r.accountData[index.offset:last] + + r.lastAccount = &index.address + r.lastAccountRead = last + + return index, data, nil +} + +// readStorage parses the storage slots from the byte stream with specified account. +func (r *decoder) readStorage(accIndex accountIndex) ([]common.Hash, map[common.Hash][]byte, error) { + var ( + last *common.Hash + count = int(accIndex.storageSlots) + list = make([]common.Hash, 0, count) + storage = make(map[common.Hash][]byte, count) + ) + for j := 0; j < count; j++ { + var ( + index slotIndex + start = (accIndex.storageOffset + uint32(j)) * uint32(slotIndexSize) + end = (accIndex.storageOffset + uint32(j+1)) * uint32(slotIndexSize) + ) + // Perform validation before parsing storage slot data, ensure + // - slot index is not out-of-slice + // - slot data is not out-of-slice + // - slot is sorted in order in byte stream + // - slot indexes is strictly encoded with no gap inside + // - slot data is strictly encoded with no gap inside + if start != r.lastSlotIndexRead { + return nil, nil, errors.New("storage index buffer is gapped") + } + if uint32(len(r.storageIndexes)) < end { + return nil, nil, errors.New("storage index buffer is corrupted") + } + index.decode(r.storageIndexes[start:end]) + + if last != nil { + if bytes.Compare(last.Bytes(), index.id.Bytes()) >= 0 { + return nil, nil, fmt.Errorf("storage slot is not in order, last: %x, current: %x", *last, index.id) + } + } + if index.offset != r.lastSlotDataRead { + return nil, nil, errors.New("storage data buffer is gapped") + } + sEnd := index.offset + uint32(index.length) + if uint32(len(r.storageData)) < sEnd { + return nil, nil, errors.New("storage data buffer is corrupted") + } + storage[index.id] = r.storageData[r.lastSlotDataRead:sEnd] + list = append(list, index.id) + + last = &index.id + r.lastSlotIndexRead = end + r.lastSlotDataRead = sEnd + } + return list, storage, nil +} + +// decode deserializes the account and storage data from the provided byte stream. +func (h *stateHistory) decode(accountData, storageData, accountIndexes, storageIndexes []byte) error { + var ( + count = len(accountIndexes) / accountIndexSize + accounts = make(map[common.Address][]byte, count) + storages = make(map[common.Address]map[common.Hash][]byte) + accountList = make([]common.Address, 0, count) + storageList = make(map[common.Address][]common.Hash) + + r = &decoder{ + accountData: accountData, + storageData: storageData, + accountIndexes: accountIndexes, + storageIndexes: storageIndexes, + } + ) + if err := r.verify(); err != nil { + return err + } + for i := 0; i < count; i++ { + // Resolve account first + accIndex, accData, err := r.readAccount(i) + if err != nil { + return err + } + accounts[accIndex.address] = accData + accountList = append(accountList, accIndex.address) + + // Resolve storage slots + slotList, slotData, err := r.readStorage(accIndex) + if err != nil { + return err + } + if len(slotList) > 0 { + storageList[accIndex.address] = slotList + storages[accIndex.address] = slotData + } + } + h.accounts = accounts + h.accountList = accountList + h.storages = storages + h.storageList = storageList + return nil +} + +// readStateHistoryMeta reads the metadata of state history with the specified id. +func readStateHistoryMeta(reader ethdb.AncientReader, id uint64) (*meta, error) { + data := rawdb.ReadStateHistoryMeta(reader, id) + if len(data) == 0 { + return nil, fmt.Errorf("metadata is not found, %d", id) + } + var m meta + err := m.decode(data) + if err != nil { + return nil, err + } + return &m, nil +} + +// readStateHistory reads a single state history records with the specified id. +func readStateHistory(reader ethdb.AncientReader, id uint64) (*stateHistory, error) { + mData, accountIndexes, storageIndexes, accountData, storageData, err := rawdb.ReadStateHistory(reader, id) + if err != nil { + return nil, err + } + var m meta + if err := m.decode(mData); err != nil { + return nil, err + } + h := stateHistory{meta: &m} + if err := h.decode(accountData, storageData, accountIndexes, storageIndexes); err != nil { + return nil, err + } + return &h, nil +} + +// readStateHistories reads a list of state history records within the specified range. +func readStateHistories(freezer ethdb.AncientReader, start uint64, count uint64) ([]history, error) { + var histories []history + metaList, aIndexList, sIndexList, aDataList, sDataList, err := rawdb.ReadStateHistoryList(freezer, start, count) + if err != nil { + return nil, err + } + for i := 0; i < len(metaList); i++ { + var m meta + if err := m.decode(metaList[i]); err != nil { + return nil, err + } + h := stateHistory{meta: &m} + if err := h.decode(aDataList[i], sDataList[i], aIndexList[i], sIndexList[i]); err != nil { + return nil, err + } + histories = append(histories, &h) + } + return histories, nil +} + +// writeStateHistory persists the state history associated with the given diff layer. +func writeStateHistory(writer ethdb.AncientWriter, dl *diffLayer) error { + // Short circuit if state set is not available. + if dl.states == nil { + return errors.New("state change set is not available") + } + var ( + start = time.Now() + history = newStateHistory(dl.rootHash(), dl.parentLayer().rootHash(), dl.block, dl.states.accountOrigin, dl.states.storageOrigin, dl.states.rawStorageKey) + ) + accountData, storageData, accountIndex, storageIndex := history.encode() + dataSize := common.StorageSize(len(accountData) + len(storageData)) + indexSize := common.StorageSize(len(accountIndex) + len(storageIndex)) + + // Write history data into five freezer table respectively. + if err := rawdb.WriteStateHistory(writer, dl.stateID(), history.meta.encode(), accountIndex, storageIndex, accountData, storageData); err != nil { + return err + } + stateHistoryDataBytesMeter.Mark(int64(dataSize)) + stateHistoryIndexBytesMeter.Mark(int64(indexSize)) + stateHistoryBuildTimeMeter.UpdateSince(start) + log.Debug("Stored state history", "id", dl.stateID(), "block", dl.block, "data", dataSize, "index", indexSize, "elapsed", common.PrettyDuration(time.Since(start))) + + return nil +} + +// checkStateHistories retrieves a batch of metadata objects with the specified +// range and performs the callback on each item. +func checkStateHistories(reader ethdb.AncientReader, start, count uint64, check func(*meta) error) error { + for count > 0 { + number := count + if number > 10000 { + number = 10000 // split the big read into small chunks + } + blobs, err := rawdb.ReadStateHistoryMetaList(reader, start, number) + if err != nil { + return err + } + for _, blob := range blobs { + var dec meta + if err := dec.decode(blob); err != nil { + return err + } + if err := check(&dec); err != nil { + return err + } + } + count -= uint64(len(blobs)) + start += uint64(len(blobs)) + } + return nil +} diff --git a/triedb/pathdb/history_test.go b/triedb/pathdb/history_state_test.go similarity index 61% rename from triedb/pathdb/history_test.go rename to triedb/pathdb/history_state_test.go index 2928d19d74..4046fb9640 100644 --- a/triedb/pathdb/history_test.go +++ b/triedb/pathdb/history_state_test.go @@ -18,6 +18,7 @@ package pathdb import ( "bytes" + "errors" "fmt" "reflect" "testing" @@ -49,36 +50,36 @@ func randomStateSet(n int) (map[common.Address][]byte, map[common.Address]map[co return accounts, storages } -func makeHistory(rawStorageKey bool) *history { +func makeStateHistory(rawStorageKey bool) *stateHistory { accounts, storages := randomStateSet(3) - return newHistory(testrand.Hash(), types.EmptyRootHash, 0, accounts, storages, rawStorageKey) + return newStateHistory(testrand.Hash(), types.EmptyRootHash, 0, accounts, storages, rawStorageKey) } -func makeHistories(n int) []*history { +func makeStateHistories(n int) []*stateHistory { var ( parent = types.EmptyRootHash - result []*history + result []*stateHistory ) for i := 0; i < n; i++ { root := testrand.Hash() accounts, storages := randomStateSet(3) - h := newHistory(root, parent, uint64(i), accounts, storages, false) + h := newStateHistory(root, parent, uint64(i), accounts, storages, false) parent = root result = append(result, h) } return result } -func TestEncodeDecodeHistory(t *testing.T) { - testEncodeDecodeHistory(t, false) - testEncodeDecodeHistory(t, true) +func TestEncodeDecodeStateHistory(t *testing.T) { + testEncodeDecodeStateHistory(t, false) + testEncodeDecodeStateHistory(t, true) } -func testEncodeDecodeHistory(t *testing.T, rawStorageKey bool) { +func testEncodeDecodeStateHistory(t *testing.T, rawStorageKey bool) { var ( m meta - dec history - obj = makeHistory(rawStorageKey) + dec stateHistory + obj = makeStateHistory(rawStorageKey) ) // check if meta data can be correctly encode/decode blob := obj.meta.encode() @@ -97,18 +98,18 @@ func testEncodeDecodeHistory(t *testing.T, rawStorageKey bool) { if !compareSet(dec.accounts, obj.accounts) { t.Fatal("account data is mismatched") } - if !compareStorages(dec.storages, obj.storages) { + if !compareMapSet(dec.storages, obj.storages) { t.Fatal("storage data is mismatched") } if !compareList(dec.accountList, obj.accountList) { t.Fatal("account list is mismatched") } - if !compareStorageList(dec.storageList, obj.storageList) { + if !compareMapList(dec.storageList, obj.storageList) { t.Fatal("storage list is mismatched") } } -func checkHistory(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientReader, id uint64, root common.Hash, exist bool) { +func checkStateHistory(t *testing.T, freezer ethdb.AncientReader, id uint64, exist bool) { blob := rawdb.ReadStateHistoryMeta(freezer, id) if exist && len(blob) == 0 { t.Fatalf("Failed to load trie history, %d", id) @@ -116,25 +117,17 @@ func checkHistory(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientRe if !exist && len(blob) != 0 { t.Fatalf("Unexpected trie history, %d", id) } - if exist && rawdb.ReadStateID(db, root) == nil { - t.Fatalf("Root->ID mapping is not found, %d", id) - } - if !exist && rawdb.ReadStateID(db, root) != nil { - t.Fatalf("Unexpected root->ID mapping, %d", id) +} + +func checkHistoriesInRange(t *testing.T, freezer ethdb.AncientReader, from, to uint64, exist bool) { + for i := from; i <= to; i = i + 1 { + checkStateHistory(t, freezer, i, exist) } } -func checkHistoriesInRange(t *testing.T, db ethdb.KeyValueReader, freezer ethdb.AncientReader, from, to uint64, roots []common.Hash, exist bool) { - for i, j := from, 0; i <= to; i, j = i+1, j+1 { - checkHistory(t, db, freezer, i, roots[j], exist) - } -} - -func TestTruncateHeadHistory(t *testing.T) { +func TestTruncateHeadStateHistory(t *testing.T) { var ( - roots []common.Hash - hs = makeHistories(10) - db = rawdb.NewMemoryDatabase() + hs = makeStateHistories(10) freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false) ) defer freezer.Close() @@ -142,27 +135,23 @@ func TestTruncateHeadHistory(t *testing.T) { for i := 0; i < len(hs); i++ { accountData, storageData, accountIndex, storageIndex := hs[i].encode() rawdb.WriteStateHistory(freezer, uint64(i+1), hs[i].meta.encode(), accountIndex, storageIndex, accountData, storageData) - rawdb.WriteStateID(db, hs[i].meta.root, uint64(i+1)) - roots = append(roots, hs[i].meta.root) } for size := len(hs); size > 0; size-- { - pruned, err := truncateFromHead(db, freezer, uint64(size-1)) + pruned, err := truncateFromHead(freezer, typeStateHistory, uint64(size-1)) if err != nil { t.Fatalf("Failed to truncate from head %v", err) } if pruned != 1 { t.Error("Unexpected pruned items", "want", 1, "got", pruned) } - checkHistoriesInRange(t, db, freezer, uint64(size), uint64(10), roots[size-1:], false) - checkHistoriesInRange(t, db, freezer, uint64(1), uint64(size-1), roots[:size-1], true) + checkHistoriesInRange(t, freezer, uint64(size), uint64(10), false) + checkHistoriesInRange(t, freezer, uint64(1), uint64(size-1), true) } } -func TestTruncateTailHistory(t *testing.T) { +func TestTruncateTailStateHistory(t *testing.T) { var ( - roots []common.Hash - hs = makeHistories(10) - db = rawdb.NewMemoryDatabase() + hs = makeStateHistories(10) freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false) ) defer freezer.Close() @@ -170,20 +159,18 @@ func TestTruncateTailHistory(t *testing.T) { for i := 0; i < len(hs); i++ { accountData, storageData, accountIndex, storageIndex := hs[i].encode() rawdb.WriteStateHistory(freezer, uint64(i+1), hs[i].meta.encode(), accountIndex, storageIndex, accountData, storageData) - rawdb.WriteStateID(db, hs[i].meta.root, uint64(i+1)) - roots = append(roots, hs[i].meta.root) } for newTail := 1; newTail < len(hs); newTail++ { - pruned, _ := truncateFromTail(db, freezer, uint64(newTail)) + pruned, _ := truncateFromTail(freezer, typeStateHistory, uint64(newTail)) if pruned != 1 { t.Error("Unexpected pruned items", "want", 1, "got", pruned) } - checkHistoriesInRange(t, db, freezer, uint64(1), uint64(newTail), roots[:newTail], false) - checkHistoriesInRange(t, db, freezer, uint64(newTail+1), uint64(10), roots[newTail:], true) + checkHistoriesInRange(t, freezer, uint64(1), uint64(newTail), false) + checkHistoriesInRange(t, freezer, uint64(newTail+1), uint64(10), true) } } -func TestTruncateTailHistories(t *testing.T) { +func TestTruncateTailStateHistories(t *testing.T) { var cases = []struct { limit uint64 expPruned int @@ -191,21 +178,29 @@ func TestTruncateTailHistories(t *testing.T) { minUnpruned uint64 empty bool }{ + // history: id [10] { - 1, 9, 9, 10, false, + limit: 1, + expPruned: 9, + maxPruned: 9, minUnpruned: 10, empty: false, }, + // history: none { - 0, 10, 10, 0 /* no meaning */, true, + limit: 0, + expPruned: 10, + empty: true, }, + // history: id [1:10] { - 10, 0, 0, 1, false, + limit: 10, + expPruned: 0, + maxPruned: 0, + minUnpruned: 1, }, } for i, c := range cases { var ( - roots []common.Hash - hs = makeHistories(10) - db = rawdb.NewMemoryDatabase() + hs = makeStateHistories(10) freezer, _ = rawdb.NewStateFreezer(t.TempDir()+fmt.Sprintf("%d", i), false, false) ) defer freezer.Close() @@ -213,27 +208,23 @@ func TestTruncateTailHistories(t *testing.T) { for i := 0; i < len(hs); i++ { accountData, storageData, accountIndex, storageIndex := hs[i].encode() rawdb.WriteStateHistory(freezer, uint64(i+1), hs[i].meta.encode(), accountIndex, storageIndex, accountData, storageData) - rawdb.WriteStateID(db, hs[i].meta.root, uint64(i+1)) - roots = append(roots, hs[i].meta.root) } - pruned, _ := truncateFromTail(db, freezer, uint64(10)-c.limit) + pruned, _ := truncateFromTail(freezer, typeStateHistory, uint64(10)-c.limit) if pruned != c.expPruned { t.Error("Unexpected pruned items", "want", c.expPruned, "got", pruned) } if c.empty { - checkHistoriesInRange(t, db, freezer, uint64(1), uint64(10), roots, false) + checkHistoriesInRange(t, freezer, uint64(1), uint64(10), false) } else { - tail := 10 - int(c.limit) - checkHistoriesInRange(t, db, freezer, uint64(1), c.maxPruned, roots[:tail], false) - checkHistoriesInRange(t, db, freezer, c.minUnpruned, uint64(10), roots[tail:], true) + checkHistoriesInRange(t, freezer, uint64(1), c.maxPruned, false) + checkHistoriesInRange(t, freezer, c.minUnpruned, uint64(10), true) } } } func TestTruncateOutOfRange(t *testing.T) { var ( - hs = makeHistories(10) - db = rawdb.NewMemoryDatabase() + hs = makeStateHistories(10) freezer, _ = rawdb.NewStateFreezer(t.TempDir(), false, false) ) defer freezer.Close() @@ -241,9 +232,8 @@ func TestTruncateOutOfRange(t *testing.T) { for i := 0; i < len(hs); i++ { accountData, storageData, accountIndex, storageIndex := hs[i].encode() rawdb.WriteStateHistory(freezer, uint64(i+1), hs[i].meta.encode(), accountIndex, storageIndex, accountData, storageData) - rawdb.WriteStateID(db, hs[i].meta.root, uint64(i+1)) } - truncateFromTail(db, freezer, uint64(len(hs)/2)) + truncateFromTail(freezer, typeStateHistory, uint64(len(hs)/2)) // Ensure of-out-range truncations are rejected correctly. head, _ := freezer.Ancients() @@ -255,20 +245,20 @@ func TestTruncateOutOfRange(t *testing.T) { expErr error }{ {0, head, nil}, // nothing to delete - {0, head + 1, fmt.Errorf("out of range, tail: %d, head: %d, target: %d", tail, head, head+1)}, - {0, tail - 1, fmt.Errorf("out of range, tail: %d, head: %d, target: %d", tail, head, tail-1)}, + {0, head + 1, errHeadTruncationOutOfRange}, + {0, tail - 1, errHeadTruncationOutOfRange}, {1, tail, nil}, // nothing to delete - {1, head + 1, fmt.Errorf("out of range, tail: %d, head: %d, target: %d", tail, head, head+1)}, - {1, tail - 1, fmt.Errorf("out of range, tail: %d, head: %d, target: %d", tail, head, tail-1)}, + {1, head + 1, errTailTruncationOutOfRange}, + {1, tail - 1, errTailTruncationOutOfRange}, } for _, c := range cases { var gotErr error if c.mode == 0 { - _, gotErr = truncateFromHead(db, freezer, c.target) + _, gotErr = truncateFromHead(freezer, typeStateHistory, c.target) } else { - _, gotErr = truncateFromTail(db, freezer, c.target) + _, gotErr = truncateFromTail(freezer, typeStateHistory, c.target) } - if !reflect.DeepEqual(gotErr, c.expErr) { + if !errors.Is(gotErr, c.expErr) { t.Errorf("Unexpected error, want: %v, got: %v", c.expErr, gotErr) } } @@ -302,32 +292,32 @@ func compareList[k comparable](a, b []k) bool { return true } -func compareStorages(a, b map[common.Address]map[common.Hash][]byte) bool { +func compareMapSet[K1 comparable, K2 comparable](a, b map[K1]map[K2][]byte) bool { if len(a) != len(b) { return false } - for h, subA := range a { - subB, ok := b[h] + for key, subsetA := range a { + subsetB, ok := b[key] if !ok { return false } - if !compareSet(subA, subB) { + if !compareSet(subsetA, subsetB) { return false } } return true } -func compareStorageList(a, b map[common.Address][]common.Hash) bool { +func compareMapList[K comparable, V comparable](a, b map[K][]V) bool { if len(a) != len(b) { return false } - for h, la := range a { - lb, ok := b[h] + for key, listA := range a { + listB, ok := b[key] if !ok { return false } - if !compareList(la, lb) { + if !compareList(listA, listB) { return false } } diff --git a/triedb/pathdb/history_trienode.go b/triedb/pathdb/history_trienode.go new file mode 100644 index 0000000000..f8ddc0665c --- /dev/null +++ b/triedb/pathdb/history_trienode.go @@ -0,0 +1,751 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pathdb + +import ( + "bytes" + "encoding/binary" + "errors" + "fmt" + "iter" + "maps" + "math" + "slices" + "sort" + "time" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/ethdb" + "github.com/ethereum/go-ethereum/log" +) + +// Each trie node history entry consists of three parts (stored in three freezer +// tables according): +// +// # Header +// The header records metadata, including: +// +// - the history version (1 byte) +// - the parent state root (32 bytes) +// - the current state root (32 bytes) +// - block number (8 bytes) +// +// - a lexicographically sorted list of trie IDs +// - the corresponding offsets into the key and value sections for each trie data chunk +// +// Although some fields (e.g., parent state root, block number) are duplicated +// between the state history and the trienode history, these two histories +// operate independently. To ensure each remains self-contained and self-descriptive, +// we have chosen to maintain these duplicate fields. +// +// # Key section +// The key section stores trie node keys (paths) in a compressed format. +// It also contains relative offsets into the value section for resolving +// the corresponding trie node data. Note that these offsets are relative +// to the data chunk for the trie; the chunk offset must be added to obtain +// the absolute position. +// +// # Value section +// The value section is a concatenated byte stream of all trie node data. +// Each trie node can be retrieved using the offset and length specified +// by its index entry. +// +// The header and key sections are sufficient for locating a trie node, +// while a partial read of the value section is enough to retrieve its data. + +// Header section: +// +// +----------+------------------+---------------------+---------------------+-------+------------------+---------------------+---------------------| +// | metadata | TrieID(32 bytes) | key offset(4 bytes) | val offset(4 bytes) | ... | TrieID(32 bytes) | key offset(4 bytes) | val offset(4 bytes) | +// +----------+------------------+---------------------+---------------------+-------+------------------+---------------------+---------------------| +// +// +// Key section: +// +// + restart point + restart point (depends on restart interval) +// / / +// +---------------+---------------+---------------+---------------+---------+ +// | node entry 1 | node entry 2 | ... | node entry n | trailer | +// +---------------+---------------+---------------+---------------+---------+ +// \ / +// +---- restart block ------+ +// +// node entry: +// +// +---- key len ----+ +// / \ +// +-------+---------+-----------+---------+-----------------------+-----------------+ +// | shared (varint) | not shared (varint) | value length (varlen) | key (varlen) | +// +-----------------+---------------------+-----------------------+-----------------+ +// +// trailer: +// +// +---- 4-bytes ----+ +---- 4-bytes ----+ +// / \ / \ +// +----------------------+------------------------+-----+--------------------------+ +// | restart_1 key offset | restart_1 value offset | ... | restart number (4-bytes) | +// +----------------------+------------------------+-----+--------------------------+ +// +// Note: Both the key offset and the value offset are relative to the start of +// the trie data chunk. To obtain the absolute offset, add the offset of the +// trie data chunk itself. +// +// Value section: +// +// +--------------+--------------+-------+---------------+ +// | node data 1 | node data 2 | ... | node data n | +// +--------------+--------------+-------+---------------+ +// +// NOTE: All fixed-length integer are big-endian. + +const ( + trienodeHistoryV0 = uint8(0) // initial version of node history structure + trienodeHistoryVersion = trienodeHistoryV0 // the default node history version + trienodeMetadataSize = 1 + 2*common.HashLength + 8 // the size of metadata in the history + trienodeTrieHeaderSize = 8 + common.HashLength // the size of a single trie header in history + trienodeDataBlockRestartLen = 16 // The restart interval length of trie node block +) + +// trienodeMetadata describes the meta data of trienode history. +type trienodeMetadata struct { + version uint8 // version tag of history object + parent common.Hash // prev-state root before the state transition + root common.Hash // post-state root after the state transition + block uint64 // associated block number +} + +// trienodeHistory represents a set of trie node changes resulting from a state +// transition across the main account trie and all associated storage tries. +type trienodeHistory struct { + meta *trienodeMetadata // Metadata of the history + owners []common.Hash // List of trie identifier sorted lexicographically + nodeList map[common.Hash][]string // Set of node paths sorted lexicographically + nodes map[common.Hash]map[string][]byte // Set of original value of trie nodes before state transition +} + +// newTrienodeHistory constructs a trienode history with the provided trie nodes. +func newTrienodeHistory(root common.Hash, parent common.Hash, block uint64, nodes map[common.Hash]map[string][]byte) *trienodeHistory { + nodeList := make(map[common.Hash][]string) + for owner, subset := range nodes { + keys := sort.StringSlice(slices.Collect(maps.Keys(subset))) + keys.Sort() + nodeList[owner] = keys + } + return &trienodeHistory{ + meta: &trienodeMetadata{ + version: trienodeHistoryVersion, + parent: parent, + root: root, + block: block, + }, + owners: slices.SortedFunc(maps.Keys(nodes), common.Hash.Cmp), + nodeList: nodeList, + nodes: nodes, + } +} + +// typ implements the history interface, returning the historical data type held. +func (h *trienodeHistory) typ() historyType { + return typeTrienodeHistory +} + +// forEach implements the history interface, returning an iterator to traverse the +// state entries in the history. +func (h *trienodeHistory) forEach() iter.Seq[indexElem] { + return func(yield func(indexElem) bool) { + for _, owner := range h.owners { + var ( + scheme *indexScheme + paths = h.nodeList[owner] + indexes = make(map[string]map[uint16]struct{}) + ) + if owner == (common.Hash{}) { + scheme = accountIndexScheme + } else { + scheme = storageIndexScheme + } + for _, leaf := range findLeafPaths(paths) { + chunks, ids := scheme.splitPath(leaf) + for i := 0; i < len(chunks); i++ { + if _, exists := indexes[chunks[i]]; !exists { + indexes[chunks[i]] = make(map[uint16]struct{}) + } + indexes[chunks[i]][ids[i]] = struct{}{} + } + } + for chunk, ids := range indexes { + elem := trienodeIndexElem{ + owner: owner, + path: chunk, + data: slices.Collect(maps.Keys(ids)), + } + if !yield(elem) { + return + } + } + } + } +} + +// encode serializes the contained trie nodes into bytes. +func (h *trienodeHistory) encode() ([]byte, []byte, []byte, error) { + var ( + buf = make([]byte, 64) + headerSection bytes.Buffer + keySection bytes.Buffer + valueSection bytes.Buffer + ) + binary.Write(&headerSection, binary.BigEndian, h.meta.version) // 1 byte + headerSection.Write(h.meta.parent.Bytes()) // 32 bytes + headerSection.Write(h.meta.root.Bytes()) // 32 bytes + binary.Write(&headerSection, binary.BigEndian, h.meta.block) // 8 byte + + for _, owner := range h.owners { + // Fill the key section with node index + var ( + prevKey []byte + restarts []uint32 + prefixLen int + + internalKeyOffset uint32 // key offset for the trie internally + internalValOffset uint32 // value offset for the trie internally + ) + for i, path := range h.nodeList[owner] { + key := []byte(path) + if i%trienodeDataBlockRestartLen == 0 { + restarts = append(restarts, internalKeyOffset) + restarts = append(restarts, internalValOffset) + prefixLen = 0 + } else { + prefixLen = commonPrefixLen(prevKey, key) + } + value := h.nodes[owner][path] + + // key section + n := binary.PutUvarint(buf[0:], uint64(prefixLen)) // key length shared (varint) + n += binary.PutUvarint(buf[n:], uint64(len(key)-prefixLen)) // key length not shared (varint) + n += binary.PutUvarint(buf[n:], uint64(len(value))) // value length (varint) + + if _, err := keySection.Write(buf[:n]); err != nil { + return nil, nil, nil, err + } + // unshared key + if _, err := keySection.Write(key[prefixLen:]); err != nil { + return nil, nil, nil, err + } + n += len(key) - prefixLen + prevKey = key + + // value section + if _, err := valueSection.Write(value); err != nil { + return nil, nil, nil, err + } + internalKeyOffset += uint32(n) + internalValOffset += uint32(len(value)) + } + + // Encode trailer, the number of restart sections is len(restarts))/2, + // as we track the offsets of both key and value sections. + var trailer []byte + for _, number := range append(restarts, uint32(len(restarts))/2) { + binary.BigEndian.PutUint32(buf[:4], number) + trailer = append(trailer, buf[:4]...) + } + if _, err := keySection.Write(trailer); err != nil { + return nil, nil, nil, err + } + + // Fill the header section with the offsets of the key and value sections. + // Note that the key/value offsets are intentionally tracked *after* encoding + // them into their respective sections, ensuring each offset refers to the end + // position. For n trie chunks, n offset pairs are sufficient to uniquely locate + // the corresponding data. + headerSection.Write(owner.Bytes()) // 32 bytes + binary.Write(&headerSection, binary.BigEndian, uint32(keySection.Len())) // 4 bytes + + // The offset to the value section is theoretically unnecessary, since the + // individual value offset is already tracked in the key section. However, + // we still keep it here for two reasons: + // - It's cheap to store (only 4 bytes for each trie). + // - It can be useful for decoding the trie data when key is not required (e.g., in hash mode). + binary.Write(&headerSection, binary.BigEndian, uint32(valueSection.Len())) // 4 bytes + } + return headerSection.Bytes(), keySection.Bytes(), valueSection.Bytes(), nil +} + +// decodeHeader resolves the metadata from the header section. An error +// should be returned if the header section is corrupted. +func decodeHeader(data []byte) (*trienodeMetadata, []common.Hash, []uint32, []uint32, error) { + if len(data) < trienodeMetadataSize { + return nil, nil, nil, nil, fmt.Errorf("trienode history is too small, index size: %d", len(data)) + } + version := data[0] + if version != trienodeHistoryVersion { + return nil, nil, nil, nil, fmt.Errorf("unregonized trienode history version: %d", version) + } + parent := common.BytesToHash(data[1 : common.HashLength+1]) // 32 bytes + root := common.BytesToHash(data[common.HashLength+1 : common.HashLength*2+1]) // 32 bytes + block := binary.BigEndian.Uint64(data[common.HashLength*2+1 : trienodeMetadataSize]) // 8 bytes + + size := len(data) - trienodeMetadataSize + if size%trienodeTrieHeaderSize != 0 { + return nil, nil, nil, nil, fmt.Errorf("truncated trienode history data, size %d", len(data)) + } + count := size / trienodeTrieHeaderSize + + var ( + owners = make([]common.Hash, 0, count) + keyOffsets = make([]uint32, 0, count) + valOffsets = make([]uint32, 0, count) + ) + for i := range count { + n := trienodeMetadataSize + trienodeTrieHeaderSize*i + owner := common.BytesToHash(data[n : n+common.HashLength]) + if i != 0 && bytes.Compare(owner.Bytes(), owners[i-1].Bytes()) <= 0 { + return nil, nil, nil, nil, fmt.Errorf("trienode owners are out of order, prev: %v, cur: %v", owners[i-1], owner) + } + owners = append(owners, owner) + + // Decode the offset to the key section + keyOffset := binary.BigEndian.Uint32(data[n+common.HashLength : n+common.HashLength+4]) + if i != 0 && keyOffset <= keyOffsets[i-1] { + return nil, nil, nil, nil, fmt.Errorf("key offset is out of order, prev: %v, cur: %v", keyOffsets[i-1], keyOffset) + } + keyOffsets = append(keyOffsets, keyOffset) + + // Decode the offset into the value section. Note that identical value offsets + // are valid if the node values in the last trie chunk are all zero (e.g., after + // a trie deletion). + valOffset := binary.BigEndian.Uint32(data[n+common.HashLength+4 : n+common.HashLength+8]) + if i != 0 && valOffset < valOffsets[i-1] { + return nil, nil, nil, nil, fmt.Errorf("value offset is out of order, prev: %v, cur: %v", valOffsets[i-1], valOffset) + } + valOffsets = append(valOffsets, valOffset) + } + return &trienodeMetadata{ + version: version, + parent: parent, + root: root, + block: block, + }, owners, keyOffsets, valOffsets, nil +} + +func decodeSingle(keySection []byte, onValue func([]byte, int, int) error) ([]string, error) { + var ( + prevKey []byte + items int + keyOffsets []uint32 + valOffsets []uint32 + + keyOff int // the key offset within the single trie data + valOff int // the value offset within the single trie data + + keys []string + ) + // Decode the number of restart section + if len(keySection) < 4 { + return nil, fmt.Errorf("key section too short, size: %d", len(keySection)) + } + nRestarts := binary.BigEndian.Uint32(keySection[len(keySection)-4:]) + + if len(keySection) < int(8*nRestarts)+4 { + return nil, fmt.Errorf("key section too short, restarts: %d, size: %d", nRestarts, len(keySection)) + } + for i := range int(nRestarts) { + o := len(keySection) - 4 - (int(nRestarts)-i)*8 + keyOffset := binary.BigEndian.Uint32(keySection[o : o+4]) + if i != 0 && keyOffset <= keyOffsets[i-1] { + return nil, fmt.Errorf("key offset is out of order, prev: %v, cur: %v", keyOffsets[i-1], keyOffset) + } + keyOffsets = append(keyOffsets, keyOffset) + + // Same value offset is allowed just in case all the trie nodes in the last + // section have zero-size value. + valOffset := binary.BigEndian.Uint32(keySection[o+4 : o+8]) + if i != 0 && valOffset < valOffsets[i-1] { + return nil, fmt.Errorf("value offset is out of order, prev: %v, cur: %v", valOffsets[i-1], valOffset) + } + valOffsets = append(valOffsets, valOffset) + } + keyLimit := len(keySection) - 4 - int(nRestarts)*8 + + // Decode data + for keyOff < keyLimit { + // Validate the key and value offsets within the single trie data chunk + if items%trienodeDataBlockRestartLen == 0 { + restartIndex := items / trienodeDataBlockRestartLen + if restartIndex >= len(keyOffsets) { + return nil, fmt.Errorf("restart index out of range: %d, available restarts: %d", restartIndex, len(keyOffsets)) + } + if keyOff != int(keyOffsets[restartIndex]) { + return nil, fmt.Errorf("key offset is not matched, recorded: %d, want: %d", keyOffsets[restartIndex], keyOff) + } + if valOff != int(valOffsets[restartIndex]) { + return nil, fmt.Errorf("value offset is not matched, recorded: %d, want: %d", valOffsets[restartIndex], valOff) + } + } + // Resolve the entry from key section + nShared, nn := binary.Uvarint(keySection[keyOff:]) // key length shared (varint) + if nn <= 0 { + return nil, fmt.Errorf("corrupted varint encoding for nShared at offset %d", keyOff) + } + keyOff += nn + nUnshared, nn := binary.Uvarint(keySection[keyOff:]) // key length not shared (varint) + if nn <= 0 { + return nil, fmt.Errorf("corrupted varint encoding for nUnshared at offset %d", keyOff) + } + keyOff += nn + nValue, nn := binary.Uvarint(keySection[keyOff:]) // value length (varint) + if nn <= 0 { + return nil, fmt.Errorf("corrupted varint encoding for nValue at offset %d", keyOff) + } + keyOff += nn + + // Validate that the values can fit in an int to prevent overflow on 32-bit systems + if nShared > uint64(math.MaxUint32) || nUnshared > uint64(math.MaxUint32) || nValue > uint64(math.MaxUint32) { + return nil, errors.New("key size too large") + } + + // Resolve unshared key + if keyOff+int(nUnshared) > len(keySection) { + return nil, fmt.Errorf("key length too long, unshared key length: %d, off: %d, section size: %d", nUnshared, keyOff, len(keySection)) + } + unsharedKey := keySection[keyOff : keyOff+int(nUnshared)] + keyOff += int(nUnshared) + + // Assemble the full key + var key []byte + if items%trienodeDataBlockRestartLen == 0 { + if nShared != 0 { + return nil, fmt.Errorf("unexpected non-zero shared key prefix: %d", nShared) + } + key = unsharedKey + } else { + // TODO(rjl493456442) mitigate the allocation pressure. + if int(nShared) > len(prevKey) { + return nil, fmt.Errorf("unexpected shared key prefix: %d, prefix key length: %d", nShared, len(prevKey)) + } + key = append([]byte{}, prevKey[:nShared]...) + key = append(key, unsharedKey...) + } + if items != 0 && bytes.Compare(prevKey, key) >= 0 { + return nil, fmt.Errorf("trienode paths are out of order, prev: %v, cur: %v", prevKey, key) + } + prevKey = key + + // Resolve value + if onValue != nil { + if err := onValue(key, valOff, valOff+int(nValue)); err != nil { + return nil, err + } + } + valOff += int(nValue) + + items++ + keys = append(keys, string(key)) + } + if keyOff != keyLimit { + return nil, fmt.Errorf("excessive key data after decoding, offset: %d, size: %d", keyOff, keyLimit) + } + return keys, nil +} + +func decodeSingleWithValue(keySection []byte, valueSection []byte) ([]string, map[string][]byte, error) { + var ( + offset int + nodes = make(map[string][]byte) + ) + paths, err := decodeSingle(keySection, func(key []byte, start int, limit int) error { + if start != offset { + return fmt.Errorf("gapped value section offset: %d, want: %d", start, offset) + } + // start == limit is allowed for zero-value trie node (e.g., non-existent node) + if start > limit { + return fmt.Errorf("invalid value offsets, start: %d, limit: %d", start, limit) + } + if start > len(valueSection) || limit > len(valueSection) { + return fmt.Errorf("value section out of range: start: %d, limit: %d, size: %d", start, limit, len(valueSection)) + } + nodes[string(key)] = valueSection[start:limit] + + offset = limit + return nil + }) + if err != nil { + return nil, nil, err + } + if offset != len(valueSection) { + return nil, nil, fmt.Errorf("excessive value data after decoding, offset: %d, size: %d", offset, len(valueSection)) + } + return paths, nodes, nil +} + +// decode deserializes the contained trie nodes from the provided bytes. +func (h *trienodeHistory) decode(header []byte, keySection []byte, valueSection []byte) error { + metadata, owners, keyOffsets, valueOffsets, err := decodeHeader(header) + if err != nil { + return err + } + h.meta = metadata + h.owners = owners + h.nodeList = make(map[common.Hash][]string) + h.nodes = make(map[common.Hash]map[string][]byte) + + for i := range len(owners) { + // Resolve the boundary of key section + var keyStart, keyLimit uint32 + if i != 0 { + keyStart = keyOffsets[i-1] + } + keyLimit = keyOffsets[i] + if int(keyStart) > len(keySection) || int(keyLimit) > len(keySection) { + return fmt.Errorf("invalid key offsets: keyStart: %d, keyLimit: %d, size: %d", keyStart, keyLimit, len(keySection)) + } + + // Resolve the boundary of value section + var valStart, valLimit uint32 + if i != 0 { + valStart = valueOffsets[i-1] + } + valLimit = valueOffsets[i] + if int(valStart) > len(valueSection) || int(valLimit) > len(valueSection) { + return fmt.Errorf("invalid value offsets: valueStart: %d, valueLimit: %d, size: %d", valStart, valLimit, len(valueSection)) + } + + // Decode the key and values for this specific trie + paths, nodes, err := decodeSingleWithValue(keySection[keyStart:keyLimit], valueSection[valStart:valLimit]) + if err != nil { + return err + } + h.nodeList[owners[i]] = paths + h.nodes[owners[i]] = nodes + } + return nil +} + +type iRange struct { + start uint32 + limit uint32 +} + +func (ir iRange) len() uint32 { + return ir.limit - ir.start +} + +// singleTrienodeHistoryReader provides read access to a single trie within the +// trienode history. It stores an offset to the trie's position in the history, +// along with a set of per-node offsets that can be resolved on demand. +type singleTrienodeHistoryReader struct { + id uint64 + reader ethdb.AncientReader + valueRange iRange // value range within the global value section + valueInternalOffsets map[string]iRange // value offset within the single trie data +} + +// TODO(rjl493456442): This function performs a large number of allocations. +// Given the large data size, a byte pool could be used to mitigate this. +func newSingleTrienodeHistoryReader(id uint64, reader ethdb.AncientReader, keyRange iRange, valueRange iRange) (*singleTrienodeHistoryReader, error) { + // TODO(rjl493456442) the data size is known in advance, allocating the + // dedicated byte slices from the pool. + keyData, err := rawdb.ReadTrienodeHistoryKeySection(reader, id, uint64(keyRange.start), uint64(keyRange.len())) + if err != nil { + return nil, err + } + valueOffsets := make(map[string]iRange) + _, err = decodeSingle(keyData, func(key []byte, start int, limit int) error { + valueOffsets[string(key)] = iRange{ + start: uint32(start), + limit: uint32(limit), + } + return nil + }) + if err != nil { + return nil, err + } + return &singleTrienodeHistoryReader{ + id: id, + reader: reader, + valueRange: valueRange, + valueInternalOffsets: valueOffsets, + }, nil +} + +// read retrieves the trie node data with the provided node path. +func (sr *singleTrienodeHistoryReader) read(path string) ([]byte, error) { + offset, exists := sr.valueInternalOffsets[path] + if !exists { + return nil, fmt.Errorf("trienode %v not found", []byte(path)) + } + return rawdb.ReadTrienodeHistoryValueSection(sr.reader, sr.id, uint64(sr.valueRange.start+offset.start), uint64(offset.len())) +} + +// trienodeHistoryReader provides read access to node data in the trie node history. +// It resolves data from the underlying ancient store only when needed, minimizing +// I/O overhead. +type trienodeHistoryReader struct { + id uint64 // ID of the associated trienode history + reader ethdb.AncientReader // Database reader of ancient store + keyRanges map[common.Hash]iRange // Key ranges identifying trie chunks + valRanges map[common.Hash]iRange // Value ranges identifying trie chunks + iReaders map[common.Hash]*singleTrienodeHistoryReader // readers for each individual trie chunk +} + +// newTrienodeHistoryReader constructs the reader for specific trienode history. +func newTrienodeHistoryReader(id uint64, reader ethdb.AncientReader) (*trienodeHistoryReader, error) { + r := &trienodeHistoryReader{ + id: id, + reader: reader, + keyRanges: make(map[common.Hash]iRange), + valRanges: make(map[common.Hash]iRange), + iReaders: make(map[common.Hash]*singleTrienodeHistoryReader), + } + if err := r.decodeHeader(); err != nil { + return nil, err + } + return r, nil +} + +// decodeHeader decodes the header section of trienode history. +func (r *trienodeHistoryReader) decodeHeader() error { + header, err := rawdb.ReadTrienodeHistoryHeader(r.reader, r.id) + if err != nil { + return err + } + _, owners, keyOffsets, valOffsets, err := decodeHeader(header) + if err != nil { + return err + } + for i, owner := range owners { + // Decode the key range for this trie chunk + var keyStart uint32 + if i != 0 { + keyStart = keyOffsets[i-1] + } + r.keyRanges[owner] = iRange{ + start: keyStart, + limit: keyOffsets[i], + } + + // Decode the value range for this trie chunk + var valStart uint32 + if i != 0 { + valStart = valOffsets[i-1] + } + r.valRanges[owner] = iRange{ + start: valStart, + limit: valOffsets[i], + } + } + return nil +} + +// read retrieves the trie node data with the provided TrieID and node path. +func (r *trienodeHistoryReader) read(owner common.Hash, path string) ([]byte, error) { + ir, ok := r.iReaders[owner] + if !ok { + keyRange, exists := r.keyRanges[owner] + if !exists { + return nil, fmt.Errorf("trie %x is unknown", owner) + } + valRange, exists := r.valRanges[owner] + if !exists { + return nil, fmt.Errorf("trie %x is unknown", owner) + } + var err error + ir, err = newSingleTrienodeHistoryReader(r.id, r.reader, keyRange, valRange) + if err != nil { + return nil, err + } + r.iReaders[owner] = ir + } + return ir.read(path) +} + +// writeTrienodeHistory persists the trienode history associated with the given diff layer. +func writeTrienodeHistory(writer ethdb.AncientWriter, dl *diffLayer, rate uint32) error { + start := time.Now() + nodes, err := dl.nodes.encodeNodeHistory(dl.root, rate) + if err != nil { + return err + } + h := newTrienodeHistory(dl.rootHash(), dl.parent.rootHash(), dl.block, nodes) + header, keySection, valueSection, err := h.encode() + if err != nil { + return err + } + // Write history data into five freezer table respectively. + if err := rawdb.WriteTrienodeHistory(writer, dl.stateID(), header, keySection, valueSection); err != nil { + return err + } + trienodeHistoryDataBytesMeter.Mark(int64(len(valueSection))) + trienodeHistoryIndexBytesMeter.Mark(int64(len(header) + len(keySection))) + trienodeHistoryBuildTimeMeter.UpdateSince(start) + + log.Debug( + "Stored trienode history", "id", dl.stateID(), "block", dl.block, + "header", common.StorageSize(len(header)), + "keySection", common.StorageSize(len(keySection)), + "valueSection", common.StorageSize(len(valueSection)), + "elapsed", common.PrettyDuration(time.Since(start)), + ) + return nil +} + +// readTrienodeMetadata resolves the metadata of the specified trienode history. +// nolint:unused +func readTrienodeMetadata(reader ethdb.AncientReader, id uint64) (*trienodeMetadata, error) { + header, err := rawdb.ReadTrienodeHistoryHeader(reader, id) + if err != nil { + return nil, err + } + metadata, _, _, _, err := decodeHeader(header) + if err != nil { + return nil, err + } + return metadata, nil +} + +// readTrienodeHistory resolves a single trienode history object with specific id. +func readTrienodeHistory(reader ethdb.AncientReader, id uint64) (*trienodeHistory, error) { + header, keySection, valueSection, err := rawdb.ReadTrienodeHistory(reader, id) + if err != nil { + return nil, err + } + var h trienodeHistory + if err := h.decode(header, keySection, valueSection); err != nil { + return nil, err + } + return &h, nil +} + +// readTrienodeHistories resolves a list of trienode histories with the specific range. +func readTrienodeHistories(reader ethdb.AncientReader, start uint64, count uint64) ([]history, error) { + headers, keySections, valueSections, err := rawdb.ReadTrienodeHistoryList(reader, start, count) + if err != nil { + return nil, err + } + var res []history + for i, header := range headers { + var h trienodeHistory + if err := h.decode(header, keySections[i], valueSections[i]); err != nil { + return nil, err + } + res = append(res, &h) + } + return res, nil +} diff --git a/triedb/pathdb/history_trienode_test.go b/triedb/pathdb/history_trienode_test.go new file mode 100644 index 0000000000..8f9b9c2600 --- /dev/null +++ b/triedb/pathdb/history_trienode_test.go @@ -0,0 +1,693 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pathdb + +import ( + "bytes" + "encoding/binary" + "math/rand" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/rawdb" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testrand" +) + +// randomTrienodes generates a random trienode set. +func randomTrienodes(n int) (map[common.Hash]map[string][]byte, common.Hash) { + var ( + root common.Hash + nodes = make(map[common.Hash]map[string][]byte) + ) + for i := 0; i < n; i++ { + owner := testrand.Hash() + if i == 0 { + owner = common.Hash{} + } + nodes[owner] = make(map[string][]byte) + + for j := 0; j < 10; j++ { + path := testrand.Bytes(rand.Intn(10)) + for z := 0; z < len(path); z++ { + nodes[owner][string(path[:z])] = testrand.Bytes(rand.Intn(128)) + } + } + // zero-size trie node, representing it was non-existent before + for j := 0; j < 10; j++ { + path := testrand.Bytes(32) + nodes[owner][string(path)] = nil + } + // root node with zero-size path + rnode := testrand.Bytes(256) + nodes[owner][""] = rnode + if owner == (common.Hash{}) { + root = crypto.Keccak256Hash(rnode) + } + } + return nodes, root +} + +func makeTrienodeHistory() *trienodeHistory { + nodes, root := randomTrienodes(10) + return newTrienodeHistory(root, common.Hash{}, 1, nodes) +} + +func makeTrienodeHistories(n int) []*trienodeHistory { + var ( + parent common.Hash + result []*trienodeHistory + ) + for i := 0; i < n; i++ { + nodes, root := randomTrienodes(10) + result = append(result, newTrienodeHistory(root, parent, uint64(i+1), nodes)) + parent = root + } + return result +} + +func TestEncodeDecodeTrienodeHistory(t *testing.T) { + var ( + dec trienodeHistory + obj = makeTrienodeHistory() + ) + header, keySection, valueSection, err := obj.encode() + if err != nil { + t.Fatalf("Failed to encode trienode history: %v", err) + } + if err := dec.decode(header, keySection, valueSection); err != nil { + t.Fatalf("Failed to decode trienode history: %v", err) + } + + if !reflect.DeepEqual(obj.meta, dec.meta) { + t.Fatal("trienode metadata is mismatched") + } + if !compareList(dec.owners, obj.owners) { + t.Fatal("trie owner list is mismatched") + } + if !compareMapList(dec.nodeList, obj.nodeList) { + t.Fatal("trienode list is mismatched") + } + if !compareMapSet(dec.nodes, obj.nodes) { + t.Fatal("trienode content is mismatched") + } + + // Re-encode again, ensuring the encoded blob still match + header2, keySection2, valueSection2, err := dec.encode() + if err != nil { + t.Fatalf("Failed to encode trienode history: %v", err) + } + if !bytes.Equal(header, header2) { + t.Fatal("re-encoded header is mismatched") + } + if !bytes.Equal(keySection, keySection2) { + t.Fatal("re-encoded key section is mismatched") + } + if !bytes.Equal(valueSection, valueSection2) { + t.Fatal("re-encoded value section is mismatched") + } +} + +func TestTrienodeHistoryReader(t *testing.T) { + var ( + hs = makeTrienodeHistories(10) + freezer, _ = rawdb.NewTrienodeFreezer(t.TempDir(), false, false) + ) + defer freezer.Close() + + for i, h := range hs { + header, keySection, valueSection, _ := h.encode() + if err := rawdb.WriteTrienodeHistory(freezer, uint64(i+1), header, keySection, valueSection); err != nil { + t.Fatalf("Failed to write trienode history: %v", err) + } + } + for i, h := range hs { + tr, err := newTrienodeHistoryReader(uint64(i+1), freezer) + if err != nil { + t.Fatalf("Failed to construct the history reader: %v", err) + } + for _, owner := range h.owners { + nodes := h.nodes[owner] + for key, value := range nodes { + blob, err := tr.read(owner, key) + if err != nil { + t.Fatalf("Failed to read trienode history: %v", err) + } + if !bytes.Equal(blob, value) { + t.Fatalf("Unexpected trie node data, want: %v, got: %v", value, blob) + } + } + } + } + for i, h := range hs { + metadata, err := readTrienodeMetadata(freezer, uint64(i+1)) + if err != nil { + t.Fatalf("Failed to read trienode history metadata: %v", err) + } + if !reflect.DeepEqual(h.meta, metadata) { + t.Fatalf("Unexpected trienode metadata, want: %v, got: %v", h.meta, metadata) + } + } +} + +// TestEmptyTrienodeHistory tests encoding/decoding of empty trienode history +func TestEmptyTrienodeHistory(t *testing.T) { + h := newTrienodeHistory(common.Hash{}, common.Hash{}, 1, make(map[common.Hash]map[string][]byte)) + + // Test encoding empty history + header, keySection, valueSection, err := h.encode() + if err != nil { + t.Fatalf("Failed to encode empty trienode history: %v", err) + } + + // Verify sections are minimal but valid + if len(header) == 0 { + t.Fatal("Header should not be empty") + } + if len(keySection) != 0 { + t.Fatal("Key section should be empty for empty history") + } + if len(valueSection) != 0 { + t.Fatal("Value section should be empty for empty history") + } + + // Test decoding empty history + var decoded trienodeHistory + if err := decoded.decode(header, keySection, valueSection); err != nil { + t.Fatalf("Failed to decode empty trienode history: %v", err) + } + + if len(decoded.owners) != 0 { + t.Fatal("Decoded history should have no owners") + } + if len(decoded.nodeList) != 0 { + t.Fatal("Decoded history should have no node lists") + } + if len(decoded.nodes) != 0 { + t.Fatal("Decoded history should have no nodes") + } +} + +// TestSingleTrieHistory tests encoding/decoding of history with single trie +func TestSingleTrieHistory(t *testing.T) { + nodes := make(map[common.Hash]map[string][]byte) + owner := testrand.Hash() + nodes[owner] = make(map[string][]byte) + + // Add some nodes with various sizes + nodes[owner][""] = testrand.Bytes(32) // empty key + nodes[owner]["a"] = testrand.Bytes(1) // small value + nodes[owner]["bb"] = testrand.Bytes(100) // medium value + nodes[owner]["ccc"] = testrand.Bytes(1000) // large value + nodes[owner]["dddd"] = testrand.Bytes(0) // empty value + + h := newTrienodeHistory(common.Hash{}, common.Hash{}, 1, nodes) + testEncodeDecode(t, h) +} + +// TestMultipleTries tests multiple tries with different node counts +func TestMultipleTries(t *testing.T) { + nodes := make(map[common.Hash]map[string][]byte) + + // First trie with many small nodes + owner1 := testrand.Hash() + nodes[owner1] = make(map[string][]byte) + for i := 0; i < 100; i++ { + key := string(testrand.Bytes(rand.Intn(10))) + nodes[owner1][key] = testrand.Bytes(rand.Intn(50)) + } + + // Second trie with few large nodes + owner2 := testrand.Hash() + nodes[owner2] = make(map[string][]byte) + for i := 0; i < 5; i++ { + key := string(testrand.Bytes(rand.Intn(20))) + nodes[owner2][key] = testrand.Bytes(1000 + rand.Intn(1000)) + } + + // Third trie with nil values (zero-size nodes) + owner3 := testrand.Hash() + nodes[owner3] = make(map[string][]byte) + for i := 0; i < 10; i++ { + key := string(testrand.Bytes(rand.Intn(15))) + nodes[owner3][key] = nil + } + + h := newTrienodeHistory(common.Hash{}, common.Hash{}, 1, nodes) + testEncodeDecode(t, h) +} + +// TestLargeNodeValues tests encoding/decoding with very large node values +func TestLargeNodeValues(t *testing.T) { + nodes := make(map[common.Hash]map[string][]byte) + owner := testrand.Hash() + nodes[owner] = make(map[string][]byte) + + // Test with progressively larger values + sizes := []int{1024, 10 * 1024, 100 * 1024, 1024 * 1024} // 1KB, 10KB, 100KB, 1MB + for _, size := range sizes { + key := string(testrand.Bytes(10)) + nodes[owner][key] = testrand.Bytes(size) + + h := newTrienodeHistory(common.Hash{}, common.Hash{}, 1, nodes) + testEncodeDecode(t, h) + t.Logf("Successfully tested encoding/decoding with %dKB value", size/1024) + } +} + +// TestNilNodeValues tests encoding/decoding with nil (zero-length) node values +func TestNilNodeValues(t *testing.T) { + nodes := make(map[common.Hash]map[string][]byte) + owner := testrand.Hash() + nodes[owner] = make(map[string][]byte) + + // Mix of nil and non-nil values + nodes[owner]["nil"] = nil + nodes[owner]["data1"] = []byte("some data") + nodes[owner]["data2"] = []byte("more data") + + h := newTrienodeHistory(common.Hash{}, common.Hash{}, 1, nodes) + testEncodeDecode(t, h) + + // Verify nil values are preserved + _, ok := h.nodes[owner]["nil"] + if !ok { + t.Fatal("Nil value should be preserved") + } +} + +// TestCorruptedHeader tests error handling for corrupted header data +func TestCorruptedHeader(t *testing.T) { + h := makeTrienodeHistory() + header, keySection, valueSection, _ := h.encode() + + // Test corrupted version + corruptedHeader := make([]byte, len(header)) + copy(corruptedHeader, header) + corruptedHeader[0] = 0xFF // Invalid version + + var decoded trienodeHistory + if err := decoded.decode(corruptedHeader, keySection, valueSection); err == nil { + t.Fatal("Expected error for corrupted version") + } + + // Test truncated header + truncatedHeader := header[:len(header)-5] + if err := decoded.decode(truncatedHeader, keySection, valueSection); err == nil { + t.Fatal("Expected error for truncated header") + } + + // Test header with invalid trie header size + invalidHeader := make([]byte, len(header)) + copy(invalidHeader, header) + invalidHeader = invalidHeader[:trienodeMetadataSize+5] // Not divisible by trie header size + + if err := decoded.decode(invalidHeader, keySection, valueSection); err == nil { + t.Fatal("Expected error for invalid header size") + } +} + +// TestCorruptedKeySection tests error handling for corrupted key section data +func TestCorruptedKeySection(t *testing.T) { + h := makeTrienodeHistory() + header, keySection, valueSection, _ := h.encode() + + // Test empty key section when header indicates data + if len(keySection) > 0 { + var decoded trienodeHistory + if err := decoded.decode(header, []byte{}, valueSection); err == nil { + t.Fatal("Expected error for empty key section with non-empty header") + } + } + + // Test truncated key section + if len(keySection) > 10 { + truncatedKeySection := keySection[:len(keySection)-10] + var decoded trienodeHistory + if err := decoded.decode(header, truncatedKeySection, valueSection); err == nil { + t.Fatal("Expected error for truncated key section") + } + } + + // Test corrupted key section with invalid varint + corruptedKeySection := make([]byte, len(keySection)) + copy(corruptedKeySection, keySection) + if len(corruptedKeySection) > 5 { + corruptedKeySection[5] = 0xFF // Corrupt varint encoding + var decoded trienodeHistory + if err := decoded.decode(header, corruptedKeySection, valueSection); err == nil { + t.Fatal("Expected error for corrupted varint in key section") + } + } +} + +// TestCorruptedValueSection tests error handling for corrupted value section data +func TestCorruptedValueSection(t *testing.T) { + h := makeTrienodeHistory() + header, keySection, valueSection, _ := h.encode() + + // Test truncated value section + if len(valueSection) > 10 { + truncatedValueSection := valueSection[:len(valueSection)-10] + var decoded trienodeHistory + if err := decoded.decode(header, keySection, truncatedValueSection); err == nil { + t.Fatal("Expected error for truncated value section") + } + } + + // Test empty value section when key section indicates data exists + if len(valueSection) > 0 { + var decoded trienodeHistory + if err := decoded.decode(header, keySection, []byte{}); err == nil { + t.Fatal("Expected error for empty value section with non-empty key section") + } + } +} + +// TestInvalidOffsets tests error handling for invalid offsets in encoded data +func TestInvalidOffsets(t *testing.T) { + h := makeTrienodeHistory() + header, keySection, valueSection, _ := h.encode() + + // Corrupt key offset in header (make it larger than key section) + corruptedHeader := make([]byte, len(header)) + copy(corruptedHeader, header) + corruptedHeader[trienodeMetadataSize+common.HashLength] = 0xff + + var dec1 trienodeHistory + if err := dec1.decode(corruptedHeader, keySection, valueSection); err == nil { + t.Fatal("Expected error for invalid key offset") + } + + // Corrupt value offset in header (make it larger than value section) + corruptedHeader = make([]byte, len(header)) + copy(corruptedHeader, header) + corruptedHeader[trienodeMetadataSize+common.HashLength+4] = 0xff + + var dec2 trienodeHistory + if err := dec2.decode(corruptedHeader, keySection, valueSection); err == nil { + t.Fatal("Expected error for invalid value offset") + } +} + +// TestTrienodeHistoryReaderNonExistentPath tests reading non-existent paths +func TestTrienodeHistoryReaderNonExistentPath(t *testing.T) { + var ( + h = makeTrienodeHistory() + freezer, _ = rawdb.NewTrienodeFreezer(t.TempDir(), false, false) + ) + defer freezer.Close() + + header, keySection, valueSection, _ := h.encode() + if err := rawdb.WriteTrienodeHistory(freezer, 1, header, keySection, valueSection); err != nil { + t.Fatalf("Failed to write trienode history: %v", err) + } + + tr, err := newTrienodeHistoryReader(1, freezer) + if err != nil { + t.Fatalf("Failed to construct history reader: %v", err) + } + + // Try to read a non-existent path + _, err = tr.read(testrand.Hash(), "nonexistent") + if err == nil { + t.Fatal("Expected error for non-existent trie owner") + } + + // Try to read from existing owner but non-existent path + owner := h.owners[0] + _, err = tr.read(owner, "nonexistent-path") + if err == nil { + t.Fatal("Expected error for non-existent path") + } +} + +// TestTrienodeHistoryReaderNilValues tests reading nil (zero-length) values +func TestTrienodeHistoryReaderNilValues(t *testing.T) { + nodes := make(map[common.Hash]map[string][]byte) + owner := testrand.Hash() + nodes[owner] = make(map[string][]byte) + + // Add some nil values + nodes[owner]["nil1"] = nil + nodes[owner]["nil2"] = nil + nodes[owner]["data1"] = []byte("some data") + + h := newTrienodeHistory(common.Hash{}, common.Hash{}, 1, nodes) + + var freezer, _ = rawdb.NewTrienodeFreezer(t.TempDir(), false, false) + defer freezer.Close() + + header, keySection, valueSection, _ := h.encode() + if err := rawdb.WriteTrienodeHistory(freezer, 1, header, keySection, valueSection); err != nil { + t.Fatalf("Failed to write trienode history: %v", err) + } + + tr, err := newTrienodeHistoryReader(1, freezer) + if err != nil { + t.Fatalf("Failed to construct history reader: %v", err) + } + + // Test reading nil values + data1, err := tr.read(owner, "nil1") + if err != nil { + t.Fatalf("Failed to read nil value: %v", err) + } + if len(data1) != 0 { + t.Fatal("Expected nil data for nil value") + } + + data2, err := tr.read(owner, "nil2") + if err != nil { + t.Fatalf("Failed to read nil value: %v", err) + } + if len(data2) != 0 { + t.Fatal("Expected nil data for nil value") + } + + // Test reading non-nil value + data3, err := tr.read(owner, "data1") + if err != nil { + t.Fatalf("Failed to read non-nil value: %v", err) + } + if !bytes.Equal(data3, []byte("some data")) { + t.Fatal("Data mismatch for non-nil value") + } +} + +// TestTrienodeHistoryReaderNilKey tests reading nil (zero-length) key +func TestTrienodeHistoryReaderNilKey(t *testing.T) { + nodes := make(map[common.Hash]map[string][]byte) + owner := testrand.Hash() + nodes[owner] = make(map[string][]byte) + + // Add some nil values + nodes[owner][""] = []byte("some data") + nodes[owner]["data1"] = []byte("some data") + + h := newTrienodeHistory(common.Hash{}, common.Hash{}, 1, nodes) + + var freezer, _ = rawdb.NewTrienodeFreezer(t.TempDir(), false, false) + defer freezer.Close() + + header, keySection, valueSection, _ := h.encode() + if err := rawdb.WriteTrienodeHistory(freezer, 1, header, keySection, valueSection); err != nil { + t.Fatalf("Failed to write trienode history: %v", err) + } + + tr, err := newTrienodeHistoryReader(1, freezer) + if err != nil { + t.Fatalf("Failed to construct history reader: %v", err) + } + + // Test reading nil values + data1, err := tr.read(owner, "") + if err != nil { + t.Fatalf("Failed to read nil value: %v", err) + } + if !bytes.Equal(data1, []byte("some data")) { + t.Fatal("Data mismatch for nil key") + } + + // Test reading non-nil value + data2, err := tr.read(owner, "data1") + if err != nil { + t.Fatalf("Failed to read non-nil value: %v", err) + } + if !bytes.Equal(data2, []byte("some data")) { + t.Fatal("Data mismatch for non-nil key") + } +} + +// TestCommonPrefixLen tests the commonPrefixLen helper function +func TestCommonPrefixLen(t *testing.T) { + tests := []struct { + a, b []byte + expected int + }{ + // Empty strings + {[]byte(""), []byte(""), 0}, + // One empty string + {[]byte(""), []byte("abc"), 0}, + {[]byte("abc"), []byte(""), 0}, + // No common prefix + {[]byte("abc"), []byte("def"), 0}, + // Partial common prefix + {[]byte("abc"), []byte("abx"), 2}, + {[]byte("prefix"), []byte("pref"), 4}, + // Complete common prefix (shorter first) + {[]byte("ab"), []byte("abcd"), 2}, + // Complete common prefix (longer first) + {[]byte("abcd"), []byte("ab"), 2}, + // Identical strings + {[]byte("identical"), []byte("identical"), 9}, + // Binary data + {[]byte{0x00, 0x01, 0x02}, []byte{0x00, 0x01, 0x03}, 2}, + // Large strings + {bytes.Repeat([]byte("a"), 1000), bytes.Repeat([]byte("a"), 1000), 1000}, + {bytes.Repeat([]byte("a"), 1000), append(bytes.Repeat([]byte("a"), 999), []byte("b")...), 999}, + } + + for i, test := range tests { + result := commonPrefixLen(test.a, test.b) + if result != test.expected { + t.Errorf("Test %d: sharedLen(%q, %q) = %d, expected %d", + i, test.a, test.b, result, test.expected) + } + // Test commutativity + resultReverse := commonPrefixLen(test.b, test.a) + if result != resultReverse { + t.Errorf("Test %d: sharedLen is not commutative: sharedLen(a,b)=%d, sharedLen(b,a)=%d", + i, result, resultReverse) + } + } +} + +// TestDecodeHeaderCorruptedData tests decodeHeader with corrupted data +func TestDecodeHeaderCorruptedData(t *testing.T) { + // Create valid header data first + h := makeTrienodeHistory() + header, _, _, _ := h.encode() + + // Test with empty header + _, _, _, _, err := decodeHeader([]byte{}) + if err == nil { + t.Fatal("Expected error for empty header") + } + + // Test with invalid version + corruptedVersion := make([]byte, len(header)) + copy(corruptedVersion, header) + corruptedVersion[0] = 0xFF + _, _, _, _, err = decodeHeader(corruptedVersion) + if err == nil { + t.Fatal("Expected error for invalid version") + } + + // Test with truncated header (not divisible by trie header size) + truncated := header[:trienodeMetadataSize+5] + _, _, _, _, err = decodeHeader(truncated) + if err == nil { + t.Fatal("Expected error for truncated header") + } + + // Test with unordered trie owners + unordered := make([]byte, len(header)) + copy(unordered, header) + + // Swap two owner hashes to make them unordered + hash1Start := trienodeMetadataSize + hash2Start := trienodeMetadataSize + trienodeTrieHeaderSize + hash1 := unordered[hash1Start : hash1Start+common.HashLength] + hash2 := unordered[hash2Start : hash2Start+common.HashLength] + + // Only swap if they would be out of order + copy(unordered[hash1Start:hash1Start+common.HashLength], hash2) + copy(unordered[hash2Start:hash2Start+common.HashLength], hash1) + + _, _, _, _, err = decodeHeader(unordered) + if err == nil { + t.Fatal("Expected error for unordered trie owners") + } +} + +// TestDecodeSingleCorruptedData tests decodeSingle with corrupted data +func TestDecodeSingleCorruptedData(t *testing.T) { + h := makeTrienodeHistory() + _, keySection, _, _ := h.encode() + + // Test with empty key section + _, err := decodeSingle([]byte{}, nil) + if err == nil { + t.Fatal("Expected error for empty key section") + } + + // Test with key section too small for trailer + if len(keySection) > 0 { + _, err := decodeSingle(keySection[:3], nil) // Less than 4 bytes for trailer + if err == nil { + t.Fatal("Expected error for key section too small for trailer") + } + } + + // Test with corrupted varint in key section + corrupted := make([]byte, len(keySection)) + copy(corrupted, keySection) + // Fill first 10 bytes with 0xFF to create a varint overflow (>64 bits) + for i := range 10 { + corrupted[i] = 0xFF + } + _, err = decodeSingle(corrupted, nil) + if err == nil { + t.Fatal("Expected error for corrupted varint") + } + + // Test with corrupted trailer (invalid restart count) + corrupted = make([]byte, len(keySection)) + copy(corrupted, keySection) + // Set restart count to something too large + binary.BigEndian.PutUint32(corrupted[len(corrupted)-4:], 10000) + _, err = decodeSingle(corrupted, nil) + if err == nil { + t.Fatal("Expected error for invalid restart count") + } +} + +// Helper function to test encode/decode cycle +func testEncodeDecode(t *testing.T, h *trienodeHistory) { + header, keySection, valueSection, err := h.encode() + if err != nil { + t.Fatalf("Failed to encode trienode history: %v", err) + } + + var decoded trienodeHistory + if err := decoded.decode(header, keySection, valueSection); err != nil { + t.Fatalf("Failed to decode trienode history: %v", err) + } + + // Compare the decoded history with original + if !compareList(decoded.owners, h.owners) { + t.Fatal("Trie owner list mismatch") + } + if !compareMapList(decoded.nodeList, h.nodeList) { + t.Fatal("Trienode list mismatch") + } + if !compareMapSet(decoded.nodes, h.nodes) { + t.Fatal("Trienode content mismatch") + } +} diff --git a/triedb/pathdb/history_trienode_utils.go b/triedb/pathdb/history_trienode_utils.go new file mode 100644 index 0000000000..11107494bb --- /dev/null +++ b/triedb/pathdb/history_trienode_utils.go @@ -0,0 +1,344 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pathdb + +import ( + "encoding/binary" + "fmt" + "math/bits" + "slices" + "strings" +) + +// commonPrefixLen returns the length of the common prefix shared by a and b. +func commonPrefixLen(a, b []byte) int { + n := min(len(a), len(b)) + for i := range n { + if a[i] != b[i] { + return i + } + } + return n +} + +// findLeafPaths scans a lexicographically sorted list of paths and returns +// the subset of paths that represent leaves. +// +// A path is considered a leaf if: +// - it is the last element in the list, or +// - the next path does not have the current path as its prefix. +// +// In other words, a leaf is a path that has no children extending it. +// +// Example: +// +// Input: ["a", "ab", "abc", "b", "ba"] +// Output: ["abc", "ba"] +// +// The input must be sorted; otherwise the result is undefined. +func findLeafPaths(paths []string) []string { + var leaves []string + for i := 0; i < len(paths); i++ { + if i == len(paths)-1 || !strings.HasPrefix(paths[i+1], paths[i]) { + leaves = append(leaves, paths[i]) + } + } + return leaves +} + +// hexPathNodeID computes a numeric node ID from the given path. The path is +// interpreted as a sequence of base-16 digits, where each byte of the input +// is treated as one hexadecimal digit in a big-endian number. +// +// The resulting node ID is constructed as: +// +// ID = 1 + 16 + 16^2 + ... + 16^(n-1) + value +// +// where n is the number of bytes in the path, and `value` is the base-16 +// interpretation of the byte sequence. +// +// The offset (1 + 16 + 16^2 + ... + 16^(n-1)) ensures that all IDs of shorter +// paths occupy a lower numeric range, preserving lexicographic ordering between +// differently-length paths. +// +// The numeric node ID is represented by the uint16 with the assumption the length +// of path won't be greater than 3. +func hexPathNodeID(path string) uint16 { + var ( + offset = uint16(0) + pow = uint16(1) + value = uint16(0) + bytes = []byte(path) + ) + for i := 0; i < len(bytes); i++ { + offset += pow + pow *= 16 + } + for i := 0; i < len(bytes); i++ { + value = value*16 + uint16(bytes[i]) + } + return offset + value +} + +// bitmapSize computes the number of bytes required for the marker bitmap +// corresponding to the remaining portion of a path after a cut point. +// The marker is a bitmap where each bit represents the presence of a +// possible element in the remaining path segment. +func bitmapSize(levels int) int { + // Compute: total = 1 + 16 + 16^2 + ... + 16^(segLen-1) + var ( + bits = 0 + pow = 1 + ) + for i := 0; i < levels; i++ { + bits += pow + pow *= 16 + } + // A small adjustment is applied to exclude the root element of this path + // segment, since any existing element would already imply the mutation of + // the root element. This trick can save us 1 byte for each bitmap which is + // non-trivial. + bits -= 1 + return bits / 8 +} + +// indexScheme defines how trie nodes are split into chunks and index them +// at chunk level. +// +// skipRoot indicates whether the root node should be excluded from indexing. +// cutPoints specifies the key length of chunks (in nibbles) extracted from +// each path. +type indexScheme struct { + // skipRoot indicates whether the root node should be excluded from indexing. + // In the account trie, the root is mutated on every state transition, so + // indexing it provides no value. + skipRoot bool + + // cutPoints defines the key lengths of chunks at different positions. + // A single trie node path may span multiple chunks vertically. + cutPoints []int + + // bitmaps specifies the required bitmap size for each chunk. The key is the + // chunk key length, and the value is the corresponding bitmap size. + bitmaps map[int]int +} + +var ( + // Account trie is split into chunks like this: + // + // - root node is excluded from indexing + // - nodes at level1 to level2 are grouped as 16 chunks + // - all other nodes are grouped 3 levels per chunk + // + // Level1 [0] ... [f] 16 chunks + // Level3 [000] ... [fff] 4096 chunks + // Level6 [000000] ... [fffffff] 16777216 chunks + // + // For the chunks at level1, there are 17 nodes per chunk. + // + // chunk-level 0 [ 0 ] 1 node + // chunk-level 1 [ 1 ] … [ 16 ] 16 nodes + // + // For the non-level1 chunks, there are 273 nodes per chunk, + // regardless of the chunk's depth in the trie. + // + // chunk-level 0 [ 0 ] 1 node + // chunk-level 1 [ 1 ] … [ 16 ] 16 nodes + // chunk-level 2 [ 17 ] … … [ 272 ] 256 nodes + accountIndexScheme = newIndexScheme(true) + + // Storage trie is split into chunks like this: (3 levels per chunk) + // + // Level0 [ ROOT ] 1 chunk + // Level3 [000] ... [fff] 4096 chunks + // Level6 [000000] ... [fffffff] 16777216 chunks + // + // Within each chunk, there are 273 nodes in total, regardless of + // the chunk's depth in the trie. + // + // chunk-level 0 [ 0 ] 1 node + // chunk-level 1 [ 1 ] … [ 16 ] 16 nodes + // chunk-level 2 [ 17 ] … … [ 272 ] 256 nodes + storageIndexScheme = newIndexScheme(false) +) + +// newIndexScheme initializes the index scheme. +func newIndexScheme(skipRoot bool) *indexScheme { + var ( + cuts []int + bitmaps = make(map[int]int) + ) + for v := 0; v <= 64; v += 3 { + var ( + levels int + length int + ) + if v == 0 && skipRoot { + length = 1 + levels = 2 + } else { + length = v + levels = 3 + } + cuts = append(cuts, length) + bitmaps[length] = bitmapSize(levels) + } + return &indexScheme{ + skipRoot: skipRoot, + cutPoints: cuts, + bitmaps: bitmaps, + } +} + +// getBitmapSize returns the required bytes for bitmap with chunk's position. +func (s *indexScheme) getBitmapSize(pathLen int) int { + return s.bitmaps[pathLen] +} + +// chunkSpan returns how many chunks should be spanned with the given path. +func (s *indexScheme) chunkSpan(length int) int { + var n int + for _, cut := range s.cutPoints { + if length >= cut { + n++ + continue + } + } + return n +} + +// splitPath applies the indexScheme to the given path and returns two lists: +// +// - chunkIDs: the progressive chunk IDs cuts defined by the scheme +// - innerIDs: the computed node ID for the path segment following each cut +// +// The scheme defines a set of cut points that partition the path. For each cut: +// +// - chunkIDs[i] is path[:cutPoints[i]] +// - innerIDs[i] is the node ID of the segment path[cutPoints[i] : nextCut-1] +func (s *indexScheme) splitPath(path string) ([]string, []uint16) { + // Special case: the root node of the account trie is mutated in every + // state transition, so its mutation records can be ignored. + n := len(path) + if n == 0 && s.skipRoot { + return nil, nil + } + var ( + // Determine how many chunks are spanned by the path + chunks = s.chunkSpan(n) + chunkIDs = make([]string, 0, chunks) + nodeIDs = make([]uint16, 0, chunks) + ) + for i := 0; i < chunks; i++ { + position := s.cutPoints[i] + chunkIDs = append(chunkIDs, path[:position]) + + var limit int + if i != chunks-1 { + limit = s.cutPoints[i+1] - 1 + } else { + limit = len(path) + } + nodeIDs = append(nodeIDs, hexPathNodeID(path[position:limit])) + } + return chunkIDs, nodeIDs +} + +// splitPathLast returns the path prefix of the deepest chunk spanned by the +// given path, along with its corresponding internal node ID. If the path +// spans no chunks, it returns an empty prefix and 0. +// +// nolint:unused +func (s *indexScheme) splitPathLast(path string) (string, uint16) { + chunkIDs, nodeIDs := s.splitPath(path) + if len(chunkIDs) == 0 { + return "", 0 + } + n := len(chunkIDs) + return chunkIDs[n-1], nodeIDs[n-1] +} + +// encodeIDs sorts the given list of uint16 IDs and encodes them into a +// compact byte slice using variable-length unsigned integer encoding. +func encodeIDs(ids []uint16) []byte { + slices.Sort(ids) + buf := make([]byte, 0, len(ids)) + for _, id := range ids { + buf = binary.AppendUvarint(buf, uint64(id)) + } + return buf +} + +// decodeIDs decodes a sequence of variable-length encoded uint16 IDs from the +// given byte slice and returns them as a set. +// +// Returns an error if the input buffer does not contain a complete Uvarint value. +func decodeIDs(buf []byte) ([]uint16, error) { + var res []uint16 + for len(buf) > 0 { + id, n := binary.Uvarint(buf) + if n <= 0 { + return nil, fmt.Errorf("too short for decoding node id, %v", buf) + } + buf = buf[n:] + res = append(res, uint16(id)) + } + return res, nil +} + +// isAncestor reports whether node x is the ancestor of node y. +func isAncestor(x, y uint16) bool { + for y > x { + y = (y - 1) / 16 // parentID(y) = (y - 1) / 16 + if y == x { + return true + } + } + return false +} + +// isBitSet reports whether the bit at `index` in the byte slice `b` is set. +func isBitSet(b []byte, index int) bool { + return b[index/8]&(1<<(7-index%8)) != 0 +} + +// setBit sets the bit at `index` in the byte slice `b` to 1. +func setBit(b []byte, index int) { + b[index/8] |= 1 << (7 - index%8) +} + +// bitPosTwoBytes returns the positions of set bits in a 2-byte bitmap. +// +// The bitmap is interpreted as a big-endian uint16. Bit positions are +// numbered from 0 to 15, where position 0 corresponds to the most +// significant bit of b[0], and position 15 corresponds to the least +// significant bit of b[1]. +func bitPosTwoBytes(b []byte) []int { + if len(b) != 2 { + panic("expect 2 bytes") + } + var ( + pos []int + mask = binary.BigEndian.Uint16(b) + ) + for mask != 0 { + p := bits.LeadingZeros16(mask) + pos = append(pos, p) + mask &^= 1 << (15 - p) + } + return pos +} diff --git a/triedb/pathdb/history_trienode_utils_test.go b/triedb/pathdb/history_trienode_utils_test.go new file mode 100644 index 0000000000..32bd91166d --- /dev/null +++ b/triedb/pathdb/history_trienode_utils_test.go @@ -0,0 +1,584 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pathdb + +import ( + "bytes" + "reflect" + "testing" +) + +func TestHexPathNodeID(t *testing.T) { + t.Parallel() + + var suites = []struct { + input string + exp uint16 + }{ + { + input: "", + exp: 0, + }, + { + input: string([]byte{0x0}), + exp: 1, + }, + { + input: string([]byte{0xf}), + exp: 16, + }, + { + input: string([]byte{0x0, 0x0}), + exp: 17, + }, + { + input: string([]byte{0x0, 0xf}), + exp: 32, + }, + { + input: string([]byte{0x1, 0x0}), + exp: 33, + }, + { + input: string([]byte{0x1, 0xf}), + exp: 48, + }, + { + input: string([]byte{0xf, 0xf}), + exp: 272, + }, + { + input: string([]byte{0xf, 0xf, 0xf}), + exp: 4368, + }, + } + for _, suite := range suites { + got := hexPathNodeID(suite.input) + if got != suite.exp { + t.Fatalf("Unexpected node ID for %v: got %d, want %d", suite.input, got, suite.exp) + } + } +} + +func TestFindLeafPaths(t *testing.T) { + t.Parallel() + + tests := []struct { + input []string + expect []string + }{ + { + input: nil, + expect: nil, + }, + { + input: []string{"a"}, + expect: []string{"a"}, + }, + { + input: []string{"", "0", "00", "01", "1"}, + expect: []string{ + "00", + "01", + "1", + }, + }, + { + input: []string{"10", "100", "11", "2"}, + expect: []string{ + "100", + "11", + "2", + }, + }, + { + input: []string{"10", "100000000", "11", "111111111", "2"}, + expect: []string{ + "100000000", + "111111111", + "2", + }, + }, + } + for _, test := range tests { + res := findLeafPaths(test.input) + if !reflect.DeepEqual(res, test.expect) { + t.Fatalf("Unexpected result: %v, expected %v", res, test.expect) + } + } +} + +func TestSplitAccountPath(t *testing.T) { + t.Parallel() + + var suites = []struct { + input string + expPrefix []string + expID []uint16 + }{ + // Length = 0 + { + "", nil, nil, + }, + // Length = 1 + { + string([]byte{0x0}), + []string{ + string([]byte{0x0}), + }, + []uint16{ + 0, + }, + }, + { + string([]byte{0x1}), + []string{ + string([]byte{0x1}), + }, + []uint16{ + 0, + }, + }, + { + string([]byte{0xf}), + []string{ + string([]byte{0xf}), + }, + []uint16{ + 0, + }, + }, + // Length = 2 + { + string([]byte{0x0, 0x0}), + []string{ + string([]byte{0x0}), + }, + []uint16{ + 1, + }, + }, + { + string([]byte{0x0, 0x1}), + []string{ + string([]byte{0x0}), + }, + []uint16{ + 2, + }, + }, + { + string([]byte{0x0, 0xf}), + []string{ + string([]byte{0x0}), + }, + []uint16{ + 16, + }, + }, + { + string([]byte{0xf, 0xf}), + []string{ + string([]byte{0xf}), + }, + []uint16{ + 16, + }, + }, + // Length = 3 + { + string([]byte{0x0, 0x0, 0x0}), + []string{ + string([]byte{0x0}), + string([]byte{0x0, 0x0, 0x0}), + }, + []uint16{ + 1, 0, + }, + }, + // Length = 3 + { + string([]byte{0xf, 0xf, 0xf}), + []string{ + string([]byte{0xf}), + string([]byte{0xf, 0xf, 0xf}), + }, + []uint16{ + 16, 0, + }, + }, + // Length = 4 + { + string([]byte{0x0, 0x0, 0x0, 0x0}), + []string{ + string([]byte{0x0}), + string([]byte{0x0, 0x0, 0x0}), + }, + []uint16{ + 1, 1, + }, + }, + { + string([]byte{0xf, 0xf, 0xf, 0xf}), + []string{ + string([]byte{0xf}), + string([]byte{0xf, 0xf, 0xf}), + }, + []uint16{ + 16, 16, + }, + }, + // Length = 5 + { + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0}), + []string{ + string([]byte{0x0}), + string([]byte{0x0, 0x0, 0x0}), + }, + []uint16{ + 1, 17, + }, + }, + { + string([]byte{0xf, 0xf, 0xf, 0xf, 0xf}), + []string{ + string([]byte{0xf}), + string([]byte{0xf, 0xf, 0xf}), + }, + []uint16{ + 16, 272, + }, + }, + // Length = 6 + { + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + []string{ + string([]byte{0x0}), + string([]byte{0x0, 0x0, 0x0}), + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + }, + []uint16{ + 1, 17, 0, + }, + }, + { + string([]byte{0xf, 0xf, 0xf, 0xf, 0xf, 0xf}), + []string{ + string([]byte{0xf}), + string([]byte{0xf, 0xf, 0xf}), + string([]byte{0xf, 0xf, 0xf, 0xf, 0xf, 0xf}), + }, + []uint16{ + 16, 272, 0, + }, + }, + } + for _, suite := range suites { + prefix, id := accountIndexScheme.splitPath(suite.input) + if !reflect.DeepEqual(prefix, suite.expPrefix) { + t.Fatalf("Unexpected prefix for %v: got %v, want %v", suite.input, prefix, suite.expPrefix) + } + if !reflect.DeepEqual(id, suite.expID) { + t.Fatalf("Unexpected ID for %v: got %v, want %v", suite.input, id, suite.expID) + } + } +} + +func TestSplitStoragePath(t *testing.T) { + t.Parallel() + + var suites = []struct { + input string + expPrefix []string + expID []uint16 + }{ + // Length = 0 + { + "", + []string{ + string([]byte{}), + }, + []uint16{ + 0, + }, + }, + // Length = 1 + { + string([]byte{0x0}), + []string{ + string([]byte{}), + }, + []uint16{ + 1, + }, + }, + { + string([]byte{0x1}), + []string{ + string([]byte{}), + }, + []uint16{ + 2, + }, + }, + { + string([]byte{0xf}), + []string{ + string([]byte{}), + }, + []uint16{ + 16, + }, + }, + // Length = 2 + { + string([]byte{0x0, 0x0}), + []string{ + string([]byte{}), + }, + []uint16{ + 17, + }, + }, + { + string([]byte{0x0, 0x1}), + []string{ + string([]byte{}), + }, + []uint16{ + 18, + }, + }, + { + string([]byte{0x0, 0xf}), + []string{ + string([]byte{}), + }, + []uint16{ + 32, + }, + }, + { + string([]byte{0xf, 0xf}), + []string{ + string([]byte{}), + }, + []uint16{ + 272, + }, + }, + // Length = 3 + { + string([]byte{0x0, 0x0, 0x0}), + []string{ + string([]byte{}), + string([]byte{0x0, 0x0, 0x0}), + }, + []uint16{ + 17, 0, + }, + }, + // Length = 3 + { + string([]byte{0xf, 0xf, 0xf}), + []string{ + string([]byte{}), + string([]byte{0xf, 0xf, 0xf}), + }, + []uint16{ + 272, 0, + }, + }, + // Length = 4 + { + string([]byte{0x0, 0x0, 0x0, 0x0}), + []string{ + string([]byte{}), + string([]byte{0x0, 0x0, 0x0}), + }, + []uint16{ + 17, 1, + }, + }, + { + string([]byte{0xf, 0xf, 0xf, 0xf}), + []string{ + string([]byte{}), + string([]byte{0xf, 0xf, 0xf}), + }, + []uint16{ + 272, 16, + }, + }, + // Length = 5 + { + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0}), + []string{ + string([]byte{}), + string([]byte{0x0, 0x0, 0x0}), + }, + []uint16{ + 17, 17, + }, + }, + { + string([]byte{0xf, 0xf, 0xf, 0xf, 0xf}), + []string{ + string([]byte{}), + string([]byte{0xf, 0xf, 0xf}), + }, + []uint16{ + 272, 272, + }, + }, + // Length = 6 + { + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + []string{ + string([]byte{}), + string([]byte{0x0, 0x0, 0x0}), + string([]byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0}), + }, + []uint16{ + 17, 17, 0, + }, + }, + { + string([]byte{0xf, 0xf, 0xf, 0xf, 0xf, 0xf}), + []string{ + string([]byte{}), + string([]byte{0xf, 0xf, 0xf}), + string([]byte{0xf, 0xf, 0xf, 0xf, 0xf, 0xf}), + }, + []uint16{ + 272, 272, 0, + }, + }, + } + for i, suite := range suites { + prefix, id := storageIndexScheme.splitPath(suite.input) + if !reflect.DeepEqual(prefix, suite.expPrefix) { + t.Fatalf("Test %d, unexpected prefix for %v: got %v, want %v", i, suite.input, prefix, suite.expPrefix) + } + if !reflect.DeepEqual(id, suite.expID) { + t.Fatalf("Test %d, unexpected ID for %v: got %v, want %v", i, suite.input, id, suite.expID) + } + } +} + +func TestIsAncestor(t *testing.T) { + suites := []struct { + x, y uint16 + want bool + }{ + {0, 1, true}, + {0, 16, true}, + {0, 17, true}, + {0, 272, true}, + + {1, 0, false}, + {1, 2, false}, + {1, 17, true}, + {1, 18, true}, + {17, 273, true}, + {1, 1, false}, + } + for _, tc := range suites { + result := isAncestor(tc.x, tc.y) + if result != tc.want { + t.Fatalf("isAncestor(%d, %d) = %v, want %v", tc.x, tc.y, result, tc.want) + } + } +} + +func TestBitmapSet(t *testing.T) { + suites := []struct { + index int + expect []byte + }{ + { + 0, []byte{0b10000000, 0x0}, + }, + { + 1, []byte{0b01000000, 0x0}, + }, + { + 7, []byte{0b00000001, 0x0}, + }, + { + 8, []byte{0b00000000, 0b10000000}, + }, + { + 15, []byte{0b00000000, 0b00000001}, + }, + } + for _, tc := range suites { + var buf [2]byte + setBit(buf[:], tc.index) + + if !bytes.Equal(buf[:], tc.expect) { + t.Fatalf("bitmap = %v, want %v", buf, tc.expect) + } + if !isBitSet(buf[:], tc.index) { + t.Fatal("bit is not set") + } + } +} + +func TestBitPositions(t *testing.T) { + suites := []struct { + input []byte + expect []int + }{ + { + []byte{0b10000000, 0x0}, []int{0}, + }, + { + []byte{0b01000000, 0x0}, []int{1}, + }, + { + []byte{0b00000001, 0x0}, []int{7}, + }, + { + []byte{0b00000000, 0b10000000}, []int{8}, + }, + { + []byte{0b00000000, 0b00000001}, []int{15}, + }, + { + []byte{0b10000000, 0b00000001}, []int{0, 15}, + }, + { + []byte{0b10000001, 0b00000001}, []int{0, 7, 15}, + }, + { + []byte{0b10000001, 0b10000001}, []int{0, 7, 8, 15}, + }, + { + []byte{0b11111111, 0b11111111}, []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + }, + { + []byte{0x0, 0x0}, nil, + }, + } + for _, tc := range suites { + got := bitPosTwoBytes(tc.input) + if !reflect.DeepEqual(got, tc.expect) { + t.Fatalf("Unexpected position set, want: %v, got: %v", tc.expect, got) + } + } +} diff --git a/triedb/pathdb/iterator.go b/triedb/pathdb/iterator.go index 84ea08ddd3..8ca8247206 100644 --- a/triedb/pathdb/iterator.go +++ b/triedb/pathdb/iterator.go @@ -309,7 +309,7 @@ type diskStorageIterator struct { it ethdb.Iterator } -// StorageIterator creates a storage iterator over the persistent state. +// newDiskStorageIterator creates a storage iterator over the persistent state. func newDiskStorageIterator(db ethdb.KeyValueStore, account common.Hash, seek common.Hash) StorageIterator { pos := common.TrimRightZeroes(seek[:]) return &diskStorageIterator{ diff --git a/triedb/pathdb/journal.go b/triedb/pathdb/journal.go index 4639932763..efcc3f2549 100644 --- a/triedb/pathdb/journal.go +++ b/triedb/pathdb/journal.go @@ -229,7 +229,7 @@ func (db *Database) loadDiffLayer(parent layer, r *rlp.Stream) (layer, error) { return nil, fmt.Errorf("load block number: %v", err) } // Read in-memory trie nodes from journal - var nodes nodeSet + var nodes nodeSetWithOrigin if err := nodes.decode(r); err != nil { return nil, err } @@ -267,7 +267,7 @@ func (dl *diskLayer) journal(w io.Writer) error { if err := dl.buffer.states.encode(w); err != nil { return err } - log.Debug("Journaled pathdb disk layer", "root", dl.root) + log.Debug("Journaled pathdb disk layer", "root", dl.root, "id", dl.id) return nil } @@ -333,7 +333,14 @@ func (db *Database) Journal(root common.Hash) error { if db.readOnly { return errDatabaseReadOnly } - + // Forcibly sync the ancient store before persisting the in-memory layers. + // This prevents an edge case where the in-memory layers are persisted + // but the ancient store is not properly closed, resulting in recent writes + // being lost. After a restart, the ancient store would then be misaligned + // with the disk layer, causing data corruption. + if err := syncHistory(db.stateFreezer, db.trienodeFreezer); err != nil { + return err + } // Store the journal into the database and return var ( file *os.File diff --git a/triedb/pathdb/layertree.go b/triedb/pathdb/layertree.go index b2f3f7f37d..ec45257db5 100644 --- a/triedb/pathdb/layertree.go +++ b/triedb/pathdb/layertree.go @@ -22,7 +22,6 @@ import ( "sync" "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/trie/trienode" ) // layerTree is a group of state layers identified by the state root. @@ -142,7 +141,7 @@ func (tree *layerTree) len() int { } // add inserts a new layer into the tree if it can be linked to an existing old parent. -func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint64, nodes *trienode.MergedNodeSet, states *StateSetWithOrigin) error { +func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint64, nodes *nodeSetWithOrigin, states *StateSetWithOrigin) error { // Reject noop updates to avoid self-loops. This is a special case that can // happen for clique networks and proof-of-stake networks where empty blocks // don't modify the state (0 block subsidy). @@ -156,7 +155,7 @@ func (tree *layerTree) add(root common.Hash, parentRoot common.Hash, block uint6 if parent == nil { return fmt.Errorf("triedb parent [%#x] layer missing", parentRoot) } - l := parent.update(root, parent.stateID()+1, block, newNodeSet(nodes.Flatten()), states) + l := parent.update(root, parent.stateID()+1, block, nodes, states) tree.lock.Lock() defer tree.lock.Unlock() diff --git a/triedb/pathdb/layertree_test.go b/triedb/pathdb/layertree_test.go index a76d60ba5b..a74c6eb045 100644 --- a/triedb/pathdb/layertree_test.go +++ b/triedb/pathdb/layertree_test.go @@ -22,7 +22,6 @@ import ( "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/rawdb" - "github.com/ethereum/go-ethereum/trie/trienode" ) func newTestLayerTree() *layerTree { @@ -45,9 +44,9 @@ func TestLayerCap(t *testing.T) { // C1->C2->C3->C4 (HEAD) init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, // Chain: @@ -66,9 +65,9 @@ func TestLayerCap(t *testing.T) { // C1->C2->C3->C4 (HEAD) init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, // Chain: @@ -86,9 +85,9 @@ func TestLayerCap(t *testing.T) { // C1->C2->C3->C4 (HEAD) init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, // Chain: @@ -106,12 +105,12 @@ func TestLayerCap(t *testing.T) { // ->C2'->C3'->C4' init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, // Chain: @@ -131,12 +130,12 @@ func TestLayerCap(t *testing.T) { // ->C2'->C3'->C4' init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, // Chain: @@ -155,11 +154,11 @@ func TestLayerCap(t *testing.T) { // ->C3'->C4' init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, // Chain: @@ -213,8 +212,8 @@ func TestBaseLayer(t *testing.T) { // C1->C2->C3 (HEAD) { func() { - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) }, common.Hash{0x1}, }, @@ -230,9 +229,9 @@ func TestBaseLayer(t *testing.T) { // C4->C5->C6 (HEAD) { func() { - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x5}, common.Hash{0x4}, 4, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x6}, common.Hash{0x5}, 5, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x5}, common.Hash{0x4}, 4, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x6}, common.Hash{0x5}, 5, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) tr.cap(common.Hash{0x6}, 2) }, common.Hash{0x4}, @@ -258,7 +257,7 @@ func TestDescendant(t *testing.T) { // C1->C2 (HEAD) init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, snapshotA: map[common.Hash]map[common.Hash]struct{}{ @@ -269,7 +268,7 @@ func TestDescendant(t *testing.T) { // Chain: // C1->C2->C3 (HEAD) op: func(tr *layerTree) { - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) }, snapshotB: map[common.Hash]map[common.Hash]struct{}{ common.Hash{0x1}: { @@ -286,9 +285,9 @@ func TestDescendant(t *testing.T) { // C1->C2->C3->C4 (HEAD) init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, snapshotA: map[common.Hash]map[common.Hash]struct{}{ @@ -325,9 +324,9 @@ func TestDescendant(t *testing.T) { // C1->C2->C3->C4 (HEAD) init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, snapshotA: map[common.Hash]map[common.Hash]struct{}{ @@ -360,9 +359,9 @@ func TestDescendant(t *testing.T) { // C1->C2->C3->C4 (HEAD) init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, snapshotA: map[common.Hash]map[common.Hash]struct{}{ @@ -392,12 +391,12 @@ func TestDescendant(t *testing.T) { // ->C2'->C3'->C4' init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, snapshotA: map[common.Hash]map[common.Hash]struct{}{ @@ -445,12 +444,12 @@ func TestDescendant(t *testing.T) { // ->C2'->C3'->C4' init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2a}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2a}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2b}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2b}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, snapshotA: map[common.Hash]map[common.Hash]struct{}{ @@ -494,11 +493,11 @@ func TestDescendant(t *testing.T) { // ->C3'->C4' init: func() *layerTree { tr := newTestLayerTree() - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) - tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, trienode.NewMergedNodeSet(), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3a}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4a}, common.Hash{0x3a}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x3b}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) + tr.add(common.Hash{0x4b}, common.Hash{0x3b}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(nil, nil, nil, nil, false)) return tr }, snapshotA: map[common.Hash]map[common.Hash]struct{}{ @@ -580,11 +579,11 @@ func TestAccountLookup(t *testing.T) { // Chain: // C1->C2->C3->C4 (HEAD) tr := newTestLayerTree() // base = 0x1 - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(randomAccountSet("0xa"), nil, nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(randomAccountSet("0xb"), nil, nil, nil, false)) - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(randomAccountSet("0xa", "0xc"), nil, nil, nil, false)) var cases = []struct { @@ -734,11 +733,11 @@ func TestStorageLookup(t *testing.T) { // Chain: // C1->C2->C3->C4 (HEAD) tr := newTestLayerTree() // base = 0x1 - tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, trienode.NewMergedNodeSet(), + tr.add(common.Hash{0x2}, common.Hash{0x1}, 1, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x1"}}, nil), nil, nil, false)) - tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, trienode.NewMergedNodeSet(), + tr.add(common.Hash{0x3}, common.Hash{0x2}, 2, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x2"}}, nil), nil, nil, false)) - tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, trienode.NewMergedNodeSet(), + tr.add(common.Hash{0x4}, common.Hash{0x3}, 3, NewNodeSetWithOrigin(nil, nil), NewStateSetWithOrigin(randomAccountSet("0xa"), randomStorageSet([]string{"0xa"}, [][]string{{"0x1", "0x3"}}, nil), nil, nil, false)) var cases = []struct { diff --git a/triedb/pathdb/lookup.go b/triedb/pathdb/lookup.go index 8b092730f8..719546f410 100644 --- a/triedb/pathdb/lookup.go +++ b/triedb/pathdb/lookup.go @@ -33,6 +33,13 @@ func storageKey(accountHash common.Hash, slotHash common.Hash) [64]byte { return key } +// storageKeySlice returns a key for uniquely identifying the storage slot in +// the slice format. +func storageKeySlice(accountHash common.Hash, slotHash common.Hash) []byte { + key := storageKey(accountHash, slotHash) + return key[:] +} + // lookup is an internal structure used to efficiently determine the layer in // which a state entry resides. type lookup struct { diff --git a/triedb/pathdb/metrics.go b/triedb/pathdb/metrics.go index 779f9d813f..a0a626f9b5 100644 --- a/triedb/pathdb/metrics.go +++ b/triedb/pathdb/metrics.go @@ -69,18 +69,25 @@ var ( gcStorageMeter = metrics.NewRegisteredMeter("pathdb/gc/storage/count", nil) gcStorageBytesMeter = metrics.NewRegisteredMeter("pathdb/gc/storage/bytes", nil) - historyBuildTimeMeter = metrics.NewRegisteredResettingTimer("pathdb/history/time", nil) - historyDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/data", nil) - historyIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/bytes/index", nil) + stateHistoryBuildTimeMeter = metrics.NewRegisteredResettingTimer("pathdb/history/state/time", nil) + stateHistoryDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/state/bytes/data", nil) + stateHistoryIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/state/bytes/index", nil) - indexHistoryTimer = metrics.NewRegisteredResettingTimer("pathdb/history/index/time", nil) - unindexHistoryTimer = metrics.NewRegisteredResettingTimer("pathdb/history/unindex/time", nil) + trienodeHistoryBuildTimeMeter = metrics.NewRegisteredResettingTimer("pathdb/history/trienode/time", nil) + trienodeHistoryDataBytesMeter = metrics.NewRegisteredMeter("pathdb/history/trienode/bytes/data", nil) + trienodeHistoryIndexBytesMeter = metrics.NewRegisteredMeter("pathdb/history/trienode/bytes/index", nil) + + stateIndexHistoryTimer = metrics.NewRegisteredResettingTimer("pathdb/history/state/index/time", nil) + stateUnindexHistoryTimer = metrics.NewRegisteredResettingTimer("pathdb/history/state/unindex/time", nil) + trienodeIndexHistoryTimer = metrics.NewRegisteredResettingTimer("pathdb/history/trienode/index/time", nil) + trienodeUnindexHistoryTimer = metrics.NewRegisteredResettingTimer("pathdb/history/trienode/unindex/time", nil) lookupAddLayerTimer = metrics.NewRegisteredResettingTimer("pathdb/lookup/add/time", nil) lookupRemoveLayerTimer = metrics.NewRegisteredResettingTimer("pathdb/lookup/remove/time", nil) - historicalAccountReadTimer = metrics.NewRegisteredResettingTimer("pathdb/history/account/reads", nil) - historicalStorageReadTimer = metrics.NewRegisteredResettingTimer("pathdb/history/storage/reads", nil) + historicalAccountReadTimer = metrics.NewRegisteredResettingTimer("pathdb/history/account/reads", nil) + historicalStorageReadTimer = metrics.NewRegisteredResettingTimer("pathdb/history/storage/reads", nil) + historicalTrienodeReadTimer = metrics.NewRegisteredResettingTimer("pathdb/history/trienode/reads", nil) ) // Metrics in generation diff --git a/triedb/pathdb/nodes.go b/triedb/pathdb/nodes.go index f90bd0f01c..62c72c1953 100644 --- a/triedb/pathdb/nodes.go +++ b/triedb/pathdb/nodes.go @@ -14,11 +14,14 @@ // You should have received a copy of the GNU Lesser General Public License // along with the go-ethereum library. If not, see . +// nolint:unused package pathdb import ( "bytes" + "errors" "fmt" + "hash/fnv" "io" "maps" @@ -29,6 +32,7 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/trie/trienode" ) @@ -301,3 +305,387 @@ func (s *nodeSet) dbsize() int { } return m + int(s.size) } + +// nodeSetWithOrigin wraps the node set with additional original values of the +// mutated trie nodes. +type nodeSetWithOrigin struct { + *nodeSet + + // nodeOrigin represents the trie nodes before the state transition. It's keyed + // by the account address hash and node path. The nil value means the trie node + // was not present. + nodeOrigin map[common.Hash]map[string][]byte + + // memory size of the state data (accountNodeOrigin and storageNodeOrigin) + size uint64 +} + +// NewNodeSetWithOrigin constructs the state set with the provided data. +func NewNodeSetWithOrigin(nodes map[common.Hash]map[string]*trienode.Node, origins map[common.Hash]map[string][]byte) *nodeSetWithOrigin { + // Don't panic for the lazy callers, initialize the nil maps instead. + if origins == nil { + origins = make(map[common.Hash]map[string][]byte) + } + set := &nodeSetWithOrigin{ + nodeSet: newNodeSet(nodes), + nodeOrigin: origins, + } + set.computeSize() + return set +} + +// computeSize calculates the database size of the held trie nodes. +func (s *nodeSetWithOrigin) computeSize() { + var size int + for owner, slots := range s.nodeOrigin { + prefixLen := common.HashLength + if owner == (common.Hash{}) { + prefixLen = 0 + } + for path, data := range slots { + size += prefixLen + len(path) + len(data) + } + } + s.size = s.nodeSet.size + uint64(size) +} + +// encode serializes the content of node set into the provided writer. +func (s *nodeSetWithOrigin) encode(w io.Writer) error { + // Encode node set + if err := s.nodeSet.encode(w); err != nil { + return err + } + // Short circuit if the origins are not tracked + if len(s.nodeOrigin) == 0 { + return nil + } + + // Encode node origins + nodes := make([]journalNodes, 0, len(s.nodeOrigin)) + for owner, subset := range s.nodeOrigin { + entry := journalNodes{ + Owner: owner, + Nodes: make([]journalNode, 0, len(subset)), + } + for path, node := range subset { + entry.Nodes = append(entry.Nodes, journalNode{ + Path: []byte(path), + Blob: node, + }) + } + nodes = append(nodes, entry) + } + return rlp.Encode(w, nodes) +} + +// hasOrigin returns whether the origin data set exists in the rlp stream. +// It's a workaround for backward compatibility. +func (s *nodeSetWithOrigin) hasOrigin(r *rlp.Stream) (bool, error) { + kind, _, err := r.Kind() + if err != nil { + if errors.Is(err, io.EOF) { + return false, nil + } + return false, err + } + // If the type of next element in the RLP stream is: + // - `rlp.List`: represents the original value of trienodes; + // - others, like `boolean`: represent a field in the following state data set; + return kind == rlp.List, nil +} + +// decode deserializes the content from the rlp stream into the node set. +func (s *nodeSetWithOrigin) decode(r *rlp.Stream) error { + if s.nodeSet == nil { + s.nodeSet = &nodeSet{} + } + if err := s.nodeSet.decode(r); err != nil { + return err + } + + // Decode node origins + s.nodeOrigin = make(map[common.Hash]map[string][]byte) + if hasOrigin, err := s.hasOrigin(r); err != nil { + return err + } else if hasOrigin { + var encoded []journalNodes + if err := r.Decode(&encoded); err != nil { + return fmt.Errorf("load nodes: %v", err) + } + for _, entry := range encoded { + subset := make(map[string][]byte, len(entry.Nodes)) + for _, n := range entry.Nodes { + if len(n.Blob) > 0 { + subset[string(n.Path)] = n.Blob + } else { + subset[string(n.Path)] = nil + } + } + s.nodeOrigin[entry.Owner] = subset + } + } + s.computeSize() + return nil +} + +// encodeNodeCompressed encodes the trie node differences between two consecutive +// versions into byte stream. The format is as below: +// +// - metadata byte layout (1 byte): +// +// ┌──── Bits (from MSB to LSB) ───┐ +// │ 7 │ 6 │ 5 │ 4 │ 3 │ 2 │ 1 │ 0 │ +// └───────────────────────────────┘ +// │ │ │ │ │ │ │ └─ FlagA: set if value is encoded in compressed format +// │ │ │ │ │ │ └───── FlagB: set if no extended bitmap is present after the metadata byte +// │ │ │ │ │ └───────── FlagC: bitmap for node (only used when flagB == 1) +// │ │ │ │ └───────────── FlagD: bitmap for node (only used when flagB == 1) +// │ │ │ └───────────────── FlagE: reserved (marks the presence of the 16th child in a full node) +// │ │ └───────────────────── FlagF: reserved +// │ └───────────────────────── FlagG: reserved +// └───────────────────────────── FlagH: reserved +// +// Note: +// - If flagB is 1, the node refers to a shortNode; +// - flagC indicates whether the key of the shortNode is recorded. +// - flagD indicates whether the value of the shortNode is recorded. +// +// - If flagB is 0, the node refers to a fullNode; +// - each bit in extended bitmap indicates whether the corresponding +// child have been modified. +// +// Example: +// +// 0b_0000_1011 +// +// Bit0=1, Bit1=1 -> node in compressed format, no extended bitmap +// Bit2=0, Bit3=1 -> the key of a short node is not stored; its value is stored. +// +// - 2 bytes extended bitmap (only if the flagB in metadata is 0), each bit +// represents a corresponding child; +// +// - concatenation of original value of modified children along with its size; +func encodeNodeCompressed(addExtension bool, elements [][]byte, indices []int) []byte { + var ( + enc []byte + flag = byte(1) // The compression format indicator + ) + // Pre-allocate the byte slice for the node encoder + size := 1 + if addExtension { + size += 2 + } + for _, element := range elements { + size += len(element) + 1 + } + enc = make([]byte, 0, size) + + if !addExtension { + flag |= 2 // The embedded bitmap indicator + + // Embedded bitmap + for _, pos := range indices { + flag |= 1 << (pos + 2) + } + enc = append(enc, flag) + } else { + // Extended bitmap + bitmap := make([]byte, 2) // bitmaps for at most 16 children + for _, pos := range indices { + // Children[16] is only theoretically possible in the Merkle-Patricia-trie, + // in practice this field is never used in the Ethereum case. If it occurs, + // use the FlagE for marking the presence. + if pos >= 16 { + log.Warn("Unexpected 16th child encountered in a full node") + flag |= 1 << 4 // Use the reserved flagE + continue + } + setBit(bitmap, pos) + } + enc = append(enc, flag) + enc = append(enc, bitmap...) + } + for _, element := range elements { + enc = append(enc, byte(len(element))) // 1 byte is sufficient for element size + enc = append(enc, element...) + } + return enc +} + +// encodeNodeFull encodes the full trie node value into byte stream. The format is +// as below: +// +// - metadata byte layout (1 byte): 0b0 +// - node value +// +// TODO(rjl493456442) it's not allocation efficient, please improve it. +func encodeNodeFull(value []byte) []byte { + enc := make([]byte, len(value)+1) + copy(enc[1:], value) + return enc +} + +// decodeNodeCompressed decodes the byte stream of compressed trie node +// back to the original elements and their indices. +// +// It assumes the byte stream contains a compressed format node. +func decodeNodeCompressed(data []byte) ([][]byte, []int, error) { + if len(data) < 1 { + return nil, nil, errors.New("invalid data: too short") + } + flag := data[0] + if flag&byte(1) == 0 { + return nil, nil, errors.New("invalid data: full node value") + } + noExtend := flag&byte(2) != 0 + + // Reconstruct indices from bitmap + var indices []int + if noExtend { + if flag&byte(4) != 0 { // flagC + indices = append(indices, 0) + } + if flag&byte(8) != 0 { // flagD + indices = append(indices, 1) + } + data = data[1:] + } else { + if len(data) < 3 { + return nil, nil, errors.New("invalid data: too short") + } + bitmap := data[1:3] + indices = bitPosTwoBytes(bitmap) + if flag&byte(16) != 0 { // flagE + indices = append(indices, 16) + log.Info("Unexpected 16th child encountered in a full node") + } + data = data[3:] + } + // Reconstruct elements + elements := make([][]byte, 0, len(indices)) + for i := 0; i < len(indices); i++ { + if len(data) == 0 { + return nil, nil, errors.New("invalid data: missing size byte") + } + // Read element size + size := int(data[0]) + data = data[1:] + + // Check if we have enough data for the element + if len(data) < size { + return nil, nil, fmt.Errorf("invalid data: expected %d bytes, got %d", size, len(data)) + } + // Extract element + if size == 0 { + elements = append(elements, nil) + + // The zero-size element is practically unexpected, for node deletion + // the rlp.EmptyString is still expected. Log loudly for the potential + // programming error. + log.Error("Empty element from compressed node, please open an issue", "raw", data) + } else { + element := make([]byte, size) + copy(element, data[:size]) + data = data[size:] + elements = append(elements, element) + } + } + // Check if all data is consumed + if len(data) != 0 { + return nil, nil, errors.New("invalid data: trailing bytes") + } + return elements, indices, nil +} + +// decodeNodeFull decodes the byte stream of full value trie node. +func decodeNodeFull(data []byte) (bool, []byte, error) { + if len(data) < 1 { + return false, nil, errors.New("invalid data: too short") + } + flag := data[0] + if flag != byte(0) { + return false, nil, nil + } + return true, data[1:], nil +} + +// encodeNodeHistory encodes the history of a node. Typically, the original values +// of dirty nodes serve as the history, but this can lead to significant storage +// overhead. +// +// For full nodes, which often see only a few modified children during state +// transitions, recording the entire child set (up to 16 children at 32 bytes +// each) is inefficient. For short nodes, which often see only the value is +// modified during the state transition, recording the key part is also unnecessary. +// To compress size, we instead record the diff of the node, rather than the +// full value. It's vital to compress the overall trienode history. +// +// However, recovering a node from a series of diffs requires applying multiple +// history records, which is computationally and IO intensive. To mitigate this, we +// periodically record the full value of a node as a checkpoint. The frequency of +// these checkpoints is a tradeoff between the compression rate and read overhead. +func (s *nodeSetWithOrigin) encodeNodeHistory(root common.Hash, rate uint32) (map[common.Hash]map[string][]byte, error) { + var ( + // the set of all encoded node history elements + nodes = make(map[common.Hash]map[string][]byte) + + // encodeFullValue determines whether a node should be encoded + // in full format with a pseudo-random probabilistic algorithm. + encodeFullValue = func(owner common.Hash, path string) bool { + // For trie nodes at the first two levels of the account trie, it is very + // likely that all children are modified within a single state transition. + // In such cases, do not use diff mode. + if owner == (common.Hash{}) && len(path) < 2 { + return true + } + h := fnv.New32a() + h.Write(root.Bytes()) + h.Write(owner.Bytes()) + h.Write([]byte(path)) + return h.Sum32()%rate == 0 + } + ) + for owner, origins := range s.nodeOrigin { + var posts map[string]*trienode.Node + if owner == (common.Hash{}) { + posts = s.nodeSet.accountNodes + } else { + posts = s.nodeSet.storageNodes[owner] + } + nodes[owner] = make(map[string][]byte) + + for path, oldvalue := range origins { + n, exists := posts[path] + if !exists { + // something not expected + return nil, fmt.Errorf("node with origin is not found, %x-%v", owner, []byte(path)) + } + encodeFull := encodeFullValue(owner, path) + if !encodeFull { + // TODO(rjl493456442) the diff-mode reencoding can take non-trivial + // time, like 1-2ms per block, is there any way to mitigate the overhead? + + // Partial encoding is required, try to find the node diffs and + // fallback to the full-value encoding if fails. + // + // The partial encoding will be failed in these certain cases: + // - the node is deleted or was not-existent; + // - the node type has been changed (e.g, from short to full) + nElem, indices, diffs, err := trie.NodeDifference(oldvalue, n.Blob) + if err != nil { + encodeFull = true // fallback to the full node encoding + } else { + // Encode the node difference as the history element + addExt := nElem != 2 // fullNode + blob := encodeNodeCompressed(addExt, diffs, indices) + nodes[owner][path] = blob + } + } + if encodeFull { + // Encode the entire original value as the history element + nodes[owner][path] = encodeNodeFull(oldvalue) + } + } + } + return nodes, nil +} diff --git a/triedb/pathdb/nodes_test.go b/triedb/pathdb/nodes_test.go new file mode 100644 index 0000000000..131d0ab012 --- /dev/null +++ b/triedb/pathdb/nodes_test.go @@ -0,0 +1,176 @@ +// Copyright 2025 The go-ethereum Authors +// This file is part of the go-ethereum library. +// +// The go-ethereum library is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// The go-ethereum library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with the go-ethereum library. If not, see . + +package pathdb + +import ( + "bytes" + "math/rand" + "reflect" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/internal/testrand" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/trie/trienode" +) + +func TestNodeSetEncode(t *testing.T) { + nodes := make(map[common.Hash]map[string]*trienode.Node) + nodes[common.Hash{}] = map[string]*trienode.Node{ + "": trienode.New(crypto.Keccak256Hash([]byte{0x0}), []byte{0x0}), + "1": trienode.New(crypto.Keccak256Hash([]byte{0x1}), []byte{0x1}), + "2": trienode.New(crypto.Keccak256Hash([]byte{0x2}), []byte{0x2}), + } + nodes[common.Hash{0x1}] = map[string]*trienode.Node{ + "": trienode.New(crypto.Keccak256Hash([]byte{0x0}), []byte{0x0}), + "1": trienode.New(crypto.Keccak256Hash([]byte{0x1}), []byte{0x1}), + "2": trienode.New(crypto.Keccak256Hash([]byte{0x2}), []byte{0x2}), + } + s := newNodeSet(nodes) + + buf := bytes.NewBuffer(nil) + if err := s.encode(buf); err != nil { + t.Fatalf("Failed to encode states, %v", err) + } + var dec nodeSet + if err := dec.decode(rlp.NewStream(buf, 0)); err != nil { + t.Fatalf("Failed to decode states, %v", err) + } + if !reflect.DeepEqual(s.accountNodes, dec.accountNodes) { + t.Fatal("Unexpected account data") + } + if !reflect.DeepEqual(s.storageNodes, dec.storageNodes) { + t.Fatal("Unexpected storage data") + } +} + +func TestNodeSetWithOriginEncode(t *testing.T) { + nodes := make(map[common.Hash]map[string]*trienode.Node) + nodes[common.Hash{}] = map[string]*trienode.Node{ + "": trienode.New(crypto.Keccak256Hash([]byte{0x0}), []byte{0x0}), + "1": trienode.New(crypto.Keccak256Hash([]byte{0x1}), []byte{0x1}), + "2": trienode.New(crypto.Keccak256Hash([]byte{0x2}), []byte{0x2}), + } + nodes[common.Hash{0x1}] = map[string]*trienode.Node{ + "": trienode.New(crypto.Keccak256Hash([]byte{0x0}), []byte{0x0}), + "1": trienode.New(crypto.Keccak256Hash([]byte{0x1}), []byte{0x1}), + "2": trienode.New(crypto.Keccak256Hash([]byte{0x2}), []byte{0x2}), + } + origins := make(map[common.Hash]map[string][]byte) + origins[common.Hash{}] = map[string][]byte{ + "": nil, + "1": {0x1}, + "2": {0x2}, + } + origins[common.Hash{0x1}] = map[string][]byte{ + "": nil, + "1": {0x1}, + "2": {0x2}, + } + + // Encode with origin set + s := NewNodeSetWithOrigin(nodes, origins) + + buf := bytes.NewBuffer(nil) + if err := s.encode(buf); err != nil { + t.Fatalf("Failed to encode states, %v", err) + } + var dec nodeSetWithOrigin + if err := dec.decode(rlp.NewStream(buf, 0)); err != nil { + t.Fatalf("Failed to decode states, %v", err) + } + if !reflect.DeepEqual(s.accountNodes, dec.accountNodes) { + t.Fatal("Unexpected account data") + } + if !reflect.DeepEqual(s.storageNodes, dec.storageNodes) { + t.Fatal("Unexpected storage data") + } + if !reflect.DeepEqual(s.nodeOrigin, dec.nodeOrigin) { + t.Fatal("Unexpected node origin data") + } + + // Encode without origin set + s = NewNodeSetWithOrigin(nodes, nil) + + buf = bytes.NewBuffer(nil) + if err := s.encode(buf); err != nil { + t.Fatalf("Failed to encode states, %v", err) + } + var dec2 nodeSetWithOrigin + if err := dec2.decode(rlp.NewStream(buf, 0)); err != nil { + t.Fatalf("Failed to decode states, %v", err) + } + if !reflect.DeepEqual(s.accountNodes, dec2.accountNodes) { + t.Fatal("Unexpected account data") + } + if !reflect.DeepEqual(s.storageNodes, dec2.storageNodes) { + t.Fatal("Unexpected storage data") + } + if len(dec2.nodeOrigin) != 0 { + t.Fatal("unexpected node origin data") + } + if dec2.size != s.size { + t.Fatalf("Unexpected data size, got: %d, want: %d", dec2.size, s.size) + } +} + +func TestEncodeFullNodeCompressed(t *testing.T) { + var ( + elements [][]byte + indices []int + ) + for i := 0; i <= 16; i++ { + if rand.Intn(2) == 0 { + elements = append(elements, testrand.Bytes(20)) + indices = append(indices, i) + } + } + enc := encodeNodeCompressed(true, elements, indices) + decElements, decIndices, err := decodeNodeCompressed(enc) + if err != nil { + t.Fatalf("Failed to decode node compressed, %v", err) + } + if !reflect.DeepEqual(elements, decElements) { + t.Fatalf("Elements are not matched") + } + if !reflect.DeepEqual(indices, decIndices) { + t.Fatalf("Indices are not matched") + } +} + +func TestEncodeShortNodeCompressed(t *testing.T) { + var ( + elements [][]byte + indices []int + ) + for i := 0; i < 2; i++ { + elements = append(elements, testrand.Bytes(20)) + indices = append(indices, i) + } + enc := encodeNodeCompressed(false, elements, indices) + decElements, decIndices, err := decodeNodeCompressed(enc) + if err != nil { + t.Fatalf("Failed to decode node compressed, %v", err) + } + if !reflect.DeepEqual(elements, decElements) { + t.Fatalf("Elements are not matched") + } + if !reflect.DeepEqual(indices, decIndices) { + t.Fatalf("Indices are not matched") + } +} diff --git a/triedb/pathdb/reader.go b/triedb/pathdb/reader.go index b7b18f13f9..f55e015ee6 100644 --- a/triedb/pathdb/reader.go +++ b/triedb/pathdb/reader.go @@ -200,37 +200,41 @@ func (db *Database) StateReader(root common.Hash) (database.StateReader, error) // historical state. type HistoricalStateReader struct { db *Database - reader *historyReader + reader *stateHistoryReader id uint64 } // HistoricReader constructs a reader for accessing the requested historic state. func (db *Database) HistoricReader(root common.Hash) (*HistoricalStateReader, error) { // Bail out if the state history hasn't been fully indexed - if db.indexer == nil || !db.indexer.inited() { + if db.stateIndexer == nil || db.stateFreezer == nil { + return nil, fmt.Errorf("historical state %x is not available", root) + } + if !db.stateIndexer.inited() { return nil, errors.New("state histories haven't been fully indexed yet") } - if db.freezer == nil { - return nil, errors.New("state histories are not available") - } - // States at the current disk layer or above are directly accessible via - // db.StateReader. + // - States at the current disk layer or above are directly accessible + // via `db.StateReader`. // - // States older than the current disk layer (including the disk layer - // itself) are available through historic state access. - // - // Note: the requested state may refer to a stale historic state that has - // already been pruned. This function does not validate availability, as - // underlying states may be pruned dynamically. Validity is checked during - // each actual state retrieval. + // - States older than the current disk layer (including the disk layer + // itself) are available via `db.HistoricReader`. id := rawdb.ReadStateID(db.diskdb, root) if id == nil { return nil, fmt.Errorf("state %#x is not available", root) } + // Ensure the requested state is canonical, historical states on side chain + // are not accessible. + meta, err := readStateHistoryMeta(db.stateFreezer, *id+1) + if err != nil { + return nil, err // e.g., the referred state history has been pruned + } + if meta.parent != root { + return nil, fmt.Errorf("state %#x is not canonincal", root) + } return &HistoricalStateReader{ id: *id, db: db, - reader: newHistoryReader(db.diskdb, db.freezer), + reader: newStateHistoryReader(db.diskdb, db.stateFreezer), }, nil } @@ -314,3 +318,90 @@ func (r *HistoricalStateReader) Storage(address common.Address, key common.Hash) } return r.reader.read(newStorageIdentQuery(address, addrHash, key, keyHash), r.id, dl.stateID(), latest) } + +// HistoricalNodeReader is a wrapper over history reader, providing access to +// historical trie node data. +type HistoricalNodeReader struct { + db *Database + reader *trienodeReader + id uint64 +} + +// HistoricNodeReader constructs a reader for accessing the requested historic state. +func (db *Database) HistoricNodeReader(root common.Hash) (*HistoricalNodeReader, error) { + // Bail out if the state history hasn't been fully indexed + if db.trienodeIndexer == nil || db.trienodeFreezer == nil { + return nil, fmt.Errorf("historical state %x is not available", root) + } + if !db.trienodeIndexer.inited() { + return nil, errors.New("trienode histories haven't been fully indexed yet") + } + // - States at the current disk layer or above are directly accessible + // via `db.NodeReader`. + // + // - States older than the current disk layer (including the disk layer + // itself) are available via `db.HistoricalNodeReader`. + id := rawdb.ReadStateID(db.diskdb, root) + if id == nil { + return nil, fmt.Errorf("state %#x is not available", root) + } + // Ensure the requested trienode history is canonical, states on side chain + // are not accessible. + meta, err := readTrienodeMetadata(db.trienodeFreezer, *id+1) + if err != nil { + return nil, err // e.g., the referred trienode history has been pruned + } + if meta.parent != root { + return nil, fmt.Errorf("state %#x is not canonincal", root) + } + return &HistoricalNodeReader{ + id: *id, + db: db, + reader: newTrienodeReader(db.diskdb, db.trienodeFreezer, int(db.config.FullValueCheckpoint)), + }, nil +} + +// Node directly retrieves the trie node data associated with a particular path, +// within a particular account. An error will be returned if the read operation +// exits abnormally. Specifically, if the layer is already stale. +// +// Note: +// - the returned trie node data is not a copy, please don't modify it. +// - an error will be returned if the requested trie node is not found in database. +func (r *HistoricalNodeReader) Node(owner common.Hash, path []byte, hash common.Hash) ([]byte, error) { + defer func(start time.Time) { + historicalTrienodeReadTimer.UpdateSince(start) + }(time.Now()) + + // TODO(rjl493456442): Theoretically, the obtained disk layer could become stale + // within a very short time window. + // + // While reading the account data while holding `db.tree.lock` can resolve + // this issue, but it will introduce a heavy contention over the lock. + // + // Let's optimistically assume the situation is very unlikely to happen, + // and try to define a low granularity lock if the current approach doesn't + // work later. + dl := r.db.tree.bottom() + latest, h, _, err := dl.node(owner, path, 0) + if err != nil { + return nil, err + } + if h == hash { + return latest, nil + } + blob, err := r.reader.read(newTrienodeIdent(owner, string(path)), r.id, dl.stateID(), latest) + if err != nil { + return nil, err + } + // Error out if the local one is inconsistent with the target. + if crypto.Keccak256Hash(blob) != hash { + blobHex := "nil" + if len(blob) > 0 { + blobHex = hexutil.Encode(blob) + } + log.Error("Unexpected historical trie node", "owner", owner.Hex(), "path", path, "blob", blobHex) + return nil, fmt.Errorf("unexpected historical trie node: (%x %v), blob: %s", owner, path, blobHex) + } + return blob, nil +} diff --git a/triedb/pathdb/states.go b/triedb/pathdb/states.go index bc638a569e..c84e2dc60c 100644 --- a/triedb/pathdb/states.go +++ b/triedb/pathdb/states.go @@ -170,18 +170,19 @@ func (s *stateSet) accountList() []common.Hash { if list != nil { return list } - // No old sorted account list exists, generate a new one. It's possible that - // multiple threads waiting for the write lock may regenerate the list - // multiple times, which is acceptable. s.listLock.Lock() defer s.listLock.Unlock() + // Double check after acquiring the write lock + if list = s.accountListSorted; list != nil { + return list + } list = slices.SortedFunc(maps.Keys(s.accountData), common.Hash.Cmp) s.accountListSorted = list return list } -// StorageList returns a sorted list of all storage slot hashes in this state set +// storageList returns a sorted list of all storage slot hashes in this state set // for the given account. The returned list will include the hash of deleted // storage slot. // @@ -200,12 +201,13 @@ func (s *stateSet) storageList(accountHash common.Hash) []common.Hash { } s.listLock.RUnlock() - // No old sorted account list exists, generate a new one. It's possible that - // multiple threads waiting for the write lock may regenerate the list - // multiple times, which is acceptable. s.listLock.Lock() defer s.listLock.Unlock() + // Double check after acquiring the write lock + if list := s.storageListSorted[accountHash]; list != nil { + return list + } list := slices.SortedFunc(maps.Keys(s.storageData[accountHash]), common.Hash.Cmp) s.storageListSorted[accountHash] = list return list diff --git a/triedb/pathdb/verifier.go b/triedb/pathdb/verifier.go index 2d6f72925b..a69b10f4f3 100644 --- a/triedb/pathdb/verifier.go +++ b/triedb/pathdb/verifier.go @@ -166,20 +166,17 @@ func (stat *generateStats) report() { // If there's progress on the account trie, estimate the time to finish crawling it if done := binary.BigEndian.Uint64(stat.head[:8]) / stat.accounts; done > 0 { var ( - left = (math.MaxUint64 - binary.BigEndian.Uint64(stat.head[:8])) / stat.accounts - speed = done/uint64(time.Since(stat.start)/time.Millisecond+1) + 1 // +1s to avoid division by zero - eta = time.Duration(left/speed) * time.Millisecond + left = (math.MaxUint64 - binary.BigEndian.Uint64(stat.head[:8])) / stat.accounts + eta = common.CalculateETA(done, left, time.Since(stat.start)) ) // If there are large contract crawls in progress, estimate their finish time for acc, head := range stat.slotsHead { start := stat.slotsStart[acc] if done := binary.BigEndian.Uint64(head[:8]); done > 0 { - var ( - left = math.MaxUint64 - binary.BigEndian.Uint64(head[:8]) - speed = done/uint64(time.Since(start)/time.Millisecond+1) + 1 // +1s to avoid division by zero - ) + left := math.MaxUint64 - binary.BigEndian.Uint64(head[:8]) + // Override the ETA if larger than the largest until now - if slotETA := time.Duration(left/speed) * time.Millisecond; eta < slotETA { + if slotETA := common.CalculateETA(done, left, time.Since(start)); eta < slotETA { eta = slotETA } } diff --git a/version/version.go b/version/version.go index 30c81b804b..bcb61f27b1 100644 --- a/version/version.go +++ b/version/version.go @@ -18,7 +18,7 @@ package version const ( Major = 1 // Major version component of the current release - Minor = 16 // Minor version component of the current release - Patch = 3 // Patch version component of the current release + Minor = 17 // Minor version component of the current release + Patch = 0 // Patch version component of the current release Meta = "unstable" // Version metadata to append to the version string )