From 74f68dc630b47e4e05b0832e0dc770e6a871a490 Mon Sep 17 00:00:00 2001 From: whyrusleeping Date: Sun, 8 Sep 2019 13:14:01 -0700 Subject: [PATCH] perform tipset expansion on sync and fix tipset comparison --- chain/gen/gen.go | 11 ++++++----- chain/store/store.go | 8 +++++++- chain/sync.go | 17 ++++++++++------- chain/sync_test.go | 1 - chain/types/blockheader.go | 11 +++++++++-- chain/types/tipset.go | 8 ++++++++ go.mod | 2 +- go.sum | 2 ++ 8 files changed, 43 insertions(+), 17 deletions(-) diff --git a/chain/gen/gen.go b/chain/gen/gen.go index 067ea6ef0..7cc472273 100644 --- a/chain/gen/gen.go +++ b/chain/gen/gen.go @@ -32,7 +32,7 @@ import ( var log = logging.Logger("gen") -const msgsPerBlock = 20 +const msgsPerBlock = 2 type ChainGen struct { accounts []address.Address @@ -260,6 +260,8 @@ func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) { return nil, err } + base := cg.curTipset.TipSet() + for len(blks) == 0 { for i, m := range cg.miners { proof, t, err := cg.nextBlockProof(context.TODO(), m, ticketSets[i]) @@ -269,7 +271,7 @@ func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) { ticketSets[i] = append(ticketSets[i], t) if proof != nil { - fblk, err := cg.makeBlock(m, proof, ticketSets[i], msgs) + fblk, err := cg.makeBlock(base, m, proof, ticketSets[i], msgs) if err != nil { return nil, xerrors.Errorf("making a block for next tipset failed: %w", err) } @@ -284,6 +286,7 @@ func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) { } cg.curTipset = store.NewFullTipSet(blks) + fmt.Printf("Mined tipset %s (%d) on top of %s (%d)\n", cg.curTipset.Cids(), cg.curTipset.TipSet().Height(), base.Cids(), base.Height()) return &MinedTipSet{ TipSet: cg.curTipset, @@ -291,9 +294,7 @@ func (cg *ChainGen) NextTipSet() (*MinedTipSet, error) { }, nil } -func (cg *ChainGen) makeBlock(m address.Address, eproof types.ElectionProof, tickets []*types.Ticket, msgs []*types.SignedMessage) (*types.FullBlock, error) { - - parents := cg.curTipset.TipSet() +func (cg *ChainGen) makeBlock(parents *types.TipSet, m address.Address, eproof types.ElectionProof, tickets []*types.Ticket, msgs []*types.SignedMessage) (*types.FullBlock, error) { ts := parents.MinTimestamp() + (uint64(len(tickets)) * build.BlockDelay) diff --git a/chain/store/store.go b/chain/store/store.go index 5115bc129..aac5cd993 100644 --- a/chain/store/store.go +++ b/chain/store/store.go @@ -179,7 +179,13 @@ func (cs *ChainStore) PutTipSet(ts *FullTipSet) error { } } - if err := cs.MaybeTakeHeavierTipSet(ts.TipSet()); err != nil { + expanded, err := cs.expandTipset(ts.TipSet().Blocks()[0]) + if err != nil { + return xerrors.Errorf("errored while expanding tipset: %w", err) + } + fmt.Printf("expanded %s into %s\n", ts.TipSet().Cids(), expanded.Cids()) + + if err := cs.MaybeTakeHeavierTipSet(expanded); err != nil { return errors.Wrap(err, "MaybeTakeHeavierTipSet failed in PutTipSet") } return nil diff --git a/chain/sync.go b/chain/sync.go index ee9a69cd4..755b10e58 100644 --- a/chain/sync.go +++ b/chain/sync.go @@ -510,11 +510,6 @@ loop: // NB: GetBlocks validates that the blocks are in-fact the ones we // requested, and that they are correctly linked to eachother. It does // not validate any state transitions - fmt.Println("Get blocks") - if len(at) == 0 { - fmt.Println("Weird situation, about to request blocks with empty tipset") - fmt.Println("info: ", len(blockSet), blockSet[len(blockSet)-1].Height(), untilHeight) - } blks, err := syncer.Bsync.GetBlocks(context.TODO(), at, 10) if err != nil { // Most likely our peers aren't fully synced yet, but forwarded @@ -537,13 +532,21 @@ loop: blockSet = append(blockSet, b) } - fmt.Println("AT CHILD: ", blks[len(blks)-1].Height()) at = blks[len(blks)-1].Parents() } + // We have now ascertained that this is *not* a 'fast forward' if !types.CidArrsEqual(blockSet[len(blockSet)-1].Parents(), to.Cids()) { + last := blockSet[len(blockSet)-1] + if types.CidArrsEqual(last.Parents(), to.Parents()) { + // common case: receiving a block thats potentially part of the same tipset as our best block + return blockSet, nil + } + // TODO: handle the case where we are on a fork and its not a simple fast forward - return nil, xerrors.Errorf("synced header chain does not link to our best block") + // need to walk back to either a common ancestor, or until we hit the fork length threshold. + return nil, xerrors.Errorf("(fork detected) synced header chain (%s - %d) does not link to our best block (%s - %d)", from.Cids(), from.Height(), to.Cids(), to.Height()) + } return blockSet, nil diff --git a/chain/sync_test.go b/chain/sync_test.go index 8a2e1b324..b81facd48 100644 --- a/chain/sync_test.go +++ b/chain/sync_test.go @@ -290,7 +290,6 @@ func TestSyncMining(t *testing.T) { tu.compareSourceState(client) for i := 0; i < 5; i++ { - fmt.Println("MINE A NEW BLOCK") tu.mineNewBlock(0) tu.waitUntilSync(0, client) tu.compareSourceState(client) diff --git a/chain/types/blockheader.go b/chain/types/blockheader.go index 784764514..f5c078e6b 100644 --- a/chain/types/blockheader.go +++ b/chain/types/blockheader.go @@ -125,8 +125,15 @@ func CidArrsEqual(a, b []cid.Cid) bool { if len(a) != len(b) { return false } - for i, v := range a { - if b[i] != v { + + // order ignoring compare... + s := make(map[cid.Cid]bool) + for _, c := range a { + s[c] = true + } + + for _, c := range b { + if !s[c] { return false } } diff --git a/chain/types/tipset.go b/chain/types/tipset.go index 2d763650a..00110dd3e 100644 --- a/chain/types/tipset.go +++ b/chain/types/tipset.go @@ -46,6 +46,14 @@ func (ts *TipSet) UnmarshalJSON(b []byte) error { } func NewTipSet(blks []*BlockHeader) (*TipSet, error) { + /* + sort.Slice(blks, func(i, j int) bool { + a := blks[i].LastTicket() + b := blks[j].LastTicket() + return bytes.Compare(a.VDFResult, b.VDFResult) < 0 + }) + */ + var ts TipSet ts.cids = []cid.Cid{blks[0].Cid()} ts.blks = blks diff --git a/go.mod b/go.mod index 18cd19baf..3d74702c5 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/gorilla/websocket v1.4.0 github.com/ipfs/go-bitswap v0.1.8 github.com/ipfs/go-block-format v0.0.2 - github.com/ipfs/go-blockservice v0.1.2 + github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c github.com/ipfs/go-car v0.0.0-20190823083746-79984a8632b4 github.com/ipfs/go-cid v0.0.3 github.com/ipfs/go-datastore v0.1.0 diff --git a/go.sum b/go.sum index c0618ce4f..0e480d313 100644 --- a/go.sum +++ b/go.sum @@ -148,6 +148,8 @@ github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJ github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= github.com/ipfs/go-blockservice v0.1.2 h1:fqFeeu1EG0lGVrqUo+BVJv7LZV31I4ZsyNthCOMAJRc= github.com/ipfs/go-blockservice v0.1.2/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= +github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c h1:lN5IQA07VtLiTLAp/Scezp1ljFhXErC6yq4O1cu+yJ0= +github.com/ipfs/go-blockservice v0.1.3-0.20190908200855-f22eea50656c/go.mod h1:t+411r7psEUhLueM8C7aPA7cxCclv4O3VsUVxt9kz2I= github.com/ipfs/go-car v0.0.0-20190823083746-79984a8632b4 h1:qYLz/x/d1SOiiFGS8dwCBCFJ5Oh64Y8HMBrS+MbaU8c= github.com/ipfs/go-car v0.0.0-20190823083746-79984a8632b4/go.mod h1:NSSM0pxlhej9rSFXQmB/lDru7TYNoDjKgmvqzlsd06Y= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=