diff --git a/pkg/rpc/client/client.go b/pkg/rpc/client/client.go index 62d7612af..4cae3a11a 100644 --- a/pkg/rpc/client/client.go +++ b/pkg/rpc/client/client.go @@ -28,15 +28,16 @@ const ( // Client represents the middleman for executing JSON RPC calls // to remote NEO RPC nodes. type Client struct { - cli *http.Client - endpoint *url.URL - network netmode.Magic - stateRootInHeader bool - initDone bool - ctx context.Context - opts Options - requestF func(*request.Raw) (*response.Raw, error) - cache cache + cli *http.Client + endpoint *url.URL + ctx context.Context + opts Options + requestF func(*request.Raw) (*response.Raw, error) + + // cache stores RPC node related information client is bound to. + // cache is mostly filled in during Init(), but can also be updated + // during regular Client lifecycle. + cache cache } // Options defines options for the RPC client. @@ -56,6 +57,9 @@ type Options struct { // cache stores cache values for the RPC client methods. type cache struct { + initDone bool + network netmode.Magic + stateRootInHeader bool calculateValidUntilBlock calculateValidUntilBlockCache nativeHashes map[string]util.Uint160 } @@ -119,11 +123,11 @@ func (c *Client) Init() error { if err != nil { return fmt.Errorf("failed to get network magic: %w", err) } - c.network = version.Protocol.Network - c.stateRootInHeader = version.Protocol.StateRootInHeader + c.cache.network = version.Protocol.Network + c.cache.stateRootInHeader = version.Protocol.StateRootInHeader if version.Protocol.MillisecondsPerBlock == 0 { - c.network = version.Magic - c.stateRootInHeader = version.StateRootInHeader + c.cache.network = version.Magic + c.cache.stateRootInHeader = version.StateRootInHeader } neoContractHash, err := c.GetContractStateByAddressOrName(nativenames.Neo) if err != nil { @@ -140,7 +144,7 @@ func (c *Client) Init() error { return fmt.Errorf("failed to get Policy contract scripthash: %w", err) } c.cache.nativeHashes[nativenames.Policy] = policyContractHash.Hash - c.initDone = true + c.cache.initDone = true return nil } diff --git a/pkg/rpc/client/nep11.go b/pkg/rpc/client/nep11.go index 1a744e435..d9f759b5d 100644 --- a/pkg/rpc/client/nep11.go +++ b/pkg/rpc/client/nep11.go @@ -46,7 +46,7 @@ func (c *Client) NEP11TokenInfo(tokenHash util.Uint160) (*wallet.Token, error) { // given account and sends it to the network returning just a hash of it. func (c *Client) TransferNEP11(acc *wallet.Account, to util.Uint160, tokenHash util.Uint160, tokenID string, data interface{}, gas int64, cosigners []SignerAccount) (util.Uint256, error) { - if !c.initDone { + if !c.cache.initDone { return util.Uint256{}, errNetworkNotInitialized } tx, err := c.CreateNEP11TransferTx(acc, tokenHash, gas, cosigners, to, tokenID, data) @@ -144,7 +144,7 @@ func (c *Client) NEP11NDOwnerOf(tokenHash util.Uint160, tokenID []byte) (util.Ui // sends it to the network returning just a hash of it. func (c *Client) TransferNEP11D(acc *wallet.Account, to util.Uint160, tokenHash util.Uint160, amount int64, tokenID []byte, data interface{}, gas int64, cosigners []SignerAccount) (util.Uint256, error) { - if !c.initDone { + if !c.cache.initDone { return util.Uint256{}, errNetworkNotInitialized } from, err := address.StringToUint160(acc.Address) diff --git a/pkg/rpc/client/nep17.go b/pkg/rpc/client/nep17.go index ee7685c20..bd296b854 100644 --- a/pkg/rpc/client/nep17.go +++ b/pkg/rpc/client/nep17.go @@ -142,7 +142,7 @@ func (c *Client) CreateTxFromScript(script []byte, acc *wallet.Account, sysFee, // impossible (e.g. due to locked cosigner's account) an error is returned. func (c *Client) TransferNEP17(acc *wallet.Account, to util.Uint160, token util.Uint160, amount int64, gas int64, data interface{}, cosigners []SignerAccount) (util.Uint256, error) { - if !c.initDone { + if !c.cache.initDone { return util.Uint256{}, errNetworkNotInitialized } @@ -156,7 +156,7 @@ func (c *Client) TransferNEP17(acc *wallet.Account, to util.Uint160, token util. // MultiTransferNEP17 is similar to TransferNEP17, buf allows to have multiple recipients. func (c *Client) MultiTransferNEP17(acc *wallet.Account, gas int64, recipients []TransferTarget, cosigners []SignerAccount) (util.Uint256, error) { - if !c.initDone { + if !c.cache.initDone { return util.Uint256{}, errNetworkNotInitialized } diff --git a/pkg/rpc/client/policy.go b/pkg/rpc/client/policy.go index e8644a025..358d2bfe6 100644 --- a/pkg/rpc/client/policy.go +++ b/pkg/rpc/client/policy.go @@ -10,7 +10,7 @@ import ( // GetFeePerByte invokes `getFeePerByte` method on a native Policy contract. func (c *Client) GetFeePerByte() (int64, error) { - if !c.initDone { + if !c.cache.initDone { return 0, errNetworkNotInitialized } return c.invokeNativePolicyMethod("getFeePerByte") @@ -18,7 +18,7 @@ func (c *Client) GetFeePerByte() (int64, error) { // GetExecFeeFactor invokes `getExecFeeFactor` method on a native Policy contract. func (c *Client) GetExecFeeFactor() (int64, error) { - if !c.initDone { + if !c.cache.initDone { return 0, errNetworkNotInitialized } return c.invokeNativePolicyMethod("getExecFeeFactor") @@ -26,7 +26,7 @@ func (c *Client) GetExecFeeFactor() (int64, error) { // GetStoragePrice invokes `getStoragePrice` method on a native Policy contract. func (c *Client) GetStoragePrice() (int64, error) { - if !c.initDone { + if !c.cache.initDone { return 0, errNetworkNotInitialized } return c.invokeNativePolicyMethod("getStoragePrice") @@ -43,7 +43,7 @@ func (c *Client) GetMaxNotValidBeforeDelta() (int64, error) { // invokeNativePolicy method invokes Get* method on a native Policy contract. func (c *Client) invokeNativePolicyMethod(operation string) (int64, error) { - if !c.initDone { + if !c.cache.initDone { return 0, errNetworkNotInitialized } return c.invokeNativeGetMethod(c.cache.nativeHashes[nativenames.Policy], operation) @@ -63,7 +63,7 @@ func (c *Client) invokeNativeGetMethod(hash util.Uint160, operation string) (int // IsBlocked invokes `isBlocked` method on native Policy contract. func (c *Client) IsBlocked(hash util.Uint160) (bool, error) { - if !c.initDone { + if !c.cache.initDone { return false, errNetworkNotInitialized } result, err := c.InvokeFunction(c.cache.nativeHashes[nativenames.Policy], "isBlocked", []smartcontract.Parameter{{ diff --git a/pkg/rpc/client/rpc.go b/pkg/rpc/client/rpc.go index 086876070..41aed20d8 100644 --- a/pkg/rpc/client/rpc.go +++ b/pkg/rpc/client/rpc.go @@ -94,7 +94,7 @@ func (c *Client) getBlock(params request.RawParams) (*block.Block, error) { err error b *block.Block ) - if !c.initDone { + if !c.cache.initDone { return nil, errNetworkNotInitialized } if err = c.performRequest("getblock", params, &resp); err != nil { @@ -127,7 +127,7 @@ func (c *Client) getBlockVerbose(params request.RawParams) (*result.Block, error resp = &result.Block{} err error ) - if !c.initDone { + if !c.cache.initDone { return nil, errNetworkNotInitialized } if err = c.performRequest("getblock", params, resp); err != nil { @@ -157,7 +157,7 @@ func (c *Client) GetBlockHeader(hash util.Uint256) (*block.Header, error) { resp []byte h *block.Header ) - if !c.initDone { + if !c.cache.initDone { return nil, errNetworkNotInitialized } if err := c.performRequest("getblockheader", params, &resp); err != nil { @@ -407,7 +407,7 @@ func (c *Client) GetRawTransaction(hash util.Uint256) (*transaction.Transaction, resp []byte err error ) - if !c.initDone { + if !c.cache.initDone { return nil, errNetworkNotInitialized } if err = c.performRequest("getrawtransaction", params, &resp); err != nil { @@ -430,7 +430,7 @@ func (c *Client) GetRawTransactionVerbose(hash util.Uint256) (*result.Transactio resp = &result.TransactionOutputRaw{} err error ) - if !c.initDone { + if !c.cache.initDone { return nil, errNetworkNotInitialized } if err = c.performRequest("getrawtransaction", params, resp); err != nil { @@ -771,7 +771,7 @@ func getSigners(sender *wallet.Account, cosigners []SignerAccount) ([]transactio // Note: client should be initialized before SignAndPushP2PNotaryRequest call. func (c *Client) SignAndPushP2PNotaryRequest(mainTx *transaction.Transaction, fallbackScript []byte, fallbackSysFee int64, fallbackNetFee int64, fallbackValidFor uint32, acc *wallet.Account) (*payload.P2PNotaryRequest, error) { var err error - if !c.initDone { + if !c.cache.initDone { return nil, errNetworkNotInitialized } notaryHash, err := c.GetNativeContractHash(nativenames.Notary) @@ -991,12 +991,12 @@ func (c *Client) AddNetworkFee(tx *transaction.Transaction, extraFee int64, accs // GetNetwork returns the network magic of the RPC node client connected to. func (c *Client) GetNetwork() netmode.Magic { - return c.network + return c.cache.network } // StateRootInHeader returns true if state root is contained in block header. func (c *Client) StateRootInHeader() bool { - return c.stateRootInHeader + return c.cache.stateRootInHeader } // GetNativeContractHash returns native contract hash by its name. diff --git a/pkg/rpc/client/rpc_test.go b/pkg/rpc/client/rpc_test.go index 51c008785..ee1b6c71b 100644 --- a/pkg/rpc/client/rpc_test.go +++ b/pkg/rpc/client/rpc_test.go @@ -1914,7 +1914,7 @@ func TestGetNetwork(t *testing.T) { } // network was not initialised require.Equal(t, netmode.Magic(0), c.GetNetwork()) - require.Equal(t, false, c.initDone) + require.Equal(t, false, c.cache.initDone) }) t.Run("good", func(t *testing.T) { diff --git a/pkg/rpc/client/wsclient_test.go b/pkg/rpc/client/wsclient_test.go index 2f43e77b6..f625a99b0 100644 --- a/pkg/rpc/client/wsclient_test.go +++ b/pkg/rpc/client/wsclient_test.go @@ -143,7 +143,7 @@ func TestWSClientEvents(t *testing.T) { wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{}) require.NoError(t, err) - wsc.network = netmode.UnitTestNet + wsc.cache.network = netmode.UnitTestNet for range events { select { case _, ok = <-wsc.Notifications: @@ -315,7 +315,7 @@ func TestWSFilteredSubscriptions(t *testing.T) { })) wsc, err := NewWS(context.TODO(), httpURLtoWS(srv.URL), Options{}) require.NoError(t, err) - wsc.network = netmode.UnitTestNet + wsc.cache.network = netmode.UnitTestNet c.clientCode(t, wsc) wsc.Close() })