Merge remote-tracking branch 'origin/feat/nv13' into feat/nv13-1.11

This commit is contained in:
Łukasz Magiera 2021-05-31 21:38:34 +02:00
commit ffa47659a1
29 changed files with 781 additions and 178 deletions

View File

@ -6,6 +6,8 @@ import (
"testing"
"time"
"github.com/filecoin-project/go-state-types/big"
"github.com/stretchr/testify/require"
"github.com/filecoin-project/go-address"
@ -846,3 +848,155 @@ waitForProof:
require.Contains(t, err.Error(), "failed to dispute valid post (RetCode=16)")
}
}
func TestWindowPostBaseFeeNoBurn(t *testing.T, b APIBuilder, blocktime time.Duration) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
och := build.UpgradeClausHeight
build.UpgradeClausHeight = 10
n, sn := b(t, DefaultFullOpts(1), OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
{
addrinfo, err := client.NetAddrsListen(ctx)
if err != nil {
t.Fatal(err)
}
if err := miner.NetConnect(ctx, addrinfo); err != nil {
t.Fatal(err)
}
}
maddr, err := miner.ActorAddress(ctx)
require.NoError(t, err)
mi, err := client.StateMinerInfo(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)
build.Clock.Sleep(time.Second)
done := make(chan struct{})
go func() {
defer close(done)
for ctx.Err() == nil {
build.Clock.Sleep(blocktime)
if err := miner.MineOne(ctx, MineNext); err != nil {
if ctx.Err() != nil {
// context was canceled, ignore the error.
return
}
t.Error(err)
}
}
}()
defer func() {
cancel()
<-done
}()
pledgeSectors(t, ctx, miner, 10, 0, nil)
wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK)
require.NoError(t, err)
en := wact.Nonce
// wait for a new message to be sent from worker address, it will be a PoSt
waitForProof:
for {
wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK)
require.NoError(t, err)
if wact.Nonce > en {
break waitForProof
}
build.Clock.Sleep(blocktime)
}
slm, err := client.StateListMessages(ctx, &api.MessageMatch{To: maddr}, types.EmptyTSK, 0)
require.NoError(t, err)
pmr, err := client.StateReplay(ctx, types.EmptyTSK, slm[0])
require.NoError(t, err)
require.Equal(t, pmr.GasCost.BaseFeeBurn, big.Zero())
build.UpgradeClausHeight = och
}
func TestWindowPostBaseFeeBurn(t *testing.T, b APIBuilder, blocktime time.Duration) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
n, sn := b(t, []FullNodeOpts{FullNodeWithLatestActorsAt(-1)}, OneMiner)
client := n[0].FullNode.(*impl.FullNodeAPI)
miner := sn[0]
{
addrinfo, err := client.NetAddrsListen(ctx)
if err != nil {
t.Fatal(err)
}
if err := miner.NetConnect(ctx, addrinfo); err != nil {
t.Fatal(err)
}
}
maddr, err := miner.ActorAddress(ctx)
require.NoError(t, err)
mi, err := client.StateMinerInfo(ctx, maddr, types.EmptyTSK)
require.NoError(t, err)
build.Clock.Sleep(time.Second)
done := make(chan struct{})
go func() {
defer close(done)
for ctx.Err() == nil {
build.Clock.Sleep(blocktime)
if err := miner.MineOne(ctx, MineNext); err != nil {
if ctx.Err() != nil {
// context was canceled, ignore the error.
return
}
t.Error(err)
}
}
}()
defer func() {
cancel()
<-done
}()
pledgeSectors(t, ctx, miner, 10, 0, nil)
wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK)
require.NoError(t, err)
en := wact.Nonce
// wait for a new message to be sent from worker address, it will be a PoSt
waitForProof:
for {
wact, err := client.StateGetActor(ctx, mi.Worker, types.EmptyTSK)
require.NoError(t, err)
if wact.Nonce > en {
break waitForProof
}
build.Clock.Sleep(blocktime)
}
slm, err := client.StateListMessages(ctx, &api.MessageMatch{To: maddr}, types.EmptyTSK, 0)
require.NoError(t, err)
pmr, err := client.StateReplay(ctx, types.EmptyTSK, slm[0])
require.NoError(t, err)
require.NotEqual(t, pmr.GasCost.BaseFeeBurn, big.Zero())
}

View File

@ -50,7 +50,7 @@ const UpgradePersianHeight = UpgradeCalicoHeight + (builtin2.EpochsInHour * 60)
const UpgradeOrangeHeight = 336458
// 2020-12-22T02:00:00Z
const UpgradeClausHeight = 343200
var UpgradeClausHeight = abi.ChainEpoch(343200)
// 2021-03-04T00:00:30Z
const UpgradeTrustHeight = 550321

View File

