reject wrong slate states in receive and finalize (#807)

This commit is contained in:
wiesche
2026-09-14 21:08:36 +02:00
committed by GitHub
parent ffcdf7831b
commit e5e319b47e
4 changed files with 95 additions and 0 deletions
+38
View File
@@ -696,6 +696,25 @@ where
args.input_file, args.input_file,
args.input_slatepack_message, args.input_slatepack_message,
)?; )?;
match slate.state {
SlateState::Invoice1 => {
return Err(Error::GenericError(
"Use the 'pay' command to process this invoice transaction".to_string(),
))
}
SlateState::Standard2 | SlateState::Invoice2 => {
return Err(Error::GenericError(
"Use the 'finalize' command to complete this transaction".to_string(),
))
}
SlateState::Standard3 | SlateState::Invoice3 => {
return Err(Error::GenericError(
"Use the 'post' command to post this finalized transaction to the chain"
.to_string(),
))
}
_ => {}
}
let km = match keychain_mask.as_ref() { let km = match keychain_mask.as_ref() {
None => None, None => None,
@@ -859,6 +878,25 @@ where
args.input_file.clone(), args.input_file.clone(),
args.input_slatepack_message.clone(), args.input_slatepack_message.clone(),
)?; )?;
match slate.state {
SlateState::Standard1 => {
return Err(Error::GenericError(
"Use the 'receive' command on the recipient's wallet first".to_string(),
))
}
SlateState::Invoice1 => {
return Err(Error::GenericError(
"Use the 'pay' command on the payer's wallet first".to_string(),
))
}
SlateState::Standard3 | SlateState::Invoice3 => {
return Err(Error::GenericError(
"Use the 'post' command to post this finalized transaction to the chain"
.to_string(),
))
}
_ => {}
}
// Rather than duplicating the entire command, we'll just // Rather than duplicating the entire command, we'll just
// try to determine what kind of finalization this is // try to determine what kind of finalization this is
+38
View File
@@ -124,6 +124,44 @@ fn invoice_tx_impl(test_dir: &'static str) -> Result<(), libwallet::Error> {
)?; )?;
assert_eq!(slate.state, SlateState::Invoice1); assert_eq!(slate.state, SlateState::Invoice1);
let receive_result = wallet::controller::foreign_single_use(
wallet1.clone(),
PathBuf::from(test_dir),
mask1_i.clone(),
|api| api.receive_tx(&slate, None, None).map(|_| ()),
);
assert_eq!(receive_result, Err(libwallet::Error::SlateState));
wallet::controller::owner_single_use(
wallet1.clone(),
mask1,
PathBuf::from(test_dir),
|api, m| {
let (_, txs) = api.retrieve_txs(m, false, None, Some(slate.id), None)?;
assert!(txs.is_empty());
Ok(())
},
)?;
// receive must reject every slate state except S1
for state in [
SlateState::Unknown,
SlateState::Standard2,
SlateState::Standard3,
SlateState::Invoice1,
SlateState::Invoice2,
SlateState::Invoice3,
] {
let mut bad_slate = slate.clone();
bad_slate.state = state.clone();
let res = wallet::controller::foreign_single_use(
wallet1.clone(),
PathBuf::from(test_dir),
mask1_i.clone(),
|api| api.receive_tx(&bad_slate, None, None).map(|_| ()),
);
assert_eq!(res, Err(libwallet::Error::SlateState), "state {}", state);
}
wallet::controller::owner_single_use( wallet::controller::owner_single_use(
wallet1.clone(), wallet1.clone(),
mask1, mask1,
+3
View File
@@ -66,6 +66,9 @@ where
K: Keychain, K: Keychain,
{ {
let mut ret_slate = slate.clone(); let mut ret_slate = slate.clone();
if ret_slate.state != SlateState::Standard1 {
return Err(Error::SlateState);
}
check_ttl(w, &ret_slate)?; check_ttl(w, &ret_slate)?;
let parent_key_id = match dest_acct_name { let parent_key_id = match dest_acct_name {
Some(d) => { Some(d) => {
+16
View File
@@ -567,6 +567,22 @@ fn command_line_test_impl(test_dir: &str) -> Result<(), grin_wallet_controller::
test_dir test_dir
); );
// receive and finalize should point to pay
for cmd in ["receive", "finalize"] {
let arg_vec = vec![
"grin-wallet",
"-a",
"mining",
"-p",
"password1",
cmd,
"-i",
&file_name,
];
let e = execute_command(&app, test_dir, "wallet1", &client1, arg_vec).unwrap_err();
assert!(e.to_string().contains("'pay'"), "{}", e);
}
// now pay the invoice tx, wallet 1 // now pay the invoice tx, wallet 1
let arg_vec = vec![ let arg_vec = vec![
"grin-wallet", "grin-wallet",