forked from TrueCloudLab/frostfs-node
[#979] adm: Deploy missing contracts during updating
Make `nnsResolveHash` function to return declared error on `token not found` fault exception. Catch this error in `deployContracts` method, and switch to deployment if updating contract is missing. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
e8f8e58e90
commit
2f2ca2e0bd
3 changed files with 25 additions and 6 deletions
|
@ -57,13 +57,13 @@ func initializeSideChainCmd(cmd *cobra.Command, args []string) error {
|
||||||
|
|
||||||
// 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("deploy"); err != nil {
|
if err := initCtx.deployNNS(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("deploy"); err != nil {
|
if err := initCtx.deployContracts(deployMethodName); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"archive/tar"
|
"archive/tar"
|
||||||
"compress/gzip"
|
"compress/gzip"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
|
@ -83,7 +84,10 @@ type contractState struct {
|
||||||
Hash util.Uint160
|
Hash util.Uint160
|
||||||
}
|
}
|
||||||
|
|
||||||
const updateMethodName = "update"
|
const (
|
||||||
|
updateMethodName = "update"
|
||||||
|
deployMethodName = "deploy"
|
||||||
|
)
|
||||||
|
|
||||||
func (c *initializeContext) deployNNS(method string) error {
|
func (c *initializeContext) deployNNS(method string) error {
|
||||||
cs := c.getContract(nnsContract)
|
cs := c.getContract(nnsContract)
|
||||||
|
@ -214,19 +218,27 @@ func (c *initializeContext) deployContracts(method string) error {
|
||||||
cs := c.Contracts[ctrName]
|
cs := c.Contracts[ctrName]
|
||||||
|
|
||||||
ctrHash := cs.Hash
|
ctrHash := cs.Hash
|
||||||
|
|
||||||
|
methodCur := method // prevent overriding in if-block
|
||||||
|
|
||||||
if method == updateMethodName {
|
if method == updateMethodName {
|
||||||
ctrHash, err = nnsResolveHash(c.Client, nnsHash, ctrName+".neofs")
|
ctrHash, err = nnsResolveHash(c.Client, nnsHash, ctrName+".neofs")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if errors.Is(err, errMissingNNSRecord) {
|
||||||
|
// if contract not found we deploy it instead of update
|
||||||
|
methodCur = deployMethodName
|
||||||
|
} else {
|
||||||
return fmt.Errorf("can't resolve hash for contract update: %w", err)
|
return fmt.Errorf("can't resolve hash for contract update: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
invokeHash := mgmtHash
|
invokeHash := mgmtHash
|
||||||
if method == updateMethodName {
|
if methodCur == updateMethodName {
|
||||||
invokeHash = ctrHash
|
invokeHash = ctrHash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +249,7 @@ func (c *initializeContext) deployContracts(method string) error {
|
||||||
Scopes: transaction.Global,
|
Scopes: transaction.Global,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := c.Client.InvokeFunction(invokeHash, method, params, []transaction.Signer{signer})
|
res, err := c.Client.InvokeFunction(invokeHash, methodCur, params, []transaction.Signer{signer})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("can't deploy %s contract: %w", ctrName, err)
|
return fmt.Errorf("can't deploy %s contract: %w", ctrName, err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
nns "github.com/nspcc-dev/neo-go/examples/nft-nd-nns"
|
nns "github.com/nspcc-dev/neo-go/examples/nft-nd-nns"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
"github.com/nspcc-dev/neo-go/pkg/core/native"
|
||||||
|
@ -116,6 +117,9 @@ func (c *initializeContext) nnsRootRegistered(nnsHash util.Uint160) (bool, error
|
||||||
return res.State == vm.HaltState.String(), nil
|
return res.State == vm.HaltState.String(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var errMissingNNSRecord = errors.New("missing NNS record")
|
||||||
|
|
||||||
|
// Returns errMissingNNSRecord if invocation fault exception contains "token not found".
|
||||||
func nnsResolveHash(c *client.Client, nnsHash util.Uint160, domain string) (util.Uint160, error) {
|
func nnsResolveHash(c *client.Client, nnsHash util.Uint160, domain string) (util.Uint160, error) {
|
||||||
result, err := c.InvokeFunction(nnsHash, "resolve", []smartcontract.Parameter{
|
result, err := c.InvokeFunction(nnsHash, "resolve", []smartcontract.Parameter{
|
||||||
{
|
{
|
||||||
|
@ -131,6 +135,9 @@ func nnsResolveHash(c *client.Client, nnsHash util.Uint160, domain string) (util
|
||||||
return util.Uint160{}, fmt.Errorf("`resolve`: %w", err)
|
return util.Uint160{}, fmt.Errorf("`resolve`: %w", err)
|
||||||
}
|
}
|
||||||
if result.State != vm.HaltState.String() {
|
if result.State != vm.HaltState.String() {
|
||||||
|
if strings.Contains(result.FaultException, "token not found") {
|
||||||
|
return util.Uint160{}, errMissingNNSRecord
|
||||||
|
}
|
||||||
return util.Uint160{}, fmt.Errorf("invocation failed: %s", result.FaultException)
|
return util.Uint160{}, fmt.Errorf("invocation failed: %s", result.FaultException)
|
||||||
}
|
}
|
||||||
if len(result.Stack) == 0 {
|
if len(result.Stack) == 0 {
|
||||||
|
|
Loading…
Reference in a new issue