changes
This commit is contained in:
parent
bb09b90c28
commit
cc796768aa
|
@ -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]
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class TestMempool:
|
|||
|
||||
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 = _
|
||||
|
@ -54,7 +54,7 @@ class TestMempool:
|
|||
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 = _
|
||||
|
@ -62,7 +62,7 @@ class TestMempool:
|
|||
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
|
||||
|
@ -88,14 +88,14 @@ class TestMempool:
|
|||
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):
|
||||
|
|
|
@ -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:
|
||||
|
@ -68,41 +71,50 @@ class WalletTool:
|
|||
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
|
||||
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: []}
|
||||
|
||||
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)))
|
||||
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])):
|
||||
|
@ -124,22 +136,10 @@ class WalletTool:
|
|||
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)
|
Loading…
Reference in New Issue