Store versioned transactions in the ledger, disabled by default (#19139)

* Add support for versioned transactions, but disable by default

* merge conflicts

* trent's feedback

* bump Cargo.lock

* Fix transaction error encoding

* Rename legacy_transaction method

* cargo clippy

* Clean up casts, int arithmetic, and unused methods

* Check for duplicates in sanitized message conversion

* fix clippy

* fix new test

* Fix bpf conditional compilation for message module
This commit is contained in:
Justin Starry
2021-08-17 15:17:56 -07:00
committed by GitHub
parent 098e2b2de3
commit c50b01cb60
47 changed files with 2373 additions and 1049 deletions

View File

@ -164,9 +164,9 @@ dependencies = [
[[package]]
name = "bitflags"
version = "1.2.1"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "blake3"
@ -3078,6 +3078,7 @@ name = "solana-program"
version = "1.8.0"
dependencies = [
"bincode",
"bitflags",
"blake3 1.0.0",
"borsh",
"borsh-derive",

View File

@ -293,7 +293,7 @@ fn process_transaction_and_record_inner(
) -> (Result<(), TransactionError>, Vec<Vec<CompiledInstruction>>) {
let signature = tx.signatures.get(0).unwrap().clone();
let txs = vec![tx];
let tx_batch = bank.prepare_batch(txs.iter()).unwrap();
let tx_batch = bank.prepare_batch(txs).unwrap();
let (mut results, _, mut inner_instructions, _transaction_logs) = bank
.load_execute_and_commit_transactions(
&tx_batch,
@ -315,8 +315,8 @@ fn process_transaction_and_record_inner(
)
}
fn execute_transactions(bank: &Bank, txs: &[Transaction]) -> Vec<ConfirmedTransaction> {
let batch = bank.prepare_batch(txs.iter()).unwrap();
fn execute_transactions(bank: &Bank, txs: Vec<Transaction>) -> Vec<ConfirmedTransaction> {
let batch = bank.prepare_batch(txs.clone()).unwrap();
let mut timings = ExecuteTimings::default();
let mut mint_decimals = HashMap::new();
let tx_pre_token_balances = collect_token_balances(&bank, &batch, &mut mint_decimals);
@ -2402,13 +2402,13 @@ fn test_program_upgradeable_locks() {
let results1 = {
let (bank, invoke_tx, upgrade_tx) =
setup_program_upgradeable_locks(&payer_keypair, &buffer_keypair, &program_keypair);
execute_transactions(&bank, &[upgrade_tx, invoke_tx])
execute_transactions(&bank, vec![upgrade_tx, invoke_tx])
};
let results2 = {
let (bank, invoke_tx, upgrade_tx) =
setup_program_upgradeable_locks(&payer_keypair, &buffer_keypair, &program_keypair);
execute_transactions(&bank, &[invoke_tx, upgrade_tx])
execute_transactions(&bank, vec![invoke_tx, upgrade_tx])
};
if false {

View File

@ -1,10 +1,11 @@
use solana_sdk::{
clock::Slot,
hash::Hash,
instruction::CompiledInstruction,
program_utils::limited_deserialize,
pubkey::Pubkey,
signature::{Keypair, Signer},
transaction::Transaction,
transaction::{SanitizedTransaction, Transaction},
};
use crate::{
@ -12,7 +13,37 @@ use crate::{
vote_state::Vote,
};
pub fn parse_vote_transaction(tx: &Transaction) -> Option<(Pubkey, Vote, Option<Hash>)> {
pub type ParsedVote = (Pubkey, Vote, Option<Hash>);
fn parse_vote(vote_ix: &CompiledInstruction, vote_key: &Pubkey) -> Option<ParsedVote> {
let vote_instruction = limited_deserialize(&vote_ix.data).ok();
vote_instruction.and_then(|vote_instruction| match vote_instruction {
VoteInstruction::Vote(vote) => Some((*vote_key, vote, None)),
VoteInstruction::VoteSwitch(vote, hash) => Some((*vote_key, vote, Some(hash))),
_ => None,
})
}
pub fn parse_sanitized_vote_transaction(tx: &SanitizedTransaction) -> Option<ParsedVote> {
// Check first instruction for a vote
let message = tx.message();
message
.program_instructions_iter()
.next()
.and_then(|(program_id, first_ix)| {
if !crate::check_id(program_id) {
return None;
}
first_ix.accounts.first().and_then(|first_account| {
message
.get_account_key(*first_account as usize)
.and_then(|key| parse_vote(first_ix, key))
})
})
}
pub fn parse_vote_transaction(tx: &Transaction) -> Option<ParsedVote> {
// Check first instruction for a vote
let message = tx.message();
message.instructions.get(0).and_then(|first_instruction| {
@ -31,19 +62,10 @@ pub fn parse_vote_transaction(tx: &Transaction) -> Option<(Pubkey, Vote, Option<
.accounts
.first()
.and_then(|first_account| {
tx.message
message
.account_keys
.get(*first_account as usize)
.and_then(|key| {
let vote_instruction = limited_deserialize(&first_instruction.data).ok();
vote_instruction.and_then(|vote_instruction| match vote_instruction {
VoteInstruction::Vote(vote) => Some((*key, vote, None)),
VoteInstruction::VoteSwitch(vote, hash) => {
Some((*key, vote, Some(hash)))
}
_ => None,
})
})
.and_then(|key| parse_vote(first_instruction, key))
})
})
}