Refactor: Rand: Return randomness digest to VM

This commit is contained in:
Aayush 2022-12-18 15:05:39 -05:00
parent 5ff0db9650
commit 2e9f4dc2ae
3 changed files with 35 additions and 32 deletions

View File

@ -595,16 +595,16 @@ var _ vm.Rand = new(fakeRand)
// 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, randEpoch abi.ChainEpoch) ([]byte, error) { func (fr *fakeRand) GetChainRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([32]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 *(*[32]byte)(out), nil
} }
func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([]byte, error) { func (fr *fakeRand) GetBeaconRandomness(ctx context.Context, randEpoch abi.ChainEpoch) ([32]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 *(*[32]byte)(out), nil
} }
func currentTotalPower(ctx context.Context, vm vm.Interface, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) { func currentTotalPower(ctx context.Context, vm vm.Interface, maddr address.Address) (*power0.CurrentTotalPowerReturn, error) {

View File

@ -22,12 +22,15 @@ import (
var log = logging.Logger("rand") var log = logging.Logger("rand")
func DrawRandomnessFromBase(rbase []byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { func DrawRandomnessFromBase(rbase []byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
return DrawRandomnessFromDigest(blake2b.Sum256(rbase), pers, round, entropy)
}
func DrawRandomnessFromDigest(digest [32]byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) {
h := blake2b.New256() h := blake2b.New256()
if err := binary.Write(h, binary.BigEndian, int64(pers)); err != nil { if err := binary.Write(h, binary.BigEndian, int64(pers)); err != nil {
return nil, xerrors.Errorf("deriving randomness: %w", err) return nil, xerrors.Errorf("deriving randomness: %w", err)
} }
VRFDigest := blake2b.Sum256(rbase) _, err := h.Write(digest[:])
_, err := h.Write(VRFDigest[:])
if err != nil { if err != nil {
return nil, xerrors.Errorf("hashing VRFDigest: %w", err) return nil, xerrors.Errorf("hashing VRFDigest: %w", err)
} }
@ -69,18 +72,18 @@ func (sr *stateRand) GetBeaconRandomnessTipset(ctx context.Context, round abi.Ch
return randTs, nil return randTs, nil
} }
func (sr *stateRand) getChainRandomness(ctx context.Context, round abi.ChainEpoch, lookback bool) ([]byte, error) { func (sr *stateRand) getChainRandomness(ctx context.Context, round abi.ChainEpoch, lookback bool) ([32]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)))
ts, err := sr.cs.LoadTipSet(ctx, types.NewTipSetKey(sr.blks...)) ts, err := sr.cs.LoadTipSet(ctx, types.NewTipSetKey(sr.blks...))
if err != nil { if err != nil {
return nil, err return [32]byte{}, err
} }
if round > ts.Height() { if round > ts.Height() {
return nil, xerrors.Errorf("cannot draw randomness from the future") return [32]byte{}, xerrors.Errorf("cannot draw randomness from the future")
} }
searchHeight := round searchHeight := round
@ -90,10 +93,10 @@ func (sr *stateRand) getChainRandomness(ctx context.Context, round abi.ChainEpoc
randTs, err := sr.cs.GetTipsetByHeight(ctx, searchHeight, ts, lookback) randTs, err := sr.cs.GetTipsetByHeight(ctx, searchHeight, ts, lookback)
if err != nil { if err != nil {
return nil, err return [32]byte{}, err
} }
return randTs.MinTicketBlock().Ticket.VRFProof, nil return blake2b.Sum256(randTs.MinTicketBlock().Ticket.VRFProof), nil
} }
type NetworkVersionGetter func(context.Context, abi.ChainEpoch) network.Version type NetworkVersionGetter func(context.Context, abi.ChainEpoch) network.Version
@ -115,37 +118,37 @@ func NewStateRand(cs *store.ChainStore, blks []cid.Cid, b beacon.Schedule, netwo
} }
// network v0-12 // network v0-12
func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, round abi.ChainEpoch) ([]byte, error) { func (sr *stateRand) getBeaconRandomnessV1(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, true) randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, true)
if err != nil { if err != nil {
return nil, err return [32]byte{}, err
} }
be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs) be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs)
if err != nil { if err != nil {
return nil, err return [32]byte{}, err
} }
return be.Data, nil return blake2b.Sum256(be.Data), nil
} }
// network v13 // network v13
func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, round abi.ChainEpoch) ([]byte, error) { func (sr *stateRand) getBeaconRandomnessV2(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, false) randTs, err := sr.GetBeaconRandomnessTipset(ctx, round, false)
if err != nil { if err != nil {
return nil, err return [32]byte{}, err
} }
be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs) be, err := sr.cs.GetLatestBeaconEntry(ctx, randTs)
if err != nil { if err != nil {
return nil, err return [32]byte{}, err
} }
return be.Data, nil return blake2b.Sum256(be.Data), nil
} }
// network v14 and on // network v14 and on
func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([]byte, error) { func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
if filecoinEpoch < 0 { if filecoinEpoch < 0 {
return sr.getBeaconRandomnessV2(ctx, filecoinEpoch) return sr.getBeaconRandomnessV2(ctx, filecoinEpoch)
} }
@ -153,13 +156,13 @@ func (sr *stateRand) getBeaconRandomnessV3(ctx context.Context, filecoinEpoch ab
be, err := sr.extractBeaconEntryForEpoch(ctx, filecoinEpoch) be, err := sr.extractBeaconEntryForEpoch(ctx, filecoinEpoch)
if err != nil { if err != nil {
log.Errorf("failed to get beacon entry as expected: %s", err) log.Errorf("failed to get beacon entry as expected: %s", err)
return nil, err return [32]byte{}, err
} }
return be.Data, nil return blake2b.Sum256(be.Data), nil
} }
func (sr *stateRand) GetChainRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([]byte, error) { func (sr *stateRand) GetChainRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
nv := sr.networkVersionGetter(ctx, filecoinEpoch) nv := sr.networkVersionGetter(ctx, filecoinEpoch)
if nv >= network.Version13 { if nv >= network.Version13 {
@ -169,7 +172,7 @@ func (sr *stateRand) GetChainRandomness(ctx context.Context, filecoinEpoch abi.C
return sr.getChainRandomness(ctx, filecoinEpoch, true) return sr.getChainRandomness(ctx, filecoinEpoch, true)
} }
func (sr *stateRand) GetBeaconRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([]byte, error) { func (sr *stateRand) GetBeaconRandomness(ctx context.Context, filecoinEpoch abi.ChainEpoch) ([32]byte, error) {
nv := sr.networkVersionGetter(ctx, filecoinEpoch) nv := sr.networkVersionGetter(ctx, filecoinEpoch)
if nv >= network.Version14 { if nv >= network.Version14 {
@ -182,13 +185,13 @@ func (sr *stateRand) GetBeaconRandomness(ctx context.Context, filecoinEpoch abi.
} }
func (sr *stateRand) DrawChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { func (sr *stateRand) DrawChainRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
rbase, err := sr.GetChainRandomness(ctx, filecoinEpoch) digest, err := sr.GetChainRandomness(ctx, filecoinEpoch)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get chain randomness: %w", err) return nil, xerrors.Errorf("failed to get chain randomness: %w", err)
} }
ret, err := DrawRandomnessFromBase(rbase, pers, filecoinEpoch, entropy) ret, err := DrawRandomnessFromDigest(digest, pers, filecoinEpoch, entropy)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to draw chain randomness: %w", err) return nil, xerrors.Errorf("failed to draw chain randomness: %w", err)
} }
@ -197,13 +200,13 @@ func (sr *stateRand) DrawChainRandomness(ctx context.Context, pers crypto.Domain
} }
func (sr *stateRand) DrawBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) { func (sr *stateRand) DrawBeaconRandomness(ctx context.Context, pers crypto.DomainSeparationTag, filecoinEpoch abi.ChainEpoch, entropy []byte) ([]byte, error) {
rbase, err := sr.GetBeaconRandomness(ctx, filecoinEpoch) digest, err := sr.GetBeaconRandomness(ctx, filecoinEpoch)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to get chain randomness: %w", err) return nil, xerrors.Errorf("failed to get chain randomness: %w", err)
} }
ret, err := DrawRandomnessFromBase(rbase, pers, filecoinEpoch, entropy) ret, err := DrawRandomnessFromDigest(digest, pers, filecoinEpoch, entropy)
if err != nil { if err != nil {
return nil, xerrors.Errorf("failed to draw chain randomness: %w", err) return nil, xerrors.Errorf("failed to draw chain randomness: %w", err)
} }