@ -0,0 +1,35 @@
package cron
import (
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/chain/actors/adt"
cron5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/cron"
)
var _ State = (*state5)(nil)
func load5(store adt.Store, root cid.Cid) (State, error) {
out := state5{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
func make5(store adt.Store) (State, error) {
out := state5{store: store}
out.State = *cron5.ConstructState(cron5.BuiltInEntries())
return &out, nil
}
type state5 struct {
cron5.State
store adt.Store
}
func (s *state5) GetState() interface{} {
return &s.State
}

View File

@ -0,0 +1,35 @@
package system
import (
"github.com/ipfs/go-cid"
"github.com/filecoin-project/lotus/chain/actors/adt"
system5 "github.com/filecoin-project/specs-actors/v5/actors/builtin/system"
)
var _ State = (*state5)(nil)
func load5(store adt.Store, root cid.Cid) (State, error) {
out := state5{store: store}
err := store.Get(store.Context(), root, &out)
if err != nil {
return nil, err
}
return &out, nil
}
func make5(store adt.Store) (State, error) {
out := state5{store: store}
out.State = system5.State{}
return &out, nil
}
type state5 struct {
system5.State
store adt.Store
}
func (s *state5) GetState() interface{} {
return &s.State
}

View File

@ -60,8 +60,6 @@ func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
miner4.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
miner4.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
miner5.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types))
miner5.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
miner5.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
AddSupportedProofTypes(types...)
@ -93,9 +91,6 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
miner4.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
miner4.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
miner5.PreCommitSealProofTypesV0[t] = struct{}{}
miner5.PreCommitSealProofTypesV7[t] = struct{}{}
miner5.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
miner5.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
}
@ -308,7 +303,7 @@ func GetDefaultAggregationProof() abi.RegisteredAggregationProof {
func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) abi.ChainEpoch {
if nwVer <= network.Version10 {
return builtin5.SealProofPoliciesV0[proof].SectorMaxLifetime
return builtin4.SealProofPoliciesV0[proof].SectorMaxLifetime
}
return builtin5.SealProofPoliciesV11[proof].SectorMaxLifetime

View File

@ -31,10 +31,12 @@ func SetSupportedProofTypes(types ...abi.RegisteredSealProof) {
{{range .versions}}
{{if (eq . 0)}}
miner{{.}}.SupportedProofTypes = make(map[abi.RegisteredSealProof]struct{}, len(types))
{{else}}
{{else if (le . 4)}}
miner{{.}}.PreCommitSealProofTypesV0 = make(map[abi.RegisteredSealProof]struct{}, len(types))
miner{{.}}.PreCommitSealProofTypesV7 = make(map[abi.RegisteredSealProof]struct{}, len(types)*2)
miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
{{else}}
miner{{.}}.PreCommitSealProofTypesV8 = make(map[abi.RegisteredSealProof]struct{}, len(types))
{{end}}
{{end}}
@ -53,11 +55,13 @@ func AddSupportedProofTypes(types ...abi.RegisteredSealProof) {
{{range .versions}}
{{if (eq . 0)}}
miner{{.}}.SupportedProofTypes[t] = struct{}{}
{{else}}
{{else if (le . 4)}}
miner{{.}}.PreCommitSealProofTypesV0[t] = struct{}{}
miner{{.}}.PreCommitSealProofTypesV7[t] = struct{}{}
miner{{.}}.PreCommitSealProofTypesV7[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
{{else}}
miner{{.}}.PreCommitSealProofTypesV8[t+abi.RegisteredSealProof_StackedDrg2KiBV1_1] = struct{}{}
{{end}}
{{end}}
}
@ -203,7 +207,7 @@ func GetDefaultAggregationProof() abi.RegisteredAggregationProof {
func GetSectorMaxLifetime(proof abi.RegisteredSealProof, nwVer network.Version) abi.ChainEpoch {
if nwVer <= network.Version10 {
return builtin{{.latestVersion}}.SealProofPoliciesV0[proof].SectorMaxLifetime
return builtin4.SealProofPoliciesV0[proof].SectorMaxLifetime
}
return builtin{{.latestVersion}}.SealProofPoliciesV11[proof].SectorMaxLifetime

View File

@ -79,6 +79,7 @@ type ChainGen struct {
eppProvs map[address.Address]WinningPoStProver
Miners []address.Address
receivers []address.Address
// a SecP address
banker address.Address
bankerNonce uint64
@ -111,7 +112,7 @@ var DefaultRemainderAccountActor = genesis.Actor{
Meta: remAccMeta.ActorMeta(),
}
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
func NewGeneratorWithSectorsAndUpgradeSchedule(numSectors int, us stmgr.UpgradeSchedule) (*ChainGen, error) {
j := journal.NilJournal()
// TODO: we really shouldn't modify a global variable here.
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
@ -246,7 +247,10 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
mgen[genesis2.MinerAddress(uint64(i))] = &wppProvider{}
}
sm := stmgr.NewStateManager(cs)
sm, err := stmgr.NewStateManagerWithUpgradeSchedule(cs, us)
if err != nil {
return nil, xerrors.Errorf("initing stmgr: %w", err)
}
miners := []address.Address{maddr1, maddr2}
@ -284,6 +288,14 @@ func NewGenerator() (*ChainGen, error) {
return NewGeneratorWithSectors(1)
}
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
return NewGeneratorWithSectorsAndUpgradeSchedule(numSectors, stmgr.DefaultUpgradeSchedule())
}
func NewGeneratorWithUpgradeSchedule(us stmgr.UpgradeSchedule) (*ChainGen, error) {
return NewGeneratorWithSectorsAndUpgradeSchedule(1, us)
}
func (cg *ChainGen) StateManager() *stmgr.StateManager {
return cg.sm
}
@ -386,7 +398,7 @@ type MinedTipSet struct {
}
func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
mts, err := cg.NextTipSetFromMiners(cg.CurTipset.TipSet(), cg.Miners)
mts, err := cg.NextTipSetFromMiners(cg.CurTipset.TipSet(), cg.Miners, 0)
if err != nil {
return nil, err
}
@ -399,7 +411,7 @@ func (cg *ChainGen) SetWinningPoStProver(m address.Address, wpp WinningPoStProve
cg.eppProvs[m] = wpp
}
func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Address) (*MinedTipSet, error) {
func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Address, nulls abi.ChainEpoch) (*MinedTipSet, error) {
ms, err := cg.GetMessages(cg)
if err != nil {
return nil, xerrors.Errorf("get random messages: %w", err)
@ -410,21 +422,23 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad
msgs[i] = ms
}
fts, err := cg.NextTipSetFromMinersWithMessages(base, miners, msgs)
fts, err := cg.NextTipSetFromMinersWithMessagesAndNulls(base, miners, msgs, nulls)
if err != nil {
return nil, err
}
cg.CurTipset = fts
return &MinedTipSet{
TipSet: fts,
Messages: ms,
}, nil
}
func (cg *ChainGen) NextTipSetFromMinersWithMessages(base *types.TipSet, miners []address.Address, msgs [][]*types.SignedMessage) (*store.FullTipSet, error) {
func (cg *ChainGen) NextTipSetFromMinersWithMessagesAndNulls(base *types.TipSet, miners []address.Address, msgs [][]*types.SignedMessage, nulls abi.ChainEpoch) (*store.FullTipSet, error) {
var blks []*types.FullBlock
for round := base.Height() + 1; len(blks) == 0; round++ {
for round := base.Height() + nulls + 1; len(blks) == 0; round++ {
for mi, m := range miners {
bvals, et, ticket, err := cg.nextBlockProof(context.TODO(), base, m, round)
if err != nil {
@ -457,6 +471,8 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessages(base *types.TipSet, miners
return nil, err
}
cg.CurTipset = fts
return fts, nil
}
@ -576,7 +592,7 @@ func (mca mca) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipS
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return mca.sm.ChainStore().GetChainRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
return mca.sm.ChainStore().GetChainRandomnessLookingBack(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
func (mca mca) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
@ -585,7 +601,7 @@ func (mca mca) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSe
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return mca.sm.ChainStore().GetBeaconRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
return mca.sm.ChainStore().GetBeaconRandomnessLookingBack(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {

View File

@ -488,13 +488,25 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
// TODO: copied from actors test harness, deduplicate or remove from here
type fakeRand struct{}
func (fr *fakeRand) GetChainRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (fr *fakeRand) GetChainRandomnessLookingForward(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
return out, nil
}
func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (fr *fakeRand) GetChainRandomnessLookingBack(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
return out, nil
}
func (fr *fakeRand) GetBeaconRandomnessLookingForward(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
return out, nil
}
func (fr *fakeRand) GetBeaconRandomnessLookingBack(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
out := make([]byte, 32)
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
return out, nil

View File

@ -107,6 +107,9 @@ func (ci *ChainIndex) fillCache(tsk types.TipSetKey) (*lbEntry, error) {
}
rheight -= ci.skipLength
if rheight < 0 {
rheight = 0
}
var skipTarget *types.TipSet
if parent.Height() < rheight {

View File

@ -1404,7 +1404,15 @@ func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.Cha
return h.Sum(nil), nil
}
func (cs *ChainStore) GetBeaconRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (cs *ChainStore) GetBeaconRandomnessLookingBack(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cs.GetBeaconRandomness(ctx, blks, pers, round, entropy, true)
}
func (cs *ChainStore) GetBeaconRandomnessLookingForward(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cs.GetBeaconRandomness(ctx, blks, pers, round, entropy, false)
}
func (cs *ChainStore) GetBeaconRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) {
_, span := trace.StartSpan(ctx, "store.GetBeaconRandomness")
defer span.End()
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
@ -1423,7 +1431,7 @@ func (cs *ChainStore) GetBeaconRandomness(ctx context.Context, blks []cid.Cid, p
searchHeight = 0
}
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, true)
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, lookback)
if err != nil {
return nil, err
}
@ -1438,7 +1446,15 @@ func (cs *ChainStore) GetBeaconRandomness(ctx context.Context, blks []cid.Cid, p
return DrawRandomness(be.Data, pers, round, entropy)
}
func (cs *ChainStore) GetChainRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (cs *ChainStore) GetChainRandomnessLookingBack(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cs.GetChainRandomness(ctx, blks, pers, round, entropy, true)
}
func (cs *ChainStore) GetChainRandomnessLookingForward(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cs.GetChainRandomness(ctx, blks, pers, round, entropy, false)
}
func (cs *ChainStore) GetChainRandomness(ctx context.Context, blks []cid.Cid, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) {
_, span := trace.StartSpan(ctx, "store.GetChainRandomness")
defer span.End()
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
@ -1457,7 +1473,7 @@ func (cs *ChainStore) GetChainRandomness(ctx context.Context, blks []cid.Cid, pe
searchHeight = 0
}
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, true)
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, lookback)
if err != nil {
return nil, err
}
@ -1732,12 +1748,20 @@ func NewChainRand(cs *ChainStore, blks []cid.Cid) vm.Rand {
}
}
func (cr *chainRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetChainRandomness(ctx, cr.blks, pers, round, entropy)
func (cr *chainRand) GetChainRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetChainRandomnessLookingBack(ctx, cr.blks, pers, round, entropy)
}
func (cr *chainRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetBeaconRandomness(ctx, cr.blks, pers, round, entropy)
func (cr *chainRand) GetChainRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetChainRandomnessLookingForward(ctx, cr.blks, pers, round, entropy)
}
func (cr *chainRand) GetBeaconRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetBeaconRandomnessLookingBack(ctx, cr.blks, pers, round, entropy)
}
func (cr *chainRand) GetBeaconRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return cr.cs.GetBeaconRandomnessLookingForward(ctx, cr.blks, pers, round, entropy)
}
func (cs *ChainStore) GetTipSetFromKey(tsk types.TipSetKey) (*types.TipSet, error) {

View File

@ -76,7 +76,7 @@ func BenchmarkGetRandomness(b *testing.B) {
b.ResetTimer()
for i := 0; i < b.N; i++ {
_, err := cs.GetChainRandomness(context.TODO(), last.Cids(), crypto.DomainSeparationTag_SealRandomness, 500, nil)
_, err := cs.GetChainRandomnessLookingBack(context.TODO(), last.Cids(), crypto.DomainSeparationTag_SealRandomness, 500, nil)
if err != nil {
b.Fatal(err)
}

View File

@ -7,6 +7,12 @@ import (
"testing"
"time"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/stmgr"
"github.com/ipfs/go-cid"
ds "github.com/ipfs/go-datastore"
@ -101,7 +107,7 @@ func prepSyncTest(t testing.TB, h int) *syncTestUtil {
g: g,
}
tu.addSourceNode(h)
tu.addSourceNode(stmgr.DefaultUpgradeSchedule(), h)
//tu.checkHeight("source", source, h)
// separate logs
@ -110,6 +116,53 @@ func prepSyncTest(t testing.TB, h int) *syncTestUtil {
return tu
}
func prepSyncTestWithV5Height(t testing.TB, h int, v5height abi.ChainEpoch) *syncTestUtil {
logging.SetLogLevel("*", "INFO")
us := stmgr.UpgradeSchedule{{
// prepare for upgrade.
Network: network.Version9,
Height: 1,
Migration: stmgr.UpgradeActorsV2,
}, {
Network: network.Version10,
Height: 2,
Migration: stmgr.UpgradeActorsV3,
}, {
Network: network.Version12,
Height: 3,
Migration: stmgr.UpgradeActorsV4,
}, {
Network: network.Version13,
Height: v5height,
Migration: stmgr.UpgradeActorsV5,
}}
g, err := gen.NewGeneratorWithUpgradeSchedule(us)
if err != nil {
t.Fatalf("%+v", err)
}
ctx, cancel := context.WithCancel(context.Background())
tu := &syncTestUtil{
t: t,
ctx: ctx,
cancel: cancel,
mn: mocknet.New(ctx),
g: g,
}
tu.addSourceNode(us, h)
//tu.checkHeight("source", source, h)
// separate logs
fmt.Println("\x1b[31m///////////////////////////////////////////////////\x1b[39b")
return tu
}
func (tu *syncTestUtil) Shutdown() {
tu.cancel()
}
@ -174,7 +227,7 @@ func (tu *syncTestUtil) pushTsExpectErr(to int, fts *store.FullTipSet, experr bo
}
}
func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, wait, fail bool, msgs [][]*types.SignedMessage) *store.FullTipSet {
func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int, wait, fail bool, msgs [][]*types.SignedMessage, nulls abi.ChainEpoch) *store.FullTipSet {
if miners == nil {
for i := range tu.g.Miners {
miners = append(miners, i)
@ -191,10 +244,10 @@ func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int,
var nts *store.FullTipSet
var err error
if msgs != nil {
nts, err = tu.g.NextTipSetFromMinersWithMessages(blk.TipSet(), maddrs, msgs)
nts, err = tu.g.NextTipSetFromMinersWithMessagesAndNulls(blk.TipSet(), maddrs, msgs, 0)
require.NoError(tu.t, err)
} else {
mt, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs)
mt, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs, nulls)
require.NoError(tu.t, err)
nts = mt.TipSet
}
@ -209,11 +262,11 @@ func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int,
}
func (tu *syncTestUtil) mineNewBlock(src int, miners []int) {
mts := tu.mineOnBlock(tu.g.CurTipset, src, miners, true, false, nil)
mts := tu.mineOnBlock(tu.g.CurTipset, src, miners, true, false, nil, 0)
tu.g.CurTipset = mts
}
func (tu *syncTestUtil) addSourceNode(gen int) {
func (tu *syncTestUtil) addSourceNode(us stmgr.UpgradeSchedule, gen int) {
if tu.genesis != nil {
tu.t.Fatal("source node already exists")
}
@ -229,6 +282,7 @@ func (tu *syncTestUtil) addSourceNode(gen int) {
node.Test(),
node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)),
node.Override(new(stmgr.UpgradeSchedule), us),
)
require.NoError(tu.t, err)
tu.t.Cleanup(func() { _ = stop(context.Background()) })
@ -445,7 +499,7 @@ func TestSyncBadTimestamp(t *testing.T) {
fmt.Println("BASE: ", base.Cids())
tu.printHeads()
a1 := tu.mineOnBlock(base, 0, nil, false, true, nil)
a1 := tu.mineOnBlock(base, 0, nil, false, true, nil, 0)
tu.g.Timestamper = nil
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
@ -454,7 +508,7 @@ func TestSyncBadTimestamp(t *testing.T) {
fmt.Println("After mine bad block!")
tu.printHeads()
a2 := tu.mineOnBlock(base, 0, nil, true, false, nil)
a2 := tu.mineOnBlock(base, 0, nil, true, false, nil, 0)
tu.waitUntilSync(0, client)
@ -498,7 +552,7 @@ func TestSyncBadWinningPoSt(t *testing.T) {
tu.g.SetWinningPoStProver(tu.g.Miners[1], &badWpp{})
// now ensure that new blocks are not accepted
tu.mineOnBlock(base, client, nil, false, true, nil)
tu.mineOnBlock(base, client, nil, false, true, nil, 0)
}
func (tu *syncTestUtil) loadChainToNode(to int) {
@ -543,16 +597,16 @@ func TestSyncFork(t *testing.T) {
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
// The two nodes fork at this point into 'a' and 'b'
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil)
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil)
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0)
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0)
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0)
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
// chain B will now be heaviest
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
@ -614,13 +668,13 @@ func TestDuplicateNonce(t *testing.T) {
msgs[k] = []*types.SignedMessage{makeMsg(tu.g.Miners[k])}
}
ts1 := tu.mineOnBlock(base, 0, []int{0, 1}, true, false, msgs)
ts1 := tu.mineOnBlock(base, 0, []int{0, 1}, true, false, msgs, 0)
tu.waitUntilSyncTarget(0, ts1.TipSet())
// mine another tipset
ts2 := tu.mineOnBlock(ts1, 0, []int{0, 1}, true, false, make([][]*types.SignedMessage, 2))
ts2 := tu.mineOnBlock(ts1, 0, []int{0, 1}, true, false, make([][]*types.SignedMessage, 2), 0)
tu.waitUntilSyncTarget(0, ts2.TipSet())
var includedMsg cid.Cid
@ -671,11 +725,15 @@ func TestBadNonce(t *testing.T) {
base := tu.g.CurTipset
// Get the banker from computed tipset state, not the parent.
st, _, err := tu.g.StateManager().TipSetState(context.TODO(), base.TipSet())
require.NoError(t, err)
ba, err := tu.g.StateManager().LoadActorRaw(context.TODO(), tu.g.Banker(), st)
require.NoError(t, err)
// Produce a message from the banker with a bad nonce
makeBadMsg := func() *types.SignedMessage {
ba, err := tu.nds[0].StateGetActor(context.TODO(), tu.g.Banker(), base.TipSet().Key())
require.NoError(t, err)
msg := types.Message{
To: tu.g.Banker(),
From: tu.g.Banker(),
@ -703,7 +761,7 @@ func TestBadNonce(t *testing.T) {
msgs := make([][]*types.SignedMessage, 1)
msgs[0] = []*types.SignedMessage{makeBadMsg()}
tu.mineOnBlock(base, 0, []int{0}, true, true, msgs)
tu.mineOnBlock(base, 0, []int{0}, true, true, msgs, 0)
}
func BenchmarkSyncBasic(b *testing.B) {
@ -768,19 +826,19 @@ func TestSyncCheckpointHead(t *testing.T) {
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
// The two nodes fork at this point into 'a' and 'b'
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil)
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil)
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0)
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0)
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0)
tu.waitUntilSyncTarget(p1, a.TipSet())
tu.checkpointTs(p1, a.TipSet().Key())
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
// chain B will now be heaviest
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
@ -815,19 +873,19 @@ func TestSyncCheckpointEarlierThanHead(t *testing.T) {
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
// The two nodes fork at this point into 'a' and 'b'
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil)
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil)
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
a1 := tu.mineOnBlock(base, p1, []int{0}, true, false, nil, 0)
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0)
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0)
tu.waitUntilSyncTarget(p1, a.TipSet())
tu.checkpointTs(p1, a1.TipSet().Key())
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
// chain B will now be heaviest
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
b := tu.mineOnBlock(base, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
@ -846,3 +904,58 @@ func TestSyncCheckpointEarlierThanHead(t *testing.T) {
p1Head = tu.getHead(p1)
require.True(tu.t, p1Head.Equals(b.TipSet()))
}
func TestDrandNull(t *testing.T) {
H := 10
v5h := abi.ChainEpoch(50)
ov5h := build.UpgradeHyperdriveHeight
build.UpgradeHyperdriveHeight = v5h
tu := prepSyncTestWithV5Height(t, H, v5h)
entropy := []byte{0, 2, 3, 4}
// arbitrarily chosen
pers := crypto.DomainSeparationTag_WinningPoStChallengeSeed
beforeNull := tu.g.CurTipset
afterNull := tu.mineOnBlock(beforeNull, 0, nil, false, false, nil, 2)
nullHeight := beforeNull.TipSet().Height() + 1
if afterNull.TipSet().Height() == nullHeight {
t.Fatal("didn't inject nulls as expected")
}
rand, err := tu.nds[0].ChainGetRandomnessFromBeacon(tu.ctx, afterNull.TipSet().Key(), pers, nullHeight, entropy)
require.NoError(t, err)
// calculate the expected randomness based on the beacon BEFORE the null
expectedBE := beforeNull.Blocks[0].Header.BeaconEntries
expectedRand, err := store.DrawRandomness(expectedBE[len(expectedBE)-1].Data, pers, nullHeight, entropy)
require.NoError(t, err)
require.Equal(t, []byte(rand), expectedRand)
// zoom zoom to past the v5 upgrade by injecting many many nulls
postUpgrade := tu.mineOnBlock(afterNull, 0, nil, false, false, nil, v5h)
nv, err := tu.nds[0].StateNetworkVersion(tu.ctx, types.EmptyTSK)
require.NoError(t, err)
if nv != network.Version13 {
t.Fatal("expect to be v13 by now")
}
afterNull = tu.mineOnBlock(postUpgrade, 0, nil, false, false, nil, 2)
nullHeight = postUpgrade.TipSet().Height() + 1
if afterNull.TipSet().Height() == nullHeight {
t.Fatal("didn't inject nulls as expected")
}
rand, err = tu.nds[0].ChainGetRandomnessFromBeacon(tu.ctx, afterNull.TipSet().Key(), pers, nullHeight, entropy)
require.NoError(t, err)
// calculate the expected randomness based on the beacon AFTER the null
expectedBE = afterNull.Blocks[0].Header.BeaconEntries
expectedRand, err = store.DrawRandomness(expectedBE[len(expectedBE)-1].Data, pers, nullHeight, entropy)
require.NoError(t, err)
require.Equal(t, []byte(rand), expectedRand)
build.UpgradeHyperdriveHeight = ov5h
}

View File

@ -160,8 +160,35 @@ var prices = map[abi.ChainEpoch]Pricelist{
hashingBase: 31355,
computeUnsealedSectorCidBase: 98647,
verifySealBase: 2000, // TODO gas , it VerifySeal syscall is not used
verifyAggregateSealBase: 400_000_000, // TODO (~40ms, I think)
verifySealBase: 2000, // TODO gas, it VerifySeal syscall is not used
verifyAggregateSealPer: map[abi.RegisteredSealProof]int64{
abi.RegisteredSealProof_StackedDrg32GiBV1_1: 449900,
abi.RegisteredSealProof_StackedDrg64GiBV1_1: 359272,
},
verifyAggregateSealSteps: map[abi.RegisteredSealProof]stepCost{
abi.RegisteredSealProof_StackedDrg32GiBV1_1: {
{4, 103994170},
{7, 112356810},
{13, 122912610},
{26, 137559930},
{52, 162039100},
{103, 210960780},
{205, 318351180},
{410, 528274980},
},
abi.RegisteredSealProof_StackedDrg64GiBV1_1: {
{4, 102581240},
{7, 110803030},
{13, 120803700},
{26, 134642130},
{52, 157357890},
{103, 203017690},
{205, 304253590},
{410, 509880640},
},
},
verifyPostLookup: map[abi.RegisteredPoStProof]scalingCost{
abi.RegisteredPoStProof_StackedDrgWindow512MiBV1: {
flat: 117680921,

View File

@ -18,6 +18,28 @@ type scalingCost struct {
scale int64
}
type stepCost []step
type step struct {
start int64
cost int64
}
func (sc stepCost) Lookup(x int64) int64 {
i := 0
for ; i < len(sc); i++ {
if sc[i].start > x {
break
}
}
i-- // look at previous item
if i < 0 {
return 0
}
return sc[i].cost
}
type pricelistV0 struct {
computeGasMulti int64
storageGasMulti int64
@ -93,6 +115,9 @@ type pricelistV0 struct {
computeUnsealedSectorCidBase int64
verifySealBase int64
verifyAggregateSealBase int64
verifyAggregateSealPer map[abi.RegisteredSealProof]int64
verifyAggregateSealSteps map[abi.RegisteredSealProof]stepCost
verifyPostLookup map[abi.RegisteredPoStProof]scalingCost
verifyPostDiscount bool
verifyConsensusFault int64
@ -189,8 +214,18 @@ func (pl *pricelistV0) OnVerifySeal(info proof2.SealVerifyInfo) GasCharge {
// OnVerifyAggregateSeals
func (pl *pricelistV0) OnVerifyAggregateSeals(aggregate proof5.AggregateSealVerifyProofAndInfos) GasCharge {
// TODO: this needs more cost tunning
return newGasCharge("OnVerifyAggregateSeals", pl.verifyAggregateSealBase, 0)
proofType := aggregate.SealProof
perProof, ok := pl.verifyAggregateSealPer[proofType]
if !ok {
perProof = pl.verifyAggregateSealPer[abi.RegisteredSealProof_StackedDrg32GiBV1_1]
}
step, ok := pl.verifyAggregateSealSteps[proofType]
if !ok {
step = pl.verifyAggregateSealSteps[abi.RegisteredSealProof_StackedDrg32GiBV1_1]
}
num := int64(len(aggregate.Infos))
return newGasCharge("OnVerifyAggregateSeals", perProof*num+step.Lookup(num), 0)
}
// OnVerifyPost

32
chain/vm/gas_v0_test.go Normal file
View File

@ -0,0 +1,32 @@
package vm
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestStepGasCost(t *testing.T) {
s := stepCost{
{4, 103994170},
{7, 112356810},
{13, 122912610},
{26, 137559930},
{52, 162039100},
{103, 210960780},
{205, 318351180},
{410, 528274980},
}
assert.EqualValues(t, 0, s.Lookup(0))
assert.EqualValues(t, 0, s.Lookup(3))
assert.EqualValues(t, 103994170, s.Lookup(4))
assert.EqualValues(t, 103994170, s.Lookup(6))
assert.EqualValues(t, 112356810, s.Lookup(7))
assert.EqualValues(t, 210960780, s.Lookup(103))
assert.EqualValues(t, 210960780, s.Lookup(204))
assert.EqualValues(t, 318351180, s.Lookup(205))
assert.EqualValues(t, 318351180, s.Lookup(409))
assert.EqualValues(t, 528274980, s.Lookup(410))
assert.EqualValues(t, 528274980, s.Lookup(10000000000))
}

View File

@ -81,6 +81,10 @@ type Runtime struct {
lastGasCharge *types.GasTrace
}
func (rt *Runtime) BaseFee() abi.TokenAmount {
return rt.vm.baseFee
}
func (rt *Runtime) NetworkVersion() network.Version {
return rt.vm.GetNtwkVersion(rt.ctx, rt.CurrEpoch())
}
@ -208,17 +212,31 @@ func (rt *Runtime) GetActorCodeCID(addr address.Address) (ret cid.Cid, ok bool)
}
func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
res, err := rt.vm.rand.GetChainRandomness(rt.ctx, personalization, randEpoch, entropy)
var err error
var res []byte
if rt.vm.GetNtwkVersion(rt.ctx, randEpoch) >= network.Version13 {
res, err = rt.vm.rand.GetChainRandomnessLookingForward(rt.ctx, personalization, randEpoch, entropy)
} else {
res, err = rt.vm.rand.GetChainRandomnessLookingBack(rt.ctx, personalization, randEpoch, entropy)
}
if err != nil {
panic(aerrors.Fatalf("could not get randomness: %s", err))
panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
}
return res
}
func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
res, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, personalization, randEpoch, entropy)
var err error
var res []byte
if rt.vm.GetNtwkVersion(rt.ctx, randEpoch) >= network.Version13 {
res, err = rt.vm.rand.GetBeaconRandomnessLookingForward(rt.ctx, personalization, randEpoch, entropy)
} else {
res, err = rt.vm.rand.GetBeaconRandomnessLookingBack(rt.ctx, personalization, randEpoch, entropy)
}
if err != nil {
panic(aerrors.Fatalf("could not get randomness: %s", err))
panic(aerrors.Fatalf("could not get beacon randomness: %s", err))
}
return res
}

View File

@ -255,8 +255,10 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
}
type Rand interface {
GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetChainRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetChainRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
GetBeaconRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error)
}
type ApplyRet struct {
@ -566,7 +568,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
gasUsed = 0
}
burn, err := vm.ShouldBurn(st, msg, errcode)
burn, err := vm.ShouldBurn(ctx, st, msg, errcode)
if err != nil {
return nil, xerrors.Errorf("deciding whether should burn failed: %w", err)
}
@ -609,7 +611,8 @@ func (vm *VM) ApplyMessage(ctx context.Context, cmsg types.ChainMsg) (*ApplyRet,
}, nil
}
func (vm *VM) ShouldBurn(st *state.StateTree, msg *types.Message, errcode exitcode.ExitCode) (bool, error) {
func (vm *VM) ShouldBurn(ctx context.Context, st *state.StateTree, msg *types.Message, errcode exitcode.ExitCode) (bool, error) {
if vm.ntwkVersion(ctx, vm.blockHeight) <= network.Version12 {
// Check to see if we should burn funds. We avoid burning on successful
// window post. This won't catch _indirect_ window post calls, but this
// is the best we can get for now.
@ -629,6 +632,10 @@ func (vm *VM) ShouldBurn(st *state.StateTree, msg *types.Message, errcode exitco
}
}
return true, nil
}
// Any "don't burn" rules from Network v13 onwards go here, for now we always return true
return true, nil
}

View File

@ -71,7 +71,7 @@ var Commands = []*cli.Command{
WithCategory("basic", walletCmd),
WithCategory("basic", clientCmd),
WithCategory("basic", multisigCmd),
WithCategory("basic", verifRegCmd),
WithCategory("basic", filplusCmd),
WithCategory("basic", paychCmd),
WithCategory("developer", AuthCmd),
WithCategory("developer", MpoolCmd),

View File

@ -3,11 +3,11 @@ package cli
import (
"context"
"fmt"
"github.com/filecoin-project/lotus/api/v0api"
verifreg4 "github.com/filecoin-project/specs-actors/v4/actors/builtin/verifreg"
"github.com/filecoin-project/go-state-types/big"
"github.com/filecoin-project/lotus/api/v0api"
"github.com/urfave/cli/v2"
"golang.org/x/xerrors"
@ -24,26 +24,26 @@ import (
cbor "github.com/ipfs/go-ipld-cbor"
)
var verifRegCmd = &cli.Command{
Name: "verifreg",
Usage: "Interact with the verified registry actor",
var filplusCmd = &cli.Command{
Name: "filplus",
Usage: "Interact with the verified registry actor used by Filplus",
Flags: []cli.Flag{},
Subcommands: []*cli.Command{
verifRegVerifyClientCmd,
verifRegListVerifiersCmd,
verifRegListClientsCmd,
verifRegCheckClientCmd,
verifRegCheckVerifierCmd,
filplusVerifyClientCmd,
filplusListNotariesCmd,
filplusListClientsCmd,
filplusCheckClientCmd,
filplusCheckNotaryCmd,
},
}
var verifRegVerifyClientCmd = &cli.Command{
Name: "verify-client",
var filplusVerifyClientCmd = &cli.Command{
Name: "grant-datacap",
Usage: "give allowance to the specified verified client address",
Flags: []cli.Flag{
&cli.StringFlag{
Name: "from",
Usage: "specify your verifier address to send the message from",
Usage: "specify your notary address to send the message from",
Required: true,
},
},
@ -79,17 +79,17 @@ var verifRegVerifyClientCmd = &cli.Command{
defer closer()
ctx := ReqContext(cctx)
found, dcap, err := checkVerifier(ctx, api, fromk)
found, dcap, err := checkNotary(ctx, api, fromk)
if err != nil {
return err
}
if !found {
return xerrors.New("sender address must be a verifier")
return xerrors.New("sender address must be a notary")
}
if dcap.Cmp(allowance.Int) < 0 {
return xerrors.Errorf("cannot allot more allowance than verifier data cap: %s < %s", dcap, allowance)
return xerrors.Errorf("cannot allot more allowance than notary data cap: %s < %s", dcap, allowance)
}
// TODO: This should be abstracted over actor versions
@ -125,9 +125,9 @@ var verifRegVerifyClientCmd = &cli.Command{
},
}
var verifRegListVerifiersCmd = &cli.Command{
Name: "list-verifiers",
Usage: "list all verifiers",
var filplusListNotariesCmd = &cli.Command{
Name: "list-notaries",
Usage: "list all notaries",
Action: func(cctx *cli.Context) error {
api, closer, err := GetFullNodeAPI(cctx)
if err != nil {
@ -155,7 +155,7 @@ var verifRegListVerifiersCmd = &cli.Command{
},
}
var verifRegListClientsCmd = &cli.Command{
var filplusListClientsCmd = &cli.Command{
Name: "list-clients",
Usage: "list all verified clients",
Action: func(cctx *cli.Context) error {
@ -185,8 +185,8 @@ var verifRegListClientsCmd = &cli.Command{
},
}
var verifRegCheckClientCmd = &cli.Command{
Name: "check-client",
var filplusCheckClientCmd = &cli.Command{
Name: "check-client-datacap",
Usage: "check verified client remaining bytes",
Action: func(cctx *cli.Context) error {
if !cctx.Args().Present() {
@ -219,12 +219,12 @@ var verifRegCheckClientCmd = &cli.Command{
},
}
var verifRegCheckVerifierCmd = &cli.Command{
Name: "check-verifier",
Usage: "check verifiers remaining bytes",
var filplusCheckNotaryCmd = &cli.Command{
Name: "check-notaries-datacap",
Usage: "check notaries remaining bytes",
Action: func(cctx *cli.Context) error {
if !cctx.Args().Present() {
return fmt.Errorf("must specify verifier address to check")
return fmt.Errorf("must specify notary address to check")
}
vaddr, err := address.NewFromString(cctx.Args().First())
@ -239,7 +239,7 @@ var verifRegCheckVerifierCmd = &cli.Command{
defer closer()
ctx := ReqContext(cctx)
found, dcap, err := checkVerifier(ctx, api, vaddr)
found, dcap, err := checkNotary(ctx, api, vaddr)
if err != nil {
return err
}
@ -253,7 +253,7 @@ var verifRegCheckVerifierCmd = &cli.Command{
},
}
func checkVerifier(ctx context.Context, api v0api.FullNode, vaddr address.Address) (bool, abi.StoragePower, error) {
func checkNotary(ctx context.Context, api v0api.FullNode, vaddr address.Address) (bool, abi.StoragePower, error) {
vid, err := api.StateLookupID(ctx, vaddr, types.EmptyTSK)
if err != nil {
return false, big.Zero(), err

View File

@ -19,10 +19,18 @@ func NewFixedRand() vm.Rand {
return &fixedRand{}
}
func (r *fixedRand) GetChainRandomness(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) {
func (r *fixedRand) GetChainRandomnessLookingForward(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) {
return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
}
func (r *fixedRand) GetBeaconRandomness(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) {
func (r *fixedRand) GetChainRandomnessLookingBack(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) {
return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
}
func (r *fixedRand) GetBeaconRandomnessLookingForward(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) {
return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
}
func (r *fixedRand) GetBeaconRandomnessLookingBack(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) {
return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
}

View File

@ -45,8 +45,17 @@ func (r *RecordingRand) loadHead() {
r.head = head.Key()
}
func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (r *RecordingRand) GetChainRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return r.getChainRandomness(ctx, pers, round, entropy)
}
func (r *RecordingRand) GetChainRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return r.getChainRandomness(ctx, pers, round, entropy)
}
func (r *RecordingRand) getChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
r.once.Do(r.loadHead)
// FullNode's ChainGetRandomnessFromTickets handles whether we should be looking forward or back
ret, err := r.api.ChainGetRandomnessFromTickets(ctx, r.head, pers, round, entropy)
if err != nil {
return ret, err
@ -70,7 +79,15 @@ func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.Doma
return ret, err
}
func (r *RecordingRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (r *RecordingRand) GetBeaconRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return r.getBeaconRandomness(ctx, pers, round, entropy)
}
func (r *RecordingRand) GetBeaconRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return r.getBeaconRandomness(ctx, pers, round, entropy)
}
func (r *RecordingRand) getBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
r.once.Do(r.loadHead)
ret, err := r.api.ChainGetRandomnessFromBeacon(ctx, r.head, pers, round, entropy)
if err != nil {

View File

@ -43,7 +43,15 @@ func (r *ReplayingRand) match(requested schema.RandomnessRule) ([]byte, bool) {
return nil, false
}
func (r *ReplayingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (r *ReplayingRand) GetChainRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return r.getChainRandomness(ctx, pers, round, entropy, false)
}
func (r *ReplayingRand) GetChainRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return r.getChainRandomness(ctx, pers, round, entropy, true)
}
func (r *ReplayingRand) getChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) {
rule := schema.RandomnessRule{
Kind: schema.RandomnessChain,
DomainSeparationTag: int64(pers),
@ -57,10 +65,23 @@ func (r *ReplayingRand) GetChainRandomness(ctx context.Context, pers crypto.Doma
}
r.reporter.Logf("returning fallback chain randomness: dst=%d, epoch=%d, entropy=%x", pers, round, entropy)
return r.fallback.GetChainRandomness(ctx, pers, round, entropy)
if lookback {
return r.fallback.GetChainRandomnessLookingBack(ctx, pers, round, entropy)
}
return r.fallback.GetChainRandomnessLookingForward(ctx, pers, round, entropy)
}
func (r *ReplayingRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
func (r *ReplayingRand) GetBeaconRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return r.getBeaconRandomness(ctx, pers, round, entropy, false)
}
func (r *ReplayingRand) GetBeaconRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return r.getBeaconRandomness(ctx, pers, round, entropy, true)
}
func (r *ReplayingRand) getBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) {
rule := schema.RandomnessRule{
Kind: schema.RandomnessBeacon,
DomainSeparationTag: int64(pers),
@ -74,6 +95,10 @@ func (r *ReplayingRand) GetBeaconRandomness(ctx context.Context, pers crypto.Dom
}
r.reporter.Logf("returning fallback beacon randomness: dst=%d, epoch=%d, entropy=%x", pers, round, entropy)
return r.fallback.GetBeaconRandomness(ctx, pers, round, entropy)
if lookback {
return r.fallback.GetBeaconRandomnessLookingBack(ctx, pers, round, entropy)
}
return r.fallback.GetBeaconRandomnessLookingForward(ctx, pers, round, entropy)
}

View File

@ -19,7 +19,7 @@ COMMANDS:
wallet Manage wallet
client Make deals, store data, retrieve data
msig Interact with a multisig wallet
verifreg Interact with the verified registry actor
filplus Interact with the verified registry actor used by Filplus
paych Manage payment channels
DEVELOPER:
auth Manage RPC permissions
@ -1035,20 +1035,20 @@ OPTIONS:
```
## lotus verifreg
## lotus filplus
```
NAME:
lotus verifreg - Interact with the verified registry actor
lotus filplus - Interact with the verified registry actor used by Filplus
USAGE:
lotus verifreg command [command options] [arguments...]
lotus filplus command [command options] [arguments...]
COMMANDS:
verify-client give allowance to the specified verified client address
list-verifiers list all verifiers
grant-datacap give allowance to the specified verified client address
list-notaries list all notaries
list-clients list all verified clients
check-client check verified client remaining bytes
check-verifier check verifiers remaining bytes
check-client-datacap check verified client remaining bytes
check-notaries-datacap check notaries remaining bytes
help, h Shows a list of commands or help for one command
OPTIONS:
@ -1057,66 +1057,66 @@ OPTIONS:
```
### lotus verifreg verify-client
### lotus filplus grant-datacap
```
NAME:
lotus verifreg verify-client - give allowance to the specified verified client address
lotus filplus grant-datacap - give allowance to the specified verified client address
USAGE:
lotus verifreg verify-client [command options] [arguments...]
lotus filplus grant-datacap [command options] [arguments...]
OPTIONS:
--from value specify your verifier address to send the message from
--from value specify your notary address to send the message from
--help, -h show help (default: false)
```
### lotus verifreg list-verifiers
### lotus filplus list-notaries
```
NAME:
lotus verifreg list-verifiers - list all verifiers
lotus filplus list-notaries - list all notaries
USAGE:
lotus verifreg list-verifiers [command options] [arguments...]
lotus filplus list-notaries [command options] [arguments...]
OPTIONS:
--help, -h show help (default: false)
```
### lotus verifreg list-clients
### lotus filplus list-clients
```
NAME:
lotus verifreg list-clients - list all verified clients
lotus filplus list-clients - list all verified clients
USAGE:
lotus verifreg list-clients [command options] [arguments...]
lotus filplus list-clients [command options] [arguments...]
OPTIONS:
--help, -h show help (default: false)
```
### lotus verifreg check-client
### lotus filplus check-client-datacap
```
NAME:
lotus verifreg check-client - check verified client remaining bytes
lotus filplus check-client-datacap - check verified client remaining bytes
USAGE:
lotus verifreg check-client [command options] [arguments...]
lotus filplus check-client-datacap [command options] [arguments...]
OPTIONS:
--help, -h show help (default: false)
```
### lotus verifreg check-verifier
### lotus filplus check-notaries-datacap
```
NAME:
lotus verifreg check-verifier - check verifiers remaining bytes
lotus filplus check-notaries-datacap - check notaries remaining bytes
USAGE:
lotus verifreg check-verifier [command options] [arguments...]
lotus filplus check-notaries-datacap [command options] [arguments...]
OPTIONS:
--help, -h show help (default: false)

View File

@ -181,7 +181,7 @@ func (b *PreCommitBatcher) processBatch(notif, after bool) (*cid.Cid, error) {
break
}
params.Sectors = append(params.Sectors, p.pci)
params.Sectors = append(params.Sectors, *p.pci)
deposit = big.Add(deposit, p.deposit)
}

2
go.mod
View File

@ -48,7 +48,7 @@ require (
github.com/filecoin-project/specs-actors/v2 v2.3.5
github.com/filecoin-project/specs-actors/v3 v3.1.1
github.com/filecoin-project/specs-actors/v4 v4.0.1
github.com/filecoin-project/specs-actors/v5 v5.0.0-20210517165532-c7cff61d07fb
github.com/filecoin-project/specs-actors/v5 v5.0.0-20210528202914-a9f9f95f5e93
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506
github.com/filecoin-project/test-vectors/schema v0.0.5
github.com/gbrlsnchs/jwt/v3 v3.0.0-beta.1

2
go.sum
View File

@ -330,6 +330,8 @@ github.com/filecoin-project/specs-actors/v3 v3.1.1 h1:BE8fsns1GnEOxt1DTE5LxBK2FT
github.com/filecoin-project/specs-actors/v3 v3.1.1/go.mod h1:mpynccOLlIRy0QnR008BwYBwT9fen+sPR13MA1VmMww=
github.com/filecoin-project/specs-actors/v4 v4.0.1 h1:AiWrtvJZ63MHGe6rn7tPu4nSUY8bA1KDNszqJaD5+Fg=
github.com/filecoin-project/specs-actors/v4 v4.0.1/go.mod h1:TkHXf/l7Wyw4ZejyXIPS2rK8bBO0rdwhTZyQQgaglng=
github.com/filecoin-project/specs-actors/v5 v5.0.0-20210528202914-a9f9f95f5e93 h1:PZ5pLy4dZVgL+fXgvSVtPOYhfEYUzEYYVEz7IfG8e5U=
github.com/filecoin-project/specs-actors/v5 v5.0.0-20210528202914-a9f9f95f5e93/go.mod h1:kSDmoQuO8jlhMVzKNoesbhka1e6gHKcLQjKm9mE9Qhw=
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506 h1:Ur/l2+6qN+lQiqjozWWc5p9UDaAMDZKTlDS98oRnlIw=
github.com/filecoin-project/specs-storage v0.1.1-0.20201105051918-5188d9774506/go.mod h1:nJRRM7Aa9XVvygr3W9k6xGF46RWzr2zxF/iGoAIfA/g=
github.com/filecoin-project/test-vectors/schema v0.0.5 h1:w3zHQhzM4pYxJDl21avXjOKBLF8egrvwUwjpT8TquDg=

View File

@ -67,7 +67,8 @@ import (
var DefaultHashFunction = uint64(mh.BLAKE2B_MIN + 31)
const dealStartBufferHours uint64 = 49
// 8 days ~= SealDuration + PreCommit + MaxProveCommitDuration + 8 hour buffer
const dealStartBufferHours uint64 = 8 * 24
type API struct {
fx.In

View File

@ -10,6 +10,8 @@ import (
"strings"
"sync"
"github.com/filecoin-project/lotus/build"
"go.uber.org/fx"
"golang.org/x/xerrors"
@ -97,7 +99,12 @@ func (a *ChainAPI) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return a.Chain.GetChainRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
// Doing this here is slightly nicer than doing it in the chainstore directly, but it's still bad for ChainAPI to reason about network upgrades
if randEpoch > build.UpgradeHyperdriveHeight {
return a.Chain.GetChainRandomnessLookingForward(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
return a.Chain.GetChainRandomnessLookingBack(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
func (a *ChainAPI) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
@ -106,7 +113,12 @@ func (a *ChainAPI) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.T
return nil, xerrors.Errorf("loading tipset key: %w", err)
}
return a.Chain.GetBeaconRandomness(ctx, pts.Cids(), personalization, randEpoch, entropy)
// Doing this here is slightly nicer than doing it in the chainstore directly, but it's still bad for ChainAPI to reason about network upgrades
if randEpoch > build.UpgradeHyperdriveHeight {
return a.Chain.GetBeaconRandomnessLookingForward(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
return a.Chain.GetBeaconRandomnessLookingBack(ctx, pts.Cids(), personalization, randEpoch, entropy)
}
func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) {

View File

@ -260,6 +260,34 @@ func TestWindowPostDisputeFails(t *testing.T) {
test.TestWindowPostDisputeFails(t, builder.MockSbBuilder, 2*time.Millisecond)
}
func TestWindowPostBaseFeeNoBurn(t *testing.T) {
if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" {
t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run")
}
logging.SetLogLevel("miner", "ERROR")
logging.SetLogLevel("gen", "ERROR")
logging.SetLogLevel("chainstore", "ERROR")
logging.SetLogLevel("chain", "ERROR")
logging.SetLogLevel("sub", "ERROR")
logging.SetLogLevel("storageminer", "ERROR")
test.TestWindowPostBaseFeeNoBurn(t, builder.MockSbBuilder, 2*time.Millisecond)
}
func TestWindowPostBaseFeeBurn(t *testing.T) {
if os.Getenv("LOTUS_TEST_WINDOW_POST") != "1" {
t.Skip("this takes a few minutes, set LOTUS_TEST_WINDOW_POST=1 to run")
}
logging.SetLogLevel("miner", "ERROR")
logging.SetLogLevel("gen", "ERROR")
logging.SetLogLevel("chainstore", "ERROR")
logging.SetLogLevel("chain", "ERROR")
logging.SetLogLevel("sub", "ERROR")
logging.SetLogLevel("storageminer", "ERROR")
test.TestWindowPostBaseFeeBurn(t, builder.MockSbBuilder, 2*time.Millisecond)
}
func TestDeadlineToggling(t *testing.T) {
if os.Getenv("LOTUS_TEST_DEADLINE_TOGGLING") != "1" {
t.Skip("this takes a few minutes, set LOTUS_TEST_DEADLINE_TOGGLING=1 to run")