From 4dee0ba7fb4a1313ef9702130f9ecd1b6c3b5f0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ra=C3=BAl=20Kripalani?= Date: Thu, 19 Jan 2023 13:49:47 +0000 Subject: [PATCH] add a lotus-shed eth check-tipsets command. This checks Eth API consistency by walking the chain backwards from HEAD and verifying that all data returned from eth_getBlockByNumber is consistent with eth_getBlockByHash. --- cmd/lotus-shed/eth.go | 70 ++++++++++++++++++++++++++++++++++++++++++ cmd/lotus-shed/main.go | 1 + 2 files changed, 71 insertions(+) create mode 100644 cmd/lotus-shed/eth.go diff --git a/cmd/lotus-shed/eth.go b/cmd/lotus-shed/eth.go new file mode 100644 index 000000000..02e1d58b4 --- /dev/null +++ b/cmd/lotus-shed/eth.go @@ -0,0 +1,70 @@ +package main + +import ( + "fmt" + "reflect" + + "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/types" + lcli "github.com/filecoin-project/lotus/cli" + "github.com/urfave/cli/v2" +) + +var ethCmd = &cli.Command{ + Name: "eth", + Description: "Ethereum compatibility related commands", + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "repo", + Value: "~/.lotus", + }, + }, + Subcommands: []*cli.Command{ + checkTipsetsCmd, + }, +} + +var checkTipsetsCmd = &cli.Command{ + Name: "check-tipsets", + Description: "Check that eth_getBlockByNumber and eth_getBlockByHash consistently return tipsets", + Action: func(cctx *cli.Context) error { + api, closer, err := lcli.GetFullNodeAPIV1(cctx) + if err != nil { + return err + } + + defer closer() + ctx := lcli.ReqContext(cctx) + + head, err := api.ChainHead(ctx) + if err != nil { + return err + } + + height := head.Height() + fmt.Println("Current height:", height) + for i := int64(height); i > 0; i-- { + if _, err := api.ChainGetTipSetByHeight(ctx, abi.ChainEpoch(i), types.EmptyTSK); err != nil { + fmt.Printf("[FAIL] failed to get tipset @%d from Lotus: %s\n", i, err) + continue + } + hex := fmt.Sprintf("0x%x", i) + ethBlockA, err := api.EthGetBlockByNumber(ctx, hex, false) + if err != nil { + fmt.Printf("[FAIL] failed to get tipset @%d via eth_getBlockByNumber: %s\n", i, err) + continue + } + ethBlockB, err := api.EthGetBlockByHash(ctx, ethBlockA.Hash, false) + if err != nil { + fmt.Printf("[FAIL] failed to get tipset @%d via eth_getBlockByHash: %s\n", i, err) + continue + } + if equal := reflect.DeepEqual(ethBlockA, ethBlockB); equal { + fmt.Printf("[OK] blocks received via eth_getBlockByNumber and eth_getBlockByHash for tipset @%d are identical\n", i) + } else { + fmt.Printf("[FAIL] blocks received via eth_getBlockByNumber and eth_getBlockByHash for tipset @%d are NOT identical\n", i) + } + } + return nil + }, +} diff --git a/cmd/lotus-shed/main.go b/cmd/lotus-shed/main.go index 6f84739fa..28a59f14d 100644 --- a/cmd/lotus-shed/main.go +++ b/cmd/lotus-shed/main.go @@ -49,6 +49,7 @@ func main() { minerCmd, mpoolStatsCmd, exportChainCmd, + ethCmd, exportCarCmd, consensusCmd, syncCmd,