From f39a59617e1531ebfff0711f1bf21e8abffdce0c Mon Sep 17 00:00:00 2001 From: ibhatt-jumptrading Date: Thu, 29 Aug 2024 20:02:19 +0000 Subject: [PATCH] first pass rough --- proto_v2/epoch_v2.proto | 47 ++++++++++++++++++++++++ proto_v2/instr_v2.options | 4 +++ proto_v2/instr_v2.proto | 42 ++++++++++++++++++++++ proto_v2/slot_v2.proto | 68 +++++++++++++++++++++++++++++++++++ proto_v2/txn_v2.options | 0 proto_v2/txn_v2.proto | 76 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 237 insertions(+) create mode 100644 proto_v2/epoch_v2.proto create mode 100644 proto_v2/instr_v2.options create mode 100644 proto_v2/instr_v2.proto create mode 100644 proto_v2/slot_v2.proto create mode 100644 proto_v2/txn_v2.options create mode 100644 proto_v2/txn_v2.proto diff --git a/proto_v2/epoch_v2.proto b/proto_v2/epoch_v2.proto new file mode 100644 index 0000000..a58fc62 --- /dev/null +++ b/proto_v2/epoch_v2.proto @@ -0,0 +1,47 @@ +syntax = "proto3"; +package fd.v2; + +import "slot_v2.proto"; + +message AcctState { + /* The account address. (32 bytes) */ + bytes address = 1; + + /* Starting lamport balance */ + uint64 lamports = 2; + + /* Account data is limited to 10 MiB on Solana mainnet as of 2024-Feb. */ + bytes data = 3; + + bool executable = 4; + + /* The rent epoch is deprecated on Solana mainnet as of 2024-Feb. + If ommitted, implies a value of UINT64_MAX. */ + uint64 rent_epoch = 5; + + /* Address of the program that owns this account. (32 bytes) */ + bytes owner = 6; + + /* TODO: do we need seed address? */ +} + +message Feature { + bytes feature_id = 1; /* Feature pubkey */ + uint64 slot = 2; /* Leave as 0 if activated */ +} + +message EpochSchedule { + uint64 slots_per_epoch = 1; + uint64 first_normal_slot = 2; +} + +message EpochEnv { + repeated AcctState acct_states = 1; + repeated Feature features = 2; + repeated SlotEnv slots = 3; + EpochSchedule epoch_schedule = 4; +} + +message EpochEffects { + repeated SlotEffects slot_effects = 1; +} \ No newline at end of file diff --git a/proto_v2/instr_v2.options b/proto_v2/instr_v2.options new file mode 100644 index 0000000..f6bb09a --- /dev/null +++ b/proto_v2/instr_v2.options @@ -0,0 +1,4 @@ +instr_v2.proto package:"fd_exec_test" + +fd_exec_test.InstrEnv.accounts type:FT_POINTER +fd_exec_test.InstrEnv.data type:FT_POINTER \ No newline at end of file diff --git a/proto_v2/instr_v2.proto b/proto_v2/instr_v2.proto new file mode 100644 index 0000000..cd8e6dd --- /dev/null +++ b/proto_v2/instr_v2.proto @@ -0,0 +1,42 @@ +syntax = "proto3"; +package fd.v2; + +message AcctState { + // TODO: Implement this + bytes addresss = 1; +} + +/* As a note, the accounts and account data fields are populated at a higher + level than the instruction. */ +message InstrEnv { + + /* Index into the set of txn accounts defined by the TxnEnv. */ + uint32 program_id_index = 1; + + /* Indexes into the set of txn accounts defined by the TxnEnv. */ + repeated uint32 accounts = 2; + + /* The instruction data */ + bytes data = 3; +} + +message InstrEffects { + /* Result of the instruction execution */ + int32 result = 1; + + /* Custom error code if applicable */ + int32 custom_err = 2; + + /* Return data from the instruction */ + bytes return_data = 3; + + /* Consumed compute units by the instruction. This value will be used + by fuzzers that operate at the trnasaction granularity. */ + uint64 cus_remain = 4; + + /* Account states after instruction execution in the order as specified by + instruction. These states are then updated at fuzzers that operate at + the transaction, slot, and epoch granularity. */ + repeated AcctState accounts = 5; + +} \ No newline at end of file diff --git a/proto_v2/slot_v2.proto b/proto_v2/slot_v2.proto new file mode 100644 index 0000000..41c09a0 --- /dev/null +++ b/proto_v2/slot_v2.proto @@ -0,0 +1,68 @@ +syntax = "proto3"; +package fd.v2; + +import "txn_v2.proto"; + +message SlotBank { + int32 todo = 1; +} + +message SysvarCache { + int32 todo = 1; +} + +/* The amount that this should be filled out is dependent on if there is + epoch or slot granularity fuzzing */ +message EpochRewardStatus { + uint32 discriminant = 1; + uint32 todo = 2; /* Rest of the struct should be populated */ +} + +/* High level of what happens in a slot: + 1. Update sysvars + 2. Distribute partitioned rewards to stake accounts + 3. Collect raw txns from the ledger/network. TODO: Figure out if we should + fuzz using the raw txn bytes or the partially parsed TxnEnvs. Perhaps + leave this as a configuration option. For the sake of simplicity as a + PoC, will assume that we pass in the partially parsed TxnEnvs. + 4. TODO: Decide if we want to fuzz the ticks/poh??? Assuming this is not being + done for the sake of simplicity as we are just trying to fuzz the runtime.enum + However, this is possible to do. + 5. Pass in all txns into waves that are generated, or use the pack code path + 6. Execute each transaction in the wave. + 7. Finalize block: update sysvar(s) update bpf cache, update + bank hash. Collect Rent too. Collect slot fees. + 8. As a note: this should also be able to handle fuzzing of the epoch + boundary. +*/ + +message SlotEnv { + + /* The slot number */ + uint64 slot_number = 1; + uint64 prev_slot = 2; + uint64 block_height = 3; + + EpochRewardStatus reward_status = 4; + + /* TODO: rent. Figure out the best way to represent a rent partition + that works with firedancer and agave. Ideally for a slot fuzzer this + is prepopulated and is recomputed at the epoch level fuzzer. */ + + + bytes stake_accounts = 5; /* for distributions */ + + SlotBank slot_bank = 6; + SysvarCache sysvar_cache = 7; + /* TODO: everything from the slot_bank */ + +} + +message SlotEffects { + /* The resulting state of the accounts after the slot */ + repeated AcctState reward_acct_states = 1; + repeated AcctState rent_acct_states = 2; + repeated AcctState sysvar_acct_states = 4; + repeated TxnEnv txn_envs = 5; /* Contains all resultant account states */ + uint64 capitalization = 6; +} diff --git a/proto_v2/txn_v2.options b/proto_v2/txn_v2.options new file mode 100644 index 0000000..e69de29 diff --git a/proto_v2/txn_v2.proto b/proto_v2/txn_v2.proto new file mode 100644 index 0000000..24d11b9 --- /dev/null +++ b/proto_v2/txn_v2.proto @@ -0,0 +1,76 @@ +syntax = "proto3"; +package fd.v2; + +import "instr_v2.proto"; + +/* Message header information. */ +message TxnHeader { + + uint32 num_required_signatures = 1; + uint32 num_readonly_signed_accounts = 2; + uint32 num_readonly_unsigned_accounts = 3; +} + +/* Address Lookup table related metadata. This is used to parse the data from + the lookup table accounts. from the account list. */ +message LUTEntry { + + bytes account_key = 1; + repeated uint32 writable_indexes = 2; + repeated uint32 readonly_indexes = 3; +} + +/* Fees paid during a transaction. */ +message FeeDetails { + + uint64 transaction_fee = 1; + uint64 prioritization_fee = 2; + } + +/* As a note, if the scope of the fuzzer is just an instruction, then all of + the fields in TxnEnv will be set to null except for account_keys and + InstrEnv. TODO: maybe aluts too for instructions. This should all be + prepopulated probably */ +message TxnEnv { + + /* Transaction header. */ + TxnHeader header = 1; + + /* Determines if the transaction is legacy or not. */ + bool is_legacy = 2; + + /* Account keys in order that they are passed into the transaction. The + account data actually comes from higher level fuzzers. */ + + repeated bytes account_keys = 3; + + /* Instruction(s) that the transaction executes. */ + repeated InstrEnv instructions = 4; + + /* Recent blockhash provided in the message. */ + bytes recent_blockhash = 5; + + /* Address table lookups that aren't availble in legacy messages. */ + repeated LUTEntry alut_entires = 6; + + /* The message hash. */ + bytes message_hash = 7; + + /* The signatures needed in the transaction. */ + repeated bytes signatures = 8; +}; + +message TxnEffects { + + /* Whether this transaction was executed */ + bool executed = 1; + + /* Whether there was a sanitization error */ + bool sanitization_error = 2; + + /* Resulting account states from each instruction execution */ + repeated InstrEffects instr_effects = 3; + + /* Details about the fee */ + FeeDetails fee_details = 4; +}