Skip to content

Commit

Permalink
Refactors tx hash removal out of finalize_block
Browse files Browse the repository at this point in the history
  • Loading branch information
grarco committed Sep 22, 2023
1 parent 037fbf7 commit bbead89
Show file tree
Hide file tree
Showing 5 changed files with 171 additions and 206 deletions.
332 changes: 137 additions & 195 deletions apps/src/lib/node/ledger/shell/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -282,178 +282,167 @@ where
continue;
}

let (
mut tx_event,
decrypted_tx_hash,
mut tx_gas_meter,
has_valid_pow,
wrapper,
) = match &tx_header.tx_type {
TxType::Wrapper(wrapper) => {
stats.increment_wrapper_txs();
let tx_event = Event::new_tx_event(&tx, height.0);
#[cfg(not(feature = "mainnet"))]
let has_valid_pow =
self.invalidate_pow_solution_if_valid(wrapper);

let gas_meter = TxGasMeter::new(wrapper.gas_limit);

(
tx_event,
None,
gas_meter,
let (mut tx_event, mut tx_gas_meter, has_valid_pow, wrapper) =
match &tx_header.tx_type {
TxType::Wrapper(wrapper) => {
stats.increment_wrapper_txs();
let tx_event = Event::new_tx_event(&tx, height.0);
#[cfg(not(feature = "mainnet"))]
has_valid_pow,
Some(tx.clone()),
)
}
TxType::Decrypted(inner) => {
// We remove the corresponding wrapper tx from the queue
let mut tx_in_queue = self
.wl_storage
.storage
.tx_queue
.pop()
.expect("Missing wrapper tx in queue");
let mut event = Event::new_tx_event(&tx, height.0);

match inner {
DecryptedTx::Decrypted { has_valid_pow: _ } => {
if let Some(code_sec) = tx
.get_section(tx.code_sechash())
.and_then(|x| Section::code_sec(x.as_ref()))
{
stats.increment_tx_type(
code_sec.code.hash().to_string(),
);
let has_valid_pow =
self.invalidate_pow_solution_if_valid(wrapper);

let gas_meter = TxGasMeter::new(wrapper.gas_limit);

(
tx_event,
gas_meter,
#[cfg(not(feature = "mainnet"))]
has_valid_pow,
Some(tx.clone()),
)
}
TxType::Decrypted(inner) => {
// We remove the corresponding wrapper tx from the queue
let mut tx_in_queue = self
.wl_storage
.storage
.tx_queue
.pop()
.expect("Missing wrapper tx in queue");
let mut event = Event::new_tx_event(&tx, height.0);

match inner {
DecryptedTx::Decrypted { has_valid_pow: _ } => {
if let Some(code_sec) = tx
.get_section(tx.code_sechash())
.and_then(|x| Section::code_sec(x.as_ref()))
{
stats.increment_tx_type(
code_sec.code.hash().to_string(),
);
}
}
}
DecryptedTx::Undecryptable => {
tracing::info!(
"Tx with hash {} was un-decryptable",
tx_in_queue.tx.header_hash()
);
// Remove inner tx hash from storage
let inner_tx_hash =
DecryptedTx::Undecryptable => {
tracing::info!(
"Tx with hash {} was un-decryptable",
tx_in_queue.tx.header_hash()
);
// Remove inner tx hash from storage
let inner_tx_hash =
replay_protection::get_replay_protection_key(
&tx_in_queue
.tx
.update_header(TxType::Raw)
.header_hash(),
);
self.wl_storage.delete(&inner_tx_hash).expect(
"Error while deleting tx hash from storage",
);
event["info"] = "Transaction is invalid.".into();
event["log"] =
"Transaction could not be decrypted.".into();
event["code"] = ErrorCodes::Undecryptable.into();
continue;
self.wl_storage.delete(&inner_tx_hash).expect(
"Error while deleting tx hash from storage",
);
event["info"] =
"Transaction is invalid.".into();
event["log"] = "Transaction could not be \
decrypted."
.into();
event["code"] =
ErrorCodes::Undecryptable.into();
continue;
}
}
}

(
event,
Some(
tx_in_queue
.tx
.update_header(TxType::Raw)
.header_hash(),
(
event,
TxGasMeter::new_from_sub_limit(tx_in_queue.gas),
#[cfg(not(feature = "mainnet"))]
false,
None,
)
}
TxType::Raw => {
tracing::error!(
"Internal logic error: FinalizeBlock received a \
TxType::Raw transaction"
);
continue;
}
TxType::Protocol(protocol_tx) => match protocol_tx.tx {
ProtocolTxType::BridgePoolVext
| ProtocolTxType::BridgePool
| ProtocolTxType::ValSetUpdateVext
| ProtocolTxType::ValidatorSetUpdate => (
Event::new_tx_event(&tx, height.0),
TxGasMeter::new_from_sub_limit(0.into()),
#[cfg(not(feature = "mainnet"))]
false,
None,
),
TxGasMeter::new_from_sub_limit(tx_in_queue.gas),
#[cfg(not(feature = "mainnet"))]
false,
None,
)
}
TxType::Raw => {
tracing::error!(
"Internal logic error: FinalizeBlock received a \
TxType::Raw transaction"
);
continue;
}
TxType::Protocol(protocol_tx) => match protocol_tx.tx {
ProtocolTxType::BridgePoolVext
| ProtocolTxType::BridgePool
| ProtocolTxType::ValSetUpdateVext
| ProtocolTxType::ValidatorSetUpdate => (
Event::new_tx_event(&tx, height.0),
None,
TxGasMeter::new_from_sub_limit(0.into()),
#[cfg(not(feature = "mainnet"))]
false,
None,
),
ProtocolTxType::EthEventsVext => {
let ext =
ProtocolTxType::EthEventsVext => {
let ext =
ethereum_tx_data_variants::EthEventsVext::try_from(
&tx,
)
.unwrap();
if self
.mode
.get_validator_address()
.map(|validator| {
validator == &ext.data.validator_addr
})
.unwrap_or(false)
{
for event in ext.data.ethereum_events.iter() {
self.mode.dequeue_eth_event(event);
if self
.mode
.get_validator_address()
.map(|validator| {
validator == &ext.data.validator_addr
})
.unwrap_or(false)
{
for event in ext.data.ethereum_events.iter() {
self.mode.dequeue_eth_event(event);
}
}
(
Event::new_tx_event(&tx, height.0),
TxGasMeter::new_from_sub_limit(0.into()),
#[cfg(not(feature = "mainnet"))]
false,
None,
)
}
(
Event::new_tx_event(&tx, height.0),
None,
TxGasMeter::new_from_sub_limit(0.into()),
#[cfg(not(feature = "mainnet"))]
false,
None,
)
}
ProtocolTxType::EthereumEvents => {
let digest =
ProtocolTxType::EthereumEvents => {
let digest =
ethereum_tx_data_variants::EthereumEvents::try_from(
&tx,
).unwrap();
if let Some(address) =
self.mode.get_validator_address().cloned()
{
let this_signer = &(
address,
self.wl_storage.storage.get_last_block_height(),
);
for MultiSignedEthEvent { event, signers } in
&digest.events
if let Some(address) =
self.mode.get_validator_address().cloned()
{
if signers.contains(this_signer) {
self.mode.dequeue_eth_event(event);
let this_signer = &(
address,
self.wl_storage
.storage
.get_last_block_height(),
);
for MultiSignedEthEvent { event, signers } in
&digest.events
{
if signers.contains(this_signer) {
self.mode.dequeue_eth_event(event);
}
}
}
(
Event::new_tx_event(&tx, height.0),
TxGasMeter::new_from_sub_limit(0.into()),
#[cfg(not(feature = "mainnet"))]
false,
None,
)
}
(
Event::new_tx_event(&tx, height.0),
None,
TxGasMeter::new_from_sub_limit(0.into()),
#[cfg(not(feature = "mainnet"))]
false,
None,
)
}
ref protocol_tx_type => {
tracing::error!(
?protocol_tx_type,
"Internal logic error: FinalizeBlock received an \
unsupported TxType::Protocol transaction: {:?}",
protocol_tx
);
continue;
}
},
};

let mut invalid_sig_sentinel = false;
ref protocol_tx_type => {
tracing::error!(
?protocol_tx_type,
"Internal logic error: FinalizeBlock received \
an unsupported TxType::Protocol transaction: \
{:?}",
protocol_tx
);
continue;
}
},
};

match protocol::dispatch_tx(
tx,
Expand All @@ -464,7 +453,6 @@ where
.expect("transaction index out of bounds"),
),
&mut tx_gas_meter,
&mut invalid_sig_sentinel,
&mut self.wl_storage,
&mut self.vp_wasm_cache,
&mut self.tx_wasm_cache,
Expand Down Expand Up @@ -536,21 +524,6 @@ where
result.vps_result.rejected_vps
);

if let Some(hash) = decrypted_tx_hash {
if invalid_sig_sentinel {
// Invalid signature was found, remove the tx
// hash from storage to allow replay
let tx_hash_key =
replay_protection::get_replay_protection_key(
&hash,
);
self.wl_storage.delete(&tx_hash_key).expect(
"Error while deleting tx hash key from \
storage",
);
}
}

stats.increment_rejected_txs();
self.wl_storage.drop_tx();
tx_event["code"] = ErrorCodes::InvalidTx.into();
Expand All @@ -565,37 +538,6 @@ where
msg
);

if let Some(hash) = decrypted_tx_hash {
if invalid_sig_sentinel {
// Invalid signature was found, remove the tx
// hash from storage to allow replay
let tx_hash_key =
replay_protection::get_replay_protection_key(
&hash,
);
self.wl_storage.delete(&tx_hash_key).expect(
"Error while deleting tx hash key from storage",
);
}
}

// If transaction type is Decrypted and failed because of
// out of gas, remove its hash from storage to allow
// rewrapping it
if let Some(hash) = decrypted_tx_hash {
if let Error::TxApply(protocol::Error::GasError(_)) =
msg
{
let tx_hash_key =
replay_protection::get_replay_protection_key(
&hash,
);
self.wl_storage.delete(&tx_hash_key).expect(
"Error while deleting tx hash key from storage",
);
}
}

stats.increment_errored_txs();
self.wl_storage.drop_tx();

Expand Down
1 change: 0 additions & 1 deletion apps/src/lib/node/ledger/shell/governance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,6 @@ where
* need it here. */
TxIndex::default(),
&mut TxGasMeter::new_from_sub_limit(u64::MAX.into()), /* No gas limit for governance proposal */
&mut false,
&mut shell.wl_storage,
&mut shell.vp_wasm_cache,
&mut shell.tx_wasm_cache,
Expand Down
1 change: 0 additions & 1 deletion apps/src/lib/node/ledger/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1431,7 +1431,6 @@ where
match apply_wasm_tx(
unshield,
&TxIndex::default(),
&mut false,
ShellParams::new(
&mut TxGasMeter::new(fee_unshielding_gas_limit),
temp_wl_storage,
Expand Down
Loading

0 comments on commit bbead89

Please sign in to comment.