( newBlock *types.BPBlock, originBrIdx int, newBranch *branch)
| 694 | } |
| 695 | |
| 696 | func (c *Chain) replaceAndSwitchToBranch( |
| 697 | newBlock *types.BPBlock, originBrIdx int, newBranch *branch) (err error, |
| 698 | ) { |
| 699 | var ( |
| 700 | lastIrre *blockNode |
| 701 | newIrres []*blockNode |
| 702 | sps []storageProcedure |
| 703 | up storageCallback |
| 704 | txCount int |
| 705 | height = c.heightOfTime(newBlock.Timestamp()) |
| 706 | |
| 707 | resultTxPool = make(map[hash.Hash]pi.Transaction) |
| 708 | expiredTxs []pi.Transaction |
| 709 | ) |
| 710 | |
| 711 | // Find new irreversible blocks |
| 712 | // |
| 713 | // NOTE(leventeliu): |
| 714 | // May have multiple new irreversible blocks here if peer list shrinks. May also have |
| 715 | // no new irreversible block at all if peer list expands. |
| 716 | lastIrre = newBranch.head.lastIrreversible(c.confirms) |
| 717 | newIrres = lastIrre.fetchNodeList(c.lastIrre.count + 1) |
| 718 | |
| 719 | // Apply irreversible blocks to create dirty map on immutable cache |
| 720 | for k, v := range c.txPool { |
| 721 | resultTxPool[k] = v |
| 722 | } |
| 723 | for _, b := range newIrres { |
| 724 | txCount += b.txCount |
| 725 | for _, tx := range b.load().Transactions { |
| 726 | if err := c.immutable.apply(tx, b.height); err != nil { |
| 727 | log.WithError(err).Fatal("failed to apply block to immutable database") |
| 728 | } |
| 729 | delete(resultTxPool, tx.Hash()) // Remove confirmed transaction |
| 730 | } |
| 731 | } |
| 732 | |
| 733 | // Check tx expiration |
| 734 | for k, v := range resultTxPool { |
| 735 | if base, err := c.immutable.nextNonce( |
| 736 | v.GetAccountAddress(), |
| 737 | ); err != nil || v.GetAccountNonce() < base { |
| 738 | log.WithFields(log.Fields{ |
| 739 | "hash": k.Short(4), |
| 740 | "type": v.GetTransactionType(), |
| 741 | "account": v.GetAccountAddress(), |
| 742 | "nonce": v.GetAccountNonce(), |
| 743 | |
| 744 | "immutable_base_nonce": base, |
| 745 | }).Debug("transaction expired") |
| 746 | expiredTxs = append(expiredTxs, v) |
| 747 | delete(resultTxPool, k) // Remove expired transaction |
| 748 | } |
| 749 | } |
| 750 | |
| 751 | // Prepare storage procedures to update immutable database |
| 752 | sps = c.immutable.compileChanges(sps) |
| 753 | sps = append(sps, addBlock(height, newBlock)) |
no test coverage detected