[#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 <alexey@nspcc.ru>
This commit is contained in:
Alex Vanin 2021-04-20 18:16:40 +03:00 committed by Alex Vanin
parent dd1ace12f7
commit bd65e41257
4 changed files with 56 additions and 16 deletions

View file

@ -58,6 +58,7 @@ func defaultConfiguration(cfg *viper.Viper) {
cfg.SetDefault("mainnet.endpoint.client", "") cfg.SetDefault("mainnet.endpoint.client", "")
cfg.SetDefault("mainnet.endpoint.notification", "") cfg.SetDefault("mainnet.endpoint.notification", "")
cfg.SetDefault("mainnet.dial_timeout", "10s") cfg.SetDefault("mainnet.dial_timeout", "10s")
cfg.SetDefault("mainnet.notary_deposit", true)
cfg.SetDefault("key", "") // inner ring node key cfg.SetDefault("key", "") // inner ring node key
@ -67,6 +68,7 @@ func defaultConfiguration(cfg *viper.Viper) {
cfg.SetDefault("contracts.container", "") cfg.SetDefault("contracts.container", "")
cfg.SetDefault("contracts.audit", "") cfg.SetDefault("contracts.audit", "")
cfg.SetDefault("contracts.proxy", "") cfg.SetDefault("contracts.proxy", "")
cfg.SetDefault("contracts.processing", "")
cfg.SetDefault("contracts.reputation", "") cfg.SetDefault("contracts.reputation", "")
// alphabet contracts // alphabet contracts
cfg.SetDefault("contracts.alphabet.amount", 7) cfg.SetDefault("contracts.alphabet.amount", 7)

View file

@ -48,7 +48,7 @@ type (
notaryDepositArgs struct { notaryDepositArgs struct {
l *zap.Logger l *zap.Logger
depositor func() (util.Uint256, error) depositor func() (util.Uint256, util.Uint256, error)
notaryDuration uint32 // in blocks notaryDuration uint32 // in blocks
} }
@ -145,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

@ -59,6 +59,7 @@ type (
notaryDepositAmount fixedn.Fixed8 notaryDepositAmount fixedn.Fixed8
notaryDuration uint32 notaryDuration uint32
notaryMainDeposit bool
// internal variables // internal variables
key *ecdsa.PrivateKey key *ecdsa.PrivateKey
@ -93,6 +94,7 @@ type (
container util.Uint160 // in morph container util.Uint160 // in morph
audit util.Uint160 // in morph audit util.Uint160 // in morph
proxy util.Uint160 // in morph proxy util.Uint160 // in morph
processing util.Uint160 // in mainnet
reputation util.Uint160 // in morph reputation util.Uint160 // in morph
alphabet alphabetContracts // 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 // make an initial deposit to notary contract to enable it
txHash, err := s.depositNotary() mainTx, sideTx, err := s.depositNotary()
if err != nil { if err != nil {
return err return err
} }
@ -146,7 +148,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, txHash) err = s.awaitNotaryDeposit(ctx, mainTx, sideTx)
if err != nil { if err != nil {
return err return err
} }
@ -268,10 +270,8 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
return nil, err return nil, err
} }
err = server.morphClient.EnableNotarySupport( // enable notary support in the client
server.contracts.proxy, err = server.morphClient.EnableNotarySupport(server.contracts.proxy)
server.contracts.netmap,
)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -299,6 +299,15 @@ func New(ctx context.Context, log *zap.Logger, cfg *viper.Viper) (*Server, error
if err != nil { if err != nil {
return nil, err 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) 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 // initialize notary deposit timer
server.notaryDepositAmount = fixedn.Fixed8(cfg.GetInt64("notary.deposit_amount")) server.notaryDepositAmount = fixedn.Fixed8(cfg.GetInt64("notary.deposit_amount"))
server.notaryDuration = cfg.GetUint32("timers.notary") server.notaryDuration = cfg.GetUint32("timers.notary")
server.notaryMainDeposit = cfg.GetBool("mainnet.notary_deposit")
notaryTimer := newNotaryDepositTimer(&notaryDepositArgs{ notaryTimer := newNotaryDepositTimer(&notaryDepositArgs{
l: log, l: log,
@ -681,6 +691,7 @@ func parseContracts(cfg *viper.Viper) (*contracts, error) {
containerContractStr := cfg.GetString("contracts.container") containerContractStr := cfg.GetString("contracts.container")
auditContractStr := cfg.GetString("contracts.audit") auditContractStr := cfg.GetString("contracts.audit")
proxyContractStr := cfg.GetString("contracts.proxy") proxyContractStr := cfg.GetString("contracts.proxy")
processingContractStr := cfg.GetString("contracts.processing")
reputationContractStr := cfg.GetString("contracts.reputation") reputationContractStr := cfg.GetString("contracts.reputation")
result.netmap, err = util.Uint160DecodeStringLE(netmapContractStr) 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") 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) result.reputation, err = util.Uint160DecodeStringLE(reputationContractStr)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "ir: can't read reputation script-hash") 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) { func (s *Server) depositNotary() (mainTx, sideTx util.Uint256, err error) {
return s.morphClient.DepositNotary( if s.notaryMainDeposit {
mainTx, err = s.mainnetClient.DepositNotary(
s.notaryDepositAmount, s.notaryDepositAmount,
s.notaryDuration+notaryExtraBlocks, s.notaryDuration+notaryExtraBlocks,
) )
if err != nil {
return
}
} }
func (s *Server) awaitNotaryDeposit(ctx context.Context, txHash util.Uint256) error { sideTx, err = s.morphClient.DepositNotary(
s.notaryDepositAmount,
s.notaryDuration+notaryExtraBlocks,
)
return
}
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++ { for i := 0; i < notaryDepositTimeout; i++ {
select { select {
case <-ctx.Done(): case <-ctx.Done():
@ -832,7 +871,7 @@ func (s *Server) awaitNotaryDeposit(ctx context.Context, txHash util.Uint256) er
default: default:
} }
ok, err := s.morphClient.TxHalt(txHash) ok, err := cli.TxHalt(txHash)
if err == nil { if err == nil {
if ok { if ok {
return nil return nil
@ -840,8 +879,7 @@ func (s *Server) awaitNotaryDeposit(ctx context.Context, txHash util.Uint256) er
return errDepositFail return errDepositFail
} }
s.log.Info("notary tx is not yet persisted, waiting one more block") cli.Wait(ctx, 1)
s.morphClient.Wait(ctx, 1)
} }
return errDepositTimeout return errDepositTimeout

View file

@ -36,7 +36,7 @@ func CashOutCheque(cli *client.Client, con util.Uint160, p *ChequeParams) error
return client.ErrNilClient return client.ErrNilClient
} }
return cli.Invoke(con, extraFee, chequeMethod, return cli.NotaryInvoke(con, chequeMethod,
p.ID, p.ID,
p.User.BytesBE(), p.User.BytesBE(),
p.Amount, p.Amount,
@ -50,5 +50,5 @@ func AlphabetUpdate(cli *client.Client, con util.Uint160, id []byte, list keys.P
return client.ErrNilClient return client.ErrNilClient
} }
return cli.Invoke(con, extraFee, alphabetUpdateMethod, id, list) return cli.NotaryInvoke(con, alphabetUpdateMethod, id, list)
} }