Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(anvil): block dumps #8160

Merged
merged 6 commits into from
Jun 18, 2024
Merged

Conversation

samlaf
Copy link
Contributor

@samlaf samlaf commented Jun 14, 2024

Motivation

Fixes #7502

Solution

Dump all blocks as part of dumped json file.

built with cargo install --path ./crates/anvil --profile local --force --locked and tested by running:

~/.cargo/bin/anvil --dump-state state3.json
# from another terminal
cast send 0x3347f1B5fE96332fEb50ec2B6D5fb5fca7997C30 --value 1wei --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
cast send 0x3347f1B5fE96332fEb50ec2B6D5fb5fca7997C30 --value 1wei --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80
cast send 0x3347f1B5fE96332fEb50ec2B6D5fb5fca7997C30 --value 1wei --private-key 0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80

then closed anvil, and restarted with

$ ~/.cargo/bin/anvil --load-state state3.json
# from another terminal
$ cast block-number
3
$ cast block 1 # cast block 2 and 3 print similar block info
baseFeePerGas        1000000000
difficulty           0
extraData            0x
gasLimit             30000000
gasUsed              21000
hash                 0x22c6b8dc4e4f65fbb1c27442f6efd5d0ca1a4840e93b04d7958744e6b9f4a00b
logsBloom            0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
miner                0x0000000000000000000000000000000000000000
mixHash              0x0000000000000000000000000000000000000000000000000000000000000000
nonce                0x0000000000000000
number               1
parentHash           0x735a92a773dc1513b64d973d4e5a14da9564ccbf1236c0ad290df6dc5c8958d3
transactionsRoot     0x3ba79c2a102c7339a4b6a481cc7e782088025321c29dbffef02264a681b5b95f
receiptsRoot         0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa
sha3Uncles           0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347
size                 629
stateRoot            0xe68d2a7edc1d8bf4e632966b28fd74d61243b9febfc27a25322e78b0664e44bd
timestamp            1718346762
withdrawalsRoot
totalDifficulty      0
transactions:        [
	0xfa8b447ff9cf082cb7cf962b25f4dc9c9efce478afbe274330c1afa6e5feafe8
]

And then dumped json db file looks like

