Skip to content

Commit daa6344

Browse files
committed
deploy: Fix witnesses for Balance and Container contract deployments
To deploy these contracts in `@v0.19.1` revision: - both must be witnessed by the Alphabet (2/3n+1) to call Netmap - Container must be also witnessed by the committee majority (n/2+1) to call NNS Signed-off-by: Leonard Lyubich <[email protected]>
1 parent 5c66479 commit daa6344

File tree

3 files changed

+63
-17
lines changed

3 files changed

+63
-17
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Changelog for NeoFS Node
66
### Added
77

88
### Fixed
9+
- Auto-deployment of the Balance and Container contracts (#2695)
910

1011
### Changed
1112

pkg/morph/deploy/contracts.go

Lines changed: 54 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
1414
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
1515
"github.com/nspcc-dev/neo-go/pkg/rpcclient/notary"
16+
"github.com/nspcc-dev/neo-go/pkg/smartcontract"
1617
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
1718
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
1819
"github.com/nspcc-dev/neo-go/pkg/util"
@@ -25,6 +26,12 @@ const (
2526
methodUpdate = "update"
2627
)
2728

29+
const (
30+
_ uint8 = iota
31+
witnessAlphabet
32+
witnessAlphabetAndCommittee
33+
)
34+
2835
// syncNeoFSContractPrm groups parameters of syncNeoFSContract.
2936
type syncNeoFSContractPrm struct {
3037
logger *zap.Logger
@@ -56,10 +63,12 @@ type syncNeoFSContractPrm struct {
5663
// if set, syncNeoFSContract attempts to deploy the contract when it's
5764
// missing on the chain
5865
tryDeploy bool
59-
// is contract must be deployed by the committee
60-
committeeDeployRequired bool
61-
// additional allowed contracts to be added to the NNS one if committeeDeployRequired
62-
extraCommitteeDeployAllowedContracts []util.Uint160
66+
// 0: committee witness is not needed
67+
// witnessAlphabet: committee 2/3n+1 with allowed alphabetDeployAllowedContracts
68+
// witnessAlphabetAndCommittee: witnessAlphabet + committee n/2+1 with allowed NNS contract calls
69+
deployWitness uint8
70+
// contracts that are allowed to be called for the Alphabet-witnessed deployment
71+
alphabetDeployAllowedContracts []util.Uint160
6372

6473
// optional constructor of extra arguments to be passed into method deploying
6574
// the contract. If returns both nil, no data is passed (noExtraDeployArgs can
@@ -126,11 +135,46 @@ func syncNeoFSContract(ctx context.Context, prm syncNeoFSContractPrm) (util.Uint
126135
Sender() util.Uint160
127136
}
128137
var managementContract *management.Contract
129-
if prm.committeeDeployRequired {
130-
deployCommitteeActor, err := newCommitteeNotaryActorWithCustomCommitteeSigner(prm.blockchain, prm.localAcc, prm.committee, func(s *transaction.Signer) {
131-
s.Scopes = transaction.CustomContracts
132-
s.AllowedContracts = append(prm.extraCommitteeDeployAllowedContracts, prm.nnsContract)
133-
})
138+
if prm.deployWitness > 0 {
139+
if prm.deployWitness != witnessAlphabet && prm.deployWitness != witnessAlphabetAndCommittee {
140+
panic(fmt.Sprintf("unexpected deploy witness mode value %v", prm.deployWitness))
141+
}
142+
143+
committeeDefaultMultiSigAcc := wallet.NewAccountFromPrivateKey(prm.localAcc.PrivateKey())
144+
err := committeeDefaultMultiSigAcc.ConvertMultisig(smartcontract.GetDefaultHonestNodeCount(len(prm.committee)), prm.committee)
145+
if err != nil {
146+
return util.Uint160{}, fmt.Errorf("compose committee default multi-signature account: %w", err)
147+
}
148+
149+
signers := make([]actor.SignerAccount, 2, 3)
150+
// payer
151+
signers[0].Account = prm.localAcc
152+
signers[0].Signer.Account = prm.localAcc.ScriptHash()
153+
signers[0].Signer.Scopes = transaction.None
154+
// Alphabet
155+
signers[1].Account = committeeDefaultMultiSigAcc
156+
signers[1].Signer.Account = committeeDefaultMultiSigAcc.ScriptHash()
157+
signers[1].Signer.Scopes = transaction.CustomContracts
158+
signers[1].Signer.AllowedContracts = prm.alphabetDeployAllowedContracts
159+
160+
if prm.deployWitness == witnessAlphabetAndCommittee {
161+
committeeMajorityMultiSigAcc := wallet.NewAccountFromPrivateKey(prm.localAcc.PrivateKey())
162+
err := committeeMajorityMultiSigAcc.ConvertMultisig(smartcontract.GetMajorityHonestNodeCount(len(prm.committee)), prm.committee)
163+
if err != nil {
164+
return util.Uint160{}, fmt.Errorf("compose committee majority multi-signature account: %w", err)
165+
}
166+
167+
signers = append(signers, actor.SignerAccount{
168+
Signer: transaction.Signer{
169+
Account: committeeMajorityMultiSigAcc.ScriptHash(),
170+
Scopes: transaction.CustomContracts,
171+
AllowedContracts: []util.Uint160{prm.nnsContract},
172+
},
173+
Account: committeeMajorityMultiSigAcc,
174+
})
175+
}
176+
177+
deployCommitteeActor, err := notary.NewActor(prm.blockchain, signers, prm.localAcc)
134178
if err != nil {
135179
return util.Uint160{}, fmt.Errorf("create Notary service client sending deploy transactions to be signed by the committee: %w", err)
136180
}
@@ -226,7 +270,7 @@ func syncNeoFSContract(ctx context.Context, prm syncNeoFSContractPrm) (util.Uint
226270
nefCp := prm.localNEF
227271
manifestCp := prm.localManifest
228272

229-
if prm.committeeDeployRequired {
273+
if prm.deployWitness > 0 {
230274
l.Info("contract requires committee witness for deployment, sending Notary request...")
231275

232276
mainTxID, fallbackTxID, vub, err := prm.committeeLocalActor.Notarize(managementContract.DeployTransaction(&nefCp, &manifestCp, extraDeployArgs))

pkg/morph/deploy/deploy.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -464,8 +464,8 @@ func Deploy(ctx context.Context, prm Prm) error {
464464
syncPrm.localNEF = prm.BalanceContract.Common.NEF
465465
syncPrm.localManifest = prm.BalanceContract.Common.Manifest
466466
syncPrm.domainName = domainBalance
467-
syncPrm.committeeDeployRequired = true
468-
syncPrm.extraCommitteeDeployAllowedContracts = []util.Uint160{netmapContractAddress}
467+
syncPrm.deployWitness = witnessAlphabet
468+
syncPrm.alphabetDeployAllowedContracts = []util.Uint160{netmapContractAddress}
469469
syncPrm.buildExtraDeployArgs = noExtraDeployArgs
470470

471471
prm.Logger.Info("synchronizing Balance contract with the chain...")
@@ -477,8 +477,8 @@ func Deploy(ctx context.Context, prm Prm) error {
477477

478478
prm.Logger.Info("Balance contract successfully synchronized", zap.Stringer("address", balanceContractAddress))
479479

480-
syncPrm.committeeDeployRequired = false
481-
syncPrm.extraCommitteeDeployAllowedContracts = nil
480+
syncPrm.deployWitness = 0
481+
syncPrm.alphabetDeployAllowedContracts = nil
482482

483483
// 5. Reputation
484484
syncPrm.localNEF = prm.ReputationContract.Common.NEF
@@ -514,8 +514,8 @@ func Deploy(ctx context.Context, prm Prm) error {
514514
syncPrm.localNEF = prm.ContainerContract.Common.NEF
515515
syncPrm.localManifest = prm.ContainerContract.Common.Manifest
516516
syncPrm.domainName = domainContainer
517-
syncPrm.committeeDeployRequired = true
518-
syncPrm.extraCommitteeDeployAllowedContracts = []util.Uint160{netmapContractAddress}
517+
syncPrm.deployWitness = witnessAlphabetAndCommittee
518+
syncPrm.alphabetDeployAllowedContracts = []util.Uint160{netmapContractAddress}
519519
syncPrm.buildExtraDeployArgs = func() ([]any, error) {
520520
return []any{
521521
notaryDisabledExtraUpdateArg,
@@ -536,7 +536,8 @@ func Deploy(ctx context.Context, prm Prm) error {
536536

537537
prm.Logger.Info("Container contract successfully synchronized", zap.Stringer("address", containerContractAddress))
538538

539-
syncPrm.committeeDeployRequired = false
539+
syncPrm.deployWitness = 0
540+
syncPrm.alphabetDeployAllowedContracts = nil
540541

541542
// 8. Alphabet
542543
syncPrm.localNEF = prm.AlphabetContract.Common.NEF

0 commit comments

Comments
 (0)