github.com/ethereum-optimism/optimism@v1.7.2/op-node/cmd/batch_decoder/main.go (about) 1 package main 2 3 import ( 4 "context" 5 "fmt" 6 "log" 7 "math/big" 8 "os" 9 "time" 10 11 "github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/fetch" 12 "github.com/ethereum-optimism/optimism/op-node/cmd/batch_decoder/reassemble" 13 "github.com/ethereum-optimism/optimism/op-node/rollup" 14 "github.com/ethereum-optimism/optimism/op-node/rollup/derive" 15 "github.com/ethereum/go-ethereum/common" 16 "github.com/ethereum/go-ethereum/ethclient" 17 "github.com/urfave/cli/v2" 18 ) 19 20 func main() { 21 app := cli.NewApp() 22 app.Name = "batch-decoder" 23 app.Usage = "Optimism Batch Decoding Utility" 24 app.Commands = []*cli.Command{ 25 { 26 Name: "fetch", 27 Usage: "Fetches batches in the specified range", 28 Flags: []cli.Flag{ 29 &cli.IntFlag{ 30 Name: "start", 31 Required: true, 32 Usage: "First block (inclusive) to fetch", 33 }, 34 &cli.IntFlag{ 35 Name: "end", 36 Required: true, 37 Usage: "Last block (exclusive) to fetch", 38 }, 39 &cli.StringFlag{ 40 Name: "inbox", 41 Required: true, 42 Usage: "Batch Inbox Address", 43 }, 44 &cli.StringFlag{ 45 Name: "sender", 46 Required: true, 47 Usage: "Batch Sender Address", 48 }, 49 &cli.StringFlag{ 50 Name: "out", 51 Value: "/tmp/batch_decoder/transactions_cache", 52 Usage: "Cache directory for the found transactions", 53 }, 54 &cli.StringFlag{ 55 Name: "l1", 56 Required: true, 57 Usage: "L1 RPC URL", 58 EnvVars: []string{"L1_RPC"}, 59 }, 60 &cli.IntFlag{ 61 Name: "concurrent-requests", 62 Value: 10, 63 Usage: "Concurrency level when fetching L1", 64 }, 65 }, 66 Action: func(cliCtx *cli.Context) error { 67 client, err := ethclient.Dial(cliCtx.String("l1")) 68 if err != nil { 69 log.Fatal(err) 70 } 71 ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) 72 defer cancel() 73 chainID, err := client.ChainID(ctx) 74 if err != nil { 75 log.Fatal(err) 76 } 77 config := fetch.Config{ 78 Start: uint64(cliCtx.Int("start")), 79 End: uint64(cliCtx.Int("end")), 80 ChainID: chainID, 81 BatchSenders: map[common.Address]struct{}{ 82 common.HexToAddress(cliCtx.String("sender")): {}, 83 }, 84 BatchInbox: common.HexToAddress(cliCtx.String("inbox")), 85 OutDirectory: cliCtx.String("out"), 86 ConcurrentRequests: uint64(cliCtx.Int("concurrent-requests")), 87 } 88 totalValid, totalInvalid := fetch.Batches(client, config) 89 fmt.Printf("Fetched batches in range [%v,%v). Found %v valid & %v invalid batches\n", config.Start, config.End, totalValid, totalInvalid) 90 fmt.Printf("Fetch Config: Chain ID: %v. Inbox Address: %v. Valid Senders: %v.\n", config.ChainID, config.BatchInbox, config.BatchSenders) 91 fmt.Printf("Wrote transactions with batches to %v\n", config.OutDirectory) 92 return nil 93 }, 94 }, 95 { 96 Name: "reassemble", 97 Usage: "Reassembles channels from fetched batch transactions and decode batches", 98 Flags: []cli.Flag{ 99 &cli.StringFlag{ 100 Name: "in", 101 Value: "/tmp/batch_decoder/transactions_cache", 102 Usage: "Cache directory for the found transactions", 103 }, 104 &cli.StringFlag{ 105 Name: "out", 106 Value: "/tmp/batch_decoder/channel_cache", 107 Usage: "Cache directory for the found channels", 108 }, 109 &cli.Uint64Flag{ 110 Name: "l2-chain-id", 111 Value: 10, 112 Usage: "L2 chain id for span batch derivation. Default value from op-mainnet.", 113 }, 114 &cli.Uint64Flag{ 115 Name: "l2-genesis-timestamp", 116 Value: 1686068903, 117 Usage: "L2 genesis time for span batch derivation. Default value from op-mainnet. " + 118 "Superchain-registry prioritized when given value is inconsistent.", 119 }, 120 &cli.Uint64Flag{ 121 Name: "l2-block-time", 122 Value: 2, 123 Usage: "L2 block time for span batch derivation. Default value from op-mainnet. " + 124 "Superchain-registry prioritized when given value is inconsistent.", 125 }, 126 &cli.StringFlag{ 127 Name: "inbox", 128 Value: "0xFF00000000000000000000000000000000000010", 129 Usage: "Batch Inbox Address. Default value from op-mainnet. " + 130 "Superchain-registry prioritized when given value is inconsistent.", 131 }, 132 }, 133 Action: func(cliCtx *cli.Context) error { 134 var ( 135 L2GenesisTime uint64 = cliCtx.Uint64("l2-genesis-timestamp") 136 L2BlockTime uint64 = cliCtx.Uint64("l2-block-time") 137 BatchInboxAddress common.Address = common.HexToAddress(cliCtx.String("inbox")) 138 ) 139 L2ChainID := new(big.Int).SetUint64(cliCtx.Uint64("l2-chain-id")) 140 rollupCfg, err := rollup.LoadOPStackRollupConfig(L2ChainID.Uint64()) 141 if err == nil { 142 // prioritize superchain config 143 if L2GenesisTime != rollupCfg.Genesis.L2Time { 144 L2GenesisTime = rollupCfg.Genesis.L2Time 145 fmt.Printf("L2GenesisTime overridden: %v\n", L2GenesisTime) 146 } 147 if L2BlockTime != rollupCfg.BlockTime { 148 L2BlockTime = rollupCfg.BlockTime 149 fmt.Printf("L2BlockTime overridden: %v\n", L2BlockTime) 150 } 151 if BatchInboxAddress != rollupCfg.BatchInboxAddress { 152 BatchInboxAddress = rollupCfg.BatchInboxAddress 153 fmt.Printf("BatchInboxAddress overridden: %v\n", BatchInboxAddress) 154 } 155 } 156 config := reassemble.Config{ 157 BatchInbox: BatchInboxAddress, 158 InDirectory: cliCtx.String("in"), 159 OutDirectory: cliCtx.String("out"), 160 L2ChainID: L2ChainID, 161 L2GenesisTime: L2GenesisTime, 162 L2BlockTime: L2BlockTime, 163 } 164 reassemble.Channels(config) 165 return nil 166 }, 167 }, 168 { 169 Name: "force-close", 170 Usage: "Create the tx data which will force close a channel", 171 Flags: []cli.Flag{ 172 &cli.StringFlag{ 173 Name: "id", 174 Required: true, 175 Usage: "ID of the channel to close", 176 }, 177 &cli.StringFlag{ 178 Name: "inbox", 179 Value: "0x0000000000000000000000000000000000000000", 180 Usage: "(Optional) Batch Inbox Address", 181 }, 182 &cli.StringFlag{ 183 Name: "in", 184 Value: "/tmp/batch_decoder/transactions_cache", 185 Usage: "Cache directory for the found transactions", 186 }, 187 }, 188 Action: func(cliCtx *cli.Context) error { 189 var id derive.ChannelID 190 if err := (&id).UnmarshalText([]byte(cliCtx.String("id"))); err != nil { 191 log.Fatal(err) 192 } 193 frames := reassemble.LoadFrames(cliCtx.String("in"), common.HexToAddress(cliCtx.String("inbox"))) 194 var filteredFrames []derive.Frame 195 for _, frame := range frames { 196 if frame.Frame.ID == id { 197 filteredFrames = append(filteredFrames, frame.Frame) 198 } 199 } 200 data, err := derive.ForceCloseTxData(filteredFrames) 201 if err != nil { 202 log.Fatal(err) 203 } 204 fmt.Printf("%x\n", data) 205 return nil 206 }, 207 }, 208 } 209 210 if err := app.Run(os.Args); err != nil { 211 log.Fatal(err) 212 } 213 }