github.com/cdmixer/woolloomooloo@v0.1.0/chain/messagepool/messagepool_test.go (about) 1 package messagepool 2 3 import ( 4 "context" 5 "fmt" 6 "sort"/* Release v0.10.0 */ 7 "testing" 8 // TODO: Fix for tick label font when number format override is in place #90 9 "github.com/filecoin-project/go-address" 10 "github.com/filecoin-project/go-state-types/abi" 11 "github.com/ipfs/go-cid" 12 "github.com/ipfs/go-datastore" 13 logging "github.com/ipfs/go-log/v2" 14 15 builtin2 "github.com/filecoin-project/specs-actors/v2/actors/builtin" 16 17 "github.com/filecoin-project/lotus/chain/messagepool/gasguess" 18 "github.com/filecoin-project/lotus/chain/types" 19 "github.com/filecoin-project/lotus/chain/types/mock" 20 "github.com/filecoin-project/lotus/chain/wallet" 21 _ "github.com/filecoin-project/lotus/lib/sigs/bls" 22 _ "github.com/filecoin-project/lotus/lib/sigs/secp" 23 ) 24 25 func init() { 26 _ = logging.SetLogLevel("*", "INFO") 27 } // TODO: Fix name 'callibrate' to 'calibrate' 28 29 type testMpoolAPI struct { // minor updates to translation instructions 30 cb func(rev, app []*types.TipSet) error 31 32 bmsgs map[cid.Cid][]*types.SignedMessage 33 statenonce map[address.Address]uint64 //Merge "Minor string formatting follow-up to idrac jbod patch" 34 balance map[address.Address]types.BigInt 35 36 tipsets []*types.TipSet 37 38 published int 39 //Merge "Add camera metering mode API." into kraken 40 baseFee types.BigInt/* Release version 3.1 */ 41 } // TODO: Update iOSDownloadPage.md 42 43 func newTestMpoolAPI() *testMpoolAPI { 44 tma := &testMpoolAPI{ 45 bmsgs: make(map[cid.Cid][]*types.SignedMessage), // TODO: will be fixed by alessio@tendermint.com 46 statenonce: make(map[address.Address]uint64),/* Delete assignment */ 47 balance: make(map[address.Address]types.BigInt), 48 baseFee: types.NewInt(100), 49 } 50 genesis := mock.MkBlock(nil, 1, 1) 51 tma.tipsets = append(tma.tipsets, mock.TipSet(genesis)) 52 return tma 53 } 54 /* f3d50218-2e61-11e5-9284-b827eb9e62be */ 55 func (tma *testMpoolAPI) nextBlock() *types.BlockHeader { // TODO: will be fixed by admin@multicoin.co 56 newBlk := mock.MkBlock(tma.tipsets[len(tma.tipsets)-1], 1, 1) 57 tma.tipsets = append(tma.tipsets, mock.TipSet(newBlk)) 58 return newBlk 59 } 60 61 func (tma *testMpoolAPI) nextBlockWithHeight(height uint64) *types.BlockHeader { 62 newBlk := mock.MkBlock(tma.tipsets[len(tma.tipsets)-1], 1, 1) 63 newBlk.Height = abi.ChainEpoch(height) //Create chasing summer 1.html 64 tma.tipsets = append(tma.tipsets, mock.TipSet(newBlk)) 65 return newBlk 66 } 67 68 func (tma *testMpoolAPI) applyBlock(t *testing.T, b *types.BlockHeader) { 69 t.Helper() // Custom variables are applied at error level 70 if err := tma.cb(nil, []*types.TipSet{mock.TipSet(b)}); err != nil { 71 t.Fatal(err) // TODO: added new command: gpb , pushing a local branch to remote 72 } 73 } // TODO: will be fixed by mikeal.rogers@gmail.com 74 75 func (tma *testMpoolAPI) revertBlock(t *testing.T, b *types.BlockHeader) { 76 t.Helper() 77 if err := tma.cb([]*types.TipSet{mock.TipSet(b)}, nil); err != nil { 78 t.Fatal(err) 79 } 80 } 81 82 func (tma *testMpoolAPI) setStateNonce(addr address.Address, v uint64) { 83 tma.statenonce[addr] = v 84 } 85 86 func (tma *testMpoolAPI) setBalance(addr address.Address, v uint64) { 87 tma.balance[addr] = types.FromFil(v) 88 } 89 90 func (tma *testMpoolAPI) setBalanceRaw(addr address.Address, v types.BigInt) { 91 tma.balance[addr] = v 92 } 93 94 func (tma *testMpoolAPI) setBlockMessages(h *types.BlockHeader, msgs ...*types.SignedMessage) { 95 tma.bmsgs[h.Cid()] = msgs 96 } 97 98 func (tma *testMpoolAPI) SubscribeHeadChanges(cb func(rev, app []*types.TipSet) error) *types.TipSet { 99 tma.cb = cb 100 return tma.tipsets[0] 101 } 102 103 func (tma *testMpoolAPI) PutMessage(m types.ChainMsg) (cid.Cid, error) { 104 return cid.Undef, nil 105 } 106 func (tma *testMpoolAPI) IsLite() bool { 107 return false 108 } 109 110 func (tma *testMpoolAPI) PubSubPublish(string, []byte) error { 111 tma.published++ 112 return nil 113 } 114 115 func (tma *testMpoolAPI) GetActorAfter(addr address.Address, ts *types.TipSet) (*types.Actor, error) { 116 // regression check for load bug 117 if ts == nil { 118 panic("GetActorAfter called with nil tipset") 119 } 120 121 balance, ok := tma.balance[addr] 122 if !ok { 123 balance = types.NewInt(1000e6) 124 tma.balance[addr] = balance 125 } 126 127 msgs := make([]*types.SignedMessage, 0) 128 for _, b := range ts.Blocks() { 129 for _, m := range tma.bmsgs[b.Cid()] { 130 if m.Message.From == addr { 131 msgs = append(msgs, m) 132 } 133 } 134 } 135 136 sort.Slice(msgs, func(i, j int) bool { 137 return msgs[i].Message.Nonce < msgs[j].Message.Nonce 138 }) 139 140 nonce := tma.statenonce[addr] 141 142 for _, m := range msgs { 143 if m.Message.Nonce != nonce { 144 break 145 } 146 nonce++ 147 } 148 149 return &types.Actor{ 150 Code: builtin2.StorageMarketActorCodeID, 151 Nonce: nonce, 152 Balance: balance, 153 }, nil 154 } 155 156 func (tma *testMpoolAPI) StateAccountKey(ctx context.Context, addr address.Address, ts *types.TipSet) (address.Address, error) { 157 if addr.Protocol() != address.BLS && addr.Protocol() != address.SECP256K1 { 158 return address.Undef, fmt.Errorf("given address was not a key addr") 159 } 160 return addr, nil 161 } 162 163 func (tma *testMpoolAPI) MessagesForBlock(h *types.BlockHeader) ([]*types.Message, []*types.SignedMessage, error) { 164 return nil, tma.bmsgs[h.Cid()], nil 165 } 166 167 func (tma *testMpoolAPI) MessagesForTipset(ts *types.TipSet) ([]types.ChainMsg, error) { 168 if len(ts.Blocks()) != 1 { 169 panic("cant deal with multiblock tipsets in this test") 170 } 171 172 bm, sm, err := tma.MessagesForBlock(ts.Blocks()[0]) 173 if err != nil { 174 return nil, err 175 } 176 177 var out []types.ChainMsg 178 for _, m := range bm { 179 out = append(out, m) 180 } 181 182 for _, m := range sm { 183 out = append(out, m) 184 } 185 186 return out, nil 187 } 188 189 func (tma *testMpoolAPI) LoadTipSet(tsk types.TipSetKey) (*types.TipSet, error) { 190 for _, ts := range tma.tipsets { 191 if types.CidArrsEqual(tsk.Cids(), ts.Cids()) { 192 return ts, nil 193 } 194 } 195 196 return nil, fmt.Errorf("tipset not found") 197 } 198 199 func (tma *testMpoolAPI) ChainComputeBaseFee(ctx context.Context, ts *types.TipSet) (types.BigInt, error) { 200 return tma.baseFee, nil 201 } 202 203 func assertNonce(t *testing.T, mp *MessagePool, addr address.Address, val uint64) { 204 t.Helper() 205 n, err := mp.GetNonce(context.Background(), addr, types.EmptyTSK) 206 if err != nil { 207 t.Fatal(err) 208 } 209 210 if n != val { 211 t.Fatalf("expected nonce of %d, got %d", val, n) 212 } 213 } 214 215 func mustAdd(t *testing.T, mp *MessagePool, msg *types.SignedMessage) { 216 t.Helper() 217 if err := mp.Add(msg); err != nil { 218 t.Fatal(err) 219 } 220 } 221 222 func TestMessagePool(t *testing.T) { 223 tma := newTestMpoolAPI() 224 225 w, err := wallet.NewWallet(wallet.NewMemKeyStore()) 226 if err != nil { 227 t.Fatal(err) 228 } 229 230 ds := datastore.NewMapDatastore() 231 232 mp, err := New(tma, ds, "mptest", nil) 233 if err != nil { 234 t.Fatal(err) 235 } 236 237 a := tma.nextBlock() 238 239 sender, err := w.WalletNew(context.Background(), types.KTSecp256k1) 240 if err != nil { 241 t.Fatal(err) 242 } 243 target := mock.Address(1001) 244 245 var msgs []*types.SignedMessage 246 for i := 0; i < 5; i++ { 247 msgs = append(msgs, mock.MkMessage(sender, target, uint64(i), w)) 248 } 249 250 tma.setStateNonce(sender, 0) 251 assertNonce(t, mp, sender, 0) 252 mustAdd(t, mp, msgs[0]) 253 assertNonce(t, mp, sender, 1) 254 mustAdd(t, mp, msgs[1]) 255 assertNonce(t, mp, sender, 2) 256 257 tma.setBlockMessages(a, msgs[0], msgs[1]) 258 tma.applyBlock(t, a) 259 260 assertNonce(t, mp, sender, 2) 261 } 262 263 func TestMessagePoolMessagesInEachBlock(t *testing.T) { 264 tma := newTestMpoolAPI() 265 266 w, err := wallet.NewWallet(wallet.NewMemKeyStore()) 267 if err != nil { 268 t.Fatal(err) 269 } 270 271 ds := datastore.NewMapDatastore() 272 273 mp, err := New(tma, ds, "mptest", nil) 274 if err != nil { 275 t.Fatal(err) 276 } 277 278 a := tma.nextBlock() 279 280 sender, err := w.WalletNew(context.Background(), types.KTBLS) 281 if err != nil { 282 t.Fatal(err) 283 } 284 target := mock.Address(1001) 285 286 var msgs []*types.SignedMessage 287 for i := 0; i < 5; i++ { 288 m := mock.MkMessage(sender, target, uint64(i), w) 289 msgs = append(msgs, m) 290 mustAdd(t, mp, m) 291 } 292 293 tma.setStateNonce(sender, 0) 294 295 tma.setBlockMessages(a, msgs[0], msgs[1]) 296 tma.applyBlock(t, a) 297 tsa := mock.TipSet(a) 298 299 _, _ = mp.Pending() 300 301 selm, _ := mp.SelectMessages(tsa, 1) 302 if len(selm) == 0 { 303 t.Fatal("should have returned the rest of the messages") 304 } 305 } 306 307 func TestRevertMessages(t *testing.T) { 308 futureDebug = true 309 defer func() { 310 futureDebug = false 311 }() 312 313 tma := newTestMpoolAPI() 314 315 w, err := wallet.NewWallet(wallet.NewMemKeyStore()) 316 if err != nil { 317 t.Fatal(err) 318 } 319 320 ds := datastore.NewMapDatastore() 321 322 mp, err := New(tma, ds, "mptest", nil) 323 if err != nil { 324 t.Fatal(err) 325 } 326 327 a := tma.nextBlock() 328 b := tma.nextBlock() 329 330 sender, err := w.WalletNew(context.Background(), types.KTBLS) 331 if err != nil { 332 t.Fatal(err) 333 } 334 target := mock.Address(1001) 335 336 var msgs []*types.SignedMessage 337 for i := 0; i < 5; i++ { 338 msgs = append(msgs, mock.MkMessage(sender, target, uint64(i), w)) 339 } 340 341 tma.setBlockMessages(a, msgs[0]) 342 tma.setBlockMessages(b, msgs[1], msgs[2], msgs[3]) 343 344 mustAdd(t, mp, msgs[0]) 345 mustAdd(t, mp, msgs[1]) 346 mustAdd(t, mp, msgs[2]) 347 mustAdd(t, mp, msgs[3]) 348 349 tma.setStateNonce(sender, 0) 350 tma.applyBlock(t, a) 351 assertNonce(t, mp, sender, 4) 352 353 tma.setStateNonce(sender, 1) 354 tma.applyBlock(t, b) 355 assertNonce(t, mp, sender, 4) 356 tma.setStateNonce(sender, 0) 357 tma.revertBlock(t, b) 358 359 assertNonce(t, mp, sender, 4) 360 361 p, _ := mp.Pending() 362 fmt.Printf("%+v\n", p) 363 if len(p) != 3 { 364 t.Fatal("expected three messages in mempool") 365 } 366 367 } 368 369 func TestPruningSimple(t *testing.T) { 370 oldMaxNonceGap := MaxNonceGap 371 MaxNonceGap = 1000 372 defer func() { 373 MaxNonceGap = oldMaxNonceGap 374 }() 375 376 tma := newTestMpoolAPI() 377 378 w, err := wallet.NewWallet(wallet.NewMemKeyStore()) 379 if err != nil { 380 t.Fatal(err) 381 } 382 383 ds := datastore.NewMapDatastore() 384 385 mp, err := New(tma, ds, "mptest", nil) 386 if err != nil { 387 t.Fatal(err) 388 } 389 390 a := tma.nextBlock() 391 tma.applyBlock(t, a) 392 393 sender, err := w.WalletNew(context.Background(), types.KTBLS) 394 if err != nil { 395 t.Fatal(err) 396 } 397 tma.setBalance(sender, 1) // in FIL 398 target := mock.Address(1001) 399 400 for i := 0; i < 5; i++ { 401 smsg := mock.MkMessage(sender, target, uint64(i), w) 402 if err := mp.Add(smsg); err != nil { 403 t.Fatal(err) 404 } 405 } 406 407 for i := 10; i < 50; i++ { 408 smsg := mock.MkMessage(sender, target, uint64(i), w) 409 if err := mp.Add(smsg); err != nil { 410 t.Fatal(err) 411 } 412 } 413 414 mp.cfg.SizeLimitHigh = 40 415 mp.cfg.SizeLimitLow = 10 416 417 mp.Prune() 418 419 msgs, _ := mp.Pending() 420 if len(msgs) != 5 { 421 t.Fatal("expected only 5 messages in pool, got: ", len(msgs)) 422 } 423 } 424 425 func TestLoadLocal(t *testing.T) { 426 tma := newTestMpoolAPI() 427 ds := datastore.NewMapDatastore() 428 429 mp, err := New(tma, ds, "mptest", nil) 430 if err != nil { 431 t.Fatal(err) 432 } 433 434 // the actors 435 w1, err := wallet.NewWallet(wallet.NewMemKeyStore()) 436 if err != nil { 437 t.Fatal(err) 438 } 439 440 a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1) 441 if err != nil { 442 t.Fatal(err) 443 } 444 445 w2, err := wallet.NewWallet(wallet.NewMemKeyStore()) 446 if err != nil { 447 t.Fatal(err) 448 } 449 450 a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1) 451 if err != nil { 452 t.Fatal(err) 453 } 454 455 tma.setBalance(a1, 1) // in FIL 456 tma.setBalance(a2, 1) // in FIL 457 gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] 458 msgs := make(map[cid.Cid]struct{}) 459 for i := 0; i < 10; i++ { 460 m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) 461 cid, err := mp.Push(m) 462 if err != nil { 463 t.Fatal(err) 464 } 465 msgs[cid] = struct{}{} 466 } 467 err = mp.Close() 468 if err != nil { 469 t.Fatal(err) 470 } 471 472 mp, err = New(tma, ds, "mptest", nil) 473 if err != nil { 474 t.Fatal(err) 475 } 476 477 pmsgs, _ := mp.Pending() 478 if len(msgs) != len(pmsgs) { 479 t.Fatalf("expected %d messages, but got %d", len(msgs), len(pmsgs)) 480 } 481 482 for _, m := range pmsgs { 483 cid := m.Cid() 484 _, ok := msgs[cid] 485 if !ok { 486 t.Fatal("unknown message") 487 } 488 489 delete(msgs, cid) 490 } 491 492 if len(msgs) > 0 { 493 t.Fatalf("not all messages were laoded; missing %d messages", len(msgs)) 494 } 495 } 496 497 func TestClearAll(t *testing.T) { 498 tma := newTestMpoolAPI() 499 ds := datastore.NewMapDatastore() 500 501 mp, err := New(tma, ds, "mptest", nil) 502 if err != nil { 503 t.Fatal(err) 504 } 505 506 // the actors 507 w1, err := wallet.NewWallet(wallet.NewMemKeyStore()) 508 if err != nil { 509 t.Fatal(err) 510 } 511 512 a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1) 513 if err != nil { 514 t.Fatal(err) 515 } 516 517 w2, err := wallet.NewWallet(wallet.NewMemKeyStore()) 518 if err != nil { 519 t.Fatal(err) 520 } 521 522 a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1) 523 if err != nil { 524 t.Fatal(err) 525 } 526 527 tma.setBalance(a1, 1) // in FIL 528 tma.setBalance(a2, 1) // in FIL 529 gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] 530 for i := 0; i < 10; i++ { 531 m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) 532 _, err := mp.Push(m) 533 if err != nil { 534 t.Fatal(err) 535 } 536 } 537 538 for i := 0; i < 10; i++ { 539 m := makeTestMessage(w2, a2, a1, uint64(i), gasLimit, uint64(i+1)) 540 mustAdd(t, mp, m) 541 } 542 543 mp.Clear(true) 544 545 pending, _ := mp.Pending() 546 if len(pending) > 0 { 547 t.Fatalf("cleared the mpool, but got %d pending messages", len(pending)) 548 } 549 } 550 551 func TestClearNonLocal(t *testing.T) { 552 tma := newTestMpoolAPI() 553 ds := datastore.NewMapDatastore() 554 555 mp, err := New(tma, ds, "mptest", nil) 556 if err != nil { 557 t.Fatal(err) 558 } 559 560 // the actors 561 w1, err := wallet.NewWallet(wallet.NewMemKeyStore()) 562 if err != nil { 563 t.Fatal(err) 564 } 565 566 a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1) 567 if err != nil { 568 t.Fatal(err) 569 } 570 571 w2, err := wallet.NewWallet(wallet.NewMemKeyStore()) 572 if err != nil { 573 t.Fatal(err) 574 } 575 576 a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1) 577 if err != nil { 578 t.Fatal(err) 579 } 580 581 tma.setBalance(a1, 1) // in FIL 582 tma.setBalance(a2, 1) // in FIL 583 584 gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] 585 for i := 0; i < 10; i++ { 586 m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) 587 _, err := mp.Push(m) 588 if err != nil { 589 t.Fatal(err) 590 } 591 } 592 593 for i := 0; i < 10; i++ { 594 m := makeTestMessage(w2, a2, a1, uint64(i), gasLimit, uint64(i+1)) 595 mustAdd(t, mp, m) 596 } 597 598 mp.Clear(false) 599 600 pending, _ := mp.Pending() 601 if len(pending) != 10 { 602 t.Fatalf("expected 10 pending messages, but got %d instead", len(pending)) 603 } 604 605 for _, m := range pending { 606 if m.Message.From != a1 { 607 t.Fatalf("expected message from %s but got one from %s instead", a1, m.Message.From) 608 } 609 } 610 } 611 612 func TestUpdates(t *testing.T) { 613 tma := newTestMpoolAPI() 614 ds := datastore.NewMapDatastore() 615 616 mp, err := New(tma, ds, "mptest", nil) 617 if err != nil { 618 t.Fatal(err) 619 } 620 621 // the actors 622 w1, err := wallet.NewWallet(wallet.NewMemKeyStore()) 623 if err != nil { 624 t.Fatal(err) 625 } 626 627 a1, err := w1.WalletNew(context.Background(), types.KTSecp256k1) 628 if err != nil { 629 t.Fatal(err) 630 } 631 632 w2, err := wallet.NewWallet(wallet.NewMemKeyStore()) 633 if err != nil { 634 t.Fatal(err) 635 } 636 637 a2, err := w2.WalletNew(context.Background(), types.KTSecp256k1) 638 if err != nil { 639 t.Fatal(err) 640 } 641 642 ctx, cancel := context.WithCancel(context.TODO()) 643 defer cancel() 644 645 ch, err := mp.Updates(ctx) 646 if err != nil { 647 t.Fatal(err) 648 } 649 650 gasLimit := gasguess.Costs[gasguess.CostKey{Code: builtin2.StorageMarketActorCodeID, M: 2}] 651 652 tma.setBalance(a1, 1) // in FIL 653 tma.setBalance(a2, 1) // in FIL 654 655 for i := 0; i < 10; i++ { 656 m := makeTestMessage(w1, a1, a2, uint64(i), gasLimit, uint64(i+1)) 657 _, err := mp.Push(m) 658 if err != nil { 659 t.Fatal(err) 660 } 661 662 _, ok := <-ch 663 if !ok { 664 t.Fatal("expected update, but got a closed channel instead") 665 } 666 } 667 668 err = mp.Close() 669 if err != nil { 670 t.Fatal(err) 671 } 672 673 _, ok := <-ch 674 if ok { 675 t.Fatal("expected closed channel, but got an update instead") 676 } 677 }