From 64fa6fd9e5363bb546c4e17936d43ce15205b54d Mon Sep 17 00:00:00 2001 From: Jakub Sztandera Date: Wed, 9 Sep 2020 20:37:12 +0200 Subject: [PATCH] Draw the rest of the owl Signed-off-by: Jakub Sztandera --- build/drand.go | 23 ++++++++++++----- build/params_2k.go | 7 +++++- build/params_testnet.go | 4 +++ chain/beacon/beacon.go | 45 +++++++++++++++++++++++++++++++--- chain/beacon/drand/drand.go | 2 +- chain/beacon/mock.go | 6 +---- node/builder.go | 6 ++--- node/impl/full/beacon.go | 7 +++--- node/modules/core.go | 4 +-- node/modules/dtypes/beacon.go | 9 +++++++ node/modules/lp2p/pubsub.go | 4 +-- node/modules/services.go | 20 ++++++++++----- node/modules/testing/beacon.go | 7 ++++-- scripts/dev/sminer-init | 2 +- 14 files changed, 110 insertions(+), 36 deletions(-) diff --git a/build/drand.go b/build/drand.go index ef3f2c498..73299249a 100644 --- a/build/drand.go +++ b/build/drand.go @@ -1,15 +1,26 @@ package build -import "github.com/filecoin-project/lotus/node/modules/dtypes" +import ( + "sort" -var DrandNetwork = DrandIncentinet - -func DrandConfig() dtypes.DrandConfig { - return DrandConfigs[DrandNetwork] -} + "github.com/filecoin-project/lotus/node/modules/dtypes" +) type DrandEnum int +func DrandConfigSchedule() dtypes.DrandSchedule { + out := dtypes.DrandSchedule{} + for start, config := range DrandSchedule { + out = append(out, dtypes.DrandPoint{Start: start, Config: DrandConfigs[config]}) + } + + sort.Slice(out, func(i, j int) bool { + return out[i].Start < out[j].Start + }) + + return out +} + const ( DrandMainnet DrandEnum = iota + 1 DrandTestnet diff --git a/build/params_2k.go b/build/params_2k.go index 4bc7c2ecc..c7ca543e7 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -13,6 +13,11 @@ import ( const UpgradeBreezeHeight = -1 const BreezeGasTampingDuration = 0 +var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ + 0: DrandIncentinet, + 3: DrandMainnet, +} + func init() { power.ConsensusMinerMinPower = big.NewInt(2048) miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ @@ -23,7 +28,7 @@ func init() { BuildType |= Build2k } -const BlockDelaySecs = uint64(4) +const BlockDelaySecs = uint64(30) const PropagationDelaySecs = uint64(1) diff --git a/build/params_testnet.go b/build/params_testnet.go index 4a7523287..84eb09e89 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -12,6 +12,10 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/power" ) +var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ + 0: DrandIncentinet, +} + const UpgradeBreezeHeight = 41280 const BreezeGasTampingDuration = 120 diff --git a/chain/beacon/beacon.go b/chain/beacon/beacon.go index 0932c0c2a..feeaa158e 100644 --- a/chain/beacon/beacon.go +++ b/chain/beacon/beacon.go @@ -42,15 +42,30 @@ type BeaconPoint struct { type RandomBeacon interface { Entry(context.Context, uint64) <-chan Response VerifyEntry(types.BeaconEntry, types.BeaconEntry) error - MaxBeaconRoundForEpoch(abi.ChainEpoch, types.BeaconEntry) uint64 + MaxBeaconRoundForEpoch(abi.ChainEpoch) uint64 } func ValidateBlockValues(bSchedule Schedule, h *types.BlockHeader, parentEpoch abi.ChainEpoch, prevEntry types.BeaconEntry) error { + { + parentBeacon := bSchedule.BeaconForEpoch(parentEpoch) + currBeacon := bSchedule.BeaconForEpoch(h.Height) + if parentBeacon != currBeacon { + if len(h.BeaconEntries) != 2 { + return xerrors.Errorf("expected two beacon entries at beacon fork, got %d", len(h.BeaconEntries)) + } + err := currBeacon.VerifyEntry(h.BeaconEntries[1], h.BeaconEntries[0]) + if err != nil { + return xerrors.Errorf("beacon at fork point invalid: (%v, %v): %w", + h.BeaconEntries[1], h.BeaconEntries[0], err) + } + return nil + } + } // TODO: fork logic b := bSchedule.BeaconForEpoch(h.Height) - maxRound := b.MaxBeaconRoundForEpoch(h.Height, prevEntry) + maxRound := b.MaxBeaconRoundForEpoch(h.Height) if maxRound == prevEntry.Round { if len(h.BeaconEntries) != 0 { return xerrors.Errorf("expected not to have any beacon entries in this block, got %d", len(h.BeaconEntries)) @@ -78,12 +93,34 @@ func ValidateBlockValues(bSchedule Schedule, h *types.BlockHeader, parentEpoch a } func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, epoch abi.ChainEpoch, parentEpoch abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) { - // TODO: fork logic + { + parentBeacon := bSchedule.BeaconForEpoch(parentEpoch) + currBeacon := bSchedule.BeaconForEpoch(epoch) + if parentBeacon != currBeacon { + // Fork logic + round := currBeacon.MaxBeaconRoundForEpoch(epoch) + out := make([]types.BeaconEntry, 2) + rch := currBeacon.Entry(ctx, round-1) + res := <-rch + if res.Err != nil { + return nil, xerrors.Errorf("getting entry %d returned error: %w", round-1, res.Err) + } + out[0] = res.Entry + rch = currBeacon.Entry(ctx, round) + res = <-rch + if res.Err != nil { + return nil, xerrors.Errorf("getting entry %d returned error: %w", round, res.Err) + } + out[1] = res.Entry + return out, nil + } + } + beacon := bSchedule.BeaconForEpoch(epoch) start := build.Clock.Now() - maxRound := beacon.MaxBeaconRoundForEpoch(epoch, prev) + maxRound := beacon.MaxBeaconRoundForEpoch(epoch) if maxRound == prev.Round { return nil, nil } diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index 6af39b65f..6e8e83a20 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -187,7 +187,7 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr return err } -func (db *DrandBeacon) MaxBeaconRoundForEpoch(filEpoch abi.ChainEpoch, prevEntry types.BeaconEntry) uint64 { +func (db *DrandBeacon) MaxBeaconRoundForEpoch(filEpoch abi.ChainEpoch) uint64 { // TODO: sometimes the genesis time for filecoin is zero and this goes negative latestTs := ((uint64(filEpoch) * db.filRoundTime) + db.filGenTime) - db.filRoundTime dround := (latestTs - db.drandGenTime) / uint64(db.interval.Seconds()) diff --git a/chain/beacon/mock.go b/chain/beacon/mock.go index 56a77df1c..502ff2ba5 100644 --- a/chain/beacon/mock.go +++ b/chain/beacon/mock.go @@ -53,11 +53,7 @@ func (mb *mockBeacon) VerifyEntry(from types.BeaconEntry, to types.BeaconEntry) return nil } -func (mb *mockBeacon) IsEntryForEpoch(e types.BeaconEntry, epoch abi.ChainEpoch, nulls int) (bool, error) { - return int64(e.Round) <= int64(epoch) && int64(epoch)-int64(nulls) >= int64(e.Round), nil -} - -func (mb *mockBeacon) MaxBeaconRoundForEpoch(epoch abi.ChainEpoch, prevEntry types.BeaconEntry) uint64 { +func (mb *mockBeacon) MaxBeaconRoundForEpoch(epoch abi.ChainEpoch) uint64 { return uint64(epoch) } diff --git a/node/builder.go b/node/builder.go index 128f44bd3..6c01258a6 100644 --- a/node/builder.go +++ b/node/builder.go @@ -226,7 +226,7 @@ func Online() Option { Override(new(dtypes.BootstrapPeers), modules.BuiltinBootstrap), Override(new(dtypes.DrandBootstrap), modules.DrandBootstrap), - Override(new(dtypes.DrandConfig), modules.BuiltinDrandConfig), + Override(new(dtypes.DrandSchedule), modules.BuiltinDrandConfig), Override(HandleIncomingMessagesKey, modules.HandleIncomingMessages), @@ -272,7 +272,7 @@ func Online() Option { Override(new(modules.ClientDealFunds), modules.NewClientDealFunds), Override(new(storagemarket.StorageClient), modules.StorageClient), Override(new(storagemarket.StorageClientNode), storageadapter.NewClientNodeAdapter), - Override(new(beacon.RandomBeacon), modules.RandomBeacon), + Override(new(beacon.Schedule), modules.RandomSchedule), Override(new(*paychmgr.Store), paychmgr.NewStore), Override(new(*paychmgr.Manager), paychmgr.NewManager), @@ -535,6 +535,6 @@ func Test() Option { return Options( Unset(RunPeerMgrKey), Unset(new(*peermgr.PeerMgr)), - Override(new(beacon.RandomBeacon), testing.RandomBeacon), + Override(new(beacon.Schedule), testing.RandomBeacon), ) } diff --git a/node/impl/full/beacon.go b/node/impl/full/beacon.go index 725c6ff1f..bc7232c27 100644 --- a/node/impl/full/beacon.go +++ b/node/impl/full/beacon.go @@ -13,12 +13,13 @@ import ( type BeaconAPI struct { fx.In - Beacon beacon.RandomBeacon + Beacon beacon.Schedule } func (a *BeaconAPI) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) { - rr := a.Beacon.MaxBeaconRoundForEpoch(epoch, types.BeaconEntry{}) - e := a.Beacon.Entry(ctx, rr) + b := a.Beacon.BeaconForEpoch(epoch) + rr := b.MaxBeaconRoundForEpoch(epoch) + e := b.Entry(ctx, rr) select { case be, ok := <-e: diff --git a/node/modules/core.go b/node/modules/core.go index d73e4e25d..c0f016ab6 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -93,9 +93,9 @@ func BuiltinBootstrap() (dtypes.BootstrapPeers, error) { return build.BuiltinBootstrap() } -func DrandBootstrap(d dtypes.DrandConfig) (dtypes.DrandBootstrap, error) { +func DrandBootstrap(d dtypes.DrandSchedule) (dtypes.DrandBootstrap, error) { // TODO: retry resolving, don't fail if at least one resolve succeeds - addrs, err := addrutil.ParseAddresses(context.TODO(), d.Relays) + addrs, err := addrutil.ParseAddresses(context.TODO(), d[0].Config.Relays) if err != nil { log.Errorf("reoslving drand relays addresses: %+v", err) return nil, nil diff --git a/node/modules/dtypes/beacon.go b/node/modules/dtypes/beacon.go index 2231f0e08..28bbdf281 100644 --- a/node/modules/dtypes/beacon.go +++ b/node/modules/dtypes/beacon.go @@ -1,5 +1,14 @@ package dtypes +import "github.com/filecoin-project/go-state-types/abi" + +type DrandSchedule []DrandPoint + +type DrandPoint struct { + Start abi.ChainEpoch + Config DrandConfig +} + type DrandConfig struct { Servers []string Relays []string diff --git a/node/modules/lp2p/pubsub.go b/node/modules/lp2p/pubsub.go index 90c56f20d..41027672c 100644 --- a/node/modules/lp2p/pubsub.go +++ b/node/modules/lp2p/pubsub.go @@ -49,7 +49,7 @@ type GossipIn struct { Db dtypes.DrandBootstrap Cfg *config.Pubsub Sk *dtypes.ScoreKeeper - Dr dtypes.DrandConfig + Dr dtypes.DrandSchedule } func getDrandTopic(chainInfoJSON string) (string, error) { @@ -74,7 +74,7 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { } isBootstrapNode := in.Cfg.Bootstrapper - drandTopic, err := getDrandTopic(in.Dr.ChainInfoJSON) + drandTopic, err := getDrandTopic(in.Dr[0].Config.ChainInfoJSON) if err != nil { return nil, err } diff --git a/node/modules/services.go b/node/modules/services.go index b54a14bb1..c93cc558d 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -126,19 +126,27 @@ type RandomBeaconParams struct { PubSub *pubsub.PubSub `optional:"true"` Cs *store.ChainStore - DrandConfig dtypes.DrandConfig + DrandConfig dtypes.DrandSchedule } -func BuiltinDrandConfig() dtypes.DrandConfig { - return build.DrandConfig() +func BuiltinDrandConfig() dtypes.DrandSchedule { + return build.DrandConfigSchedule() } -func RandomBeacon(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) { +func RandomSchedule(p RandomBeaconParams, _ dtypes.AfterGenesisSet) (beacon.Schedule, error) { gen, err := p.Cs.GetGenesis() if err != nil { return nil, err } - //return beacon.NewMockBeacon(build.BlockDelaySecs * time.Second) - return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelaySecs, p.PubSub, p.DrandConfig) + shd := beacon.Schedule{} + for _, dc := range p.DrandConfig { + bc, err := drand.NewDrandBeacon(gen.Timestamp, build.BlockDelaySecs, p.PubSub, dc.Config) + if err != nil { + return nil, xerrors.Errorf("creating drand beacon: %w", err) + } + shd = append(shd, beacon.BeaconPoint{Start: dc.Start, Beacon: bc}) + } + + return shd, nil } diff --git a/node/modules/testing/beacon.go b/node/modules/testing/beacon.go index a4ef822fc..7876e1d05 100644 --- a/node/modules/testing/beacon.go +++ b/node/modules/testing/beacon.go @@ -7,6 +7,9 @@ import ( "github.com/filecoin-project/lotus/chain/beacon" ) -func RandomBeacon() (beacon.RandomBeacon, error) { - return beacon.NewMockBeacon(time.Duration(build.BlockDelaySecs) * time.Second), nil +func RandomBeacon() (beacon.Schedule, error) { + return beacon.Schedule{ + {Start: 0, + Beacon: beacon.NewMockBeacon(time.Duration(build.BlockDelaySecs) * time.Second), + }}, nil } diff --git a/scripts/dev/sminer-init b/scripts/dev/sminer-init index 767921511..2f4a3f7af 100755 --- a/scripts/dev/sminer-init +++ b/scripts/dev/sminer-init @@ -7,4 +7,4 @@ export TRUST_PARAMS=1 tag=${TAG:-debug} go run -tags=$tag ./cmd/lotus wallet import ~/.genesis-sectors/pre-seal-t01000.key -go run -tags=$tag ./cmd/lotus-miner init --actor=t01000 --genesis-miner --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t01000.json +go run -tags=$tag ./cmd/lotus-storage-miner init --actor=t01000 --genesis-miner --pre-sealed-sectors=~/.genesis-sectors --pre-sealed-metadata=~/.genesis-sectors/pre-seal-t01000.json