forked from TrueCloudLab/frostfs-node
[#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:
parent
e29bcd98e2
commit
722b844aa2
4 changed files with 104 additions and 2 deletions
|
@ -8,6 +8,7 @@ import (
|
|||
"time"
|
||||
|
||||
"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"
|
||||
"github.com/nspcc-dev/neofs-api-go/pkg"
|
||||
apiclient "github.com/nspcc-dev/neofs-api-go/pkg/client"
|
||||
|
@ -127,6 +128,10 @@ type cfgGRPC struct {
|
|||
type cfgMorph struct {
|
||||
client *client.Client
|
||||
|
||||
notaryEnabled bool
|
||||
notaryDepositAmount fixedn.Fixed8
|
||||
notaryDepositDuration uint32
|
||||
|
||||
disableCache bool
|
||||
|
||||
blockTimers []*timer.BlockTimer // all combined timers
|
||||
|
|
|
@ -90,6 +90,7 @@ func initApp(c *cfg) {
|
|||
func bootUp(c *cfg) {
|
||||
serveGRPC(c)
|
||||
bootstrapNode(c)
|
||||
makeAndWaitNotaryDeposit(c)
|
||||
startWorkers(c)
|
||||
startBlockTimers(c)
|
||||
}
|
||||
|
|
|
@ -2,11 +2,13 @@ package main
|
|||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/block"
|
||||
"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"
|
||||
morphconfig "github.com/nspcc-dev/neofs-node/cmd/neofs-node/config/morph"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
|
||||
|
@ -19,7 +21,18 @@ import (
|
|||
"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) {
|
||||
var err error
|
||||
|
@ -62,8 +75,24 @@ func initMorphComponents(c *cfg) {
|
|||
fn(morphconfig.RPCEndpoint(c.appCfg), morphconfig.DialTimeout(c.appCfg), func(cli *client.Client) {
|
||||
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",
|
||||
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
|
||||
}
|
||||
|
||||
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) {
|
||||
var (
|
||||
err error
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
wrapNetmap "github.com/nspcc-dev/neofs-node/pkg/morph/client/netmap/wrapper"
|
||||
"github.com/nspcc-dev/neofs-node/pkg/morph/timer"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
type (
|
||||
|
@ -83,3 +84,18 @@ func newEigenTrustIterTimer(c *cfg, it *EigenTrustDuration, handler timer.BlockT
|
|||
|
||||
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()))
|
||||
}
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue