transaction history /value
This commit is contained in:
parent
d4a96d3e1b
commit
a54931d735
|
@ -252,10 +252,12 @@ function get_wallet_balance_response(response) {
|
|||
var confirmed = parseInt(response["confirmed_wallet_balance"])
|
||||
var unconfirmed = parseInt(response["unconfirmed_wallet_balance"])
|
||||
var pending = confirmed - unconfirmed
|
||||
var wallet_id = response["wallet_id"]
|
||||
|
||||
var wallet_id = response["wallet_id"]
|
||||
console.log("wallet_id = " + wallet_id + "confirmed: " + confirmed + "unconfirmed: " + unconfirmed )
|
||||
chia_confirmed = chia_formatter(confirmed, 'mojo').to('chia').toString()
|
||||
chia_pending = chia_formatter(pending, 'mojo').to('chia').toString()
|
||||
chia_pending_abs = chia_formatter(Math.abs(pending), 'mojo').to('chia').toString()
|
||||
|
||||
wallet_balance_holder = document.querySelector("#" + "balance_wallet_" + wallet_id )
|
||||
wallet_pending_holder = document.querySelector("#" + "pending_wallet_" + wallet_id )
|
||||
|
@ -265,7 +267,7 @@ function get_wallet_balance_response(response) {
|
|||
if (pending > 0) {
|
||||
pending_textfield.innerHTML = lock + " - " + chia_pending + " CH"
|
||||
} else {
|
||||
pending_textfield.innerHTML = lock + " " + chia_pending + " CH"
|
||||
pending_textfield.innerHTML = lock + " " + chia_pending_abs + " CH"
|
||||
}
|
||||
}
|
||||
if (wallet_balance_holder) {
|
||||
|
@ -275,7 +277,7 @@ function get_wallet_balance_response(response) {
|
|||
if (pending > 0) {
|
||||
wallet_pending_holder.innerHTML = lock + " - " + chia_pending + " CH"
|
||||
} else {
|
||||
wallet_pending_holder.innerHTML = lock + " " + chia_pending + " CH"
|
||||
wallet_pending_holder.innerHTML = lock + " " + chia_pending_abs + " CH"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -323,10 +323,12 @@ function get_wallet_balance_response(response) {
|
|||
var confirmed = parseInt(response["confirmed_wallet_balance"])
|
||||
var unconfirmed = parseInt(response["unconfirmed_wallet_balance"])
|
||||
var pending = confirmed - unconfirmed
|
||||
var wallet_id = response["wallet_id"]
|
||||
|
||||
var wallet_id = response["wallet_id"]
|
||||
console.log("wallet_id = " + wallet_id + "confirmed: " + confirmed + "unconfirmed: " + unconfirmed )
|
||||
chia_confirmed = chia_formatter(confirmed, 'mojo').to('chia').toString()
|
||||
chia_pending = chia_formatter(pending, 'mojo').to('chia').toString()
|
||||
chia_pending_abs = chia_formatter(Math.abs(pending), 'mojo').to('chia').toString()
|
||||
|
||||
wallet_balance_holder = document.querySelector("#" + "balance_wallet_" + wallet_id )
|
||||
wallet_pending_holder = document.querySelector("#" + "pending_wallet_" + wallet_id )
|
||||
|
@ -336,7 +338,7 @@ function get_wallet_balance_response(response) {
|
|||
if (pending > 0) {
|
||||
pending_textfield.innerHTML = lock + " - " + chia_pending + " CH"
|
||||
} else {
|
||||
pending_textfield.innerHTML = lock + " " + chia_pending + " CH"
|
||||
pending_textfield.innerHTML = lock + " " + chia_pending_abs + " CH"
|
||||
}
|
||||
}
|
||||
if (wallet_balance_holder) {
|
||||
|
@ -346,7 +348,7 @@ function get_wallet_balance_response(response) {
|
|||
if (pending > 0) {
|
||||
wallet_pending_holder.innerHTML = lock + " - " + chia_pending + " CH"
|
||||
} else {
|
||||
wallet_pending_holder.innerHTML = lock + " " + chia_pending + " CH"
|
||||
wallet_pending_holder.innerHTML = lock + " " + chia_pending_abs + " CH"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -220,6 +220,7 @@ function get_wallet_balance_response(response) {
|
|||
|
||||
chia_confirmed = chia_formatter(confirmed, 'mojo').to('chia').toString()
|
||||
chia_pending = chia_formatter(pending, 'mojo').to('chia').toString()
|
||||
chia_pending_abs = chia_formatter(Math.abs(pending), 'mojo').to('chia').toString()
|
||||
|
||||
wallet_balance_holder = document.querySelector("#" + "balance_wallet_" + wallet_id )
|
||||
wallet_pending_holder = document.querySelector("#" + "pending_wallet_" + wallet_id )
|
||||
|
@ -231,7 +232,7 @@ function get_wallet_balance_response(response) {
|
|||
if (pending > 0) {
|
||||
wallet_pending_holder.innerHTML = lock + " - " + chia_pending + " CH"
|
||||
} else {
|
||||
wallet_pending_holder.innerHTML = lock + " " + chia_pending + " CH"
|
||||
wallet_pending_holder.innerHTML = lock + " " + chia_pending_abs + " CH"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,3 +73,15 @@ class SpendBundle(Streamable):
|
|||
result.append(rem)
|
||||
|
||||
return result
|
||||
|
||||
def not_ephemeral_additions(self):
|
||||
all_removals = self.removals()
|
||||
all_additions = self.additions()
|
||||
result: List[Coin] = []
|
||||
|
||||
for add in all_additions:
|
||||
if add in all_removals:
|
||||
continue
|
||||
result.append(add)
|
||||
|
||||
return result
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import logging
|
||||
import time
|
||||
|
||||
import clvm
|
||||
from typing import Dict, Optional, List, Any, Set
|
||||
|
@ -27,6 +28,7 @@ from src.wallet.cc_wallet.cc_wallet_puzzles import (
|
|||
create_spend_for_ephemeral,
|
||||
)
|
||||
from src.wallet.cc_wallet.ccparent import CCParent
|
||||
from src.wallet.transaction_record import TransactionRecord
|
||||
from src.wallet.util.json_util import dict_to_json_str
|
||||
from src.wallet.util.wallet_types import WalletType
|
||||
from src.wallet.wallet import Wallet
|
||||
|
@ -75,14 +77,62 @@ class CCWallet:
|
|||
"CC Wallet", WalletType.COLOURED_COIN, info_as_string
|
||||
)
|
||||
if self.wallet_info is None:
|
||||
raise
|
||||
raise ValueError("Internal Error")
|
||||
|
||||
spend_bundle = await self.generate_new_coloured_coin(amount)
|
||||
if spend_bundle is None:
|
||||
raise
|
||||
raise ValueError("Internal Error, unable to generate new coloured coin")
|
||||
|
||||
await self.wallet_state_manager.add_new_wallet(self, self.wallet_info.id)
|
||||
await self.standard_wallet.push_transaction(spend_bundle)
|
||||
|
||||
# Change and actual coloured coin
|
||||
non_ephemeral_spends: List[Coin] = spend_bundle.not_ephemeral_additions()
|
||||
cc_coin = None
|
||||
puzzle_store = self.wallet_state_manager.puzzle_store
|
||||
|
||||
for c in non_ephemeral_spends:
|
||||
info = await puzzle_store.wallet_info_for_puzzle_hash(c.puzzle_hash)
|
||||
if info is None:
|
||||
raise ValueError("Internal Error")
|
||||
id, wallet_type = info
|
||||
if id == self.wallet_info.id:
|
||||
cc_coin = c
|
||||
|
||||
if cc_coin is None:
|
||||
raise ValueError("Internal Error, unable to generate new coloured coin")
|
||||
|
||||
regular_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=uint64(int(time.time())),
|
||||
to_puzzle_hash=cc_coin.puzzle_hash,
|
||||
amount=uint64(cc_coin.amount),
|
||||
fee_amount=uint64(0),
|
||||
incoming=False,
|
||||
confirmed=False,
|
||||
sent=uint32(0),
|
||||
spend_bundle=spend_bundle,
|
||||
additions=spend_bundle.additions(),
|
||||
removals=spend_bundle.removals(),
|
||||
wallet_id=self.wallet_state_manager.main_wallet.wallet_info.id,
|
||||
sent_to=[],
|
||||
)
|
||||
cc_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=uint64(int(time.time())),
|
||||
to_puzzle_hash=cc_coin.puzzle_hash,
|
||||
amount=uint64(cc_coin.amount),
|
||||
fee_amount=uint64(0),
|
||||
incoming=True,
|
||||
confirmed=False,
|
||||
sent=uint32(10),
|
||||
spend_bundle=None,
|
||||
additions=spend_bundle.additions(),
|
||||
removals=spend_bundle.removals(),
|
||||
wallet_id=self.wallet_info.id,
|
||||
sent_to=[],
|
||||
)
|
||||
await self.standard_wallet.push_transaction(regular_record)
|
||||
await self.standard_wallet.push_transaction(cc_record)
|
||||
return self
|
||||
|
||||
@staticmethod
|
||||
|
@ -154,20 +204,18 @@ class CCWallet:
|
|||
|
||||
async def get_unconfirmed_balance(self) -> uint64:
|
||||
confirmed = await self.get_confirmed_balance()
|
||||
unconfirmed_tx = await self.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(
|
||||
unconfirmed_tx: List[TransactionRecord] = await self.wallet_state_manager.tx_store.get_unconfirmed_for_wallet(
|
||||
self.wallet_info.id
|
||||
)
|
||||
addition_amount = 0
|
||||
removal_amount = 0
|
||||
|
||||
for record in unconfirmed_tx:
|
||||
for coin in record.additions:
|
||||
if await self.wallet_state_manager.puzzle_store.puzzle_hash_exists(
|
||||
coin.puzzle_hash
|
||||
):
|
||||
addition_amount += coin.amount
|
||||
for coin in record.removals:
|
||||
removal_amount += coin.amount
|
||||
if record.incoming:
|
||||
addition_amount += record.amount
|
||||
else:
|
||||
removal_amount += record.amount
|
||||
|
||||
result = confirmed - removal_amount + addition_amount
|
||||
|
||||
self.log.info(f"Unconfirmed balance for cc wallet is {result}")
|
||||
|
@ -426,16 +474,16 @@ class CCWallet:
|
|||
cc_puzzle = cc_wallet_puzzles.cc_make_puzzle(cc_inner, self.cc_info.my_core)
|
||||
cc_puzzle_hash = cc_puzzle.get_tree_hash()
|
||||
|
||||
spend_bundle = await self.standard_wallet.generate_signed_transaction(
|
||||
tx = await self.standard_wallet.generate_signed_transaction(
|
||||
uint64(0), cc_puzzle_hash, uint64(0), origin_id, coins
|
||||
)
|
||||
self.log.warning(f"cc_puzzle_hash is {cc_puzzle_hash}")
|
||||
eve_coin = Coin(origin_id, cc_puzzle_hash, uint64(0))
|
||||
if spend_bundle is None:
|
||||
if tx is None or tx.spend_bundle is None:
|
||||
return None
|
||||
|
||||
eve_spend = cc_generate_eve_spend(eve_coin, cc_puzzle)
|
||||
full_spend = SpendBundle.aggregate([spend_bundle, eve_spend])
|
||||
full_spend = SpendBundle.aggregate([tx.spend_bundle, eve_spend])
|
||||
|
||||
future_parent = CCParent(eve_coin.parent_coin_info, cc_inner, eve_coin.amount)
|
||||
eve_parent = CCParent(
|
||||
|
@ -446,7 +494,39 @@ class CCWallet:
|
|||
await self.add_parent(eve_coin.parent_coin_info, eve_parent)
|
||||
|
||||
if send:
|
||||
await self.standard_wallet.push_transaction(full_spend)
|
||||
regular_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=uint64(int(time.time())),
|
||||
to_puzzle_hash=cc_puzzle_hash,
|
||||
amount=uint64(0),
|
||||
fee_amount=uint64(0),
|
||||
incoming=False,
|
||||
confirmed=False,
|
||||
sent=uint32(10),
|
||||
spend_bundle=full_spend,
|
||||
additions=full_spend.additions(),
|
||||
removals=full_spend.removals(),
|
||||
wallet_id=uint32(1),
|
||||
sent_to=[],
|
||||
)
|
||||
cc_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=uint64(int(time.time())),
|
||||
to_puzzle_hash=cc_puzzle_hash,
|
||||
amount=uint64(0),
|
||||
fee_amount=uint64(0),
|
||||
incoming=True,
|
||||
confirmed=False,
|
||||
sent=uint32(0),
|
||||
spend_bundle=full_spend,
|
||||
additions=full_spend.additions(),
|
||||
removals=full_spend.removals(),
|
||||
wallet_id=self.wallet_info.id,
|
||||
sent_to=[],
|
||||
)
|
||||
await self.wallet_state_manager.add_transaction(regular_record)
|
||||
await self.wallet_state_manager.add_pending_transaction(cc_record)
|
||||
|
||||
return full_spend
|
||||
|
||||
async def get_cc_spendable_coins(self) -> List[WalletCoinRecord]:
|
||||
|
@ -676,8 +756,23 @@ class CCWallet:
|
|||
aggsig = BLSSignature.aggregate(sigs)
|
||||
spend_bundle = SpendBundle(list_of_solutions, aggsig)
|
||||
|
||||
tx_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=uint64(int(time.time())),
|
||||
to_puzzle_hash=to_address,
|
||||
amount=uint64(amount),
|
||||
fee_amount=uint64(0),
|
||||
incoming=False,
|
||||
confirmed=False,
|
||||
sent=uint32(0),
|
||||
spend_bundle=spend_bundle,
|
||||
additions=spend_bundle.additions(),
|
||||
removals=spend_bundle.removals(),
|
||||
wallet_id=self.wallet_info.id,
|
||||
sent_to=[],
|
||||
)
|
||||
await self.wallet_state_manager.add_pending_transaction(
|
||||
spend_bundle, self.wallet_info.id
|
||||
tx_record
|
||||
)
|
||||
|
||||
return spend_bundle
|
||||
|
@ -725,17 +820,17 @@ class CCWallet:
|
|||
cc_puzzle = cc_wallet_puzzles.cc_make_puzzle(cc_inner, cc_core)
|
||||
cc_puzzle_hash = cc_puzzle.get_tree_hash()
|
||||
|
||||
spend_bundle = await self.standard_wallet.generate_signed_transaction(
|
||||
tx_record: Optional[TransactionRecord] = await self.standard_wallet.generate_signed_transaction(
|
||||
amount, cc_puzzle_hash, uint64(0), origin_id, coins
|
||||
)
|
||||
self.log.warning(f"cc_puzzle_hash is {cc_puzzle_hash}")
|
||||
eve_coin = Coin(origin_id, cc_puzzle_hash, amount)
|
||||
if spend_bundle is None:
|
||||
if tx_record is None or tx_record.spend_bundle is None:
|
||||
return None
|
||||
|
||||
eve_spend = cc_generate_eve_spend(eve_coin, cc_puzzle)
|
||||
|
||||
full_spend = SpendBundle.aggregate([spend_bundle, eve_spend])
|
||||
full_spend = SpendBundle.aggregate([tx_record.spend_bundle, eve_spend])
|
||||
return full_spend
|
||||
|
||||
async def create_spend_bundle_relative_amount(
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
import time
|
||||
from pathlib import Path
|
||||
from secrets import token_bytes
|
||||
from typing import Dict, Optional, Tuple, List, Any
|
||||
import logging
|
||||
|
||||
|
@ -10,13 +12,14 @@ from src.types.coin_solution import CoinSolution
|
|||
from src.types.program import Program
|
||||
from src.types.sized_bytes import bytes32
|
||||
from src.types.spend_bundle import SpendBundle
|
||||
from src.util.ints import uint32
|
||||
from src.util.ints import uint32, uint64
|
||||
from src.wallet.cc_wallet import cc_wallet_puzzles
|
||||
from src.wallet.cc_wallet.cc_wallet import CCWallet
|
||||
from src.wallet.cc_wallet.cc_wallet_puzzles import (
|
||||
create_spend_for_auditor,
|
||||
create_spend_for_ephemeral,
|
||||
)
|
||||
from src.wallet.transaction_record import TransactionRecord
|
||||
from src.wallet.wallet import Wallet
|
||||
from src.wallet.wallet_state_manager import WalletStateManager
|
||||
from clvm_tools import binutils
|
||||
|
@ -476,8 +479,22 @@ class TradeManager:
|
|||
zero_spend_list.append(spend_bundle)
|
||||
spend_bundle = SpendBundle.aggregate(zero_spend_list)
|
||||
|
||||
await self.wallet_state_manager.add_pending_transaction(
|
||||
spend_bundle, self.wallet_state_manager.main_wallet.wallet_info.id
|
||||
tx_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=uint64(int(time.time())),
|
||||
to_puzzle_hash=token_bytes(),
|
||||
amount=uint64(0),
|
||||
fee_amount=uint64(0),
|
||||
incoming=False,
|
||||
confirmed=False,
|
||||
sent=uint32(0),
|
||||
spend_bundle=spend_bundle,
|
||||
additions=spend_bundle.additions(),
|
||||
removals=spend_bundle.removals(),
|
||||
wallet_id=uint32(1),
|
||||
sent_to=[],
|
||||
)
|
||||
|
||||
await self.wallet_state_manager.add_pending_transaction(tx_record)
|
||||
|
||||
return True
|
||||
|
|
|
@ -4,6 +4,7 @@ from typing import Optional, List, Tuple
|
|||
from src.types.coin import Coin
|
||||
from src.types.spend_bundle import SpendBundle
|
||||
from src.types.sized_bytes import bytes32
|
||||
from src.util.hash import std_hash
|
||||
from src.util.streamable import Streamable, streamable
|
||||
from src.util.ints import uint32, uint64, uint8
|
||||
|
||||
|
@ -35,4 +36,4 @@ class TransactionRecord(Streamable):
|
|||
def name(self) -> bytes32:
|
||||
if self.spend_bundle:
|
||||
return self.spend_bundle.name()
|
||||
return self.get_hash()
|
||||
return std_hash(bytes(self.to_puzzle_hash) + bytes(self.created_at_time) + bytes(self.amount))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import time
|
||||
from typing import Dict, Optional, List, Tuple, Set, Any
|
||||
import clvm
|
||||
import logging
|
||||
|
@ -13,7 +14,7 @@ from src.util.condition_tools import (
|
|||
conditions_by_opcode,
|
||||
hash_key_pairs_for_conditions_dict,
|
||||
)
|
||||
from src.util.ints import uint64
|
||||
from src.util.ints import uint64, uint32
|
||||
from src.wallet.BLSPrivateKey import BLSPrivateKey
|
||||
from src.wallet.puzzles.p2_conditions import puzzle_for_conditions
|
||||
from src.wallet.puzzles.p2_delegated_puzzle import puzzle_for_pk
|
||||
|
@ -24,6 +25,7 @@ from src.wallet.puzzles.puzzle_utils import (
|
|||
make_create_coin_condition,
|
||||
make_assert_fee_condition,
|
||||
)
|
||||
from src.wallet.transaction_record import TransactionRecord
|
||||
from src.wallet.wallet_coin_record import WalletCoinRecord
|
||||
from src.wallet.wallet_info import WalletInfo
|
||||
|
||||
|
@ -299,7 +301,7 @@ class Wallet:
|
|||
|
||||
async def generate_signed_transaction_dict(
|
||||
self, data: Dict[str, Any]
|
||||
) -> Optional[SpendBundle]:
|
||||
) -> Optional[TransactionRecord]:
|
||||
""" Use this to generate transaction. """
|
||||
# Check that both are integers
|
||||
if not isinstance(data["amount"], int) or not isinstance(data["amount"], int):
|
||||
|
@ -322,7 +324,7 @@ class Wallet:
|
|||
fee: uint64 = uint64(0),
|
||||
origin_id: bytes32 = None,
|
||||
coins: Set[Coin] = None,
|
||||
) -> Optional[SpendBundle]:
|
||||
) -> Optional[TransactionRecord]:
|
||||
""" Use this to generate transaction. """
|
||||
|
||||
transaction = await self.generate_unsigned_transaction(
|
||||
|
@ -333,14 +335,41 @@ class Wallet:
|
|||
return None
|
||||
|
||||
self.log.info("About to sign a transaction")
|
||||
return await self.sign_transaction(transaction)
|
||||
spend_bundle: Optional[SpendBundle] = await self.sign_transaction(transaction)
|
||||
if spend_bundle is None:
|
||||
return None
|
||||
|
||||
async def push_transaction(self, spend_bundle: SpendBundle) -> None:
|
||||
""" Use this API to send transactions. """
|
||||
await self.wallet_state_manager.add_pending_transaction(
|
||||
spend_bundle, self.wallet_info.id
|
||||
now = uint64(int(time.time()))
|
||||
add_list: List[Coin] = []
|
||||
rem_list: List[Coin] = []
|
||||
|
||||
for add in spend_bundle.additions():
|
||||
add_list.append(add)
|
||||
for rem in spend_bundle.removals():
|
||||
rem_list.append(rem)
|
||||
|
||||
tx_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=now,
|
||||
to_puzzle_hash=puzzle_hash,
|
||||
amount=uint64(amount),
|
||||
fee_amount=uint64(fee),
|
||||
incoming=False,
|
||||
confirmed=False,
|
||||
sent=uint32(0),
|
||||
spend_bundle=spend_bundle,
|
||||
additions=add_list,
|
||||
removals=rem_list,
|
||||
wallet_id=self.wallet_info.id,
|
||||
sent_to=[],
|
||||
)
|
||||
|
||||
return tx_record
|
||||
|
||||
async def push_transaction(self, tx: TransactionRecord) -> None:
|
||||
""" Use this API to send transactions. """
|
||||
await self.wallet_state_manager.add_pending_transaction(tx)
|
||||
|
||||
# This is also defined in CCWallet as get_sigs()
|
||||
# I think this should be a the default way the wallet gets signatures in sign_transaction()
|
||||
async def get_sigs_for_innerpuz_with_innersol(
|
||||
|
|
|
@ -403,17 +403,15 @@ class WalletStateManager:
|
|||
transactions.
|
||||
"""
|
||||
confirmed = await self.get_confirmed_balance_for_wallet(wallet_id)
|
||||
unconfirmed_tx = await self.tx_store.get_unconfirmed_for_wallet(wallet_id)
|
||||
addition_amount = 0
|
||||
unconfirmed_tx: List[TransactionRecord] = await self.tx_store.get_unconfirmed_for_wallet(wallet_id)
|
||||
removal_amount = 0
|
||||
|
||||
for record in unconfirmed_tx:
|
||||
for coin in record.additions:
|
||||
if await self.puzzle_store.puzzle_hash_exists(coin.puzzle_hash):
|
||||
addition_amount += coin.amount
|
||||
for coin in record.removals:
|
||||
removal_amount += coin.amount
|
||||
result = confirmed - removal_amount + addition_amount
|
||||
|
||||
removal_amount += record.amount
|
||||
removal_amount += record.fee_amount
|
||||
|
||||
result = confirmed - removal_amount
|
||||
return uint64(result)
|
||||
|
||||
async def unconfirmed_additions_for_wallet(
|
||||
|
@ -455,11 +453,11 @@ class WalletStateManager:
|
|||
|
||||
await self.wallet_store.set_spent(coin.name(), index)
|
||||
|
||||
unconfirmed_record = await self.tx_store.unconfirmed_with_removal_coin(
|
||||
unconfirmed_record: List[TransactionRecord] = await self.tx_store.unconfirmed_with_removal_coin(
|
||||
coin.name()
|
||||
)
|
||||
if unconfirmed_record:
|
||||
await self.tx_store.set_confirmed(unconfirmed_record.name(), index)
|
||||
for unconfirmed in unconfirmed_record:
|
||||
await self.tx_store.set_confirmed(unconfirmed.name(), index)
|
||||
|
||||
async def coin_added(self, coin: Coin, index: uint32, coinbase: bool):
|
||||
"""
|
||||
|
@ -491,9 +489,10 @@ class WalletStateManager:
|
|||
coin.name()
|
||||
)
|
||||
|
||||
if unconfirmed_record:
|
||||
if len(unconfirmed_record) > 0:
|
||||
# This is the change from this transaction
|
||||
await self.tx_store.set_confirmed(unconfirmed_record.name(), index)
|
||||
for record in unconfirmed_record:
|
||||
await self.tx_store.set_confirmed(record.name(), index)
|
||||
else:
|
||||
now = uint64(int(time.time()))
|
||||
tx_record = TransactionRecord(
|
||||
|
@ -526,59 +525,22 @@ class WalletStateManager:
|
|||
assert block.removals is not None
|
||||
await wallet.coin_added(coin, index, header_hash, block.removals)
|
||||
|
||||
async def add_pending_transaction(self, spend_bundle: SpendBundle, wallet_id):
|
||||
async def add_pending_transaction(self, tx_record: TransactionRecord):
|
||||
"""
|
||||
Called from wallet_node before new transaction is sent to the full_node
|
||||
Called from wallet before new transaction is sent to the full_node
|
||||
"""
|
||||
now = uint64(int(time.time()))
|
||||
add_list: List[Coin] = []
|
||||
rem_list: List[Coin] = []
|
||||
total_removed = 0
|
||||
total_added = 0
|
||||
outgoing_amount = 0
|
||||
|
||||
for add in spend_bundle.additions():
|
||||
total_added += add.amount
|
||||
add_list.append(add)
|
||||
for rem in spend_bundle.removals():
|
||||
total_removed += rem.amount
|
||||
rem_list.append(rem)
|
||||
|
||||
fee_amount = total_removed - total_added
|
||||
|
||||
# Figure out if we are sending to ourself or someone else.
|
||||
to_puzzle_hash: Optional[bytes32] = None
|
||||
for add in add_list:
|
||||
if not await self.puzzle_store.puzzle_hash_exists(add.puzzle_hash):
|
||||
to_puzzle_hash = add.puzzle_hash
|
||||
outgoing_amount += add.amount
|
||||
break
|
||||
|
||||
# If there is no addition for outside puzzlehash we are sending tx to ourself
|
||||
if to_puzzle_hash is None:
|
||||
to_puzzle_hash = add_list[0].puzzle_hash
|
||||
outgoing_amount += total_added
|
||||
|
||||
tx_record = TransactionRecord(
|
||||
confirmed_at_index=uint32(0),
|
||||
created_at_time=now,
|
||||
to_puzzle_hash=to_puzzle_hash,
|
||||
amount=uint64(outgoing_amount),
|
||||
fee_amount=uint64(fee_amount),
|
||||
incoming=False,
|
||||
confirmed=False,
|
||||
sent=uint32(0),
|
||||
spend_bundle=spend_bundle,
|
||||
additions=add_list,
|
||||
removals=rem_list,
|
||||
wallet_id=wallet_id,
|
||||
sent_to=[],
|
||||
)
|
||||
# Wallet node will use this queue to retry sending this transaction until full nodes receives it
|
||||
await self.tx_store.add_transaction_record(tx_record)
|
||||
self.state_changed("pending_transaction")
|
||||
self.tx_pending_changed()
|
||||
|
||||
async def add_transaction(self, tx_record: TransactionRecord):
|
||||
"""
|
||||
Called from wallet to add transaction that is not being set to full_node
|
||||
"""
|
||||
await self.tx_store.add_transaction_record(tx_record)
|
||||
|
||||
async def remove_from_queue(
|
||||
self,
|
||||
spendbundle_id: bytes32,
|
||||
|
@ -1390,7 +1352,7 @@ class WalletStateManager:
|
|||
await callback(height, header_hash, program, action.id)
|
||||
|
||||
async def get_transaction_status(
|
||||
self, tx_id: SpendBundle
|
||||
self, tx_id: bytes32
|
||||
) -> List[Tuple[str, MempoolInclusionStatus, Optional[str]]]:
|
||||
tr: Optional[TransactionRecord] = await self.get_transaction(tx_id)
|
||||
ret_list = []
|
||||
|
|
|
@ -142,29 +142,29 @@ class WalletTransactionStore:
|
|||
|
||||
async def unconfirmed_with_removal_coin(
|
||||
self, removal_id: bytes32
|
||||
) -> Optional[TransactionRecord]:
|
||||
) -> List[TransactionRecord]:
|
||||
""" Returns a record containing removed coin with id: removal_id"""
|
||||
|
||||
result = []
|
||||
all_unconfirmed: List[TransactionRecord] = await self.get_all_unconfirmed()
|
||||
for record in all_unconfirmed:
|
||||
for coin in record.removals:
|
||||
if coin.name() == removal_id:
|
||||
return record
|
||||
result.append(record)
|
||||
|
||||
return None
|
||||
return result
|
||||
|
||||
async def unconfirmed_with_addition_coin(
|
||||
self, removal_id: bytes32
|
||||
) -> Optional[TransactionRecord]:
|
||||
) -> List[TransactionRecord]:
|
||||
""" Returns a record containing removed coin with id: removal_id"""
|
||||
|
||||
result = []
|
||||
all_unconfirmed: List[TransactionRecord] = await self.get_all_unconfirmed()
|
||||
for record in all_unconfirmed:
|
||||
for coin in record.additions:
|
||||
if coin.name() == removal_id:
|
||||
return record
|
||||
result.append(record)
|
||||
|
||||
return None
|
||||
return result
|
||||
|
||||
async def increment_sent(
|
||||
self,
|
||||
|
@ -237,7 +237,6 @@ class WalletTransactionStore:
|
|||
"""
|
||||
Checks DB and cache for TransactionRecord with id: id and returns it.
|
||||
"""
|
||||
|
||||
if id.hex() in self.tx_record_cache:
|
||||
return self.tx_record_cache[id.hex()]
|
||||
cursor = await self.db_connection.execute(
|
||||
|
|
|
@ -100,20 +100,20 @@ class TestTransactions:
|
|||
== funds
|
||||
)
|
||||
|
||||
spend_bundle = await wallet_0.wallet_state_manager.main_wallet.generate_signed_transaction(
|
||||
tx = await wallet_0.wallet_state_manager.main_wallet.generate_signed_transaction(
|
||||
10, ph1, 0
|
||||
)
|
||||
await wallet_0.wallet_state_manager.main_wallet.push_transaction(spend_bundle)
|
||||
await wallet_0.wallet_state_manager.main_wallet.push_transaction(tx)
|
||||
|
||||
await asyncio.sleep(3)
|
||||
|
||||
bundle0 = full_node_0.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle2 = full_node_2.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle0 = full_node_0.mempool_manager.get_spendbundle(tx.name())
|
||||
bundle1 = full_node_1.mempool_manager.get_spendbundle(tx.name())
|
||||
bundle2 = full_node_2.mempool_manager.get_spendbundle(tx.name())
|
||||
|
||||
assert spend_bundle == bundle0
|
||||
assert spend_bundle == bundle1
|
||||
assert spend_bundle == bundle2
|
||||
assert tx.spend_bundle == bundle0
|
||||
assert tx.spend_bundle == bundle1
|
||||
assert tx.spend_bundle == bundle2
|
||||
|
||||
# Farm another block
|
||||
for i in range(1, 8):
|
||||
|
@ -178,19 +178,19 @@ class TestTransactions:
|
|||
== funds
|
||||
)
|
||||
|
||||
spend_bundle = await wallet_0.wallet_state_manager.main_wallet.generate_signed_transaction(
|
||||
tx = await wallet_0.wallet_state_manager.main_wallet.generate_signed_transaction(
|
||||
10, token_bytes(), 0
|
||||
)
|
||||
await wallet_0.wallet_state_manager.main_wallet.push_transaction(spend_bundle)
|
||||
await wallet_0.wallet_state_manager.main_wallet.push_transaction(tx)
|
||||
|
||||
await asyncio.sleep(2)
|
||||
|
||||
bundle0 = full_node_0.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle2 = full_node_2.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle0 = full_node_0.mempool_manager.get_spendbundle(tx.name())
|
||||
bundle1 = full_node_1.mempool_manager.get_spendbundle(tx.name())
|
||||
bundle2 = full_node_2.mempool_manager.get_spendbundle(tx.name())
|
||||
|
||||
assert spend_bundle == bundle0
|
||||
assert spend_bundle == bundle1
|
||||
assert tx.spend_bundle == bundle0
|
||||
assert tx.spend_bundle == bundle1
|
||||
assert None is bundle2
|
||||
|
||||
# make a final connection.
|
||||
|
@ -200,10 +200,10 @@ class TestTransactions:
|
|||
|
||||
await asyncio.sleep(2)
|
||||
|
||||
bundle0 = full_node_0.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle2 = full_node_2.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle0 = full_node_0.mempool_manager.get_spendbundle(tx.name())
|
||||
bundle1 = full_node_1.mempool_manager.get_spendbundle(tx.name())
|
||||
bundle2 = full_node_2.mempool_manager.get_spendbundle(tx.name())
|
||||
|
||||
assert spend_bundle == bundle0
|
||||
assert spend_bundle == bundle1
|
||||
assert spend_bundle == bundle2
|
||||
assert tx.spend_bundle == bundle0
|
||||
assert tx.spend_bundle == bundle1
|
||||
assert tx.spend_bundle == bundle2
|
||||
|
|
|
@ -93,12 +93,12 @@ class TestWalletSimulator:
|
|||
assert await wallet.get_confirmed_balance() == funds
|
||||
assert await wallet.get_unconfirmed_balance() == funds
|
||||
|
||||
spend_bundle = await wallet.generate_signed_transaction(
|
||||
tx = await wallet.generate_signed_transaction(
|
||||
10,
|
||||
await wallet_node_2.wallet_state_manager.main_wallet.get_new_puzzlehash(),
|
||||
0,
|
||||
)
|
||||
await wallet.push_transaction(spend_bundle)
|
||||
await wallet.push_transaction(tx)
|
||||
|
||||
await asyncio.sleep(2)
|
||||
confirmed_balance = await wallet.get_confirmed_balance()
|
||||
|
@ -205,14 +205,14 @@ class TestWalletSimulator:
|
|||
== funds
|
||||
)
|
||||
|
||||
spend_bundle = await wallet_0.wallet_state_manager.main_wallet.generate_signed_transaction(
|
||||
tx = await wallet_0.wallet_state_manager.main_wallet.generate_signed_transaction(
|
||||
10, token_bytes(), 0
|
||||
)
|
||||
await wallet_0.wallet_state_manager.main_wallet.push_transaction(spend_bundle)
|
||||
await wallet_0.wallet_state_manager.main_wallet.push_transaction(tx)
|
||||
|
||||
await asyncio.sleep(1)
|
||||
|
||||
bundle0 = full_node_0.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle0 = full_node_0.mempool_manager.get_spendbundle(tx.name())
|
||||
assert bundle0 is not None
|
||||
|
||||
# wallet0 <-> sever1
|
||||
|
@ -221,7 +221,7 @@ class TestWalletSimulator:
|
|||
)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
bundle1 = full_node_1.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle1 = full_node_1.mempool_manager.get_spendbundle(tx.name())
|
||||
assert bundle1 is not None
|
||||
|
||||
# wallet0 <-> sever2
|
||||
|
@ -230,7 +230,7 @@ class TestWalletSimulator:
|
|||
)
|
||||
await asyncio.sleep(1)
|
||||
|
||||
bundle2 = full_node_2.mempool_manager.get_spendbundle(spend_bundle.name())
|
||||
bundle2 = full_node_2.mempool_manager.get_spendbundle(tx.name())
|
||||
assert bundle2 is not None
|
||||
|
||||
@pytest.mark.asyncio
|
||||
|
@ -267,13 +267,13 @@ class TestWalletSimulator:
|
|||
assert await wallet_0.get_confirmed_balance() == funds
|
||||
assert await wallet_0.get_unconfirmed_balance() == funds
|
||||
|
||||
spend_bundle = await wallet_0.generate_signed_transaction(
|
||||
tx = await wallet_0.generate_signed_transaction(
|
||||
10,
|
||||
await wallet_node_1.wallet_state_manager.main_wallet.get_new_puzzlehash(),
|
||||
0,
|
||||
)
|
||||
|
||||
await wallet_0.push_transaction(spend_bundle)
|
||||
await wallet_0.push_transaction(tx)
|
||||
|
||||
await asyncio.sleep(1)
|
||||
# Full node height 11, wallet height 9
|
||||
|
@ -304,10 +304,10 @@ class TestWalletSimulator:
|
|||
assert unconfirmed_balance == new_funds - 10
|
||||
assert wallet_2_confirmed_balance == 10
|
||||
|
||||
spend_bundle = await wallet_1.generate_signed_transaction(
|
||||
tx = await wallet_1.generate_signed_transaction(
|
||||
5, await wallet_0.get_new_puzzlehash(), 0
|
||||
)
|
||||
await wallet_1.push_transaction(spend_bundle)
|
||||
await wallet_1.push_transaction(tx)
|
||||
|
||||
for i in range(0, 7):
|
||||
await full_node_0.farm_new_block(FarmNewBlockProtocol(token_bytes()))
|
||||
|
@ -350,16 +350,16 @@ class TestWalletSimulator:
|
|||
assert await wallet.get_unconfirmed_balance() == funds
|
||||
tx_amount = 32000000000000
|
||||
tx_fee = 10
|
||||
spend_bundle = await wallet.generate_signed_transaction(
|
||||
tx = await wallet.generate_signed_transaction(
|
||||
tx_amount,
|
||||
await wallet_node_2.wallet_state_manager.main_wallet.get_new_puzzlehash(),
|
||||
tx_fee,
|
||||
)
|
||||
|
||||
fees = spend_bundle.fees()
|
||||
fees = tx.spend_bundle.fees()
|
||||
assert fees == tx_fee
|
||||
|
||||
await wallet.push_transaction(spend_bundle)
|
||||
await wallet.push_transaction(tx)
|
||||
|
||||
await asyncio.sleep(2)
|
||||
confirmed_balance = await wallet.get_confirmed_balance()
|
||||
|
|
Loading…
Reference in New Issue