From 1fe7736d921a06411f8076cedb8edf68519aca62 Mon Sep 17 00:00:00 2001 From: Airat Arifullin Date: Wed, 24 Jan 2024 15:55:04 +0300 Subject: [PATCH] [#925] morph: Introduce switch rpc guarded rpc actor * Introduce switch rpc guarded rpc actor in morph client to prevent using invalidated rpc actor when RPC switch happens. * Initialize NewContractStorage with SwitchRPCGuardedActor. Signed-off-by: Airat Arifullin --- cmd/frostfs-node/config.go | 2 +- pkg/morph/client/actor.go | 120 +++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 pkg/morph/client/actor.go diff --git a/cmd/frostfs-node/config.go b/cmd/frostfs-node/config.go index ffe49a7ef..1b3e094d9 100644 --- a/cmd/frostfs-node/config.go +++ b/cmd/frostfs-node/config.go @@ -1061,7 +1061,7 @@ func initAccessPolicyEngine(_ context.Context, c *cfg) { } morphRuleStorage := policy_client.NewContractStorage( - c.cfgMorph.client.GetActor(), + client.NewSwitchRPCGuardedActor(c.cfgMorph.client), c.cfgObject.cfgAccessPolicyEngine.policyContractHash) ape := newAccessPolicyEngine(morphRuleStorage, localOverrideDB) diff --git a/pkg/morph/client/actor.go b/pkg/morph/client/actor.go new file mode 100644 index 000000000..ea6bc974c --- /dev/null +++ b/pkg/morph/client/actor.go @@ -0,0 +1,120 @@ +package client + +import ( + "github.com/nspcc-dev/neo-go/pkg/config/netmode" + "github.com/nspcc-dev/neo-go/pkg/core/transaction" + "github.com/nspcc-dev/neo-go/pkg/neorpc/result" + "github.com/nspcc-dev/neo-go/pkg/rpcclient/actor" + "github.com/nspcc-dev/neo-go/pkg/util" +) + +type actorProvider interface { + GetActor() *actor.Actor +} + +// Client switches an established connection with neo-go if it is broken. +// This leads to an invalidation of an rpc actor within Client. That means the +// components that are initilized with the rpc actor may unintentionally use +// it when it is already invalidated. SwitchRPCGuardedActor is used to prevent +// this situation, getting the rpc actor from Client. +type SwitchRPCGuardedActor struct { + actorProvider actorProvider +} + +func NewSwitchRPCGuardedActor(c *Client) *SwitchRPCGuardedActor { + return &SwitchRPCGuardedActor{ + actorProvider: c, + } +} + +func (a *SwitchRPCGuardedActor) Call(contract util.Uint160, operation string, params ...any) (*result.Invoke, error) { + return a.actorProvider.GetActor().Call(contract, operation, params...) +} + +func (a *SwitchRPCGuardedActor) CalculateNetworkFee(tx *transaction.Transaction) (int64, error) { + return a.actorProvider.GetActor().CalculateNetworkFee(tx) +} + +func (a *SwitchRPCGuardedActor) CalculateValidUntilBlock() (uint32, error) { + return a.actorProvider.GetActor().CalculateValidUntilBlock() +} + +func (a *SwitchRPCGuardedActor) GetBlockCount() (uint32, error) { + return a.actorProvider.GetActor().GetBlockCount() +} + +func (a *SwitchRPCGuardedActor) GetNetwork() netmode.Magic { + return a.actorProvider.GetActor().GetNetwork() +} + +func (a *SwitchRPCGuardedActor) GetVersion() result.Version { + return a.actorProvider.GetActor().GetVersion() +} + +func (a *SwitchRPCGuardedActor) MakeCall(contract util.Uint160, method string, params ...any) (*transaction.Transaction, error) { + return a.actorProvider.GetActor().MakeCall(contract, method, params...) +} + +func (a *SwitchRPCGuardedActor) MakeRun(script []byte) (*transaction.Transaction, error) { + return a.actorProvider.GetActor().MakeRun(script) +} + +func (a *SwitchRPCGuardedActor) MakeTunedCall(contract util.Uint160, method string, attrs []transaction.Attribute, txHook actor.TransactionCheckerModifier, params ...any) (*transaction.Transaction, error) { + return a.actorProvider.GetActor().MakeTunedCall(contract, method, attrs, txHook, params...) +} + +func (a *SwitchRPCGuardedActor) MakeTunedRun(script []byte, attrs []transaction.Attribute, txHook actor.TransactionCheckerModifier) (*transaction.Transaction, error) { + return a.actorProvider.GetActor().MakeTunedRun(script, attrs, txHook) +} + +func (a *SwitchRPCGuardedActor) MakeUncheckedRun(script []byte, sysfee int64, attrs []transaction.Attribute, txHook actor.TransactionModifier) (*transaction.Transaction, error) { + return a.actorProvider.GetActor().MakeUncheckedRun(script, sysfee, attrs, txHook) +} + +func (a *SwitchRPCGuardedActor) MakeUnsignedCall(contract util.Uint160, method string, attrs []transaction.Attribute, params ...any) (*transaction.Transaction, error) { + return a.actorProvider.GetActor().MakeUnsignedCall(contract, method, attrs, params...) +} + +func (a *SwitchRPCGuardedActor) MakeUnsignedRun(script []byte, attrs []transaction.Attribute) (*transaction.Transaction, error) { + return a.actorProvider.GetActor().MakeUnsignedRun(script, attrs) +} + +func (a *SwitchRPCGuardedActor) MakeUnsignedUncheckedRun(script []byte, sysFee int64, attrs []transaction.Attribute) (*transaction.Transaction, error) { + return a.actorProvider.GetActor().MakeUnsignedUncheckedRun(script, sysFee, attrs) +} + +func (a *SwitchRPCGuardedActor) Send(tx *transaction.Transaction) (util.Uint256, uint32, error) { + return a.actorProvider.GetActor().Send(tx) +} + +func (a *SwitchRPCGuardedActor) SendCall(contract util.Uint160, method string, params ...any) (util.Uint256, uint32, error) { + return a.actorProvider.GetActor().SendCall(contract, method, params...) +} + +func (a *SwitchRPCGuardedActor) SendRun(script []byte) (util.Uint256, uint32, error) { + return a.actorProvider.GetActor().SendRun(script) +} + +func (a *SwitchRPCGuardedActor) SendTunedCall(contract util.Uint160, method string, attrs []transaction.Attribute, txHook actor.TransactionCheckerModifier, params ...any) (util.Uint256, uint32, error) { + return a.actorProvider.GetActor().SendTunedCall(contract, method, attrs, txHook, params...) +} + +func (a *SwitchRPCGuardedActor) SendTunedRun(script []byte, attrs []transaction.Attribute, txHook actor.TransactionCheckerModifier) (util.Uint256, uint32, error) { + return a.actorProvider.GetActor().SendTunedRun(script, attrs, txHook) +} + +func (a *SwitchRPCGuardedActor) SendUncheckedRun(script []byte, sysfee int64, attrs []transaction.Attribute, txHook actor.TransactionModifier) (util.Uint256, uint32, error) { + return a.actorProvider.GetActor().SendUncheckedRun(script, sysfee, attrs, txHook) +} + +func (a *SwitchRPCGuardedActor) Sender() util.Uint160 { + return a.actorProvider.GetActor().Sender() +} + +func (a *SwitchRPCGuardedActor) Sign(tx *transaction.Transaction) error { + return a.actorProvider.GetActor().Sign(tx) +} + +func (a *SwitchRPCGuardedActor) SignAndSend(tx *transaction.Transaction) (util.Uint256, uint32, error) { + return a.actorProvider.GetActor().SignAndSend(tx) +}