{
  "block": {
    "number": "0x3",
    "coinbase": "0x0000000000000000000000000000000000000000",
    "timestamp": "0x666be40c",
    "gas_limit": "0x1c9c380",
    "basefee": "0x2da72f11",
    "difficulty": "0x0",
    "prevrandao": "0x0000000000000000000000000000000000000000000000000000000000000000",
    "blob_excess_gas_and_price": {
      "excess_blob_gas": 0,
      "blob_gasprice": 1
    }
  },
  "accounts": {
    "0x0000000000000000000000000000000000000000": {
      "nonce": 0,
      "balance": "0xf618",
      "code": "0x",
      "storage": {}
    },
    "0x14dc79964da2c08b23698b3d3cc7ca32193d9955": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0x15d34aaf54267db7d7c367839aaf71a00a2c6a65": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0x23618e81e3f5cdf7f54c3d65f7fbc0abf5b21e8f": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0x3347f1b5fe96332feb50ec2b6d5fb5fca7997c30": {
      "nonce": 0,
      "balance": "0x3",
      "code": "0x",
      "storage": {}
    },
    "0x3c44cdddb6a900fa2b585dd299e03d12fa4293bc": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0x4e59b44847b379578588920ca78fbf26c0b4956c": {
      "nonce": 0,
      "balance": "0x0",
      "code": "0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf3",
      "storage": {}
    },
    "0x70997970c51812dc3a010c7d01b50e0d17dc79c8": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0x90f79bf6eb2c4f870365e785982e1f101e93b906": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0x976ea74026e726554db657fa54763abd0c3a0aa9": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0x9965507d1a55bcc2695c58ba16fb37d819b0a4dc": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0xa0ee7a142d267c1f36714e4a8f75612f20a79720": {
      "nonce": 0,
      "balance": "0x21e19e0c9bab2400000",
      "code": "0x",
      "storage": {}
    },
    "0xf39fd6e51aad88f6f4ce6ab8827279cfffb92266": {
      "nonce": 3,
      "balance": "0x21e19e097492802bc9d",
      "code": "0x",
      "storage": {}
    }
  },
  "best_block_number": "0x3",
  "blocks": [
    {
      "header": {
        "parent_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
        "beneficiary": "0x0000000000000000000000000000000000000000",
        "state_root": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "transactions_root": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421",
        "receipts_root": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "withdrawals_root": null,
        "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "difficulty": "0x0",
        "number": 0,
        "gas_limit": 30000000,
        "gas_used": 0,
        "timestamp": 1718346754,
        "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "nonce": "0x0000000000000000",
        "base_fee_per_gas": 1000000000,
        "blob_gas_used": 0,
        "excess_blob_gas": 0,
        "parent_beacon_block_root": null,
        "requests_root": null,
        "extra_data": "0x"
      },
      "transactions": [],
      "ommers": []
    },
    {
      "header": {
        "parent_hash": "0x735a92a773dc1513b64d973d4e5a14da9564ccbf1236c0ad290df6dc5c8958d3",
        "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
        "beneficiary": "0x0000000000000000000000000000000000000000",
        "state_root": "0xe68d2a7edc1d8bf4e632966b28fd74d61243b9febfc27a25322e78b0664e44bd",
        "transactions_root": "0x3ba79c2a102c7339a4b6a481cc7e782088025321c29dbffef02264a681b5b95f",
        "receipts_root": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa",
        "withdrawals_root": null,
        "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "difficulty": "0x0",
        "number": 1,
        "gas_limit": 30000000,
        "gas_used": 21000,
        "timestamp": 1718346762,
        "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "nonce": "0x0000000000000000",
        "base_fee_per_gas": 1000000000,
        "blob_gas_used": 0,
        "excess_blob_gas": 0,
        "parent_beacon_block_root": null,
        "requests_root": null,
        "extra_data": "0x"
      },
      "transactions": [
        {
          "EIP1559": {
            "chainId": "0x7a69",
            "nonce": "0x0",
            "gasLimit": "0x5209",
            "maxFeePerGas": "0x77359401",
            "maxPriorityFeePerGas": "0x1",
            "to": "0x3347f1b5fe96332feb50ec2b6d5fb5fca7997c30",
            "value": "0x1",
            "accessList": [],
            "input": "0x",
            "r": "0x12fa914feffa5fbf4194b35db56a5bc26906787341a9b907d98e719ff2018269",
            "s": "0x6dfdd477e2028880fd435ca1c67676dddfbd6ab6bbb28c8985f78ed1bbfcc4e3",
            "yParity": "0x1",
            "hash": "0xfa8b447ff9cf082cb7cf962b25f4dc9c9efce478afbe274330c1afa6e5feafe8"
          }
        }
      ],
      "ommers": []
    },
    {
      "header": {
        "parent_hash": "0xc4bc1968698ae72336ddbe40d753faaab06bda7e29e5bdcd7f3f55c2d8b34139",
        "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
        "beneficiary": "0x0000000000000000000000000000000000000000",
        "state_root": "0x64aec446d4a00286e9750496acec267ac0b93f981cfb51f071a27456af09e3b8",
        "transactions_root": "0xed995902ea0c6bf2b651725867381fd692fa991e38c2a4e6b09c43ebc91779fc",
        "receipts_root": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa",
        "withdrawals_root": null,
        "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "difficulty": "0x0",
        "number": 3,
        "gas_limit": 30000000,
        "gas_used": 21000,
        "timestamp": 1718346764,
        "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "nonce": "0x0000000000000000",
        "base_fee_per_gas": 765931281,
        "blob_gas_used": 0,
        "excess_blob_gas": 0,
        "parent_beacon_block_root": null,
        "requests_root": null,
        "extra_data": "0x"
      },
      "transactions": [
        {
          "EIP1559": {
            "chainId": "0x7a69",
            "nonce": "0x2",
            "gasLimit": "0x5209",
            "maxFeePerGas": "0x5b4e5e23",
            "maxPriorityFeePerGas": "0x1",
            "to": "0x3347f1b5fe96332feb50ec2b6d5fb5fca7997c30",
            "value": "0x1",
            "accessList": [],
            "input": "0x",
            "r": "0x5775a100103963679c35a78c520509535d68aa6dcfdb00d52b43657dbac52e02",
            "s": "0x71e9495ef54f41023ad15e1ac9225232b006a83624189cd89690a1eebbb19cc7",
            "yParity": "0x0",
            "hash": "0x850f03198f29450eaa11505c52a29da794a3fa75c52964861f0c56425f861de1"
          }
        }
      ],
      "ommers": []
    },
    {
      "header": {
        "parent_hash": "0x22c6b8dc4e4f65fbb1c27442f6efd5d0ca1a4840e93b04d7958744e6b9f4a00b",
        "ommers_hash": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347",
        "beneficiary": "0x0000000000000000000000000000000000000000",
        "state_root": "0xb18393d1a8a8f4a4bbd3820eab4f6b9d4b7306cbe9dd8f0d8a7418450b8b3bc4",
        "transactions_root": "0x43c36fa7a815ef2fac10a51a71ecb93222721bd07df56df56670bfa678fe0ecc",
        "receipts_root": "0xf78dfb743fbd92ade140711c8bbc542b5e307f0ab7984eff35d751969fe57efa",
        "withdrawals_root": null,
        "logs_bloom": "0x00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "difficulty": "0x0",
        "number": 2,
        "gas_limit": 30000000,
        "gas_used": 21000,
        "timestamp": 1718346763,
        "mix_hash": "0x0000000000000000000000000000000000000000000000000000000000000000",
        "nonce": "0x0000000000000000",
        "base_fee_per_gas": 875175000,
        "blob_gas_used": 0,
        "excess_blob_gas": 0,
        "parent_beacon_block_root": null,
        "requests_root": null,
        "extra_data": "0x"
      },
      "transactions": [
        {
          "EIP1559": {
            "chainId": "0x7a69",
            "nonce": "0x1",
            "gasLimit": "0x5209",
            "maxFeePerGas": "0x685438b1",
            "maxPriorityFeePerGas": "0x1",
            "to": "0x3347f1b5fe96332feb50ec2b6d5fb5fca7997c30",
            "value": "0x1",
            "accessList": [],
            "input": "0x",
            "r": "0x3b3ec3bec4a6d2a37924373a8089ff6d1b116d825bf067f26f2c79b7ae2c73a0",
            "s": "0x485a37fc0169d4db0b06acf62d7602fcd896ba05fcd4397caf574439483b7a81",
            "yParity": "0x0",
            "hash": "0x5357c2b71e56686c1f4a5f3ce7ea4b748a064a5811413b6751919888bf3402b4"
          }
        }
      ],
      "ommers": []
    }
  ]
}

