chia-blockchain/chia/wallet/rl_wallet/rl_wallet_puzzles.py

125 lines
3.8 KiB
Python

import math
from binascii import hexlify
from clvm_tools import binutils
from chia.types.blockchain_format.program import Program
from chia.types.blockchain_format.sized_bytes import bytes32
from chia.types.condition_opcodes import ConditionOpcode
from chia.util.ints import uint64
from chia.wallet.chialisp import sexp
from chia.wallet.puzzles.load_clvm import load_clvm
RATE_LIMITED_MODE = 1
AGGREGATION_MODE = 2
CLAWBACK_MODE = 3
def rl_puzzle_for_pk(
pubkey: bytes,
rate_amount: uint64,
interval_time: uint64,
origin_id: bytes32,
clawback_pk: bytes,
):
"""
Solution to this puzzle must be in format:
(1 my_parent_id, my_puzzlehash, my_amount, outgoing_puzzle_hash, outgoing_amount,
min_block_time, parent_parent_id, parent_amount, fee)
RATE LIMIT LOGIC:
M - chia_per_interval
N - interval_blocks
V - amount being spent
MIN_BLOCK_AGE = V / (M / N)
if not (min_block_age * M >= V * N) do X (raise)
ASSERT_COIN_BLOCK_AGE_EXCEEDS min_block_age
"""
MOD = load_clvm("rl.clvm")
return MOD.curry(pubkey, rate_amount, interval_time, origin_id, clawback_pk)
def rl_make_aggregation_solution(myid, wallet_coin_primary_input, wallet_coin_amount):
opcode_myid = "0x" + hexlify(myid).decode("ascii")
primary_input = "0x" + hexlify(wallet_coin_primary_input).decode("ascii")
sol = sexp(opcode_myid, primary_input, wallet_coin_amount)
return Program.to(binutils.assemble(sol))
def make_clawback_solution(puzzlehash, amount, fee):
opcode_create = hexlify(ConditionOpcode.CREATE_COIN).decode("ascii")
solution = sexp(CLAWBACK_MODE, sexp("0x" + opcode_create, "0x" + str(puzzlehash), amount - fee))
return Program.to(binutils.assemble(solution))
def rl_make_solution_mode_2(
my_puzzle_hash,
consolidating_primary_input,
consolidating_coin_puzzle_hash,
outgoing_amount,
my_primary_input,
incoming_amount,
parent_amount,
my_parent_parent_id,
):
my_puzzle_hash = hexlify(my_puzzle_hash).decode("ascii")
consolidating_primary_input = hexlify(consolidating_primary_input).decode("ascii")
consolidating_coin_puzzle_hash = hexlify(consolidating_coin_puzzle_hash).decode("ascii")
primary_input = hexlify(my_primary_input).decode("ascii")
sol = sexp(
AGGREGATION_MODE,
"0x" + my_puzzle_hash,
"0x" + consolidating_primary_input,
"0x" + consolidating_coin_puzzle_hash,
outgoing_amount,
"0x" + primary_input,
incoming_amount,
parent_amount,
"0x" + str(my_parent_parent_id),
)
return Program.to(binutils.assemble(sol))
def solution_for_rl(
my_parent_id: bytes32,
my_puzzlehash: bytes32,
my_amount: uint64,
out_puzzlehash: bytes32,
out_amount: uint64,
my_parent_parent_id: bytes32,
parent_amount: uint64,
interval,
limit,
fee,
):
"""
Solution is (1 my_parent_id, my_puzzlehash, my_amount, outgoing_puzzle_hash, outgoing_amount,
min_block_time, parent_parent_id, parent_amount, fee)
min block time = Math.ceil((new_amount * self.interval) / self.limit)
"""
min_block_count = math.ceil((out_amount * interval) / limit)
solution = sexp(
RATE_LIMITED_MODE,
"0x" + my_parent_id.hex(),
"0x" + my_puzzlehash.hex(),
my_amount,
"0x" + out_puzzlehash.hex(),
out_amount,
min_block_count,
"0x" + my_parent_parent_id.hex(),
parent_amount,
fee,
)
return Program.to(binutils.assemble(solution))
def rl_make_aggregation_puzzle(wallet_puzzle):
"""
If Wallet A wants to send further funds to Wallet B then they can lock them up using this code
Solution will be (my_id wallet_coin_primary_input wallet_coin_amount)
"""
MOD = load_clvm("rl_aggregation.clvm")
return MOD.curry(wallet_puzzle)