first take

This commit is contained in:
Yostra 2020-07-09 03:42:37 +02:00 committed by Gene Hoffman
parent eb7cc872ae
commit c0622ec1d1
3 changed files with 87 additions and 50 deletions

View File

@ -49,23 +49,15 @@ class RLInfo(Streamable):
class RLWallet:
private_key: PrivateKey
key_config: Dict
config: Dict
server: Optional[ChiaServer]
wallet_state_manager: Any
log: logging.Logger
wallet_info: WalletInfo
rl_coin_record: WalletCoinRecord
rl_info: RLInfo
standard_wallet: Wallet
main_wallet: Wallet
@staticmethod
async def create_rl_admin(
config: Dict,
key_config: Dict,
wallet_state_manager: Any,
wallet: Wallet,
name: str = None,
):
unused: Optional[
uint32
@ -75,18 +67,15 @@ class RLWallet:
unused = await wallet_state_manager.puzzle_store.get_unused_derivation_path()
assert unused is not None
sk_hex = key_config["wallet_sk"]
private_key = PrivateKey.from_bytes(bytes.fromhex(sk_hex))
pubkey_bytes: bytes = bytes(
master_sk_to_wallet_sk(private_key, unused).get_g1()
)
private_key = wallet_state_manager.private_key
pubkey_bytes: bytes = bytes(private_key.public_child(unused).get_public_key())
rl_info = RLInfo("admin", pubkey_bytes, None, None, None, None, None, None)
info_as_string = json.dumps(rl_info.to_json_dict())
await wallet_state_manager.user_store.create_wallet(
wallet_info: Optional[WalletInfo] = await wallet_state_manager.user_store.create_wallet(
"RL Admin", WalletType.RATE_LIMITED, info_as_string
)
wallet_info = await wallet_state_manager.user_store.get_last_wallet()
if wallet_info is None:
raise Exception("wallet_info is None")
@ -103,18 +92,12 @@ class RLWallet:
)
await wallet_state_manager.puzzle_store.set_used_up_to(unused)
self = await RLWallet.create(
config, key_config, wallet_state_manager, wallet_info, wallet, name
)
self = await RLWallet.create(wallet_state_manager, wallet_info)
return self
@staticmethod
async def create_rl_user(
config: Dict,
key_config: Dict,
wallet_state_manager: Any,
wallet: Wallet,
name: str = None,
):
async with wallet_state_manager.puzzle_store.lock:
unused: Optional[
@ -127,8 +110,8 @@ class RLWallet:
)
assert unused is not None
sk_hex = key_config["wallet_sk"]
private_key = PrivateKey.from_bytes(bytes.fromhex(sk_hex))
private_key = wallet_state_manager.private_key
pubkey_bytes: bytes = bytes(
master_sk_to_wallet_sk(private_key, unused).get_g1()
)
@ -142,9 +125,7 @@ class RLWallet:
if wallet_info is None:
raise Exception("wallet_info is None")
self = await RLWallet.create(
config, key_config, wallet_state_manager, wallet_info, wallet, name
)
self = await RLWallet.create(wallet_state_manager, wallet_info)
await wallet_state_manager.puzzle_store.add_derivation_paths(
[
@ -163,18 +144,13 @@ class RLWallet:
@staticmethod
async def create(
config: Dict,
key_config: Dict,
wallet_state_manager: Any,
info: WalletInfo,
wallet: Wallet,
name: str = None,
):
self = RLWallet()
self.config = config
self.key_config = key_config
sk_hex = self.key_config["wallet_sk"]
self.private_key = PrivateKey.from_bytes(bytes.fromhex(sk_hex))
self.private_key = wallet_state_manager.private_key
if name:
self.log = logging.getLogger(name)
else:
@ -183,14 +159,14 @@ class RLWallet:
self.wallet_state_manager = wallet_state_manager
self.wallet_info = info
self.standard_wallet = wallet
self.rl_info = RLInfo.from_json_dict(json.loads(info.data))
self.main_wallet = wallet_state_manager.main_wallet
return self
async def admin_create_coin(
self, interval: uint64, limit: uint64, user_pubkey: str, amount: uint64
) -> bool:
coins = await self.standard_wallet.select_coins(amount)
coins = await self.wallet_state_manager.main_wallet.select_coins(amount)
if coins is None:
return False
@ -211,9 +187,9 @@ class RLWallet:
clawback_pk=self.rl_info.admin_pubkey,
)
rl_puzzle_hash = rl_puzzle.get_hash()
rl_puzzle_hash = rl_puzzle.get_tree_hash()
index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(
self.rl_info.admin_pubkey.hex()
PrivateKey.from_bytes(self.rl_info.admin_pubkey)
)
assert index is not None
@ -226,13 +202,13 @@ class RLWallet:
)
await self.wallet_state_manager.puzzle_store.add_derivation_paths([record])
spend_bundle = await self.standard_wallet.generate_signed_transaction(
spend_bundle = await self.main_wallet.generate_signed_transaction(
amount, rl_puzzle_hash, uint64(0), origin_id, coins
)
if spend_bundle is None:
return False
await self.standard_wallet.push_transaction(spend_bundle)
await self.main_wallet.push_transaction(spend_bundle)
new_rl_info = RLInfo(
"admin",
self.rl_info.admin_pubkey,
@ -271,7 +247,7 @@ class RLWallet:
clawback_pk=admin_pubkey_bytes,
)
rl_puzzle_hash = rl_puzzle.get_hash()
rl_puzzle_hash = rl_puzzle.get_tree_hash()
new_rl_info = RLInfo(
"admin",
admin_pubkey_bytes,
@ -282,7 +258,7 @@ class RLWallet:
origin_id,
rl_puzzle_hash,
)
rl_puzzle_hash = rl_puzzle.get_hash()
rl_puzzle_hash = rl_puzzle.get_tree_hash()
index = await self.wallet_state_manager.puzzle_store.index_for_pubkey(
self.rl_info.user_pubkey.hex()
@ -323,7 +299,6 @@ class RLWallet:
return available_amount
async def get_confirmed_balance(self) -> uint64:
self.log.info(f"wallet_id balance {self.wallet_info.id}")
return await self.wallet_state_manager.get_confirmed_balance_for_wallet(
self.wallet_info.id
)
@ -413,17 +388,17 @@ class RLWallet:
spends.append((puzzle, CoinSolution(coin, solution)))
return spends
def rl_generate_signed_transaction(self, amount, to_puzzle_hash):
async def rl_generate_signed_transaction(self, amount, to_puzzle_hash):
if amount > self.rl_coin_record.coin.amount:
return None
transaction = self.rl_generate_unsigned_transaction(to_puzzle_hash, amount)
transaction = await self.rl_generate_unsigned_transaction(to_puzzle_hash, amount)
return self.rl_sign_transaction(transaction)
async def rl_sign_transaction(self, spends: List[Tuple[Program, CoinSolution]]):
sigs = []
for puzzle, solution in spends:
pubkey, secretkey = await self.get_keys(solution.coin.puzzle_hash)
signature = secretkey.sign(Program(solution.solution).get_hash())
signature = secretkey.sign(Program(solution.solution).get_tree_hash())
sigs.append(signature)
aggsig = AugSchemeMPL.aggregate(sigs)
@ -468,7 +443,7 @@ class RLWallet:
sigs = []
for puzzle, solution in spends:
pubkey, secretkey = await self.get_keys_pk(clawback_pubkey)
signature = secretkey.sign(Program(solution.solution).get_hash())
signature = secretkey.sign(Program(solution.solution).get_tree_hash())
sigs.append(signature)
aggsig = AugSchemeMPL.aggregate(sigs)
solution_list = []
@ -530,7 +505,7 @@ class RLWallet:
rl_parent.parent_coin_info,
)
signature = secretkey.sign(solution.get_hash())
signature = secretkey.sign(solution.get_tree_hash())
list_of_coinsolutions.append(
CoinSolution(self.rl_coin_record.coin, Program.to([puzzle, solution]))
)
@ -566,6 +541,6 @@ class RLWallet:
return SpendBundle(list_of_coinsolutions, aggsig)
def rl_get_aggregation_puzzlehash(self, wallet_puzzle):
puzzle_hash = rl_make_aggregation_puzzle(wallet_puzzle).get_hash()
puzzle_hash = rl_make_aggregation_puzzle(wallet_puzzle).get_tree_hash()
return puzzle_hash

View File

View File

@ -0,0 +1,62 @@
import asyncio
import pytest
from src.simulator.simulator_protocol import FarmNewBlockProtocol
from src.types.peer_info import PeerInfo
from src.util.ints import uint16, uint32, uint64
from src.wallet.rl_wallet.rl_wallet import RLWallet
from tests.setup_nodes import setup_simulators_and_wallets
from src.consensus.block_rewards import calculate_base_fee, calculate_block_reward
from tests.time_out_assert import time_out_assert
@pytest.fixture(scope="module")
def event_loop():
loop = asyncio.get_event_loop()
yield loop
class TestCCWallet:
@pytest.fixture(scope="function")
async def two_wallet_nodes(self):
async for _ in setup_simulators_and_wallets(
1, 2, {"COINBASE_FREEZE_PERIOD": 0}
):
yield _
@pytest.mark.asyncio
async def test_create_rl_coin(self, two_wallet_nodes):
num_blocks = 5
full_nodes, wallets = two_wallet_nodes
full_node_1, server_1 = full_nodes[0]
wallet_node, server_2 = wallets[0]
wallet = wallet_node.wallet_state_manager.main_wallet
ph = await wallet.get_new_puzzlehash()
await 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.get_confirmed_balance, funds)
rl_admin: RLWallet = await RLWallet.create_rl_admin(wallet_node.wallet_state_manager)
rl_user: RLWallet = await RLWallet.create_rl_user(wallet_node.wallet_state_manager)
interval = uint64(2)
limit = uint64(1)
amount = uint64(100)
await rl_admin.admin_create_coin(interval ,limit,rl_user.rl_info.user_pubkey.hex(), amount)
origin_id = rl_admin.rl_info.rl_origin_id
admin_pubkey = rl_admin.rl_info.admin_pubkey
await rl_user.set_user_info(interval, limit, origin_id, admin_pubkey.hex())
for i in range(1, num_blocks):
await full_node_1.farm_new_block(FarmNewBlockProtocol(ph))