From f5e26578d707e838b8f81f87f8269ffa59c8659f Mon Sep 17 00:00:00 2001 From: Josh Klopfenstein Date: Fri, 24 Nov 2023 11:13:43 +0300 Subject: [PATCH 1/2] Update blockifier --- mocks/mock_vm.go | 8 ++-- node/throttled_vm.go | 4 +- rpc/handlers.go | 4 +- rpc/handlers_test.go | 16 ++++---- vm/rust/Cargo.toml | 8 ++-- vm/rust/src/jsonrpc.rs | 13 ++++--- vm/rust/src/lib.rs | 84 ++++++++++++++++++++++++------------------ vm/transaction.go | 7 +++- vm/vm.go | 19 +++++++--- vm/vm_test.go | 4 +- 10 files changed, 96 insertions(+), 71 deletions(-) diff --git a/mocks/mock_vm.go b/mocks/mock_vm.go index 4622e705d7..a1c9255b3b 100644 --- a/mocks/mock_vm.go +++ b/mocks/mock_vm.go @@ -57,9 +57,9 @@ func (mr *MockVMMockRecorder) Call(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg } // Execute mocks base method. -func (m *MockVM) Execute(arg0 []core.Transaction, arg1 []core.Class, arg2, arg3 uint64, arg4 *felt.Felt, arg5 core.StateReader, arg6 utils.Network, arg7 []*felt.Felt, arg8, arg9 bool, arg10 *felt.Felt, arg11 bool) ([]*felt.Felt, []json.RawMessage, error) { +func (m *MockVM) Execute(arg0 []core.Transaction, arg1 []core.Class, arg2, arg3 uint64, arg4 *felt.Felt, arg5 core.StateReader, arg6 utils.Network, arg7 []*felt.Felt, arg8, arg9 bool, arg10, arg11 *felt.Felt, arg12 bool) ([]*felt.Felt, []json.RawMessage, error) { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "Execute", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11) + ret := m.ctrl.Call(m, "Execute", arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) ret0, _ := ret[0].([]*felt.Felt) ret1, _ := ret[1].([]json.RawMessage) ret2, _ := ret[2].(error) @@ -67,7 +67,7 @@ func (m *MockVM) Execute(arg0 []core.Transaction, arg1 []core.Class, arg2, arg3 } // Execute indicates an expected call of Execute. -func (mr *MockVMMockRecorder) Execute(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11 any) *gomock.Call { +func (mr *MockVMMockRecorder) Execute(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12 any) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Execute", reflect.TypeOf((*MockVM)(nil).Execute), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Execute", reflect.TypeOf((*MockVM)(nil).Execute), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11, arg12) } diff --git a/node/throttled_vm.go b/node/throttled_vm.go index c1857f5776..08e26f8c54 100644 --- a/node/throttled_vm.go +++ b/node/throttled_vm.go @@ -31,7 +31,7 @@ func (tvm *ThrottledVM) Call(contractAddr, classHash, selector *felt.Felt, calld func (tvm *ThrottledVM) Execute(txns []core.Transaction, declaredClasses []core.Class, blockNumber, blockTimestamp uint64, sequencerAddress *felt.Felt, state core.StateReader, network utils.Network, paidFeesOnL1 []*felt.Felt, - skipChargeFee, skipValidate bool, gasPrice *felt.Felt, legacyTraceJSON bool, + skipChargeFee, skipValidate bool, gasPriceWEI *felt.Felt, gasPriceSTRK *felt.Felt, legacyTraceJSON bool, ) ([]*felt.Felt, []json.RawMessage, error) { var ret []*felt.Felt var traces []json.RawMessage @@ -39,7 +39,7 @@ func (tvm *ThrottledVM) Execute(txns []core.Transaction, declaredClasses []core. return ret, traces, throttler.Do(func(vm *vm.VM) error { var err error ret, traces, err = (*vm).Execute(txns, declaredClasses, blockNumber, blockTimestamp, sequencerAddress, - state, network, paidFeesOnL1, skipChargeFee, skipValidate, gasPrice, legacyTraceJSON) + state, network, paidFeesOnL1, skipChargeFee, skipValidate, gasPriceWEI, gasPriceSTRK, legacyTraceJSON) return err }) } diff --git a/rpc/handlers.go b/rpc/handlers.go index 293cde60fe..d8da53c3d4 100644 --- a/rpc/handlers.go +++ b/rpc/handlers.go @@ -1349,7 +1349,7 @@ func (h *Handler) simulateTransactions(id BlockID, transactions []BroadcastedTra sequencerAddress = core.NetworkBlockHashMetaInfo(h.network).FallBackSequencerAddress } overallFees, traces, err := h.vm.Execute(txns, classes, blockNumber, header.Timestamp, sequencerAddress, - state, h.network, paidFeesOnL1, skipFeeCharge, skipValidate, header.GasPrice, legacyTraceJSON) + state, h.network, paidFeesOnL1, skipFeeCharge, skipValidate, header.GasPrice, header.GasPriceSTRK, legacyTraceJSON) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { return nil, ErrUnexpectedError.CloneWithData(err.Error()) @@ -1482,7 +1482,7 @@ func (h *Handler) traceBlockTransactions(ctx context.Context, block *core.Block, } _, traces, err := h.vm.Execute(block.Transactions, classes, blockNumber, block.Header.Timestamp, - sequencerAddress, state, h.network, paidFeesOnL1, false, false, block.Header.GasPrice, legacyJSON) + sequencerAddress, state, h.network, paidFeesOnL1, false, false, block.Header.GasPrice, block.Header.GasPriceSTRK, legacyJSON) if err != nil { if errors.Is(err, utils.ErrResourceBusy) { return nil, ErrUnexpectedError.CloneWithData(err.Error()) diff --git a/rpc/handlers_test.go b/rpc/handlers_test.go index 27c8ee34f8..305194304c 100644 --- a/rpc/handlers_test.go +++ b/rpc/handlers_test.go @@ -2055,10 +2055,10 @@ func TestEstimateMessageFee(t *testing.T) { expectedGasConsumed := new(felt.Felt).SetUint64(37) mockVM.EXPECT().Execute(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any(), - gomock.Any(), utils.Mainnet, gomock.Any(), gomock.Any(), gomock.Any(), latestHeader.GasPrice, gomock.Any()).DoAndReturn( + gomock.Any(), utils.Mainnet, gomock.Any(), gomock.Any(), gomock.Any(), latestHeader.GasPrice, latestHeader.GasPriceSTRK, gomock.Any()).DoAndReturn( func(txns []core.Transaction, declaredClasses []core.Class, blockNumber, blockTimestamp uint64, sequencerAddress *felt.Felt, state core.StateReader, network utils.Network, paidFeesOnL1 []*felt.Felt, - skipChargeFee, skipValidate bool, gasPrice *felt.Felt, legacyTraceJson bool, + skipChargeFee, skipValidate bool, gasPriceWei, gasPriceSTRK *felt.Felt, legacyTraceJson bool, ) ([]*felt.Felt, []json.RawMessage, error) { require.Len(t, txns, 1) assert.NotNil(t, txns[0].(*core.L1HandlerTransaction)) @@ -2069,7 +2069,7 @@ func TestEstimateMessageFee(t *testing.T) { assert.NotNil(t, sequencerAddress) assert.Len(t, paidFeesOnL1, 1) - actualFee := new(felt.Felt).Mul(expectedGasConsumed, gasPrice) + actualFee := new(felt.Felt).Mul(expectedGasConsumed, gasPriceWei) return []*felt.Felt{actualFee}, []json.RawMessage{{}}, nil }, ) @@ -2138,7 +2138,7 @@ func TestTraceTransaction(t *testing.T) { "fee_transfer_invocation": {"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3", "entry_point_type": "EXTERNAL", "call_type": "CALL", "result": ["0x1"], "calls": [{"contract_address": "0x49d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", "entry_point_selector": "0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e", "calldata": ["0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"], "caller_address": "0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "class_hash": "0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0", "entry_point_type": "EXTERNAL", "call_type": "DELEGATE", "result": ["0x1"], "calls": [], "events": [{"keys": ["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"], "data": ["0xd747220b2744d8d8d48c8a52bd3869fb98aea915665ab2485d5eadb49def6a", "0x1176a1bd84444c89232ec27754698e5d2e7e1a7f1539f12027f28b23ec9f3d8", "0x2cb6", "0x0"]}], "messages": []}], "events": [], "messages": []} }`) mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, header.Number, header.Timestamp, header.SequencerAddress, - gomock.Any(), utils.Mainnet, []*felt.Felt{}, false, false, gomock.Any(), false).Return(nil, []json.RawMessage{vmTrace}, nil) + gomock.Any(), utils.Mainnet, []*felt.Felt{}, false, false, gomock.Any(), gomock.Any(), false).Return(nil, []json.RawMessage{vmTrace}, nil) trace, err := handler.TraceTransaction(context.Background(), *hash) require.Nil(t, err) @@ -2165,7 +2165,7 @@ func TestSimulateTransactions(t *testing.T) { mockReader.EXPECT().HeadsHeader().Return(&core.Header{}, nil) sequencerAddress := core.NetworkBlockHashMetaInfo(network).FallBackSequencerAddress - mockVM.EXPECT().Execute(nil, nil, uint64(0), uint64(0), sequencerAddress, mockState, network, []*felt.Felt{}, true, false, nil, false). + mockVM.EXPECT().Execute(nil, nil, uint64(0), uint64(0), sequencerAddress, mockState, network, []*felt.Felt{}, true, false, nil, nil, false). Return([]*felt.Felt{}, []json.RawMessage{}, nil) _, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipFeeChargeFlag}) @@ -2180,7 +2180,7 @@ func TestSimulateTransactions(t *testing.T) { mockReader.EXPECT().HeadsHeader().Return(&core.Header{}, nil) sequencerAddress := core.NetworkBlockHashMetaInfo(network).FallBackSequencerAddress - mockVM.EXPECT().Execute(nil, nil, uint64(0), uint64(0), sequencerAddress, mockState, network, []*felt.Felt{}, false, true, nil, false). + mockVM.EXPECT().Execute(nil, nil, uint64(0), uint64(0), sequencerAddress, mockState, network, []*felt.Felt{}, false, true, nil, nil, false). Return([]*felt.Felt{}, []json.RawMessage{}, nil) _, err := handler.SimulateTransactions(rpc.BlockID{Latest: true}, []rpc.BroadcastedTransaction{}, []rpc.SimulationFlag{rpc.SkipValidateFlag}) @@ -2249,7 +2249,7 @@ func TestTraceBlockTransactions(t *testing.T) { "fee_transfer_invocation": {} }`) mockVM.EXPECT().Execute(block.Transactions, []core.Class{declaredClass.Class}, height+1, header.Timestamp, sequencerAddress, - gomock.Any(), network, paidL1Fees, false, false, header.GasPrice, false).Return(nil, []json.RawMessage{vmTrace, vmTrace}, nil) + gomock.Any(), network, paidL1Fees, false, false, header.GasPrice, header.GasPriceSTRK, false).Return(nil, []json.RawMessage{vmTrace, vmTrace}, nil) result, err := handler.TraceBlockTransactions(context.Background(), rpc.BlockID{Hash: blockHash}) require.Nil(t, err) @@ -2293,7 +2293,7 @@ func TestTraceBlockTransactions(t *testing.T) { "fee_transfer_invocation":{"entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"],"caller_address":"0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","class_hash":"0xd0e183745e9dae3e4e78a8ffedcce0903fc4900beace4e0abf192d4c202da3","entry_point_type":"EXTERNAL","call_type":"CALL","result":["0x1"],"calls":[{"entry_point_selector":"0x83afd3f4caedc6eebf44246fe54e38c95e3179a5ec9ea81740eca5b482d12e","calldata":["0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"],"caller_address":"0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","class_hash":"0x2760f25d5a4fb2bdde5f561fd0b44a3dee78c28903577d37d669939d97036a0","entry_point_type":"EXTERNAL","call_type":"DELEGATE","result":["0x1"],"calls":[],"events":[{"keys":["0x99cd8bde557814842a3121e8ddfd433a539b8c9f14bf31ebf108d12e6196e9"],"data":["0xdac9bcffb3d967f19a7fe21002c98c984d5a9458a88e6fc5d1c478a97ed412","0x5dcd266a80b8a5f29f04d779c6b166b80150c24f2180a75e82427242dab20a9","0x15be","0x0"]}],"messages":[]}],"events":[],"messages":[]}} }`) mockVM.EXPECT().Execute([]core.Transaction{tx}, []core.Class{declaredClass.Class}, header.Number, header.Timestamp, header.SequencerAddress, - gomock.Any(), network, []*felt.Felt{}, false, false, header.GasPrice, false).Return(nil, []json.RawMessage{vmTrace}, nil) + gomock.Any(), network, []*felt.Felt{}, false, false, header.GasPrice, header.GasPriceSTRK, false).Return(nil, []json.RawMessage{vmTrace}, nil) expectedResult := []rpc.TracedBlockTransaction{ { diff --git a/vm/rust/Cargo.toml b/vm/rust/Cargo.toml index c2f3dc1417..97aa90245b 100644 --- a/vm/rust/Cargo.toml +++ b/vm/rust/Cargo.toml @@ -8,11 +8,11 @@ edition = "2021" [dependencies] serde = "1.0.171" serde_json = { version = "1.0.96", features = ["raw_value"] } -blockifier = {git = "https://github.com/starkware-libs/blockifier", rev = "v0.3.0-rc1"} -starknet_api = { git = "https://github.com/starkware-libs/starknet-api", rev = "8f620bc" } +blockifier = "0.4.0-rc8" +starknet_api = "0.6.0-rc2" cairo-vm = "0.8.2" -cairo-lang-casm = "2.1.0" -cairo-lang-starknet = "2.1.0" +cairo-lang-casm = "2.4.0-rc2" +cairo-lang-starknet = "2.4.0-rc2" indexmap = "1.9.2" starknet = { rev = "starknet-core/v0.4.0", git = "https://github.com/xJonathanLEI/starknet-rs" } cached = "0.44.0" diff --git a/vm/rust/src/jsonrpc.rs b/vm/rust/src/jsonrpc.rs index 3c1bd359ea..86b1875ce4 100644 --- a/vm/rust/src/jsonrpc.rs +++ b/vm/rust/src/jsonrpc.rs @@ -1,13 +1,14 @@ use blockifier; -use blockifier::execution::entry_point::{CallType, OrderedL2ToL1Message}; +use blockifier::execution::entry_point::CallType; +use blockifier::execution::call_info::OrderedL2ToL1Message; use blockifier::state::cached_state::TransactionalState; use blockifier::state::errors::StateError; use blockifier::state::state_api::{State, StateReader}; use serde::Serialize; -use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, PatriciaKey}; +use starknet_api::core::{ClassHash, ContractAddress, EntryPointSelector, PatriciaKey, EthAddress}; use starknet_api::deprecated_contract_class::EntryPointType; use starknet_api::hash::StarkFelt; -use starknet_api::transaction::{Calldata, EthAddress, EventContent, L2ToL1Payload}; +use starknet_api::transaction::{Calldata, EventContent, L2ToL1Payload}; use starknet_api::transaction::{DeclareTransaction, Transaction as StarknetApiTransaction}; use crate::juno_state_reader::JunoStateReader; @@ -156,7 +157,7 @@ pub fn new_transaction_trace( match declare_txn { DeclareTransaction::V0(_) => Some(declare_txn.class_hash()), DeclareTransaction::V1(_) => Some(declare_txn.class_hash()), - DeclareTransaction::V2(_) => None, + _ => None, } } else { None @@ -180,7 +181,7 @@ pub struct OrderedEvent { pub event: EventContent, } -type BlockifierOrderedEvent = blockifier::execution::entry_point::OrderedEvent; +use blockifier::execution::call_info::OrderedEvent as BlockifierOrderedEvent; impl From for OrderedEvent { fn from(val: BlockifierOrderedEvent) -> Self { OrderedEvent { @@ -218,7 +219,7 @@ impl FunctionInvocation { } } -type BlockifierCallInfo = blockifier::execution::entry_point::CallInfo; +use blockifier::execution::call_info::CallInfo as BlockifierCallInfo; impl From for FunctionInvocation { fn from(val: BlockifierCallInfo) -> Self { FunctionInvocation { diff --git a/vm/rust/src/lib.rs b/vm/rust/src/lib.rs index b81b380ba4..45a60d44b6 100644 --- a/vm/rust/src/lib.rs +++ b/vm/rust/src/lib.rs @@ -11,16 +11,17 @@ use std::{ use blockifier::{ abi::constants::{INITIAL_GAS_COST, N_STEPS_RESOURCE}, - block_context::BlockContext, + block_context::{BlockContext, GasPrices, FeeTokenAddresses}, execution::{ common_hints::ExecutionMode, contract_class::{ContractClass, ContractClassV1}, entry_point::{CallEntryPoint, CallType, EntryPointExecutionContext, ExecutionResources}, }, fee::fee_utils::calculate_tx_fee, - state::cached_state::CachedState, + state::cached_state::{CachedState, GlobalContractCache}, transaction::{ - objects::AccountTransactionContext, transaction_execution::Transaction, + objects::{AccountTransactionContext, DeprecatedAccountTransactionContext, FeeType, HasRelatedFeeType}, + transaction_execution::Transaction, transactions::ExecutableTransaction, }, }; @@ -33,7 +34,7 @@ use cairo_vm::vm::runners::builtin_runner::{ }; use juno_state_reader::{contract_class_from_json_str, felt_to_byte_array}; use serde::Deserialize; -use starknet_api::transaction::{Calldata, Transaction as StarknetApiTransaction}; +use starknet_api::transaction::{Calldata, Transaction as StarknetApiTransaction, TransactionHash}; use starknet_api::{ block::{BlockNumber, BlockTimestamp}, deprecated_contract_class::EntryPointType, @@ -98,24 +99,29 @@ pub extern "C" fn cairoVMCall( initial_gas: INITIAL_GAS_COST, }; - const GAS_PRICE: u128 = 1; - let mut state = CachedState::new(reader); + const GAS_PRICES: GasPrices = GasPrices { + eth_l1_gas_price: 1, + strk_l1_gas_price: 1, + }; + let mut state = CachedState::new(reader, GlobalContractCache::default()); let mut resources = ExecutionResources::default(); - let mut context = EntryPointExecutionContext::new( - build_block_context( + let context = EntryPointExecutionContext::new( + &build_block_context( chain_id_str, block_number, block_timestamp, StarkFelt::default(), - GAS_PRICE, + GAS_PRICES, ), - AccountTransactionContext::default(), - 4_000_000, + &AccountTransactionContext::Deprecated(DeprecatedAccountTransactionContext::default()), ExecutionMode::Execute, + false, ); - let call_info = entry_point.execute(&mut state, &mut resources, &mut context); - - match call_info { + if let Err(e) = context { + report_error(reader_handle, e.to_string().as_str()); + return; + } + match entry_point.execute(&mut state, &mut resources, &mut context.unwrap()) { Err(e) => report_error(reader_handle, e.to_string().as_str()), Ok(t) => { for data in t.execution.retdata.0 { @@ -130,6 +136,7 @@ pub extern "C" fn cairoVMCall( #[derive(Deserialize)] pub struct TxnAndQueryBit { pub txn: StarknetApiTransaction, + pub txn_hash: TransactionHash, pub query_bit: bool, } @@ -145,7 +152,8 @@ pub extern "C" fn cairoVMExecute( paid_fees_on_l1_json: *const c_char, skip_charge_fee: c_uchar, skip_validate: c_uchar, - gas_price: *const c_uchar, + gas_price_wei: *const c_uchar, + gas_price_strk: *const c_uchar, legacy_json: c_uchar, ) { let reader = JunoStateReader::new(reader_handle, block_number); @@ -183,15 +191,19 @@ pub extern "C" fn cairoVMExecute( let mut classes = classes.unwrap(); let sequencer_address_felt = ptr_to_felt(sequencer_address); - let gas_price_felt = ptr_to_felt(gas_price); + let gas_price_wei_felt = ptr_to_felt(gas_price_wei); + let gas_price_strk_felt = ptr_to_felt(gas_price_strk); let block_context: BlockContext = build_block_context( chain_id_str, block_number, block_timestamp, sequencer_address_felt, - felt_to_u128(gas_price_felt), + GasPrices { + eth_l1_gas_price: felt_to_u128(gas_price_wei_felt), + strk_l1_gas_price: felt_to_u128(gas_price_strk_felt), + }, ); - let mut state = CachedState::new(reader); + let mut state = CachedState::new(reader, GlobalContractCache::default()); let charge_fee = skip_charge_fee == 0; let validate = skip_validate == 0; @@ -234,6 +246,7 @@ pub extern "C" fn cairoVMExecute( let txn = transaction_from_api( txn_and_query_bit.txn.clone(), + txn_and_query_bit.txn_hash, contract_class, paid_fee_on_l1, txn_and_query_bit.query_bit, @@ -244,11 +257,14 @@ pub extern "C" fn cairoVMExecute( } let mut txn_state = CachedState::create_transactional(&mut state); + let mut fee_type = FeeType::Eth; let res = match txn.unwrap() { Transaction::AccountTransaction(t) => { + fee_type = t.fee_type(); t.execute(&mut txn_state, &block_context, charge_fee, validate) } Transaction::L1HandlerTransaction(t) => { + fee_type = t.fee_type(); t.execute(&mut txn_state, &block_context, charge_fee, validate) } }; @@ -259,7 +275,7 @@ pub extern "C" fn cairoVMExecute( reader_handle, format!( "failed txn {:?} reason:{:?}", - txn_and_query_bit.txn.transaction_hash(), + txn_and_query_bit.txn_hash, e ) .as_str(), @@ -269,7 +285,7 @@ pub extern "C" fn cairoVMExecute( Ok(mut t) => { // we are estimating fee, override actual fee calculation if !charge_fee { - t.actual_fee = calculate_tx_fee(&t.actual_resources, &block_context).unwrap(); + t.actual_fee = calculate_tx_fee(&t.actual_resources, &block_context, &fee_type).unwrap(); } let actual_fee = t.actual_fee.0.into(); @@ -311,27 +327,28 @@ fn felt_to_u128(felt: StarkFelt) -> u128 { fn transaction_from_api( tx: StarknetApiTransaction, + tx_hash: TransactionHash, contract_class: Option, paid_fee_on_l1: Option, query_bit: bool, ) -> Result { match tx { - StarknetApiTransaction::Deploy(deploy) => { + StarknetApiTransaction::Deploy(_) => { return Err(format!( "Unsupported deploy transaction in the traced block (transaction_hash={})", - deploy.transaction_hash + tx_hash, )) } - StarknetApiTransaction::Declare(declare) if contract_class.is_none() => { + StarknetApiTransaction::Declare(_) if contract_class.is_none() => { return Err(format!( "Declare transaction must be created with a ContractClass (transaction_hash={})", - declare.transaction_hash() + tx_hash, )) } _ => {} // all ok }; - Transaction::from_api(tx, contract_class, paid_fee_on_l1, query_bit) + Transaction::from_api(tx, tx_hash, contract_class, paid_fee_on_l1, None, query_bit) .map_err(|err| format!("failed to create transaction from api: {:?}", err)) } @@ -363,7 +380,7 @@ fn build_block_context( block_number: c_ulonglong, block_timestamp: c_ulonglong, sequencer_address: StarkFelt, - gas_price: u128, + gas_prices: GasPrices, ) -> BlockContext { BlockContext { chain_id: ChainId(chain_id_str.into()), @@ -372,15 +389,12 @@ fn build_block_context( sequencer_address: ContractAddress::try_from(sequencer_address).unwrap(), // https://github.com/starknet-io/starknet-addresses/blob/df19b17d2c83f11c30e65e2373e8a0c65446f17c/bridged_tokens/mainnet.json - // fee_token_address is the same for all networks - fee_token_address: ContractAddress::try_from( - StarkHash::try_from( - "0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7", - ) - .unwrap(), - ) - .unwrap(), - gas_price, // fixed gas price, so that we can return "consumed gas" to Go side + fee_token_addresses: FeeTokenAddresses { + // both addresses are the same for all networks + eth_fee_token_address: ContractAddress::try_from(StarkHash::try_from("0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7").unwrap()).unwrap(), + strk_fee_token_address: ContractAddress::try_from(StarkHash::try_from("0x04718f5a0fc34cc1af16a1cdee98ffb20c31f5cd61d6ab07201858f4287c938d").unwrap()).unwrap(), + }, + gas_prices, // fixed gas price, so that we can return "consumed gas" to Go side vm_resource_fee_cost: HashMap::from([ (N_STEPS_RESOURCE.to_string(), N_STEPS_FEE_WEIGHT), (OUTPUT_BUILTIN_NAME.to_string(), 0.0), diff --git a/vm/transaction.go b/vm/transaction.go index 6f8014966b..bcd3ac087d 100644 --- a/vm/transaction.go +++ b/vm/transaction.go @@ -22,7 +22,8 @@ func marshalTxn(txn core.Transaction) (json.RawMessage, error) { txnAndQueryBit := struct { QueryBit bool `json:"query_bit"` Txn map[string]any `json:"txn"` - }{Txn: make(map[string]any), QueryBit: version.HasQueryBit()} + TxnHash *felt.Felt `json:"txn_hash"` + }{Txn: make(map[string]any), QueryBit: version.HasQueryBit(), TxnHash: t.Hash} versionWithoutQueryBit := version.WithoutQueryBit() t.Version = versionWithoutQueryBit.AsFelt() @@ -37,7 +38,9 @@ func marshalTxn(txn core.Transaction) (json.RawMessage, error) { "V" + t.Version.Text(felt.Base10): t, } case *core.DeployAccountTransaction: - txnAndQueryBit.Txn["DeployAccount"] = t + txnAndQueryBit.Txn["DeployAccount"] = map[string]any{ + "V" + t.Version.Text(felt.Base10): t, + } case *core.DeclareTransaction: txnAndQueryBit.Txn["Declare"] = map[string]any{ "V" + t.Version.Text(felt.Base10): t, diff --git a/vm/vm.go b/vm/vm.go index f8e10ede25..8c26a4225c 100644 --- a/vm/vm.go +++ b/vm/vm.go @@ -9,7 +9,7 @@ package vm // // extern void cairoVMExecute(char* txns_json, char* classes_json, uintptr_t readerHandle, unsigned long long block_number, // unsigned long long block_timestamp, char* chain_id, char* sequencer_address, char* paid_fees_on_l1_json, -// unsigned char skip_charge_fee, unsigned char skip_validate, char* gas_price, unsigned char legacy_json); +// unsigned char skip_charge_fee, unsigned char skip_validate, char* gas_price_wei, char* gas_price_strk, unsigned char legacy_json); // // #cgo vm_debug LDFLAGS: -L./rust/target/debug -ljuno_starknet_rs -lm -ldl // #cgo !vm_debug LDFLAGS: -L./rust/target/release -ljuno_starknet_rs -lm -ldl @@ -33,7 +33,7 @@ type VM interface { ) ([]*felt.Felt, error) Execute(txns []core.Transaction, declaredClasses []core.Class, blockNumber, blockTimestamp uint64, sequencerAddress *felt.Felt, state core.StateReader, network utils.Network, paidFeesOnL1 []*felt.Felt, - skipChargeFee, skipValidate bool, gasPrice *felt.Felt, legacyTraceJSON bool, + skipChargeFee, skipValidate bool, gasPriceWEI *felt.Felt, gasPriceSTRK *felt.Felt, legacyTraceJSON bool, ) ([]*felt.Felt, []json.RawMessage, error) } @@ -143,7 +143,8 @@ func (v *vm) Call(contractAddr, classHash, selector *felt.Felt, calldata []felt. C.uintptr_t(handle), C.ulonglong(blockNumber), C.ulonglong(blockTimestamp), - chainID) + chainID, + ) for _, ptr := range calldataPtrs { C.free(unsafe.Pointer(ptr)) @@ -159,7 +160,7 @@ func (v *vm) Call(contractAddr, classHash, selector *felt.Felt, calldata []felt. // Execute executes a given transaction set and returns the gas spent per transaction func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, blockNumber, blockTimestamp uint64, sequencerAddress *felt.Felt, state core.StateReader, network utils.Network, paidFeesOnL1 []*felt.Felt, - skipChargeFee, skipValidate bool, gasPrice *felt.Felt, legacyTraceJSON bool, + skipChargeFee, skipValidate bool, gasPriceWEI *felt.Felt, gasPriceSTRK *felt.Felt, legacyTraceJSON bool, ) ([]*felt.Felt, []json.RawMessage, error) { context := &callContext{ state: state, @@ -183,7 +184,12 @@ func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, bloc classesJSONCStr := cstring(classesJSON) sequencerAddressBytes := sequencerAddress.Bytes() - gasPriceBytes := gasPrice.Bytes() + gasPriceWEIBytes := gasPriceWEI.Bytes() + + if gasPriceSTRK == nil { + gasPriceSTRK = &felt.Zero + } + gasPriceSTRKBytes := gasPriceSTRK.Bytes() var skipChargeFeeByte byte if skipChargeFee { @@ -211,7 +217,8 @@ func (v *vm) Execute(txns []core.Transaction, declaredClasses []core.Class, bloc paidFeesOnL1CStr, C.uchar(skipChargeFeeByte), C.uchar(skipValidateByte), - (*C.char)(unsafe.Pointer(&gasPriceBytes[0])), + (*C.char)(unsafe.Pointer(&gasPriceWEIBytes[0])), + (*C.char)(unsafe.Pointer(&gasPriceSTRKBytes[0])), C.uchar(legacyTraceJSONByte), ) diff --git a/vm/vm_test.go b/vm/vm_test.go index fd2a616cb1..2226606598 100644 --- a/vm/vm_test.go +++ b/vm/vm_test.go @@ -158,11 +158,11 @@ func TestExecute(t *testing.T) { address = utils.HexToFelt(t, "0x46a89ae102987331d369645031b49c27738ed096f2789c24449966da4c6de6b") timestamp = uint64(1666877926) ) - _, _, err := New(nil).Execute([]core.Transaction{}, []core.Class{}, 0, timestamp, address, state, network, []*felt.Felt{}, false, false, &felt.Zero, false) + _, _, err := New(nil).Execute([]core.Transaction{}, []core.Class{}, 0, timestamp, address, state, network, []*felt.Felt{}, false, false, &felt.Zero, &felt.Zero, false) require.NoError(t, err) }) t.Run("zero data", func(t *testing.T) { - _, _, err := New(nil).Execute(nil, nil, 0, 0, &felt.Zero, state, network, []*felt.Felt{}, false, false, &felt.Zero, false) + _, _, err := New(nil).Execute(nil, nil, 0, 0, &felt.Zero, state, network, []*felt.Felt{}, false, false, &felt.Zero, &felt.Zero, false) require.NoError(t, err) }) } From b7c7f699b8423e7d64a7ad0dcca8a2db61713123 Mon Sep 17 00:00:00 2001 From: Ninja342 Date: Fri, 24 Nov 2023 15:15:35 +0300 Subject: [PATCH 2/2] Update Roadmap (#1424) --- README.md | 33 +++++++++++++++++++++++++++++++-- 1 file changed, 31 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f388da201a..87799e9272 100644 --- a/README.md +++ b/README.md @@ -198,7 +198,7 @@ After following these steps, Juno should be up and running on your machine, util ## 🛣 Roadmap -### Phase 1 +### Phase 1: Permissionless access to Starknet ✅
@@ -232,7 +232,7 @@ After following these steps, Juno should be up and running on your machine, util
-### Phase 2 +### Phase 2: Full JSON RPC Support ✅
@@ -262,6 +262,35 @@ The focus of Phase 2 will be to Verify the state from layer 1 and implement the
+### Phase 3: Starknet decentralization begins 🚧 + +
+ + +Juno can synchronize Starknet state from other full nodes with the aim of decentralizing Starknet by removing the dependency from the centralized sequencer. + + +Snap sync is implemented, significantly reducing sync times. + +
+ +### Phase 4: Juno becomes a Starknet Sequencer 🔜 + +
+ + +The decentralization of Starknet is complete! Juno becomes a sequencer and participates in L2 consensus to secure the network. Juno has multiple modes of operation: +‍ + +• Light client: provides fast permissionless access to Starknet with minimal verification. + +• Full Node: complete verification of Starknet state along with transaction execution. + +• Sequencer: secure the network by taking part in the L2 consensus mechanism. + +
+ + ## 👍 Contribute We welcome PRs from external contributors and would love to help you get up to speed.