Skip to content

Commit

Permalink
Merge pull request #3 from BCWResearch/june26
Browse files Browse the repository at this point in the history
June 26 commits
  • Loading branch information
Stephen-BCW authored Jul 1, 2024
2 parents f521766 + c684fe8 commit af2d911
Show file tree
Hide file tree
Showing 6 changed files with 215 additions and 33 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Continuous Integration

on:
push:
branches: [main]
branches: [develop, main]
pull_request:
branches:
- "**"
Expand Down
85 changes: 85 additions & 0 deletions .github/workflows/jerigon.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
name: Jerigon Integration

on:
push:
branches: [develop, main]
pull_request:
branches:
- "**"
workflow_dispatch:
branches:
- "**"


env:
CARGO_TERM_COLOR: always
REGISTRY: ghcr.io

jobs:
test_jerigon_input_proving:
name: Test proof generation with jerigon input
runs-on: zero-ci
timeout-minutes: 40
if: "! contains(toJSON(github.event.commits.*.message), '[skip-ci]')"
steps:
- name: Checkout sources
uses: actions/checkout@v4

- name: Checkout test-jerigon-network sources
uses: actions/checkout@v4
with:
repository: 0xPolygonZero/jerigon-test-network
path: test-jerigon-network

- name: Install nightly toolchain
uses: dtolnay/rust-toolchain@nightly

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Set up rust cache
uses: Swatinem/rust-cache@v2
with:
cache-on-failure: true

- name: Run jerigon test network with docker compose
run: |
cd test-jerigon-network
docker-compose -f docker-compose.yml up -d
docker logs -f smart-contracts
echo "Jerigon network is up and running, ready for testing"
- name: Rpc test with curl
run: |
curl -X POST -H "Content-Type: application/json" --data '{"jsonrpc": "2.0", "method": "eth_blockNumber", "params": [], "id":83}' localhost:8545
env:
RUST_LOG: info

