diff --git a/go/common/gethencoding/geth_encoding.go b/go/common/gethencoding/geth_encoding.go index cfc29024d1..4e4d83d7ee 100644 --- a/go/common/gethencoding/geth_encoding.go +++ b/go/common/gethencoding/geth_encoding.go @@ -161,41 +161,50 @@ func ExtractOptionalBlockNumber(params []interface{}, idx int) (*gethrpc.BlockNu // ExtractBlockNumber returns a gethrpc.BlockNumber given an interface{}, errors if unexpected values are used func ExtractBlockNumber(param interface{}) (*gethrpc.BlockNumberOrHash, error) { + var blockNo *gethrpc.BlockNumber + var blockHa *gethcommon.Hash + var reqCanon bool + if param == nil { latest := gethrpc.BlockNumberOrHashWithNumber(gethrpc.LatestBlockNumber) return &latest, nil } - - p, ok := param.(map[string]any) - if !ok { - return nil, fmt.Errorf("invalid block or hash parameter %s", param.(string)) - } - var blockNo *gethrpc.BlockNumber - var blockHa *gethcommon.Hash - var reqCanon bool - if p["blockNumber"] != nil { - b := p["blockNumber"].(string) + blockString, ok := param.(string) + if ok { blockNumber := gethrpc.BlockNumber(0) - err := blockNumber.UnmarshalJSON([]byte(b)) + err := blockNumber.UnmarshalJSON([]byte(blockString)) if err != nil { - return nil, fmt.Errorf("invalid block number %s - %w", b, err) + return nil, fmt.Errorf("invalid block number %s - %w", blockString, err) } blockNo = &blockNumber + } else { + blockAndHash, ok := param.(map[string]any) + if !ok { + return nil, fmt.Errorf("invalid block or hash parameter %s", param.(string)) + } + if blockAndHash["blockNumber"] != nil { + b := blockAndHash["blockNumber"].(string) + blockNumber := gethrpc.BlockNumber(0) + err := blockNumber.UnmarshalJSON([]byte(b)) + if err != nil { + return nil, fmt.Errorf("invalid block number %s - %w", b, err) + } + blockNo = &blockNumber + } + if blockAndHash["blockHash"] != nil { + bh := blockAndHash["blockHash"].(gethcommon.Hash) + blockHa = &bh + } + if blockAndHash["RequireCanonical"] != nil { + reqCanon = blockAndHash["RequireCanonical"].(bool) + } } - if p["blockHash"] != nil { - bh := p["blockHash"].(gethcommon.Hash) - blockHa = &bh - } - if p["RequireCanonical"] != nil { - reqCanon = p["RequireCanonical"].(bool) - } - blockNumber := gethrpc.BlockNumberOrHash{ + + return &gethrpc.BlockNumberOrHash{ BlockNumber: blockNo, BlockHash: blockHa, RequireCanonical: reqCanon, - } - - return &blockNumber, nil + }, nil } // ExtractEthCall extracts the eth_call gethapi.TransactionArgs from an interface{} diff --git a/go/enclave/rpc/TenEthCall.go b/go/enclave/rpc/TenEthCall.go index 129baf4e8a..4b1126d9c2 100644 --- a/go/enclave/rpc/TenEthCall.go +++ b/go/enclave/rpc/TenEthCall.go @@ -14,7 +14,7 @@ import ( func TenCallValidate(reqParams []any, builder *CallBuilder[CallParamsWithBlock, string], _ *EncryptionManager) error { // Parameters are [TransactionArgs, BlockNumber, a few more] - if len(reqParams) != 4 { + if len(reqParams) < 2 && len(reqParams) > 4 { builder.Err = fmt.Errorf("unexpected number of parameters") return nil } diff --git a/go/obsclient/authclient.go b/go/obsclient/authclient.go index 2db0151f61..86c758a00a 100644 --- a/go/obsclient/authclient.go +++ b/go/obsclient/authclient.go @@ -19,14 +19,6 @@ import ( gethlog "github.com/ethereum/go-ethereum/log" ) -const ( - filterKeyBlockHash = "blockHash" - filterKeyFromBlock = "fromBlock" - filterKeyToBlock = "toBlock" - filterKeyAddress = "address" - filterKeyTopics = "topics" -) - // AuthObsClient extends the functionality of the ObsClient for all methods that require encryption when communicating with the enclave // It is created with an EncRPCClient rather than basic RPC client so encryption/decryption is supported // @@ -89,12 +81,16 @@ func (ac *AuthObsClient) GasPrice(ctx context.Context) (*big.Int, error) { func (ac *AuthObsClient) TransactionReceipt(ctx context.Context, txHash gethcommon.Hash) (*types.Receipt, error) { var result responses.ReceiptType + var emptyHash gethcommon.Hash err := ac.rpcClient.CallContext(ctx, &result, rpc.GetTransactionReceipt, txHash) if err != nil { return nil, err } + if result.TxHash != emptyHash { + return &result, nil + } - return &result, nil + return nil, nil } // NonceAt retrieves the nonce for the account registered on this client (due to obscuro privacy restrictions, @@ -125,7 +121,7 @@ func (ac *AuthObsClient) SendTransaction(ctx context.Context, signedTx *types.Tr if err != nil { return err } - + println(result.Hex()) return nil } @@ -142,14 +138,7 @@ func (ac *AuthObsClient) BalanceAt(ctx context.Context, blockNumber *big.Int) (* } func (ac *AuthObsClient) SubscribeFilterLogs(ctx context.Context, filterCriteria filters.FilterCriteria, ch chan common.IDAndLog) (ethereum.Subscription, error) { - filterCriteriaMap := map[string]interface{}{ - filterKeyBlockHash: filterCriteria.BlockHash, - filterKeyFromBlock: filterCriteria.FromBlock, - filterKeyToBlock: filterCriteria.ToBlock, - filterKeyAddress: filterCriteria.Addresses, - filterKeyTopics: filterCriteria.Topics, - } - return ac.rpcClient.Subscribe(ctx, nil, rpc.SubscribeNamespace, ch, rpc.SubscriptionTypeLogs, filterCriteriaMap) + return ac.rpcClient.Subscribe(ctx, nil, rpc.SubscribeNamespace, ch, rpc.SubscriptionTypeLogs, filterCriteria) } func (ac *AuthObsClient) GetLogs(ctx context.Context, filterCriteria common.FilterCriteriaJSON) ([]*types.Log, error) { diff --git a/go/rpc/encrypted_client.go b/go/rpc/encrypted_client.go index 535d15cb93..31efc9a0f2 100644 --- a/go/rpc/encrypted_client.go +++ b/go/rpc/encrypted_client.go @@ -265,6 +265,7 @@ func (c *EncRPCClient) executeSensitiveCall(ctx context.Context, result interfac // We put the raw json in the passed result object. // This works for structs, strings, integers and interface types. err = json.Unmarshal(resultBytes, result) + err = json.Unmarshal(resultBytes, result) if err != nil { return fmt.Errorf("could not populate the response object with the json_rpc result. Cause: %w", err) } diff --git a/integration/common/utils.go b/integration/common/utils.go index f0ff1839ad..369cbb7eb0 100644 --- a/integration/common/utils.go +++ b/integration/common/utils.go @@ -23,7 +23,6 @@ import ( gethcommon "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" - "github.com/ten-protocol/go-ten/go/rpc" ) var _awaitReceiptPollingInterval = 200 * time.Millisecond @@ -49,11 +48,13 @@ func AwaitReceipt(ctx context.Context, client *obsclient.AuthObsClient, txHash g var err error err = retry.Do(func() error { receipt, err = client.TransactionReceipt(ctx, txHash) - if err != nil && !errors.Is(err, rpc.ErrNilResponse) { - // we only retry for a nil "not found" response. This is a different error, so we bail out of the retry loop + if err != nil { return retry.FailFast(err) } - return err + if receipt != nil { + return nil + } + return fmt.Errorf("not found") }, retry.NewTimeoutStrategy(timeout, _awaitReceiptPollingInterval)) if err != nil { return fmt.Errorf("could not retrieve receipt for transaction %s - %w", txHash.Hex(), err) @@ -130,10 +131,12 @@ func PrefundWallets(ctx context.Context, faucetWallet wallet.Wallet, faucetClien wg.Add(1) go func(txHash gethcommon.Hash) { defer wg.Done() + fmt.Printf("get receipt tx: %s\n", txHash) err := AwaitReceipt(ctx, faucetClient, txHash, timeout) if err != nil { panic(fmt.Sprintf("faucet transfer transaction %s unsuccessful. Cause: %s", txHash, err)) } + fmt.Printf("success receipt tx: %s\n", txHash) }(txHash) } wg.Wait() diff --git a/integration/networktest/userwallet/authclient.go b/integration/networktest/userwallet/authclient.go index 3a22bfa763..62ff88ed5e 100644 --- a/integration/networktest/userwallet/authclient.go +++ b/integration/networktest/userwallet/authclient.go @@ -2,7 +2,6 @@ package userwallet import ( "context" - "errors" "fmt" "math/big" "time" @@ -12,7 +11,6 @@ import ( gethlog "github.com/ethereum/go-ethereum/log" "github.com/ten-protocol/go-ten/go/common/retry" "github.com/ten-protocol/go-ten/go/obsclient" - "github.com/ten-protocol/go-ten/go/rpc" "github.com/ten-protocol/go-ten/go/wallet" ) @@ -82,7 +80,7 @@ func (s *AuthClientUser) AwaitReceipt(ctx context.Context, txHash *gethcommon.Ha var err error err = retry.Do(func() error { receipt, err = s.client.TransactionReceipt(ctx, *txHash) - if !errors.Is(err, rpc.ErrNilResponse) { + if err != nil { // nil response means not found. Any other error is unexpected, so we stop polling and fail immediately return retry.FailFast(err) } diff --git a/integration/networktest/userwallet/gateway.go b/integration/networktest/userwallet/gateway.go index a6ca793191..c446124791 100644 --- a/integration/networktest/userwallet/gateway.go +++ b/integration/networktest/userwallet/gateway.go @@ -2,7 +2,6 @@ package userwallet import ( "context" - "errors" "fmt" "math/big" "time" @@ -13,7 +12,6 @@ import ( "github.com/ethereum/go-ethereum/ethclient" gethlog "github.com/ethereum/go-ethereum/log" "github.com/ten-protocol/go-ten/go/common/retry" - "github.com/ten-protocol/go-ten/go/rpc" "github.com/ten-protocol/go-ten/go/wallet" "github.com/ten-protocol/go-ten/tools/walletextension/lib" ) @@ -95,7 +93,7 @@ func (g *GatewayUser) AwaitReceipt(ctx context.Context, txHash *gethcommon.Hash) var err error err = retry.Do(func() error { receipt, err = g.client.TransactionReceipt(ctx, *txHash) - if !errors.Is(err, rpc.ErrNilResponse) { + if err != nil { return retry.FailFast(err) } return err diff --git a/integration/simulation/simulation_full_network_test.go b/integration/simulation/simulation_full_network_test.go index 926f736cd8..046d57c7a4 100644 --- a/integration/simulation/simulation_full_network_test.go +++ b/integration/simulation/simulation_full_network_test.go @@ -29,7 +29,7 @@ func TestFullNetworkMonteCarloSimulation(t *testing.T) { L1EfficiencyThreshold: 0.2, Wallets: wallets, StartPort: integration.StartPortSimulationFullNetwork, - ReceiptTimeout: 20 * time.Second, + ReceiptTimeout: 30 * time.Second, StoppingDelay: 15 * time.Second, NodeWithInboundP2PDisabled: 2, } diff --git a/tools/faucet/faucet/faucet.go b/tools/faucet/faucet/faucet.go index 4efb7c6132..a765d041c7 100644 --- a/tools/faucet/faucet/faucet.go +++ b/tools/faucet/faucet/faucet.go @@ -3,7 +3,6 @@ package faucet import ( "context" "encoding/json" - "errors" "fmt" "math/big" "os" @@ -15,7 +14,6 @@ import ( "github.com/ethereum/go-ethereum/log" tenlog "github.com/ten-protocol/go-ten/go/common/log" "github.com/ten-protocol/go-ten/go/obsclient" - "github.com/ten-protocol/go-ten/go/rpc" "github.com/ten-protocol/go-ten/go/wallet" ) @@ -85,12 +83,12 @@ func (f *Faucet) validateTx(tx *types.Transaction) error { for now := time.Now(); time.Since(now) < _timeout; time.Sleep(time.Second) { receipt, err := f.client.TransactionReceipt(context.Background(), tx.Hash()) if err != nil { - if errors.Is(err, rpc.ErrNilResponse) { - // tx receipt is not available yet - continue - } return fmt.Errorf("could not retrieve transaction receipt in eth_getTransactionReceipt request. Cause: %w", err) } + if receipt == nil { + // tx receipt is not available yet + continue + } txReceiptBytes, err := receipt.MarshalJSON() if err != nil { diff --git a/tools/walletextension/common/constants.go b/tools/walletextension/common/constants.go index 1db463ac90..e872932cde 100644 --- a/tools/walletextension/common/constants.go +++ b/tools/walletextension/common/constants.go @@ -50,7 +50,7 @@ const ( MethodEthSubscription = "eth_subscription" PathVersion = "/version/" DeduplicationBufferSize = 20 - ErrNoViewingKey = "authentication failed" + ErrNoViewingKey = "authentication failed %s" ) var ReaderHeadTimeout = 10 * time.Second diff --git a/tools/walletextension/rpcapi/transaction_api.go b/tools/walletextension/rpcapi/transaction_api.go index 171a1f7b9b..5c53ba8672 100644 --- a/tools/walletextension/rpcapi/transaction_api.go +++ b/tools/walletextension/rpcapi/transaction_api.go @@ -81,28 +81,26 @@ func (s *TransactionAPI) GetRawTransactionByHash(ctx context.Context, hash commo func (s *TransactionAPI) GetTransactionReceipt(ctx context.Context, hash common.Hash) (map[string]interface{}, error) { txRec, err := ExecAuthRPC[map[string]interface{}](ctx, s.we, &ExecCfg{tryUntilAuthorised: true}, "eth_getTransactionReceipt", hash) - if txRec != nil { - return *txRec, err + if err != nil { + return nil, err } - return nil, err + return *txRec, err } func (s *TransactionAPI) SendTransaction(ctx context.Context, args gethapi.TransactionArgs) (common.Hash, error) { - // txRec, err := ExecAuthRPC[common.Hash](ctx, s.we, &ExecCfg{account: args.From}, "eth_sendTransaction", args) - txRec, err := UnauthenticatedTenRPCCall[common.Hash](ctx, s.we, nil, "eth_sendTransaction", args) + txRec, err := ExecAuthRPC[common.Hash](ctx, s.we, &ExecCfg{account: args.From}, "eth_sendTransaction", args) if err != nil { return common.Hash{}, err } if s.we.Config.StoreIncomingTxs { - userIDBytes, err := extractUserId(ctx) - if err != nil { - return common.Hash{}, err - } - tx, err := json.Marshal(args) - if err != nil { - err = s.we.Storage.StoreTransaction(string(tx), userIDBytes) + userIDBytes, _ := extractUserId(ctx) + if len(userIDBytes) > 10 { + tx, err := json.Marshal(args) if err != nil { - s.we.Logger().Error(fmt.Errorf("error storing transaction in the database: %w", err).Error()) + err = s.we.Storage.StoreTransaction(string(tx), userIDBytes) + if err != nil { + s.we.Logger().Error(fmt.Errorf("error storing transaction in the database: %w", err).Error()) + } } } } @@ -120,19 +118,17 @@ func (s *TransactionAPI) FillTransaction(ctx context.Context, args gethapi.Trans } func (s *TransactionAPI) SendRawTransaction(ctx context.Context, input hexutil.Bytes) (common.Hash, error) { - // txRec, err := ExecAuthRPC[common.Hash](ctx, s.we, &ExecCfg{tryAll: true}, "eth_sendRawTransaction", input) - txRec, err := UnauthenticatedTenRPCCall[common.Hash](ctx, s.we, nil, "eth_sendRawTransaction", input) + txRec, err := ExecAuthRPC[common.Hash](ctx, s.we, &ExecCfg{tryAll: true}, "eth_sendRawTransaction", input) if err != nil { return common.Hash{}, err } if s.we.Config.StoreIncomingTxs { userIDBytes, err := extractUserId(ctx) - if err != nil { - return common.Hash{}, err - } - err = s.we.Storage.StoreTransaction(input.String(), userIDBytes) - if err != nil { - s.we.Logger().Error(fmt.Errorf("error storing transaction in the database: %w", err).Error()) + if len(userIDBytes) > 10 { + err = s.we.Storage.StoreTransaction(input.String(), userIDBytes) + if err != nil { + s.we.Logger().Error(fmt.Errorf("error storing transaction in the database: %w", err).Error()) + } } }