forked from TrueCloudLab/frostfs-node
[#749] neofs-adm: include neofs contracts in a group
Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
parent
e03cb91b64
commit
b416285eb0
3 changed files with 112 additions and 12 deletions
73
cmd/neofs-adm/internal/modules/morph/group.go
Normal file
73
cmd/neofs-adm/internal/modules/morph/group.go
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
package morph
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/cli/input"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
|
"github.com/spf13/viper"
|
||||||
|
)
|
||||||
|
|
||||||
|
const contractWalletName = "contract.json"
|
||||||
|
|
||||||
|
func openContractWallet(walletDir string) (*wallet.Wallet, error) {
|
||||||
|
p := path.Join(walletDir, contractWalletName)
|
||||||
|
w, err := wallet.NewWalletFromFile(p)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("can't open wallet: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var password string
|
||||||
|
if key := "credentials.contract"; viper.IsSet(key) {
|
||||||
|
password = viper.GetString(key)
|
||||||
|
} else {
|
||||||
|
prompt := "Password for contract wallet > "
|
||||||
|
password, err = input.ReadPassword(prompt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("can't fetch password: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for i := range w.Accounts {
|
||||||
|
if err := w.Accounts[i].Decrypt(password, keys.NEP2ScryptParams()); err != nil {
|
||||||
|
return nil, fmt.Errorf("can't unlock wallet: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return w, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *initializeContext) addManifestGroup(h util.Uint160, cs *contractState) error {
|
||||||
|
priv := c.ContractWallet.Accounts[0].PrivateKey()
|
||||||
|
pub := priv.PublicKey()
|
||||||
|
|
||||||
|
sig := priv.Sign(h.BytesBE())
|
||||||
|
found := false
|
||||||
|
|
||||||
|
for i := range cs.Manifest.Groups {
|
||||||
|
if cs.Manifest.Groups[i].PublicKey.Equal(pub) {
|
||||||
|
cs.Manifest.Groups[i].Signature = sig
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
cs.Manifest.Groups = append(cs.Manifest.Groups, manifest.Group{
|
||||||
|
PublicKey: pub,
|
||||||
|
Signature: sig,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
data, err := json.Marshal(cs.Manifest)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
cs.RawManifest = data
|
||||||
|
return nil
|
||||||
|
}
|
|
@ -28,6 +28,8 @@ type initializeContext struct {
|
||||||
// ConsensusAcc is used for retrieving committee address and verification script.
|
// ConsensusAcc is used for retrieving committee address and verification script.
|
||||||
ConsensusAcc *wallet.Account
|
ConsensusAcc *wallet.Account
|
||||||
Wallets []*wallet.Wallet
|
Wallets []*wallet.Wallet
|
||||||
|
// ContractWallet is a wallet for providing contract group signature.
|
||||||
|
ContractWallet *wallet.Wallet
|
||||||
// Accounts contains simple signature accounts in the same order as in Wallets.
|
// Accounts contains simple signature accounts in the same order as in Wallets.
|
||||||
Accounts []*wallet.Account
|
Accounts []*wallet.Account
|
||||||
Contracts map[string]*contractState
|
Contracts map[string]*contractState
|
||||||
|
@ -95,6 +97,11 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
w, err := openContractWallet(walletDir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
c, err := getN3Client(v)
|
c, err := getN3Client(v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't create N3 client: %w", err)
|
return nil, fmt.Errorf("can't create N3 client: %w", err)
|
||||||
|
@ -144,15 +151,16 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
}
|
}
|
||||||
|
|
||||||
initCtx := &initializeContext{
|
initCtx := &initializeContext{
|
||||||
clientContext: *defaultClientContext(c),
|
clientContext: *defaultClientContext(c),
|
||||||
ConsensusAcc: consensusAcc,
|
ConsensusAcc: consensusAcc,
|
||||||
CommitteeAcc: committeeAcc,
|
CommitteeAcc: committeeAcc,
|
||||||
Wallets: wallets,
|
ContractWallet: w,
|
||||||
Accounts: accounts,
|
Wallets: wallets,
|
||||||
Command: cmd,
|
Accounts: accounts,
|
||||||
Contracts: make(map[string]*contractState),
|
Command: cmd,
|
||||||
ContractPath: ctrPath,
|
Contracts: make(map[string]*contractState),
|
||||||
Natives: nativeHashes,
|
ContractPath: ctrPath,
|
||||||
|
Natives: nativeHashes,
|
||||||
}
|
}
|
||||||
|
|
||||||
if needContracts {
|
if needContracts {
|
||||||
|
|
|
@ -96,11 +96,20 @@ const (
|
||||||
|
|
||||||
func (c *initializeContext) deployNNS(method string) error {
|
func (c *initializeContext) deployNNS(method string) error {
|
||||||
cs := c.getContract(nnsContract)
|
cs := c.getContract(nnsContract)
|
||||||
|
h := cs.Hash
|
||||||
|
|
||||||
realCs, err := c.Client.GetContractStateByID(1)
|
realCs, err := c.Client.GetContractStateByID(1)
|
||||||
if err == nil && realCs.NEF.Checksum == cs.NEF.Checksum {
|
if err == nil {
|
||||||
c.Command.Println("NNS contract is already deployed.")
|
if realCs.NEF.Checksum == cs.NEF.Checksum {
|
||||||
return nil
|
c.Command.Println("NNS contract is already deployed.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
h = realCs.Hash
|
||||||
|
}
|
||||||
|
|
||||||
|
err = c.addManifestGroup(h, cs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't sign manifest group: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
params := getContractDeployParameters(cs.RawNEF, cs.RawManifest, nil)
|
params := getContractDeployParameters(cs.RawNEF, cs.RawManifest, nil)
|
||||||
|
@ -220,6 +229,11 @@ func (c *initializeContext) updateContracts() error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = c.addManifestGroup(ctrHash, alphaCs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't sign manifest group: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
invokeHash := mgmtHash
|
invokeHash := mgmtHash
|
||||||
if method == updateMethodName {
|
if method == updateMethodName {
|
||||||
invokeHash = ctrHash
|
invokeHash = ctrHash
|
||||||
|
@ -322,6 +336,11 @@ func (c *initializeContext) deployContracts() error {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err := c.addManifestGroup(ctrHash, cs)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't sign manifest group: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
invokeHash := mgmtHash
|
invokeHash := mgmtHash
|
||||||
params := getContractDeployParameters(cs.RawNEF, cs.RawManifest,
|
params := getContractDeployParameters(cs.RawNEF, cs.RawManifest,
|
||||||
c.getContractDeployData(ctrName, keysParam))
|
c.getContractDeployData(ctrName, keysParam))
|
||||||
|
|
Loading…
Reference in a new issue