first take
This commit is contained in:
parent
eb7cc872ae
commit
c0622ec1d1
|
@ -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
|
||||
|
|
|
@ -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))
|
Loading…
Reference in New Issue