diff --git a/common/types.go b/common/types.go index 77fabeb..f6f1c7d 100644 --- a/common/types.go +++ b/common/types.go @@ -3,10 +3,10 @@ package common import ( "encoding/json" "fmt" - "math/big" "strconv" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" ) @@ -45,27 +45,28 @@ type Transactions struct { Hashes [][32]byte Full []Transaction // transaction needs to be defined } - +// Updated as earlier, txn data fetched from rpc was not able to unmarshal +// into the struct type Transaction struct { - AccessList types.AccessList - Hash common.Hash - Nonce uint64 - BlockHash [32]byte - BlockNumber *uint64 - TransactionIndex uint64 - From string - To *common.Address - Value *big.Int - GasPrice *big.Int - Gas uint64 - Input []byte - ChainID *big.Int - TransactionType uint8 - Signature *Signature - MaxFeePerGas *big.Int - MaxPriorityFeePerGas *big.Int - MaxFeePerBlobGas *big.Int - BlobVersionedHashes []common.Hash + AccessList types.AccessList `json:"accessList"` + Hash common.Hash `json:"hash"` + Nonce hexutil.Uint64 `json:"nonce"` + BlockHash string `json:"blockHash"` // Pointer because it's nullable + BlockNumber hexutil.Uint64 `json:"blockNumber"` // Pointer because it's nullable + TransactionIndex hexutil.Uint64 `json:"transactionIndex"` + From string `json:"from"` + To *common.Address `json:"to"` // Pointer because 'to' can be null for contract creation + Value hexutil.Big `json:"value"` + GasPrice hexutil.Big `json:"gasPrice"` + Gas hexutil.Uint64 `json:"gas"` + Input hexutil.Bytes `json:"input"` + ChainID hexutil.Big `json:"chainId"` + TransactionType hexutil.Uint `json:"type"` + Signature *Signature `json:"signature"` + MaxFeePerGas hexutil.Big `json:"maxFeePerGas"` + MaxPriorityFeePerGas hexutil.Big `json:"maxPriorityFeePerGas"` + MaxFeePerBlobGas hexutil.Big `json:"maxFeePerBlobGas"` + BlobVersionedHashes []common.Hash `json:"blobVersionedHashes"` } type Signature struct { diff --git a/consensus/consensus.go b/consensus/consensus.go index 2a25cf3..064800a 100644 --- a/consensus/consensus.go +++ b/consensus/consensus.go @@ -27,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/holiman/uint256" "github.com/pkg/errors" + "github.com/ethereum/go-ethereum/common/hexutil" ) // Error definitions @@ -953,20 +954,24 @@ func processTransaction(txBytes *[1073741824]byte, blockHash consensus_core.Byte if err != nil { return common.Transaction{}, fmt.Errorf("failed to decode transaction: %v", err) } - + // Updated due to update in Transaction struct tx := common.Transaction{ Hash: txEnvelope.Hash(), - Nonce: txEnvelope.Nonce(), - BlockHash: blockHash, - BlockNumber: blockNumber, - TransactionIndex: index, + Nonce: hexutil.Uint64(txEnvelope.Nonce()), + BlockHash: func() string { + data := [32]byte(blockHash) + hexString := hex.EncodeToString(data[:]) + return hexString + }(), + BlockNumber: hexutil.Uint64(*blockNumber), + TransactionIndex: hexutil.Uint64(index), To: txEnvelope.To(), - Value: txEnvelope.Value(), - GasPrice: txEnvelope.GasPrice(), - Gas: txEnvelope.Gas(), + Value: hexutil.Big(*txEnvelope.Value()), + GasPrice: hexutil.Big(*txEnvelope.GasPrice()), + Gas: hexutil.Uint64(txEnvelope.Gas()), Input: txEnvelope.Data(), - ChainID: txEnvelope.ChainId(), - TransactionType: txEnvelope.Type(), + ChainID: hexutil.Big(*txEnvelope.ChainId()), + TransactionType: hexutil.Uint(uint(txEnvelope.Type())), } // Handle signature and transaction type logic @@ -990,12 +995,13 @@ func processTransaction(txBytes *[1073741824]byte, blockHash consensus_core.Byte case types.AccessListTxType: tx.AccessList = txEnvelope.AccessList() case types.DynamicFeeTxType: - tx.MaxFeePerGas = new(big.Int).Set(txEnvelope.GasFeeCap()) - tx.MaxPriorityFeePerGas = new(big.Int).Set(txEnvelope.GasTipCap()) + // Update due to update in Transaction struct + tx.MaxFeePerGas = hexutil.Big(*new(big.Int).Set(txEnvelope.GasFeeCap())) + tx.MaxPriorityFeePerGas = hexutil.Big(*new(big.Int).Set(txEnvelope.GasTipCap())) case types.BlobTxType: - tx.MaxFeePerGas = new(big.Int).Set(txEnvelope.GasFeeCap()) - tx.MaxPriorityFeePerGas = new(big.Int).Set(txEnvelope.GasTipCap()) - tx.MaxFeePerBlobGas = new(big.Int).Set(txEnvelope.BlobGasFeeCap()) + tx.MaxFeePerGas = hexutil.Big(*new(big.Int).Set(txEnvelope.GasFeeCap())) + tx.MaxPriorityFeePerGas = hexutil.Big(*new(big.Int).Set(txEnvelope.GasTipCap())) + tx.MaxFeePerBlobGas = hexutil.Big(*new(big.Int).Set(txEnvelope.BlobGasFeeCap())) tx.BlobVersionedHashes = txEnvelope.BlobHashes() default: fmt.Println("Unhandled transaction type") diff --git a/execution/errors_test.go b/execution/errors_test.go new file mode 100644 index 0000000..b7bc686 --- /dev/null +++ b/execution/errors_test.go @@ -0,0 +1,85 @@ +package execution + +import ( + "errors" + "testing" + + "github.com/BlocSoc-iitr/selene/consensus/consensus_core" + "github.com/BlocSoc-iitr/selene/consensus/types" + "github.com/stretchr/testify/assert" +) + +func TestExecutionErrors(t *testing.T) { + // Test InvalidAccountProofError + address := types.Address{0x01, 0x02} + err := NewInvalidAccountProofError(address) + assert.EqualError(t, err, "invalid account proof for string: [1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]") + + // Test InvalidStorageProofError + slot := consensus_core.Bytes32{0x0a} + err = NewInvalidStorageProofError(address, slot) + assert.EqualError(t, err, "invalid storage proof for string: [1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], slot: [10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]") + + // Test CodeHashMismatchError + found := consensus_core.Bytes32{0x03} + expected := consensus_core.Bytes32{0x04} + err = NewCodeHashMismatchError(address, found, expected) + assert.EqualError(t, err, "code hash mismatch for string: [1 2 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], found: [3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], expected: [4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]") + + // Test ReceiptRootMismatchError + tx := consensus_core.Bytes32{0x05} + err = NewReceiptRootMismatchError(tx) + assert.EqualError(t, err, "receipt root mismatch for tx: [5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]") + + // Test MissingTransactionError + err = NewMissingTransactionError(tx) + assert.EqualError(t, err, "missing transaction for tx: [5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]") + + // Test MissingLogError + err = NewMissingLogError(tx, 3) + assert.EqualError(t, err, "missing log for transaction: [5 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0], index: 3") + + // Test TooManyLogsToProveError + err = NewTooManyLogsToProveError(5000, 1000) + assert.EqualError(t, err, "too many logs to prove: 5000, current limit is: 1000") + + // Test InvalidBaseGasFeeError + err = NewInvalidBaseGasFeeError(1000, 2000, 123456) + assert.EqualError(t, err, "Invalid base gas fee selene 1000 vs rpc endpoint 2000 at block 123456") + + // Test BlockNotFoundError + err = NewBlockNotFoundError(123456) + assert.EqualError(t, err, "Block 123456 not found") + + // Test EmptyExecutionPayloadError + err = NewEmptyExecutionPayloadError() + assert.EqualError(t, err, "Selene Execution Payload is empty") +} + +func TestEvmErrors(t *testing.T) { + // Test RevertError + data := []byte{0x08, 0xc3, 0x79, 0xa0} + err := NewRevertError(data) + assert.EqualError(t, err, "execution reverted: [8 195 121 160]") + + // Test GenericError + err = NewGenericError("generic error") + assert.EqualError(t, err, "evm error: generic error") + + // Test RpcError + rpcErr := errors.New("rpc connection failed") + err = NewRpcError(rpcErr) + assert.EqualError(t, err, "rpc error: rpc connection failed") +} + +func TestDecodeRevertReason(t *testing.T) { + // Test successful revert reason decoding + reasonData := []byte{0x08, 0xc3, 0x79, 0xa0} + reason := DecodeRevertReason(reasonData) + assert.NotEmpty(t, reason, "Revert reason should be decoded") + + // Test invalid revert data + invalidData := []byte{0x00} + reason = DecodeRevertReason(invalidData) + assert.Contains(t, reason, "invalid data for unpacking") +} \ No newline at end of file diff --git a/execution/execution.go b/execution/execution.go index 59b69e8..8e072b1 100644 --- a/execution/execution.go +++ b/execution/execution.go @@ -26,12 +26,15 @@ type ExecutionClient struct { } func (e *ExecutionClient) New(rpc string, state *State) (*ExecutionClient, error) { - r, err := ExecutionRpc.New(nil, &rpc) + // This is updated as earlier, when ExecutionRpc.New() was called, it was giving an + // invalid address or nil pointer dereference error as there wasn't a concrete type that implemented ExecutionRpc + var r ExecutionRpc + r, err := (&HttpRpc{}).New(&rpc) if err != nil { return nil, err } return &ExecutionClient{ - Rpc: *r, + Rpc: r, state: state, }, nil } @@ -60,12 +63,18 @@ func (e *ExecutionClient) CheckRpc(chainID uint64) error { } // GetAccount retrieves the account information -func (e *ExecutionClient) GetAccount(address *seleneCommon.Address, slots []common.Hash, tag seleneCommon.BlockTag) (Account, error) { //Account from execution/types.go +func (e *ExecutionClient) GetAccount(address *seleneCommon.Address, slots *[]common.Hash, tag seleneCommon.BlockTag) (Account, error) { //Account from execution/types.go block := e.state.GetBlock(tag) - proof, _ := e.Rpc.GetProof(address, &slots, block.Number) - + // Error Handling + proof, err := e.Rpc.GetProof(address, slots, block.Number) + if err != nil { + return Account{}, err + } accountPath := crypto.Keccak256(address.Addr[:]) - accountEncoded, _ := EncodeAccount(&proof) + accountEncoded, err := EncodeAccount(&proof) + if err != nil { + return Account{}, err + } accountProofBytes := make([][]byte, len(proof.AccountProof)) for i, hexByte := range proof.AccountProof { accountProofBytes[i] = hexByte @@ -78,7 +87,7 @@ func (e *ExecutionClient) GetAccount(address *seleneCommon.Address, slots []comm return Account{}, NewInvalidAccountProofError(address.Addr) } // modify - slotMap := make(map[common.Hash]*big.Int) + slotMap := []Slot{} for _, storageProof := range proof.StorageProof { key, err := utils.Hex_str_to_bytes(storageProof.Key.Hex()) if err != nil { @@ -105,7 +114,10 @@ func (e *ExecutionClient) GetAccount(address *seleneCommon.Address, slots []comm if !isValid { return Account{}, fmt.Errorf("invalid storage proof for address: %v, key: %v", *address, storageProof.Key) } - slotMap[storageProof.Key] = storageProof.Value.ToBig() + slotMap = append(slotMap, Slot{ + Key: storageProof.Key, + Value: storageProof.Value.ToBig(), + }) } var code []byte if bytes.Equal(proof.CodeHash.Bytes(), crypto.Keccak256([]byte(KECCAK_EMPTY))) { @@ -123,7 +135,7 @@ func (e *ExecutionClient) GetAccount(address *seleneCommon.Address, slots []comm } account := Account{ Balance: proof.Balance.ToBig(), - Nonce: proof.Nonce, + Nonce: uint64(proof.Nonce), Code: code, CodeHash: proof.CodeHash, StorageHash: proof.StorageHash, @@ -298,10 +310,8 @@ func (e *ExecutionClient) GetLogs(filter ethereum.FilterQuery) ([]types.Log, err select { case logs := <-logsChan: if len(logs) > MAX_SUPPORTED_LOGS_NUMBER { - return nil, &ExecutionError{ - Kind: "TooManyLogs", - Details: fmt.Sprintf("Too many logs to prove: %d, max: %d", len(logs), MAX_SUPPORTED_LOGS_NUMBER), - } + // The earlier error was not returning properly + return nil, errors.New("logs exceed max supported logs number") } logPtrs := make([]*types.Log, len(logs)) for i := range logs { @@ -506,19 +516,24 @@ func rlpHash(obj interface{}) (common.Hash, error) { } return crypto.Keccak256Hash(encoded), nil } +// This function is updated as it was going in an infinite loop func calculateMerkleRoot(hashes []common.Hash) common.Hash { - if len(hashes) == 1 { + switch len(hashes) { + case 0: + return common.Hash{} // Return empty hash for empty slice + case 1: return hashes[0] + default: + if len(hashes)%2 != 0 { + hashes = append(hashes, hashes[len(hashes)-1]) + } + var newLevel []common.Hash + for i := 0; i < len(hashes); i += 2 { + combinedHash := crypto.Keccak256(append(hashes[i].Bytes(), hashes[i+1].Bytes()...)) + newLevel = append(newLevel, common.BytesToHash(combinedHash)) + } + return calculateMerkleRoot(newLevel) } - if len(hashes)%2 != 0 { - hashes = append(hashes, hashes[len(hashes)-1]) - } - var newLevel []common.Hash - for i := 0; i < len(hashes); i += 2 { - combinedHash := crypto.Keccak256(append(hashes[i].Bytes(), hashes[i+1].Bytes()...)) - newLevel = append(newLevel, common.BytesToHash(combinedHash)) - } - return calculateMerkleRoot(newLevel) } // contains checks if a receipt is in the list of receipts diff --git a/execution/execution_test.go b/execution/execution_test.go new file mode 100644 index 0000000..a4d948e --- /dev/null +++ b/execution/execution_test.go @@ -0,0 +1,695 @@ +package execution + +import ( + "bytes" + "encoding/json" + "math/big" + "sync" + "testing" + + seleneCommon "github.com/BlocSoc-iitr/selene/common" + "github.com/ethereum/go-ethereum" + "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/ethereum/go-ethereum/rlp" + "github.com/holiman/uint256" + "github.com/stretchr/testify/assert" +) + +func CreateNewState() *State { + blockChan := make(chan *seleneCommon.Block) + finalizedBlockChan := make(chan *seleneCommon.Block) + + state := NewState(5, blockChan, finalizedBlockChan) + + // Simulate blocks to push + block1 := &seleneCommon.Block{ + Number: 1, + Hash: [32]byte{0x1}, + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{{0x11}, {0x12}}, + }, + } + block2 := &seleneCommon.Block{ + Number: 2, + Hash: [32]byte{0x2}, + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{{0x21}, {0x22}}, + Full: []seleneCommon.Transaction{ + { + Hash: common.Hash([32]byte{0x21}), + GasPrice: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + Gas: hexutil.Uint64(5), + MaxFeePerGas: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + }, + {Hash: common.Hash([32]byte{0x22})}, + }, + }, + } + + block3 := &seleneCommon.Block{ + Number: 1000000, + Hash: common.HexToHash("0x8e38b4dbf6b11fcc3b9dee84fb7986e29ca0a02cecd8977c161ff7333329681e"), + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{ + common.HexToHash("0xe9e91f1ee4b56c0df2e9f06c2b8c27c6076195a88a7b8537ba8313d80e6f124e"), + common.HexToHash("0xea1093d492a1dcb1bef708f771a99a96ff05dcab81ca76c31940300177fcf49f"), + }, + Full: []seleneCommon.Transaction{ + { + Hash: common.HexToHash("0xe9e91f1ee4b56c0df2e9f06c2b8c27c6076195a88a7b8537ba8313d80e6f124e"), + GasPrice: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + Gas: hexutil.Uint64(60), + MaxFeePerGas: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + }, + { + Hash: common.HexToHash("0xea1093d492a1dcb1bef708f771a99a96ff05dcab81ca76c31940300177fcf49f"), + GasPrice: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + Gas: hexutil.Uint64(60), + MaxFeePerGas: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + }, + }, + }, + } + + // Push blocks through channel + go func() { + blockChan <- block1 + blockChan <- block2 + blockChan <- block3 + close(blockChan) + }() + + // Allow goroutine to process the blocks + wg := sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + for len(state.blocks) < 3 { + // wait for blocks to be processed + } + }() + + wg.Wait() + + // Simulate finalized block + finalizedBlock := &seleneCommon.Block{ + Number: 2, + Hash: [32]byte{0x2}, + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{{0x21}, {0x22}}, + Full: []seleneCommon.Transaction{ + { + Hash: common.Hash([32]byte{0x21}), + GasPrice: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + Gas: hexutil.Uint64(5), + MaxFeePerGas: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + }, + {Hash: common.Hash([32]byte{0x22})}, + }, + }, + } + go func() { + finalizedBlockChan <- finalizedBlock + close(finalizedBlockChan) + }() + + // Wait for finalized block to be processed + wg.Add(1) + go func() { + defer wg.Done() + for state.finalizedBlock == nil { + // wait for finalized block to be processed + } + }() + wg.Wait() + + return state +} + +func CreateNewExecutionClient() *ExecutionClient { + rpc := "https://eth-mainnet.g.alchemy.com/v2/j28GcevSYukh-GvSeBOYcwHOfIggF1Gt" + state := CreateNewState() + var executionClient *ExecutionClient + executionClient, _ = executionClient.New(rpc, state) + + return executionClient +} + +func TestCheckRpc(t *testing.T) { + executionClient := CreateNewExecutionClient() + chainId := uint64(1) + err := executionClient.CheckRpc(chainId) + + assert.NoError(t, err, "Error Found") + + chainId = uint64(2) + err = executionClient.CheckRpc(chainId) + + assert.Equal(t, NewIncorrectRpcNetworkError() , err, "Error didn't match") +} + +// Both GetAccount() and GetTransactionReceipt() depend on state + +// func TestGetAccount(t *testing.T) { +// executionClient := CreateNewExecutionClient() +// addressBytes, _ := utils.Hex_str_to_bytes("0x457a22804cf255ee8c1b7628601c5682b3d70c71") + +// address := seleneCommon.Address{Addr: [20]byte(addressBytes)} + +// slots := []common.Hash{} +// tag := seleneCommon.BlockTag{ +// Finalized: true, +// } +// print("Check\n") +// account, err := executionClient.GetAccount(&address, &slots, tag) + +// assert.NoError(t, err, "Error found") +// assert.Equal(t, Account{}, account, "Account didn't match") +// } + +func TestToBlockNumberArg(t *testing.T) { + blockNumber := uint64(5050) + assert.Equal(t, "0x13ba", toBlockNumArg(blockNumber), "Block Number didn't match") + + blockNumber = uint64(0) + assert.Equal(t, "latest", toBlockNumArg(blockNumber), "Block Number didn't match") +} + +//* Not possible to test as we would have to send actual txn on mainnet +// func TestSendRawTransaction(t *testing.T) { +// executionClient := CreateNewExecutionClient() +// transaction := common.Hex2Bytes("02f8720113840a436fe4850749a01900825208942ce3384fcaea81a0f10b2599ffb2f0603e6169f1878e1bc9bf04000080c080a097f6540a48025bd28dd3c43f33aa0269a29b40d852396fab1ab7c2f95a3930e7a03f69a6bca9ef4be6ce60735e76133670617286e15e18af96b7e5e0afcdc240c6") +// fmt.Printf("Transaction Bytes: %v ", transaction) +// hash, err := executionClient.SendRawTransaction(transaction) + +// assert.NoError(t, err, "Found Error") +// assert.Equal(t, common.Hash{}, hash, "Transaction Hash didn't match") +// } + +func TestGetBlock(t *testing.T) { + executionClient := CreateNewExecutionClient() + blockTag := seleneCommon.BlockTag{ + Number: 1, + } + + block, err := executionClient.GetBlock(blockTag, false) + expected := seleneCommon.Block{ + Number: 1, + Hash: [32]byte{0x1}, + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{{0x11}, {0x12}}, + }, + } + + assert.NoError(t, err, "Found Error") + assert.Equal(t, expected, block , "Value didn't match expected") + + blockTag = seleneCommon.BlockTag{ + Finalized: true, + } + + block, err = executionClient.GetBlock(blockTag, false) + expected = seleneCommon.Block{ + Number: 2, + Hash: [32]byte{0x2}, + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{{0x21}, {0x22}}, + }, + } + + assert.NoError(t, err, "Found Error") + assert.Equal(t, expected, block , "Value didn't match expected") + + block, err = executionClient.GetBlock(blockTag, true) + expected = seleneCommon.Block{ + Number: 2, + Hash: [32]byte{0x2}, + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{{0x21}, {0x22}}, + Full: []seleneCommon.Transaction{ + { + Hash: common.Hash([32]byte{0x21}), + GasPrice: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + Gas: hexutil.Uint64(5), + MaxFeePerGas: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + }, + {Hash: common.Hash([32]byte{0x22})}, + }, + }, + } + + assert.NoError(t, err, "Found Error") + assert.Equal(t, expected, block , "Value didn't match expected") +} + +func TestExecutionGetBlockByHash(t *testing.T) { + executionClient := CreateNewExecutionClient() + hash := common.Hash([32]byte{0x2}) + + block, err := executionClient.GetBlockByHash(hash, false) + expected := seleneCommon.Block{ + Number: 2, + Hash: [32]byte{0x2}, + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{{0x21}, {0x22}}, + }, + } + + assert.NoError(t, err, "Found Error") + assert.Equal(t, expected, block , "Value didn't match expected") + + block, err = executionClient.GetBlockByHash(hash, true) + expected = seleneCommon.Block{ + Number: 2, + Hash: [32]byte{0x2}, + Transactions: seleneCommon.Transactions{ + Hashes: [][32]byte{{0x21}, {0x22}}, + Full: []seleneCommon.Transaction{ + { + Hash: common.Hash([32]byte{0x21}), + GasPrice: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + Gas: hexutil.Uint64(5), + MaxFeePerGas: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + }, + {Hash: common.Hash([32]byte{0x22})}, + }, + }, + } + + assert.NoError(t, err, "Found Error") + assert.Equal(t, expected, block, "Value didn't match expected") +} + +func TestGetTransactionByBlockHashAndIndex(t *testing.T) { + executionClient := CreateNewExecutionClient() + hash := common.Hash([32]byte{0x2}) + + txn, err := executionClient.GetTransactionByBlockHashAndIndex(hash, 0) + + expected := seleneCommon.Transaction{ + Hash: common.Hash([32]byte{0x21}), + GasPrice: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + Gas: hexutil.Uint64(5), + MaxFeePerGas: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + } + + assert.NoError(t, err, "Found Error") + assert.Equal(t, expected, txn, "Value didn't match expected") +} + +// func TestExecutionGetTransactionReceipt(t *testing.T) { +// executionClient := CreateNewExecutionClient() +// txHash := common.HexToHash("0xea1093d492a1dcb1bef708f771a99a96ff05dcab81ca76c31940300177fcf49f") +// txnReceipt, err := executionClient.GetTransactionReceipt(txHash) +// expected := types.Receipt{} + +// assert.NoError(t, err, "Found Error") +// assert.Equal(t, expected, txnReceipt, "Receipt didn't match") +// } + +func TestExecutionGetTransaction(t *testing.T) { + executionClient := CreateNewExecutionClient() + txHash := common.Hash([32]byte{0x21}) + + txn, err := executionClient.GetTransaction(txHash) + expected := seleneCommon.Transaction{ + Hash: common.Hash([32]byte{0x21}), + GasPrice: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + Gas: hexutil.Uint64(5), + MaxFeePerGas: hexutil.Big(*hexutil.MustDecodeBig("0x12345")), + } + + assert.NoError(t, err, "Found Error") + assert.Equal(t, expected, txn, "Txn didn't match") +} + +func TestExecutionGetLogs(t *testing.T) { + executionClient := CreateNewExecutionClient() + + // Test case 1: Basic log retrieval + filter := ethereum.FilterQuery{ + FromBlock: hexutil.MustDecodeBig("0x14057d0"), + ToBlock: hexutil.MustDecodeBig("0x1405814"), + Addresses: []common.Address{ + common.HexToAddress("0x6F9116ea572a207e4267f92b1D7b6F9b23536b07"), + }, + } + + _, err := executionClient.GetLogs(filter) + assert.NoError(t, err, "GetLogs should not return error for valid filter") +} + +func TestExecutionGetFilterChanges(t *testing.T) { + executionClient := CreateNewExecutionClient() + // Test case 1: Basic filter creation + filter := ethereum.FilterQuery{ + FromBlock: big.NewInt(1), + ToBlock: big.NewInt(2), + Addresses: []common.Address{ + common.HexToAddress("0x1234567890123456789012345678901234567890"), + }, + } + + filterID, _ := executionClient.GetNewFilter(filter) + + _, err := executionClient.GetFilterChanges(&filterID) + assert.NoError(t, err, "GetFilterChanges should not return error for valid filter ID") +} + +func TestExecutionUninstallFilter(t *testing.T) { + executionClient := CreateNewExecutionClient() + + // Test case 1: Basic filter creation + filter := ethereum.FilterQuery{ + FromBlock: big.NewInt(1), + ToBlock: big.NewInt(2), + Addresses: []common.Address{ + common.HexToAddress("0x1234567890123456789012345678901234567890"), + }, + } + filterID, _ := executionClient.GetNewFilter(filter) + + result, err := executionClient.UninstallFilter(&filterID) + assert.NoError(t, err, "UninstallFilter should not return error for valid filter ID") + assert.True(t, result, "UninstallFilter should return true on success") + + // Test case 2: Invalid filter ID + invalidFilterID := uint256.NewInt(999) + result, err = executionClient.UninstallFilter(invalidFilterID) + assert.NoError(t, err, "UninstallFilter should not return error for invalid filter ID") + assert.False(t, result, "UninstallFilter should return false for invalid filter ID") +} + +func TestExecutionGetNewFilter(t *testing.T) { + executionClient := CreateNewExecutionClient() + + // Test case 1: Basic filter creation + filter := ethereum.FilterQuery{ + FromBlock: big.NewInt(1), + ToBlock: big.NewInt(2), + Addresses: []common.Address{ + common.HexToAddress("0x1234567890123456789012345678901234567890"), + }, + } + + filterID, err := executionClient.GetNewFilter(filter) + assert.NoError(t, err, "GetNewFilter should not return error for valid filter") + assert.NotEqual(t, uint256.Int{}, filterID, "FilterID should not be empty") + + // Test case 2: Null blocks defaults to latest + filterNullBlocks := ethereum.FilterQuery{ + Addresses: []common.Address{ + common.HexToAddress("0x1234567890123456789012345678901234567890"), + }, + } + + filterID, err = executionClient.GetNewFilter(filterNullBlocks) + assert.NoError(t, err, "GetNewFilter should handle null blocks") + assert.NotEqual(t, uint256.Int{}, filterID, "FilterID should not be empty") +} + +func TestExecutionGetNewBlockFilter(t *testing.T) { + executionClient := CreateNewExecutionClient() + + filterID, err := executionClient.GetNewBlockFilter() + assert.NoError(t, err, "GetNewBlockFilter should not return error") + assert.NotEqual(t, uint256.Int{}, filterID, "FilterID should not be empty") +} + +func TestExecutionGetNewPendingTransactionFilter(t *testing.T) { + executionClient := CreateNewExecutionClient() + + filterID, err := executionClient.GetNewPendingTransactionFilter() + assert.NoError(t, err, "GetNewPendingTransactionFilter should not return error") + assert.NotEqual(t, uint256.Int{}, filterID, "FilterID should not be empty") +} + +func TestCalculateReceiptRoot(t *testing.T) { + // Test case 1: Empty receipts + _, err := CalculateReceiptRoot([][]byte{}) + assert.Error(t, err, "CalculateReceiptRoot should return error for empty receipts") + assert.Contains(t, err.Error(), "no receipts to calculate root") + + // Test case 2: Single receipt + receipt1 := []byte{1, 2, 3} + root, err := CalculateReceiptRoot([][]byte{receipt1}) + assert.NoError(t, err, "CalculateReceiptRoot should not return error for single receipt") + assert.NotEqual(t, common.Hash{}, root, "Root should not be empty") + + // Test case 3: Multiple receipts + receipt2 := []byte{4, 5, 6} + root, err = CalculateReceiptRoot([][]byte{receipt1, receipt2}) + assert.NoError(t, err, "CalculateReceiptRoot should not return error for multiple receipts") + assert.NotEqual(t, common.Hash{}, root, "Root should not be empty") +} + +func TestVerifyLogs(t *testing.T) { + executionClient := CreateNewExecutionClient() + logData := `{ + "address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2", + "blockHash": "0xa495e3d87cf01430e9838341e1d36929fc9c8dfdb89133b372cae4019b5a534a", + "blockNumber": "0xC166C3", + "data": "0x0000000000000000000000000000000000000000000000003a395039b420f1bd", + "logIndex": "0x0", + "removed": false, + "topics": [ + "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef", + "0x00000000000000000000000043cc25b1fb6435d8d893fcf308de5c300a568be2", + "0x00000000000000000000000044d34985826578e5ba24ec78c93be968549bb918"], + "transactionHash": "0xac80bab0940f061e184b0dda380d994e6fc14ab5d0c6f689035631c81bfe220b", + "transactionIndex": "0x0" + }` + + var log types.Log + err := json.Unmarshal([]byte(logData), &log) + assert.NoError(t, err, "VerifyLogs should not give an error") + + // fmt.Printf("Expected Log: %v\n", log) + err = executionClient.verifyLogs([]*types.Log{&log}) + assert.NoError(t, err, "VerifyLogs should not give an error") +} + +func TestContains(t *testing.T) { + // Create test receipts + receipt1 := types.Receipt{ + TxHash: common.HexToHash("0x1"), + } + receipt2 := types.Receipt{ + TxHash: common.HexToHash("0x2"), + } + receipts := []types.Receipt{receipt1} + + // Test case 1: Receipt exists + assert.True(t, contains(receipts, receipt1), "Contains should return true for existing receipt") + + // Test case 2: Receipt doesn't exist + assert.False(t, contains(receipts, receipt2), "Contains should return false for non-existing receipt") +} + +// TestRlpHash tests the rlpHash function with various inputs +func TestRlpHash(t *testing.T) { + tests := []struct { + name string + input interface{} + wantErr bool + }{ + { + name: "Simple string", + input: "test", + wantErr: false, + }, + { + name: "Empty slice", + input: []byte{}, + wantErr: false, + }, + { + name: "Complex struct", + input: struct { + A string + B uint64 + }{"test", 123}, + wantErr: false, + }, + { + name: "Invalid input", + input: make(chan int), // channels cannot be RLP encoded + wantErr: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + hash, err := rlpHash(tt.input) + if (err != nil) != tt.wantErr { + t.Errorf("rlpHash() error = %v, wantErr %v", err, tt.wantErr) + return + } + if !tt.wantErr { + // Verify the hash is not empty + if hash == (common.Hash{}) { + t.Error("rlpHash() returned empty hash") + } + + // Verify deterministic behavior + hash2, _ := rlpHash(tt.input) + if hash != hash2 { + t.Error("rlpHash() is not deterministic") + } + } + }) + } +} + +// TestCalculateMerkleRoot tests the calculateMerkleRoot function +func TestCalculateMerkleRoot(t *testing.T) { + tests := []struct { + name string + hashes []common.Hash + want common.Hash + }{ + { + name: "Two hashes", + hashes: []common.Hash{ + common.HexToHash("0x1234"), + common.HexToHash("0x5678"), + }, + want: crypto.Keccak256Hash( + append( + common.HexToHash("0x1234").Bytes(), + common.HexToHash("0x5678").Bytes()..., + ), + ), + }, + { + name: "Odd number of hashes", + hashes: []common.Hash{ + common.HexToHash("0x1234"), + common.HexToHash("0x5678"), + common.HexToHash("0x9abc"), + }, + want: func() common.Hash { + // Duplicate last hash since odd number + hashes := []common.Hash{ + common.HexToHash("0x1234"), + common.HexToHash("0x5678"), + common.HexToHash("0x9abc"), + common.HexToHash("0x9abc"), + } + // Calculate first level + h1 := crypto.Keccak256Hash(append(hashes[0].Bytes(), hashes[1].Bytes()...)) + h2 := crypto.Keccak256Hash(append(hashes[2].Bytes(), hashes[3].Bytes()...)) + // Calculate root + return crypto.Keccak256Hash(append(h1.Bytes(), h2.Bytes()...)) + }(), + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := calculateMerkleRoot(tt.hashes) + if got != tt.want { + t.Errorf("calculateMerkleRoot() = %v, want %v", got, tt.want) + } + + // Verify deterministic behavior + got2 := calculateMerkleRoot(tt.hashes) + if got != got2 { + t.Error("calculateMerkleRoot() is not deterministic") + } + }) + } +} + +// TestEncodeReceipt tests the encodeReceipt function +func TestEncodeReceipt(t *testing.T) { + bloom := types.Bloom{} + logs := []*types.Log{} + + tests := []struct { + name string + receipt *types.Receipt + wantErr bool + }{ + { + name: "Legacy receipt (type 0)", + receipt: &types.Receipt{ + Type: 0, + Status: 1, + CumulativeGasUsed: 21000, + Bloom: bloom, + Logs: logs, + }, + wantErr: false, + }, + { + name: "EIP-2930 receipt (type 1)", + receipt: &types.Receipt{ + Type: 1, + Status: 1, + CumulativeGasUsed: 21000, + Bloom: bloom, + Logs: logs, + }, + wantErr: false, + }, + { + name: "EIP-1559 receipt (type 2)", + receipt: &types.Receipt{ + Type: 2, + Status: 1, + CumulativeGasUsed: 21000, + Bloom: bloom, + Logs: logs, + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := encodeReceipt(tt.receipt) + if (err != nil) != tt.wantErr { + t.Errorf("encodeReceipt() error = %v, wantErr %v", err, tt.wantErr) + return + } + + if !tt.wantErr { + // Verify the encoding starts with the correct type byte for non-legacy transactions + if tt.receipt.Type > 0 { + if got[0] != tt.receipt.Type { + t.Errorf("encodeReceipt() first byte = %d, want %d", got[0], tt.receipt.Type) + } + } + + // Verify the encoding is deterministic + got2, _ := encodeReceipt(tt.receipt) + if !bytes.Equal(got, got2) { + t.Error("encodeReceipt() is not deterministic") + } + + // Verify the encoded data can be decoded back + var decoded []interface{} + var decodedData []byte + if tt.receipt.Type > 0 { + decodedData = got[1:] // Skip type byte + } else { + decodedData = got + } + + err = rlp.DecodeBytes(decodedData, &decoded) + if err != nil { + t.Errorf("Failed to decode receipt: %v", err) + } + + // Verify decoded fields match original + if len(decoded) != 4 { + t.Errorf("Decoded receipt has wrong number of fields: got %d, want 4", len(decoded)) + } + } + }) + } +} \ No newline at end of file diff --git a/execution/http_rpc.go b/execution/http_rpc.go index 01bd876..24dbffa 100644 --- a/execution/http_rpc.go +++ b/execution/http_rpc.go @@ -1,374 +1,398 @@ -package execution - -import ( - seleneCommon "github.com/BlocSoc-iitr/selene/common" - "github.com/ethereum/go-ethereum" - "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/rpc" - "github.com/holiman/uint256" - "strconv" -) - -type HttpRpc struct { - url string - provider *rpc.Client -} - -func New(rpcUrl string) (*HttpRpc, error) { - client, err := rpc.Dial(rpcUrl) - if err != nil { - return nil, err - } - - return &HttpRpc{ - url: rpcUrl, - provider: client, - }, nil -} - -func (h *HttpRpc) GetProof(address *common.Address, slots *[]common.Hash, block uint64) (EIP1186ProofResponse, error) { - resultChan := make(chan struct { - proof EIP1186ProofResponse - err error - }) - - go func() { - var proof EIP1186ProofResponse - err := h.provider.Call(&proof, "eth_getProof", address, slots, toBlockNumArg(block)) - resultChan <- struct { - proof EIP1186ProofResponse - err error - }{proof, err} - close(resultChan) - }() - result := <-resultChan - if result.err != nil { - return EIP1186ProofResponse{}, result.err - } - return result.proof, nil -} - -func (h *HttpRpc) CreateAccessList(opts CallOpts, block seleneCommon.BlockTag) (types.AccessList, error) { - resultChan := make(chan struct { - accessList types.AccessList - err error - }) - - go func() { - var accessList types.AccessList - err := h.provider.Call(&accessList, "eth_createAccessList", opts, block) - resultChan <- struct { - accessList types.AccessList - err error - }{accessList, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return nil, result.err - } - return result.accessList, nil -} - -func (h *HttpRpc) GetCode(address *common.Address, block uint64) (hexutil.Bytes, error) { - resultChan := make(chan struct { - code hexutil.Bytes - err error - }) - - go func() { - var code hexutil.Bytes - err := h.provider.Call(&code, "eth_getCode", address, toBlockNumArg(block)) - resultChan <- struct { - code hexutil.Bytes - err error - }{code, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return nil, result.err - } - return result.code, nil -} - -func (h *HttpRpc) SendRawTransaction(data *[]byte) (common.Hash, error) { - resultChan := make(chan struct { - txHash common.Hash - err error - }) - - go func() { - var txHash common.Hash - err := h.provider.Call(&txHash, "eth_sendRawTransaction", hexutil.Bytes(*data)) - resultChan <- struct { - txHash common.Hash - err error - }{txHash, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return common.Hash{}, result.err - } - return result.txHash, nil -} - -func (h *HttpRpc) GetTransactionReceipt(txHash *common.Hash) (types.Receipt, error) { - resultChan := make(chan struct { - receipt types.Receipt - err error - }) - - go func() { - var receipt types.Receipt - err := h.provider.Call(&receipt, "eth_getTransactionReceipt", txHash) - resultChan <- struct { - receipt types.Receipt - err error - }{receipt, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return types.Receipt{}, result.err - } - return result.receipt, nil -} - -func (h *HttpRpc) GetTransaction(txHash *common.Hash) (seleneCommon.Transaction, error) { - resultChan := make(chan struct { - tx seleneCommon.Transaction - err error - }) - - go func() { - var tx seleneCommon.Transaction - err := h.provider.Call(&tx, "eth_getTransactionByHash", txHash) - resultChan <- struct { - tx seleneCommon.Transaction - err error - }{tx, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return seleneCommon.Transaction{}, result.err - } - return result.tx, nil -} - -func (h *HttpRpc) GetLogs(filter *ethereum.FilterQuery) ([]types.Log, error) { - resultChan := make(chan struct { - logs []types.Log - err error - }) - - go func() { - var logs []types.Log - err := h.provider.Call(&logs, "eth_getLogs", toFilterArg(*filter)) - resultChan <- struct { - logs []types.Log - err error - }{logs, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return nil, result.err - } - return result.logs, nil -} - -func (h *HttpRpc) GetFilterChanges(filterID *uint256.Int) ([]types.Log, error) { - resultChan := make(chan struct { - logs []types.Log - err error - }) - - go func() { - var logs []types.Log - err := h.provider.Call(&logs, "eth_getFilterChanges", filterID) - resultChan <- struct { - logs []types.Log - err error - }{logs, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return nil, result.err - } - return result.logs, nil -} - -func (h *HttpRpc) UninstallFilter(filterID *uint256.Int) (bool, error) { - resultChan := make(chan struct { - result bool - err error - }) - - go func() { - var result bool - err := h.provider.Call(&result, "eth_uninstallFilter", filterID) - resultChan <- struct { - result bool - err error - }{result, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return false, result.err - } - return result.result, nil -} - -func (h *HttpRpc) GetNewFilter(filter *ethereum.FilterQuery) (uint256.Int, error) { - resultChan := make(chan struct { - filterID uint256.Int - err error - }) - - go func() { - var filterID uint256.Int - err := h.provider.Call(&filterID, "eth_newFilter", toFilterArg(*filter)) - resultChan <- struct { - filterID uint256.Int - err error - }{filterID, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return uint256.Int{}, result.err - } - return result.filterID, nil -} - -func (h *HttpRpc) GetNewBlockFilter() (uint256.Int, error) { - resultChan := make(chan struct { - filterID uint256.Int - err error - }) - - go func() { - var filterID uint256.Int - err := h.provider.Call(&filterID, "eth_newBlockFilter") - resultChan <- struct { - filterID uint256.Int - err error - }{filterID, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return uint256.Int{}, result.err - } - return result.filterID, nil -} - -func (h *HttpRpc) GetNewPendingTransactionFilter() (uint256.Int, error) { - resultChan := make(chan struct { - filterID uint256.Int - err error - }) - - go func() { - var filterID uint256.Int - err := h.provider.Call(&filterID, "eth_newPendingTransactionFilter") - resultChan <- struct { - filterID uint256.Int - err error - }{filterID, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return uint256.Int{}, result.err - } - return result.filterID, nil -} - -func (h *HttpRpc) ChainId() (uint64, error) { - resultChan := make(chan struct { - chainID uint64 - err error - }) - - go func() { - var chainID uint64 - err := h.provider.Call(&chainID, "eth_chainId") - resultChan <- struct { - chainID uint64 - err error - }{chainID, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return 0, result.err - } - return result.chainID, nil -} - -func (h *HttpRpc) GetFeeHistory(blockCount uint64, lastBlock uint64, rewardPercentiles *[]float64) (ethereum.FeeHistory, error) { - resultChan := make(chan struct { - feeHistory ethereum.FeeHistory - err error - }) - - go func() { - var feeHistory ethereum.FeeHistory - err := h.provider.Call(&feeHistory, "eth_feeHistory", blockCount, lastBlock, rewardPercentiles) - resultChan <- struct { - feeHistory ethereum.FeeHistory - err error - }{feeHistory, err} - close(resultChan) - }() - - result := <-resultChan - if result.err != nil { - return ethereum.FeeHistory{}, result.err - } - return result.feeHistory, nil -} - -func toBlockNumArg(number uint64) string { - if number == 0 { - return "latest" - } - return "0x" + strconv.FormatUint(number, 16) -} - -func toFilterArg(q ethereum.FilterQuery) map[string]interface{} { - arg := make(map[string]interface{}) - if len(q.Addresses) > 0 { - arg["address"] = q.Addresses - } - if len(q.Topics) > 0 { - arg["topics"] = q.Topics - } - if q.FromBlock != nil { - arg["fromBlock"] = q.FromBlock.String() - } - if q.ToBlock != nil { - arg["toBlock"] = q.ToBlock.String() - } - return arg -} +package execution + +import ( + "strconv" + "encoding/hex" + "math/big" + + seleneCommon "github.com/BlocSoc-iitr/selene/common" + "github.com/ethereum/go-ethereum" + "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/rpc" + "github.com/holiman/uint256" +) + +type HttpRpc struct { + url string + provider *rpc.Client +} + +// I have made some changes to ExecutionRpc and to HttpRpc as HttpRpc was not satisfying +// ExecutionRpc interface before +func (h *HttpRpc) New(rpcUrl *string) (ExecutionRpc, error) { + client, err := rpc.Dial(*rpcUrl) + if err != nil { + return nil, err + } + + return &HttpRpc{ + url: *rpcUrl, + provider: client, + }, nil +} + +// All the changes that have been made in functions that fetch from rpc are because: +// The rpc expects request to be in form of hexadecimal strings. For example, if we want +// to send block number equal to 1405, it will interpret it as 0x1405, which is not it's hex representation +// +// Similarly, the values recieved from rpc should also be treated as hex strings +func (h *HttpRpc) GetProof(address *seleneCommon.Address, slots *[]common.Hash, block uint64) (EIP1186ProofResponse, error) { + resultChan := make(chan struct { + proof EIP1186ProofResponse + err error + }) + // All arguments to rpc are expected to be in form of hex strings + var slotHex []string + if slots != nil { + for _, slot := range *slots { + slotHex = append(slotHex, slot.Hex()) + } + } + if len(*slots) == 0 { + slotHex = []string{} + } + go func() { + var proof EIP1186ProofResponse + err := h.provider.Call(&proof, "eth_getProof", "0x"+hex.EncodeToString(address.Addr[:]), slotHex, toBlockNumArg(block)) + resultChan <- struct { + proof EIP1186ProofResponse + err error + }{proof, err} + close(resultChan) + }() + result := <-resultChan + if result.err != nil { + return EIP1186ProofResponse{}, result.err + } + return result.proof, nil +} + +// TODO: CreateAccessList is throwing an error +// There is a problem in unmarshaling the response into types.AccessList +func (h *HttpRpc) CreateAccessList(opts CallOpts, block seleneCommon.BlockTag) (types.AccessList, error) { + resultChan := make(chan struct { + accessList types.AccessList + err error + }) + + go func() { + var accessList types.AccessList + err := h.provider.Call(&accessList, "eth_createAccessList", opts, block.String()) + resultChan <- struct { + accessList types.AccessList + err error + }{accessList, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return nil, result.err + } + return result.accessList, nil +} + +func (h *HttpRpc) GetCode(address *seleneCommon.Address, block uint64) ([]byte, error) { + resultChan := make(chan struct { + code hexutil.Bytes + err error + }) + + go func() { + var code hexutil.Bytes + err := h.provider.Call(&code, "eth_getCode", "0x"+hex.EncodeToString(address.Addr[:]), toBlockNumArg(block)) + resultChan <- struct { + code hexutil.Bytes + err error + }{code, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return nil, result.err + } + return result.code, nil +} + +func (h *HttpRpc) SendRawTransaction(data *[]byte) (common.Hash, error) { + resultChan := make(chan struct { + txHash common.Hash + err error + }) + + go func() { + var txHash common.Hash + err := h.provider.Call(&txHash, "eth_sendRawTransaction", hexutil.Bytes(*data)) + resultChan <- struct { + txHash common.Hash + err error + }{txHash, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return common.Hash{}, result.err + } + return result.txHash, nil +} + +func (h *HttpRpc) GetTransactionReceipt(txHash *common.Hash) (types.Receipt, error) { + resultChan := make(chan struct { + receipt types.Receipt + err error + }) + + go func() { + var receipt types.Receipt + err := h.provider.Call(&receipt, "eth_getTransactionReceipt", txHash) + resultChan <- struct { + receipt types.Receipt + err error + }{receipt, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return types.Receipt{}, result.err + } + return result.receipt, nil +} + +func (h *HttpRpc) GetTransaction(txHash *common.Hash) (seleneCommon.Transaction, error) { + resultChan := make(chan struct { + tx seleneCommon.Transaction + err error + }) + + go func() { + var tx seleneCommon.Transaction + err := h.provider.Call(&tx, "eth_getTransactionByHash", txHash) + resultChan <- struct { + tx seleneCommon.Transaction + err error + }{tx, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return seleneCommon.Transaction{}, result.err + } + return result.tx, nil +} + +func (h *HttpRpc) GetLogs(filter *ethereum.FilterQuery) ([]types.Log, error) { + resultChan := make(chan struct { + logs []types.Log + err error + }) + + go func() { + var logs []types.Log + err := h.provider.Call(&logs, "eth_getLogs", toFilterArg(*filter)) + resultChan <- struct { + logs []types.Log + err error + }{logs, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return nil, result.err + } + return result.logs, nil +} + +func (h *HttpRpc) GetFilterChanges(filterID *uint256.Int) ([]types.Log, error) { + resultChan := make(chan struct { + logs []types.Log + err error + }) + + go func() { + var logs []types.Log + err := h.provider.Call(&logs, "eth_getFilterChanges", filterID.Hex()) + resultChan <- struct { + logs []types.Log + err error + }{logs, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return nil, result.err + } + return result.logs, nil +} + +func (h *HttpRpc) UninstallFilter(filterID *uint256.Int) (bool, error) { + resultChan := make(chan struct { + result bool + err error + }) + + go func() { + var result bool + err := h.provider.Call(&result, "eth_uninstallFilter", filterID.Hex()) + resultChan <- struct { + result bool + err error + }{result, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return false, result.err + } + return result.result, nil +} + +func (h *HttpRpc) GetNewFilter(filter *ethereum.FilterQuery) (uint256.Int, error) { + resultChan := make(chan struct { + filterID uint256.Int + err error + }) + + go func() { + var filterID hexutil.Big + err := h.provider.Call(&filterID, "eth_newFilter", toFilterArg(*filter)) + filterResult := big.Int(filterID) + resultChan <- struct { + filterID uint256.Int + err error + }{*uint256.MustFromBig(&filterResult), err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return uint256.Int{}, result.err + } + return result.filterID, nil +} + +func (h *HttpRpc) GetNewBlockFilter() (uint256.Int, error) { + resultChan := make(chan struct { + filterID uint256.Int + err error + }) + + go func() { + var filterID hexutil.Big + err := h.provider.Call(&filterID, "eth_newBlockFilter") + filterResult := big.Int(filterID) + resultChan <- struct { + filterID uint256.Int + err error + }{*uint256.MustFromBig(&filterResult), err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return uint256.Int{}, result.err + } + return result.filterID, nil +} + +func (h *HttpRpc) GetNewPendingTransactionFilter() (uint256.Int, error) { + resultChan := make(chan struct { + filterID uint256.Int + err error + }) + + go func() { + var filterID hexutil.Big + err := h.provider.Call(&filterID, "eth_newPendingTransactionFilter") + filterResult := big.Int(filterID) + resultChan <- struct { + filterID uint256.Int + err error + }{*uint256.MustFromBig(&filterResult), err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return uint256.Int{}, result.err + } + return result.filterID, nil +} + +func (h *HttpRpc) ChainId() (uint64, error) { + resultChan := make(chan struct { + chainID uint64 + err error + }) + + go func() { + var chainID hexutil.Uint64 + err := h.provider.Call(&chainID, "eth_chainId") + resultChan <- struct { + chainID uint64 + err error + }{uint64(chainID), err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return 0, result.err + } + return result.chainID, nil +} + +func (h *HttpRpc) GetFeeHistory(blockCount uint64, lastBlock uint64, rewardPercentiles *[]float64) (FeeHistory, error) { + resultChan := make(chan struct { + feeHistory FeeHistory + err error + }) + + go func() { + var feeHistory FeeHistory + err := h.provider.Call(&feeHistory, "eth_feeHistory", hexutil.Uint64(blockCount).String(), toBlockNumArg(lastBlock), rewardPercentiles) + resultChan <- struct { + feeHistory FeeHistory + err error + }{feeHistory, err} + close(resultChan) + }() + + result := <-resultChan + if result.err != nil { + return FeeHistory{}, result.err + } + return result.feeHistory, nil +} + +func toBlockNumArg(number uint64) string { + if number == 0 { + return "latest" + } + return "0x" + strconv.FormatUint(number, 16) +} + +func toFilterArg(q ethereum.FilterQuery) map[string]interface{} { + arg := make(map[string]interface{}) + if len(q.Addresses) > 0 { + arg["address"] = q.Addresses + } + if len(q.Topics) > 0 { + arg["topics"] = q.Topics + } + if q.FromBlock != nil { + arg["fromBlock"] = toBlockNumArg(q.FromBlock.Uint64()) + } + if q.ToBlock != nil { + arg["toBlock"] = toBlockNumArg(q.ToBlock.Uint64()) + } + return arg +} diff --git a/execution/http_rpc_test.go b/execution/http_rpc_test.go new file mode 100644 index 0000000..785b7c2 --- /dev/null +++ b/execution/http_rpc_test.go @@ -0,0 +1,270 @@ +package execution + +import ( + "encoding/json" + "fmt" + "math/big" + "testing" + + seleneCommon "github.com/BlocSoc-iitr/selene/common" + "github.com/BlocSoc-iitr/selene/utils" + "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/stretchr/testify/assert" +) + +func MakeNewRpc(t *testing.T) ExecutionRpc{ + rpcUrl := "https://eth-mainnet.g.alchemy.com/v2/j28GcevSYukh-GvSeBOYcwHOfIggF1Gt" + + var httpRpc ExecutionRpc + httpRpc, err := (&HttpRpc{}).New(&rpcUrl) + + if err != nil { + t.Errorf("Error in creating new rpc: %v", err) + } + + return httpRpc +} + +func TestGetProof(t *testing.T) { + rpc := MakeNewRpc(t) + + addressBytes, err := utils.Hex_str_to_bytes("0xB856af30B938B6f52e5BfF365675F358CD52F91B") + if err != nil { + t.Errorf("Error in decoding address string:, %v", err) + } + + var address seleneCommon.Address = seleneCommon.Address{Addr: [20]byte(addressBytes)} + slots := []common.Hash{} + var block uint64 = 14900001 + + proof, err := rpc.GetProof(&address, &slots, block) + // fmt.Printf("Proof: %v", proof) + if err != nil { + t.Errorf("Error in fetching proof: %v", err) + } + + var accountProof EIP1186ProofResponse + proofString := `{ + "address": "0xb856af30b938b6f52e5bff365675f358cd52f91b", + "accountProof": [ + "0xf90211a021162657aa1e0af5eef47130ffc3362cb675ebbccfc99ee38ef9196144623507a073dec98f4943e2ab00f5751c23db67b65009bb3cb178d33f5aa93f0c08d583dda0d85b4e33773aaab742db880f8b64ea71f348c6eccb0a56854571bbd3db267f24a0bdcca489de03a49f109c1a2e7d3bd4e644d72de38b7b26dca2f8d3f112110c6fa05c7e8fdff6de07c4cb9ca6bea487a6e5be04af538c25480ce30761901b17e4bfa0d9891f4870e745509cfe17a31568f870b367a36329c892f1b2a37bf59e547183a0af08f747d2ea66efa5bcd03729a95f56297ef9b1e8533ac0d3c7546ebefd2418a0a107595919d4b102afaa0d9b91d9f554f83f0ad61a1e04487e5091543eb81db8a0a0725da6da3b62f88fc573a3fd0dd9dea9cba1750786021da836fd95b7295636a0fd7a768700af3caadaf52a08a23ab0b71ca52830f2b88b1a6b23a52f9ee05507a059434ae837706d7d317e4f7d03cd91f94ed0465fa8b99eaf18ca363bb318c7b3a09e9b831a5f59b781efd5dae8bea30bfd81b9fd5ea231d6b7e82da495c95dd35da0e72d02a01ed9bc928d94cad59ae0695f45120b7fbdbce43a2239a7e5bc81f731a0184bfb9a4051cbaa79917183d004c8d574d7ed5becaf9614c650ed40e8d123d9a0fa4797dc4a35af07f1cd6955318e3ff59578d4df32fd2174ed35f6c4db3471f9a0fec098d1fee8e975b5e78e19003699cf7cd746f47d03692d8e11c5fd58ba92a680", + "0xf90211a07fc5351578eb6ab7618a31e18c87b2b8b2703c682f2d4c1d01aaa8b53343036ea0e8871ae1828c54b9c9bbf7530890a2fe4e160fb62f72c740c7e79a756e07dbf3a04dd116a7d37146cd0ec730172fa97e84b1f13e687d56118e2d666a02a31a629fa08949d66b81ba98e5ca453ba1faf95c8476873d4c32ff6c9a2558b772c51c5768a028db2de6d80f3a06861d3acc082e3a6bb4a6948980a8e5527bd354a2da037779a09b01ba0fe0193c511161448c602bb9fff88b87ab0ded3255606a15f8bca9d348a0c1c1c6a89f2fdbee0840ff309b5cecd9764b5b5815b385576e75e235d1f04656a04e827215bb9511b3a288e33bb418132940a4d42d589b8db0f796ec917e8f9373a099398993d1d6fdd15d6082be370e4d2cc5d9870923d22770aaec9418f4b675d7a00cd1db5e131341b472af1bdf9a1bf1f1ca82bc5b280c8a50a20bcfff1ab0bdd4a09bbcc86c94be1aabf5c5ceced29f462f59103aa6dafe0fc60172bb2c549a8dbaa0902df0ba9eed7e8a6ebff2d06de8bcec5785bb98cba7606f7f40648408157ef4a0ba9dfd07c453e54504d41b7a44ea42e8220767d1e2a0e6e91ae8d5677ac70e50a0f02f2a5e26d7848f0e5a07de68cbbbd24253d545afb74aac81b35a70b6323f1ca0218b955deca7177f8f58c2da188611b333e5c7ef9212000f64ca92cd5bb6e5a0a049cd750f59e2d6f411d7b611b21b17c8eefe637ca01e1566c53f412308b34c6280", + "0xf90211a05303302919681c3ad0a56c607c9530ed910f44515f6b40c9633d1900bbbc7e0fa0459fc49e57f39ca6471b1c6905ede7eaa6d7186c8249485cc28338ba18c540cba0825307726d1b7c9d74973d37c12e8b035bf0334836e48ec3f2ff18bf2232dabea0a67ef68daba820c7d6343d1b147b73430ce5c5915a27581cfd12946c2307dc49a003c9b0f0b784de7d72f3b5d5fea87e30dc5fc6f93a0c218240f79a2c74b0f8e2a05a38ddf70df168305b8ba38e8ee54dfadc3f7d81335ec849cb143a10d9738a91a058f0692b5cb07a1c8c800fcf8a70c6e6189a5d72f24ca0040423cf450df1da44a0890dbc62e7429fcca3f1507ad2cd4799c0a7aab25db37ccad434ae23ae889807a075be60d2f635292e69dbc600600605cb8eaf75e96425fd3f2347a5c644db43b9a07b65ba06ee9d2b5dab0a9acc1b8b521cb42f91566de9c174636e817c3d990265a0de65bc6092e28b0cc1ed454fcc07ce26df21bb05efe0a4b4472ff63278e28b95a08077cd7de83428d376ff7588b32df903d2764af7d41deb9c873e9ae889823cd3a0af2f63837dc01e2efb9e40815761015a0d740c2d2549593eefd291a05d40b55aa0c3214baa8d347bd5703926b6fe3ee2f607d0debc0fd73352696dc10f4cbc517da01756cf85b4785bda4a9867a453f8ca1948f015bd329b84083f14d313bddafb80a00dac89194bc1f28d3971b9ca9d1e16a49c6383557187d7bbeb899626d60bfb1980", + "0xf90211a0bf50b49fae6cfe8b7671e3fa0c163aed76f6457720a2b7c18f567b3c02194c29a070dc71bb7e399e5ae66958261108c84b75e8aacc8d255ce28cd7c9029358872ba0d2ae86d376e65eee52338ad4a1951deb9312f2c161fdf5cfc3e36d5a07ee4239a0f2029dea5033d0e788191ba25fc25bb0570bdbbaf321dfdb076f6695c649a07ca066074b59980560ecdd8ebc96eeb93f50dc1e92983659ea4a6a61a4cff0f474cba01ad85159ddc98609ea628cd17897fe08b0d9a7bb07a2087d92a673e063039aaba04921580f8766f8f156546abd8f0e44af250b34e7323f35c40fdc078223822344a034e07b24a1c17f5dcff27b766099c206fbbb6e549d3f4c02fd8db0241061482aa0c852267182c35e2e5014ab6d656672e9446aaf79c6248d103870d55ee36368b1a00aed203f7e2684942a64f05306e57d64fd44eded94e2ce95e462be93adff640da02cea88d74264c91c546de3822b6169a427559781a774511409864d70a834706ea01d542f8a9b69674e58a5bb89fafb5e79cbe3607732455b09c2a996df48e48837a04c3bbb4f47041018455347567a4e3af472fafe179871f667c3d26038f5dabacfa03c4f12f7cdd35126ce5452aa8322bc8b497eb06c5c41741b590d40645a8fd14ea01334e9a4160b44b622e9523cb587d8ba4795bbf9ad3dd0aa1a2b7f5c6a5cbe94a08feae3d50602063d65763185633aa6e23bb47eca9a39982a4863a7cc6d3586ff80", + "0xf90211a03fc22103871f30d114942583d24adfab1ce2e651ff6705a05964318fde7c425aa01c86fd2e9d2a823db33bf4089ce1af41332b4e3069b31bb70a67861944d71688a08a90ae88b4479d21135517195f50df20fc29dbe495e09440b0fa5797fc0352c8a02a195c4a89ab6322d8daa221124274d711a9435587406addfb289f9360c0b1caa02f7ed0113a1b72febc7ceb7d9193baeaa093aebea76eea4729821f53d29b302ea07d5cbbeffd22fb0f9d510576cac47a604b2121ef8b08588eaefc46a07844515ca01c0c09d203e342fab9f80835f3aa7bb7e94cbf94d3a18b21ce905e75b690673fa07c310f931f12d1651dbb9bdffbe5e0a16db981dccfb3f4a838592e2347b1b187a091b24e00d37034ed70e0c6653f8616363efbea43be86d52aabf6a9c5d5049d3aa017cc8ab2e63508691dee64ddb2dbe5352fe531f55728368cab3d8634450730dca0d8ee92d688eabcdf28af1830d7217fcd1431c0b0e3311039c422c5f45f9d525da0abe4323ef90fb783ffd6bf29d240818b0a2477d2ad4577fce57642a5ba476957a0eee3fbc510b1a6d8da176b9eab2035837769988b216fcef67f6a215e5e261d5ea082bc27591d8b0408739712c2f0e623e3d296d12afd6b7356dae237a315a6ce3ba0634affb8f9744fed774851772cb5ce495c50212961a64262d915632c2bede721a0345017d846f3be29dca1f56a734886c26cb49d3bcbbae5f7356e55e71d84147d80", + "0xf90211a0a152d08043b3865248d8ae9c4594d6e09079f61ee4ad9afca98d3befb3a9307ca01313ea4df7ec991f5ba1b2175408765ea67111857ae25cafe21986810d633353a05cb00f30a4b6749cb8d01dda2ad665a2c570b7c6959b364c46da75fc2aebfa14a0a493d42fa40d6c8fb23090f20cebe9f1cde8a47d9594e666096c3f76219cfb34a06d2149e05ba1a31bcc352fd3a79fd42d95383f14a312862fa5f4b7b7bdb63254a0f40094679bf0599fdeecae8c800a423ad2499b67f9546d4085d5b7a351561072a05036fc625ed5a13d143fd0984e99969d2d48f962baec80b3f0e78323c8e864ffa0c0887db54ab0d4309ed5f563448bfc78a4a88c3a5473fcbd9bd263c8fcca4b9fa04287b193a315cba13a49482b4d83c068cf08b622593111e416b7a3b815e3595aa051b82224b54dc4050703157cdd6c74c618872c798badce7192fe1fd534814d5da017ac02273956b25dc2429750156e0a45bf461437bec84b784d19a5b964dd6882a05be9c25f80a6f34e9eb526d6c3c89e3ec2c5dd769d2d915d835208cac3f56d36a0ea7ae8e74baeae9d6307371f85cce46ba7ad46b5c2b3616a3573a26e1260bc31a04446678b6bf75075ae0261c179d88e49fae1d9482c214ec8c693239b583a6b18a09ec91d47f671c343cea224def0afcd62a57a408ac0e36b79cf29a4495ff9055ca0c3da71d14030daf8fb9157ec84f077df97dff395c1fcf8f04361e02aa1af36ff80", + "0xf8b1808080a038f5e1b2680d95eaf7f225b996fc482f60cabcebeae26f883a4b58e1e9c7bbeda0c220c5d76d85ad38d8f82d0d6d6f48db3c23ae3657d1ac3ca6e2d98b4e48bfde8080a06fe32c7c1f8f80ebe5128f11a7af3a5bc47dbc6ac0af705069532b1cbefd6792a0015eb7d24835c910fc5f906627968a1a9e810cb164afd634ca683b6bb34f0241808080808080a03ca1d0ead152d38c16bda91dac49e3f0c9a0afeaa67598c1fce2506f5f03162680", + "0xf86d9d3c3738deb88e49108e7a5bd83c14ad65b5ba598e2932551dc9b9ad1879b84df84b10874ef05b2fe9d8c8a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" + ], + "balance": "0x4ef05b2fe9d8c8", + "codeHash": "0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "nonce": "0x10", + "storageHash": "0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421", + "storageProof": [] + }` + err = json.Unmarshal([]byte(proofString), &accountProof) + assert.NoError(t, err, "Found unexpected error") + assert.Equal(t, accountProof, proof, "Proof didn't match expected value") +} + +// func TestCreateAccessList(t *testing.T) { +// rpc := MakeNewRpc(t) + +// fromAddress := common.HexToAddress("0x8885d8FFefb29AC94FCe584014266A6fE8437356") +// toAddress := common.HexToAddress("0xb5C3dd56b4Dc6108b21b0Dac4A20898A464b8c41") +// inputData := common.Hex2Bytes("0x") +// // data, err := utils.Hex_str_to_bytes("0x608060806080608155") + +// opts := CallOpts{ +// From: &fromAddress, +// To: &toAddress, +// Data: inputData, +// } +// block := seleneCommon.BlockTag{ +// Finalized: true, +// Number: 20985649, +// } + +// accessList, err := rpc.CreateAccessList(opts, block) +// fmt.Println("Access list:", accessList) +// assert.NoError(t, err, "Found Error") + +// } + +func TestGetCode(t *testing.T) { + rpc := MakeNewRpc(t) + + addressBytes, err := utils.Hex_str_to_bytes("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") + if err != nil { + t.Errorf("Error in decoding address string:, %v", err) + } + + var address seleneCommon.Address = seleneCommon.Address{Addr: [20]byte(addressBytes)} + blockNumber := 20983632 + + code, _ := rpc.GetCode(&address, uint64(blockNumber)) + + codeString := "0x6060604052600436106100af576000357c0100000000000000000000000000000000000000000000000000000000900463ffffffff16806306fdde03146100b9578063095ea7b31461014757806318160ddd146101a157806323b872dd146101ca5780632e1a7d4d14610243578063313ce5671461026657806370a082311461029557806395d89b41146102e2578063a9059cbb14610370578063d0e30db0146103ca578063dd62ed3e146103d4575b6100b7610440565b005b34156100c457600080fd5b6100cc6104dd565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561010c5780820151818401526020810190506100f1565b50505050905090810190601f1680156101395780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561015257600080fd5b610187600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061057b565b604051808215151515815260200191505060405180910390f35b34156101ac57600080fd5b6101b461066d565b6040518082815260200191505060405180910390f35b34156101d557600080fd5b610229600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803590602001909190505061068c565b604051808215151515815260200191505060405180910390f35b341561024e57600080fd5b61026460048080359060200190919050506109d9565b005b341561027157600080fd5b610279610b05565b604051808260ff1660ff16815260200191505060405180910390f35b34156102a057600080fd5b6102cc600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610b18565b6040518082815260200191505060405180910390f35b34156102ed57600080fd5b6102f5610b30565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561033557808201518184015260208101905061031a565b50505050905090810190601f1680156103625780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b341561037b57600080fd5b6103b0600480803573ffffffffffffffffffffffffffffffffffffffff16906020019091908035906020019091905050610bce565b604051808215151515815260200191505060405180910390f35b6103d2610440565b005b34156103df57600080fd5b61042a600480803573ffffffffffffffffffffffffffffffffffffffff1690602001909190803573ffffffffffffffffffffffffffffffffffffffff16906020019091905050610be3565b6040518082815260200191505060405180910390f35b34600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055503373ffffffffffffffffffffffffffffffffffffffff167fe1fffcc4923d04b559f4d29a8bfc6cda04eb5b0d3c460751c2402c5c5cc9109c346040518082815260200191505060405180910390a2565b60008054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156105735780601f1061054857610100808354040283529160200191610573565b820191906000526020600020905b81548152906001019060200180831161055657829003601f168201915b505050505081565b600081600460003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508273ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040518082815260200191505060405180910390a36001905092915050565b60003073ffffffffffffffffffffffffffffffffffffffff1631905090565b600081600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054101515156106dc57600080fd5b3373ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff16141580156107b457507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205414155b156108cf5781600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541015151561084457600080fd5b81600460008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b81600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254039250508190555081600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040518082815260200191505060405180910390a3600190509392505050565b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205410151515610a2757600080fd5b80600360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f193505050501515610ab457600080fd5b3373ffffffffffffffffffffffffffffffffffffffff167f7fcf532c15f0a6db0bd6d0e038bea71d30d808c7d98cb3bf7268a95bf5081b65826040518082815260200191505060405180910390a250565b600260009054906101000a900460ff1681565b60036020528060005260406000206000915090505481565b60018054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015610bc65780601f10610b9b57610100808354040283529160200191610bc6565b820191906000526020600020905b815481529060010190602001808311610ba957829003601f168201915b505050505081565b6000610bdb33848461068c565b905092915050565b60046020528160005260406000206020528060005260406000206000915091505054815600a165627a7a72305820deb4c2ccab3c2fdca32ab3f46728389c2fe2c165d5fafa07661e4e004f6c344a0029" + codeBytes, err := utils.Hex_str_to_bytes(codeString) + + // fmt.Println("Code:", code) + assert.NoError(t, err, "Found Error") + assert.Equal(t, codeBytes, code, "Code didn't match expected value") +} + +// ** Not possible to test as to send actual transaction, ETH is needed on mainnet +// func TestSendRawTransaction(t *testing.T) { +// rpc := MakeNewRpc(t) +// // Raw Transaction Data +// data, _ := utils.Hex_str_to_bytes("") +// // transaction := seleneCommon.Transaction{ +// // From: "", +// // Nonce: , +// // } +// // data, err := json.Marshal(transaction) +// hash, err := rpc.SendRawTransaction(&data) + +// fmt.Println("Hash: ", hash) +// assert.NoError(t, err, "Found Error") +// } + +func TestGetTransactionReceipt(t *testing.T) { + rpc := MakeNewRpc(t) + txHash, _ := utils.Hex_str_to_bytes("0x4bc11033063e445e038e52e72266f5054845d3879704d0cf38bedeb86c924cec") + + _, err := rpc.GetTransactionReceipt((*common.Hash)(txHash)) + // expectedReceipt := types.Receipt{} + + assert.NoError(t, err, "Found Error") + // assert.Equal(t, expectedReceipt ,txnReceipt, "Receipt didn't match") +} + +func TestGetTransaction(t *testing.T) { + rpc := MakeNewRpc(t) + txHash, _ := utils.Hex_str_to_bytes("0x4bc11033063e445e038e52e72266f5054845d3879704d0cf38bedeb86c924cec") + + _, err := rpc.GetTransaction((*common.Hash)(txHash)) + // expectedTxn := seleneCommon.Transaction{} + + assert.NoError(t, err, "Found Error") + // assert.Equal(t, expectedTxn ,txn, "Receipt didn't match") +} + +func TestGetLogs(t *testing.T) { + rpc := MakeNewRpc(t) + address := common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") + blockHash := common.HexToHash("0x945b6b3568c39736fe1595234f0529efc8d64930a5343196aa8ef799b02dd609") + + filterQuery := ethereum.FilterQuery{ + Addresses: []common.Address{address}, + BlockHash: &blockHash, + } + + _, err := rpc.GetLogs(&filterQuery) + // expectedLogs := []types.Log{} + fmt.Println("") + assert.NoError(t, err, "Found Error") + // assert.Equal(t, expectedLogs, logs, "Logs didn't match") +} + +func TestGetChainId(t *testing.T) { + rpc := MakeNewRpc(t) + + chainId, err := rpc.ChainId() + + assert.NoError(t, err, "Found Error") + assert.Equal(t, chainId, uint64(1), "Expected chain Id to be 1") +} + +func TestGetNewFilter(t *testing.T) { + rpc := MakeNewRpc(t) + address := common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") + blockHash := common.HexToHash("0x945b6b3568c39736fe1595234f0529efc8d64930a5343196aa8ef799b02dd609") + + filterQuery := ethereum.FilterQuery{ + Addresses: []common.Address{address}, + BlockHash: &blockHash, + FromBlock: big.NewInt(200000000), + } + + _, err := rpc.GetNewFilter(&filterQuery) + + assert.NoError(t, err, "Found Error") + // assert.Equal(t, *uint256.MustFromHex("0x35ef5ae2a28c50b0a6a8fd0903c99e7f"), filterId, "Filter Id doesn't match") +} + +func TestGetFilterChanges(t *testing.T) { + rpc := MakeNewRpc(t) + + address := common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") + blockHash := common.HexToHash("0x945b6b3568c39736fe1595234f0529efc8d64930a5343196aa8ef799b02dd609") + + filterQuery := ethereum.FilterQuery{ + Addresses: []common.Address{address}, + BlockHash: &blockHash, + FromBlock: big.NewInt(200000000), + } + + filterId, _ := rpc.GetNewFilter(&filterQuery) + + logs, err := rpc.GetFilterChanges(&filterId) + expectedLogs := []types.Log{} + assert.NoError(t, err, "Found Error") + assert.Equal(t, expectedLogs, logs, "Logs didn't match") +} + +func TestUninstallFilter(t *testing.T) { + rpc := MakeNewRpc(t) + + address := common.HexToAddress("0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2") + blockHash := common.HexToHash("0x945b6b3568c39736fe1595234f0529efc8d64930a5343196aa8ef799b02dd609") + + filterQuery := ethereum.FilterQuery{ + Addresses: []common.Address{address}, + BlockHash: &blockHash, + FromBlock: big.NewInt(200000000), + } + + filterId, _ := rpc.GetNewFilter(&filterQuery) + + success, err := rpc.UninstallFilter(&filterId) + + assert.NoError(t, err, "Found Error") + assert.Equal(t, true, success, "Success didn't match") + + //Check whether the filter still exists + _, err = rpc.GetFilterChanges(&filterId) + assert.Error(t, err, "Found Error") +} + +func TestGetNewBlockFilter(t *testing.T) { + rpc := MakeNewRpc(t) + + _, err := rpc.GetNewBlockFilter() + + assert.NoError(t, err, "Found Error") + // assert.Equal(t, 0, filterId, "Filter ID not equal") + // _, err = rpc.GetFilterChanges(&filterId) + // assert.NoError(t, err, "Found Error") +} + +func TestGetNewPendingTransactionFilter(t *testing.T) { + rpc := MakeNewRpc(t) + + _, err := rpc.GetNewPendingTransactionFilter() + + assert.NoError(t, err, "Found Error") +} + +func TestGetFeeHistory(t *testing.T) { + rpc := MakeNewRpc(t) + blockCount := uint64(5) + lastBlock := uint64(20000000) + rewardPercentiles := []float64{10, 40, 90} + _, err := rpc.GetFeeHistory(blockCount, lastBlock, &rewardPercentiles) + + assert.NoError(t, err, "Found Error") + // assert.Equal(t, FeeHistory{}, feeHistory, "Fee History does not match") +} \ No newline at end of file diff --git a/execution/proof.go b/execution/proof.go index 09085ee..0d1ae42 100644 --- a/execution/proof.go +++ b/execution/proof.go @@ -100,8 +100,8 @@ func isEmptyValue(value []byte) bool { StorageHash: [32]byte{0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21}, CodeHash: [32]byte{0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70}, } - - encodedEmptyAccount, _ := rlp.EncodeToBytes(emptyAccount) + // EncodeToBytes needs pointer as argument + encodedEmptyAccount, _ := rlp.EncodeToBytes(&emptyAccount) isEmptySlot := len(value) == 1 && value[0] == 0x80 isEmptyAccount := bytes.Equal(value, encodedEmptyAccount) @@ -156,16 +156,16 @@ func keccak256(data []byte) []byte { hash.Write(data) return hash.Sum(nil) } - +// Updated as EIP1186ProofResponse was updated func EncodeAccount(proof *EIP1186ProofResponse) ([]byte, error) { account := Account{ - Nonce: proof.Nonce, + Nonce: uint64(proof.Nonce), Balance: proof.Balance.ToBig(), StorageHash: proof.StorageHash, CodeHash: proof.CodeHash, } - - return rlp.EncodeToBytes(account) + // EncodeToBytes needs pointer as argument + return rlp.EncodeToBytes(&account) } // Make a generic function for it @@ -174,4 +174,4 @@ func min(a, b int) int { return a } return b -} +} \ No newline at end of file diff --git a/execution/proof_test.go b/execution/proof_test.go new file mode 100644 index 0000000..4849dca --- /dev/null +++ b/execution/proof_test.go @@ -0,0 +1,262 @@ +package execution + +import ( + "encoding/hex" + "encoding/json" + "fmt" + "io" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/common/hexutil" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/rlp" + "github.com/holiman/uint256" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func (a *Account) EncodeRLP(w io.Writer) error { + return rlp.Encode(w, []interface{}{a.Nonce, a.Balance, a.StorageHash, a.CodeHash}) +} + +func (a *Account) DecodeRLP(s *rlp.Stream) error { + var accountRLP struct { + Nonce uint64 + Balance *big.Int + StorageHash common.Hash + CodeHash common.Hash + } + if err := s.Decode(&accountRLP); err != nil { + return err + } + a.Nonce = accountRLP.Nonce + a.Balance = accountRLP.Balance + a.StorageHash = accountRLP.StorageHash + a.CodeHash = accountRLP.CodeHash + + return nil +} + +func TestSharedPrefixLength(t *testing.T) { + t.Run("Match first 5 nibbles", func(t *testing.T) { + path := []byte{0x12, 0x13, 0x14, 0x6f, 0x6c, 0x64, 0x21} + pathOffset := 6 + nodePath := []byte{0x6f, 0x6c, 0x63, 0x21} + + sharedLen := sharedPrefixLength(path, pathOffset, nodePath) + assert.Equal(t, 5, sharedLen) + }) + + t.Run("Match first 7 nibbles with skip", func(t *testing.T) { + path := []byte{0x12, 0x13, 0x14, 0x6f, 0x6c, 0x64, 0x21} + pathOffset := 5 + nodePath := []byte{0x14, 0x6f, 0x6c, 0x64, 0x11} + + sharedLen := sharedPrefixLength(path, pathOffset, nodePath) + assert.Equal(t, 7, sharedLen) + }) + + t.Run("No match", func(t *testing.T) { + path := []byte{0x12, 0x34, 0x56} + pathOffset := 0 + nodePath := []byte{0x78, 0x9a, 0xbc} + + sharedLen := sharedPrefixLength(path, pathOffset, nodePath) + assert.Equal(t, 0, sharedLen) + }) + + t.Run("Complete match", func(t *testing.T) { + path := []byte{0x12, 0x34, 0x56} + pathOffset := 0 + nodePath := []byte{0x00, 0x12, 0x34, 0x56} + + sharedLen := sharedPrefixLength(path, pathOffset, nodePath) + assert.Equal(t, 6, sharedLen) + }) +} + +func TestSkipLength(t *testing.T) { + testCases := []struct { + name string + node []byte + expected int + }{ + {"Empty node", []byte{}, 0}, + {"Nibble 0", []byte{0x00}, 2}, + {"Nibble 1", []byte{0x10}, 1}, + {"Nibble 2", []byte{0x20}, 2}, + {"Nibble 3", []byte{0x30}, 1}, + {"Nibble 4", []byte{0x40}, 0}, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + result := skipLength(tc.node) + assert.Equal(t, tc.expected, result) + }) + } +} + +func TestGetNibble(t *testing.T) { + path := []byte{0x12, 0x34, 0x56} + + testCases := []struct { + offset int + expected byte + }{ + {0, 0x1}, + {1, 0x2}, + {2, 0x3}, + {3, 0x4}, + {4, 0x5}, + {5, 0x6}, + } + + for _, tc := range testCases { + t.Run(fmt.Sprintf("Offset %d", tc.offset), func(t *testing.T) { + result := getNibble(path, tc.offset) + assert.Equal(t, tc.expected, result) + }) + } +} + +func TestIsEmptyValue(t *testing.T) { + t.Run("Empty slot", func(t *testing.T) { + value := []byte{0x80} + assert.True(t, isEmptyValue(value)) + }) + + t.Run("Empty account", func(t *testing.T) { + emptyAccount := Account{ + Nonce: 0, + Balance: big.NewInt(0), + StorageHash: [32]byte{0x56, 0xe8, 0x1f, 0x17, 0x1b, 0xcc, 0x55, 0xa6, 0xff, 0x83, 0x45, 0xe6, 0x92, 0xc0, 0xf8, 0x6e, 0x5b, 0x48, 0xe0, 0x1b, 0x99, 0x6c, 0xad, 0xc0, 0x01, 0x62, 0x2f, 0xb5, 0xe3, 0x63, 0xb4, 0x21}, + CodeHash: [32]byte{0xc5, 0xd2, 0x46, 0x01, 0x86, 0xf7, 0x23, 0x3c, 0x92, 0x7e, 0x7d, 0xb2, 0xdc, 0xc7, 0x03, 0xc0, 0xe5, 0x00, 0xb6, 0x53, 0xca, 0x82, 0x27, 0x3b, 0x7b, 0xfa, 0xd8, 0x04, 0x5d, 0x85, 0xa4, 0x70}, + } + encodedEmptyAccount, err := rlp.EncodeToBytes(&emptyAccount) + require.NoError(t, err) + assert.True(t, isEmptyValue(encodedEmptyAccount)) + }) + + t.Run("Non-empty value", func(t *testing.T) { + value := []byte{0x01, 0x23, 0x45} + assert.False(t, isEmptyValue(value)) + }) +} + +func TestEncodeAccount(t *testing.T) { + proof := &EIP1186ProofResponse{ + Nonce: 1, + Balance: uint256.NewInt(1000), + StorageHash: [32]byte{1, 2, 3}, + CodeHash: [32]byte{4, 5, 6}, + } + + encoded, err := EncodeAccount(proof) + require.NoError(t, err) + + var decodedAccount Account + err = rlp.DecodeBytes(encoded, &decodedAccount) + require.NoError(t, err) + + // Assert the decoded values match the original + assert.Equal(t, uint64(1), decodedAccount.Nonce) + assert.Equal(t, big.NewInt(1000), decodedAccount.Balance) + assert.Equal(t, proof.StorageHash, decodedAccount.StorageHash) + assert.Equal(t, proof.CodeHash, decodedAccount.CodeHash) +} + +func TestKeccak256(t *testing.T) { + input := []byte("hello world") + expected, _ := hex.DecodeString("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad") + + result := keccak256(input) + assert.Equal(t, expected, result) +} + +type Proof struct { + Address string `json:"address"` + AccountProof []string `json:"accountProof"` + Balance string `json:"balance"` + CodeHash string `json:"codeHash"` + Nonce string `json:"nonce"` + StorageHash string `json:"storageHash"` + StorageProof string `json:"storageProof"` +} + +func TestVerifyProof(t *testing.T) { + jsonString := `{ + "address":"0x457a22804cf255ee8c1b7628601c5682b3d70c71", + "accountProof":[ + "0xf90211a0c48ed6536f719a4e24c1195b099fd19f127448c0e2b4ad5729dcdcccb41a56b5a0a338e0f373eac20e4ad9528f9895da93762623350bb5defa693263ea6f9af4afa0304e41961a40be33e5213d3e583c0d30989e795b541c810e8456c12a7478c841a05b26d8545de569451cd3baee25ef6d525f6c27c89844b76ccebf99801708c1d9a069b7051e21066a40847fbe6e4217628f6979b1a361819c7ebe0980c063d684f5a06f5948452762bfe7061717765ab322a5e086ece9c4eddf442a047e253b557dc4a0ef37b2aaf540e598e0e046ee6a8c51c1c100d68dcda70bea1ebe4924ef7911f3a03218af1883a1bfb9828b0c3f07f16a8df859e81543633808ec625164db6b3644a0121b6fdd1951f7915bd55c96dc2cc546fa42bfadb4cfa3fc1a2cc3de232df289a0fdf5a771f4ee044d9c6a7ddd6d797ca102022d4786db1332c5530091f52a2238a08e59837befa581ee0e4d2d9b2caeac403106090117844590d876df445df09509a0d0eb738155e240e6c069c765102f526b54124d788c8e501ed96a6a29a326f4d7a0c14d799f056ca9d6bf91a10272dff64cf34eb4aff42e7b56bf14176e2e36a58aa03ae0cf5dc0b96aa9755207ec060c45b149e071f1453e7416acd282660a66a371a0495a02815d4434895bf7997771016ab2bf29c1f970c778c696444d4b5573ae87a008d340cb14293c576f934b7f8cbab6f0b07f6d4804957d6f8d6c48e2465d027f80", + "0xf90211a0a0b5e06bee86e09cc7f63d64ef1f3bd9a970ba8881d52b9a1a60849eef16b535a022756912563afa1c6cc7a49d0f34704f5919df048091561e21511bff585fc6d2a0eaa5bd3c14a851aeaeff1a7dbafb5456d4a218f12c63f0795ba2679d8f412ba6a07f8b49a363a58d81b7c51eab08998532ff3efdec14e6015d43429180a5a74929a0e62a8be403d29d6972426603c4a0962a24d5c56325bf1661c0984414605eaa55a0d567f6a8520f25ed64ece7d37b405374a51c3af48356c6fa72efec22f7d42e2aa0696255c12473694333c6724ff234a04f6995b8eb376e8e8be0c171965767ca2ea0b1b08ecb635708f8c0f42dffe86e09ac6b3bfe8319e544797a4199bde4d1fd15a05c0e9906e3d20bbec170f769824250862fd7dad378d6cfeda9b713acf3b72568a03d160d95900a9bc2e7e9c08766b4392a9ac86b7e006979c426e0885229e5f44da00bc337a5b553d0ffb67859b28cc59246262bf532c2b14dd456f160d778540b34a005d784ba4f478f2f315f1b678fbfc39ed2c0b01b02b55ed82ea9d62369cd35faa023f24fd63f87a947ee148c8001bc4039a5f481fca1e0f3f10a3791a9e0451571a01ffb2845581388c6b915135a9ee856bcc896f2def7eeeb88bdfd53ae32323431a09d7bde3d951bcc3505684616bf760dfdd69e03e6b2ca2a180bc7b6fc7922d9c6a01b29670cbbe0bb02bf764032d347af708db1cd34dd2a9ceaa056d0c96ebcc06380", + "0xf90211a0532c4b817232369b476e2f512431248940bc2b62b268750eafb19725b1ea3f61a023d73bdeaa7d23f1ae3c7e45a961f6828a8c84da890802d9e76c4ad040f9dfa8a0b2b86151f708e0970051496defa3a21a9e38add3710dcdf3128f350eed7545b7a0c6f14ab140c8c849900d90e72430cc8ed9e05bb11c0bc1ef74653813fe184908a085382b28cc5d147da5be0ad99cf65ba09a70031f9ad6ddb5a1b8676adf620d27a05002c30689fcafbe153d3dd120d8e2ed2d867ed4dc38e29c488914cfb2d773e1a0061763ee76bdc20123bd89151b0d3311d3500ffe9502013f79147983497323a2a0b27cccc06c21e8ec8a41076e872360263864d2c2a033bff15cdc4c422f5efbc4a061d3b9c9582aaa05e4c0c4c5e269194ad2337465c88fe15721dce420872df88aa0bf0cf79d1546129128ee59aa52f987f0a92d4ee8b50d34178d49ccbc3b542fbda08dcb375e470c4b7e33e9b30a18c77557c3afaf29a3423ebc457193ffa4afafeda00f37ee5c7e78a14120c393f96aaa2eb77c7a2b290b3e390d868f901d7935b91ea0189ba4abb7a368dc21faa9009e56f08dbabbf2b169237b2c3343cdce84b9734ba001a06747b252f00070e5c6857db4d2bd984ac1e3ca8e2c1768a1b15c7caaa32aa06f68846bda765c1ebe37c4f460a5501ea49d32e2873e0333b1db3f8b11353345a046ee87393f4507c48fffeaefb60f86d39be7f3164101a254c978154bdf440e0680", + "0xf90211a01d3ed8ac26e69d88bf7c5ede07a54e9e58497b152539ca91e50a92287db07f0ea085e2443725c20842d26d4989ba1a56dfb13fbafbd95628dd6ea0ecfaebbd956ea06d11f90d431eabe083bde15c02ca665d6bd270102108105d1179aa3e350ea327a0c95a53dd831c6b4f71406d0549369d20a6a19831ee70cb2bbfce0089328c3ceba0b84a29614ca66250d59c07792808522acf7137ed2027f1a0148ffe1b467c5623a01abe3994fd1fa6276a00a2bf2db562a3418bcd6ef53c2daf62f899d95e31e15aa01b26905ddf68b2ec3ee23558c6c931f2d86436caeaf078d772b5f659e900f782a02b7f348cd686aa44c2dc0d8ab03dccc700728d2acbb645d84036ee5b26dcb4aaa0ed6662d9fcde2a8fd39bc7f26c8537bec1a6193955cd63d739cd6c8eeb5f2c35a090a7e073bb5df6de34707cb679c2ef359e66550c557abd28c8dbfec598a7a5b6a0d8899a7e2839d10b61c59546af49af8b723dab8ddcafc68ecdf4994d42b5badaa09aa471b32e1f8ac6b811137e6cc15245fcb4d8e40b6f27c0955e31ae3e428619a00e6f9245fc44c37708a41ccde7bb764b9e54b69f12c79c5c1ad9eedc21075d59a0d83ec73c7ef8bfea0448174f53a174ea07397d8ba9a55cd1589ca9e9a4d41b7da0b3ceb20f69ce1a99b8e110bb3c56213ed047167cf9b794b9ab0d5dd3227f9d62a0a9e3612f28c1cd13e9f1ac7b6e5f984afa226b2b6037ebb2f8d6fcc4505c7f1c80", + "0xf90211a0fd032ce4009ac0aa95170293240d6bef6cefd073fcf5d430e2a526410dab705aa09ed14f5069549d06740b6946a651b4bd90bff6ad44133b779fdcada5b621d690a0b833494b9e3f58f773aa5cec7645ceac4ebfdcd985f234d33eb283415a14cdd4a0c2e1ff80fdcff52539b161fb2ce25cd2825bc61453e63f72347d5be029441ed6a082cb4d21a71f220cc1fc05e6d544a79a102c296a0a30634006757aa9dcf0dacba03930cac361c2eb6edbbe3cb453c1d301aedb25bfc0c12b32adb56849545a8390a0bdbcc436e5eded0ca5daf6f37ea2626d3977f745245190a62d24f0fe4e12b8eaa05ab7a229f5a628f7606948ff694c05a5a08f87e0e3c3ad1f45b747eec521c5eea0e9a0e18f800afc38bcabe3cbca21695a0d399b235285de2819791d88baa7c339a0bbb17f8b5dfbb24a4a15e6d606c54d67c103dd44f0f1246d6604e9b71a671866a048fe8956aa652d57f0322990f94c9df6af0f7c28c41776b1c80cc0eafa5ab458a01ed5fcbfd2efe7381e1f98081bc98896086615236cb8f7f7a44a04493286a0a0a020c202d8b2b22ed074692df8dd21df64105643b9a97d1fdd0ec235a59711909da0d8ac47fa535011dc28cd3f649f9391f881ba3822d05b4d25421a21ce3c50499ea025db02e0e16e04f2b3e69dacac680d3c8fbfcc5cadbf441fdf0f303f43b7aaa1a0f646b6d69c1fce8ad6fc064c1341da989a59c4157b5da5ff25b760f041707f0680", + "0xf90211a0a57894cce27679d5a469be71ae0c582159b51a71381f0365404bbe1b2af0d8d3a03243d088fb7f888a461e06d9339dda036d10fdc13fdc18d68680680117133cc8a0fe66886652b91264cb2e9e99cdae776928be462c0e76a1b2af3673de8c1e09f4a08a47de5ebfaa75fe79082627efa51108ad86235e6576c6dab5cad9f374dc3a33a0663fcc26c76d08a85004b4ca2e02baaf067ecbf1e0a121dc95be500cf541d56ea092f22428ae816de7a5a95e46ac3579d614e4c44d55be89d869a815a2e654e599a04adf75bc024ab9dc2bc280249a610422166f52c9fbc0bf9b401984b79e03211aa0d6ae689b2f5dabbc30e1e612cafc960fbb342f523617f7f6a8df1845a7564154a0bee5ca129557312716be21cf0e91273532e573ed162f0c8cdf0b1f1da38a30cca01aa1ca8998d04f89182c022aebcf6828d5d808ef4e663bf690e51aeb133ef1d5a0147cac105fa6c368d8a9013cd1873271ddacda2be2345051fdd3fa50a2c003c8a0caf1ff1075e0f30fb12b29e1278b61d69bf5cbd059131ba18f4b89422c188cd2a0fc0dc4f79e218c884075a69b52bfe84b8bbbb98e9e252299bda742ef77ee4264a05153dc26c8c558e394488fc70a45c0d863f2a930a215fb6fa0e1fdc92d990b31a010899ac22f43b3031f16cc9c660d7c5a93bf3ce5538a545056d9b1d364b06195a060e86b07bb6e96e4ea87eaeaa162108408bd5fadcc3496910c9fc59df5c0320480", + "0xf90191a0a1f0ab277fc1d351526eadeb8bcd95db08d710f0d3d1a0cc0cc8609d961a47d1a0c756a865d28d6bdcff435c90f5bf251107c230ad7558f57583d14be37e1ccaafa0828901d38fd39ade9bd74cbe07996e8cc45f8c43c6637fe7b7a43ab467e52098a022e4fb3dc11ca5e38ed9527e4eb534162c878ac048ac428abba29633b607d6258080a018d60336d1d9723e0d43567745464372e11f9f7a146abf163b0f43b338c0d827a00b44f7040c54b2bd63b0741062a96495dc4b92f7fec136c8effbc213cfffd02b80a0b81fcd189fbc66780a932367f874cbd4c85fed1fd37af109acc052f8ba80e51d80a0bbbcbe635193161c1e53442c06d0d14ed1af96af105a9fdd46a493195d62c1bba00050d231707972af60f163aa425401abb860f6c04b770fe0983e2f0f90ad6254a0804a9abf1b69bd16b1f6dc7cbbbf7592cd93fdf785b9cc61b01816583d9cd928a0ad85c29c3adbf2291cead9df6602560b93e485af7da680697ef9d1703f6f91cea040134ec8f47e1c599c0b7b4d237b8d3349f026fcfbacf885673438ffd2e9c72e80", + "0xf851a01a5a4c757ab8653aad3a83cbb491142c776b91e252ffe849c253dab5d109819380808080808080a09fc998b2c0347275d9f98a9ac5bbb205387c04387672cda1a0360c4ef7cffb1a8080808080808080", + "0xf86d9d205eb14112905ead3a2b16b733af37911d729cec51f559baf570332371b84df84b8087cc756b8ad2e000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470" + ], + "balance":"0xcc756b8ad2e000", + "codeHash":"0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + "nonce":"0x0", + "storageHash":"0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421" + ,"storageProof":"" + }` + + accountProof := []string{ + "0xf90211a0c48ed6536f719a4e24c1195b099fd19f127448c0e2b4ad5729dcdcccb41a56b5a0a338e0f373eac20e4ad9528f9895da93762623350bb5defa693263ea6f9af4afa0304e41961a40be33e5213d3e583c0d30989e795b541c810e8456c12a7478c841a05b26d8545de569451cd3baee25ef6d525f6c27c89844b76ccebf99801708c1d9a069b7051e21066a40847fbe6e4217628f6979b1a361819c7ebe0980c063d684f5a06f5948452762bfe7061717765ab322a5e086ece9c4eddf442a047e253b557dc4a0ef37b2aaf540e598e0e046ee6a8c51c1c100d68dcda70bea1ebe4924ef7911f3a03218af1883a1bfb9828b0c3f07f16a8df859e81543633808ec625164db6b3644a0121b6fdd1951f7915bd55c96dc2cc546fa42bfadb4cfa3fc1a2cc3de232df289a0fdf5a771f4ee044d9c6a7ddd6d797ca102022d4786db1332c5530091f52a2238a08e59837befa581ee0e4d2d9b2caeac403106090117844590d876df445df09509a0d0eb738155e240e6c069c765102f526b54124d788c8e501ed96a6a29a326f4d7a0c14d799f056ca9d6bf91a10272dff64cf34eb4aff42e7b56bf14176e2e36a58aa03ae0cf5dc0b96aa9755207ec060c45b149e071f1453e7416acd282660a66a371a0495a02815d4434895bf7997771016ab2bf29c1f970c778c696444d4b5573ae87a008d340cb14293c576f934b7f8cbab6f0b07f6d4804957d6f8d6c48e2465d027f80", + "0xf90211a0a0b5e06bee86e09cc7f63d64ef1f3bd9a970ba8881d52b9a1a60849eef16b535a022756912563afa1c6cc7a49d0f34704f5919df048091561e21511bff585fc6d2a0eaa5bd3c14a851aeaeff1a7dbafb5456d4a218f12c63f0795ba2679d8f412ba6a07f8b49a363a58d81b7c51eab08998532ff3efdec14e6015d43429180a5a74929a0e62a8be403d29d6972426603c4a0962a24d5c56325bf1661c0984414605eaa55a0d567f6a8520f25ed64ece7d37b405374a51c3af48356c6fa72efec22f7d42e2aa0696255c12473694333c6724ff234a04f6995b8eb376e8e8be0c171965767ca2ea0b1b08ecb635708f8c0f42dffe86e09ac6b3bfe8319e544797a4199bde4d1fd15a05c0e9906e3d20bbec170f769824250862fd7dad378d6cfeda9b713acf3b72568a03d160d95900a9bc2e7e9c08766b4392a9ac86b7e006979c426e0885229e5f44da00bc337a5b553d0ffb67859b28cc59246262bf532c2b14dd456f160d778540b34a005d784ba4f478f2f315f1b678fbfc39ed2c0b01b02b55ed82ea9d62369cd35faa023f24fd63f87a947ee148c8001bc4039a5f481fca1e0f3f10a3791a9e0451571a01ffb2845581388c6b915135a9ee856bcc896f2def7eeeb88bdfd53ae32323431a09d7bde3d951bcc3505684616bf760dfdd69e03e6b2ca2a180bc7b6fc7922d9c6a01b29670cbbe0bb02bf764032d347af708db1cd34dd2a9ceaa056d0c96ebcc06380", + "0xf90211a0532c4b817232369b476e2f512431248940bc2b62b268750eafb19725b1ea3f61a023d73bdeaa7d23f1ae3c7e45a961f6828a8c84da890802d9e76c4ad040f9dfa8a0b2b86151f708e0970051496defa3a21a9e38add3710dcdf3128f350eed7545b7a0c6f14ab140c8c849900d90e72430cc8ed9e05bb11c0bc1ef74653813fe184908a085382b28cc5d147da5be0ad99cf65ba09a70031f9ad6ddb5a1b8676adf620d27a05002c30689fcafbe153d3dd120d8e2ed2d867ed4dc38e29c488914cfb2d773e1a0061763ee76bdc20123bd89151b0d3311d3500ffe9502013f79147983497323a2a0b27cccc06c21e8ec8a41076e872360263864d2c2a033bff15cdc4c422f5efbc4a061d3b9c9582aaa05e4c0c4c5e269194ad2337465c88fe15721dce420872df88aa0bf0cf79d1546129128ee59aa52f987f0a92d4ee8b50d34178d49ccbc3b542fbda08dcb375e470c4b7e33e9b30a18c77557c3afaf29a3423ebc457193ffa4afafeda00f37ee5c7e78a14120c393f96aaa2eb77c7a2b290b3e390d868f901d7935b91ea0189ba4abb7a368dc21faa9009e56f08dbabbf2b169237b2c3343cdce84b9734ba001a06747b252f00070e5c6857db4d2bd984ac1e3ca8e2c1768a1b15c7caaa32aa06f68846bda765c1ebe37c4f460a5501ea49d32e2873e0333b1db3f8b11353345a046ee87393f4507c48fffeaefb60f86d39be7f3164101a254c978154bdf440e0680", + "0xf90211a01d3ed8ac26e69d88bf7c5ede07a54e9e58497b152539ca91e50a92287db07f0ea085e2443725c20842d26d4989ba1a56dfb13fbafbd95628dd6ea0ecfaebbd956ea06d11f90d431eabe083bde15c02ca665d6bd270102108105d1179aa3e350ea327a0c95a53dd831c6b4f71406d0549369d20a6a19831ee70cb2bbfce0089328c3ceba0b84a29614ca66250d59c07792808522acf7137ed2027f1a0148ffe1b467c5623a01abe3994fd1fa6276a00a2bf2db562a3418bcd6ef53c2daf62f899d95e31e15aa01b26905ddf68b2ec3ee23558c6c931f2d86436caeaf078d772b5f659e900f782a02b7f348cd686aa44c2dc0d8ab03dccc700728d2acbb645d84036ee5b26dcb4aaa0ed6662d9fcde2a8fd39bc7f26c8537bec1a6193955cd63d739cd6c8eeb5f2c35a090a7e073bb5df6de34707cb679c2ef359e66550c557abd28c8dbfec598a7a5b6a0d8899a7e2839d10b61c59546af49af8b723dab8ddcafc68ecdf4994d42b5badaa09aa471b32e1f8ac6b811137e6cc15245fcb4d8e40b6f27c0955e31ae3e428619a00e6f9245fc44c37708a41ccde7bb764b9e54b69f12c79c5c1ad9eedc21075d59a0d83ec73c7ef8bfea0448174f53a174ea07397d8ba9a55cd1589ca9e9a4d41b7da0b3ceb20f69ce1a99b8e110bb3c56213ed047167cf9b794b9ab0d5dd3227f9d62a0a9e3612f28c1cd13e9f1ac7b6e5f984afa226b2b6037ebb2f8d6fcc4505c7f1c80", + "0xf90211a0fd032ce4009ac0aa95170293240d6bef6cefd073fcf5d430e2a526410dab705aa09ed14f5069549d06740b6946a651b4bd90bff6ad44133b779fdcada5b621d690a0b833494b9e3f58f773aa5cec7645ceac4ebfdcd985f234d33eb283415a14cdd4a0c2e1ff80fdcff52539b161fb2ce25cd2825bc61453e63f72347d5be029441ed6a082cb4d21a71f220cc1fc05e6d544a79a102c296a0a30634006757aa9dcf0dacba03930cac361c2eb6edbbe3cb453c1d301aedb25bfc0c12b32adb56849545a8390a0bdbcc436e5eded0ca5daf6f37ea2626d3977f745245190a62d24f0fe4e12b8eaa05ab7a229f5a628f7606948ff694c05a5a08f87e0e3c3ad1f45b747eec521c5eea0e9a0e18f800afc38bcabe3cbca21695a0d399b235285de2819791d88baa7c339a0bbb17f8b5dfbb24a4a15e6d606c54d67c103dd44f0f1246d6604e9b71a671866a048fe8956aa652d57f0322990f94c9df6af0f7c28c41776b1c80cc0eafa5ab458a01ed5fcbfd2efe7381e1f98081bc98896086615236cb8f7f7a44a04493286a0a0a020c202d8b2b22ed074692df8dd21df64105643b9a97d1fdd0ec235a59711909da0d8ac47fa535011dc28cd3f649f9391f881ba3822d05b4d25421a21ce3c50499ea025db02e0e16e04f2b3e69dacac680d3c8fbfcc5cadbf441fdf0f303f43b7aaa1a0f646b6d69c1fce8ad6fc064c1341da989a59c4157b5da5ff25b760f041707f0680", + "0xf90211a0a57894cce27679d5a469be71ae0c582159b51a71381f0365404bbe1b2af0d8d3a03243d088fb7f888a461e06d9339dda036d10fdc13fdc18d68680680117133cc8a0fe66886652b91264cb2e9e99cdae776928be462c0e76a1b2af3673de8c1e09f4a08a47de5ebfaa75fe79082627efa51108ad86235e6576c6dab5cad9f374dc3a33a0663fcc26c76d08a85004b4ca2e02baaf067ecbf1e0a121dc95be500cf541d56ea092f22428ae816de7a5a95e46ac3579d614e4c44d55be89d869a815a2e654e599a04adf75bc024ab9dc2bc280249a610422166f52c9fbc0bf9b401984b79e03211aa0d6ae689b2f5dabbc30e1e612cafc960fbb342f523617f7f6a8df1845a7564154a0bee5ca129557312716be21cf0e91273532e573ed162f0c8cdf0b1f1da38a30cca01aa1ca8998d04f89182c022aebcf6828d5d808ef4e663bf690e51aeb133ef1d5a0147cac105fa6c368d8a9013cd1873271ddacda2be2345051fdd3fa50a2c003c8a0caf1ff1075e0f30fb12b29e1278b61d69bf5cbd059131ba18f4b89422c188cd2a0fc0dc4f79e218c884075a69b52bfe84b8bbbb98e9e252299bda742ef77ee4264a05153dc26c8c558e394488fc70a45c0d863f2a930a215fb6fa0e1fdc92d990b31a010899ac22f43b3031f16cc9c660d7c5a93bf3ce5538a545056d9b1d364b06195a060e86b07bb6e96e4ea87eaeaa162108408bd5fadcc3496910c9fc59df5c0320480", + "0xf90191a0a1f0ab277fc1d351526eadeb8bcd95db08d710f0d3d1a0cc0cc8609d961a47d1a0c756a865d28d6bdcff435c90f5bf251107c230ad7558f57583d14be37e1ccaafa0828901d38fd39ade9bd74cbe07996e8cc45f8c43c6637fe7b7a43ab467e52098a022e4fb3dc11ca5e38ed9527e4eb534162c878ac048ac428abba29633b607d6258080a018d60336d1d9723e0d43567745464372e11f9f7a146abf163b0f43b338c0d827a00b44f7040c54b2bd63b0741062a96495dc4b92f7fec136c8effbc213cfffd02b80a0b81fcd189fbc66780a932367f874cbd4c85fed1fd37af109acc052f8ba80e51d80a0bbbcbe635193161c1e53442c06d0d14ed1af96af105a9fdd46a493195d62c1bba00050d231707972af60f163aa425401abb860f6c04b770fe0983e2f0f90ad6254a0804a9abf1b69bd16b1f6dc7cbbbf7592cd93fdf785b9cc61b01816583d9cd928a0ad85c29c3adbf2291cead9df6602560b93e485af7da680697ef9d1703f6f91cea040134ec8f47e1c599c0b7b4d237b8d3349f026fcfbacf885673438ffd2e9c72e80", + "0xf851a01a5a4c757ab8653aad3a83cbb491142c776b91e252ffe849c253dab5d109819380808080808080a09fc998b2c0347275d9f98a9ac5bbb205387c04387672cda1a0360c4ef7cffb1a8080808080808080", + "0xf86d9d205eb14112905ead3a2b16b733af37911d729cec51f559baf570332371b84df84b8087cc756b8ad2e000a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470", + } + address := common.HexToAddress("0x457a22804cf255ee8c1b7628601c5682b3d70c71") + proof := [][]byte{} + + for _, s := range accountProof { + bytes1, _ := hex.DecodeString(s[2:]) + proof = append(proof, bytes1) + } + + stateRoot := "b666170175a47b5dde7514e732d935e58f7b379b0cf2774051c3fad5e9224000" + root, err := hex.DecodeString(stateRoot) + accountPath := crypto.Keccak256(address.Bytes()) + + assert.NoError(t, err, "Expected no error") + assert.Equal(t, root, keccak256(proof[0]), "Not Equal") + var testData Proof + + err = json.Unmarshal([]byte(jsonString), &testData) + assert.NoError(t, err, "Error in unmarshaling json string") + + proofStruct := EIP1186ProofResponse{ + Address: common.HexToAddress(testData.Address), + Balance: uint256.MustFromHex(testData.Balance), + CodeHash: common.HexToHash(testData.CodeHash), + Nonce: hexutil.Uint64(hexutil.MustDecodeUint64(testData.Nonce)), + StorageHash: common.HexToHash(testData.StorageHash), + AccountProof: func() []hexutil.Bytes { + var bytes []hexutil.Bytes + for _, h := range testData.AccountProof { + bytes = append(bytes, common.Hex2Bytes(h)) + } + return bytes + }(), + StorageProof: []StorageProof{}, + } + + value, err := EncodeAccount(&proofStruct) + assert.NoError(t, err, "Error in encoding account") + + isValid, err := VerifyProof(proof, root, accountPath, value) + assert.NoError(t, err, "Found Error") + assert.Equal(t, true, isValid, "ProofValidity not matching") +} \ No newline at end of file diff --git a/execution/rpc.go b/execution/rpc.go index 8b2d9bf..d028d41 100644 --- a/execution/rpc.go +++ b/execution/rpc.go @@ -8,14 +8,15 @@ import ( "github.com/holiman/uint256" ) +// Changes have been made as HttpRpc was not satisfying ExecutionRpc type ExecutionRpc interface { - New(rpc *string) (*ExecutionRpc, error) + New(rpc *string) (ExecutionRpc, error) GetProof(address *seleneCommon.Address, slots *[]common.Hash, block uint64) (EIP1186ProofResponse, error) CreateAccessList(opts CallOpts, block seleneCommon.BlockTag) (types.AccessList, error) GetCode(address *seleneCommon.Address, block uint64) ([]byte, error) SendRawTransaction(bytes *[]byte) (common.Hash, error) GetTransactionReceipt(tx_hash *common.Hash) (types.Receipt, error) - GetTransaction(tx_hash *common.Hash) (types.Transaction, error) + GetTransaction(tx_hash *common.Hash) (seleneCommon.Transaction, error) GetLogs(filter *ethereum.FilterQuery) ([]types.Log, error) GetFilterChanges(filer_id *uint256.Int) ([]types.Log, error) UninstallFilter(filter_id *uint256.Int) (bool, error) @@ -24,4 +25,4 @@ type ExecutionRpc interface { GetNewPendingTransactionFilter() (uint256.Int, error) ChainId() (uint64, error) GetFeeHistory(block_count uint64, last_block uint64, reward_percentiles *[]float64) (FeeHistory, error) -} +} \ No newline at end of file diff --git a/execution/types.go b/execution/types.go index a735c9a..b84a2f9 100644 --- a/execution/types.go +++ b/execution/types.go @@ -3,7 +3,6 @@ package execution import ( "encoding/json" "fmt" - seleneCommon "github.com/BlocSoc-iitr/selene/common" "github.com/BlocSoc-iitr/selene/utils" "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common/hexutil" @@ -19,20 +18,20 @@ type FeeHistory struct { Reward [][]hexutil.Big } -// defined storage proof and EIP1186ProofResponse structs +// This is to help in unmarshaling values from rpc response type StorageProof struct { - Key common.Hash - Proof []hexutil.Bytes - Value *uint256.Int + Key common.Hash `json:"key"` + Proof []hexutil.Bytes `json:"proof"` + Value *uint256.Int `json:"value"` } type EIP1186ProofResponse struct { - Address seleneCommon.Address - Balance *uint256.Int - CodeHash common.Hash - Nonce uint64 - StorageHash common.Hash - AccountProof []hexutil.Bytes - StorageProof []StorageProof + Address common.Address `json:"address"` + Balance *uint256.Int `json:"balance"` + CodeHash common.Hash `json:"codeHash"` + Nonce hexutil.Uint64 `json:"nonce"` + StorageHash common.Hash `json:"storageHash"` + AccountProof []hexutil.Bytes `json:"accountProof"` + StorageProof []StorageProof `json:"storageProof"` } type Account struct { Balance *big.Int @@ -40,7 +39,12 @@ type Account struct { CodeHash common.Hash Code []byte StorageHash common.Hash - Slots map[common.Hash]*big.Int + Slots []Slot +} +// This is to help in unmarshaling values from rpc response +type Slot struct { + Key common.Hash // The key (slot) + Value *big.Int // The value (storage value) } type CallOpts struct { From *common.Address `json:"from,omitempty"` @@ -132,4 +136,4 @@ func (c *CallOpts) Deserialize(data []byte) error { } return nil -} +} \ No newline at end of file diff --git a/go.mod b/go.mod index f48cbb4..15e8a93 100644 --- a/go.mod +++ b/go.mod @@ -3,29 +3,25 @@ module github.com/BlocSoc-iitr/selene go 1.22.3 require ( + github.com/avast/retry-go v3.0.0+incompatible + github.com/consensys/gnark-crypto v0.12.1 github.com/ethereum/go-ethereum v1.14.11 github.com/holiman/uint256 v1.3.1 github.com/pkg/errors v0.9.1 github.com/spf13/viper v1.19.0 + github.com/stretchr/testify v1.9.0 + github.com/ugorji/go/codec v1.2.12 + github.com/wealdtech/go-merkletree v1.0.0 + golang.org/x/crypto v0.22.0 + gopkg.in/yaml.v2 v2.4.0 ) require ( - github.com/DataDog/zstd v1.4.5 // indirect github.com/Microsoft/go-winio v0.6.2 // indirect github.com/StackExchange/wmi v1.2.1 // indirect - github.com/avast/retry-go v3.0.0+incompatible // indirect - github.com/beorn7/perks v1.0.1 // indirect github.com/bits-and-blooms/bitset v1.13.0 // indirect github.com/btcsuite/btcd/btcec/v2 v2.3.4 // indirect - github.com/cespare/xxhash/v2 v2.3.0 // indirect - github.com/cockroachdb/errors v1.11.3 // indirect - github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce // indirect - github.com/cockroachdb/logtags v0.0.0-20230118201751-21c54148d20b // indirect - github.com/cockroachdb/pebble v1.1.2 // indirect - github.com/cockroachdb/redact v1.1.5 // indirect - github.com/cockroachdb/tokenbucket v0.0.0-20230807174530-cc333fc44b06 // indirect github.com/consensys/bavard v0.1.13 // indirect - github.com/consensys/gnark-crypto v0.12.1 // indirect github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c // indirect github.com/crate-crypto/go-kzg-4844 v1.0.0 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect @@ -34,31 +30,14 @@ require ( github.com/ethereum/c-kzg-4844 v1.0.0 // indirect github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect - github.com/getsentry/sentry-go v0.27.0 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/gofrs/flock v0.8.1 // indirect - github.com/gogo/protobuf v1.3.2 // indirect - github.com/golang/protobuf v1.5.4 // indirect - github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb // indirect github.com/gorilla/websocket v1.4.2 // indirect github.com/hashicorp/hcl v1.0.0 // indirect - github.com/klauspost/compress v1.17.2 // indirect - github.com/kr/pretty v0.3.1 // indirect - github.com/kr/text v0.2.0 // indirect github.com/magiconair/properties v1.8.7 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mmcloughlin/addchain v0.4.0 // indirect - github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/prometheus/client_golang v1.12.0 // indirect - github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect - github.com/prometheus/common v0.32.1 // indirect - github.com/prometheus/procfs v0.7.3 // indirect - github.com/rivo/uniseg v0.2.0 // indirect - github.com/rogpeppe/go-internal v1.9.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible // indirect @@ -67,24 +46,17 @@ require ( github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stretchr/objx v0.5.2 // indirect - github.com/stretchr/testify v1.9.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/supranational/blst v0.3.13 // indirect - github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/ugorji/go/codec v1.2.12 // indirect - github.com/wealdtech/go-merkletree v1.0.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.9.0 // indirect - golang.org/x/crypto v0.22.0 // indirect golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.22.0 // indirect golang.org/x/text v0.14.0 // indirect - google.golang.org/protobuf v1.34.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect rsc.io/tmplfunc v0.0.3 // indirect ) diff --git a/go.sum b/go.sum index bdf4ceb..62e0b16 100644 --- a/go.sum +++ b/go.sum @@ -1,73 +1,23 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= github.com/StackExchange/wmi v1.2.1 h1:VIkavFPXSjcnS+O8yTq7NI32k0R5Aj+v39y29VYDOSA= github.com/StackExchange/wmi v1.2.1/go.mod h1:rcmrprowKIVzvc+NUiLncP2uuArMWLCbu9SBzvHz7e8= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -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/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/VictoriaMetrics/fastcache v1.12.2 h1:N0y9ASrJ0F6h0QaC3o6uJb3NIZ9VKLjCM7NQbSmF7WI= +github.com/VictoriaMetrics/fastcache v1.12.2/go.mod h1:AmC+Nzz1+3G2eCPapF6UcsnkThDcMsQicp4xDukwJYI= github.com/avast/retry-go v3.0.0+incompatible h1:4SOWQ7Qs+oroOTQOYnAHqelpCO0biHSxpiH9JdtuBj0= github.com/avast/retry-go v3.0.0+incompatible/go.mod h1:XtSnn+n/sHqQIpZ10K1qAevBhOOCWBLXXy3hyiqqBrY= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bits-and-blooms/bitset v1.7.0 h1:YjAGVd3XmtK9ktAbX8Zg2g2PwLIMjGREZJHlV4j7NEo= -github.com/bits-and-blooms/bitset v1.7.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bits-and-blooms/bitset v1.10.0 h1:ePXTeiPEazB5+opbv5fr8umg2R/1NlzgDsyepwsSr88= -github.com/bits-and-blooms/bitset v1.10.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/bits-and-blooms/bitset v1.13.0 h1:bAQ9OPNFYbGHV6Nez0tmNI0RiEu7/hxlYJRUA0wFAVE= github.com/bits-and-blooms/bitset v1.13.0/go.mod h1:7hO7Gc7Pp1vODcmWvKMRA9BNmbv6a/7QIWpPxHddWR8= github.com/btcsuite/btcd/btcec/v2 v2.3.4 h1:3EJjcN70HCu/mwqlUsGK8GcNVyLVxFDlWurTXGPFfiQ= github.com/btcsuite/btcd/btcec/v2 v2.3.4/go.mod h1:zYzJ8etWJQIv1Ogk7OzpWjowwOdXY1W/17j2MW85J04= -github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1 h1:q0rUy8C/TYNBQS1+CGKw68tLOFYSNEs0TFnxxnS9+4U= +github.com/btcsuite/btcd/chaincfg/chainhash v1.0.1/go.mod h1:7SFka0XMvUgj3hfZtydOrQY2mwhPclbT2snogU7SQQc= github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/errors v1.11.3 h1:5bA+k2Y6r+oz/6Z/RFlNeVCesGARKuC6YymtcDrbC/I= github.com/cockroachdb/errors v1.11.3/go.mod h1:m4UIW4CDjx+R5cybPsNrRbreomiFqt8o1h1wUVazSd8= github.com/cockroachdb/fifo v0.0.0-20240606204812-0bbfbd93a7ce h1:giXvy4KSc/6g/esnpM7Geqxka4WSqI1SZc7sMJFd3y4= @@ -88,148 +38,64 @@ github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c h1:uQYC5Z1mdLR github.com/crate-crypto/go-ipa v0.0.0-20240223125850-b1e8a79f509c/go.mod h1:geZJZH3SzKCqnz5VT0q/DyIG/tvu/dZk+VIfXicupJs= github.com/crate-crypto/go-kzg-4844 v1.0.0 h1:TsSgHwrkTKecKJ4kadtHi4b3xHW5dCFUDFnUp1TsawI= github.com/crate-crypto/go-kzg-4844 v1.0.0/go.mod h1:1kMhvPgI0Ky3yIa+9lFySEBUBXkYxeOi8ZF1sYioxhc= -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/decred/dcrd/crypto/blake256 v1.0.0 h1:/8DMNYp9SGi5f0w7uCm6d6M4OU2rGFK09Y2A4Xv7EE0= github.com/decred/dcrd/crypto/blake256 v1.0.0/go.mod h1:sQl2p6Y26YV+ZOcSTP6thNdn47hh8kt6rqSlvmrXFAc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1 h1:YLtO71vCjJRCBcrPMtQ9nqBsqpA1m5sE92cU+pd5Mcc= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.0.1/go.mod h1:hyedUtir6IdtD/7lIxGeCxkaw7y45JueMRL4DIyJDKs= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ethereum/c-kzg-4844 v1.0.0 h1:0X1LBXxaEtYD9xsyj9B9ctQEZIpnvVDeoBx8aHEwTNA= github.com/ethereum/c-kzg-4844 v1.0.0/go.mod h1:VewdlzQmpT5QSrVhbBuGoCdFJkpaJlO1aQputP83wc0= -github.com/ethereum/go-ethereum v1.14.8 h1:NgOWvXS+lauK+zFukEvi85UmmsS/OkV0N23UZ1VTIig= -github.com/ethereum/go-ethereum v1.14.8/go.mod h1:TJhyuDq0JDppAkFXgqjwpdlQApywnu/m10kFPxh8vvs= github.com/ethereum/go-ethereum v1.14.11 h1:8nFDCUUE67rPc6AKxFj7JKaOa2W/W1Rse3oS6LvvxEY= github.com/ethereum/go-ethereum v1.14.11/go.mod h1:+l/fr42Mma+xBnhefL/+z11/hcmJ2egl+ScIVPjhc7E= github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9 h1:8NfxH2iXvJ60YRB8ChToFTUzl8awsc3cJ8CbLjGIl/A= github.com/ethereum/go-verkle v0.1.1-0.20240829091221-dffa7562dbe9/go.mod h1:M3b90YRnzqKyyzBEWJGqj8Qff4IDeXnzFw0P9bFw3uk= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/getsentry/sentry-go v0.27.0 h1:Pv98CIbtB3LkMWmXi4Joa5OOcwbmnX88sF5qbK3r3Ps= github.com/getsentry/sentry-go v0.27.0/go.mod h1:lc76E2QywIyW8WuBnwl8Lc4bkmQH4+w1gwTf25trprY= -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-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -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/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= -github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -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.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -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/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb h1:PBC98N2aIaM3XXiurYmW7fx4GZkL8feAMVq7nEjURHk= github.com/golang/snappy v0.0.5-0.20220116011046-fa5810519dcb/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.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/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/subcommands v1.2.0/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= 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/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/holiman/uint256 v1.3.1 h1:JfTzmih28bittyHM8z360dCjIA9dbPIBlcTI6lmctQs= github.com/holiman/uint256 v1.3.1/go.mod h1:EOMSn4q6Nyt9P6efbI3bueV4e1b3dGlUCXeiRV4ng7E= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -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/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4= github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -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.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -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 v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= +github.com/leanovate/gopter v0.2.9 h1:fQjYxZaynp97ozCzfOyOuAGOU4aU/z37zf/tOujFk7c= +github.com/leanovate/gopter v0.2.9/go.mod h1:U2L/78B+KVFIx2VmW6onHJQzXtFb+p5y3y2Sh+Jxxv8= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -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= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -237,57 +103,25 @@ github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/mmcloughlin/addchain v0.4.0 h1:SobOdjm2xLj1KkXN5/n0xTIWyZA2+s99UCY1iPfkHRY= github.com/mmcloughlin/addchain v0.4.0/go.mod h1:A86O+tHqZLMNO4w6ZZ4FlVQEadcoqkyU72HC5wJ4RlU= github.com/mmcloughlin/profile v0.1.1/go.mod h1:IhHD7q1ooxgwTgjxQYkACGA77oFTDdFVejUS1/tS/qU= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo v1.6.0/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/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= github.com/prometheus/client_golang v1.12.0 h1:C+UIj/QWtmqY13Arb8kwMt5j34/0Z2iKamrJ+ryC0Gg= github.com/prometheus/client_golang v1.12.0/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a h1:CmF68hwI0XsOQ5UwlBopMi2Ow4Pbg32akc4KIVCOm+Y= github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= @@ -296,9 +130,6 @@ github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6g github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU= github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= @@ -310,14 +141,11 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI= github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= @@ -325,8 +153,6 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/supranational/blst v0.3.11 h1:LyU6FolezeWAhvQk0k6O/d49jqgO52MSDDfYgbeoEm4= -github.com/supranational/blst v0.3.11/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/supranational/blst v0.3.13 h1:AYeSxdOMacwu7FBmpfloBz5pbFXDmJL33RuwnKtmTjk= github.com/supranational/blst v0.3.13/go.mod h1:jZJtfjgudtNl4en1tzwPIV3KjUnQUvG3/j+w+fVonLw= github.com/syndtr/goleveldb v1.0.1-0.20210819022825-2ae1ddf74ef7 h1:epCh84lMvA70Z7CTTCmYQn2CKbY8j86K7/FAIr141uY= @@ -339,328 +165,35 @@ github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65E github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/wealdtech/go-merkletree v1.0.0 h1:DsF1xMzj5rK3pSQM6mPv8jlyJyHXhFxpnA2bwEjMMBY= github.com/wealdtech/go-merkletree v1.0.0/go.mod h1:cdil512d/8ZC7Kx3bfrDvGMQXB25NTKbsm0rFrmDax4= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI= go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM= -golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -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-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -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= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= -golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= -golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -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-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= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -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= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -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.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= -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/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +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/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/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= -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= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= rsc.io/tmplfunc v0.0.3 h1:53XFQh69AfOa8Tw0Jm7t+GV7KZhOi6jzsCzTtKbMvzU= rsc.io/tmplfunc v0.0.3/go.mod h1:AG3sTPzElb1Io3Yg4voV9AGZJuleGAwaVRxL9M49PhA=