Skip to content

Commit 5e64ca8

Browse files
committed
Fix the tracking of txs coming from other wallets
1 parent d46526c commit 5e64ca8

File tree

2 files changed

+183
-30
lines changed

2 files changed

+183
-30
lines changed

wallet/src/account/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ use common::address::{Address, RpcAddress};
5656
use common::chain::output_value::{OutputValue, RpcOutputValue};
5757
use common::chain::tokens::{
5858
make_token_id, IsTokenUnfreezable, NftIssuance, NftIssuanceV0, RPCFungibleTokenInfo, TokenId,
59+
TokenIssuance,
5960
};
6061
use common::chain::{
6162
AccountNonce, Block, ChainConfig, DelegationId, Destination, GenBlock, PoolId,
@@ -1697,11 +1698,17 @@ impl Account {
16971698
vec![data.decommission_key().clone(), data.staker().clone()]
16981699
}
16991700
TxOutput::Htlc(_, htlc) => vec![htlc.spend_key.clone(), htlc.refund_key.clone()],
1700-
TxOutput::IssueFungibleToken(_)
1701-
| TxOutput::Burn(_)
1702-
| TxOutput::DelegateStaking(_, _)
1703-
| TxOutput::DataDeposit(_)
1704-
| TxOutput::CreateOrder(_) => Vec::new(),
1701+
TxOutput::IssueFungibleToken(data) => match data.as_ref() {
1702+
TokenIssuance::V1(data) => vec![data.authority.clone()],
1703+
},
1704+
TxOutput::DelegateStaking(_, delegation_id) => self
1705+
.output_cache
1706+
.delegation_data(delegation_id)
1707+
.map_or(vec![], |data| vec![data.destination.clone()]),
1708+
TxOutput::CreateOrder(data) => {
1709+
vec![data.conclude_key().clone()]
1710+
}
1711+
TxOutput::Burn(_) | TxOutput::DataDeposit(_) => Vec::new(),
17051712
}
17061713
}
17071714

wallet/src/wallet/tests.rs

