2020-10-07 18:52:37 +00:00
|
|
|
package conformance
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-10-07 19:12:35 +00:00
|
|
|
"fmt"
|
2020-10-07 18:52:37 +00:00
|
|
|
"sync"
|
|
|
|
|
|
|
|
"github.com/filecoin-project/go-state-types/abi"
|
2020-10-07 19:12:35 +00:00
|
|
|
"github.com/filecoin-project/test-vectors/schema"
|
|
|
|
|
2023-08-21 21:09:44 +00:00
|
|
|
"github.com/filecoin-project/lotus/api/v1api"
|
2020-10-07 18:52:37 +00:00
|
|
|
"github.com/filecoin-project/lotus/chain/types"
|
|
|
|
"github.com/filecoin-project/lotus/chain/vm"
|
|
|
|
)
|
|
|
|
|
|
|
|
type RecordingRand struct {
|
|
|
|
reporter Reporter
|
2023-08-21 21:09:44 +00:00
|
|
|
api v1api.FullNode
|
2020-10-07 18:52:37 +00:00
|
|
|
|
2020-10-07 19:12:35 +00:00
|
|
|
// once guards the loading of the head tipset.
|
|
|
|
// can be removed when https://github.com/filecoin-project/lotus/issues/4223
|
|
|
|
// is fixed.
|
|
|
|
once sync.Once
|
|
|
|
head types.TipSetKey
|
2020-10-07 18:52:37 +00:00
|
|
|
lk sync.Mutex
|
|
|
|
recorded schema.Randomness
|
|
|
|
}
|
|
|
|
|
|
|
|
var _ vm.Rand = (*RecordingRand)(nil)
|
|
|
|
|
|
|
|
// NewRecordingRand returns a vm.Rand implementation that proxies calls to a
|
|
|
|
// full Lotus node via JSON-RPC, and records matching rules and responses so
|
|
|
|
// they can later be embedded in test vectors.
|
2023-08-21 21:09:44 +00:00
|
|
|
func NewRecordingRand(reporter Reporter, api v1api.FullNode) *RecordingRand {
|
2020-10-07 18:52:37 +00:00
|
|
|
return &RecordingRand{reporter: reporter, api: api}
|
|
|
|
}
|
|
|
|
|
2020-10-07 19:12:35 +00:00
|
|
|
func (r *RecordingRand) loadHead() {
|
|
|
|
head, err := r.api.ChainHead(context.Background())
|
|
|
|
if err != nil {
|
|
|
|
panic(fmt.Sprintf("could not fetch chain head while fetching randomness: %s", err))
|
|
|
|
}
|
|
|
|
r.head = head.Key()
|
|
|
|
}
|
|
|
|
|
2023-08-21 20:26:51 +00:00
|
|
|
func (r *RecordingRand) GetChainRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
|
2020-10-07 19:12:35 +00:00
|
|
|
r.once.Do(r.loadHead)
|
2023-08-21 21:09:44 +00:00
|
|
|
// FullNode's v1 ChainGetRandomnessFromTickets handles whether we should be looking forward or back
|
|
|
|
ret, err := r.api.StateGetRandomnessDigestFromTickets(ctx, round, r.head)
|
2020-10-07 18:52:37 +00:00
|
|
|
if err != nil {
|
2023-08-21 21:09:44 +00:00
|
|
|
return [32]byte{}, err
|
2020-10-07 18:52:37 +00:00
|
|
|
}
|
|
|
|
|
2023-08-21 20:26:51 +00:00
|
|
|
r.reporter.Logf("fetched and recorded chain randomness for: epoch=%d, result=%x", round, ret)
|
2020-10-07 18:52:37 +00:00
|
|
|
|
|
|
|
match := schema.RandomnessMatch{
|
|
|
|
On: schema.RandomnessRule{
|
2023-08-21 20:26:51 +00:00
|
|
|
Kind: schema.RandomnessChain,
|
|
|
|
Epoch: int64(round),
|
2020-10-07 18:52:37 +00:00
|
|
|
},
|
|
|
|
Return: []byte(ret),
|
|
|
|
}
|
|
|
|
r.lk.Lock()
|
|
|
|
r.recorded = append(r.recorded, match)
|
|
|
|
r.lk.Unlock()
|
|
|
|
|
2023-08-21 21:09:44 +00:00
|
|
|
return *(*[32]byte)(ret), err
|
2020-10-07 18:52:37 +00:00
|
|
|
}
|
|
|
|
|
2023-08-21 20:26:51 +00:00
|
|
|
func (r *RecordingRand) GetBeaconRandomness(ctx context.Context, round abi.ChainEpoch) ([32]byte, error) {
|
2020-10-07 19:12:35 +00:00
|
|
|
r.once.Do(r.loadHead)
|
2023-08-21 21:09:44 +00:00
|
|
|
ret, err := r.api.StateGetRandomnessDigestFromBeacon(ctx, round, r.head)
|
2020-10-07 18:52:37 +00:00
|
|
|
if err != nil {
|
2023-08-21 21:09:44 +00:00
|
|
|
return [32]byte{}, err
|
2020-10-07 18:52:37 +00:00
|
|
|
}
|
|
|
|
|
2023-08-21 20:26:51 +00:00
|
|
|
r.reporter.Logf("fetched and recorded beacon randomness for: epoch=%d, result=%x", round, ret)
|
2020-10-07 18:52:37 +00:00
|
|
|
|
|
|
|
match := schema.RandomnessMatch{
|
|
|
|
On: schema.RandomnessRule{
|
2023-08-21 20:26:51 +00:00
|
|
|
Kind: schema.RandomnessBeacon,
|
|
|
|
Epoch: int64(round),
|
2020-10-07 18:52:37 +00:00
|
|
|
},
|
|
|
|
Return: []byte(ret),
|
|
|
|
}
|
|
|
|
r.lk.Lock()
|
|
|
|
r.recorded = append(r.recorded, match)
|
|
|
|
r.lk.Unlock()
|
|
|
|
|
2023-08-21 21:09:44 +00:00
|
|
|
return *(*[32]byte)(ret), err
|
2020-10-07 18:52:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (r *RecordingRand) Recorded() schema.Randomness {
|
|
|
|
r.lk.Lock()
|
|
|
|
defer r.lk.Unlock()
|
|
|
|
|
|
|
|
return r.recorded
|
|
|
|
}
|