[#457] innerring: wait until notary tx persists on chain

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2021-04-27 14:07:06 +03:00 committed by Alex Vanin
parent 60d74bce67
commit 5b85519f20
4 changed files with 31 additions and 18 deletions

View file

@ -1,6 +1,7 @@
package innerring package innerring
import ( 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/alphabet"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/netmap"
"github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement" "github.com/nspcc-dev/neofs-node/pkg/innerring/processors/settlement"
@ -47,7 +48,7 @@ type (
notaryDepositArgs struct { notaryDepositArgs struct {
l *zap.Logger l *zap.Logger
depositor func() error depositor func() (util.Uint256, error)
notaryDuration uint32 // in blocks notaryDuration uint32 // in blocks
} }
@ -144,7 +145,7 @@ func newNotaryDepositTimer(args *notaryDepositArgs) *timer.BlockTimer {
return timer.NewBlockTimer( return timer.NewBlockTimer(
timer.StaticBlockMeter(args.notaryDuration), timer.StaticBlockMeter(args.notaryDuration),
func() { func() {
err := args.depositor() _, err := args.depositor()
if err != nil { if err != nil {
args.l.Warn("can't deposit notary contract", args.l.Warn("can't deposit notary contract",
zap.String("error", err.Error())) zap.String("error", err.Error()))

View file

@ -121,6 +121,7 @@ const (
var ( var (
errDepositTimeout = errors.New("notary deposit didn't appeared in the network") errDepositTimeout = errors.New("notary deposit didn't appeared in the network")
errDepositFail = errors.New("notary tx has faulted")
) )
// Start runs all event providers. // 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 // make an initial deposit to notary contract to enable it
err = s.depositNotary() txHash, err := s.depositNotary()
if err != nil { if err != nil {
return err return err
} }
@ -145,7 +146,7 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) error {
// wait a bit for notary contract deposit // wait a bit for notary contract deposit
s.log.Info("waiting to accept notary deposit") s.log.Info("waiting to accept notary deposit")
err = s.awaitNotaryDeposit(ctx) err = s.awaitNotaryDeposit(ctx, txHash)
if err != nil { if err != nil {
return err 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( return s.morphClient.DepositNotary(
s.notaryDepositAmount, s.notaryDepositAmount,
s.notaryDuration+notaryExtraBlocks, 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++ { for i := 0; i < notaryDepositTimeout; i++ {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -819,16 +820,15 @@ func (s *Server) awaitNotaryDeposit(ctx context.Context) error {
default: default:
} }
deposit, err := s.morphClient.GetNotaryDeposit() ok, err := s.morphClient.TxHalt(txHash)
if err != nil { if err == nil {
return errors.Wrap(err, "can't get notary deposit") if ok {
return nil
}
return errDepositFail
} }
if deposit > 0 { s.log.Info("notary tx is not yet persisted, waiting one more block")
return nil
}
s.log.Info("empty notary deposit, waiting one more block")
s.morphClient.Wait(ctx, 1) s.morphClient.Wait(ctx, 1)
} }

View file

@ -11,7 +11,9 @@ import (
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
"github.com/nspcc-dev/neo-go/pkg/rpc/client" "github.com/nspcc-dev/neo-go/pkg/rpc/client"
sc "github.com/nspcc-dev/neo-go/pkg/smartcontract" 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/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/vm/stackitem"
"github.com/nspcc-dev/neo-go/pkg/wallet" "github.com/nspcc-dev/neo-go/pkg/wallet"
"github.com/nspcc-dev/neofs-node/pkg/util/logger" "github.com/nspcc-dev/neofs-node/pkg/util/logger"
@ -212,6 +214,16 @@ func (c *Client) Committee() (keys.PublicKeys, error) {
return c.client.GetCommittee() 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 // NeoFSAlphabetList returns keys that stored in NeoFS Alphabet role. Main chain
// stores alphabet node keys of inner ring there, however side chain stores both // stores alphabet node keys of inner ring there, however side chain stores both
// alphabet and non alphabet node keys of inner ring. // alphabet and non alphabet node keys of inner ring.

View file

@ -96,14 +96,14 @@ func (c *Client) EnableNotarySupport(proxy, netmap util.Uint160, opts ...NotaryO
// //
// This function must be invoked after `EnableNotarySupport()` otherwise it // This function must be invoked after `EnableNotarySupport()` otherwise it
// throws panic. // 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 { if c.notary == nil {
panic(notaryNotEnabledPanicMsg) panic(notaryNotEnabledPanicMsg)
} }
bc, err := c.client.GetBlockCount() bc, err := c.client.GetBlockCount()
if err != nil { 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( 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)}, []interface{}{c.acc.PrivateKey().GetScriptHash(), int64(bc + delta)},
) )
if err != nil { 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", 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.Uint32("expire_at", bc+delta),
zap.Stringer("tx_hash", txHash.Reverse())) zap.Stringer("tx_hash", txHash.Reverse()))
return nil return txHash, nil
} }
// GetNotaryDeposit returns deposit of client's account in notary contract. // GetNotaryDeposit returns deposit of client's account in notary contract.