Skip to content

Commit

Permalink
changes
Browse files Browse the repository at this point in the history
  • Loading branch information
Yostra committed Feb 4, 2020
1 parent bb09b90 commit cc79676
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 55 deletions.
4 changes: 4 additions & 0 deletions src/wallet/puzzles/puzzle_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ def make_create_coin_condition(puzzle_hash, amount):
return [ConditionOpcode.CREATE_COIN, puzzle_hash, amount]


def make_assert_aggsig_condition(pubkey):
return [ConditionOpcode.AGG_SIG, pubkey]


def make_assert_coin_consumed_condition(coin_name):
return [ConditionOpcode.ASSERT_COIN_CONSUMED, coin_name]

Expand Down
10 changes: 5 additions & 5 deletions tests/test_mempool.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ async def test_basic_mempool(self, two_nodes):

block = blocks[1]
async for _ in full_node_1.block(peer_protocol.Block(block)):
spend_bundle = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, [block.body.coinbase])
spend_bundle = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase)
tx: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle)
async for _ in full_node_1.transaction(tx):
outbound: OutboundMessage = _
Expand All @@ -54,15 +54,15 @@ async def test_double_spend(self, two_nodes):
async for _ in full_node_1.block(peer_protocol.Block(block)):
pass

spend_bundle1 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, [block.body.coinbase])
spend_bundle1 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase)
tx1: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle1)
async for _ in full_node_1.transaction(tx1):
outbound: OutboundMessage = _
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "maybe_transaction"

other_receiver = WalletTool()
spend_bundle2 = wallet_a.generate_signed_transaction(1000, other_receiver.get_new_puzzlehash(), [block.body.coinbase])
spend_bundle2 = wallet_a.generate_signed_transaction(1000, other_receiver.get_new_puzzlehash(), block.body.coinbase)
tx2: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle2)
async for _ in full_node_1.transaction(tx2):
pass
Expand All @@ -88,14 +88,14 @@ async def test_double_spend_with_higher_fee(self, two_nodes):
async for _ in full_node_1.block(peer_protocol.Block(block)):
pass

spend_bundle1 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, [block.body.coinbase])
spend_bundle1 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase)
tx1: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle1)
async for _ in full_node_1.transaction(tx1):
outbound: OutboundMessage = _
# Maybe transaction means that it's accepted in mempool
assert outbound.message.function == "maybe_transaction"

spend_bundle2 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, [block.body.coinbase], 1)
spend_bundle2 = wallet_a.generate_signed_transaction(1000, receiver_puzzlehash, block.body.coinbase, fee=1)

tx2: peer_protocol.Transaction = peer_protocol.Transaction(spend_bundle2)
async for _ in full_node_1.transaction(tx2):
Expand Down
100 changes: 50 additions & 50 deletions tests/wallet_tools.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
from typing import List, Optional
from typing import List, Optional, Dict

import clvm
from os import urandom
from blspy import ExtendedPrivateKey

from src.types.hashable import ProgramHash, CoinSolution, SpendBundle, Program, BLSSignature, Coin
from src.util.Conditions import conditions_by_opcode
from src.util.Conditions import conditions_by_opcode, ConditionVarPair, ConditionOpcode
from src.util.consensus import hash_key_pairs_for_conditions_dict, conditions_for_solution
from src.wallet import keychain
from src.wallet.BLSPrivateKey import BLSPrivateKey
from src.wallet.puzzles.p2_conditions import puzzle_for_conditions
from src.wallet.puzzles.p2_delegated_conditions import solution_for_conditions
from src.wallet.puzzles.p2_delegated_puzzle import puzzle_for_pk
from src.wallet.puzzles.puzzle_utils import make_assert_coin_consumed_condition, make_assert_min_time_condition, \
make_assert_my_coin_id_condition, make_create_coin_condition
make_assert_my_coin_id_condition, make_create_coin_condition, make_assert_block_index_exceeds_condition, \
make_assert_block_age_exceeds_condition, make_assert_aggsig_condition


class WalletTool:
Expand Down Expand Up @@ -68,41 +71,50 @@ def sign(self, value, pubkey):
blskey = BLSPrivateKey(privatekey)
return blskey.sign(value)

def make_solution(self, primaries=[], min_time=0, me={}, consumed=[]):
def make_solution(self, condition_dic: Dict[ConditionOpcode, List[ConditionVarPair]]):
ret = []
for primary in primaries:
ret.append(make_create_coin_condition(
primary['puzzlehash'], primary['amount']))
for coin in consumed:
ret.append(make_assert_coin_consumed_condition(coin))
if min_time > 0:
ret.append(make_assert_min_time_condition(min_time))
if me:
ret.append(make_assert_my_coin_id_condition(me['id']))

