[#770] node: Add notary deposit timer

Storage Node needs to have notary deposit
for successful notary request sending.
Add notary deposit on startup(and wait for
its acceptance). Add notary deposit timer,
its config in `morph` section and env vars
for its tuning.

Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
Pavel Karpy 2021-08-25 13:49:59 +03:00 committed by Pavel Karpy
parent e29bcd98e2
commit 722b844aa2
4 changed files with 104 additions and 2 deletions

View file

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/encoding/fixedn"
neogoutil "github.com/nspcc-dev/neo-go/pkg/util" neogoutil "github.com/nspcc-dev/neo-go/pkg/util"
"github.com/nspcc-dev/neofs-api-go/pkg" "github.com/nspcc-dev/neofs-api-go/pkg"
apiclient "github.com/nspcc-dev/neofs-api-go/pkg/client" apiclient "github.com/nspcc-dev/neofs-api-go/pkg/client"
@ -127,6 +128,10 @@ type cfgGRPC struct {
type cfgMorph struct { type cfgMorph struct {
client *client.Client client *client.Client
notaryEnabled bool
notaryDepositAmount fixedn.Fixed8
notaryDepositDuration uint32
disableCache bool disableCache bool
blockTimers []*timer.BlockTimer // all combined timers blockTimers []*timer.BlockTimer // all combined timers

View file

@ -90,6 +90,7 @@ func initApp(c *cfg) {
func bootUp(c *cfg) { func bootUp(c *cfg) {
serveGRPC(c) serveGRPC(c)
bootstrapNode(c) bootstrapNode(c)
makeAndWaitNotaryDeposit(c)
startWorkers(c) startWorkers(c)
startBlockTimers(c) startBlockTimers(c)
} }

View file

@ -2,11 +2,13 @@ package main
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/core/block" "github.com/nspcc-dev/neo-go/pkg/core/block"
"github.com/nspcc-dev/neo-go/pkg/util" "github.com/nspcc-dev/neo-go/pkg/util"
contractsconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/contracts"
mainchainconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/mainchain" mainchainconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/mainchain"
morphconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/morph" morphconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/morph"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap" "github.com/nspcc-dev/neofs-node/pkg/core/netmap"
@ -19,7 +21,18 @@ import (
"go.uber.org/zap" "go.uber.org/zap"
) )
const newEpochNotification = "NewEpoch" const (
newEpochNotification = "NewEpoch"
// notaryDepositExtraBlocks is amount of 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; make sure it is bigger than any extra rounding
// value in notary client.
notaryDepositExtraBlocks = 300
// amount of tries(blocks) before notary deposit timeout.
notaryDepositRetriesAmount
)
func initMorphComponents(c *cfg) { func initMorphComponents(c *cfg) {
var err error var err error
@ -62,8 +75,24 @@ func initMorphComponents(c *cfg) {
fn(morphconfig.RPCEndpoint(c.appCfg), morphconfig.DialTimeout(c.appCfg), func(cli *client.Client) { fn(morphconfig.RPCEndpoint(c.appCfg), morphconfig.DialTimeout(c.appCfg), func(cli *client.Client) {
c.cfgMorph.client = cli c.cfgMorph.client = cli
c.cfgMorph.notaryEnabled = cli.ProbeNotary()
if c.cfgMorph.notaryEnabled {
err = c.cfgMorph.client.EnableNotarySupport(
client.WithProxyContract(
contractsconfig.Proxy(c.appCfg),
),
)
fatalOnErr(err)
c.cfgMorph.notaryDepositAmount = morphconfig.Notary(c.appCfg).Amount()
c.cfgMorph.notaryDepositDuration = morphconfig.Notary(c.appCfg).Duration()
newDepositTimer(c)
}
c.log.Debug("notary support", c.log.Debug("notary support",
zap.Bool("sidechain_enabled", cli.ProbeNotary()), zap.Bool("sidechain_enabled", c.cfgMorph.notaryEnabled),
) )
}) })
@ -85,6 +114,57 @@ func initMorphComponents(c *cfg) {
c.cfgNetmap.wrapper = wrap c.cfgNetmap.wrapper = wrap
} }
func makeAndWaitNotaryDeposit(c *cfg) {
// skip notary deposit in non-notary environments
if !c.cfgMorph.notaryEnabled {
return
}
tx, err := makeNotaryDeposit(c)
fatalOnErr(err)
err = waitNotaryDeposit(c, tx)
fatalOnErr(err)
}
func makeNotaryDeposit(c *cfg) (util.Uint256, error) {
return c.cfgMorph.client.DepositNotary(
c.cfgMorph.notaryDepositAmount,
c.cfgMorph.notaryDepositDuration+notaryDepositExtraBlocks,
)
}
var (
errNotaryDepositFail = errors.New("notary deposit tx has faulted")
errNotaryDepositTimeout = errors.New("notary deposit tx has not appeared in the network")
)
func waitNotaryDeposit(c *cfg, tx util.Uint256) error {
for i := 0; i < notaryDepositRetriesAmount; i++ {
select {
case <-c.ctx.Done():
return nil
default:
}
ok, err := c.cfgMorph.client.TxHalt(tx)
if err == nil {
if ok {
return nil
}
return errNotaryDepositFail
}
err = c.cfgMorph.client.Wait(c.ctx, 1)
if err != nil {
return fmt.Errorf("could not wait for one block in chain: %w", err)
}
}
return errNotaryDepositTimeout
}
func listenMorphNotifications(c *cfg) { func listenMorphNotifications(c *cfg) {
var ( var (
err error err error

View file

@ -5,6 +5,7 @@ import (
wrapNetmap "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper" wrapNetmap "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
"github.com/nspcc-dev/neofs-node/pkg/morph/timer" "github.com/nspcc-dev/neofs-node/pkg/morph/timer"
"go.uber.org/zap"
) )
type ( type (
@ -83,3 +84,18 @@ func newEigenTrustIterTimer(c *cfg, it *EigenTrustDuration, handler timer.BlockT
c.cfgMorph.blockTimers = append(c.cfgMorph.blockTimers, c.cfgMorph.eigenTrustTimer) c.cfgMorph.blockTimers = append(c.cfgMorph.blockTimers, c.cfgMorph.eigenTrustTimer)
} }
func newDepositTimer(c *cfg) {
c.cfgMorph.blockTimers = append(c.cfgMorph.blockTimers,
timer.NewBlockTimer(
timer.StaticBlockMeter(c.cfgMorph.notaryDepositDuration),
func() {
_, err := makeNotaryDeposit(c)
if err != nil {
c.log.Warn("can't deposit notary contract",
zap.String("error", err.Error()))
}
},
),
)
}