Skip to content

Commit

Permalink
lots of cleanup, and finally a chain fork test case repro!
Browse files Browse the repository at this point in the history
  • Loading branch information
whyrusleeping committed Oct 6, 2019
1 parent 76ceb1f commit 5cb819b
Showing 7 changed files with 233 additions and 74 deletions.
26 changes: 16 additions & 10 deletions chain/gen/gen.go
Original file line number Diff line number Diff line change
@@ -31,7 +31,7 @@ import (

var log = logging.Logger("gen")

const msgsPerBlock = 20
const msgsPerBlock = 0

type ChainGen struct {
accounts []address.Address
@@ -104,7 +104,12 @@ func NewGenerator() (*ChainGen, error) {
return nil, xerrors.Errorf("creating memrepo wallet failed: %w", err)
}

worker, err := w.GenerateKey(types.KTBLS)
worker1, err := w.GenerateKey(types.KTBLS)
if err != nil {
return nil, xerrors.Errorf("failed to generate worker key: %w", err)
}

worker2, err := w.GenerateKey(types.KTBLS)
if err != nil {
return nil, xerrors.Errorf("failed to generate worker key: %w", err)
}
@@ -123,18 +128,20 @@ func NewGenerator() (*ChainGen, error) {
}

minercfg := &GenMinerCfg{
Workers: []address.Address{worker, worker},
Owners: []address.Address{worker, worker},
Workers: []address.Address{worker1, worker2},
Owners: []address.Address{worker1, worker2},
PeerIDs: []peer.ID{"peerID1", "peerID2"},
}

genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
worker: types.FromFil(40000),
banker: types.FromFil(50000),
worker1: types.FromFil(40000),
worker2: types.FromFil(40000),
banker: types.FromFil(50000),
}, minercfg, 100000)
if err != nil {
return nil, xerrors.Errorf("make genesis block failed: %w", err)
}
fmt.Println("MINER CFG ADDRESSES: ", minercfg.MinerAddrs)

cs := store.NewChainStore(bs, ds)

@@ -191,8 +198,7 @@ func (cg *ChainGen) GenesisCar() ([]byte, error) {
return out.Bytes(), nil
}

