diff --git a/chain/beacon/beacon.go b/chain/beacon/beacon.go index ccd71c6b4..4838e1a98 100644 --- a/chain/beacon/beacon.go +++ b/chain/beacon/beacon.go @@ -1,17 +1,13 @@ package beacon import ( - "bytes" "context" - "encoding/binary" "time" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/abi" logging "github.com/ipfs/go-log" "golang.org/x/xerrors" - - "github.com/minio/blake2b-simd" ) var log = logging.Logger("beacon") @@ -21,17 +17,13 @@ type Response struct { Err error } -type DrandBeacon interface { - //RoundTime() uint64 - //StartTime() uint64 - LastEntry() (types.BeaconEntry, error) +type RandomBeacon interface { Entry(context.Context, uint64) <-chan Response VerifyEntry(types.BeaconEntry, types.BeaconEntry) error MaxBeaconRoundForEpoch(abi.ChainEpoch, types.BeaconEntry) uint64 - IsEntryForEpoch(e types.BeaconEntry, epoch abi.ChainEpoch, nulls int) (bool, error) } -func ValidateBlockValues(b DrandBeacon, h *types.BlockHeader, prevEntry types.BeaconEntry) error { +func ValidateBlockValues(b RandomBeacon, h *types.BlockHeader, prevEntry types.BeaconEntry) error { maxRound := b.MaxBeaconRoundForEpoch(h.Height, prevEntry) if maxRound == prevEntry.Round { if len(h.BeaconEntries) != 0 { @@ -55,7 +47,7 @@ func ValidateBlockValues(b DrandBeacon, h *types.BlockHeader, prevEntry types.Be return nil } -func BeaconEntriesForBlock(ctx context.Context, beacon DrandBeacon, round abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) { +func BeaconEntriesForBlock(ctx context.Context, beacon RandomBeacon, round abi.ChainEpoch, prev types.BeaconEntry) ([]types.BeaconEntry, error) { start := time.Now() maxRound := beacon.MaxBeaconRoundForEpoch(round, prev) @@ -90,58 +82,3 @@ func reverse(arr []types.BeaconEntry) { arr[i], arr[len(arr)-(1+i)] = arr[len(arr)-(1+i)], arr[i] } } - -// Mock beacon assumes that filecoin rounds are 1:1 mapped with the beacon rounds -type mockBeacon struct { - interval time.Duration -} - -func NewMockBeacon(interval time.Duration) DrandBeacon { - mb := &mockBeacon{interval: interval} - - return mb -} - -func (mb *mockBeacon) RoundTime() time.Duration { - return mb.interval -} - -func (mb *mockBeacon) LastEntry() (types.BeaconEntry, error) { - panic("NYI") -} - -func (mb *mockBeacon) entryForIndex(index uint64) types.BeaconEntry { - buf := make([]byte, 8) - binary.BigEndian.PutUint64(buf, index) - rval := blake2b.Sum256(buf) - return types.BeaconEntry{ - Round: index, - Data: rval[:], - } -} - -func (mb *mockBeacon) Entry(ctx context.Context, index uint64) <-chan Response { - e := mb.entryForIndex(index) - out := make(chan Response, 1) - out <- Response{Entry: e} - return out -} - -func (mb *mockBeacon) VerifyEntry(from types.BeaconEntry, to types.BeaconEntry) error { - // TODO: cache this, especially for bls - oe := mb.entryForIndex(from.Round) - if !bytes.Equal(from.Data, oe.Data) { - return xerrors.Errorf("mock beacon entry was invalid!") - } - return nil -} - -func (mb *mockBeacon) IsEntryForEpoch(e types.BeaconEntry, epoch abi.ChainEpoch, nulls int) (bool, error) { - return int64(e.Round) <= int64(epoch) && int64(epoch)-int64(nulls) >= int64(e.Round), nil -} - -func (mb *mockBeacon) MaxBeaconRoundForEpoch(epoch abi.ChainEpoch, prevEntry types.BeaconEntry) uint64 { - return uint64(epoch) -} - -var _ DrandBeacon = (*mockBeacon)(nil) diff --git a/chain/beacon/mock.go b/chain/beacon/mock.go new file mode 100644 index 000000000..4dcda2e8b --- /dev/null +++ b/chain/beacon/mock.go @@ -0,0 +1,68 @@ +package beacon + +import ( + "bytes" + "context" + "encoding/binary" + "time" + + "github.com/filecoin-project/lotus/chain/types" + "github.com/filecoin-project/specs-actors/actors/abi" + "github.com/minio/blake2b-simd" + "golang.org/x/xerrors" +) + +// Mock beacon assumes that filecoin rounds are 1:1 mapped with the beacon rounds +type mockBeacon struct { + interval time.Duration +} + +func NewMockBeacon(interval time.Duration) RandomBeacon { + mb := &mockBeacon{interval: interval} + + return mb +} + +func (mb *mockBeacon) RoundTime() time.Duration { + return mb.interval +} + +func (mb *mockBeacon) LastEntry() (types.BeaconEntry, error) { + panic("NYI") +} + +func (mb *mockBeacon) entryForIndex(index uint64) types.BeaconEntry { + buf := make([]byte, 8) + binary.BigEndian.PutUint64(buf, index) + rval := blake2b.Sum256(buf) + return types.BeaconEntry{ + Round: index, + Data: rval[:], + } +} + +func (mb *mockBeacon) Entry(ctx context.Context, index uint64) <-chan Response { + e := mb.entryForIndex(index) + out := make(chan Response, 1) + out <- Response{Entry: e} + return out +} + +func (mb *mockBeacon) VerifyEntry(from types.BeaconEntry, to types.BeaconEntry) error { + // TODO: cache this, especially for bls + oe := mb.entryForIndex(from.Round) + if !bytes.Equal(from.Data, oe.Data) { + return xerrors.Errorf("mock beacon entry was invalid!") + } + return nil +} + +func (mb *mockBeacon) IsEntryForEpoch(e types.BeaconEntry, epoch abi.ChainEpoch, nulls int) (bool, error) { + return int64(e.Round) <= int64(epoch) && int64(epoch)-int64(nulls) >= int64(e.Round), nil +} + +func (mb *mockBeacon) MaxBeaconRoundForEpoch(epoch abi.ChainEpoch, prevEntry types.BeaconEntry) uint64 { + return uint64(epoch) +} + +var _ RandomBeacon = (*mockBeacon)(nil) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 84d1bbd13..9436c1e3c 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -52,7 +52,7 @@ type ChainGen struct { cs *store.ChainStore - beacon beacon.DrandBeacon + beacon beacon.RandomBeacon sm *stmgr.StateManager diff --git a/chain/sync.go b/chain/sync.go index b9e682d29..cff29a050 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -54,7 +54,7 @@ type Syncer struct { store *store.ChainStore // handle to the random beacon for verification - beacon beacon.DrandBeacon + beacon beacon.RandomBeacon // the state manager handles making state queries sm *stmgr.StateManager @@ -79,7 +79,7 @@ type Syncer struct { receiptTracker *blockReceiptTracker } -func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.DrandBeacon) (*Syncer, error) { +func NewSyncer(sm *stmgr.StateManager, bsync *blocksync.BlockSync, connmgr connmgr.ConnManager, self peer.ID, beacon beacon.RandomBeacon) (*Syncer, error) { gen, err := sm.ChainStore().GetGenesis() if err != nil { return nil, err diff --git a/miner/miner.go b/miner/miner.go index 3377d57d0..dc2b8d5dd 100644 --- a/miner/miner.go +++ b/miner/miner.go @@ -27,7 +27,7 @@ var log = logging.Logger("miner") type waitFunc func(ctx context.Context, baseTime uint64) error -func NewMiner(api api.FullNode, epp gen.ElectionPoStProver, beacon beacon.DrandBeacon) *Miner { +func NewMiner(api api.FullNode, epp gen.ElectionPoStProver, beacon beacon.RandomBeacon) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) @@ -52,7 +52,7 @@ type Miner struct { api api.FullNode epp gen.ElectionPoStProver - beacon beacon.DrandBeacon + beacon beacon.RandomBeacon lk sync.Mutex addresses []address.Address diff --git a/node/builder.go b/node/builder.go index f6f1a83bf..5c840aa3c 100644 --- a/node/builder.go +++ b/node/builder.go @@ -256,7 +256,7 @@ func Online() Option { Override(new(storagemarket.StorageClientNode), storageadapter.NewClientNodeAdapter), Override(RegisterClientValidatorKey, modules.RegisterClientValidator), Override(RunDealClientKey, modules.RunDealClient), - Override(new(beacon.DrandBeacon), modules.RandomBeacon), + Override(new(beacon.RandomBeacon), modules.RandomBeacon), Override(new(*paychmgr.Store), paychmgr.NewStore), Override(new(*paychmgr.Manager), paychmgr.NewManager), diff --git a/node/modules/chain.go b/node/modules/chain.go index f0d87df37..fee18ea30 100644 --- a/node/modules/chain.go +++ b/node/modules/chain.go @@ -142,7 +142,7 @@ func NetworkName(mctx helpers.MetricsCtx, lc fx.Lifecycle, cs *store.ChainStore, return netName, err } -func NewSyncer(lc fx.Lifecycle, sm *stmgr.StateManager, bsync *blocksync.BlockSync, h host.Host, beacon beacon.DrandBeacon) (*chain.Syncer, error) { +func NewSyncer(lc fx.Lifecycle, sm *stmgr.StateManager, bsync *blocksync.BlockSync, h host.Host, beacon beacon.RandomBeacon) (*chain.Syncer, error) { syncer, err := chain.NewSyncer(sm, bsync, h.ConnManager(), h.ID(), beacon) if err != nil { return nil, err diff --git a/node/modules/services.go b/node/modules/services.go index 2160a3b50..774c0a6fe 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -2,7 +2,6 @@ package modules import ( "context" - "fmt" "time" eventbus "github.com/libp2p/go-eventbus" @@ -118,7 +117,6 @@ func RetrievalResolver(l *discovery.Local) retrievalmarket.PeerResolver { return discovery.Multi(l) } -func RandomBeacon() beacon.DrandBeacon { - fmt.Println("RANDOM BEACON!") +func RandomBeacon() beacon.RandomBeacon { return beacon.NewMockBeacon(build.BlockDelay * time.Second) } diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 9d3fb7333..0b041e5ae 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -258,7 +258,7 @@ func StagingGraphsync(mctx helpers.MetricsCtx, lc fx.Lifecycle, ibs dtypes.Stagi return gs } -func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.ElectionPoStProver, beacon beacon.DrandBeacon) (*miner.Miner, error) { +func SetupBlockProducer(lc fx.Lifecycle, ds dtypes.MetadataDS, api lapi.FullNode, epp gen.ElectionPoStProver, beacon beacon.RandomBeacon) (*miner.Miner, error) { minerAddr, err := minerAddrFromDS(ds) if err != nil { return nil, err