mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
contract/money: Use simplified harness API for tests
This commit is contained in:
@@ -34,84 +34,50 @@ fn genesis_mint() -> Result<()> {
|
||||
smol::block_on(async {
|
||||
init_logger();
|
||||
|
||||
// Holders this test will use
|
||||
const HOLDERS: [Holder; 2] = [Holder::Alice, Holder::Bob];
|
||||
init_logger();
|
||||
|
||||
// Some numbers we want to assert
|
||||
const ALICE_INITIAL: [u64; 1] = [100];
|
||||
const BOB_INITIAL: [u64; 2] = [100, 100];
|
||||
use Holder::{Alice, Bob};
|
||||
|
||||
// Block height to verify against
|
||||
let current_block_height = 0;
|
||||
const ALICE_INITIAL: u64 = 100;
|
||||
const BOB_AMOUNTS: [u64; 2] = [100, 100];
|
||||
|
||||
// Initialize harness
|
||||
let mut th = TestHarness::new(&HOLDERS, false).await?;
|
||||
let block_height = 0;
|
||||
|
||||
info!(target: "money", "[Alice] ========================");
|
||||
info!(target: "money", "[Alice] Building genesis mint tx");
|
||||
info!(target: "money", "[Alice] ========================");
|
||||
let (genesis_mint_tx, genesis_mint_params) =
|
||||
th.genesis_mint(&Holder::Alice, &ALICE_INITIAL, None, None).await?;
|
||||
let mut th = TestHarness::new(&[Alice, Bob], false).await?;
|
||||
|
||||
info!(target: "money", "[Malicious] =============================================");
|
||||
info!(target: "money", "[Malicious] Checking genesis mint tx not on genesis block");
|
||||
info!(target: "money", "[Malicious] =============================================");
|
||||
// Build Alice's genesis mint
|
||||
info!(target: "money", "Building Alice genesis mint tx");
|
||||
let (genesis_tx, genesis_params) =
|
||||
th.genesis_mint(&Alice, &[ALICE_INITIAL], None, None).await?;
|
||||
|
||||
// Malicious: verify genesis mint fails on non-genesis block
|
||||
info!(target: "money", "Checking genesis mint tx not on genesis block");
|
||||
assert!(th
|
||||
.execute_genesis_mint_tx(
|
||||
&Holder::Alice,
|
||||
genesis_mint_tx.clone(),
|
||||
&genesis_mint_params,
|
||||
current_block_height + 1,
|
||||
&Alice,
|
||||
genesis_tx.clone(),
|
||||
&genesis_params,
|
||||
block_height + 1,
|
||||
true,
|
||||
)
|
||||
.await
|
||||
.is_err());
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ================================");
|
||||
info!(target: "money", "[{holder:?}] Executing Alice genesis mint tx");
|
||||
info!(target: "money", "[{holder:?}] ================================");
|
||||
th.execute_genesis_mint_tx(
|
||||
holder,
|
||||
genesis_mint_tx.clone(),
|
||||
&genesis_mint_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
// Execute on all holders
|
||||
info!(target: "money", "Executing Alice genesis mint tx on all holders");
|
||||
th.genesis_mint_to_all_with(genesis_tx, &genesis_params, block_height).await?;
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
// Build and execute Bob's genesis mint
|
||||
info!(target: "money", "Building and executing Bob genesis mint tx");
|
||||
let (genesis_tx, genesis_params) = th.genesis_mint(&Bob, &BOB_AMOUNTS, None, None).await?;
|
||||
th.genesis_mint_to_all_with(genesis_tx, &genesis_params, block_height).await?;
|
||||
|
||||
info!(target: "money", "[Bob] ========================");
|
||||
info!(target: "money", "[Bob] Building genesis mint tx");
|
||||
info!(target: "money", "[Bob] ========================");
|
||||
let (genesis_mint_tx, genesis_mint_params) =
|
||||
th.genesis_mint(&Holder::Bob, &BOB_INITIAL, None, None).await?;
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] =============================");
|
||||
info!(target: "money", "[{holder:?}] Executing Bob genesis mint tx");
|
||||
info!(target: "money", "[{holder:?}] =============================");
|
||||
th.execute_genesis_mint_tx(
|
||||
holder,
|
||||
genesis_mint_tx.clone(),
|
||||
&genesis_mint_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
let alice_owncoins = &th.holders.get(&Holder::Alice).unwrap().unspent_money_coins;
|
||||
let bob_owncoins = &th.holders.get(&Holder::Bob).unwrap().unspent_money_coins;
|
||||
assert!(alice_owncoins.len() == 1);
|
||||
assert!(alice_owncoins[0].note.value == ALICE_INITIAL[0]);
|
||||
assert!(bob_owncoins.len() == 2);
|
||||
assert!(bob_owncoins[0].note.value == BOB_INITIAL[0]);
|
||||
assert!(bob_owncoins[1].note.value == BOB_INITIAL[1]);
|
||||
// Assert final state
|
||||
assert_eq!(th.coins(&Alice).len(), 1);
|
||||
assert_eq!(th.coins(&Alice)[0].note.value, ALICE_INITIAL);
|
||||
assert_eq!(th.coins(&Bob).len(), 2);
|
||||
assert_eq!(th.coins(&Bob)[0].note.value, BOB_AMOUNTS[0]);
|
||||
assert_eq!(th.coins(&Bob)[1].note.value, BOB_AMOUNTS[1]);
|
||||
|
||||
// Thanks for reading
|
||||
Ok(())
|
||||
|
||||
@@ -25,64 +25,36 @@ fn money_integration() -> Result<()> {
|
||||
smol::block_on(async {
|
||||
init_logger();
|
||||
|
||||
// Holders this test will use
|
||||
const HOLDERS: [Holder; 2] = [Holder::Alice, Holder::Bob];
|
||||
use Holder::{Alice, Bob};
|
||||
|
||||
// Initialize harness
|
||||
let mut th = TestHarness::new(&HOLDERS, true).await?;
|
||||
let mut th = TestHarness::new(&[Alice, Bob], true).await?;
|
||||
|
||||
// Generate two new blocks mined by Alice
|
||||
th.generate_block(&Holder::Alice, &HOLDERS).await?;
|
||||
th.generate_block(&Holder::Alice, &HOLDERS).await?;
|
||||
|
||||
// Generate two new blocks mined by Bob
|
||||
th.generate_block(&Holder::Bob, &HOLDERS).await?;
|
||||
th.generate_block(&Holder::Bob, &HOLDERS).await?;
|
||||
// Mine 2 blocks each
|
||||
th.generate_block_all(&Alice).await?;
|
||||
th.generate_block_all(&Alice).await?;
|
||||
th.generate_block_all(&Bob).await?;
|
||||
th.generate_block_all(&Bob).await?;
|
||||
|
||||
// Assert correct rewards
|
||||
let alice_coins = &th.holders.get(&Holder::Alice).unwrap().unspent_money_coins;
|
||||
let bob_coins = &th.holders.get(&Holder::Bob).unwrap().unspent_money_coins;
|
||||
assert!(alice_coins.len() == 2);
|
||||
assert!(bob_coins.len() == 2);
|
||||
assert!(alice_coins[0].note.value == expected_reward(1));
|
||||
assert!(alice_coins[1].note.value == expected_reward(2));
|
||||
assert!(bob_coins[0].note.value == expected_reward(3));
|
||||
assert!(bob_coins[1].note.value == expected_reward(4));
|
||||
assert_eq!(th.coins(&Alice).len(), 2);
|
||||
assert_eq!(th.coins(&Bob).len(), 2);
|
||||
assert_eq!(th.coins(&Alice)[0].note.value, expected_reward(1));
|
||||
assert_eq!(th.coins(&Alice)[1].note.value, expected_reward(2));
|
||||
assert_eq!(th.coins(&Bob)[0].note.value, expected_reward(3));
|
||||
assert_eq!(th.coins(&Bob)[1].note.value, expected_reward(4));
|
||||
|
||||
let current_block_height = 4;
|
||||
let block_height = 4;
|
||||
let native_token = th.coins(&Alice)[0].note.token_id;
|
||||
|
||||
// Alice transfers some tokens to Bob
|
||||
let (tx, (xfer_params, fee_params), _spent_soins) = th
|
||||
.transfer(
|
||||
alice_coins[0].note.value,
|
||||
&Holder::Alice,
|
||||
&Holder::Bob,
|
||||
&[alice_coins[0].clone()],
|
||||
alice_coins[0].note.token_id,
|
||||
current_block_height,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
// Alice transfers her first block reward to Bob
|
||||
let transfer_amount = expected_reward(1);
|
||||
th.transfer_to_all(transfer_amount, &Alice, &Bob, native_token, block_height).await?;
|
||||
|
||||
// Execute the transaction
|
||||
for holder in &HOLDERS {
|
||||
th.execute_transfer_tx(
|
||||
holder,
|
||||
tx.clone(),
|
||||
&xfer_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Assert coins in wallets
|
||||
let alice_coins = &th.holders.get(&Holder::Alice).unwrap().unspent_money_coins;
|
||||
let bob_coins = &th.holders.get(&Holder::Bob).unwrap().unspent_money_coins;
|
||||
assert!(alice_coins.len() == 1); // Change from fee
|
||||
assert!(bob_coins.len() == 3);
|
||||
assert!(bob_coins[2].note.value == expected_reward(1));
|
||||
// Alice: 1 coin (fee change from reward(2))
|
||||
// Bob: 3 coins (reward(3) + reward(4) + received reward(1))
|
||||
assert_eq!(th.coins(&Alice).len(), 1);
|
||||
assert_eq!(th.coins(&Bob).len(), 3);
|
||||
assert_eq!(th.coins(&Bob)[2].note.value, transfer_amount);
|
||||
|
||||
// Thanks for reading
|
||||
Ok(())
|
||||
|
||||
@@ -29,8 +29,6 @@
|
||||
|
||||
use darkfi::Result;
|
||||
use darkfi_contract_test_harness::{init_logger, Holder, TestHarness};
|
||||
use darkfi_sdk::crypto::BaseBlind;
|
||||
use rand::rngs::OsRng;
|
||||
use tracing::info;
|
||||
|
||||
#[test]
|
||||
@@ -38,395 +36,69 @@ fn mint_pay_swap() -> Result<()> {
|
||||
smol::block_on(async {
|
||||
init_logger();
|
||||
|
||||
// Holders this test will use
|
||||
const HOLDERS: [Holder; 2] = [Holder::Alice, Holder::Bob];
|
||||
use Holder::{Alice, Bob};
|
||||
|
||||
// Some numbers we want to assert
|
||||
const ALICE_INITIAL: u64 = 100;
|
||||
const BOB_INITIAL: u64 = 200;
|
||||
const ALICE_SEND: u64 = 50;
|
||||
const BOB_SEND: u64 = 180;
|
||||
let block_height = 0;
|
||||
|
||||
// Alice = 50 ALICE
|
||||
// Bob = 200 BOB + 50 ALICE
|
||||
const ALICE_FIRST_SEND: u64 = ALICE_INITIAL - 50;
|
||||
// Alice = 50 ALICE + 180 BOB
|
||||
// Bob = 20 BOB + 50 ALICE
|
||||
const BOB_FIRST_SEND: u64 = BOB_INITIAL - 20;
|
||||
let mut th = TestHarness::new(&[Alice, Bob], false).await?;
|
||||
|
||||
// Block height to verify against
|
||||
let current_block_height = 0;
|
||||
// Mint tokens for Alice and Bob
|
||||
info!(target: "money", "Minting tokens for Alice and Bob");
|
||||
let alice_token = th.token_mint_to_all(ALICE_INITIAL, &Alice, &Alice, block_height).await?;
|
||||
let bob_token = th.token_mint_to_all(BOB_INITIAL, &Bob, &Bob, block_height).await?;
|
||||
|
||||
// Initialize harness
|
||||
let mut th = TestHarness::new(&HOLDERS, false).await?;
|
||||
// Alice sends some tokens to Bob
|
||||
info!(target: "money", "Alice sends {ALICE_SEND} to Bob");
|
||||
th.transfer_to_all(ALICE_SEND, &Alice, &Bob, alice_token, block_height).await?;
|
||||
|
||||
info!(target: "money", "[Alice] ================================");
|
||||
info!(target: "money", "[Alice] Building token mint tx for Alice");
|
||||
info!(target: "money", "[Alice] ================================");
|
||||
let alice_token_blind = BaseBlind::random(&mut OsRng);
|
||||
let (mint_tx, mint_params, mint_auth_params, fee_params) = th
|
||||
.token_mint(
|
||||
ALICE_INITIAL,
|
||||
&Holder::Alice,
|
||||
&Holder::Alice,
|
||||
alice_token_blind,
|
||||
None,
|
||||
None,
|
||||
current_block_height,
|
||||
)
|
||||
.await?;
|
||||
assert_eq!(th.coins(&Alice).len(), 1); // change coin
|
||||
assert_eq!(th.coins(&Bob).len(), 2); // original BOB + received ALICE
|
||||
assert_eq!(th.balance(&Alice, alice_token), ALICE_INITIAL - ALICE_SEND);
|
||||
assert_eq!(th.balance(&Bob, alice_token), ALICE_SEND);
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ==============================");
|
||||
info!(target: "money", "[{holder:?}] Executing Alice token mint tx");
|
||||
info!(target: "money", "[{holder:?}] ==============================");
|
||||
th.execute_token_mint_tx(
|
||||
holder,
|
||||
mint_tx.clone(),
|
||||
&mint_params,
|
||||
&mint_auth_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
// Bob sends some tokens to Alice
|
||||
info!(target: "money", "Bob sends {BOB_SEND} to Alice");
|
||||
th.transfer_to_all(BOB_SEND, &Bob, &Alice, bob_token, block_height).await?;
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
assert_eq!(th.balance(&Alice, alice_token), ALICE_INITIAL - ALICE_SEND);
|
||||
assert_eq!(th.balance(&Alice, bob_token), BOB_SEND);
|
||||
assert_eq!(th.balance(&Bob, alice_token), ALICE_SEND);
|
||||
assert_eq!(th.balance(&Bob, bob_token), BOB_INITIAL - BOB_SEND);
|
||||
|
||||
info!(target: "money", "[Bob] ==============================");
|
||||
info!(target: "money", "[Bob] Building token mint tx for Bob");
|
||||
info!(target: "money", "[Bob] ==============================");
|
||||
let bob_token_blind = BaseBlind::random(&mut OsRng);
|
||||
let (mint_tx, mint_params, mint_auth_params, fee_params) = th
|
||||
.token_mint(
|
||||
BOB_INITIAL,
|
||||
&Holder::Bob,
|
||||
&Holder::Bob,
|
||||
bob_token_blind,
|
||||
None,
|
||||
None,
|
||||
current_block_height,
|
||||
)
|
||||
.await?;
|
||||
// Alice and Bob swap back their foreign tokens
|
||||
info!(target: "money", "Alice and Bob swap foreign tokens");
|
||||
let alice_bob_coin = th.coins_by_token(&Alice, bob_token)[0].clone();
|
||||
let bob_alice_coin = th.coins_by_token(&Bob, alice_token)[0].clone();
|
||||
th.otc_swap_to_all(&Alice, &alice_bob_coin, &Bob, &bob_alice_coin, block_height).await?;
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ===========================");
|
||||
info!(target: "money", "[{holder:?}] Executing Bob token mint tx");
|
||||
info!(target: "money", "[{holder:?}] ===========================");
|
||||
th.execute_token_mint_tx(
|
||||
holder,
|
||||
mint_tx.clone(),
|
||||
&mint_params,
|
||||
&mint_auth_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
// Both now hold only their own token types
|
||||
assert!(th.coins(&Alice).iter().all(|c| c.note.token_id == alice_token));
|
||||
assert!(th.coins(&Bob).iter().all(|c| c.note.token_id == bob_token));
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
// Consolidate fragmented coins
|
||||
info!(target: "money", "Consolidating coins");
|
||||
th.consolidate_to_all(&Alice, alice_token, block_height).await?;
|
||||
th.consolidate_to_all(&Bob, bob_token, block_height).await?;
|
||||
|
||||
// Now Alice can send a little bit of funds to Bob
|
||||
info!(target: "money", "[Alice] ====================================================");
|
||||
info!(target: "money", "[Alice] Building Money::Transfer params for a payment to Bob");
|
||||
info!(target: "money", "[Alice] ====================================================");
|
||||
let mut alice_owncoins =
|
||||
th.holders.get(&Holder::Alice).unwrap().unspent_money_coins.clone();
|
||||
let alice_token_id = alice_owncoins[0].note.token_id;
|
||||
assert_eq!(th.coins(&Alice).len(), 1);
|
||||
assert_eq!(th.coins(&Alice)[0].note.value, ALICE_INITIAL);
|
||||
assert_eq!(th.coins(&Bob).len(), 1);
|
||||
assert_eq!(th.coins(&Bob)[0].note.value, BOB_INITIAL);
|
||||
|
||||
let (transfer_tx, (transfer_params, fee_params), spent_coins) = th
|
||||
.transfer(
|
||||
ALICE_FIRST_SEND,
|
||||
&Holder::Alice,
|
||||
&Holder::Bob,
|
||||
&alice_owncoins,
|
||||
alice_token_id,
|
||||
current_block_height,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
// Final swap: Alice and Bob exchange everything
|
||||
info!(target: "money", "Final swap: Alice and Bob exchange all tokens");
|
||||
let alice_coin = th.coins(&Alice)[0].clone();
|
||||
let bob_coin = th.coins(&Bob)[0].clone();
|
||||
th.otc_swap_to_all(&Alice, &alice_coin, &Bob, &bob_coin, block_height).await?;
|
||||
|
||||
// Validating transfer params
|
||||
assert!(transfer_params.inputs.len() == 1);
|
||||
assert!(transfer_params.outputs.len() == 2);
|
||||
assert!(spent_coins.len() == 1);
|
||||
alice_owncoins.retain(|x| x != &spent_coins[0]);
|
||||
assert!(alice_owncoins.is_empty());
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ==============================");
|
||||
info!(target: "money", "[{holder:?}] Executing Alice2Bob payment tx");
|
||||
info!(target: "money", "[{holder:?}] ==============================");
|
||||
th.execute_transfer_tx(
|
||||
holder,
|
||||
transfer_tx.clone(),
|
||||
&transfer_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Alice should now have one OwnCoin with the change from the above transfer.
|
||||
// Bob should now have a new OwnCoin.
|
||||
let alice_owncoins = &th.holders.get(&Holder::Alice).unwrap().unspent_money_coins;
|
||||
let mut bob_owncoins = th.holders.get(&Holder::Bob).unwrap().unspent_money_coins.clone();
|
||||
assert!(alice_owncoins.len() == 1);
|
||||
assert!(bob_owncoins.len() == 2);
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
// Bob can send a little bit to Alice as well
|
||||
info!(target: "money", "[Bob] ======================================================");
|
||||
info!(target: "money", "[Bob] Building Money::Transfer params for a payment to Alice");
|
||||
info!(target: "money", "[Bob] ======================================================");
|
||||
let bob_token_id = bob_owncoins[0].note.token_id;
|
||||
let mut bob_owncoins_tmp = bob_owncoins.clone();
|
||||
bob_owncoins_tmp.retain(|x| x.note.token_id == bob_token_id);
|
||||
let (transfer_tx, (transfer_params, fee_params), spent_coins) = th
|
||||
.transfer(
|
||||
BOB_FIRST_SEND,
|
||||
&Holder::Bob,
|
||||
&Holder::Alice,
|
||||
&bob_owncoins_tmp,
|
||||
bob_token_id,
|
||||
current_block_height,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
|
||||
// Validating transfer params
|
||||
assert!(transfer_params.inputs.len() == 1);
|
||||
assert!(transfer_params.outputs.len() == 2);
|
||||
assert!(spent_coins.len() == 1);
|
||||
bob_owncoins.retain(|x| x != &spent_coins[0]);
|
||||
assert!(bob_owncoins.len() == 1);
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ==============================");
|
||||
info!(target: "money", "[{holder:?}] Executing Bob2Alice payment tx");
|
||||
info!(target: "money", "[{holder:?}] ==============================");
|
||||
th.execute_transfer_tx(
|
||||
holder,
|
||||
transfer_tx.clone(),
|
||||
&transfer_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Alice should now have two OwnCoins
|
||||
// Bob should have two with the change from the above tx
|
||||
let mut alice_owncoins =
|
||||
th.holders.get(&Holder::Alice).unwrap().unspent_money_coins.clone();
|
||||
let mut bob_owncoins = th.holders.get(&Holder::Bob).unwrap().unspent_money_coins.clone();
|
||||
|
||||
assert!(alice_owncoins.len() == 2);
|
||||
assert!(bob_owncoins.len() == 2);
|
||||
|
||||
assert!(alice_owncoins[0].note.value == ALICE_INITIAL - ALICE_FIRST_SEND);
|
||||
assert!(alice_owncoins[0].note.token_id == alice_token_id);
|
||||
assert!(alice_owncoins[1].note.value == BOB_FIRST_SEND);
|
||||
assert!(alice_owncoins[1].note.token_id == bob_token_id);
|
||||
|
||||
assert!(bob_owncoins[0].note.value == ALICE_FIRST_SEND);
|
||||
assert!(bob_owncoins[0].note.token_id == alice_token_id);
|
||||
assert!(bob_owncoins[1].note.value == BOB_INITIAL - BOB_FIRST_SEND);
|
||||
assert!(bob_owncoins[1].note.token_id == bob_token_id);
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
// Alice and Bob decide to swap back their tokens so Alice gets back her initial
|
||||
// tokens and Bob gets his.
|
||||
info!(target: "money", "[Alice, Bob] ================");
|
||||
info!(target: "money", "[Alice, Bob] Building OtcSwap");
|
||||
info!(target: "money", "[Alice, Bob] ================");
|
||||
let alice_oc = alice_owncoins[1].clone();
|
||||
alice_owncoins.remove(1);
|
||||
assert!(alice_owncoins.len() == 1);
|
||||
let bob_oc = bob_owncoins[0].clone();
|
||||
bob_owncoins.remove(0);
|
||||
assert!(bob_owncoins.len() == 1);
|
||||
|
||||
let (otc_swap_tx, otc_swap_params, fee_params) = th
|
||||
.otc_swap(&Holder::Alice, &alice_oc, &Holder::Bob, &bob_oc, current_block_height)
|
||||
.await?;
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ==========================");
|
||||
info!(target: "money", "[{holder:?}] Executing AliceBob swap tx");
|
||||
info!(target: "money", "[{holder:?}] ==========================");
|
||||
th.execute_otc_swap_tx(
|
||||
holder,
|
||||
otc_swap_tx.clone(),
|
||||
&otc_swap_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
// Alice should now have two OwnCoins with the same token ID (ALICE)
|
||||
let mut alice_owncoins =
|
||||
th.holders.get(&Holder::Alice).unwrap().unspent_money_coins.clone();
|
||||
let mut bob_owncoins = th.holders.get(&Holder::Bob).unwrap().unspent_money_coins.clone();
|
||||
|
||||
assert!(alice_owncoins.len() == 2);
|
||||
assert!(alice_owncoins[0].note.token_id == alice_token_id);
|
||||
assert!(alice_owncoins[1].note.token_id == alice_token_id);
|
||||
|
||||
// Same for Bob with BOB tokens
|
||||
assert!(bob_owncoins.len() == 2);
|
||||
assert!(bob_owncoins[0].note.token_id == bob_token_id);
|
||||
assert!(bob_owncoins[1].note.token_id == bob_token_id);
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
// Now Alice will create a new coin for herself to combine the two owncoins.
|
||||
info!(target: "money", "[Alice] ======================================================");
|
||||
info!(target: "money", "[Alice] Building Money::Transfer params for a payment to Alice");
|
||||
info!(target: "money", "[Alice] ======================================================");
|
||||
let (tx, (params, fee_params), spent_coins) = th
|
||||
.transfer(
|
||||
ALICE_INITIAL,
|
||||
&Holder::Alice,
|
||||
&Holder::Alice,
|
||||
&alice_owncoins,
|
||||
alice_token_id,
|
||||
current_block_height,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
|
||||
for coin in spent_coins {
|
||||
alice_owncoins.retain(|x| x != &coin);
|
||||
}
|
||||
assert!(alice_owncoins.is_empty());
|
||||
assert!(params.inputs.len() == 2);
|
||||
assert!(params.outputs.len() == 1);
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ================================");
|
||||
info!(target: "money", "[{holder:?}] Executing Alice2Alice payment tx");
|
||||
info!(target: "money", "[{holder:?}] ================================");
|
||||
th.execute_transfer_tx(
|
||||
holder,
|
||||
tx.clone(),
|
||||
¶ms,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
// Alice should now have a single OwnCoin with her initial airdrop
|
||||
let alice_owncoins = th.holders.get(&Holder::Alice).unwrap().unspent_money_coins.clone();
|
||||
assert!(alice_owncoins.len() == 1);
|
||||
assert!(alice_owncoins[0].note.value == ALICE_INITIAL);
|
||||
assert!(alice_owncoins[0].note.token_id == alice_token_id);
|
||||
|
||||
// Bob does the same
|
||||
info!(target: "money", "[Bob] ====================================================");
|
||||
info!(target: "money", "[Bob] Building Money::Transfer params for a payment to Bob");
|
||||
info!(target: "money", "[Bob] ====================================================");
|
||||
let (tx, (params, fee_params), spent_coins) = th
|
||||
.transfer(
|
||||
BOB_INITIAL,
|
||||
&Holder::Bob,
|
||||
&Holder::Bob,
|
||||
&bob_owncoins,
|
||||
bob_token_id,
|
||||
current_block_height,
|
||||
false,
|
||||
)
|
||||
.await?;
|
||||
|
||||
for coin in spent_coins {
|
||||
bob_owncoins.retain(|x| x != &coin);
|
||||
}
|
||||
assert!(bob_owncoins.is_empty());
|
||||
assert!(params.inputs.len() == 2);
|
||||
assert!(params.outputs.len() == 1);
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ============================");
|
||||
info!(target: "money", "[{holder:?}] Executing Bob2Bob payment tx");
|
||||
info!(target: "money", "[{holder:?}] ============================");
|
||||
th.execute_transfer_tx(
|
||||
holder,
|
||||
tx.clone(),
|
||||
¶ms,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
// Bob should now have a single OwnCoin with his initial airdrop
|
||||
let bob_owncoins = th.holders.get(&Holder::Bob).unwrap().unspent_money_coins.clone();
|
||||
assert!(bob_owncoins.len() == 1);
|
||||
assert!(bob_owncoins[0].note.value == BOB_INITIAL);
|
||||
assert!(bob_owncoins[0].note.token_id == bob_token_id);
|
||||
|
||||
// Now they decide to swap all of their tokens
|
||||
info!(target: "money", "[Alice, Bob] ================");
|
||||
info!(target: "money", "[Alice, Bob] Building OtcSwap");
|
||||
info!(target: "money", "[Alice, Bob] ================");
|
||||
let mut alice_owncoins =
|
||||
th.holders.get(&Holder::Alice).unwrap().unspent_money_coins.clone();
|
||||
let mut bob_owncoins = th.holders.get(&Holder::Bob).unwrap().unspent_money_coins.clone();
|
||||
|
||||
let alice_oc = alice_owncoins[0].clone();
|
||||
alice_owncoins.remove(0);
|
||||
assert!(alice_owncoins.is_empty());
|
||||
let bob_oc = bob_owncoins[0].clone();
|
||||
bob_owncoins.remove(0);
|
||||
assert!(bob_owncoins.is_empty());
|
||||
|
||||
let (otc_swap_tx, otc_swap_params, fee_params) = th
|
||||
.otc_swap(&Holder::Alice, &alice_oc, &Holder::Bob, &bob_oc, current_block_height)
|
||||
.await?;
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!(target: "money", "[{holder:?}] ==========================");
|
||||
info!(target: "money", "[{holder:?}] Executing AliceBob swap tx");
|
||||
info!(target: "money", "[{holder:?}] ==========================");
|
||||
th.execute_otc_swap_tx(
|
||||
holder,
|
||||
otc_swap_tx.clone(),
|
||||
&otc_swap_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
assert_eq!(otc_swap_params.outputs.len(), 2);
|
||||
|
||||
// Alice should now have Bob's BOB tokens
|
||||
let alice_owncoins = th.holders.get(&Holder::Alice).unwrap().unspent_money_coins.clone();
|
||||
assert!(alice_owncoins.len() == 1);
|
||||
assert!(alice_owncoins[0].note.value == BOB_INITIAL);
|
||||
assert!(alice_owncoins[0].note.token_id == bob_token_id);
|
||||
|
||||
// And Bob should have Alice's ALICE tokens
|
||||
let bob_owncoins = th.holders.get(&Holder::Bob).unwrap().unspent_money_coins.clone();
|
||||
assert!(bob_owncoins.len() == 1);
|
||||
assert!(bob_owncoins[0].note.value == ALICE_INITIAL);
|
||||
assert!(bob_owncoins[0].note.token_id == alice_token_id);
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
assert_eq!(th.balance(&Alice, bob_token), BOB_INITIAL);
|
||||
assert_eq!(th.balance(&Bob, alice_token), ALICE_INITIAL);
|
||||
assert_eq!(th.coins(&Alice).len(), 1);
|
||||
assert_eq!(th.coins(&Bob).len(), 1);
|
||||
|
||||
// Thanks for reading
|
||||
Ok(())
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
|
||||
use darkfi::Result;
|
||||
use darkfi_contract_test_harness::{init_logger, Holder, TestHarness};
|
||||
use darkfi_sdk::crypto::BaseBlind;
|
||||
use rand::rngs::OsRng;
|
||||
use tracing::info;
|
||||
|
||||
#[test]
|
||||
@@ -27,66 +25,24 @@ fn token_mint() -> Result<()> {
|
||||
smol::block_on(async {
|
||||
init_logger();
|
||||
|
||||
// Holders this test will use
|
||||
const HOLDERS: [Holder; 2] = [Holder::Alice, Holder::Bob];
|
||||
use Holder::{Alice, Bob};
|
||||
|
||||
// Some numbers we want to assert
|
||||
const BOB_SUPPLY: u64 = 2000000000; // 10 BOB
|
||||
|
||||
// Block height to verify against
|
||||
let current_block_height = 0;
|
||||
let block_height = 0;
|
||||
|
||||
// Initialize harness
|
||||
let mut th = TestHarness::new(&HOLDERS, false).await?;
|
||||
let mut th = TestHarness::new(&[Alice, Bob], false).await?;
|
||||
|
||||
info!("[Bob] Building BOB token mint tx");
|
||||
let bob_token_blind = BaseBlind::random(&mut OsRng);
|
||||
let (token_mint_tx, token_mint_params, token_auth_mint_params, fee_params) = th
|
||||
.token_mint(
|
||||
BOB_SUPPLY,
|
||||
&Holder::Bob,
|
||||
&Holder::Bob,
|
||||
bob_token_blind,
|
||||
None,
|
||||
None,
|
||||
current_block_height,
|
||||
)
|
||||
.await?;
|
||||
// Mint BOB token
|
||||
info!("Minting BOB token");
|
||||
let bob_token = th.token_mint_to_all(BOB_SUPPLY, &Bob, &Bob, block_height).await?;
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!("[{holder:?}] Executing BOB token mint tx");
|
||||
th.execute_token_mint_tx(
|
||||
holder,
|
||||
token_mint_tx.clone(),
|
||||
&token_mint_params,
|
||||
&token_auth_mint_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
assert_eq!(th.coins(&Bob).len(), 1);
|
||||
assert_eq!(th.balance(&Bob, bob_token), BOB_SUPPLY);
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
|
||||
info!("[Bob] Building BOB token freeze tx");
|
||||
let (token_frz_tx, token_frz_params, fee_params) =
|
||||
th.token_freeze(&Holder::Bob, current_block_height).await?;
|
||||
|
||||
for holder in &HOLDERS {
|
||||
info!("[{holder:?}] Executing BOB token freeze tx");
|
||||
th.execute_token_freeze_tx(
|
||||
holder,
|
||||
token_frz_tx.clone(),
|
||||
&token_frz_params,
|
||||
&fee_params,
|
||||
current_block_height,
|
||||
true,
|
||||
)
|
||||
.await?;
|
||||
}
|
||||
|
||||
th.assert_trees(&HOLDERS);
|
||||
// Freeze BOB token authority
|
||||
info!("Freezing BOB token authority");
|
||||
th.token_freeze_to_all(&Bob, block_height).await?;
|
||||
|
||||
// Thanks for reading
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user