From 3e52e2b9a9e74b80bd14a2896843517d1ee378b0 Mon Sep 17 00:00:00 2001 From: Manik Jain Date: Mon, 9 Dec 2024 21:33:41 +0000 Subject: [PATCH] WIP block fuzzing suport --- commands.md | 20 +- src/test_suite/block/codec_utils.py | 81 +++++ src/test_suite/block_pb2.py | 411 ++++++++++++++++++++++++++ src/test_suite/context/codec_utils.py | 22 ++ src/test_suite/context_pb2.py | 338 ++++++++++++++++++++- src/test_suite/fuzz_context.py | 16 + src/test_suite/instr/codec_utils.py | 28 +- src/test_suite/test_suite.py | 1 + src/test_suite/txn/codec_utils.py | 153 ++++------ src/test_suite/vm_pb2.py | 238 +++++++++++++-- 10 files changed, 1153 insertions(+), 155 deletions(-) create mode 100644 src/test_suite/block/codec_utils.py create mode 100644 src/test_suite/block_pb2.py create mode 100644 src/test_suite/context/codec_utils.py diff --git a/commands.md b/commands.md index 42cf80f..54bd5f7 100644 --- a/commands.md +++ b/commands.md @@ -40,9 +40,9 @@ $ solana-test-suite create-env [OPTIONS] **Options**: -* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: /data/mjain/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] +* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: impl/lib/libsolfuzz_agave_v2.0.so] * `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness] -* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined [default: /data/mjain/repos/firedancer/build/native/clang/lib/libfd_exec_sol_compat.so] +* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined [default: impl/lib/libsolfuzz_firedancer.so] * `-o, --output-dir PATH`: Output directory for messages [default: debug_mismatch] * `-u, --repro-urls TEXT`: Comma-delimited list of FuzzCorp mismatch links * `-n, --section-names TEXT`: Comma-delimited list of FuzzCorp section names @@ -72,7 +72,7 @@ $ solana-test-suite create-fixtures [OPTIONS] * `-i, --input PATH`: Input protobuf file or directory of protobuf files [default: corpus8] * `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness] -* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: /data/mjain/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] +* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: impl/lib/libsolfuzz_agave_v2.0.so] * `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined * `-o, --output-dir PATH`: Output directory for fixtures [default: test_fixtures] * `-p, --num-processes INTEGER`: Number of processes to use [default: 4] @@ -96,9 +96,9 @@ $ solana-test-suite debug-mismatches [OPTIONS] **Options**: -* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: /data/mjain/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] +* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: impl/lib/libsolfuzz_agave_v2.0.so] * `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness] -* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined [default: /data/mjain/repos/firedancer/build/native/clang/lib/libfd_exec_sol_compat.so] +* `-t, --target PATH`: Shared object (.so) target file paths (pairs with --keep-passing). Targets must have required function entrypoints defined [default: impl/lib/libsolfuzz_firedancer.so] * `-o, --output-dir PATH`: Output directory for messages [default: debug_mismatch] * `-u, --repro-urls TEXT`: Comma-delimited list of FuzzCorp mismatch links * `-n, --section-names TEXT`: Comma-delimited list of FuzzCorp section names @@ -211,8 +211,8 @@ $ solana-test-suite mass-regenerate-fixtures [OPTIONS] * `-i, --input PATH`: Input test-vectors directory [default: corpus8] * `-o, --output-dir PATH`: Output directory for regenerated fixtures [default: /tmp/regenerated_fixtures] -* `-t, --target PATH`: Shared object (.so) target file path to execute [default: /data/mjain/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] -* `-s, --stubbed-target PATH`: Stubbed shared object (.so) target file path to execute [default: /data/mjain/repos/solfuzz-agave/target/debug/libsolfuzz_agave_stubbed.so] +* `-t, --target PATH`: Shared object (.so) target file path to execute [default: impl/lib/libsolfuzz_agave_v2.0.so] +* `-s, --stubbed-target PATH`: Stubbed shared object (.so) target file path to execute [default: impl/lib/libsolfuzz_firedancer.so] * `-f, --add-feature TEXT`: List of feature pubkeys to force add to the fixtures. * `-r, --remove-feature TEXT`: List of feature pubkeys to force remove from the fixtures. * `-k, --rekey-feature TEXT`: List of feature pubkeys to rekey in the fixtures, formatted 'old/new' (e.g. `--rekey-feature old/new`). @@ -233,7 +233,7 @@ $ solana-test-suite regenerate-fixtures [OPTIONS] **Options**: * `-i, --input PATH`: Either a file or directory containing messages [default: corpus8] -* `-t, --target PATH`: Shared object (.so) target file path to execute [default: /data/mjain/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] +* `-t, --target PATH`: Shared object (.so) target file path to execute [default: impl/lib/libsolfuzz_agave_v2.0.so] * `-o, --output-dir PATH`: Output directory for regenerated fixtures [default: regenerated_fixtures] * `-d, --dry-run`: Only print the fixtures that would be regenerated * `-f, --add-feature TEXT`: List of feature pubkeys to force add to the fixtures. @@ -260,8 +260,8 @@ $ solana-test-suite run-tests [OPTIONS] * `-i, --input PATH`: Input protobuf file or directory of protobuf files [default: corpus8] * `-h, --default-harness-type TEXT`: Harness type to use for Context protobufs [default: InstrHarness] -* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: /data/mjain/repos/solfuzz-agave/target/release/libsolfuzz_agave.so] -* `-t, --target PATH`: Shared object (.so) target file paths [default: /data/mjain/repos/firedancer/build/native/clang/lib/libfd_exec_sol_compat.so] +* `-s, --solana-target PATH`: Solana (or ground truth) shared object (.so) target file path [default: impl/lib/libsolfuzz_agave_v2.0.so] +* `-t, --target PATH`: Shared object (.so) target file paths [default: impl/lib/libsolfuzz_firedancer.so] * `-o, --output-dir PATH`: Output directory for test results [default: test_results] * `-p, --num-processes INTEGER`: Number of processes to use [default: 4] * `-r, --randomize-output-buffer`: Randomizes bytes in output buffer before shared library execution diff --git a/src/test_suite/block/codec_utils.py b/src/test_suite/block/codec_utils.py new file mode 100644 index 0000000..6d6357f --- /dev/null +++ b/src/test_suite/block/codec_utils.py @@ -0,0 +1,81 @@ +import fd58 +import test_suite.block_pb2 as block_pb +from test_suite.context.codec_utils import decode_acct_state, encode_acct_state +from test_suite.txn.codec_utils import decode_sanitized_tx, encode_sanitized_tx + + +def decode_input(context: block_pb.BlockContext): + """ + Decode BlockContext fields in-place into human-readable format. + Addresses are decoded from base58, data from base64. + + Args: + - context (block_pb.BlockContext): Instruction context (will be modified). + """ + if context.program_id: + context.program_id = fd58.dec32(context.program_id) + + for i in range(len(context.microblocks)): + for j in range(len(context.microblocks[i].txns)): + decode_sanitized_tx(context.microblocks[i].txns[j]) + + for i in range(len(context.acct_states)): + decode_acct_state(context.acct_states[i]) + + # POH hash + context.slot_ctx.poh = fd58.dec32(context.slot_ctx.poh) + + # Vote accounts + for i in range(len(context.epoch_ctx.vote_accounts)): + context.epoch_ctx.vote_accounts[i].pubkey = fd58.dec32( + context.epoch_ctx.vote_accounts[i].pubkey + ) + + # Blockhash queue + for i in range(len(context.blockhash_queue)): + context.blockhash_queue[i] = fd58.dec32(context.blockhash_queue[i]) + + +def encode_input(context: block_pb.BlockContext): + """ + Encode BlockContext fields in-place into binary, digestable format. + Addresses are encoded in base58, data in base64. + + Args: + - context (block_pb.BlockContext): Instruction context (will be modified). + """ + for i in range(len(context.microblocks)): + for j in range(len(context.microblocks[i].txns)): + encode_sanitized_tx(context.microblocks[i].txns[j]) + + for i in range(len(context.acct_states)): + encode_acct_state(context.acct_states[i]) + + # POH hash + context.slot_ctx.poh = fd58.enc32(context.slot_ctx.poh) + + # Vote accounts + for i in range(len(context.epoch_ctx.vote_accounts)): + context.epoch_ctx.vote_accounts[i].pubkey = fd58.enc32( + context.epoch_ctx.vote_accounts[i].pubkey + ) + + # Blockhash queue + for i in range(len(context.blockhash_queue)): + context.blockhash_queue[i] = fd58.enc32(context.blockhash_queue[i]) + + +def encode_output(effects: block_pb.BlockEffects): + """ + Encode BlockEffects fields in-place into human-readable format. + Addresses are encoded in base58, data in base64. + + Args: + - effects (block_pb.BlockEffects): Instruction effects (will be modified). + """ + for i in range(len(effects.acct_states)): + encode_acct_state(effects.acct_states[i]) + + effects.bank_hash = fd58.enc32(effects.bank_hash) + effects.lt_hash = fd58.enc32(effects.lt_hash) + effects.account_delta_hash = fd58.enc32(effects.account_delta_hash) diff --git a/src/test_suite/block_pb2.py b/src/test_suite/block_pb2.py new file mode 100644 index 0000000..40aea7e --- /dev/null +++ b/src/test_suite/block_pb2.py @@ -0,0 +1,411 @@ +import sys + +_b = sys.version_info[0] < 3 and (lambda x: x) or (lambda x: x.encode("latin1")) +from google.protobuf import descriptor as _descriptor +from google.protobuf import message as _message +from google.protobuf import reflection as _reflection +from google.protobuf import symbol_database as _symbol_database +from google.protobuf import descriptor_pb2 + +_sym_db = _symbol_database.Default() +from . import context_pb2 as context__pb2 +from . import txn_pb2 as txn__pb2 +from . import metadata_pb2 as metadata__pb2 + +DESCRIPTOR = _descriptor.FileDescriptor( + name="block.proto", + package="org.solana.sealevel.v1", + syntax="proto3", + serialized_pb=_b( + '\n\x0bblock.proto\x12\x16org.solana.sealevel.v1\x1a\rcontext.proto\x1a\ttxn.proto\x1a\x0emetadata.proto"H\n\nMicroblock\x12:\n\x04txns\x18\x01 \x03(\x0b2,.org.solana.sealevel.v1.SanitizedTransaction"\x88\x02\n\x0cBlockContext\x127\n\x0bmicroblocks\x18\x01 \x03(\x0b2".org.solana.sealevel.v1.Microblock\x126\n\x0bacct_states\x18\x02 \x03(\x0b2!.org.solana.sealevel.v1.AcctState\x12\x17\n\x0fblockhash_queue\x18\x03 \x03(\x0c\x125\n\x08slot_ctx\x18\x04 \x01(\x0b2#.org.solana.sealevel.v1.SlotContext\x127\n\tepoch_ctx\x18\x05 \x01(\x0b2$.org.solana.sealevel.v1.EpochContext"¶\x01\n\x0cBlockEffects\x12\x11\n\thas_error\x18\x01 \x01(\x08\x126\n\x0bacct_states\x18\x02 \x03(\x0b2!.org.solana.sealevel.v1.AcctState\x12\x1b\n\x13slot_capitalization\x18\x03 \x01(\x04\x12\x11\n\tbank_hash\x18\x04 \x01(\x0c\x12\x0f\n\x07lt_hash\x18\x05 \x01(\x0c\x12\x1a\n\x12account_delta_hash\x18\x06 \x01(\x0c"´\x01\n\x0cBlockFixture\x129\n\x08metadata\x18\x01 \x01(\x0b2\'.org.solana.sealevel.v1.FixtureMetadata\x123\n\x05input\x18\x02 \x01(\x0b2$.org.solana.sealevel.v1.BlockContext\x124\n\x06output\x18\x03 \x01(\x0b2$.org.solana.sealevel.v1.BlockEffectsb\x06proto3' + ), + dependencies=[ + context__pb2.DESCRIPTOR, + txn__pb2.DESCRIPTOR, + metadata__pb2.DESCRIPTOR, + ], +) +_MICROBLOCK = _descriptor.Descriptor( + name="Microblock", + full_name="org.solana.sealevel.v1.Microblock", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="txns", + full_name="org.solana.sealevel.v1.Microblock.txns", + index=0, + number=1, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ) + ], + extensions=[], + nested_types=[], + enum_types=[], + options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=81, + serialized_end=153, +) +_BLOCKCONTEXT = _descriptor.Descriptor( + name="BlockContext", + full_name="org.solana.sealevel.v1.BlockContext", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="microblocks", + full_name="org.solana.sealevel.v1.BlockContext.microblocks", + index=0, + number=1, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="acct_states", + full_name="org.solana.sealevel.v1.BlockContext.acct_states", + index=1, + number=2, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="blockhash_queue", + full_name="org.solana.sealevel.v1.BlockContext.blockhash_queue", + index=2, + number=3, + type=12, + cpp_type=9, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="slot_ctx", + full_name="org.solana.sealevel.v1.BlockContext.slot_ctx", + index=3, + number=4, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="epoch_ctx", + full_name="org.solana.sealevel.v1.BlockContext.epoch_ctx", + index=4, + number=5, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=156, + serialized_end=420, +) +_BLOCKEFFECTS = _descriptor.Descriptor( + name="BlockEffects", + full_name="org.solana.sealevel.v1.BlockEffects", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="has_error", + full_name="org.solana.sealevel.v1.BlockEffects.has_error", + index=0, + number=1, + type=8, + cpp_type=7, + label=1, + has_default_value=False, + default_value=False, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="acct_states", + full_name="org.solana.sealevel.v1.BlockEffects.acct_states", + index=1, + number=2, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="slot_capitalization", + full_name="org.solana.sealevel.v1.BlockEffects.slot_capitalization", + index=2, + number=3, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="bank_hash", + full_name="org.solana.sealevel.v1.BlockEffects.bank_hash", + index=3, + number=4, + type=12, + cpp_type=9, + label=1, + has_default_value=False, + default_value=_b(""), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="lt_hash", + full_name="org.solana.sealevel.v1.BlockEffects.lt_hash", + index=4, + number=5, + type=12, + cpp_type=9, + label=1, + has_default_value=False, + default_value=_b(""), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="account_delta_hash", + full_name="org.solana.sealevel.v1.BlockEffects.account_delta_hash", + index=5, + number=6, + type=12, + cpp_type=9, + label=1, + has_default_value=False, + default_value=_b(""), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=423, + serialized_end=605, +) +_BLOCKFIXTURE = _descriptor.Descriptor( + name="BlockFixture", + full_name="org.solana.sealevel.v1.BlockFixture", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="metadata", + full_name="org.solana.sealevel.v1.BlockFixture.metadata", + index=0, + number=1, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="input", + full_name="org.solana.sealevel.v1.BlockFixture.input", + index=1, + number=2, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="output", + full_name="org.solana.sealevel.v1.BlockFixture.output", + index=2, + number=3, + type=11, + cpp_type=10, + label=1, + has_default_value=False, + default_value=None, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=608, + serialized_end=788, +) +_MICROBLOCK.fields_by_name["txns"].message_type = txn__pb2._SANITIZEDTRANSACTION +_BLOCKCONTEXT.fields_by_name["microblocks"].message_type = _MICROBLOCK +_BLOCKCONTEXT.fields_by_name["acct_states"].message_type = context__pb2._ACCTSTATE +_BLOCKCONTEXT.fields_by_name["slot_ctx"].message_type = context__pb2._SLOTCONTEXT +_BLOCKCONTEXT.fields_by_name["epoch_ctx"].message_type = context__pb2._EPOCHCONTEXT +_BLOCKEFFECTS.fields_by_name["acct_states"].message_type = context__pb2._ACCTSTATE +_BLOCKFIXTURE.fields_by_name["metadata"].message_type = metadata__pb2._FIXTUREMETADATA +_BLOCKFIXTURE.fields_by_name["input"].message_type = _BLOCKCONTEXT +_BLOCKFIXTURE.fields_by_name["output"].message_type = _BLOCKEFFECTS +DESCRIPTOR.message_types_by_name["Microblock"] = _MICROBLOCK +DESCRIPTOR.message_types_by_name["BlockContext"] = _BLOCKCONTEXT +DESCRIPTOR.message_types_by_name["BlockEffects"] = _BLOCKEFFECTS +DESCRIPTOR.message_types_by_name["BlockFixture"] = _BLOCKFIXTURE +_sym_db.RegisterFileDescriptor(DESCRIPTOR) +Microblock = _reflection.GeneratedProtocolMessageType( + "Microblock", + (_message.Message,), + dict(DESCRIPTOR=_MICROBLOCK, __module__="block_pb2"), +) +_sym_db.RegisterMessage(Microblock) +BlockContext = _reflection.GeneratedProtocolMessageType( + "BlockContext", + (_message.Message,), + dict(DESCRIPTOR=_BLOCKCONTEXT, __module__="block_pb2"), +) +_sym_db.RegisterMessage(BlockContext) +BlockEffects = _reflection.GeneratedProtocolMessageType( + "BlockEffects", + (_message.Message,), + dict(DESCRIPTOR=_BLOCKEFFECTS, __module__="block_pb2"), +) +_sym_db.RegisterMessage(BlockEffects) +BlockFixture = _reflection.GeneratedProtocolMessageType( + "BlockFixture", + (_message.Message,), + dict(DESCRIPTOR=_BLOCKFIXTURE, __module__="block_pb2"), +) +_sym_db.RegisterMessage(BlockFixture) diff --git a/src/test_suite/context/codec_utils.py b/src/test_suite/context/codec_utils.py new file mode 100644 index 0000000..b0e8409 --- /dev/null +++ b/src/test_suite/context/codec_utils.py @@ -0,0 +1,22 @@ +import test_suite.context_pb2 as context_pb +import fd58 + + +def encode_acct_state(acct_state: context_pb.AcctState): + # Pubkey + if acct_state.address: + acct_state.address = fd58.enc32(acct_state.address) + + # Owner + if acct_state.owner: + acct_state.owner = fd58.enc32(acct_state.owner) + + +def decode_acct_state(acct_state: context_pb.AcctState): + # Pubkey + if acct_state.address: + acct_state.address = fd58.dec32(acct_state.address) + + # Owner + if acct_state.owner: + acct_state.owner = fd58.dec32(acct_state.owner) diff --git a/src/test_suite/context_pb2.py b/src/test_suite/context_pb2.py index b2bfbde..c33054d 100644 --- a/src/test_suite/context_pb2.py +++ b/src/test_suite/context_pb2.py @@ -13,7 +13,7 @@ package="org.solana.sealevel.v1", syntax="proto3", serialized_pb=_b( - '\n\rcontext.proto\x12\x16org.solana.sealevel.v1"\x1e\n\nFeatureSet\x12\x10\n\x08features\x18\x01 \x03(\x06"8\n\x0bSeedAddress\x12\x0c\n\x04base\x18\x01 \x01(\x0c\x12\x0c\n\x04seed\x18\x02 \x01(\x0c\x12\r\n\x05owner\x18\x03 \x01(\x0c"«\x01\n\tAcctState\x12\x0f\n\x07address\x18\x01 \x01(\x0c\x12\x10\n\x08lamports\x18\x02 \x01(\x04\x12\x0c\n\x04data\x18\x03 \x01(\x0c\x12\x12\n\nexecutable\x18\x04 \x01(\x08\x12\x12\n\nrent_epoch\x18\x05 \x01(\x04\x12\r\n\x05owner\x18\x06 \x01(\x0c\x126\n\tseed_addr\x18\x07 \x01(\x0b2#.org.solana.sealevel.v1.SeedAddress"D\n\x0cEpochContext\x124\n\x08features\x18\x01 \x01(\x0b2".org.solana.sealevel.v1.FeatureSet"\x1b\n\x0bSlotContext\x12\x0c\n\x04slot\x18\x01 \x01(\x06b\x06proto3' + '\n\rcontext.proto\x12\x16org.solana.sealevel.v1"\x1e\n\nFeatureSet\x12\x10\n\x08features\x18\x01 \x03(\x06"8\n\x0bSeedAddress\x12\x0c\n\x04base\x18\x01 \x01(\x0c\x12\x0c\n\x04seed\x18\x02 \x01(\x0c\x12\r\n\x05owner\x18\x03 \x01(\x0c"«\x01\n\tAcctState\x12\x0f\n\x07address\x18\x01 \x01(\x0c\x12\x10\n\x08lamports\x18\x02 \x01(\x04\x12\x0c\n\x04data\x18\x03 \x01(\x0c\x12\x12\n\nexecutable\x18\x04 \x01(\x08\x12\x12\n\nrent_epoch\x18\x05 \x01(\x04\x12\r\n\x05owner\x18\x06 \x01(\x0c\x126\n\tseed_addr\x18\x07 \x01(\x0b2#.org.solana.sealevel.v1.SeedAddress"3\n\x08VoteAcct\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\x17\n\x0fdelegated_stake\x18\x02 \x01(\x04"*\n\tStakeAcct\x12\x0e\n\x06pubkey\x18\x01 \x01(\x0c\x12\r\n\x05stake\x18\x02 \x01(\x04"Ð\x02\n\x0cEpochContext\x124\n\x08features\x18\x01 \x01(\x0b2".org.solana.sealevel.v1.FeatureSet\x12\x17\n\x0fhashes_per_tick\x18\x02 \x01(\x04\x12\x16\n\x0eticks_per_slot\x18\x03 \x01(\x04\x12\x16\n\x0ens_per_slot_lo\x18\x04 \x01(\x04\x12\x16\n\x0ens_per_slot_hi\x18\x05 \x01(\x04\x12\x1d\n\x15genesis_creation_time\x18\x06 \x01(\x04\x12\x16\n\x0eslots_per_year\x18\x07 \x01(\x01\x127\n\rvote_accounts\x18\t \x03(\x0b2 .org.solana.sealevel.v1.VoteAcct\x129\n\x0estake_accounts\x18\n \x03(\x0b2!.org.solana.sealevel.v1.StakeAcct"Z\n\x0bSlotContext\x12\x0c\n\x04slot\x18\x01 \x01(\x06\x12\x11\n\tprev_slot\x18\x02 \x01(\x06\x12\x10\n\x08prev_lps\x18\x03 \x01(\x04\x12\x18\n\x10parent_bank_hash\x18\x04 \x01(\x0cb\x06proto3' ), ) _FEATURESET = _descriptor.Descriptor( @@ -271,6 +271,116 @@ serialized_start=132, serialized_end=303, ) +_VOTEACCT = _descriptor.Descriptor( + name="VoteAcct", + full_name="org.solana.sealevel.v1.VoteAcct", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="pubkey", + full_name="org.solana.sealevel.v1.VoteAcct.pubkey", + index=0, + number=1, + type=12, + cpp_type=9, + label=1, + has_default_value=False, + default_value=_b(""), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="delegated_stake", + full_name="org.solana.sealevel.v1.VoteAcct.delegated_stake", + index=1, + number=2, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=305, + serialized_end=356, +) +_STAKEACCT = _descriptor.Descriptor( + name="StakeAcct", + full_name="org.solana.sealevel.v1.StakeAcct", + filename=None, + file=DESCRIPTOR, + containing_type=None, + fields=[ + _descriptor.FieldDescriptor( + name="pubkey", + full_name="org.solana.sealevel.v1.StakeAcct.pubkey", + index=0, + number=1, + type=12, + cpp_type=9, + label=1, + has_default_value=False, + default_value=_b(""), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="stake", + full_name="org.solana.sealevel.v1.StakeAcct.stake", + index=1, + number=2, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + ], + extensions=[], + nested_types=[], + enum_types=[], + options=None, + is_extendable=False, + syntax="proto3", + extension_ranges=[], + oneofs=[], + serialized_start=358, + serialized_end=400, +) _EPOCHCONTEXT = _descriptor.Descriptor( name="EpochContext", full_name="org.solana.sealevel.v1.EpochContext", @@ -295,7 +405,151 @@ extension_scope=None, options=None, file=DESCRIPTOR, - ) + ), + _descriptor.FieldDescriptor( + name="hashes_per_tick", + full_name="org.solana.sealevel.v1.EpochContext.hashes_per_tick", + index=1, + number=2, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="ticks_per_slot", + full_name="org.solana.sealevel.v1.EpochContext.ticks_per_slot", + index=2, + number=3, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="ns_per_slot_lo", + full_name="org.solana.sealevel.v1.EpochContext.ns_per_slot_lo", + index=3, + number=4, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="ns_per_slot_hi", + full_name="org.solana.sealevel.v1.EpochContext.ns_per_slot_hi", + index=4, + number=5, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="genesis_creation_time", + full_name="org.solana.sealevel.v1.EpochContext.genesis_creation_time", + index=5, + number=6, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="slots_per_year", + full_name="org.solana.sealevel.v1.EpochContext.slots_per_year", + index=6, + number=7, + type=1, + cpp_type=5, + label=1, + has_default_value=False, + default_value=float(0), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="vote_accounts", + full_name="org.solana.sealevel.v1.EpochContext.vote_accounts", + index=7, + number=9, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="stake_accounts", + full_name="org.solana.sealevel.v1.EpochContext.stake_accounts", + index=8, + number=10, + type=11, + cpp_type=10, + label=3, + has_default_value=False, + default_value=[], + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), ], extensions=[], nested_types=[], @@ -305,8 +559,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=305, - serialized_end=373, + serialized_start=403, + serialized_end=739, ) _SLOTCONTEXT = _descriptor.Descriptor( name="SlotContext", @@ -332,7 +586,61 @@ extension_scope=None, options=None, file=DESCRIPTOR, - ) + ), + _descriptor.FieldDescriptor( + name="prev_slot", + full_name="org.solana.sealevel.v1.SlotContext.prev_slot", + index=1, + number=2, + type=6, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="prev_lps", + full_name="org.solana.sealevel.v1.SlotContext.prev_lps", + index=2, + number=3, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="parent_bank_hash", + full_name="org.solana.sealevel.v1.SlotContext.parent_bank_hash", + index=3, + number=4, + type=12, + cpp_type=9, + label=1, + has_default_value=False, + default_value=_b(""), + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), ], extensions=[], nested_types=[], @@ -342,14 +650,18 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=375, - serialized_end=402, + serialized_start=741, + serialized_end=831, ) _ACCTSTATE.fields_by_name["seed_addr"].message_type = _SEEDADDRESS _EPOCHCONTEXT.fields_by_name["features"].message_type = _FEATURESET +_EPOCHCONTEXT.fields_by_name["vote_accounts"].message_type = _VOTEACCT +_EPOCHCONTEXT.fields_by_name["stake_accounts"].message_type = _STAKEACCT DESCRIPTOR.message_types_by_name["FeatureSet"] = _FEATURESET DESCRIPTOR.message_types_by_name["SeedAddress"] = _SEEDADDRESS DESCRIPTOR.message_types_by_name["AcctState"] = _ACCTSTATE +DESCRIPTOR.message_types_by_name["VoteAcct"] = _VOTEACCT +DESCRIPTOR.message_types_by_name["StakeAcct"] = _STAKEACCT DESCRIPTOR.message_types_by_name["EpochContext"] = _EPOCHCONTEXT DESCRIPTOR.message_types_by_name["SlotContext"] = _SLOTCONTEXT _sym_db.RegisterFileDescriptor(DESCRIPTOR) @@ -371,6 +683,18 @@ dict(DESCRIPTOR=_ACCTSTATE, __module__="context_pb2"), ) _sym_db.RegisterMessage(AcctState) +VoteAcct = _reflection.GeneratedProtocolMessageType( + "VoteAcct", + (_message.Message,), + dict(DESCRIPTOR=_VOTEACCT, __module__="context_pb2"), +) +_sym_db.RegisterMessage(VoteAcct) +StakeAcct = _reflection.GeneratedProtocolMessageType( + "StakeAcct", + (_message.Message,), + dict(DESCRIPTOR=_STAKEACCT, __module__="context_pb2"), +) +_sym_db.RegisterMessage(StakeAcct) EpochContext = _reflection.GeneratedProtocolMessageType( "EpochContext", (_message.Message,), diff --git a/src/test_suite/fuzz_context.py b/src/test_suite/fuzz_context.py index 941dbf7..323e2e5 100644 --- a/src/test_suite/fuzz_context.py +++ b/src/test_suite/fuzz_context.py @@ -1,14 +1,21 @@ from test_suite.fuzz_interface import HarnessCtx + import test_suite.txn_pb2 as txn_pb import test_suite.invoke_pb2 as invoke_pb import test_suite.elf_pb2 as elf_pb import test_suite.vm_pb2 as vm_pb +import test_suite.block_pb2 as block_pb + +import test_suite.block.codec_utils as block_codec + import test_suite.txn.codec_utils as txn_codec import test_suite.txn.prune_utils as txn_prune import test_suite.txn.diff_utils as txn_diff + import test_suite.instr.codec_utils as instr_codec import test_suite.instr.prune_utils as instr_prune import test_suite.instr.diff_utils as instr_diff + import test_suite.syscall.codec_utils as syscall_codec @@ -67,6 +74,15 @@ consensus_diff_effect_fn=txn_diff.consensus_txn_diff_effects, ) +BlockHarness = HarnessCtx( + fuzz_fn_name="sol_compat_block_execute_v1", + fixture_desc=block_pb.BlockFixture.DESCRIPTOR, + context_human_encode_fn=block_codec.encode_input, + context_human_decode_fn=block_codec.decode_input, + effects_human_encode_fn=block_codec.encode_output, + # TODO: Fill in other fields... +) + ENTRYPOINT_HARNESS_MAP = { obj.fuzz_fn_name: obj for name, obj in globals().items() diff --git a/src/test_suite/instr/codec_utils.py b/src/test_suite/instr/codec_utils.py index 5a78e0f..3ae1cd6 100644 --- a/src/test_suite/instr/codec_utils.py +++ b/src/test_suite/instr/codec_utils.py @@ -1,4 +1,5 @@ import fd58 +from test_suite.context.codec_utils import decode_acct_state, encode_acct_state import test_suite.invoke_pb2 as invoke_pb @@ -14,14 +15,7 @@ def decode_input(instruction_context: invoke_pb.InstrContext): instruction_context.program_id = fd58.dec32(instruction_context.program_id) for i in range(len(instruction_context.accounts)): - if instruction_context.accounts[i].address: - instruction_context.accounts[i].address = fd58.dec32( - instruction_context.accounts[i].address - ) - if instruction_context.accounts[i].owner: - instruction_context.accounts[i].owner = fd58.dec32( - instruction_context.accounts[i].owner - ) + decode_acct_state(instruction_context.accounts[i]) def encode_input(instruction_context: invoke_pb.InstrContext): @@ -36,14 +30,7 @@ def encode_input(instruction_context: invoke_pb.InstrContext): instruction_context.program_id = fd58.enc32(instruction_context.program_id) for i in range(len(instruction_context.accounts)): - if instruction_context.accounts[i].address: - instruction_context.accounts[i].address = fd58.enc32( - instruction_context.accounts[i].address - ) - if instruction_context.accounts[i].owner: - instruction_context.accounts[i].owner = fd58.enc32( - instruction_context.accounts[i].owner - ) + encode_acct_state(instruction_context.accounts[i]) def encode_output(instruction_effects: invoke_pb.InstrEffects): @@ -55,11 +42,4 @@ def encode_output(instruction_effects: invoke_pb.InstrEffects): - instruction_effects (invoke_pb.InstrEffects): Instruction effects (will be modified). """ for i in range(len(instruction_effects.modified_accounts)): - if instruction_effects.modified_accounts[i].address: - instruction_effects.modified_accounts[i].address = fd58.enc32( - instruction_effects.modified_accounts[i].address - ) - if instruction_effects.modified_accounts[i].owner: - instruction_effects.modified_accounts[i].owner = fd58.enc32( - instruction_effects.modified_accounts[i].owner - ) + encode_acct_state(instruction_effects.modified_accounts[i]) diff --git a/src/test_suite/test_suite.py b/src/test_suite/test_suite.py index 81e8207..b9e4f97 100644 --- a/src/test_suite/test_suite.py +++ b/src/test_suite/test_suite.py @@ -46,6 +46,7 @@ Harness options: - InstrHarness - TxnHarness +- BlockHarness - SyscallHarness - ValidateVM - ElfHarness diff --git a/src/test_suite/txn/codec_utils.py b/src/test_suite/txn/codec_utils.py index a4a8ba7..ed82234 100644 --- a/src/test_suite/txn/codec_utils.py +++ b/src/test_suite/txn/codec_utils.py @@ -1,64 +1,80 @@ import fd58 +from test_suite.context.codec_utils import decode_acct_state, encode_acct_state import test_suite.txn_pb2 as txn_pb -def decode_input(txn_context: txn_pb.TxnContext): - """ - Decode TxnContext fields in-place into binary, digestable format. - Addresses are decoded from base58. - - Args: - - txn_context (txn_pb.TxnContext): Transaction context (will be modified). - """ +def decode_sanitized_tx(tx: txn_pb.SanitizedTransaction): # Message hash - txn_context.tx.message_hash = fd58.dec32( - txn_context.tx.message_hash or bytes([0] * 32) - ) + tx.message_hash = fd58.dec32(tx.message_hash or bytes([0] * 32)) # Signatures - for i in range(len(txn_context.tx.signatures)): - if txn_context.tx.signatures[i]: - txn_context.tx.signatures[i] = fd58.dec64(txn_context.tx.signatures[i]) + for i in range(len(tx.signatures)): + if tx.signatures[i]: + tx.signatures[i] = fd58.dec64(tx.signatures[i]) # Account keys - for i in range(len(txn_context.tx.message.account_keys)): - if txn_context.tx.message.account_keys[i]: - txn_context.tx.message.account_keys[i] = fd58.dec32( - txn_context.tx.message.account_keys[i] - ) + for i in range(len(tx.message.account_keys)): + if tx.message.account_keys[i]: + tx.message.account_keys[i] = fd58.dec32(tx.message.account_keys[i]) - # Account shared data - for i in range(len(txn_context.tx.message.account_shared_data)): - # Pubkey - if txn_context.tx.message.account_shared_data[i].address: - txn_context.tx.message.account_shared_data[i].address = fd58.dec32( - txn_context.tx.message.account_shared_data[i].address + # Recent blockhash + tx.message.recent_blockhash = fd58.dec32( + tx.message.recent_blockhash or bytes([0] * 32) + ) + + # Address table lookups + for i in range(len(tx.message.address_table_lookups)): + if tx.message.address_table_lookups[i].account_key: + tx.message.address_table_lookups[i].account_key = fd58.dec32( + tx.message.address_table_lookups[i].account_key ) - # Not encoding data because it's not super useful in inspection - # Owner - if txn_context.tx.message.account_shared_data[i].owner: - txn_context.tx.message.account_shared_data[i].owner = fd58.dec32( - txn_context.tx.message.account_shared_data[i].owner - ) +def encode_sanitized_tx(tx: txn_pb.SanitizedTransaction): + # Message hash + tx.message_hash = fd58.enc32(tx.message_hash or bytes([0] * 32)) + + # Signatures + for i in range(len(tx.signatures)): + if tx.signatures[i]: + tx.signatures[i] = fd58.enc64(tx.signatures[i]) + + # Account keys + for i in range(len(tx.message.account_keys)): + if tx.message.account_keys[i]: + tx.message.account_keys[i] = fd58.enc32(tx.message.account_keys[i]) # Recent blockhash - txn_context.tx.message.recent_blockhash = fd58.dec32( - txn_context.tx.message.recent_blockhash or bytes([0] * 32) + tx.message.recent_blockhash = fd58.enc32( + tx.message.recent_blockhash or bytes([0] * 32) ) # Address table lookups - for i in range(len(txn_context.tx.message.address_table_lookups)): - if txn_context.tx.message.address_table_lookups[i].account_key: - txn_context.tx.message.address_table_lookups[i].account_key = fd58.dec32( - txn_context.tx.message.address_table_lookups[i].account_key + for i in range(len(tx.message.address_table_lookups)): + if tx.message.address_table_lookups[i].account_key: + tx.message.address_table_lookups[i].account_key = fd58.enc32( + tx.message.address_table_lookups[i].account_key ) + +def decode_input(txn_context: txn_pb.TxnContext): + """ + Decode TxnContext fields in-place into binary, digestable format. + Addresses are decoded from base58. + + Args: + - txn_context (txn_pb.TxnContext): Transaction context (will be modified). + """ + decode_sanitized_tx(txn_context.tx) + # Blockhash queue for i in range(len(txn_context.blockhash_queue)): txn_context.blockhash_queue[i] = fd58.dec32(txn_context.blockhash_queue[i]) + # Account shared data + for i in range(len(txn_context.account_shared_data)): + decode_acct_state(txn_context.account_shared_data[i]) + def encode_input(txn_context: txn_pb.TxnContext): """ @@ -68,55 +84,16 @@ def encode_input(txn_context: txn_pb.TxnContext): Args: - txn_context (txn_pb.TxnContext): Transaction context (will be modified). """ - # Message hash - txn_context.tx.message_hash = fd58.enc32( - txn_context.tx.message_hash or bytes([0] * 32) - ) - - # Signatures - for i in range(len(txn_context.tx.signatures)): - if txn_context.tx.signatures[i]: - txn_context.tx.signatures[i] = fd58.enc64(txn_context.tx.signatures[i]) - - # Account keys - for i in range(len(txn_context.tx.message.account_keys)): - if txn_context.tx.message.account_keys[i]: - txn_context.tx.message.account_keys[i] = fd58.enc32( - txn_context.tx.message.account_keys[i] - ) - - # Account shared data - for i in range(len(txn_context.tx.message.account_shared_data)): - # Pubkey - if txn_context.tx.message.account_shared_data[i].address: - txn_context.tx.message.account_shared_data[i].address = fd58.enc32( - txn_context.tx.message.account_shared_data[i].address - ) - - # Not encoding data because it's not super useful in inspection - - # Owner - if txn_context.tx.message.account_shared_data[i].owner: - txn_context.tx.message.account_shared_data[i].owner = fd58.enc32( - txn_context.tx.message.account_shared_data[i].owner - ) - - # Recent blockhash - txn_context.tx.message.recent_blockhash = fd58.enc32( - txn_context.tx.message.recent_blockhash or bytes([0] * 32) - ) - - # Address table lookups - for i in range(len(txn_context.tx.message.address_table_lookups)): - if txn_context.tx.message.address_table_lookups[i].account_key: - txn_context.tx.message.address_table_lookups[i].account_key = fd58.enc32( - txn_context.tx.message.address_table_lookups[i].account_key - ) + encode_sanitized_tx(txn_context.tx) # Blockhash queue for i in range(len(txn_context.blockhash_queue)): txn_context.blockhash_queue[i] = fd58.enc32(txn_context.blockhash_queue[i]) + # Account shared data + for i in range(len(txn_context.account_shared_data)): + encode_acct_state(txn_context.account_shared_data[i]) + def encode_output(txn_result: txn_pb.TxnResult): """ @@ -129,16 +106,4 @@ def encode_output(txn_result: txn_pb.TxnResult): # Account states for i in range(len(txn_result.resulting_state.acct_states)): - # Pubkey - if txn_result.resulting_state.acct_states[i].address: - txn_result.resulting_state.acct_states[i].address = fd58.enc32( - txn_result.resulting_state.acct_states[i].address - ) - - # Not encoding data because it's not super useful in inspection - - # Owner - if txn_result.resulting_state.acct_states[i].owner: - txn_result.resulting_state.acct_states[i].owner = fd58.enc32( - txn_result.resulting_state.acct_states[i].owner - ) + encode_acct_state(txn_result.resulting_state.acct_states[i]) diff --git a/src/test_suite/vm_pb2.py b/src/test_suite/vm_pb2.py index 5db92a1..6d10803 100644 --- a/src/test_suite/vm_pb2.py +++ b/src/test_suite/vm_pb2.py @@ -18,7 +18,7 @@ package="org.solana.sealevel.v1", syntax="proto3", serialized_pb=_b( - '\n\x08vm.proto\x12\x16org.solana.sealevel.v1\x1a\x0cinvoke.proto\x1a\rcontext.proto\x1a\x0emetadata.proto"G\n\x0fInputDataRegion\x12\x0e\n\x06offset\x18\x01 \x01(\x04\x12\x0f\n\x07content\x18\x02 \x01(\x0c\x12\x13\n\x0bis_writable\x18\x03 \x01(\x08"ñ\x03\n\tVmContext\x12\x10\n\x08heap_max\x18\x01 \x01(\x04\x12\x0e\n\x06rodata\x18\x02 \x01(\x0c\x12"\n\x1arodata_text_section_offset\x18\x03 \x01(\x04\x12"\n\x1arodata_text_section_length\x18\x04 \x01(\x04\x12C\n\x12input_data_regions\x18\x05 \x03(\x0b2\'.org.solana.sealevel.v1.InputDataRegion\x12\n\n\x02r0\x18\x06 \x01(\x04\x12\n\n\x02r1\x18\x07 \x01(\x04\x12\n\n\x02r2\x18\x08 \x01(\x04\x12\n\n\x02r3\x18\t \x01(\x04\x12\n\n\x02r4\x18\n \x01(\x04\x12\n\n\x02r5\x18\x0b \x01(\x04\x12\n\n\x02r6\x18\x0c \x01(\x04\x12\n\n\x02r7\x18\r \x01(\x04\x12\n\n\x02r8\x18\x0e \x01(\x04\x12\n\n\x02r9\x18\x0f \x01(\x04\x12\x0b\n\x03r10\x18\x10 \x01(\x04\x12\x0b\n\x03r11\x18\x11 \x01(\x04\x12\x13\n\x0bcheck_align\x18\x12 \x01(\x08\x12\x12\n\ncheck_size\x18\x13 \x01(\x08\x12\x10\n\x08entry_pc\x18\x14 \x01(\x04\x12\x16\n\x0ecall_whitelist\x18\x15 \x01(\x0c\x12\x17\n\x0ftracing_enabled\x18\x16 \x01(\x08\x127\n\x0breturn_data\x18\x17 \x01(\x0b2".org.solana.sealevel.v1.ReturnData"U\n\x11SyscallInvocation\x12\x15\n\rfunction_name\x18\x01 \x01(\x0c\x12\x13\n\x0bheap_prefix\x18\x02 \x01(\x0c\x12\x14\n\x0cstack_prefix\x18\x03 \x01(\x0c"ÿ\x01\n\x0eSyscallContext\x121\n\x06vm_ctx\x18\x01 \x01(\x0b2!.org.solana.sealevel.v1.VmContext\x127\n\tinstr_ctx\x18\x02 \x01(\x0b2$.org.solana.sealevel.v1.InstrContext\x12E\n\x12syscall_invocation\x18\x03 \x01(\x0b2).org.solana.sealevel.v1.SyscallInvocation\x12:\n\x0cexec_effects\x18\x04 \x01(\x0b2$.org.solana.sealevel.v1.InstrEffects"¥\x02\n\x0eSyscallEffects\x12\r\n\x05error\x18\x01 \x01(\x03\x123\n\nerror_kind\x18\x0c \x01(\x0e2\x1f.org.solana.sealevel.v1.ErrKind\x12\n\n\x02r0\x18\x02 \x01(\x04\x12\x10\n\x08cu_avail\x18\x03 \x01(\x04\x12\x0c\n\x04heap\x18\x04 \x01(\x0c\x12\r\n\x05stack\x18\x05 \x01(\x0c\x12\x11\n\tinputdata\x18\x06 \x01(\x0c\x12C\n\x12input_data_regions\x18\x0b \x03(\x0b2\'.org.solana.sealevel.v1.InputDataRegion\x12\x13\n\x0bframe_count\x18\x07 \x01(\x04\x12\x0b\n\x03log\x18\x08 \x01(\x0c\x12\x0e\n\x06rodata\x18\t \x01(\x0c\x12\n\n\x02pc\x18\n \x01(\x04"º\x01\n\x0eSyscallFixture\x129\n\x08metadata\x18\x01 \x01(\x0b2\'.org.solana.sealevel.v1.FixtureMetadata\x125\n\x05input\x18\x02 \x01(\x0b2&.org.solana.sealevel.v1.SyscallContext\x126\n\x06output\x18\x03 \x01(\x0b2&.org.solana.sealevel.v1.SyscallEffects"x\n\rFullVmContext\x121\n\x06vm_ctx\x18\x01 \x01(\x0b2!.org.solana.sealevel.v1.VmContext\x124\n\x08features\x18\x03 \x01(\x0b2".org.solana.sealevel.v1.FeatureSet"4\n\x11ValidateVmEffects\x12\x0e\n\x06result\x18\x01 \x01(\x05\x12\x0f\n\x07success\x18\x02 \x01(\x08"¿\x01\n\x11ValidateVmFixture\x129\n\x08metadata\x18\x01 \x01(\x0b2\'.org.solana.sealevel.v1.FixtureMetadata\x124\n\x05input\x18\x02 \x01(\x0b2%.org.solana.sealevel.v1.FullVmContext\x129\n\x06output\x18\x03 \x01(\x0b2).org.solana.sealevel.v1.ValidateVmEffects".\n\nReturnData\x12\x12\n\nprogram_id\x18\x01 \x01(\x0c\x12\x0c\n\x04data\x18\x02 \x01(\x0c*B\n\x07ErrKind\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x08\n\x04EBPF\x10\x01\x12\x0b\n\x07SYSCALL\x10\x02\x12\x0f\n\x0bINSTRUCTION\x10\x03b\x06proto3' + '\n\x08vm.proto\x12\x16org.solana.sealevel.v1\x1a\x0cinvoke.proto\x1a\rcontext.proto\x1a\x0emetadata.proto"G\n\x0fInputDataRegion\x12\x0e\n\x06offset\x18\x01 \x01(\x04\x12\x0f\n\x07content\x18\x02 \x01(\x0c\x12\x13\n\x0bis_writable\x18\x03 \x01(\x08"\x87\x04\n\tVmContext\x12\x10\n\x08heap_max\x18\x01 \x01(\x04\x12\x0e\n\x06rodata\x18\x02 \x01(\x0c\x12"\n\x1arodata_text_section_offset\x18\x03 \x01(\x04\x12"\n\x1arodata_text_section_length\x18\x04 \x01(\x04\x12C\n\x12input_data_regions\x18\x05 \x03(\x0b2\'.org.solana.sealevel.v1.InputDataRegion\x12\n\n\x02r0\x18\x06 \x01(\x04\x12\n\n\x02r1\x18\x07 \x01(\x04\x12\n\n\x02r2\x18\x08 \x01(\x04\x12\n\n\x02r3\x18\t \x01(\x04\x12\n\n\x02r4\x18\n \x01(\x04\x12\n\n\x02r5\x18\x0b \x01(\x04\x12\n\n\x02r6\x18\x0c \x01(\x04\x12\n\n\x02r7\x18\r \x01(\x04\x12\n\n\x02r8\x18\x0e \x01(\x04\x12\n\n\x02r9\x18\x0f \x01(\x04\x12\x0b\n\x03r10\x18\x10 \x01(\x04\x12\x0b\n\x03r11\x18\x11 \x01(\x04\x12\x13\n\x0bcheck_align\x18\x12 \x01(\x08\x12\x12\n\ncheck_size\x18\x13 \x01(\x08\x12\x10\n\x08entry_pc\x18\x14 \x01(\x04\x12\x16\n\x0ecall_whitelist\x18\x15 \x01(\x0c\x12\x17\n\x0ftracing_enabled\x18\x16 \x01(\x08\x127\n\x0breturn_data\x18\x17 \x01(\x0b2".org.solana.sealevel.v1.ReturnData\x12\x14\n\x0csbpf_version\x18\x18 \x01(\r"U\n\x11SyscallInvocation\x12\x15\n\rfunction_name\x18\x01 \x01(\x0c\x12\x13\n\x0bheap_prefix\x18\x02 \x01(\x0c\x12\x14\n\x0cstack_prefix\x18\x03 \x01(\x0c"ÿ\x01\n\x0eSyscallContext\x121\n\x06vm_ctx\x18\x01 \x01(\x0b2!.org.solana.sealevel.v1.VmContext\x127\n\tinstr_ctx\x18\x02 \x01(\x0b2$.org.solana.sealevel.v1.InstrContext\x12E\n\x12syscall_invocation\x18\x03 \x01(\x0b2).org.solana.sealevel.v1.SyscallInvocation\x12:\n\x0cexec_effects\x18\x04 \x01(\x0b2$.org.solana.sealevel.v1.InstrEffects"\x9e\x03\n\x0eSyscallEffects\x12\r\n\x05error\x18\x01 \x01(\x03\x123\n\nerror_kind\x18\x0c \x01(\x0e2\x1f.org.solana.sealevel.v1.ErrKind\x12\n\n\x02r0\x18\x02 \x01(\x04\x12\x10\n\x08cu_avail\x18\x03 \x01(\x04\x12\x0c\n\x04heap\x18\x04 \x01(\x0c\x12\r\n\x05stack\x18\x05 \x01(\x0c\x12\x11\n\tinputdata\x18\x06 \x01(\x0c\x12C\n\x12input_data_regions\x18\x0b \x03(\x0b2\'.org.solana.sealevel.v1.InputDataRegion\x12\x13\n\x0bframe_count\x18\x07 \x01(\x04\x12\x0b\n\x03log\x18\x08 \x01(\x0c\x12\x0e\n\x06rodata\x18\t \x01(\x0c\x12\n\n\x02pc\x18\n \x01(\x04\x12\n\n\x02r1\x18k \x01(\x04\x12\n\n\x02r2\x18l \x01(\x04\x12\n\n\x02r3\x18m \x01(\x04\x12\n\n\x02r4\x18n \x01(\x04\x12\n\n\x02r5\x18o \x01(\x04\x12\n\n\x02r6\x18p \x01(\x04\x12\n\n\x02r7\x18q \x01(\x04\x12\n\n\x02r8\x18r \x01(\x04\x12\n\n\x02r9\x18s \x01(\x04\x12\x0b\n\x03r10\x18t \x01(\x04"º\x01\n\x0eSyscallFixture\x129\n\x08metadata\x18\x01 \x01(\x0b2\'.org.solana.sealevel.v1.FixtureMetadata\x125\n\x05input\x18\x02 \x01(\x0b2&.org.solana.sealevel.v1.SyscallContext\x126\n\x06output\x18\x03 \x01(\x0b2&.org.solana.sealevel.v1.SyscallEffects"x\n\rFullVmContext\x121\n\x06vm_ctx\x18\x01 \x01(\x0b2!.org.solana.sealevel.v1.VmContext\x124\n\x08features\x18\x03 \x01(\x0b2".org.solana.sealevel.v1.FeatureSet"4\n\x11ValidateVmEffects\x12\x0e\n\x06result\x18\x01 \x01(\x05\x12\x0f\n\x07success\x18\x02 \x01(\x08"¿\x01\n\x11ValidateVmFixture\x129\n\x08metadata\x18\x01 \x01(\x0b2\'.org.solana.sealevel.v1.FixtureMetadata\x124\n\x05input\x18\x02 \x01(\x0b2%.org.solana.sealevel.v1.FullVmContext\x129\n\x06output\x18\x03 \x01(\x0b2).org.solana.sealevel.v1.ValidateVmEffects".\n\nReturnData\x12\x12\n\nprogram_id\x18\x01 \x01(\x0c\x12\x0c\n\x04data\x18\x02 \x01(\x0c*B\n\x07ErrKind\x12\x0f\n\x0bUNSPECIFIED\x10\x00\x12\x08\n\x04EBPF\x10\x01\x12\x0b\n\x07SYSCALL\x10\x02\x12\x0f\n\x0bINSTRUCTION\x10\x03b\x06proto3' ), dependencies=[ invoke__pb2.DESCRIPTOR, @@ -47,8 +47,8 @@ ], containing_type=None, options=None, - serialized_start=1902, - serialized_end=1968, + serialized_start=2045, + serialized_end=2111, ) _sym_db.RegisterEnumDescriptor(_ERRKIND) ErrKind = enum_type_wrapper.EnumTypeWrapper(_ERRKIND) @@ -550,6 +550,24 @@ options=None, file=DESCRIPTOR, ), + _descriptor.FieldDescriptor( + name="sbpf_version", + full_name="org.solana.sealevel.v1.VmContext.sbpf_version", + index=23, + number=24, + type=13, + cpp_type=3, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), ], extensions=[], nested_types=[], @@ -560,7 +578,7 @@ extension_ranges=[], oneofs=[], serialized_start=155, - serialized_end=652, + serialized_end=674, ) _SYSCALLINVOCATION = _descriptor.Descriptor( name="SyscallInvocation", @@ -632,8 +650,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=654, - serialized_end=739, + serialized_start=676, + serialized_end=761, ) _SYSCALLCONTEXT = _descriptor.Descriptor( name="SyscallContext", @@ -723,8 +741,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=742, - serialized_end=997, + serialized_start=764, + serialized_end=1019, ) _SYSCALLEFFECTS = _descriptor.Descriptor( name="SyscallEffects", @@ -949,6 +967,186 @@ options=None, file=DESCRIPTOR, ), + _descriptor.FieldDescriptor( + name="r1", + full_name="org.solana.sealevel.v1.SyscallEffects.r1", + index=12, + number=107, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r2", + full_name="org.solana.sealevel.v1.SyscallEffects.r2", + index=13, + number=108, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r3", + full_name="org.solana.sealevel.v1.SyscallEffects.r3", + index=14, + number=109, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r4", + full_name="org.solana.sealevel.v1.SyscallEffects.r4", + index=15, + number=110, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r5", + full_name="org.solana.sealevel.v1.SyscallEffects.r5", + index=16, + number=111, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r6", + full_name="org.solana.sealevel.v1.SyscallEffects.r6", + index=17, + number=112, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r7", + full_name="org.solana.sealevel.v1.SyscallEffects.r7", + index=18, + number=113, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r8", + full_name="org.solana.sealevel.v1.SyscallEffects.r8", + index=19, + number=114, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r9", + full_name="org.solana.sealevel.v1.SyscallEffects.r9", + index=20, + number=115, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), + _descriptor.FieldDescriptor( + name="r10", + full_name="org.solana.sealevel.v1.SyscallEffects.r10", + index=21, + number=116, + type=4, + cpp_type=4, + label=1, + has_default_value=False, + default_value=0, + message_type=None, + enum_type=None, + containing_type=None, + is_extension=False, + extension_scope=None, + options=None, + file=DESCRIPTOR, + ), ], extensions=[], nested_types=[], @@ -958,8 +1156,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=1000, - serialized_end=1293, + serialized_start=1022, + serialized_end=1436, ) _SYSCALLFIXTURE = _descriptor.Descriptor( name="SyscallFixture", @@ -1031,8 +1229,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=1296, - serialized_end=1482, + serialized_start=1439, + serialized_end=1625, ) _FULLVMCONTEXT = _descriptor.Descriptor( name="FullVmContext", @@ -1086,8 +1284,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=1484, - serialized_end=1604, + serialized_start=1627, + serialized_end=1747, ) _VALIDATEVMEFFECTS = _descriptor.Descriptor( name="ValidateVmEffects", @@ -1141,8 +1339,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=1606, - serialized_end=1658, + serialized_start=1749, + serialized_end=1801, ) _VALIDATEVMFIXTURE = _descriptor.Descriptor( name="ValidateVmFixture", @@ -1214,8 +1412,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=1661, - serialized_end=1852, + serialized_start=1804, + serialized_end=1995, ) _RETURNDATA = _descriptor.Descriptor( name="ReturnData", @@ -1269,8 +1467,8 @@ syntax="proto3", extension_ranges=[], oneofs=[], - serialized_start=1854, - serialized_end=1900, + serialized_start=1997, + serialized_end=2043, ) _VMCONTEXT.fields_by_name["input_data_regions"].message_type = _INPUTDATAREGION _VMCONTEXT.fields_by_name["return_data"].message_type = _RETURNDATA