Fix randomness fetching around null blocks
This commit is contained in:
parent
2b93bcde72
commit
21b4741e30
@ -75,9 +75,10 @@ type ChainGen struct {
|
|||||||
|
|
||||||
w *wallet.LocalWallet
|
w *wallet.LocalWallet
|
||||||
|
|
||||||
eppProvs map[address.Address]WinningPoStProver
|
eppProvs map[address.Address]WinningPoStProver
|
||||||
Miners []address.Address
|
Miners []address.Address
|
||||||
receivers []address.Address
|
receivers []address.Address
|
||||||
|
// a SecP address
|
||||||
banker address.Address
|
banker address.Address
|
||||||
bankerNonce uint64
|
bankerNonce uint64
|
||||||
|
|
||||||
@ -110,7 +111,7 @@ var DefaultRemainderAccountActor = genesis.Actor{
|
|||||||
Meta: remAccMeta.ActorMeta(),
|
Meta: remAccMeta.ActorMeta(),
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
func NewGeneratorWithSectorsAndUpgradeSchedule(numSectors int, us stmgr.UpgradeSchedule) (*ChainGen, error) {
|
||||||
j := journal.NilJournal()
|
j := journal.NilJournal()
|
||||||
// TODO: we really shouldn't modify a global variable here.
|
// TODO: we really shouldn't modify a global variable here.
|
||||||
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
policy.SetSupportedProofTypes(abi.RegisteredSealProof_StackedDrg2KiBV1)
|
||||||
@ -244,7 +245,10 @@ func NewGeneratorWithSectors(numSectors int) (*ChainGen, error) {
|
|||||||
mgen[genesis2.MinerAddress(uint64(i))] = &wppProvider{}
|
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}
|
miners := []address.Address{maddr1, maddr2}
|
||||||
|
|
||||||
@ -282,6 +286,14 @@ func NewGenerator() (*ChainGen, error) {
|
|||||||
return NewGeneratorWithSectors(1)
|
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 {
|
func (cg *ChainGen) StateManager() *stmgr.StateManager {
|
||||||
return cg.sm
|
return cg.sm
|
||||||
}
|
}
|
||||||
@ -384,7 +396,7 @@ type MinedTipSet struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -397,7 +409,7 @@ func (cg *ChainGen) SetWinningPoStProver(m address.Address, wpp WinningPoStProve
|
|||||||
cg.eppProvs[m] = wpp
|
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)
|
ms, err := cg.GetMessages(cg)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, xerrors.Errorf("get random messages: %w", err)
|
return nil, xerrors.Errorf("get random messages: %w", err)
|
||||||
@ -408,21 +420,23 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad
|
|||||||
msgs[i] = ms
|
msgs[i] = ms
|
||||||
}
|
}
|
||||||
|
|
||||||
fts, err := cg.NextTipSetFromMinersWithMessages(base, miners, msgs)
|
fts, err := cg.NextTipSetFromMinersWithMessagesAndNulls(base, miners, msgs, nulls)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cg.CurTipset = fts
|
||||||
|
|
||||||
return &MinedTipSet{
|
return &MinedTipSet{
|
||||||
TipSet: fts,
|
TipSet: fts,
|
||||||
Messages: ms,
|
Messages: ms,
|
||||||
}, nil
|
}, 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
|
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 {
|
for mi, m := range miners {
|
||||||
bvals, et, ticket, err := cg.nextBlockProof(context.TODO(), base, m, round)
|
bvals, et, ticket, err := cg.nextBlockProof(context.TODO(), base, m, round)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -455,6 +469,8 @@ func (cg *ChainGen) NextTipSetFromMinersWithMessages(base *types.TipSet, miners
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cg.CurTipset = fts
|
||||||
|
|
||||||
return fts, nil
|
return fts, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,7 +590,7 @@ func (mca mca) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.TipS
|
|||||||
return nil, xerrors.Errorf("loading tipset key: %w", err)
|
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) {
|
func (mca mca) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
|
||||||
@ -583,7 +599,7 @@ func (mca mca) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSe
|
|||||||
return nil, xerrors.Errorf("loading tipset key: %w", err)
|
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) {
|
func (mca mca) MinerGetBaseInfo(ctx context.Context, maddr address.Address, epoch abi.ChainEpoch, tsk types.TipSetKey) (*api.MiningBaseInfo, error) {
|
||||||
|
@ -335,13 +335,25 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid
|
|||||||
// TODO: copied from actors test harness, deduplicate or remove from here
|
// TODO: copied from actors test harness, deduplicate or remove from here
|
||||||
type fakeRand struct{}
|
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)
|
out := make([]byte, 32)
|
||||||
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
|
_, _ = rand.New(rand.NewSource(int64(randEpoch * 1000))).Read(out) //nolint
|
||||||
return out, nil
|
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)
|
out := make([]byte, 32)
|
||||||
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
|
_, _ = rand.New(rand.NewSource(int64(randEpoch))).Read(out) //nolint
|
||||||
return out, nil
|
return out, nil
|
||||||
|
@ -1280,7 +1280,15 @@ func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.Cha
|
|||||||
return h.Sum(nil), nil
|
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")
|
_, span := trace.StartSpan(ctx, "store.GetBeaconRandomness")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
|
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
|
||||||
@ -1299,7 +1307,7 @@ func (cs *ChainStore) GetBeaconRandomness(ctx context.Context, blks []cid.Cid, p
|
|||||||
searchHeight = 0
|
searchHeight = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, true)
|
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, lookback)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1314,7 +1322,15 @@ func (cs *ChainStore) GetBeaconRandomness(ctx context.Context, blks []cid.Cid, p
|
|||||||
return DrawRandomness(be.Data, pers, round, entropy)
|
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")
|
_, span := trace.StartSpan(ctx, "store.GetChainRandomness")
|
||||||
defer span.End()
|
defer span.End()
|
||||||
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
|
span.AddAttributes(trace.Int64Attribute("round", int64(round)))
|
||||||
@ -1333,7 +1349,7 @@ func (cs *ChainStore) GetChainRandomness(ctx context.Context, blks []cid.Cid, pe
|
|||||||
searchHeight = 0
|
searchHeight = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, true)
|
randTs, err := cs.GetTipsetByHeight(ctx, searchHeight, ts, lookback)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -1608,12 +1624,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) {
|
func (cr *chainRand) GetChainRandomnessLookingBack(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||||
return cr.cs.GetChainRandomness(ctx, cr.blks, pers, round, entropy)
|
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) {
|
func (cr *chainRand) GetChainRandomnessLookingForward(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
|
||||||
return cr.cs.GetBeaconRandomness(ctx, cr.blks, pers, round, entropy)
|
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) {
|
func (cs *ChainStore) GetTipSetFromKey(tsk types.TipSetKey) (*types.TipSet, error) {
|
||||||
|
@ -76,7 +76,7 @@ func BenchmarkGetRandomness(b *testing.B) {
|
|||||||
b.ResetTimer()
|
b.ResetTimer()
|
||||||
|
|
||||||
for i := 0; i < b.N; i++ {
|
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 {
|
if err != nil {
|
||||||
b.Fatal(err)
|
b.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"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"
|
"github.com/ipfs/go-cid"
|
||||||
|
|
||||||
ds "github.com/ipfs/go-datastore"
|
ds "github.com/ipfs/go-datastore"
|
||||||
@ -101,7 +107,7 @@ func prepSyncTest(t testing.TB, h int) *syncTestUtil {
|
|||||||
g: g,
|
g: g,
|
||||||
}
|
}
|
||||||
|
|
||||||
tu.addSourceNode(h)
|
tu.addSourceNode(stmgr.DefaultUpgradeSchedule(), h)
|
||||||
//tu.checkHeight("source", source, h)
|
//tu.checkHeight("source", source, h)
|
||||||
|
|
||||||
// separate logs
|
// separate logs
|
||||||
@ -110,6 +116,53 @@ func prepSyncTest(t testing.TB, h int) *syncTestUtil {
|
|||||||
return tu
|
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() {
|
func (tu *syncTestUtil) Shutdown() {
|
||||||
tu.cancel()
|
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 {
|
if miners == nil {
|
||||||
for i := range tu.g.Miners {
|
for i := range tu.g.Miners {
|
||||||
miners = append(miners, i)
|
miners = append(miners, i)
|
||||||
@ -191,10 +244,10 @@ func (tu *syncTestUtil) mineOnBlock(blk *store.FullTipSet, to int, miners []int,
|
|||||||
var nts *store.FullTipSet
|
var nts *store.FullTipSet
|
||||||
var err error
|
var err error
|
||||||
if msgs != nil {
|
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)
|
require.NoError(tu.t, err)
|
||||||
} else {
|
} else {
|
||||||
mt, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs)
|
mt, err := tu.g.NextTipSetFromMiners(blk.TipSet(), maddrs, nulls)
|
||||||
require.NoError(tu.t, err)
|
require.NoError(tu.t, err)
|
||||||
nts = mt.TipSet
|
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) {
|
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
|
tu.g.CurTipset = mts
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tu *syncTestUtil) addSourceNode(gen int) {
|
func (tu *syncTestUtil) addSourceNode(us stmgr.UpgradeSchedule, gen int) {
|
||||||
if tu.genesis != nil {
|
if tu.genesis != nil {
|
||||||
tu.t.Fatal("source node already exists")
|
tu.t.Fatal("source node already exists")
|
||||||
}
|
}
|
||||||
@ -229,6 +282,7 @@ func (tu *syncTestUtil) addSourceNode(gen int) {
|
|||||||
node.Test(),
|
node.Test(),
|
||||||
|
|
||||||
node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)),
|
node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)),
|
||||||
|
node.Override(new(stmgr.UpgradeSchedule), us),
|
||||||
)
|
)
|
||||||
require.NoError(tu.t, err)
|
require.NoError(tu.t, err)
|
||||||
tu.t.Cleanup(func() { _ = stop(context.Background()) })
|
tu.t.Cleanup(func() { _ = stop(context.Background()) })
|
||||||
@ -442,7 +496,7 @@ func TestSyncBadTimestamp(t *testing.T) {
|
|||||||
fmt.Println("BASE: ", base.Cids())
|
fmt.Println("BASE: ", base.Cids())
|
||||||
tu.printHeads()
|
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
|
tu.g.Timestamper = nil
|
||||||
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
||||||
@ -451,7 +505,7 @@ func TestSyncBadTimestamp(t *testing.T) {
|
|||||||
|
|
||||||
fmt.Println("After mine bad block!")
|
fmt.Println("After mine bad block!")
|
||||||
tu.printHeads()
|
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)
|
tu.waitUntilSync(0, client)
|
||||||
|
|
||||||
@ -495,7 +549,7 @@ func TestSyncBadWinningPoSt(t *testing.T) {
|
|||||||
tu.g.SetWinningPoStProver(tu.g.Miners[1], &badWpp{})
|
tu.g.SetWinningPoStProver(tu.g.Miners[1], &badWpp{})
|
||||||
|
|
||||||
// now ensure that new blocks are not accepted
|
// 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) {
|
func (tu *syncTestUtil) loadChainToNode(to int) {
|
||||||
@ -540,16 +594,16 @@ func TestSyncFork(t *testing.T) {
|
|||||||
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
||||||
|
|
||||||
// The two nodes fork at this point into 'a' and 'b'
|
// The two nodes fork at this point into 'a' and 'b'
|
||||||
a1 := tu.mineOnBlock(base, 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)
|
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0)
|
||||||
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
|
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0)
|
||||||
|
|
||||||
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
||||||
// chain B will now be heaviest
|
// chain B will now be heaviest
|
||||||
b := tu.mineOnBlock(base, 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)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
|
|
||||||
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
||||||
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
||||||
@ -611,13 +665,13 @@ func TestDuplicateNonce(t *testing.T) {
|
|||||||
msgs[k] = []*types.SignedMessage{makeMsg(tu.g.Miners[k])}
|
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())
|
tu.waitUntilSyncTarget(0, ts1.TipSet())
|
||||||
|
|
||||||
// mine another 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())
|
tu.waitUntilSyncTarget(0, ts2.TipSet())
|
||||||
|
|
||||||
var includedMsg cid.Cid
|
var includedMsg cid.Cid
|
||||||
@ -668,11 +722,15 @@ func TestBadNonce(t *testing.T) {
|
|||||||
|
|
||||||
base := tu.g.CurTipset
|
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
|
// Produce a message from the banker with a bad nonce
|
||||||
makeBadMsg := func() *types.SignedMessage {
|
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{
|
msg := types.Message{
|
||||||
To: tu.g.Banker(),
|
To: tu.g.Banker(),
|
||||||
From: tu.g.Banker(),
|
From: tu.g.Banker(),
|
||||||
@ -700,7 +758,7 @@ func TestBadNonce(t *testing.T) {
|
|||||||
msgs := make([][]*types.SignedMessage, 1)
|
msgs := make([][]*types.SignedMessage, 1)
|
||||||
msgs[0] = []*types.SignedMessage{makeBadMsg()}
|
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) {
|
func BenchmarkSyncBasic(b *testing.B) {
|
||||||
@ -765,19 +823,19 @@ func TestSyncCheckpointHead(t *testing.T) {
|
|||||||
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
||||||
|
|
||||||
// The two nodes fork at this point into 'a' and 'b'
|
// The two nodes fork at this point into 'a' and 'b'
|
||||||
a1 := tu.mineOnBlock(base, 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)
|
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0)
|
||||||
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
|
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0)
|
||||||
|
|
||||||
tu.waitUntilSyncTarget(p1, a.TipSet())
|
tu.waitUntilSyncTarget(p1, a.TipSet())
|
||||||
tu.checkpointTs(p1, a.TipSet().Key())
|
tu.checkpointTs(p1, a.TipSet().Key())
|
||||||
|
|
||||||
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
||||||
// chain B will now be heaviest
|
// chain B will now be heaviest
|
||||||
b := tu.mineOnBlock(base, 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)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
|
|
||||||
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
||||||
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
||||||
@ -807,19 +865,19 @@ func TestSyncCheckpointEarlierThanHead(t *testing.T) {
|
|||||||
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
fmt.Println("Mining base: ", base.TipSet().Cids(), base.TipSet().Height())
|
||||||
|
|
||||||
// The two nodes fork at this point into 'a' and 'b'
|
// The two nodes fork at this point into 'a' and 'b'
|
||||||
a1 := tu.mineOnBlock(base, 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)
|
a := tu.mineOnBlock(a1, p1, []int{0}, true, false, nil, 0)
|
||||||
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil)
|
a = tu.mineOnBlock(a, p1, []int{0}, true, false, nil, 0)
|
||||||
|
|
||||||
tu.waitUntilSyncTarget(p1, a.TipSet())
|
tu.waitUntilSyncTarget(p1, a.TipSet())
|
||||||
tu.checkpointTs(p1, a1.TipSet().Key())
|
tu.checkpointTs(p1, a1.TipSet().Key())
|
||||||
|
|
||||||
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
require.NoError(t, tu.g.ResyncBankerNonce(a1.TipSet()))
|
||||||
// chain B will now be heaviest
|
// chain B will now be heaviest
|
||||||
b := tu.mineOnBlock(base, 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)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil)
|
b = tu.mineOnBlock(b, p2, []int{1}, true, false, nil, 0)
|
||||||
|
|
||||||
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
fmt.Println("A: ", a.Cids(), a.TipSet().Height())
|
||||||
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
fmt.Println("B: ", b.Cids(), b.TipSet().Height())
|
||||||
@ -833,3 +891,55 @@ func TestSyncCheckpointEarlierThanHead(t *testing.T) {
|
|||||||
require.Equal(tu.t, p1Head, a.TipSet())
|
require.Equal(tu.t, p1Head, a.TipSet())
|
||||||
tu.assertBad(p1, b.TipSet())
|
tu.assertBad(p1, b.TipSet())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDrandNull(t *testing.T) {
|
||||||
|
H := 10
|
||||||
|
v5h := abi.ChainEpoch(50)
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
@ -208,17 +208,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 {
|
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 {
|
if err != nil {
|
||||||
panic(aerrors.Fatalf("could not get randomness: %s", err))
|
panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness {
|
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 {
|
if err != nil {
|
||||||
panic(aerrors.Fatalf("could not get randomness: %s", err))
|
panic(aerrors.Fatalf("could not get beacon randomness: %s", err))
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
@ -255,8 +255,10 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Rand interface {
|
type Rand interface {
|
||||||
GetChainRandomness(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)
|
||||||
GetBeaconRandomness(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 {
|
type ApplyRet struct {
|
||||||
|
@ -19,10 +19,18 @@ func NewFixedRand() vm.Rand {
|
|||||||
return &fixedRand{}
|
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.
|
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.
|
return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes.
|
||||||
}
|
}
|
||||||
|
@ -45,8 +45,17 @@ func (r *RecordingRand) loadHead() {
|
|||||||
r.head = head.Key()
|
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)
|
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)
|
ret, err := r.api.ChainGetRandomnessFromTickets(ctx, r.head, pers, round, entropy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ret, err
|
return ret, err
|
||||||
@ -70,7 +79,15 @@ func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.Doma
|
|||||||
return ret, err
|
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)
|
r.once.Do(r.loadHead)
|
||||||
ret, err := r.api.ChainGetRandomnessFromBeacon(ctx, r.head, pers, round, entropy)
|
ret, err := r.api.ChainGetRandomnessFromBeacon(ctx, r.head, pers, round, entropy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -43,7 +43,15 @@ func (r *ReplayingRand) match(requested schema.RandomnessRule) ([]byte, bool) {
|
|||||||
return nil, false
|
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{
|
rule := schema.RandomnessRule{
|
||||||
Kind: schema.RandomnessChain,
|
Kind: schema.RandomnessChain,
|
||||||
DomainSeparationTag: int64(pers),
|
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)
|
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{
|
rule := schema.RandomnessRule{
|
||||||
Kind: schema.RandomnessBeacon,
|
Kind: schema.RandomnessBeacon,
|
||||||
DomainSeparationTag: int64(pers),
|
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)
|
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)
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/lotus/build"
|
||||||
|
|
||||||
"go.uber.org/fx"
|
"go.uber.org/fx"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
|
|
||||||
@ -95,7 +97,12 @@ func (a *ChainAPI) ChainGetRandomnessFromTickets(ctx context.Context, tsk types.
|
|||||||
return nil, xerrors.Errorf("loading tipset key: %w", err)
|
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) {
|
func (a *ChainAPI) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.TipSetKey, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) (abi.Randomness, error) {
|
||||||
@ -104,7 +111,12 @@ func (a *ChainAPI) ChainGetRandomnessFromBeacon(ctx context.Context, tsk types.T
|
|||||||
return nil, xerrors.Errorf("loading tipset key: %w", err)
|
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) {
|
func (a *ChainAPI) ChainGetBlock(ctx context.Context, msg cid.Cid) (*types.BlockHeader, error) {
|
||||||
|
Loading…
Reference in New Issue
Block a user