From 44e0124a54c5ab7210c75562ea46a48660dc78bf Mon Sep 17 00:00:00 2001 From: Pavel Karpy Date: Fri, 24 Mar 2023 06:30:02 +0300 Subject: [PATCH] wip Signed-off-by: Pavel Karpy --- .golangci.yml | 2 - pkg/morph/client/notary.go | 220 ++++++++++++++++++++----------------- 2 files changed, 122 insertions(+), 100 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index fae355a3d..4fc9500a5 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -24,8 +24,6 @@ linters-settings: govet: # report about shadowed variables check-shadowing: false - staticcheck: - checks: ["all", "-SA1019"] # TODO Enable SA1019 after deprecated warning are fixed. funlen: lines: 80 # default 60 statements: 60 # default 40 diff --git a/pkg/morph/client/notary.go b/pkg/morph/client/notary.go index 307a989fa..1582e946f 100644 --- a/pkg/morph/client/notary.go +++ b/pkg/morph/client/notary.go @@ -16,10 +16,13 @@ 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/actor" "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" "github.com/nspcc-dev/neo-go/pkg/vm/opcode" + "github.com/nspcc-dev/neo-go/pkg/vm/vmstate" "github.com/nspcc-dev/neo-go/pkg/wallet" "go.uber.org/zap" ) @@ -34,6 +37,8 @@ type ( notary util.Uint160 proxy util.Uint160 + + act notary.Actor } notaryCfg struct { @@ -462,34 +467,34 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint if err != nil { return err } - - params, err := invocationParams(args...) - if err != nil { - return err - } - - // make test invocation of the method - test, err := c.client.InvokeFunction(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 - } + // + //params, err := invocationParams(args...) + //if err != nil { + // return err + //} + // + //// make test invocation of the method + //test, err := c.client.InvokeFunction(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 @@ -502,47 +507,21 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint } } - // prepare main tx - mainTx := &transaction.Transaction{ - Nonce: nonce, - SystemFee: test.GasConsumed, - ValidUntilBlock: until, - Script: test.Script, - Attributes: []transaction.Attribute{ - { - Type: transaction.NotaryAssistedT, - Value: &transaction.NotaryAssisted{NKeys: u8n}, - }, - }, - Signers: cosigners, - } - - // calculate notary fee - notaryFee, err := c.client.CalculateNotaryFee(u8n) + nAct, err := notary.NewActor(c.client, cosigners, c.acc) if err != nil { return err } - // add network fee for cosigners - //nolint:staticcheck // waits for neo-go v0.99.3 with notary actors - err = c.client.AddNetworkFee( - mainTx, - notaryFee, - c.notaryAccounts(invokedByAlpha, multiaddrAccount)..., - ) - if err != nil { - return err - } + h, _, _, err := nAct.Notarize(nAct.MakeTunedCall(contract, method, nil, func(r *result.Invoke, t *transaction.Transaction) error { + if r.State != vmstate.Halt.String() { + return wrapFrostFSError(¬HaltStateError{state: r.State, exception: r.FaultException}) + } - // define witnesses - mainTx.Scripts = c.notaryWitnesses(invokedByAlpha, multiaddrAccount, mainTx) + t.ValidUntilBlock = until + t.Nonce = nonce - resp, err := c.client.SignAndPushP2PNotaryRequest(mainTx, - []byte{byte(opcode.RET)}, - -1, - 0, - c.notary.fallbackTime, - c.acc) + return nil + }, args...)) if err != nil && !alreadyOnChainError(err) { return err } @@ -551,53 +530,98 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint 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())) + zap.Stringer("tx_hash", h.Reverse())) + + //// prepare main tx + //mainTx := &transaction.Transaction{ + // Nonce: nonce, + // SystemFee: test.GasConsumed, + // ValidUntilBlock: until, + // Script: test.Script, + // Attributes: []transaction.Attribute{ + // { + // Type: transaction.NotaryAssistedT, + // Value: &transaction.NotaryAssisted{NKeys: u8n}, + // }, + // }, + // Signers: cosigners, + //} + // + //// calculate notary fee + //notaryFee, err := c.client.CalculateNotaryFee(u8n) + //if err != nil { + // return err + //} + // + //// add network fee for cosigners + ////nolint:staticcheck // waits for neo-go v0.99.3 with notary actors + //err = c.client.AddNetworkFee( + // mainTx, + // notaryFee, + // c.notaryAccounts(invokedByAlpha, multiaddrAccount)..., + //) + //if err != nil { + // return err + //} + // + //// define witnesses + //mainTx.Scripts = c.notaryWitnesses(invokedByAlpha, multiaddrAccount, mainTx) + // + //resp, err := c.client.SignAndPushP2PNotaryRequest(mainTx, + // []byte{byte(opcode.RET)}, + // -1, + // 0, + // c.notary.fallbackTime, + // c.acc) + //if err != nil && !alreadyOnChainError(err) { + // return err + //} return nil } -func (c *Client) notaryCosigners(invokedByAlpha bool, ir []*keys.PublicKey, committee bool) ([]transaction.Signer, error) { - s := make([]transaction.Signer, 0, 4) - - // first we have proxy contract signature, as it will pay for the execution - s = append(s, transaction.Signer{ - Account: c.notary.proxy, - Scopes: transaction.None, - }) - - // then we have inner ring multiaddress signature - m := sigCount(ir, committee) - - multisigScript, err := sc.CreateMultiSigRedeemScript(m, ir) +func (c *Client) notaryCosigners(invokedByAlpha bool, ir []*keys.PublicKey, committee bool) ([]actor.SignerAccount, error) { + multiaddrAccount, err := c.notaryMultisigAccount(ir, committee, invokedByAlpha) if err != nil { - // wrap error as FrostFS-specific since the call is not related to any client - return nil, wrapFrostFSError(fmt.Errorf("can't create ir multisig redeem script: %w", err)) + return nil, err } - s = append(s, transaction.Signer{ - Account: hash.Hash160(multisigScript), - Scopes: c.signer.Scopes, - AllowedContracts: c.signer.AllowedContracts, - AllowedGroups: c.signer.AllowedGroups, - }) + ss := make([]actor.SignerAccount, 0, 3) + ss = append(ss, []actor.SignerAccount{ + { + // proxy contract + Signer: transaction.Signer{ + Account: c.notary.proxy, + Scopes: transaction.None, + }, + Account: notary.FakeContractAccount(c.notary.proxy), + }, + { + // multi signature + Signer: transaction.Signer{ + Account: multiaddrAccount.ScriptHash(), + Scopes: c.signer.Scopes, + AllowedContracts: c.signer.AllowedContracts, + AllowedGroups: c.signer.AllowedGroups, + }, + Account: multiaddrAccount, + }, + }...) if !invokedByAlpha { - // then we have invoker signature - s = append(s, transaction.Signer{ - Account: hash.Hash160(c.acc.GetVerificationScript()), - Scopes: c.signer.Scopes, - AllowedContracts: c.signer.AllowedContracts, - AllowedGroups: c.signer.AllowedGroups, + // invoker signature + ss = append(ss, actor.SignerAccount{ + Signer: transaction.Signer{ + Account: hash.Hash160(c.acc.GetVerificationScript()), + Scopes: c.signer.Scopes, + AllowedContracts: c.signer.AllowedContracts, + AllowedGroups: c.signer.AllowedGroups, + }, + Account: c.acc, }) } - // last one is a placeholder for notary contract signature - s = append(s, transaction.Signer{ - Account: c.notary.notary, - Scopes: transaction.None, - }) - - return s, nil + return ss, nil } func (c *Client) notaryAccounts(invokedByAlpha bool, multiaddr *wallet.Account) []*wallet.Account {