diff --git a/build/params_shared.go b/build/params_shared.go index 203ef4541..310333710 100644 --- a/build/params_shared.go +++ b/build/params_shared.go @@ -99,3 +99,9 @@ const BlsSignatureCacheSize = 40000 // Limits const BlockMessageLimit = 512 + +var DrandCoeffs = []string{ + "a2a34cf9a6be2f66b5385caa520364f994ae7dbac08371ffaca575dfb3e04c8e149b32dc78f077322c613a151dc07440", + "b0c5baca062191f13099229c9a229a9946204f74fc28baa212745243553ab1f50b581b2086e24374ceb40fe34bd23ca2", + "a9c6449cf647e0a0ffaf1e01277e2821213c80310165990daf77610208abfa0ce56c7e40995e26aff3873c624362ca78", +} diff --git a/chain/beacon/beacon.go b/chain/beacon/beacon.go index 4838e1a98..34405f3c8 100644 --- a/chain/beacon/beacon.go +++ b/chain/beacon/beacon.go @@ -39,7 +39,7 @@ func ValidateBlockValues(b RandomBeacon, h *types.BlockHeader, prevEntry types.B for i, e := range h.BeaconEntries { if err := b.VerifyEntry(e, prevEntry); err != nil { - return xerrors.Errorf("beacon entry %d was invalid: %w", i, err) + return xerrors.Errorf("beacon entry %d (%d - %x (%d)) was invalid: %w", i, e.Round, e.Data, len(e.Data), err) } prevEntry = e } @@ -55,6 +55,11 @@ func BeaconEntriesForBlock(ctx context.Context, beacon RandomBeacon, round abi.C return nil, nil } + // TODO: this is a sketchy way to handle the genesis block not having a beacon entry + if prev.Round == 0 { + prev.Round = maxRound - 1 + } + cur := maxRound var out []types.BeaconEntry for cur > prev.Round { diff --git a/chain/beacon/drand/drand.go b/chain/beacon/drand/drand.go index b75a51314..be231e74c 100644 --- a/chain/beacon/drand/drand.go +++ b/chain/beacon/drand/drand.go @@ -3,57 +3,200 @@ package drand import ( "context" "sync" + "time" + "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/beacon" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/specs-actors/actors/abi" + "golang.org/x/xerrors" + logging "github.com/ipfs/go-log" + + dbeacon "github.com/drand/drand/beacon" + "github.com/drand/drand/core" + dkey "github.com/drand/drand/key" dnet "github.com/drand/drand/net" dproto "github.com/drand/drand/protobuf/drand" ) -type DrandBeacon struct { - client dnet.Client +var log = logging.Logger("drand") - cacheLk sync.Mutex - localCache map[int64]types.BeaconEntry +var drandServers = []string{ + "drand-test1.nikkolasg.xyz:5001", } -func NewDrandBeacon() *DrandBeacon { - return &DrandBeacon{ - client: dnet.NewGrpcClient(), - localCache: make(map[int64]types.BeaconEntry), +var drandPubKey *dkey.DistPublic + +func init() { + drandPubKey = new(dkey.DistPublic) + err := drandPubKey.FromTOML(&dkey.DistPublicTOML{Coefficients: build.DrandCoeffs}) + if err != nil { + panic(err) } } -//func (db *DrandBeacon) +type drandPeer struct { + addr string + tls bool +} + +func (dp *drandPeer) Address() string { + return dp.addr +} + +func (dp *drandPeer) IsTLS() bool { + return dp.tls +} + +type DrandBeacon struct { + client dnet.Client + peers []dnet.Peer + + pubkey *dkey.DistPublic + + // seconds + interval time.Duration + + drandGenTime uint64 + filGenTime uint64 + filRoundTime uint64 + + cacheLk sync.Mutex + localCache map[uint64]types.BeaconEntry +} + +func NewDrandBeacon(genesisTs, interval uint64) (*DrandBeacon, error) { + if genesisTs == 0 { + panic("what are you doing this cant be zero") + } + db := &DrandBeacon{ + client: dnet.NewGrpcClient(), + localCache: make(map[uint64]types.BeaconEntry), + } + for _, ds := range drandServers { + db.peers = append(db.peers, &drandPeer{addr: ds, tls: true}) + } + + groupResp, err := db.client.Group(context.TODO(), db.peers[0], &dproto.GroupRequest{}) + if err != nil { + return nil, xerrors.Errorf("failed to get group response from beacon peer: %w", err) + } + + kgroup, err := core.ProtoToGroup(groupResp) + if err != nil { + return nil, xerrors.Errorf("failed to parse group response: %w", err) + } + + // TODO: verify these values are what we expect them to be + if !kgroup.PublicKey.Equal(drandPubKey) { + return nil, xerrors.Errorf("public key does not match") + } + // fmt.Printf("Drand Pubkey:\n%#v\n", kgroup.PublicKey.TOML()) // use to print public key + db.pubkey = drandPubKey + db.interval = kgroup.Period + db.drandGenTime = uint64(kgroup.GenesisTime) + db.filRoundTime = interval + db.filGenTime = genesisTs + + // TODO: the stream currently gives you back *all* values since drand genesis. + // Having the stream in the background is merely an optimization, so not a big deal to disable it for now + //go db.handleStreamingUpdates() + + return db, nil +} + +func (db *DrandBeacon) handleStreamingUpdates() { + for { + ch, err := db.client.PublicRandStream(context.Background(), db.peers[0], &dproto.PublicRandRequest{}) + if err != nil { + log.Warnf("failed to get public rand stream: %s", err) + log.Warnf("trying again in 10 seconds") + time.Sleep(time.Second * 10) + continue + } + + for e := range ch { + db.cacheValue(types.BeaconEntry{ + Round: e.Round, + Data: e.Signature, + }) + } + log.Warn("drand beacon stream broke, reconnecting in 10 seconds") + time.Sleep(time.Second * 10) + } +} func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.Response { // check cache, it it if there, otherwise query the endpoint - resp, err := db.client.PublicRand(nil, &dproto.PublicRandRequest{Round: round}) - - var br beacon.Response - if err != nil { - br.Err = err - } else { - br.Entry.Round = resp.GetRound() - br.Entry.Data = resp.GetSignature() + cres := db.getCachedValue(round) + if cres != nil { + out := make(chan beacon.Response, 1) + out <- beacon.Response{Entry: *cres} + close(out) + return out } out := make(chan beacon.Response, 1) - out <- br - close(out) + + go func() { + resp, err := db.client.PublicRand(ctx, db.peers[0], &dproto.PublicRandRequest{Round: round}) + + var br beacon.Response + if err != nil { + br.Err = err + } else { + br.Entry.Round = resp.GetRound() + br.Entry.Data = resp.GetSignature() + } + + out <- br + close(out) + }() return out } -func (db *DrandBeacon) VerifyEntry(types.BeaconEntry, types.BeaconEntry) error { - return nil +func (db *DrandBeacon) cacheValue(e types.BeaconEntry) { + db.cacheLk.Lock() + defer db.cacheLk.Unlock() + db.localCache[e.Round] = e } -func (db *DrandBeacon) MaxBeaconRoundForEpoch(abi.ChainEpoch, types.BeaconEntry) uint64 { - // this is just some local math - return 0 +func (db *DrandBeacon) getCachedValue(round uint64) *types.BeaconEntry { + db.cacheLk.Lock() + defer db.cacheLk.Unlock() + v, ok := db.localCache[round] + if !ok { + return nil + } + return &v +} + +func (db *DrandBeacon) VerifyEntry(curr types.BeaconEntry, prev types.BeaconEntry) error { + if prev.Round == 0 { + // TODO handle genesis better + return nil + } + b := &dbeacon.Beacon{ + PreviousRound: prev.Round, + PreviousSig: prev.Data, + Round: curr.Round, + Signature: curr.Data, + } + //log.Warnw("VerifyEntry", "beacon", b) + err := dbeacon.VerifyBeacon(db.pubkey.Key(), b) + if err == nil { + db.cacheValue(curr) + } + return err +} + +func (db *DrandBeacon) MaxBeaconRoundForEpoch(filEpoch abi.ChainEpoch, prevEntry types.BeaconEntry) uint64 { + // TODO: sometimes the genesis time for filecoin is zero and this goes negative + latestTs := ((uint64(filEpoch) * db.filRoundTime) + db.filGenTime) - db.filRoundTime + dround := (latestTs - db.drandGenTime) / uint64(db.interval.Seconds()) + return dround } var _ beacon.RandomBeacon = (*DrandBeacon)(nil) diff --git a/chain/beacon/drand/drand_test.go b/chain/beacon/drand/drand_test.go new file mode 100644 index 000000000..2055597bd --- /dev/null +++ b/chain/beacon/drand/drand_test.go @@ -0,0 +1,14 @@ +package drand + +import ( + "fmt" + "testing" +) + +func TestPrintDrandPubkey(t *testing.T) { + bc, err := NewDrandBeacon(1, 1) + if err != nil { + t.Fatal(err) + } + fmt.Printf("Drand Pubkey:\n%#v\n", bc.pubkey.TOML()) +} diff --git a/chain/beacon/mock.go b/chain/beacon/mock.go index 4dcda2e8b..dc45ae895 100644 --- a/chain/beacon/mock.go +++ b/chain/beacon/mock.go @@ -27,10 +27,6 @@ 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) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index d75215083..05083f3d7 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -188,7 +188,7 @@ func NewGenerator() (*ChainGen, error) { *genm2, }, NetworkName: "", - Timestamp: 100000, + Timestamp: uint64(time.Now().Add(-500 * build.BlockDelay * time.Second).Unix()), } genb, err := genesis2.MakeGenesisBlock(context.TODO(), bs, sys, tpl) diff --git a/chain/store/store.go b/chain/store/store.go index fc032f5f9..d076d2599 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -23,7 +23,6 @@ import ( "go.opencensus.io/stats" "go.opencensus.io/trace" "go.uber.org/multierr" - "go.uber.org/zap" amt "github.com/filecoin-project/go-amt-ipld/v2" @@ -894,7 +893,6 @@ func (cs *ChainStore) TryFillTipSet(ts *types.TipSet) (*FullTipSet, error) { } func DrawRandomness(rbase []byte, pers crypto.DomainSeparationTag, round abi.ChainEpoch, entropy []byte) ([]byte, error) { - log.Desugar().WithOptions(zap.AddCallerSkip(2)).Sugar().Warnw("DrawRandomness", "base", rbase, "dsep", pers, "round", round, "entropy", entropy) h := blake2b.New256() if err := binary.Write(h, binary.BigEndian, int64(pers)); err != nil { return nil, xerrors.Errorf("deriving randomness: %w", err) diff --git a/chain/sync.go b/chain/sync.go index f177566cc..e5d5a5ff0 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -5,6 +5,7 @@ import ( "context" "errors" "fmt" + "sort" "strings" "sync" "time" @@ -983,28 +984,24 @@ func (syncer *Syncer) collectHeaders(ctx context.Context, from *types.TipSet, to { // ensure consistency of beacon entires targetBE := from.Blocks()[0].BeaconEntries - if len(targetBE) == 0 { - syncer.bad.Add(from.Cids()[0], "no beacon entires") - return nil, xerrors.Errorf("block (%s) contained no drand entires", from.Cids()[0]) + sorted := sort.SliceIsSorted(targetBE, func(i, j int) bool { + return targetBE[i].Round < targetBE[j].Round + }) + if !sorted { + syncer.bad.Add(from.Cids()[0], "wrong order of beacon entires") + return nil, xerrors.Errorf("wrong order of beacon entires") } - cur := targetBE[0].Round - for _, e := range targetBE[1:] { - if cur >= e.Round { - syncer.bad.Add(from.Cids()[0], "wrong order of beacon entires") - return nil, xerrors.Errorf("wrong order of beacon entires") - } - - } for _, bh := range from.Blocks()[1:] { if len(targetBE) != len(bh.BeaconEntries) { // cannot mark bad, I think @Kubuxu return nil, xerrors.Errorf("tipset contained different number for beacon entires") } for i, be := range bh.BeaconEntries { - if targetBE[i].Round != be.Round || !bytes.Equal(targetBE[i].Data, be.Data) { + if targetBE[i].Round != be.Round || !bytes.Equal(targetBE[i].Data, be.Data) || + targetBE[i].PrevRound() != be.PrevRound() { // cannot mark bad, I think @Kubuxu - return nil, xerrors.Errorf("tipset contained different number for beacon entires") + return nil, xerrors.Errorf("tipset contained different beacon entires") } } diff --git a/chain/types/blockheader.go b/chain/types/blockheader.go index de96e535e..65e593a91 100644 --- a/chain/types/blockheader.go +++ b/chain/types/blockheader.go @@ -29,6 +29,20 @@ type ElectionProof struct { type BeaconEntry struct { Round uint64 Data []byte + + prevRound uint64 +} + +func NewBeaconEntry(round, prevRound uint64, data []byte) BeaconEntry { + return BeaconEntry{ + Round: round, + Data: data, + prevRound: prevRound, + } +} + +func (be *BeaconEntry) PrevRound() uint64 { + return be.prevRound } type BlockHeader struct { diff --git a/cmd/lotus-storage-miner/init.go b/cmd/lotus-storage-miner/init.go index 2ecfe8b74..e679a49fc 100644 --- a/cmd/lotus-storage-miner/init.go +++ b/cmd/lotus-storage-miner/init.go @@ -11,7 +11,6 @@ import ( "os" "path/filepath" "strconv" - "time" "github.com/docker/go-units" "github.com/google/uuid" @@ -38,7 +37,7 @@ import ( lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/actors" - "github.com/filecoin-project/lotus/chain/beacon" + "github.com/filecoin-project/lotus/chain/beacon/drand" "github.com/filecoin-project/lotus/chain/types" lcli "github.com/filecoin-project/lotus/cli" "github.com/filecoin-project/lotus/genesis" @@ -445,7 +444,15 @@ func storageMinerInit(ctx context.Context, cctx *cli.Context, api lapi.FullNode, } epp := storage.NewElectionPoStProver(smgr, dtypes.MinerID(mid)) - beacon := beacon.NewMockBeacon(build.BlockDelay * time.Second) + gen, err := api.ChainGetGenesis(ctx) + if err != nil { + return err + } + + beacon, err := drand.NewDrandBeacon(gen.Blocks()[0].Timestamp, build.BlockDelay) + if err != nil { + return err + } m := miner.NewMiner(api, epp, beacon) { diff --git a/go.mod b/go.mod index 919060f25..345379919 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/coreos/go-systemd/v22 v22.0.0 github.com/davidlazar/go-crypto v0.0.0-20190912175916-7055855a373f // indirect github.com/docker/go-units v0.4.0 - github.com/drand/drand v0.5.4 + github.com/drand/drand v0.7.2 github.com/filecoin-project/chain-validation v0.0.6-0.20200331143132-15970e639ac2 github.com/filecoin-project/filecoin-ffi v0.0.0-20200326153646-e899cc1dd072 github.com/filecoin-project/go-address v0.0.2-0.20200218010043-eb9bb40ed5be @@ -104,7 +104,7 @@ require ( go.uber.org/multierr v1.5.0 go.uber.org/zap v1.14.1 golang.org/x/net v0.0.0-20200301022130-244492dfa37a // indirect - golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d + golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 gopkg.in/urfave/cli.v2 v2.0.0-20180128182452-d3ae77c26ac8 diff --git a/go.sum b/go.sum index e31fcfdbe..8b1774503 100644 --- a/go.sum +++ b/go.sum @@ -36,8 +36,6 @@ github.com/antihax/optional v0.0.0-20180407024304-ca021399b1a6/go.mod h1:V8iCPQY github.com/apache/thrift v0.12.0 h1:pODnxUFNcjP9UTLZGTdeh+j16A8lJbRvD3rOtrk/7bs= github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/benbjohnson/clock v1.0.0 h1:78Jk/r6m4wCi6sndMpty7A//t4dw/RW5fV4ZgDVfX1w= -github.com/benbjohnson/clock v1.0.0/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 h1:xJ4a3vCFaGF/jqvzLMYoU8P317H5OQ+Via4RmuPwCS0= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= @@ -104,13 +102,13 @@ github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczC github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/drand/bls12-381 v0.0.0-20200110233355-faca855b3a67 h1:+zwFBPeS6Tx0ShngG44wyJ8wBh8ENK9upPxN2fE58Uc= -github.com/drand/bls12-381 v0.0.0-20200110233355-faca855b3a67/go.mod h1:HRtP9ULniFcAfoXvSrD5Kebk1e3/g4cvtBfjlT80PuQ= -github.com/drand/drand v0.5.4 h1:DyCkE4YHy1klVtu0YgYiYtsryyzyc0x6Y78HM2C9Mws= -github.com/drand/drand v0.5.4/go.mod h1:n9JV/s1TIL/kx/4002pct7qjilbdzScQKVu05IfHf8c= +github.com/drand/bls12-381 v0.2.0 h1:nsHrbHaz5Ys0OwAdWERn49hRSkoWUr7lwXrT+ZRLybY= +github.com/drand/bls12-381 v0.2.0/go.mod h1:dtcLgPtYT38L3NO6mPDYH0nbpc5tjPassDqiniuAt4Y= +github.com/drand/drand v0.7.2 h1:y18ZS0UgIvZVhKiib0rOYn0Gn3ZlZ8zicW20UmE3404= +github.com/drand/drand v0.7.2/go.mod h1:fsPW9+Vl3h4/6Gjjt2ZNJc+fjo1lJeqbBcG0t8MCoxo= github.com/drand/kyber v1.0.1-0.20200110225416-8de27ed8c0e2/go.mod h1:UpXoA0Upd1N9l4TvRPHr1qAUBBERj6JQ/mnKI3BPEmw= -github.com/drand/kyber v1.0.1-0.20200128205555-52819dbafde7 h1:ItV7+85W8JU5bQd/DxjT9y5Khsetlrp9CErHvDtYlE4= -github.com/drand/kyber v1.0.1-0.20200128205555-52819dbafde7/go.mod h1:Rzu9PGFt3q8d7WWdrHmR8dktHucO0dSTWlMYrgqjSpA= +github.com/drand/kyber v1.0.1-0.20200331114745-30e90cc60f99 h1:BxLbcT0yq9ii6ShXn7U+0oXB2ABfEfw6GutaVPxoj2Y= +github.com/drand/kyber v1.0.1-0.20200331114745-30e90cc60f99/go.mod h1:Rzu9PGFt3q8d7WWdrHmR8dktHucO0dSTWlMYrgqjSpA= github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= @@ -194,6 +192,7 @@ github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-ole/go-ole v1.2.4 h1:nNBDSCOigTSiarFpYE9J/KtEA1IOW4CNeqT9TQDqCxI= github.com/go-ole/go-ole v1.2.4/go.mod h1:XCwSNxSkXRo4vlyPy93sltvi/qJq0jqQhjqQNIwKuxM= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/godbus/dbus/v5 v5.0.3 h1:ZqHaoEF7TBzh4jzPmqVhE/5A1z9of6orkAe5uHoAeME= github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= @@ -215,6 +214,9 @@ github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= @@ -239,8 +241,8 @@ github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway v1.12.1 h1:zCy2xE9ablevUOrUZc3Dl72Dt+ya2FNAvC2yLYMHzi4= -github.com/grpc-ecosystem/grpc-gateway v1.12.1/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= +github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY= +github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= github.com/gxed/pubsub v0.0.0-20180201040156-26ebdf44f824/go.mod h1:OiEWyHgK+CWrmOlVquHaIK1vhpUJydC9m0Je6mhaiNE= @@ -439,6 +441,8 @@ github.com/jessevdk/go-flags v1.4.0 h1:4IU2WS7AumrZ/40jfhf4QVDMsQwqA7VEHozFRrGAR github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901 h1:rp+c0RAYOWj8l6qbCUTSiRLG/iKnW3K3/QfPPuSsBt4= github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= +github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1 h1:qBCV/RLV02TSfQa7tFmxTihnG+u+7JXByOkhlkR5rmQ= +github.com/jonboulle/clockwork v0.1.1-0.20190114141812-62fb9bc030d1/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= @@ -447,7 +451,6 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3 h1:Iy7Ifq2ysilWU4QlCx/97OoI4xT1IV7i8byT/EyIT/M= github.com/kabukky/httpscerts v0.0.0-20150320125433-617593d7dcb3/go.mod h1:BYpt4ufZiIGv2nXn4gMxnfKV306n3mWXgNu/d2TqdTU= github.com/kami-zh/go-capturer v0.0.0-20171211120116-e492ea43421d/go.mod h1:P2viExyCEfeWGU259JnaQ34Inuec4R38JCyBx2edgD0= -github.com/kilic/bls12-381 v0.0.0-20191103193557-038659eaa189/go.mod h1:INznczsRc7ASFbWFUI9GnIvpi9s2FhenKE+24rdTmBQ= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= @@ -858,10 +861,10 @@ github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpP github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli/v2 v2.0.0 h1:+HU9SCbu8GnEUFtIBfuUNXN39ofWViIEJIp6SURMpCg= github.com/urfave/cli/v2 v2.0.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= +github.com/urfave/cli/v2 v2.2.0 h1:JTTnM6wKzdA0Jqodd966MVj4vWbbquZykeX1sKbe2C4= +github.com/urfave/cli/v2 v2.2.0/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ= github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fasttemplate v1.0.1 h1:tY9CJiPnMXf1ERmG2EyK7gNUd+c6RKGD0IfU8WdUSz8= @@ -909,13 +912,16 @@ github.com/x-cray/logrus-prefixed-formatter v0.5.2 h1:00txxvfBM9muc0jiLIEAkAcIMJ github.com/x-cray/logrus-prefixed-formatter v0.5.2/go.mod h1:2duySbKsL6M18s5GU7VPsoEPHyzalCE06qoARUCeBBE= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.dedis.ch/fixbuf v1.0.3 h1:hGcV9Cd/znUxlusJ64eAlExS+5cJDIyTyEG+otu5wQs= go.dedis.ch/fixbuf v1.0.3/go.mod h1:yzJMt34Wa5xD37V5RTdmp38cz3QhMagdGoem9anUalw= go.dedis.ch/kyber/v3 v3.0.4/go.mod h1:OzvaEnPvKlyrWyp3kGXlFdp7ap1VC6RkZDTaPikqhsQ= +go.dedis.ch/kyber/v3 v3.0.9 h1:i0ZbOQocHUjfFasBiUql5zVeC7u/vahFd96DFA8UOWk= go.dedis.ch/kyber/v3 v3.0.9/go.mod h1:rhNjUUg6ahf8HEg5HUvVBYoWY4boAafX8tYxX+PS+qg= go.dedis.ch/protobuf v1.0.5/go.mod h1:eIV4wicvi6JK0q/QnfIEGeSFNG0ZeB24kzut5+HaRLo= go.dedis.ch/protobuf v1.0.7/go.mod h1:pv5ysfkDX/EawiPqcW3ikOxsL5t+BqnV6xHSmE79KI4= go.dedis.ch/protobuf v1.0.11 h1:FTYVIEzY/bfl37lu3pR4lIj+F9Vp1jE8oh91VmxKgLo= go.dedis.ch/protobuf v1.0.11/go.mod h1:97QR256dnkimeNdfmURz0wAMNVbd1VmLXhG1CrTYrJ4= +go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -973,6 +979,8 @@ golang.org/x/crypto v0.0.0-20200128174031-69ecbb4d6d5d/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6 h1:TjszyFsQsyZNHwdVdZ5m7bjmreu0znc2kRYsEml9/Ww= golang.org/x/crypto v0.0.0-20200317142112-1b76d66859c6/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200406173513-056763e48d71 h1:DOmugCavvUtnUD114C1Wh+UgTgQZ4pMLzXxi1pSt+/Y= +golang.org/x/crypto v0.0.0-20200406173513-056763e48d71/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -1052,6 +1060,8 @@ golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d h1:62ap6LNOjDU6uGmKXHJbSfciMoV+FeI1sRXx/pLDL44= golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa h1:mQTN3ECqfsViCNBgq+A40vdwhkGykrrQlYe3mPj6BoU= +golang.org/x/sys v0.0.0-20200409092240-59c9f1ba88fa/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -1097,15 +1107,15 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190927181202-20e1ac93f88c/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24 h1:wDju+RU97qa0FZT0QnZDg9Uc2dH0Ql513kFvHocz+WM= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2 h1:KlOjjpQjL4dqscfbhtQvAnRMm5PaRTchHHczffkUiq0= +google.golang.org/genproto v0.0.0-20200406120821-33397c535dc2/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= -google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1129,6 +1139,8 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/miner/testminer.go b/miner/testminer.go index 7b7d6f476..6b7a04c5c 100644 --- a/miner/testminer.go +++ b/miner/testminer.go @@ -10,16 +10,15 @@ import ( lru "github.com/hashicorp/golang-lru" ) -func NewTestMiner(nextCh <-chan struct{}, addr address.Address) func(api.FullNode, gen.ElectionPoStProver) *Miner { - return func(api api.FullNode, epp gen.ElectionPoStProver) *Miner { +func NewTestMiner(nextCh <-chan struct{}, addr address.Address) func(api.FullNode, gen.ElectionPoStProver, beacon.RandomBeacon) *Miner { + return func(api api.FullNode, epp gen.ElectionPoStProver, b beacon.RandomBeacon) *Miner { arc, err := lru.NewARC(10000) if err != nil { panic(err) } - beacon := beacon.NewMockBeacon(0) m := &Miner{ - beacon: beacon, + beacon: b, api: api, waitFunc: chanWaiter(nextCh), epp: epp, diff --git a/node/builder.go b/node/builder.go index 4b799fcf7..469daa821 100644 --- a/node/builder.go +++ b/node/builder.go @@ -283,6 +283,7 @@ func Online() Option { Override(new(sealing.TicketFn), modules.SealTicketGen), Override(new(*storage.Miner), modules.StorageMiner), Override(new(dtypes.NetworkName), modules.StorageNetworkName), + Override(new(beacon.RandomBeacon), modules.MinerRandomBeacon), Override(new(dtypes.StagingBlockstore), modules.StagingBlockstore), Override(new(dtypes.StagingDAG), modules.StagingDAG), @@ -485,5 +486,6 @@ func Test() Option { return Options( Unset(RunPeerMgrKey), Unset(new(*peermgr.PeerMgr)), + Override(new(beacon.RandomBeacon), testing.RandomBeacon), ) } diff --git a/node/modules/services.go b/node/modules/services.go index 774c0a6fe..64fca5b27 100644 --- a/node/modules/services.go +++ b/node/modules/services.go @@ -2,7 +2,6 @@ package modules import ( "context" - "time" eventbus "github.com/libp2p/go-eventbus" event "github.com/libp2p/go-libp2p-core/event" @@ -18,8 +17,10 @@ import ( "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain" "github.com/filecoin-project/lotus/chain/beacon" + "github.com/filecoin-project/lotus/chain/beacon/drand" "github.com/filecoin-project/lotus/chain/blocksync" "github.com/filecoin-project/lotus/chain/messagepool" + "github.com/filecoin-project/lotus/chain/store" "github.com/filecoin-project/lotus/chain/sub" "github.com/filecoin-project/lotus/lib/peermgr" "github.com/filecoin-project/lotus/node/hello" @@ -117,6 +118,12 @@ func RetrievalResolver(l *discovery.Local) retrievalmarket.PeerResolver { return discovery.Multi(l) } -func RandomBeacon() beacon.RandomBeacon { - return beacon.NewMockBeacon(build.BlockDelay * time.Second) +func RandomBeacon(cs *store.ChainStore, _ dtypes.AfterGenesisSet) (beacon.RandomBeacon, error) { + gen, err := cs.GetGenesis() + if err != nil { + return nil, err + } + + //return beacon.NewMockBeacon(build.BlockDelay * time.Second) + return drand.NewDrandBeacon(gen.Timestamp, build.BlockDelay) } diff --git a/node/modules/storageminer.go b/node/modules/storageminer.go index 03cd736da..a50dbfeb2 100644 --- a/node/modules/storageminer.go +++ b/node/modules/storageminer.go @@ -43,6 +43,7 @@ import ( lapi "github.com/filecoin-project/lotus/api" "github.com/filecoin-project/lotus/build" "github.com/filecoin-project/lotus/chain/beacon" + "github.com/filecoin-project/lotus/chain/beacon/drand" "github.com/filecoin-project/lotus/chain/gen" "github.com/filecoin-project/lotus/chain/types" "github.com/filecoin-project/lotus/markets/retrievaladapter" @@ -375,3 +376,12 @@ func StorageAuth(ctx helpers.MetricsCtx, ca lapi.Common) (sectorstorage.StorageA headers.Add("Authorization", "Bearer "+string(token)) return sectorstorage.StorageAuth(headers), nil } + +func MinerRandomBeacon(api lapi.FullNode) (beacon.RandomBeacon, error) { + gents, err := api.ChainGetGenesis(context.TODO()) + if err != nil { + return nil, err + } + + return drand.NewDrandBeacon(gents.Blocks()[0].Timestamp, build.BlockDelay) +} diff --git a/node/modules/testing/beacon.go b/node/modules/testing/beacon.go new file mode 100644 index 000000000..37d229982 --- /dev/null +++ b/node/modules/testing/beacon.go @@ -0,0 +1,12 @@ +package testing + +import ( + "time" + + "github.com/filecoin-project/lotus/build" + "github.com/filecoin-project/lotus/chain/beacon" +) + +func RandomBeacon() (beacon.RandomBeacon, error) { + return beacon.NewMockBeacon(build.BlockDelay * time.Second), nil +} diff --git a/node/node_test.go b/node/node_test.go index 2b650658a..5bac49c22 100644 --- a/node/node_test.go +++ b/node/node_test.go @@ -206,8 +206,9 @@ func builder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []test.Te } templ := &genesis.Template{ - Accounts: genaccs, - Miners: genms, + Accounts: genaccs, + Miners: genms, + Timestamp: uint64(time.Now().Unix() - 1000), // some time sufficiently far in the past } // END PRESEAL SECTION @@ -335,8 +336,9 @@ func mockSbBuilder(t *testing.T, nFull int, storage []int) ([]test.TestNode, []t genms = append(genms, *genm) } templ := &genesis.Template{ - Accounts: genaccs, - Miners: genms, + Accounts: genaccs, + Miners: genms, + Timestamp: uint64(time.Now().Unix() - 1000), } // END PRESEAL SECTION