diff --git a/CHANGELOG.md b/CHANGELOG.md index a3d85ab6f..8617554a9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,60 @@ # Lotus changelog +# 0.7.0 / 2020-09-10 + +This consensus-breaking release of Lotus is designed to test a network upgrade on the space race testnet. The changes that break consensus are: + +- Upgrading the Drand network used from the test Drand network to the League of Entropy main drand network. This is the same Drand network that will be used in the Filecoin mainnet. +- Upgrading to specs-actors v0.9.8, which adds a new method to the Multisig actor. + +## Changes + +#### Core Lotus + +- Fix IsAncestorOf (https://github.com/filecoin-project/lotus/pull/3717) +- Update to specs-actors v0.9.8 (https://github.com/filecoin-project/lotus/pull/3725) +- Increase chain throughput by 20% (https://github.com/filecoin-project/lotus/pull/3732) +- Updare to go-libp2p-pubsub `master` (https://github.com/filecoin-project/lotus/pull/3735) +- Drand upgrade (https://github.com/filecoin-project/lotus/pull/3670) +- Multisig API additions (https://github.com/filecoin-project/lotus/pull/3590) + +#### Storage Miner + +- Increase the number of times precommit2 is attempted before moving back to precommit1 (https://github.com/filecoin-project/lotus/pull/3720) + +#### Message pool + +- Relax mpool add strictness checks for local pushes (https://github.com/filecoin-project/lotus/pull/3724) + + +#### Maintenance + +- Fix devnets (https://github.com/filecoin-project/lotus/pull/3712) +- Fix(chainwatch): compare prev miner with cur miner (https://github.com/filecoin-project/lotus/pull/3715) +- CI: fix statediff build; make optional (https://github.com/filecoin-project/lotus/pull/3729) +- Feat: Chaos abort (https://github.com/filecoin-project/lotus/pull/3733) + +## Contributors + +The following contributors had commits go into this release. +We are grateful for every contribution! + +| Contributor | Commits | Lines ± | +|--------------------|---------|---------------| +| arajasek | 28 | +1144/-239 | +| Kubuxu | 19 | +452/-261 | +| whyrusleeping | 13 | +456/-87 | +| vyzo | 11 | +318/-20 | +| raulk | 10 | +1289/-350 | +| magik6k | 6 | +188/-55 | +| dirkmc | 3 | +31/-8 | +| alanshaw | 3 | +176/-37 | +| Stebalien | 2 | +9/-12 | +| lanzafame | 1 | +1/-1 | +| frrist | 1 | +1/-1 | +| mishmosh | 1 | +1/-1 | +| nonsense | 1 | +1/-0 | + # 0.6.2 / 2020-09-09 This release introduces some critical fixes to message selection and gas estimation logic. It also adds the ability for nodes to mark a certain tipset as checkpointed, as well as various minor improvements and bugfixes. @@ -38,7 +93,6 @@ This release introduces some critical fixes to message selection and gas estimat - Paych: add docs on how to use paych status (https://github.com/filecoin-project/lotus/pull/3690) - Initial CODEOWNERS (https://github.com/filecoin-project/lotus/pull/3691) - # 0.6.1 / 2020-09-08 This optional release introduces a minor improvement to the sync process, ensuring nodes don't fall behind and then resync. diff --git a/api/api_full.go b/api/api_full.go index 02417bf78..a604028fb 100644 --- a/api/api_full.go +++ b/api/api_full.go @@ -5,6 +5,8 @@ import ( "fmt" "time" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/specs-actors/actors/runtime/proof" "github.com/ipfs/go-cid" @@ -318,7 +320,7 @@ type FullNode interface { StateMinerActiveSectors(context.Context, address.Address, types.TipSetKey) ([]*ChainSectorInfo, error) // StateMinerProvingDeadline calculates the deadline at some epoch for a proving period // and returns the deadline-related calculations. - StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) + StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) // StateMinerPower returns the power of the indicated miner StateMinerPower(context.Context, address.Address, types.TipSetKey) (*MinerPower, error) // StateMinerInfo returns info about the indicated miner diff --git a/api/apistruct/struct.go b/api/apistruct/struct.go index ffb837785..6f32d204b 100644 --- a/api/apistruct/struct.go +++ b/api/apistruct/struct.go @@ -5,6 +5,8 @@ import ( "io" "time" + "github.com/filecoin-project/go-state-types/dline" + "github.com/ipfs/go-cid" metrics "github.com/libp2p/go-libp2p-core/metrics" "github.com/libp2p/go-libp2p-core/network" @@ -162,7 +164,7 @@ type FullNodeStruct struct { StateNetworkName func(context.Context) (dtypes.NetworkName, error) `perm:"read"` StateMinerSectors func(context.Context, address.Address, *bitfield.BitField, bool, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"` StateMinerActiveSectors func(context.Context, address.Address, types.TipSetKey) ([]*api.ChainSectorInfo, error) `perm:"read"` - StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) `perm:"read"` + StateMinerProvingDeadline func(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) `perm:"read"` StateMinerPower func(context.Context, address.Address, types.TipSetKey) (*api.MinerPower, error) `perm:"read"` StateMinerInfo func(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) `perm:"read"` StateMinerDeadlines func(context.Context, address.Address, types.TipSetKey) ([]*miner.Deadline, error) `perm:"read"` @@ -738,7 +740,7 @@ func (c *FullNodeStruct) StateMinerActiveSectors(ctx context.Context, addr addre return c.Internal.StateMinerActiveSectors(ctx, addr, tsk) } -func (c *FullNodeStruct) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*miner.DeadlineInfo, error) { +func (c *FullNodeStruct) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) { return c.Internal.StateMinerProvingDeadline(ctx, addr, tsk) } 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..0ef1d9b34 100644 --- a/build/params_2k.go +++ b/build/params_2k.go @@ -13,6 +13,12 @@ import ( const UpgradeBreezeHeight = -1 const BreezeGasTampingDuration = 0 +const UpgradeSmokeHeight = -1 + +var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ + 0: DrandMainnet, +} + func init() { power.ConsensusMinerMinPower = big.NewInt(2048) miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ @@ -23,7 +29,7 @@ func init() { BuildType |= Build2k } -const BlockDelaySecs = uint64(4) +const BlockDelaySecs = uint64(30) const PropagationDelaySecs = uint64(1) diff --git a/build/params_shared_funcs.go b/build/params_shared_funcs.go index 2c9ef0b94..2c585271a 100644 --- a/build/params_shared_funcs.go +++ b/build/params_shared_funcs.go @@ -36,3 +36,11 @@ func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + st func DhtProtocolName(netName dtypes.NetworkName) protocol.ID { return protocol.ID("/fil/kad/" + string(netName)) } + +func UseNewestNetwork() bool { + // TODO: Put these in a container we can iterate over + if UpgradeBreezeHeight <= 0 && UpgradeSmokeHeight <= 0 { + return true + } + return false +} diff --git a/build/params_shared_vals.go b/build/params_shared_vals.go index 7b4d4574b..4a46b7fd1 100644 --- a/build/params_shared_vals.go +++ b/build/params_shared_vals.go @@ -5,6 +5,8 @@ package build import ( "math/big" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" @@ -20,6 +22,7 @@ const UnixfsLinksPerLevel = 1024 // Consensus / Network const AllowableClockDriftSecs = uint64(1) +const NewestNetworkVersion = network.Version2 // Epochs const ForkLengthThreshold = Finality diff --git a/build/params_testground.go b/build/params_testground.go index 06d4aecc5..395d2a855 100644 --- a/build/params_testground.go +++ b/build/params_testground.go @@ -11,6 +11,7 @@ import ( "math/big" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/miner" ) @@ -70,6 +71,14 @@ var ( PackingEfficiencyNum int64 = 4 PackingEfficiencyDenom int64 = 5 - UpgradeBreezeHeight abi.ChainEpoch = 0 + UpgradeBreezeHeight abi.ChainEpoch = -1 BreezeGasTampingDuration abi.ChainEpoch = 0 + + UpgradeSmokeHeight abi.ChainEpoch = -1 + + DrandSchedule = map[abi.ChainEpoch]DrandEnum{ + 0: DrandMainnet, + } + + NewestNetworkVersion = network.Version2 ) diff --git a/build/params_testnet.go b/build/params_testnet.go index 4a7523287..932ad7a7d 100644 --- a/build/params_testnet.go +++ b/build/params_testnet.go @@ -12,9 +12,16 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/power" ) +var DrandSchedule = map[abi.ChainEpoch]DrandEnum{ + 0: DrandIncentinet, + UpgradeSmokeHeight: DrandMainnet, +} + const UpgradeBreezeHeight = 41280 const BreezeGasTampingDuration = 120 +const UpgradeSmokeHeight = 51000 + func init() { power.ConsensusMinerMinPower = big.NewInt(10 << 40) miner.SupportedProofTypes = map[abi.RegisteredSealProof]struct{}{ diff --git a/build/version.go b/build/version.go index ba5519a7c..2466d8023 100644 --- a/build/version.go +++ b/build/version.go @@ -29,7 +29,7 @@ func buildType() string { } // BuildVersion is the local build version, set by build system -const BuildVersion = "0.6.2" +const BuildVersion = "0.7.0" func UserVersion() string { return BuildVersion + buildType() + CurrentCommit diff --git a/chain/beacon/beacon.go b/chain/beacon/beacon.go index 5f8a18951..9543bec54 100644 --- a/chain/beacon/beacon.go +++ b/chain/beacon/beacon.go @@ -18,6 +18,23 @@ type Response struct { Err error } +type Schedule []BeaconPoint + +func (bs Schedule) BeaconForEpoch(e abi.ChainEpoch) RandomBeacon { + for i := len(bs) - 1; i >= 0; i-- { + bp := bs[i] + if e >= bp.Start { + return bp.Beacon + } + } + return bs[0].Beacon +} + +type BeaconPoint struct { + Start abi.ChainEpoch + Beacon RandomBeacon +} + // RandomBeacon represents a system that provides randomness to Lotus. // Other components interrogate the RandomBeacon to acquire randomness that's // valid for a specific chain epoch. Also to verify beacon entries that have @@ -25,11 +42,30 @@ type Response 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(b RandomBeacon, h *types.BlockHeader, prevEntry types.BeaconEntry) error { - maxRound := b.MaxBeaconRoundForEpoch(h.Height, prevEntry) +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) 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)) @@ -56,10 +92,35 @@ func ValidateBlockValues(b RandomBeacon, h *types.BlockHeader, prevEntry types.B return nil } -func BeaconEntriesForBlock(ctx context.Context, beacon RandomBeacon, round abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) { +func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, epoch abi.ChainEpoch, parentEpoch abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) { + { + 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(round, prev) + maxRound := beacon.MaxBeaconRoundForEpoch(epoch) if maxRound == prev.Round { return nil, nil } @@ -82,7 +143,7 @@ func BeaconEntriesForBlock(ctx context.Context, beacon RandomBeacon, round abi.C out = append(out, resp.Entry) cur = resp.Entry.Round - 1 case <-ctx.Done(): - return nil, xerrors.Errorf("context timed out waiting on beacon entry to come back for round %d: %w", round, ctx.Err()) + return nil, xerrors.Errorf("context timed out waiting on beacon entry to come back for epoch %d: %w", epoch, ctx.Err()) } } 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/drand/drand_test.go b/chain/beacon/drand/drand_test.go index 8d7c1b2cc..0cb9c2ba8 100644 --- a/chain/beacon/drand/drand_test.go +++ b/chain/beacon/drand/drand_test.go @@ -12,7 +12,7 @@ import ( ) func TestPrintGroupInfo(t *testing.T) { - server := build.DrandConfig().Servers[0] + server := build.DrandConfigs[build.DrandIncentinet].Servers[0] c, err := hclient.New(server, nil, nil) assert.NoError(t, err) cg := c.(interface { 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/chain/gen/gen.go b/chain/gen/gen.go index e6127508e..d661411fe 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -59,7 +59,7 @@ type ChainGen struct { cs *store.ChainStore - beacon beacon.RandomBeacon + beacon beacon.Schedule sm *stmgr.StateManager @@ -252,7 +252,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) { miners := []address.Address{maddr1, maddr2} - beac := beacon.NewMockBeacon(time.Second) + beac := beacon.Schedule{{Start: 0, Beacon: beacon.NewMockBeacon(time.Second)}} //beac, err := drand.NewDrandBeacon(tpl.Timestamp, build.BlockDelaySecs) //if err != nil { //return nil, xerrors.Errorf("creating drand beacon: %w", err) @@ -338,7 +338,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add prev := mbi.PrevBeaconEntry - entries, err := beacon.BeaconEntriesForBlock(ctx, cg.beacon, round, prev) + entries, err := beacon.BeaconEntriesForBlock(ctx, cg.beacon, round, pts.Height(), prev) if err != nil { return nil, nil, nil, xerrors.Errorf("get beacon entries for block: %w", err) } @@ -358,7 +358,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add return nil, nil, nil, xerrors.Errorf("failed to cbor marshal address: %w", err) } - if len(entries) == 0 { + if round > build.UpgradeSmokeHeight { buf.Write(pts.MinTicket().VRFProof) } @@ -559,7 +559,7 @@ type mca struct { w *wallet.Wallet sm *stmgr.StateManager pv ffiwrapper.Verifier - bcn beacon.RandomBeacon + bcn beacon.Schedule } func (mca mca) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) { diff --git a/chain/gen/genesis/genesis.go b/chain/gen/genesis/genesis.go index ac22b5b19..0a9d58924 100644 --- a/chain/gen/genesis/genesis.go +++ b/chain/gen/genesis/genesis.go @@ -6,7 +6,7 @@ import ( "encoding/json" "fmt" - "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/go-state-types/network" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" @@ -406,8 +406,8 @@ func VerifyPreSealedData(ctx context.Context, cs *store.ChainStore, stateroot ci verifNeeds := make(map[address.Address]abi.PaddedPieceSize) var sum abi.PaddedPieceSize - nwv := func(context.Context, abi.ChainEpoch) runtime.NetworkVersion { - return runtime.NetworkVersion1 + nwv := func(context.Context, abi.ChainEpoch) network.Version { + return build.NewestNetworkVersion } vmopt := vm.VMOpts{ diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index d8441c66c..b57608a5f 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -6,6 +6,10 @@ import ( "fmt" "math/rand" + "github.com/filecoin-project/lotus/build" + + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/lotus/chain/state" "github.com/ipfs/go-cid" @@ -61,8 +65,8 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid return big.Zero(), nil } - nwv := func(context.Context, abi.ChainEpoch) runtime.NetworkVersion { - return runtime.NetworkVersion1 + nwv := func(context.Context, abi.ChainEpoch) network.Version { + return build.NewestNetworkVersion } vmopt := &vm.VMOpts{ diff --git a/chain/stmgr/forks_test.go b/chain/stmgr/forks_test.go index b5fb0c602..e96d3f316 100644 --- a/chain/stmgr/forks_test.go +++ b/chain/stmgr/forks_test.go @@ -15,7 +15,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/power" "github.com/filecoin-project/specs-actors/actors/builtin/verifreg" "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/filecoin-project/specs-actors/actors/util/adt" "golang.org/x/xerrors" "github.com/filecoin-project/lotus/chain/actors" @@ -73,15 +72,15 @@ func (ta *testActor) Exports() []interface{} { } } -func (ta *testActor) Constructor(rt runtime.Runtime, params *adt.EmptyValue) *adt.EmptyValue { +func (ta *testActor) Constructor(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() rt.State().Create(&testActorState{11}) fmt.Println("NEW ACTOR ADDRESS IS: ", rt.Message().Receiver()) - return adt.Empty + return abi.Empty } -func (ta *testActor) TestMethod(rt runtime.Runtime, params *adt.EmptyValue) *adt.EmptyValue { +func (ta *testActor) TestMethod(rt runtime.Runtime, params *abi.EmptyValue) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() var st testActorState rt.State().Readonly(&st) @@ -96,7 +95,7 @@ func (ta *testActor) TestMethod(rt runtime.Runtime, params *adt.EmptyValue) *adt } } - return adt.Empty + return abi.Empty } func TestForkHeightTriggers(t *testing.T) { diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 929c9daf7..e6103e2b3 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -5,7 +5,7 @@ import ( "fmt" "sync" - "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/go-state-types/network" "github.com/filecoin-project/specs-actors/actors/builtin/power" @@ -1124,14 +1124,18 @@ func (sm *StateManager) GetCirculatingSupply(ctx context.Context, height abi.Cha return csi.FilCirculating, nil } -func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) runtime.NetworkVersion { - if build.UpgradeBreezeHeight == 0 { - return runtime.NetworkVersion1 +func (sm *StateManager) GetNtwkVersion(ctx context.Context, height abi.ChainEpoch) network.Version { + if build.UseNewestNetwork() { + return build.NewestNetworkVersion } if height <= build.UpgradeBreezeHeight { - return runtime.NetworkVersion0 + return network.Version0 } - return runtime.NetworkVersion1 + if height <= build.UpgradeSmokeHeight { + return network.Version1 + } + + return build.NewestNetworkVersion } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index b21400da6..f77ec20ff 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -502,7 +502,7 @@ func GetLookbackTipSetForRound(ctx context.Context, sm *StateManager, ts *types. return lbts, nil } -func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcn beacon.RandomBeacon, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) { +func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule, tsk types.TipSetKey, round abi.ChainEpoch, maddr address.Address, pv ffiwrapper.Verifier) (*api.MiningBaseInfo, error) { ts, err := sm.ChainStore().LoadTipSet(tsk) if err != nil { return nil, xerrors.Errorf("failed to load tipset for mining base: %w", err) @@ -517,7 +517,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcn beacon.RandomBe prev = &types.BeaconEntry{} } - entries, err := beacon.BeaconEntriesForBlock(ctx, bcn, round, *prev) + entries, err := beacon.BeaconEntriesForBlock(ctx, bcs, round, ts.Height(), *prev) if err != nil { return nil, err } @@ -624,8 +624,8 @@ func init() { // Explicitly add send, it's special. methods[builtin.MethodSend] = MethodMeta{ Name: "Send", - Params: reflect.TypeOf(new(adt.EmptyValue)), - Ret: reflect.TypeOf(new(adt.EmptyValue)), + Params: reflect.TypeOf(new(abi.EmptyValue)), + Ret: reflect.TypeOf(new(abi.EmptyValue)), } // Learn method names from the builtin.Methods* structs. diff --git a/chain/store/basefee.go b/chain/store/basefee.go index 69970dd96..45785240e 100644 --- a/chain/store/basefee.go +++ b/chain/store/basefee.go @@ -11,14 +11,20 @@ import ( "golang.org/x/xerrors" ) -func computeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int) types.BigInt { - // deta := 1/PackingEfficiency * gasLimitUsed/noOfBlocks - build.BlockGasTarget - // change := baseFee * deta / BlockGasTarget / BaseFeeMaxChangeDenom +func ComputeNextBaseFee(baseFee types.BigInt, gasLimitUsed int64, noOfBlocks int, epoch abi.ChainEpoch) types.BigInt { + // deta := gasLimitUsed/noOfBlocks - build.BlockGasTarget + // change := baseFee * deta / BlockGasTarget // nextBaseFee = baseFee + change // nextBaseFee = max(nextBaseFee, build.MinimumBaseFee) - delta := build.PackingEfficiencyDenom * gasLimitUsed / (int64(noOfBlocks) * build.PackingEfficiencyNum) - delta -= build.BlockGasTarget + var delta int64 + if epoch > build.UpgradeSmokeHeight { + delta = gasLimitUsed / int64(noOfBlocks) + delta -= build.BlockGasTarget + } else { + delta = build.PackingEfficiencyDenom * gasLimitUsed / (int64(noOfBlocks) * build.PackingEfficiencyNum) + delta -= build.BlockGasTarget + } // cap change at 12.5% (BaseFeeMaxChangeDenom) by capping delta if delta > build.BlockGasTarget { @@ -73,5 +79,5 @@ func (cs *ChainStore) ComputeBaseFee(ctx context.Context, ts *types.TipSet) (abi } parentBaseFee := ts.Blocks()[0].ParentBaseFee - return computeNextBaseFee(parentBaseFee, totalLimit, len(ts.Blocks())), nil + return ComputeNextBaseFee(parentBaseFee, totalLimit, len(ts.Blocks()), ts.Height()), nil } diff --git a/chain/store/basefee_test.go b/chain/store/basefee_test.go index 7a7cae911..b4757f70e 100644 --- a/chain/store/basefee_test.go +++ b/chain/store/basefee_test.go @@ -27,7 +27,7 @@ func TestBaseFee(t *testing.T) { for _, test := range tests { test := test t.Run(fmt.Sprintf("%v", test), func(t *testing.T) { - output := computeNextBaseFee(types.NewInt(test.basefee), test.limitUsed, test.noOfBlocks) + output := ComputeNextBaseFee(types.NewInt(test.basefee), test.limitUsed, test.noOfBlocks, 0) assert.Equal(t, fmt.Sprintf("%d", test.output), output.String()) }) } diff --git a/chain/sync.go b/chain/sync.go index d64e68055..9864600dd 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -103,7 +103,7 @@ type Syncer struct { store *store.ChainStore // handle to the random beacon for verification - beacon beacon.RandomBeacon + beacon beacon.Schedule // the state manager handles making state queries sm *stmgr.StateManager @@ -141,7 +141,7 @@ type Syncer struct { } // NewSyncer creates a new Syncer object. -func NewSyncer(ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.Client, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*Syncer, error) { +func NewSyncer(ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.Client, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.Schedule, verifier ffiwrapper.Verifier) (*Syncer, error) { gen, err := sm.ChainStore().GetGenesis() if err != nil { return nil, xerrors.Errorf("getting genesis block: %w", err) @@ -879,7 +879,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er return nil } - if err := beacon.ValidateBlockValues(syncer.beacon, h, *prevBeacon); err != nil { + if err := beacon.ValidateBlockValues(syncer.beacon, h, baseTs.Height(), *prevBeacon); err != nil { return xerrors.Errorf("failed to validate blocks random beacon values: %w", err) } return nil @@ -891,10 +891,12 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er return xerrors.Errorf("failed to marshal miner address to cbor: %w", err) } - beaconBase := *prevBeacon - if len(h.BeaconEntries) == 0 { + if h.Height > build.UpgradeSmokeHeight { buf.Write(baseTs.MinTicket().VRFProof) - } else { + } + + beaconBase := *prevBeacon + if len(h.BeaconEntries) != 0 { beaconBase = h.BeaconEntries[len(h.BeaconEntries)-1] } diff --git a/chain/vm/invoker.go b/chain/vm/invoker.go index 2ec56a9db..c9d22cd4c 100644 --- a/chain/vm/invoker.go +++ b/chain/vm/invoker.go @@ -15,6 +15,7 @@ import ( "golang.org/x/xerrors" "github.com/filecoin-project/go-state-types/abi" + "github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/cron" init_ "github.com/filecoin-project/specs-actors/actors/builtin/init" @@ -27,9 +28,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin/system" "github.com/filecoin-project/specs-actors/actors/runtime" vmr "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/filecoin-project/specs-actors/actors/util/adt" - - "github.com/filecoin-project/lotus/chain/actors/aerrors" ) type Invoker struct { @@ -47,7 +45,7 @@ func NewInvoker() *Invoker { } // add builtInCode using: register(cid, singleton) - inv.Register(builtin.SystemActorCodeID, system.Actor{}, adt.EmptyValue{}) + inv.Register(builtin.SystemActorCodeID, system.Actor{}, abi.EmptyValue{}) inv.Register(builtin.InitActorCodeID, init_.Actor{}, init_.State{}) inv.Register(builtin.RewardActorCodeID, reward.Actor{}, reward.State{}) inv.Register(builtin.CronActorCodeID, cron.Actor{}, cron.State{}) diff --git a/chain/vm/invoker_test.go b/chain/vm/invoker_test.go index d19321c99..3744aa8d2 100644 --- a/chain/vm/invoker_test.go +++ b/chain/vm/invoker_test.go @@ -5,6 +5,8 @@ import ( "io" "testing" + "github.com/filecoin-project/go-state-types/abi" + cbor "github.com/ipfs/go-ipld-cbor" "github.com/stretchr/testify/assert" cbg "github.com/whyrusleeping/cbor-gen" @@ -13,7 +15,6 @@ import ( "github.com/filecoin-project/lotus/chain/actors" "github.com/filecoin-project/lotus/chain/actors/aerrors" "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/filecoin-project/specs-actors/actors/util/adt" ) type basicContract struct{} @@ -60,17 +61,17 @@ func (b basicContract) Exports() []interface{} { } } -func (basicContract) InvokeSomething0(rt runtime.Runtime, params *basicParams) *adt.EmptyValue { +func (basicContract) InvokeSomething0(rt runtime.Runtime, params *basicParams) *abi.EmptyValue { rt.Abortf(exitcode.ExitCode(params.B), "params.B") return nil } -func (basicContract) BadParam(rt runtime.Runtime, params *basicParams) *adt.EmptyValue { +func (basicContract) BadParam(rt runtime.Runtime, params *basicParams) *abi.EmptyValue { rt.Abortf(255, "bad params") return nil } -func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams) *adt.EmptyValue { +func (basicContract) InvokeSomething10(rt runtime.Runtime, params *basicParams) *abi.EmptyValue { rt.Abortf(exitcode.ExitCode(params.B+10), "params.B") return nil } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 043ea3a45..7e9dd894b 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -8,6 +8,8 @@ import ( gruntime "runtime" "time" + "github.com/filecoin-project/go-state-types/network" + "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" @@ -16,7 +18,6 @@ import ( "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/runtime" vmr "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" @@ -56,7 +57,7 @@ type Runtime struct { lastGasCharge *types.GasTrace } -func (rt *Runtime) NetworkVersion() vmr.NetworkVersion { +func (rt *Runtime) NetworkVersion() network.Version { return rt.vm.GetNtwkVersion(rt.ctx, rt.CurrEpoch()) } @@ -136,7 +137,7 @@ func (rt *Runtime) shimCall(f func() interface{}) (rval []byte, aerr aerrors.Act switch ret := ret.(type) { case []byte: return ret, nil - case *adt.EmptyValue: + case *abi.EmptyValue: return nil, nil case cbg.CBORMarshaler: buf := new(bytes.Buffer) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index eb6c2f354..e389a3531 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -7,7 +7,7 @@ import ( "reflect" "time" - "github.com/filecoin-project/specs-actors/actors/runtime" + "github.com/filecoin-project/go-state-types/network" bstore "github.com/filecoin-project/lotus/lib/blockstore" @@ -142,7 +142,7 @@ func (vm *UnsafeVM) MakeRuntime(ctx context.Context, msg *types.Message, origin } type CircSupplyCalculator func(context.Context, abi.ChainEpoch, *state.StateTree) (abi.TokenAmount, error) -type NtwkVersionGetter func(context.Context, abi.ChainEpoch) runtime.NetworkVersion +type NtwkVersionGetter func(context.Context, abi.ChainEpoch) network.Version type VM struct { cstate *state.StateTree @@ -722,7 +722,7 @@ func (vm *VM) SetInvoker(i *Invoker) { vm.inv = i } -func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) runtime.NetworkVersion { +func (vm *VM) GetNtwkVersion(ctx context.Context, ce abi.ChainEpoch) network.Version { return vm.ntwkVersion(ctx, ce) } diff --git a/cmd/lotus/debug_advance.go b/cmd/lotus/debug_advance.go index 73eab49fc..4e74a995f 100644 --- a/cmd/lotus/debug_advance.go +++ b/cmd/lotus/debug_advance.go @@ -46,6 +46,7 @@ func init() { return xerrors.Errorf("StateMinerWorker: %w", err) } + // XXX: This can't be right rand, err := api.ChainGetRandomnessFromTickets(ctx, head.Key(), crypto.DomainSeparationTag_TicketProduction, head.Height(), addr.Bytes()) if err != nil { return xerrors.Errorf("failed to get randomness: %w", err) diff --git a/conformance/chaos/actor.go b/conformance/chaos/actor.go index f3da42bb6..b9a181ba7 100644 --- a/conformance/chaos/actor.go +++ b/conformance/chaos/actor.go @@ -6,7 +6,6 @@ import ( "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/runtime" - "github.com/filecoin-project/specs-actors/actors/util/adt" "github.com/ipfs/go-cid" typegen "github.com/whyrusleeping/cbor-gen" @@ -120,7 +119,7 @@ func (a Actor) Send(rt runtime.Runtime, args *SendArgs) *SendReturn { } // Constructor will panic because the Chaos actor is a singleton. -func (a Actor) Constructor(_ runtime.Runtime, _ *adt.EmptyValue) *adt.EmptyValue { +func (a Actor) Constructor(_ runtime.Runtime, _ *abi.EmptyValue) *abi.EmptyValue { panic("constructor should not be called; the Chaos actor is a singleton actor") } @@ -131,7 +130,7 @@ func (a Actor) Constructor(_ runtime.Runtime, _ *adt.EmptyValue) *adt.EmptyValue // CallerValidationBranchAddrNilSet validates against an empty caller // address set. // CallerValidationBranchTypeNilSet validates against an empty caller type set. -func (a Actor) CallerValidation(rt runtime.Runtime, branch *typegen.CborInt) *adt.EmptyValue { +func (a Actor) CallerValidation(rt runtime.Runtime, branch *typegen.CborInt) *abi.EmptyValue { switch CallerValidationBranch(*branch) { case CallerValidationBranchNone: case CallerValidationBranchTwice: @@ -161,7 +160,7 @@ type CreateActorArgs struct { } // CreateActor creates an actor with the supplied CID and Address. -func (a Actor) CreateActor(rt runtime.Runtime, args *CreateActorArgs) *adt.EmptyValue { +func (a Actor) CreateActor(rt runtime.Runtime, args *CreateActorArgs) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() var ( @@ -199,7 +198,7 @@ func (a Actor) ResolveAddress(rt runtime.Runtime, args *address.Address) *Resolv // DeleteActor deletes the executing actor from the state tree, transferring any // balance to beneficiary. -func (a Actor) DeleteActor(rt runtime.Runtime, beneficiary *address.Address) *adt.EmptyValue { +func (a Actor) DeleteActor(rt runtime.Runtime, beneficiary *address.Address) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() rt.DeleteActor(*beneficiary) return nil @@ -213,7 +212,7 @@ type MutateStateArgs struct { } // MutateState attempts to mutate a state value in the actor. -func (a Actor) MutateState(rt runtime.Runtime, args *MutateStateArgs) *adt.EmptyValue { +func (a Actor) MutateState(rt runtime.Runtime, args *MutateStateArgs) *abi.EmptyValue { rt.ValidateImmediateCallerAcceptAny() var st State switch args.Branch { @@ -244,7 +243,7 @@ type AbortWithArgs struct { } // AbortWith simply causes a panic with the passed exit code. -func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *adt.EmptyValue { +func (a Actor) AbortWith(rt runtime.Runtime, args *AbortWithArgs) *abi.EmptyValue { if args.Uncontrolled { // uncontrolled abort: directly panic panic(args.Message) } else { diff --git a/documentation/en/api-methods.md b/documentation/en/api-methods.md index 49582d6f8..7c2d91881 100644 --- a/documentation/en/api-methods.md +++ b/documentation/en/api-methods.md @@ -3633,7 +3633,12 @@ Response: "Open": 10101, "Close": 10101, "Challenge": 10101, - "FaultCutoff": 10101 + "FaultCutoff": 10101, + "WPoStPeriodDeadlines": 42, + "WPoStProvingPeriod": 10101, + "WPoStChallengeWindow": 10101, + "WPoStChallengeLookback": 10101, + "FaultDeclarationCutoff": 10101 } ``` diff --git a/go.mod b/go.mod index 20e3e647e..df1c598a3 100644 --- a/go.mod +++ b/go.mod @@ -15,8 +15,8 @@ require ( github.com/detailyang/go-fallocate v0.0.0-20180908115635-432fa640bd2e github.com/dgraph-io/badger/v2 v2.0.3 github.com/docker/go-units v0.4.0 - github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4 - github.com/drand/kyber v1.1.1 + github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32 + github.com/drand/kyber v1.1.2 github.com/dustin/go-humanize v1.0.0 github.com/elastic/go-sysinfo v1.3.0 github.com/fatih/color v1.8.0 @@ -32,11 +32,11 @@ require ( github.com/filecoin-project/go-multistore v0.0.3 github.com/filecoin-project/go-padreader v0.0.0-20200903213702-ed5fae088b20 github.com/filecoin-project/go-paramfetch v0.0.2-0.20200701152213-3e0f0afdc261 - github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df + github.com/filecoin-project/go-state-types v0.0.0-20200909080127-001afaca718c github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370 github.com/filecoin-project/go-statestore v0.1.0 github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b - github.com/filecoin-project/specs-actors v0.9.7 + github.com/filecoin-project/specs-actors v0.9.8 github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 github.com/filecoin-project/test-vectors/schema v0.0.1 github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1 diff --git a/go.sum b/go.sum index 2c645fec1..e9ad1c4d0 100644 --- a/go.sum +++ b/go.sum @@ -91,6 +91,7 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g= +github.com/briandowns/spinner v1.11.1 h1:OixPqDEcX3juo5AjQZAnFPbeUA0jvkp2qzB5gOZJ/L0= github.com/briandowns/spinner v1.11.1/go.mod h1:QOuQk7x+EaDASo80FEXwlwiA+j/PPIcX3FScO+3/ZPQ= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= @@ -179,12 +180,12 @@ github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/drand/bls12-381 v0.3.2 h1:RImU8Wckmx8XQx1tp1q04OV73J9Tj6mmpQLYDP7V1XE= github.com/drand/bls12-381 v0.3.2/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y= -github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4 h1:+Rov3bfUriGWFR/lUVXnpimx+HMr9BXRC4by0BxuQ8k= -github.com/drand/drand v1.0.3-0.20200714175734-29705eaf09d4/go.mod h1:SnqWL9jksIMK63UKkfmWI6f9PDN8ROoCgg+Z4zWk7hg= +github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32 h1:sU+51aQRaDxg0KnjQg19KuYRIxDBEUHffBAICSnBys8= +github.com/drand/drand v1.1.2-0.20200905144319-79c957281b32/go.mod h1:0sQEVg+ngs1jaDPVIiEgY0lbENWJPaUlWxGHEaSmKVM= github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw= github.com/drand/kyber v1.0.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= -github.com/drand/kyber v1.1.1 h1:mwCY2XGRB+Qc1MPfrnRuVuXELkPhcq/r9yMoJIcDhHI= -github.com/drand/kyber v1.1.1/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= +github.com/drand/kyber v1.1.2 h1:faemqlaFyLrbBSjZGRzzu5SG/do+uTYpHlnrJIHbAhQ= +github.com/drand/kyber v1.1.2/go.mod h1:x6KOpK7avKj0GJ4emhXFP5n7M7W7ChAPmnQh/OL6vRw= github.com/drand/kyber-bls12381 v0.1.0 h1:/P4C65VnyEwxzR5ZYYVMNzY1If+aYBrdUU5ukwh7LQw= github.com/drand/kyber-bls12381 v0.1.0/go.mod h1:N1emiHpm+jj7kMlxEbu3MUyOiooTgNySln564cgD9mk= github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= @@ -226,6 +227,8 @@ github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f h1 github.com/filecoin-project/go-fil-commcid v0.0.0-20200716160307-8f644712406f/go.mod h1:Eaox7Hvus1JgPrL5+M3+h7aSPHc0cVqpSxA+TxIEpZQ= github.com/filecoin-project/go-fil-markets v0.6.0 h1:gfxMweUHo4u+2BZh2Q7/7+cV0/ttikuJfhkkxLRsE2Q= github.com/filecoin-project/go-fil-markets v0.6.0/go.mod h1:LhSFYLkjaoe0vFRKABGYyw1Jz+9jCpF1sPA7yOftLTw= +github.com/filecoin-project/go-hamt-ipld v0.1.5 h1:uoXrKbCQZ49OHpsTCkrThPNelC4W3LPEk0OrS/ytIBM= +github.com/filecoin-project/go-hamt-ipld v0.1.5/go.mod h1:6Is+ONR5Cd5R6XZoCse1CWaXZc0Hdb/JeX+EQCQzX24= github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52 h1:FXtCp0ybqdQL9knb3OGDpkNTaBbPxgkqPeWKotUwkH0= github.com/filecoin-project/go-jsonrpc v0.1.2-0.20200822201400-474f4fdccc52/go.mod h1:XBBpuKIMaXIIzeqzO1iucq4GvbF8CxmXRFoezRh+Cx4= github.com/filecoin-project/go-multistore v0.0.3 h1:vaRBY4YiA2UZFPK57RNuewypB8u0DzzQwqsL0XarpnI= @@ -238,6 +241,8 @@ github.com/filecoin-project/go-state-types v0.0.0-20200903145444-247639ffa6ad/go github.com/filecoin-project/go-state-types v0.0.0-20200904021452-1883f36ca2f4/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df h1:m2esXSuGBkuXlRyCsl1a/7/FkFam63o1OzIgzaHtOfI= github.com/filecoin-project/go-state-types v0.0.0-20200905071437-95828685f9df/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= +github.com/filecoin-project/go-state-types v0.0.0-20200909080127-001afaca718c h1:HHRMFpU8OrODDUja5NmGWNBAVGoSy4MRjxgZa+a0qIw= +github.com/filecoin-project/go-state-types v0.0.0-20200909080127-001afaca718c/go.mod h1:IQ0MBPnonv35CJHtWSN3YY1Hz2gkPru1Q9qoaYLxx9I= github.com/filecoin-project/go-statemachine v0.0.0-20200714194326-a77c3ae20989/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370 h1:Jbburj7Ih2iaJ/o5Q9A+EAeTabME6YII7FLi9SKUf5c= github.com/filecoin-project/go-statemachine v0.0.0-20200813232949-df9b130df370/go.mod h1:FGwQgZAt2Gh5mjlwJUlVB62JeYdo+if0xWxSEfBD9ig= @@ -248,6 +253,8 @@ github.com/filecoin-project/go-storedcounter v0.0.0-20200421200003-1c99c62e8a5b/ github.com/filecoin-project/specs-actors v0.9.4/go.mod h1:BStZQzx5x7TmCkLv0Bpa07U6cPKol6fd3w9KjMPZ6Z4= github.com/filecoin-project/specs-actors v0.9.7 h1:7PAZ8kdqwBdmgf/23FCkQZLCXcVu02XJrkpkhBikiA8= github.com/filecoin-project/specs-actors v0.9.7/go.mod h1:wM2z+kwqYgXn5Z7scV1YHLyd1Q1cy0R8HfTIWQ0BFGU= +github.com/filecoin-project/specs-actors v0.9.8 h1:45fnx/BsseFL3CtvSoR6CszFY26TFtsh9AHwCW2vkg8= +github.com/filecoin-project/specs-actors v0.9.8/go.mod h1:xFObDoWPySBNTNBrGXVVrutmgSZH/mMo46Q1bec/0hw= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796 h1:dJsTPWpG2pcTeojO2pyn0c6l+x/3MZYCBgo/9d11JEk= github.com/filecoin-project/specs-storage v0.1.1-0.20200907031224-ed2e5cd13796/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g= github.com/filecoin-project/test-vectors/schema v0.0.1 h1:5fNF76nl4qolEvcIsjc0kUADlTMVHO73tW4kXXPnsus= @@ -1745,7 +1752,6 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v0.0.0-20200617041141-9a465503579e/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/miner/miner.go b/miner/miner.go index 9c11dcc46..1b0f0c766 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -362,7 +362,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, rbase = bvals[len(bvals)-1] } - ticket, err := m.computeTicket(ctx, &rbase, base, len(bvals) > 0) + ticket, err := m.computeTicket(ctx, &rbase, base) if err != nil { return nil, xerrors.Errorf("scratching ticket failed: %w", err) } @@ -432,7 +432,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, return b, nil } -func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase, haveNewEntries bool) (*types.Ticket, error) { +func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, base *MiningBase) (*types.Ticket, error) { mi, err := m.api.StateMinerInfo(ctx, m.address, types.EmptyTSK) if err != nil { return nil, err @@ -447,11 +447,12 @@ func (m *Miner) computeTicket(ctx context.Context, brand *types.BeaconEntry, bas return nil, xerrors.Errorf("failed to marshal address to cbor: %w", err) } - if !haveNewEntries { + round := base.TipSet.Height() + base.NullRounds + 1 + if round > build.UpgradeSmokeHeight { buf.Write(base.TipSet.MinTicket().VRFProof) } - input, err := store.DrawRandomness(brand.Data, crypto.DomainSeparationTag_TicketProduction, base.TipSet.Height()+base.NullRounds+1-build.TicketRandomnessLookback, buf.Bytes()) + input, err := store.DrawRandomness(brand.Data, crypto.DomainSeparationTag_TicketProduction, round-build.TicketRandomnessLookback, buf.Bytes()) if err != nil { return nil, err } 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/client/client.go b/node/impl/client/client.go index d12a4ae73..7a107c2fd 100644 --- a/node/impl/client/client.go +++ b/node/impl/client/client.go @@ -6,6 +6,8 @@ import ( "io" "os" + "github.com/filecoin-project/go-state-types/dline" + datatransfer "github.com/filecoin-project/go-data-transfer" "github.com/filecoin-project/go-state-types/big" "golang.org/x/xerrors" @@ -80,7 +82,7 @@ type API struct { Host host.Host } -func calcDealExpiration(minDuration uint64, md *miner.DeadlineInfo, startEpoch abi.ChainEpoch) abi.ChainEpoch { +func calcDealExpiration(minDuration uint64, md *dline.Info, startEpoch abi.ChainEpoch) abi.ChainEpoch { // Make sure we give some time for the miner to seal minExp := startEpoch + abi.ChainEpoch(minDuration) 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/impl/full/state.go b/node/impl/full/state.go index 1cef5eaee..e183fafa4 100644 --- a/node/impl/full/state.go +++ b/node/impl/full/state.go @@ -7,6 +7,8 @@ import ( "fmt" "strconv" + "github.com/filecoin-project/go-state-types/dline" + cid "github.com/ipfs/go-cid" cbor "github.com/ipfs/go-ipld-cbor" cbg "github.com/whyrusleeping/cbor-gen" @@ -53,7 +55,7 @@ type StateAPI struct { ProofVerifier ffiwrapper.Verifier StateManager *stmgr.StateManager Chain *store.ChainStore - Beacon beacon.RandomBeacon + Beacon beacon.Schedule } func (a *StateAPI) StateNetworkName(ctx context.Context) (dtypes.NetworkName, error) { @@ -145,7 +147,7 @@ func (a *StateAPI) StateMinerPartitions(ctx context.Context, m address.Address, })))))) } -func (a *StateAPI) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*miner.DeadlineInfo, error) { +func (a *StateAPI) StateMinerProvingDeadline(ctx context.Context, addr address.Address, tsk types.TipSetKey) (*dline.Info, error) { ts, err := a.Chain.GetTipSetFromKey(tsk) if err != nil { return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) diff --git a/node/modules/chain.go b/node/modules/chain.go index cc86156b6..7b7e03e44 100644 --- a/node/modules/chain.go +++ b/node/modules/chain.go @@ -163,7 +163,7 @@ func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore, return netName, err } -func NewSyncer(lc fx.Lifecycle, ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.Client, h host.Host, beacon beacon.RandomBeacon, verifier ffiwrapper.Verifier) (*chain.Syncer, error) { +func NewSyncer(lc fx.Lifecycle, ds dtypes.MetadataDS, sm *stmgr.StateManager, exchange exchange.Client, h host.Host, beacon beacon.Schedule, verifier ffiwrapper.Verifier) (*chain.Syncer, error) { syncer, err := chain.NewSyncer(ds, sm, exchange, h.ConnManager(), h.ID(), beacon, verifier) if err != nil { return nil, err diff --git a/node/modules/core.go b/node/modules/core.go index d73e4e25d..65b5eecb2 100644 --- a/node/modules/core.go +++ b/node/modules/core.go @@ -10,6 +10,7 @@ import ( "github.com/gbrlsnchs/jwt/v3" logging "github.com/ipfs/go-log/v2" + "github.com/libp2p/go-libp2p-core/peer" "github.com/libp2p/go-libp2p-core/peerstore" record "github.com/libp2p/go-libp2p-record" "golang.org/x/xerrors" @@ -93,14 +94,18 @@ func BuiltinBootstrap() (dtypes.BootstrapPeers, error) { return build.BuiltinBootstrap() } -func DrandBootstrap(d dtypes.DrandConfig) (dtypes.DrandBootstrap, error) { +func DrandBootstrap(ds 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) - if err != nil { - log.Errorf("reoslving drand relays addresses: %+v", err) - return nil, nil + res := []peer.AddrInfo{} + for _, d := range ds { + addrs, err := addrutil.ParseAddresses(context.TODO(), d.Config.Relays) + if err != nil { + log.Errorf("reoslving drand relays addresses: %+v", err) + return res, nil + } + res = append(res, addrs...) } - return addrs, nil + return res, nil } func SetupJournal(lr repo.LockedRepo) error { 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..aefb06d89 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,9 +74,126 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { } isBootstrapNode := in.Cfg.Bootstrapper - drandTopic, err := getDrandTopic(in.Dr.ChainInfoJSON) - if err != nil { - return nil, err + + drandTopicParams := &pubsub.TopicScoreParams{ + // expected 2 beaconsn/min + TopicWeight: 0.5, // 5x block topic; max cap is 62.5 + + // 1 tick per second, maxes at 1 after 1 hour + TimeInMeshWeight: 0.00027, // ~1/3600 + TimeInMeshQuantum: time.Second, + TimeInMeshCap: 1, + + // deliveries decay after 1 hour, cap at 25 beacons + FirstMessageDeliveriesWeight: 5, // max value is 125 + FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), + FirstMessageDeliveriesCap: 25, // the maximum expected in an hour is ~26, including the decay + + // Mesh Delivery Failure is currently turned off for beacons + // This is on purpose as + // - the traffic is very low for meaningful distribution of incoming edges. + // - the reaction time needs to be very slow -- in the order of 10 min at least + // so we might as well let opportunistic grafting repair the mesh on its own + // pace. + // - the network is too small, so large asymmetries can be expected between mesh + // edges. + // We should revisit this once the network grows. + + // invalid messages decay after 1 hour + InvalidMessageDeliveriesWeight: -1000, + InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), + } + + topicParams := map[string]*pubsub.TopicScoreParams{ + build.BlocksTopic(in.Nn): { + // expected 10 blocks/min + TopicWeight: 0.1, // max cap is 50, max mesh penalty is -10, single invalid message is -100 + + // 1 tick per second, maxes at 1 after 1 hour + TimeInMeshWeight: 0.00027, // ~1/3600 + TimeInMeshQuantum: time.Second, + TimeInMeshCap: 1, + + // deliveries decay after 1 hour, cap at 100 blocks + FirstMessageDeliveriesWeight: 5, // max value is 500 + FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), + FirstMessageDeliveriesCap: 100, // 100 blocks in an hour + + // Mesh Delivery Failure is currently turned off for blocks + // This is on purpose as + // - the traffic is very low for meaningful distribution of incoming edges. + // - the reaction time needs to be very slow -- in the order of 10 min at least + // so we might as well let opportunistic grafting repair the mesh on its own + // pace. + // - the network is too small, so large asymmetries can be expected between mesh + // edges. + // We should revisit this once the network grows. + // + // // tracks deliveries in the last minute + // // penalty activates at 1 minute and expects ~0.4 blocks + // MeshMessageDeliveriesWeight: -576, // max penalty is -100 + // MeshMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Minute), + // MeshMessageDeliveriesCap: 10, // 10 blocks in a minute + // MeshMessageDeliveriesThreshold: 0.41666, // 10/12/2 blocks/min + // MeshMessageDeliveriesWindow: 10 * time.Millisecond, + // MeshMessageDeliveriesActivation: time.Minute, + // + // // decays after 15 min + // MeshFailurePenaltyWeight: -576, + // MeshFailurePenaltyDecay: pubsub.ScoreParameterDecay(15 * time.Minute), + + // invalid messages decay after 1 hour + InvalidMessageDeliveriesWeight: -1000, + InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), + }, + build.MessagesTopic(in.Nn): { + // expected > 1 tx/second + TopicWeight: 0.1, // max cap is 5, single invalid message is -100 + + // 1 tick per second, maxes at 1 hour + TimeInMeshWeight: 0.0002778, // ~1/3600 + TimeInMeshQuantum: time.Second, + TimeInMeshCap: 1, + + // deliveries decay after 10min, cap at 100 tx + FirstMessageDeliveriesWeight: 0.5, // max value is 50 + FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(10 * time.Minute), + FirstMessageDeliveriesCap: 100, // 100 messages in 10 minutes + + // Mesh Delivery Failure is currently turned off for messages + // This is on purpose as the network is still too small, which results in + // asymmetries and potential unmeshing from negative scores. + // // tracks deliveries in the last minute + // // penalty activates at 1 min and expects 2.5 txs + // MeshMessageDeliveriesWeight: -16, // max penalty is -100 + // MeshMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Minute), + // MeshMessageDeliveriesCap: 100, // 100 txs in a minute + // MeshMessageDeliveriesThreshold: 2.5, // 60/12/2 txs/minute + // MeshMessageDeliveriesWindow: 10 * time.Millisecond, + // MeshMessageDeliveriesActivation: time.Minute, + + // // decays after 5min + // MeshFailurePenaltyWeight: -16, + // MeshFailurePenaltyDecay: pubsub.ScoreParameterDecay(5 * time.Minute), + + // invalid messages decay after 1 hour + InvalidMessageDeliveriesWeight: -1000, + InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), + }, + } + + pgTopicWeights := map[string]float64{ + build.BlocksTopic(in.Nn): 10, + build.MessagesTopic(in.Nn): 1, + } + + for _, d := range in.Dr { + topic, err := getDrandTopic(d.Config.ChainInfoJSON) + if err != nil { + return nil, err + } + topicParams[topic] = drandTopicParams + pgTopicWeights[topic] = 5 } options := []pubsub.Option{ @@ -124,111 +241,7 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { RetainScore: 6 * time.Hour, // topic parameters - Topics: map[string]*pubsub.TopicScoreParams{ - drandTopic: { - // expected 2 beaconsn/min - TopicWeight: 0.5, // 5x block topic; max cap is 62.5 - - // 1 tick per second, maxes at 1 after 1 hour - TimeInMeshWeight: 0.00027, // ~1/3600 - TimeInMeshQuantum: time.Second, - TimeInMeshCap: 1, - - // deliveries decay after 1 hour, cap at 25 beacons - FirstMessageDeliveriesWeight: 5, // max value is 125 - FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), - FirstMessageDeliveriesCap: 25, // the maximum expected in an hour is ~26, including the decay - - // Mesh Delivery Failure is currently turned off for beacons - // This is on purpose as - // - the traffic is very low for meaningful distribution of incoming edges. - // - the reaction time needs to be very slow -- in the order of 10 min at least - // so we might as well let opportunistic grafting repair the mesh on its own - // pace. - // - the network is too small, so large asymmetries can be expected between mesh - // edges. - // We should revisit this once the network grows. - - // invalid messages decay after 1 hour - InvalidMessageDeliveriesWeight: -1000, - InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), - }, - build.BlocksTopic(in.Nn): { - // expected 10 blocks/min - TopicWeight: 0.1, // max cap is 50, max mesh penalty is -10, single invalid message is -100 - - // 1 tick per second, maxes at 1 after 1 hour - TimeInMeshWeight: 0.00027, // ~1/3600 - TimeInMeshQuantum: time.Second, - TimeInMeshCap: 1, - - // deliveries decay after 1 hour, cap at 100 blocks - FirstMessageDeliveriesWeight: 5, // max value is 500 - FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), - FirstMessageDeliveriesCap: 100, // 100 blocks in an hour - - // Mesh Delivery Failure is currently turned off for blocks - // This is on purpose as - // - the traffic is very low for meaningful distribution of incoming edges. - // - the reaction time needs to be very slow -- in the order of 10 min at least - // so we might as well let opportunistic grafting repair the mesh on its own - // pace. - // - the network is too small, so large asymmetries can be expected between mesh - // edges. - // We should revisit this once the network grows. - // - // // tracks deliveries in the last minute - // // penalty activates at 1 minute and expects ~0.4 blocks - // MeshMessageDeliveriesWeight: -576, // max penalty is -100 - // MeshMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Minute), - // MeshMessageDeliveriesCap: 10, // 10 blocks in a minute - // MeshMessageDeliveriesThreshold: 0.41666, // 10/12/2 blocks/min - // MeshMessageDeliveriesWindow: 10 * time.Millisecond, - // MeshMessageDeliveriesActivation: time.Minute, - // - // // decays after 15 min - // MeshFailurePenaltyWeight: -576, - // MeshFailurePenaltyDecay: pubsub.ScoreParameterDecay(15 * time.Minute), - - // invalid messages decay after 1 hour - InvalidMessageDeliveriesWeight: -1000, - InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), - }, - build.MessagesTopic(in.Nn): { - // expected > 1 tx/second - TopicWeight: 0.1, // max cap is 5, single invalid message is -100 - - // 1 tick per second, maxes at 1 hour - TimeInMeshWeight: 0.0002778, // ~1/3600 - TimeInMeshQuantum: time.Second, - TimeInMeshCap: 1, - - // deliveries decay after 10min, cap at 100 tx - FirstMessageDeliveriesWeight: 0.5, // max value is 50 - FirstMessageDeliveriesDecay: pubsub.ScoreParameterDecay(10 * time.Minute), - FirstMessageDeliveriesCap: 100, // 100 messages in 10 minutes - - // Mesh Delivery Failure is currently turned off for messages - // This is on purpose as the network is still too small, which results in - // asymmetries and potential unmeshing from negative scores. - // // tracks deliveries in the last minute - // // penalty activates at 1 min and expects 2.5 txs - // MeshMessageDeliveriesWeight: -16, // max penalty is -100 - // MeshMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Minute), - // MeshMessageDeliveriesCap: 100, // 100 txs in a minute - // MeshMessageDeliveriesThreshold: 2.5, // 60/12/2 txs/minute - // MeshMessageDeliveriesWindow: 10 * time.Millisecond, - // MeshMessageDeliveriesActivation: time.Minute, - - // // decays after 5min - // MeshFailurePenaltyWeight: -16, - // MeshFailurePenaltyDecay: pubsub.ScoreParameterDecay(5 * time.Minute), - - // invalid messages decay after 1 hour - InvalidMessageDeliveriesWeight: -1000, - InvalidMessageDeliveriesDecay: pubsub.ScoreParameterDecay(time.Hour), - }, - }, + Topics: topicParams, }, &pubsub.PeerScoreThresholds{ GossipThreshold: -500, @@ -278,11 +291,6 @@ func GossipSub(in GossipIn) (service *pubsub.PubSub, err error) { } // validation queue RED - pgTopicWeights := map[string]float64{ - drandTopic: 5, - build.BlocksTopic(in.Nn): 10, - build.MessagesTopic(in.Nn): 1, - } var pgParams *pubsub.PeerGaterParams if isBootstrapNode { 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 diff --git a/storage/miner.go b/storage/miner.go index a9728433b..572a0d811 100644 --- a/storage/miner.go +++ b/storage/miner.go @@ -5,6 +5,8 @@ import ( "errors" "time" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/go-bitfield" "github.com/filecoin-project/specs-actors/actors/runtime/proof" @@ -60,7 +62,7 @@ type storageMinerApi interface { StateSectorGetInfo(context.Context, address.Address, abi.SectorNumber, types.TipSetKey) (*miner.SectorOnChainInfo, error) StateSectorPartition(ctx context.Context, maddr address.Address, sectorNumber abi.SectorNumber, tok types.TipSetKey) (*api.SectorLocation, error) StateMinerInfo(context.Context, address.Address, types.TipSetKey) (api.MinerInfo, error) - StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*miner.DeadlineInfo, error) + StateMinerProvingDeadline(context.Context, address.Address, types.TipSetKey) (*dline.Info, error) StateMinerPreCommitDepositForPower(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) StateMinerInitialPledgeCollateral(context.Context, address.Address, miner.SectorPreCommitInfo, types.TipSetKey) (types.BigInt, error) StateSearchMsg(context.Context, cid.Cid) (*api.MsgLookup, error) diff --git a/storage/wdpost_run.go b/storage/wdpost_run.go index 4fd4d51e6..cff110d18 100644 --- a/storage/wdpost_run.go +++ b/storage/wdpost_run.go @@ -6,6 +6,8 @@ import ( "errors" "time" + "github.com/filecoin-project/go-state-types/dline" + "github.com/filecoin-project/specs-actors/actors/runtime/proof" "github.com/filecoin-project/go-bitfield" @@ -27,7 +29,7 @@ import ( var errNoPartitions = errors.New("no partitions") -func (s *WindowPoStScheduler) failPost(deadline *miner.DeadlineInfo) { +func (s *WindowPoStScheduler) failPost(deadline *dline.Info) { log.Errorf("TODO") /*s.failLk.Lock() if eps > s.failed { @@ -36,7 +38,7 @@ func (s *WindowPoStScheduler) failPost(deadline *miner.DeadlineInfo) { s.failLk.Unlock()*/ } -func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *miner.DeadlineInfo, ts *types.TipSet) { +func (s *WindowPoStScheduler) doPost(ctx context.Context, deadline *dline.Info, ts *types.TipSet) { ctx, abort := context.WithCancel(ctx) s.abort = abort @@ -286,7 +288,7 @@ func (s *WindowPoStScheduler) checkNextFaults(ctx context.Context, dlIdx uint64, return nil } -func (s *WindowPoStScheduler) runPost(ctx context.Context, di miner.DeadlineInfo, ts *types.TipSet) (*miner.SubmitWindowedPoStParams, error) { +func (s *WindowPoStScheduler) runPost(ctx context.Context, di dline.Info, ts *types.TipSet) (*miner.SubmitWindowedPoStParams, error) { ctx, span := trace.StartSpan(ctx, "storage.runPost") defer span.End() diff --git a/storage/wdpost_sched.go b/storage/wdpost_sched.go index b238a490d..905a2409c 100644 --- a/storage/wdpost_sched.go +++ b/storage/wdpost_sched.go @@ -4,11 +4,12 @@ import ( "context" "time" + "github.com/filecoin-project/go-state-types/dline" + "golang.org/x/xerrors" "github.com/filecoin-project/go-address" "github.com/filecoin-project/go-state-types/abi" - "github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-storage/storage" "github.com/filecoin-project/lotus/api" @@ -37,7 +38,7 @@ type WindowPoStScheduler struct { cur *types.TipSet // if a post is in progress, this indicates for which ElectionPeriodStart - activeDeadline *miner.DeadlineInfo + activeDeadline *dline.Info abort context.CancelFunc //failed abi.ChainEpoch // eps @@ -68,7 +69,7 @@ func NewWindowedPoStScheduler(api storageMinerApi, fc config.MinerFeeConfig, sb }, nil } -func deadlineEquals(a, b *miner.DeadlineInfo) bool { +func deadlineEquals(a, b *dline.Info) bool { if a == nil || b == nil { return b == a } diff --git a/tools/stats/metrics.go b/tools/stats/metrics.go index 39fecf47b..ae79d9273 100644 --- a/tools/stats/metrics.go +++ b/tools/stats/metrics.go @@ -5,6 +5,7 @@ import ( "context" "encoding/json" "fmt" + "math" "math/big" "strings" "time" @@ -12,6 +13,7 @@ import ( "github.com/filecoin-project/go-address" "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin/power" @@ -131,12 +133,6 @@ func RecordTipsetPoints(ctx context.Context, api api.FullNode, pl *PointList, ti p = NewPoint("chain.blocktime", tsTime.Unix()) pl.AddPoint(p) - baseFeeBig := tipset.Blocks()[0].ParentBaseFee.Copy() - baseFeeRat := new(big.Rat).SetFrac(baseFeeBig.Int, new(big.Int).SetUint64(build.FilecoinPrecision)) - baseFeeFloat, _ := baseFeeRat.Float64() - p = NewPoint("chain.basefee", baseFeeFloat) - pl.AddPoint(p) - totalGasLimit := int64(0) totalUniqGasLimit := int64(0) seen := make(map[cid.Cid]struct{}) @@ -178,6 +174,30 @@ func RecordTipsetPoints(ctx context.Context, api api.FullNode, pl *PointList, ti p = NewPoint("chain.gas_limit_uniq_total", totalUniqGasLimit) pl.AddPoint(p) + { + baseFeeIn := tipset.Blocks()[0].ParentBaseFee + newBaseFee := store.ComputeNextBaseFee(baseFeeIn, totalUniqGasLimit, len(tipset.Blocks()), tipset.Height()) + + baseFeeRat := new(big.Rat).SetFrac(newBaseFee.Int, new(big.Int).SetUint64(build.FilecoinPrecision)) + baseFeeFloat, _ := baseFeeRat.Float64() + p = NewPoint("chain.basefee", baseFeeFloat) + pl.AddPoint(p) + + baseFeeChange := new(big.Rat).SetFrac(newBaseFee.Int, baseFeeIn.Int) + baseFeeChangeF, _ := baseFeeChange.Float64() + p = NewPoint("chain.basefee_change_log", math.Log(baseFeeChangeF)/math.Log(1.125)) + pl.AddPoint(p) + } + { + blks := len(cids) + p = NewPoint("chain.gas_fill_ratio", float64(totalGasLimit)/float64(blks*build.BlockGasTarget)) + pl.AddPoint(p) + p = NewPoint("chain.gas_capacity_ratio", float64(totalUniqGasLimit)/float64(blks*build.BlockGasTarget)) + pl.AddPoint(p) + p = NewPoint("chain.gas_waste_ratio", float64(totalGasLimit-totalUniqGasLimit)/float64(blks*build.BlockGasTarget)) + pl.AddPoint(p) + } + return nil }