From 5b85519f20f12f122a9ebec25209012027d4a28b Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 27 Apr 2021 14:07:06 +0300 Subject: [PATCH] [#457] innerring: wait until notary tx persists on chain Signed-off-by: Evgenii Stratonikov --- pkg/innerring/blocktimer.go | 5 +++-- pkg/innerring/innerring.go | 24 ++++++++++++------------ pkg/morph/client/client.go | 12 ++++++++++++ pkg/morph/client/notary.go | 8 ++++---- 4 files changed, 31 insertions(+), 18 deletions(-) diff --git a/pkg/innerring/blocktimer.go b/pkg/innerring/blocktimer.go index 2357b0f6..cd3c0837 100644 --- a/pkg/innerring/blocktimer.go +++ b/pkg/innerring/blocktimer.go @@ -1,6 +1,7 @@ package innerring import ( + "github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/alphabet" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement" @@ -47,7 +48,7 @@ type ( notaryDepositArgs struct { l *zap.Logger - depositor func() error + depositor func() (util.Uint256, error) notaryDuration uint32 // in blocks } @@ -144,7 +145,7 @@ func newNotaryDepositTimer(args *notaryDepositArgs) *timer.BlockTimer { return timer.NewBlockTimer( timer.StaticBlockMeter(args.notaryDuration), func() { - err := args.depositor() + _, err := args.depositor() if err != nil { args.l.Warn("can't deposit notary contract", zap.String("error", err.Error())) diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 0c989c03..bb9560af 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -121,6 +121,7 @@ const ( var ( errDepositTimeout = errors.New("notary deposit didn't appeared in the network") + errDepositFail = errors.New("notary tx has faulted") ) // Start runs all event providers. @@ -137,7 +138,7 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) error { } // make an initial deposit to notary contract to enable it - err = s.depositNotary() + txHash, err := s.depositNotary() if err != nil { return err } @@ -145,7 +146,7 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) error { // wait a bit for notary contract deposit s.log.Info("waiting to accept notary deposit") - err = s.awaitNotaryDeposit(ctx) + err = s.awaitNotaryDeposit(ctx, txHash) if err != nil { return err } @@ -804,14 +805,14 @@ func (s *Server) onlyAlphabetEventHandler(f event.Handler) event.Handler { } } -func (s *Server) depositNotary() error { +func (s *Server) depositNotary() (util.Uint256, error) { return s.morphClient.DepositNotary( s.notaryDepositAmount, s.notaryDuration+notaryExtraBlocks, ) } -func (s *Server) awaitNotaryDeposit(ctx context.Context) error { +func (s *Server) awaitNotaryDeposit(ctx context.Context, txHash util.Uint256) error { for i := 0; i < notaryDepositTimeout; i++ { select { case <-ctx.Done(): @@ -819,16 +820,15 @@ func (s *Server) awaitNotaryDeposit(ctx context.Context) error { default: } - deposit, err := s.morphClient.GetNotaryDeposit() - if err != nil { - return errors.Wrap(err, "can't get notary deposit") + ok, err := s.morphClient.TxHalt(txHash) + if err == nil { + if ok { + return nil + } + return errDepositFail } - if deposit > 0 { - return nil - } - - s.log.Info("empty notary deposit, waiting one more block") + s.log.Info("notary tx is not yet persisted, waiting one more block") s.morphClient.Wait(ctx, 1) } diff --git a/pkg/morph/client/client.go b/pkg/morph/client/client.go index 4e797847..c7bdf462 100644 --- a/pkg/morph/client/client.go +++ b/pkg/morph/client/client.go @@ -11,7 +11,9 @@ import ( "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/rpc/client" sc "github.com/nspcc-dev/neo-go/pkg/smartcontract" + "github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger" "github.com/nspcc-dev/neo-go/pkg/util" + "github.com/nspcc-dev/neo-go/pkg/vm" "github.com/nspcc-dev/neo-go/pkg/vm/stackitem" "github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neofs-node/pkg/util/logger" @@ -212,6 +214,16 @@ func (c *Client) Committee() (keys.PublicKeys, error) { return c.client.GetCommittee() } +// TxHalt returns true if transaction has been successfully executed and persisted. +func (c *Client) TxHalt(h util.Uint256) (bool, error) { + trig := trigger.Application + aer, err := c.client.GetApplicationLog(h, &trig) + if err != nil { + return false, err + } + return len(aer.Executions) > 0 && aer.Executions[0].VMState.HasFlag(vm.HaltState), nil +} + // NeoFSAlphabetList returns keys that stored in NeoFS Alphabet role. Main chain // stores alphabet node keys of inner ring there, however side chain stores both // alphabet and non alphabet node keys of inner ring. diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index 061ad350..6d802f36 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -96,14 +96,14 @@ func (c *Client) EnableNotarySupport(proxy, netmap util.Uint160, opts ...NotaryO // // This function must be invoked after `EnableNotarySupport()` otherwise it // throws panic. -func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) error { +func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) (util.Uint256, error) { if c.notary == nil { panic(notaryNotEnabledPanicMsg) } bc, err := c.client.GetBlockCount() if err != nil { - return errors.Wrap(err, "can't get blockchain height") + return util.Uint256{}, errors.Wrap(err, "can't get blockchain height") } txHash, err := c.client.TransferNEP17( @@ -115,7 +115,7 @@ func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) error { []interface{}{c.acc.PrivateKey().GetScriptHash(), int64(bc + delta)}, ) if err != nil { - return errors.Wrap(err, "can't make notary deposit") + return util.Uint256{}, errors.Wrap(err, "can't make notary deposit") } c.logger.Debug("notary deposit invoke", @@ -123,7 +123,7 @@ func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) error { zap.Uint32("expire_at", bc+delta), zap.Stringer("tx_hash", txHash.Reverse())) - return nil + return txHash, nil } // GetNotaryDeposit returns deposit of client's account in notary contract.