chain: Test sync with messages

This commit is contained in:
Łukasz Magiera 2019-07-30 15:20:40 +02:00 committed by whyrusleeping
parent 9ef5e1266e
commit b6439fa57d
4 changed files with 137 additions and 49 deletions

View File

@ -3,6 +3,7 @@ package gen
import ( import (
"bytes" "bytes"
"context" "context"
"sync/atomic"
"github.com/ipfs/go-blockservice" "github.com/ipfs/go-blockservice"
"github.com/ipfs/go-car" "github.com/ipfs/go-car"
@ -23,6 +24,8 @@ import (
var log = logging.Logger("gen") var log = logging.Logger("gen")
const msgsPerBlock = 2
type ChainGen struct { type ChainGen struct {
accounts []address.Address accounts []address.Address
@ -32,11 +35,15 @@ type ChainGen struct {
cs *store.ChainStore cs *store.ChainStore
genesis *types.BlockHeader genesis *types.BlockHeader
curBlock *types.FullBlock curBlock *types.FullBlock
miner address.Address w *wallet.Wallet
miner address.Address
receivers []address.Address
banker address.Address
bankerNonce uint64
r repo.Repo r repo.Repo
lr repo.LockedRepo lr repo.LockedRepo
@ -95,7 +102,16 @@ func NewGenerator() (*ChainGen, error) {
return nil, err return nil, err
} }
receievers := make([]address.Address, msgsPerBlock)
for r := range receievers {
receievers[r], err = w.GenerateKey(types.KTBLS)
if err != nil {
return nil, err
}
}
genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{ genb, err := MakeGenesisBlock(bs, map[address.Address]types.BigInt{
miner: types.NewInt(5),
banker: types.NewInt(90000000), banker: types.NewInt(90000000),
}) })
if err != nil { if err != nil {
@ -104,8 +120,6 @@ func NewGenerator() (*ChainGen, error) {
cs := store.NewChainStore(bs, ds) cs := store.NewChainStore(bs, ds)
msgsPerBlock := 10
genfb := &types.FullBlock{Header: genb.Genesis} genfb := &types.FullBlock{Header: genb.Genesis}
if err := cs.SetGenesis(genb.Genesis); err != nil { if err := cs.SetGenesis(genb.Genesis); err != nil {
@ -117,8 +131,13 @@ func NewGenerator() (*ChainGen, error) {
cs: cs, cs: cs,
msgsPerBlock: msgsPerBlock, msgsPerBlock: msgsPerBlock,
genesis: genb.Genesis, genesis: genb.Genesis,
miner: miner, w: w,
curBlock: genfb,
miner: miner,
banker: banker,
receivers: receievers,
curBlock: genfb,
r: mr, r: mr,
lr: lr, lr: lr,
@ -155,7 +174,45 @@ func (cg *ChainGen) NextBlock() (*types.FullBlock, error) {
return nil, err return nil, err
} }
var msgs []*types.SignedMessage // make some transfers from banker
msgs := make([]*types.SignedMessage, cg.msgsPerBlock)
for m := range msgs {
msg := types.Message{
To: cg.receivers[m],
From: cg.banker,
Nonce: atomic.AddUint64(&cg.bankerNonce, 1) - 1,
Value: types.NewInt(uint64(m + 1)),
Method: 0,
GasLimit: types.NewInt(10000),
GasPrice: types.NewInt(0),
}
unsigned, err := msg.Serialize()
if err != nil {
return nil, err
}
sig, err := cg.w.Sign(cg.banker, unsigned)
if err != nil {
return &types.FullBlock{}, err
}
msgs[m] = &types.SignedMessage{
Message: msg,
Signature: *sig,
}
if _, err := cg.cs.PutMessage(msgs[m]); err != nil {
return nil, err
}
}
// create block
parents, err := types.NewTipSet([]*types.BlockHeader{cg.curBlock.Header}) parents, err := types.NewTipSet([]*types.BlockHeader{cg.curBlock.Header})
if err != nil { if err != nil {

View File

@ -143,16 +143,6 @@ func (syncer *Syncer) InformNewHead(from peer.ID, fts *store.FullTipSet) {
}() }()
} }
func (syncer *Syncer) GetPeers() []peer.ID {
syncer.peerHeadsLk.Lock()
defer syncer.peerHeadsLk.Unlock()
var out []peer.ID
for p, _ := range syncer.peerHeads {
out = append(out, p)
}
return out
}
func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) { func (syncer *Syncer) InformNewBlock(from peer.ID, blk *types.FullBlock) {
// TODO: search for other blocks that could form a tipset with this block // TODO: search for other blocks that could form a tipset with this block
// and then send that tipset to InformNewHead // and then send that tipset to InformNewHead

View File

@ -37,59 +37,100 @@ func repoWithChain(t *testing.T, h int) (repo.Repo, []byte) {
return r, genb return r, genb
} }
func TestSyncSimple(t *testing.T) { type syncTestUtil struct {
ctx := context.Background() t *testing.T
var source api.FullNode ctx context.Context
var client api.FullNode mn mocknet.Mocknet
genesis []byte
nds []api.FullNode
}
func (tu *syncTestUtil) addSourceNode(gen int) int {
if tu.genesis != nil {
tu.t.Fatal("source node already exists")
}
sourceRepo, genesis := repoWithChain(tu.t, gen)
var out api.FullNode
err := node.New(tu.ctx,
node.FullAPI(&out),
node.Online(),
node.Repo(sourceRepo),
node.MockHost(tu.mn),
node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)),
)
require.NoError(tu.t, err)
tu.genesis = genesis
tu.nds = append(tu.nds, out)
return len(tu.nds) - 1
}
func (tu *syncTestUtil) addClientNode() int {
var out api.FullNode
err := node.New(tu.ctx,
node.FullAPI(&out),
node.Online(),
node.Repo(repo.NewMemory(nil)),
node.MockHost(tu.mn),
node.Override(new(modules.Genesis), modules.LoadGenesis(tu.genesis)),
)
require.NoError(tu.t, err)
tu.nds = append(tu.nds, out)
return len(tu.nds) - 1
}
func TestSyncSimple(t *testing.T) {
H := 3
ctx := context.Background()
mn := mocknet.New(ctx) mn := mocknet.New(ctx)
sourceRepo, genesis := repoWithChain(t, 20) tu := &syncTestUtil{
t: t,
ctx: ctx,
mn: mn,
}
err := node.New(ctx, source := tu.addSourceNode(H)
node.FullAPI(&source),
node.Online(),
node.Repo(sourceRepo),
node.MockHost(mn),
node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)), b, err := tu.nds[source].ChainHead(ctx)
)
require.NoError(t, err) require.NoError(t, err)
b, err := source.ChainHead(ctx) require.Equal(t, uint64(H), b.Height())
require.NoError(t, err)
require.Equal(t, uint64(20), b.Height())
fmt.Printf("source H: %d\n", b.Height()) fmt.Printf("source H: %d\n", b.Height())
err = node.New(ctx, // separate logs
node.FullAPI(&client), fmt.Println("///////////////////////////////////////////////////")
node.Online(),
node.Repo(repo.NewMemory(nil)),
node.MockHost(mn),
node.Override(new(modules.Genesis), modules.LoadGenesis(genesis)), client := tu.addClientNode()
)
require.NoError(t, err)
require.NoError(t, mn.LinkAll()) require.NoError(t, mn.LinkAll())
cb, err := client.ChainHead(ctx) cb, err := tu.nds[client].ChainHead(ctx)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint64(0), cb.Height()) require.Equal(t, uint64(0), cb.Height())
fmt.Printf("client H: %d\n", cb.Height()) fmt.Printf("client H: %d\n", cb.Height())
sourcePI, err := source.NetAddrsListen(ctx) sourcePI, err := tu.nds[source].NetAddrsListen(ctx)
require.NoError(t, err) require.NoError(t, err)
err = client.NetConnect(ctx, sourcePI) err = tu.nds[client].NetConnect(ctx, sourcePI)
require.NoError(t, err) require.NoError(t, err)
time.Sleep(time.Second) time.Sleep(time.Second * 1)
cb, err = client.ChainHead(ctx) cb, err = tu.nds[client].ChainHead(ctx)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, uint64(20), cb.Height()) require.Equal(t, uint64(H), cb.Height())
fmt.Printf("client H: %d\n", cb.Height()) fmt.Printf("client H: %d\n", cb.Height())
} }

View File

@ -220,7 +220,7 @@ func (vm *VM) ApplyMessage(ctx context.Context, msg *types.Message) (*types.Mess
} }
if msg.Nonce != fromActor.Nonce { if msg.Nonce != fromActor.Nonce {
return nil, xerrors.Errorf("invalid nonce") return nil, xerrors.Errorf("invalid nonce (got %d, expected %d)", msg.Nonce, fromActor.Nonce)
} }
fromActor.Nonce++ fromActor.Nonce++