github.com/turingchain2020/turingchain@v1.1.21/system/p2p/dht/protocol/p2pstore/p2pstore_test.go (about)

     1  package p2pstore
     2  
     3  import (
     4  	"context"
     5  	"encoding/hex"
     6  	"fmt"
     7  	"os"
     8  	"testing"
     9  	"time"
    10  
    11  	"github.com/turingchain2020/turingchain/client"
    12  	dbm "github.com/turingchain2020/turingchain/common/db"
    13  	"github.com/turingchain2020/turingchain/queue"
    14  	"github.com/turingchain2020/turingchain/system/p2p/dht/protocol"
    15  	types2 "github.com/turingchain2020/turingchain/system/p2p/dht/types"
    16  	"github.com/turingchain2020/turingchain/types"
    17  	"github.com/libp2p/go-libp2p"
    18  	"github.com/libp2p/go-libp2p-core/crypto"
    19  	"github.com/libp2p/go-libp2p-core/peer"
    20  	discovery "github.com/libp2p/go-libp2p-discovery"
    21  	dht "github.com/libp2p/go-libp2p-kad-dht"
    22  	kb "github.com/libp2p/go-libp2p-kbucket"
    23  	"github.com/multiformats/go-multiaddr"
    24  	"github.com/stretchr/testify/require"
    25  )
    26  
    27  const dataDir = "./datadir"
    28  
    29  func TestUpdateChunkWhiteList(t *testing.T) {
    30  	p := &Protocol{}
    31  
    32  	p.chunkWhiteList.Store("test1", time.Now())
    33  	p.chunkWhiteList.Store("test2", time.Now().Add(-time.Minute*11))
    34  	p.updateChunkWhiteList()
    35  	_, ok := p.chunkWhiteList.Load("test1")
    36  	require.True(t, ok)
    37  	_, ok = p.chunkWhiteList.Load("test2")
    38  	require.False(t, ok)
    39  }
    40  
    41  //HOST1 ID: Qma91H212PWtAFcioW7h9eKiosJtwHsb9x3RmjqRWTwciZ
    42  //HOST2 ID: QmbazrBU4HthhnQWcUTiJLnj5ihbFHXsAkGAG6QfmrqJDs
    43  func TestInit(t *testing.T) {
    44  	os.RemoveAll(dataDir)
    45  	defer os.RemoveAll(dataDir)
    46  	protocol.ClearEventHandler()
    47  	var err error
    48  	q := queue.New("test")
    49  	p2 := initEnv(t, q)
    50  	time.Sleep(time.Second * 1)
    51  	msgCh := initMockBlockchain(q)
    52  	client := q.Client()
    53  	//client用来模拟blockchain模块向p2p模块发消息,host1接收topic为p2p的消息,host2接收topic为p2p2的消息
    54  	//向host1请求数据
    55  	msg := testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
    56  		ChunkHash: []byte("test0"),
    57  		Start:     0,
    58  		End:       999,
    59  	})
    60  	require.False(t, msg.Data.(*types.Reply).IsOk, msg)
    61  	//向host2请求数据
    62  	msg = testGetBody(t, client, "p2p2", &types.ChunkInfoMsg{
    63  		ChunkHash: []byte("test0"),
    64  		Start:     500,
    65  		End:       999,
    66  	})
    67  	require.False(t, msg.Data.(*types.Reply).IsOk, msg)
    68  
    69  	// 通知host2保存数据
    70  	testStoreChunk(t, client, "p2p2", &types.ChunkInfoMsg{
    71  		ChunkHash: []byte("test0"),
    72  		Start:     0,
    73  		End:       999,
    74  	})
    75  	time.Sleep(time.Second / 2)
    76  	p2.republish()
    77  	//数据保存之后应该可以查到数据了
    78  	time.Sleep(time.Second / 2)
    79  
    80  	//向host1请求BlockBody
    81  	msg = testGetBody(t, client, "p2p2", &types.ChunkInfoMsg{
    82  		ChunkHash: []byte("test0"),
    83  		Start:     0,
    84  		End:       99,
    85  	})
    86  
    87  	require.Equal(t, 100, len(msg.Data.(*types.BlockBodys).Items))
    88  	//向host2请求BlockBody
    89  	msg = testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
    90  		ChunkHash: []byte("test0"),
    91  		Start:     666,
    92  		End:       888,
    93  	})
    94  	bodys := msg.Data.(*types.BlockBodys).Items
    95  	require.Equal(t, 223, len(bodys))
    96  	require.Equal(t, int64(666), bodys[0].Height)
    97  	require.Equal(t, int64(888), bodys[222].Height)
    98  
    99  	//向host1请求数据
   100  	msg = testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
   101  		ChunkHash: []byte("test1"),
   102  		Start:     1000,
   103  		End:       1999,
   104  	})
   105  	require.False(t, msg.Data.(*types.Reply).IsOk, msg)
   106  	//向host2请求数据
   107  	msg = testGetBody(t, client, "p2p2", &types.ChunkInfoMsg{
   108  		ChunkHash: []byte("test1"),
   109  		Start:     1500,
   110  		End:       1999,
   111  	})
   112  	require.False(t, msg.Data.(*types.Reply).IsOk, msg)
   113  
   114  	//向host1请求Block
   115  	testGetBlock(t, client, "p2p", &types.ChunkInfoMsg{
   116  		ChunkHash: []byte("test0"),
   117  		Start:     0,
   118  		End:       499,
   119  	})
   120  	msg = <-msgCh
   121  	require.Equal(t, 500, len(msg.Data.(*types.Blocks).Items))
   122  
   123  	//向host2请求Block
   124  	testGetBlock(t, client, "p2p2", &types.ChunkInfoMsg{
   125  		ChunkHash: []byte("test0"),
   126  		Start:     111,
   127  		End:       666,
   128  	})
   129  	msg = <-msgCh
   130  	require.Equal(t, 556, len(msg.Data.(*types.Blocks).Items))
   131  	//向host1请求Records
   132  	testGetRecord(t, client, "p2p", &types.ReqChunkRecords{
   133  		Start: 1,
   134  		End:   100,
   135  	})
   136  	msg = <-msgCh
   137  	require.Equal(t, 100, len(msg.Data.(*types.ChunkRecords).Infos))
   138  
   139  	//向host2请求Records
   140  	testGetRecord(t, client, "p2p", &types.ReqChunkRecords{
   141  		Start: 50,
   142  		End:   60,
   143  	})
   144  	msg = <-msgCh
   145  	require.Equal(t, 11, len(msg.Data.(*types.ChunkRecords).Infos))
   146  
   147  	//保存4000~4999的block,会检查0~3999的blockchunk是否能查到
   148  	// 通知host1保存数据
   149  	testStoreChunk(t, client, "p2p", &types.ChunkInfoMsg{
   150  		ChunkHash: []byte("test4"),
   151  		Start:     4000,
   152  		End:       4999,
   153  	})
   154  	time.Sleep(time.Second / 2)
   155  	//数据保存之后应该可以查到数据了
   156  
   157  	//向host1请求BlockBody
   158  	msg = testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
   159  		ChunkHash: []byte("test2"),
   160  		Start:     2000,
   161  		End:       2999,
   162  	})
   163  	require.Equal(t, 1000, len(msg.Data.(*types.BlockBodys).Items))
   164  	msg = testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
   165  		ChunkHash: []byte("test1"),
   166  		Start:     1000,
   167  		End:       1999,
   168  	})
   169  	require.Equal(t, 1000, len(msg.Data.(*types.BlockBodys).Items))
   170  	msg = testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
   171  		ChunkHash: []byte("test2"),
   172  		Start:     2000,
   173  		End:       2999,
   174  	})
   175  	require.Equal(t, 1000, len(msg.Data.(*types.BlockBodys).Items))
   176  	msg = testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
   177  		ChunkHash: []byte("test3"),
   178  		Start:     3000,
   179  		End:       3999,
   180  	})
   181  	require.Equal(t, 1000, len(msg.Data.(*types.BlockBodys).Items))
   182  	msg = testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
   183  		ChunkHash: []byte("test4"),
   184  		Start:     4000,
   185  		End:       4999,
   186  	})
   187  	require.Equal(t, 1000, len(msg.Data.(*types.BlockBodys).Items))
   188  	//向host2请求BlockBody
   189  	msg = testGetBody(t, client, "p2p2", &types.ChunkInfoMsg{
   190  		ChunkHash: []byte("test1"),
   191  		Start:     1666,
   192  		End:       1888,
   193  	})
   194  	require.Equal(t, 223, len(msg.Data.(*types.BlockBodys).Items))
   195  
   196  	err = p2.deleteChunkBlock([]byte("test1"))
   197  	if err != nil {
   198  		t.Fatal(err)
   199  	}
   200  	//向host2请求BlockBody
   201  	msg = testGetBody(t, client, "p2p2", &types.ChunkInfoMsg{
   202  		ChunkHash: []byte("test1"),
   203  		Start:     1000,
   204  		End:       1999,
   205  	})
   206  	require.Equal(t, 1000, len(msg.Data.(*types.BlockBodys).Items))
   207  
   208  	testGetHeaders(t, client, "p2p", &types.ReqBlocks{
   209  		Start: 100,
   210  		End:   199,
   211  		Pid:   []string{p2.Host.ID().Pretty()},
   212  	})
   213  	msg = <-msgCh
   214  	require.Equal(t, p2.Host.ID().Pretty(), msg.Data.(*types.HeadersPid).GetPid())
   215  	require.Equal(t, 100, len(msg.Data.(*types.HeadersPid).GetHeaders().Items))
   216  }
   217  
   218  func TestFullNode(t *testing.T) {
   219  	os.RemoveAll(dataDir)
   220  	defer os.RemoveAll(dataDir)
   221  	protocol.ClearEventHandler()
   222  	q := queue.New("test")
   223  	p2 := initFullNode(t, q)
   224  	time.Sleep(time.Second * 1)
   225  	_ = p2
   226  	msgCh := initMockBlockchain(q)
   227  	client := q.Client()
   228  	//client用来模拟blockchain模块向p2p模块发消息,host1接收topic为p2p的消息,host2接收topic为p2p2的消息
   229  	//向host1请求数据
   230  	msg := testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
   231  		ChunkHash: []byte("test0"),
   232  		Start:     0,
   233  		End:       999,
   234  	})
   235  	require.False(t, msg.Data.(*types.Reply).IsOk, msg)
   236  	//向host2请求数据
   237  	msg = testGetBody(t, client, "p2p3", &types.ChunkInfoMsg{
   238  		ChunkHash: []byte("test0"),
   239  		Start:     500,
   240  		End:       999,
   241  	})
   242  	require.False(t, msg.Data.(*types.Reply).IsOk, msg)
   243  
   244  	// 通知host3保存数据
   245  	testStoreChunk(t, client, "p2p3", &types.ChunkInfoMsg{
   246  		ChunkHash: []byte("test0"),
   247  		Start:     0,
   248  		End:       999,
   249  	})
   250  	testStoreChunk(t, client, "p2p3", &types.ChunkInfoMsg{
   251  		ChunkHash: []byte("test1"),
   252  		Start:     1000,
   253  		End:       1999,
   254  	})
   255  	testStoreChunk(t, client, "p2p3", &types.ChunkInfoMsg{
   256  		ChunkHash: []byte("test2"),
   257  		Start:     2000,
   258  		End:       2999,
   259  	})
   260  	time.Sleep(time.Second / 2)
   261  	//向host1请求BlockBody
   262  	msg = testGetBody(t, client, "p2p", &types.ChunkInfoMsg{
   263  		ChunkHash: []byte("test0"),
   264  		Start:     0,
   265  		End:       99,
   266  	})
   267  	require.Equal(t, 100, len(msg.Data.(*types.BlockBodys).Items))
   268  	//向host2请求BlockBody
   269  	msg = testGetBody(t, client, "p2p3", &types.ChunkInfoMsg{
   270  		ChunkHash: []byte("test0"),
   271  		Start:     666,
   272  		End:       888,
   273  	})
   274  	require.Equal(t, 223, len(msg.Data.(*types.BlockBodys).Items))
   275  
   276  	//向host1请求Block
   277  	testGetBlock(t, client, "p2p", &types.ChunkInfoMsg{
   278  		ChunkHash: []byte("test0"),
   279  		Start:     0,
   280  		End:       499,
   281  	})
   282  	msg = <-msgCh
   283  	require.Equal(t, 500, len(msg.Data.(*types.Blocks).Items))
   284  
   285  	//向host2请求Block
   286  	testGetBlock(t, client, "p2p3", &types.ChunkInfoMsg{
   287  		ChunkHash: []byte("test0"),
   288  		Start:     111,
   289  		End:       666,
   290  	})
   291  	msg = <-msgCh
   292  	require.Equal(t, 556, len(msg.Data.(*types.Blocks).Items))
   293  }
   294  
   295  func testStoreChunk(t *testing.T, client queue.Client, topic string, req *types.ChunkInfoMsg) *queue.Message {
   296  	msg := client.NewMessage(topic, types.EventNotifyStoreChunk, req)
   297  	err := client.Send(msg, false)
   298  	if err != nil {
   299  		t.Fatal(err)
   300  	}
   301  	return msg
   302  }
   303  
   304  func testGetBody(t *testing.T, client queue.Client, topic string, req *types.ChunkInfoMsg) *queue.Message {
   305  	msg := client.NewMessage(topic, types.EventGetChunkBlockBody, req)
   306  	err := client.Send(msg, true)
   307  	if err != nil {
   308  		t.Fatal(err)
   309  	}
   310  	msg, err = client.Wait(msg)
   311  	if err != nil {
   312  		t.Fatal(err)
   313  	}
   314  	return msg
   315  }
   316  
   317  func testGetBlock(t *testing.T, client queue.Client, topic string, req *types.ChunkInfoMsg) *queue.Message {
   318  	msg := client.NewMessage(topic, types.EventGetChunkBlock, req)
   319  	err := client.Send(msg, false)
   320  	if err != nil {
   321  		t.Fatal(err)
   322  	}
   323  	return msg
   324  }
   325  
   326  func testGetRecord(t *testing.T, client queue.Client, topic string, req *types.ReqChunkRecords) *queue.Message {
   327  	msg := client.NewMessage(topic, types.EventGetChunkRecord, req)
   328  	err := client.Send(msg, false)
   329  	if err != nil {
   330  		t.Fatal(err)
   331  	}
   332  	return msg
   333  }
   334  
   335  func testGetHeaders(t *testing.T, client queue.Client, topic string, req *types.ReqBlocks) *queue.Message {
   336  	msg := client.NewMessage(topic, types.EventFetchBlockHeaders, req)
   337  	err := client.Send(msg, true)
   338  	if err != nil {
   339  		t.Fatal(err)
   340  	}
   341  	msg, err = client.Wait(msg)
   342  	if err != nil {
   343  		t.Fatal(err)
   344  	}
   345  	return msg
   346  }
   347  
   348  func initMockBlockchain(q queue.Queue) <-chan *queue.Message {
   349  	client := q.Client()
   350  	client.Sub("blockchain")
   351  	ch := make(chan *queue.Message)
   352  	go func() {
   353  		for msg := range client.Recv() {
   354  			switch msg.Ty {
   355  			case types.EventIsSync:
   356  				msg.Reply(queue.NewMessage(0, "", 0, &types.IsCaughtUp{Iscaughtup: true}))
   357  			case types.EventGetLastHeader:
   358  				msg.Reply(queue.NewMessage(0, "", 0, &types.Header{Height: 14000}))
   359  			case types.EventGetChunkBlockBody:
   360  				req := msg.Data.(*types.ChunkInfoMsg)
   361  				bodys := &types.BlockBodys{Items: make([]*types.BlockBody, 0, req.End-req.Start+1)}
   362  				for i := req.Start; i <= req.End; i++ {
   363  					bodys.Items = append(bodys.Items, &types.BlockBody{
   364  						Height: i,
   365  					})
   366  				}
   367  				msg.Reply(queue.NewMessage(0, "", 0, bodys))
   368  			case types.EventGetHeaders:
   369  				req := msg.Data.(*types.ReqBlocks)
   370  				items := make([]*types.Header, 0, req.End-req.Start+1)
   371  				for i := req.Start; i <= req.End; i++ {
   372  					items = append(items, &types.Header{
   373  						Height: i,
   374  					})
   375  				}
   376  				headers := &types.Headers{
   377  					Items: items,
   378  				}
   379  				msg.Reply(queue.NewMessage(0, "", 0, headers))
   380  			case types.EventGetChunkRecord:
   381  				req := msg.Data.(*types.ReqChunkRecords)
   382  				records := types.ChunkRecords{}
   383  				for i := req.Start; i <= req.End; i++ {
   384  					records.Infos = append(records.Infos, &types.ChunkInfo{
   385  						ChunkHash: []byte(fmt.Sprintf("test%d", i)),
   386  						Start:     i * 1000,
   387  						End:       i*1000 + 999,
   388  					})
   389  				}
   390  				msg.Reply(&queue.Message{Data: &records})
   391  			default:
   392  				msg.Reply(&queue.Message{})
   393  				ch <- msg
   394  			}
   395  		}
   396  	}()
   397  
   398  	return ch
   399  }
   400  
   401  func initEnv(t *testing.T, q queue.Queue) *Protocol {
   402  	privkey1 := "080012a709308204a30201000282010100a28d698a090b02222f97c928b45e78821a87b6382b5057ec9cf12331da3fd8a1c6c71731a8075ae41383460908b483585676f4312249de6929423c2c5d7865bb28d50c5a57e7cad3cc7ca2ddcbc486ac0260fe68e4cdff7f86e46ac65403baf6a5ef50ce7cbb9d0f5f23b02fcc6d5211e2df2bf24fc84565ba5d0777458ad82b46579cba0a16c88ff946812e7f17ad85a2b35dc1bae732a74f83262358fefcc985a632aee8129a73d1d17aaceebd5bae9ffbeab6c5505e8eafd8af8448a6dd74d76885bc71c7d85bad761680bc7cdd04a99cb90d8c27467769c500e603677469a73cec7983a7dba6d7656ab241b4446355a89a267eeb72f0fd7c89c470d93a6302030100010282010002db797f73a93de05bf5cf136818410608715a42a280470b61b6db6784ee9a603d9e424a1d2a03eefe68d0525854d3fa398addbfff5a4d0e8c2b1de3a9c0f408d62ee888ae02e50dd40a5cd289426b1b9aef1989be7be081dd5d268355f6bad29b1819d3875dc4e500472051b6c6352b1b51d0f3f17313c536016ca02c18c4b3f6dba52c616f93bf831589d0dd2fc190f875e37a4e9654bd9e63e04fc5d9cea45664cd6d26c17659ee4b8c6837c6dfe86e4e6b8e17af332a736267ee5a68ac0b0c60ced47f1aaf7ec65547f664a9f1409e7d116ca325c29b1058e5892dc04c79337a15b875e7139bca7ddfb6c5c7f822adff8cd65f1dfa84d1b0f87166604c0102818100c5694c5a55465a068075e5274ca926615632ef710917f4a2ece4b4108041ea6dc99ee244d97d1a687c5f6879a97df6685346d7fff315bb3be008c787f67ad9934563127b07511f57ac72be2f7771a9e29b67a022e12567be3591c033a0202e44742429e3266709f17e79c1caa4618f0e5c37a6d3f238f92f33539be7aa5beee502818100d2cba3ec75b664129ecdbe29324b3fde83ddc7291fe3d6073ebb2db508632f370f54affae7c7ebbc143a5c07ac8f7734eb2f537d3662e4bc05d80eed942a94d5084683dac388cfcd601c9cd59330ff021cf18fa618b25e8a5351f2036f65007a8b4162058f2242d953379d349d9a484c800e8ae539f3e3cd4c6dc9c7b455a7a70281806d790a2d61f2a483cc831473a9b077a72cbd0c493bc8bc12099a7e3c5453b963ee961c561fe19f5e67f224a6ab163e29f65c67f5f8e0893717f2e66b8084f9d91076734e246d991aee77a6fdfd97dba4dd9726979111442997dd5e9f8261b626a1dd58192e379facfafd1c397ad4db17148e8c0626e1ef557c7a160fef4a11fd028180555c679e3ab0c8678ded4d034bbd93389d77b2cde17f16cdca466c24f227901820da2f855054f20e30b6cd4bc2423a88b07072c3b2c16b55049cd0b6be985bbac4e62140f68bb172be67f7ceb9134f40e0cda559228920a5ad45f2d61746f461ab80a79c0eb15616c18f34d6f8b7606db231b167500786893d58fc2c25c7c5e302818100ad587bed92aef2dedb19766c72e5caeadf1f7226d2c3ed0c6ffd1e885b665f55df63d54f91d2fb3f2c4e608bc16bc70eec6300ec5fe61cd31dd48c19544058d1fbb3e39e09117b6e8ab0cc832c481b1c364fbce5b07bf681a0af8e554bef3017dfd53197b87bcebf080fbaef42df5f51c900148499fa7be9e05640dc79d04ad8"
   403  	b1, _ := hex.DecodeString(privkey1)
   404  	sk1, _ := crypto.UnmarshalPrivateKey(b1)
   405  	privkey2 := "080012aa09308204a60201000282010100edc5cda732934aee4df8926b9520f3bc4e6b7e3232bb2b496ce591704b86684cbddf645b4b8dda506e2676801b9c43006607b5bad1835de65fe7e4b6f470210eec172eff4ebb6a88d930e9656d30b01fa01f57ccb9d280b284f0786ca0d3ebbe47346c2ab7c815067fe089cf7b2ce0968e50b0892533f7a3d0c8b7ca4b8884efd8731b455762b4298a89393a468ac3b0ace8ea8d89a683ba09b3312f608c4bc439aeef282150c32a2e92b4f80ab6153471900e3ca1a694ade8e589a5e89aa9274dd7df033c9b7c5f2b61b2dcc2e740f2709ed17908626fe55d59dd93433e623eff5e576949608e7f772eddf0bf5bd6044969f9018e6ad91a1b91a07192decff9020301000102820101008f8a76589583ae1ca71d84e745a41b007727158c206c35f9a1b00559117f16c01d701b19b246f4a0d19e8eb34ff7c9cb17cd57bc6c772ddcc1d13095f2832eb1df7d2f761985b30ee26f50b7566faa23ad7abe7a6d43d345f253699fca87a52dbdb6bc061de4c02ca84e5963d42c8778dc7981d9898811dbe75305012f103f8f91d52803513bbc294fbb86fc8852398a8e358513de1935202d38bc55ddfa05e592851e278309b2df6240f8abb4f411997baefc8f4652ac75a29c9faf9b39d53c3f19dcd8843e311344ca0ac4dea77da719972c025dbb114e6e5c8f690a4db8ccf27493db3977a6a8c0db968307c16ab9f8e8671793e18382d08744505687100102818100f09ef4e9249f4d640d9dbf29d6308c1eab87056564f0d5c820b8b15ea8112278be1b61a7492298d503872e493e1da0a5c99f422035cb203575c0b14e636ae54b3a4c707370b061196dc5f7169fa753e79092aa30fc40d08acbad4a28f35fb55b505ef0e917e8d3e1edb2bfcbaba119e28d1ceb3383e99b4fcf5e1428a9a5717902818100fcf83e52eca79ef469b5ba5ae15c9cafcc1dd46d908712202c0f1e040e47f100fdc59ab998a1c4b66663f245372df5b2ef3788140450f11744b9015d10ea30e337b6d62704ca2d0b42ca0a19ad0b33bc53eed19367a426f764138c9fb219b7df3c96be79b0319d0e2ddc24fc95305a61050a4dcfbae2682199082a03524f328102818100e9cf6be808400b7187919b29ca098e7e56ea72a1ddfdef9df1bdc60c567f9fe177c91f90f00e00382c9f74a89305330f25e5ecd963ac27760b1fdcaa710c74162f660b77012f428af5120251277dee97faf1a912c46b2eb94fc4e964f56830cfb43f2d1532b878faf68054c251d9cf4f4713acb07823cd59360512cd985b3cf102818100c79822ac9116ec5f122d15bd7104fe87e27842ccb3f52ec2fda06be16d572bfbc93f298678bc62963c116ded58cd45880a20f998399397b5f13e3baa2f97683d4f0f4ec6f88b80a0daf0c8a95b94741c8ae8eaa8f0645f6e60a2e0187c90b83845f8f68ed30b424d16b814e2c9df9ddfe0f7314fceb7a6cba390027e1e6a688102818100a9f015ca2223e7af4cddc53811efb583af65128ad9e0da28166634c41c36ada04cd5ae25e48bf53b5b8a596f3d714516a59b86ba9b37ff22d67200a75a4b7dae13406083ce74c9478474e36e73066e524d0ccd991719af60066a0e15001b8eaf7561458eb8d2982222da3d10eb7d23df3a9f3ef3c52921d26ad44c8780bfd379"
   406  	b2, _ := hex.DecodeString(privkey2)
   407  	sk2, _ := crypto.UnmarshalPrivateKey(b2)
   408  	client1, client2 := q.Client(), q.Client()
   409  	m1, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 13806))
   410  	if err != nil {
   411  		t.Fatal(err)
   412  	}
   413  	host1, err := libp2p.New(context.Background(), libp2p.ListenAddrs(m1), libp2p.Identity(sk1))
   414  	if err != nil {
   415  		t.Fatal(err)
   416  	}
   417  	m2, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 13807))
   418  	if err != nil {
   419  		t.Fatal(err)
   420  	}
   421  	host2, err := libp2p.New(context.Background(), libp2p.ListenAddrs(m2), libp2p.Identity(sk2))
   422  	if err != nil {
   423  		t.Fatal(err)
   424  	}
   425  
   426  	cfg := types.NewTuringchainConfig(types.ReadFile("../../../../../cmd/turingchain/turingchain.test.toml"))
   427  	mcfg := &types2.P2PSubConfig{}
   428  	types.MustDecode(cfg.GetSubConfig().P2P[types2.DHTTypeName], mcfg)
   429  	mcfg.DisableFindLANPeers = true
   430  	kademliaDHT1, err := dht.New(context.Background(), host1)
   431  	if err != nil {
   432  		panic(err)
   433  	}
   434  	mockAPI1, err := client.New(client1, nil)
   435  	if err != nil {
   436  		panic(err)
   437  	}
   438  	env1 := protocol.P2PEnv{
   439  		Ctx:              context.Background(),
   440  		ChainCfg:         cfg,
   441  		API:              mockAPI1,
   442  		QueueClient:      client1,
   443  		Host:             host1,
   444  		SubConfig:        mcfg,
   445  		RoutingDiscovery: discovery.NewRoutingDiscovery(kademliaDHT1),
   446  		RoutingTable:     kademliaDHT1.RoutingTable(),
   447  		PeerInfoManager:  &peerInfoManager{},
   448  		DB:               dbm.NewDB("p2pstore1", "leveldb", dataDir, 128),
   449  	}
   450  	InitProtocol(&env1)
   451  
   452  	kademliaDHT2, err := dht.New(context.Background(), host2)
   453  	if err != nil {
   454  		panic(err)
   455  	}
   456  
   457  	mockAPI2, err := client.New(client2, nil)
   458  	if err != nil {
   459  		panic(err)
   460  	}
   461  	env2 := protocol.P2PEnv{
   462  		Ctx:              context.Background(),
   463  		ChainCfg:         cfg,
   464  		API:              mockAPI2,
   465  		QueueClient:      client2,
   466  		Host:             host2,
   467  		SubConfig:        mcfg,
   468  		RoutingDiscovery: discovery.NewRoutingDiscovery(kademliaDHT2),
   469  		RoutingTable:     kademliaDHT2.RoutingTable(),
   470  		PeerInfoManager:  &peerInfoManager{},
   471  		DB:               dbm.NewDB("p2pstore2", "leveldb", dataDir, 128),
   472  	}
   473  	p2 := &Protocol{
   474  		P2PEnv:                   &env2,
   475  		ShardHealthyRoutingTable: kb.NewRoutingTable(dht.KValue, kb.ConvertPeerID(env2.Host.ID()), time.Minute, env2.Host.Peerstore()),
   476  		localChunkInfo:           make(map[string]LocalChunkInfo),
   477  		notifyingQueue:           make(chan *types.ChunkInfoMsg, 100),
   478  	}
   479  	go p2.updateShardHealthyRoutingTableRoutine()
   480  	//注册p2p通信协议,用于处理节点之间请求
   481  	protocol.RegisterStreamHandler(p2.Host, getHeaderOld, p2.handleStreamGetHeaderOld)
   482  	protocol.RegisterStreamHandler(p2.Host, fetchShardPeer, protocol.HandlerWithRW(p2.handleStreamFetchShardPeers))
   483  	protocol.RegisterStreamHandler(p2.Host, fullNode, protocol.HandlerWithWrite(p2.handleStreamIsFullNode))
   484  	protocol.RegisterStreamHandler(p2.Host, fetchChunk, p2.handleStreamFetchChunk) //数据较大,采用特殊写入方式
   485  	protocol.RegisterStreamHandler(p2.Host, storeChunk, protocol.HandlerWithAuth(p2.handleStreamStoreChunks))
   486  	protocol.RegisterStreamHandler(p2.Host, getHeader, protocol.HandlerWithAuthAndSign(p2.handleStreamGetHeader))
   487  	protocol.RegisterStreamHandler(p2.Host, getChunkRecord, protocol.HandlerWithAuthAndSign(p2.handleStreamGetChunkRecord))
   488  
   489  	go p2.syncRoutine()
   490  	addr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/13806/p2p/%s", host1.ID().Pretty()))
   491  	peerinfo, _ := peer.AddrInfoFromP2pAddr(addr)
   492  	err = host2.Connect(context.Background(), *peerinfo)
   493  	require.Nil(t, err)
   494  	err = kademliaDHT2.Bootstrap(context.Background())
   495  	require.Nil(t, err)
   496  
   497  	client1.Sub("p2p")
   498  	client2.Sub("p2p2")
   499  	go func() {
   500  		for msg := range client1.Recv() {
   501  			protocol.GetEventHandler(msg.Ty)(msg)
   502  		}
   503  	}()
   504  	go func() {
   505  		for msg := range client2.Recv() {
   506  			switch msg.Ty {
   507  			case types.EventNotifyStoreChunk:
   508  				protocol.EventHandlerWithRecover(p2.handleEventNotifyStoreChunk)(msg)
   509  			case types.EventGetChunkBlock:
   510  				protocol.EventHandlerWithRecover(p2.handleEventGetChunkBlock)(msg)
   511  			case types.EventGetChunkBlockBody:
   512  				protocol.EventHandlerWithRecover(p2.handleEventGetChunkBlockBody)(msg)
   513  			case types.EventGetChunkRecord:
   514  				protocol.EventHandlerWithRecover(p2.handleEventGetChunkRecord)(msg)
   515  			}
   516  		}
   517  	}()
   518  
   519  	return p2
   520  }
   521  
   522  func initFullNode(t *testing.T, q queue.Queue) *Protocol {
   523  	privkey1 := "080012a709308204a30201000282010100a28d698a090b02222f97c928b45e78821a87b6382b5057ec9cf12331da3fd8a1c6c71731a8075ae41383460908b483585676f4312249de6929423c2c5d7865bb28d50c5a57e7cad3cc7ca2ddcbc486ac0260fe68e4cdff7f86e46ac65403baf6a5ef50ce7cbb9d0f5f23b02fcc6d5211e2df2bf24fc84565ba5d0777458ad82b46579cba0a16c88ff946812e7f17ad85a2b35dc1bae732a74f83262358fefcc985a632aee8129a73d1d17aaceebd5bae9ffbeab6c5505e8eafd8af8448a6dd74d76885bc71c7d85bad761680bc7cdd04a99cb90d8c27467769c500e603677469a73cec7983a7dba6d7656ab241b4446355a89a267eeb72f0fd7c89c470d93a6302030100010282010002db797f73a93de05bf5cf136818410608715a42a280470b61b6db6784ee9a603d9e424a1d2a03eefe68d0525854d3fa398addbfff5a4d0e8c2b1de3a9c0f408d62ee888ae02e50dd40a5cd289426b1b9aef1989be7be081dd5d268355f6bad29b1819d3875dc4e500472051b6c6352b1b51d0f3f17313c536016ca02c18c4b3f6dba52c616f93bf831589d0dd2fc190f875e37a4e9654bd9e63e04fc5d9cea45664cd6d26c17659ee4b8c6837c6dfe86e4e6b8e17af332a736267ee5a68ac0b0c60ced47f1aaf7ec65547f664a9f1409e7d116ca325c29b1058e5892dc04c79337a15b875e7139bca7ddfb6c5c7f822adff8cd65f1dfa84d1b0f87166604c0102818100c5694c5a55465a068075e5274ca926615632ef710917f4a2ece4b4108041ea6dc99ee244d97d1a687c5f6879a97df6685346d7fff315bb3be008c787f67ad9934563127b07511f57ac72be2f7771a9e29b67a022e12567be3591c033a0202e44742429e3266709f17e79c1caa4618f0e5c37a6d3f238f92f33539be7aa5beee502818100d2cba3ec75b664129ecdbe29324b3fde83ddc7291fe3d6073ebb2db508632f370f54affae7c7ebbc143a5c07ac8f7734eb2f537d3662e4bc05d80eed942a94d5084683dac388cfcd601c9cd59330ff021cf18fa618b25e8a5351f2036f65007a8b4162058f2242d953379d349d9a484c800e8ae539f3e3cd4c6dc9c7b455a7a70281806d790a2d61f2a483cc831473a9b077a72cbd0c493bc8bc12099a7e3c5453b963ee961c561fe19f5e67f224a6ab163e29f65c67f5f8e0893717f2e66b8084f9d91076734e246d991aee77a6fdfd97dba4dd9726979111442997dd5e9f8261b626a1dd58192e379facfafd1c397ad4db17148e8c0626e1ef557c7a160fef4a11fd028180555c679e3ab0c8678ded4d034bbd93389d77b2cde17f16cdca466c24f227901820da2f855054f20e30b6cd4bc2423a88b07072c3b2c16b55049cd0b6be985bbac4e62140f68bb172be67f7ceb9134f40e0cda559228920a5ad45f2d61746f461ab80a79c0eb15616c18f34d6f8b7606db231b167500786893d58fc2c25c7c5e302818100ad587bed92aef2dedb19766c72e5caeadf1f7226d2c3ed0c6ffd1e885b665f55df63d54f91d2fb3f2c4e608bc16bc70eec6300ec5fe61cd31dd48c19544058d1fbb3e39e09117b6e8ab0cc832c481b1c364fbce5b07bf681a0af8e554bef3017dfd53197b87bcebf080fbaef42df5f51c900148499fa7be9e05640dc79d04ad8"
   524  	b1, _ := hex.DecodeString(privkey1)
   525  	sk1, _ := crypto.UnmarshalPrivateKey(b1)
   526  	privkey3 := "080012a809308204a40201000282010100cdcc5ff051a4a30405620f971038997817e5f899db5ebb4f03ca744537ba29f0149dd71a47b8ac3523052809e14accb565507f2d70ae64686dd065950f3fbc8a84a8d692cda207e923363da1a5d4a7d6a8eb420a0d87d383649633c2feee147382083cc8e451b90f217b0920d9381ace0a769fdcf1b5a4c88e5aebe7213a18207f68f737d323235c0a8e61130230c5fe272d84ffa8ef01857e327f391d62e88d72bc8b9969dc40451b211962339c950ebab4d5fdaa407fc6905720b1cfedb4d7f6fc6ab66c6f7fb43c004c2ba22033e24c878d3e4472eb36e81e4beef9eb2b9b7a0746d69e75468d00e0c4a17bc2fb8eb1142538db67b512cb88464869f2f52b0203010001028201010083ba46ca8fa7bf448aa18af319c9f0ca031a0bb787c82a42d85d55711ccb879e89c3c274aae5d52ca9fed9f301071ce31b379c401cb933c1f8508545151ea9f34c18ba47fb61b48891265deac337cc3ac5a2d88190c99924a854d04b075ca3309051ef7e734eb012b44e89b841f1fc8e57fa3837776bda4f1977af3a21758b0cd2cac32e6db0aec3a72d4f2b076cdd42cfd806a5f73b26a9e70ef009aaf83f2e5cf31000055fa59a090aadfade3387b9315e4ff786436457a8d7bc70af3f17bd542b9faca50f3abab8cf392023c3b4e1b448040ae78610458f2a2df9f9d96037cb565eb6ab2f1407eebd3e538205bcd6519fe2e7419688d5cbf530c2a332449102818100cf82a445bef1625df4522a2ecd666f1bc5818f48cba6e3c6fdeb05d67a7aada71e5cf1424ea4aa9314b0388c29309b28ca18afd4c6b88ee7bd08333f2883d1f4ebf7ce17b1dd17bd30217031bb377e05d036afa75d844a4528dc8b304ee3a42554457c7efc380fc144fe6d112268739210b3a56f2cc9ffb0401db8a654909f2902818100fde35258ad69b1af5e80c4fbc241ac2899142297dea902324b6055f4aaa554f8fd9d9809ff402efbd2104aa0d632f0f73296b5a56c94260adf8aad4514cfa135260c03e7dd53c6a2bdb869b9edb873eb6e1482276a5a55e890e8a8d3db87f70f4271cd7c2582359342ec279acb6dcf714059bbf58540ea496a47675a2eb140330281804e566e779a16fc60a5cca2fa1a36b279547d8dbf188abf70af091ba21588dca7bb71b0eeac4bc3cd54c11607ebc0dac2725111880d213d69c4d624aa923bf97631e2d21de5daa68c986ff72fff127af3ecdfc83e31b2b06b1d7aecdce6db4f6b7c3de33af9329cd80498dc49dca87c00c7675a6bf707a70c3d983ace281c94c902818100ea64e98c772542672eaf61ad30ede29c649f6344a4cb91fc8efc74befaa0c32f512e22c4f003f89c829689dfad81c057e83b9d9e08fd4995f64598ac53875144b948947e8726a6176f628731a1980e6547eee52eb0909009b367291ed6e9d31d2271e08d02301178506ba830d02924406171b706f82c3360ee1ed7fb396a6963028180667b478c2e5759fd73000e13874295611812b689f96f32a2b6e876eea4b66e0b90123d86fb7320548c30ce3d5f45f9f00b9faa23228fe70e79f4215a8328062ba474a753bfed99c5bb0efc120856f25141b00181757e47f84ec4e63d54e81595585b22651a01d1c956fc7d5c3ce9d1f7f1355b5dba7d79ceacf9e3c7e9f6be5a"
   527  	b3, _ := hex.DecodeString(privkey3)
   528  	sk3, _ := crypto.UnmarshalPrivateKey(b3)
   529  	client1, client3 := q.Client(), q.Client()
   530  	m1, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 13808))
   531  	if err != nil {
   532  		t.Fatal(err)
   533  	}
   534  	host1, err := libp2p.New(context.Background(), libp2p.ListenAddrs(m1), libp2p.Identity(sk1))
   535  	if err != nil {
   536  		t.Fatal(err)
   537  	}
   538  
   539  	m3, err := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/%d", 13809))
   540  	if err != nil {
   541  		t.Fatal(err)
   542  	}
   543  	host3, err := libp2p.New(context.Background(), libp2p.ListenAddrs(m3), libp2p.Identity(sk3))
   544  	if err != nil {
   545  		t.Fatal(err)
   546  	}
   547  	cfg := types.NewTuringchainConfig(types.ReadFile("../../../../../cmd/turingchain/turingchain.test.toml"))
   548  	mcfg := &types2.P2PSubConfig{}
   549  	types.MustDecode(cfg.GetSubConfig().P2P[types2.DHTTypeName], mcfg)
   550  	mcfg.DisableFindLANPeers = true
   551  	kademliaDHT1, err := dht.New(context.Background(), host1)
   552  	if err != nil {
   553  		panic(err)
   554  	}
   555  	mockAPI1, err := client.New(client1, nil)
   556  	if err != nil {
   557  		panic(err)
   558  	}
   559  	env1 := protocol.P2PEnv{
   560  		Ctx:              context.Background(),
   561  		ChainCfg:         cfg,
   562  		API:              mockAPI1,
   563  		QueueClient:      client1,
   564  		Host:             host1,
   565  		SubConfig:        mcfg,
   566  		RoutingDiscovery: discovery.NewRoutingDiscovery(kademliaDHT1),
   567  		RoutingTable:     kademliaDHT1.RoutingTable(),
   568  		PeerInfoManager:  &peerInfoManager{},
   569  		DB:               dbm.NewDB("p2pstore1", "leveldb", dataDir, 128),
   570  	}
   571  	InitProtocol(&env1)
   572  
   573  	mcfg3 := &types2.P2PSubConfig{}
   574  	types.MustDecode(cfg.GetSubConfig().P2P[types2.DHTTypeName], mcfg3)
   575  	mcfg3.IsFullNode = true
   576  	mcfg3.DisableFindLANPeers = true
   577  
   578  	kademliaDHT3, err := dht.New(context.Background(), host3)
   579  	if err != nil {
   580  		panic(err)
   581  	}
   582  	addr, _ := multiaddr.NewMultiaddr(fmt.Sprintf("/ip4/127.0.0.1/tcp/13808/p2p/%s", host1.ID().Pretty()))
   583  	peerInfo, _ := peer.AddrInfoFromP2pAddr(addr)
   584  	err = host3.Connect(context.Background(), *peerInfo)
   585  	require.Nil(t, err)
   586  
   587  	mockAPI3, err := client.New(client3, nil)
   588  	if err != nil {
   589  		panic(err)
   590  	}
   591  	env3 := protocol.P2PEnv{
   592  		Ctx:              context.Background(),
   593  		ChainCfg:         cfg,
   594  		API:              mockAPI3,
   595  		QueueClient:      client3,
   596  		Host:             host3,
   597  		SubConfig:        mcfg3,
   598  		RoutingDiscovery: discovery.NewRoutingDiscovery(kademliaDHT3),
   599  		RoutingTable:     kademliaDHT3.RoutingTable(),
   600  		PeerInfoManager:  &peerInfoManager{},
   601  		DB:               dbm.NewDB("p2pstore3", "leveldb", dataDir, 128),
   602  	}
   603  	p3 := &Protocol{
   604  		P2PEnv:                   &env3,
   605  		ShardHealthyRoutingTable: kb.NewRoutingTable(dht.KValue, kb.ConvertPeerID(env3.Host.ID()), time.Minute, env3.Host.Peerstore()),
   606  		localChunkInfo:           make(map[string]LocalChunkInfo),
   607  		notifyingQueue:           make(chan *types.ChunkInfoMsg, 100),
   608  	}
   609  	//注册p2p通信协议,用于处理节点之间请求
   610  	protocol.RegisterStreamHandler(p3.Host, getHeaderOld, p3.handleStreamGetHeaderOld)
   611  	protocol.RegisterStreamHandler(p3.Host, fetchShardPeer, protocol.HandlerWithRW(p3.handleStreamFetchShardPeers))
   612  	protocol.RegisterStreamHandler(p3.Host, fullNode, protocol.HandlerWithWrite(p3.handleStreamIsFullNode))
   613  	protocol.RegisterStreamHandler(p3.Host, fetchChunk, p3.handleStreamFetchChunk) //数据较大,采用特殊写入方式
   614  	protocol.RegisterStreamHandler(p3.Host, storeChunk, protocol.HandlerWithAuth(p3.handleStreamStoreChunks))
   615  	protocol.RegisterStreamHandler(p3.Host, getHeader, protocol.HandlerWithAuthAndSign(p3.handleStreamGetHeader))
   616  	protocol.RegisterStreamHandler(p3.Host, getChunkRecord, protocol.HandlerWithAuthAndSign(p3.handleStreamGetChunkRecord))
   617  	go p3.syncRoutine()
   618  	discovery.Advertise(context.Background(), p3.RoutingDiscovery, fullNode)
   619  
   620  	client1.Sub("p2p")
   621  	client3.Sub("p2p3")
   622  	go func() {
   623  		for msg := range client1.Recv() {
   624  			protocol.GetEventHandler(msg.Ty)(msg)
   625  		}
   626  	}()
   627  
   628  	go func() {
   629  		for msg := range client3.Recv() {
   630  			switch msg.Ty {
   631  			case types.EventNotifyStoreChunk:
   632  				protocol.EventHandlerWithRecover(p3.handleEventNotifyStoreChunk)(msg)
   633  			case types.EventGetChunkBlock:
   634  				protocol.EventHandlerWithRecover(p3.handleEventGetChunkBlock)(msg)
   635  			case types.EventGetChunkBlockBody:
   636  				protocol.EventHandlerWithRecover(p3.handleEventGetChunkBlockBody)(msg)
   637  			case types.EventGetChunkRecord:
   638  				protocol.EventHandlerWithRecover(p3.handleEventGetChunkRecord)(msg)
   639  			}
   640  		}
   641  	}()
   642  
   643  	return p3
   644  }
   645  
   646  type peerInfoManager struct{}
   647  
   648  func (p *peerInfoManager) Refresh(info *types.Peer)      {}
   649  func (p *peerInfoManager) Fetch(pid peer.ID) *types.Peer { return nil }
   650  func (p *peerInfoManager) FetchAll() []*types.Peer       { return nil }
   651  func (p *peerInfoManager) PeerHeight(pid peer.ID) int64 {
   652  	return p.PeerMaxHeight()
   653  }
   654  
   655  func (p *peerInfoManager) PeerMaxHeight() int64 {
   656  	return 14000
   657  }