From 6af025718622592607912c096b083b3557515541 Mon Sep 17 00:00:00 2001 From: Andreas Bigger Date: Mon, 30 Jan 2023 10:35:28 -0500 Subject: [PATCH 1/5] feat: burn test :test_tube: --- pkg/client/client.go | 16 ++++++- pkg/handlers/burn_test.go | 89 +++++++++++++++++++++++++++++++++++++++ pkg/handlers/common.go | 3 ++ pkg/utils/types.go | 2 + 4 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 pkg/handlers/burn_test.go diff --git a/pkg/client/client.go b/pkg/client/client.go index 7ef7830..61ccc9b 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -20,6 +20,7 @@ import ( EthTypes "github.com/ethereum/go-ethereum/core/types" ) +// OpClient wraps the [evmClient.SDKClient] to add Optimism-specific functionality. type OpClient struct { *evmClient.SDKClient } @@ -98,9 +99,20 @@ func (c *OpClient) GetBlockReceipts( Result: ðReceipts[i], } } - if err := c.BatchCallContext(ctx, reqs); err != nil { - return nil, err + + maxBatchSize := 25 + for i := 0; i < len(txs); i += maxBatchSize { + if i+maxBatchSize < len(txs) { + if err := c.BatchCallContext(ctx, reqs[i:i+maxBatchSize]); err != nil { + return nil, err + } + } else { + if err := c.BatchCallContext(ctx, reqs[i:]); err != nil { + return nil, err + } + } } + for i := range reqs { if reqs[i].Error != nil { return nil, reqs[i].Error diff --git a/pkg/handlers/burn_test.go b/pkg/handlers/burn_test.go new file mode 100644 index 0000000..f23d876 --- /dev/null +++ b/pkg/handlers/burn_test.go @@ -0,0 +1,89 @@ +package handlers_test + +import ( + "math/big" + "testing" + + evmClient "github.com/coinbase/rosetta-geth-sdk/client" + sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" + RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" + gethCommon "github.com/ethereum/go-ethereum/common" + EthTypes "github.com/ethereum/go-ethereum/core/types" + handlers "github.com/mdehoog/op-rosetta/pkg/handlers" + suite "github.com/stretchr/testify/suite" +) + +type BurnTestSuite struct { + suite.Suite +} + +// TestBurn runs the BurnTestSuite. +func TestBurn(t *testing.T) { + suite.Run(t, new(BurnTestSuite)) +} + +// TestInvalidDestination tests that a [evmClient.LoadedTransaction] with an invalid destination is not a burn. +func (testSuite *BurnTestSuite) TestInvalidDestination() { + // dest := handlers.L2ToL1MessagePasser + + // Construct a loaded transaction with an invalid burn destination (not L2ToL1MessagePasser). + h := gethCommon.HexToHash("0xb358c6958b1cab722752939cbb92e3fec6b6023de360305910ce80c56c3dad9d") + gasPrice := big.NewInt(10000) + myTx := EthTypes.NewTransaction( + 0, + gethCommon.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), + big.NewInt(0), + 0, + gasPrice, + nil, + ) + loadedTxn := &evmClient.LoadedTransaction{ + TxHash: &h, + Transaction: myTx, + } + + // BurnOps should return nil for a transaction with an invalid destination. + ops := handlers.BurnOps(loadedTxn, 0) + testSuite.Nil(ops) +} + +// TestValidBurn tests that [handlers.BurnOps] correctly constructs [RosettaTypes.Operation], +// given a [evmClient.LoadedTransaction] with the correct destination address. +func (testSuite *BurnTestSuite) TestValidBurn() { + // Construct a loaded transaction with the correct burn destination (L2ToL1MessagePasser). + // Note: this hash is incorrect and was hijacked from the above transaction. + h := gethCommon.HexToHash("0xb358c6958b1cab722752939cbb92e3fec6b6023de360305910ce80c56c3dad9d") + gasPrice := big.NewInt(10000) + amount := big.NewInt(100) + index := 1 + myTx := EthTypes.NewTransaction( + 0, + handlers.L2ToL1MessagePasser, + amount, + 0, + gasPrice, + nil, + ) + from := gethCommon.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") + loadedTxn := &evmClient.LoadedTransaction{ + From: &from, + TxHash: &h, + Transaction: myTx, + } + + // BurnOps should return nil for a transaction with an invalid destination. + ops := handlers.BurnOps(loadedTxn, index) + testSuite.Equal(ops, []*RosettaTypes.Operation{ + { + OperationIdentifier: &RosettaTypes.OperationIdentifier{ + Index: int64(index), + }, + Type: handlers.BurnOpType, + Status: RosettaTypes.String(sdkTypes.SuccessStatus), + Account: &RosettaTypes.AccountIdentifier{ + Address: from.String(), + }, + Amount: evmClient.Amount(amount, sdkTypes.Currency), + }, + }) +} diff --git a/pkg/handlers/common.go b/pkg/handlers/common.go index 57fff33..7e6be60 100644 --- a/pkg/handlers/common.go +++ b/pkg/handlers/common.go @@ -10,6 +10,9 @@ const ( MintOpType = "MINT" // BurnOpType is a [RosettaTypes.Operation] type for an Optimism Withdrawal or "burn" transaction. BurnOpType = "BURN" + + // An erroneous STOP Type not defined in rosetta-geth-sdk + StopOpType = "STOP" ) // Optimism Predeploy Addresses diff --git a/pkg/utils/types.go b/pkg/utils/types.go index 7691716..d71fad7 100644 --- a/pkg/utils/types.go +++ b/pkg/utils/types.go @@ -18,6 +18,8 @@ func LoadTypes() *sdkTypes.Types { ots = append(ots, ot) } ots = append(ots, handlers.MintOpType) + // ots = append(ots, handlers.BurnOpType) + ots = append(ots, handlers.StopOpType) t.OperationTypes = ots return t From c113fb9fbb8d5bbec4c4ff4dc5d352837b558b3e Mon Sep 17 00:00:00 2001 From: Andreas Bigger Date: Mon, 30 Jan 2023 11:42:14 -0500 Subject: [PATCH 2/5] feat: refactoring and mint tests --- configs/optimism/goerli-basic.json | 38 ++++++ configs/optimism/goerli.json | 8 +- pkg/client/client.go | 194 ----------------------------- pkg/client/client_blocks.go | 96 ++++++++++++++ pkg/client/client_gas.go | 25 ++++ pkg/client/client_ops.go | 69 ++++++++++ pkg/client/client_receipts.go | 42 +++++++ pkg/handlers/burn_test.go | 4 +- pkg/handlers/mint_test.go | 88 +++++++++++++ 9 files changed, 363 insertions(+), 201 deletions(-) create mode 100644 configs/optimism/goerli-basic.json create mode 100644 pkg/client/client_blocks.go create mode 100644 pkg/client/client_gas.go create mode 100644 pkg/client/client_ops.go create mode 100644 pkg/client/client_receipts.go create mode 100644 pkg/handlers/mint_test.go diff --git a/configs/optimism/goerli-basic.json b/configs/optimism/goerli-basic.json new file mode 100644 index 0000000..c891c08 --- /dev/null +++ b/configs/optimism/goerli-basic.json @@ -0,0 +1,38 @@ +{ + "network": { + "blockchain": "Optimism", + "network": "Goerli", + "sub_network_identifier": null + }, + "online_url": "http://localhost:8080", + "data_directory": "", + "http_timeout": 300, + "max_retries": 100, + "max_online_connections": 500, + "force_retry": true, + "max_sync_concurrency": 64, + "tip_delay": 120, + "max_reorg_depth": 64, + "log_configuration": false, + "compression_disabled": true, + "l0_in_memory_enabled": true, + "all_in_memory_enabled": true, + "table_size": 1, + "value_log_file_size": 1024, + "construction": null, + "data": { + "start_index": 4307133, + "reconciliation_disabled": true, + "inactive_discrepancy_search_disabled": true, + "balance_tracking_disabled": true, + "initial_balance_fetch_disabled":true, + "active_reconciliation_concurrency": 32, + "bootstrap_balances": "", + "log_balance_changes": true, + "log_transactions": true, + "log_blocks": true, + "end_conditions": { + "tip": true + } + } +} diff --git a/configs/optimism/goerli.json b/configs/optimism/goerli.json index c891c08..d910950 100644 --- a/configs/optimism/goerli.json +++ b/configs/optimism/goerli.json @@ -22,10 +22,10 @@ "construction": null, "data": { "start_index": 4307133, - "reconciliation_disabled": true, - "inactive_discrepancy_search_disabled": true, - "balance_tracking_disabled": true, - "initial_balance_fetch_disabled":true, + "reconciliation_disabled": false, + "inactive_discrepancy_search_disabled": false, + "balance_tracking_disabled": false, + "initial_balance_fetch_disabled": false, "active_reconciliation_concurrency": 32, "bootstrap_balances": "", "log_balance_changes": true, diff --git a/pkg/client/client.go b/pkg/client/client.go index 61ccc9b..5b71201 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -1,23 +1,11 @@ package client import ( - "context" "fmt" - "math/big" - "strings" "github.com/coinbase/rosetta-geth-sdk/configuration" - "github.com/mdehoog/op-rosetta/pkg/handlers" - - "github.com/ethereum/go-ethereum" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/rpc" evmClient "github.com/coinbase/rosetta-geth-sdk/client" - "github.com/coinbase/rosetta-geth-sdk/services" - sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" - RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" - EthTypes "github.com/ethereum/go-ethereum/core/types" ) // OpClient wraps the [evmClient.SDKClient] to add Optimism-specific functionality. @@ -25,188 +13,6 @@ type OpClient struct { *evmClient.SDKClient } -func (c *OpClient) ParseOps( - tx *evmClient.LoadedTransaction, -) ([]*RosettaTypes.Operation, error) { - var ops []*RosettaTypes.Operation - - if tx.Receipt.Type == L1ToL2DepositType && len(tx.Trace) > 0 && tx.Transaction.IsSystemTx() { - trace := tx.Trace[0] - traceType := strings.ToUpper(trace.Type) - opStatus := sdkTypes.SuccessStatus - from := evmClient.MustChecksum(trace.From.String()) - to := evmClient.MustChecksum(trace.To.String()) - metadata := map[string]interface{}{} - - if from != to { - feeOps, err := handlers.FeeOps(tx) - if err != nil { - return nil, err - } - ops = append(ops, feeOps...) - } - - toOp := &RosettaTypes.Operation{ - OperationIdentifier: &RosettaTypes.OperationIdentifier{ - Index: int64(len(ops) + 0), - }, - Type: traceType, - Status: RosettaTypes.String(opStatus), - Account: &RosettaTypes.AccountIdentifier{ - Address: to, - }, - Amount: &RosettaTypes.Amount{ - Value: trace.Value.String(), - Currency: sdkTypes.Currency, - }, - Metadata: metadata, - } - ops = append(ops, toOp) - return ops, nil - } - - feeOps, err := handlers.FeeOps(tx) - if err != nil { - return nil, err - } - ops = append(ops, feeOps...) - - ops = append(ops, handlers.MintOps(tx, len(ops))...) - // ops = append(ops, handlers.BurnOps(tx, len(ops))...) - traceOps := services.TraceOps(tx.Trace, len(ops)) - ops = append(ops, traceOps...) - - return ops, nil -} - -func (c *OpClient) GetBlockReceipts( - ctx context.Context, - blockHash common.Hash, - txs []evmClient.RPCTransaction, - baseFee *big.Int, -) ([]*evmClient.RosettaTxReceipt, error) { - receipts := make([]*evmClient.RosettaTxReceipt, len(txs)) - if len(txs) == 0 { - return receipts, nil - } - - ethReceipts := make([]*EthTypes.Receipt, len(txs)) - reqs := make([]rpc.BatchElem, len(txs)) - for i := range reqs { - reqs[i] = rpc.BatchElem{ - Method: "eth_getTransactionReceipt", - Args: []interface{}{txs[i].TxExtraInfo.TxHash.String()}, - Result: ðReceipts[i], - } - } - - maxBatchSize := 25 - for i := 0; i < len(txs); i += maxBatchSize { - if i+maxBatchSize < len(txs) { - if err := c.BatchCallContext(ctx, reqs[i:i+maxBatchSize]); err != nil { - return nil, err - } - } else { - if err := c.BatchCallContext(ctx, reqs[i:]); err != nil { - return nil, err - } - } - } - - for i := range reqs { - if reqs[i].Error != nil { - return nil, reqs[i].Error - } - - gasPrice, err := evmClient.EffectiveGasPrice(txs[i].Tx, baseFee) - if err != nil { - return nil, err - } - gasUsed := new(big.Int).SetUint64(ethReceipts[i].GasUsed) - feeAmount := new(big.Int).Mul(gasUsed, gasPrice) - if ethReceipts[i].L1Fee != nil { - feeAmount.Add(feeAmount, ethReceipts[i].L1Fee) - } - - receiptJSON, err := ethReceipts[i].MarshalJSON() - if err != nil { - return nil, fmt.Errorf("unable to marshal receipt for %x: %v", txs[i].Tx.Hash().Hex(), err) - } - receipt := &evmClient.RosettaTxReceipt{ - Type: ethReceipts[i].Type, - GasPrice: gasPrice, - GasUsed: gasUsed, - Logs: ethReceipts[i].Logs, - // This is a hack to get around the fact that the RosettaTxReceipt doesn't contain L1 fees. We add the raw receipt here so we can access other rollup fields later - RawMessage: receiptJSON, - TransactionFee: feeAmount, - } - - receipts[i] = receipt - - if ethReceipts[i] == nil { - return nil, fmt.Errorf("got empty receipt for %x", txs[i].Tx.Hash().Hex()) - } - - if ethReceipts[i].BlockHash != blockHash { - return nil, fmt.Errorf( - "%w: expected block hash %s for Transaction but got %s", - sdkTypes.ErrClientBlockOrphaned, - blockHash.Hex(), - ethReceipts[i].BlockHash.Hex(), - ) - } - } - - return receipts, nil -} - -func (c *OpClient) GetTransactionReceipt( - ctx context.Context, - tx *evmClient.LoadedTransaction, -) (*evmClient.RosettaTxReceipt, error) { - var r *EthTypes.Receipt - err := c.CallContext(ctx, &r, "eth_getTransactionReceipt", tx.TxHash) - if err == nil { - if r == nil { - return nil, ethereum.NotFound - } - } - gasPrice, err := evmClient.EffectiveGasPrice(tx.Transaction, tx.BaseFee) - if err != nil { - return nil, err - } - gasUsed := new(big.Int).SetUint64(r.GasUsed) - feeAmount := new(big.Int).Mul(gasUsed, gasPrice) - if r.L1Fee != nil { - feeAmount.Add(feeAmount, r.L1Fee) - } - - return &evmClient.RosettaTxReceipt{ - GasPrice: gasPrice, - GasUsed: gasUsed, - Logs: r.Logs, - RawMessage: nil, - TransactionFee: feeAmount, - }, err -} - -// GetNativeTransferGasLimit is Ethereum's custom implementation of estimating gas. -func (c *OpClient) GetNativeTransferGasLimit(ctx context.Context, toAddress string, - fromAddress string, value *big.Int) (uint64, error) { - if len(toAddress) == 0 || value == nil { - // We guard against malformed inputs that may have been generated using - // a previous version of asset's rosetta - return 21000, nil - } - to := common.HexToAddress(toAddress) - return c.EstimateGas(ctx, ethereum.CallMsg{ - From: common.HexToAddress(fromAddress), - To: &to, - Value: value, - }) -} - // NewOpClient creates a client that can interact with the Optimism network. func NewOpClient(cfg *configuration.Configuration) (*OpClient, error) { client, err := evmClient.NewClient(cfg, nil) diff --git a/pkg/client/client_blocks.go b/pkg/client/client_blocks.go new file mode 100644 index 0000000..63e3872 --- /dev/null +++ b/pkg/client/client_blocks.go @@ -0,0 +1,96 @@ +package client + +import ( + "context" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/rpc" + + evmClient "github.com/coinbase/rosetta-geth-sdk/client" + sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" + EthTypes "github.com/ethereum/go-ethereum/core/types" +) + +func (c *OpClient) GetBlockReceipts( + ctx context.Context, + blockHash common.Hash, + txs []evmClient.RPCTransaction, + baseFee *big.Int, +) ([]*evmClient.RosettaTxReceipt, error) { + receipts := make([]*evmClient.RosettaTxReceipt, len(txs)) + if len(txs) == 0 { + return receipts, nil + } + + ethReceipts := make([]*EthTypes.Receipt, len(txs)) + reqs := make([]rpc.BatchElem, len(txs)) + for i := range reqs { + reqs[i] = rpc.BatchElem{ + Method: "eth_getTransactionReceipt", + Args: []interface{}{txs[i].TxExtraInfo.TxHash.String()}, + Result: ðReceipts[i], + } + } + + maxBatchSize := 25 + for i := 0; i < len(txs); i += maxBatchSize { + if i+maxBatchSize < len(txs) { + if err := c.BatchCallContext(ctx, reqs[i:i+maxBatchSize]); err != nil { + return nil, err + } + } else { + if err := c.BatchCallContext(ctx, reqs[i:]); err != nil { + return nil, err + } + } + } + + for i := range reqs { + if reqs[i].Error != nil { + return nil, reqs[i].Error + } + + gasPrice, err := evmClient.EffectiveGasPrice(txs[i].Tx, baseFee) + if err != nil { + return nil, err + } + gasUsed := new(big.Int).SetUint64(ethReceipts[i].GasUsed) + feeAmount := new(big.Int).Mul(gasUsed, gasPrice) + if ethReceipts[i].L1Fee != nil { + feeAmount.Add(feeAmount, ethReceipts[i].L1Fee) + } + + receiptJSON, err := ethReceipts[i].MarshalJSON() + if err != nil { + return nil, fmt.Errorf("unable to marshal receipt for %x: %v", txs[i].Tx.Hash().Hex(), err) + } + receipt := &evmClient.RosettaTxReceipt{ + Type: ethReceipts[i].Type, + GasPrice: gasPrice, + GasUsed: gasUsed, + Logs: ethReceipts[i].Logs, + // This is a hack to get around the fact that the RosettaTxReceipt doesn't contain L1 fees. We add the raw receipt here so we can access other rollup fields later + RawMessage: receiptJSON, + TransactionFee: feeAmount, + } + + receipts[i] = receipt + + if ethReceipts[i] == nil { + return nil, fmt.Errorf("got empty receipt for %x", txs[i].Tx.Hash().Hex()) + } + + if ethReceipts[i].BlockHash != blockHash { + return nil, fmt.Errorf( + "%w: expected block hash %s for Transaction but got %s", + sdkTypes.ErrClientBlockOrphaned, + blockHash.Hex(), + ethReceipts[i].BlockHash.Hex(), + ) + } + } + + return receipts, nil +} diff --git a/pkg/client/client_gas.go b/pkg/client/client_gas.go new file mode 100644 index 0000000..54d4a47 --- /dev/null +++ b/pkg/client/client_gas.go @@ -0,0 +1,25 @@ +package client + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" +) + +// GetNativeTransferGasLimit is Ethereum's custom implementation of estimating gas. +func (c *OpClient) GetNativeTransferGasLimit(ctx context.Context, toAddress string, + fromAddress string, value *big.Int) (uint64, error) { + if len(toAddress) == 0 || value == nil { + // We guard against malformed inputs that may have been generated using + // a previous version of asset's rosetta + return 21000, nil + } + to := common.HexToAddress(toAddress) + return c.EstimateGas(ctx, ethereum.CallMsg{ + From: common.HexToAddress(fromAddress), + To: &to, + Value: value, + }) +} diff --git a/pkg/client/client_ops.go b/pkg/client/client_ops.go new file mode 100644 index 0000000..95a680b --- /dev/null +++ b/pkg/client/client_ops.go @@ -0,0 +1,69 @@ +package client + +import ( + "strings" + + "github.com/mdehoog/op-rosetta/pkg/handlers" + + evmClient "github.com/coinbase/rosetta-geth-sdk/client" + "github.com/coinbase/rosetta-geth-sdk/services" + sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" + RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" +) + +// ParseOps must be implemented by downstream clients from the [evmClient.SDKClient]. +// This method is called by the [evmClient.SDKClient] when populating Block Transactions. +// See [evmClient.SDKClient.PopulateTransactions] for usage. +func (c *OpClient) ParseOps( + tx *evmClient.LoadedTransaction, +) ([]*RosettaTypes.Operation, error) { + var ops []*RosettaTypes.Operation + + if tx.Receipt.Type == L1ToL2DepositType && len(tx.Trace) > 0 && tx.Transaction.IsSystemTx() { + trace := tx.Trace[0] + traceType := strings.ToUpper(trace.Type) + opStatus := sdkTypes.SuccessStatus + from := evmClient.MustChecksum(trace.From.String()) + to := evmClient.MustChecksum(trace.To.String()) + metadata := map[string]interface{}{} + + if from != to { + feeOps, err := handlers.FeeOps(tx) + if err != nil { + return nil, err + } + ops = append(ops, feeOps...) + } + + toOp := &RosettaTypes.Operation{ + OperationIdentifier: &RosettaTypes.OperationIdentifier{ + Index: int64(len(ops) + 0), + }, + Type: traceType, + Status: RosettaTypes.String(opStatus), + Account: &RosettaTypes.AccountIdentifier{ + Address: to, + }, + Amount: &RosettaTypes.Amount{ + Value: trace.Value.String(), + Currency: sdkTypes.Currency, + }, + Metadata: metadata, + } + ops = append(ops, toOp) + return ops, nil + } + + feeOps, err := handlers.FeeOps(tx) + if err != nil { + return nil, err + } + ops = append(ops, feeOps...) + + ops = append(ops, handlers.MintOps(tx, len(ops))...) + // ops = append(ops, handlers.BurnOps(tx, len(ops))...) + traceOps := services.TraceOps(tx.Trace, len(ops)) + ops = append(ops, traceOps...) + + return ops, nil +} diff --git a/pkg/client/client_receipts.go b/pkg/client/client_receipts.go new file mode 100644 index 0000000..0c4f996 --- /dev/null +++ b/pkg/client/client_receipts.go @@ -0,0 +1,42 @@ +package client + +import ( + "context" + "math/big" + + "github.com/ethereum/go-ethereum" + + evmClient "github.com/coinbase/rosetta-geth-sdk/client" + EthTypes "github.com/ethereum/go-ethereum/core/types" +) + +// GetTransactionReceipt returns the receipt for an [evmClient.LoadedTransaction]. +func (c *OpClient) GetTransactionReceipt( + ctx context.Context, + tx *evmClient.LoadedTransaction, +) (*evmClient.RosettaTxReceipt, error) { + var r *EthTypes.Receipt + err := c.CallContext(ctx, &r, "eth_getTransactionReceipt", tx.TxHash) + if err == nil { + if r == nil { + return nil, ethereum.NotFound + } + } + gasPrice, err := evmClient.EffectiveGasPrice(tx.Transaction, tx.BaseFee) + if err != nil { + return nil, err + } + gasUsed := new(big.Int).SetUint64(r.GasUsed) + feeAmount := new(big.Int).Mul(gasUsed, gasPrice) + if r.L1Fee != nil { + feeAmount.Add(feeAmount, r.L1Fee) + } + + return &evmClient.RosettaTxReceipt{ + GasPrice: gasPrice, + GasUsed: gasUsed, + Logs: r.Logs, + RawMessage: nil, + TransactionFee: feeAmount, + }, err +} diff --git a/pkg/handlers/burn_test.go b/pkg/handlers/burn_test.go index f23d876..cd7fe7c 100644 --- a/pkg/handlers/burn_test.go +++ b/pkg/handlers/burn_test.go @@ -24,8 +24,6 @@ func TestBurn(t *testing.T) { // TestInvalidDestination tests that a [evmClient.LoadedTransaction] with an invalid destination is not a burn. func (testSuite *BurnTestSuite) TestInvalidDestination() { - // dest := handlers.L2ToL1MessagePasser - // Construct a loaded transaction with an invalid burn destination (not L2ToL1MessagePasser). h := gethCommon.HexToHash("0xb358c6958b1cab722752939cbb92e3fec6b6023de360305910ce80c56c3dad9d") gasPrice := big.NewInt(10000) @@ -71,7 +69,7 @@ func (testSuite *BurnTestSuite) TestValidBurn() { Transaction: myTx, } - // BurnOps should return nil for a transaction with an invalid destination. + // BurnOps should successfully construct a BurnOp for a transaction with the correct destination. ops := handlers.BurnOps(loadedTxn, index) testSuite.Equal(ops, []*RosettaTypes.Operation{ { diff --git a/pkg/handlers/mint_test.go b/pkg/handlers/mint_test.go new file mode 100644 index 0000000..7b812f0 --- /dev/null +++ b/pkg/handlers/mint_test.go @@ -0,0 +1,88 @@ +package handlers_test + +import ( + "math/big" + "testing" + + evmClient "github.com/coinbase/rosetta-geth-sdk/client" + sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" + RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" + gethCommon "github.com/ethereum/go-ethereum/common" + EthTypes "github.com/ethereum/go-ethereum/core/types" + handlers "github.com/mdehoog/op-rosetta/pkg/handlers" + suite "github.com/stretchr/testify/suite" +) + +type MintTestSuite struct { + suite.Suite +} + +// TestMint runs the MintTestSuite. +func TestMint(t *testing.T) { + suite.Run(t, new(MintTestSuite)) +} + +// TestInvalidDeposit tests that a non-deposit [evmClient.LoadedTransaction] is not handled by MintOps. +func (testSuite *MintTestSuite) TestInvalidDeposit() { + // Construct a random transaction (non-DepositTx) + h := gethCommon.HexToHash("0xb358c6958b1cab722752939cbb92e3fec6b6023de360305910ce80c56c3dad9d") + gasPrice := big.NewInt(10000) + myTx := EthTypes.NewTransaction( + 0, + gethCommon.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), + big.NewInt(0), + 0, + gasPrice, + nil, + ) + loadedTxn := &evmClient.LoadedTransaction{ + TxHash: &h, + Transaction: myTx, + } + + // MintOps should return nil for non-min transactions. + ops := handlers.MintOps(loadedTxn, 0) + testSuite.Nil(ops) +} + +// TestValidMint tests that [handlers.MintOps] correctly constructs [RosettaTypes.Operation], +// given a [evmClient.LoadedTransaction] with a Mint transaction. +func (testSuite *MintTestSuite) TestValidMint() { + // Construct a loaded mint transaction. + // Note: this hash is incorrect and was hijacked from the above transaction. + h := gethCommon.HexToHash("0xb358c6958b1cab722752939cbb92e3fec6b6023de360305910ce80c56c3dad9d") + gasPrice := big.NewInt(10000) + amount := big.NewInt(100) + index := 1 + to := gethCommon.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") + myTx := EthTypes.DepositTx{ + From: gethCommon.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87"), + Value: amount, + To: &to, + Mint: amount, + Gas: gasPrice.Uint64(), + IsSystemTransaction: false, + } + from := gethCommon.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") + loadedTxn := &evmClient.LoadedTransaction{ + From: &from, + TxHash: &h, + Transaction: EthTypes.NewTx(&myTx), + } + + // MintOps should successfully construct a Mint operation. + ops := handlers.MintOps(loadedTxn, index) + testSuite.Equal(ops, []*RosettaTypes.Operation{ + { + OperationIdentifier: &RosettaTypes.OperationIdentifier{ + Index: int64(index), + }, + Type: handlers.MintOpType, + Status: RosettaTypes.String(sdkTypes.SuccessStatus), + Account: &RosettaTypes.AccountIdentifier{ + Address: from.String(), + }, + Amount: evmClient.Amount(amount, sdkTypes.Currency), + }, + }) +} From 7f9133bdf8be081b37286ff25c5d31cbebc5c967 Mon Sep 17 00:00:00 2001 From: Andreas Bigger Date: Mon, 30 Jan 2023 15:05:32 -0500 Subject: [PATCH 3/5] feat: refactoring and improvements --- configs/optimism/goerli.json | 2 +- pkg/client/client_ops.go | 3 +- pkg/common/hash.go | 13 ++++ pkg/{topics => common}/topic_test.go | 19 +++--- pkg/common/topics.go | 23 +++++++ pkg/common/types.go | 91 ++++++++++++++++++++++++++++ pkg/common/types_test.go | 38 ++++++++++++ pkg/handlers/burn.go | 5 +- pkg/handlers/burn_test.go | 5 +- pkg/handlers/common.go | 42 ------------- pkg/handlers/erc20_bridge.go | 61 +++++++++++++++++++ pkg/handlers/erc20_bridge_test.go | 22 +++++++ pkg/handlers/fees.go | 9 +-- pkg/handlers/mint.go | 5 +- pkg/handlers/mint_test.go | 3 +- pkg/topics/topics.go | 27 --------- pkg/utils/types.go | 7 +-- 17 files changed, 279 insertions(+), 96 deletions(-) create mode 100644 pkg/common/hash.go rename pkg/{topics => common}/topic_test.go (66%) create mode 100644 pkg/common/topics.go create mode 100644 pkg/common/types.go create mode 100644 pkg/common/types_test.go delete mode 100644 pkg/handlers/common.go create mode 100644 pkg/handlers/erc20_bridge.go create mode 100644 pkg/handlers/erc20_bridge_test.go delete mode 100644 pkg/topics/topics.go diff --git a/configs/optimism/goerli.json b/configs/optimism/goerli.json index d910950..245f1cf 100644 --- a/configs/optimism/goerli.json +++ b/configs/optimism/goerli.json @@ -23,7 +23,7 @@ "data": { "start_index": 4307133, "reconciliation_disabled": false, - "inactive_discrepancy_search_disabled": false, + "inactive_discrepancy_search_disabled": true, "balance_tracking_disabled": false, "initial_balance_fetch_disabled": false, "active_reconciliation_concurrency": 32, diff --git a/pkg/client/client_ops.go b/pkg/client/client_ops.go index 95a680b..2ecfe83 100644 --- a/pkg/client/client_ops.go +++ b/pkg/client/client_ops.go @@ -3,12 +3,11 @@ package client import ( "strings" - "github.com/mdehoog/op-rosetta/pkg/handlers" - evmClient "github.com/coinbase/rosetta-geth-sdk/client" "github.com/coinbase/rosetta-geth-sdk/services" sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" + "github.com/mdehoog/op-rosetta/pkg/handlers" ) // ParseOps must be implemented by downstream clients from the [evmClient.SDKClient]. diff --git a/pkg/common/hash.go b/pkg/common/hash.go new file mode 100644 index 0000000..465e844 --- /dev/null +++ b/pkg/common/hash.go @@ -0,0 +1,13 @@ +package common + +import ( + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" +) + +// Keccak256 computes the keccak256 hash of the given string. +// Encodes the resulting hash as a hex string with a 0x prefix. +func Keccak256(s string) string { + keccak := crypto.Keccak256([]byte(s)) + return hexutil.Encode(keccak) +} diff --git a/pkg/topics/topic_test.go b/pkg/common/topic_test.go similarity index 66% rename from pkg/topics/topic_test.go rename to pkg/common/topic_test.go index a28a14a..b761842 100644 --- a/pkg/topics/topic_test.go +++ b/pkg/common/topic_test.go @@ -1,13 +1,14 @@ -package topics_test +package common_test import ( "testing" - "github.com/ethereum-optimism/optimism/l2geth/common" - "github.com/ethereum-optimism/optimism/l2geth/core/types" + gethCommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" - "github.com/mdehoog/op-rosetta/pkg/topics" + "github.com/mdehoog/op-rosetta/pkg/common" + "github.com/stretchr/testify/suite" ) @@ -23,10 +24,10 @@ func TestTopics(t *testing.T) { // ERC20_TRANSFER_EVENT_HASH is the keccak256 hash of the Transfer(address,address,uint256) event. const ERC20_TRANSFER_EVENT_HASH = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" -// TestEncodeEventString tests encoding an event topic string. -func (testSuite *TopicTestSuite) TestEncodeEventString() { +// TestHashEvent tests encoding an event topic string. +func (testSuite *TopicTestSuite) TestHashEvent() { topicString := "Transfer(address,address,uint256)" - encoded := topics.EncodeEventString(topicString) + encoded := common.Keccak256(topicString) testSuite.Equal(ERC20_TRANSFER_EVENT_HASH, encoded) } @@ -36,6 +37,6 @@ func (testSuite *TopicTestSuite) TestContainsTopic() { keccak := crypto.Keccak256([]byte(topicString)) encodedTransferMethod := hexutil.Encode(keccak) testSuite.Equal(ERC20_TRANSFER_EVENT_HASH, encodedTransferMethod) - l := &types.Log{Topics: []common.Hash{common.HexToHash(ERC20_TRANSFER_EVENT_HASH)}} - topics.ContainsTopic(l, encodedTransferMethod) + l := &types.Log{Topics: []gethCommon.Hash{gethCommon.HexToHash(ERC20_TRANSFER_EVENT_HASH)}} + common.ContainsTopic(l, encodedTransferMethod) } diff --git a/pkg/common/topics.go b/pkg/common/topics.go new file mode 100644 index 0000000..0703ab8 --- /dev/null +++ b/pkg/common/topics.go @@ -0,0 +1,23 @@ +package common + +import ( + "github.com/ethereum/go-ethereum/core/types" +) + +// ContainsTopic tests if a log contains a given topic. +// It is expected that the topic is encoded as a hex string. +// To encode a topic string, use the below [EncodeEventString] function. +func ContainsTopic(log *types.Log, topic string) bool { + for _, t := range log.Topics { + hex := t.Hex() + if hex == topic { + return true + } + } + return false +} + +// HashEvent encodes an event string into a topic hash. +func HashEvent(topic string) string { + return Keccak256(topic) +} diff --git a/pkg/common/types.go b/pkg/common/types.go new file mode 100644 index 0000000..810c1c1 --- /dev/null +++ b/pkg/common/types.go @@ -0,0 +1,91 @@ +// Package common contains constants and types used across op-rosetta. +package common + +import ( + "github.com/ethereum/go-ethereum/common" +) + +// Op Types +const ( + // MintOpType is a [RosettaTypes.Operation] type for an Optimism Deposit or "mint" transaction. + MintOpType = "MINT" + // BurnOpType is a [RosettaTypes.Operation] type for an Optimism Withdrawal or "burn" transaction. + BurnOpType = "BURN" + // An erroneous STOP Type not defined in rosetta-geth-sdk + StopOpType = "STOP" +) + +// Event Topics +const ( + // - If the token is an native token being *sent* to a non-native chain (in either direction), then you should expect an `ERC20BridgeInitiated` event alongside a `Transfer` event FROM the sender TO the bridge contract. + // - If the token is a non-native token being *sent* to a native chain (in either direction), then you should expect an `ERC20BridgeInitiated` event alongside a `Burn` event FROM the sender. + // - If the token is a native token being *received* on a non-native chain (in either direction), then you should expect an `ERC20BridgeFinalized` event alongside a `Mint` event TO the sender. + // - If the token is a non-native token being *received* on a native chain (in either direction), then you should expect an `ERC20BridgeFinalized` event alongside a `Transfer` event FROM the bridge contract TO the sender. + + // TransferEvent is emitted when an ERC20 token is transferred. + // + // TransferEvent is emitted in two bridging scenarios: + // 1. When a native token is being sent to a non-native chain, from the sender to the bridge contract. + // Think: Transferring USDC on Ethereum Mainnet to the Optimism bridge contract, + // you will see a Transfer event from the sender (you) to the bridge contract. + // 2. When a non-native token is being sent to a native chain, from the bridge to the sender contract. + // Think: "Withdrawing" USDC from Optimism to Ethereum Mainnet. You will see a Transfer event + // from the bridge contract to you (the sender) once the withdrawal is finalized on Mainnet. + TransferEvent = "Transfer(address,address,uint256)" + + // ERC20BridgeInitiatedEvent is the topic for the ERC20BridgeInitiated event. + // It is emitted on the originating chain where a bridge is initiated. + ERC20BridgeInitiatedEvent = "ERC20BridgeInitiated(address,address,address,address,uint256,bytes)" + + // ERC20BridgeFinalizedEvent is the topic for the ERC20BridgeFinalized event. + // It is emitted on the destination chain where a bridge is finalized. + ERC20BridgeFinalizedEvent = "ERC20BridgeFinalized(address,address,address,address,uint256,bytes)" + + // Burn event is emitted when a non-native token is being sent to a native chain. + // For example, consider Bob bridged 100 Token A (native to Ethereum Mainnet) from Ethereum Mainnet to Optimism. + // Bob now has 100 Token A on Optimism. He then bridges 100 Token A from Optimism to Ethereum Mainnet. + // In this case, Bob is bridging a non-native token (Token A) from Optimism to the token's native chain (Ethereum Mainnet). + // In this case, an ERC20BridgeInitiated event will be emitted alongside a Burn event FROM the sender. + BurnEvent = "Burn(address,uint256)" + + // Mint event is emitted when a non-native token is being sent to a native chain. + // For example, consider Bob is bridging 100 Token A (native to Ethereum Mainnet) from Ethereum Mainnet to Optimism. + // Bob will see a Mint event on Optimism TO the sender (Bob). + MintEvent = "Mint(address,uint256)" +) + +// Optimism Deployed Contracts +var ( + // L1StandardBridge is the Ethereum Mainnet Standard Bridge contract deployment. + // + L1StandardBridge = common.HexToAddress("0x25ace71c97B33Cc4729CF772ae268934F7ab5fA1") +) + +// Optimism Predeploy Addresses (represented as 0x-prefixed hex string) +// See [PredeployedContracts] for more information. +// +// [PredeployedContracts]: https://github.com/ethereum-optimism/optimism/blob/d8e328ae936c6a5f3987c04cbde7bd94403a96a0/specs/predeploys.md +var ( + // The BaseFeeVault predeploy receives the basefees on L2. + // The basefee is not burnt on L2 like it is on L1. + // Once the contract has received a certain amount of fees, + // the ETH can be permissionlessly withdrawn to an immutable address on L1. + BaseFeeVault = common.HexToAddress("0x4200000000000000000000000000000000000019") + + // The L1FeeVault predeploy receives the L1 portion of the transaction fees. + // Once the contract has received a certain amount of fees, + // the ETH can be permissionlessly withdrawn to an immutable address on L1. + L1FeeVault = common.HexToAddress("0x420000000000000000000000000000000000001a") + + // The L2ToL1MessagePasser stores commitments to withdrawal transactions. + // When a user is submitting the withdrawing transaction on L1, + // they provide a proof that the transaction that they withdrew on L2 is in + // the sentMessages mapping of this contract. + // + // Any withdrawn ETH accumulates into this contract on L2 and can be + // permissionlessly removed from the L2 supply by calling the burn() function. + L2ToL1MessagePasser = common.HexToAddress("0x4200000000000000000000000000000000000016") + + // The L2StandardBridge predeploy is the contract on L2 used to bridge assets to L1. + L2StandardBridge = common.HexToAddress("0x4200000000000000000000000000000000000010") +) diff --git a/pkg/common/types_test.go b/pkg/common/types_test.go new file mode 100644 index 0000000..502fa6f --- /dev/null +++ b/pkg/common/types_test.go @@ -0,0 +1,38 @@ +package common_test + +import ( + "testing" + + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/mdehoog/op-rosetta/pkg/common" + suite "github.com/stretchr/testify/suite" +) + +type CommonTestSuite struct { + suite.Suite +} + +// TestCommon runs the CommonTestSuite. +func TestCommon(t *testing.T) { + suite.Run(t, new(CommonTestSuite)) +} + +func hash(s string) string { + keccak := crypto.Keccak256([]byte(s)) + return hexutil.Encode(keccak) +} + +// TestEventTopics tests that the event strings are correctly hashed to their topics. +func (testSuite *CommonTestSuite) TestEventTopics() { + burnEventHash := "0xcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca5" + mintEventHash := "0x0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d4121396885" + transferEventHash := "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" + erc20BridgeInitiatedEventHash := "0x7ff126db8024424bbfd9826e8ab82ff59136289ea440b04b39a0df1b03b9cabf" + erc20BridgeFinalizedEventHash := "0xd59c65b35445225835c83f50b6ede06a7be047d22e357073e250d9af537518cd" + testSuite.Equal(hash(common.BurnEvent), burnEventHash) + testSuite.Equal(hash(common.MintEvent), mintEventHash) + testSuite.Equal(hash(common.TransferEvent), transferEventHash) + testSuite.Equal(hash(common.ERC20BridgeInitiatedEvent), erc20BridgeInitiatedEventHash) + testSuite.Equal(hash(common.ERC20BridgeFinalizedEvent), erc20BridgeFinalizedEventHash) +} diff --git a/pkg/handlers/burn.go b/pkg/handlers/burn.go index 4ca8b5a..5339acb 100644 --- a/pkg/handlers/burn.go +++ b/pkg/handlers/burn.go @@ -4,11 +4,12 @@ import ( evmClient "github.com/coinbase/rosetta-geth-sdk/client" sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" + common "github.com/mdehoog/op-rosetta/pkg/common" ) // BurnOps constructs a list of [RosettaTypes.Operation]s for an Optimism Withdrawal or "burn" transaction. func BurnOps(tx *evmClient.LoadedTransaction, startIndex int) []*RosettaTypes.Operation { - if *tx.Transaction.To() != L2ToL1MessagePasser { + if *tx.Transaction.To() != common.L2ToL1MessagePasser { return nil } return []*RosettaTypes.Operation{ @@ -16,7 +17,7 @@ func BurnOps(tx *evmClient.LoadedTransaction, startIndex int) []*RosettaTypes.Op OperationIdentifier: &RosettaTypes.OperationIdentifier{ Index: int64(startIndex), }, - Type: BurnOpType, + Type: common.BurnOpType, Status: RosettaTypes.String(sdkTypes.SuccessStatus), Account: &RosettaTypes.AccountIdentifier{ Address: tx.From.String(), diff --git a/pkg/handlers/burn_test.go b/pkg/handlers/burn_test.go index cd7fe7c..2de2451 100644 --- a/pkg/handlers/burn_test.go +++ b/pkg/handlers/burn_test.go @@ -9,6 +9,7 @@ import ( RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" gethCommon "github.com/ethereum/go-ethereum/common" EthTypes "github.com/ethereum/go-ethereum/core/types" + common "github.com/mdehoog/op-rosetta/pkg/common" handlers "github.com/mdehoog/op-rosetta/pkg/handlers" suite "github.com/stretchr/testify/suite" ) @@ -56,7 +57,7 @@ func (testSuite *BurnTestSuite) TestValidBurn() { index := 1 myTx := EthTypes.NewTransaction( 0, - handlers.L2ToL1MessagePasser, + common.L2ToL1MessagePasser, amount, 0, gasPrice, @@ -76,7 +77,7 @@ func (testSuite *BurnTestSuite) TestValidBurn() { OperationIdentifier: &RosettaTypes.OperationIdentifier{ Index: int64(index), }, - Type: handlers.BurnOpType, + Type: common.BurnOpType, Status: RosettaTypes.String(sdkTypes.SuccessStatus), Account: &RosettaTypes.AccountIdentifier{ Address: from.String(), diff --git a/pkg/handlers/common.go b/pkg/handlers/common.go deleted file mode 100644 index 7e6be60..0000000 --- a/pkg/handlers/common.go +++ /dev/null @@ -1,42 +0,0 @@ -// Package handlers handles translating transactions into [RosettaTypes.Operation]s. -package handlers - -import ( - "github.com/ethereum/go-ethereum/common" -) - -const ( - // MintOpType is a [RosettaTypes.Operation] type for an Optimism Deposit or "mint" transaction. - MintOpType = "MINT" - // BurnOpType is a [RosettaTypes.Operation] type for an Optimism Withdrawal or "burn" transaction. - BurnOpType = "BURN" - - // An erroneous STOP Type not defined in rosetta-geth-sdk - StopOpType = "STOP" -) - -// Optimism Predeploy Addresses -// See [PredeployedContracts] for more information. -// -// [PredeployedContracts]: https://github.com/ethereum-optimism/optimism/blob/d8e328ae936c6a5f3987c04cbde7bd94403a96a0/specs/predeploys.md -var ( - // The BaseFeeVault predeploy receives the basefees on L2. - // The basefee is not burnt on L2 like it is on L1. - // Once the contract has received a certain amount of fees, - // the ETH can be permissionlessly withdrawn to an immutable address on L1. - BaseFeeVault = common.HexToAddress("0x4200000000000000000000000000000000000019") - - // The L1FeeVault predeploy receives the L1 portion of the transaction fees. - // Once the contract has received a certain amount of fees, - // the ETH can be permissionlessly withdrawn to an immutable address on L1. - L1FeeVault = common.HexToAddress("0x420000000000000000000000000000000000001a") - - // The L2ToL1MessagePasser stores commitments to withdrawal transactions. - // When a user is submitting the withdrawing transaction on L1, - // they provide a proof that the transaction that they withdrew on L2 is in - // the sentMessages mapping of this contract. - // - // Any withdrawn ETH accumulates into this contract on L2 and can be - // permissionlessly removed from the L2 supply by calling the burn() function. - L2ToL1MessagePasser = common.HexToAddress("0x4200000000000000000000000000000000000016") -) diff --git a/pkg/handlers/erc20_bridge.go b/pkg/handlers/erc20_bridge.go new file mode 100644 index 0000000..80973f6 --- /dev/null +++ b/pkg/handlers/erc20_bridge.go @@ -0,0 +1,61 @@ +package handlers + +import ( + evmClient "github.com/coinbase/rosetta-geth-sdk/client" + sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" + RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" + EthTypes "github.com/ethereum/go-ethereum/core/types" + "github.com/mdehoog/op-rosetta/pkg/common" +) + +// Erc20BridgeOps constructs a list of [RosettaTypes.Operation]s for ERC20 transactions when bridging. +func Erc20BridgeOps(tx *evmClient.LoadedTransaction, startIndex int) []*RosettaTypes.Operation { + ops := []*RosettaTypes.Operation{} + ops = append(ops, NativeInitializationOps(tx, startIndex)...) + + return ops +} + +// NativeInitializationOps constructs a list of [RosettaTypes.Operation]s for native token initializations. +// +// Native token initializations occur when a native token is being *sent* to a non-native chain. +// In this case, `ERC20BridgeInitiated` and `Transfer` events are emitted FROM the sender TO the bridge contract. +func NativeInitializationOps(tx *evmClient.LoadedTransaction, startIndex int) []*RosettaTypes.Operation { + // The bridge transaction must be sent to the [common.L2StandardBridge] + if *tx.Transaction.To() != common.L2StandardBridge { + return nil + } + + // Parse tx receipt logs + var receiptLogs []*EthTypes.Log + if tx.Receipt != nil { + receiptLogs = tx.Receipt.Logs + } + + // Grab the transfer log + var transferLog *EthTypes.Log + for _, log := range receiptLogs { + // Check if this is a transfer event + if common.ContainsTopic(log, common.TransferEvent) { + transferLog = log + } + } + if transferLog == (&EthTypes.Log{}) || transferLog == nil { + return nil + } + + // Return the associated operation + return []*RosettaTypes.Operation{ + { + OperationIdentifier: &RosettaTypes.OperationIdentifier{ + Index: int64(startIndex), + }, + Type: sdkTypes.OpErc20Transfer, + Status: RosettaTypes.String(sdkTypes.SuccessStatus), + Account: &RosettaTypes.AccountIdentifier{ + Address: tx.From.String(), + }, + Amount: evmClient.Erc20Amount(transferLog.Data, transferLog.Address, sdkTypes.Currency.Symbol, sdkTypes.Currency.Decimals, false), + }, + } +} diff --git a/pkg/handlers/erc20_bridge_test.go b/pkg/handlers/erc20_bridge_test.go new file mode 100644 index 0000000..59f3fe1 --- /dev/null +++ b/pkg/handlers/erc20_bridge_test.go @@ -0,0 +1,22 @@ +package handlers_test + +import ( + "testing" + + suite "github.com/stretchr/testify/suite" +) + +type Erc20BridgeTestSuite struct { + suite.Suite +} + +// TestErc20Bridging runs the Erc20BridgeTestSuite. +func TestErc20Bridging(t *testing.T) { + suite.Run(t, new(Erc20BridgeTestSuite)) +} + +// TestValidNativeInitialization tests that a valid ERC20 transfer was made to the L2StandardBridge contract. +// This is when a native token is being bridged from L2 to L1. +func (testSuite *Erc20BridgeTestSuite) TestValidNativeInitialization() { + // TODO: +} diff --git a/pkg/handlers/fees.go b/pkg/handlers/fees.go index cd20dee..7982652 100644 --- a/pkg/handlers/fees.go +++ b/pkg/handlers/fees.go @@ -1,13 +1,14 @@ +// Package handlers handles translating transactions into [RosettaTypes.Operation]s. package handlers import ( "math/big" evmClient "github.com/coinbase/rosetta-geth-sdk/client" + sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" EthTypes "github.com/ethereum/go-ethereum/core/types" - - sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" + common "github.com/mdehoog/op-rosetta/pkg/common" ) // FeeOps returns the fee operations for a given transaction. @@ -80,7 +81,7 @@ func FeeOps(tx *evmClient.LoadedTransaction) ([]*RosettaTypes.Operation, error) Type: sdkTypes.FeeOpType, Status: RosettaTypes.String(sdkTypes.SuccessStatus), Account: &RosettaTypes.AccountIdentifier{ - Address: BaseFeeVault.Hex(), + Address: common.BaseFeeVault.Hex(), }, // Note: The basefee is not actually burned on L2 Amount: evmClient.Amount(tx.FeeBurned, sdkTypes.Currency), @@ -98,7 +99,7 @@ func FeeOps(tx *evmClient.LoadedTransaction) ([]*RosettaTypes.Operation, error) Type: sdkTypes.FeeOpType, Status: RosettaTypes.String(sdkTypes.SuccessStatus), Account: &RosettaTypes.AccountIdentifier{ - Address: L1FeeVault.Hex(), + Address: common.L1FeeVault.Hex(), }, Amount: evmClient.Amount(receipt.L1Fee, sdkTypes.Currency), }, diff --git a/pkg/handlers/mint.go b/pkg/handlers/mint.go index b9f9778..0809ec4 100644 --- a/pkg/handlers/mint.go +++ b/pkg/handlers/mint.go @@ -4,7 +4,8 @@ import ( evmClient "github.com/coinbase/rosetta-geth-sdk/client" sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" - "github.com/ethereum/go-ethereum/log" + log "github.com/ethereum/go-ethereum/log" + common "github.com/mdehoog/op-rosetta/pkg/common" ) // MintOps constructs a list of [RosettaTypes.Operation]s for an Optimism Deposit or "mint" transaction. @@ -18,7 +19,7 @@ func MintOps(tx *evmClient.LoadedTransaction, startIndex int) []*RosettaTypes.Op OperationIdentifier: &RosettaTypes.OperationIdentifier{ Index: int64(startIndex), }, - Type: MintOpType, + Type: common.MintOpType, Status: RosettaTypes.String(sdkTypes.SuccessStatus), Account: &RosettaTypes.AccountIdentifier{ Address: tx.From.String(), diff --git a/pkg/handlers/mint_test.go b/pkg/handlers/mint_test.go index 7b812f0..84986a5 100644 --- a/pkg/handlers/mint_test.go +++ b/pkg/handlers/mint_test.go @@ -9,6 +9,7 @@ import ( RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" gethCommon "github.com/ethereum/go-ethereum/common" EthTypes "github.com/ethereum/go-ethereum/core/types" + common "github.com/mdehoog/op-rosetta/pkg/common" handlers "github.com/mdehoog/op-rosetta/pkg/handlers" suite "github.com/stretchr/testify/suite" ) @@ -77,7 +78,7 @@ func (testSuite *MintTestSuite) TestValidMint() { OperationIdentifier: &RosettaTypes.OperationIdentifier{ Index: int64(index), }, - Type: handlers.MintOpType, + Type: common.MintOpType, Status: RosettaTypes.String(sdkTypes.SuccessStatus), Account: &RosettaTypes.AccountIdentifier{ Address: from.String(), diff --git a/pkg/topics/topics.go b/pkg/topics/topics.go deleted file mode 100644 index 7112836..0000000 --- a/pkg/topics/topics.go +++ /dev/null @@ -1,27 +0,0 @@ -package topics - -import ( - "github.com/ethereum-optimism/optimism/l2geth/core/types" - "github.com/ethereum/go-ethereum/common/hexutil" - "github.com/ethereum/go-ethereum/crypto" -) - -// ContainsTopic tests if a log contains a given topic. -// It is expected that the topic is encoded as a hex string. -// To encode a topic string, use the below [EncodeEventString] function. -func ContainsTopic(log *types.Log, topic string) bool { - for _, t := range log.Topics { - hex := t.Hex() - if hex == topic { - return true - } - } - return false -} - -// EncodeEventString encodes a string into a topic. -func EncodeEventString(topicString string) string { - keccak := crypto.Keccak256([]byte(topicString)) - encodedTransferMethod := hexutil.Encode(keccak) - return encodedTransferMethod -} diff --git a/pkg/utils/types.go b/pkg/utils/types.go index d71fad7..0dade91 100644 --- a/pkg/utils/types.go +++ b/pkg/utils/types.go @@ -2,8 +2,7 @@ package utils import ( sdkTypes "github.com/coinbase/rosetta-geth-sdk/types" - - "github.com/mdehoog/op-rosetta/pkg/handlers" + common "github.com/mdehoog/op-rosetta/pkg/common" ) // LoadTypes loads the types for the Optimism Rosetta service. @@ -17,9 +16,9 @@ func LoadTypes() *sdkTypes.Types { } ots = append(ots, ot) } - ots = append(ots, handlers.MintOpType) + ots = append(ots, common.MintOpType) // ots = append(ots, handlers.BurnOpType) - ots = append(ots, handlers.StopOpType) + ots = append(ots, common.StopOpType) t.OperationTypes = ots return t From 54d8c30f7e6857ed94f6733d66a686e603209b20 Mon Sep 17 00:00:00 2001 From: Andreas Bigger Date: Mon, 30 Jan 2023 16:24:21 -0500 Subject: [PATCH 4/5] fix: remove redundant config --- configs/optimism/goerli.json | 1 + pkg/client/config.go | 209 ----------------------------------- 2 files changed, 1 insertion(+), 209 deletions(-) delete mode 100644 pkg/client/config.go diff --git a/configs/optimism/goerli.json b/configs/optimism/goerli.json index 245f1cf..65be0c3 100644 --- a/configs/optimism/goerli.json +++ b/configs/optimism/goerli.json @@ -27,6 +27,7 @@ "balance_tracking_disabled": false, "initial_balance_fetch_disabled": false, "active_reconciliation_concurrency": 32, + "historical_balance_disabled": false, "bootstrap_balances": "", "log_balance_changes": true, "log_transactions": true, diff --git a/pkg/client/config.go b/pkg/client/config.go deleted file mode 100644 index 7ca55f5..0000000 --- a/pkg/client/config.go +++ /dev/null @@ -1,209 +0,0 @@ -package client - -import ( - "encoding/json" - "errors" - "fmt" - "os" - "strconv" - - "github.com/ethereum/go-ethereum/params" - - "github.com/coinbase/rosetta-geth-sdk/configuration" - RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" -) - -const ( - // DefaultBlockchain is Optimism. - DefaultBlockchain string = "Optimism" - - // BlockchainEnv is the environment variable - // read to determine the blockchain. - BlockchainEnv = "BLOCKCHAIN" - - // Symbol is the symbol value - // used in Currency. - Symbol = "ETH" - - // Decimals is the decimals value - // used in Currency. - Decimals = 18 - - // Online is when the implementation is permitted - // to make outbound connections. - Online configuration.Mode = "ONLINE" - - // Offline is when the implementation is not permitted - // to make outbound connections. - Offline configuration.Mode = "OFFLINE" - - // ModeEnv is the environment variable read - // to determine mode. - ModeEnv = "MODE" - - // NetworkEnv is the environment variable - // read to determine network. - NetworkEnv = "NETWORK" - - // GenesisBlockHashEnv is the environment variable - // from which to read the genesis block hash. - GenesisBlockHashEnv = "GENESIS_BLOCK_HASH" - - // ChainConfigEnv is the environment variable from - // which to read the chain configuration, defined as - // JSON (or pointing to a JSON file). - ChainConfigEnv = "CHAIN_CONFIG" - - // PortEnv is the environment variable - // read to determine the port for the Rosetta - // implementation. - PortEnv = "PORT" - - // FilterTokensEnv is the environment variable - // read to determine if we will filter tokens - // using our token white list - FilterTokensEnv = "FILTER" - - // TokenListEnv is the environment variable - // from which to read the list of tokens, defined - // as JSON (or pointing to a JSON file). - TokenListEnv = "TOKENS" - - // GethEnv is an optional environment variable - // used to connect rosetta-ethereum to an already - // running geth node. - GethEnv = "GETH" - - // DefaultGethURL is the default URL for - // a running geth node. This is used - // when GethEnv is not populated. - DefaultGethURL = "http://127.0.0.1:8545" - - // SkipGethAdminEnv is an optional environment variable - // to skip geth `admin` calls which are typically not supported - // by hosted node services. When not set, defaults to false. - SkipGethAdminEnv = "SKIP_GETH_ADMIN" - - // GenesisBlockIndex is the index of the genesis block. - GenesisBlockIndex = int64(0) -) - -// LoadConfiguration attempts to create a new [configuration.Configuration] -// using environment variables. -func LoadConfiguration() (*configuration.Configuration, error) { - config := &configuration.Configuration{} - - mode := os.Getenv(ModeEnv) - modeValue := configuration.Mode(mode) - - switch modeValue { - case Online: - config.Mode = Online - case Offline: - config.Mode = Offline - case "": - return nil, fmt.Errorf("%s must be populated", ModeEnv) - default: - return nil, fmt.Errorf("%s is not a valid mode", modeValue) - } - - blockchain := os.Getenv(BlockchainEnv) - if blockchain == "" { - blockchain = DefaultBlockchain - } - - networkValue := os.Getenv(NetworkEnv) - genesisBlockHash := &RosettaTypes.BlockIdentifier{ - Index: GenesisBlockIndex, - Hash: os.Getenv(GenesisBlockHashEnv), - } - - chainConfigJson := os.Getenv(ChainConfigEnv) - if file, err := os.ReadFile(chainConfigJson); err == nil { - // if the envvar points to a file, read it; otherwise the envvar contents is expected to be JSON - chainConfigJson = string(file) - } - if chainConfigJson == "" { - return nil, fmt.Errorf("%s not set", ChainConfigEnv) - } - - chainConfig := ¶ms.ChainConfig{} - err := json.Unmarshal([]byte(chainConfigJson), &chainConfig) - if err != nil { - return nil, fmt.Errorf("unable to parse chain config: %w", err) - } - - config.Network = &RosettaTypes.NetworkIdentifier{ - Blockchain: blockchain, - Network: networkValue, - } - config.GenesisBlockIdentifier = genesisBlockHash - config.ChainConfig = chainConfig - - config.GethURL = DefaultGethURL - envGethURL := os.Getenv(GethEnv) - if len(envGethURL) > 0 { - config.RemoteGeth = true - config.GethURL = envGethURL - } - - config.SkipGethAdmin = false - envSkipGethAdmin := os.Getenv(SkipGethAdminEnv) - if len(envSkipGethAdmin) > 0 { - val, err := strconv.ParseBool(envSkipGethAdmin) - if err != nil { - return nil, fmt.Errorf("unable to parse SKIP_GETH_ADMIN %s: %w", envSkipGethAdmin, err) - } - config.SkipGethAdmin = val - } - - portValue := os.Getenv(PortEnv) - if len(portValue) == 0 { - return nil, errors.New("PORT must be populated") - } - - port, err := strconv.Atoi(portValue) - if err != nil || len(portValue) == 0 || port <= 0 { - return nil, fmt.Errorf("unable to parse port %s: %w", portValue, err) - } - config.Port = port - - filterTokens := true - filterTokensStr := os.Getenv(FilterTokensEnv) - if len(filterTokensStr) > 0 { - filterTokens, err = strconv.ParseBool(filterTokensStr) - if err != nil { - return nil, fmt.Errorf("unable to parse token filter %s: %w", filterTokensStr, err) - } - } - - tokenListJson := os.Getenv(TokenListEnv) - if file, err := os.ReadFile(tokenListJson); err == nil { - // if the envvar points to a file, read it; otherwise the envvar contents is expected to be JSON - tokenListJson = string(file) - } - if tokenListJson == "" { - tokenListJson = "[]" - } - - var payload []configuration.Token - err = json.Unmarshal([]byte(tokenListJson), &payload) - if err != nil { - return nil, fmt.Errorf("error parsing %s: %w", tokenListJson, err) - } - - config.RosettaCfg = configuration.RosettaConfig{ - SupportRewardTx: false, - TraceType: configuration.GethNativeTrace, - Currency: &RosettaTypes.Currency{ - Symbol: Symbol, - Decimals: Decimals, - }, - TracePrefix: "optrace", - FilterTokens: filterTokens, - TokenWhiteList: payload, - SupportsSyncing: true, - } - - return config, nil -} From 62ac17a89c88e522a771363b1acd8bf9eb2ee051 Mon Sep 17 00:00:00 2001 From: Andreas Bigger Date: Tue, 31 Jan 2023 12:46:04 -0500 Subject: [PATCH 5/5] feat: tests overhaul --- .env.example | 5 + Makefile | 11 +- configs/optimism/goerli.json | 14 +- configs/optimism/goerli.ros | 137 +++++++ configs/optimism/optimism.ros | 111 +++++ go.mod | 14 +- go.sum | 112 +---- pkg/client/client.go | 7 +- pkg/client/client_blocks.go | 2 + pkg/client/client_blocks_test.go | 115 ++++++ pkg/client/mocks/InternalClient.go | 629 +++++++++++++++++++++++++++++ pkg/client/types.go | 91 +++++ 12 files changed, 1134 insertions(+), 114 deletions(-) create mode 100644 configs/optimism/goerli.ros create mode 100644 configs/optimism/optimism.ros create mode 100644 pkg/client/client_blocks_test.go create mode 100644 pkg/client/mocks/InternalClient.go create mode 100644 pkg/client/types.go diff --git a/.env.example b/.env.example index 95ea49d..948f05b 100644 --- a/.env.example +++ b/.env.example @@ -11,3 +11,8 @@ OPTIMISM_GOERLI_NODE= # Optimism Mainnet Node URL OPTIMISM_MAINNET_NODE= +# Optimism Goerli Genesis Block Hash +OPTIMISM_GOERLI_GENESIS_BLOCK_HASH= + +# Optimism Mainnet Genesis Block Hash +OPTIMISM_MAINNET_GENESIS_BLOCK_HASH= \ No newline at end of file diff --git a/Makefile b/Makefile index 2305910..5bbf188 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ GOLINES_INSTALL=go install github.com/segmentio/golines@latest GOLINES_CMD=golines # Run the full pipeline -all: clean format build test lint +all: clean tidy format build test lint .PHONY: \ test \ tests \ @@ -31,6 +31,10 @@ all: clean format build test lint clean: rm -rf bin/op-rosetta +# Tidy the go mod +tidy: + go mod tidy + # Formatting with gofmt format: gofmt -s -w -l . @@ -87,7 +91,7 @@ run-optimism-goerli: GETH=${OPTIMISM_GOERLI_NODE} \ ENABLE_TRACE_CACHE=true \ ENABLE_GETH_TRACER=true \ - GENESIS_BLOCK_HASH=0x0f783549ea4313b784eadd9b8e8a69913b368b7366363ea814d7707ac505175f \ + GENESIS_BLOCK_HASH=${OPTIMISM_GOERLI_GENESIS_BLOCK_HASH} \ bin/op-rosetta ##################################################################################### @@ -106,7 +110,6 @@ run-optimism-mainnet-data-check: run-optimism-mainnet-construction-check: ROSETTA_CONFIGURATION_FILE=configs/optimism/mainnet.json rosetta-cli check:construction configs/optimism/mainnet.json -# TODO: Set the GENESIS_BLOCK_HASH value for this command # Runs an instance of `op-rosetta` configured for Optimism Mainnet # For the genesis block hash, see: # https://github.com/ethereum-optimism/optimism/blob/5e8bc3d5b4f36f0192b22b032e25b09f23cd0985/op-node/chaincfg/chains.go @@ -120,6 +123,6 @@ run-optimism-mainnet: ENABLE_TRACE_CACHE=true \ ENABLE_GETH_TRACER=true \ GETH=${OPTIMISM_MAINNET_NODE} \ - GENESIS_BLOCK_HASH= \ + GENESIS_BLOCK_HASH=${OPTIMISM_MAINNET_GENESIS_BLOCK_HASH} \ bin/op-rosetta diff --git a/configs/optimism/goerli.json b/configs/optimism/goerli.json index 65be0c3..26a0474 100644 --- a/configs/optimism/goerli.json +++ b/configs/optimism/goerli.json @@ -19,7 +19,19 @@ "all_in_memory_enabled": true, "table_size": 1, "value_log_file_size": 1024, - "construction": null, + "construction": { + "stale_depth": 3, + "broadcast_limit": 5, + "ignore_broadcast_failures": false, + "clear_broadcasts": true, + "constructor_dsl_file": "goerli.ros", + "quiet": false, + "initial_balance_fetch_disabled": false, + "end_conditions": { + "create_account": 10, + "transfer": 20 + } + }, "data": { "start_index": 4307133, "reconciliation_disabled": false, diff --git a/configs/optimism/goerli.ros b/configs/optimism/goerli.ros new file mode 100644 index 0000000..367f7c0 --- /dev/null +++ b/configs/optimism/goerli.ros @@ -0,0 +1,137 @@ +request_funds(1){ + find_account{ + currency = {"symbol":"ETH", "decimals":18}; + random_account = find_balance({ + "minimum_balance":{ + "value": "0", + "currency": {{currency}} + }, + "create_limit":1 + }); + }, + + // Create a separate scenario to request funds so that + // the address we are using to request funds does not + // get rolled back if funds do not yet exist. + request{ + loaded_account = find_balance({ + "account_identifier": {{random_account.account_identifier}}, + "minimum_balance":{ + "value": "10000000000000", + "currency": {{currency}} + } + }); + } +} + +create_account(1){ + create{ + network = {"network":"Goerli", "blockchain":"Optimism"}; + key = generate_key({"curve_type": "secp256k1"}); + account = derive({ + "network_identifier": {{network}}, + "public_key": {{key.public_key}} + }); + + // If the account is not saved, the key will be lost! + save_account({ + "account_identifier": {{account.account_identifier}}, + "keypair": {{key}} + }); + } +} + +transfer(1){ + transfer{ + transfer.network = {"network":"Goerli", "blockchain":"Optimism"}; + currency = {"symbol":"ETH", "decimals":18}; + sender = find_balance({ + "minimum_balance":{ + "value": "10000000000000", + "currency": {{currency}} + } + }); + + // Set the recipient_amount as some value <= sender.balance-max_fee + max_fee = "0"; + available_amount = {{sender.balance.value}} - {{max_fee}}; + recipient_amount = random_number({"minimum": "1", "maximum": {{available_amount}}}); + print_message({"recipient_amount":{{recipient_amount}}}); + + // Find recipient and construct operations + sender_amount = 0 - {{recipient_amount}}; + recipient = find_balance({ + "not_account_identifier":[{{sender.account_identifier}}], + "minimum_balance":{ + "value": "0", + "currency": {{currency}} + }, + "create_limit": 100, + "create_probability": 50 + }); + transfer.confirmation_depth = "1"; + transfer.operations = [ + { + "operation_identifier":{"index":0}, + "type":"CALL", + "account":{{sender.account_identifier}}, + "amount":{ + "value":{{sender_amount}}, + "currency":{{currency}} + } + }, + { + "operation_identifier":{"index":1}, + "type":"CALL", + "account":{{recipient.account_identifier}}, + "amount":{ + "value":{{recipient_amount}}, + "currency":{{currency}} + } + } + ]; + } +} + +return_funds(1){ + transfer{ + transfer.network = {"network":"Goerli", "blockchain":"Optimism"}; + currency = {"symbol":"ETH", "decimals":18}; + max_fee = "0"; + sender = find_balance({ + "minimum_balance":{ + "value": {{max_fee}}, + "currency": {{currency}} + } + }); + + // Set the recipient_amount as some sender.balance-max_fee + available_amount = {{sender.balance.value}} - {{max_fee}}; + print_message({"available_amount":{{available_amount}}}); + sender_amount = 0 - {{available_amount}}; + + // Provide a static address as the recipient and construct operations + faucet = {"address":"0xb41B39479a525AB69e38c701A713D98E3074252c"}; + transfer.confirmation_depth = "1"; + transfer.operations = [ + { + "operation_identifier":{"index":0}, + "type":"CALL", + "account":{{sender.account_identifier}}, + "amount":{ + "value":{{sender_amount}}, + "currency":{{currency}} + } + }, + { + "operation_identifier":{"index":1}, + "type":"CALL", + "account":{{faucet}}, + "amount":{ + "value":{{available_amount}}, + "currency":{{currency}} + } + } + ]; + } +} \ No newline at end of file diff --git a/configs/optimism/optimism.ros b/configs/optimism/optimism.ros new file mode 100644 index 0000000..5420ef7 --- /dev/null +++ b/configs/optimism/optimism.ros @@ -0,0 +1,111 @@ +create_account(1){ + create{ + network = {"network":"Goerli", "blockchain":"Optimism"}; + key = generate_key({"curve_type": "secp256k1"}); + account = derive({ + "network_identifier": {{network}}, + "public_key": {{key.public_key}} + }); + + // If the account is not saved, the key will be lost! + save_account({ + "account_identifier": {{account.account_identifier}}, + "keypair": {{key}} + }); + } +} + +transfer(10){ + transfer{ + transfer.network = {"network":"Goerli", "blockchain":"Optimism"}; + currency = {"symbol":"ETH", "decimals":18}; + sender = find_balance({ + "minimum_balance":{ + "value": "10000000000000000", + "currency": {{currency}} + } + }); + + // Set the recipient_amount as some value <= sender.balance-max_fee + max_fee = "84000000000000"; + available_amount = {{sender.balance.value}} - {{max_fee}}; + recipient_amount = random_number({"minimum": "1", "maximum": {{available_amount}}}); + print_message({"recipient_amount":{{recipient_amount}}}); + + // Find recipient and construct operations + sender_amount = 0 - {{recipient_amount}}; + recipient = find_balance({ + "not_account_identifier":[{{sender.account_identifier}}], + "minimum_balance":{ + "value": "0", + "currency": {{currency}} + }, + "create_limit": 100, + "create_probability": 50 + }); + transfer.confirmation_depth = "1"; + transfer.operations = [ + { + "operation_identifier":{"index":0}, + "type":"CALL", + "account":{{sender.account_identifier}}, + "amount":{ + "value":{{sender_amount}}, + "currency":{{currency}} + } + }, + { + "operation_identifier":{"index":1}, + "type":"CALL", + "account":{{recipient.account_identifier}}, + "amount":{ + "value":{{recipient_amount}}, + "currency":{{currency}} + } + } + ]; + } +} + +return_funds(10){ + transfer{ + transfer.network = {"network":"Goerli", "blockchain":"Optimism"}; + currency = {"symbol":"ETH", "decimals":18}; + max_fee = "84000000000000"; + sender = find_balance({ + "minimum_balance":{ + "value": {{max_fee}}, + "currency": {{currency}} + } + }); + + // Set the recipient_amount as some sender.balance-max_fee + available_amount = {{sender.balance.value}} - {{max_fee}}; + print_message({"available_amount":{{available_amount}}}); + sender_amount = 0 - {{available_amount}}; + + // Provide a static address as the recipient and construct operations + faucet = {"address":"0x9670d6977d0b10130E5d4916c9134363281B6B0e"}; + transfer.confirmation_depth = "1"; + transfer.operations = [ + { + "operation_identifier":{"index":0}, + "type":"CALL", + "account":{{sender.account_identifier}}, + "amount":{ + "value":{{sender_amount}}, + "currency":{{currency}} + } + }, + { + "operation_identifier":{"index":1}, + "type":"CALL", + "account":{{faucet}}, + "amount":{ + "value":{{available_amount}}, + "currency":{{currency}} + } + } + ]; + } +} diff --git a/go.mod b/go.mod index 493f855..1b9e28c 100644 --- a/go.mod +++ b/go.mod @@ -9,15 +9,18 @@ require ( ) require ( - github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 // indirect - github.com/btcsuite/btcd v0.22.1 // indirect + github.com/allegro/bigcache v1.2.1 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect - github.com/elastic/gosigar v0.12.0 // indirect + github.com/fjl/memsize v0.0.1 // indirect + github.com/go-kit/kit v0.10.0 // indirect + github.com/onsi/ginkgo v1.16.4 // indirect + github.com/onsi/gomega v1.16.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/rivo/uniseg v0.2.0 // indirect + github.com/rs/cors v1.8.2 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 // indirect - github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 // indirect + github.com/stretchr/objx v0.5.0 // indirect + golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) @@ -31,7 +34,6 @@ require ( github.com/deckarep/golang-set v1.8.0 // indirect github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 // indirect github.com/edsrzf/mmap-go v1.1.0 // indirect - github.com/ethereum-optimism/optimism/l2geth v0.0.0-20230126221930-d11d4ad7b7df github.com/fatih/color v1.13.0 // indirect github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 // indirect github.com/go-ole/go-ole v1.2.1 // indirect diff --git a/go.sum b/go.sum index 1e8252b..e57f33b 100644 --- a/go.sum +++ b/go.sum @@ -21,27 +21,9 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= git.sr.ht/~sircmpwn/getopt v0.0.0-20191230200459-23622cc906b3/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw= git.sr.ht/~sircmpwn/go-bare v0.0.0-20210406120253-ab86bc2846d9/go.mod h1:BVJwbDfVjCjoFiKrhkei6NdGcZYpkDkdyCdg1ukytRA= -github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.21.1/go.mod h1:fBF9PQNqB8scdgpZ3ufzaLntG0AG7C1WjPMsiFOmfHM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.8.3/go.mod h1:KLF4gFr6DcKFZwSuH8w8yEK6DpFl3LP5rhdvAb7Yz5I= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.3.0/go.mod h1:tPaiy8S5bQ+S5sOiDlINkp7+Ef339+Nz5L5XO+cnOHo= -github.com/Azure/azure-storage-blob-go v0.7.0/go.mod h1:f9YQKtsG1nMisotuTPpO0tjNuEjKRYAcJU8/ydDI++4= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI= -github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0= -github.com/Azure/go-autorest/autorest/adal v0.8.0/go.mod h1:Z6vX6WXXuyieHAXwMj0S6HY6e6wcHn37qQMBQlvY3lc= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA= -github.com/Azure/go-autorest/autorest/date v0.2.0/go.mod h1:vcORJHLJEh643/Ioh9+vPmf1Ij9AEBM5FuBIXLmIy0g= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.1.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxBee2F5Gr4kF2zd2J5cFRaIDN0= -github.com/Azure/go-autorest/autorest/mocks v0.3.0/go.mod h1:a8FDP3DYzQ4RYfVAxAN3SVSiiO77gL2j2ronKKP0syM= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc= -github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= @@ -54,7 +36,6 @@ github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWX github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6 h1:fLjPD/aNc3UIOA6tDi6QXUemppXK3P9BI7mr2hd6gx8= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= -github.com/VictoriaMetrics/fastcache v1.6.0 h1:C/3Oi3EiBCqufydp1neRZkqcwmEiuRT9c3fqvvgKm5o= github.com/VictoriaMetrics/fastcache v1.6.0/go.mod h1:0qHz5QP0GMX4pfmMA/zt5RgfNuXJrTP0zS7DqpHGGTw= github.com/VictoriaMetrics/fastcache v1.9.0 h1:oMwsS6c8abz98B7ytAewQ7M1ZN/Im/iwKoE1euaFvhs= github.com/VictoriaMetrics/fastcache v1.9.0/go.mod h1:otoTS3xu+6IzF/qByjqzjp3rTuzM3Qf0ScU1UTj97iU= @@ -67,15 +48,13 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -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/allegro/bigcache v1.2.1 h1:hg1sY1raCwic3Vnsvje6TT7/pnZba83LeFck5NrFKSc= github.com/allegro/bigcache v1.2.1/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/apache/arrow/go/arrow v0.0.0-20191024131854-af6fa24be0db/go.mod h1:VTxUBvSJ3s3eHAg65PNgrsn5BtqCRPdmyXh6rAfdxN0= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847 h1:rtI0fD4oG/8eVokGVPYJEW1F88p1ZNgXiEIs9thEE4A= -github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= @@ -83,7 +62,6 @@ github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.42.6/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.2.0/go.mod h1:zEQs02YRBw1DjK0PoJv3ygDYOFTre1ejlJWl8FwAuQo= github.com/aws/aws-sdk-go-v2/config v1.1.1/go.mod h1:0XsVy9lBI/BCXm+2Tuvt39YmdHwS5unDQmxZOYe8F5Y= @@ -103,7 +81,6 @@ github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx2 github.com/btcsuite/btcd v0.0.0-20190315201642-aa6e0f35703c/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ= github.com/btcsuite/btcd v0.21.0-beta.0.20201114000516-e9c7a5ac6401/go.mod h1:Sv4JPQ3/M+teHz9Bo5jBpkNcP0x6r7rdihlNL/7tTAs= -github.com/btcsuite/btcd v0.22.0-beta/go.mod h1:9n5ntfhhHQBIhUvlhDvD3Qg6fRUj4jkN0VB8L8svzOA= github.com/btcsuite/btcd v0.22.1 h1:CnwP9LM/M9xuRrGSCGeMVs9iv09uMqwsVX7EeIpgV2c= github.com/btcsuite/btcd v0.22.1/go.mod h1:wqgTSL29+50LRkmOVknEdmt8ZojIzhuWvgu/iptuN7Y= github.com/btcsuite/btcd/btcec/v2 v2.2.0 h1:fzn1qaOt32TuLjFlkzYSsBC35Q3KUjT1SwPxiMSCF5k= @@ -131,7 +108,6 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA 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 v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= @@ -170,7 +146,6 @@ github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2 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/deckarep/golang-set v0.0.0-20180603214616-504e848d77ea/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ= github.com/deckarep/golang-set v1.8.0 h1:sk9/l/KqpunDwP7pSjUg0keiOOLEnOBHzykLrsPppp4= github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS383rP6+o6qqo= github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= @@ -188,15 +163,10 @@ github.com/dgryski/go-bitstream v0.0.0-20180413035011-3522498ce2c8/go.mod h1:VMa github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-farm v0.0.0-20200201041132-a6ae2369ad13/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dlclark/regexp2 v1.4.1-0.20201116162257-a2a8dda75c91/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc= github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/docker v1.4.2-0.20180625184442-8e610b2b55bf/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v1.6.2/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.10+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/dop251/goja v0.0.0-20200721192441-a695b0cdd498/go.mod h1:Mw6PkjjMXWbTj+nnj4s3QPXq1jaT0s5pC0iFD4+BOAA= -github.com/dop251/goja v0.0.0-20211011172007-d99e4b8cbf48/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja v0.0.0-20220405120441-9037c2b61cbf/go.mod h1:R9ET47fwRVRPZnOGvHxxhuZcbrMCuiqOz3Rlrh4KSnk= github.com/dop251/goja_nodejs v0.0.0-20210225215109-d91c329300e7/go.mod h1:hn7BA7c8pLvoGndExHudxTDKZ84Pyvv+90pbBjbTz0Y= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -205,38 +175,29 @@ github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5m github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= github.com/eclipse/paho.mqtt.golang v1.2.0/go.mod h1:H9keYFcgq3Qr5OUJm/JZI/i6U7joQ8SYLhZwfeOo6Ts= -github.com/edsrzf/mmap-go v1.0.0 h1:CEBF7HpRnUCSJgGUb5h1Gm7e3VkmVDrR8lvWVLtrOFw= github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= github.com/edsrzf/mmap-go v1.1.0 h1:6EUwBLQ/Mcr1EYLE4Tn1VdW1A4ckqCQWZBw8Hr0kjpQ= github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= -github.com/elastic/gosigar v0.12.0 h1:AsdhYCJlTudhfOYQyFNgx+fIVTfrDO0V1ST0vHgiapU= -github.com/elastic/gosigar v0.12.0/go.mod h1:iXRIGg2tLnu7LBdpqzyQfGDEidKCfWcCMS0WKyPWoMs= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum-optimism/op-geth v0.0.0-20221104231810-30db39cae2be h1:8TdM3M7FjZkrYeGGX9nEVtDDlZ5RiuHtc0mbi5bGKyY= github.com/ethereum-optimism/op-geth v0.0.0-20221104231810-30db39cae2be/go.mod h1:1g9UmZgEINqvYfXmWOUCRJX9fxegeOHudVkLCRAXO5Y= -github.com/ethereum-optimism/optimism/l2geth v0.0.0-20230126221930-d11d4ad7b7df h1:lD1SPGGnD5ftjHHWXQXolAb+IAXRawetzJt1ANfRM70= -github.com/ethereum-optimism/optimism/l2geth v0.0.0-20230126221930-d11d4ad7b7df/go.mod h1:Oj5A6Qs/Ao1SP17i3uKroyhz49q/ehagSXRAlvwaI5Y= -github.com/ethereum/go-ethereum v1.10.4/go.mod h1:nEE0TP5MtxGzOMd7egIrbPJMQBnhVU3ELNxhBglIzhg= -github.com/ethereum/go-ethereum v1.10.16/go.mod h1:Anj6cxczl+AHy63o4X9O8yWNHuN5wMpfb8MAnHkWn7Y= github.com/ethereum/go-ethereum v1.10.21/go.mod h1:EYFyF19u3ezGLD4RqOkLq+ZCXzYbLoNDdZlMt7kyKFg= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/fjl/gencodec v0.0.0-20220412091415-8bb9e558978c/go.mod h1:AzA8Lj6YtixmJWL+wkKoBGsLWy9gFrAzi4g+5bCKwpY= -github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5 h1:FtmdgXiUlNeRsoNMFlKLDt+S+6hbjVMEW6RGQ7aUf7c= github.com/fjl/memsize v0.0.0-20190710130421-bcb5799ab5e5/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= +github.com/fjl/memsize v0.0.1 h1:+zhkb+dhUgx0/e+M8sF0QqiouvMQUiKR+QYvdxIOKcQ= github.com/fjl/memsize v0.0.1/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/garslo/gogen v0.0.0-20170306192744-1d203ffc1f61/go.mod h1:Q0X6pkwTILDlzrGEckF6HKjXe48EgsY/l7K7vhY4MW8= -github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff h1:tY80oXqGNY4FhTFhk+o9oFHGINQ/+vhlm8HFzi6znCI= github.com/gballet/go-libpcsclite v0.0.0-20190607065134-2772fd86a8ff/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08 h1:f6D9Hr8xV8uYKlyuj8XIruxlh9WjVjdh1gIicAS7ays= github.com/gballet/go-libpcsclite v0.0.0-20191108122812-4678299bea08/go.mod h1:x7DCsMOv1taUwEWCzT4cmDeAkigA5/QCwUodaVOe8Ww= @@ -249,24 +210,21 @@ github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1T github.com/go-chi/chi/v5 v5.0.0/go.mod h1:BBug9lr0cqtdAhsu6R4AAdvufI0/XBzAQSsUqJpoZOs= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-kit/kit v0.8.0 h1:Wz+5lgoB0kkuqLEc6NVmwRknTKP6dTGbSqvhZtBI/j0= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0 h1:dXFJfIHVvUcpSgDOV+Ne6t7jXri8Tfv2uOLHUZ2XNuo= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80nA= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.1 h1:2lOsA72HgjxAuMlKpFiCbHTvu44PIVkZ5hqm3RSdI/E= github.com/go-ole/go-ole v1.2.1/go.mod h1:7FAglXiTm7HKlQRDeOQ6ZNUHidzCWXuZWq/1dTyBNF8= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-resty/resty/v2 v2.4.0/go.mod h1:B88+xCTEwvfD94NOuE6GS1wMlnoKNY8eEiNizfNwOwA= -github.com/go-sourcemap/sourcemap v2.1.2+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sourcemap/sourcemap v2.1.3+incompatible/go.mod h1:F8jJfvm2KbVjc5NqelyYJmf/v5J0dwNLS2mL4sNA1Jg= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= -github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= @@ -297,7 +255,6 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -316,7 +273,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -326,8 +282,6 @@ github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hf github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.5/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0 h1:qJYtXnJRWmpe7m/3XlyhrsLrEURqHRM2kxzoxXqyUDs= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -341,11 +295,9 @@ github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -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/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/graph-gophers/graphql-go v0.0.0-20201113091052-beb923fada29/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= @@ -384,8 +336,6 @@ github.com/holiman/uint256 v1.2.0 h1:gpSYcPLWGv4sG43I2mVLiDZCNDh/EpGjSk8tmtxitHM github.com/holiman/uint256 v1.2.0/go.mod h1:y4ga/t+u+Xwd7CpDgZESaRcWy0I7XMlTMA25ApIH5Jw= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= -github.com/huin/goupnp v1.0.1-0.20210310174557-0ca763054c88/go.mod h1:nNs7wvRfN1eKaMknBydLNQU6146XQim8t4h+q90biWo= -github.com/huin/goupnp v1.0.2/go.mod h1:0dxJBVBHqTMjIUMkESDTNgOOx/Mw5wYIfyFmdzSamkM= github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= @@ -403,10 +353,8 @@ github.com/influxdata/promql/v2 v2.12.0/go.mod h1:fxOPu+DY0bqCTCECchSRtWfc+0X19y github.com/influxdata/roaring v0.4.13-0.20180809181101-fc520f41fab6/go.mod h1:bSgUQ7q5ZLSO+bKBGqJiCBGAl+9DxyW63zLTujjUlOE= github.com/influxdata/tdigest v0.0.0-20181121200506-bf2b5ad3c0a9/go.mod h1:Js0mqiSBE6Ffsg94weZZ2c+v/ciT8QRHFOap7EKDrR0= github.com/influxdata/usage-client v0.0.0-20160829180054-6d3895376368/go.mod h1:Wbbw6tYNvwa5dlB6304Sd+82Z3f7PmVZHVKU637d4po= -github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= -github.com/jarcoal/httpmock v1.0.8/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT8nX0Txik= github.com/jedisct1/go-minisign v0.0.0-20190909160543-45766022959e/go.mod h1:G1CVv03EnqU1wYL2dFwXxW2An0az9JTl/ZsqXQeBlkU= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= @@ -423,10 +371,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jsternberg/zap-logfmt v1.0.0/go.mod h1:uvPs/4X51zdkcm5jXl5SYoN+4RK21K8mysFmDaM/h+o= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= github.com/jwilder/encoding v0.0.0-20170811194829-b4e1701a28ef/go.mod h1:Ct9fl0F6iIOGgxJ5npU/IUOhOhqlVrGjyIZc8/MagT0= -github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -438,12 +384,13 @@ github.com/klauspost/cpuid v0.0.0-20170728055534-ae7887de9fa5/go.mod h1:Pj4uuM52 github.com/klauspost/crc32 v0.0.0-20161016154125-cb6bfca970f6/go.mod h1:+ZoRqAPRLkC4NPOvfYeR5KNOrY6TD+/sAC3HXPZgDYg= github.com/klauspost/pgzip v1.0.2-0.20170402124221-0bf5dcad4ada/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +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 v0.0.0-20170224010052-a616ab194758/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= @@ -460,19 +407,14 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= -github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= @@ -480,7 +422,6 @@ github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9 github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= 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= @@ -520,8 +461,8 @@ github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxzi github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/neilotoole/errgroup v0.1.6 h1:PODGqPXdT5BC/zCYIMoTrwV+ujKcW+gBXM6Ye9Ve3R8= github.com/neilotoole/errgroup v0.1.6/go.mod h1:Q2nLGf+594h0CLBs/Mbg6qOr7GtqDK7C2S41udRnToE= -github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= @@ -533,14 +474,14 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.10.3/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= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c= github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -548,7 +489,6 @@ github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKw github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.0.3-0.20180606204148-bd9c31933947/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= @@ -591,7 +531,6 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/tsdb v0.7.1 h1:YZcsG11NqnK4czYLrWd9mpEuAJIHVQLwdrleYfszMAA= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= @@ -599,15 +538,13 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn github.com/retailnext/hllpp v1.0.1-0.20180308014038-101a6d2f8b52/go.mod h1:RDpi1RftBQPUCDRw6SmxeaREsAaRKnOclghuzp/WRzc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rjeczalik/notify v0.9.1 h1:CLCKso/QK1snAlnhNR/CNvNiFU2saUtjV0bx3EwNeCE= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rjeczalik/notify v0.9.2 h1:MiTWrPj55mNDHEiIX5YUSKefw/+lCQVoAFmD6oQm5w8= github.com/rjeczalik/notify v0.9.2/go.mod h1:aErll2f0sUX9PXZnVNyeiObbmTlk5jnMoCa4QEjJeqM= -github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -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/rs/cors v1.8.2 h1:KCooALfAYGs415Cwu5ABvv9n9509fSiG5SQJn/AQo4U= github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -640,14 +577,9 @@ github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb6 github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= -github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4 h1:Gb2Tyox57NRNuZ2d3rmvB3pcmbu7O1RS3m8WRx7ilrg= github.com/status-im/keycard-go v0.0.0-20190316090335-8537d3370df4/go.mod h1:RZLeN1LMWmRsyYjvAu+I6Dm9QmlDaIIt+Y+4Kd7Tp+Q= github.com/status-im/keycard-go v0.0.0-20211109104530-b0e0482ba91d h1:vmirMegf1vqPJ+lDBxLQ0MAt3tz+JL57UPxu44JBOjA= github.com/status-im/keycard-go v0.0.0-20211109104530-b0e0482ba91d/go.mod h1:97vT0Rym0wCnK4B++hNA3nCetr0Mh1KXaVxzSt1arjg= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570 h1:gIlAHnH1vJb5vwEjIp5kBj/eu99p/bl0Ay2goiPe5xE= -github.com/steakknife/bloomfilter v0.0.0-20180922174646-6819c0d2a570/go.mod h1:8OR4w3TdeIHIh1g6EMY5p0gVNOovcWC+1vpc7naMuAw= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3 h1:njlZPzLwU639dk2kqnCPPv+wNjq7Xb6EfUxe/oX0/NM= -github.com/steakknife/hamming v0.0.0-20180906055917-c99c65617cd3/go.mod h1:hpGUWaI9xL8pRQCTXQgocU38Qw1g0Us7n5PxxTwTCYU= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= @@ -669,7 +601,6 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/supranational/blst v0.3.8-0.20220526154634-513d2456b344/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= -github.com/syndtr/goleveldb v1.0.1-0.20210305035536-64b5b1c73954/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= 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/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= @@ -684,7 +615,6 @@ github.com/tklauser/numcpus v0.2.2 h1:oyhllyrScuYI6g+h/zUvNXNp1wy7x8qQy3t/piefld github.com/tklauser/numcpus v0.2.2/go.mod h1:x3qojaO3uyYt0i56EW/VUYs7uBvdl2fkfZFu0T9wgjM= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= -github.com/tyler-smith/go-bip39 v1.0.2 h1:+t3w+KwLXO6154GNJY+qUtIxLTmFjfUmpguQT1OlOT8= github.com/tyler-smith/go-bip39 v1.0.2/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.1.0 h1:5eUemwrMargf3BSLRRCalXT93Ns6pQJIjYQN2nyfOP8= github.com/tyler-smith/go-bip39 v1.1.0/go.mod h1:gUYDtqQw1JS3ZJ8UWVcGTGqqr6YIN3CWg+kkNaLt55U= @@ -703,7 +633,6 @@ github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+ github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= @@ -743,12 +672,10 @@ golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220307211146-efcb8507fb70/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -786,7 +713,6 @@ golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -809,14 +735,12 @@ golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= @@ -833,13 +757,11 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f h1:Ax0t5p6N38Ga0dThY21weqDEyz2oklo4IvDkpigvkD8= golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180810173357-98c5dad5d1a0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -890,13 +812,10 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211020174200-9d6173849985/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20221013171732-95e765b1cc43 h1:OK7RB6t2WQX54srQQYSXMW8dF5C6/8+oA/s5QBmmto4= @@ -918,8 +837,8 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxb golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20201208040808-7e3f01d25324/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba h1:O8mE0/t419eoIwhTFpKVkHiTs/Igowgfkj25AcZrtiE= golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 h1:M73Iuj3xbbb9Uk1DYhzydthsj6oOd6l9bpuFcNoUvTs= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -938,7 +857,6 @@ golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBn golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -962,7 +880,6 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= gonum.org/v1/gonum v0.0.0-20181121035319-3f7ecaa7e8ca/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= @@ -1017,11 +934,11 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/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/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= @@ -1029,12 +946,9 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= -gopkg.in/olebedev/go-duktape.v3 v3.0.0-20200619000410-60c24ae608a6/go.mod h1:uAJfkITjFhyEEuUfm7bsmCZRbW5WRq8s9EY8HZ6hCns= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/urfave/cli.v1 v1.20.0/go.mod h1:vuBzUtMdQeixQj8LVd+/98pzhxNGQoyuPBlsXHOQNO0= gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -1049,8 +963,6 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/pkg/client/client.go b/pkg/client/client.go index 5b71201..456d5b6 100644 --- a/pkg/client/client.go +++ b/pkg/client/client.go @@ -3,14 +3,15 @@ package client import ( "fmt" - "github.com/coinbase/rosetta-geth-sdk/configuration" - evmClient "github.com/coinbase/rosetta-geth-sdk/client" + configuration "github.com/coinbase/rosetta-geth-sdk/configuration" ) // OpClient wraps the [evmClient.SDKClient] to add Optimism-specific functionality. +// +//go:generate mockery --name OpClient --output ./mocks type OpClient struct { - *evmClient.SDKClient + InternalClient } // NewOpClient creates a client that can interact with the Optimism network. diff --git a/pkg/client/client_blocks.go b/pkg/client/client_blocks.go index 63e3872..f1de3bc 100644 --- a/pkg/client/client_blocks.go +++ b/pkg/client/client_blocks.go @@ -13,6 +13,8 @@ import ( EthTypes "github.com/ethereum/go-ethereum/core/types" ) +// GetBlockReceipts returns [evmClient.RosettaTxReceipt] for a given blockhash. +// Calls to eth_getTransactionReceipt are batched to reduce the number of RPC calls with a max batch size of 25. func (c *OpClient) GetBlockReceipts( ctx context.Context, blockHash common.Hash, diff --git a/pkg/client/client_blocks_test.go b/pkg/client/client_blocks_test.go new file mode 100644 index 0000000..78065b9 --- /dev/null +++ b/pkg/client/client_blocks_test.go @@ -0,0 +1,115 @@ +package client_test + +import ( + "context" + "fmt" + "math/big" + "testing" + + client "github.com/mdehoog/op-rosetta/pkg/client" + mocks "github.com/mdehoog/op-rosetta/pkg/client/mocks" + + SdkClient "github.com/coinbase/rosetta-geth-sdk/client" + EthCommon "github.com/ethereum/go-ethereum/common" + EthTypes "github.com/ethereum/go-ethereum/core/types" + EthRpc "github.com/ethereum/go-ethereum/rpc" + + "github.com/stretchr/testify/mock" + "github.com/stretchr/testify/suite" +) + +// ClientBlocksTestSuite is a test suite for the client block handler. +type ClientBlocksTestSuite struct { + suite.Suite + + internalClient *mocks.InternalClient + client *client.OpClient +} + +// SetupTest sets up the test suite. +func (testSuite *ClientBlocksTestSuite) SetupTest() { + testSuite.internalClient = new(mocks.InternalClient) + testSuite.client = &client.OpClient{testSuite.internalClient} +} + +// TestClientBlocks runs the ClientBlocksTestSuite. +func TestClientBlocks(t *testing.T) { + suite.Run(t, new(ClientBlocksTestSuite)) +} + +// TestGetBlockReceiptsBatchCallErrors tests fetching block receipts from the op client with failing batch calls. +func (testSuite *ClientBlocksTestSuite) TestGetBlockReceiptsBatchCallErrors() { + // Construct arguments + ctx := context.Background() + hash := EthCommon.HexToHash("0xb358c6958b1cab722752939cbb92e3fec6b6023de360305910ce80c56c3dad9d") + gasPrice := big.NewInt(10000) + blockNumber := big.NewInt(1) + blockNumberString := blockNumber.String() + to := EthCommon.HexToAddress("095e7baea6a6c7c4c2dfeb977efac326af552d87") + myTx := EthTypes.NewTransaction( + 0, + to, + big.NewInt(0), + 0, + gasPrice, + nil, + ) + txs := []SdkClient.RPCTransaction{ + { + Tx: myTx, + TxExtraInfo: SdkClient.TxExtraInfo{ + BlockNumber: &blockNumberString, + BlockHash: &hash, + From: &to, + TxHash: &hash, + }, + }, + } + baseFee := big.NewInt(10000) + + // Mock the internall call to the mock client + ethReceipt := EthTypes.Receipt{ + // Consensus fields: These fields are defined by the Yellow Paper + Type: 0, + PostState: []byte{0x00}, + Status: 1, + CumulativeGasUsed: 0, + Bloom: EthTypes.BytesToBloom([]byte{0x00}), + Logs: []*EthTypes.Log{}, + // Implementation fields: These fields are added by geth when processing a transaction. + // They are stored in the chain database. + TxHash: hash, + ContractAddress: to, + GasUsed: 0, + // transaction corresponding to this receipt. + BlockHash: hash, + BlockNumber: blockNumber, + TransactionIndex: 0, + // OVM legacy: extend receipts with their L1 price (if a rollup tx) + // IGNORED + } + testSuite.internalClient.On("BatchCallContext", ctx, mock.Anything).Return(nil).Run(func(args mock.Arguments) { + arg := args.Get(1).([]EthRpc.BatchElem) + arg[0].Result = ethReceipt + arg[0].Error = fmt.Errorf("error") + }) + + // Execute and validate the call + _, err := testSuite.client.GetBlockReceipts(ctx, hash, txs, baseFee) + testSuite.Equal(fmt.Errorf("error"), err) + // testSuite.Equal([]*SdkClient.RosettaTxReceipt{}, txReceipts) +} + +// TestGetBlockReceiptsEmptyTxs tests fetching block receipts from the op client with no transactions. +func (testSuite *ClientBlocksTestSuite) TestGetBlockReceiptsEmptyTxs() { + // Construct arguments + ctx := context.Background() + hash := EthCommon.HexToHash("0xb358c6958b1cab722752939cbb92e3fec6b6023de360305910ce80c56c3dad9d") + txs := []SdkClient.RPCTransaction{} + baseFee := big.NewInt(10000) + + // Execute and validate the call + txReceipts, err := testSuite.client.GetBlockReceipts(ctx, hash, txs, baseFee) + testSuite.NoError(err) + testSuite.Equal([]*SdkClient.RosettaTxReceipt{}, txReceipts) +} diff --git a/pkg/client/mocks/InternalClient.go b/pkg/client/mocks/InternalClient.go new file mode 100644 index 0000000..94f36ca --- /dev/null +++ b/pkg/client/mocks/InternalClient.go @@ -0,0 +1,629 @@ +// Code generated by mockery v2.14.0. DO NOT EDIT. + +package mocks + +import ( + big "math/big" + + common "github.com/ethereum/go-ethereum/common" + + configuration "github.com/coinbase/rosetta-geth-sdk/configuration" + + context "context" + + coretypes "github.com/ethereum/go-ethereum/core/types" + + ethereum "github.com/ethereum/go-ethereum" + + json "encoding/json" + + mock "github.com/stretchr/testify/mock" + + rosetta_geth_sdkclient "github.com/coinbase/rosetta-geth-sdk/client" + + rpc "github.com/ethereum/go-ethereum/rpc" + + types "github.com/coinbase/rosetta-sdk-go/types" +) + +// InternalClient is an autogenerated mock type for the InternalClient type +type InternalClient struct { + mock.Mock +} + +// Balance provides a mock function with given fields: ctx, account, block, currencies +func (_m *InternalClient) Balance(ctx context.Context, account *types.AccountIdentifier, block *types.PartialBlockIdentifier, currencies []*types.Currency) (*types.AccountBalanceResponse, error) { + ret := _m.Called(ctx, account, block, currencies) + + var r0 *types.AccountBalanceResponse + if rf, ok := ret.Get(0).(func(context.Context, *types.AccountIdentifier, *types.PartialBlockIdentifier, []*types.Currency) *types.AccountBalanceResponse); ok { + r0 = rf(ctx, account, block, currencies) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.AccountBalanceResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.AccountIdentifier, *types.PartialBlockIdentifier, []*types.Currency) error); ok { + r1 = rf(ctx, account, block, currencies) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BatchCallContext provides a mock function with given fields: ctx, b +func (_m *InternalClient) BatchCallContext(ctx context.Context, b []rpc.BatchElem) error { + ret := _m.Called(ctx, b) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []rpc.BatchElem) error); ok { + r0 = rf(ctx, b) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// BlockAuthor provides a mock function with given fields: ctx, blockIndex +func (_m *InternalClient) BlockAuthor(ctx context.Context, blockIndex int64) (string, error) { + ret := _m.Called(ctx, blockIndex) + + var r0 string + if rf, ok := ret.Get(0).(func(context.Context, int64) string); ok { + r0 = rf(ctx, blockIndex) + } else { + r0 = ret.Get(0).(string) + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, int64) error); ok { + r1 = rf(ctx, blockIndex) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BlockRewardTransaction provides a mock function with given fields: blockIdentifier, miner, uncles +func (_m *InternalClient) BlockRewardTransaction(blockIdentifier *types.BlockIdentifier, miner string, uncles []*coretypes.Header) *types.Transaction { + ret := _m.Called(blockIdentifier, miner, uncles) + + var r0 *types.Transaction + if rf, ok := ret.Get(0).(func(*types.BlockIdentifier, string, []*coretypes.Header) *types.Transaction); ok { + r0 = rf(blockIdentifier, miner, uncles) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Transaction) + } + } + + return r0 +} + +// CallContext provides a mock function with given fields: ctx, result, method, args +func (_m *InternalClient) CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error { + var _ca []interface{} + _ca = append(_ca, ctx, result, method) + _ca = append(_ca, args...) + ret := _m.Called(_ca...) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, interface{}, string, ...interface{}) error); ok { + r0 = rf(ctx, result, method, args...) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// EstimateGas provides a mock function with given fields: ctx, msg +func (_m *InternalClient) EstimateGas(ctx context.Context, msg ethereum.CallMsg) (uint64, error) { + ret := _m.Called(ctx, msg) + + var r0 uint64 + if rf, ok := ret.Get(0).(func(context.Context, ethereum.CallMsg) uint64); ok { + r0 = rf(ctx, msg) + } else { + r0 = ret.Get(0).(uint64) + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, ethereum.CallMsg) error); ok { + r1 = rf(ctx, msg) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlockReceipts provides a mock function with given fields: ctx, blockHash, txs, baseFee +func (_m *InternalClient) GetBlockReceipts(ctx context.Context, blockHash common.Hash, txs []rosetta_geth_sdkclient.RPCTransaction, baseFee *big.Int) ([]*rosetta_geth_sdkclient.RosettaTxReceipt, error) { + ret := _m.Called(ctx, blockHash, txs, baseFee) + + var r0 []*rosetta_geth_sdkclient.RosettaTxReceipt + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, []rosetta_geth_sdkclient.RPCTransaction, *big.Int) []*rosetta_geth_sdkclient.RosettaTxReceipt); ok { + r0 = rf(ctx, blockHash, txs, baseFee) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*rosetta_geth_sdkclient.RosettaTxReceipt) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, []rosetta_geth_sdkclient.RPCTransaction, *big.Int) error); ok { + r1 = rf(ctx, blockHash, txs, baseFee) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetClient provides a mock function with given fields: +func (_m *InternalClient) GetClient() *rosetta_geth_sdkclient.SDKClient { + ret := _m.Called() + + var r0 *rosetta_geth_sdkclient.SDKClient + if rf, ok := ret.Get(0).(func() *rosetta_geth_sdkclient.SDKClient); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*rosetta_geth_sdkclient.SDKClient) + } + } + + return r0 +} + +// GetContractCallGasLimit provides a mock function with given fields: ctx, toAddress, fromAddress, data +func (_m *InternalClient) GetContractCallGasLimit(ctx context.Context, toAddress string, fromAddress string, data []byte) (uint64, error) { + ret := _m.Called(ctx, toAddress, fromAddress, data) + + var r0 uint64 + if rf, ok := ret.Get(0).(func(context.Context, string, string, []byte) uint64); ok { + r0 = rf(ctx, toAddress, fromAddress, data) + } else { + r0 = ret.Get(0).(uint64) + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string, string, []byte) error); ok { + r1 = rf(ctx, toAddress, fromAddress, data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetContractCurrency provides a mock function with given fields: addr, erc20 +func (_m *InternalClient) GetContractCurrency(addr common.Address, erc20 bool) (*rosetta_geth_sdkclient.ContractCurrency, error) { + ret := _m.Called(addr, erc20) + + var r0 *rosetta_geth_sdkclient.ContractCurrency + if rf, ok := ret.Get(0).(func(common.Address, bool) *rosetta_geth_sdkclient.ContractCurrency); ok { + r0 = rf(addr, erc20) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*rosetta_geth_sdkclient.ContractCurrency) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(common.Address, bool) error); ok { + r1 = rf(addr, erc20) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetErc20TransferGasLimit provides a mock function with given fields: ctx, toAddress, fromAddress, value, currency +func (_m *InternalClient) GetErc20TransferGasLimit(ctx context.Context, toAddress string, fromAddress string, value *big.Int, currency *types.Currency) (uint64, error) { + ret := _m.Called(ctx, toAddress, fromAddress, value, currency) + + var r0 uint64 + if rf, ok := ret.Get(0).(func(context.Context, string, string, *big.Int, *types.Currency) uint64); ok { + r0 = rf(ctx, toAddress, fromAddress, value, currency) + } else { + r0 = ret.Get(0).(uint64) + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string, string, *big.Int, *types.Currency) error); ok { + r1 = rf(ctx, toAddress, fromAddress, value, currency) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetGasPrice provides a mock function with given fields: ctx, input +func (_m *InternalClient) GetGasPrice(ctx context.Context, input rosetta_geth_sdkclient.Options) (*big.Int, error) { + ret := _m.Called(ctx, input) + + var r0 *big.Int + if rf, ok := ret.Get(0).(func(context.Context, rosetta_geth_sdkclient.Options) *big.Int); ok { + r0 = rf(ctx, input) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, rosetta_geth_sdkclient.Options) error); ok { + r1 = rf(ctx, input) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetLoadedTransaction provides a mock function with given fields: ctx, request +func (_m *InternalClient) GetLoadedTransaction(ctx context.Context, request *types.BlockTransactionRequest) (*rosetta_geth_sdkclient.LoadedTransaction, error) { + ret := _m.Called(ctx, request) + + var r0 *rosetta_geth_sdkclient.LoadedTransaction + if rf, ok := ret.Get(0).(func(context.Context, *types.BlockTransactionRequest) *rosetta_geth_sdkclient.LoadedTransaction); ok { + r0 = rf(ctx, request) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*rosetta_geth_sdkclient.LoadedTransaction) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *types.BlockTransactionRequest) error); ok { + r1 = rf(ctx, request) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNativeTransferGasLimit provides a mock function with given fields: ctx, toAddress, fromAddress, value +func (_m *InternalClient) GetNativeTransferGasLimit(ctx context.Context, toAddress string, fromAddress string, value *big.Int) (uint64, error) { + ret := _m.Called(ctx, toAddress, fromAddress, value) + + var r0 uint64 + if rf, ok := ret.Get(0).(func(context.Context, string, string, *big.Int) uint64); ok { + r0 = rf(ctx, toAddress, fromAddress, value) + } else { + r0 = ret.Get(0).(uint64) + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string, string, *big.Int) error); ok { + r1 = rf(ctx, toAddress, fromAddress, value) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetNonce provides a mock function with given fields: ctx, input +func (_m *InternalClient) GetNonce(ctx context.Context, input rosetta_geth_sdkclient.Options) (uint64, error) { + ret := _m.Called(ctx, input) + + var r0 uint64 + if rf, ok := ret.Get(0).(func(context.Context, rosetta_geth_sdkclient.Options) uint64); ok { + r0 = rf(ctx, input) + } else { + r0 = ret.Get(0).(uint64) + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, rosetta_geth_sdkclient.Options) error); ok { + r1 = rf(ctx, input) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRosettaConfig provides a mock function with given fields: +func (_m *InternalClient) GetRosettaConfig() configuration.RosettaConfig { + ret := _m.Called() + + var r0 configuration.RosettaConfig + if rf, ok := ret.Get(0).(func() configuration.RosettaConfig); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(configuration.RosettaConfig) + } + + return r0 +} + +// GetTransactionReceipt provides a mock function with given fields: ctx, tx +func (_m *InternalClient) GetTransactionReceipt(ctx context.Context, tx *rosetta_geth_sdkclient.LoadedTransaction) (*rosetta_geth_sdkclient.RosettaTxReceipt, error) { + ret := _m.Called(ctx, tx) + + var r0 *rosetta_geth_sdkclient.RosettaTxReceipt + if rf, ok := ret.Get(0).(func(context.Context, *rosetta_geth_sdkclient.LoadedTransaction) *rosetta_geth_sdkclient.RosettaTxReceipt); ok { + r0 = rf(ctx, tx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*rosetta_geth_sdkclient.RosettaTxReceipt) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *rosetta_geth_sdkclient.LoadedTransaction) error); ok { + r1 = rf(ctx, tx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetUncles provides a mock function with given fields: ctx, head, body +func (_m *InternalClient) GetUncles(ctx context.Context, head *coretypes.Header, body *rosetta_geth_sdkclient.RPCBlock) ([]*coretypes.Header, error) { + ret := _m.Called(ctx, head, body) + + var r0 []*coretypes.Header + if rf, ok := ret.Get(0).(func(context.Context, *coretypes.Header, *rosetta_geth_sdkclient.RPCBlock) []*coretypes.Header); ok { + r0 = rf(ctx, head, body) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*coretypes.Header) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, *coretypes.Header, *rosetta_geth_sdkclient.RPCBlock) error); ok { + r1 = rf(ctx, head, body) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ParseOps provides a mock function with given fields: tx +func (_m *InternalClient) ParseOps(tx *rosetta_geth_sdkclient.LoadedTransaction) ([]*types.Operation, error) { + ret := _m.Called(tx) + + var r0 []*types.Operation + if rf, ok := ret.Get(0).(func(*rosetta_geth_sdkclient.LoadedTransaction) []*types.Operation); ok { + r0 = rf(tx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*types.Operation) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*rosetta_geth_sdkclient.LoadedTransaction) error); ok { + r1 = rf(tx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// PopulateCrossChainTransactions provides a mock function with given fields: _a0, _a1 +func (_m *InternalClient) PopulateCrossChainTransactions(_a0 *coretypes.Block, _a1 []*rosetta_geth_sdkclient.LoadedTransaction) ([]*types.Transaction, error) { + ret := _m.Called(_a0, _a1) + + var r0 []*types.Transaction + if rf, ok := ret.Get(0).(func(*coretypes.Block, []*rosetta_geth_sdkclient.LoadedTransaction) []*types.Transaction); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]*types.Transaction) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*coretypes.Block, []*rosetta_geth_sdkclient.LoadedTransaction) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// Status provides a mock function with given fields: ctx +func (_m *InternalClient) Status(ctx context.Context) (*types.BlockIdentifier, int64, *types.SyncStatus, []*types.Peer, error) { + ret := _m.Called(ctx) + + var r0 *types.BlockIdentifier + if rf, ok := ret.Get(0).(func(context.Context) *types.BlockIdentifier); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.BlockIdentifier) + } + } + + var r1 int64 + if rf, ok := ret.Get(1).(func(context.Context) int64); ok { + r1 = rf(ctx) + } else { + r1 = ret.Get(1).(int64) + } + + var r2 *types.SyncStatus + if rf, ok := ret.Get(2).(func(context.Context) *types.SyncStatus); ok { + r2 = rf(ctx) + } else { + if ret.Get(2) != nil { + r2 = ret.Get(2).(*types.SyncStatus) + } + } + + var r3 []*types.Peer + if rf, ok := ret.Get(3).(func(context.Context) []*types.Peer); ok { + r3 = rf(ctx) + } else { + if ret.Get(3) != nil { + r3 = ret.Get(3).([]*types.Peer) + } + } + + var r4 error + if rf, ok := ret.Get(4).(func(context.Context) error); ok { + r4 = rf(ctx) + } else { + r4 = ret.Error(4) + } + + return r0, r1, r2, r3, r4 +} + +// Submit provides a mock function with given fields: ctx, signedTx +func (_m *InternalClient) Submit(ctx context.Context, signedTx *coretypes.Transaction) error { + ret := _m.Called(ctx, signedTx) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, *coretypes.Transaction) error); ok { + r0 = rf(ctx, signedTx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// TraceBlockByHash provides a mock function with given fields: ctx, blockHash, txs +func (_m *InternalClient) TraceBlockByHash(ctx context.Context, blockHash common.Hash, txs []rosetta_geth_sdkclient.RPCTransaction) (map[string][]*rosetta_geth_sdkclient.FlatCall, error) { + ret := _m.Called(ctx, blockHash, txs) + + var r0 map[string][]*rosetta_geth_sdkclient.FlatCall + if rf, ok := ret.Get(0).(func(context.Context, common.Hash, []rosetta_geth_sdkclient.RPCTransaction) map[string][]*rosetta_geth_sdkclient.FlatCall); ok { + r0 = rf(ctx, blockHash, txs) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string][]*rosetta_geth_sdkclient.FlatCall) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, common.Hash, []rosetta_geth_sdkclient.RPCTransaction) error); ok { + r1 = rf(ctx, blockHash, txs) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TraceReplayBlockTransactions provides a mock function with given fields: ctx, hsh +func (_m *InternalClient) TraceReplayBlockTransactions(ctx context.Context, hsh string) (map[string][]*rosetta_geth_sdkclient.FlatCall, error) { + ret := _m.Called(ctx, hsh) + + var r0 map[string][]*rosetta_geth_sdkclient.FlatCall + if rf, ok := ret.Get(0).(func(context.Context, string) map[string][]*rosetta_geth_sdkclient.FlatCall); ok { + r0 = rf(ctx, hsh) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string][]*rosetta_geth_sdkclient.FlatCall) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = rf(ctx, hsh) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// TraceReplayTransaction provides a mock function with given fields: ctx, hsh +func (_m *InternalClient) TraceReplayTransaction(ctx context.Context, hsh string) (json.RawMessage, []*rosetta_geth_sdkclient.FlatCall, error) { + ret := _m.Called(ctx, hsh) + + var r0 json.RawMessage + if rf, ok := ret.Get(0).(func(context.Context, string) json.RawMessage); ok { + r0 = rf(ctx, hsh) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(json.RawMessage) + } + } + + var r1 []*rosetta_geth_sdkclient.FlatCall + if rf, ok := ret.Get(1).(func(context.Context, string) []*rosetta_geth_sdkclient.FlatCall); ok { + r1 = rf(ctx, hsh) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]*rosetta_geth_sdkclient.FlatCall) + } + } + + var r2 error + if rf, ok := ret.Get(2).(func(context.Context, string) error); ok { + r2 = rf(ctx, hsh) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +// TraceTransaction provides a mock function with given fields: ctx, hash +func (_m *InternalClient) TraceTransaction(ctx context.Context, hash common.Hash) (json.RawMessage, []*rosetta_geth_sdkclient.FlatCall, error) { + ret := _m.Called(ctx, hash) + + var r0 json.RawMessage + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) json.RawMessage); ok { + r0 = rf(ctx, hash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(json.RawMessage) + } + } + + var r1 []*rosetta_geth_sdkclient.FlatCall + if rf, ok := ret.Get(1).(func(context.Context, common.Hash) []*rosetta_geth_sdkclient.FlatCall); ok { + r1 = rf(ctx, hash) + } else { + if ret.Get(1) != nil { + r1 = ret.Get(1).([]*rosetta_geth_sdkclient.FlatCall) + } + } + + var r2 error + if rf, ok := ret.Get(2).(func(context.Context, common.Hash) error); ok { + r2 = rf(ctx, hash) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 +} + +type mockConstructorTestingTNewInternalClient interface { + mock.TestingT + Cleanup(func()) +} + +// NewInternalClient creates a new instance of InternalClient. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +func NewInternalClient(t mockConstructorTestingTNewInternalClient) *InternalClient { + mock := &InternalClient{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/pkg/client/types.go b/pkg/client/types.go new file mode 100644 index 0000000..4db41b5 --- /dev/null +++ b/pkg/client/types.go @@ -0,0 +1,91 @@ +package client + +import ( + "context" + "encoding/json" + "math/big" + + evmClient "github.com/coinbase/rosetta-geth-sdk/client" + configuration "github.com/coinbase/rosetta-geth-sdk/configuration" + RosettaTypes "github.com/coinbase/rosetta-sdk-go/types" + Eth "github.com/ethereum/go-ethereum" + EthCommon "github.com/ethereum/go-ethereum/common" + EthTypes "github.com/ethereum/go-ethereum/core/types" + EthRpc "github.com/ethereum/go-ethereum/rpc" +) + +// InternalClient contains the methods that must be implemented by the parameter to [NewOpClient]. +type InternalClient interface { + // CallContext performs a JSON-RPC call with the given arguments. If the context is + // canceled before the call has successfully returned, CallContext returns immediately. + // + // The result must be a pointer so that package json can unmarshal into it. You + // can also pass nil, in which case the result is ignored. + CallContext(ctx context.Context, result interface{}, method string, args ...interface{}) error + + // BatchCallContext sends all given requests as a single batch and waits for the server + // to return a response for all of them. The wait duration is bounded by the + // context's deadline. + // + // In contrast to CallContext, BatchCallContext only returns errors that have occurred + // while sending the request. Any error specific to a request is reported through the + // Error field of the corresponding BatchElem. + // + // Note that batch calls may not be executed atomically on the server side. + BatchCallContext(ctx context.Context, b []EthRpc.BatchElem) error + + // EstimateGas tries to estimate the gas needed to execute a specific transaction based on + // the current pending state of the backend blockchain. There is no guarantee that this is + // the true gas limit requirement as other transactions may be added or removed by miners, + // but it should provide a basis for setting a reasonable default. + EstimateGas(ctx context.Context, msg Eth.CallMsg) (uint64, error) + + // TODO: remove the methods below that aren't needed + + // Balance returns the balance of an account at a given block. + Balance(ctx context.Context, account *RosettaTypes.AccountIdentifier, block *RosettaTypes.PartialBlockIdentifier, currencies []*RosettaTypes.Currency) (*RosettaTypes.AccountBalanceResponse, error) + // BlockAuthor returns the author of a block. + BlockAuthor(ctx context.Context, blockIndex int64) (string, error) + // BlockRewardTransaction returns the transaction that rewards the miner of a block. + BlockRewardTransaction(blockIdentifier *RosettaTypes.BlockIdentifier, miner string, uncles []*EthTypes.Header) *RosettaTypes.Transaction + // GetBlockReceipts returns [evmClient.RosettaTxReceipt] for a given blockhash. + GetBlockReceipts(ctx context.Context, blockHash EthCommon.Hash, txs []evmClient.RPCTransaction, baseFee *big.Int) ([]*evmClient.RosettaTxReceipt, error) + // GetClient returns the internal [evmClient.SDKClient]. + GetClient() *evmClient.SDKClient + // GetContractCallGasLimit returns the gas limit for a contract call. + GetContractCallGasLimit(ctx context.Context, toAddress string, fromAddress string, data []byte) (uint64, error) + // GetContractCurrency returns the currency for a contract. + GetContractCurrency(addr EthCommon.Address, erc20 bool) (*evmClient.ContractCurrency, error) + // GetErc20TransferGasLimit returns the gas limit for an ERC20 transfer. + GetErc20TransferGasLimit(ctx context.Context, toAddress string, fromAddress string, value *big.Int, currency *RosettaTypes.Currency) (uint64, error) + // GetGasPrice returns the gas price for a transaction. + GetGasPrice(ctx context.Context, input evmClient.Options) (*big.Int, error) + // GetLoadedTransaction returns a [evmClient.LoadedTransaction] for a given transaction hash. + GetLoadedTransaction(ctx context.Context, request *RosettaTypes.BlockTransactionRequest) (*evmClient.LoadedTransaction, error) + // GetNativeTransferGasLimit returns the gas limit for a native transfer. + GetNativeTransferGasLimit(ctx context.Context, toAddress string, fromAddress string, value *big.Int) (uint64, error) + // GetNonce returns the nonce for an account. + GetNonce(ctx context.Context, input evmClient.Options) (uint64, error) + // GetRosettaConfig returns the [configuration.RosettaConfig] for the client. + GetRosettaConfig() configuration.RosettaConfig + // GetTransactionReceipt returns the [evmClient.RosettaTxReceipt] for a given transaction hash. + GetTransactionReceipt(ctx context.Context, tx *evmClient.LoadedTransaction) (*evmClient.RosettaTxReceipt, error) + // GetUncles returns the uncles for a given block. + GetUncles(ctx context.Context, head *EthTypes.Header, body *evmClient.RPCBlock) ([]*EthTypes.Header, error) + // ParseOps returns the [RosettaTypes.Operation] for a given [evmClient.LoadedTransaction]. + ParseOps(tx *evmClient.LoadedTransaction) ([]*RosettaTypes.Operation, error) + // PopulateCrossChainTransactions returns the [RosettaTypes.Transaction] for a given [EthTypes.Block] and [evmClient.LoadedTransaction]. + PopulateCrossChainTransactions(*EthTypes.Block, []*evmClient.LoadedTransaction) ([]*RosettaTypes.Transaction, error) + // Status returns the current client status. + Status(ctx context.Context) (*RosettaTypes.BlockIdentifier, int64, *RosettaTypes.SyncStatus, []*RosettaTypes.Peer, error) + // Submit submits a signed transaction. + Submit(ctx context.Context, signedTx *EthTypes.Transaction) error + // TraceBlockByHash returns the [evmClient.FlatCall] for a given block hash. + TraceBlockByHash(ctx context.Context, blockHash EthCommon.Hash, txs []evmClient.RPCTransaction) (map[string][]*evmClient.FlatCall, error) + // TraceReplayBlockTransactions returns the [evmClient.FlatCall] for a given block hash. + TraceReplayBlockTransactions(ctx context.Context, hsh string) (map[string][]*evmClient.FlatCall, error) + // TraceReplayTransaction returns the [evmClient.FlatCall] for a given transaction hash. + TraceReplayTransaction(ctx context.Context, hsh string) (json.RawMessage, []*evmClient.FlatCall, error) + // TraceTransaction constructs trace enriched [emvClient.FlatCall]s for a given [EthCommon.Hash]. + TraceTransaction(ctx context.Context, hash EthCommon.Hash) (json.RawMessage, []*evmClient.FlatCall, error) +}