make system constants configurable as vars.

This configurability is unlocked through the `testground`
build tag, which Project Oni will uses.

Changes in the usage places of these relaxed constants
were required due to the fact that Golang constants are
untyped, but vars aren't.

Read https://blog.golang.org/constants for more info.
This commit is contained in:
Raúl Kripalani 2020-06-30 14:18:01 +01:00
parent c3898e4abf
commit 0fddf3e114
20 changed files with 144 additions and 57 deletions

View File

@ -0,0 +1,38 @@
package build
import (
"sort"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/node/modules/dtypes"
)
func DefaultSectorSize() abi.SectorSize {
szs := make([]abi.SectorSize, 0, len(miner.SupportedProofTypes))
for spt := range miner.SupportedProofTypes {
ss, err := spt.SectorSize()
if err != nil {
panic(err)
}
szs = append(szs, ss)
}
sort.Slice(szs, func(i, j int) bool {
return szs[i] < szs[j]
})
return szs[0]
}
// Core network constants
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) }
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
return protocol.ID("/fil/kad/" + string(netName))
}

View File

@ -1,44 +1,16 @@
// +build !testground
package build package build
import ( import (
"math/big" "math/big"
"sort"
"github.com/libp2p/go-libp2p-core/protocol"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin" "github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner" "github.com/filecoin-project/specs-actors/actors/builtin/miner"
"github.com/filecoin-project/lotus/node/modules/dtypes" "github.com/filecoin-project/lotus/node/modules/dtypes"
) )
func DefaultSectorSize() abi.SectorSize {
szs := make([]abi.SectorSize, 0, len(miner.SupportedProofTypes))
for spt := range miner.SupportedProofTypes {
ss, err := spt.SectorSize()
if err != nil {
panic(err)
}
szs = append(szs, ss)
}
sort.Slice(szs, func(i, j int) bool {
return szs[i] < szs[j]
})
return szs[0]
}
// Core network constants
func BlocksTopic(netName dtypes.NetworkName) string { return "/fil/blocks/" + string(netName) }
func MessagesTopic(netName dtypes.NetworkName) string { return "/fil/msgs/" + string(netName) }
func DhtProtocolName(netName dtypes.NetworkName) protocol.ID {
return protocol.ID("/fil/kad/" + string(netName))
}
// ///// // /////
// Storage // Storage

View File

@ -0,0 +1,70 @@
// +build testground
// This file makes hardcoded parameters (const) configurable as vars.
//
// Its purpose is to unlock various degrees of flexibility and parametrization
// when writing Testground plans for Lotus.
//
package build
import (
"math/big"
"github.com/filecoin-project/lotus/node/modules/dtypes"
"github.com/filecoin-project/specs-actors/actors/abi"
"github.com/filecoin-project/specs-actors/actors/builtin"
"github.com/filecoin-project/specs-actors/actors/builtin/miner"
)
var (
UnixfsChunkSize = uint64(1 << 20)
UnixfsLinksPerLevel = 1024
BlocksPerEpoch = uint64(builtin.ExpectedLeadersPerEpoch)
BlockMessageLimit = 512
BlockGasLimit = int64(100_000_000_000)
BlockDelay = uint64(builtin.EpochDurationSeconds)
PropagationDelay = uint64(6)
AllowableClockDrift = uint64(1)
Finality = miner.ChainFinalityish
ForkLengthThreshold = Finality
MessageConfidence uint64 = 5
WRatioNum = int64(1)
WRatioDen = uint64(2)
BadBlockCacheSize = 1 << 15
BlsSignatureCacheSize = 40000
VerifSigCacheSize = 32000
SealRandomnessLookback = Finality
SealRandomnessLookbackLimit = SealRandomnessLookback + 2000
MaxSealLookback = SealRandomnessLookbackLimit + 2000
TicketRandomnessLookback = abi.ChainEpoch(1)
WinningPoStSectorSetLookback = abi.ChainEpoch(10)
TotalFilecoin uint64 = 2_000_000_000
MiningRewardTotal uint64 = 1_400_000_000
FilecoinPrecision uint64 = 1_000_000_000_000_000_000
InitialRewardBalance = func() *big.Int {
v := big.NewInt(int64(MiningRewardTotal))
v = v.Mul(v, big.NewInt(int64(FilecoinPrecision)))
return v
}()
DrandConfig = dtypes.DrandConfig{
Servers: []string{
"https://pl-eu.testnet.drand.sh",
"https://pl-us.testnet.drand.sh",
"https://pl-sin.testnet.drand.sh",
},
ChainInfoJSON: `{"public_key":"922a2e93828ff83345bae533f5172669a26c02dc76d6bf59c80892e12ab1455c229211886f35bb56af6d5bea981024df","period":25,"genesis_time":1590445175,"hash":"138a324aa6540f93d0dad002aa89454b1bec2b6e948682cde6bd4db40f4b7c9b"}`,
}
)