View File

@ -231,13 +231,13 @@ 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 {
randomnessBase, err := rt.vm.rand.GetChainRandomness(rt.ctx, randEpoch) digest, err := rt.vm.rand.GetChainRandomness(rt.ctx, randEpoch)
if err != nil { if err != nil {
panic(aerrors.Fatalf("could not get ticket randomness: %s", err)) panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
} }
ret, err := rand.DrawRandomnessFromBase(randomnessBase, personalization, randEpoch, entropy) ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
if err != nil { if err != nil {
panic(aerrors.Fatalf("could not draw ticket randomness: %s", err)) panic(aerrors.Fatalf("could not draw ticket randomness: %s", err))
@ -247,13 +247,13 @@ func (rt *Runtime) GetRandomnessFromTickets(personalization crypto.DomainSeparat
} }
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 {
randomnessBase, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, randEpoch) digest, err := rt.vm.rand.GetBeaconRandomness(rt.ctx, randEpoch)
if err != nil { if err != nil {
panic(aerrors.Fatalf("could not get ticket randomness: %s", err)) panic(aerrors.Fatalf("could not get ticket randomness: %s", err))
} }
ret, err := rand.DrawRandomnessFromBase(randomnessBase, personalization, randEpoch, entropy) ret, err := rand.DrawRandomnessFromDigest(digest, personalization, randEpoch, entropy)
if err != nil { if err != nil {
panic(aerrors.Fatalf("could not draw ticket randomness: %s", err)) panic(aerrors.Fatalf("could not draw ticket randomness: %s", err))