chain: Cleanup consensus logic

This commit is contained in:
Łukasz Magiera
2021-09-02 18:09:37 +02:00
parent 5831a6ba4a
commit 95b128b7bc
58 changed files with 1858 additions and 1492 deletions
+7 -1
View File
@@ -12,6 +12,8 @@ import (
"github.com/filecoin-project/lotus/api"
"github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/consensus"
"github.com/filecoin-project/lotus/chain/consensus/filcns"
"github.com/filecoin-project/lotus/chain/exchange"
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
"github.com/filecoin-project/lotus/chain/market"
@@ -46,7 +48,7 @@ var ChainNode = Options(
// Consensus settings
Override(new(dtypes.DrandSchedule), modules.BuiltinDrandConfig),
Override(new(stmgr.UpgradeSchedule), stmgr.DefaultUpgradeSchedule()),
Override(new(stmgr.UpgradeSchedule), filcns.DefaultUpgradeSchedule()),
Override(new(dtypes.NetworkName), modules.NetworkName),
Override(new(modules.Genesis), modules.ErrorGenesis),
Override(new(dtypes.AfterGenesisSet), modules.SetGenesis),
@@ -65,6 +67,10 @@ var ChainNode = Options(
Override(new(vm.SyscallBuilder), vm.Syscalls),
// Consensus: Chain storage/access
Override(new(chain.Genesis), chain.LoadGenesis),
Override(new(store.WeightFunc), filcns.Weight),
Override(new(stmgr.Executor), filcns.TipSetExecutor()),
Override(new(consensus.Consensus), filcns.NewFilecoinExpectedConsensus),
Override(new(*store.ChainStore), modules.ChainStore),
Override(new(*stmgr.StateManager), modules.StateManager),
Override(new(dtypes.ChainBitswap), modules.ChainBitswap),
+4 -1
View File
@@ -2,6 +2,7 @@ package hello
import (
"context"
"github.com/filecoin-project/lotus/chain/consensus"
"time"
"github.com/filecoin-project/go-state-types/abi"
@@ -48,10 +49,11 @@ type Service struct {
cs *store.ChainStore
syncer *chain.Syncer
cons consensus.Consensus
pmgr *peermgr.PeerMgr
}
func NewHelloService(h host.Host, cs *store.ChainStore, syncer *chain.Syncer, pmgr peermgr.MaybePeerMgr) *Service {
func NewHelloService(h host.Host, cs *store.ChainStore, syncer *chain.Syncer, cons consensus.Consensus, pmgr peermgr.MaybePeerMgr) *Service {
if pmgr.Mgr == nil {
log.Warn("running without peer manager")
}
@@ -61,6 +63,7 @@ func NewHelloService(h host.Host, cs *store.ChainStore, syncer *chain.Syncer, pm
cs: cs,
syncer: syncer,
cons: cons,
pmgr: pmgr.Mgr,
}
}
+9 -7
View File
@@ -11,6 +11,7 @@ import (
"sync"
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain/stmgr"
"go.uber.org/fx"
"golang.org/x/xerrors"
@@ -78,7 +79,8 @@ type ChainAPI struct {
WalletAPI
ChainModuleAPI
Chain *store.ChainStore
Chain *store.ChainStore
TsExec stmgr.Executor
// ExposedBlockstore is the global monolith blockstore that is safe to
// expose externally. In the future, this will be segregated into two
@@ -394,7 +396,7 @@ func (s stringKey) Key() string {
// TODO: ActorUpgrade: this entire function is a problem (in theory) as we don't know the HAMT version.
// In practice, hamt v0 should work "just fine" for reading.
func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) {
func resolveOnce(bs blockstore.Blockstore, tse stmgr.Executor) func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) {
return func(ctx context.Context, ds ipld.NodeGetter, nd ipld.Node, names []string) (*ipld.Link, []string, error) {
store := adt.WrapStore(ctx, cbor.NewCborStore(bs))
@@ -468,7 +470,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
}, nil, nil
}
return resolveOnce(bs)(ctx, ds, n, names[1:])
return resolveOnce(bs, tse)(ctx, ds, n, names[1:])
}
if strings.HasPrefix(names[0], "@A:") {
@@ -517,7 +519,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
}, nil, nil
}
return resolveOnce(bs)(ctx, ds, n, names[1:])
return resolveOnce(bs, tse)(ctx, ds, n, names[1:])
}
if names[0] == "@state" {
@@ -531,7 +533,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
return nil, nil, xerrors.Errorf("getting actor head for @state: %w", err)
}
m, err := vm.DumpActorState(&act, head.RawData())
m, err := vm.DumpActorState(tse.NewActorRegistry(), &act, head.RawData())
if err != nil {
return nil, nil, err
}
@@ -565,7 +567,7 @@ func resolveOnce(bs blockstore.Blockstore) func(ctx context.Context, ds ipld.Nod
}, nil, nil
}
return resolveOnce(bs)(ctx, ds, n, names[1:])
return resolveOnce(bs, tse)(ctx, ds, n, names[1:])
}
return nd.ResolveLink(names)
@@ -585,7 +587,7 @@ func (a *ChainAPI) ChainGetNode(ctx context.Context, p string) (*api.IpldObject,
r := &resolver.Resolver{
DAG: dag,
ResolveOnce: resolveOnce(bs),
ResolveOnce: resolveOnce(bs, a.TsExec),
}
node, err := r.ResolvePath(ctx, ip)
+10 -5
View File
@@ -29,7 +29,7 @@ import (
"github.com/filecoin-project/lotus/chain/actors/builtin/verifreg"
"github.com/filecoin-project/lotus/chain/actors/policy"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/gen"
"github.com/filecoin-project/lotus/chain/consensus"
"github.com/filecoin-project/lotus/chain/state"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
@@ -88,6 +88,8 @@ type StateAPI struct {
StateManager *stmgr.StateManager
Chain *store.ChainStore
Beacon beacon.Schedule
Consensus consensus.Consensus
TsExec stmgr.Executor
}
func (a *StateAPI) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) {
@@ -469,7 +471,7 @@ func (a *StateAPI) StateReadState(ctx context.Context, actor address.Address, ts
return nil, xerrors.Errorf("getting actor head: %w", err)
}
oif, err := vm.DumpActorState(act, blk.RawData())
oif, err := vm.DumpActorState(a.TsExec.NewActorRegistry(), act, blk.RawData())
if err != nil {
return nil, xerrors.Errorf("dumping actor state (a:%s): %w", actor, err)
}
@@ -487,7 +489,7 @@ func (a *StateAPI) StateDecodeParams(ctx context.Context, toAddr address.Address
return nil, xerrors.Errorf("getting actor: %w", err)
}
paramType, err := stmgr.GetParamType(act.Code, method)
paramType, err := stmgr.GetParamType(a.TsExec.NewActorRegistry(), act.Code, method)
if err != nil {
return nil, xerrors.Errorf("getting params type: %w", err)
}
@@ -500,7 +502,7 @@ func (a *StateAPI) StateDecodeParams(ctx context.Context, toAddr address.Address
}
func (a *StateAPI) StateEncodeParams(ctx context.Context, toActCode cid.Cid, method abi.MethodNum, params json.RawMessage) ([]byte, error) {
paramType, err := stmgr.GetParamType(toActCode, method)
paramType, err := stmgr.GetParamType(a.TsExec.NewActorRegistry(), toActCode, method)
if err != nil {
return nil, xerrors.Errorf("getting params type: %w", err)
}
@@ -524,10 +526,13 @@ func (a *StateAPI) MinerGetBaseInfo(ctx context.Context, maddr address.Address,
}
func (a *StateAPI) MinerCreateBlock(ctx context.Context, bt *api.BlockTemplate) (*types.BlockMsg, error) {
fblk, err := gen.MinerCreateBlock(ctx, a.StateManager, a.Wallet, bt)
fblk, err := a.Consensus.CreateBlock(ctx, a.Wallet, bt)
if err != nil {
return nil, err
}
if fblk == nil {
return nil, nil
}
var out types.BlockMsg
out.Header = fblk.Header
+6 -4
View File
@@ -21,7 +21,7 @@ import (
type SyncAPI struct {
fx.In
SlashFilter *slashfilter.SlashFilter
SlashFilter *slashfilter.SlashFilter `optional:"true"`
Syncer *chain.Syncer
PubSub *pubsub.PubSub
NetName dtypes.NetworkName
@@ -56,9 +56,11 @@ func (a *SyncAPI) SyncSubmitBlock(ctx context.Context, blk *types.BlockMsg) erro
return xerrors.Errorf("loading parent block: %w", err)
}
if err := a.SlashFilter.MinedBlock(blk.Header, parent.Height); err != nil {
log.Errorf("<!!> SLASH FILTER ERROR: %s", err)
return xerrors.Errorf("<!!> SLASH FILTER ERROR: %w", err)
if a.SlashFilter != nil {
if err := a.SlashFilter.MinedBlock(blk.Header, parent.Height); err != nil {
log.Errorf("<!!> SLASH FILTER ERROR: %s", err)
return xerrors.Errorf("<!!> SLASH FILTER ERROR: %w", err)
}
}
// TODO: should we have some sort of fast path to adding a local block?
+23 -10
View File
@@ -17,13 +17,13 @@ import (
"github.com/filecoin-project/lotus/build"
"github.com/filecoin-project/lotus/chain"
"github.com/filecoin-project/lotus/chain/beacon"
"github.com/filecoin-project/lotus/chain/consensus"
"github.com/filecoin-project/lotus/chain/exchange"
"github.com/filecoin-project/lotus/chain/gen/slashfilter"
"github.com/filecoin-project/lotus/chain/messagepool"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/filecoin-project/lotus/chain/store"
"github.com/filecoin-project/lotus/chain/vm"
"github.com/filecoin-project/lotus/extern/sector-storage/ffiwrapper"
"github.com/filecoin-project/lotus/journal"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/lotus/node/modules/helpers"
@@ -58,8 +58,8 @@ func ChainBlockService(bs dtypes.ExposedBlockstore, rem dtypes.ChainBitswap) dty
return blockservice.New(bs, rem)
}
func MessagePool(lc fx.Lifecycle, mpp messagepool.Provider, ds dtypes.MetadataDS, nn dtypes.NetworkName, j journal.Journal, protector dtypes.GCReferenceProtector) (*messagepool.MessagePool, error) {
mp, err := messagepool.New(mpp, ds, nn, j)
func MessagePool(lc fx.Lifecycle, us stmgr.UpgradeSchedule, mpp messagepool.Provider, ds dtypes.MetadataDS, nn dtypes.NetworkName, j journal.Journal, protector dtypes.GCReferenceProtector) (*messagepool.MessagePool, error) {
mp, err := messagepool.New(mpp, ds, us, nn, j)
if err != nil {
return nil, xerrors.Errorf("constructing mpool: %w", err)
}
@@ -72,8 +72,15 @@ func MessagePool(lc fx.Lifecycle, mpp messagepool.Provider, ds dtypes.MetadataDS
return mp, nil
}
func ChainStore(lc fx.Lifecycle, cbs dtypes.ChainBlockstore, sbs dtypes.StateBlockstore, ds dtypes.MetadataDS, basebs dtypes.BaseBlockstore, j journal.Journal) *store.ChainStore {
chain := store.NewChainStore(cbs, sbs, ds, j)
func ChainStore(lc fx.Lifecycle,
cbs dtypes.ChainBlockstore,
sbs dtypes.StateBlockstore,
ds dtypes.MetadataDS,
basebs dtypes.BaseBlockstore,
weight store.WeightFunc,
j journal.Journal) *store.ChainStore {
chain := store.NewChainStore(cbs, sbs, ds, weight, j)
if err := chain.Load(); err != nil {
log.Warnf("loading chain state from disk: %s", err)
@@ -100,14 +107,20 @@ func ChainStore(lc fx.Lifecycle, cbs dtypes.ChainBlockstore, sbs dtypes.StateBlo
return chain
}
func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore, syscalls vm.SyscallBuilder, us stmgr.UpgradeSchedule, _ dtypes.AfterGenesisSet) (dtypes.NetworkName, error) {
func NetworkName(mctx helpers.MetricsCtx,
lc fx.Lifecycle,
cs *store.ChainStore,
tsexec stmgr.Executor,
syscalls vm.SyscallBuilder,
us stmgr.UpgradeSchedule,
_ dtypes.AfterGenesisSet) (dtypes.NetworkName, error) {
if !build.Devnet {
return "testnetnet", nil
}
ctx := helpers.LifecycleCtx(mctx, lc)
sm, err := stmgr.NewStateManagerWithUpgradeSchedule(cs, syscalls, us)
sm, err := stmgr.NewStateManager(cs, tsexec, syscalls, us)
if err != nil {
return "", err
}
@@ -126,7 +139,8 @@ type SyncerParams struct {
SyncMgrCtor chain.SyncManagerCtor
Host host.Host
Beacon beacon.Schedule
Verifier ffiwrapper.Verifier
Gent chain.Genesis
Consensus consensus.Consensus
}
func NewSyncer(params SyncerParams) (*chain.Syncer, error) {
@@ -138,9 +152,8 @@ func NewSyncer(params SyncerParams) (*chain.Syncer, error) {
smCtor = params.SyncMgrCtor
h = params.Host
b = params.Beacon
v = params.Verifier
)
syncer, err := chain.NewSyncer(ds, sm, ex, smCtor, h.ConnManager(), h.ID(), b, v)
syncer, err := chain.NewSyncer(ds, sm, ex, smCtor, h.ConnManager(), h.ID(), b, params.Gent, params.Consensus)
if err != nil {
return nil, err
}
+11 -2
View File
@@ -6,6 +6,7 @@ import (
"strconv"
"time"
"github.com/filecoin-project/lotus/chain/consensus"
"github.com/ipfs/go-datastore"
"github.com/ipfs/go-datastore/namespace"
eventbus "github.com/libp2p/go-eventbus"
@@ -136,11 +137,19 @@ func waitForSync(stmgr *stmgr.StateManager, epochs int, subscribe func()) {
})
}
func HandleIncomingBlocks(mctx helpers.MetricsCtx, lc fx.Lifecycle, ps *pubsub.PubSub, s *chain.Syncer, bserv dtypes.ChainBlockService, chain *store.ChainStore, stmgr *stmgr.StateManager, h host.Host, nn dtypes.NetworkName) {
func HandleIncomingBlocks(mctx helpers.MetricsCtx,
lc fx.Lifecycle,
ps *pubsub.PubSub,
s *chain.Syncer,
bserv dtypes.ChainBlockService,
chain *store.ChainStore,
cns consensus.Consensus,
h host.Host,
nn dtypes.NetworkName) {
ctx := helpers.LifecycleCtx(mctx, lc)
v := sub.NewBlockValidator(
h.ID(), chain, stmgr,
h.ID(), chain, cns,
func(p peer.ID) {
ps.BlacklistPeer(p)
h.ConnManager().TagPeer(p, "badblock", -1000)
+2 -2
View File
@@ -8,8 +8,8 @@ import (
"github.com/filecoin-project/lotus/chain/store"
)
func StateManager(lc fx.Lifecycle, cs *store.ChainStore, sys vm.SyscallBuilder, us stmgr.UpgradeSchedule) (*stmgr.StateManager, error) {
sm, err := stmgr.NewStateManagerWithUpgradeSchedule(cs, sys, us)
func StateManager(lc fx.Lifecycle, cs *store.ChainStore, exec stmgr.Executor, sys vm.SyscallBuilder, us stmgr.UpgradeSchedule) (*stmgr.StateManager, error) {
sm, err := stmgr.NewStateManager(cs, exec, sys, us)
if err != nil {
return nil, err
}
+3 -3
View File
@@ -110,7 +110,9 @@ func as(in interface{}, as interface{}) interface{} {
panic("outType is not a pointer")
}
if reflect.TypeOf(in).Kind() != reflect.Func {
inType := reflect.TypeOf(in)
if inType.Kind() != reflect.Func || inType.AssignableTo(outType.Elem()) {
ctype := reflect.FuncOf(nil, []reflect.Type{outType.Elem()}, false)
return reflect.MakeFunc(ctype, func(args []reflect.Value) (results []reflect.Value) {
@@ -121,8 +123,6 @@ func as(in interface{}, as interface{}) interface{} {
}).Interface()
}
inType := reflect.TypeOf(in)
ins := make([]reflect.Type, inType.NumIn())
outs := make([]reflect.Type, inType.NumOut())