def _validate_merkle_root( self, block: FullBlock, tx_additions: List[Coin] = None, tx_removals: List[bytes32] = None, ) -> Optional[Err]: additions = [] removals = [] if tx_additions: additions.extend(tx_additions) if tx_removals: removals.extend(tx_removals) removal_merkle_set = MerkleSet() addition_merkle_set = MerkleSet() # Create removal Merkle set for coin_name in removals: removal_merkle_set.add_already_hashed(coin_name) # Create addition Merkle set puzzlehash_coins_map: Dict[bytes32, List[Coin]] = {} for coin in additions + [block.get_coinbase(), block.get_fees_coin()]: if coin.puzzle_hash in puzzlehash_coins_map: puzzlehash_coins_map[coin.puzzle_hash].append(coin) else: puzzlehash_coins_map[coin.puzzle_hash] = [coin] # Addition Merkle set contains puzzlehash and hash of all coins with that puzzlehash for puzzle, coins in puzzlehash_coins_map.items(): addition_merkle_set.add_already_hashed(puzzle) addition_merkle_set.add_already_hashed(hash_coin_list(coins)) additions_root = addition_merkle_set.get_root() removals_root = removal_merkle_set.get_root() if block.header.data.additions_root != additions_root: return Err.BAD_ADDITION_ROOT if block.header.data.removals_root != removals_root: return Err.BAD_REMOVAL_ROOT return None
async def new_lca(self, block: FullBlock): removals, additions = await block.tx_removals_and_additions() for coin in additions: record: CoinRecord = CoinRecord(coin, block.height, uint32(0), False, False) await self.add_coin_record(record) for coin_name in removals: await self.set_spent(coin_name, block.height) coinbase_coin = block.get_coinbase() fees_coin = block.get_fees_coin() coinbase_r: CoinRecord = CoinRecord(coinbase_coin, block.height, uint32(0), False, True) fees_r: CoinRecord = CoinRecord(fees_coin, block.height, uint32(0), False, True) await self.add_coin_record(coinbase_r) await self.add_coin_record(fees_r)
async def add_diffs( self, removals: List[bytes32], additions: List[Coin], block: FullBlock, diff_store: DiffStore, ): for coin in additions: added: CoinRecord = CoinRecord(coin, block.height, 0, 0, 0) # type: ignore # noqa diff_store.diffs[added.name.hex()] = added coinbase: CoinRecord = CoinRecord(block.get_coinbase(), block.height, 0, 0, 1) # type: ignore # noqa diff_store.diffs[coinbase.name.hex()] = coinbase fees_coin: CoinRecord = CoinRecord(block.get_fees_coin(), block.height, 0, 0, 1) # type: ignore # noqa diff_store.diffs[fees_coin.name.hex()] = fees_coin for coin_name in removals: removed: Optional[CoinRecord] = None if coin_name.hex() in diff_store.diffs: removed = diff_store.diffs[coin_name.hex()] if removed is None: removed = await self.get_coin_record(coin_name) if removed is None: raise Exception spent = CoinRecord( removed.coin, removed.confirmed_block_index, block.height, True, removed.coinbase, ) # type: ignore # noqa diff_store.diffs[spent.name.hex()] = spent