- name: Run prove blocks in test_only mode
run: |
cd zero_bin/tools
OUTPUT_TO_TERMINAL=true ./prove_rpc.sh 0x2 0x3 http://localhost:8546 jerigon true 0 0 test_only
echo "Proving blocks in test_only mode finished"
- name: Run prove blocks in real mode
run: |
cd zero_bin/tools
rm -rf proofs/* circuits/* ./proofs.json test.out verify.out leader.out
OUTPUT_TO_TERMINAL=true RUN_VERIFICATION=true ./prove_rpc.sh 0x4 0x5 http://localhost:8546 jerigon true
echo "Proving blocks in real mode finished"
- name: Shut down network
run: |
cd test-jerigon-network
docker-compose -f docker-compose.yml down -v
22 changes: 22 additions & 0 deletions .github/workflows/pr_checking.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: PR check

on:
pull_request_target:
types:
- opened
- edited
- synchronize

jobs:
title:
name: Validate PR
runs-on: ubuntu-latest
if: ${{
github.event.pull_request.author_association != 'CONTRIBUTOR' &&
github.event.pull_request.author_association != 'MEMBER' &&
(
contains(fromJSON(secrets.RESTRICTED_KEYWORDS), github.event.pull_request.title) ||
contains(fromJSON(secrets.RESTRICTED_KEYWORDS), github.event.pull_request.description
) }}
steps:
- run: gh pr close
36 changes: 26 additions & 10 deletions evm_arithmetization/src/cpu/decode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,16 @@ pub(crate) fn eval_packed_generic<P: PackedField>(
.sum()
};

// Manually check that the fp254 operations are kernel-only instructions.
yield_constr.constraint((kernel_mode - P::ONES) * lv.op.fp254_op);

// Manually check that SUBMOD is a kernel-only instruction. SUBMOD is
// differentiated by its second bit set to 1.
yield_constr.constraint(lv.op.ternary_op * lv.opcode_bits[1] * (kernel_mode - P::ONES));

// Manually check lv.op.m_op_constr
let opcode = opcode_high_bits(8);
yield_constr.constraint((P::ONES - kernel_mode) * lv.op.m_op_general);
yield_constr.constraint((kernel_mode - P::ONES) * lv.op.m_op_general);

let m_op_constr = (opcode - P::Scalar::from_canonical_usize(0xfb_usize))
* (opcode - P::Scalar::from_canonical_usize(0xfc_usize))
Expand All @@ -161,7 +168,7 @@ pub(crate) fn eval_packed_generic<P: PackedField>(
// KECCAK_GENERAL is a kernel-only instruction, but not JUMPDEST.
// JUMPDEST is differentiated from KECCAK_GENERAL by its second bit set to 1.
yield_constr.constraint(
(P::ONES - kernel_mode) * lv.op.jumpdest_keccak_general * (P::ONES - lv.opcode_bits[1]),
(kernel_mode - P::ONES) * lv.op.jumpdest_keccak_general * (P::ONES - lv.opcode_bits[1]),
);

// Check the JUMPDEST and KERNEL_GENERAL opcodes.
Expand Down Expand Up @@ -190,7 +197,7 @@ pub(crate) fn eval_packed_generic<P: PackedField>(

// Manually check lv.op.m_op_32bytes.
// Both are kernel-only.
yield_constr.constraint((P::ONES - kernel_mode) * lv.op.m_op_32bytes);
yield_constr.constraint((kernel_mode - P::ONES) * lv.op.m_op_32bytes);

// Check the MSTORE_32BYTES and MLOAD-32BYTES opcodes.
let opcode_high_three = opcode_high_bits(3);
Expand All @@ -206,7 +213,7 @@ pub(crate) fn eval_packed_generic<P: PackedField>(
* lv.op.push_prover_input;
yield_constr.constraint(push_prover_input_constr);
let prover_input_constr =
lv.op.push_prover_input * (lv.opcode_bits[5] - P::ONES) * (P::ONES - kernel_mode);
lv.op.push_prover_input * (lv.opcode_bits[5] - P::ONES) * (kernel_mode - P::ONES);
yield_constr.constraint(prover_input_constr);
}

Expand Down Expand Up @@ -304,15 +311,23 @@ pub(crate) fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
yield_constr.constraint(builder, constr);
}

// Manually check that the fp254 operations are kernel-only instructions.
let constr = builder.mul_sub_extension(kernel_mode, lv.op.fp254_op, lv.op.fp254_op);
yield_constr.constraint(builder, constr);

// Manually check that SUBMOD is a kernel-only instruction. SUBMOD is
// differentiated by its second bit set to 1.
let submod_op = builder.mul_extension(lv.op.ternary_op, lv.opcode_bits[1]);
let constr = builder.mul_sub_extension(kernel_mode, submod_op, submod_op);
yield_constr.constraint(builder, constr);

// Manually check lv.op.m_op_constr
let opcode = opcode_high_bits_circuit(builder, lv, 8);

let mload_opcode = builder.constant_extension(F::Extension::from_canonical_usize(0xfb_usize));
let mstore_opcode = builder.constant_extension(F::Extension::from_canonical_usize(0xfc_usize));

let one_extension = builder.constant_extension(F::Extension::ONE);
let is_not_kernel_mode = builder.sub_extension(one_extension, kernel_mode);
let constr = builder.mul_extension(is_not_kernel_mode, lv.op.m_op_general);
let constr = builder.mul_sub_extension(kernel_mode, lv.op.m_op_general, lv.op.m_op_general);
yield_constr.constraint(builder, constr);

let mload_constr = builder.sub_extension(opcode, mload_opcode);
Expand All @@ -334,7 +349,8 @@ pub(crate) fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
let mut kernel_general_filter = builder.sub_extension(one, lv.opcode_bits[1]);
kernel_general_filter =
builder.mul_extension(lv.op.jumpdest_keccak_general, kernel_general_filter);
let constr = builder.mul_extension(is_not_kernel_mode, kernel_general_filter);
let constr =
builder.mul_sub_extension(kernel_mode, kernel_general_filter, kernel_general_filter);
yield_constr.constraint(builder, constr);

// Check the JUMPDEST and KERNEL_GENERAL opcodes.
Expand Down Expand Up @@ -375,7 +391,7 @@ pub(crate) fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(

// Manually check lv.op.m_op_32bytes.
// Both are kernel-only.
let constr = builder.mul_extension(is_not_kernel_mode, lv.op.m_op_32bytes);
let constr = builder.mul_sub_extension(kernel_mode, lv.op.m_op_32bytes, lv.op.m_op_32bytes);
yield_constr.constraint(builder, constr);

// Check the MSTORE_32BYTES and MLOAD-32BYTES opcodes.
Expand Down Expand Up @@ -407,6 +423,6 @@ pub(crate) fn eval_ext_circuit<F: RichField + Extendable<D>, const D: usize>(
lv.opcode_bits[5],
lv.op.push_prover_input,
);
let constr = builder.mul_extension(prover_input_filter, is_not_kernel_mode);
let constr = builder.mul_sub_extension(kernel_mode, prover_input_filter, prover_input_filter);
yield_constr.constraint(builder, constr);
}
27 changes: 27 additions & 0 deletions evm_arithmetization/src/cpu/kernel/asm/core/terminate.asm
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,36 @@ global sys_selfdestruct:
%add_eth

sys_selfdestruct_journal_add:
// stack: address, recipient, balance, kexit_info
DUP3 ISZERO

// If balance is 0, we didn't perform any transfer. Hence, the recipient
// may not exist, and we need to verify this before adding a new journal entry.

// stack: balance=0, address, recipient, balance, kexit_info
%jumpi(skip_journal_entry_if_nonexistent)

sys_selfdestruct_journal_add_after_check:
// stack: address, recipient, balance, kexit_info
%journal_add_account_destroyed
%jump(sys_selfdestruct_exit)

skip_journal_entry_if_nonexistent:
// stack: address, recipient, balance, kexit_info
DUP2 %is_non_existent

// If the account doesn't exist, there is no need to add a journal entry.
// stack: recipient_is_non_existent, address, recipient, balance, kexit_info
%jumpi(skip_journal_entry)

// stack: address, recipient, balance, kexit_info
%jump(sys_selfdestruct_journal_add_after_check)

skip_journal_entry:
// stack: address, recipient, balance, kexit_info
%pop3

sys_selfdestruct_exit:
// stack: kexit_info
%leftover_gas
// stack: leftover_gas
Expand Down
76 changes: 54 additions & 22 deletions zero_bin/tools/prove_rpc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ IGNORE_PREVIOUS_PROOFS=$5
BACKOFF=${6:-0}
RETRIES=${7:-0}

# Sometimes we need to override file logging, e.g. in the CI run
OUTPUT_TO_TERMINAL="${OUTPUT_TO_TERMINAL:-false}"
# Only generate proof by default
RUN_VERIFICATION="${RUN_VERIFICATION:-false}"

mkdir -p $PROOF_OUTPUT_DIR

Expand Down Expand Up @@ -87,38 +91,66 @@ fi
if [[ $8 == "test_only" ]]; then
# test only run
echo "Proving blocks ${BLOCK_INTERVAL} in a test_only mode now... (Total: ${TOT_BLOCKS})"
cargo r --release --features test_only --bin leader -- --runtime in-memory --load-strategy on-demand rpc --rpc-type "$NODE_RPC_TYPE" --rpc-url "$NODE_RPC_URL" --block-interval $BLOCK_INTERVAL --proof-output-dir $PROOF_OUTPUT_DIR $PREV_PROOF_EXTRA_ARG --backoff "$BACKOFF" --max-retries "$RETRIES" > $OUT_LOG_PATH 2>&1
if grep -q 'All proof witnesses have been generated successfully.' $OUT_LOG_PATH; then
echo -e "Success - Note this was just a test, not a proof"
# Remove the log on success if we don't want to keep it.
if [ $ALWAYS_WRITE_LOGS -ne 1 ]; then
rm $OUT_LOG_PATH
fi
exit
command='cargo r --release --features test_only --bin leader -- --runtime in-memory --load-strategy on-demand rpc --rpc-type "$NODE_RPC_TYPE" --rpc-url "$NODE_RPC_URL" --block-interval $BLOCK_INTERVAL --proof-output-dir $PROOF_OUTPUT_DIR $PREV_PROOF_EXTRA_ARG --backoff "$BACKOFF" --max-retries "$RETRIES" '
if [ "$OUTPUT_TO_TERMINAL" = true ]; then
eval $command
retVal=$?
echo -e "Proof witness generation finished with result: $retVal"
exit $retVal
else
echo "Failed to create proof witnesses. See ${OUT_LOG_PATH} for more details."
exit 1
eval $command > $OUT_LOG_PATH 2>&1
if grep -q 'All proof witnesses have been generated successfully.' $OUT_LOG_PATH; then
echo -e "Success - Note this was just a test, not a proof"
# Remove the log on success if we don't want to keep it.
if [ $ALWAYS_WRITE_LOGS -ne 1 ]; then
rm $OUT_LOG_PATH
fi
exit
else
echo "Failed to create proof witnesses. See ${OUT_LOG_PATH} for more details."
exit 1
fi
fi
else
# normal run
echo "Proving blocks ${BLOCK_INTERVAL} now... (Total: ${TOT_BLOCKS})"
cargo r --release --bin leader -- --runtime in-memory --load-strategy on-demand rpc --rpc-type "$NODE_RPC_TYPE" --rpc-url "$3" --block-interval $BLOCK_INTERVAL --proof-output-dir $PROOF_OUTPUT_DIR $PREV_PROOF_EXTRA_ARG --backoff "$BACKOFF" --max-retries "$RETRIES" > $OUT_LOG_PATH 2>&1

retVal=$?
if [ $retVal -ne 0 ]; then
# Some error occurred.
echo "Block ${i} errored. See ${OUT_LOG_PATH} for more details."
exit $retVal
command='cargo r --release --bin leader -- --runtime in-memory --load-strategy on-demand rpc --rpc-type "$NODE_RPC_TYPE" --rpc-url "$3" --block-interval $BLOCK_INTERVAL --proof-output-dir $PROOF_OUTPUT_DIR $PREV_PROOF_EXTRA_ARG --backoff "$BACKOFF" --max-retries "$RETRIES" '
if [ "$OUTPUT_TO_TERMINAL" = true ]; then
eval $command
echo -e "Proof generation finished with result: $?"
else
# Remove the log on success if we don't want to keep it.
if [ $ALWAYS_WRITE_LOGS -ne 1 ]; then
rm $OUT_LOG_PATH
eval $command > $OUT_LOG_PATH 2>&1
retVal=$?
if [ $retVal -ne 0 ]; then
# Some error occurred.
echo "Block ${i} errored. See ${OUT_LOG_PATH} for more details."
exit $retVal
else
# Remove the log on success if we don't want to keep it.
if [ $ALWAYS_WRITE_LOGS -ne 1 ]; then
rm $OUT_LOG_PATH
fi
fi
echo "Successfully generated ${TOT_BLOCKS} proofs!"
fi

echo "Successfully generated ${TOT_BLOCKS} proofs!"
fi


# If we're running the verification, we'll do it here.
if [ "$RUN_VERIFICATION" = true ]; then
echo "Running the verification"

proof_file_name=$PROOF_OUTPUT_DIR/b$END_BLOCK.zkproof
echo "Verifying the proof of the latest block in the interval:" $proof_file_name
echo [ > $PROOF_OUTPUT_DIR/proofs.json && cat $proof_file_name >> $PROOF_OUTPUT_DIR/proofs.json && echo ] >> $PROOF_OUTPUT_DIR/proofs.json
cargo r --release --bin verifier -- -f $PROOF_OUTPUT_DIR/proofs.json > $PROOF_OUTPUT_DIR/verify.out 2>&1

if grep -q 'All proofs verified successfully!' $PROOF_OUTPUT_DIR/verify.out; then
echo "All proofs verified successfully!";
else
echo "there was an issue with proof verification";
exit 1
fi
else
echo "Skipping verification..."
fi

0 comments on commit af2d911

Please sign in to comment.