forked from TrueCloudLab/frostfs-node
[#846] morph/notary: Add nonce parameter to notary invocation method
This prevents notary requests collisions for TXs that contains equals hashable fields. Signed-off-by: Pavel Karpy <carpawell@nspcc.ru>
This commit is contained in:
parent
3a8f0edac1
commit
e3c0288e50
3 changed files with 18 additions and 10 deletions
|
@ -94,7 +94,8 @@ func (s *Server) voteForSidechainValidator(validators keys.PublicKeys) error {
|
||||||
epoch := s.EpochCounter()
|
epoch := s.EpochCounter()
|
||||||
|
|
||||||
s.contracts.alphabet.iterate(func(letter GlagoliticLetter, contract util.Uint160) {
|
s.contracts.alphabet.iterate(func(letter GlagoliticLetter, contract util.Uint160) {
|
||||||
err := s.morphClient.NotaryInvoke(contract, s.feeConfig.SideChainFee(), voteMethod, int64(epoch), validators)
|
// FIXME: do not use constant nonce for alphabet NR: #844
|
||||||
|
err := s.morphClient.NotaryInvoke(contract, s.feeConfig.SideChainFee(), 1, voteMethod, int64(epoch), validators)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.log.Warn("can't invoke vote method in alphabet contract",
|
s.log.Warn("can't invoke vote method in alphabet contract",
|
||||||
zap.Int8("alphabet_index", int8(letter)),
|
zap.Int8("alphabet_index", int8(letter)),
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
"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/wallet"
|
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||||
|
"github.com/nspcc-dev/neofs-node/pkg/util/rand"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -248,6 +249,7 @@ func (c *Client) UpdateNotaryList(list keys.PublicKeys) error {
|
||||||
|
|
||||||
return c.notaryInvokeAsCommittee(
|
return c.notaryInvokeAsCommittee(
|
||||||
setDesignateMethod,
|
setDesignateMethod,
|
||||||
|
1, // FIXME: do not use constant nonce for alphabet NR: #844
|
||||||
noderoles.P2PNotary,
|
noderoles.P2PNotary,
|
||||||
list,
|
list,
|
||||||
)
|
)
|
||||||
|
@ -271,6 +273,7 @@ func (c *Client) UpdateNeoFSAlphabetList(list keys.PublicKeys) error {
|
||||||
|
|
||||||
return c.notaryInvokeAsCommittee(
|
return c.notaryInvokeAsCommittee(
|
||||||
setDesignateMethod,
|
setDesignateMethod,
|
||||||
|
1, // FIXME: do not use constant nonce for alphabet NR: #844
|
||||||
noderoles.NeoFSAlphabet,
|
noderoles.NeoFSAlphabet,
|
||||||
list,
|
list,
|
||||||
)
|
)
|
||||||
|
@ -281,10 +284,10 @@ func (c *Client) UpdateNeoFSAlphabetList(list keys.PublicKeys) error {
|
||||||
// it fallbacks to a simple `Invoke()`.
|
// it fallbacks to a simple `Invoke()`.
|
||||||
//
|
//
|
||||||
// This function must be invoked with notary enabled otherwise it throws panic.
|
// This function must be invoked with notary enabled otherwise it throws panic.
|
||||||
func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, method string, args ...interface{}) error {
|
func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, nonce uint32, method string, args ...interface{}) error {
|
||||||
if c.multiClient != nil {
|
if c.multiClient != nil {
|
||||||
return c.multiClient.iterateClients(func(c *Client) error {
|
return c.multiClient.iterateClients(func(c *Client) error {
|
||||||
return c.NotaryInvoke(contract, fee, method, args...)
|
return c.NotaryInvoke(contract, fee, nonce, method, args...)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,9 +295,12 @@ func (c *Client) NotaryInvoke(contract util.Uint160, fee fixedn.Fixed8, method s
|
||||||
return c.Invoke(contract, fee, method, args...)
|
return c.Invoke(contract, fee, method, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.notaryInvoke(false, true, contract, method, args...)
|
return c.notaryInvoke(false, true, contract, nonce, method, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// randSource is a source of random numbers.
|
||||||
|
var randSource = rand.New()
|
||||||
|
|
||||||
// NotaryInvokeNotAlpha does the same as NotaryInvoke but does not use client's
|
// NotaryInvokeNotAlpha does the same as NotaryInvoke but does not use client's
|
||||||
// private key in Invocation script. It means that main TX of notary request is
|
// private key in Invocation script. It means that main TX of notary request is
|
||||||
// not expected to be signed by the current node.
|
// not expected to be signed by the current node.
|
||||||
|
@ -311,7 +317,7 @@ func (c *Client) NotaryInvokeNotAlpha(contract util.Uint160, fee fixedn.Fixed8,
|
||||||
return c.Invoke(contract, fee, method, args...)
|
return c.Invoke(contract, fee, method, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.notaryInvoke(false, false, contract, method, args...)
|
return c.notaryInvoke(false, false, contract, randSource.Uint32(), method, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NotarySignAndInvokeTX signs and sends notary request that was received from
|
// NotarySignAndInvokeTX signs and sends notary request that was received from
|
||||||
|
@ -359,16 +365,16 @@ func (c *Client) NotarySignAndInvokeTX(mainTx *transaction.Transaction) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) notaryInvokeAsCommittee(method string, args ...interface{}) error {
|
func (c *Client) notaryInvokeAsCommittee(method string, nonce uint32, args ...interface{}) error {
|
||||||
designate, err := c.GetDesignateHash()
|
designate, err := c.GetDesignateHash()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.notaryInvoke(true, true, designate, method, args...)
|
return c.notaryInvoke(true, true, designate, nonce, method, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint160, method string, args ...interface{}) error {
|
func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint160, nonce uint32, method string, args ...interface{}) error {
|
||||||
alphabetList, err := c.notary.alphabetSource() // prepare arguments for test invocation
|
alphabetList, err := c.notary.alphabetSource() // prepare arguments for test invocation
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -417,7 +423,7 @@ func (c *Client) notaryInvoke(committee, invokedByAlpha bool, contract util.Uint
|
||||||
|
|
||||||
// prepare main tx
|
// prepare main tx
|
||||||
mainTx := &transaction.Transaction{
|
mainTx := &transaction.Transaction{
|
||||||
Nonce: 1,
|
Nonce: nonce,
|
||||||
SystemFee: test.GasConsumed,
|
SystemFee: test.GasConsumed,
|
||||||
ValidUntilBlock: until,
|
ValidUntilBlock: until,
|
||||||
Script: test.Script,
|
Script: test.Script,
|
||||||
|
|
|
@ -78,7 +78,8 @@ func (s StaticClient) Morph() *Client {
|
||||||
func (s StaticClient) Invoke(method string, args ...interface{}) error {
|
func (s StaticClient) Invoke(method string, args ...interface{}) error {
|
||||||
if s.tryNotary {
|
if s.tryNotary {
|
||||||
if s.alpha {
|
if s.alpha {
|
||||||
return s.client.NotaryInvoke(s.scScriptHash, s.fee, method, args...)
|
// FIXME: do not use constant nonce for alphabet NR: #844
|
||||||
|
return s.client.NotaryInvoke(s.scScriptHash, s.fee, 1, method, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.client.NotaryInvokeNotAlpha(s.scScriptHash, s.fee, method, args...)
|
return s.client.NotaryInvokeNotAlpha(s.scScriptHash, s.fee, method, args...)
|
||||||
|
|
Loading…
Reference in a new issue