Merge pull request #3682 from filecoin-project/asr/chainstore-state-tree
Sever chainstore's dependence on the state tree
This commit is contained in:
commit
e04331b07c
@ -18,7 +18,6 @@ import (
|
|||||||
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
"github.com/filecoin-project/specs-actors/actors/util/adt"
|
||||||
|
|
||||||
"github.com/filecoin-project/lotus/api"
|
"github.com/filecoin-project/lotus/api"
|
||||||
"github.com/filecoin-project/lotus/chain/state"
|
|
||||||
"github.com/filecoin-project/lotus/chain/vm"
|
"github.com/filecoin-project/lotus/chain/vm"
|
||||||
"github.com/filecoin-project/lotus/journal"
|
"github.com/filecoin-project/lotus/journal"
|
||||||
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
bstore "github.com/filecoin-project/lotus/lib/blockstore"
|
||||||
@ -767,32 +766,16 @@ type BlockMessages struct {
|
|||||||
func (cs *ChainStore) BlockMsgsForTipset(ts *types.TipSet) ([]BlockMessages, error) {
|
func (cs *ChainStore) BlockMsgsForTipset(ts *types.TipSet) ([]BlockMessages, error) {
|
||||||
applied := make(map[address.Address]uint64)
|
applied := make(map[address.Address]uint64)
|
||||||
|
|
||||||
cst := cbor.NewCborStore(cs.bs)
|
|
||||||
st, err := state.LoadStateTree(cst, ts.Blocks()[0].ParentStateRoot)
|
|
||||||
if err != nil {
|
|
||||||
return nil, xerrors.Errorf("failed to load state tree")
|
|
||||||
}
|
|
||||||
|
|
||||||
preloadAddr := func(a address.Address) error {
|
|
||||||
if _, ok := applied[a]; !ok {
|
|
||||||
act, err := st.GetActor(a)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
applied[a] = act.Nonce
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
selectMsg := func(m *types.Message) (bool, error) {
|
selectMsg := func(m *types.Message) (bool, error) {
|
||||||
if err := preloadAddr(m.From); err != nil {
|
// The first match for a sender is guaranteed to have correct nonce -- the block isn't valid otherwise
|
||||||
return false, err
|
if _, ok := applied[m.From]; !ok {
|
||||||
|
applied[m.From] = m.Nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
if applied[m.From] != m.Nonce {
|
if applied[m.From] != m.Nonce {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
applied[m.From]++
|
applied[m.From]++
|
||||||
|
|
||||||
return true, nil
|
return true, nil
|
||||||
|
@ -662,6 +662,49 @@ func TestDuplicateNonce(t *testing.T) {
|
|||||||
require.Equal(t, includedMsg, mft[0].VMMessage().Cid(), "messages for tipset didn't contain expected message")
|
require.Equal(t, includedMsg, mft[0].VMMessage().Cid(), "messages for tipset didn't contain expected message")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This test asserts that a block that includes a message with bad nonce can't be synced. A nonce is "bad" if it can't
|
||||||
|
// be applied on the parent state.
|
||||||
|
func TestBadNonce(t *testing.T) {
|
||||||
|
H := 10
|
||||||
|
tu := prepSyncTest(t, H)
|
||||||
|
|
||||||
|
base := tu.g.CurTipset
|
||||||
|
|
||||||
|
// Produce a message from the banker with a bad nonce
|
||||||
|
makeBadMsg := func() *types.SignedMessage {
|
||||||
|
|
||||||
|
ba, err := tu.nds[0].StateGetActor(context.TODO(), tu.g.Banker(), base.TipSet().Key())
|
||||||
|
require.NoError(t, err)
|
||||||
|
msg := types.Message{
|
||||||
|
To: tu.g.Banker(),
|
||||||
|
From: tu.g.Banker(),
|
||||||
|
|
||||||
|
Nonce: ba.Nonce + 5,
|
||||||
|
|
||||||
|
Value: types.NewInt(1),
|
||||||
|
|
||||||
|
Method: 0,
|
||||||
|
|
||||||
|
GasLimit: 100_000_000,
|
||||||
|
GasFeeCap: types.NewInt(0),
|
||||||
|
GasPremium: types.NewInt(0),
|
||||||
|
}
|
||||||
|
|
||||||
|
sig, err := tu.g.Wallet().Sign(context.TODO(), tu.g.Banker(), msg.Cid().Bytes())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return &types.SignedMessage{
|
||||||
|
Message: msg,
|
||||||
|
Signature: *sig,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
msgs := make([][]*types.SignedMessage, 1)
|
||||||
|
msgs[0] = []*types.SignedMessage{makeBadMsg()}
|
||||||
|
|
||||||
|
tu.mineOnBlock(base, 0, []int{0}, true, true, msgs)
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkSyncBasic(b *testing.B) {
|
func BenchmarkSyncBasic(b *testing.B) {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
runSyncBenchLength(b, 100)
|
runSyncBenchLength(b, 100)
|
||||||
|
Loading…
Reference in New Issue
Block a user