remove VDFs from tickets
This commit is contained in:
parent
49e8b5d334
commit
19b16077fe
@ -20,7 +20,6 @@ import (
|
|||||||
"github.com/filecoin-project/go-lotus/chain/store"
|
"github.com/filecoin-project/go-lotus/chain/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/chain/wallet"
|
"github.com/filecoin-project/go-lotus/chain/wallet"
|
||||||
"github.com/filecoin-project/go-lotus/lib/vdf"
|
|
||||||
"github.com/filecoin-project/go-lotus/node/repo"
|
"github.com/filecoin-project/go-lotus/node/repo"
|
||||||
|
|
||||||
block "github.com/ipfs/go-block-format"
|
block "github.com/ipfs/go-block-format"
|
||||||
@ -213,20 +212,13 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m add
|
|||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, lastTicket.VDFResult)
|
vrfout, err := ComputeVRF(ctx, cg.w.Sign, worker, lastTicket.VRFProof)
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
out, proof, err := vdf.Run(vrfout)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
tick := &types.Ticket{
|
tick := &types.Ticket{
|
||||||
VRFProof: vrfout,
|
VRFProof: vrfout,
|
||||||
VDFProof: proof,
|
|
||||||
VDFResult: out,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
win, eproof, err := IsRoundWinner(ctx, pts, append(ticks, tick), m, &mca{w: cg.w, sm: cg.sm})
|
win, eproof, err := IsRoundWinner(ctx, pts, append(ticks, tick), m, &mca{w: cg.w, sm: cg.sm})
|
||||||
|
@ -329,9 +329,7 @@ func MakeGenesisBlock(bs bstore.Blockstore, balances map[address.Address]types.B
|
|||||||
log.Infof("Empty Genesis root: %s", emptyroot)
|
log.Infof("Empty Genesis root: %s", emptyroot)
|
||||||
|
|
||||||
genesisticket := &types.Ticket{
|
genesisticket := &types.Ticket{
|
||||||
VRFProof: []byte("vrf proof"),
|
VRFProof: []byte("vrf proof"),
|
||||||
VDFResult: []byte("i am a vdf result"),
|
|
||||||
VDFProof: []byte("vdf proof"),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
b := &types.BlockHeader{
|
b := &types.BlockHeader{
|
||||||
|
@ -743,7 +743,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, tickets
|
|||||||
|
|
||||||
t := tickets[lt-(1+lb)]
|
t := tickets[lt-(1+lb)]
|
||||||
|
|
||||||
return t.VDFResult, nil
|
return t.VRFProof, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
nv := lb - lt
|
nv := lb - lt
|
||||||
@ -758,7 +758,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, tickets
|
|||||||
lt := int64(len(mtb.Tickets))
|
lt := int64(len(mtb.Tickets))
|
||||||
if nv < lt {
|
if nv < lt {
|
||||||
t := mtb.Tickets[lt-(1+nv)]
|
t := mtb.Tickets[lt-(1+nv)]
|
||||||
return t.VDFResult, nil
|
return t.VRFProof, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
nv -= lt
|
nv -= lt
|
||||||
@ -769,7 +769,7 @@ func (cs *ChainStore) GetRandomness(ctx context.Context, blks []cid.Cid, tickets
|
|||||||
|
|
||||||
t := mtb.Tickets[0]
|
t := mtb.Tickets[0]
|
||||||
|
|
||||||
rval := t.VDFResult
|
rval := t.VRFProof
|
||||||
for i := int64(0); i < nv; i++ {
|
for i := int64(0); i < nv; i++ {
|
||||||
h := sha256.Sum256(rval)
|
h := sha256.Sum256(rval)
|
||||||
rval = h[:]
|
rval = h[:]
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
"github.com/filecoin-project/go-lotus/chain/stmgr"
|
||||||
"github.com/filecoin-project/go-lotus/chain/store"
|
"github.com/filecoin-project/go-lotus/chain/store"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/lib/vdf"
|
|
||||||
|
|
||||||
amt "github.com/filecoin-project/go-amt-ipld"
|
amt "github.com/filecoin-project/go-amt-ipld"
|
||||||
"github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
@ -405,15 +404,11 @@ func (syncer *Syncer) validateTickets(ctx context.Context, mworker address.Addre
|
|||||||
Data: next.VRFProof,
|
Data: next.VRFProof,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := sig.Verify(mworker, cur.VDFResult); err != nil {
|
// TODO: ticket signatures should also include miner address
|
||||||
|
if err := sig.Verify(mworker, cur.VRFProof); err != nil {
|
||||||
return xerrors.Errorf("invalid ticket, VRFProof invalid: %w", err)
|
return xerrors.Errorf("invalid ticket, VRFProof invalid: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// now verify the VDF
|
|
||||||
if err := vdf.Verify(next.VRFProof, next.VDFResult, next.VDFProof); err != nil {
|
|
||||||
return xerrors.Errorf("ticket %d had invalid VDF: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = next
|
cur = next
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -14,9 +14,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Ticket struct {
|
type Ticket struct {
|
||||||
VRFProof []byte
|
VRFProof []byte
|
||||||
VDFResult []byte
|
|
||||||
VDFProof []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type ElectionProof []byte
|
type ElectionProof []byte
|
||||||
@ -176,5 +174,5 @@ func PowerCmp(eproof ElectionProof, mpow, totpow BigInt) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Ticket) Equals(ot *Ticket) bool {
|
func (t *Ticket) Equals(ot *Ticket) bool {
|
||||||
return bytes.Equal(t.VDFResult, ot.VDFResult)
|
return bytes.Equal(t.VRFProof, ot.VRFProof)
|
||||||
}
|
}
|
||||||
|
@ -27,9 +27,7 @@ func testBlockHeader(t testing.TB) *BlockHeader {
|
|||||||
ElectionProof: []byte("cats won the election"),
|
ElectionProof: []byte("cats won the election"),
|
||||||
Tickets: []*Ticket{
|
Tickets: []*Ticket{
|
||||||
&Ticket{
|
&Ticket{
|
||||||
VRFProof: []byte("vrf proof"),
|
VRFProof: []byte("vrf proof"),
|
||||||
VDFResult: []byte("vdf result"),
|
|
||||||
VDFProof: []byte("vrf proof"),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Parents: []cid.Cid{c, c},
|
Parents: []cid.Cid{c, c},
|
||||||
|
@ -5,7 +5,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
|
||||||
cid "github.com/ipfs/go-cid"
|
"github.com/ipfs/go-cid"
|
||||||
cbg "github.com/whyrusleeping/cbor-gen"
|
cbg "github.com/whyrusleeping/cbor-gen"
|
||||||
xerrors "golang.org/x/xerrors"
|
xerrors "golang.org/x/xerrors"
|
||||||
)
|
)
|
||||||
@ -284,7 +284,7 @@ func (t *Ticket) MarshalCBOR(w io.Writer) error {
|
|||||||
_, err := w.Write(cbg.CborNull)
|
_, err := w.Write(cbg.CborNull)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if _, err := w.Write([]byte{131}); err != nil {
|
if _, err := w.Write([]byte{129}); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,22 +295,6 @@ func (t *Ticket) MarshalCBOR(w io.Writer) error {
|
|||||||
if _, err := w.Write(t.VRFProof); err != nil {
|
if _, err := w.Write(t.VRFProof); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// t.t.VDFResult ([]uint8)
|
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.VDFResult)))); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := w.Write(t.VDFResult); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// t.t.VDFProof ([]uint8)
|
|
||||||
if _, err := w.Write(cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(t.VDFProof)))); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if _, err := w.Write(t.VDFProof); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -325,7 +309,7 @@ func (t *Ticket) UnmarshalCBOR(r io.Reader) error {
|
|||||||
return fmt.Errorf("cbor input should be of type array")
|
return fmt.Errorf("cbor input should be of type array")
|
||||||
}
|
}
|
||||||
|
|
||||||
if extra != 3 {
|
if extra != 1 {
|
||||||
return fmt.Errorf("cbor input had wrong number of fields")
|
return fmt.Errorf("cbor input had wrong number of fields")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,40 +330,6 @@ func (t *Ticket) UnmarshalCBOR(r io.Reader) error {
|
|||||||
if _, err := io.ReadFull(br, t.VRFProof); err != nil {
|
if _, err := io.ReadFull(br, t.VRFProof); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// t.t.VDFResult ([]uint8)
|
|
||||||
|
|
||||||
maj, extra, err = cbg.CborReadHeader(br)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if extra > 8192 {
|
|
||||||
return fmt.Errorf("t.VDFResult: array too large (%d)", extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
if maj != cbg.MajByteString {
|
|
||||||
return fmt.Errorf("expected byte array")
|
|
||||||
}
|
|
||||||
t.VDFResult = make([]byte, extra)
|
|
||||||
if _, err := io.ReadFull(br, t.VDFResult); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// t.t.VDFProof ([]uint8)
|
|
||||||
|
|
||||||
maj, extra, err = cbg.CborReadHeader(br)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if extra > 8192 {
|
|
||||||
return fmt.Errorf("t.VDFProof: array too large (%d)", extra)
|
|
||||||
}
|
|
||||||
|
|
||||||
if maj != cbg.MajByteString {
|
|
||||||
return fmt.Errorf("expected byte array")
|
|
||||||
}
|
|
||||||
t.VDFProof = make([]byte, extra)
|
|
||||||
if _, err := io.ReadFull(br, t.VDFProof); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ func (ts *TipSet) Equals(ots *TipSet) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (t *Ticket) Less(o *Ticket) bool {
|
func (t *Ticket) Less(o *Ticket) bool {
|
||||||
return bytes.Compare(t.VDFResult, o.VDFResult) < 0
|
return bytes.Compare(t.VRFProof, o.VRFProof) < 0
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ts *TipSet) MinTicket() *Ticket {
|
func (ts *TipSet) MinTicket() *Ticket {
|
||||||
|
@ -1,28 +0,0 @@
|
|||||||
package vdf
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/sha256"
|
|
||||||
"fmt"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Run(input []byte) ([]byte, []byte, error) {
|
|
||||||
h := sha256.Sum256(input)
|
|
||||||
// TODO: THIS IS A FAKE VDF. THE SPEC IS UNCLEAR ON WHAT TO REALLY DO HERE
|
|
||||||
return h[:], []byte("proof"), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Verify(input []byte, out []byte, proof []byte) error {
|
|
||||||
// this is a fake VDF
|
|
||||||
h := sha256.Sum256(input)
|
|
||||||
|
|
||||||
if !bytes.Equal(h[:], out) {
|
|
||||||
return fmt.Errorf("vdf output incorrect")
|
|
||||||
}
|
|
||||||
|
|
||||||
if !bytes.Equal(proof, []byte("proof")) {
|
|
||||||
return fmt.Errorf("vdf proof failed to validate")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -10,7 +10,6 @@ import (
|
|||||||
"github.com/filecoin-project/go-lotus/chain/address"
|
"github.com/filecoin-project/go-lotus/chain/address"
|
||||||
"github.com/filecoin-project/go-lotus/chain/gen"
|
"github.com/filecoin-project/go-lotus/chain/gen"
|
||||||
"github.com/filecoin-project/go-lotus/chain/types"
|
"github.com/filecoin-project/go-lotus/chain/types"
|
||||||
"github.com/filecoin-project/go-lotus/lib/vdf"
|
|
||||||
"github.com/filecoin-project/go-lotus/node/impl/full"
|
"github.com/filecoin-project/go-lotus/node/impl/full"
|
||||||
|
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
@ -22,7 +21,7 @@ import (
|
|||||||
|
|
||||||
var log = logging.Logger("miner")
|
var log = logging.Logger("miner")
|
||||||
|
|
||||||
type vdfFunc func(ctx context.Context, input []byte) ([]byte, []byte, error)
|
type waitFunc func(ctx context.Context) error
|
||||||
|
|
||||||
type api struct {
|
type api struct {
|
||||||
fx.In
|
fx.In
|
||||||
@ -36,9 +35,11 @@ type api struct {
|
|||||||
func NewMiner(api api) *Miner {
|
func NewMiner(api api) *Miner {
|
||||||
return &Miner{
|
return &Miner{
|
||||||
api: api,
|
api: api,
|
||||||
|
waitFunc: func(ctx context.Context) error {
|
||||||
// time between blocks, network parameter
|
// Wait around for half the block time in case other parents come in
|
||||||
runVDF: delayVDF(build.BlockDelay * time.Second),
|
time.Sleep(build.BlockDelay * time.Second / 2)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ type Miner struct {
|
|||||||
stop chan struct{}
|
stop chan struct{}
|
||||||
stopping chan struct{}
|
stopping chan struct{}
|
||||||
|
|
||||||
runVDF vdfFunc
|
waitFunc waitFunc
|
||||||
|
|
||||||
lastWork *MiningBase
|
lastWork *MiningBase
|
||||||
}
|
}
|
||||||
@ -144,6 +145,10 @@ func (m *Miner) mine(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
if err := m.waitFunc(ctx); err != nil {
|
||||||
|
log.Error(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
base, err := m.GetBestMiningCandidate()
|
base, err := m.GetBestMiningCandidate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -159,6 +164,11 @@ func (m *Miner) mine(ctx context.Context) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
btime := time.Unix(int64(b.Header.Timestamp), 0)
|
||||||
|
if time.Now().Before(btime) {
|
||||||
|
time.Sleep(time.Until(btime))
|
||||||
|
}
|
||||||
|
|
||||||
if b != nil {
|
if b != nil {
|
||||||
if err := m.api.ChainSubmitBlock(ctx, b); err != nil {
|
if err := m.api.ChainSubmitBlock(ctx, b); err != nil {
|
||||||
log.Errorf("failed to submit newly mined block: %s", err)
|
log.Errorf("failed to submit newly mined block: %s", err)
|
||||||
@ -255,18 +265,6 @@ func (m *Miner) getMinerWorker(ctx context.Context, addr address.Address, ts *ty
|
|||||||
return w, nil
|
return w, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func delayVDF(delay time.Duration) func(ctx context.Context, input []byte) ([]byte, []byte, error) {
|
|
||||||
return func(ctx context.Context, input []byte) ([]byte, []byte, error) {
|
|
||||||
select {
|
|
||||||
case <-ctx.Done():
|
|
||||||
return nil, nil, ctx.Err()
|
|
||||||
case <-time.After(delay):
|
|
||||||
}
|
|
||||||
|
|
||||||
return vdf.Run(input)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *Miner) scratchTicket(ctx context.Context, base *MiningBase) (*types.Ticket, error) {
|
func (m *Miner) scratchTicket(ctx context.Context, base *MiningBase) (*types.Ticket, error) {
|
||||||
var lastTicket *types.Ticket
|
var lastTicket *types.Ticket
|
||||||
if len(base.tickets) > 0 {
|
if len(base.tickets) > 0 {
|
||||||
@ -275,20 +273,13 @@ func (m *Miner) scratchTicket(ctx context.Context, base *MiningBase) (*types.Tic
|
|||||||
lastTicket = base.ts.MinTicket()
|
lastTicket = base.ts.MinTicket()
|
||||||
}
|
}
|
||||||
|
|
||||||
vrfOut, err := m.computeVRF(ctx, lastTicket.VDFResult)
|
vrfOut, err := m.computeVRF(ctx, lastTicket.VRFProof)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
res, proof, err := m.runVDF(ctx, vrfOut)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &types.Ticket{
|
return &types.Ticket{
|
||||||
VRFProof: vrfOut,
|
VRFProof: vrfOut,
|
||||||
VDFResult: res,
|
|
||||||
VDFProof: proof,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,7 +295,7 @@ func (m *Miner) createBlock(base *MiningBase, ticket *types.Ticket, proof types.
|
|||||||
return nil, xerrors.Errorf("message filtering failed: %w", err)
|
return nil, xerrors.Errorf("message filtering failed: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
uts := time.Now().Unix() // TODO: put smallest valid timestamp
|
uts := base.ts.MinTimestamp() + uint64(build.BlockDelay*(len(base.tickets)+1))
|
||||||
|
|
||||||
// why even return this? that api call could just submit it for us
|
// why even return this? that api call could just submit it for us
|
||||||
return m.api.MinerCreateBlock(context.TODO(), m.addresses[0], base.ts, append(base.tickets, ticket), proof, msgs, uint64(uts))
|
return m.api.MinerCreateBlock(context.TODO(), m.addresses[0], base.ts, append(base.tickets, ticket), proof, msgs, uint64(uts))
|
||||||
|
@ -2,27 +2,25 @@ package miner
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/filecoin-project/go-lotus/lib/vdf"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTestMiner(nextCh <-chan struct{}) func(api api) *Miner {
|
func NewTestMiner(nextCh <-chan struct{}) func(api api) *Miner {
|
||||||
return func(api api) *Miner {
|
return func(api api) *Miner {
|
||||||
return &Miner{
|
return &Miner{
|
||||||
api: api,
|
api: api,
|
||||||
runVDF: chanVDF(nextCh),
|
waitFunc: chanWaiter(nextCh),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func chanVDF(next <-chan struct{}) func(ctx context.Context, input []byte) ([]byte, []byte, error) {
|
func chanWaiter(next <-chan struct{}) func(ctx context.Context) error {
|
||||||
return func(ctx context.Context, input []byte) ([]byte, []byte, error) {
|
return func(ctx context.Context) error {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
return nil, nil, ctx.Err()
|
return ctx.Err()
|
||||||
case <-next:
|
case <-next:
|
||||||
}
|
}
|
||||||
|
|
||||||
return vdf.Run(input)
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user