From bd65e41257bed295524b80678cadc34bcca2d957 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Tue, 20 Apr 2021 18:16:40 +0300 Subject: [PATCH] [#486] innerring: Add notary support in main chain client With `mainnet.notary_deposit=false` inner ring will ignore notary deposit \ awaiting routines in the application start, so it can run on the environments without notary support. Signed-off-by: Alex Vanin --- cmd/neofs-ir/defaults.go | 2 ++ pkg/innerring/blocktimer.go | 4 +-- pkg/innerring/innerring.go | 62 ++++++++++++++++++++++++++++------- pkg/innerring/invoke/neofs.go | 4 +-- 4 files changed, 56 insertions(+), 16 deletions(-) diff --git a/cmd/neofs-ir/defaults.go b/cmd/neofs-ir/defaults.go index 6af176227..58079e44a 100644 --- a/cmd/neofs-ir/defaults.go +++ b/cmd/neofs-ir/defaults.go @@ -58,6 +58,7 @@ func defaultConfiguration(cfg *viper.Viper) { cfg.SetDefault("mainnet.endpoint.client", "") cfg.SetDefault("mainnet.endpoint.notification", "") cfg.SetDefault("mainnet.dial_timeout", "10s") + cfg.SetDefault("mainnet.notary_deposit", true) cfg.SetDefault("key", "") // inner ring node key @@ -67,6 +68,7 @@ func defaultConfiguration(cfg *viper.Viper) { cfg.SetDefault("contracts.container", "") cfg.SetDefault("contracts.audit", "") cfg.SetDefault("contracts.proxy", "") + cfg.SetDefault("contracts.processing", "") cfg.SetDefault("contracts.reputation", "") // alphabet contracts cfg.SetDefault("contracts.alphabet.amount", 7) diff --git a/pkg/innerring/blocktimer.go b/pkg/innerring/blocktimer.go index cd3c0837e..3c54a6ece 100644 --- a/pkg/innerring/blocktimer.go +++ b/pkg/innerring/blocktimer.go @@ -48,7 +48,7 @@ type ( notaryDepositArgs struct { l *zap.Logger - depositor func() (util.Uint256, error) + depositor func() (util.Uint256, util.Uint256, error) notaryDuration uint32 // in blocks } @@ -145,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 02a94f285..afcc03fef 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -59,6 +59,7 @@ type ( notaryDepositAmount fixedn.Fixed8 notaryDuration uint32 + notaryMainDeposit bool // internal variables key *ecdsa.PrivateKey @@ -93,6 +94,7 @@ type ( container util.Uint160 // in morph audit util.Uint160 // in morph proxy util.Uint160 // in morph + processing util.Uint160 // in mainnet reputation util.Uint160 // in morph alphabet alphabetContracts // in morph @@ -138,7 +140,7 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) error { } // make an initial deposit to notary contract to enable it - txHash, err := s.depositNotary() + mainTx, sideTx, err := s.depositNotary() if err != nil { return err } @@ -146,7 +148,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, txHash) + err = s.awaitNotaryDeposit(ctx, mainTx, sideTx) if err != nil { return err } @@ -268,10 +270,8 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error return nil, err } - err = server.morphClient.EnableNotarySupport( - server.contracts.proxy, - server.contracts.netmap, - ) + // enable notary support in the client + err = server.morphClient.EnableNotarySupport(server.contracts.proxy) if err != nil { return nil, err } @@ -299,6 +299,15 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error if err != nil { return nil, err } + + // enable notary support in the client + err = server.mainnetClient.EnableNotarySupport( + server.contracts.processing, + client.WithAlphabetSource(server.morphClient.Committee), + ) + if err != nil { + return nil, err + } } server.pubKey = crypto.MarshalPublicKey(&server.key.PublicKey) @@ -626,6 +635,7 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error // initialize notary deposit timer server.notaryDepositAmount = fixedn.Fixed8(cfg.GetInt64("notary.deposit_amount")) server.notaryDuration = cfg.GetUint32("timers.notary") + server.notaryMainDeposit = cfg.GetBool("mainnet.notary_deposit") notaryTimer := newNotaryDepositTimer(¬aryDepositArgs{ l: log, @@ -681,6 +691,7 @@ func parseContracts(cfg *viper.Viper) (*contracts, error) { containerContractStr := cfg.GetString("contracts.container") auditContractStr := cfg.GetString("contracts.audit") proxyContractStr := cfg.GetString("contracts.proxy") + processingContractStr := cfg.GetString("contracts.processing") reputationContractStr := cfg.GetString("contracts.reputation") result.netmap, err = util.Uint160DecodeStringLE(netmapContractStr) @@ -713,6 +724,11 @@ func parseContracts(cfg *viper.Viper) (*contracts, error) { return nil, errors.Wrap(err, "ir: can't read proxy script-hash") } + result.processing, err = util.Uint160DecodeStringLE(processingContractStr) + if err != nil { + return nil, errors.Wrap(err, "ir: can't read processing script-hash") + } + result.reputation, err = util.Uint160DecodeStringLE(reputationContractStr) if err != nil { return nil, errors.Wrap(err, "ir: can't read reputation script-hash") @@ -817,14 +833,37 @@ func (s *Server) onlyAlphabetEventHandler(f event.Handler) event.Handler { } } -func (s *Server) depositNotary() (util.Uint256, error) { - return s.morphClient.DepositNotary( +func (s *Server) depositNotary() (mainTx, sideTx util.Uint256, err error) { + if s.notaryMainDeposit { + mainTx, err = s.mainnetClient.DepositNotary( + s.notaryDepositAmount, + s.notaryDuration+notaryExtraBlocks, + ) + if err != nil { + return + } + } + + sideTx, err = s.morphClient.DepositNotary( s.notaryDepositAmount, s.notaryDuration+notaryExtraBlocks, ) + + return } -func (s *Server) awaitNotaryDeposit(ctx context.Context, txHash util.Uint256) error { +func (s *Server) awaitNotaryDeposit(ctx context.Context, mainTx, sideTx util.Uint256) error { + if s.notaryMainDeposit { + err := awaitNotaryDepositInClient(ctx, s.mainnetClient, mainTx) + if err != nil { + return err + } + } + + return awaitNotaryDepositInClient(ctx, s.morphClient, sideTx) +} + +func awaitNotaryDepositInClient(ctx context.Context, cli *client.Client, txHash util.Uint256) error { for i := 0; i < notaryDepositTimeout; i++ { select { case <-ctx.Done(): @@ -832,7 +871,7 @@ func (s *Server) awaitNotaryDeposit(ctx context.Context, txHash util.Uint256) er default: } - ok, err := s.morphClient.TxHalt(txHash) + ok, err := cli.TxHalt(txHash) if err == nil { if ok { return nil @@ -840,8 +879,7 @@ func (s *Server) awaitNotaryDeposit(ctx context.Context, txHash util.Uint256) er return errDepositFail } - s.log.Info("notary tx is not yet persisted, waiting one more block") - s.morphClient.Wait(ctx, 1) + cli.Wait(ctx, 1) } return errDepositTimeout diff --git a/pkg/innerring/invoke/neofs.go b/pkg/innerring/invoke/neofs.go index 632240120..6794efffb 100644 --- a/pkg/innerring/invoke/neofs.go +++ b/pkg/innerring/invoke/neofs.go @@ -36,7 +36,7 @@ func CashOutCheque(cli *client.Client, con util.Uint160, p *ChequeParams) error return client.ErrNilClient } - return cli.Invoke(con, extraFee, chequeMethod, + return cli.NotaryInvoke(con, chequeMethod, p.ID, p.User.BytesBE(), p.Amount, @@ -50,5 +50,5 @@ func AlphabetUpdate(cli *client.Client, con util.Uint160, id []byte, list keys.P return client.ErrNilClient } - return cli.Invoke(con, extraFee, alphabetUpdateMethod, id, list) + return cli.NotaryInvoke(con, alphabetUpdateMethod, id, list) }