mirror of
https://github.com/jwinterm/grin-wallet.git
synced 2026-10-17 07:11:36 +02:00
test contract input features
This commit is contained in:
@@ -22,7 +22,7 @@ use grin_core as core;
|
||||
use grin_keychain as keychain;
|
||||
use grin_util as util;
|
||||
|
||||
use self::core::core::{FeeFields, KernelFeatures};
|
||||
use self::core::core::{FeeFields, Inputs, KernelFeatures, OutputFeatures};
|
||||
use self::core::global;
|
||||
use self::core::global::ChainTypes;
|
||||
use self::keychain::{ExtKeychain, Keychain};
|
||||
@@ -102,6 +102,7 @@ pub struct ExpectedContractSlate {
|
||||
pub amount: u64,
|
||||
pub fee: u64,
|
||||
pub inputs: usize,
|
||||
pub coinbase_inputs: usize,
|
||||
pub outputs: usize,
|
||||
pub kernels: usize,
|
||||
pub num_participants: u8,
|
||||
@@ -120,8 +121,20 @@ pub fn assert_basic_contract_slate(slate: &libwallet::Slate, expected: ExpectedC
|
||||
assert!(slate.kernel_features_args.is_none());
|
||||
assert!(slate.payment_proof.is_none());
|
||||
assert_eq!(slate.num_participants, expected.num_participants);
|
||||
assert_eq!(tx.inputs().len(), expected.inputs);
|
||||
let inputs = tx.inputs();
|
||||
assert_eq!(inputs.len(), expected.inputs);
|
||||
match inputs {
|
||||
Inputs::FeaturesAndCommit(inputs) => assert_eq!(
|
||||
inputs
|
||||
.iter()
|
||||
.filter(|input| input.features == OutputFeatures::Coinbase)
|
||||
.count(),
|
||||
expected.coinbase_inputs
|
||||
),
|
||||
Inputs::CommitOnly(_) => panic!("contract inputs must include their features"),
|
||||
}
|
||||
assert_eq!(tx.outputs().len(), expected.outputs);
|
||||
assert!(tx.outputs().iter().all(|output| output.is_plain()));
|
||||
assert_eq!(tx.kernels().len(), expected.kernels);
|
||||
assert_eq!(slate.participant_data.len(), expected.participant_data);
|
||||
assert_eq!(
|
||||
|
||||
@@ -111,6 +111,7 @@ fn contract_rsr_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
|
||||
amount: 5_000_000_000,
|
||||
fee: participant_fee,
|
||||
inputs: 0,
|
||||
coinbase_inputs: 0,
|
||||
outputs: 0,
|
||||
kernels: 0,
|
||||
num_participants: 2,
|
||||
@@ -153,6 +154,7 @@ fn contract_rsr_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
|
||||
amount: 5_000_000_000,
|
||||
fee: 2 * participant_fee,
|
||||
inputs: 1,
|
||||
coinbase_inputs: 1,
|
||||
outputs: 1,
|
||||
kernels: 1,
|
||||
num_participants: 2,
|
||||
@@ -182,6 +184,7 @@ fn contract_rsr_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
|
||||
amount: 5_000_000_000,
|
||||
fee: 2 * participant_fee,
|
||||
inputs: 2,
|
||||
coinbase_inputs: 2,
|
||||
outputs: 2,
|
||||
kernels: 1,
|
||||
num_participants: 2,
|
||||
|
||||
@@ -20,6 +20,7 @@ extern crate log;
|
||||
use grin_wallet_libwallet as libwallet;
|
||||
|
||||
use grin_core::consensus;
|
||||
use grin_core::core::transaction::CommitWrapper;
|
||||
use impls::test_framework::{self};
|
||||
use libwallet::contract::my_fee_contribution;
|
||||
use libwallet::contract::types::{ContractNewArgsAPI, ContractSetupArgsAPI, OutputSelectionArgs};
|
||||
@@ -43,6 +44,7 @@ fn contract_self_spend_custom_tx_impl(test_dir: &'static str) -> Result<(), libw
|
||||
|
||||
let mut use_inputs = String::from("");
|
||||
|
||||
let mut plain_input = None;
|
||||
wallet::controller::owner_single_use(
|
||||
send_wallet.clone(),
|
||||
send_mask,
|
||||
@@ -166,6 +168,15 @@ fn contract_self_spend_custom_tx_impl(test_dir: &'static str) -> Result<(), libw
|
||||
// Assert expected outputs were created
|
||||
// 88, 35, 3, 0.2, 15 and a change output
|
||||
assert_eq!(commits[10].output.value, 88 * consensus::GRIN_BASE);
|
||||
assert!(!commits[10].output.is_coinbase);
|
||||
plain_input = Some((
|
||||
commits[10]
|
||||
.output
|
||||
.commit
|
||||
.clone()
|
||||
.expect("plain output has no commitment"),
|
||||
commits[10].commit,
|
||||
));
|
||||
assert_eq!(commits[11].output.value, 35 * consensus::GRIN_BASE);
|
||||
assert_eq!(commits[12].output.value, 3 * consensus::GRIN_BASE);
|
||||
assert_eq!(
|
||||
@@ -184,6 +195,50 @@ fn contract_self_spend_custom_tx_impl(test_dir: &'static str) -> Result<(), libw
|
||||
},
|
||||
)?;
|
||||
|
||||
let (plain_input, plain_commitment) = plain_input.expect("plain output was not found");
|
||||
wallet::controller::owner_single_use(
|
||||
send_wallet.clone(),
|
||||
send_mask,
|
||||
PathBuf::from(test_dir),
|
||||
|api, m| {
|
||||
slate = api.contract_new(
|
||||
m,
|
||||
&ContractNewArgsAPI {
|
||||
setup_args: ContractSetupArgsAPI {
|
||||
net_change: Some(0),
|
||||
num_participants: 1,
|
||||
selection_args: OutputSelectionArgs {
|
||||
minimum_confirmations: Some(1),
|
||||
use_inputs: Some(plain_input),
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
..Default::default()
|
||||
},
|
||||
)?;
|
||||
slate = api.contract_sign(m, &slate, &ContractSetupArgsAPI::default())?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
assert_eq!(slate.state, SlateState::Standard2);
|
||||
common::assert_basic_contract_slate(
|
||||
&slate,
|
||||
common::ExpectedContractSlate {
|
||||
amount: 0,
|
||||
fee: my_fee_contribution(1, 1, 1, 1)?.fee(),
|
||||
inputs: 1,
|
||||
coinbase_inputs: 0,
|
||||
outputs: 1,
|
||||
kernels: 1,
|
||||
num_participants: 1,
|
||||
participant_data: 1,
|
||||
signatures: 1,
|
||||
},
|
||||
);
|
||||
let inputs = Vec::<CommitWrapper>::from(&slate.tx_or_err()?.inputs());
|
||||
assert_eq!(inputs[0].commitment(), plain_commitment);
|
||||
|
||||
// let logging finish
|
||||
stopper.store(false, Ordering::Relaxed);
|
||||
thread::sleep(Duration::from_millis(200));
|
||||
|
||||
@@ -86,6 +86,7 @@ fn contract_srs_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
|
||||
amount: 5_000_000_000,
|
||||
fee: participant_fee,
|
||||
inputs: 0,
|
||||
coinbase_inputs: 0,
|
||||
outputs: 0,
|
||||
kernels: 0,
|
||||
num_participants: 2,
|
||||
@@ -201,6 +202,7 @@ fn contract_srs_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
|
||||
amount: 5_000_000_000,
|
||||
fee: 2 * participant_fee,
|
||||
inputs: 1,
|
||||
coinbase_inputs: 1,
|
||||
outputs: 1,
|
||||
kernels: 1,
|
||||
num_participants: 2,
|
||||
@@ -394,6 +396,7 @@ fn contract_srs_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error>
|
||||
amount: 5_000_000_000,
|
||||
fee: 2 * participant_fee,
|
||||
inputs: 2,
|
||||
coinbase_inputs: 2,
|
||||
outputs: 2,
|
||||
kernels: 1,
|
||||
num_participants: 2,
|
||||
|
||||
@@ -39,8 +39,6 @@ Separating side effects until the 'save_step' part would make these functions mu
|
||||
|
||||
- Reserve funds across open late-locked contracts, or make the possible signing failure
|
||||
clearer to callers.
|
||||
- Handle the coinbase flows. Coinbase inputs are built into the slate, but nothing else
|
||||
is exercised.
|
||||
- Keep contracts at two participants until the known multi-party attack is addressed.
|
||||
- For a payjoin, `--use-inputs any` picks an input for us; naming the commitment would be
|
||||
clearer, for the API as much as the CLI.
|
||||
|
||||
@@ -643,14 +643,24 @@ mod tests {
|
||||
assert!(check_identifiers(&[], &[own_input], "input").is_err());
|
||||
assert!(check_identifiers(&[own_input], &[own_output], "output").is_err());
|
||||
assert!(check_identifiers(&[own_input, own_input], &[own_input], "input").is_err());
|
||||
assert!(check_identifiers(
|
||||
&[identifier(1, OutputFeatures::Coinbase)],
|
||||
&[own_input],
|
||||
"input"
|
||||
)
|
||||
.is_err());
|
||||
assert!(cached_commitment("01").is_none());
|
||||
assert!(cached_commitment("not hex").is_none());
|
||||
assert!(cached_commitment(&"00".repeat(PEDERSEN_COMMITMENT_SIZE)).is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn coinbase_features() {
|
||||
let commit = Commitment::from_vec(vec![1]);
|
||||
let plain = OutputIdentifier::new(OutputFeatures::Plain, &commit);
|
||||
let coinbase = OutputIdentifier::new(OutputFeatures::Coinbase, &commit);
|
||||
|
||||
for (actual, expected) in [(plain, coinbase), (coinbase, plain)] {
|
||||
let err = check_identifiers(&[actual], &[expected], "input").unwrap_err();
|
||||
assert!(matches!(
|
||||
err,
|
||||
Error::GenericError(ref message)
|
||||
if message == "Contract slate changed or duplicated one of our input commitments"
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user