From b705293cfd50fbcefa3f65c1aadd15c7c49f492c Mon Sep 17 00:00:00 2001 From: DarkLord017 Date: Mon, 16 Sep 2024 20:53:16 +0530 Subject: [PATCH 1/8] Implemented_execution_proof_go_execution_errors_go_#30 --- execution/errors.go | 158 ++++++++++++++++++++++++++++++++++++ execution/proof.go | 192 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 350 insertions(+) create mode 100644 execution/errors.go create mode 100644 execution/proof.go diff --git a/execution/errors.go b/execution/errors.go new file mode 100644 index 0000000..be05f9c --- /dev/null +++ b/execution/errors.go @@ -0,0 +1,158 @@ +package execution + +import ( + "fmt" + + "github.com/ethereum/go-ethereum/accounts/abi" +) + +// Alloy's primitive type replacements (placeholders) +type Address string +type Bytes []byte +type B256 [32]byte +type U256 uint64 + +// ExecutionError represents various execution-related errors +type ExecutionError struct { + Kind string + Details interface{} +} + +func (e *ExecutionError) Error() string { + switch e.Kind { + case "InvalidAccountProof": + return fmt.Sprintf("invalid account proof for address: %v", e.Details) + case "InvalidStorageProof": + details := e.Details.([]interface{}) + return fmt.Sprintf("invalid storage proof for address: %v, slot: %v", details[0], details[1]) + case "CodeHashMismatch": + details := e.Details.([]interface{}) + return fmt.Sprintf("code hash mismatch for address: %v, found: %v, expected: %v", details[0], details[1], details[2]) + case "ReceiptRootMismatch": + return fmt.Sprintf("receipt root mismatch for tx: %v", e.Details) + case "MissingTransaction": + return fmt.Sprintf("missing transaction for tx: %v", e.Details) + case "NoReceiptForTransaction": + return fmt.Sprintf("could not prove receipt for tx: %v", e.Details) + case "MissingLog": + details := e.Details.([]interface{}) + return fmt.Sprintf("missing log for transaction: %v, index: %v", details[0], details[1]) + case "TooManyLogsToProve": + details := e.Details.([]interface{}) + return fmt.Sprintf("too many logs to prove: %v, current limit is: %v", details[0], details[1]) + case "IncorrectRpcNetwork": + return "execution RPC is for the incorrect network" + case "InvalidBaseGasFee": + details := e.Details.([]interface{}) + return fmt.Sprintf("Invalid base gas fee selene %v vs rpc endpoint %v at block %v", details[0], details[1], details[2]) + case "InvalidGasUsedRatio": + details := e.Details.([]interface{}) + return fmt.Sprintf("Invalid gas used ratio of selene %v vs rpc endpoint %v at block %v", details[0], details[1], details[2]) + case "BlockNotFoundError": + return fmt.Sprintf("Block %v not found", e.Details) + case "EmptyExecutionPayload": + return "Selene Execution Payload is empty" + case "InvalidBlockRange": + details := e.Details.([]interface{}) + return fmt.Sprintf("User query for block %v but selene oldest block is %v", details[0], details[1]) + default: + return "unknown execution error" + } +} + +// Helper functions to create specific ExecutionError instances +func NewInvalidAccountProofError(address Address) error { + return &ExecutionError{"InvalidAccountProof", address} +} + +func NewInvalidStorageProofError(address Address, slot B256) error { + return &ExecutionError{"InvalidStorageProof", []interface{}{address, slot}} +} + +func NewCodeHashMismatchError(address Address, found B256, expected B256) error { + return &ExecutionError{"CodeHashMismatch", []interface{}{address, found, expected}} +} + +func NewReceiptRootMismatchError(tx B256) error { + return &ExecutionError{"ReceiptRootMismatch", tx} +} + +func NewMissingTransactionError(tx B256) error { + return &ExecutionError{"MissingTransaction", tx} +} + +func NewNoReceiptForTransactionError(tx B256) error { + return &ExecutionError{"NoReceiptForTransaction", tx} +} + +func NewMissingLogError(tx B256, index U256) error { + return &ExecutionError{"MissingLog", []interface{}{tx, index}} +} + +func NewTooManyLogsToProveError(count int, limit int) error { + return &ExecutionError{"TooManyLogsToProve", []interface{}{count, limit}} +} + +func NewIncorrectRpcNetworkError() error { + return &ExecutionError{"IncorrectRpcNetwork", nil} +} + +func NewInvalidBaseGasFeeError(selene U256, rpc U256, block uint64) error { + return &ExecutionError{"InvalidBaseGasFee", []interface{}{selene, rpc, block}} +} + +func NewInvalidGasUsedRatioError(seleneRatio float64, rpcRatio float64, block uint64) error { + return &ExecutionError{"InvalidGasUsedRatio", []interface{}{seleneRatio, rpcRatio, block}} +} + +func NewBlockNotFoundError(block uint64) error { + return &ExecutionError{"BlockNotFoundError", block} +} + +func NewEmptyExecutionPayloadError() error { + return &ExecutionError{"EmptyExecutionPayload", nil} +} + +func NewInvalidBlockRangeError(queryBlock uint64, oldestBlock uint64) error { + return &ExecutionError{"InvalidBlockRange", []interface{}{queryBlock, oldestBlock}} +} + +// EvmError represents EVM-related errors +type EvmError struct { + Kind string + Details interface{} +} + +func (e *EvmError) Error() string { + switch e.Kind { + case "Revert": + return fmt.Sprintf("execution reverted: %v", e.Details) + case "Generic": + return fmt.Sprintf("evm error: %v", e.Details) + case "RpcError": + return fmt.Sprintf("rpc error: %v", e.Details) + default: + return "unknown evm error" + } +} + +// Helper functions for creating specific EVM errors +func NewRevertError(data Bytes) error { + return &EvmError{"Revert", data} +} + +func NewGenericError(message string) error { + return &EvmError{"Generic", message} +} + +func NewRpcError(report error) error { + return &EvmError{"RpcError", report} +} + +func DecodeRevertReason(data []byte) string { + reason, err := abi.UnpackRevert(data) + if err != nil { + reason = string(err.Error()) + } + return reason +} diff --git a/execution/proof.go b/execution/proof.go new file mode 100644 index 0000000..f6358b7 --- /dev/null +++ b/execution/proof.go @@ -0,0 +1,192 @@ +package execution + +import ( + "bytes" + "fmt" + "math/big" + + "github.com/ethereum/go-ethereum/rlp" + "golang.org/x/crypto/sha3" +) + +// Account struct to represent the account in the Merkle proof +type Account struct { + Nonce uint64 + Balance *big.Int + StorageRoot [32]byte + CodeHash [32]byte +} + +// EIP1186AccountProofResponse for account proof encoding +type EIP1186AccountProofResponse struct { + Nonce uint64 + Balance *big.Int + StorageHash [32]byte + CodeHash [32]byte +} + +func verifyProof(proof [][]byte, root []byte, path []byte, value []byte) (bool, error) { + expectedHash := root + pathOffset := 0 + + for i, node := range proof { + if !bytes.Equal(expectedHash, keccak256(node)) { + return false, nil + } + + var nodeList [][]byte + if err := rlp.DecodeBytes(node, &nodeList); err != nil { + fmt.Println("Error decoding node:", err) + return false, err + } + + if len(nodeList) == 17 { + if i == len(proof)-1 { + // exclusion proof + nibble := getNibble(path, pathOffset) + if len(nodeList[nibble]) == 0 && isEmptyValue(value) { + return true, nil + } + } else { + nibble := getNibble(path, pathOffset) + expectedHash = nodeList[nibble] + pathOffset++ + } + } else if len(nodeList) == 2 { + if i == len(proof)-1 { + // exclusion proof + if !pathsMatch(nodeList[0], skipLength(nodeList[0]), path, pathOffset) && isEmptyValue(value) { + return true, nil + } + + // inclusion proof + if bytes.Equal(nodeList[1], value) { + return pathsMatch(nodeList[0], skipLength(nodeList[0]), path, pathOffset), nil + } + } else { + nodePath := nodeList[0] + prefixLength := sharedPrefixLength(path, pathOffset, nodePath) + if prefixLength < len(nodePath)*2-skipLength(nodePath) { + // Proof shows a divergent path , but we're not at the leaf yet + return false, nil + } + pathOffset += prefixLength + expectedHash = nodeList[1] + } + } else { + return false, nil + } + } + + return false, nil +} + +func pathsMatch(p1 []byte, s1 int, p2 []byte, s2 int) bool { + len1 := len(p1)*2 - s1 + len2 := len(p2)*2 - s2 + + if len1 != len2 { + return false + } + + for offset := 0; offset < len1; offset++ { + n1 := getNibble(p1, s1+offset) + n2 := getNibble(p2, s2+offset) + if n1 != n2 { + return false + } + } + + return true +} + +func getRestPath(p []byte, s int) string { + var ret string + for i := s; i < len(p)*2; i++ { + n := getNibble(p, i) + ret += fmt.Sprintf("%01x", n) + } + return ret +} + +func isEmptyValue(value []byte) bool { + emptyAccount := Account{ + Nonce: 0, + Balance: big.NewInt(0), + StorageRoot: [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) + + isEmptySlot := len(value) == 1 && value[0] == 0x80 + isEmptyAccount := bytes.Equal(value, encodedEmptyAccount) + + return isEmptySlot || isEmptyAccount +} + +func sharedPrefixLength(path []byte, pathOffset int, nodePath []byte) int { + skipLength := skipLength(nodePath) + + len1 := min(len(nodePath)*2-skipLength, len(path)*2-pathOffset) + prefixLen := 0 + + for i := 0; i < len1; i++ { + pathNibble := getNibble(path, i+pathOffset) + nodePathNibble := getNibble(nodePath, i+skipLength) + if pathNibble != nodePathNibble { + break + } + prefixLen++ + } + + return prefixLen +} + +func skipLength(node []byte) int { + if len(node) == 0 { + return 0 + } + + nibble := getNibble(node, 0) + switch nibble { + case 0, 2: + return 2 + case 1, 3: + return 1 + default: + return 0 + } +} + +func getNibble(path []byte, offset int) byte { + byteVal := path[offset/2] + if offset%2 == 0 { + return byteVal >> 4 + } + return byteVal & 0xF +} + +func keccak256(data []byte) []byte { + hash := sha3.NewLegacyKeccak256() + hash.Write(data) + return hash.Sum(nil) +} + +func encodeAccount(proof *EIP1186AccountProofResponse) ([]byte, error) { + account := Account{ + Nonce: proof.Nonce, + Balance: proof.Balance, + StorageRoot: proof.StorageHash, + CodeHash: proof.CodeHash, + } + + return rlp.EncodeToBytes(account) +} + +func min(a, b int) int { + if a < b { + return a + } + return b +} From 25e996bac3c92aa40ea98051ff49d7d9e81d5449 Mon Sep 17 00:00:00 2001 From: Sambhav Jain <136801346+DarkLord017@users.noreply.github.com> Date: Fri, 20 Sep 2024 01:56:37 +0530 Subject: [PATCH 2/8] Update errors.go removed unnecessary types --- execution/errors.go | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/execution/errors.go b/execution/errors.go index be05f9c..e38813c 100644 --- a/execution/errors.go +++ b/execution/errors.go @@ -6,12 +6,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" ) -// Alloy's primitive type replacements (placeholders) -type Address string -type Bytes []byte -type B256 [32]byte -type U256 uint64 - // ExecutionError represents various execution-related errors type ExecutionError struct { Kind string @@ -21,13 +15,13 @@ type ExecutionError struct { func (e *ExecutionError) Error() string { switch e.Kind { case "InvalidAccountProof": - return fmt.Sprintf("invalid account proof for address: %v", e.Details) + return fmt.Sprintf("invalid account proof for string: %v", e.Details) case "InvalidStorageProof": details := e.Details.([]interface{}) - return fmt.Sprintf("invalid storage proof for address: %v, slot: %v", details[0], details[1]) + return fmt.Sprintf("invalid storage proof for string: %v, slot: %v", details[0], details[1]) case "CodeHashMismatch": details := e.Details.([]interface{}) - return fmt.Sprintf("code hash mismatch for address: %v, found: %v, expected: %v", details[0], details[1], details[2]) + return fmt.Sprintf("code hash mismatch for string: %v, found: %v, expected: %v", details[0], details[1], details[2]) case "ReceiptRootMismatch": return fmt.Sprintf("receipt root mismatch for tx: %v", e.Details) case "MissingTransaction": @@ -61,31 +55,31 @@ func (e *ExecutionError) Error() string { } // Helper functions to create specific ExecutionError instances -func NewInvalidAccountProofError(address Address) error { - return &ExecutionError{"InvalidAccountProof", address} +func NewInvalidAccountProofError(string string) error { + return &ExecutionError{"InvalidAccountProof", string} } -func NewInvalidStorageProofError(address Address, slot B256) error { - return &ExecutionError{"InvalidStorageProof", []interface{}{address, slot}} +func NewInvalidStorageProofError(string string, slot [32]byte) error { + return &ExecutionError{"InvalidStorageProof", []interface{}{string, slot}} } -func NewCodeHashMismatchError(address Address, found B256, expected B256) error { - return &ExecutionError{"CodeHashMismatch", []interface{}{address, found, expected}} +func NewCodeHashMismatchError(string string, found [32]byte, expected [32]byte) error { + return &ExecutionError{"CodeHashMismatch", []interface{}{string, found, expected}} } -func NewReceiptRootMismatchError(tx B256) error { +func NewReceiptRootMismatchError(tx [32]byte) error { return &ExecutionError{"ReceiptRootMismatch", tx} } -func NewMissingTransactionError(tx B256) error { +func NewMissingTransactionError(tx [32]byte) error { return &ExecutionError{"MissingTransaction", tx} } -func NewNoReceiptForTransactionError(tx B256) error { +func NewNoReceiptForTransactionError(tx [32]byte) error { return &ExecutionError{"NoReceiptForTransaction", tx} } -func NewMissingLogError(tx B256, index U256) error { +func NewMissingLogError(tx [32]byte, index uint64) error { return &ExecutionError{"MissingLog", []interface{}{tx, index}} } @@ -97,7 +91,7 @@ func NewIncorrectRpcNetworkError() error { return &ExecutionError{"IncorrectRpcNetwork", nil} } -func NewInvalidBaseGasFeeError(selene U256, rpc U256, block uint64) error { +func NewInvalidBaseGasFeeError(selene uint64, rpc uint64, block uint64) error { return &ExecutionError{"InvalidBaseGasFee", []interface{}{selene, rpc, block}} } @@ -137,7 +131,7 @@ func (e *EvmError) Error() string { } // Helper functions for creating specific EVM errors -func NewRevertError(data Bytes) error { +func NewRevertError(data []byte) error { return &EvmError{"Revert", data} } From 0f1203ab599ecd1e6a78c7a82e16ba783dccb427 Mon Sep 17 00:00:00 2001 From: Sambhav Jain <136801346+DarkLord017@users.noreply.github.com> Date: Fri, 20 Sep 2024 02:00:40 +0530 Subject: [PATCH 3/8] Update proof.go made required functions public --- execution/proof.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/execution/proof.go b/execution/proof.go index f6358b7..a3b5ab8 100644 --- a/execution/proof.go +++ b/execution/proof.go @@ -25,7 +25,7 @@ type EIP1186AccountProofResponse struct { CodeHash [32]byte } -func verifyProof(proof [][]byte, root []byte, path []byte, value []byte) (bool, error) { +func VerifyProof(proof [][]byte, root []byte, path []byte, value []byte) (bool, error) { expectedHash := root pathOffset := 0 @@ -173,7 +173,7 @@ func keccak256(data []byte) []byte { return hash.Sum(nil) } -func encodeAccount(proof *EIP1186AccountProofResponse) ([]byte, error) { +func EncodeAccount(proof *EIP1186AccountProofResponse) ([]byte, error) { account := Account{ Nonce: proof.Nonce, Balance: proof.Balance, From 9ede1ab3b5caee467697eb7b2f6e896c03282875 Mon Sep 17 00:00:00 2001 From: DarkLord017 Date: Mon, 16 Sep 2024 20:53:16 +0530 Subject: [PATCH 4/8] Rebasing it with dev to resiolve merge conflicts --- execution/errors.go | 36 +++++++++++++++++++++--------------- execution/proof.go | 4 ++-- 2 files changed, 23 insertions(+), 17 deletions(-) diff --git a/execution/errors.go b/execution/errors.go index e38813c..be05f9c 100644 --- a/execution/errors.go +++ b/execution/errors.go @@ -6,6 +6,12 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" ) +// Alloy's primitive type replacements (placeholders) +type Address string +type Bytes []byte +type B256 [32]byte +type U256 uint64 + // ExecutionError represents various execution-related errors type ExecutionError struct { Kind string @@ -15,13 +21,13 @@ type ExecutionError struct { func (e *ExecutionError) Error() string { switch e.Kind { case "InvalidAccountProof": - return fmt.Sprintf("invalid account proof for string: %v", e.Details) + return fmt.Sprintf("invalid account proof for address: %v", e.Details) case "InvalidStorageProof": details := e.Details.([]interface{}) - return fmt.Sprintf("invalid storage proof for string: %v, slot: %v", details[0], details[1]) + return fmt.Sprintf("invalid storage proof for address: %v, slot: %v", details[0], details[1]) case "CodeHashMismatch": details := e.Details.([]interface{}) - return fmt.Sprintf("code hash mismatch for string: %v, found: %v, expected: %v", details[0], details[1], details[2]) + return fmt.Sprintf("code hash mismatch for address: %v, found: %v, expected: %v", details[0], details[1], details[2]) case "ReceiptRootMismatch": return fmt.Sprintf("receipt root mismatch for tx: %v", e.Details) case "MissingTransaction": @@ -55,31 +61,31 @@ func (e *ExecutionError) Error() string { } // Helper functions to create specific ExecutionError instances -func NewInvalidAccountProofError(string string) error { - return &ExecutionError{"InvalidAccountProof", string} +func NewInvalidAccountProofError(address Address) error { + return &ExecutionError{"InvalidAccountProof", address} } -func NewInvalidStorageProofError(string string, slot [32]byte) error { - return &ExecutionError{"InvalidStorageProof", []interface{}{string, slot}} +func NewInvalidStorageProofError(address Address, slot B256) error { + return &ExecutionError{"InvalidStorageProof", []interface{}{address, slot}} } -func NewCodeHashMismatchError(string string, found [32]byte, expected [32]byte) error { - return &ExecutionError{"CodeHashMismatch", []interface{}{string, found, expected}} +func NewCodeHashMismatchError(address Address, found B256, expected B256) error { + return &ExecutionError{"CodeHashMismatch", []interface{}{address, found, expected}} } -func NewReceiptRootMismatchError(tx [32]byte) error { +func NewReceiptRootMismatchError(tx B256) error { return &ExecutionError{"ReceiptRootMismatch", tx} } -func NewMissingTransactionError(tx [32]byte) error { +func NewMissingTransactionError(tx B256) error { return &ExecutionError{"MissingTransaction", tx} } -func NewNoReceiptForTransactionError(tx [32]byte) error { +func NewNoReceiptForTransactionError(tx B256) error { return &ExecutionError{"NoReceiptForTransaction", tx} } -func NewMissingLogError(tx [32]byte, index uint64) error { +func NewMissingLogError(tx B256, index U256) error { return &ExecutionError{"MissingLog", []interface{}{tx, index}} } @@ -91,7 +97,7 @@ func NewIncorrectRpcNetworkError() error { return &ExecutionError{"IncorrectRpcNetwork", nil} } -func NewInvalidBaseGasFeeError(selene uint64, rpc uint64, block uint64) error { +func NewInvalidBaseGasFeeError(selene U256, rpc U256, block uint64) error { return &ExecutionError{"InvalidBaseGasFee", []interface{}{selene, rpc, block}} } @@ -131,7 +137,7 @@ func (e *EvmError) Error() string { } // Helper functions for creating specific EVM errors -func NewRevertError(data []byte) error { +func NewRevertError(data Bytes) error { return &EvmError{"Revert", data} } diff --git a/execution/proof.go b/execution/proof.go index a3b5ab8..f6358b7 100644 --- a/execution/proof.go +++ b/execution/proof.go @@ -25,7 +25,7 @@ type EIP1186AccountProofResponse struct { CodeHash [32]byte } -func VerifyProof(proof [][]byte, root []byte, path []byte, value []byte) (bool, error) { +func verifyProof(proof [][]byte, root []byte, path []byte, value []byte) (bool, error) { expectedHash := root pathOffset := 0 @@ -173,7 +173,7 @@ func keccak256(data []byte) []byte { return hash.Sum(nil) } -func EncodeAccount(proof *EIP1186AccountProofResponse) ([]byte, error) { +func encodeAccount(proof *EIP1186AccountProofResponse) ([]byte, error) { account := Account{ Nonce: proof.Nonce, Balance: proof.Balance, From 0129bf408559dd44965137e95cd18c8f1363f78d Mon Sep 17 00:00:00 2001 From: Sambhav Jain <136801346+DarkLord017@users.noreply.github.com> Date: Fri, 20 Sep 2024 01:56:37 +0530 Subject: [PATCH 5/8] Update errors.go removed unnecessary types --- execution/errors.go | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/execution/errors.go b/execution/errors.go index be05f9c..e38813c 100644 --- a/execution/errors.go +++ b/execution/errors.go @@ -6,12 +6,6 @@ import ( "github.com/ethereum/go-ethereum/accounts/abi" ) -// Alloy's primitive type replacements (placeholders) -type Address string -type Bytes []byte -type B256 [32]byte -type U256 uint64 - // ExecutionError represents various execution-related errors type ExecutionError struct { Kind string @@ -21,13 +15,13 @@ type ExecutionError struct { func (e *ExecutionError) Error() string { switch e.Kind { case "InvalidAccountProof": - return fmt.Sprintf("invalid account proof for address: %v", e.Details) + return fmt.Sprintf("invalid account proof for string: %v", e.Details) case "InvalidStorageProof": details := e.Details.([]interface{}) - return fmt.Sprintf("invalid storage proof for address: %v, slot: %v", details[0], details[1]) + return fmt.Sprintf("invalid storage proof for string: %v, slot: %v", details[0], details[1]) case "CodeHashMismatch": details := e.Details.([]interface{}) - return fmt.Sprintf("code hash mismatch for address: %v, found: %v, expected: %v", details[0], details[1], details[2]) + return fmt.Sprintf("code hash mismatch for string: %v, found: %v, expected: %v", details[0], details[1], details[2]) case "ReceiptRootMismatch": return fmt.Sprintf("receipt root mismatch for tx: %v", e.Details) case "MissingTransaction": @@ -61,31 +55,31 @@ func (e *ExecutionError) Error() string { } // Helper functions to create specific ExecutionError instances -func NewInvalidAccountProofError(address Address) error { - return &ExecutionError{"InvalidAccountProof", address} +func NewInvalidAccountProofError(string string) error { + return &ExecutionError{"InvalidAccountProof", string} } -func NewInvalidStorageProofError(address Address, slot B256) error { - return &ExecutionError{"InvalidStorageProof", []interface{}{address, slot}} +func NewInvalidStorageProofError(string string, slot [32]byte) error { + return &ExecutionError{"InvalidStorageProof", []interface{}{string, slot}} } -func NewCodeHashMismatchError(address Address, found B256, expected B256) error { - return &ExecutionError{"CodeHashMismatch", []interface{}{address, found, expected}} +func NewCodeHashMismatchError(string string, found [32]byte, expected [32]byte) error { + return &ExecutionError{"CodeHashMismatch", []interface{}{string, found, expected}} } -func NewReceiptRootMismatchError(tx B256) error { +func NewReceiptRootMismatchError(tx [32]byte) error { return &ExecutionError{"ReceiptRootMismatch", tx} } -func NewMissingTransactionError(tx B256) error { +func NewMissingTransactionError(tx [32]byte) error { return &ExecutionError{"MissingTransaction", tx} } -func NewNoReceiptForTransactionError(tx B256) error { +func NewNoReceiptForTransactionError(tx [32]byte) error { return &ExecutionError{"NoReceiptForTransaction", tx} } -func NewMissingLogError(tx B256, index U256) error { +func NewMissingLogError(tx [32]byte, index uint64) error { return &ExecutionError{"MissingLog", []interface{}{tx, index}} } @@ -97,7 +91,7 @@ func NewIncorrectRpcNetworkError() error { return &ExecutionError{"IncorrectRpcNetwork", nil} } -func NewInvalidBaseGasFeeError(selene U256, rpc U256, block uint64) error { +func NewInvalidBaseGasFeeError(selene uint64, rpc uint64, block uint64) error { return &ExecutionError{"InvalidBaseGasFee", []interface{}{selene, rpc, block}} } @@ -137,7 +131,7 @@ func (e *EvmError) Error() string { } // Helper functions for creating specific EVM errors -func NewRevertError(data Bytes) error { +func NewRevertError(data []byte) error { return &EvmError{"Revert", data} } From 02548aa473feed1fa6f88b1a22176b6c90f5375f Mon Sep 17 00:00:00 2001 From: Sambhav Jain <136801346+DarkLord017@users.noreply.github.com> Date: Fri, 20 Sep 2024 02:00:40 +0530 Subject: [PATCH 6/8] Update proof.go made required functions public --- execution/proof.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/execution/proof.go b/execution/proof.go index f6358b7..a3b5ab8 100644 --- a/execution/proof.go +++ b/execution/proof.go @@ -25,7 +25,7 @@ type EIP1186AccountProofResponse struct { CodeHash [32]byte } -func verifyProof(proof [][]byte, root []byte, path []byte, value []byte) (bool, error) { +func VerifyProof(proof [][]byte, root []byte, path []byte, value []byte) (bool, error) { expectedHash := root pathOffset := 0 @@ -173,7 +173,7 @@ func keccak256(data []byte) []byte { return hash.Sum(nil) } -func encodeAccount(proof *EIP1186AccountProofResponse) ([]byte, error) { +func EncodeAccount(proof *EIP1186AccountProofResponse) ([]byte, error) { account := Account{ Nonce: proof.Nonce, Balance: proof.Balance, From 2b738b1b088e885d74bf9d1bbba90a84152b3ba5 Mon Sep 17 00:00:00 2001 From: Sambhav Jain <136801346+DarkLord017@users.noreply.github.com> Date: Fri, 27 Sep 2024 22:39:23 +0530 Subject: [PATCH 7/8] Update errors.go to use address instead of string --- execution/errors.go | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/execution/errors.go b/execution/errors.go index e38813c..2241b86 100644 --- a/execution/errors.go +++ b/execution/errors.go @@ -3,6 +3,8 @@ package execution import ( "fmt" + "github.com/BlocSoc-iitr/selene/consensus/consensus_core" + "github.com/BlocSoc-iitr/selene/consensus/types" "github.com/ethereum/go-ethereum/accounts/abi" ) @@ -55,31 +57,31 @@ func (e *ExecutionError) Error() string { } // Helper functions to create specific ExecutionError instances -func NewInvalidAccountProofError(string string) error { - return &ExecutionError{"InvalidAccountProof", string} +func NewInvalidAccountProofError(address types.Address) error { + return &ExecutionError{"InvalidAccountProof", address} } -func NewInvalidStorageProofError(string string, slot [32]byte) error { - return &ExecutionError{"InvalidStorageProof", []interface{}{string, slot}} +func NewInvalidStorageProofError(address types.Address, slot consensus_core.Bytes32) error { + return &ExecutionError{"InvalidStorageProof", []interface{}{address, slot}} } -func NewCodeHashMismatchError(string string, found [32]byte, expected [32]byte) error { - return &ExecutionError{"CodeHashMismatch", []interface{}{string, found, expected}} +func NewCodeHashMismatchError(address types.Address, found consensus_core.Bytes32, expected consensus_core.Bytes32) error { + return &ExecutionError{"CodeHashMismatch", []interface{}{address, found, expected}} } -func NewReceiptRootMismatchError(tx [32]byte) error { +func NewReceiptRootMismatchError(tx consensus_core.Bytes32) error { return &ExecutionError{"ReceiptRootMismatch", tx} } -func NewMissingTransactionError(tx [32]byte) error { +func NewMissingTransactionError(tx consensus_core.Bytes32) error { return &ExecutionError{"MissingTransaction", tx} } -func NewNoReceiptForTransactionError(tx [32]byte) error { +func NewNoReceiptForTransactionError(tx consensus_core.Bytes32) error { return &ExecutionError{"NoReceiptForTransaction", tx} } -func NewMissingLogError(tx [32]byte, index uint64) error { +func NewMissingLogError(tx consensus_core.Bytes32, index uint64) error { return &ExecutionError{"MissingLog", []interface{}{tx, index}} } From 394539bf62cf2788ac661b5385a03203c8ba026f Mon Sep 17 00:00:00 2001 From: DarkLord017 Date: Sat, 28 Sep 2024 02:08:26 +0530 Subject: [PATCH 8/8] Rebased the branch n updated address types n added comment --- execution/proof.go | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/execution/proof.go b/execution/proof.go index a3b5ab8..549e7ec 100644 --- a/execution/proof.go +++ b/execution/proof.go @@ -9,14 +9,6 @@ import ( "golang.org/x/crypto/sha3" ) -// Account struct to represent the account in the Merkle proof -type Account struct { - Nonce uint64 - Balance *big.Int - StorageRoot [32]byte - CodeHash [32]byte -} - // EIP1186AccountProofResponse for account proof encoding type EIP1186AccountProofResponse struct { Nonce uint64 @@ -100,7 +92,8 @@ func pathsMatch(p1 []byte, s1 int, p2 []byte, s2 int) bool { return true } -func getRestPath(p []byte, s int) string { +// dead code +func GetRestPath(p []byte, s int) string { var ret string for i := s; i < len(p)*2; i++ { n := getNibble(p, i) @@ -113,7 +106,7 @@ func isEmptyValue(value []byte) bool { emptyAccount := Account{ Nonce: 0, Balance: big.NewInt(0), - StorageRoot: [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}, + 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}, } @@ -177,13 +170,14 @@ func EncodeAccount(proof *EIP1186AccountProofResponse) ([]byte, error) { account := Account{ Nonce: proof.Nonce, Balance: proof.Balance, - StorageRoot: proof.StorageHash, + StorageHash: proof.StorageHash, CodeHash: proof.CodeHash, } return rlp.EncodeToBytes(account) } +// Make a generic function for it func min(a, b int) int { if a < b { return a