func (cg *ChainGen) nextBlockProof(ctx context.Context, m address.Address, ticks []*types.Ticket) (types.ElectionProof, *types.Ticket, error) {
pts := cg.CurTipset.TipSet()
func (cg *ChainGen) nextBlockProof(ctx context.Context, pts *types.TipSet, m address.Address, ticks []*types.Ticket) (types.ElectionProof, *types.Ticket, error) {

var lastTicket *types.Ticket
if len(ticks) == 0 {
@@ -201,7 +207,7 @@ func (cg *ChainGen) nextBlockProof(ctx context.Context, m address.Address, ticks
lastTicket = ticks[len(ticks)-1]
}

st := cg.CurTipset.TipSet().ParentState()
st := pts.ParentState()

worker, err := stmgr.GetMinerWorker(ctx, cg.sm, st, m)
if err != nil {
@@ -261,7 +267,7 @@ func (cg *ChainGen) NextTipSetFromMiners(base *types.TipSet, miners []address.Ad

for len(blks) == 0 {
for i, m := range miners {
proof, t, err := cg.nextBlockProof(context.TODO(), m, ticketSets[i])
proof, t, err := cg.nextBlockProof(context.TODO(), base, m, ticketSets[i])
if err != nil {
return nil, xerrors.Errorf("next block proof: %w", err)
}
2 changes: 1 addition & 1 deletion chain/gen/utils.go
Original file line number Diff line number Diff line change
@@ -202,7 +202,7 @@ func SetupStorageMiners(ctx context.Context, cs *store.ChainStore, sroot cid.Cid

// TODO: hardcoding 7000000 here is a little fragile, it changes any
// time anyone changes the initial account allocations
rval, err := doExecValue(ctx, vm, actors.StorageMarketAddress, owner, types.FromFil(6000), actors.SMAMethods.CreateStorageMiner, params)
rval, err := doExecValue(ctx, vm, actors.StorageMarketAddress, owner, types.FromFil(6500), actors.SMAMethods.CreateStorageMiner, params)
if err != nil {
return cid.Undef, xerrors.Errorf("failed to create genesis miner: %w", err)
}
2 changes: 1 addition & 1 deletion chain/messagepool.go
Original file line number Diff line number Diff line change
@@ -87,7 +87,7 @@ func (mp *MessagePool) addLocked(m *types.SignedMessage) error {
return err
}

log.Infof("mpooladd: %d %s", m.Message.Nonce, base64.StdEncoding.EncodeToString(data))
log.Debugf("mpooladd: %d %s", m.Message.Nonce, base64.StdEncoding.EncodeToString(data))

if err := m.Signature.Verify(m.Message.From, data); err != nil {
log.Warnf("mpooladd signature verification failed: %s", err)
37 changes: 9 additions & 28 deletions chain/store/store.go
Original file line number Diff line number Diff line change
@@ -173,31 +173,30 @@ func (cs *ChainStore) SubscribeHeadChanges(f func(rev, app []*types.TipSet) erro
}

func (cs *ChainStore) SetGenesis(b *types.BlockHeader) error {
fts := &FullTipSet{
Blocks: []*types.FullBlock{
{Header: b},
},
ts, err := types.NewTipSet([]*types.BlockHeader{b})
if err != nil {
return err
}

if err := cs.PutTipSet(fts); err != nil {
if err := cs.PutTipSet(ts); err != nil {
return err
}

return cs.ds.Put(dstore.NewKey("0"), b.Cid().Bytes())
}

func (cs *ChainStore) PutTipSet(ts *FullTipSet) error {
for _, b := range ts.Blocks {
if err := cs.persistBlock(b); err != nil {
func (cs *ChainStore) PutTipSet(ts *types.TipSet) error {
for _, b := range ts.Blocks() {
if err := cs.PersistBlockHeader(b); err != nil {
return err
}
}

expanded, err := cs.expandTipset(ts.TipSet().Blocks()[0])
expanded, err := cs.expandTipset(ts.Blocks()[0])
if err != nil {
return xerrors.Errorf("errored while expanding tipset: %w", err)
}
log.Debugf("expanded %s into %s\n", ts.TipSet().Cids(), expanded.Cids())
log.Debugf("expanded %s into %s\n", ts.Cids(), expanded.Cids())

if err := cs.MaybeTakeHeavierTipSet(expanded); err != nil {
return errors.Wrap(err, "MaybeTakeHeavierTipSet failed in PutTipSet")
@@ -373,24 +372,6 @@ func (cs *ChainStore) PersistBlockHeader(b *types.BlockHeader) error {
return cs.bs.Put(sb)
}

func (cs *ChainStore) persistBlock(b *types.FullBlock) error {
if err := cs.PersistBlockHeader(b.Header); err != nil {
return err
}

for _, m := range b.BlsMessages {
if _, err := cs.PutMessage(m); err != nil {
return err
}
}
for _, m := range b.SecpkMessages {
if _, err := cs.PutMessage(m); err != nil {
return err
}
}
return nil
}

type storable interface {
ToStorageBlock() (block.Block, error)
}
120 changes: 95 additions & 25 deletions chain/sync.go
Original file line number Diff line number Diff line change
@@ -94,11 +94,19 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
if fts == nil {
panic("bad")
}

for _, b := range fts.Blocks {
if err := syncer.validateMsgMeta(b); err != nil {
log.Warnf("invalid block received: %s", err)
return
}
}

if from == syncer.self {
// TODO: this is kindof a hack...
log.Info("got block from ourselves")

if err := syncer.Sync(fts); err != nil {
if err := syncer.Sync(fts.TipSet()); err != nil {
log.Errorf("failed to sync our own block: %+v", err)
}

@@ -110,12 +118,37 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
syncer.Bsync.AddPeer(from)

go func() {
if err := syncer.Sync(fts); err != nil {
if err := syncer.Sync(fts.TipSet()); err != nil {
log.Errorf("sync error: %+v", err)
}
}()
}

func (syncer *Syncer) validateMsgMeta(fblk *types.FullBlock) error {
var bcids, scids []cbg.CBORMarshaler
for _, m := range fblk.BlsMessages {
c := cbg.CborCid(m.Cid())
bcids = append(bcids, &c)
}

for _, m := range fblk.SecpkMessages {
c := cbg.CborCid(m.Cid())
scids = append(scids, &c)
}

bs := amt.WrapBlockstore(syncer.store.Blockstore())
smroot, err := computeMsgMeta(bs, bcids, scids)
if err != nil {
return xerrors.Errorf("validating msgmeta, compute failed: %w", err)
}

if fblk.Header.Messages != smroot {
return xerrors.Errorf("messages in full block did not match msgmeta root in header (%s != %s)", fblk.Header.Messages, smroot)
}

return nil
}

func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) {
// TODO: search for other blocks that could form a tipset with this block
// and then send that tipset to InformNewHead
@@ -171,11 +204,6 @@ func zipTipSetAndMessages(bs amt.Blocks, ts *types.TipSet, allbmsgs []*types.Mes
smsgCids = append(smsgCids, &c)
}

smroot, err := amt.FromArray(bs, smsgCids)
if err != nil {
return nil, err
}

var bmsgs []*types.Message
var bmsgCids []cbg.CBORMarshaler
for _, m := range bmi[bi] {
@@ -184,15 +212,7 @@ func zipTipSetAndMessages(bs amt.Blocks, ts *types.TipSet, allbmsgs []*types.Mes
bmsgCids = append(bmsgCids, &c)
}

bmroot, err := amt.FromArray(bs, bmsgCids)
if err != nil {
return nil, err
}

mrcid, err := bs.Put(&types.MsgMeta{
BlsMessages: bmroot,
SecpkMessages: smroot,
})
mrcid, err := computeMsgMeta(bs, bmsgCids, smsgCids)
if err != nil {
return nil, err
}
@@ -213,6 +233,28 @@ func zipTipSetAndMessages(bs amt.Blocks, ts *types.TipSet, allbmsgs []*types.Mes
return fts, nil
}

func computeMsgMeta(bs amt.Blocks, bmsgCids, smsgCids []cbg.CBORMarshaler) (cid.Cid, error) {
bmroot, err := amt.FromArray(bs, bmsgCids)
if err != nil {
return cid.Undef, err
}

smroot, err := amt.FromArray(bs, smsgCids)
if err != nil {
return cid.Undef, err
}

mrcid, err := bs.Put(&types.MsgMeta{
BlsMessages: bmroot,
SecpkMessages: smroot,
})
if err != nil {
return cid.Undef, xerrors.Errorf("failed to put msgmeta: %w", err)
}

return mrcid, nil
}

func (syncer *Syncer) selectHead(heads map[peer.ID]*types.TipSet) (*types.TipSet, error) {
var headsArr []*types.TipSet
for _, ts := range heads {
@@ -289,12 +331,12 @@ func (syncer *Syncer) tryLoadFullTipSet(cids []cid.Cid) (*store.FullTipSet, erro
return fts, nil
}

func (syncer *Syncer) Sync(maybeHead *store.FullTipSet) error {
func (syncer *Syncer) Sync(maybeHead *types.TipSet) error {

syncer.syncLock.Lock()
defer syncer.syncLock.Unlock()

ts := maybeHead.TipSet()
if syncer.Genesis.Equals(ts) || syncer.store.GetHeaviestTipSet().Equals(ts) {
if syncer.Genesis.Equals(maybeHead) || syncer.store.GetHeaviestTipSet().Equals(maybeHead) {
return nil
}

@@ -384,7 +426,7 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err

baseTs, err := syncer.store.LoadTipSet(h.Parents)
if err != nil {
return xerrors.Errorf("load tipset failed: %w", err)
return xerrors.Errorf("load parent tipset failed (%s): %w", h.Parents, err)
}

stateroot, precp, err := syncer.sm.TipSetState(baseTs)
@@ -476,16 +518,43 @@ func (syncer *Syncer) ValidateBlock(ctx context.Context, b *types.FullBlock) err
return nil
}

bs := amt.WrapBlockstore(syncer.store.Blockstore())
var blsCids []cbg.CBORMarshaler
for i, m := range b.BlsMessages {
if err := checkMsg(m); err != nil {
xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
return xerrors.Errorf("block had invalid bls message at index %d: %w", i, err)
}
c := cbg.CborCid(m.Cid())
blsCids = append(blsCids, &c)
}
bmroot, err := amt.FromArray(bs, blsCids)
if err != nil {
return xerrors.Errorf("failed to build amt from bls msg cids: %w", err)
}

var secpkCids []cbg.CBORMarshaler
for i, m := range b.SecpkMessages {
if err := checkMsg(&m.Message); err != nil {
xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
return xerrors.Errorf("block had invalid secpk message at index %d: %w", i, err)
}
c := cbg.CborCid(m.Cid())
secpkCids = append(secpkCids, &c)
}
smroot, err := amt.FromArray(bs, secpkCids)
if err != nil {
return xerrors.Errorf("failed to build amt from bls msg cids: %w", err)
}

mrcid, err := bs.Put(&types.MsgMeta{
BlsMessages: bmroot,
SecpkMessages: smroot,
})
if err != nil {
return err
}

if h.Messages != mrcid {
return fmt.Errorf("messages didnt match message root in header")
}

return nil
@@ -592,6 +661,7 @@ func (syncer *Syncer) iterFullTipsets(headers []*types.TipSet, cb func(*store.Fu
return err
}
if fts == nil {
fmt.Println("Failed to fill tipset for: ", beg, headers[beg].Cids(), headers[beg].Height())
break
}
if err := cb(fts); err != nil {
@@ -671,10 +741,10 @@ func persistMessages(bs bstore.Blockstore, bst *BSTipSet) error {
return nil
}

func (syncer *Syncer) collectChain(fts *store.FullTipSet) error {
syncer.syncState.Init(syncer.store.GetHeaviestTipSet(), fts.TipSet())
func (syncer *Syncer) collectChain(ts *types.TipSet) error {
syncer.syncState.Init(syncer.store.GetHeaviestTipSet(), ts)

headers, err := syncer.collectHeaders(fts.TipSet(), syncer.store.GetHeaviestTipSet())
headers, err := syncer.collectHeaders(ts, syncer.store.GetHeaviestTipSet())
if err != nil {
return err
}
Loading

0 comments on commit 5cb819b

Please sign in to comment.