diff --git a/pkg/innerring/innerring.go b/pkg/innerring/innerring.go index 706bbd1dfe..d49598fcbf 100644 --- a/pkg/innerring/innerring.go +++ b/pkg/innerring/innerring.go @@ -112,6 +112,12 @@ const ( // extra blocks to overlap two deposits, we do that to make sure that // there won't be any blocks without deposited assets in notary contract. notaryExtraBlocks = 100 + // amount of tries before notary deposit timeout. + notaryDepositTimeout = 100 +) + +var ( + errDepositTimeout = errors.New("notary deposit didn't appeared in the network") ) // Start runs all event providers. @@ -133,6 +139,14 @@ func (s *Server) Start(ctx context.Context, intError chan<- error) error { return err } + // wait a bit for notary contract deposit + s.log.Info("waiting to accept notary deposit") + + err = s.awaitNotaryDeposit(ctx) + if err != nil { + return err + } + // vote for sidechain validator if it is prepared in config err = s.voteForSidechainValidator(s.predefinedValidators) if err != nil { @@ -739,3 +753,27 @@ func (s *Server) depositNotary() error { s.notaryDuration+notaryExtraBlocks, ) } + +func (s *Server) awaitNotaryDeposit(ctx context.Context) error { + for i := 0; i < notaryDepositTimeout; i++ { + select { + case <-ctx.Done(): + return nil + default: + } + + deposit, err := s.morphClient.GetNotaryDeposit() + if err != nil { + return errors.Wrap(err, "can't get notary deposit") + } + + if deposit > 0 { + return nil + } + + s.log.Info("empty notary deposit, waiting one more block") + s.morphClient.Wait(ctx, 1) + } + + return errDepositTimeout +} diff --git a/pkg/morph/client/client.go b/pkg/morph/client/client.go index 27398bf025..c2329e9e06 100644 --- a/pkg/morph/client/client.go +++ b/pkg/morph/client/client.go @@ -209,6 +209,9 @@ func toStackParameter(value interface{}) (sc.Parameter, error) { result.Value = arr case string: result.Type = sc.StringType + case util.Uint160: + result.Type = sc.ByteArrayType + result.Value = v.BytesBE() default: return result, errors.Errorf("chain/client: unsupported parameter %v", value) } diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index 51c853828a..c290c67829 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -46,12 +46,16 @@ const ( defaultNotaryRoundTime = 100 defaultNotaryFallbackTime = 40 - innerRingListMethod = "innerRingList" + innerRingListMethod = "innerRingList" + notaryBalanceOfMethod = "balanceOf" + + notaryBalanceErrMsg = "can't fetch notary balance" ) var ( errNotaryNotEnabled = errors.New("notary support was not enabled on this client") errInvalidIR = errors.New("invalid inner ring list from netmap contract") + errUnexpectedItems = errors.New("invalid number of NEO VM arguments on stack") ) func defaultNotaryConfig() *notaryCfg { @@ -126,6 +130,32 @@ func (c *Client) DepositNotary(amount fixedn.Fixed8, delta uint32) error { return nil } +// GetNotaryDeposit returns deposit of client's account in notary contract. +// Notary support should be enabled in client to use this function. +func (c *Client) GetNotaryDeposit() (int64, error) { + if c.notary == nil { + return 0, errNotaryNotEnabled + } + + sh := c.acc.PrivateKey().PublicKey().GetScriptHash() + + items, err := c.TestInvoke(c.notary.notary, notaryBalanceOfMethod, sh) + if err != nil { + return 0, errors.Wrap(err, notaryBalanceErrMsg) + } + + if len(items) != 1 { + return 0, errors.Wrap(errUnexpectedItems, notaryBalanceErrMsg) + } + + bigIntDeposit, err := items[0].TryInteger() + if err != nil { + return 0, errors.Wrap(err, notaryBalanceErrMsg) + } + + return bigIntDeposit.Int64(), nil +} + // Invoke invokes contract method by sending tx to notary contract in // blockchain. Fallback tx is a `RET`. Notary support should be enabled // in client to use this function.