()
| 99 | } |
| 100 | |
| 101 | func (bb *BlockBuilder) Build() (*bc.UnsignedBlock, *state.Snapshot, error) { |
| 102 | prev := bb.snapshot.Header |
| 103 | refsCount := bb.MaxBlockWindow |
| 104 | if prev.RefsCount < refsCount { |
| 105 | refsCount = prev.RefsCount + 1 |
| 106 | } |
| 107 | |
| 108 | var ( |
| 109 | txs = make([]*bc.Tx, 0, len(bb.txs)) |
| 110 | wcs = make([][]byte, 0, len(bb.txs)) |
| 111 | ) |
| 112 | for _, tx := range bb.txs { |
| 113 | txs = append(txs, tx.Tx) |
| 114 | wcs = append(wcs, tx.WitnessCommitment) |
| 115 | } |
| 116 | |
| 117 | var ( |
| 118 | txRoot = bc.NewHash(merkle.Root(wcs)) |
| 119 | contractsRoot = bc.NewHash(bb.snapshot.ContractsTree.RootHash()) |
| 120 | nonceRoot = bc.NewHash(bb.snapshot.NonceTree.RootHash()) |
| 121 | ) |
| 122 | |
| 123 | prevID := prev.Hash() |
| 124 | h := &bc.BlockHeader{ |
| 125 | Version: bb.Version, |
| 126 | Height: prev.Height + 1, |
| 127 | PreviousBlockId: &prevID, |
| 128 | TimestampMs: bb.timestampMS, |
| 129 | RefsCount: refsCount, |
| 130 | NextPredicate: prev.NextPredicate, |
| 131 | Runlimit: bb.runlimit, |
| 132 | TransactionsRoot: &txRoot, |
| 133 | ContractsRoot: &contractsRoot, |
| 134 | NoncesRoot: &nonceRoot, |
| 135 | } |
| 136 | b := &bc.UnsignedBlock{ |
| 137 | BlockHeader: h, |
| 138 | Transactions: txs, |
| 139 | } |
| 140 | err := bb.snapshot.ApplyBlockHeader(h) |
| 141 | if err != nil { |
| 142 | return nil, nil, err |
| 143 | } |
| 144 | |
| 145 | snapshot := bb.snapshot |
| 146 | bb.snapshot = nil |
| 147 | bb.txs = nil |
| 148 | bb.timestampMS = 0 |
| 149 | bb.runlimit = 0 |
| 150 | |
| 151 | return b, snapshot, nil |
| 152 | } |
| 153 | |
| 154 | // checkTransactionTime ensures that a transaction is fit |
| 155 | // to be included in a block generated at blockTimeMS. |
no test coverage detected