Lines changed: 171 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1675,39 +1675,119 @@ fn send_to_unknown_delegation(#[case] seed: Seed) {
16751675
let mut rng = make_seedable_rng(seed);
16761676
let chain_config = Arc::new(create_mainnet());
16771677

1678-
let mut wallet = create_wallet(chain_config.clone());
1678+
let mut wallet = create_wallet_with_mnemonic(chain_config.clone(), MNEMONIC);
1679+
let mut wallet2 = create_wallet_with_mnemonic(chain_config.clone(), MNEMONIC2);
16791680

16801681
let coin_balance = get_coin_balance(&wallet);
16811682
assert_eq!(coin_balance, Amount::ZERO);
16821683

16831684
// Generate a new block which sends reward to the wallet
16841685
let delegation_amount = Amount::from_atoms(rng.gen_range(2..100));
16851686
let block1_amount = delegation_amount;
1686-
let _ = create_block(&chain_config, &mut wallet, vec![], block1_amount, 0);
1687+
let block_height = 0;
1688+
let (_, block) = create_block(
1689+
&chain_config,
1690+
&mut wallet,
1691+
vec![],
1692+
block1_amount,
1693+
block_height,
1694+
);
1695+
1696+
scan_wallet(
1697+
&mut wallet2,
1698+
BlockHeight::new(block_height),
1699+
vec![block.clone()],
1700+
);
16871701

16881702
let coin_balance = get_coin_balance(&wallet);
16891703
assert_eq!(coin_balance, delegation_amount);
1704+
let coin_balance = get_coin_balance(&wallet2);
1705+
assert_eq!(coin_balance, Amount::ZERO);
16901706

1691-
let unknown_delegation_id = DelegationId::new(H256::zero());
1707+
let block_height = 1;
1708+
let (_, block) = create_block(
1709+
&chain_config,
1710+
&mut wallet2,
1711+
vec![],
1712+
block1_amount,
1713+
block_height,
1714+
);
1715+
1716+
scan_wallet(
1717+
&mut wallet,
1718+
BlockHeight::new(block_height),
1719+
vec![block.clone()],
1720+
);
1721+
1722+
let coin_balance = get_coin_balance(&wallet);
1723+
assert_eq!(coin_balance, delegation_amount);
1724+
let coin_balance = get_coin_balance(&wallet2);
1725+
assert_eq!(coin_balance, delegation_amount);
1726+
1727+
let unknown_pool_id = PoolId::new(H256::zero());
1728+
let address2 = wallet2.get_new_address(DEFAULT_ACCOUNT_INDEX).unwrap().1;
1729+
let (wallet2_delegation_id, delegation_tx) = wallet2
1730+
.create_delegation(
1731+
DEFAULT_ACCOUNT_INDEX,
1732+
vec![make_create_delegation_output(address2.clone(), unknown_pool_id)],
1733+
FeeRate::from_amount_per_kb(Amount::ZERO),
1734+
FeeRate::from_amount_per_kb(Amount::ZERO),
1735+
)
1736+
.unwrap();
1737+
1738+
let block_height = 2;
1739+
let (_, block) = create_block(
1740+
&chain_config,
1741+
&mut wallet,
1742+
vec![delegation_tx],
1743+
Amount::ZERO,
1744+
block_height,
1745+
);
1746+
scan_wallet(
1747+
&mut wallet2,
1748+
BlockHeight::new(block_height),
1749+
vec![block.clone()],
1750+
);
1751+
1752+
let delegation_data =
1753+
wallet2.get_delegation(DEFAULT_ACCOUNT_INDEX, wallet2_delegation_id).unwrap();
1754+
assert_eq!(delegation_data.pool_id, unknown_pool_id);
1755+
assert_eq!(&delegation_data.destination, address2.as_object());
1756+
assert!(delegation_data.not_staked_yet);
1757+
1758+
// Stake from wallet1 to wallet2's delegation
16921759
let delegation_stake_tx = wallet
16931760
.create_transaction_to_addresses(
16941761
DEFAULT_ACCOUNT_INDEX,
1695-
[TxOutput::DelegateStaking(delegation_amount, unknown_delegation_id)],
1762+
[TxOutput::DelegateStaking(delegation_amount, wallet2_delegation_id)],
16961763
SelectedInputs::Utxos(vec![]),
16971764
BTreeMap::new(),
16981765
FeeRate::from_amount_per_kb(Amount::ZERO),
16991766
FeeRate::from_amount_per_kb(Amount::ZERO),
17001767
)
17011768
.unwrap();
17021769

1703-
let _ = create_block(
1770+
let block_height = 3;
1771+
let (_, block) = create_block(
17041772
&chain_config,
17051773
&mut wallet,
17061774
vec![delegation_stake_tx],
17071775
block1_amount,
1708-
1,
1776+
block_height,
1777+
);
1778+
scan_wallet(
1779+
&mut wallet2,
1780+
BlockHeight::new(block_height),
1781+
vec![block.clone()],
17091782
);
17101783

1784+
// Wallet2 should see the transaction and know that someone has staked to the delegation
1785+
let delegation_data =
1786+
wallet2.get_delegation(DEFAULT_ACCOUNT_INDEX, wallet2_delegation_id).unwrap();
1787+
assert_eq!(delegation_data.pool_id, unknown_pool_id);
1788+
assert_eq!(&delegation_data.destination, address2.as_object());
1789+
assert!(!delegation_data.not_staked_yet);
1790+
17111791
let coin_balance = get_coin_balance(&wallet);
17121792
assert_eq!(coin_balance, block1_amount);
17131793

@@ -1984,7 +2064,8 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) {
19842064
let mut rng = make_seedable_rng(seed);
19852065
let chain_config = Arc::new(create_mainnet());
19862066

1987-
let mut wallet = create_wallet(chain_config.clone());
2067+
let mut wallet = create_wallet_with_mnemonic(chain_config.clone(), MNEMONIC);
2068+
let mut wallet2 = create_wallet_with_mnemonic(chain_config.clone(), MNEMONIC2);
19882069

19892070
let coin_balance = get_coin_balance(&wallet);
19902071
assert_eq!(coin_balance, Amount::ZERO);
@@ -1998,36 +2079,53 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) {
19982079
chain_config.nft_issuance_fee(BlockHeight::zero())
19992080
};
20002081

2001-
// Generate a new block which sends reward to the wallet
2002-
let mut block1_amount =
2003-
(Amount::from_atoms(rng.gen_range(NETWORK_FEE + 100..NETWORK_FEE + 10000)) + issuance_fee)
2004-
.unwrap();
2082+
let some_coins = 100;
2083+
// Generate a new block which sends reward to the wallet2
2084+
let mut block1_amount = (Amount::from_atoms(
2085+
rng.gen_range(NETWORK_FEE + some_coins..NETWORK_FEE + some_coins * 100),
2086+
) + issuance_fee)
2087+
.unwrap();
20052088

20062089
if issue_fungible_token {
20072090
block1_amount =
20082091
(block1_amount + chain_config.token_supply_change_fee(BlockHeight::zero())).unwrap();
20092092
}
20102093

2011-
let _ = create_block(&chain_config, &mut wallet, vec![], block1_amount, 0);
2094+
let token_authority_and_destination = wallet.get_new_address(DEFAULT_ACCOUNT_INDEX).unwrap().1;
20122095

2013-
let coin_balance = get_coin_balance(&wallet);
2014-
assert_eq!(coin_balance, block1_amount);
2096+
// Issue token randomly from wallet2 to wallet1 or wallet1 to wallet1
2097+
let (random_issuing_wallet, other_wallet) = if rng.gen::<bool>() {
2098+
(&mut wallet, &mut wallet2)
2099+
} else {
2100+
(&mut wallet2, &mut wallet)
2101+
};
20152102

2016-
let address2 = wallet.get_new_address(DEFAULT_ACCOUNT_INDEX).unwrap().1;
2103+
let (_, block) = create_block(
2104+
&chain_config,
2105+
random_issuing_wallet,
2106+
vec![],
2107+
block1_amount,
2108+
0,
2109+
);
2110+
scan_wallet(other_wallet, BlockHeight::new(0), vec![block.clone()]);
2111+
2112+
let coin_balance = get_coin_balance(random_issuing_wallet);
2113+
assert_eq!(coin_balance, block1_amount);
20172114

20182115
let amount_fraction = (block1_amount.into_atoms() - NETWORK_FEE) / 10;
20192116
let mut token_amount_to_issue = Amount::from_atoms(rng.gen_range(1..amount_fraction));
20202117

2021-
let (issued_token_id, token_issuance_transaction) = if issue_fungible_token {
2118+
let (issued_token_id, token_issuance_transactions) = if issue_fungible_token {
20222119
let token_issuance = TokenIssuanceV1 {
20232120
token_ticker: "XXXX".as_bytes().to_vec(),
20242121
number_of_decimals: rng.gen_range(1..18),
20252122
metadata_uri: "http://uri".as_bytes().to_vec(),
20262123
total_supply: common::chain::tokens::TokenTotalSupply::Unlimited,
2027-
authority: address2.as_object().clone(),
2124+
authority: token_authority_and_destination.as_object().clone(),
20282125
is_freezable: common::chain::tokens::IsTokenFreezable::No,
20292126
};
2030-
let (issued_token_id, token_issuance_transaction) = wallet
2127+
// issue a new token from a random wallet 1 or 2 to a destination from wallet1
2128+
let (issued_token_id, token_issuance_transaction) = random_issuing_wallet
20312129
.issue_new_token(
20322130
DEFAULT_ACCOUNT_INDEX,
20332131
TokenIssuance::V1(token_issuance.clone()),
@@ -2049,37 +2147,68 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) {
20492147
token_issuance.authority,
20502148
);
20512149

2052-
wallet
2150+
random_issuing_wallet
20532151
.add_account_unconfirmed_tx(
20542152
DEFAULT_ACCOUNT_INDEX,
20552153
token_issuance_transaction.clone(),
20562154
&WalletEventsNoOp,
20572155
)
20582156
.unwrap();
2157+
other_wallet
2158+
.add_account_unconfirmed_tx(
2159+
DEFAULT_ACCOUNT_INDEX,
2160+
token_issuance_transaction.clone(),
2161+
&WalletEventsNoOp,
2162+
)
2163+
.unwrap();
2164+
2165+
// transfer the remaining coins from the random wallet to wallet1 so it can continue with
2166+
// other transactions
2167+
let transfer_tx = random_issuing_wallet
2168+
.create_transaction_to_addresses(
2169+
DEFAULT_ACCOUNT_INDEX,
2170+
[TxOutput::Transfer(
2171+
OutputValue::Coin((block1_amount - issuance_fee).unwrap()),
2172+
token_authority_and_destination.as_object().clone(),
2173+
)],
2174+
SelectedInputs::Utxos(vec![]),
2175+
BTreeMap::new(),
2176+
FeeRate::from_amount_per_kb(Amount::ZERO),
2177+
FeeRate::from_amount_per_kb(Amount::ZERO),
2178+
)
2179+
.unwrap();
2180+
wallet
2181+
.add_account_unconfirmed_tx(
2182+
DEFAULT_ACCOUNT_INDEX,
2183+
transfer_tx.clone(),
2184+
&WalletEventsNoOp,
2185+
)
2186+
.unwrap();
20592187

2188+
// wallet1 should know about the issued token from the random wallet
20602189
let unconfirmed_token_info =
20612190
wallet.get_token_unconfirmed_info(DEFAULT_ACCOUNT_INDEX, &token_info).unwrap();
20622191
let mint_transaction = wallet
20632192
.mint_tokens(
20642193
DEFAULT_ACCOUNT_INDEX,
20652194
&unconfirmed_token_info,
20662195
token_amount_to_issue,
2067-
address2,
2196+
token_authority_and_destination,
20682197
FeeRate::from_amount_per_kb(Amount::ZERO),
20692198
FeeRate::from_amount_per_kb(Amount::ZERO),
20702199
)
20712200
.unwrap();
20722201

20732202
(
20742203
issued_token_id,
2075-
vec![token_issuance_transaction, mint_transaction],
2204+
vec![token_issuance_transaction, transfer_tx, mint_transaction],
20762205
)
20772206
} else {
20782207
token_amount_to_issue = Amount::from_atoms(1);
2079-
let (issued_token_id, token_issuance_transaction) = wallet
2208+
let (issued_token_id, nft_issuance_transaction) = random_issuing_wallet
20802209
.issue_new_nft(
20812210
DEFAULT_ACCOUNT_INDEX,
2082-
address2,
2211+
token_authority_and_destination.clone(),
20832212
Metadata {
20842213
creator: None,
20852214
name: "Name".as_bytes().to_vec(),
@@ -2094,13 +2223,30 @@ fn issue_and_transfer_tokens(#[case] seed: Seed) {
20942223
FeeRate::from_amount_per_kb(Amount::ZERO),
20952224
)
20962225
.unwrap();
2097-
(issued_token_id, vec![token_issuance_transaction])
2226+
random_issuing_wallet
2227+
.add_unconfirmed_tx(nft_issuance_transaction.clone(), &WalletEventsNoOp)
2228+
.unwrap();
2229+
2230+
let transfer_tx = random_issuing_wallet
2231+
.create_transaction_to_addresses(
2232+
DEFAULT_ACCOUNT_INDEX,
2233+
[TxOutput::Transfer(
2234+
OutputValue::Coin((block1_amount - issuance_fee).unwrap()),
2235+
token_authority_and_destination.as_object().clone(),
2236+
)],
2237+
SelectedInputs::Utxos(vec![]),
2238+
BTreeMap::new(),
2239+
FeeRate::from_amount_per_kb(Amount::ZERO),
2240+
FeeRate::from_amount_per_kb(Amount::ZERO),
2241+
)
2242+
.unwrap();
2243+
(issued_token_id, vec![nft_issuance_transaction, transfer_tx])
20982244
};
20992245

21002246
let _ = create_block(
21012247
&chain_config,
21022248
&mut wallet,
2103-
token_issuance_transaction,
2249+
token_issuance_transactions,
21042250
block1_amount,
21052251
1,
21062252
);

0 commit comments

Comments
 (0)