forked from TrueCloudLab/frostfs-node
[#932] adm: Prepare to move InitializeContext
to util
package
Signed-off-by: Anton Nikiforov <an.nikiforov@yadro.com>
This commit is contained in:
parent
bee3741f4e
commit
b68f7be0b6
20 changed files with 277 additions and 270 deletions
|
@ -85,7 +85,7 @@ func setConfigCmd(cmd *cobra.Command, args []string) error {
|
||||||
return errors.New("empty config pairs")
|
return errors.New("empty config pairs")
|
||||||
}
|
}
|
||||||
|
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't initialize context: %w", err)
|
return fmt.Errorf("can't initialize context: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -119,12 +119,12 @@ func setConfigCmd(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = wCtx.sendConsensusTx(bw.Bytes())
|
err = wCtx.SendConsensusTx(bw.Bytes())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return wCtx.awaitTx()
|
return wCtx.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseConfigPair(kvStr string, force bool) (key string, val any, err error) {
|
func parseConfigPair(kvStr string, force bool) (key string, val any, err error) {
|
||||||
|
|
|
@ -193,11 +193,11 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
return fmt.Errorf("invalid filename: %w", err)
|
return fmt.Errorf("invalid filename: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer wCtx.close()
|
defer wCtx.Close()
|
||||||
|
|
||||||
containers, err := parseContainers(filename)
|
containers, err := parseContainers(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -219,10 +219,10 @@ func restoreContainers(cmd *cobra.Command, _ []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return wCtx.awaitTx()
|
return wCtx.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func restoreOrPutContainers(containers []Container, isOK func([]byte) bool, cmd *cobra.Command, wCtx *initializeContext, ch util.Uint160) error {
|
func restoreOrPutContainers(containers []Container, isOK func([]byte) bool, cmd *cobra.Command, wCtx *InitializeContext, ch util.Uint160) error {
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
for _, cnt := range containers {
|
for _, cnt := range containers {
|
||||||
hv := hash.Sha256(cnt.Value)
|
hv := hash.Sha256(cnt.Value)
|
||||||
|
@ -246,7 +246,7 @@ func restoreOrPutContainers(containers []Container, isOK func([]byte) bool, cmd
|
||||||
panic(bw.Err)
|
panic(bw.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := wCtx.sendConsensusTx(bw.Bytes()); err != nil {
|
if err := wCtx.SendConsensusTx(bw.Bytes()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -262,7 +262,7 @@ func putContainer(bw *io.BufBinWriter, ch util.Uint160, cnt Container) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func isContainerRestored(cmd *cobra.Command, wCtx *initializeContext, containerHash util.Uint160, bw *io.BufBinWriter, hashValue util.Uint256) (bool, error) {
|
func isContainerRestored(cmd *cobra.Command, wCtx *InitializeContext, containerHash util.Uint160, bw *io.BufBinWriter, hashValue util.Uint256) (bool, error) {
|
||||||
emit.AppCall(bw.BinWriter, containerHash, "get", callflag.All, hashValue.BytesBE())
|
emit.AppCall(bw.BinWriter, containerHash, "get", callflag.All, hashValue.BytesBE())
|
||||||
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
|
res, err := wCtx.Client.InvokeScript(bw.Bytes(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -300,7 +300,7 @@ func parseContainers(filename string) ([]Container, error) {
|
||||||
return containers, nil
|
return containers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func fetchContainerContractHash(wCtx *initializeContext) (util.Uint160, error) {
|
func fetchContainerContractHash(wCtx *InitializeContext) (util.Uint160, error) {
|
||||||
r := management.NewReader(wCtx.ReadOnlyInvoker)
|
r := management.NewReader(wCtx.ReadOnlyInvoker)
|
||||||
nnsCs, err := r.GetContractByID(1)
|
nnsCs, err := r.GetContractByID(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -60,11 +60,11 @@ func init() {
|
||||||
|
|
||||||
func deployContractCmd(cmd *cobra.Command, args []string) error {
|
func deployContractCmd(cmd *cobra.Command, args []string) error {
|
||||||
v := viper.GetViper()
|
v := viper.GetViper()
|
||||||
c, err := newInitializeContext(cmd, v)
|
c, err := NewInitializeContext(cmd, v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("initialization error: %w", err)
|
return fmt.Errorf("initialization error: %w", err)
|
||||||
}
|
}
|
||||||
defer c.close()
|
defer c.Close()
|
||||||
|
|
||||||
ctrPath, _ := cmd.Flags().GetString(contractPathFlag)
|
ctrPath, _ := cmd.Flags().GetString(contractPathFlag)
|
||||||
ctrName, err := probeContractName(ctrPath)
|
ctrName, err := probeContractName(ctrPath)
|
||||||
|
@ -123,13 +123,13 @@ func deployContractCmd(cmd *cobra.Command, args []string) error {
|
||||||
panic(fmt.Errorf("BUG: can't create deployment script: %w", writer.Err))
|
panic(fmt.Errorf("BUG: can't create deployment script: %w", writer.Err))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.sendCommitteeTx(writer.Bytes(), false); err != nil {
|
if err := c.SendCommitteeTx(writer.Bytes(), false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func registerNNS(nnsCs *state.Contract, c *initializeContext, zone string, domain string, cs *contractState, writer *io.BufBinWriter) error {
|
func registerNNS(nnsCs *state.Contract, c *InitializeContext, zone string, domain string, cs *util.ContractState, writer *io.BufBinWriter) error {
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
emit.Instruction(bw.BinWriter, opcode.INITSSLOT, []byte{1})
|
emit.Instruction(bw.BinWriter, opcode.INITSSLOT, []byte{1})
|
||||||
emit.AppCall(bw.BinWriter, nnsCs.Hash, "getPrice", callflag.All)
|
emit.AppCall(bw.BinWriter, nnsCs.Hash, "getPrice", callflag.All)
|
||||||
|
@ -139,7 +139,7 @@ func registerNNS(nnsCs *state.Contract, c *initializeContext, zone string, domai
|
||||||
start := bw.Len()
|
start := bw.Len()
|
||||||
needRecord := false
|
needRecord := false
|
||||||
|
|
||||||
ok, err := c.nnsRootRegistered(nnsCs.Hash, zone)
|
ok, err := c.NNSRootRegistered(nnsCs.Hash, zone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !ok {
|
} else if !ok {
|
||||||
|
@ -155,7 +155,7 @@ func registerNNS(nnsCs *state.Contract, c *initializeContext, zone string, domai
|
||||||
frostfsOpsEmail, int64(3600), int64(600), int64(defaultExpirationTime), int64(3600))
|
frostfsOpsEmail, int64(3600), int64(600), int64(defaultExpirationTime), int64(3600))
|
||||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||||
} else {
|
} else {
|
||||||
s, ok, err := c.nnsRegisterDomainScript(nnsCs.Hash, cs.Hash, domain)
|
s, ok, err := c.NNSRegisterDomainScript(nnsCs.Hash, cs.Hash, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ func dumpContractHashes(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
||||||
irSize := 0
|
irSize := 0
|
||||||
for ; irSize < lastGlagoliticLetter; irSize++ {
|
for ; irSize < lastGlagoliticLetter; irSize++ {
|
||||||
ok, err := nnsIsAvailable(c, cs.Hash, getAlphabetNNSDomain(irSize))
|
ok, err := morphUtil.NNSIsAvailable(c, cs.Hash, getAlphabetNNSDomain(irSize))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if ok {
|
} else if ok {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func forceNewEpochCmd(cmd *cobra.Command, _ []string) error {
|
func forceNewEpochCmd(cmd *cobra.Command, _ []string) error {
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't to initialize context: %w", err)
|
return fmt.Errorf("can't to initialize context: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -38,8 +38,8 @@ func forceNewEpochCmd(cmd *cobra.Command, _ []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = wCtx.sendConsensusTx(bw.Bytes()); err == nil {
|
if err = wCtx.SendConsensusTx(bw.Bytes()); err == nil {
|
||||||
err = wCtx.awaitTx()
|
err = wCtx.AwaitTx()
|
||||||
}
|
}
|
||||||
if err != nil && strings.Contains(err.Error(), "invalid epoch") {
|
if err != nil && strings.Contains(err.Error(), "invalid epoch") {
|
||||||
cmd.Println("Epoch has already ticked.")
|
cmd.Println("Epoch has already ticked.")
|
||||||
|
@ -48,7 +48,7 @@ func forceNewEpochCmd(cmd *cobra.Command, _ []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func emitNewEpochCall(bw *io.BufBinWriter, wCtx *initializeContext, nmHash util.Uint160) error {
|
func emitNewEpochCall(bw *io.BufBinWriter, wCtx *InitializeContext, nmHash util.Uint160) error {
|
||||||
curr, err := unwrap.Int64(wCtx.ReadOnlyInvoker.Call(nmHash, "epoch"))
|
curr, err := unwrap.Int64(wCtx.ReadOnlyInvoker.Call(nmHash, "epoch"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.New("can't fetch current epoch from the netmap contract")
|
return errors.New("can't fetch current epoch from the netmap contract")
|
||||||
|
|
|
@ -416,11 +416,11 @@ type frostfsidClient struct {
|
||||||
bw *io.BufBinWriter
|
bw *io.BufBinWriter
|
||||||
contractHash util.Uint160
|
contractHash util.Uint160
|
||||||
roCli *frostfsidclient.Client // client can be used only for waiting tx, parsing and forming method params
|
roCli *frostfsidclient.Client // client can be used only for waiting tx, parsing and forming method params
|
||||||
wCtx *initializeContext
|
wCtx *InitializeContext
|
||||||
}
|
}
|
||||||
|
|
||||||
func newFrostfsIDClient(cmd *cobra.Command) (*frostfsidClient, error) {
|
func newFrostfsIDClient(cmd *cobra.Command) (*frostfsidClient, error) {
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't to initialize context: %w", err)
|
return nil, fmt.Errorf("can't to initialize context: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -449,16 +449,16 @@ func (f *frostfsidClient) addCall(method string, args []any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *frostfsidClient) sendWait() error {
|
func (f *frostfsidClient) sendWait() error {
|
||||||
if err := f.wCtx.sendConsensusTx(f.bw.Bytes()); err != nil {
|
if err := f.wCtx.SendConsensusTx(f.bw.Bytes()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
f.bw.Reset()
|
f.bw.Reset()
|
||||||
|
|
||||||
return f.wCtx.awaitTx()
|
return f.wCtx.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *frostfsidClient) sendWaitRes() (*state.AppExecResult, error) {
|
func (f *frostfsidClient) sendWaitRes() (*state.AppExecResult, error) {
|
||||||
if err := f.wCtx.sendConsensusTx(f.bw.Bytes()); err != nil {
|
if err := f.wCtx.SendConsensusTx(f.bw.Bytes()); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
f.bw.Reset()
|
f.bw.Reset()
|
||||||
|
|
|
@ -195,7 +195,7 @@ func refillGas(cmd *cobra.Command, gasFlag string, createWallet bool) (err error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -208,11 +208,11 @@ func refillGas(cmd *cobra.Command, gasFlag string, createWallet bool) (err error
|
||||||
return fmt.Errorf("BUG: invalid transfer arguments: %w", bw.Err)
|
return fmt.Errorf("BUG: invalid transfer arguments: %w", bw.Err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := wCtx.sendCommitteeTx(bw.Bytes(), false); err != nil {
|
if err := wCtx.SendCommitteeTx(bw.Bytes(), false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return wCtx.awaitTx()
|
return wCtx.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseGASAmount(s string) (fixedn.Fixed8, error) {
|
func parseGASAmount(s string) (fixedn.Fixed8, error) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/config"
|
||||||
|
util2 "git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/modules/morph/util"
|
||||||
"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/smartcontract/manifest"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -75,8 +76,8 @@ func openContractWallet(v *viper.Viper, cmd *cobra.Command, walletDir string) (*
|
||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) addManifestGroup(h util.Uint160, cs *contractState) error {
|
func addManifestGroup(cw *wallet.Wallet, h util.Uint160, cs *util2.ContractState) error {
|
||||||
priv := c.ContractWallet.Accounts[0].PrivateKey()
|
priv := cw.Accounts[0].PrivateKey()
|
||||||
pub := priv.PublicKey()
|
pub := priv.PublicKey()
|
||||||
|
|
||||||
sig := priv.Sign(h.BytesBE())
|
sig := priv.Sign(h.BytesBE())
|
||||||
|
|
|
@ -20,14 +20,14 @@ import (
|
||||||
"github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
)
|
)
|
||||||
|
|
||||||
type cache struct {
|
type Cache struct {
|
||||||
nnsCs *state.Contract
|
NNSCs *state.Contract
|
||||||
groupKey *keys.PublicKey
|
GroupKey *keys.PublicKey
|
||||||
}
|
}
|
||||||
|
|
||||||
type initializeContext struct {
|
type InitializeContext struct {
|
||||||
morphUtil.ClientContext
|
morphUtil.ClientContext
|
||||||
cache
|
Cache
|
||||||
// CommitteeAcc is used for retrieving the committee address and the verification script.
|
// CommitteeAcc is used for retrieving the committee address and the verification script.
|
||||||
CommitteeAcc *wallet.Account
|
CommitteeAcc *wallet.Account
|
||||||
// ConsensusAcc is used for retrieving the committee address and the verification script.
|
// ConsensusAcc is used for retrieving the committee address and the verification script.
|
||||||
|
@ -37,62 +37,62 @@ type initializeContext struct {
|
||||||
ContractWallet *wallet.Wallet
|
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]*morphUtil.ContractState
|
||||||
Command *cobra.Command
|
Command *cobra.Command
|
||||||
ContractPath string
|
ContractPath string
|
||||||
ContractURL string
|
ContractURL string
|
||||||
}
|
}
|
||||||
|
|
||||||
func initializeSideChainCmd(cmd *cobra.Command, _ []string) error {
|
func initializeSideChainCmd(cmd *cobra.Command, _ []string) error {
|
||||||
initCtx, err := newInitializeContext(cmd, viper.GetViper())
|
initCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("initialization error: %w", err)
|
return fmt.Errorf("initialization error: %w", err)
|
||||||
}
|
}
|
||||||
defer initCtx.close()
|
defer initCtx.Close()
|
||||||
|
|
||||||
// 1. Transfer funds to committee accounts.
|
// 1. Transfer funds to committee accounts.
|
||||||
cmd.Println("Stage 1: transfer GAS to alphabet nodes.")
|
cmd.Println("Stage 1: transfer GAS to alphabet nodes.")
|
||||||
if err := initCtx.transferFunds(); err != nil {
|
if err := transferFunds(initCtx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Stage 2: set notary and alphabet nodes in designate contract.")
|
cmd.Println("Stage 2: set notary and alphabet nodes in designate contract.")
|
||||||
if err := initCtx.setNotaryAndAlphabetNodes(); err != nil {
|
if err := setNotaryAndAlphabetNodes(initCtx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Deploy NNS contract.
|
// 3. Deploy NNS contract.
|
||||||
cmd.Println("Stage 3: deploy NNS contract.")
|
cmd.Println("Stage 3: deploy NNS contract.")
|
||||||
if err := initCtx.deployNNS(deployMethodName); err != nil {
|
if err := deployNNS(initCtx, deployMethodName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Deploy NeoFS contracts.
|
// 4. Deploy NeoFS contracts.
|
||||||
cmd.Println("Stage 4: deploy NeoFS contracts.")
|
cmd.Println("Stage 4: deploy NeoFS contracts.")
|
||||||
if err := initCtx.deployContracts(); err != nil {
|
if err := deployContracts(initCtx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Stage 4.1: Transfer GAS to proxy contract.")
|
cmd.Println("Stage 4.1: Transfer GAS to proxy contract.")
|
||||||
if err := initCtx.transferGASToProxy(); err != nil {
|
if err := transferGASToProxy(initCtx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Stage 5: register candidates.")
|
cmd.Println("Stage 5: register candidates.")
|
||||||
if err := initCtx.registerCandidates(); err != nil {
|
if err := registerCandidates(initCtx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Stage 6: transfer NEO to alphabet contracts.")
|
cmd.Println("Stage 6: transfer NEO to alphabet contracts.")
|
||||||
if err := initCtx.transferNEOToAlphabetContracts(); err != nil {
|
if err := transferNEOToAlphabetContracts(initCtx); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd.Println("Stage 7: set addresses in NNS.")
|
cmd.Println("Stage 7: set addresses in NNS.")
|
||||||
return initCtx.setNNS()
|
return setNNS(initCtx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) close() {
|
func (c *InitializeContext) Close() {
|
||||||
if local, ok := c.Client.(*morphUtil.LocalClient); ok {
|
if local, ok := c.Client.(*morphUtil.LocalClient); ok {
|
||||||
err := local.Dump()
|
err := local.Dump()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -102,7 +102,7 @@ func (c *initializeContext) close() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContext, error) {
|
func NewInitializeContext(cmd *cobra.Command, v *viper.Viper) (*InitializeContext, error) {
|
||||||
walletDir := config.ResolveHomePath(viper.GetString(morphUtil.AlphabetWalletsFlag))
|
walletDir := config.ResolveHomePath(viper.GetString(morphUtil.AlphabetWalletsFlag))
|
||||||
wallets, err := morphUtil.GetAlphabetWallets(v, walletDir)
|
wallets, err := morphUtil.GetAlphabetWallets(v, walletDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -160,7 +160,7 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
return nil, fmt.Errorf("client context: %w", err)
|
return nil, fmt.Errorf("client context: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
initCtx := &initializeContext{
|
initCtx := &InitializeContext{
|
||||||
ClientContext: *cliCtx,
|
ClientContext: *cliCtx,
|
||||||
ConsensusAcc: consensusAcc,
|
ConsensusAcc: consensusAcc,
|
||||||
CommitteeAcc: committeeAcc,
|
CommitteeAcc: committeeAcc,
|
||||||
|
@ -168,7 +168,7 @@ func newInitializeContext(cmd *cobra.Command, v *viper.Viper) (*initializeContex
|
||||||
Wallets: wallets,
|
Wallets: wallets,
|
||||||
Accounts: accounts,
|
Accounts: accounts,
|
||||||
Command: cmd,
|
Command: cmd,
|
||||||
Contracts: make(map[string]*contractState),
|
Contracts: make(map[string]*morphUtil.ContractState),
|
||||||
ContractPath: ctrPath,
|
ContractPath: ctrPath,
|
||||||
ContractURL: ctrURL,
|
ContractURL: ctrURL,
|
||||||
}
|
}
|
||||||
|
@ -246,13 +246,13 @@ func createWalletAccounts(wallets []*wallet.Wallet) ([]*wallet.Account, error) {
|
||||||
return accounts, nil
|
return accounts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) awaitTx() error {
|
func (c *InitializeContext) AwaitTx() error {
|
||||||
return c.ClientContext.AwaitTx(c.Command)
|
return c.ClientContext.AwaitTx(c.Command)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) nnsContractState() (*state.Contract, error) {
|
func (c *InitializeContext) NNSContractState() (*state.Contract, error) {
|
||||||
if c.nnsCs != nil {
|
if c.NNSCs != nil {
|
||||||
return c.nnsCs, nil
|
return c.NNSCs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
r := management.NewReader(c.ReadOnlyInvoker)
|
r := management.NewReader(c.ReadOnlyInvoker)
|
||||||
|
@ -261,16 +261,16 @@ func (c *initializeContext) nnsContractState() (*state.Contract, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c.nnsCs = cs
|
c.NNSCs = cs
|
||||||
return cs, nil
|
return cs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) getSigner(tryGroup bool, acc *wallet.Account) transaction.Signer {
|
func (c *InitializeContext) GetSigner(tryGroup bool, acc *wallet.Account) transaction.Signer {
|
||||||
if tryGroup && c.groupKey != nil {
|
if tryGroup && c.GroupKey != nil {
|
||||||
return transaction.Signer{
|
return transaction.Signer{
|
||||||
Account: acc.Contract.ScriptHash(),
|
Account: acc.Contract.ScriptHash(),
|
||||||
Scopes: transaction.CustomGroups,
|
Scopes: transaction.CustomGroups,
|
||||||
AllowedGroups: keys.PublicKeys{c.groupKey},
|
AllowedGroups: keys.PublicKeys{c.GroupKey},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -283,14 +283,14 @@ func (c *initializeContext) getSigner(tryGroup bool, acc *wallet.Account) transa
|
||||||
return signer
|
return signer
|
||||||
}
|
}
|
||||||
|
|
||||||
nnsCs, err := c.nnsContractState()
|
nnsCs, err := c.NNSContractState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return signer
|
return signer
|
||||||
}
|
}
|
||||||
|
|
||||||
groupKey, err := nnsResolveKey(c.ReadOnlyInvoker, nnsCs.Hash, morphClient.NNSGroupKeyName)
|
groupKey, err := morphUtil.NNSResolveKey(c.ReadOnlyInvoker, nnsCs.Hash, morphClient.NNSGroupKeyName)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.groupKey = groupKey
|
c.GroupKey = groupKey
|
||||||
|
|
||||||
signer.Scopes = transaction.CustomGroups
|
signer.Scopes = transaction.CustomGroups
|
||||||
signer.AllowedGroups = keys.PublicKeys{groupKey}
|
signer.AllowedGroups = keys.PublicKeys{groupKey}
|
||||||
|
@ -298,21 +298,21 @@ func (c *initializeContext) getSigner(tryGroup bool, acc *wallet.Account) transa
|
||||||
return signer
|
return signer
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendCommitteeTx creates transaction from script, signs it by committee nodes and sends it to RPC.
|
// SendCommitteeTx creates transaction from script, signs it by committee nodes and sends it to RPC.
|
||||||
// If tryGroup is false, global scope is used for the signer (useful when
|
// If tryGroup is false, global scope is used for the signer (useful when
|
||||||
// working with native contracts).
|
// working with native contracts).
|
||||||
func (c *initializeContext) sendCommitteeTx(script []byte, tryGroup bool) error {
|
func (c *InitializeContext) SendCommitteeTx(script []byte, tryGroup bool) error {
|
||||||
return c.sendMultiTx(script, tryGroup, false)
|
return c.sendMultiTx(script, tryGroup, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendConsensusTx creates transaction from script, signs it by alphabet nodes and sends it to RPC.
|
// SendConsensusTx creates transaction from script, signs it by alphabet nodes and sends it to RPC.
|
||||||
// Not that because this is used only after the contracts were initialized and deployed,
|
// Not that because this is used only after the contracts were initialized and deployed,
|
||||||
// we always try to have a group scope.
|
// we always try to have a group scope.
|
||||||
func (c *initializeContext) sendConsensusTx(script []byte) error {
|
func (c *InitializeContext) SendConsensusTx(script []byte) error {
|
||||||
return c.sendMultiTx(script, true, true)
|
return c.sendMultiTx(script, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) sendMultiTx(script []byte, tryGroup bool, withConsensus bool) error {
|
func (c *InitializeContext) sendMultiTx(script []byte, tryGroup bool, withConsensus bool) error {
|
||||||
var act *actor.Actor
|
var act *actor.Actor
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -321,12 +321,12 @@ func (c *initializeContext) sendMultiTx(script []byte, tryGroup bool, withConsen
|
||||||
// Even for consensus signatures we need the committee to pay.
|
// Even for consensus signatures we need the committee to pay.
|
||||||
signers := make([]actor.SignerAccount, 1, 2)
|
signers := make([]actor.SignerAccount, 1, 2)
|
||||||
signers[0] = actor.SignerAccount{
|
signers[0] = actor.SignerAccount{
|
||||||
Signer: c.getSigner(tryGroup, c.CommitteeAcc),
|
Signer: c.GetSigner(tryGroup, c.CommitteeAcc),
|
||||||
Account: c.CommitteeAcc,
|
Account: c.CommitteeAcc,
|
||||||
}
|
}
|
||||||
if withConsensus {
|
if withConsensus {
|
||||||
signers = append(signers, actor.SignerAccount{
|
signers = append(signers, actor.SignerAccount{
|
||||||
Signer: c.getSigner(tryGroup, c.ConsensusAcc),
|
Signer: c.GetSigner(tryGroup, c.ConsensusAcc),
|
||||||
Account: c.ConsensusAcc,
|
Account: c.ConsensusAcc,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -346,11 +346,11 @@ func (c *initializeContext) sendMultiTx(script []byte, tryGroup bool, withConsen
|
||||||
return fmt.Errorf("could not perform test invocation: %w", err)
|
return fmt.Errorf("could not perform test invocation: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.multiSign(tx, morphUtil.CommitteeAccountName); err != nil {
|
if err := c.MultiSign(tx, morphUtil.CommitteeAccountName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if withConsensus {
|
if withConsensus {
|
||||||
if err := c.multiSign(tx, morphUtil.ConsensusAccountName); err != nil {
|
if err := c.MultiSign(tx, morphUtil.ConsensusAccountName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
@ -22,12 +21,11 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
io2 "github.com/nspcc-dev/neo-go/pkg/io"
|
io2 "github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/actor"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||||
"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"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
|
@ -66,24 +64,16 @@ var (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
type contractState struct {
|
|
||||||
NEF *nef.File
|
|
||||||
RawNEF []byte
|
|
||||||
Manifest *manifest.Manifest
|
|
||||||
RawManifest []byte
|
|
||||||
Hash util.Uint160
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
updateMethodName = "update"
|
updateMethodName = "update"
|
||||||
deployMethodName = "deploy"
|
deployMethodName = "deploy"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *initializeContext) deployNNS(method string) error {
|
func deployNNS(c *InitializeContext, method string) error {
|
||||||
cs := c.getContract(morphUtil.NNSContract)
|
cs := c.GetContract(morphUtil.NNSContract)
|
||||||
h := cs.Hash
|
h := cs.Hash
|
||||||
|
|
||||||
nnsCs, err := c.nnsContractState()
|
nnsCs, err := c.NNSContractState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -99,7 +89,7 @@ func (c *initializeContext) deployNNS(method string) error {
|
||||||
h = nnsCs.Hash
|
h = nnsCs.Hash
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.addManifestGroup(h, cs)
|
err = addManifestGroup(c.ContractWallet, h, cs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't sign manifest group: %v", err)
|
return fmt.Errorf("can't sign manifest group: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -116,17 +106,17 @@ func (c *initializeContext) deployNNS(method string) error {
|
||||||
return fmt.Errorf("failed to create deploy tx for %s: %w", morphUtil.NNSContract, err)
|
return fmt.Errorf("failed to create deploy tx for %s: %w", morphUtil.NNSContract, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.multiSignAndSend(tx, morphUtil.CommitteeAccountName); err != nil {
|
if err := c.MultiSignAndSend(tx, morphUtil.CommitteeAccountName); err != nil {
|
||||||
return fmt.Errorf("can't send deploy transaction: %w", err)
|
return fmt.Errorf("can't send deploy transaction: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) updateContracts() error {
|
func updateContractsInternal(c *InitializeContext) error {
|
||||||
alphaCs := c.getContract(morphUtil.AlphabetContract)
|
alphaCs := c.GetContract(morphUtil.AlphabetContract)
|
||||||
|
|
||||||
nnsCs, err := c.nnsContractState()
|
nnsCs, err := c.NNSContractState()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -147,19 +137,19 @@ func (c *initializeContext) updateContracts() error {
|
||||||
emit.Bytes(w.BinWriter, alphaCs.RawNEF)
|
emit.Bytes(w.BinWriter, alphaCs.RawNEF)
|
||||||
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
||||||
|
|
||||||
keysParam, err := c.deployAlphabetAccounts(nnsHash, w, alphaCs)
|
keysParam, err := deployAlphabetAccounts(c, nnsHash, w, alphaCs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Reset()
|
w.Reset()
|
||||||
|
|
||||||
if err = c.deployOrUpdateContracts(w, nnsHash, keysParam); err != nil {
|
if err = deployOrUpdateContracts(c, w, nnsHash, keysParam); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
|
groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
|
||||||
_, _, err = c.emitUpdateNNSGroupScript(w, nnsHash, groupKey)
|
_, _, err = c.EmitUpdateNNSGroupScript(w, nnsHash, groupKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -170,20 +160,20 @@ func (c *initializeContext) updateContracts() error {
|
||||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||||
emit.AppCallNoArgs(w.BinWriter, nnsHash, "setPrice", callflag.All)
|
emit.AppCallNoArgs(w.BinWriter, nnsHash, "setPrice", callflag.All)
|
||||||
|
|
||||||
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
if err := c.SendCommitteeTx(w.Bytes(), false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash util.Uint160, keysParam []any) error {
|
func deployOrUpdateContracts(c *InitializeContext, w *io2.BufBinWriter, nnsHash util.Uint160, keysParam []any) error {
|
||||||
emit.Instruction(w.BinWriter, opcode.INITSSLOT, []byte{1})
|
emit.Instruction(w.BinWriter, opcode.INITSSLOT, []byte{1})
|
||||||
emit.AppCall(w.BinWriter, nnsHash, "getPrice", callflag.All)
|
emit.AppCall(w.BinWriter, nnsHash, "getPrice", callflag.All)
|
||||||
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
emit.Opcodes(w.BinWriter, opcode.STSFLD0)
|
||||||
emit.AppCall(w.BinWriter, nnsHash, "setPrice", callflag.All, 1)
|
emit.AppCall(w.BinWriter, nnsHash, "setPrice", callflag.All, 1)
|
||||||
|
|
||||||
for _, ctrName := range contractList {
|
for _, ctrName := range contractList {
|
||||||
cs := c.getContract(ctrName)
|
cs := c.GetContract(ctrName)
|
||||||
|
|
||||||
method := updateMethodName
|
method := updateMethodName
|
||||||
ctrHash, err := morphUtil.NNSResolveHash(c.ReadOnlyInvoker, nnsHash, morphUtil.DomainOf(ctrName))
|
ctrHash, err := morphUtil.NNSResolveHash(c.ReadOnlyInvoker, nnsHash, morphUtil.DomainOf(ctrName))
|
||||||
|
@ -196,7 +186,7 @@ func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = c.addManifestGroup(ctrHash, cs)
|
err = addManifestGroup(c.ContractWallet, ctrHash, cs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't sign manifest group: %v", err)
|
return fmt.Errorf("can't sign manifest group: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -206,7 +196,7 @@ func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash
|
||||||
invokeHash = ctrHash
|
invokeHash = ctrHash
|
||||||
}
|
}
|
||||||
|
|
||||||
args, err := c.getContractDeployData(ctrName, keysParam, updateMethodName)
|
args, err := getContractDeployData(c, ctrName, keysParam, updateMethodName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: getting update params: %v", ctrName, err)
|
return fmt.Errorf("%s: getting update params: %v", ctrName, err)
|
||||||
}
|
}
|
||||||
|
@ -223,9 +213,9 @@ func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash
|
||||||
w.WriteBytes(res.Script)
|
w.WriteBytes(res.Script)
|
||||||
|
|
||||||
if method == deployMethodName {
|
if method == deployMethodName {
|
||||||
// same actions are done in initializeContext.setNNS, can be unified
|
// same actions are done in InitializeContext.setNNS, can be unified
|
||||||
domain := ctrName + ".frostfs"
|
domain := ctrName + ".frostfs"
|
||||||
script, ok, err := c.nnsRegisterDomainScript(nnsHash, cs.Hash, domain)
|
script, ok, err := c.NNSRegisterDomainScript(nnsHash, cs.Hash, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -243,7 +233,7 @@ func (c *initializeContext) deployOrUpdateContracts(w *io2.BufBinWriter, nnsHash
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) deployAlphabetAccounts(nnsHash util.Uint160, w *io2.BufBinWriter, alphaCs *contractState) ([]any, error) {
|
func deployAlphabetAccounts(c *InitializeContext, nnsHash util.Uint160, w *io2.BufBinWriter, alphaCs *morphUtil.ContractState) ([]any, error) {
|
||||||
var keysParam []any
|
var keysParam []any
|
||||||
|
|
||||||
baseGroups := alphaCs.Manifest.Groups
|
baseGroups := alphaCs.Manifest.Groups
|
||||||
|
@ -257,11 +247,11 @@ func (c *initializeContext) deployAlphabetAccounts(nnsHash util.Uint160, w *io2.
|
||||||
|
|
||||||
keysParam = append(keysParam, acc.PrivateKey().PublicKey().Bytes())
|
keysParam = append(keysParam, acc.PrivateKey().PublicKey().Bytes())
|
||||||
|
|
||||||
params := c.getAlphabetDeployItems(i, len(c.Wallets))
|
params := c.GetAlphabetDeployItems(i, len(c.Wallets))
|
||||||
emit.Array(w.BinWriter, params...)
|
emit.Array(w.BinWriter, params...)
|
||||||
|
|
||||||
alphaCs.Manifest.Groups = baseGroups
|
alphaCs.Manifest.Groups = baseGroups
|
||||||
err = c.addManifestGroup(ctrHash, alphaCs)
|
err = addManifestGroup(c.ContractWallet, ctrHash, alphaCs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't sign manifest group: %v", err)
|
return nil, fmt.Errorf("can't sign manifest group: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -272,7 +262,7 @@ func (c *initializeContext) deployAlphabetAccounts(nnsHash util.Uint160, w *io2.
|
||||||
emit.Opcodes(w.BinWriter, opcode.PACK)
|
emit.Opcodes(w.BinWriter, opcode.PACK)
|
||||||
emit.AppCallNoArgs(w.BinWriter, ctrHash, updateMethodName, callflag.All)
|
emit.AppCallNoArgs(w.BinWriter, ctrHash, updateMethodName, callflag.All)
|
||||||
}
|
}
|
||||||
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
if err := c.SendCommitteeTx(w.Bytes(), false); err != nil {
|
||||||
if !strings.Contains(err.Error(), common.ErrAlreadyUpdated) {
|
if !strings.Contains(err.Error(), common.ErrAlreadyUpdated) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -282,8 +272,8 @@ func (c *initializeContext) deployAlphabetAccounts(nnsHash util.Uint160, w *io2.
|
||||||
return keysParam, nil
|
return keysParam, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) deployContracts() error {
|
func deployContracts(c *InitializeContext) error {
|
||||||
alphaCs := c.getContract(morphUtil.AlphabetContract)
|
alphaCs := c.GetContract(morphUtil.AlphabetContract)
|
||||||
|
|
||||||
var keysParam []any
|
var keysParam []any
|
||||||
|
|
||||||
|
@ -292,19 +282,19 @@ func (c *initializeContext) deployContracts() error {
|
||||||
// alphabet contracts should be deployed by individual nodes to get different hashes.
|
// alphabet contracts should be deployed by individual nodes to get different hashes.
|
||||||
for i, acc := range c.Accounts {
|
for i, acc := range c.Accounts {
|
||||||
ctrHash := state.CreateContractHash(acc.Contract.ScriptHash(), alphaCs.NEF.Checksum, alphaCs.Manifest.Name)
|
ctrHash := state.CreateContractHash(acc.Contract.ScriptHash(), alphaCs.NEF.Checksum, alphaCs.Manifest.Name)
|
||||||
if c.isUpdated(ctrHash, alphaCs) {
|
if c.IsUpdated(ctrHash, alphaCs) {
|
||||||
c.Command.Printf("Alphabet contract #%d is already deployed.\n", i)
|
c.Command.Printf("Alphabet contract #%d is already deployed.\n", i)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
alphaCs.Manifest.Groups = baseGroups
|
alphaCs.Manifest.Groups = baseGroups
|
||||||
err := c.addManifestGroup(ctrHash, alphaCs)
|
err := addManifestGroup(c.ContractWallet, ctrHash, alphaCs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't sign manifest group: %v", err)
|
return fmt.Errorf("can't sign manifest group: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
keysParam = append(keysParam, acc.PrivateKey().PublicKey().Bytes())
|
keysParam = append(keysParam, acc.PrivateKey().PublicKey().Bytes())
|
||||||
params := getContractDeployParameters(alphaCs, c.getAlphabetDeployItems(i, len(c.Wallets)))
|
params := getContractDeployParameters(alphaCs, c.GetAlphabetDeployItems(i, len(c.Wallets)))
|
||||||
|
|
||||||
act, err := actor.NewSimple(c.Client, acc)
|
act, err := actor.NewSimple(c.Client, acc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -320,20 +310,20 @@ func (c *initializeContext) deployContracts() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ctrName := range contractList {
|
for _, ctrName := range contractList {
|
||||||
cs := c.getContract(ctrName)
|
cs := c.GetContract(ctrName)
|
||||||
|
|
||||||
ctrHash := cs.Hash
|
ctrHash := cs.Hash
|
||||||
if c.isUpdated(ctrHash, cs) {
|
if c.IsUpdated(ctrHash, cs) {
|
||||||
c.Command.Printf("%s contract is already deployed.\n", ctrName)
|
c.Command.Printf("%s contract is already deployed.\n", ctrName)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
err := c.addManifestGroup(ctrHash, cs)
|
err := addManifestGroup(c.ContractWallet, ctrHash, cs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't sign manifest group: %v", err)
|
return fmt.Errorf("can't sign manifest group: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
args, err := c.getContractDeployData(ctrName, keysParam, deployMethodName)
|
args, err := getContractDeployData(c, ctrName, keysParam, deployMethodName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s: getting deploy params: %v", ctrName, err)
|
return fmt.Errorf("%s: getting deploy params: %v", ctrName, err)
|
||||||
}
|
}
|
||||||
|
@ -343,25 +333,25 @@ func (c *initializeContext) deployContracts() error {
|
||||||
return fmt.Errorf("can't deploy %s contract: %w", ctrName, err)
|
return fmt.Errorf("can't deploy %s contract: %w", ctrName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.sendCommitteeTx(res.Script, false); err != nil {
|
if err := c.SendCommitteeTx(res.Script, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) isUpdated(ctrHash util.Uint160, cs *contractState) bool {
|
func (c *InitializeContext) IsUpdated(ctrHash util.Uint160, cs *morphUtil.ContractState) bool {
|
||||||
r := management.NewReader(c.ReadOnlyInvoker)
|
r := management.NewReader(c.ReadOnlyInvoker)
|
||||||
realCs, err := r.GetContract(ctrHash)
|
realCs, err := r.GetContract(ctrHash)
|
||||||
return err == nil && realCs != nil && realCs.NEF.Checksum == cs.NEF.Checksum
|
return err == nil && realCs != nil && realCs.NEF.Checksum == cs.NEF.Checksum
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) getContract(ctrName string) *contractState {
|
func (c *InitializeContext) GetContract(ctrName string) *morphUtil.ContractState {
|
||||||
return c.Contracts[ctrName]
|
return c.Contracts[ctrName]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) readContracts(names []string) error {
|
func (c *InitializeContext) readContracts(names []string) error {
|
||||||
var (
|
var (
|
||||||
fi os.FileInfo
|
fi os.FileInfo
|
||||||
err error
|
err error
|
||||||
|
@ -401,7 +391,7 @@ func (c *initializeContext) readContracts(names []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, name := range names {
|
for _, name := range names {
|
||||||
if err := m[name].parse(); err != nil {
|
if err := m[name].Parse(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.Contracts[name] = m[name]
|
c.Contracts[name] = m[name]
|
||||||
|
@ -418,7 +408,7 @@ func (c *initializeContext) readContracts(names []string) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func readContract(ctrPath, ctrName string) (*contractState, error) {
|
func readContract(ctrPath, ctrName string) (*morphUtil.ContractState, error) {
|
||||||
rawNef, err := os.ReadFile(filepath.Join(ctrPath, ctrName+"_contract.nef"))
|
rawNef, err := os.ReadFile(filepath.Join(ctrPath, ctrName+"_contract.nef"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't read NEF file for %s contract: %w", ctrName, err)
|
return nil, fmt.Errorf("can't read NEF file for %s contract: %w", ctrName, err)
|
||||||
|
@ -428,34 +418,18 @@ func readContract(ctrPath, ctrName string) (*contractState, error) {
|
||||||
return nil, fmt.Errorf("can't read manifest file for %s contract: %w", ctrName, err)
|
return nil, fmt.Errorf("can't read manifest file for %s contract: %w", ctrName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := &contractState{
|
cs := &morphUtil.ContractState{
|
||||||
RawNEF: rawNef,
|
RawNEF: rawNef,
|
||||||
RawManifest: rawManif,
|
RawManifest: rawManif,
|
||||||
}
|
}
|
||||||
|
|
||||||
return cs, cs.parse()
|
return cs, cs.Parse()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cs *contractState) parse() error {
|
func readContractsFromArchive(file io.Reader, names []string) (map[string]*morphUtil.ContractState, error) {
|
||||||
nf, err := nef.FileFromBytes(cs.RawNEF)
|
m := make(map[string]*morphUtil.ContractState, len(names))
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("can't parse NEF file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
m := new(manifest.Manifest)
|
|
||||||
if err := json.Unmarshal(cs.RawManifest, m); err != nil {
|
|
||||||
return fmt.Errorf("can't parse manifest file: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cs.NEF = &nf
|
|
||||||
cs.Manifest = m
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readContractsFromArchive(file io.Reader, names []string) (map[string]*contractState, error) {
|
|
||||||
m := make(map[string]*contractState, len(names))
|
|
||||||
for i := range names {
|
for i := range names {
|
||||||
m[names[i]] = new(contractState)
|
m[names[i]] = new(morphUtil.ContractState)
|
||||||
}
|
}
|
||||||
|
|
||||||
gr, err := gzip.NewReader(file)
|
gr, err := gzip.NewReader(file)
|
||||||
|
@ -503,11 +477,11 @@ func readContractsFromArchive(file io.Reader, names []string) (map[string]*contr
|
||||||
return m, nil
|
return m, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getContractDeployParameters(cs *contractState, deployData []any) []any {
|
func getContractDeployParameters(cs *morphUtil.ContractState, deployData []any) []any {
|
||||||
return []any{cs.RawNEF, cs.RawManifest, deployData}
|
return []any{cs.RawNEF, cs.RawManifest, deployData}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) getContractDeployData(ctrName string, keysParam []any, method string) ([]any, error) {
|
func getContractDeployData(c *InitializeContext, ctrName string, keysParam []any, method string) ([]any, error) {
|
||||||
items := make([]any, 0, 6)
|
items := make([]any, 0, 6)
|
||||||
|
|
||||||
switch ctrName {
|
switch ctrName {
|
||||||
|
@ -544,7 +518,7 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
if method == updateMethodName {
|
if method == updateMethodName {
|
||||||
h, found, err = c.getFrostfsIDAdminFromContract()
|
h, found, err = getFrostfsIDAdminFromContract(c.ReadOnlyInvoker)
|
||||||
}
|
}
|
||||||
if method != updateMethodName || err == nil && !found {
|
if method != updateMethodName || err == nil && !found {
|
||||||
h, found, err = getFrostfsIDAdmin(viper.GetViper())
|
h, found, err = getFrostfsIDAdmin(viper.GetViper())
|
||||||
|
@ -561,7 +535,7 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an
|
||||||
case morphUtil.NetmapContract:
|
case morphUtil.NetmapContract:
|
||||||
md := getDefaultNetmapContractConfigMap()
|
md := getDefaultNetmapContractConfigMap()
|
||||||
if method == updateMethodName {
|
if method == updateMethodName {
|
||||||
if err := c.mergeNetmapConfig(md); err != nil {
|
if err := mergeNetmapConfig(c.ReadOnlyInvoker, md); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -586,17 +560,17 @@ func (c *initializeContext) getContractDeployData(ctrName string, keysParam []an
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) getFrostfsIDAdminFromContract() (util.Uint160, bool, error) {
|
func getFrostfsIDAdminFromContract(roInvoker *invoker.Invoker) (util.Uint160, bool, error) {
|
||||||
r := management.NewReader(c.ReadOnlyInvoker)
|
r := management.NewReader(roInvoker)
|
||||||
cs, err := r.GetContractByID(1)
|
cs, err := r.GetContractByID(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.Uint160{}, false, fmt.Errorf("get nns contract: %w", err)
|
return util.Uint160{}, false, fmt.Errorf("get nns contract: %w", err)
|
||||||
}
|
}
|
||||||
fidHash, err := morphUtil.NNSResolveHash(c.ReadOnlyInvoker, cs.Hash, morphUtil.DomainOf(morphUtil.FrostfsIDContract))
|
fidHash, err := morphUtil.NNSResolveHash(roInvoker, cs.Hash, morphUtil.DomainOf(morphUtil.FrostfsIDContract))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.Uint160{}, false, fmt.Errorf("resolve frostfsid contract hash: %w", err)
|
return util.Uint160{}, false, fmt.Errorf("resolve frostfsid contract hash: %w", err)
|
||||||
}
|
}
|
||||||
item, err := unwrap.Item(c.ReadOnlyInvoker.Call(fidHash, "getAdmin"))
|
item, err := unwrap.Item(roInvoker.Call(fidHash, "getAdmin"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.Uint160{}, false, fmt.Errorf("getAdmin: %w", err)
|
return util.Uint160{}, false, fmt.Errorf("getAdmin: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -615,25 +589,25 @@ func (c *initializeContext) getFrostfsIDAdminFromContract() (util.Uint160, bool,
|
||||||
return h, true, nil
|
return h, true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) getNetConfigFromNetmapContract() ([]stackitem.Item, error) {
|
func getNetConfigFromNetmapContract(roInvoker *invoker.Invoker) ([]stackitem.Item, error) {
|
||||||
r := management.NewReader(c.ReadOnlyInvoker)
|
r := management.NewReader(roInvoker)
|
||||||
cs, err := r.GetContractByID(1)
|
cs, err := r.GetContractByID(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get nns contract: %w", err)
|
return nil, fmt.Errorf("get nns contract: %w", err)
|
||||||
}
|
}
|
||||||
nmHash, err := morphUtil.NNSResolveHash(c.ReadOnlyInvoker, cs.Hash, morphUtil.DomainOf(morphUtil.NetmapContract))
|
nmHash, err := morphUtil.NNSResolveHash(roInvoker, cs.Hash, morphUtil.DomainOf(morphUtil.NetmapContract))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't get netmap contract hash: %w", err)
|
return nil, fmt.Errorf("can't get netmap contract hash: %w", err)
|
||||||
}
|
}
|
||||||
arr, err := unwrap.Array(c.ReadOnlyInvoker.Call(nmHash, "listConfig"))
|
arr, err := unwrap.Array(roInvoker.Call(nmHash, "listConfig"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("can't fetch list of network config keys from the netmap contract")
|
return nil, fmt.Errorf("can't fetch list of network config keys from the netmap contract")
|
||||||
}
|
}
|
||||||
return arr, err
|
return arr, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) mergeNetmapConfig(md map[string]any) error {
|
func mergeNetmapConfig(roInvoker *invoker.Invoker, md map[string]any) error {
|
||||||
arr, err := c.getNetConfigFromNetmapContract()
|
arr, err := getNetConfigFromNetmapContract(roInvoker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -652,7 +626,7 @@ func (c *initializeContext) mergeNetmapConfig(md map[string]any) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) getAlphabetDeployItems(i, n int) []any {
|
func (c *InitializeContext) GetAlphabetDeployItems(i, n int) []any {
|
||||||
items := make([]any, 5)
|
items := make([]any, 5)
|
||||||
items[0] = c.Contracts[morphUtil.NetmapContract].Hash
|
items[0] = c.Contracts[morphUtil.NetmapContract].Hash
|
||||||
items[1] = c.Contracts[morphUtil.ProxyContract].Hash
|
items[1] = c.Contracts[morphUtil.ProxyContract].Hash
|
||||||
|
|
|
@ -14,16 +14,11 @@ import (
|
||||||
"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/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/io"
|
"github.com/nspcc-dev/neo-go/pkg/io"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/management"
|
||||||
nnsClient "github.com/nspcc-dev/neo-go/pkg/rpcclient/nns"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/callflag"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
"github.com/nspcc-dev/neo-go/pkg/vm/opcode"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -31,14 +26,14 @@ const defaultExpirationTime = 10 * 365 * 24 * time.Hour / time.Second
|
||||||
|
|
||||||
const frostfsOpsEmail = "ops@frostfs.info"
|
const frostfsOpsEmail = "ops@frostfs.info"
|
||||||
|
|
||||||
func (c *initializeContext) setNNS() error {
|
func setNNS(c *InitializeContext) error {
|
||||||
r := management.NewReader(c.ReadOnlyInvoker)
|
r := management.NewReader(c.ReadOnlyInvoker)
|
||||||
nnsCs, err := r.GetContractByID(1)
|
nnsCs, err := r.GetContractByID(1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ok, err := c.nnsRootRegistered(nnsCs.Hash, "frostfs")
|
ok, err := c.NNSRootRegistered(nnsCs.Hash, "frostfs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
} else if !ok {
|
} else if !ok {
|
||||||
|
@ -47,48 +42,48 @@ func (c *initializeContext) setNNS() error {
|
||||||
"frostfs", c.CommitteeAcc.Contract.ScriptHash(),
|
"frostfs", c.CommitteeAcc.Contract.ScriptHash(),
|
||||||
frostfsOpsEmail, int64(3600), int64(600), int64(defaultExpirationTime), int64(3600))
|
frostfsOpsEmail, int64(3600), int64(600), int64(defaultExpirationTime), int64(3600))
|
||||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||||
if err := c.sendCommitteeTx(bw.Bytes(), true); err != nil {
|
if err := c.SendCommitteeTx(bw.Bytes(), true); err != nil {
|
||||||
return fmt.Errorf("can't add domain root to NNS: %w", err)
|
return fmt.Errorf("can't add domain root to NNS: %w", err)
|
||||||
}
|
}
|
||||||
if err := c.awaitTx(); err != nil {
|
if err := c.AwaitTx(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
alphaCs := c.getContract(morphUtil.AlphabetContract)
|
alphaCs := c.GetContract(morphUtil.AlphabetContract)
|
||||||
for i, acc := range c.Accounts {
|
for i, acc := range c.Accounts {
|
||||||
alphaCs.Hash = state.CreateContractHash(acc.Contract.ScriptHash(), alphaCs.NEF.Checksum, alphaCs.Manifest.Name)
|
alphaCs.Hash = state.CreateContractHash(acc.Contract.ScriptHash(), alphaCs.NEF.Checksum, alphaCs.Manifest.Name)
|
||||||
|
|
||||||
domain := getAlphabetNNSDomain(i)
|
domain := getAlphabetNNSDomain(i)
|
||||||
if err := c.nnsRegisterDomain(nnsCs.Hash, alphaCs.Hash, domain); err != nil {
|
if err := nnsRegisterDomain(c, nnsCs.Hash, alphaCs.Hash, domain); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.Command.Printf("NNS: Set %s -> %s\n", domain, alphaCs.Hash.StringLE())
|
c.Command.Printf("NNS: Set %s -> %s\n", domain, alphaCs.Hash.StringLE())
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ctrName := range contractList {
|
for _, ctrName := range contractList {
|
||||||
cs := c.getContract(ctrName)
|
cs := c.GetContract(ctrName)
|
||||||
|
|
||||||
domain := ctrName + ".frostfs"
|
domain := ctrName + ".frostfs"
|
||||||
if err := c.nnsRegisterDomain(nnsCs.Hash, cs.Hash, domain); err != nil {
|
if err := nnsRegisterDomain(c, nnsCs.Hash, cs.Hash, domain); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE())
|
c.Command.Printf("NNS: Set %s -> %s\n", domain, cs.Hash.StringLE())
|
||||||
}
|
}
|
||||||
|
|
||||||
groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
|
groupKey := c.ContractWallet.Accounts[0].PrivateKey().PublicKey()
|
||||||
err = c.updateNNSGroup(nnsCs.Hash, groupKey)
|
err = updateNNSGroup(c, nnsCs.Hash, groupKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
c.Command.Printf("NNS: Set %s -> %s\n", morphClient.NNSGroupKeyName, hex.EncodeToString(groupKey.Bytes()))
|
c.Command.Printf("NNS: Set %s -> %s\n", morphClient.NNSGroupKeyName, hex.EncodeToString(groupKey.Bytes()))
|
||||||
|
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) updateNNSGroup(nnsHash util.Uint160, pub *keys.PublicKey) error {
|
func updateNNSGroup(c *InitializeContext, nnsHash util.Uint160, pub *keys.PublicKey) error {
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
keyAlreadyAdded, domainRegCodeEmitted, err := c.emitUpdateNNSGroupScript(bw, nnsHash, pub)
|
keyAlreadyAdded, domainRegCodeEmitted, err := c.EmitUpdateNNSGroupScript(bw, nnsHash, pub)
|
||||||
if keyAlreadyAdded || err != nil {
|
if keyAlreadyAdded || err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -101,20 +96,20 @@ func (c *initializeContext) updateNNSGroup(nnsHash util.Uint160, pub *keys.Publi
|
||||||
script = w.Bytes()
|
script = w.Bytes()
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.sendCommitteeTx(script, true)
|
return c.SendCommitteeTx(script, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// emitUpdateNNSGroupScript emits script for updating group key stored in NNS.
|
// EmitUpdateNNSGroupScript emits script for updating group key stored in NNS.
|
||||||
// First return value is true iff the key is already there and nothing should be done.
|
// First return value is true iff the key is already there and nothing should be done.
|
||||||
// Second return value is true iff a domain registration code was emitted.
|
// Second return value is true iff a domain registration code was emitted.
|
||||||
func (c *initializeContext) emitUpdateNNSGroupScript(bw *io.BufBinWriter, nnsHash util.Uint160, pub *keys.PublicKey) (bool, bool, error) {
|
func (c *InitializeContext) EmitUpdateNNSGroupScript(bw *io.BufBinWriter, nnsHash util.Uint160, pub *keys.PublicKey) (bool, bool, error) {
|
||||||
isAvail, err := nnsIsAvailable(c.Client, nnsHash, morphClient.NNSGroupKeyName)
|
isAvail, err := morphUtil.NNSIsAvailable(c.Client, nnsHash, morphClient.NNSGroupKeyName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, false, err
|
return false, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isAvail {
|
if !isAvail {
|
||||||
currentPub, err := nnsResolveKey(c.ReadOnlyInvoker, nnsHash, morphClient.NNSGroupKeyName)
|
currentPub, err := morphUtil.NNSResolveKey(c.ReadOnlyInvoker, nnsHash, morphClient.NNSGroupKeyName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, false, err
|
return false, false, err
|
||||||
}
|
}
|
||||||
|
@ -165,8 +160,8 @@ func wrapRegisterScriptWithPrice(w *io.BufBinWriter, nnsHash util.Uint160, s []b
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) nnsRegisterDomainScript(nnsHash, expectedHash util.Uint160, domain string) ([]byte, bool, error) {
|
func (c *InitializeContext) NNSRegisterDomainScript(nnsHash, expectedHash util.Uint160, domain string) ([]byte, bool, error) {
|
||||||
ok, err := nnsIsAvailable(c.Client, nnsHash, domain)
|
ok, err := morphUtil.NNSIsAvailable(c.Client, nnsHash, domain)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
}
|
}
|
||||||
|
@ -191,8 +186,8 @@ func (c *initializeContext) nnsRegisterDomainScript(nnsHash, expectedHash util.U
|
||||||
return nil, s == expectedHash, nil
|
return nil, s == expectedHash, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) nnsRegisterDomain(nnsHash, expectedHash util.Uint160, domain string) error {
|
func nnsRegisterDomain(c *InitializeContext, nnsHash, expectedHash util.Uint160, domain string) error {
|
||||||
script, ok, err := c.nnsRegisterDomainScript(nnsHash, expectedHash, domain)
|
script, ok, err := c.NNSRegisterDomainScript(nnsHash, expectedHash, domain)
|
||||||
if ok || err != nil {
|
if ok || err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -206,10 +201,10 @@ func (c *initializeContext) nnsRegisterDomain(nnsHash, expectedHash util.Uint160
|
||||||
domain, int64(nns.TXT), expectedHash.StringLE())
|
domain, int64(nns.TXT), expectedHash.StringLE())
|
||||||
emit.AppCall(w.BinWriter, nnsHash, "addRecord", callflag.All,
|
emit.AppCall(w.BinWriter, nnsHash, "addRecord", callflag.All,
|
||||||
domain, int64(nns.TXT), address.Uint160ToString(expectedHash))
|
domain, int64(nns.TXT), address.Uint160ToString(expectedHash))
|
||||||
return c.sendCommitteeTx(w.Bytes(), true)
|
return c.SendCommitteeTx(w.Bytes(), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) nnsRootRegistered(nnsHash util.Uint160, zone string) (bool, error) {
|
func (c *InitializeContext) NNSRootRegistered(nnsHash util.Uint160, zone string) (bool, error) {
|
||||||
res, err := c.CommitteeAct.Call(nnsHash, "isAvailable", "name."+zone)
|
res, err := c.CommitteeAct.Call(nnsHash, "isAvailable", "name."+zone)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
@ -219,43 +214,3 @@ func (c *initializeContext) nnsRootRegistered(nnsHash util.Uint160, zone string)
|
||||||
}
|
}
|
||||||
|
|
||||||
var errMissingNNSRecord = errors.New("missing NNS record")
|
var errMissingNNSRecord = errors.New("missing NNS record")
|
||||||
|
|
||||||
func nnsResolveKey(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) {
|
|
||||||
res, err := morphUtil.NNSResolve(inv, nnsHash, domain)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if _, ok := res.Value().(stackitem.Null); ok {
|
|
||||||
return nil, errors.New("NNS record is missing")
|
|
||||||
}
|
|
||||||
arr, ok := res.Value().([]stackitem.Item)
|
|
||||||
if !ok {
|
|
||||||
return nil, errors.New("API of the NNS contract method `resolve` has changed")
|
|
||||||
}
|
|
||||||
for i := range arr {
|
|
||||||
var bs []byte
|
|
||||||
bs, err = arr[i].TryBytes()
|
|
||||||
if err != nil {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
return keys.NewPublicKeyFromString(string(bs))
|
|
||||||
}
|
|
||||||
return nil, errors.New("no valid keys are found")
|
|
||||||
}
|
|
||||||
|
|
||||||
func nnsIsAvailable(c morphUtil.Client, nnsHash util.Uint160, name string) (bool, error) {
|
|
||||||
switch c.(type) {
|
|
||||||
case *rpcclient.Client:
|
|
||||||
inv := invoker.New(c, nil)
|
|
||||||
reader := nnsClient.NewReader(inv, nnsHash)
|
|
||||||
return reader.IsAvailable(name)
|
|
||||||
default:
|
|
||||||
b, err := unwrap.Bool(morphUtil.InvokeFunction(c, nnsHash, "isAvailable", []any{name}, nil))
|
|
||||||
if err != nil {
|
|
||||||
return false, fmt.Errorf("`isAvailable`: invalid response: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return b, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -28,8 +28,8 @@ const (
|
||||||
registerBatchSize = transaction.MaxAttributes - 1
|
registerBatchSize = transaction.MaxAttributes - 1
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *initializeContext) registerCandidateRange(start, end int) error {
|
func registerCandidateRange(c *InitializeContext, start, end int) error {
|
||||||
regPrice, err := c.getCandidateRegisterPrice()
|
regPrice, err := getCandidateRegisterPrice(c)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't fetch registration price: %w", err)
|
return fmt.Errorf("can't fetch registration price: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ func (c *initializeContext) registerCandidateRange(start, end int) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
signers := []actor.SignerAccount{{
|
signers := []actor.SignerAccount{{
|
||||||
Signer: c.getSigner(false, c.CommitteeAcc),
|
Signer: c.GetSigner(false, c.CommitteeAcc),
|
||||||
Account: c.CommitteeAcc,
|
Account: c.CommitteeAcc,
|
||||||
}}
|
}}
|
||||||
for _, acc := range c.Accounts[start:end] {
|
for _, acc := range c.Accounts[start:end] {
|
||||||
|
@ -68,7 +68,7 @@ func (c *initializeContext) registerCandidateRange(start, end int) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't create tx: %w", err)
|
return fmt.Errorf("can't create tx: %w", err)
|
||||||
}
|
}
|
||||||
if err := c.multiSign(tx, morphUtil.CommitteeAccountName); err != nil {
|
if err := c.MultiSign(tx, morphUtil.CommitteeAccountName); err != nil {
|
||||||
return fmt.Errorf("can't sign a transaction: %w", err)
|
return fmt.Errorf("can't sign a transaction: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ func (c *initializeContext) registerCandidateRange(start, end int) error {
|
||||||
return c.SendTx(tx, c.Command, true)
|
return c.SendTx(tx, c.Command, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) registerCandidates() error {
|
func registerCandidates(c *InitializeContext) error {
|
||||||
cc, err := unwrap.Array(c.ReadOnlyInvoker.Call(neo.Hash, "getCandidates"))
|
cc, err := unwrap.Array(c.ReadOnlyInvoker.Call(neo.Hash, "getCandidates"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("`getCandidates`: %w", err)
|
return fmt.Errorf("`getCandidates`: %w", err)
|
||||||
|
@ -107,7 +107,7 @@ func (c *initializeContext) registerCandidates() error {
|
||||||
if have >= end {
|
if have >= end {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err := c.registerCandidateRange(start, end); err != nil {
|
if err := registerCandidateRange(c, start, end); err != nil {
|
||||||
return fmt.Errorf("registering candidates %d..%d: %q", start, end-1, err)
|
return fmt.Errorf("registering candidates %d..%d: %q", start, end-1, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,15 +115,15 @@ func (c *initializeContext) registerCandidates() error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) transferNEOToAlphabetContracts() error {
|
func transferNEOToAlphabetContracts(c *InitializeContext) error {
|
||||||
neoHash := neo.Hash
|
neoHash := neo.Hash
|
||||||
|
|
||||||
ok, err := c.transferNEOFinished(neoHash)
|
ok, err := transferNEOFinished(c, neoHash)
|
||||||
if ok || err != nil {
|
if ok || err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := c.getContract(morphUtil.AlphabetContract)
|
cs := c.GetContract(morphUtil.AlphabetContract)
|
||||||
amount := initialAlphabetNEOAmount / len(c.Wallets)
|
amount := initialAlphabetNEOAmount / len(c.Wallets)
|
||||||
|
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
|
@ -134,14 +134,14 @@ func (c *initializeContext) transferNEOToAlphabetContracts() error {
|
||||||
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
emit.Opcodes(bw.BinWriter, opcode.ASSERT)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.sendCommitteeTx(bw.Bytes(), false); err != nil {
|
if err := c.SendCommitteeTx(bw.Bytes(), false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) transferNEOFinished(neoHash util.Uint160) (bool, error) {
|
func transferNEOFinished(c *InitializeContext, neoHash util.Uint160) (bool, error) {
|
||||||
r := nep17.NewReader(c.ReadOnlyInvoker, neoHash)
|
r := nep17.NewReader(c.ReadOnlyInvoker, neoHash)
|
||||||
bal, err := r.BalanceOf(c.CommitteeAcc.Contract.ScriptHash())
|
bal, err := r.BalanceOf(c.CommitteeAcc.Contract.ScriptHash())
|
||||||
return bal.Cmp(big.NewInt(native.NEOTotalSupply)) == -1, err
|
return bal.Cmp(big.NewInt(native.NEOTotalSupply)) == -1, err
|
||||||
|
@ -149,7 +149,7 @@ func (c *initializeContext) transferNEOFinished(neoHash util.Uint160) (bool, err
|
||||||
|
|
||||||
var errGetPriceInvalid = errors.New("`getRegisterPrice`: invalid response")
|
var errGetPriceInvalid = errors.New("`getRegisterPrice`: invalid response")
|
||||||
|
|
||||||
func (c *initializeContext) getCandidateRegisterPrice() (int64, error) {
|
func getCandidateRegisterPrice(c *InitializeContext) (int64, error) {
|
||||||
switch c.Client.(type) {
|
switch c.Client.(type) {
|
||||||
case *rpcclient.Client:
|
case *rpcclient.Client:
|
||||||
inv := invoker.New(c.Client, nil)
|
inv := invoker.New(c.Client, nil)
|
||||||
|
|
|
@ -9,8 +9,8 @@ import (
|
||||||
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
"github.com/nspcc-dev/neo-go/pkg/vm/emit"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *initializeContext) setNotaryAndAlphabetNodes() error {
|
func setNotaryAndAlphabetNodes(c *InitializeContext) error {
|
||||||
if ok, err := c.setRolesFinished(); ok || err != nil {
|
if ok, err := setRolesFinished(c); ok || err != nil {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.Command.Println("Stage 2: already performed.")
|
c.Command.Println("Stage 2: already performed.")
|
||||||
}
|
}
|
||||||
|
@ -28,14 +28,14 @@ func (c *initializeContext) setNotaryAndAlphabetNodes() error {
|
||||||
emit.AppCall(w.BinWriter, rolemgmt.Hash, "designateAsRole",
|
emit.AppCall(w.BinWriter, rolemgmt.Hash, "designateAsRole",
|
||||||
callflag.States|callflag.AllowNotify, int64(noderoles.NeoFSAlphabet), pubs)
|
callflag.States|callflag.AllowNotify, int64(noderoles.NeoFSAlphabet), pubs)
|
||||||
|
|
||||||
if err := c.sendCommitteeTx(w.Bytes(), false); err != nil {
|
if err := c.SendCommitteeTx(w.Bytes(), false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) setRolesFinished() (bool, error) {
|
func setRolesFinished(c *InitializeContext) (bool, error) {
|
||||||
height, err := c.Client.GetBlockCount()
|
height, err := c.Client.GetBlockCount()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
|
|
|
@ -28,8 +28,8 @@ const (
|
||||||
initialProxyGASAmount = 50_000 * native.GASFactor
|
initialProxyGASAmount = 50_000 * native.GASFactor
|
||||||
)
|
)
|
||||||
|
|
||||||
func (c *initializeContext) transferFunds() error {
|
func transferFunds(c *InitializeContext) error {
|
||||||
ok, err := c.transferFundsFinished()
|
ok, err := transferFundsFinished(c)
|
||||||
if ok || err != nil {
|
if ok || err != nil {
|
||||||
if err == nil {
|
if err == nil {
|
||||||
c.Command.Println("Stage 1: already performed.")
|
c.Command.Println("Stage 1: already performed.")
|
||||||
|
@ -68,14 +68,14 @@ func (c *initializeContext) transferFunds() error {
|
||||||
return fmt.Errorf("can't create transfer transaction: %w", err)
|
return fmt.Errorf("can't create transfer transaction: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.multiSignAndSend(tx, morphUtil.ConsensusAccountName); err != nil {
|
if err := c.MultiSignAndSend(tx, morphUtil.ConsensusAccountName); err != nil {
|
||||||
return fmt.Errorf("can't send transfer transaction: %w", err)
|
return fmt.Errorf("can't send transfer transaction: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) transferFundsFinished() (bool, error) {
|
func transferFundsFinished(c *InitializeContext) (bool, error) {
|
||||||
acc := c.Accounts[0]
|
acc := c.Accounts[0]
|
||||||
|
|
||||||
r := nep17.NewReader(c.ReadOnlyInvoker, gas.Hash)
|
r := nep17.NewReader(c.ReadOnlyInvoker, gas.Hash)
|
||||||
|
@ -83,15 +83,15 @@ func (c *initializeContext) transferFundsFinished() (bool, error) {
|
||||||
return res.Cmp(big.NewInt(initialAlphabetGASAmount/2)) == 1, err
|
return res.Cmp(big.NewInt(initialAlphabetGASAmount/2)) == 1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) multiSignAndSend(tx *transaction.Transaction, accType string) error {
|
func (c *InitializeContext) MultiSignAndSend(tx *transaction.Transaction, accType string) error {
|
||||||
if err := c.multiSign(tx, accType); err != nil {
|
if err := c.MultiSign(tx, accType); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.SendTx(tx, c.Command, false)
|
return c.SendTx(tx, c.Command, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) multiSign(tx *transaction.Transaction, accType string) error {
|
func (c *InitializeContext) MultiSign(tx *transaction.Transaction, accType string) error {
|
||||||
version, err := c.Client.GetVersion()
|
version, err := c.Client.GetVersion()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// error appears only if client
|
// error appears only if client
|
||||||
|
@ -143,8 +143,8 @@ func (c *initializeContext) multiSign(tx *transaction.Transaction, accType strin
|
||||||
return fmt.Errorf("%s account was not found among transaction signers", accType)
|
return fmt.Errorf("%s account was not found among transaction signers", accType)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *initializeContext) transferGASToProxy() error {
|
func transferGASToProxy(c *InitializeContext) error {
|
||||||
proxyCs := c.getContract(morphUtil.ProxyContract)
|
proxyCs := c.GetContract(morphUtil.ProxyContract)
|
||||||
|
|
||||||
r := nep17.NewReader(c.ReadOnlyInvoker, gas.Hash)
|
r := nep17.NewReader(c.ReadOnlyInvoker, gas.Hash)
|
||||||
bal, err := r.BalanceOf(proxyCs.Hash)
|
bal, err := r.BalanceOf(proxyCs.Hash)
|
||||||
|
@ -161,11 +161,11 @@ func (c *initializeContext) transferGASToProxy() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.multiSignAndSend(tx, morphUtil.CommitteeAccountName); err != nil {
|
if err := c.MultiSignAndSend(tx, morphUtil.CommitteeAccountName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.awaitTx()
|
return c.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
type transferTarget struct {
|
type transferTarget struct {
|
||||||
|
|
|
@ -25,7 +25,7 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
func setPolicyCmd(cmd *cobra.Command, args []string) error {
|
func setPolicyCmd(cmd *cobra.Command, args []string) error {
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't to initialize context: %w", err)
|
return fmt.Errorf("can't to initialize context: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -51,11 +51,11 @@ func setPolicyCmd(cmd *cobra.Command, args []string) error {
|
||||||
emit.AppCall(bw.BinWriter, policy.Hash, "set"+k, callflag.All, int64(value))
|
emit.AppCall(bw.BinWriter, policy.Hash, "set"+k, callflag.All, int64(value))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := wCtx.sendCommitteeTx(bw.Bytes(), false); err != nil {
|
if err := wCtx.SendCommitteeTx(bw.Bytes(), false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return wCtx.awaitTx()
|
return wCtx.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
||||||
func dumpPolicyCmd(cmd *cobra.Command, _ []string) error {
|
func dumpPolicyCmd(cmd *cobra.Command, _ []string) error {
|
||||||
|
|
|
@ -36,7 +36,7 @@ func removeProxyAccount(cmd *cobra.Command, _ []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func processAccount(cmd *cobra.Command, addr util.Uint160, method string) error {
|
func processAccount(cmd *cobra.Command, addr util.Uint160, method string) error {
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't to initialize context: %w", err)
|
return fmt.Errorf("can't to initialize context: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -55,11 +55,11 @@ func processAccount(cmd *cobra.Command, addr util.Uint160, method string) error
|
||||||
bw := io.NewBufBinWriter()
|
bw := io.NewBufBinWriter()
|
||||||
emit.AppCall(bw.BinWriter, proxyHash, method, callflag.All, addr)
|
emit.AppCall(bw.BinWriter, proxyHash, method, callflag.All, addr)
|
||||||
|
|
||||||
if err := wCtx.sendConsensusTx(bw.Bytes()); err != nil {
|
if err := wCtx.SendConsensusTx(bw.Bytes()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = wCtx.awaitTx(); err != nil {
|
if err = wCtx.AwaitTx(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,11 +29,11 @@ func removeNodesCmd(cmd *cobra.Command, args []string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't initialize context: %w", err)
|
return fmt.Errorf("can't initialize context: %w", err)
|
||||||
}
|
}
|
||||||
defer wCtx.close()
|
defer wCtx.Close()
|
||||||
|
|
||||||
r := management.NewReader(wCtx.ReadOnlyInvoker)
|
r := management.NewReader(wCtx.ReadOnlyInvoker)
|
||||||
cs, err := r.GetContractByID(1)
|
cs, err := r.GetContractByID(1)
|
||||||
|
@ -56,9 +56,9 @@ func removeNodesCmd(cmd *cobra.Command, args []string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := wCtx.sendConsensusTx(bw.Bytes()); err != nil {
|
if err := wCtx.SendConsensusTx(bw.Bytes()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return wCtx.awaitTx()
|
return wCtx.AwaitTx()
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,14 +8,14 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func updateContracts(cmd *cobra.Command, _ []string) error {
|
func updateContracts(cmd *cobra.Command, _ []string) error {
|
||||||
wCtx, err := newInitializeContext(cmd, viper.GetViper())
|
wCtx, err := NewInitializeContext(cmd, viper.GetViper())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("initialization error: %w", err)
|
return fmt.Errorf("initialization error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := wCtx.deployNNS(updateMethodName); err != nil {
|
if err := deployNNS(wCtx, updateMethodName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return wCtx.updateContracts()
|
return updateContractsInternal(wCtx)
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,8 +7,11 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
"git.frostfs.info/TrueCloudLab/frostfs-contract/nns"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/cmd/frostfs-adm/internal/commonflags"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
"github.com/nspcc-dev/neo-go/pkg/encoding/address"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/invoker"
|
||||||
|
nns2 "github.com/nspcc-dev/neo-go/pkg/rpcclient/nns"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/trigger"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -144,3 +147,43 @@ func NNSResolveHash(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (
|
||||||
func DomainOf(contract string) string {
|
func DomainOf(contract string) string {
|
||||||
return contract + ".frostfs"
|
return contract + ".frostfs"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NNSResolveKey(inv *invoker.Invoker, nnsHash util.Uint160, domain string) (*keys.PublicKey, error) {
|
||||||
|
res, err := NNSResolve(inv, nnsHash, domain)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, ok := res.Value().(stackitem.Null); ok {
|
||||||
|
return nil, errors.New("NNS record is missing")
|
||||||
|
}
|
||||||
|
arr, ok := res.Value().([]stackitem.Item)
|
||||||
|
if !ok {
|
||||||
|
return nil, errors.New("API of the NNS contract method `resolve` has changed")
|
||||||
|
}
|
||||||
|
for i := range arr {
|
||||||
|
var bs []byte
|
||||||
|
bs, err = arr[i].TryBytes()
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
return keys.NewPublicKeyFromString(string(bs))
|
||||||
|
}
|
||||||
|
return nil, errors.New("no valid keys are found")
|
||||||
|
}
|
||||||
|
|
||||||
|
func NNSIsAvailable(c Client, nnsHash util.Uint160, name string) (bool, error) {
|
||||||
|
switch c.(type) {
|
||||||
|
case *rpcclient.Client:
|
||||||
|
inv := invoker.New(c, nil)
|
||||||
|
reader := nns2.NewReader(inv, nnsHash)
|
||||||
|
return reader.IsAvailable(name)
|
||||||
|
default:
|
||||||
|
b, err := unwrap.Bool(InvokeFunction(c, nnsHash, "isAvailable", []any{name}, nil))
|
||||||
|
if err != nil {
|
||||||
|
return false, fmt.Errorf("`isAvailable`: invalid response: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return b, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/manifest"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/smartcontract/nef"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (cs *ContractState) Parse() error {
|
||||||
|
nf, err := nef.FileFromBytes(cs.RawNEF)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("can't parse NEF file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
m := new(manifest.Manifest)
|
||||||
|
if err := json.Unmarshal(cs.RawManifest, m); err != nil {
|
||||||
|
return fmt.Errorf("can't parse manifest file: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
cs.NEF = &nf
|
||||||
|
cs.Manifest = m
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type ContractState struct {
|
||||||
|
NEF *nef.File
|
||||||
|
RawNEF []byte
|
||||||
|
Manifest *manifest.Manifest
|
||||||
|
RawManifest []byte
|
||||||
|
Hash util.Uint160
|
||||||
|
}
|
Loading…
Reference in a new issue