Skip to content

Commit

Permalink
feat: update docker and genesis (#779)
Browse files Browse the repository at this point in the history
* update the rpc docker and fix some genesis issues

* add automatic deployment of an eoa with hive feature
  • Loading branch information
greged93 authored Feb 21, 2024
1 parent d24903a commit 606aefa
Show file tree
Hide file tree
Showing 14 changed files with 148 additions and 24 deletions.
6 changes: 3 additions & 3 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
version: 0.1
cli:
version: 1.19.0
version: 1.20.1
plugins:
sources:
- id: trunk
ref: v1.4.2
ref: v1.4.3
uri: https://github.com/trunk-io/plugins
runtimes:
enabled:
Expand All @@ -32,7 +32,7 @@ lint:
- [email protected]
- [email protected]
- [email protected]
- yamllint@1.34.0
- yamllint@1.35.1
ignore:
- linters: [ALL]
paths:
Expand Down
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@
"**/.git": false
},
"rust-analyzer.check.command": "clippy",
"rust-analyzer.cargo.features": ["testing"]
"rust-analyzer.cargo.features": ["testing", "hive"]
}
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ toml = { version = "0.7.5", default-features = false }

[features]
testing = ["testcontainers", "rayon", "sequencer", "ef-testing"]
hive = []

[[bin]]
name = "katana_genesis"
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ benchmark-madara:
cd benchmarks && bun i && bun run benchmark-madara

test-target: load-env
cargo test --tests --features testing $(TARGET) -- --nocapture
cargo test --tests --features "testing,hive" $(TARGET) -- --nocapture

benchmark-katana:
cd benchmarks && bun i && bun run benchmark-katana
Expand Down
9 changes: 7 additions & 2 deletions docker/rpc/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ COPY scripts scripts
RUN make setup

# Define ARG for build platform
FROM --platform=$BUILDPLATFORM rust:1.64 as builder
FROM --platform=$BUILDPLATFORM rust:1.75 as builder