Remaining bugs

seems like full block is not dumped?

$ cast block 1 --full
Error:
block Number(Number(1)) not found

Random comments

Was originally formatting with cargo fmt which was creating a huge number of diffs (mostly adding ; at end of lines). Realized you guys probably use cargo +nightly fmt since it didn't create diffs. However it also doesn't enforce the styling, so I had to manually remove all the ; added by cargo fmt, which was very annoying. Is there a way to enforce a single style from cargo +nightly fmt? This way it would have removed (or added) all ;, but not accept both and leave my git status in a weird state.

Comment on lines 380 to 382
// TODO: only implementing here for now, need to upstream this
// can we make alloy_consensus::header Serializable/Deserializable?
/// this is the same struct, literally, with derive(Serialize, Deserialize)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highlighting this. Copied a bunch of structs just to make them Serialize/Deserialize. We can clean this up by deriving Serialize/Deserialize upstream in alloy if needed.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should upstream this instead, looks like the serde impl for header is just missing

Comment on lines +739 to +741
let blocks = self.blockchain.storage.read().serialized_blocks();
let state = self.db.read().await.dump_state(at, best_number, blocks)?;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if this is the best implementation. Reading the blocks and then passing them to the dump_state function in db to also include them in the dumped json.

Will want to also dump events soon, so the db dump_state function might become cluttered and coupled. An alternative design is to pass mut references to a serialized_state to db, storage, event services, and have them add whatever information they are dumping, so that we can partially construct the serialized_state?


// verifies that blocks in BlockchainStorage remain the same when dumped and reloaded
#[test]
fn test_storage_dump_reload_cycle() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added this unit test for storage, but now that we are dumping and reloading both the db and storage, we might need an integration test in mod.rs for the dumping/reloading of the entire serialized_state?

@DaniPopes DaniPopes changed the title Fix 7502 block dumps fix(anvil): block dumps Jun 14, 2024
@DaniPopes
Copy link
Member

DaniPopes commented Jun 14, 2024

FYI you can just build and run in debug mode with cargo run --bin anvil. Generally performance is fine even in debug mode.

@samlaf
Copy link
Contributor Author

samlaf commented Jun 14, 2024

@DaniPopes fixed the anvil related clippy errors from https://github.com/foundry-rs/foundry/actions/runs/9512891848/job/26223615034?pr=8160 in 036aeed
But there was also an error with cast, which I didn't touch... so not sure why. Should I fix it here?
image

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment on lines 380 to 382
// TODO: only implementing here for now, need to upstream this
// can we make alloy_consensus::header Serializable/Deserializable?
/// this is the same struct, literally, with derive(Serialize, Deserialize)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should upstream this instead, looks like the serde impl for header is just missing

@samlaf
Copy link
Contributor Author

samlaf commented Jun 17, 2024

Hey @mattsse , tried to update this PR to alloy's commit b857ea5
image

but running into

error: no matching package named `alloy-signer-wallet` found
location searched: https://github.com/alloy-rs/alloy?rev=b857ea5
required by package `anvil v0.2.0 (/Users/samlaf/devel/ethereum/foundry-fork-samlaf/crates/anvil)`

was signer-wallet renamed to signer-trezor? How can I fix this? Or can you guys make the upgrade and commit it so I can rebase my stuff off of it if it requires big changes?

@DaniPopes
Copy link
Member

#8177 was just merged, pls just rebase

Copy link
Member

@mattsse mattsse left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems okay, ty

@mattsse mattsse merged commit 6f41cd9 into foundry-rs:master Jun 18, 2024
17 of 19 checks passed
klkvr pushed a commit to klkvr/foundry that referenced this pull request Jun 19, 2024
* implemented latest_block dump/load

* update to dump/load all blocks instead of only latest

* refactored state loading into storage.rs, and added load-dump cycle test

* fix clippy errors for anvil

* remove SerializableHeader and use Header (now serializable)

* clippy happy

---------

Co-authored-by: Matthias Seitz <matthias.seitz@outlook.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

recent anvil --state/dump-state changes are broken
3 participants