From 1d63611aa1fef519d47e9a3ed52f5a6e95f65b2a Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:11:48 +0200 Subject: [PATCH 1/5] special handle out of range on en --- services/requester/requester.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/services/requester/requester.go b/services/requester/requester.go index 39632d1cc..98b19c3e1 100644 --- a/services/requester/requester.go +++ b/services/requester/requester.go @@ -677,12 +677,21 @@ func (e *EVM) executeScriptAtHeight( ) } - return e.client.ExecuteScriptAtBlockHeight( + res, err := e.client.ExecuteScriptAtBlockHeight( ctx, height, e.replaceAddresses(script), arguments, ) + if err != nil { + // if snapshot doesn't exist on EN, the height at which script was executed is out + // of the boundaries the EN keeps state, so return out of range + if strings.Contains(err.Error(), "failed to create storage snapshot") { + return nil, ErrOutOfRange + } + } + + return res, err } func addressToCadenceString(address common.Address) (cadence.String, error) { From ec96200f50cc1628f8902694954f0d83443e8cf7 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:18:22 +0200 Subject: [PATCH 2/5] improve handling of errors in api --- api/api.go | 24 +++++++++++------------- services/requester/cross-spork_client.go | 2 +- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/api/api.go b/api/api.go index a9a603be3..ffd2584c3 100644 --- a/api/api.go +++ b/api/api.go @@ -191,17 +191,7 @@ func (b *BlockChainAPI) SendRawTransaction( id, err := b.evm.SendRawTransaction(ctx, input) if err != nil { - var errGasPriceTooLow *errs.GasPriceTooLowError - - // handle typed errors - switch { - case errors.As(err, &errGasPriceTooLow): - return common.Hash{}, errGasPriceTooLow - case errors.Is(err, models.ErrInvalidEVMTransaction): - return common.Hash{}, err - default: - return common.Hash{}, errs.ErrInternal - } + return handleError[common.Hash](b.logger, err) } return id, nil @@ -912,17 +902,25 @@ func (b *BlockChainAPI) GetStorageAt( // if the error is not of type ErrNotFound it will return the error and the generic // empty type. func handleError[T any](log zerolog.Logger, err error) (T, error) { - var zero T + var ( + zero T + errGasPriceTooLow *errs.GasPriceTooLowError + ) + switch { // as per specification returning nil and nil for not found resources case errors.Is(err, storageErrs.ErrNotFound): return zero, nil case errors.Is(err, storageErrs.ErrInvalidRange): return zero, err + case errors.Is(err, models.ErrInvalidEVMTransaction): + return zero, err case errors.Is(err, requester.ErrOutOfRange): - return zero, fmt.Errorf("requested height is out of supported range") + return zero, err case errors.Is(err, errs.ErrInvalid): return zero, err + case errors.As(err, &errGasPriceTooLow): + return zero, errGasPriceTooLow default: log.Error().Err(err).Msg("api error") return zero, errs.ErrInternal diff --git a/services/requester/cross-spork_client.go b/services/requester/cross-spork_client.go index ae7650cff..73bdfd195 100644 --- a/services/requester/cross-spork_client.go +++ b/services/requester/cross-spork_client.go @@ -13,7 +13,7 @@ import ( "golang.org/x/exp/slices" ) -var ErrOutOfRange = errors.New("height is out of range for provided spork clients") +var ErrOutOfRange = errors.New("height is out of available range") type sporkClient struct { firstHeight uint64 From 2743833d631df73e5619e48f573472c16a87ac06 Mon Sep 17 00:00:00 2001 From: sideninja <75445744+sideninja@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:52:06 +0200 Subject: [PATCH 3/5] add payload that fails to decode to th error for easier debugging --- models/block.go | 2 +- models/transaction.go | 18 +++++++++--------- services/requester/requester.go | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/models/block.go b/models/block.go index ef06007b9..8a331b16a 100644 --- a/models/block.go +++ b/models/block.go @@ -22,7 +22,7 @@ var ( func decodeBlock(event cadence.Event) (*types.Block, error) { payload, err := types.DecodeBlockEventPayload(event) if err != nil { - return nil, fmt.Errorf("failed to cadence decode block: %w", err) + return nil, fmt.Errorf("failed to cadence decode block [%s]: %w", event.String(), err) } hashes := make([]common.Hash, len(payload.TransactionHashes)) diff --git a/models/transaction.go b/models/transaction.go index 1012e3a9d..5973aeea8 100644 --- a/models/transaction.go +++ b/models/transaction.go @@ -190,24 +190,24 @@ func decodeTransactionEvent( ) (Transaction, *StorageReceipt, error) { txEvent, err := types.DecodeTransactionEventPayload(event) if err != nil { - return nil, nil, fmt.Errorf("failed to Cadence decode transaction event: %w", err) + return nil, nil, fmt.Errorf("failed to Cadence decode transaction event [%s]: %w", event.String(), err) } encodedTx, err := hex.DecodeString(txEvent.Payload) if err != nil { - return nil, nil, fmt.Errorf("failed to hex-decode transaction payload: %w", err) + return nil, nil, fmt.Errorf("failed to hex decode transaction payload [%s]: %w", txEvent.Payload, err) } encodedLogs, err := hex.DecodeString(txEvent.Logs) if err != nil { - return nil, nil, fmt.Errorf("failed to hex decode receipt: %w", err) + return nil, nil, fmt.Errorf("failed to hex decode receipt [%s]: %w", txEvent.Logs, err) } var logs []*gethTypes.Log if len(encodedLogs) > 0 { err = rlp.Decode(bytes.NewReader(encodedLogs), &logs) if err != nil { - return nil, nil, fmt.Errorf("failed to RLP-decode receipt: %w", err) + return nil, nil, fmt.Errorf("failed to RLP-decode receipt [%x]: %w", encodedLogs, err) } } @@ -235,7 +235,7 @@ func decodeTransactionEvent( if txEvent.ErrorCode == uint16(types.ExecutionErrCodeExecutionReverted) { revert, err := hex.DecodeString(txEvent.ReturnedData) if err != nil { - return nil, nil, fmt.Errorf("failed to hex-decode transaction return data: %w", err) + return nil, nil, fmt.Errorf("failed to hex-decode transaction return data [%s]: %w", txEvent.ReturnedData, err) } receipt.RevertReason = revert } @@ -246,7 +246,7 @@ func decodeTransactionEvent( if txEvent.TransactionType == types.DirectCallTxType { directCall, err := types.DirectCallFromEncoded(encodedTx) if err != nil { - return nil, nil, fmt.Errorf("failed to RLP-decode direct call: %w", err) + return nil, nil, fmt.Errorf("failed to RLP-decode direct call [%x]: %w", encodedTx, err) } evmHeight := receipt.BlockNumber.Uint64() @@ -254,7 +254,7 @@ func decodeTransactionEvent( } else { gethTx := &gethTypes.Transaction{} if err := gethTx.UnmarshalBinary(encodedTx); err != nil { - return nil, nil, fmt.Errorf("failed to RLP-decode transaction: %w", err) + return nil, nil, fmt.Errorf("failed to RLP-decode transaction [%x]: %w", encodedTx, err) } tx = TransactionCall{Transaction: gethTx} } @@ -269,7 +269,7 @@ func UnmarshalTransaction(value []byte, blockHeight uint64) (Transaction, error) if value[0] == types.DirectCallTxType { directCall, err := types.DirectCallFromEncoded(value) if err != nil { - return nil, fmt.Errorf("failed to RLP-decode direct call: %w", err) + return nil, fmt.Errorf("failed to RLP-decode direct call [%x]: %w", value, err) } // TEMP: Remove `blockHeight` after PreviewNet is reset @@ -284,7 +284,7 @@ func UnmarshalTransaction(value []byte, blockHeight uint64) (Transaction, error) return TransactionCall{Transaction: tx}, nil } - return nil, fmt.Errorf("failed to RLP-decode transaction: %w", err) + return nil, fmt.Errorf("failed to RLP-decode transaction [%x]: %w", value, err) } return TransactionCall{Transaction: tx}, nil diff --git a/services/requester/requester.go b/services/requester/requester.go index 98b19c3e1..5dc6a3ba8 100644 --- a/services/requester/requester.go +++ b/services/requester/requester.go @@ -453,7 +453,7 @@ func (e *EVM) Call( evmResult, err := stdlib.ResultSummaryFromEVMResultValue(scriptResult) if err != nil { - return nil, fmt.Errorf("failed to decode EVM result from call: %w", err) + return nil, fmt.Errorf("failed to decode EVM result from call [%s]: %w", scriptResult.String(), err) } if evmResult.ErrorCode != 0 { @@ -708,7 +708,7 @@ func cadenceStringToBytes(value cadence.Value) ([]byte, error) { code, err := hex.DecodeString(string(cdcString)) if err != nil { - return nil, fmt.Errorf("failed to decode string to byte array: %w", err) + return nil, fmt.Errorf("failed to decode string to byte array [%s]: %w", cdcString, err) } return code, nil From 4e3712ab81d818be42423e4752109453ed0b536e Mon Sep 17 00:00:00 2001 From: "Gregor G." <75445744+sideninja@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:17:23 +0200 Subject: [PATCH 4/5] Update models/transaction.go Co-authored-by: Ardit Marku --- models/transaction.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/transaction.go b/models/transaction.go index 5973aeea8..d8d900ad5 100644 --- a/models/transaction.go +++ b/models/transaction.go @@ -207,7 +207,7 @@ func decodeTransactionEvent( if len(encodedLogs) > 0 { err = rlp.Decode(bytes.NewReader(encodedLogs), &logs) if err != nil { - return nil, nil, fmt.Errorf("failed to RLP-decode receipt [%x]: %w", encodedLogs, err) + return nil, nil, fmt.Errorf("failed to RLP-decode transaction logs [%x]: %w", encodedLogs, err) } } From 0a407df44019dc07dc0eea9c0c09499c75903a81 Mon Sep 17 00:00:00 2001 From: "Gregor G." <75445744+sideninja@users.noreply.github.com> Date: Fri, 19 Jul 2024 13:17:30 +0200 Subject: [PATCH 5/5] Update models/transaction.go Co-authored-by: Ardit Marku --- models/transaction.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/transaction.go b/models/transaction.go index d8d900ad5..97304104c 100644 --- a/models/transaction.go +++ b/models/transaction.go @@ -200,7 +200,7 @@ func decodeTransactionEvent( encodedLogs, err := hex.DecodeString(txEvent.Logs) if err != nil { - return nil, nil, fmt.Errorf("failed to hex decode receipt [%s]: %w", txEvent.Logs, err) + return nil, nil, fmt.Errorf("failed to hex decode transaction logs [%s]: %w", txEvent.Logs, err) } var logs []*gethTypes.Log