# Set ARG for build and target platform
ARG BUILDPLATFORM
Expand Down Expand Up @@ -65,8 +65,13 @@ RUN build_platform() { \
--target=$ARCH; \
# Copy the built binary to a common release directory
cp /usr/src/rpc/target/$ARCH/release/kakarot-rpc /usr/src/rpc/target/release/; \
# Build the Rust application for the specified target for hive
BINDGEN_EXTRA_CLANG_ARGS=$BINDGEN_EXTRA_CLANG_ARGS cargo build --all --release \
--features hive --target=$ARCH; \
# Copy the built binary to a common release directory
cp /usr/src/rpc/target/$ARCH/release/kakarot-rpc /usr/src/rpc/target/release/kakarot-rpc-hive; \
# Build the hive genesis binary
BINDGEN_EXTRA_CLANG_ARGS=$BINDGEN_EXTRA_CLANG_ARGS cargo build --release \
BINDGEN_EXTRA_CLANG_ARGS=$BINDGEN_EXTRA_CLANG_ARGS cargo build --all --release \
--bin hive_genesis --features testing --target=$ARCH; \
# Copy the genesis binary to a common release directory
cp /usr/src/rpc/target/$ARCH/release/hive_genesis /usr/src/rpc/target/release/; \
Expand Down
27 changes: 25 additions & 2 deletions src/bin/hive_genesis.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
use dotenv::dotenv;
use kakarot_rpc::test_utils::{hive::HiveGenesisConfig, katana::genesis::KatanaGenesisBuilder};
use katana_primitives::genesis::{
allocation::DevAllocationsGenerator, constant::DEFAULT_PREFUNDED_ACCOUNT_BALANCE, json::GenesisAccountJson,
};
use starknet_crypto::FieldElement;
use std::{env::var, path::Path};

Expand All @@ -21,15 +24,35 @@ fn main() {
serde_json::from_str(&hive_genesis_content).expect("Failed to parse hive genesis json");

// Convert the hive genesis to a katana genesis.
let genesis =
let mut genesis_json =
hive_genesis.try_into_genesis_json(builder.clone()).expect("Failed to convert hive genesis to katana genesis");

// Add dev allocations.
let dev_allocations = DevAllocationsGenerator::new(10)
.with_balance(DEFAULT_PREFUNDED_ACCOUNT_BALANCE)
.generate()
.into_iter()
.map(|(address, account)| {
(
address,
GenesisAccountJson {
public_key: account.public_key,
balance: Some(account.balance),
nonce: account.nonce,
class: None,
storage: account.storage.clone(),
},
)
})
.collect::<Vec<_>>();
genesis_json.accounts.extend(dev_allocations);

let builder = builder.with_kakarot(FieldElement::ZERO).expect("Failed to set up Kakarot");
let manifest = builder.manifest();

// Write the genesis json to the file.
let genesis_path = Path::new(&var("GENESIS_OUTPUT").expect("Failed to load GENESIS_OUTPUT var")).to_path_buf();
std::fs::write(genesis_path, serde_json::to_string(&genesis).expect("Failed to serialize genesis json"))
std::fs::write(genesis_path, serde_json::to_string(&genesis_json).expect("Failed to serialize genesis json"))
.expect("Failed to write genesis json");

// Write the manifest to the file.
Expand Down
2 changes: 1 addition & 1 deletion src/bin/katana_genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ fn main() {
.load_classes(KAKAROT_CONTRACTS_PATH.clone())
.with_kakarot(*COINBASE_ADDRESS)
.expect("Failed to set up Kakarot");
builder = builder.with_eoa(pk, None).expect("Failed to set up EOA").fund(pk, U256::from(u128::MAX)).unwrap();
builder = builder.with_eoa(pk).expect("Failed to set up EOA").fund(pk, U256::from(u128::MAX)).unwrap();

let manifest = builder.manifest();

Expand Down
32 changes: 32 additions & 0 deletions src/eth_provider/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,35 @@ use lazy_static::lazy_static;
lazy_static! {
pub static ref MAX_PRIORITY_FEE_PER_GAS: u64 = 0;
}

#[cfg(feature = "hive")]
use {
crate::config::KakarotRpcConfig,
starknet::{
accounts::{ExecutionEncoding, SingleOwnerAccount},
providers::{jsonrpc::HttpTransport, JsonRpcClient},
signers::{LocalWallet, SigningKey},
},
starknet_crypto::FieldElement,
std::{env::var, str::FromStr, sync::OnceLock},
};

#[cfg(feature = "hive")]
pub static CHAIN_ID: OnceLock<FieldElement> = OnceLock::new();

#[cfg(feature = "hive")]
lazy_static! {
static ref RPC_CONFIG: KakarotRpcConfig = KakarotRpcConfig::from_env().expect("Failed to load Kakarot RPC config");
pub static ref DEPLOY_WALLET: SingleOwnerAccount<JsonRpcClient<HttpTransport>, LocalWallet> =
SingleOwnerAccount::new(
JsonRpcClient::new(HttpTransport::new(RPC_CONFIG.network.provider_url().expect("Incorrect provider URL"))),
LocalWallet::from_signing_key(SigningKey::from_secret_scalar(
FieldElement::from_str(&var("KATANA_PRIVATE_KEY").expect("Missing deployer private key"))
.expect("Failed to parse deployer private key")
)),
FieldElement::from_str(&var("KATANA_ACCOUNT_ADDRESS").expect("Missing deployer address"))
.expect("Failed to parse deployer address"),
*CHAIN_ID.get().expect("Missing chain ID"),
ExecutionEncoding::New
);
}
3 changes: 3 additions & 0 deletions src/eth_provider/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ pub enum EthProviderError {
/// Method not supported.
#[error("Method not supported: {0}")]
MethodNotSupported(String),
/// Other error.
#[error(transparent)]
Other(#[from] eyre::Error),
}

impl From<EthProviderError> for ErrorObject<'static> {
Expand Down
41 changes: 41 additions & 0 deletions src/eth_provider/provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,47 @@ where
.ok_or_else(|| ConversionError::ToStarknetTransactionError("Failed to recover signer".to_string()))?;
let transaction = to_starknet_transaction(&transaction_signed, chain_id, signer)?;

// If the contract is not found, we need to deploy it.
#[cfg(feature = "hive")]
{
use crate::eth_provider::constant::{CHAIN_ID, DEPLOY_WALLET};
use starknet::accounts::Account;
use starknet::accounts::Call;
use starknet::accounts::Execution;
use starknet::core::types::BlockTag;
use starknet::core::utils::get_selector_from_name;
let sender = transaction.sender_address;
let proxy = ProxyReader::new(sender, &self.starknet_provider);
let maybe_class_hash =
proxy.get_implementation().block_id(StarknetBlockId::Tag(BlockTag::Latest)).call().await;

if contract_not_found(&maybe_class_hash) {
let chain_id = self.starknet_provider.chain_id().await?;
let _ = CHAIN_ID.set(chain_id);
let execution = Execution::new(
vec![Call {
to: *KAKAROT_ADDRESS,
selector: get_selector_from_name("deploy_externally_owned_account").unwrap(),
calldata: vec![into_via_wrapper!(signer)],
}],
&*DEPLOY_WALLET,
);
let nonce = self
.starknet_provider
.get_nonce(StarknetBlockId::Tag(BlockTag::Latest), DEPLOY_WALLET.address())
.await?;
let tx = execution
.nonce(nonce)
.max_fee(FieldElement::from(u64::MAX))
.prepared()
.map_err(|err| eyre::eyre!(err.to_string()))?
.get_invoke_request(false)
.await
.map_err(|err| eyre::eyre!(err.to_string()))?;
self.starknet_provider.add_invoke_transaction(tx).await?;
};
}

#[cfg(not(feature = "testing"))]
{
let hash = transaction_signed.hash();
Expand Down
1 change: 0 additions & 1 deletion src/test_utils/eoa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ impl<P: Provider + Send + Sync> KakarotEOA<P> {
///
/// allow(dead_code) is used because this function is used in tests,
/// and each test is compiled separately, so the compiler thinks this function is unused
#[allow(dead_code)]
pub async fn transfer(&self, to: Address, value: u128) -> Result<B256, eyre::Error> {
let nonce = self.nonce().await?;
let nonce: u64 = nonce.try_into()?;
Expand Down
8 changes: 8 additions & 0 deletions src/test_utils/hive/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ impl HiveGenesisConfig {

// Fetch the contracts from the alloc field.
let mut additional_kakarot_storage = HashMap::new();
let mut fee_token_storage = HashMap::new();
let contracts = self
.alloc
.into_iter()
Expand Down Expand Up @@ -97,6 +98,10 @@ impl HiveGenesisConfig {
};
kakarot_account_storage.push((get_storage_var_address("kakarot_address", &[])?, kakarot_address));

let key = get_storage_var_address("ERC20_allowances", &[starknet_address, kakarot_address])?;
fee_token_storage.insert(key, FieldElement::from(u128::MAX));
fee_token_storage.insert(key + 1u8.into(), FieldElement::from(u128::MAX));

Ok((
ContractAddress::new(starknet_address),
GenesisContractJson {
Expand All @@ -112,10 +117,13 @@ impl HiveGenesisConfig {
// Build the builder
let kakarot_address = ContractAddress::new(kakarot_address);
let mut genesis = builder.build()?;

let kakarot_contract =
genesis.contracts.get_mut(&kakarot_address).ok_or(eyre!("Kakarot contract not found"))?;
kakarot_contract.storage.get_or_insert_with(HashMap::new).extend(additional_kakarot_storage);

genesis.fee_token.storage.get_or_insert_with(HashMap::new).extend(fee_token_storage);

// Add the contracts to the genesis.
genesis.contracts.extend(contracts);

Expand Down
16 changes: 3 additions & 13 deletions src/test_utils/katana/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use katana_primitives::{
};
use lazy_static::lazy_static;
use rayon::prelude::*;
use reth_primitives::{Address, B256};
use reth_primitives::B256;
use serde::Serialize;
use serde_json::Value;
use serde_with::serde_as;
Expand Down Expand Up @@ -205,18 +205,8 @@ impl KatanaGenesisBuilder<Loaded> {

impl KatanaGenesisBuilder<Initialized> {
/// Add an EOA to the genesis. The EOA is deployed to the address derived from the given private key.
pub fn with_eoa(
mut self,
private_key: impl Into<Option<B256>>,
evm_address: impl Into<Option<Address>>,
) -> Result<Self> {
let private_key: Option<B256> = private_key.into();
let evm_address: Option<Address> = evm_address.into();

let evm_address = evm_address
.and_then(|addr| FieldElement::from_byte_slice_be(addr.as_slice()).ok())
.or(private_key.and_then(|pk| self.evm_address(pk).ok()));
let evm_address = evm_address.ok_or(eyre!("Failed to derive EVM address"))?;
pub fn with_eoa(mut self, private_key: B256) -> Result<Self> {
let evm_address = self.evm_address(private_key)?;

let kakarot_address = self.cache_load("kakarot_address")?;
let eoa_class_hash = self.eoa_class_hash()?;
Expand Down
22 changes: 22 additions & 0 deletions tests/eth_provider.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,3 +258,25 @@ async fn test_fee_history(#[future] katana: Katana, _setup: ()) {
assert_eq!(fee_history.gas_used_ratio.len(), actual_block_count);
assert_eq!(fee_history.oldest_block, U256::ZERO);
}

#[rstest]
#[awt]
#[tokio::test(flavor = "multi_thread")]
#[cfg(feature = "hive")]
async fn test_predeploy_eoa(#[future] katana: Katana, _setup: ()) {
use kakarot_rpc::test_utils::eoa::KakarotEOA;
use reth_primitives::B256;
// Given
let eoa = katana.eoa();
let eth_provider = katana.eth_provider();
let other_eoa = KakarotEOA::new(B256::from_str(&format!("0x{:0>64}", "0abde1")).unwrap(), eth_provider.clone());

// When
let balance_before = eth_provider.balance(eoa.evm_address().unwrap(), None).await.unwrap();
eoa.transfer(other_eoa.evm_address().unwrap(), 1).await.expect("Failed to transfer funds to other eoa");
other_eoa.transfer(eoa.evm_address().unwrap(), 1).await.expect("Failed to transfer funds back to eoa");
let balance_after = eth_provider.balance(eoa.evm_address().unwrap(), None).await.unwrap();

// Then
assert_eq!(balance_after, balance_before);
}

0 comments on commit 606aefa

Please sign in to comment.