From 7cfcaf0f8f7595b68edd767bac31f5330cca2210 Mon Sep 17 00:00:00 2001 From: Aayush Date: Sun, 18 Dec 2022 14:14:50 -0500 Subject: [PATCH] Refactor: Rand: return randomness base without hashing --- chain/gen/genesis/miners.go | 6 ++- chain/rand/rand.go | 73 ++++++++++++++++++++++++------------- chain/stmgr/stmgr.go | 4 +- chain/vm/runtime.go | 26 ++++++++++--- chain/vm/vm.go | 6 --- chain/vm/vmi.go | 7 ++++ 6 files changed, 81 insertions(+), 41 deletions(-) diff --git a/chain/gen/genesis/miners.go b/chain/gen/genesis/miners.go index c083f4fda..ebbe16326 100644 --- a/chain/gen/genesis/miners.go +++ b/chain/gen/genesis/miners.go @@ -590,16 +590,18 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sys vm.Syscal return c, nil } +var _ vm.Rand = new(fakeRand) + // 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) GetChainRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([]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) GetBeaconRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([]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 c35280ab5..dce4231e2 100644 --- a/chain/rand/rand.go +++ b/chain/rand/rand.go @@ -17,7 +17,6 @@ import ( "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/types" - "github.com/filecoin-project/lotus/chain/vm" ) var log = logging.Logger("rand") @@ -70,7 +69,7 @@ func (sr *stateRand) GetBeaconRandomnessTipset(ctx context.Context, round abi.Ch return randTs, nil } -func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte, lookback bool) ([]byte, error) { +func (sr *stateRand) getChainRandomness(ctx context.Context, round abi.ChainEpoch, lookback bool) ([]byte, error) { _, span := trace.StartSpan(ctx, "store.GetChainRandomness") defer span.End() span.AddAttributes(trace.Int64Attribute("round", int64(round))) @@ -94,11 +93,7 @@ func (sr *stateRand) getChainRandomness(ctx context.Context, pers crypto.DomainS return nil, err } - mtb := randTs.MinTicketBlock() - - // if at (or just past -- for null epochs) appropriate epoch - // or at genesis (works for negative epochs) - return DrawRandomness(mtb.Ticket.VRFProof, pers, round, entropy) + return randTs.MinTicketBlock().Ticket.VRFProof, nil } type NetworkVersionGetter func(context.Context, abi.ChainEpoch) network.Version @@ -110,7 +105,7 @@ type stateRand struct { networkVersionGetter NetworkVersionGetter } -func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, networkVersionGetter NetworkVersionGetter) vm.Rand { +func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, networkVersionGetter NetworkVersionGetter) *stateRand { return &stateRand{ cs: cs, blks: blks, @@ -120,7 +115,7 @@ func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, netwo } // network v0-12 -func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, round abi.ChainEpoch) ([]byte, error) { randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, true) if err != nil { return nil, err @@ -131,13 +126,11 @@ func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, pers crypto.Doma return nil, err } - // if at (or just past -- for null epochs) appropriate epoch - // or at genesis (works for negative epochs) - return DrawRandomness(be.Data, pers, round, entropy) + return be.Data, nil } // network v13 -func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, round abi.ChainEpoch) ([]byte, error) { randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, false) if err != nil { return nil, err @@ -148,15 +141,13 @@ func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, pers crypto.Doma return nil, err } - // if at (or just past -- for null epochs) appropriate epoch - // or at genesis (works for negative epochs) - return DrawRandomness(be.Data, pers, round, entropy) + return be.Data, nil } // network v14 and on -func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([]byte, error) { if filecoinEpoch < 0 { - return sr.getBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy) + return sr.getBeaconRandomnessV2(ctx, filecoinEpoch) } be, err := sr.extractBeaconEntryForEpoch(ctx, filecoinEpoch) @@ -165,31 +156,61 @@ func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, pers crypto.Doma return nil, err } - return DrawRandomness(be.Data, pers, filecoinEpoch, entropy) + return be.Data, nil } -func (sr *stateRand) GetChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (sr *stateRand) GetChainRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([]byte, error) { nv := sr.networkVersionGetter(ctx, filecoinEpoch) if nv >= network.Version13 { - return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, false) + return sr.getChainRandomness(ctx, filecoinEpoch, false) } - return sr.getChainRandomness(ctx, pers, filecoinEpoch, entropy, true) + return sr.getChainRandomness(ctx, filecoinEpoch, true) } -func (sr *stateRand) GetBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { +func (sr *stateRand) GetBeaconRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([]byte, error) { nv := sr.networkVersionGetter(ctx, filecoinEpoch) if nv >= network.Version14 { - return sr.getBeaconRandomnessV3(ctx, pers, filecoinEpoch, entropy) + return sr.getBeaconRandomnessV3(ctx, filecoinEpoch) } else if nv == network.Version13 { - return sr.getBeaconRandomnessV2(ctx, pers, filecoinEpoch, entropy) + return sr.getBeaconRandomnessV2(ctx, filecoinEpoch) } else { - return sr.getBeaconRandomnessV1(ctx, pers, filecoinEpoch, entropy) + return sr.getBeaconRandomnessV1(ctx, filecoinEpoch) } } +func (sr *stateRand) DrawChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { + rbase, err := sr.GetChainRandomness(ctx, filecoinEpoch) + + if err != nil { + return nil, xerrors.Errorf("failed to get chain randomness: %w", err) + } + + ret, err := DrawRandomness(rbase, pers, filecoinEpoch, entropy) + if err != nil { + return nil, xerrors.Errorf("failed to draw chain randomness: %w", err) + } + + return ret, nil +} + +func (sr *stateRand) DrawBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { + rbase, err := sr.GetBeaconRandomness(ctx, filecoinEpoch) + + if err != nil { + return nil, xerrors.Errorf("failed to get chain randomness: %w", err) + } + + ret, err := DrawRandomness(rbase, pers, filecoinEpoch, entropy) + if err != nil { + return nil, xerrors.Errorf("failed to draw chain randomness: %w", err) + } + + return ret, nil +} + func (sr *stateRand) extractBeaconEntryForEpoch(ctx context.Context, filecoinEpoch abi.ChainEpoch) (*types.BeaconEntry, error) { randTs, err := sr.GetBeaconRandomnessTipset(ctx, filecoinEpoch, false) if err != nil { diff --git a/chain/stmgr/stmgr.go b/chain/stmgr/stmgr.go index 12b991e57..d7ac71d66 100644 --- a/chain/stmgr/stmgr.go +++ b/chain/stmgr/stmgr.go @@ -509,7 +509,7 @@ func (sm *StateManager) GetRandomnessFromBeacon(ctx context.Context, personaliza r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion) - return r.GetBeaconRandomness(ctx, personalization, randEpoch, entropy) + return r.DrawBeaconRandomness(ctx, personalization, randEpoch, entropy) } @@ -521,5 +521,5 @@ func (sm *StateManager) GetRandomnessFromTickets(ctx context.Context, personaliz r := rand.NewStateRand(sm.ChainStore(), pts.Cids(), sm.beacon, sm.GetNetworkVersion) - return r.GetChainRandomness(ctx, personalization, randEpoch, entropy) + return r.DrawChainRandomness(ctx, personalization, randEpoch, entropy) } diff --git a/chain/vm/runtime.go b/chain/vm/runtime.go index a5b108238..f647918e9 100644 --- a/chain/vm/runtime.go +++ b/chain/vm/runtime.go @@ -8,6 +8,8 @@ import ( "os" "time" + "github.com/filecoin-project/lotus/chain/rand" + "github.com/ipfs/go-cid" ipldcbor "github.com/ipfs/go-ipld-cbor" "go.opencensus.io/trace" @@ -229,21 +231,35 @@ 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) + randomnessBase, err := rt.vm.rand.GetChainRandomness(rt.ctx, randEpoch) if err != nil { panic(aerrors.Fatalf("could not get ticket randomness: %s", err)) } - return res + + ret, err := rand.DrawRandomness(randomnessBase, personalization, randEpoch, entropy) + + if err != nil { + panic(aerrors.Fatalf("could not draw ticket randomness: %s", err)) + } + + return ret } 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) + randomnessBase, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, randEpoch) if err != nil { - panic(aerrors.Fatalf("could not get beacon randomness: %s", err)) + panic(aerrors.Fatalf("could not get ticket randomness: %s", err)) } - return res + + ret, err := rand.DrawRandomness(randomnessBase, personalization, randEpoch, entropy) + + if err != nil { + panic(aerrors.Fatalf("could not draw ticket randomness: %s", err)) + } + + return ret } func (rt *Runtime) NewActorAddress() address.Address { diff --git a/chain/vm/vm.go b/chain/vm/vm.go index 58afc14bc..6bea6cebf 100644 --- a/chain/vm/vm.go +++ b/chain/vm/vm.go @@ -21,7 +21,6 @@ import ( "github.com/filecoin-project/go-state-types/abi" "github.com/filecoin-project/go-state-types/big" builtin_types "github.com/filecoin-project/go-state-types/builtin" - "github.com/filecoin-project/go-state-types/crypto" "github.com/filecoin-project/go-state-types/exitcode" "github.com/filecoin-project/go-state-types/network" @@ -287,11 +286,6 @@ func NewLegacyVM(ctx context.Context, opts *VMOpts) (*LegacyVM, error) { }, nil } -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) -} - type ApplyRet struct { types.MessageReceipt ActorErr aerrors.ActorError diff --git a/chain/vm/vmi.go b/chain/vm/vmi.go index 042621ca2..749d38d44 100644 --- a/chain/vm/vmi.go +++ b/chain/vm/vmi.go @@ -5,6 +5,8 @@ import ( "fmt" "os" + "github.com/filecoin-project/go-state-types/abi" + cid "github.com/ipfs/go-cid" "github.com/filecoin-project/go-state-types/network" @@ -68,3 +70,8 @@ func NewVM(ctx context.Context, opts *VMOpts) (Interface, error) { return newVMExecutor(vmi, opts.ExecutionLane), nil } + +type Rand interface { + GetChainRandomness(ctx context.Context, round abi.ChainEpoch) ([]byte, error) + GetBeaconRandomness(ctx context.Context, round abi.ChainEpoch) ([]byte, error) +}