Skip to content

Commit

Permalink
sidechain/deploy: Use single blockchain monitoring utility
Browse files Browse the repository at this point in the history
Previously, Sidechain deployment procedure initialized and stopped
multiple times. It's more efficient to run monitor once (it's almost
always needed) and stop at the end of the procedure. This also prevents
duplicated log messages about new block arrival.

Signed-off-by: Leonard Lyubich <[email protected]>
  • Loading branch information
cthulhu-rider committed Jun 27, 2023
1 parent 5ca26a8 commit 52c6ef0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 44 deletions.
10 changes: 10 additions & 0 deletions pkg/morph/deploy/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,9 +121,17 @@ func Deploy(ctx context.Context, prm Prm) error {
return errors.New("local account does not belong to any Neo committee member")
}

monitor, err := newBlockchainMonitor(prm.Logger, prm.Blockchain)
if err != nil {
return fmt.Errorf("init blockchain monitor: %w", err)
}

defer monitor.stop()

deployNNSPrm := deployNNSContractPrm{
logger: prm.Logger,
blockchain: prm.Blockchain,
monitor: monitor,
localAcc: prm.LocalAccount,
localNEF: prm.NNS.Common.NEF,
localManifest: prm.NNS.Common.Manifest,
Expand Down Expand Up @@ -169,6 +177,7 @@ func Deploy(ctx context.Context, prm Prm) error {
err = enableNotary(ctx, enableNotaryPrm{
logger: prm.Logger,
blockchain: prm.Blockchain,
monitor: monitor,
nnsOnChainAddress: nnsOnChainAddress,
systemEmail: prm.NNS.SystemEmail,
committee: committee,
Expand All @@ -186,6 +195,7 @@ func Deploy(ctx context.Context, prm Prm) error {
committeeGroupKey, err := initCommitteeGroup(ctx, initCommitteeGroupPrm{
logger: prm.Logger,
blockchain: prm.Blockchain,
monitor: monitor,
nnsOnChainAddress: nnsOnChainAddress,
systemEmail: prm.NNS.SystemEmail,
committee: committee,
Expand Down
21 changes: 10 additions & 11 deletions pkg/morph/deploy/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type initCommitteeGroupPrm struct {

blockchain Blockchain

// based on blockchain
monitor *blockchainMonitor

nnsOnChainAddress util.Uint160
systemEmail string

Expand All @@ -36,19 +39,13 @@ type initCommitteeGroupPrm struct {

// initCommitteeGroup initializes committee group and returns corresponding private key.
func initCommitteeGroup(ctx context.Context, prm initCommitteeGroupPrm) (*keys.PrivateKey, error) {
monitor, err := newBlockchainMonitor(prm.logger, prm.blockchain)
if err != nil {
return nil, fmt.Errorf("init blockchain monitor: %w", err)
}
defer monitor.stop()

inv := invoker.New(prm.blockchain, nil)
const leaderCommitteeIndex = 0
var committeeGroupKey *keys.PrivateKey
var leaderTick func()

upperLoop:
for ; ; monitor.waitForNextBlock(ctx) {
for ; ; prm.monitor.waitForNextBlock(ctx) {
select {
case <-ctx.Done():
return nil, fmt.Errorf("wait for committee group key to be distributed: %w", ctx.Err())
Expand Down Expand Up @@ -100,6 +97,8 @@ upperLoop:
continue
}

var err error

if committeeGroupKey == nil {
committeeGroupKey, err = prm.keyStorage.GetPersistedPrivateKey()
if err != nil {
Expand All @@ -109,7 +108,7 @@ upperLoop:
}

if leaderTick == nil {
leaderTick, err = initShareCommitteeGroupKeyAsLeaderTick(prm, monitor, committeeGroupKey)
leaderTick, err = initShareCommitteeGroupKeyAsLeaderTick(prm, committeeGroupKey)
if err != nil {
prm.logger.Error("failed to construct action sharing committee group key between committee members as leader, will try again later",
zap.Error(err))
Expand All @@ -124,7 +123,7 @@ upperLoop:
// initShareCommitteeGroupKeyAsLeaderTick returns a function that preserves
// context of the committee group key distribution by leading committee member
// between calls.
func initShareCommitteeGroupKeyAsLeaderTick(prm initCommitteeGroupPrm, monitor *blockchainMonitor, committeeGroupKey *keys.PrivateKey) (func(), error) {
func initShareCommitteeGroupKeyAsLeaderTick(prm initCommitteeGroupPrm, committeeGroupKey *keys.PrivateKey) (func(), error) {
_actor, err := actor.NewSimple(prm.blockchain, prm.localAcc)
if err != nil {
return nil, fmt.Errorf("init transaction sender from local account: %w", err)
Expand Down Expand Up @@ -153,7 +152,7 @@ func initShareCommitteeGroupKeyAsLeaderTick(prm initCommitteeGroupPrm, monitor *
if ok && vubs[0] > 0 {
l.Info("transaction registering NNS domain was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= vubs[0] {
if cur := prm.monitor.currentHeight(); cur <= vubs[0] {
l.Info("previously sent transaction registering NNS domain may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", vubs[0]))
return
Expand Down Expand Up @@ -194,7 +193,7 @@ func initShareCommitteeGroupKeyAsLeaderTick(prm initCommitteeGroupPrm, monitor *
if ok && vubs[1] > 0 {
l.Info("transaction setting NNS domain record was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= vubs[1] {
if cur := prm.monitor.currentHeight(); cur <= vubs[1] {
l.Info("previously sent transaction setting NNS domain record may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", vubs[1]))
return
Expand Down
13 changes: 5 additions & 8 deletions pkg/morph/deploy/nns.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ type deployNNSContractPrm struct {

blockchain Blockchain

// based on blockchain
monitor *blockchainMonitor

localAcc *wallet.Account

localNEF nef.File
Expand All @@ -91,17 +94,11 @@ type deployNNSContractPrm struct {
// If contract is missing and deployNNSContractPrm.initCommitteeGroupKey is provided,
// initNNSContract attempts to deploy local contract.
func initNNSContract(ctx context.Context, prm deployNNSContractPrm) (res util.Uint160, err error) {
monitor, err := newBlockchainMonitor(prm.logger, prm.blockchain)
if err != nil {
return res, fmt.Errorf("init blockchain monitor: %w", err)
}
defer monitor.stop()

var managementContract *management.Contract
var sentTxValidUntilBlock uint32
var committeeGroupKey *keys.PrivateKey

for ; ; monitor.waitForNextBlock(ctx) {
for ; ; prm.monitor.waitForNextBlock(ctx) {
select {
case <-ctx.Done():
return res, fmt.Errorf("wait for NNS contract synchronization: %w", ctx.Err())
Expand Down Expand Up @@ -149,7 +146,7 @@ func initNNSContract(ctx context.Context, prm deployNNSContractPrm) (res util.Ui
if sentTxValidUntilBlock > 0 {
prm.logger.Info("transaction deploying NNS contract was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= sentTxValidUntilBlock {
if cur := prm.monitor.currentHeight(); cur <= sentTxValidUntilBlock {
prm.logger.Info("previously sent transaction deploying NNS contract may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", sentTxValidUntilBlock))
continue
Expand Down
48 changes: 23 additions & 25 deletions pkg/morph/deploy/notary.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ type enableNotaryPrm struct {

blockchain Blockchain

// based on blockchain
monitor *blockchainMonitor

nnsOnChainAddress util.Uint160
systemEmail string

Expand All @@ -41,31 +44,26 @@ type enableNotaryPrm struct {

// enableNotary makes Notary service ready-to-go for the committee members.
func enableNotary(ctx context.Context, prm enableNotaryPrm) error {
monitor, err := newBlockchainMonitor(prm.logger, prm.blockchain)
if err != nil {
return fmt.Errorf("init blockchain monitor: %w", err)
}
defer monitor.stop()

var tick func()
var err error

if len(prm.committee) == 1 {
prm.logger.Info("committee is single-acc, no multi-signature needed for Notary role designation")

tick, err = initDesignateNotaryRoleToLocalAccountTick(prm, monitor)
tick, err = initDesignateNotaryRoleToLocalAccountTick(prm)
if err != nil {
return fmt.Errorf("construct action designating Notary role to the local account: %w", err)
}
} else {
prm.logger.Info("committee is multi-acc, multi-signature is needed for Notary role designation")

if prm.localAccCommitteeIndex == 0 {
tick, err = initDesignateNotaryRoleAsLeaderTick(prm, monitor)
tick, err = initDesignateNotaryRoleAsLeaderTick(prm)
if err != nil {
return fmt.Errorf("construct action designating Notary role to the multi-acc committee as leader: %w", err)
}
} else {
tick, err = initDesignateNotaryRoleAsSignerTick(prm, monitor)
tick, err = initDesignateNotaryRoleAsSignerTick(prm)
if err != nil {
return fmt.Errorf("construct action designating Notary role to the multi-acc committee as signer: %w", err)
}
Expand All @@ -74,7 +72,7 @@ func enableNotary(ctx context.Context, prm enableNotaryPrm) error {

roleContract := rolemgmt.NewReader(invoker.New(prm.blockchain, nil))

for ; ; monitor.waitForNextBlock(ctx) {
for ; ; prm.monitor.waitForNextBlock(ctx) {
select {
case <-ctx.Done():
return fmt.Errorf("wait for Notary service to be enabled for the committee: %w", ctx.Err())
Expand All @@ -83,7 +81,7 @@ func enableNotary(ctx context.Context, prm enableNotaryPrm) error {

prm.logger.Info("checking Notary role of the committee members...")

accsWithNotaryRole, err := roleContract.GetDesignatedByRole(noderoles.P2PNotary, monitor.currentHeight())
accsWithNotaryRole, err := roleContract.GetDesignatedByRole(noderoles.P2PNotary, prm.monitor.currentHeight())
if err != nil {
prm.logger.Error("failed to check role of the committee, will try again later", zap.Error(err))
continue
Expand Down Expand Up @@ -111,7 +109,7 @@ func enableNotary(ctx context.Context, prm enableNotaryPrm) error {

// initDesignateNotaryRoleToLocalAccountTick returns a function that preserves
// context of the Notary role designation to the local account between calls.
func initDesignateNotaryRoleToLocalAccountTick(prm enableNotaryPrm, monitor *blockchainMonitor) (func(), error) {
func initDesignateNotaryRoleToLocalAccountTick(prm enableNotaryPrm) (func(), error) {
_actor, err := actor.NewSimple(prm.blockchain, prm.localAcc)
if err != nil {
return nil, fmt.Errorf("init transaction sender from local account: %w", err)
Expand All @@ -123,15 +121,15 @@ func initDesignateNotaryRoleToLocalAccountTick(prm enableNotaryPrm, monitor *blo
var sentTxValidUntilBlock uint32

return func() {
if sentTxValidUntilBlock > 0 && sentTxValidUntilBlock <= monitor.currentHeight() {
if sentTxValidUntilBlock > 0 && sentTxValidUntilBlock <= prm.monitor.currentHeight() {
prm.logger.Info("previously sent transaction designating Notary role to the local account may still be relevant, will wait for the outcome")
return
}

if sentTxValidUntilBlock > 0 {
prm.logger.Info("transaction designating Notary role to the local account was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= sentTxValidUntilBlock {
if cur := prm.monitor.currentHeight(); cur <= sentTxValidUntilBlock {
prm.logger.Info("previously sent transaction designating Notary role to the local account may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", sentTxValidUntilBlock))
return
Expand Down Expand Up @@ -165,7 +163,7 @@ func initDesignateNotaryRoleToLocalAccountTick(prm enableNotaryPrm, monitor *blo
// of the Notary role designation to the multi-acc committee between calls. The
// operation is performed by the leading committee member which is assigned to
// collect signatures for the corresponding transaction.
func initDesignateNotaryRoleAsLeaderTick(prm enableNotaryPrm, monitor *blockchainMonitor) (func(), error) {
func initDesignateNotaryRoleAsLeaderTick(prm enableNotaryPrm) (func(), error) {
committeeMultiSigM := smartcontract.GetMajorityHonestNodeCount(len(prm.committee))
committeeMultiSigAcc := wallet.NewAccountFromPrivateKey(prm.localAcc.PrivateKey())

Expand Down Expand Up @@ -247,9 +245,9 @@ func initDesignateNotaryRoleAsLeaderTick(prm enableNotaryPrm, monitor *blockchai
var txValidUntilBlock uint32

if defaultValidUntilBlockIncrement <= ver.Protocol.MaxValidUntilBlockIncrement {
txValidUntilBlock = monitor.currentHeight() + defaultValidUntilBlockIncrement
txValidUntilBlock = prm.monitor.currentHeight() + defaultValidUntilBlockIncrement
} else {
txValidUntilBlock = monitor.currentHeight() + ver.Protocol.MaxValidUntilBlockIncrement
txValidUntilBlock = prm.monitor.currentHeight() + ver.Protocol.MaxValidUntilBlockIncrement
}

strSharedTxData := sharedTransactionData{
Expand Down Expand Up @@ -291,7 +289,7 @@ func initDesignateNotaryRoleAsLeaderTick(prm enableNotaryPrm, monitor *blockchai
if registerDomainTxValidUntilBlock > 0 {
l.Info("transaction registering NNS domain was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= registerDomainTxValidUntilBlock {
if cur := prm.monitor.currentHeight(); cur <= registerDomainTxValidUntilBlock {
l.Info("previously sent transaction registering NNS domain may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", registerDomainTxValidUntilBlock))
return
Expand Down Expand Up @@ -329,7 +327,7 @@ func initDesignateNotaryRoleAsLeaderTick(prm enableNotaryPrm, monitor *blockchai
if setDomainRecordTxValidUntilBlock > 0 {
l.Info("transaction setting NNS domain record was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= setDomainRecordTxValidUntilBlock {
if cur := prm.monitor.currentHeight(); cur <= setDomainRecordTxValidUntilBlock {
l.Info("previously sent transaction setting NNS domain record may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", setDomainRecordTxValidUntilBlock))
return
Expand All @@ -349,7 +347,7 @@ func initDesignateNotaryRoleAsLeaderTick(prm enableNotaryPrm, monitor *blockchai
return
}

if cur := monitor.currentHeight(); cur > sharedTxData.validUntilBlock {
if cur := prm.monitor.currentHeight(); cur > sharedTxData.validUntilBlock {
l.Error("previously used shared data of the transaction expired, need a reset",
zap.Uint32("expires after height", sharedTxData.validUntilBlock), zap.Uint32("current height", cur))
generateAndShareTxData(true)
Expand Down Expand Up @@ -481,7 +479,7 @@ func initDesignateNotaryRoleAsLeaderTick(prm enableNotaryPrm, monitor *blockchai
if designateRoleTxValidUntilBlock > 0 {
prm.logger.Info("transaction designating Notary role to the committee was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= designateRoleTxValidUntilBlock {
if cur := prm.monitor.currentHeight(); cur <= designateRoleTxValidUntilBlock {
prm.logger.Info("previously sent transaction designating Notary role to the committee may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", designateRoleTxValidUntilBlock))
return
Expand Down Expand Up @@ -545,7 +543,7 @@ func initDesignateNotaryRoleAsLeaderTick(prm enableNotaryPrm, monitor *blockchai
// of the Notary role designation to the multi-acc committee between calls. The
// operation is performed by the non-leading committee member which is assigned to
// sign transaction submitted by the leader.
func initDesignateNotaryRoleAsSignerTick(prm enableNotaryPrm, monitor *blockchainMonitor) (func(), error) {
func initDesignateNotaryRoleAsSignerTick(prm enableNotaryPrm) (func(), error) {
committeeMultiSigM := smartcontract.GetMajorityHonestNodeCount(len(prm.committee))
committeeMultiSigAcc := wallet.NewAccountFromPrivateKey(prm.localAcc.PrivateKey())

Expand Down Expand Up @@ -621,7 +619,7 @@ func initDesignateNotaryRoleAsSignerTick(prm enableNotaryPrm, monitor *blockchai
return
}

if cur := monitor.currentHeight(); cur > sharedTxData.validUntilBlock {
if cur := prm.monitor.currentHeight(); cur > sharedTxData.validUntilBlock {
l.Error("previously used shared data of the transaction expired, will wait for update by leader",
zap.Uint32("expires after height", sharedTxData.validUntilBlock), zap.Uint32("current height", cur))
resetTx()
Expand Down Expand Up @@ -663,7 +661,7 @@ func initDesignateNotaryRoleAsSignerTick(prm enableNotaryPrm, monitor *blockchai
if registerDomainTxValidUntilBlock > 0 {
l.Info("transaction registering NNS domain was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= registerDomainTxValidUntilBlock {
if cur := prm.monitor.currentHeight(); cur <= registerDomainTxValidUntilBlock {
l.Info("previously sent transaction registering NNS domain may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", registerDomainTxValidUntilBlock))
return
Expand Down Expand Up @@ -701,7 +699,7 @@ func initDesignateNotaryRoleAsSignerTick(prm enableNotaryPrm, monitor *blockchai
if setDomainRecordTxValidUntilBlock > 0 {
l.Info("transaction setting NNS domain record was sent earlier, checking relevance...")

if cur := monitor.currentHeight(); cur <= setDomainRecordTxValidUntilBlock {
if cur := prm.monitor.currentHeight(); cur <= setDomainRecordTxValidUntilBlock {
l.Info("previously sent transaction setting NNS domain record may still be relevant, will wait for the outcome",
zap.Uint32("current height", cur), zap.Uint32("retry after height", setDomainRecordTxValidUntilBlock))
return
Expand Down

0 comments on commit 52c6ef0

Please sign in to comment.