Fix calculation of Drand round from Filecoin epochs
This commit is contained in:
parent
8323ff77b6
commit
6924a3d5f2
@ -171,14 +171,6 @@ type FullNode interface {
|
|||||||
// ChainBlockstoreInfo returns some basic information about the blockstore
|
// ChainBlockstoreInfo returns some basic information about the blockstore
|
||||||
ChainBlockstoreInfo(context.Context) (map[string]interface{}, error) //perm:read
|
ChainBlockstoreInfo(context.Context) (map[string]interface{}, error) //perm:read
|
||||||
|
|
||||||
// MethodGroup: Beacon
|
|
||||||
// The Beacon method group contains methods for interacting with the random beacon (DRAND)
|
|
||||||
|
|
||||||
// BeaconGetEntry returns the beacon entry for the given filecoin epoch. If
|
|
||||||
// the entry has not yet been produced, the call will block until the entry
|
|
||||||
// becomes available
|
|
||||||
BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) //perm:read
|
|
||||||
|
|
||||||
// GasEstimateFeeCap estimates gas fee cap
|
// GasEstimateFeeCap estimates gas fee cap
|
||||||
GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) //perm:read
|
GasEstimateFeeCap(context.Context, *types.Message, int64, types.TipSetKey) (types.BigInt, error) //perm:read
|
||||||
|
|
||||||
@ -591,6 +583,11 @@ type FullNode interface {
|
|||||||
// StateGetRandomnessFromBeacon is used to sample the beacon for randomness.
|
// StateGetRandomnessFromBeacon is used to sample the beacon for randomness.
|
||||||
StateGetRandomnessFromBeacon(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) //perm:read
|
StateGetRandomnessFromBeacon(ctx context.Context, personalization crypto.DomainSeparationTag, randEpoch abi.ChainEpoch, entropy []byte, tsk types.TipSetKey) (abi.Randomness, error) //perm:read
|
||||||
|
|
||||||
|
// StateGetBeaconEntry returns the beacon entry for the given filecoin epoch. If
|
||||||
|
// the entry has not yet been produced, the call will block until the entry
|
||||||
|
// becomes available
|
||||||
|
StateGetBeaconEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) //perm:read
|
||||||
|
|
||||||
// MethodGroup: Msig
|
// MethodGroup: Msig
|
||||||
// The Msig methods are used to interact with multisig wallets on the
|
// The Msig methods are used to interact with multisig wallets on the
|
||||||
// filecoin network
|
// filecoin network
|
||||||
|
@ -91,21 +91,6 @@ func (mr *MockFullNodeMockRecorder) AuthVerify(arg0, arg1 interface{}) *gomock.C
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthVerify", reflect.TypeOf((*MockFullNode)(nil).AuthVerify), arg0, arg1)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthVerify", reflect.TypeOf((*MockFullNode)(nil).AuthVerify), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BeaconGetEntry mocks base method.
|
|
||||||
func (m *MockFullNode) BeaconGetEntry(arg0 context.Context, arg1 abi.ChainEpoch) (*types.BeaconEntry, error) {
|
|
||||||
m.ctrl.T.Helper()
|
|
||||||
ret := m.ctrl.Call(m, "BeaconGetEntry", arg0, arg1)
|
|
||||||
ret0, _ := ret[0].(*types.BeaconEntry)
|
|
||||||
ret1, _ := ret[1].(error)
|
|
||||||
return ret0, ret1
|
|
||||||
}
|
|
||||||
|
|
||||||
// BeaconGetEntry indicates an expected call of BeaconGetEntry.
|
|
||||||
func (mr *MockFullNodeMockRecorder) BeaconGetEntry(arg0, arg1 interface{}) *gomock.Call {
|
|
||||||
mr.mock.ctrl.T.Helper()
|
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BeaconGetEntry", reflect.TypeOf((*MockFullNode)(nil).BeaconGetEntry), arg0, arg1)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ChainBlockstoreInfo mocks base method.
|
// ChainBlockstoreInfo mocks base method.
|
||||||
func (m *MockFullNode) ChainBlockstoreInfo(arg0 context.Context) (map[string]interface{}, error) {
|
func (m *MockFullNode) ChainBlockstoreInfo(arg0 context.Context) (map[string]interface{}, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
@ -2406,6 +2391,21 @@ func (mr *MockFullNodeMockRecorder) StateGetActor(arg0, arg1, arg2 interface{})
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetActor", reflect.TypeOf((*MockFullNode)(nil).StateGetActor), arg0, arg1, arg2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StateGetBeaconEntry mocks base method.
|
||||||
|
func (m *MockFullNode) StateGetBeaconEntry(arg0 context.Context, arg1 abi.ChainEpoch) (*types.BeaconEntry, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
ret := m.ctrl.Call(m, "StateGetBeaconEntry", arg0, arg1)
|
||||||
|
ret0, _ := ret[0].(*types.BeaconEntry)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// StateGetBeaconEntry indicates an expected call of StateGetBeaconEntry.
|
||||||
|
func (mr *MockFullNodeMockRecorder) StateGetBeaconEntry(arg0, arg1 interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StateGetBeaconEntry", reflect.TypeOf((*MockFullNode)(nil).StateGetBeaconEntry), arg0, arg1)
|
||||||
|
}
|
||||||
|
|
||||||
// StateGetRandomnessFromBeacon mocks base method.
|
// StateGetRandomnessFromBeacon mocks base method.
|
||||||
func (m *MockFullNode) StateGetRandomnessFromBeacon(arg0 context.Context, arg1 crypto.DomainSeparationTag, arg2 abi.ChainEpoch, arg3 []byte, arg4 types.TipSetKey) (abi.Randomness, error) {
|
func (m *MockFullNode) StateGetRandomnessFromBeacon(arg0 context.Context, arg1 crypto.DomainSeparationTag, arg2 abi.ChainEpoch, arg3 []byte, arg4 types.TipSetKey) (abi.Randomness, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -103,8 +103,6 @@ type FullNodeStruct struct {
|
|||||||
NetStruct
|
NetStruct
|
||||||
|
|
||||||
Internal struct {
|
Internal struct {
|
||||||
BeaconGetEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
|
|
||||||
|
|
||||||
ChainBlockstoreInfo func(p0 context.Context) (map[string]interface{}, error) `perm:"read"`
|
ChainBlockstoreInfo func(p0 context.Context) (map[string]interface{}, error) `perm:"read"`
|
||||||
|
|
||||||
ChainCheckBlockstore func(p0 context.Context) error `perm:"admin"`
|
ChainCheckBlockstore func(p0 context.Context) error `perm:"admin"`
|
||||||
@ -353,6 +351,8 @@ type FullNodeStruct struct {
|
|||||||
|
|
||||||
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
StateGetActor func(p0 context.Context, p1 address.Address, p2 types.TipSetKey) (*types.Actor, error) `perm:"read"`
|
||||||
|
|
||||||
|
StateGetBeaconEntry func(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) `perm:"read"`
|
||||||
|
|
||||||
StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
|
StateGetRandomnessFromBeacon func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
|
||||||
|
|
||||||
StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
|
StateGetRandomnessFromTickets func(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) `perm:"read"`
|
||||||
@ -1088,17 +1088,6 @@ func (s *CommonStub) Version(p0 context.Context) (APIVersion, error) {
|
|||||||
return *new(APIVersion), ErrNotSupported
|
return *new(APIVersion), ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) {
|
|
||||||
if s.Internal.BeaconGetEntry == nil {
|
|
||||||
return nil, ErrNotSupported
|
|
||||||
}
|
|
||||||
return s.Internal.BeaconGetEntry(p0, p1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *FullNodeStub) BeaconGetEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) {
|
|
||||||
return nil, ErrNotSupported
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *FullNodeStruct) ChainBlockstoreInfo(p0 context.Context) (map[string]interface{}, error) {
|
func (s *FullNodeStruct) ChainBlockstoreInfo(p0 context.Context) (map[string]interface{}, error) {
|
||||||
if s.Internal.ChainBlockstoreInfo == nil {
|
if s.Internal.ChainBlockstoreInfo == nil {
|
||||||
return *new(map[string]interface{}), ErrNotSupported
|
return *new(map[string]interface{}), ErrNotSupported
|
||||||
@ -2463,6 +2452,17 @@ func (s *FullNodeStub) StateGetActor(p0 context.Context, p1 address.Address, p2
|
|||||||
return nil, ErrNotSupported
|
return nil, ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStruct) StateGetBeaconEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) {
|
||||||
|
if s.Internal.StateGetBeaconEntry == nil {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
return s.Internal.StateGetBeaconEntry(p0, p1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *FullNodeStub) StateGetBeaconEntry(p0 context.Context, p1 abi.ChainEpoch) (*types.BeaconEntry, error) {
|
||||||
|
return nil, ErrNotSupported
|
||||||
|
}
|
||||||
|
|
||||||
func (s *FullNodeStruct) StateGetRandomnessFromBeacon(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) {
|
func (s *FullNodeStruct) StateGetRandomnessFromBeacon(p0 context.Context, p1 crypto.DomainSeparationTag, p2 abi.ChainEpoch, p3 []byte, p4 types.TipSetKey) (abi.Randomness, error) {
|
||||||
if s.Internal.StateGetRandomnessFromBeacon == nil {
|
if s.Internal.StateGetRandomnessFromBeacon == nil {
|
||||||
return *new(abi.Randomness), ErrNotSupported
|
return *new(abi.Randomness), ErrNotSupported
|
||||||
|
@ -352,4 +352,8 @@ func (w *WrapperV1Full) ClientQueryAsk(ctx context.Context, p peer.ID, miner add
|
|||||||
return a.Response, nil
|
return a.Response, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (w *WrapperV1Full) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) {
|
||||||
|
return w.StateGetBeaconEntry(ctx, epoch)
|
||||||
|
}
|
||||||
|
|
||||||
var _ FullNode = &WrapperV1Full{}
|
var _ FullNode = &WrapperV1Full{}
|
||||||
|
Binary file not shown.
@ -3,6 +3,8 @@ package beacon
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
logging "github.com/ipfs/go-log/v2"
|
logging "github.com/ipfs/go-log/v2"
|
||||||
"golang.org/x/xerrors"
|
"golang.org/x/xerrors"
|
||||||
@ -42,10 +44,10 @@ type BeaconPoint struct {
|
|||||||
type RandomBeacon interface {
|
type RandomBeacon interface {
|
||||||
Entry(context.Context, uint64) <-chan Response
|
Entry(context.Context, uint64) <-chan Response
|
||||||
VerifyEntry(types.BeaconEntry, types.BeaconEntry) error
|
VerifyEntry(types.BeaconEntry, types.BeaconEntry) error
|
||||||
MaxBeaconRoundForEpoch(abi.ChainEpoch) uint64
|
MaxBeaconRoundForEpoch(network.Version, abi.ChainEpoch) uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
func ValidateBlockValues(bSchedule Schedule, h *types.BlockHeader, parentEpoch abi.ChainEpoch,
|
func ValidateBlockValues(bSchedule Schedule, nv network.Version, h *types.BlockHeader, parentEpoch abi.ChainEpoch,
|
||||||
prevEntry types.BeaconEntry) error {
|
prevEntry types.BeaconEntry) error {
|
||||||
{
|
{
|
||||||
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
||||||
@ -65,7 +67,7 @@ func ValidateBlockValues(bSchedule Schedule, h *types.BlockHeader, parentEpoch a
|
|||||||
|
|
||||||
// TODO: fork logic
|
// TODO: fork logic
|
||||||
b := bSchedule.BeaconForEpoch(h.Height)
|
b := bSchedule.BeaconForEpoch(h.Height)
|
||||||
maxRound := b.MaxBeaconRoundForEpoch(h.Height)
|
maxRound := b.MaxBeaconRoundForEpoch(nv, h.Height)
|
||||||
if maxRound == prevEntry.Round {
|
if maxRound == prevEntry.Round {
|
||||||
if len(h.BeaconEntries) != 0 {
|
if len(h.BeaconEntries) != 0 {
|
||||||
return xerrors.Errorf("expected not to have any beacon entries in this block, got %d", len(h.BeaconEntries))
|
return xerrors.Errorf("expected not to have any beacon entries in this block, got %d", len(h.BeaconEntries))
|
||||||
@ -92,13 +94,13 @@ func ValidateBlockValues(bSchedule Schedule, h *types.BlockHeader, parentEpoch a
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, epoch abi.ChainEpoch, parentEpoch abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) {
|
func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, nv network.Version, epoch abi.ChainEpoch, parentEpoch abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) {
|
||||||
{
|
{
|
||||||
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
parentBeacon := bSchedule.BeaconForEpoch(parentEpoch)
|
||||||
currBeacon := bSchedule.BeaconForEpoch(epoch)
|
currBeacon := bSchedule.BeaconForEpoch(epoch)
|
||||||
if parentBeacon != currBeacon {
|
if parentBeacon != currBeacon {
|
||||||
// Fork logic
|
// Fork logic
|
||||||
round := currBeacon.MaxBeaconRoundForEpoch(epoch)
|
round := currBeacon.MaxBeaconRoundForEpoch(nv, epoch)
|
||||||
out := make([]types.BeaconEntry, 2)
|
out := make([]types.BeaconEntry, 2)
|
||||||
rch := currBeacon.Entry(ctx, round-1)
|
rch := currBeacon.Entry(ctx, round-1)
|
||||||
res := <-rch
|
res := <-rch
|
||||||
@ -120,7 +122,7 @@ func BeaconEntriesForBlock(ctx context.Context, bSchedule Schedule, epoch abi.Ch
|
|||||||
|
|
||||||
start := build.Clock.Now()
|
start := build.Clock.Now()
|
||||||
|
|
||||||
maxRound := beacon.MaxBeaconRoundForEpoch(epoch)
|
maxRound := beacon.MaxBeaconRoundForEpoch(nv, epoch)
|
||||||
if maxRound == prev.Round {
|
if maxRound == prev.Round {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
dchain "github.com/drand/drand/chain"
|
dchain "github.com/drand/drand/chain"
|
||||||
dclient "github.com/drand/drand/client"
|
dclient "github.com/drand/drand/client"
|
||||||
hclient "github.com/drand/drand/client/http"
|
hclient "github.com/drand/drand/client/http"
|
||||||
@ -201,11 +203,32 @@ func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntr
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DrandBeacon) MaxBeaconRoundForEpoch(filEpoch abi.ChainEpoch) uint64 {
|
func (db *DrandBeacon) MaxBeaconRoundForEpoch(nv network.Version, filEpoch abi.ChainEpoch) uint64 {
|
||||||
// TODO: sometimes the genesis time for filecoin is zero and this goes negative
|
// TODO: sometimes the genesis time for filecoin is zero and this goes negative
|
||||||
latestTs := ((uint64(filEpoch) * db.filRoundTime) + db.filGenTime) - db.filRoundTime
|
latestTs := ((uint64(filEpoch) * db.filRoundTime) + db.filGenTime) - db.filRoundTime
|
||||||
|
|
||||||
|
if nv <= network.Version15 {
|
||||||
|
return db.maxBeaconRoundV1(latestTs)
|
||||||
|
}
|
||||||
|
|
||||||
|
return db.maxBeaconRoundV2(latestTs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DrandBeacon) maxBeaconRoundV1(latestTs uint64) uint64 {
|
||||||
dround := (latestTs - db.drandGenTime) / uint64(db.interval.Seconds())
|
dround := (latestTs - db.drandGenTime) / uint64(db.interval.Seconds())
|
||||||
return dround
|
return dround
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DrandBeacon) maxBeaconRoundV2(latestTs uint64) uint64 {
|
||||||
|
if latestTs < db.drandGenTime {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fromGenesis := latestTs - db.drandGenTime
|
||||||
|
// we take the time from genesis divided by the periods in seconds, that
|
||||||
|
// gives us the number of periods since genesis. We also add +1 because
|
||||||
|
// round 1 starts at genesis time.
|
||||||
|
return fromGenesis/uint64(db.interval.Seconds()) + 1
|
||||||
|
}
|
||||||
|
|
||||||
var _ beacon.RandomBeacon = (*DrandBeacon)(nil)
|
var _ beacon.RandomBeacon = (*DrandBeacon)(nil)
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
dchain "github.com/drand/drand/chain"
|
dchain "github.com/drand/drand/chain"
|
||||||
hclient "github.com/drand/drand/client/http"
|
hclient "github.com/drand/drand/client/http"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -25,3 +27,12 @@ func TestPrintGroupInfo(t *testing.T) {
|
|||||||
err = chain.ToJSON(os.Stdout)
|
err = chain.ToJSON(os.Stdout)
|
||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMaxBeaconRoundForEpoch(t *testing.T) {
|
||||||
|
todayTs := uint64(1652222222)
|
||||||
|
db, err := NewDrandBeacon(todayTs, build.BlockDelaySecs, nil, build.DrandConfigs[build.DrandDevnet])
|
||||||
|
assert.NoError(t, err)
|
||||||
|
mbr15 := db.MaxBeaconRoundForEpoch(network.Version15, 100)
|
||||||
|
mbr16 := db.MaxBeaconRoundForEpoch(network.Version16, 100)
|
||||||
|
assert.Equal(t, mbr15+1, mbr16)
|
||||||
|
}
|
||||||
|
@ -6,6 +6,8 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/filecoin-project/go-state-types/network"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
"github.com/filecoin-project/go-state-types/abi"
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
"github.com/filecoin-project/lotus/chain/types"
|
||||||
"github.com/minio/blake2b-simd"
|
"github.com/minio/blake2b-simd"
|
||||||
@ -53,7 +55,7 @@ func (mb *mockBeacon) VerifyEntry(from types.BeaconEntry, to types.BeaconEntry)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mb *mockBeacon) MaxBeaconRoundForEpoch(epoch abi.ChainEpoch) uint64 {
|
func (mb *mockBeacon) MaxBeaconRoundForEpoch(nv network.Version, epoch abi.ChainEpoch) uint64 {
|
||||||
// offset for better testing
|
// offset for better testing
|
||||||
return uint64(epoch + 100)
|
return uint64(epoch + 100)
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,8 @@ func (filec *FilecoinEC) ValidateBlock(ctx context.Context, b *types.FullBlock)
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := beacon.ValidateBlockValues(filec.beacon, h, baseTs.Height(), *prevBeacon); err != nil {
|
nv := filec.sm.GetNetworkVersion(ctx, h.Height)
|
||||||
|
if err := beacon.ValidateBlockValues(filec.beacon, nv, h, baseTs.Height(), *prevBeacon); err != nil {
|
||||||
return xerrors.Errorf("failed to validate blocks random beacon values: %w", err)
|
return xerrors.Errorf("failed to validate blocks random beacon values: %w", err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@ -488,7 +489,7 @@ func (filec *FilecoinEC) checkBlockMessages(ctx context.Context, b *types.FullBl
|
|||||||
// Phase 2: (Partial) semantic validation:
|
// Phase 2: (Partial) semantic validation:
|
||||||
// the sender exists and is an account actor, and the nonces make sense
|
// the sender exists and is an account actor, and the nonces make sense
|
||||||
var sender address.Address
|
var sender address.Address
|
||||||
if filec.sm.GetNetworkVersion(ctx, b.Header.Height) >= network.Version13 {
|
if nv >= network.Version13 {
|
||||||
sender, err = st.LookupID(m.From)
|
sender, err = st.LookupID(m.From)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("failed to lookup sender %s: %w", m.From, err)
|
return xerrors.Errorf("failed to lookup sender %s: %w", m.From, err)
|
||||||
|
@ -198,7 +198,9 @@ func (sr *stateRand) extractBeaconEntryForEpoch(ctx context.Context, filecoinEpo
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
round := sr.beacon.BeaconForEpoch(filecoinEpoch).MaxBeaconRoundForEpoch(filecoinEpoch)
|
nv := sr.networkVersionGetter(ctx, filecoinEpoch)
|
||||||
|
|
||||||
|
round := sr.beacon.BeaconForEpoch(filecoinEpoch).MaxBeaconRoundForEpoch(nv, filecoinEpoch)
|
||||||
|
|
||||||
for i := 0; i < 20; i++ {
|
for i := 0; i < 20; i++ {
|
||||||
cbe := randTs.Blocks()[0].BeaconEntries
|
cbe := randTs.Blocks()[0].BeaconEntries
|
||||||
|
@ -317,7 +317,7 @@ func MinerGetBaseInfo(ctx context.Context, sm *StateManager, bcs beacon.Schedule
|
|||||||
prev = &types.BeaconEntry{}
|
prev = &types.BeaconEntry{}
|
||||||
}
|
}
|
||||||
|
|
||||||
entries, err := beacon.BeaconEntriesForBlock(ctx, bcs, round, ts.Height(), *prev)
|
entries, err := beacon.BeaconEntriesForBlock(ctx, bcs, sm.GetNetworkVersion(ctx, round), round, ts.Height(), *prev)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -8,8 +8,6 @@
|
|||||||
* [Auth](#Auth)
|
* [Auth](#Auth)
|
||||||
* [AuthNew](#AuthNew)
|
* [AuthNew](#AuthNew)
|
||||||
* [AuthVerify](#AuthVerify)
|
* [AuthVerify](#AuthVerify)
|
||||||
* [Beacon](#Beacon)
|
|
||||||
* [BeaconGetEntry](#BeaconGetEntry)
|
|
||||||
* [Chain](#Chain)
|
* [Chain](#Chain)
|
||||||
* [ChainBlockstoreInfo](#ChainBlockstoreInfo)
|
* [ChainBlockstoreInfo](#ChainBlockstoreInfo)
|
||||||
* [ChainCheckBlockstore](#ChainCheckBlockstore)
|
* [ChainCheckBlockstore](#ChainCheckBlockstore)
|
||||||
@ -175,6 +173,7 @@
|
|||||||
* [StateDecodeParams](#StateDecodeParams)
|
* [StateDecodeParams](#StateDecodeParams)
|
||||||
* [StateEncodeParams](#StateEncodeParams)
|
* [StateEncodeParams](#StateEncodeParams)
|
||||||
* [StateGetActor](#StateGetActor)
|
* [StateGetActor](#StateGetActor)
|
||||||
|
* [StateGetBeaconEntry](#StateGetBeaconEntry)
|
||||||
* [StateGetRandomnessFromBeacon](#StateGetRandomnessFromBeacon)
|
* [StateGetRandomnessFromBeacon](#StateGetRandomnessFromBeacon)
|
||||||
* [StateGetRandomnessFromTickets](#StateGetRandomnessFromTickets)
|
* [StateGetRandomnessFromTickets](#StateGetRandomnessFromTickets)
|
||||||
* [StateListActors](#StateListActors)
|
* [StateListActors](#StateListActors)
|
||||||
@ -340,33 +339,6 @@ Response:
|
|||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
## Beacon
|
|
||||||
The Beacon method group contains methods for interacting with the random beacon (DRAND)
|
|
||||||
|
|
||||||
|
|
||||||
### BeaconGetEntry
|
|
||||||
BeaconGetEntry returns the beacon entry for the given filecoin epoch. If
|
|
||||||
the entry has not yet been produced, the call will block until the entry
|
|
||||||
becomes available
|
|
||||||
|
|
||||||
|
|
||||||
Perms: read
|
|
||||||
|
|
||||||
Inputs:
|
|
||||||
```json
|
|
||||||
[
|
|
||||||
10101
|
|
||||||
]
|
|
||||||
```
|
|
||||||
|
|
||||||
Response:
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"Round": 42,
|
|
||||||
"Data": "Ynl0ZSBhcnJheQ=="
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Chain
|
## Chain
|
||||||
The Chain method group contains methods for interacting with the
|
The Chain method group contains methods for interacting with the
|
||||||
blockchain, but that do not require any form of state computation.
|
blockchain, but that do not require any form of state computation.
|
||||||
@ -5641,6 +5613,29 @@ Response:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### StateGetBeaconEntry
|
||||||
|
StateGetBeaconEntry returns the beacon entry for the given filecoin epoch. If
|
||||||
|
the entry has not yet been produced, the call will block until the entry
|
||||||
|
becomes available
|
||||||
|
|
||||||
|
|
||||||
|
Perms: read
|
||||||
|
|
||||||
|
Inputs:
|
||||||
|
```json
|
||||||
|
[
|
||||||
|
10101
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
Response:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Round": 42,
|
||||||
|
"Data": "Ynl0ZSBhcnJheQ=="
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### StateGetRandomnessFromBeacon
|
### StateGetRandomnessFromBeacon
|
||||||
StateGetRandomnessFromBeacon is used to sample the beacon for randomness.
|
StateGetRandomnessFromBeacon is used to sample the beacon for randomness.
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ minerLoop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// just wait for the beacon entry to become available before we select our final mining base
|
// just wait for the beacon entry to become available before we select our final mining base
|
||||||
_, err = m.api.BeaconGetEntry(ctx, prebase.TipSet.Height()+prebase.NullRounds+1)
|
_, err = m.api.StateGetBeaconEntry(ctx, prebase.TipSet.Height()+prebase.NullRounds+1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("failed getting beacon entry: %s", err)
|
log.Errorf("failed getting beacon entry: %s", err)
|
||||||
if !m.niceSleep(time.Second) {
|
if !m.niceSleep(time.Second) {
|
||||||
|
@ -35,7 +35,6 @@ type FullNodeAPI struct {
|
|||||||
full.MsigAPI
|
full.MsigAPI
|
||||||
full.WalletAPI
|
full.WalletAPI
|
||||||
full.SyncAPI
|
full.SyncAPI
|
||||||
full.BeaconAPI
|
|
||||||
|
|
||||||
DS dtypes.MetadataDS
|
DS dtypes.MetadataDS
|
||||||
NetworkName dtypes.NetworkName
|
NetworkName dtypes.NetworkName
|
||||||
|
@ -1,36 +0,0 @@
|
|||||||
package full
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/go-state-types/abi"
|
|
||||||
"github.com/filecoin-project/lotus/chain/beacon"
|
|
||||||
"github.com/filecoin-project/lotus/chain/types"
|
|
||||||
"go.uber.org/fx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type BeaconAPI struct {
|
|
||||||
fx.In
|
|
||||||
|
|
||||||
Beacon beacon.Schedule
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *BeaconAPI) BeaconGetEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) {
|
|
||||||
b := a.Beacon.BeaconForEpoch(epoch)
|
|
||||||
rr := b.MaxBeaconRoundForEpoch(epoch)
|
|
||||||
e := b.Entry(ctx, rr)
|
|
||||||
|
|
||||||
select {
|
|
||||||
case be, ok := <-e:
|
|
||||||
if !ok {
|
|
||||||
return nil, fmt.Errorf("beacon get returned no value")
|
|
||||||
}
|
|
||||||
if be.Err != nil {
|
|
||||||
return nil, be.Err
|
|
||||||
}
|
|
||||||
return &be.Entry, nil
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil, ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/libp2p/go-libp2p-core/peer"
|
"github.com/libp2p/go-libp2p-core/peer"
|
||||||
@ -1457,3 +1458,22 @@ func (a *StateAPI) StateGetRandomnessFromBeacon(ctx context.Context, personaliza
|
|||||||
return a.StateManager.GetRandomnessFromBeacon(ctx, personalization, randEpoch, entropy, tsk)
|
return a.StateManager.GetRandomnessFromBeacon(ctx, personalization, randEpoch, entropy, tsk)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *StateAPI) StateGetBeaconEntry(ctx context.Context, epoch abi.ChainEpoch) (*types.BeaconEntry, error) {
|
||||||
|
b := a.Beacon.BeaconForEpoch(epoch)
|
||||||
|
rr := b.MaxBeaconRoundForEpoch(a.StateManager.GetNetworkVersion(ctx, epoch), epoch)
|
||||||
|
e := b.Entry(ctx, rr)
|
||||||
|
|
||||||
|
select {
|
||||||
|
case be, ok := <-e:
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("beacon get returned no value")
|
||||||
|
}
|
||||||
|
if be.Err != nil {
|
||||||
|
return nil, be.Err
|
||||||
|
}
|
||||||
|
return &be.Entry, nil
|
||||||
|
case <-ctx.Done():
|
||||||
|
return nil, ctx.Err()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user