Transaction format changes toward Credit-Only accounts (#4386)

* Add num_readonly_accounts slice

* Impl programs in account_keys

* Emulate current account-loading functionality using program-account_keys (breaks exchange_program_api tests)

* Fix test

* Add temporary exchange faucet id

* Update chacha golden

* Split num_credit_only_accounts into separate fields

* Improve readability

* Move message field constants into Message

* Add MessageHeader struct and fixup comments
This commit is contained in:
Tyera Eulberg
2019-05-22 18:23:16 -04:00
committed by GitHub
parent c121498b5b
commit 99d2428041
12 changed files with 156 additions and 91 deletions

View File

@@ -67,7 +67,7 @@ pub struct Transaction {
impl Transaction {
pub fn new_unsigned(message: Message) -> Self {
Self {
signatures: vec![Signature::default(); message.num_required_signatures as usize],
signatures: vec![Signature::default(); message.header.num_required_signatures as usize],
message,
}
}
@@ -115,11 +115,13 @@ impl Transaction {
.map(|keypair| (*keypair).pubkey())
.collect();
account_keys.extend_from_slice(keys);
account_keys.extend(&program_ids);
let message = Message::new_with_compiled_instructions(
from_keypairs.len() as u8,
0,
program_ids.len() as u8,
account_keys,
Hash::default(),
program_ids,
instructions,
);
Transaction::new(from_keypairs, message, recent_blockhash)
@@ -175,7 +177,7 @@ impl Transaction {
/// Check keys and keypair lengths, then sign this transaction.
pub fn sign<T: KeypairUtil>(&mut self, keypairs: &[&T], recent_blockhash: Hash) {
let signed_keys =
&self.message.account_keys[0..self.message.num_required_signatures as usize];
&self.message.account_keys[0..self.message.header.num_required_signatures as usize];
for (i, keypair) in keypairs.iter().enumerate() {
assert_eq!(keypair.pubkey(), signed_keys[i], "keypair-pubkey mismatch");
}
@@ -188,7 +190,7 @@ impl Transaction {
/// clear any prior signatures and update recent_blockhash
pub fn partial_sign<T: KeypairUtil>(&mut self, keypairs: &[&T], recent_blockhash: Hash) {
let signed_keys =
&self.message.account_keys[0..self.message.num_required_signatures as usize];
&self.message.account_keys[0..self.message.header.num_required_signatures as usize];
// if you change the blockhash, you're re-signing...
if recent_blockhash != self.message.recent_blockhash {
@@ -218,7 +220,7 @@ impl Transaction {
pub fn verify_refs(&self) -> bool {
let message = self.message();
for instruction in &message.instructions {
if (instruction.program_ids_index as usize) >= message.program_ids().len() {
if (instruction.program_ids_index as usize) >= message.account_keys.len() {
return false;
}
for account_index in &instruction.accounts {
@@ -304,7 +306,7 @@ mod tests {
#[test]
fn test_refs_invalid_account() {
let key = Keypair::new();
let instructions = vec![CompiledInstruction::new(0, &(), vec![1])];
let instructions = vec![CompiledInstruction::new(0, &(), vec![2])];
let tx = Transaction::new_with_compiled_instructions(
&[&key],
&[],
@@ -380,18 +382,18 @@ mod tests {
let len_size = 1;
let num_required_sigs_size = 1;
let num_credit_only_accounts_size = 2;
let blockhash_size = size_of::<Hash>();
let expected_transaction_size = len_size
+ (tx.signatures.len() * size_of::<Signature>())
+ num_required_sigs_size
+ num_credit_only_accounts_size
+ len_size
+ (tx.message.account_keys.len() * size_of::<Pubkey>())
+ blockhash_size
+ len_size
+ (tx.message.program_ids().len() * size_of::<Pubkey>())
+ len_size
+ expected_instruction_size;
assert_eq!(expected_transaction_size, 214);
assert_eq!(expected_transaction_size, 215);
assert_eq!(
serialized_size(&tx).unwrap() as usize,
@@ -407,16 +409,16 @@ mod tests {
assert_eq!(
serialize(&create_sample_transaction()).unwrap(),
vec![
1, 134, 84, 186, 62, 126, 175, 48, 6, 80, 185, 139, 108, 109, 157, 213, 17, 249, 3,
79, 83, 21, 89, 242, 148, 51, 140, 115, 77, 161, 134, 116, 136, 206, 171, 239, 236,
240, 19, 73, 217, 152, 60, 159, 170, 41, 104, 29, 217, 93, 65, 139, 191, 202, 181,
77, 246, 26, 15, 156, 186, 66, 32, 139, 6, 1, 2, 156, 227, 116, 193, 215, 38, 142,
22, 8, 14, 229, 239, 119, 93, 5, 218, 161, 35, 3, 33, 0, 36, 100, 158, 252, 33,
161, 97, 185, 62, 89, 99, 1, 1, 1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 2, 2, 4, 5, 6, 7, 8, 9, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 1, 0, 2, 0, 1, 3,
1, 2, 3
1, 71, 59, 9, 187, 190, 129, 150, 165, 21, 33, 158, 72, 87, 110, 144, 120, 79, 238,
132, 134, 105, 39, 102, 116, 209, 29, 229, 154, 36, 105, 44, 172, 118, 131, 22,
124, 131, 179, 142, 176, 27, 117, 160, 89, 102, 224, 204, 1, 252, 141, 2, 136, 0,
37, 218, 225, 129, 92, 154, 250, 59, 97, 178, 10, 1, 0, 1, 3, 156, 227, 116, 193,
215, 38, 142, 22, 8, 14, 229, 239, 119, 93, 5, 218, 161, 35, 3, 33, 0, 36, 100,
158, 252, 33, 161, 97, 185, 62, 89, 99, 1, 1, 1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9,
9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1, 1, 1, 2, 2, 2, 4, 5, 6, 7, 8, 9, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2,
2, 0, 1, 3, 1, 2, 3
]
);
}
@@ -498,7 +500,7 @@ mod tests {
tx.sign(&[&keypair0], Hash::default());
assert_eq!(
tx.message.instructions[0],
CompiledInstruction::new(0, &0, vec![0])
CompiledInstruction::new(1, &0, vec![0])
);
assert!(tx.is_signed());
}