[#749] neofs-adm: Set signer for committee transactions

Signed-off-by: Evgenii Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgenii Stratonikov 2022-02-02 17:19:27 +03:00 committed by Alex Vanin
parent 8fa2b364a1
commit 1deea4e8c6
4 changed files with 61 additions and 29 deletions

View file

@ -4,8 +4,6 @@ import (
"errors" "errors"
"fmt" "fmt"
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/nspcc-dev/neo-go/pkg/io" "github.com/nspcc-dev/neo-go/pkg/io"
"github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/smartcontract"
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag" "github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
@ -31,19 +29,6 @@ func forceNewEpochCmd(cmd *cobra.Command, args []string) error {
return fmt.Errorf("can't get netmap contract hash: %w", err) return fmt.Errorf("can't get netmap contract hash: %w", err)
} }
signer := transaction.Signer{
Account: wCtx.CommitteeAcc.Contract.ScriptHash(),
Scopes: transaction.Global, // Scope is important, as we have nested call to container contract.
}
groupKey, err := nnsResolveKey(wCtx.Client, cs.Hash, groupKeyDomain)
if err != nil {
cmd.Println("Can't resolve neofs contract group key, using Global scope")
} else {
signer.Scopes = transaction.CustomGroups
signer.AllowedGroups = keys.PublicKeys{groupKey}
}
res, err := wCtx.Client.InvokeFunction(nmHash, "epoch", []smartcontract.Parameter{}, nil) res, err := wCtx.Client.InvokeFunction(nmHash, "epoch", []smartcontract.Parameter{}, nil)
if err != nil || res.State != vm.HaltState.String() || len(res.Stack) == 0 { if err != nil || res.State != vm.HaltState.String() || len(res.Stack) == 0 {
return errors.New("can't fetch current epoch from the netmap contract") return errors.New("can't fetch current epoch from the netmap contract")

View file

@ -9,6 +9,7 @@ import (
"time" "time"
"github.com/nspcc-dev/neo-go/pkg/core/native/nativenames" "github.com/nspcc-dev/neo-go/pkg/core/native/nativenames"
"github.com/nspcc-dev/neo-go/pkg/core/state"
"github.com/nspcc-dev/neo-go/pkg/core/transaction" "github.com/nspcc-dev/neo-go/pkg/core/transaction"
"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/rpc/client" "github.com/nspcc-dev/neo-go/pkg/rpc/client"
@ -21,8 +22,14 @@ import (
"github.com/spf13/viper" "github.com/spf13/viper"
) )
type cache struct {
nnsCs *state.Contract
groupKey *keys.PublicKey
}
type initializeContext struct { type initializeContext struct {
clientContext clientContext
cache
// CommitteeAcc is used for retrieving committee address and verification script. // CommitteeAcc is used for retrieving committee address and verification script.
CommitteeAcc *wallet.Account CommitteeAcc *wallet.Account
// ConsensusAcc is used for retrieving committee address and verification script. // ConsensusAcc is used for retrieving committee address and verification script.
@ -227,6 +234,48 @@ func (c *initializeContext) awaitTx() error {
return c.clientContext.awaitTx(c.Command) return c.clientContext.awaitTx(c.Command)
} }
func (c *initializeContext) nnsContractState() (*state.Contract, error) {
if c.nnsCs != nil {
return c.nnsCs, nil
}
cs, err := c.Client.GetContractStateByID(1)
if err != nil {
return nil, err
}
c.nnsCs = cs
return cs, nil
}
func (c *initializeContext) getSigner() transaction.Signer {
if c.groupKey != nil {
return transaction.Signer{
Scopes: transaction.CustomGroups,
AllowedGroups: keys.PublicKeys{c.groupKey},
}
}
signer := transaction.Signer{
Account: c.CommitteeAcc.Contract.ScriptHash(),
Scopes: transaction.Global, // Scope is important, as we have nested call to container contract.
}
nnsCs, err := c.nnsContractState()
if err != nil {
return signer
}
groupKey, err := nnsResolveKey(c.Client, nnsCs.Hash, groupKeyDomain)
if err == nil {
c.groupKey = groupKey
signer.Scopes = transaction.CustomGroups
signer.AllowedGroups = keys.PublicKeys{groupKey}
}
return signer
}
func (c *clientContext) awaitTx(cmd *cobra.Command) error { func (c *clientContext) awaitTx(cmd *cobra.Command) error {
if len(c.Hashes) == 0 { if len(c.Hashes) == 0 {
return nil return nil
@ -266,10 +315,7 @@ loop:
func (c *initializeContext) sendCommitteeTx(script []byte, sysFee int64) error { func (c *initializeContext) sendCommitteeTx(script []byte, sysFee int64) error {
tx, err := c.Client.CreateTxFromScript(script, c.CommitteeAcc, sysFee, 0, []client.SignerAccount{{ tx, err := c.Client.CreateTxFromScript(script, c.CommitteeAcc, sysFee, 0, []client.SignerAccount{{
Signer: transaction.Signer{ Signer: c.getSigner(),
Account: c.CommitteeAcc.Contract.ScriptHash(),
Scopes: transaction.Global,
},
Account: c.CommitteeAcc, Account: c.CommitteeAcc,
}}) }})
if err != nil { if err != nil {

View file

@ -3,6 +3,7 @@ package morph
import ( import (
"archive/tar" "archive/tar"
"compress/gzip" "compress/gzip"
"encoding/hex"
"encoding/json" "encoding/json"
"errors" "errors"
"fmt" "fmt"
@ -98,13 +99,13 @@ func (c *initializeContext) deployNNS(method string) error {
cs := c.getContract(nnsContract) cs := c.getContract(nnsContract)
h := cs.Hash h := cs.Hash
realCs, err := c.Client.GetContractStateByID(1) nnsCs, err := c.nnsContractState()
if err == nil { if err == nil {
if realCs.NEF.Checksum == cs.NEF.Checksum { if nnsCs.NEF.Checksum == cs.NEF.Checksum {
c.Command.Println("NNS contract is already deployed.") c.Command.Println("NNS contract is already deployed.")
return nil return nil
} }
h = realCs.Hash h = nnsCs.Hash
} }
err = c.addManifestGroup(h, cs) err = c.addManifestGroup(h, cs)
@ -121,10 +122,6 @@ func (c *initializeContext) deployNNS(method string) error {
mgmtHash := c.nativeHash(nativenames.Management) mgmtHash := c.nativeHash(nativenames.Management)
if method == updateMethodName { if method == updateMethodName {
nnsCs, err := c.Client.GetContractStateByID(1)
if err != nil {
return fmt.Errorf("can't resolve NNS hash for contract update: %w", err)
}
mgmtHash = nnsCs.Hash mgmtHash = nnsCs.Hash
} }
@ -155,7 +152,7 @@ func (c *initializeContext) updateContracts() error {
mgmtHash := c.nativeHash(nativenames.Management) mgmtHash := c.nativeHash(nativenames.Management)
alphaCs := c.getContract(alphabetContract) alphaCs := c.getContract(alphabetContract)
nnsCs, err := c.Client.GetContractStateByID(1) nnsCs, err := c.nnsContractState()
if err != nil { if err != nil {
return err return err
} }
@ -272,10 +269,12 @@ func (c *initializeContext) updateContracts() error {
} }
} }
sysFee, err := c.emitUpdateNNSGroupScript(w, nnsHash, c.ContractWallet.Accounts[0].PrivateKey().PublicKey()) groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
sysFee, err := c.emitUpdateNNSGroupScript(w, nnsHash, groupKey)
if err != nil { if err != nil {
return err return err
} }
c.Command.Printf("NNS: Set %s -> %s\n", groupKeyDomain, hex.EncodeToString(groupKey.Bytes()))
totalGasCost += sysFee totalGasCost += sysFee
if err := c.sendCommitteeTx(w.Bytes(), totalGasCost); err != nil { if err := c.sendCommitteeTx(w.Bytes(), totalGasCost); err != nil {

View file

@ -69,10 +69,12 @@ func (c *initializeContext) setNNS() error {
c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE()) c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE())
} }
err = c.updateNNSGroup(nnsCs.Hash, c.ContractWallet.Accounts[0].PrivateKey().PublicKey()) groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
err = c.updateNNSGroup(nnsCs.Hash, groupKey)
if err != nil { if err != nil {
return err return err
} }
c.Command.Printf("NNS: Set %s -> %s\n", groupKeyDomain, hex.EncodeToString(groupKey.Bytes()))
return c.awaitTx() return c.awaitTx()
} }