Complete removal of body

This commit is contained in:
Mariano Sorgente 2020-03-02 15:06:03 +09:00
parent f460480406
commit 3b0b7dfb72
No known key found for this signature in database
GPG Key ID: 0F866338C369278C
23 changed files with 321 additions and 244 deletions

View File

@ -31,6 +31,7 @@ from src.util.mempool_check_conditions import get_name_puzzle_conditions
from src.util.errors import InvalidGenesisBlock
from src.util.ints import uint32, uint64
from src.types.challenge import Challenge
from src.util.hash import std_hash
log = logging.getLogger(__name__)
@ -511,16 +512,12 @@ class Blockchain:
if block.proof_of_space.get_hash() != block.header.data.proof_of_space_hash:
return False
# 2. Check body hash
if block.body.get_hash() != block.header.data.body_hash:
return False
# 3. Check coinbase signature with pool pk
pair = block.body.coinbase_signature.PkMessagePair(
block.proof_of_space.pool_pubkey, block.body.coinbase.name(),
pair = block.header.data.coinbase_signature.PkMessagePair(
block.proof_of_space.pool_pubkey, block.header.data.coinbase.name(),
)
if not block.body.coinbase_signature.validate([pair]):
if not block.header.data.coinbase_signature.validate([pair]):
return False
# 4. Check harvester signature of header data is valid based on harvester key
@ -559,7 +556,10 @@ class Blockchain:
):
return False
# 7. Check filter hash is correct TODO
# 7. Check filter hash is correct
if block.header.data.filter_hash != bytes32([0] * 32):
if std_hash(block.transactions_filter) != block.header.data.filter_hash:
return False
# 8. Check extension data, if any is added
@ -681,19 +681,19 @@ class Blockchain:
return False
coinbase_reward = calculate_block_reward(block.height)
if coinbase_reward != block.body.coinbase.amount:
if coinbase_reward != block.header.data.coinbase.amount:
return False
fee_base = calculate_base_fee(block.height)
# 8 Validate transactions
# target reward_fee = 1/8 coinbase reward + tx fees
if block.body.transactions:
if block.transactions_generator:
# Validate transactions, and verify that fee_base + TX fees = fee_coin.amount
err = await self._validate_transactions(block, fee_base)
if err:
return False
else:
if fee_base != block.body.fees_coin.amount:
if fee_base != block.header.data.fees_coin.amount:
return False
root_error = self._validate_merkle_root(block)
if root_error:
@ -932,8 +932,8 @@ class Blockchain:
if tx_removals:
removals.extend(tx_removals)
additions.append(block.body.coinbase)
additions.append(block.body.fees_coin)
additions.append(block.header.data.coinbase)
additions.append(block.header.data.fees_coin)
removal_merkle_set = MerkleSet()
addition_merkle_set = MerkleSet()
@ -969,10 +969,10 @@ class Blockchain:
self, block: FullBlock, fee_base: uint64
) -> Optional[Err]:
if not block.body.transactions:
if not block.transactions_generator:
return Err.UNKNOWN
# Get List of names removed, puzzles hashes for removed coins and conditions crated
error, npc_list, cost = get_name_puzzle_conditions(block.body.transactions)
error, npc_list, cost = get_name_puzzle_conditions(block.transactions_generator)
if cost > self.constants["MAX_BLOCK_COST"]:
return Err.BLOCK_COST_EXCEEDS_MAX
@ -1004,6 +1004,8 @@ class Blockchain:
if root_error:
return root_error
# TODO(straya): validate filter
# Watch out for duplicate outputs
addition_counter = collections.Counter(_.name() for _ in additions)
for k, v in addition_counter.items():
@ -1055,7 +1057,7 @@ class Blockchain:
fees = removed - added
# Check coinbase reward
if fees + fee_base != block.body.fees_coin.amount:
if fees + fee_base != block.header.data.fees_coin.amount:
return Err.BAD_COINBASE_REWARD
# Verify that removed coin puzzle_hashes match with calculated puzzle_hashes
@ -1077,9 +1079,9 @@ class Blockchain:
)
# Verify aggregated signature
if not block.body.aggregated_signature:
if not block.header.data.aggregated_signature:
return Err.BAD_AGGREGATE_SIGNATURE
if not block.body.aggregated_signature.validate(hash_key_pairs):
if not block.header.data.aggregated_signature.validate(hash_key_pairs):
return Err.BAD_AGGREGATE_SIGNATURE
return None

View File

@ -106,10 +106,10 @@ class CoinStore:
await self.set_spent(coin_name, block.height)
coinbase: CoinRecord = CoinRecord(
block.body.coinbase, block.height, uint32(0), False, True
block.header.data.coinbase, block.height, uint32(0), False, True
)
fees_coin: CoinRecord = CoinRecord(
block.body.fees_coin, block.height, uint32(0), False, True
block.header.data.fees_coin, block.height, uint32(0), False, True
)
await self.add_coin_record(coinbase)
@ -142,9 +142,9 @@ class CoinStore:
added: CoinRecord = CoinRecord(coin, block.height, 0, 0, 0) # type: ignore # noqa
diff_store.diffs[added.name.hex()] = added
coinbase: CoinRecord = CoinRecord(block.body.coinbase, block.height, 0, 0, 1) # type: ignore # noqa
coinbase: CoinRecord = CoinRecord(block.header.data.coinbase, block.height, 0, 0, 1) # type: ignore # noqa
diff_store.diffs[coinbase.name.hex()] = coinbase
fees_coin: CoinRecord = CoinRecord(block.body.fees_coin, block.height, 0, 0, 1) # type: ignore # noqa
fees_coin: CoinRecord = CoinRecord(block.header.data.fees_coin, block.height, 0, 0, 1) # type: ignore # noqa
diff_store.diffs[fees_coin.name.hex()] = fees_coin
for coin_name in removals:

View File

@ -22,7 +22,6 @@ from src.util.bundle_tools import best_solution_program
from src.full_node.mempool_manager import MempoolManager
from src.server.outbound_message import Delivery, Message, NodeType, OutboundMessage
from src.server.server import ChiaServer
from src.types.body import Body
from src.types.challenge import Challenge
from src.types.full_block import FullBlock
from src.types.hashable.coin import Coin, hash_coin_list
@ -1234,20 +1233,12 @@ class FullNode:
extension_data: bytes32 = bytes32([0] * 32)
# Creates a block with transactions, coinbase, and fees
body: Body = Body(
request.coinbase,
request.coinbase_signature,
fees_coin,
solution_program,
aggregate_sig,
cost,
extension_data,
)
# Creates the block header
prev_header_hash: bytes32 = target_tip.get_hash()
timestamp: uint64 = uint64(int(time.time()))
# Create filter
encoded_filter: Optional[bytes] = None
byte_array_tx: List[bytes32] = []
if spend_bundle:
additions: List[Coin] = spend_bundle.additions()
@ -1256,14 +1247,11 @@ class FullNode:
byte_array_tx.append(bytearray(coin.puzzle_hash))
for coin in removals:
byte_array_tx.append(bytearray(coin.name()))
byte_array_tx.append(bytearray(request.coinbase.puzzle_hash))
byte_array_tx.append(bytearray(fees_coin.puzzle_hash))
bip158: PyBIP158 = PyBIP158(byte_array_tx)
encoded_filter = bytes(bip158.GetEncoded())
bip158: PyBIP158 = PyBIP158(byte_array_tx)
encoded_filter = bytes(bip158.GetEncoded())
proof_of_space_hash: bytes32 = request.proof_of_space.get_hash()
body_hash: Body = body.get_hash()
difficulty = self.blockchain.get_next_difficulty(target_tip.header_hash)
assert target_tip_block is not None
@ -1309,17 +1297,33 @@ class FullNode:
additions_root = addition_merkle_set.get_root()
removal_root = removal_merkle_set.get_root()
generator_hash = (
solution_program.get_hash()
if solution_program is not None
else bytes32([0] * 32)
)
filter_hash = (
std_hash(encoded_filter)
if encoded_filter is not None
else bytes32([0] * 32)
)
block_header_data: HeaderData = HeaderData(
uint32(target_tip.height + 1),
prev_header_hash,
timestamp,
encoded_filter,
filter_hash,
proof_of_space_hash,
body_hash,
target_tip.weight + difficulty,
uint64(target_tip.data.total_iters + iterations_needed),
additions_root,
removal_root,
request.coinbase,
request.coinbase_signature,
fees_coin,
aggregate_sig,
cost,
extension_data,
generator_hash,
)
block_header_data_hash: bytes32 = block_header_data.get_hash()
@ -1327,7 +1331,8 @@ class FullNode:
# Stores this block so we can submit it to the blockchain after it's signed by harvester
self.store.add_candidate_block(
proof_of_space_hash,
body,
solution_program,
encoded_filter,
block_header_data,
request.proof_of_space,
target_tip.height + 1,
@ -1350,7 +1355,7 @@ class FullNode:
we call the unfinished_block routine.
"""
candidate: Optional[
Tuple[Body, HeaderData, ProofOfSpace]
Tuple[Optional[Program], Optional[bytes], HeaderData, ProofOfSpace]
] = self.store.get_candidate_block(header_signature.pos_hash)
if candidate is None:
self.log.warning(
@ -1358,14 +1363,16 @@ class FullNode:
)
return
# Verifies that we have the correct header and body self.stored
block_body, block_header_data, pos = candidate
generator, filt, block_header_data, pos = candidate
assert block_header_data.get_hash() == header_signature.header_hash
block_header: Header = Header(
block_header_data, header_signature.header_signature
)
unfinished_block_obj: FullBlock = FullBlock(pos, None, block_header, block_body)
unfinished_block_obj: FullBlock = FullBlock(
pos, None, block_header, generator, filt
)
# Propagate to ourselves (which validates and does further propagations)
request = full_node_protocol.RespondUnfinishedBlock(unfinished_block_obj)
@ -1400,7 +1407,8 @@ class FullNode:
unfinished_block_obj.proof_of_space,
request.proof,
unfinished_block_obj.header,
unfinished_block_obj.body,
unfinished_block_obj.transactions_generator,
unfinished_block_obj.transactions_filter,
)
if self.store.get_sync_mode():

View File

@ -342,8 +342,8 @@ class MempoolManager:
This function removes removals and additions that happened in block from mempool.
"""
removals, additions = await new_tip.tx_removals_and_additions()
additions.append(new_tip.body.coinbase)
additions.append(new_tip.body.fees_coin)
additions.append(new_tip.header.data.coinbase)
additions.append(new_tip.header.data.fees_coin)
pool.header = new_tip.header
items: Dict[bytes32, MempoolItem] = {}

View File

@ -4,7 +4,7 @@ import aiosqlite
from pathlib import Path
from typing import Dict, List, Optional, Tuple
from src.types.body import Body
from src.types.hashable.program import Program
from src.types.full_block import FullBlock
from src.types.header import HeaderData, Header
from src.types.header_block import HeaderBlock
@ -42,7 +42,10 @@ class FullNodeStore:
# Our best unfinished block
unfinished_blocks_leader: Tuple[uint32, uint64]
# Blocks which we have created, but don't have proof of space yet, old ones are cleared
candidate_blocks: Dict[bytes32, Tuple[Body, HeaderData, ProofOfSpace, uint32]]
candidate_blocks: Dict[
bytes32,
Tuple[Optional[Program], Optional[bytes], HeaderData, ProofOfSpace, uint32],
]
# Blocks which are not finalized yet (no proof of time), old ones are cleared
unfinished_blocks: Dict[Tuple[bytes32, uint64], FullBlock]
# Header hashes of unfinished blocks that we have seen recently
@ -270,25 +273,32 @@ class FullNodeStore:
def add_candidate_block(
self,
pos_hash: bytes32,
body: Body,
transactions_generator: Optional[Program],
transactions_filter: Optional[bytes],
header: HeaderData,
pos: ProofOfSpace,
height: uint32 = uint32(0),
):
self.candidate_blocks[pos_hash] = (body, header, pos, height)
self.candidate_blocks[pos_hash] = (
transactions_generator,
transactions_filter,
header,
pos,
height,
)
def get_candidate_block(
self, pos_hash: bytes32
) -> Optional[Tuple[Body, HeaderData, ProofOfSpace]]:
) -> Optional[Tuple[Optional[Program], Optional[bytes], HeaderData, ProofOfSpace]]:
res = self.candidate_blocks.get(pos_hash, None)
if res is None:
return None
return (res[0], res[1], res[2])
return (res[0], res[1], res[2], res[3])
def clear_candidate_blocks_below(self, height: uint32) -> None:
del_keys = []
for key, value in self.candidate_blocks.items():
if value[3] < height:
if value[4] < height:
del_keys.append(key)
for key in del_keys:
try:

View File

@ -1,10 +1,11 @@
from dataclasses import dataclass
from typing import List, Tuple
from typing import List, Tuple, Optional
from src.types.body import Body
from src.types.hashable.coin import Coin
from src.types.hashable.spend_bundle import SpendBundle
from src.types.header_block import HeaderBlock
from src.types.header import Header
from src.types.hashable.program import Program
from src.types.sized_bytes import bytes32
from src.util.cbor_message import cbor_message
from src.util.ints import uint32
@ -44,16 +45,15 @@ class RequestHeader:
@dataclass(frozen=True)
@cbor_message
class Header:
class RespondHeader:
header_block: HeaderBlock
bip158_filter: bytes
@dataclass(frozen=True)
@cbor_message
class RequestAncestors:
header_hash: bytes32
previous_heights_desired: List[uint32]
class RequestAllProofHashes:
pass
@dataclass(frozen=True)
@ -72,7 +72,8 @@ class RequestBody:
@dataclass(frozen=True)
@cbor_message
class RespondBody:
body: Body
header: Header
transactions_generator: Optional[Program]
height: uint32

View File

@ -1,21 +0,0 @@
from dataclasses import dataclass
from typing import Optional
from src.types.hashable.BLSSignature import BLSSignature
from src.types.hashable.program import Program
from src.types.hashable.coin import Coin
from src.util.ints import uint64
from src.util.streamable import Streamable, streamable
from src.types.sized_bytes import bytes32
@dataclass(frozen=True)
@streamable
class Body(Streamable):
coinbase: Coin
coinbase_signature: BLSSignature
fees_coin: Coin
transactions: Optional[Program]
aggregated_signature: Optional[BLSSignature]
cost: uint64
extension_data: bytes32

View File

@ -2,7 +2,7 @@ from dataclasses import dataclass
from typing import Tuple, List, Optional
from src.types.name_puzzle_condition import NPC
from src.types.body import Body
from src.types.hashable.program import Program
from src.types.hashable.coin import Coin
from src.types.header import Header
from src.types.sized_bytes import bytes32
@ -32,7 +32,8 @@ class FullBlock(Streamable):
proof_of_space: ProofOfSpace
proof_of_time: Optional[ProofOfTime]
header: Header
body: Body
transactions_generator: Optional[Program]
transactions_filter: Optional[bytes]
@property
def prev_header_hash(self) -> bytes32:
@ -53,15 +54,17 @@ class FullBlock(Streamable):
def additions(self) -> List[Coin]:
additions: List[Coin] = []
if self.body.transactions is not None:
if self.transactions_generator is not None:
# This should never throw here, block must be valid if it comes to here
err, npc_list, cost = get_name_puzzle_conditions(self.body.transactions)
err, npc_list, cost = get_name_puzzle_conditions(
self.transactions_generator
)
# created coins
if npc_list is not None:
additions.extend(additions_for_npc(npc_list))
additions.append(self.body.coinbase)
additions.append(self.body.fees_coin)
additions.append(self.header.data.coinbase)
additions.append(self.header.data.fees_coin)
return additions
@ -74,9 +77,11 @@ class FullBlock(Streamable):
removals: List[bytes32] = []
additions: List[Coin] = []
if self.body.transactions is not None:
if self.transactions_generator is not None:
# This should never throw here, block must be valid if it comes to here
err, npc_list, cost = get_name_puzzle_conditions(self.body.transactions)
err, npc_list, cost = get_name_puzzle_conditions(
self.transactions_generator
)
# build removals list
if npc_list is None:
return [], []

View File

@ -1,10 +1,13 @@
from dataclasses import dataclass
from typing import Optional
from blspy import PrependSignature
from src.types.sized_bytes import bytes32
from src.util.ints import uint64, uint32
from src.util.streamable import Streamable, streamable
from src.types.hashable.BLSSignature import BLSSignature
from src.types.hashable.coin import Coin
@dataclass(frozen=True)
@ -13,13 +16,19 @@ class HeaderData(Streamable):
height: uint32
prev_header_hash: bytes32
timestamp: uint64
filter: bytes
filter_hash: bytes32
proof_of_space_hash: bytes32
body_hash: bytes32
weight: uint64
total_iters: uint64
additions_root: bytes32
removals_root: bytes32
coinbase: Coin
coinbase_signature: BLSSignature
fees_coin: Coin
aggregated_signature: Optional[BLSSignature]
cost: uint64
extension_data: bytes32
generator_hash: bytes32
@dataclass(frozen=True)

View File

@ -35,7 +35,7 @@ async def start_ssh_server(ssh_port: int, ssh_key_filename: str, rpc_port: int):
uis = [] # type: ignore
permenantly_closed = False
ssh_server = None
node_stop_task: Optional[asyncio.Task] = None
node_stop_task = None
rpc_client: RpcClient = await RpcClient.create(rpc_port)

View File

@ -114,19 +114,19 @@ class WalletNode:
additions: List[Coin] = []
if self.wallet.can_generate_puzzle_hash(response.body.coinbase.puzzle_hash):
if self.wallet.can_generate_puzzle_hash(response.header.data.coinbase.puzzle_hash):
await self.wallet_state_manager.coin_added(
response.body.coinbase, response.height, True
response.header.data.coinbase, response.height, True
)
if self.wallet.can_generate_puzzle_hash(response.body.fees_coin.puzzle_hash):
if self.wallet.can_generate_puzzle_hash(response.header.data.fees_coin.puzzle_hash):
await self.wallet_state_manager.coin_added(
response.body.fees_coin, response.height, True
response.header.data.fees_coin, response.height, True
)
npc_list: List[NPC]
if response.body.transactions:
if response.transactions_generator:
error, npc_list, cost = get_name_puzzle_conditions(
response.body.transactions
response.transactions_generator
)
additions.extend(additions_for_npc(npc_list))

View File

@ -16,7 +16,6 @@ from src.consensus import block_rewards, pot_iterations
from src.consensus.constants import constants
from src.consensus.pot_iterations import calculate_ips_from_iterations
from src.pool import create_coinbase_coin_and_signature
from src.types.body import Body
from src.types.challenge import Challenge
from src.types.classgroup import ClassgroupElement
from src.types.full_block import FullBlock, additions_for_npc
@ -438,20 +437,11 @@ class BlockTools:
fee_hash = blspy.Util.hash256(coinbase_coin.name())
fees_coin = Coin(fee_hash, reward_puzzlehash, uint64(fee_reward))
body: Body = Body(
coinbase_coin,
coinbase_signature,
fees_coin,
transactions,
aggsig,
cost,
extension_data,
)
# Create filter
byte_array_tx: List[bytes32] = []
tx_additions: List[Coin] = []
tx_removals: List[bytes32] = []
encoded = None
if transactions:
error, npc_list, _ = get_name_puzzle_conditions(transactions)
additions: List[Coin] = additions_for_npc(npc_list)
@ -462,11 +452,8 @@ class BlockTools:
tx_removals.append(npc.coin_name)
byte_array_tx.append(bytearray(npc.coin_name))
byte_array_tx.append(bytearray(coinbase_coin.puzzle_hash))
byte_array_tx.append(bytearray(fees_coin.puzzle_hash))
bip158: PyBIP158 = PyBIP158(byte_array_tx)
encoded = bytes(bip158.GetEncoded())
bip158: PyBIP158 = PyBIP158(byte_array_tx)
encoded = bytes(bip158.GetEncoded())
removal_merkle_set = MerkleSet()
addition_merkle_set = MerkleSet()
@ -494,24 +481,37 @@ class BlockTools:
additions_root = addition_merkle_set.get_root()
removal_root = removal_merkle_set.get_root()
generator_hash = (
transactions.get_hash() if transactions is not None else bytes32([0] * 32)
)
filter_hash = std_hash(encoded) if encoded is not None else bytes32([0] * 32)
header_data: HeaderData = HeaderData(
height,
prev_header_hash,
timestamp,
encoded,
filter_hash,
proof_of_space.get_hash(),
body.get_hash(),
uint64(prev_weight + difficulty),
uint64(prev_iters + number_iters),
additions_root,
removal_root,
coinbase_coin,
coinbase_signature,
fees_coin,
aggsig,
cost,
extension_data,
generator_hash,
)
header_hash_sig: PrependSignature = plot_sk.sign_prepend(header_data.get_hash())
header: Header = Header(header_data, header_hash_sig)
full_block: FullBlock = FullBlock(proof_of_space, proof_of_time, header, body)
full_block: FullBlock = FullBlock(
proof_of_space, proof_of_time, header, transactions, encoded
)
return full_block

View File

@ -8,7 +8,6 @@ from blspy import PrivateKey
from src.full_node.blockchain import Blockchain, ReceiveBlockResult
from src.full_node.store import FullNodeStore
from src.types.body import Body
from src.types.full_block import FullBlock
from src.types.hashable.coin import Coin
from src.types.header import Header, HeaderData
@ -90,17 +89,24 @@ class TestBlockValidation:
blocks[9].header.data.height,
bytes([1] * 32),
blocks[9].header.data.timestamp,
blocks[9].header.data.filter,
blocks[9].header.data.filter_hash,
blocks[9].header.data.proof_of_space_hash,
blocks[9].header.data.body_hash,
blocks[9].header.data.weight,
blocks[9].header.data.total_iters,
blocks[9].header.data.additions_root,
blocks[9].header.data.removals_root,
blocks[9].header.data.coinbase,
blocks[9].header.data.coinbase_signature,
blocks[9].header.data.fees_coin,
blocks[9].header.data.aggregated_signature,
blocks[9].header.data.cost,
blocks[9].header.data.extension_data,
blocks[9].header.data.generator_hash,
),
blocks[9].header.harvester_signature,
),
blocks[9].body,
blocks[9].transactions_generator,
blocks[9].transactions_filter,
)
result, removed = await b.receive_block(block_bad)
assert (result) == ReceiveBlockResult.DISCONNECTED_BLOCK
@ -117,17 +123,24 @@ class TestBlockValidation:
blocks[9].header.data.height,
blocks[9].header.data.prev_header_hash,
blocks[9].header.data.timestamp - 1000,
blocks[9].header.data.filter,
blocks[9].header.data.filter_hash,
blocks[9].header.data.proof_of_space_hash,
blocks[9].header.data.body_hash,
blocks[9].header.data.weight,
blocks[9].header.data.total_iters,
blocks[9].header.data.additions_root,
blocks[9].header.data.removals_root,
blocks[9].header.data.coinbase,
blocks[9].header.data.coinbase_signature,
blocks[9].header.data.fees_coin,
blocks[9].header.data.aggregated_signature,
blocks[9].header.data.cost,
blocks[9].header.data.extension_data,
blocks[9].header.data.generator_hash,
),
blocks[9].header.harvester_signature,
),
blocks[9].body,
blocks[9].transactions_generator,
blocks[9].transactions_filter,
)
result, removed = await b.receive_block(block_bad)
assert (result) == ReceiveBlockResult.INVALID_BLOCK
@ -141,23 +154,30 @@ class TestBlockValidation:
blocks[9].header.data.height,
blocks[9].header.data.prev_header_hash,
uint64(int(time.time() + 3600 * 3)),
blocks[9].header.data.filter,
blocks[9].header.data.filter_hash,
blocks[9].header.data.proof_of_space_hash,
blocks[9].header.data.body_hash,
blocks[9].header.data.weight,
blocks[9].header.data.total_iters,
blocks[9].header.data.additions_root,
blocks[9].header.data.removals_root,
blocks[9].header.data.coinbase,
blocks[9].header.data.coinbase_signature,
blocks[9].header.data.fees_coin,
blocks[9].header.data.aggregated_signature,
blocks[9].header.data.cost,
blocks[9].header.data.extension_data,
blocks[9].header.data.generator_hash,
),
blocks[9].header.harvester_signature,
),
blocks[9].body,
blocks[9].transactions_generator,
blocks[9].transactions_filter,
)
result, removed = await b.receive_block(block_bad)
assert (result) == ReceiveBlockResult.INVALID_BLOCK
@pytest.mark.asyncio
async def test_body_hash(self, initial_blockchain):
async def test_generator_hash(self, initial_blockchain):
blocks, b = initial_blockchain
block_bad = FullBlock(
blocks[9].proof_of_space,
@ -167,17 +187,24 @@ class TestBlockValidation:
blocks[9].header.data.height,
blocks[9].header.data.prev_header_hash,
blocks[9].header.data.timestamp,
blocks[9].header.data.filter,
blocks[9].header.data.filter_hash,
blocks[9].header.data.proof_of_space_hash,
bytes([1] * 32),
blocks[9].header.data.weight,
blocks[9].header.data.total_iters,
blocks[9].header.data.additions_root,
blocks[9].header.data.removals_root,
blocks[9].header.data.coinbase,
blocks[9].header.data.coinbase_signature,
blocks[9].header.data.fees_coin,
blocks[9].header.data.aggregated_signature,
blocks[9].header.data.cost,
blocks[9].header.data.extension_data,
bytes([1] * 32),
),
blocks[9].header.harvester_signature,
),
blocks[9].body,
blocks[9].transactions_generator,
blocks[9].transactions_filter,
)
result, removed = await b.receive_block(block_bad)
assert result == ReceiveBlockResult.INVALID_BLOCK
@ -193,7 +220,8 @@ class TestBlockValidation:
blocks[9].header.data,
PrivateKey.from_seed(b"0").sign_prepend(b"random junk"),
),
blocks[9].body,
blocks[9].transactions_generator,
blocks[9].transactions_filter,
)
result, removed = await b.receive_block(block_bad)
assert result == ReceiveBlockResult.INVALID_BLOCK
@ -215,7 +243,8 @@ class TestBlockValidation:
),
blocks[9].proof_of_time,
blocks[9].header,
blocks[9].body,
blocks[9].transactions_generator,
blocks[9].transactions_filter,
)
result, removed = await b.receive_block(block_bad)
assert result == ReceiveBlockResult.INVALID_BLOCK
@ -228,20 +257,33 @@ class TestBlockValidation:
block_bad = FullBlock(
blocks[9].proof_of_space,
blocks[9].proof_of_time,
blocks[9].header,
Body(
Coin(
blocks[7].body.coinbase.parent_coin_info,
blocks[9].body.coinbase.puzzle_hash,
uint64(9999999999),
Header(
HeaderData(
blocks[9].header.data.height,
blocks[9].header.data.prev_header_hash,
blocks[9].header.data.timestamp,
blocks[9].header.data.filter_hash,
blocks[9].header.data.proof_of_space_hash,
blocks[9].header.data.weight,
blocks[9].header.data.total_iters,
blocks[9].header.data.additions_root,
blocks[9].header.data.removals_root,
Coin(
blocks[9].header.data.coinbase.parent_coin_info,
blocks[9].header.data.coinbase.puzzle_hash,
uint64(9999999999),
),
blocks[9].header.data.coinbase_signature,
blocks[9].header.data.fees_coin,
blocks[9].header.data.aggregated_signature,
blocks[9].header.data.cost,
blocks[9].header.data.extension_data,
blocks[9].header.data.generator_hash,
),
blocks[9].body.coinbase_signature,
blocks[9].body.fees_coin,
None,
blocks[9].body.aggregated_signature,
blocks[9].body.cost,
blocks[9].body.extension_data,
blocks[9].header.harvester_signature,
),
blocks[9].transactions_generator,
blocks[9].transactions_filter,
)
result, removed = await b.receive_block(block_bad)
assert result == ReceiveBlockResult.INVALID_BLOCK
@ -324,7 +366,6 @@ class TestReorgs:
test_constants, 21, [blocks[0]], 9, b"3"
)
for i in range(1, len(blocks_reorg_chain)):
print("I", i)
reorg_block = blocks_reorg_chain[i]
result, removed = await b.receive_block(reorg_block)
if reorg_block.height == 0:

View File

@ -56,7 +56,7 @@ class TestBlockchainTransactions:
spent_block = blocks[1]
spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spent_block.body.coinbase
1000, receiver_puzzlehash, spent_block.header.data.coinbase
)
assert spend_bundle is not None
@ -115,8 +115,8 @@ class TestBlockchainTransactions:
assert in_full_tips
assert farmed_block is not None
assert farmed_block.body.transactions == program
assert farmed_block.body.aggregated_signature == aggsig
assert farmed_block.transactions_generator == program
assert farmed_block.header.data.aggregated_signature == aggsig
@pytest.mark.asyncio
async def test_validate_blockchain_with_double_spend(self, two_nodes):
@ -141,10 +141,10 @@ class TestBlockchainTransactions:
spent_block = blocks[1]
spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spent_block.body.coinbase
1000, receiver_puzzlehash, spent_block.header.data.coinbase
)
spend_bundle_double = wallet_a.generate_signed_transaction(
1001, receiver_puzzlehash, spent_block.body.coinbase
1001, receiver_puzzlehash, spent_block.header.data.coinbase
)
block_spendbundle = SpendBundle.aggregate([spend_bundle, spend_bundle_double])
@ -158,7 +158,7 @@ class TestBlockchainTransactions:
next_block = new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is Err.DOUBLE_SPEND
@ -186,10 +186,10 @@ class TestBlockchainTransactions:
spent_block = blocks[1]
spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spent_block.body.coinbase
1000, receiver_puzzlehash, spent_block.header.data.coinbase
)
spend_bundle_double = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spent_block.body.coinbase
1000, receiver_puzzlehash, spent_block.header.data.coinbase
)
block_spendbundle = SpendBundle.aggregate([spend_bundle, spend_bundle_double])
@ -203,7 +203,7 @@ class TestBlockchainTransactions:
next_block = new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is Err.DUPLICATE_OUTPUT
@ -233,20 +233,24 @@ class TestBlockchainTransactions:
spent_block = blocks[1]
bad_block = blocks[2]
valid_cvp = ConditionVarPair(
ConditionOpcode.ASSERT_MY_COIN_ID, spent_block.body.coinbase.name(), None
ConditionOpcode.ASSERT_MY_COIN_ID,
spent_block.header.data.coinbase.name(),
None,
)
valid_dic = {valid_cvp.opcode: [valid_cvp]}
bad_cvp = ConditionVarPair(
ConditionOpcode.ASSERT_MY_COIN_ID, bad_block.body.coinbase.name(), None
ConditionOpcode.ASSERT_MY_COIN_ID,
bad_block.header.data.coinbase.name(),
None,
)
bad_dic = {bad_cvp.opcode: [bad_cvp]}
bad_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spent_block.body.coinbase, bad_dic
1000, receiver_puzzlehash, spent_block.header.data.coinbase, bad_dic
)
valid_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, spent_block.body.coinbase, valid_dic
1000, receiver_puzzlehash, spent_block.header.data.coinbase, valid_dic
)
# Invalid block bundle
@ -263,7 +267,7 @@ class TestBlockchainTransactions:
# Try to validate that block
next_block = invalid_new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is Err.ASSERT_MY_COIN_ID_FAILED
@ -280,7 +284,7 @@ class TestBlockchainTransactions:
)
next_block = new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is None
@ -311,20 +315,24 @@ class TestBlockchainTransactions:
# This condition requires block2 coinbase to be spent
block1_cvp = ConditionVarPair(
ConditionOpcode.ASSERT_COIN_CONSUMED, block2.body.coinbase.name(), None
ConditionOpcode.ASSERT_COIN_CONSUMED,
block2.header.data.coinbase.name(),
None,
)
block1_dic = {block1_cvp.opcode: [block1_cvp]}
block1_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block1.body.coinbase, block1_dic
1000, receiver_puzzlehash, block1.header.data.coinbase, block1_dic
)
# This condition requires block1 coinbase to be spent
block2_cvp = ConditionVarPair(
ConditionOpcode.ASSERT_COIN_CONSUMED, block1.body.coinbase.name(), None
ConditionOpcode.ASSERT_COIN_CONSUMED,
block1.header.data.coinbase.name(),
None,
)
block2_dic = {block2_cvp.opcode: [block2_cvp]}
block2_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block2.body.coinbase, block2_dic
1000, receiver_puzzlehash, block2.header.data.coinbase, block2_dic
)
# Invalid block bundle
@ -341,7 +349,7 @@ class TestBlockchainTransactions:
# Try to validate that block
next_block = invalid_new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is Err.ASSERT_COIN_CONSUMED_FAILED
@ -362,7 +370,7 @@ class TestBlockchainTransactions:
# Try to validate newly created block
next_block = new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is None
@ -397,7 +405,7 @@ class TestBlockchainTransactions:
)
block1_dic = {block1_cvp.opcode: [block1_cvp]}
block1_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block1.body.coinbase, block1_dic
1000, receiver_puzzlehash, block1.header.data.coinbase, block1_dic
)
# program that will be sent to early
@ -414,7 +422,7 @@ class TestBlockchainTransactions:
# Try to validate that block at index 11
next_block = invalid_new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is Err.ASSERT_BLOCK_INDEX_EXCEEDS_FAILED
@ -434,7 +442,7 @@ class TestBlockchainTransactions:
next_block = valid_new_blocks[12]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is None
@ -470,7 +478,7 @@ class TestBlockchainTransactions:
)
block1_dic = {block1_cvp.opcode: [block1_cvp]}
block1_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block1.body.coinbase, block1_dic
1000, receiver_puzzlehash, block1.header.data.coinbase, block1_dic
)
# program that will be sent to early
@ -487,7 +495,7 @@ class TestBlockchainTransactions:
# Try to validate that block at index 11
next_block = invalid_new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is Err.ASSERT_BLOCK_AGE_EXCEEDS_FAILED
@ -507,7 +515,7 @@ class TestBlockchainTransactions:
next_block = valid_new_blocks[12]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is None
@ -543,7 +551,7 @@ class TestBlockchainTransactions:
)
block1_dic = {block1_cvp.opcode: [block1_cvp]}
block1_spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block1.body.coinbase, block1_dic
1000, receiver_puzzlehash, block1.header.data.coinbase, block1_dic
)
# program that will be sent to early
@ -560,7 +568,7 @@ class TestBlockchainTransactions:
# Try to validate that block before 3 sec
next_block = invalid_new_blocks[11]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is Err.ASSERT_TIME_EXCEEDS_FAILED
@ -583,7 +591,7 @@ class TestBlockchainTransactions:
next_block = valid_new_blocks[12]
error = await full_node_1.blockchain._validate_transactions(
next_block, next_block.body.fees_coin.amount
next_block, next_block.header.data.fees_coin.amount
)
assert error is None

