fix multi receive, add multi send

This commit is contained in:
Yostra 2020-09-17 16:39:11 -07:00 committed by Gene Hoffman
parent 4c16f2b8d0
commit e2ac44d017
4 changed files with 131 additions and 16 deletions

View File

@ -541,7 +541,7 @@ class WalletRpcApi:
fee = uint64(0)
tx: TransactionRecord = await wallet.generate_signed_transaction(
amount, puzzle_hash, fee
[amount], [puzzle_hash], fee
)
await wallet.wallet_state_manager.add_pending_transaction(tx)

View File

@ -300,6 +300,8 @@ class CCWallet:
except Program.EvalError:
return False
parents = []
for name_solution in sexp.as_iter():
_ = name_solution.as_python()
if len(_) != 2:
@ -355,11 +357,10 @@ class CCWallet:
lineage_proof = get_lineage_proof_from_coin_and_puz(
coin, puzzle_program
)
parents.append(lineage_proof)
await self.add_lineage(coin_name, lineage_proof)
return True
return False
return len(parents) > 0
async def generator_received(
self, height: uint32, header_hash: bytes32, generator: Program, action_id: int
@ -611,8 +612,8 @@ class CCWallet:
async def generate_signed_transaction(
self,
amount: uint64,
to_address: bytes32,
amounts: List[uint64],
puzzle_hashes: List[bytes32],
fee: uint64 = uint64(0),
origin_id: bytes32 = None,
coins: Set[Coin] = None,
@ -620,20 +621,28 @@ class CCWallet:
sigs: List[G2Element] = []
# Get coins and calculate amount of change required
outgoing_amount = uint64(sum(amounts))
if coins is None:
selected_coins: Set[Coin] = await self.select_coins(amount)
selected_coins: Set[Coin] = await self.select_coins(uint64(outgoing_amount + fee))
else:
selected_coins = coins
total_amount = sum([x.amount for x in selected_coins])
change = total_amount - amount
change = total_amount - outgoing_amount - fee
primaries = []
for amount, puzzle_hash in zip(amounts, puzzle_hashes):
primaries.append({"puzzlehash": puzzle_hash, "amount": amount})
primaries = [{"puzzlehash": to_address, "amount": amount}]
if change > 0:
changepuzzlehash = await self.get_new_inner_hash()
primaries.append({"puzzlehash": changepuzzlehash, "amount": change})
innersol = self.standard_wallet.make_solution(primaries=primaries)
if fee > 0:
innersol = self.standard_wallet.make_solution(primaries=primaries, fee=fee)
else:
innersol = self.standard_wallet.make_solution(primaries=primaries)
coin = selected_coins.pop()
inner_puzzle = await self.inner_puzzle_for_cc_puzhash(coin.puzzle_hash)
@ -663,11 +672,12 @@ class CCWallet:
innersol_list,
sigs,
)
# TODO add support for array in stored records
return TransactionRecord(
confirmed_at_index=uint32(0),
created_at_time=uint64(int(time.time())),
to_puzzle_hash=to_address,
amount=uint64(amount),
to_puzzle_hash=puzzle_hashes[0],
amount=uint64(outgoing_amount),
fee_amount=uint64(0),
incoming=False,
confirmed=False,

View File

@ -33,6 +33,13 @@ class TestCCWallet:
):
yield _
@pytest.fixture(scope="function")
async def three_wallet_nodes(self):
async for _ in setup_simulators_and_wallets(
1, 3, {"COINBASE_FREEZE_PERIOD": 0}
):
yield _
@pytest.mark.asyncio
async def test_colour_creation(self, two_wallet_nodes):
num_blocks = 5
@ -116,7 +123,7 @@ class TestCCWallet:
)
cc_2_hash = await cc_wallet_2.get_new_inner_hash()
tx_record = await cc_wallet.generate_signed_transaction(uint64(60), cc_2_hash)
tx_record = await cc_wallet.generate_signed_transaction([uint64(60)], [cc_2_hash])
await wallet.wallet_state_manager.add_pending_transaction(tx_record)
for i in range(1, num_blocks):
@ -129,7 +136,7 @@ class TestCCWallet:
await time_out_assert(30, cc_wallet_2.get_unconfirmed_balance, 60)
cc_hash = await cc_wallet.get_new_inner_hash()
tx_record = await cc_wallet_2.generate_signed_transaction(uint64(15), cc_hash)
tx_record = await cc_wallet_2.generate_signed_transaction([uint64(15)], [cc_hash])
await wallet.wallet_state_manager.add_pending_transaction(tx_record)
for i in range(1, num_blocks):
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))
@ -285,7 +292,7 @@ class TestCCWallet:
)
cc_2_hash = await cc_wallet_2.get_new_inner_hash()
tx_record = await cc_wallet.generate_signed_transaction(uint64(60), cc_2_hash)
tx_record = await cc_wallet.generate_signed_transaction([uint64(60)], [cc_2_hash])
await wallet.wallet_state_manager.add_pending_transaction(tx_record)
for i in range(1, num_blocks):
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))
@ -312,3 +319,101 @@ class TestCCWallet:
await time_out_assert(15, wsm.get_confirmed_balance_for_wallet, 70, id)
await time_out_assert(15, cc_wallet_2.get_confirmed_balance, 60)
await time_out_assert(15, cc_wallet_2.get_unconfirmed_balance, 60)
@pytest.mark.asyncio
async def test_cc_spend_multiple(self, three_wallet_nodes):
num_blocks = 8
full_nodes, wallets = three_wallet_nodes
full_node_1, server_1 = full_nodes[0]
wallet_node_0, wallet_server_0 = wallets[0]
wallet_node_1, wallet_server_1 = wallets[1]
wallet_node_2, wallet_server_2 = wallets[2]
wallet_0 = wallet_node_0.wallet_state_manager.main_wallet
wallet_1 = wallet_node_1.wallet_state_manager.main_wallet
wallet_2 = wallet_node_2.wallet_state_manager.main_wallet
ph = await wallet_0.get_new_puzzlehash()
await wallet_server_0.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
await wallet_server_1.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
await wallet_server_2.start_client(PeerInfo("localhost", uint16(server_1._port)), None)
for i in range(1, 4):
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))
funds = sum(
[
calculate_base_fee(uint32(i)) + calculate_block_reward(uint32(i))
for i in range(1, 4 - 2)
]
)
await time_out_assert(15, wallet_0.get_confirmed_balance, funds)
cc_wallet_0: CCWallet = await CCWallet.create_new_cc(
wallet_node_0.wallet_state_manager, wallet_0, uint64(100)
)
for i in range(1, num_blocks):
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))
await time_out_assert(15, cc_wallet_0.get_confirmed_balance, 100)
await time_out_assert(15, cc_wallet_0.get_unconfirmed_balance, 100)
assert cc_wallet_0.cc_info.my_genesis_checker is not None
colour = cc_wallet_0.get_colour()
cc_wallet_1: CCWallet = await CCWallet.create_wallet_for_cc(
wallet_node_1.wallet_state_manager, wallet_1, colour
)
cc_wallet_2: CCWallet = await CCWallet.create_wallet_for_cc(
wallet_node_2.wallet_state_manager, wallet_2, colour
)
assert (
cc_wallet_0.cc_info.my_genesis_checker
== cc_wallet_1.cc_info.my_genesis_checker
)
assert (
cc_wallet_0.cc_info.my_genesis_checker
== cc_wallet_2.cc_info.my_genesis_checker
)
cc_1_hash = await cc_wallet_1.get_new_inner_hash()
cc_2_hash = await cc_wallet_2.get_new_inner_hash()
tx_record = await cc_wallet_0.generate_signed_transaction([uint64(60), uint64(20)], [cc_1_hash, cc_2_hash])
await wallet_0.wallet_state_manager.add_pending_transaction(tx_record)
for i in range(1, num_blocks):
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))
await time_out_assert(15, cc_wallet_0.get_confirmed_balance, 20)
await time_out_assert(15, cc_wallet_0.get_unconfirmed_balance, 20)
await time_out_assert(30, cc_wallet_1.get_confirmed_balance, 60)
await time_out_assert(30, cc_wallet_1.get_unconfirmed_balance, 60)
await time_out_assert(30, cc_wallet_2.get_confirmed_balance, 20)
await time_out_assert(30, cc_wallet_2.get_unconfirmed_balance, 20)
cc_hash = await cc_wallet_0.get_new_inner_hash()
tx_record = await cc_wallet_1.generate_signed_transaction([uint64(15)], [cc_hash])
await wallet_1.wallet_state_manager.add_pending_transaction(tx_record)
tx_record_2 = await cc_wallet_2.generate_signed_transaction([uint64(20)], [cc_hash])
await wallet_2.wallet_state_manager.add_pending_transaction(tx_record_2)
for i in range(1, num_blocks):
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))
await time_out_assert(15, cc_wallet_0.get_confirmed_balance, 55)
await time_out_assert(15, cc_wallet_0.get_unconfirmed_balance, 55)
await time_out_assert(30, cc_wallet_1.get_confirmed_balance, 45)
await time_out_assert(30, cc_wallet_1.get_unconfirmed_balance, 45)
await time_out_assert(30, cc_wallet_2.get_confirmed_balance, 0)
await time_out_assert(30, cc_wallet_2.get_unconfirmed_balance, 0)

View File

@ -112,7 +112,7 @@ class TestCCTrades:
# send cc_wallet 2 a coin
cc_hash = await cc_wallet_2.get_new_inner_hash()
tx_record = await cc_wallet.generate_signed_transaction(uint64(1), cc_hash)
tx_record = await cc_wallet.generate_signed_transaction([uint64(1)], [cc_hash])
await wallet_0.wallet_state_manager.add_pending_transaction(tx_record)
for i in range(0, buffer_blocks):
await full_node.farm_new_block(FarmNewBlockProtocol(token_bytes()))