Skip to content

Commit

Permalink
Merge pull request #2084 from filecoin-project/feat/poiss-sortition
Browse files Browse the repository at this point in the history
Initial implementation of Poisson Sortition
  • Loading branch information
magik6k committed Jun 26, 2020
2 parents 68d38ef + 4895c89 commit 2db8611
Show file tree
Hide file tree
Showing 27 changed files with 829 additions and 28 deletions.
4 changes: 4 additions & 0 deletions api/test/mining.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,10 @@ func TestDealMining(t *testing.T, b APIBuilder, blocktime time.Duration, carExpo
expect += <-wait

time.Sleep(blocktime)
if expect == 0 {
// null block
continue
}

for {
n := 0
Expand Down
8 changes: 5 additions & 3 deletions chain/gen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -558,12 +558,14 @@ func IsRoundWinner(ctx context.Context, ts *types.TipSet, round abi.ChainEpoch,
return nil, xerrors.Errorf("failed to compute VRF: %w", err)
}

// TODO: wire in real power
if !types.IsTicketWinner(vrfout, mbi.MinerPower, mbi.NetworkPower) {
ep := &types.ElectionProof{VRFProof: vrfout}
j := ep.ComputeWinCount(mbi.MinerPower, mbi.NetworkPower)
ep.WinCount = j
if j < 1 {
return nil, nil
}

return &types.ElectionProof{VRFProof: vrfout}, nil
return ep, nil
}

type SignFunc func(context.Context, address.Address, []byte) (*crypto.Signature, error)
Expand Down
4 changes: 2 additions & 2 deletions chain/stmgr/stmgr.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ type BlockMessages struct {
Miner address.Address
BlsMessages []types.ChainMsg
SecpkMessages []types.ChainMsg
TicketCount int64
WinCount int64
}

type ExecCallback func(cid.Cid, *types.Message, *vm.ApplyRet) error
Expand Down Expand Up @@ -311,7 +311,7 @@ func (sm *StateManager) computeTipSetState(ctx context.Context, blks []*types.Bl
Miner: b.Miner,
BlsMessages: make([]types.ChainMsg, 0, len(bms)),
SecpkMessages: make([]types.ChainMsg, 0, len(sms)),
TicketCount: 1, //int64(len(b.EPostProof.Proofs)), // TODO fix this
WinCount: b.ElectionProof.WinCount,
}

for _, m := range bms {
Expand Down
20 changes: 14 additions & 6 deletions chain/store/weight.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn
if ts == nil {
return types.NewInt(0), nil
}
// >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
// >>> w[r] <<< + wFunction(totalPowerAtTipset(ts)) * 2^8 + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)

var out = new(big.Int).Set(ts.Blocks()[0].ParentWeight.Int)

// >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
// >>> wFunction(totalPowerAtTipset(ts)) * 2^8 <<< + (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)

tpow := big2.Zero()
{
Expand Down Expand Up @@ -57,11 +57,19 @@ func (cs *ChainStore) Weight(ctx context.Context, ts *types.TipSet) (types.BigIn

out.Add(out, big.NewInt(log2P<<8))

// (wFunction(totalPowerAtTipset(ts)) * len(ts.blocks) * wRatio_num * 2^8) / (e * wRatio_den)
// (wFunction(totalPowerAtTipset(ts)) * sum(ts.blocks[].ElectionProof.WinCount) * wRatio_num * 2^8) / (e * wRatio_den)

eWeight := big.NewInt((log2P * int64(len(ts.Blocks())) * build.WRatioNum) << 8)
eWeight.Div(eWeight, big.NewInt(int64(build.BlocksPerEpoch*build.WRatioDen)))
out.Add(out, eWeight)
totalJ := int64(0)
for _, b := range ts.Blocks() {
totalJ += b.ElectionProof.WinCount
}

eWeight := big.NewInt((log2P * build.WRatioNum))
eWeight = eWeight.Lsh(eWeight, 8)
eWeight = eWeight.Mul(eWeight, new(big.Int).SetInt64(totalJ))
eWeight = eWeight.Div(eWeight, big.NewInt(int64(build.BlocksPerEpoch*build.WRatioDen)))

out = out.Add(out, eWeight)

return types.BigInt{Int: out}, nil
}
Expand Down
6 changes: 6 additions & 0 deletions chain/sub/incoming.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,12 @@ func (bv *BlockValidator) Validate(ctx context.Context, pid peer.ID, msg *pubsub
return pubsub.ValidationReject
}

if blk.Header.ElectionProof.WinCount < 1 {
log.Errorf("block is not claiming to be winning")
recordFailure("not_winning")
return pubsub.ValidationReject
}

// it's a good block! make sure we've only seen it once
if bv.recvBlocks.add(blk.Header.Cid()) > 0 {
// TODO: once these changes propagate to the network, we can consider
Expand Down
10 changes: 7 additions & 3 deletions chain/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,10 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
}

winnerCheck := async.Err(func() error {
if h.ElectionProof.WinCount < 1 {
return xerrors.Errorf("block is not claiming to be a winner")
}

rBeacon := *prevBeacon
if len(h.BeaconEntries) != 0 {
rBeacon = h.BeaconEntries[len(h.BeaconEntries)-1]
Expand All @@ -660,7 +664,6 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
return xerrors.Errorf("failed to marshal miner address to cbor: %w", err)
}

//TODO: DST from spec actors when it is there
vrfBase, err := store.DrawRandomness(rBeacon.Data, crypto.DomainSeparationTag_ElectionProofProduction, h.Height, buf.Bytes())
if err != nil {
return xerrors.Errorf("could not draw randomness: %w", err)
Expand All @@ -684,8 +687,9 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) (er
return xerrors.Errorf("failed getting power: %w", err)
}

if !types.IsTicketWinner(h.ElectionProof.VRFProof, mpow.QualityAdjPower, tpow.QualityAdjPower) {
return xerrors.Errorf("miner created a block but was not a winner")
j := h.ElectionProof.ComputeWinCount(mpow.QualityAdjPower, tpow.QualityAdjPower)
if h.ElectionProof.WinCount != j {
return xerrors.Errorf("miner claims wrong number of wins: miner: %d, computed: %d", h.ElectionProof.WinCount, j)
}

return nil
Expand Down
2 changes: 1 addition & 1 deletion chain/types/bigint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestSizeStrUnitsSymmetry(t *testing.T) {
s := rand.NewSource(time.Now().UnixNano())
r := rand.New(s)

for i := 0; i < 1000000; i++ {
for i := 0; i < 10000; i++ {
n := r.Uint64()
l := strings.ReplaceAll(units.BytesSize(float64(n)), " ", "")
r := strings.ReplaceAll(SizeStr(NewInt(n)), " ", "")
Expand Down
4 changes: 0 additions & 4 deletions chain/types/blockheader.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ type Ticket struct {
VRFProof []byte
}

type ElectionProof struct {
VRFProof []byte
}

type BeaconEntry struct {
Round uint64
Data []byte
Expand Down
7 changes: 3 additions & 4 deletions chain/types/blockheader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import (
"bytes"
"encoding/hex"
"fmt"
"github.com/stretchr/testify/require"
"reflect"
"testing"

cid "github.com/ipfs/go-cid"
"github.com/stretchr/testify/require"

"github.com/filecoin-project/go-address"
"github.com/filecoin-project/specs-actors/actors/abi"
Expand Down Expand Up @@ -86,7 +86,7 @@ func TestInteropBH(t *testing.T) {
bh := &BlockHeader{
Miner: newAddr,
Ticket: &Ticket{[]byte{0x01, 0x02, 0x03}},
ElectionProof: &ElectionProof{[]byte{0x0a, 0x0b}},
ElectionProof: &ElectionProof{0, []byte{0x0a, 0x0b}},
BeaconEntries: []BeaconEntry{
{
Round: 5,
Expand Down Expand Up @@ -116,8 +116,7 @@ func TestInteropBH(t *testing.T) {
t.Fatal(err)
}

// acquired from go-filecoin
gfc := "8f5501d04cb15021bf6bd003073d79e2238d4e61f1ad22814301020381420a0b818205410c818200410781d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc430003e802d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc410001f603"
gfc := "8f5501d04cb15021bf6bd003073d79e2238d4e61f1ad2281430102038200420a0b818205410c818200410781d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc430003e802d82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619ccd82a5827000171a0e402202f84fef0d7cc2d7f9f00d22445f7bf7539fdd685fd9f284aa37f3822b57619cc410001f603"
require.Equal(t, gfc, hex.EncodeToString(bhsb))
}

Expand Down
40 changes: 38 additions & 2 deletions chain/types/cbor_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2db8611

Please sign in to comment.