View File

@ -100,7 +100,7 @@ class TestFullNode:
spend_bundle = wallet_a.generate_signed_transaction(
100,
receiver_puzzlehash,
blocks[1].body.coinbase,
blocks[1].header.data.coinbase,
condition_dic=conditions_dict,
)
assert spend_bundle is not None
@ -197,7 +197,7 @@ class TestFullNode:
receiver_puzzlehash = wallet_receiver.get_new_puzzlehash()
spend_bundle = wallet_a.generate_signed_transaction(
100, receiver_puzzlehash, blocks[2].body.coinbase,
100, receiver_puzzlehash, blocks[2].header.data.coinbase,
)
assert spend_bundle is not None
respond_transaction = fnp.RespondTransaction(spend_bundle)
@ -225,7 +225,7 @@ class TestFullNode:
# Invalid transaction does not propagate
spend_bundle = wallet_a.generate_signed_transaction(
100000000000000, receiver_puzzlehash, blocks[3].body.coinbase,
100000000000000, receiver_puzzlehash, blocks[3].header.data.coinbase,
)
assert spend_bundle is not None
respond_transaction = fnp.RespondTransaction(spend_bundle)
@ -255,7 +255,8 @@ class TestFullNode:
blocks_new[-1].proof_of_space,
None,
blocks_new[-1].header,
blocks_new[-1].body,
blocks_new[-1].transactions_generator,
blocks_new[-1].transactions_filter,
)
unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
@ -336,7 +337,8 @@ class TestFullNode:
blocks_new[-1].proof_of_space,
None,
blocks_new[-1].header,
blocks_new[-1].body,
blocks_new[-1].transactions_generator,
blocks_new[-1].transactions_filter,
)
unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
[x async for x in full_node_1.respond_unfinished_block(unf_block_req)]
@ -395,7 +397,8 @@ class TestFullNode:
blocks_new[-1].proof_of_space,
None,
blocks_new[-1].header,
blocks_new[-1].body,
blocks_new[-1].transactions_generator,
blocks_new[-1].transactions_filter,
)
unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
[x async for x in full_node_1.respond_unfinished_block(unf_block_req)]
@ -425,7 +428,8 @@ class TestFullNode:
blocks_new[-1].proof_of_space,
None,
blocks_new[-1].header,
blocks_new[-1].body,
blocks_new[-1].transactions_generator,
blocks_new[-1].transactions_filter,
)
unf_block_req = fnp.RespondUnfinishedBlock(unf_block)
@ -487,7 +491,8 @@ class TestFullNode:
blocks_new[30].proof_of_space,
None,
blocks_new[30].header,
blocks_new[30].body,
blocks_new[30].transactions_generator,
blocks_new[30].transactions_filter,
)
unf_block_req_bad = fnp.RespondUnfinishedBlock(unf_block_not_child)
@ -510,7 +515,8 @@ class TestFullNode:
candidates[index].proof_of_space,
None,
candidates[index].header,
candidates[index].body,
candidates[index].transactions_generator,
candidates[index].transactions_filter,
)
return fnp.RespondUnfinishedBlock(unf_block)
@ -587,7 +593,8 @@ class TestFullNode:
blocks_new_3[-1].proof_of_space,
None,
blocks_new_3[-1].header,
blocks_new_3[-1].body,
blocks_new_3[-1].transactions_generator,
blocks_new_3[-1].transactions_filter,
)
unf_block_new_req = fnp.RespondUnfinishedBlock(unf_block_new)
@ -705,7 +712,8 @@ class TestFullNode:
),
blocks_new[-5].proof_of_time,
blocks_new[-5].header,
blocks_new[-5].body,
blocks_new[-5].transactions_generator,
blocks_new[-5].transactions_filter,
)
msgs = [
_ async for _ in full_node_1.respond_block(fnp.RespondBlock(block_invalid))

View File

@ -49,7 +49,7 @@ class TestMempool:
pass
spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase
1000, receiver_puzzlehash, block.header.data.coinbase
)
assert spend_bundle is not None
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
@ -83,7 +83,7 @@ class TestMempool:
pass
spend_bundle = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase
1000, receiver_puzzlehash, block.header.data.coinbase
)
assert spend_bundle is not None
tx: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
@ -135,7 +135,7 @@ class TestMempool:
pass
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase
1000, receiver_puzzlehash, block.header.data.coinbase
)
assert spend_bundle1 is not None
@ -149,7 +149,7 @@ class TestMempool:
other_receiver = WalletTool()
spend_bundle2 = wallet_a.generate_signed_transaction(
1000, other_receiver.get_new_puzzlehash(), block.body.coinbase
1000, other_receiver.get_new_puzzlehash(), block.header.data.coinbase
)
assert spend_bundle2 is not None
tx2: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
@ -184,7 +184,7 @@ class TestMempool:
pass
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase
1000, receiver_puzzlehash, block.header.data.coinbase
)
assert spend_bundle1 is not None
tx1: full_node_protocol.RespondTransaction = full_node_protocol.RespondTransaction(
@ -196,7 +196,7 @@ class TestMempool:
assert outbound.message.function == "new_transaction"
spend_bundle2 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, fee=1
1000, receiver_puzzlehash, block.header.data.coinbase, fee=1
)
assert spend_bundle2 is not None
@ -239,7 +239,7 @@ class TestMempool:
dic = {ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, dic
1000, receiver_puzzlehash, block.header.data.coinbase, dic
)
assert spend_bundle1 is not None
@ -282,7 +282,7 @@ class TestMempool:
dic = {ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, dic
1000, receiver_puzzlehash, block.header.data.coinbase, dic
)
assert spend_bundle1 is not None
@ -323,7 +323,7 @@ class TestMempool:
dic = {cvp.opcode: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, dic
1000, receiver_puzzlehash, block.header.data.coinbase, dic
)
assert spend_bundle1 is not None
@ -366,7 +366,7 @@ class TestMempool:
dic = {cvp.opcode: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, dic
1000, receiver_puzzlehash, block.header.data.coinbase, dic
)
assert spend_bundle1 is not None
@ -404,12 +404,12 @@ class TestMempool:
pass
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_MY_COIN_ID, block.body.coinbase.name(), None
ConditionOpcode.ASSERT_MY_COIN_ID, block.header.data.coinbase.name(), None
)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, dic
1000, receiver_puzzlehash, block.header.data.coinbase, dic
)
assert spend_bundle1 is not None
@ -447,12 +447,14 @@ class TestMempool:
pass
cvp = ConditionVarPair(
ConditionOpcode.ASSERT_MY_COIN_ID, blocks[2].body.coinbase.name(), None
ConditionOpcode.ASSERT_MY_COIN_ID,
blocks[2].header.data.coinbase.name(),
None,
)
dic = {cvp.opcode: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, dic
1000, receiver_puzzlehash, block.header.data.coinbase, dic
)
assert spend_bundle1 is not None
@ -497,7 +499,7 @@ class TestMempool:
dic = {cvp.opcode: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, dic
1000, receiver_puzzlehash, block.header.data.coinbase, dic
)
assert spend_bundle1 is not None
@ -545,7 +547,7 @@ class TestMempool:
dic = {cvp.opcode: [cvp]}
spend_bundle1 = wallet_a.generate_signed_transaction(
1000, receiver_puzzlehash, block.body.coinbase, dic
1000, receiver_puzzlehash, block.header.data.coinbase, dic
)
assert spend_bundle1 is not None

View File

@ -89,7 +89,8 @@ class TestStore:
# Add/get candidate block
assert db.get_candidate_block(0) is None
partial = (
blocks[5].body,
blocks[5].transactions_generator,
blocks[5].transactions_filter,
blocks[5].header.data,
blocks[5].proof_of_space,
)

View File

@ -43,10 +43,10 @@ class TestUnspent:
# Save/get block
for block in blocks:
await db.new_lca(block)
unspent = await db.get_coin_record(block.body.coinbase.name())
unspent_fee = await db.get_coin_record(block.body.fees_coin.name())
assert block.body.coinbase == unspent.coin
assert block.body.fees_coin == unspent_fee.coin
unspent = await db.get_coin_record(block.header.data.coinbase.name())
unspent_fee = await db.get_coin_record(block.header.data.fees_coin.name())
assert block.header.data.coinbase == unspent.coin
assert block.header.data.fees_coin == unspent_fee.coin
await db.close()
Path("fndb_test.db").unlink()
@ -61,15 +61,15 @@ class TestUnspent:
# Save/get block
for block in blocks:
await db.new_lca(block)
unspent = await db.get_coin_record(block.body.coinbase.name())
unspent_fee = await db.get_coin_record(block.body.fees_coin.name())
assert block.body.coinbase == unspent.coin
assert block.body.fees_coin == unspent_fee.coin
unspent = await db.get_coin_record(block.header.data.coinbase.name())
unspent_fee = await db.get_coin_record(block.header.data.fees_coin.name())
assert block.header.data.coinbase == unspent.coin
assert block.header.data.fees_coin == unspent_fee.coin
await db.set_spent(unspent.coin.name(), block.height)
await db.set_spent(unspent_fee.coin.name(), block.height)
unspent = await db.get_coin_record(block.body.coinbase.name())
unspent_fee = await db.get_coin_record(block.body.fees_coin.name())
unspent = await db.get_coin_record(block.header.data.coinbase.name())
unspent_fee = await db.get_coin_record(block.header.data.fees_coin.name())
assert unspent.spent == 1
assert unspent_fee.spent == 1
@ -86,15 +86,15 @@ class TestUnspent:
# Save/get block
for block in blocks:
await db.new_lca(block)
unspent = await db.get_coin_record(block.body.coinbase.name())
unspent_fee = await db.get_coin_record(block.body.fees_coin.name())
assert block.body.coinbase == unspent.coin
assert block.body.fees_coin == unspent_fee.coin
unspent = await db.get_coin_record(block.header.data.coinbase.name())
unspent_fee = await db.get_coin_record(block.header.data.fees_coin.name())
assert block.header.data.coinbase == unspent.coin
assert block.header.data.fees_coin == unspent_fee.coin
await db.set_spent(unspent.coin.name(), block.height)
await db.set_spent(unspent_fee.coin.name(), block.height)
unspent = await db.get_coin_record(block.body.coinbase.name())
unspent_fee = await db.get_coin_record(block.body.fees_coin.name())
unspent = await db.get_coin_record(block.header.data.coinbase.name())
unspent_fee = await db.get_coin_record(block.header.data.fees_coin.name())
assert unspent.spent == 1
assert unspent_fee.spent == 1
@ -102,8 +102,8 @@ class TestUnspent:
await db.rollback_lca_to_block(reorg_index)
for c, block in enumerate(blocks):
unspent = await db.get_coin_record(block.body.coinbase.name())
unspent_fee = await db.get_coin_record(block.body.fees_coin.name())
unspent = await db.get_coin_record(block.header.data.coinbase.name())
unspent_fee = await db.get_coin_record(block.header.data.fees_coin.name())
if c <= reorg_index:
assert unspent.spent == 1
assert unspent_fee.spent == 1
@ -129,17 +129,17 @@ class TestUnspent:
for c, block in enumerate(blocks):
unspent = await unspent_store.get_coin_record(
block.body.coinbase.name(), block.header
block.header.data.coinbase.name(), block.header
)
unspent_fee = await unspent_store.get_coin_record(
block.body.fees_coin.name(), block.header
block.header.data.fees_coin.name(), block.header
)
assert unspent.spent == 0
assert unspent_fee.spent == 0
assert unspent.confirmed_block_index == block.height
assert unspent.spent_block_index == 0
assert unspent.name == block.body.coinbase.name()
assert unspent_fee.name == block.body.fees_coin.name()
assert unspent.name == block.header.data.coinbase.name()
assert unspent_fee.name == block.header.data.fees_coin.name()
blocks_reorg_chain = bt.get_consecutive_blocks(
test_constants, 30, blocks[:90], 9, b"1"
@ -155,9 +155,9 @@ class TestUnspent:
elif reorg_block.height >= 100:
assert result == ReceiveBlockResult.ADDED_TO_HEAD
unspent = await unspent_store.get_coin_record(
reorg_block.body.coinbase.name(), reorg_block.header
reorg_block.header.data.coinbase.name(), reorg_block.header
)
assert unspent.name == reorg_block.body.coinbase.name()
assert unspent.name == reorg_block.header.data.coinbase.name()
assert unspent.confirmed_block_index == reorg_block.height
assert unspent.spent == 0
assert unspent.spent_block_index == 0
@ -185,7 +185,7 @@ class TestUnspent:
await b.receive_block(blocks[i])
assert b.get_current_tips()[0].height == num_blocks
unspent = await unspent_store.get_coin_record(
blocks[1].body.coinbase.name(), blocks[-1].header
blocks[1].header.data.coinbase.name(), blocks[-1].header
)
unspent_puzzle_hash = unspent.coin.puzzle_hash

View File

@ -56,11 +56,11 @@ class TestRpc:
assert header == blocks[7].header
coins = await client.get_unspent_coins(
blocks[-1].body.coinbase.puzzle_hash, blocks[-1].header_hash
blocks[-1].header.data.coinbase.puzzle_hash, blocks[-1].header_hash
)
assert len(coins) == 16
coins_lca = await client.get_unspent_coins(
blocks[-1].body.coinbase.puzzle_hash
blocks[-1].header.data.coinbase.puzzle_hash
)
assert len(coins_lca) == 16

View File

@ -31,9 +31,9 @@ class TestCostCalculation:
)
spend_bundle = wallet_tool.generate_signed_transaction(
blocks[1].body.coinbase.amount,
blocks[1].header.data.coinbase.amount,
receiver.get_new_puzzlehash(),
blocks[1].body.coinbase,
blocks[1].header.data.coinbase,
)
assert spend_bundle is not None
program = best_solution_program(spend_bundle)