for con_list in condition_dic.values():
for cvp in con_list:
if cvp.opcode == ConditionOpcode.CREATE_COIN:
ret.append(make_create_coin_condition(cvp.var1, cvp.var2))
if cvp.opcode == ConditionOpcode.AGG_SIG:
ret.append(make_assert_aggsig_condition(cvp.var1))
if cvp.opcode == ConditionOpcode.ASSERT_COIN_CONSUMED:
ret.append(make_assert_coin_consumed_condition(cvp.var1))
if cvp.opcode == ConditionOpcode.ASSERT_MIN_TIME:
ret.append(make_assert_min_time_condition(cvp.var1))
if cvp.opcode == ConditionOpcode.ASSERT_MY_COIN_ID:
ret.append(make_assert_my_coin_id_condition(cvp.var1))
if cvp.opcode == ConditionOpcode.ASSERT_BLOCK_INDEX_EXCEEDS:
ret.append(make_assert_block_index_exceeds_condition(cvp.var1))
if cvp.opcode == ConditionOpcode.ASSERT_BLOCK_AGE_EXCEEDS:
ret.append(make_assert_block_age_exceeds_condition(cvp.var1))

return clvm.to_sexp_f([puzzle_for_conditions(ret), []])

def generate_unsigned_transaction(self, amount, newpuzzlehash, utxos: List[Coin], fee: int = 0):
def generate_unsigned_transaction(self, amount, newpuzzlehash, coin: Coin,
condition_dic: Dict[ConditionOpcode, List[ConditionVarPair]]= {}, fee: int = 0):
spends = []
output_created = False
spend_value = sum([coin.amount for coin in utxos])
spend_value = coin.amount
change = spend_value - amount - fee
for coin in utxos:
puzzle_hash = coin.puzzle_hash

pubkey, secretkey = self.get_keys(puzzle_hash)
puzzle = puzzle_for_pk(pubkey.serialize())
if output_created is False:
primaries = [{'puzzlehash': newpuzzlehash, 'amount': amount}]
if change > 0:
changepuzzlehash = self.get_new_puzzlehash()
primaries.append(
{'puzzlehash': changepuzzlehash, 'amount': change})
# add change coin into temp_utxo set
solution = self.make_solution(primaries=primaries)
output_created = True
else:
solution = self.make_solution(consumed=[coin.name()])
spends.append((puzzle, CoinSolution(coin, solution)))
puzzle_hash = coin.puzzle_hash
pubkey, secretkey = self.get_keys(puzzle_hash)
puzzle = puzzle_for_pk(pubkey.serialize())
if ConditionOpcode.CREATE_COIN not in condition_dic:
condition_dic = {ConditionOpcode.CREATE_COIN: []}

output = ConditionVarPair(ConditionOpcode.CREATE_COIN, newpuzzlehash, amount)
condition_dic[output.opcode].append(output)
if change > 0:
changepuzzlehash = self.get_new_puzzlehash()
change_output = ConditionVarPair(ConditionOpcode.CREATE_COIN, changepuzzlehash, change)
condition_dic[output.opcode].append(change_output)
solution = self.make_solution(condition_dic)
else:
solution = self.make_solution(condition_dic)

spends.append((puzzle, CoinSolution(coin, solution)))
return spends

def sign_transaction(self, spends: (Program, [CoinSolution])):
Expand All @@ -124,22 +136,10 @@ def sign_transaction(self, spends: (Program, [CoinSolution])):
spend_bundle = SpendBundle(solution_list, aggsig)
return spend_bundle

def generate_signed_transaction(self, amount, newpuzzlehash, coins: List[Coin], fee: int = 0) -> Optional[SpendBundle]:
transaction = self.generate_unsigned_transaction(amount, newpuzzlehash, coins, fee)
def generate_signed_transaction(self, amount, newpuzzlehash, coin: Coin,
condition_dic: Dict[ConditionOpcode, List[ConditionVarPair]] = {},
fee: int = 0) -> Optional[SpendBundle]:
transaction = self.generate_unsigned_transaction(amount, newpuzzlehash, coin, condition_dic, fee)
if transaction is None:
return None
return self.sign_transaction(transaction)


"""
Copyright 2018 Chia Network Inc
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
return self.sign_transaction(transaction)

0 comments on commit cc79676

Please sign in to comment.