Commit f910bf28 authored by protolambda's avatar protolambda Committed by GitHub

op-chain-ops: op-run-block debug tool (PR v2) (#13811)

* op-chain-ops: op-run-block debug tool

* op-run-block: fix conflict with geth merge
parent 06903370
# op-run-block
This tool enables local op-geth EVM debugging,
to re-run bad blocks in a controlled local environment,
where arbitrary tracers can be attached,
and experimental changes can be tested quickly.
This helps debug why these blocks may fail or diverge in unexpected ways.
E.g. a block produced by op-reth that does not get accepted by op-geth
can be replayed in a debugger to find what is happening.
## Usage
```bash
go run . --rpc=http://my-debug-geth-endpoint:8545 --block=badblock.json --out=trace.txt
```
Where `badblock.json` looks like:
```json
[
{
"block": {
"timestamp": ...
"number": ...
"transactions": [ ... ],
...
}
}
]
```
This type of block can be collected with:
```bash
cast rpc --rpc-url=http://localhost:8545 debug_getBadBlocks
```
See Go-ethereum `debug` RPC namespace docs: https://geth.ethereum.org/docs/interacting-with-geth/rpc/ns-debug
This diff is collapsed.
...@@ -89,11 +89,11 @@ func (hdr *RPCHeader) checkPostMerge() error { ...@@ -89,11 +89,11 @@ func (hdr *RPCHeader) checkPostMerge() error {
} }
func (hdr *RPCHeader) computeBlockHash() common.Hash { func (hdr *RPCHeader) computeBlockHash() common.Hash {
gethHeader := hdr.createGethHeader() gethHeader := hdr.CreateGethHeader()
return gethHeader.Hash() return gethHeader.Hash()
} }
func (hdr *RPCHeader) createGethHeader() *types.Header { func (hdr *RPCHeader) CreateGethHeader() *types.Header {
return &types.Header{ return &types.Header{
ParentHash: hdr.ParentHash, ParentHash: hdr.ParentHash,
UncleHash: hdr.UncleHash, UncleHash: hdr.UncleHash,
...@@ -130,7 +130,7 @@ func (hdr *RPCHeader) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInfo ...@@ -130,7 +130,7 @@ func (hdr *RPCHeader) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInfo
return nil, fmt.Errorf("failed to verify block hash: computed %s but RPC said %s", computed, hdr.Hash) return nil, fmt.Errorf("failed to verify block hash: computed %s but RPC said %s", computed, hdr.Hash)
} }
} }
return eth.HeaderBlockInfoTrusted(hdr.Hash, hdr.createGethHeader()), nil return eth.HeaderBlockInfoTrusted(hdr.Hash, hdr.CreateGethHeader()), nil
} }
func (hdr *RPCHeader) BlockID() eth.BlockID { func (hdr *RPCHeader) BlockID() eth.BlockID {
...@@ -146,7 +146,7 @@ type RPCBlock struct { ...@@ -146,7 +146,7 @@ type RPCBlock struct {
Withdrawals *types.Withdrawals `json:"withdrawals,omitempty"` Withdrawals *types.Withdrawals `json:"withdrawals,omitempty"`
} }
func (block *RPCBlock) verify() error { func (block *RPCBlock) Verify() error {
if computed := block.computeBlockHash(); computed != block.Hash { if computed := block.computeBlockHash(); computed != block.Hash {
return fmt.Errorf("failed to verify block hash: computed %s but RPC said %s", computed, block.Hash) return fmt.Errorf("failed to verify block hash: computed %s but RPC said %s", computed, block.Hash)
} }
...@@ -185,7 +185,7 @@ func (block *RPCBlock) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInf ...@@ -185,7 +185,7 @@ func (block *RPCBlock) Info(trustCache bool, mustBePostMerge bool) (eth.BlockInf
} }
} }
if !trustCache { if !trustCache {
if err := block.verify(); err != nil { if err := block.Verify(); err != nil {
return nil, nil, err return nil, nil, err
} }
} }
...@@ -204,7 +204,7 @@ func (block *RPCBlock) ExecutionPayloadEnvelope(trustCache bool) (*eth.Execution ...@@ -204,7 +204,7 @@ func (block *RPCBlock) ExecutionPayloadEnvelope(trustCache bool) (*eth.Execution
return nil, err return nil, err
} }
if !trustCache { if !trustCache {
if err := block.verify(); err != nil { if err := block.Verify(); err != nil {
return nil, err return nil, err
} }
} }
......
...@@ -70,7 +70,7 @@ func TestBlockJSON(t *testing.T) { ...@@ -70,7 +70,7 @@ func TestBlockJSON(t *testing.T) {
var block RPCBlock var block RPCBlock
readJsonTestdata(t, "testdata/data/blocks/"+strings.Replace(entry.Name(), "_metadata.json", "_data.json", 1), &block) readJsonTestdata(t, "testdata/data/blocks/"+strings.Replace(entry.Name(), "_metadata.json", "_data.json", 1), &block)
err := block.verify() err := block.Verify()
if metadata.Fail { if metadata.Fail {
require.NotNil(t, err, "expecting verification error") require.NotNil(t, err, "expecting verification error")
require.ErrorContains(t, err, metadata.Reason, "validation failed for incorrect reason") require.ErrorContains(t, err, metadata.Reason, "validation failed for incorrect reason")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment