Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Transactions with atomic sequences of Programs #1381

Merged
merged 1 commit into from
Sep 28, 2018

Conversation

aeyakovenko
Copy link
Member

@aeyakovenko aeyakovenko commented Sep 27, 2018

Transactions contain a vector of instructions that are executed atomically.
Bench shows a 2.3x speed up when using 5 instructions per tx.
More ips for the same tps.
with pr

test bench_banking_stage_multi_accounts ... bench:   2,932,757 ns/iter (+/- 233,628)
test bench_banking_stage_multi_programs ... bench:   5,605,320 ns/iter (+/- 580,425)

master

test bench_banking_stage_multi_accounts ... bench:   2,583,595 ns/iter (+/- 398,312)

2.5/(5.6/5) = 2.23x more ips o a mac. We could pack more than 5 instructions into a larger transaction size. 5 fit into 512 bytes.

@aeyakovenko aeyakovenko requested review from garious and mvines and removed request for garious September 27, 2018 21:38
@aeyakovenko aeyakovenko force-pushed the programs branch 3 times, most recently from d5d6937 to 8b0c19b Compare September 27, 2018 22:00
@@ -10,6 +10,17 @@ pub const SIGNED_DATA_OFFSET: usize = size_of::<Signature>();
pub const SIG_OFFSET: usize = 0;
pub const PUB_KEY_OFFSET: usize = size_of::<Signature>() + size_of::<u64>();

#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
pub struct Program {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you rename this to Instruction?

@garious
Copy link
Contributor

garious commented Sep 27, 2018

Can you rebase this PR to get clippy feedback from CI?

@aeyakovenko aeyakovenko force-pushed the programs branch 3 times, most recently from f9e804a to d55bce8 Compare September 28, 2018 00:28
pub fn process_transaction(tx: &Transaction, accounts: &mut [Account]) -> Result<()> {
pub fn process_transaction(
tx: &Transaction,
pix: usize,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: it's not at all obvious to me what a pix is. can we use more letters in this variable name?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, index please.

Copy link
Contributor

@mvines mvines left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly skimmed, the Transaction struct changes LGTM. We need to add multisig transactions and a way for programs to know what keys have signed the transaction, as it's no longer safe for a program to assume it's key[0] was what signed the transaction. But we can do that as a part of #1293 later

/// The program code that executes this transaction is identified by the program_id.
/// this is an offset into the Transaction::program_keys field
pub program_id: u8,
/// Indecies into the keys array of which accounts to load
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indices

.iter_mut()
.map(|a| (a.program_id, a.tokens))
.collect();
fn execute_transaction(&self, tx: &Transaction, tx_accounts: &mut [Account]) -> Result<()> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be two functions, the original function renamed to execute_instruction and this additional loop in a new execute_instructions. If the original function had any unit tests, this would have been the natural thing to do.


let program_id = serialize(&(&self.program_id)).expect("serialize program_id");
data.extend_from_slice(&program_id);
let mut data = serialize(&(&self.account_keys)).expect("serialize account_keys");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you test this? The double-reference will work since serialize will accept any type, but is it useful? How does it affect the serialization format? If I remove it, what breaks?

@garious
Copy link
Contributor

garious commented Sep 28, 2018

Bench shows a 3x speed up when using 5 instructions per tx.

Need more data. Maybe just post the relevant benchcmp output. Looks like this PR ought to cause TPS to drop a hair because of that additional 8 bytes in the transaction format.

@@ -83,7 +83,7 @@ impl BudgetTransaction for Transaction {
let budget = Budget::Pay(payment);
let instruction = Instruction::NewContract(Contract { budget, tokens });
let userdata = serialize(&instruction).unwrap();
Self::new(
Self::new_one_program(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like new was the right name. What happened here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@garious i am ok with either one. Just seemed that new was the most general interface. I can name this one new and the other one new_multi_instruction. How does that sound?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, sounds good. Use new for the most common, not the most general. The most general one will keep changing as we add parameters. That'd be a big pain to keep updating all the earlier, probably simpler, use cases.

) -> Self {
let program_keys = vec![program_id];
let instructions = vec![Instruction {
program_id: 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need a test to ensure the input program_id ends up in both the expected places of the returned tx.

src/bank.rs Show resolved Hide resolved
@aeyakovenko aeyakovenko force-pushed the programs branch 2 times, most recently from 9a5593a to d14ffbe Compare September 28, 2018 21:44
Transactions contain a vector of instructions that are executed atomically.
Bench shows a 2.3x speed up when using 5 instructions per tx.
@aeyakovenko
Copy link
Member Author

@garious i think i addressed everyones comments. thanks for the review input everyone!

Copy link
Contributor

@garious garious left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"test_..._atomic_fail", what could possibly go wrong?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants