Compare commits
1 commit
master
...
upd/neo-go
Author | SHA1 | Date | |
---|---|---|---|
|
44e0124a54 |
2 changed files with 122 additions and 100 deletions
|
@ -24,8 +24,6 @@ linters-settings:
|
||||||
govet:
|
govet:
|
||||||
# report about shadowed variables
|
# report about shadowed variables
|
||||||
check-shadowing: false
|
check-shadowing: false
|
||||||
staticcheck:
|
|
||||||
checks: ["all", "-SA1019"] # TODO Enable SA1019 after deprecated warning are fixed.
|
|
||||||
funlen:
|
funlen:
|
||||||
lines: 80 # default 60
|
lines: 80 # default 60
|
||||||
statements: 60 # default 40
|
statements: 60 # default 40
|
||||||
|
|
|
@ -16,10 +16,13 @@ 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/fixedn"
|
"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"
|
||||||
|
"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"
|
"github.com/nspcc-dev/neo-go/pkg/rpcclient/notary"
|
||||||
sc "github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
sc "github.com/nspcc-dev/neo-go/pkg/smartcontract"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"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/opcode"
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/vm/vmstate"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -34,6 +37,8 @@ type (
|
||||||
|
|
||||||
notary util.Uint160
|
notary util.Uint160
|
||||||
proxy util.Uint160
|
proxy util.Uint160
|
||||||
|
|
||||||
|
act notary.Actor
|
||||||
}
|
}
|
||||||
|
|
||||||
notaryCfg struct {
|
notaryCfg struct {
|
||||||
|
@ -462,34 +467,34 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
//
|
||||||
params, err := invocationParams(args...)
|
//params, err := invocationParams(args...)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// make test invocation of the method
|
//// make test invocation of the method
|
||||||
test, err := c.client.InvokeFunction(contract, method, params, cosigners)
|
//test, err := c.client.InvokeFunction(contract, method, params, cosigners)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// check invocation state
|
//// check invocation state
|
||||||
if test.State != HaltState {
|
//if test.State != HaltState {
|
||||||
return wrapFrostFSError(¬HaltStateError{state: test.State, exception: test.FaultException})
|
// return wrapFrostFSError(¬HaltStateError{state: test.State, exception: test.FaultException})
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// if test invocation failed, then return error
|
//// if test invocation failed, then return error
|
||||||
if len(test.Script) == 0 {
|
//if len(test.Script) == 0 {
|
||||||
return wrapFrostFSError(errEmptyInvocationScript)
|
// return wrapFrostFSError(errEmptyInvocationScript)
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
// after test invocation we build main multisig transaction
|
//// after test invocation we build main multisig transaction
|
||||||
|
//
|
||||||
multiaddrAccount, err := c.notaryMultisigAccount(alphabetList, committee, invokedByAlpha)
|
//multiaddrAccount, err := c.notaryMultisigAccount(alphabetList, committee, invokedByAlpha)
|
||||||
if err != nil {
|
//if err != nil {
|
||||||
return err
|
// return err
|
||||||
}
|
//}
|
||||||
|
|
||||||
var until uint32
|
var until uint32
|
||||||
|
|
||||||
|
@ -502,47 +507,21 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare main tx
|
nAct, err := notary.NewActor(c.client, cosigners, c.acc)
|
||||||
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 {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// add network fee for cosigners
|
h, _, _, err := nAct.Notarize(nAct.MakeTunedCall(contract, method, nil, func(r *result.Invoke, t *transaction.Transaction) error {
|
||||||
//nolint:staticcheck // waits for neo-go v0.99.3 with notary actors
|
if r.State != vmstate.Halt.String() {
|
||||||
err = c.client.AddNetworkFee(
|
return wrapFrostFSError(¬HaltStateError{state: r.State, exception: r.FaultException})
|
||||||
mainTx,
|
}
|
||||||
notaryFee,
|
|
||||||
c.notaryAccounts(invokedByAlpha, multiaddrAccount)...,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// define witnesses
|
t.ValidUntilBlock = until
|
||||||
mainTx.Scripts = c.notaryWitnesses(invokedByAlpha, multiaddrAccount, mainTx)
|
t.Nonce = nonce
|
||||||
|
|
||||||
resp, err := c.client.SignAndPushP2PNotaryRequest(mainTx,
|
return nil
|
||||||
[]byte{byte(opcode.RET)},
|
}, args...))
|
||||||
-1,
|
|
||||||
0,
|
|
||||||
c.notary.fallbackTime,
|
|
||||||
c.acc)
|
|
||||||
if err != nil && !alreadyOnChainError(err) {
|
if err != nil && !alreadyOnChainError(err) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -551,53 +530,98 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint
|
||||||
zap.String("method", method),
|
zap.String("method", method),
|
||||||
zap.Uint32("valid_until_block", until),
|
zap.Uint32("valid_until_block", until),
|
||||||
zap.Uint32("fallback_valid_for", c.notary.fallbackTime),
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) notaryCosigners(invokedByAlpha bool, ir []*keys.PublicKey, committee bool) ([]transaction.Signer, error) {
|
func (c *Client) notaryCosigners(invokedByAlpha bool, ir []*keys.PublicKey, committee bool) ([]actor.SignerAccount, error) {
|
||||||
s := make([]transaction.Signer, 0, 4)
|
multiaddrAccount, err := c.notaryMultisigAccount(ir, committee, invokedByAlpha)
|
||||||
|
|
||||||
// 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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// wrap error as FrostFS-specific since the call is not related to any client
|
return nil, err
|
||||||
return nil, wrapFrostFSError(fmt.Errorf("can't create ir multisig redeem script: %w", err))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s = append(s, transaction.Signer{
|
ss := make([]actor.SignerAccount, 0, 3)
|
||||||
Account: hash.Hash160(multisigScript),
|
ss = append(ss, []actor.SignerAccount{
|
||||||
Scopes: c.signer.Scopes,
|
{
|
||||||
AllowedContracts: c.signer.AllowedContracts,
|
// proxy contract
|
||||||
AllowedGroups: c.signer.AllowedGroups,
|
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 {
|
if !invokedByAlpha {
|
||||||
// then we have invoker signature
|
// invoker signature
|
||||||
s = append(s, transaction.Signer{
|
ss = append(ss, actor.SignerAccount{
|
||||||
Account: hash.Hash160(c.acc.GetVerificationScript()),
|
Signer: transaction.Signer{
|
||||||
Scopes: c.signer.Scopes,
|
Account: hash.Hash160(c.acc.GetVerificationScript()),
|
||||||
AllowedContracts: c.signer.AllowedContracts,
|
Scopes: c.signer.Scopes,
|
||||||
AllowedGroups: c.signer.AllowedGroups,
|
AllowedContracts: c.signer.AllowedContracts,
|
||||||
|
AllowedGroups: c.signer.AllowedGroups,
|
||||||
|
},
|
||||||
|
Account: c.acc,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// last one is a placeholder for notary contract signature
|
return ss, nil
|
||||||
s = append(s, transaction.Signer{
|
|
||||||
Account: c.notary.notary,
|
|
||||||
Scopes: transaction.None,
|
|
||||||
})
|
|
||||||
|
|
||||||
return s, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) notaryAccounts(invokedByAlpha bool, multiaddr *wallet.Account) []*wallet.Account {
|
func (c *Client) notaryAccounts(invokedByAlpha bool, multiaddr *wallet.Account) []*wallet.Account {
|
||||||
|
|
Loading…
Reference in a new issue