github.com/annchain/OG@v0.0.9/arefactor_core/core/tx_pool_test.go (about) 1 // Copyright © 2019 Annchain Authors <EMAIL ADDRESS> 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 package core_test 15 16 import ( 17 "github.com/annchain/OG/common" 18 "github.com/annchain/OG/types/tx_types" 19 "testing" 20 21 "github.com/annchain/OG/common/crypto" 22 "github.com/annchain/OG/common/math" 23 "github.com/annchain/OG/core" 24 "github.com/annchain/OG/core/state" 25 "github.com/annchain/OG/og" 26 "github.com/annchain/OG/ogdb" 27 ) 28 29 func newTestTxPool(t *testing.T) (*core.TxPool, *core.Dag, *tx_types.Sequencer, func()) { 30 txpoolconfig := core.TxPoolConfig{ 31 QueueSize: 100, 32 TipsSize: 100, 33 ResetDuration: 5, 34 TxVerifyTime: 2, 35 TxValidTime: 7, 36 } 37 db := ogdb.NewMemDatabase() 38 dag, errnew := core.NewDag(core.DagConfig{}, state.DefaultStateDBConfig(), db, nil) 39 if errnew != nil { 40 t.Fatalf("new a dag failed with error: %v", errnew) 41 } 42 pool := core.NewTxPool(txpoolconfig, dag) 43 44 genesis, balance := core.DefaultGenesis("genesis.json") 45 err := dag.Init(genesis, balance) 46 if err != nil { 47 t.Fatalf("init dag failed with error: %v", err) 48 } 49 pool.Init(genesis) 50 51 pool.Start() 52 dag.Start() 53 54 return pool, dag, genesis, func() { 55 pool.Stop() 56 dag.Stop() 57 } 58 } 59 60 func newTestPoolTx(nonce uint64) *tx_types.Tx { 61 txCreator := &og.TxCreator{} 62 pk, _ := crypto.PrivateKeyFromString(testPkSecp0) 63 addr := newTestAddress(pk) 64 65 tx := txCreator.NewSignedTx(addr, addr, math.NewBigInt(0), nonce, pk, 0) 66 tx.SetHash(tx.CalcTxHash()) 67 68 return tx.(*tx_types.Tx) 69 } 70 71 func newTestPoolBadTx() *tx_types.Tx { 72 txCreator := &og.TxCreator{} 73 pk, _ := crypto.PrivateKeyFromString(testPkSecp2) 74 addr := newTestAddress(pk) 75 76 tx := txCreator.NewSignedTx(addr, addr, math.NewBigInt(100), 0, pk, 0) 77 tx.SetHash(tx.CalcTxHash()) 78 79 return tx.(*tx_types.Tx) 80 } 81 82 func TestPoolInit(t *testing.T) { 83 t.Parallel() 84 85 pool, _, genesis, finish := newTestTxPool(t) 86 defer finish() 87 88 // check if genesis is the only tip 89 tips := pool.GetAllTips() 90 if len(tips) != 1 { 91 t.Fatalf("should have only one tip") 92 } 93 tip := tips[genesis.GetTxHash()] 94 if tip == nil { 95 t.Fatalf("genesis not stored in tips") 96 } 97 98 // check if genesis is in txLookUp 99 ge := pool.Get(genesis.GetTxHash()) 100 if ge == nil { 101 t.Fatalf("cant get genesis from pool.txLookUp") 102 } 103 104 // check genesis's status 105 status := pool.GetStatus(genesis.GetTxHash()) 106 if status != core.TxStatusTip { 107 t.Fatalf("genesis's status is not tip but %s", status.String()) 108 } 109 110 } 111 112 func TestPoolCommit(t *testing.T) { 113 t.Parallel() 114 115 pool, _, genesis, finish := newTestTxPool(t) 116 defer finish() 117 118 var err error 119 120 // tx0's parent is genesis 121 tx0 := newTestPoolTx(0) 122 tx0.ParentsHash = common.Hashes{genesis.GetTxHash()} 123 err = pool.AddLocalTx(tx0, true) 124 if err != nil { 125 t.Fatalf("add tx0 to pool failed: %v", err) 126 } 127 if pool.Get(tx0.GetTxHash()) == nil { 128 t.Fatalf("tx0 is not added into pool") 129 } 130 if status := pool.GetStatus(tx0.GetTxHash()); status != core.TxStatusTip { 131 t.Fatalf("tx0's status is not tip but %s after commit, addr %s", status.String(), tx0.Sender()) 132 } 133 geInPool := pool.Get(genesis.GetTxHash()) 134 if geInPool != nil { 135 t.Fatalf("parent genesis is not removed from pool.") 136 } 137 138 // tx1's parent is tx0 139 tx1 := newTestPoolTx(1) 140 tx1.ParentsHash = common.Hashes{tx0.GetTxHash()} 141 err = pool.AddLocalTx(tx1, true) 142 if err != nil { 143 t.Fatalf("add tx1 to pool failed: %v", err) 144 } 145 if pool.Get(tx1.GetTxHash()) == nil { 146 t.Fatalf("tx1 is not added into pool") 147 } 148 if status := pool.GetStatus(tx1.GetTxHash()); status != core.TxStatusTip { 149 t.Fatalf("tx1's status is not tip but %s after commit", status.String()) 150 } 151 if pool.Get(tx0.GetTxHash()) == nil { 152 t.Fatalf("tx0 is not in pool after added tx1") 153 } 154 if status := pool.GetStatus(tx0.GetTxHash()); status != core.TxStatusPending { 155 t.Fatalf("tx0's status is not pending but %s after tx1 added", status.String()) 156 } 157 158 // tx2's parent is genesis which is not in pool yet 159 tx2 := newTestPoolTx(2) 160 tx2.ParentsHash = common.Hashes{genesis.GetTxHash()} 161 err = pool.AddLocalTx(tx2, true) 162 if err != nil { 163 t.Fatalf("add tx2 to pool failed: %v", err) 164 } 165 if pool.Get(tx2.GetTxHash()) == nil { 166 t.Fatalf("tx2 is not added into pool") 167 } 168 if status := pool.GetStatus(tx2.GetTxHash()); status != core.TxStatusTip { 169 t.Fatalf("tx2's status is not tip but %s after commit", status.String()) 170 } 171 172 // TODO bad tx unit test 173 // // test bad tx 174 // badtx := newTestPoolBadTx() 175 // badtx.ParentsHash = common.Hashes{genesis.GetTxHash()} 176 // err = pool.AddLocalTx(badtx) 177 // if err != nil { 178 // t.Fatalf("add badtx to pool failed: %v", err) 179 // } 180 // if pool.Get(badtx.GetTxHash()) == nil { 181 // t.Fatalf("badtx is not added into pool") 182 // } 183 // if status := pool.GetStatus(badtx.GetTxHash()); status != core.TxStatusBadTx { 184 // t.Fatalf("badtx's status is not badtx but %s after commit", status.String()) 185 // } 186 187 } 188 189 func TestPoolConfirm(t *testing.T) { 190 t.Parallel() 191 192 pool, dag, genesis, finish := newTestTxPool(t) 193 defer finish() 194 195 var err error 196 197 // sequencer's parents are normal txs 198 tx0 := newTestPoolTx(0) 199 tx0.ParentsHash = common.Hashes{genesis.GetTxHash()} 200 pool.AddLocalTx(tx0, true) 201 202 // TODO 203 // tx3 := newTestPoolBadTx() 204 // pool.AddLocalTx(tx3) 205 206 tx1 := newTestPoolTx(1) 207 tx1.ParentsHash = common.Hashes{genesis.GetTxHash()} 208 pool.AddLocalTx(tx1, true) 209 210 seq := newTestSeq(1) 211 seq.ParentsHash = common.Hashes{ 212 tx0.GetTxHash(), 213 tx1.GetTxHash(), 214 } 215 err = pool.AddLocalTx(seq, true) 216 if err != nil { 217 t.Fatalf("add seq to pool failed: %v", err) 218 } 219 if pool.Get(seq.GetTxHash()) == nil { 220 t.Fatalf("sequencer is not added into pool") 221 } 222 if status := pool.GetStatus(seq.GetTxHash()); status != core.TxStatusTip { 223 t.Fatalf("sequencer's status is not tip but %s after added", status.String()) 224 } 225 if pool.Get(tx0.GetTxHash()) != nil { 226 t.Fatalf("tx0 is not removed from pool") 227 } 228 if pool.Get(tx1.GetTxHash()) != nil { 229 t.Fatalf("tx1 is not removed from pool") 230 } 231 if dag.GetTx(tx0.GetTxHash()) == nil { 232 t.Fatalf("tx0 is not stored in dag") 233 } 234 if dag.GetTx(tx1.GetTxHash()) == nil { 235 t.Fatalf("tx1 is not stored in dag") 236 } 237 if dag.GetTx(seq.GetTxHash()) == nil { 238 t.Fatalf("seq is not stored in dag") 239 } 240 if dag.LatestSequencer().GetTxHash().Cmp(seq.GetTxHash()) != 0 { 241 t.Fatalf("latest seq in dag is not the seq we want") 242 } 243 244 // TODO bad tx unit test 245 // // sequencer's parent is bad tx 246 // badtx := newTestPoolBadTx() 247 // badtx.ParentsHash = common.Hashes{seq.GetTxHash()} 248 // pool.AddLocalTx(badtx) 249 250 // addr := common.HexToAddress(testAddr2) 251 // dag.Accessor().SetBalance(addr, math.NewBigInt(1000)) 252 253 // badtxseq := newTestSeq(2) 254 // badtxseq.ParentsHash = common.Hashes{badtx.GetTxHash()} 255 // badtxseq.ContractHashOrder = common.Hashes{badtx.GetTxHash()} 256 // err = pool.AddLocalTx(badtxseq) 257 // if err != nil { 258 // t.Fatalf("add badtxseq to pool failed: %v", err) 259 // } 260 // if pool.Get(badtxseq.GetTxHash()) == nil { 261 // t.Fatalf("badtxseq is not added into pool") 262 // } 263 // if status := pool.GetStatus(badtxseq.GetTxHash()); status != core.TxStatusTip { 264 // t.Fatalf("badtxseq's status is not tip but %s after added", status.String()) 265 // } 266 // if pool.Get(badtx.GetTxHash()) != nil { 267 // t.Fatalf("badtx is not removed from pool") 268 // } 269 // if dag.GetTx(badtx.GetTxHash()) == nil { 270 // t.Fatalf("badtx is not stored in dag") 271 // } 272 // if dag.GetTx(badtxseq.GetTxHash()) == nil { 273 // t.Fatalf("battxseq is not stored in dag") 274 // } 275 // if dag.LatestSequencer().GetTxHash().Cmp(badtxseq.GetTxHash()) != 0 { 276 // t.Fatalf("latest seq in dag is not the battxseq we want") 277 // } 278 279 }