From 6f6f5d79fbccab1d6e34bf563c0bc9b8ae4b2830 Mon Sep 17 00:00:00 2001 From: Aayush Rajasekaran Date: Fri, 17 Dec 2021 18:54:17 -0500 Subject: [PATCH] Refactor: State: Let Rand get network versions --- chain/consensus/filcns/compute_state.go | 2 +- chain/gen/genesis/miners.go | 4 +-- chain/rand/rand.go | 26 ++++++++++++------- chain/stmgr/call.go | 4 +-- chain/stmgr/stmgr.go | 10 +++---- chain/stmgr/utils.go | 2 +- chain/vm/runtime.go | 6 ++--- chain/vm/vm.go | 4 +-- .../simulation/blockbuilder/blockbuilder.go | 2 +- conformance/rand_fixed.go | 6 ++--- conformance/rand_record.go | 6 ++--- conformance/rand_replay.go | 10 +++---- 12 files changed, 40 insertions(+), 42 deletions(-) diff --git a/chain/consensus/filcns/compute_state.go b/chain/consensus/filcns/compute_state.go index 6a25e6df287..ba4cc0335dd 100644 --- a/chain/consensus/filcns/compute_state.go +++ b/chain/consensus/filcns/compute_state.go @@ -299,7 +299,7 @@ func (t *TipSetExecutor) ExecuteTipSet(ctx context.Context, sm *stmgr.StateManag parentEpoch = parent.Height } - r := rand.NewStateRand(sm.ChainStore(), ts.Cids(), sm.Beacon()) + r := rand.NewStateRand(sm.ChainStore(), ts.Cids(), sm.Beacon(), sm.GetNetworkVersion) blkmsgs, err := sm.ChainStore().BlockMsgsForTipset(ctx, ts) if err != nil { diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index a688a032420..101f1d3b509 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -510,13 +510,13 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal // TODO: copied from actors test harness, deduplicate or remove from here type fakeRand struct{} -func (fr *fakeRand) GetChainRandomness(ctx context.Context, rnv network.Version, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (fr *fakeRand) GetChainRandomness(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, rnv network.Version, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (fr *fakeRand) GetBeaconRandomness(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 diff --git a/chain/rand/rand.go b/chain/rand/rand.go index 6a54a2427bf..427648f2a85 100644 --- a/chain/rand/rand.go +++ b/chain/rand/rand.go @@ -103,17 +103,21 @@ func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainS return DrawRandomness(mtb.Ticket.VRFProof, pers, round, entropy) } +type NetworkVersionGetter func(context.Context, abi.ChainEpoch) network.Version + type stateRand struct { - cs *store.ChainStore - blks []cid.Cid - beacon beacon.Schedule + cs *store.ChainStore + blks []cid.Cid + beacon beacon.Schedule + networkVersionGetter NetworkVersionGetter } -func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule) vm.Rand { +func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, networkVersionGetter NetworkVersionGetter) vm.Rand { return &stateRand{ - cs: cs, - blks: blks, - beacon: b, + cs: cs, + blks: blks, + beacon: b, + networkVersionGetter: networkVersionGetter, } } @@ -166,7 +170,9 @@ func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, pers crypto.Doma return DrawRandomness(be.Data, pers, filecoinEpoch, entropy) } -func (sr *stateRand) GetChainRandomness(ctx context.Context, nv network.Version, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (sr *stateRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { + nv := sr.networkVersionGetter(ctx, filecoinEpoch) + if nv >= network.Version13 { return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, false) } @@ -174,7 +180,9 @@ func (sr *stateRand) GetChainRandomness(ctx context.Context, nv network.Version, return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, true) } -func (sr *stateRand) GetBeaconRandomness(ctx context.Context, nv network.Version, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (sr *stateRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { + nv := sr.networkVersionGetter(ctx, filecoinEpoch) + if nv >= network.Version14 { return sr.getBeaconRandomnessV3(ctx, pers, filecoinEpoch, entropy) } else if nv == network.Version13 { diff --git a/chain/stmgr/call.go b/chain/stmgr/call.go index 2d5d64ae786..7f76628e826 100644 --- a/chain/stmgr/call.go +++ b/chain/stmgr/call.go @@ -75,7 +75,7 @@ func (sm *StateManager) Call(ctx context.Context, msg *types.Message, ts *types. vmopt := &vm.VMOpts{ StateBase: bstate, Epoch: pheight + 1, - Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon), + Rand: rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion), Bstore: sm.cs.StateBlockstore(), Actors: sm.tsExec.NewActorRegistry(), Syscalls: sm.Syscalls, @@ -186,7 +186,7 @@ func (sm *StateManager) CallWithGas(ctx context.Context, msg *types.Message, pri return nil, fmt.Errorf("failed to handle fork: %w", err) } - r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon) + r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion) if span.IsRecordingEvents() { span.AddAttributes( diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index b19dd62c46b..fd3558a1cf4 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -377,10 +377,9 @@ func (sm *StateManager) GetRandomnessFromBeacon(ctx context.Context, personaliza return nil, xerrors.Errorf("loading tipset %s: %w", tsk, err) } - r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon) - rnv := sm.GetNetworkVersion(ctx, randEpoch) + r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion) - return r.GetBeaconRandomness(ctx, rnv, personalization, randEpoch, entropy) + return r.GetBeaconRandomness(ctx, personalization, randEpoch, entropy) } @@ -390,8 +389,7 @@ func (sm *StateManager) GetRandomnessFromTickets(ctx context.Context, personaliz return nil, xerrors.Errorf("loading tipset key: %w", err) } - r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon) - rnv := sm.GetNetworkVersion(ctx, randEpoch) + r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion) - return r.GetChainRandomness(ctx, rnv, personalization, randEpoch, entropy) + return r.GetChainRandomness(ctx, personalization, randEpoch, entropy) } diff --git a/chain/stmgr/utils.go b/chain/stmgr/utils.go index 5f23ce630ba..698ffc13f66 100644 --- a/chain/stmgr/utils.go +++ b/chain/stmgr/utils.go @@ -79,7 +79,7 @@ func ComputeState(ctx context.Context, sm *StateManager, height abi.ChainEpoch, // future. It's not guaranteed to be accurate... but that's fine. } - r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon) + r := rand.NewStateRand(sm.cs, ts.Cids(), sm.beacon, sm.GetNetworkVersion) vmopt := &vm.VMOpts{ StateBase: base, Epoch: height, diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index 9bbed403093..844f5d2539e 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -224,8 +224,7 @@ 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 { - rnv := rt.vm.ntwkVersion(rt.ctx, randEpoch) - res, err := rt.vm.rand.GetChainRandomness(rt.ctx, rnv, personalization, randEpoch, entropy) + res, err := rt.vm.rand.GetChainRandomness(rt.ctx, personalization, randEpoch, entropy) if err != nil { panic(aerrors.Fatalf("could not get ticket randomness: %s", err)) @@ -234,8 +233,7 @@ func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparat } func (rt *Runtime) GetRandomnessFromBeacon(personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte) abi.Randomness { - rnv := rt.vm.ntwkVersion(rt.ctx, randEpoch) - res, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, rnv, personalization, randEpoch, entropy) + res, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, personalization, randEpoch, entropy) if err != nil { panic(aerrors.Fatalf("could not get beacon randomness: %s", err)) diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 4536460309f..c0b730774de 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -260,8 +260,8 @@ func NewVM(ctx context.Context, opts *VMOpts) (*VM, error) { } type Rand interface { - GetChainRandomness(ctx context.Context, nv network.Version, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) - GetBeaconRandomness(ctx context.Context, nv network.Version, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) + 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) } type ApplyRet struct { diff --git a/cmd/lotus-sim/simulation/blockbuilder/blockbuilder.go b/cmd/lotus-sim/simulation/blockbuilder/blockbuilder.go index c656a820837..360368b8222 100644 --- a/cmd/lotus-sim/simulation/blockbuilder/blockbuilder.go +++ b/cmd/lotus-sim/simulation/blockbuilder/blockbuilder.go @@ -79,7 +79,7 @@ func NewBlockBuilder(ctx context.Context, logger *zap.SugaredLogger, sm *stmgr.S // 1. We don't charge a fee. // 2. The runtime has "fake" proof logic. // 3. We don't actually save any of the results. - r := lrand.NewStateRand(sm.ChainStore(), parentTs.Cids(), sm.Beacon()) + r := lrand.NewStateRand(sm.ChainStore(), parentTs.Cids(), sm.Beacon(), sm.GetNetworkVersion) vmopt := &vm.VMOpts{ StateBase: parentState, Epoch: parentTs.Height() + 1, diff --git a/conformance/rand_fixed.go b/conformance/rand_fixed.go index 4284f98ff00..d356b53d049 100644 --- a/conformance/rand_fixed.go +++ b/conformance/rand_fixed.go @@ -3,8 +3,6 @@ package conformance import ( "context" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" @@ -21,10 +19,10 @@ func NewFixedRand() vm.Rand { return &fixedRand{} } -func (r *fixedRand) GetChainRandomness(_ context.Context, _ network.Version, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) { +func (r *fixedRand) GetChainRandomness(_ 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, _ network.Version, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) { +func (r *fixedRand) GetBeaconRandomness(_ context.Context, _ crypto.DomainSeparationTag, _ abi.ChainEpoch, _ []byte) ([]byte, error) { return []byte("i_am_random_____i_am_random_____"), nil // 32 bytes. } diff --git a/conformance/rand_record.go b/conformance/rand_record.go index f6eeaa6c98d..8422ad31d64 100644 --- a/conformance/rand_record.go +++ b/conformance/rand_record.go @@ -5,8 +5,6 @@ import ( "fmt" "sync" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" @@ -47,7 +45,7 @@ func (r *RecordingRand) loadHead() { r.head = head.Key() } -func (r *RecordingRand) GetChainRandomness(ctx context.Context, nv network.Version, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (r *RecordingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { r.once.Do(r.loadHead) // FullNode's v0 ChainGetRandomnessFromTickets handles whether we should be looking forward or back ret, err := r.api.ChainGetRandomnessFromTickets(ctx, r.head, pers, round, entropy) @@ -73,7 +71,7 @@ func (r *RecordingRand) GetChainRandomness(ctx context.Context, nv network.Versi return ret, err } -func (r *RecordingRand) GetBeaconRandomness(ctx context.Context, nv network.Version, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { +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.StateGetRandomnessFromBeacon(ctx, pers, round, entropy, r.head) if err != nil { diff --git a/conformance/rand_replay.go b/conformance/rand_replay.go index 1907ddf24d0..6c228275232 100644 --- a/conformance/rand_replay.go +++ b/conformance/rand_replay.go @@ -4,8 +4,6 @@ import ( "bytes" "context" - "github.com/filecoin-project/go-state-types/network" - "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/crypto" @@ -45,7 +43,7 @@ func (r *ReplayingRand) match(requested schema.RandomnessRule) ([]byte, bool) { return nil, false } -func (r *ReplayingRand) GetChainRandomness(ctx context.Context, nv network.Version, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (r *ReplayingRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { rule := schema.RandomnessRule{ Kind: schema.RandomnessChain, DomainSeparationTag: int64(pers), @@ -60,10 +58,10 @@ func (r *ReplayingRand) GetChainRandomness(ctx context.Context, nv network.Versi r.reporter.Logf("returning fallback chain randomness: dst=%d, epoch=%d, entropy=%x", pers, round, entropy) - return r.fallback.GetChainRandomness(ctx, nv, pers, round, entropy) + return r.fallback.GetChainRandomness(ctx, pers, round, entropy) } -func (r *ReplayingRand) GetBeaconRandomness(ctx context.Context, nv network.Version, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (r *ReplayingRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { rule := schema.RandomnessRule{ Kind: schema.RandomnessBeacon, DomainSeparationTag: int64(pers), @@ -78,5 +76,5 @@ func (r *ReplayingRand) GetBeaconRandomness(ctx context.Context, nv network.Vers r.reporter.Logf("returning fallback beacon randomness: dst=%d, epoch=%d, entropy=%x", pers, round, entropy) - return r.fallback.GetBeaconRandomness(ctx, nv, pers, round, entropy) + return r.fallback.GetBeaconRandomness(ctx, pers, round, entropy) }