diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index 9c7071e5a..96dca0319 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -16,6 +16,7 @@ import ( "github.com/nspcc-dev/neo-go/pkg/crypto/keys" "github.com/nspcc-dev/neo-go/pkg/encoding/fixedn" "github.com/nspcc-dev/neo-go/pkg/neorpc" + "github.com/nspcc-dev/neo-go/pkg/neorpc/result" "github.com/nspcc-dev/neo-go/pkg/rpcclient/notary" sc "github.com/nspcc-dev/neo-go/pkg/smartcontract" "github.com/nspcc-dev/neo-go/pkg/util" @@ -446,19 +447,12 @@ func (c *Client) notaryInvokeAsCommittee(method string, nonce, vub uint32, args return c.notaryInvoke(true, true, designate, nonce, &vub, method, args...) } -// nolint: funlen func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint160, nonce uint32, vub *uint32, method string, args ...any) error { - alphabetList, err := c.notary.alphabetSource() // prepare arguments for test invocation + alphabetList, err := c.notary.alphabetSource() if err != nil { return err } - u8n := uint8(len(alphabetList)) - - if !invokedByAlpha { - u8n++ - } - cosigners, err := c.notaryCosigners(invokedByAlpha, alphabetList, committee) if err != nil { return err @@ -469,38 +463,77 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint return err } - // make test invocation of the method - test, err := c.client.InvokeFunction(contract, method, params, cosigners) + test, err := c.makeTestInvocation(contract, method, params, cosigners) if err != nil { return err } - // check invocation state - if test.State != HaltState { - return wrapFrostFSError(¬HaltStateError{state: test.State, exception: test.FaultException}) - } - - // if test invocation failed, then return error - if len(test.Script) == 0 { - return wrapFrostFSError(errEmptyInvocationScript) - } - - // after test invocation we build main multisig transaction - multiaddrAccount, err := c.notaryMultisigAccount(alphabetList, committee, invokedByAlpha) if err != nil { return err } - var until uint32 + until, err := c.getUntilValue(vub) + if err != nil { + return err + } + mainTx, err := c.buildMainTx(invokedByAlpha, nonce, alphabetList, test, cosigners, multiaddrAccount, until) + if err != nil { + return err + } + + //lint:ignore SA1019 https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/202 + resp, err := c.client.SignAndPushP2PNotaryRequest(mainTx, + []byte{byte(opcode.RET)}, + -1, + 0, + c.notary.fallbackTime, + c.acc) + if err != nil && !alreadyOnChainError(err) { + return err + } + + c.logger.Debug("notary request invoked", + zap.String("method", method), + zap.Uint32("valid_until_block", until), + zap.Uint32("fallback_valid_for", c.notary.fallbackTime), + zap.Stringer("tx_hash", resp.Hash().Reverse())) + + return nil +} + +func (c *Client) makeTestInvocation(contract util.Uint160, method string, params []sc.Parameter, cosigners []transaction.Signer) (*result.Invoke, error) { + test, err := c.client.InvokeFunction(contract, method, params, cosigners) + if err != nil { + return nil, err + } + + if test.State != HaltState { + return nil, wrapFrostFSError(¬HaltStateError{state: test.State, exception: test.FaultException}) + } + + if len(test.Script) == 0 { + return nil, wrapFrostFSError(errEmptyInvocationScript) + } + return test, nil +} + +func (c *Client) getUntilValue(vub *uint32) (uint32, error) { if vub != nil { - until = *vub - } else { - until, err = c.notaryTxValidationLimit() - if err != nil { - return err - } + return *vub, nil + } + return c.notaryTxValidationLimit() +} + +func (c *Client) buildMainTx(invokedByAlpha bool, nonce uint32, alphabetList keys.PublicKeys, test *result.Invoke, + cosigners []transaction.Signer, multiaddrAccount *wallet.Account, until uint32) (*transaction.Transaction, error) { + // after test invocation we build main multisig transaction + + u8n := uint8(len(alphabetList)) + + if !invokedByAlpha { + u8n++ } // prepare main tx @@ -522,7 +555,7 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint //lint:ignore SA1019 https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/202 notaryFee, err := c.client.CalculateNotaryFee(u8n) if err != nil { - return err + return nil, err } // add network fee for cosigners @@ -534,30 +567,13 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint c.notaryAccounts(invokedByAlpha, multiaddrAccount)..., ) if err != nil { - return err + return nil, err } // define witnesses mainTx.Scripts = c.notaryWitnesses(invokedByAlpha, multiaddrAccount, mainTx) - //lint:ignore SA1019 https://git.frostfs.info/TrueCloudLab/frostfs-node/issues/202 - resp, err := c.client.SignAndPushP2PNotaryRequest(mainTx, - []byte{byte(opcode.RET)}, - -1, - 0, - c.notary.fallbackTime, - c.acc) - if err != nil && !alreadyOnChainError(err) { - return err - } - - c.logger.Debug("notary request invoked", - zap.String("method", method), - zap.Uint32("valid_until_block", until), - zap.Uint32("fallback_valid_for", c.notary.fallbackTime), - zap.Stringer("tx_hash", resp.Hash().Reverse())) - - return nil + return mainTx, nil } func (c *Client) notaryCosigners(invokedByAlpha bool, ir []*keys.PublicKey, committee bool) ([]transaction.Signer, error) {