From 2c5d67433735ce8a2ae2f6748681f72814c71396 Mon Sep 17 00:00:00 2001 From: Michael Zaikin Date: Tue, 15 Oct 2024 11:04:39 +0100 Subject: [PATCH] Cairo1-run compatibility (#264) --- Scarb.toml | 7 +++++- packages/client/src/lib.cairo | 3 --- packages/client/src/main.cairo | 33 ------------------------- packages/client/src/test.cairo | 40 +++++++++++++------------------ scripts/data/client.sh | 2 +- scripts/data/format_args.py | 16 ++++++++++--- scripts/data/integration_tests.sh | 4 ++-- 7 files changed, 38 insertions(+), 67 deletions(-) delete mode 100644 packages/client/src/main.cairo diff --git a/Scarb.toml b/Scarb.toml index afb00256..f14a8ecb 100644 --- a/Scarb.toml +++ b/Scarb.toml @@ -11,5 +11,10 @@ license-file = "LICENSE" [workspace.dependencies] cairo_test = "2.8.0" - shinigami_engine = { git = "https://github.com/keep-starknet-strange/shinigami.git", rev = "9e7692d" } + +[profile.cairo1-run.cairo] +# https://github.com/lambdaclass/cairo-vm/issues/1745 +enable-gas = false +# https://github.com/software-mansion/scarb/blob/4d91be7a7dbfeb24327e3ba21c62fbac43a2105a/scarb/src/compiler/compilers/lib.rs#L154 +sierra-replace-ids = true \ No newline at end of file diff --git a/packages/client/src/lib.cairo b/packages/client/src/lib.cairo index c1bd37d3..58572291 100644 --- a/packages/client/src/lib.cairo +++ b/packages/client/src/lib.cairo @@ -1,4 +1 @@ -mod main; -// TODO: scarb cairo-run should support "features" argument -// so that we can conditionally compile this module mod test; diff --git a/packages/client/src/main.cairo b/packages/client/src/main.cairo deleted file mode 100644 index d694be71..00000000 --- a/packages/client/src/main.cairo +++ /dev/null @@ -1,33 +0,0 @@ -use consensus::types::block::Block; -use consensus::types::chain_state::{ChainState, BlockValidator}; -use consensus::types::utxo_set::UtxoSet; - -/// Raito program arguments. -#[derive(Serde)] -struct Args { - /// Current (initial) chain state - chain_state: ChainState, - /// Batch of blocks that have to be applied to the current chain state - blocks: Array, -} - -/// Raito program entrypoint. -/// -/// Receives current state (chain state + utreexo state) and pending blocks, -/// then validates and applies them one by one. -/// Returns new state in case of success, otherwise raises an error. -fn main(mut arguments: Span) -> ChainState { - let Args { mut chain_state, blocks, } = Serde::deserialize(ref arguments) - .expect('Failed to deserialize'); - - let mut utxo_set: UtxoSet = Default::default(); - - // Validate and apply block, accumulating UTXO updates in utxo_set - for block in blocks { - chain_state = chain_state - .validate_and_apply(block, ref utxo_set, false) - .expect('Block validation failed'); - }; - - chain_state -} diff --git a/packages/client/src/test.cairo b/packages/client/src/test.cairo index 7fef9f2a..65bac1dc 100644 --- a/packages/client/src/test.cairo +++ b/packages/client/src/test.cairo @@ -35,29 +35,21 @@ struct UtreexoArgs { /// Receives arguments in a serialized format (Cairo serde). /// Panics in case of a validation error or chain state mismatch. /// Prints result to the stdout. -fn test(mut arguments: Span, execute_script: bool) { +pub(crate) fn main(mut arguments: Span, execute_script: bool) { + let mut gas_before = get_available_gas(); + let Args { mut chain_state, blocks, expected_chain_state, utreexo_args } = Serde::deserialize( ref arguments ) .expect('Failed to deserialize'); let mut utxo_set: UtxoSet = Default::default(); - let mut gas_before = get_available_gas(); for block in blocks { - let height = chain_state.block_height + 1; match chain_state.validate_and_apply(block, ref utxo_set, execute_script) { - Result::Ok(new_chain_state) => { - chain_state = new_chain_state; - let gas_after = get_available_gas(); - println!("OK: block={} gas_spent={}", height, gas_before - gas_after); - gas_before = gas_after; - }, + Result::Ok(new_chain_state) => { chain_state = new_chain_state; }, Result::Err(err) => { - let gas_after = get_available_gas(); - println!( - "FAIL: block={} gas_spent={} error='{}'", height, gas_before - gas_after, err - ); + println!("FAIL: gas_spent={} error='{}'", gas_before - get_available_gas(), err); panic!(); } } @@ -65,8 +57,8 @@ fn test(mut arguments: Span, execute_script: bool) { if chain_state != expected_chain_state { println!( - "FAIL: block={} error='expected chain state {:?}, actual {:?}'", - chain_state.block_height, + "FAIL: gas_spent={} error='expected chain state {:?}, actual {:?}'", + gas_before - get_available_gas(), expected_chain_state, chain_state ); @@ -74,7 +66,7 @@ fn test(mut arguments: Span, execute_script: bool) { } if let Result::Err(err) = utxo_set.finalize() { - println!("FAIL: error='{}'", err); + println!("FAIL: gas_spent={} error='{}'", gas_before - get_available_gas(), err); panic!(); } @@ -83,25 +75,25 @@ fn test(mut arguments: Span, execute_script: bool) { .validate_and_apply( utxo_set.leaves_to_add.span(), utxo_set.leaves_to_delete.span(), proofs.span(), ) { - Result::Ok(new_state) => { - state = new_state; - let gas_after = get_available_gas(); - println!("OK: gas_spent={}", gas_before - gas_after); - }, + Result::Ok(new_state) => { state = new_state; }, Result::Err(err) => { - let gas_after = get_available_gas(); - println!("FAIL: gas_spent={} error='{:?}'", gas_before - gas_after, err); + println!("FAIL: gas_spent={} error='{:?}'", gas_before - get_available_gas(), err); panic!(); } } if state != expected_state { println!( - "FAIL: error='expected utreexo state {:?}, actual {:?}'", expected_state, state + "FAIL: gas_spent={} error='expected utreexo state {:?}, actual {:?}'", + gas_before - get_available_gas(), + expected_state, + state ); panic!(); } } + + println!("OK: gas_spent={}", gas_before - get_available_gas()); } /// Workaround for handling missing `utreexo_args` field. diff --git a/scripts/data/client.sh b/scripts/data/client.sh index 6f8bf5ec..69c77c24 100755 --- a/scripts/data/client.sh +++ b/scripts/data/client.sh @@ -29,7 +29,7 @@ run_client() { echo -n "Running $mode client on blocks $first - $second " python ../../scripts/data/format_args.py $batch_file > $arguments_file - output=$(scarb cairo-run --no-build --package client --function test --arguments-file $arguments_file) + output=$(scarb cairo-run --no-build --package client --function main --arguments-file $arguments_file) if [[ $? -ne 0 || "$output" == *"FAIL"* || "$output" == *error* || "$output" == *panicked* ]]; then echo "fail" echo $output diff --git a/scripts/data/format_args.py b/scripts/data/format_args.py index e7c066b6..1accde48 100644 --- a/scripts/data/format_args.py +++ b/scripts/data/format_args.py @@ -110,14 +110,18 @@ def format_item(item): return format_item(args) -def format_args(input_file, execute_script): +def format_args(input_file, execute_script, cairo1_run): """Reads arguments from JSON file and prints formatted result. Expects a single CLI argument containing file path. Output is compatible with the Scarb runner arguments format. """ args = json.loads(Path(input_file).read_text()) res = flatten_tuples(serialize(args)) - print([res, 1 if execute_script else 0]) + flag = 1 if execute_script else 0 + if cairo1_run: + print(f"{format_cairo1_run(res)} {flag}") + else: + print([res, flag]) if __name__ == "__main__": @@ -138,6 +142,12 @@ def format_args(input_file, execute_script): help="Input file with arguments in JSON format", ) + parser.add_argument( + "--cairo1_run", + action=argparse.BooleanOptionalAction, + help="Whether to format args for cairo1-run or not", + ) + args = parser.parse_args() - format_args(args.input_file, args.execute_script) + format_args(args.input_file, args.execute_script, args.cairo1_run) diff --git a/scripts/data/integration_tests.sh b/scripts/data/integration_tests.sh index 8028713e..cf32e288 100755 --- a/scripts/data/integration_tests.sh +++ b/scripts/data/integration_tests.sh @@ -75,8 +75,8 @@ for test_file in "${test_files[@]}"; do else arguments_file=".arguments-$(basename "$test_file")" python ../../scripts/data/format_args.py --input_file ${test_file} $([[ $execute_scripts -eq 1 ]] && echo "--execute_script") > $arguments_file - output=$(scarb cairo-run --no-build --function test --arguments-file $arguments_file) - gas_spent=$(echo "$output" | grep -o 'gas_spent=[0-9]*' | awk -F= '{sum += $2} END {print sum}') + output=$(scarb cairo-run --no-build --function main --arguments-file $arguments_file) + gas_spent=$(echo $output | grep -o 'gas_spent=[0-9]*' | sed 's/gas_spent=//') if [[ "$nocapture" -eq 1 ]]; then echo -e "\n$output"