fix: message signer - always compare with mpool nonce
This commit is contained in:
parent
3c524ac0e0
commit
d1c10a61dd
@ -4,21 +4,22 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/wallet"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
|
"github.com/filecoin-project/lotus/chain/wallet"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
"github.com/ipfs/go-datastore"
|
"github.com/ipfs/go-datastore"
|
||||||
"github.com/ipfs/go-datastore/namespace"
|
"github.com/ipfs/go-datastore/namespace"
|
||||||
|
logging "github.com/ipfs/go-log/v2"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
|
|
||||||
const dsKeyActorNonce = "ActorNonce"
|
const dsKeyActorNonce = "ActorNonce"
|
||||||
|
|
||||||
|
var log = logging.Logger("messagesigner")
|
||||||
|
|
||||||
type mpoolAPI interface {
|
type mpoolAPI interface {
|
||||||
GetNonce(address.Address) (uint64, error)
|
GetNonce(address.Address) (uint64, error)
|
||||||
}
|
}
|
||||||
@ -67,30 +68,30 @@ func (ms *MessageSigner) SignMessage(ctx context.Context, msg *types.Message) (*
|
|||||||
// nextNonce increments the nonce.
|
// nextNonce increments the nonce.
|
||||||
// If there is no nonce in the datastore, gets the nonce from the message pool.
|
// If there is no nonce in the datastore, gets the nonce from the message pool.
|
||||||
func (ms *MessageSigner) nextNonce(addr address.Address) (uint64, error) {
|
func (ms *MessageSigner) nextNonce(addr address.Address) (uint64, error) {
|
||||||
addrNonceKey := datastore.KeyWithNamespaces([]string{dsKeyActorNonce, addr.String()})
|
// Nonces used to be created by the mempool and we need to support nodes
|
||||||
|
// that have mempool nonces, so first check the mempool for a nonce for
|
||||||
|
// this address. Note that the mempool returns the actor state's nonce
|
||||||
|
// by default.
|
||||||
|
nonce, err := ms.mpool.GetNonce(addr)
|
||||||
|
if err != nil {
|
||||||
|
return 0, xerrors.Errorf("failed to get nonce from mempool: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
// Get the nonce for this address from the datastore
|
// Get the nonce for this address from the datastore
|
||||||
nonceBytes, err := ms.ds.Get(addrNonceKey)
|
addrNonceKey := datastore.KeyWithNamespaces([]string{dsKeyActorNonce, addr.String()})
|
||||||
|
dsNonceBytes, err := ms.ds.Get(addrNonceKey)
|
||||||
|
|
||||||
var nonce uint64
|
|
||||||
switch {
|
switch {
|
||||||
case xerrors.Is(err, datastore.ErrNotFound):
|
case xerrors.Is(err, datastore.ErrNotFound):
|
||||||
// If a nonce for this address hasn't yet been created in the
|
// If a nonce for this address hasn't yet been created in the
|
||||||
// datastore, check the mempool - nonces used to be created by
|
// datastore, just use the nonce from the mempool
|
||||||
// the mempool so we need to support nodes that still have mempool
|
|
||||||
// nonces. Note that the mempool returns the actor state's nonce by
|
|
||||||
// default.
|
|
||||||
nonce, err = ms.mpool.GetNonce(addr)
|
|
||||||
if err != nil {
|
|
||||||
return 0, xerrors.Errorf("failed to get nonce from mempool: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
case err != nil:
|
case err != nil:
|
||||||
return 0, xerrors.Errorf("failed to get nonce from datastore: %w", err)
|
return 0, xerrors.Errorf("failed to get nonce from datastore: %w", err)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// There is a nonce in the mempool, so unmarshall and increment it
|
// There is a nonce in the datastore, so unmarshall and increment it
|
||||||
maj, val, err := cbg.CborReadHeader(bytes.NewReader(nonceBytes))
|
maj, val, err := cbg.CborReadHeader(bytes.NewReader(dsNonceBytes))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, xerrors.Errorf("failed to parse nonce from datastore: %w", err)
|
return 0, xerrors.Errorf("failed to parse nonce from datastore: %w", err)
|
||||||
}
|
}
|
||||||
@ -98,7 +99,14 @@ func (ms *MessageSigner) nextNonce(addr address.Address) (uint64, error) {
|
|||||||
return 0, xerrors.Errorf("bad cbor type parsing nonce from datastore")
|
return 0, xerrors.Errorf("bad cbor type parsing nonce from datastore")
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce = val + 1
|
dsNonce := val + 1
|
||||||
|
|
||||||
|
// The message pool nonce should be <= than the datastore nonce
|
||||||
|
if nonce <= dsNonce {
|
||||||
|
nonce = dsNonce
|
||||||
|
} else {
|
||||||
|
log.Warnf("mempool nonce was larger than datastore nonce (%d > %d)", nonce, dsNonce)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the nonce for this address to the datastore
|
// Write the nonce for this address to the datastore
|
||||||
|
@ -98,10 +98,9 @@ func TestMessageSignerSignMessage(t *testing.T) {
|
|||||||
To: to1,
|
To: to1,
|
||||||
From: from1,
|
From: from1,
|
||||||
},
|
},
|
||||||
// Should ignore mpool nonce because after the first message nonce
|
// Should adjust datastore nonce because mpool nonce is higher
|
||||||
// will come from the datastore
|
|
||||||
mpoolNonce: [1]uint64{10},
|
mpoolNonce: [1]uint64{10},
|
||||||
expNonce: 6,
|
expNonce: 10,
|
||||||
}},
|
}},
|
||||||
}, {
|
}, {
|
||||||
// Nonce should increment independently for each address
|
// Nonce should increment independently for each address
|
||||||
|
@ -6,8 +6,6 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/messagesigner"
|
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
ci "github.com/libp2p/go-libp2p-core/crypto"
|
ci "github.com/libp2p/go-libp2p-core/crypto"
|
||||||
"github.com/libp2p/go-libp2p-core/host"
|
"github.com/libp2p/go-libp2p-core/host"
|
||||||
@ -37,6 +35,7 @@ import (
|
|||||||
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
|
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
|
||||||
"github.com/filecoin-project/lotus/chain/market"
|
"github.com/filecoin-project/lotus/chain/market"
|
||||||
"github.com/filecoin-project/lotus/chain/messagepool"
|
"github.com/filecoin-project/lotus/chain/messagepool"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagesigner"
|
||||||
"github.com/filecoin-project/lotus/chain/metrics"
|
"github.com/filecoin-project/lotus/chain/metrics"
|
||||||
"github.com/filecoin-project/lotus/chain/stmgr"
|
"github.com/filecoin-project/lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/lotus/chain/store"
|
"github.com/filecoin-project/lotus/chain/store"
|
||||||
|
@ -4,14 +4,13 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/chain/messagesigner"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-address"
|
"github.com/filecoin-project/go-address"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
|
"github.com/filecoin-project/lotus/chain/messagesigner"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
"github.com/filecoin-project/lotus/node/modules/dtypes"
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user