8 "github.com/vapor/consensus"
9 "github.com/vapor/errors"
10 msgs "github.com/vapor/netsync/messages"
11 "github.com/vapor/protocol/bc"
12 "github.com/vapor/protocol/bc/types"
13 "github.com/vapor/testutil"
16 func TestRegularBlockSync(t *testing.T) {
17 baseChain := mockBlocks(nil, 50)
18 chainX := append(baseChain, mockBlocks(baseChain[50], 60)...)
19 chainY := append(baseChain, mockBlocks(baseChain[50], 70)...)
20 chainZ := append(baseChain, mockBlocks(baseChain[50], 200)...)
23 syncTimeout time.Duration
24 aBlocks []*types.Block
25 bBlocks []*types.Block
30 syncTimeout: 30 * time.Second,
31 aBlocks: baseChain[:20],
32 bBlocks: baseChain[:50],
37 syncTimeout: 30 * time.Second,
44 syncTimeout: 30 * time.Second,
51 syncTimeout: 30 * time.Second,
59 for i, c := range cases {
60 syncTimeout = c.syncTimeout
61 a := mockSync(c.aBlocks, nil)
62 b := mockSync(c.bBlocks, nil)
63 netWork := NewNetWork()
64 netWork.Register(a, "192.168.0.1", "test node A", consensus.SFFullNode)
65 netWork.Register(b, "192.168.0.2", "test node B", consensus.SFFullNode)
66 if B2A, A2B, err := netWork.HandsShake(a, b); err != nil {
67 t.Errorf("fail on peer hands shake %v", err)
73 a.blockKeeper.syncPeer = a.peers.GetPeer("test node B")
74 if err := a.blockKeeper.regularBlockSync(); errors.Root(err) != c.err {
75 t.Errorf("case %d: got %v want %v", i, err, c.err)
78 got := []*types.Block{}
79 for i := uint64(0); i <= a.chain.BestBlockHeight(); i++ {
80 block, err := a.chain.GetBlockByHeight(i)
82 t.Errorf("case %d got err %v", i, err)
84 got = append(got, block)
87 if !testutil.DeepEqual(got, c.want) {
88 t.Errorf("case %d: got %v want %v", i, got, c.want)
93 func TestRequireBlock(t *testing.T) {
94 blocks := mockBlocks(nil, 5)
95 a := mockSync(blocks[:1], nil)
96 b := mockSync(blocks[:5], nil)
97 netWork := NewNetWork()
98 netWork.Register(a, "192.168.0.1", "test node A", consensus.SFFullNode)
99 netWork.Register(b, "192.168.0.2", "test node B", consensus.SFFullNode)
100 if B2A, A2B, err := netWork.HandsShake(a, b); err != nil {
101 t.Errorf("fail on peer hands shake %v", err)
107 a.blockKeeper.syncPeer = a.peers.GetPeer("test node B")
108 b.blockKeeper.syncPeer = b.peers.GetPeer("test node A")
110 syncTimeout time.Duration
117 syncTimeout: 30 * time.Second,
124 syncTimeout: 1 * time.Millisecond,
128 err: errRequestTimeout,
132 for i, c := range cases {
133 syncTimeout = c.syncTimeout
134 got, err := c.testNode.blockKeeper.msgFetcher.requireBlock(c.testNode.blockKeeper.syncPeer.ID(), c.requireHeight)
135 if !testutil.DeepEqual(got, c.want) {
136 t.Errorf("case %d: got %v want %v", i, got, c.want)
138 if errors.Root(err) != c.err {
139 t.Errorf("case %d: got %v want %v", i, err, c.err)
144 func TestSendMerkleBlock(t *testing.T) {
151 relatedTxIndex: []int{0, 2, 5},
155 relatedTxIndex: []int{},
159 relatedTxIndex: []int{},
163 relatedTxIndex: []int{0, 1, 2, 3, 4},
167 relatedTxIndex: []int{1, 6, 3, 9, 10, 19},
171 for _, c := range cases {
172 blocks := mockBlocks(nil, 2)
173 targetBlock := blocks[1]
174 txs, bcTxs := mockTxs(c.txCount)
177 targetBlock.Transactions = txs
178 if targetBlock.TransactionsMerkleRoot, err = types.TxMerkleRoot(bcTxs); err != nil {
182 spvNode := mockSync(blocks, nil)
183 blockHash := targetBlock.Hash()
184 var statusResult *bc.TransactionStatus
185 if statusResult, err = spvNode.chain.GetTransactionStatus(&blockHash); err != nil {
189 if targetBlock.TransactionStatusHash, err = types.TxStatusMerkleRoot(statusResult.VerifyStatus); err != nil {
193 fullNode := mockSync(blocks, nil)
194 netWork := NewNetWork()
195 netWork.Register(spvNode, "192.168.0.1", "spv_node", consensus.SFFastSync)
196 netWork.Register(fullNode, "192.168.0.2", "full_node", consensus.DefaultServices)
199 if F2S, _, err = netWork.HandsShake(spvNode, fullNode); err != nil {
200 t.Errorf("fail on peer hands shake %v", err)
203 completed := make(chan error)
205 msgBytes := <-F2S.msgCh
206 _, msg, _ := decodeMessage(msgBytes)
207 switch m := msg.(type) {
208 case *msgs.MerkleBlockMessage:
209 var relatedTxIDs []*bc.Hash
210 for _, rawTx := range m.RawTxDatas {
212 if err := tx.UnmarshalText(rawTx); err != nil {
216 relatedTxIDs = append(relatedTxIDs, &tx.ID)
218 var txHashes []*bc.Hash
219 for _, hashByte := range m.TxHashes {
220 hash := bc.NewHash(hashByte)
221 txHashes = append(txHashes, &hash)
223 if ok := types.ValidateTxMerkleTreeProof(txHashes, m.Flags, relatedTxIDs, targetBlock.TransactionsMerkleRoot); !ok {
224 completed <- errors.New("validate tx fail")
227 var statusHashes []*bc.Hash
228 for _, statusByte := range m.StatusHashes {
229 hash := bc.NewHash(statusByte)
230 statusHashes = append(statusHashes, &hash)
232 var relatedStatuses []*bc.TxVerifyResult
233 for _, statusByte := range m.RawTxStatuses {
234 status := &bc.TxVerifyResult{}
235 err := json.Unmarshal(statusByte, status)
239 relatedStatuses = append(relatedStatuses, status)
241 if ok := types.ValidateStatusMerkleTreeProof(statusHashes, m.Flags, relatedStatuses, targetBlock.TransactionStatusHash); !ok {
242 completed <- errors.New("validate status fail")
249 spvPeer := fullNode.peers.GetPeer("spv_node")
250 for i := 0; i < len(c.relatedTxIndex); i++ {
251 spvPeer.AddFilterAddress(txs[c.relatedTxIndex[i]].Outputs[0].ControlProgram())
253 msg := &msgs.GetMerkleBlockMessage{RawHash: targetBlock.Hash().Byte32()}
254 fullNode.handleGetMerkleBlockMsg(spvPeer, msg)
255 if err := <-completed; err != nil {