github.com/bytom/bytom@v1.1.2-0.20221014091027-bbcba3df6075/netsync/chainmgr/tx_keeper_test.go (about) 1 package chainmgr 2 3 import ( 4 "io/ioutil" 5 "os" 6 "reflect" 7 "testing" 8 "time" 9 10 "github.com/davecgh/go-spew/spew" 11 12 "github.com/bytom/bytom/consensus" 13 dbm "github.com/bytom/bytom/database/leveldb" 14 "github.com/bytom/bytom/protocol" 15 core "github.com/bytom/bytom/protocol" 16 "github.com/bytom/bytom/protocol/bc" 17 "github.com/bytom/bytom/protocol/bc/types" 18 "github.com/bytom/bytom/test/mock" 19 "github.com/bytom/bytom/testcontrol" 20 ) 21 22 const txsNumber = 2000 23 24 type mempool struct { 25 } 26 27 func (m *mempool) GetTransactions() []*core.TxDesc { 28 txs := []*core.TxDesc{} 29 for i := 0; i < txsNumber; i++ { 30 txInput := types.NewSpendInput(nil, bc.NewHash([32]byte{0x01}), *consensus.BTMAssetID, uint64(i), 1, []byte{0x51}, [][]byte{}) 31 txInput.CommitmentSuffix = []byte{0, 1, 2} 32 txInput.WitnessSuffix = []byte{0, 1, 2} 33 34 tx := &types.Tx{ 35 36 TxData: types.TxData{ 37 //SerializedSize: uint64(i * 10), 38 Inputs: []*types.TxInput{ 39 txInput, 40 }, 41 Outputs: []*types.TxOutput{ 42 types.NewOriginalTxOutput(*consensus.BTMAssetID, uint64(i), []byte{0x6a}, [][]byte{}), 43 }, 44 SerializedSize: 1000, 45 }, 46 Tx: &bc.Tx{ 47 ID: bc.Hash{V0: uint64(i), V1: uint64(i), V2: uint64(i), V3: uint64(i)}, 48 }, 49 } 50 txs = append(txs, &core.TxDesc{Tx: tx}) 51 } 52 return txs 53 } 54 55 func (m *mempool) IsDust(tx *types.Tx) bool { 56 return false 57 } 58 59 func TestSyncMempool(t *testing.T) { 60 if testcontrol.IgnoreTestTemporary { 61 return 62 } 63 64 tmpDir, err := ioutil.TempDir(".", "") 65 if err != nil { 66 t.Fatalf("failed to create temporary data folder: %v", err) 67 } 68 defer os.RemoveAll(tmpDir) 69 testDBA := dbm.NewDB("testdba", "leveldb", tmpDir) 70 testDBB := dbm.NewDB("testdbb", "leveldb", tmpDir) 71 72 blocks := mockBlocks(nil, 5) 73 a := mockSync(blocks, &mock.Mempool{}, testDBA) 74 b := mockSync(blocks, &mock.Mempool{}, testDBB) 75 a.mempool = &mempool{} 76 netWork := NewNetWork() 77 netWork.Register(a, "192.168.0.1", "test node A", consensus.SFFullNode) 78 netWork.Register(b, "192.168.0.2", "test node B", consensus.SFFullNode) 79 if B2A, A2B, err := netWork.HandsShake(a, b); err != nil { 80 t.Errorf("fail on peer hands shake %v", err) 81 } else { 82 go B2A.postMan() 83 go A2B.postMan() 84 } 85 86 go a.syncMempoolLoop() 87 a.syncMempool("test node B") 88 wantTxs := a.mempool.GetTransactions() 89 90 timeout := time.NewTimer(2 * time.Second) 91 defer timeout.Stop() 92 ticker := time.NewTicker(500 * time.Millisecond) 93 defer ticker.Stop() 94 95 gotTxs := []*protocol.TxDesc{} 96 for { 97 select { 98 case <-ticker.C: 99 gotTxs = b.mempool.GetTransactions() 100 if len(gotTxs) >= txsNumber { 101 goto out 102 } 103 case <-timeout.C: 104 t.Fatalf("mempool sync timeout") 105 } 106 } 107 108 out: 109 if len(gotTxs) != txsNumber { 110 t.Fatalf("mempool sync txs num err. got:%d want:%d", len(gotTxs), txsNumber) 111 } 112 113 for i, gotTx := range gotTxs { 114 index := gotTx.Tx.Inputs[0].Amount() 115 if !reflect.DeepEqual(gotTx.Tx.Inputs[0].Amount(), wantTxs[index].Tx.Inputs[0].Amount()) { 116 t.Fatalf("mempool tx err. index:%d\n,gotTx:%s\n,wantTx:%s", i, spew.Sdump(gotTx.Tx.Inputs), spew.Sdump(wantTxs[0].Tx.Inputs)) 117 } 118 119 if !reflect.DeepEqual(gotTx.Tx.Outputs[0].AssetAmount, wantTxs[index].Tx.Outputs[0].AssetAmount) { 120 t.Fatalf("mempool tx err. index:%d\n,gotTx:%s\n,wantTx:%s", i, spew.Sdump(gotTx.Tx.Outputs), spew.Sdump(wantTxs[0].Tx.Outputs)) 121 } 122 } 123 } 124 125 func TestBroadcastTxsLoop(t *testing.T) { 126 if testcontrol.IgnoreTestTemporary { 127 return 128 } 129 130 tmpDir, err := ioutil.TempDir(".", "") 131 if err != nil { 132 t.Fatalf("failed to create temporary data folder: %v", err) 133 } 134 defer os.RemoveAll(tmpDir) 135 testDBA := dbm.NewDB("testdba", "leveldb", tmpDir) 136 testDBB := dbm.NewDB("testdbb", "leveldb", tmpDir) 137 138 blocks := mockBlocks(nil, 5) 139 a := mockSync(blocks, &mock.Mempool{}, testDBA) 140 b := mockSync(blocks, &mock.Mempool{}, testDBB) 141 a.mempool = &mempool{} 142 netWork := NewNetWork() 143 netWork.Register(a, "192.168.0.1", "test node A", consensus.SFFullNode) 144 netWork.Register(b, "192.168.0.2", "test node B", consensus.SFFullNode) 145 if B2A, A2B, err := netWork.HandsShake(a, b); err != nil { 146 t.Errorf("fail on peer hands shake %v", err) 147 } else { 148 go B2A.postMan() 149 go A2B.postMan() 150 } 151 a.txMsgSub, err = a.eventDispatcher.Subscribe(core.TxMsgEvent{}) 152 if err != nil { 153 t.Fatal("txMsgSub subscribe err", err) 154 } 155 go a.broadcastTxsLoop() 156 wantTxs := a.mempool.GetTransactions() 157 txsNum := 50 158 for i, txD := range wantTxs { 159 if i >= txsNum { 160 break 161 } 162 a.eventDispatcher.Post(core.TxMsgEvent{TxMsg: &core.TxPoolMsg{TxDesc: txD, MsgType: core.MsgNewTx}}) 163 } 164 timeout := time.NewTimer(2 * time.Second) 165 defer timeout.Stop() 166 ticker := time.NewTicker(500 * time.Millisecond) 167 defer ticker.Stop() 168 169 gotTxs := []*protocol.TxDesc{} 170 for { 171 select { 172 case <-ticker.C: 173 gotTxs = b.mempool.GetTransactions() 174 if len(gotTxs) >= txsNum { 175 goto out 176 } 177 case <-timeout.C: 178 t.Fatalf("mempool sync timeout") 179 } 180 } 181 182 out: 183 if len(gotTxs) != txsNum { 184 t.Fatalf("mempool sync txs num err. got:%d want:%d", len(gotTxs), txsNumber) 185 } 186 187 for i, gotTx := range gotTxs { 188 index := gotTx.Tx.Inputs[0].Amount() 189 if !reflect.DeepEqual(gotTx.Tx.Inputs[0].Amount(), wantTxs[index].Tx.Inputs[0].Amount()) { 190 t.Fatalf("mempool tx err. index:%d\n,gotTx:%s\n,wantTx:%s", i, spew.Sdump(gotTx.Tx.Inputs), spew.Sdump(wantTxs[0].Tx.Inputs)) 191 } 192 193 if !reflect.DeepEqual(gotTx.Tx.Outputs[0].AssetAmount, wantTxs[index].Tx.Outputs[0].AssetAmount) { 194 t.Fatalf("mempool tx err. index:%d\n,gotTx:%s\n,wantTx:%s", i, spew.Sdump(gotTx.Tx.Outputs), spew.Sdump(wantTxs[0].Tx.Outputs)) 195 } 196 } 197 }