Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix L2 reorg related issues #203

Merged
merged 3 commits into from
Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/pathfinder/src/cairo/ext_py.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ mod tests {
crate::storage::ContractCodeTable::insert(tx, hash, &abi, &bytecode, &contract_definition)
.unwrap();

crate::storage::ContractsTable::insert(tx, crate::core::ContractAddress(address), hash)
crate::storage::ContractsTable::upsert(tx, crate::core::ContractAddress(address), hash)
.unwrap();

// this will create the table, not created by migration
Expand Down
27 changes: 6 additions & 21 deletions crates/pathfinder/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -362,8 +362,8 @@ mod tests {
ContractCodeTable::insert_compressed(&db_txn, &contract0_code).unwrap();
ContractCodeTable::insert_compressed(&db_txn, &contract1_code).unwrap();

ContractsTable::insert(&db_txn, contract0_addr, contract0_hash).unwrap();
ContractsTable::insert(&db_txn, contract1_addr, contract1_hash).unwrap();
ContractsTable::upsert(&db_txn, contract0_addr, contract0_hash).unwrap();
ContractsTable::upsert(&db_txn, contract1_addr, contract1_hash).unwrap();

let mut global_tree = GlobalStateTree::load(&db_txn, GlobalRoot(StarkHash::ZERO)).unwrap();
let contract_state_hash =
Expand Down Expand Up @@ -479,24 +479,9 @@ mod tests {
let transaction_data0 = [(txn0, receipt0)];
let transaction_data1 = [(txn1, receipt1), (txn2, receipt2)];
let transaction_data2 = [(txn3, receipt3), (txn4, receipt4), (txn5, receipt5)];
StarknetTransactionsTable::insert_block_transactions(
&db_txn,
genesis_hash,
&transaction_data0,
)
.unwrap();
StarknetTransactionsTable::insert_block_transactions(
&db_txn,
block1_hash,
&transaction_data1,
)
.unwrap();
StarknetTransactionsTable::insert_block_transactions(
&db_txn,
latest_hash,
&transaction_data2,
)
.unwrap();
StarknetTransactionsTable::upsert(&db_txn, genesis_hash, &transaction_data0).unwrap();
StarknetTransactionsTable::upsert(&db_txn, block1_hash, &transaction_data1).unwrap();
StarknetTransactionsTable::upsert(&db_txn, latest_hash, &transaction_data2).unwrap();

db_txn.commit().unwrap();
storage
Expand Down Expand Up @@ -1575,7 +1560,7 @@ mod tests {
.context("Deploy testing contract")
.unwrap();

crate::storage::ContractsTable::insert(
crate::storage::ContractsTable::upsert(
&tx,
crate::core::ContractAddress(address),
hash,
Expand Down
2 changes: 1 addition & 1 deletion crates/pathfinder/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ pub(crate) fn update_contract_state(
.context("Contract hash is missing from contracts table")?;
let contract_state_hash = calculate_contract_state_hash(contract_hash, new_contract_root);

ContractsStateTable::insert(db, contract_state_hash, contract_hash, new_contract_root)
ContractsStateTable::upsert(db, contract_state_hash, contract_hash, new_contract_root)
.context("Insert constract state hash into contracts state table")?;

Ok(contract_state_hash)
Expand Down
12 changes: 4 additions & 8 deletions crates/pathfinder/src/state/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,12 +455,8 @@ async fn l2_update(
.into_iter()
.zip(block.transaction_receipts.into_iter())
.collect::<Vec<_>>();
StarknetTransactionsTable::insert_block_transactions(
&transaction,
starknet_block.hash,
&transaction_data,
)
.context("Insert transaction data into database")?;
StarknetTransactionsTable::upsert(&transaction, starknet_block.hash, &transaction_data)
.context("Insert transaction data into database")?;

// Track combined L1 and L2 state.
let l1_l2_head = RefsTable::get_l1_l2_head(&transaction).context("Query L1-L2 head")?;
Expand Down Expand Up @@ -554,8 +550,8 @@ fn deploy_contract(
global_tree
.set(contract.address, state_hash)
.context("Adding deployed contract to global state tree")?;
ContractsStateTable::insert(transaction, state_hash, contract.hash, contract_root)
ContractsStateTable::upsert(transaction, state_hash, contract.hash, contract_root)
.context("Insert constract state hash into contracts state table")?;
ContractsTable::insert(transaction, contract.address, contract.hash)
ContractsTable::upsert(transaction, contract.address, contract.hash)
.context("Inserting contract hash into contracts table")
}
2 changes: 1 addition & 1 deletion crates/pathfinder/src/state/sync/l2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ async fn reorg(
};

let reorg_tail = new_head
.map(|x| x.0)
.map(|x| x.0 + 1)
.unwrap_or(StarknetBlockNumber::GENESIS);

tx_event
Expand Down
12 changes: 6 additions & 6 deletions crates/pathfinder/src/storage/contract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,17 +135,17 @@ impl ContractCodeTable {
pub struct ContractsTable {}

impl ContractsTable {
/// Insert a contract into the table, does nothing if the contract already exists.
/// Insert a contract into the table, overwrites the data if it already exists.
///
/// Note that [hash](ContractHash) must reference a contract stored in [ContractCodeTable].
pub fn insert(
pub fn upsert(
transaction: &Transaction,
address: ContractAddress,
hash: ContractHash,
) -> anyhow::Result<()> {
// A contract may be deployed multiple times due to L2 reorgs, so we ignore all after the first.
transaction.execute(
r"INSERT OR IGNORE INTO contracts (address, hash) VALUES (:address, :hash)",
r"INSERT OR REPLACE INTO contracts (address, hash) VALUES (:address, :hash)",
named_params! {
":address": &address.0.to_be_bytes()[..],
":hash": &hash.0.to_be_bytes()[..],
Expand Down Expand Up @@ -201,7 +201,7 @@ mod tests {
let address = ContractAddress(StarkHash::from_hex_str("abc").unwrap());
let hash = ContractHash(StarkHash::from_hex_str("123").unwrap());

ContractsTable::insert(&transaction, address, hash).unwrap_err();
ContractsTable::upsert(&transaction, address, hash).unwrap_err();
}

#[test]
Expand All @@ -215,7 +215,7 @@ mod tests {
let definition = vec![9, 13, 25];

ContractCodeTable::insert(&transaction, hash, &[][..], &[][..], &definition[..]).unwrap();
ContractsTable::insert(&transaction, address, hash).unwrap();
ContractsTable::upsert(&transaction, address, hash).unwrap();

let result = ContractsTable::get_hash(&transaction, address).unwrap();

Expand All @@ -241,7 +241,7 @@ mod tests {

ContractCodeTable::insert(&transaction, hash, &abi[..], &code[..], &definition[..])
.unwrap();
ContractsTable::insert(&transaction, address, hash).unwrap();
ContractsTable::upsert(&transaction, address, hash).unwrap();

let result = ContractCodeTable::get_code(&transaction, address).unwrap();

Expand Down
14 changes: 5 additions & 9 deletions crates/pathfinder/src/storage/ethereum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,14 @@ pub struct EthereumBlocksTable {}
impl EthereumBlocksTable {
/// Inserts a new Ethereum block with the given [hash](EthereumBlockHash) and [number](EthereumBlockNumber).
///
/// Does nothing if the hash already exists.
/// overwrites the data if the hash already exists.
pub fn insert(
transaction: &Transaction,
hash: EthereumBlockHash,
number: EthereumBlockNumber,
) -> anyhow::Result<()> {
transaction.execute(
r"INSERT INTO ethereum_blocks ( hash, number)
VALUES (:hash, :number)
ON CONFLICT DO NOTHING",
"INSERT OR REPLACE INTO ethereum_blocks (hash, number) VALUES (:hash, :number)",
named_params! {
":hash": hash.0.as_bytes(),
":number": number.0,
Expand All @@ -46,20 +44,18 @@ pub struct EthereumTransactionsTable {}
impl EthereumTransactionsTable {
/// Insert a new Ethereum transaction.
///
/// Does nothing if the ethereum hash already exists.
/// Overwrites the data if the ethereum hash already exists.
///
/// Note that [block_hash](EthereumBlockHash) must reference an
/// Ethereum block stored in [EthereumBlocksTable].
pub fn insert(
pub fn upsert(
transaction: &Transaction,
block_hash: EthereumBlockHash,
tx_hash: EthereumTransactionHash,
tx_index: EthereumTransactionIndex,
) -> anyhow::Result<()> {
transaction.execute(
r"INSERT INTO ethereum_transactions ( hash, idx, block_hash)
VALUES (:hash, :idx, :block_hash)
ON CONFLICT DO NOTHING",
"INSERT OR REPLACE INTO ethereum_transactions (hash, idx, block_hash) VALUES (:hash, :idx, :block_hash)",
named_params! {
":hash": tx_hash.0.as_bytes(),
":idx": tx_index.0,
Expand Down
17 changes: 8 additions & 9 deletions crates/pathfinder/src/storage/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,9 @@ impl From<StarknetBlockHash> for StarknetBlocksBlockId {
pub struct StarknetTransactionsTable {}
impl StarknetTransactionsTable {
/// Inserts a Starknet block's transactions and transaction receipts into the [StarknetTransactionsTable].
pub fn insert_block_transactions(
///
/// overwrites existing data if the transaction hash already exists.
pub fn upsert(
connection: &Connection,
block: StarknetBlockHash,
transaction_data: &[(transaction::Transaction, transaction::Receipt)],
Expand All @@ -427,8 +429,7 @@ impl StarknetTransactionsTable {
.compress(&receipt)
.context("Compress Starknet transaction receipt")?;

connection.execute(r"INSERT INTO starknet_transactions ( hash, idx, block_hash, tx, receipt)
VALUES (:hash, :idx, :block_hash, :tx, :receipt)",
connection.execute(r"INSERT OR REPLACE INTO starknet_transactions (hash, idx, block_hash, tx, receipt) VALUES (:hash, :idx, :block_hash, :tx, :receipt)",
named_params![
":hash": &transaction.transaction_hash.0.as_be_bytes()[..],
":idx": i,
Expand Down Expand Up @@ -667,17 +668,15 @@ pub struct StarknetBlock {
pub struct ContractsStateTable {}

impl ContractsStateTable {
/// Insert a state hash into the table. Does nothing if the state hash already exists.
pub fn insert(
/// Insert a state hash into the table, overwrites the data if the hash already exists.
pub fn upsert(
transaction: &Transaction,
state_hash: ContractStateHash,
hash: ContractHash,
root: ContractRoot,
) -> anyhow::Result<()> {
transaction.execute(
r"INSERT INTO contract_states ( state_hash, hash, root)
VALUES (:state_hash, :hash, :root)
ON CONFLICT DO NOTHING",
"INSERT OR IGNORE INTO contract_states (state_hash, hash, root) VALUES (:state_hash, :hash, :root)",
named_params! {
":state_hash": &state_hash.0.to_be_bytes()[..],
":hash": &hash.0.to_be_bytes()[..],
Expand Down Expand Up @@ -738,7 +737,7 @@ mod tests {
let hash = ContractHash(StarkHash::from_hex_str("123").unwrap());
let root = ContractRoot(StarkHash::from_hex_str("def").unwrap());

ContractsStateTable::insert(&transaction, state_hash, hash, root).unwrap();
ContractsStateTable::upsert(&transaction, state_hash, hash, root).unwrap();

let result = ContractsStateTable::get_root(&transaction, state_hash).unwrap();

Expand Down