View File

@ -41,8 +41,8 @@ class TestFilter:
for i in range(1, num_blocks):
byte_array_tx: List[bytes] = []
block = blocks[i]
coinbase = bytearray(block.body.coinbase.puzzle_hash)
fee = bytearray(block.body.fees_coin.puzzle_hash)
coinbase = bytearray(block.header.data.coinbase.puzzle_hash)
fee = bytearray(block.header.data.fees_coin.puzzle_hash)
byte_array_tx.append(coinbase)
byte_array_tx.append(fee)

View File

@ -31,25 +31,25 @@ class TestMerkleSet:
merkle_set_reverse = MerkleSet()
for block in reversed(blocks):
merkle_set_reverse.add_already_hashed(block.body.coinbase.name())
merkle_set_reverse.add_already_hashed(block.header.data.coinbase.name())
for block in blocks:
merkle_set.add_already_hashed(block.body.coinbase.name())
merkle_set.add_already_hashed(block.header.data.coinbase.name())
for block in blocks:
result, proof = merkle_set.is_included_already_hashed(
block.body.coinbase.name()
block.header.data.coinbase.name()
)
assert result is True
result_fee, proof_fee = merkle_set.is_included_already_hashed(
block.body.fees_coin.name()
block.header.data.fees_coin.name()
)
assert result_fee is False
validate_proof = confirm_included_already_hashed(
merkle_set.get_root(), block.body.coinbase.name(), proof
merkle_set.get_root(), block.header.data.coinbase.name(), proof
)
validate_proof_fee = confirm_included_already_hashed(
merkle_set.get_root(), block.body.fees_coin.name(), proof_fee
merkle_set.get_root(), block.header.data.fees_coin.name(), proof_fee
)
assert validate_proof is True
assert validate_proof_fee is False

View File

@ -4,7 +4,6 @@ import pytest
from blspy import ExtendedPrivateKey
from src.protocols.wallet_protocol import RespondBody
from src.wallet.wallet import Wallet
from src.wallet.wallet_node import WalletNode
from tests.setup_nodes import setup_two_nodes, test_constants, bt
@ -41,7 +40,9 @@ class TestWallet:
)
for i in range(1, num_blocks):
a = RespondBody(blocks[i].body, blocks[i].height)
a = RespondBody(
blocks[i].header, blocks[i].transactions_generator, blocks[i].height
)
await wallet_node.received_body(a)
assert await wallet.get_confirmed_balance() == 144000000000000
@ -76,7 +77,9 @@ class TestWallet:
)
for i in range(1, num_blocks):
a = RespondBody(blocks[i].body, blocks[i].height)
a = RespondBody(
blocks[i].header, blocks[i].transactions_generator, blocks[i].height
)
await wallet_node.received_body(a)
assert await wallet.get_confirmed_balance() == 144000000000000