CLI: Add multi-session signing support (#8927)

* SDK: Add `NullSigner` implementation

* SDK: Split `Transaction::verify()` to gain access to results

* CLI: Minor refactor of --sign_only result parsing

* CLI: Enable paritial signing

Signers specified by pubkey, but without a matching --signer arg
supplied fall back to a `NullSigner` when --sign-only is in effect.
This allows their pubkey to be used for TX construction as usual,
but leaves their `sign_message()` a NOP. As such, with --sign-only
in effect, signing and verification must be done separately, with
the latter's per-signature results considered

* CLI: Surface/report missing/bad signers to user

* CLI: Suppress --sign-only JSON output

* nits

* Docs for multi-session offline signing
This commit is contained in:
Trent Nelson
2020-03-18 21:49:38 -06:00
committed by GitHub
parent aeb7278b00
commit 98228c392e
12 changed files with 455 additions and 86 deletions

View File

@@ -845,11 +845,12 @@ pub fn process_create_stake_account(
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
};
let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&config.signers, recent_blockhash)?;
if sign_only {
tx.try_partial_sign(&config.signers, recent_blockhash)?;
return_signers(&tx)
} else {
tx.try_sign(&config.signers, recent_blockhash)?;
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority.pubkey(), &recent_blockhash)?;
@@ -907,11 +908,12 @@ pub fn process_stake_authorize(
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
};
let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&config.signers, recent_blockhash)?;
if sign_only {
tx.try_partial_sign(&config.signers, recent_blockhash)?;
return_signers(&tx)
} else {
tx.try_sign(&config.signers, recent_blockhash)?;
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority.pubkey(), &recent_blockhash)?;
@@ -960,11 +962,12 @@ pub fn process_deactivate_stake_account(
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
};
let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&config.signers, recent_blockhash)?;
if sign_only {
tx.try_partial_sign(&config.signers, recent_blockhash)?;
return_signers(&tx)
} else {
tx.try_sign(&config.signers, recent_blockhash)?;
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority.pubkey(), &recent_blockhash)?;
@@ -1019,11 +1022,12 @@ pub fn process_withdraw_stake(
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
};
let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&config.signers, recent_blockhash)?;
if sign_only {
tx.try_partial_sign(&config.signers, recent_blockhash)?;
return_signers(&tx)
} else {
tx.try_sign(&config.signers, recent_blockhash)?;
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority.pubkey(), &recent_blockhash)?;
@@ -1152,11 +1156,12 @@ pub fn process_split_stake(
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
};
let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&config.signers, recent_blockhash)?;
if sign_only {
tx.try_partial_sign(&config.signers, recent_blockhash)?;
return_signers(&tx)
} else {
tx.try_sign(&config.signers, recent_blockhash)?;
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority.pubkey(), &recent_blockhash)?;
@@ -1208,11 +1213,12 @@ pub fn process_stake_set_lockup(
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
};
let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&config.signers, recent_blockhash)?;
if sign_only {
tx.try_partial_sign(&config.signers, recent_blockhash)?;
return_signers(&tx)
} else {
tx.try_sign(&config.signers, recent_blockhash)?;
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority.pubkey(), &recent_blockhash)?;
@@ -1442,11 +1448,12 @@ pub fn process_delegate_stake(
Message::new_with_payer(&ixs, Some(&fee_payer.pubkey()))
};
let mut tx = Transaction::new_unsigned(message);
tx.try_sign(&config.signers, recent_blockhash)?;
if sign_only {
tx.try_partial_sign(&config.signers, recent_blockhash)?;
return_signers(&tx)
} else {
tx.try_sign(&config.signers, recent_blockhash)?;
if let Some(nonce_account) = &nonce_account {
let nonce_account = rpc_client.get_account(nonce_account)?;
check_nonce_account(&nonce_account, &nonce_authority.pubkey(), &recent_blockhash)?;