View File

@ -1,5 +1,6 @@
// +build !debug // +build !debug
// +build !2k // +build !2k
// +build !testground
package build package build

View File

@ -196,7 +196,7 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
*genm2, *genm2,
}, },
NetworkName: "", NetworkName: "",
Timestamp: uint64(time.Now().Add(-500 * build.BlockDelay * time.Second).Unix()), Timestamp: uint64(time.Now().Add(-500 * time.Duration(build.BlockDelay) * time.Second).Unix()),
} }
genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl) genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl)
@ -414,7 +414,7 @@ func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, vrfticke
if cg.Timestamper != nil { if cg.Timestamper != nil {
ts = cg.Timestamper(parents, height-parents.Height()) ts = cg.Timestamper(parents, height-parents.Height())
} else { } else {
ts = parents.MinTimestamp() + uint64((height-parents.Height())*build.BlockDelay) ts = parents.MinTimestamp() + uint64(height-parents.Height())*uint64(build.BlockDelay)
} }
fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, &api.BlockTemplate{ fblk, err := MinerCreateBlock(context.TODO(), cg.sm, cg.w, &api.BlockTemplate{

View File

@ -187,7 +187,7 @@ func New(api Provider, ds dtypes.MetadataDS, netName dtypes.NetworkName) (*Messa
mp := &MessagePool{ mp := &MessagePool{
closer: make(chan struct{}), closer: make(chan struct{}),
repubTk: time.NewTicker(build.BlockDelay * 10 * time.Second), repubTk: time.NewTicker(time.Duration(build.BlockDelay) * 10 * time.Second),
localAddrs: make(map[address.Address]struct{}), localAddrs: make(map[address.Address]struct{}),
pending: make(map[address.Address]*msgSet), pending: make(map[address.Address]*msgSet),
minGasPrice: types.NewInt(0), minGasPrice: types.NewInt(0),

View File

@ -11,7 +11,7 @@ import (
type FIL BigInt type FIL BigInt
func (f FIL) String() string { func (f FIL) String() string {
r := new(big.Rat).SetFrac(f.Int, big.NewInt(build.FilecoinPrecision)) r := new(big.Rat).SetFrac(f.Int, big.NewInt(int64(build.FilecoinPrecision)))
if r.Sign() == 0 { if r.Sign() == 0 {
return "0" return "0"
} }
@ -33,7 +33,7 @@ func ParseFIL(s string) (FIL, error) {
return FIL{}, fmt.Errorf("failed to parse %q as a decimal number", s) return FIL{}, fmt.Errorf("failed to parse %q as a decimal number", s)
} }
r = r.Mul(r, big.NewRat(build.FilecoinPrecision, 1)) r = r.Mul(r, big.NewRat(int64(build.FilecoinPrecision), 1))
if !r.IsInt() { if !r.IsInt() {
return FIL{}, fmt.Errorf("invalid FIL value: %q", s) return FIL{}, fmt.Errorf("invalid FIL value: %q", s)
} }

View File

@ -186,7 +186,7 @@ func SyncWait(ctx context.Context, napi api.FullNode) error {
fmt.Printf("\r\x1b[2KWorker %d: Target: %s\tState: %s\tHeight: %d", working, target, chain.SyncStageString(ss.Stage), ss.Height) fmt.Printf("\r\x1b[2KWorker %d: Target: %s\tState: %s\tHeight: %d", working, target, chain.SyncStageString(ss.Stage), ss.Height)
if time.Now().Unix()-int64(head.MinTimestamp()) < build.BlockDelay { if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelay) {
fmt.Println("\nDone!") fmt.Println("\nDone!")
return nil return nil
} }

View File

@ -63,7 +63,7 @@ var watchHeadCmd = &cli.Command{
}, },
&cli.IntFlag{ &cli.IntFlag{
Name: "interval", Name: "interval",
Value: build.BlockDelay, Value: int(build.BlockDelay),
Usage: "interval in seconds between chain head checks", Usage: "interval in seconds between chain head checks",
}, },
&cli.StringFlag{ &cli.StringFlag{
@ -72,8 +72,9 @@ var watchHeadCmd = &cli.Command{
Usage: "systemd unit name to restart on health check failure", Usage: "systemd unit name to restart on health check failure",
}, },
&cli.IntFlag{ &cli.IntFlag{
Name: "api-timeout", Name: "api-timeout",
Value: build.BlockDelay, // TODO: this default value seems spurious.
Value: int(build.BlockDelay),
Usage: "timeout between API retries", Usage: "timeout between API retries",
}, },
&cli.IntFlag{ &cli.IntFlag{
@ -236,7 +237,7 @@ func waitForSyncComplete(ctx context.Context, a api.FullNode, r int, t time.Dura
return err return err
} }
if time.Now().Unix()-int64(head.MinTimestamp()) < build.BlockDelay { if time.Now().Unix()-int64(head.MinTimestamp()) < int64(build.BlockDelay) {
return nil return nil
} }
} }

View File

@ -124,7 +124,7 @@ var genesisAddMinerCmd = &cli.Command{
log.Infof("Giving %s some initial balance", miner.Owner) log.Infof("Giving %s some initial balance", miner.Owner)
template.Accounts = append(template.Accounts, genesis.Actor{ template.Accounts = append(template.Accounts, genesis.Actor{
Type: genesis.TAccount, Type: genesis.TAccount,
Balance: big.Mul(big.NewInt(50_000_000), big.NewInt(build.FilecoinPrecision)), Balance: big.Mul(big.NewInt(50_000_000), big.NewInt(int64(build.FilecoinPrecision))),
Meta: (&genesis.AccountMeta{Owner: miner.Owner}).ActorMeta(), Meta: (&genesis.AccountMeta{Owner: miner.Owner}).ActorMeta(),
}) })
} }

View File

@ -128,7 +128,7 @@ var infoCmd = &cli.Command{
if expWinChance > 1 { if expWinChance > 1 {
expWinChance = 1 expWinChance = 1
} }
winRate := time.Duration(float64(time.Second*build.BlockDelay) / expWinChance) winRate := time.Duration(float64(time.Second*time.Duration(build.BlockDelay)) / expWinChance)
winPerDay := float64(time.Hour*24) / float64(winRate) winPerDay := float64(time.Hour*24) / float64(winRate)
fmt.Print("Expected block win rate: ") fmt.Print("Expected block win rate: ")

View File

@ -123,7 +123,7 @@ var setAskCmd = &cli.Command{
return xerrors.Errorf("cannot parse duration: %w", err) return xerrors.Errorf("cannot parse duration: %w", err)
} }
qty := dur.Seconds() / build.BlockDelay qty := dur.Seconds() / float64(build.BlockDelay)
min, err := units.RAMInBytes(cctx.String("min-piece-size")) min, err := units.RAMInBytes(cctx.String("min-piece-size"))
if err != nil { if err != nil {
@ -208,7 +208,7 @@ var getAskCmd = &cli.Command{
dlt := ask.Expiry - head.Height() dlt := ask.Expiry - head.Height()
rem := "<expired>" rem := "<expired>"
if dlt > 0 { if dlt > 0 {
rem = (time.Second * time.Duration(dlt*build.BlockDelay)).String() rem = (time.Second * time.Duration(int64(dlt)*int64(build.BlockDelay))).String()
} }
fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, rem, ask.SeqNo) fmt.Fprintf(w, "%s\t%s\t%s\t%d\t%s\t%d\n", ask.Price, types.SizeStr(types.NewInt(uint64(ask.MinPieceSize))), types.SizeStr(types.NewInt(uint64(ask.MaxPieceSize))), ask.Expiry, rem, ask.SeqNo)

View File

@ -211,11 +211,11 @@ var provingInfoCmd = &cli.Command{
func epochTime(curr, e abi.ChainEpoch) string { func epochTime(curr, e abi.ChainEpoch) string {
switch { switch {
case curr > e: case curr > e:
return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(build.BlockDelay*(curr-e))) return fmt.Sprintf("%d (%s ago)", e, time.Second*time.Duration(int64(build.BlockDelay)*int64(curr-e)))
case curr == e: case curr == e:
return fmt.Sprintf("%d (now)", e) return fmt.Sprintf("%d (now)", e)
case curr < e: case curr < e:
return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(build.BlockDelay*(e-curr))) return fmt.Sprintf("%d (in %s)", e, time.Second*time.Duration(int64(build.BlockDelay)*int64(e-curr)))
} }
panic("math broke") panic("math broke")

1
go.sum
View File

@ -259,6 +259,7 @@ github.com/filecoin-project/sector-storage v0.0.0-20200625154333-98ef8e4ef246/go
github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA= github.com/filecoin-project/specs-actors v0.0.0-20200210130641-2d1fbd8672cf/go.mod h1:xtDZUB6pe4Pksa/bAJbJ693OilaC5Wbot9jMhLm3cZA=
github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y= github.com/filecoin-project/specs-actors v0.3.0/go.mod h1:nQYnFbQ7Y0bHZyq6HDEuVlCPR+U3z5Q3wMOQ+2aiV+Y=
github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.0/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
github.com/filecoin-project/specs-actors v0.6.1/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121 h1:oRA+b4iN4H86xXDXbU3TOyvmBZp7//c5VqTc0oJ6nLg=
github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY= github.com/filecoin-project/specs-actors v0.6.2-0.20200617175406-de392ca14121/go.mod h1:dRdy3cURykh2R8O/DKqy8olScl70rmIS7GrB4hB1IDY=
github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94= github.com/filecoin-project/specs-storage v0.1.0 h1:PkDgTOT5W5Ao7752onjDl4QSv+sgOVdJbvFjOnD5w94=

View File

@ -330,7 +330,7 @@ func (c *ClientNodeAdapter) OnDealSectorCommitted(ctx context.Context, provider
} }
} }
if err := c.ev.Called(checkFunc, called, revert, build.MessageConfidence+1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { if err := c.ev.Called(checkFunc, called, revert, int(build.MessageConfidence+1), build.SealRandomnessLookbackLimit, matchEvent); err != nil {
return xerrors.Errorf("failed to set up called handler: %w", err) return xerrors.Errorf("failed to set up called handler: %w", err)
} }

View File

@ -321,7 +321,7 @@ func (n *ProviderNodeAdapter) OnDealSectorCommitted(ctx context.Context, provide
} }
if err := n.ev.Called(checkFunc, called, revert, build.MessageConfidence+1, build.SealRandomnessLookbackLimit, matchEvent); err != nil { if err := n.ev.Called(checkFunc, called, revert, int(build.MessageConfidence+1), build.SealRandomnessLookbackLimit, matchEvent); err != nil {
return xerrors.Errorf("failed to set up called handler: %w", err) return xerrors.Errorf("failed to set up called handler: %w", err)
} }

View File

@ -150,7 +150,7 @@ func (m *Miner) mine(ctx context.Context) {
} }
if base.TipSet.Equals(lastBase.TipSet) && lastBase.NullRounds == base.NullRounds { if base.TipSet.Equals(lastBase.TipSet) && lastBase.NullRounds == base.NullRounds {
log.Warnf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.TipSet.Cids(), lastBase.NullRounds) log.Warnf("BestMiningCandidate from the previous round: %s (nulls:%d)", lastBase.TipSet.Cids(), lastBase.NullRounds)
m.niceSleep(build.BlockDelay * time.Second) m.niceSleep(time.Duration(build.BlockDelay) * time.Second)
continue continue
} }
@ -194,7 +194,7 @@ func (m *Miner) mine(ctx context.Context) {
// has enough time to form. // has enough time to form.
// //
// See: https://github.com/filecoin-project/lotus/issues/1845 // See: https://github.com/filecoin-project/lotus/issues/1845
nextRound := time.Unix(int64(base.TipSet.MinTimestamp()+uint64(build.BlockDelay*base.NullRounds))+int64(build.PropagationDelay), 0) nextRound := time.Unix(int64(base.TipSet.MinTimestamp()+build.BlockDelay*uint64(base.NullRounds))+int64(build.PropagationDelay), 0)
select { select {
case <-time.After(time.Until(nextRound)): case <-time.After(time.Until(nextRound)):
@ -255,12 +255,16 @@ func (m *Miner) hasPower(ctx context.Context, addr address.Address, ts *types.Ti
return mpower.MinerPower.QualityAdjPower.GreaterThanEqual(power.ConsensusMinerMinPower), nil return mpower.MinerPower.QualityAdjPower.GreaterThanEqual(power.ConsensusMinerMinPower), nil
} }
// mineOne mines a single block, and does so synchronously, if and only if we // mineOne attempts to mine a single block, and does so synchronously, if and
// have won the current round. // only if we are eligible to mine.
// //
// {hint/landmark}: This method coordinates all the steps involved in mining a // {hint/landmark}: This method coordinates all the steps involved in mining a
// block, including the condition of whether mine or not at all depending on // block, including the condition of whether mine or not at all depending on
// whether we win the round or not. // whether we win the round or not.
//
// This method does the following:
//
// 1.
func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, error) { func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg, error) {
log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.TipSet.Cids())) log.Debugw("attempting to mine a block", "tipset", types.LogCids(base.TipSet.Cids()))
start := time.Now() start := time.Now()
@ -352,7 +356,7 @@ func (m *Miner) mineOne(ctx context.Context, base *MiningBase) (*types.BlockMsg,
tCreateBlock := time.Now() tCreateBlock := time.Now()
dur := tCreateBlock.Sub(start) dur := tCreateBlock.Sub(start)
log.Infow("mined new block", "cid", b.Cid(), "height", b.Header.Height, "took", dur) log.Infow("mined new block", "cid", b.Cid(), "height", b.Header.Height, "took", dur)
if dur > time.Second*build.BlockDelay { if dur > time.Second*time.Duration(build.BlockDelay) {
log.Warn("CAUTION: block production took longer than the block delay. Your computer may not be fast enough to keep up") log.Warn("CAUTION: block production took longer than the block delay. Your computer may not be fast enough to keep up")
log.Warnw("tMinerBaseInfo ", "duration", tMBI.Sub(start)) log.Warnw("tMinerBaseInfo ", "duration", tMBI.Sub(start))
@ -413,7 +417,7 @@ func (m *Miner) createBlock(base *MiningBase, addr address.Address, ticket *type
msgs = msgs[:build.BlockMessageLimit] msgs = msgs[:build.BlockMessageLimit]
} }
uts := base.TipSet.MinTimestamp() + uint64(build.BlockDelay*(base.NullRounds+1)) uts := base.TipSet.MinTimestamp() + build.BlockDelay*(uint64(base.NullRounds)+1)
nheight := base.TipSet.Height() + base.NullRounds + 1 nheight := base.TipSet.Height() + base.NullRounds + 1

View File

@ -122,7 +122,7 @@ func (a *CommonAPI) Version(context.Context) (api.Version, error) {
Version: build.UserVersion(), Version: build.UserVersion(),
APIVersion: build.APIVersion, APIVersion: build.APIVersion,
BlockDelay: build.BlockDelay, BlockDelay: uint64(build.BlockDelay),
}, nil }, nil
} }

View File

@ -8,5 +8,5 @@ import (
) )
func RandomBeacon() (beacon.RandomBeacon, error) { func RandomBeacon() (beacon.RandomBeacon, error) {
return beacon.NewMockBeacon(build.BlockDelay * time.Second), nil return beacon.NewMockBeacon(time.Duration(build.BlockDelay) * time.Second), nil
} }

View File

@ -114,7 +114,7 @@ sync_complete:
// If we get within 20 blocks of the current exected block height we // If we get within 20 blocks of the current exected block height we
// consider sync complete. Block propagation is not always great but we still // consider sync complete. Block propagation is not always great but we still
// want to be recording stats as soon as we can // want to be recording stats as soon as we can
if timestampDelta < build.BlockDelay*20 { if timestampDelta < int64(build.BlockDelay)*20 {
return nil return nil
} }
} }