Skip to content

Commit

Permalink
Feature/new fti event (#1770)
Browse files Browse the repository at this point in the history
closes #1742 


Adds a new relayer event type in support of forced transactions,
assuming the following ABI from L1:

```
[
    event MessageSent(bytes32 indexed sender, bytes32 indexed recipient, uint256 indexed nonce, uint64 amount, bytes data)
    event Transaction(uint64 max_gas, bytes canonically_serialized_tx)
]
```

Specifically, this PR adds:

- Parsing FTI logs from ethereum
- Saving parsed FTI events to the relayer events table
- Reshuffles the message entity in fuel-core-types to be grouped under a
relayer module, which also includes the new entity for
RelayedTransaction's (this may cause a lot of breaking changes for the
regenesis workstream, so if this seems like more trouble than it's worth
I can put things back to how they were)

---------

Co-authored-by: Green Baneling <XgreenX9999@gmail.com>
Co-authored-by: Brandon Vrooman <brandon.vrooman@fuel.sh>
  • Loading branch information
3 people authored Mar 22, 2024
1 parent c855fda commit fb79894
Show file tree
Hide file tree
Showing 38 changed files with 494 additions and 109 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Description of the upcoming release here.

### Added

- [#1770](https://github.com/FuelLabs/fuel-core/pull/1770): Add the new L1 event type for forced transactions.
- [#1767](https://github.com/FuelLabs/fuel-core/pull/1767): Added consensus parameters version and state transition version to the `ApplicationHeader` to describe what was used to produce this block.
- [#1760](https://github.com/FuelLabs/fuel-core/pull/1760): Added tests to verify that the network operates with a custom chain id and base asset id.
- [#1752](https://github.com/FuelLabs/fuel-core/pull/1752): Add `ProducerGasPrice` trait that the `Producer` depends on to get the gas price for the block.
Expand Down
2 changes: 1 addition & 1 deletion bin/fuel-core/src/cli/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ mod tests {
CompressedCoinV1,
},
contract::ContractUtxoInfo,
message::{
relayer::message::{
Message,
MessageV1,
},
Expand Down
2 changes: 1 addition & 1 deletion crates/chain-config/src/config/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use crate::{
use fuel_core_storage::MerkleRoot;
use fuel_core_types::{
blockchain::primitives::DaBlockHeight,
entities::message::{
entities::relayer::message::{
Message,
MessageV1,
},
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/coins_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,7 @@ mod tests {
Coin,
CompressedCoin,
},
message::{
relayer::message::{
Message,
MessageV1,
},
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/database/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use fuel_core_types::{
},
primitives::BlockId,
},
entities::message::MerkleProof,
entities::relayer::message::MerkleProof,
fuel_merkle::binary::MerkleTree,
fuel_types::BlockHeight,
};
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/database/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use fuel_core_storage::{
Result as StorageResult,
};
use fuel_core_types::{
entities::message::Message,
entities::relayer::message::Message,
fuel_types::{
Address,
Nonce,
Expand Down
31 changes: 28 additions & 3 deletions crates/fuel-core/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ mod tests {
},
entities::{
coins::coin::CompressedCoin,
message::{
relayer::message::{
Message,
MessageV1,
},
Expand Down Expand Up @@ -2954,7 +2954,10 @@ mod tests {
},
StorageAsMut,
};
use fuel_core_types::fuel_merkle::binary::root_calculator::MerkleRootCalculator;
use fuel_core_types::{
entities::RelayedTransaction,
fuel_merkle::binary::root_calculator::MerkleRootCalculator,
};

fn database_with_genesis_block(da_block_height: u64) -> Database<OnChain> {
let mut db = Database::default();
Expand All @@ -2975,6 +2978,16 @@ mod tests {
.expect("Should insert event");
}

fn add_events_to_relayer(
db: &mut Database<Relayer>,
da_height: DaBlockHeight,
events: &[Event],
) {
db.storage::<EventsHistory>()
.insert(&da_height, events)
.expect("Should insert event");
}

fn add_messages_to_relayer(db: &mut Database<Relayer>, relayer_da_height: u64) {
for da_height in 0..=relayer_da_height {
let mut message = Message::default();
Expand Down Expand Up @@ -3112,11 +3125,23 @@ mod tests {
let relayer_da_height = 10u64;
let mut root_calculator = MerkleRootCalculator::new();
for da_height in (genesis_da_height + 1)..=relayer_da_height {
// message
let mut message = Message::default();
message.set_da_height(da_height.into());
message.set_nonce(da_height.into());
root_calculator.push(message.id().as_ref());
add_message_to_relayer(&mut relayer_db, message);
// transaction
let mut transaction = RelayedTransaction::default();
transaction.set_da_height(da_height.into());
transaction.set_max_gas(da_height);
transaction.set_serialized_transaction(da_height.to_be_bytes().to_vec());
root_calculator.push(Bytes32::from(transaction.id()).as_ref());
// add events to relayer
add_events_to_relayer(
&mut relayer_db,
da_height.into(),
&[message.into(), transaction.into()],
);
}
let producer = create_relayer_executor(on_chain_db, relayer_db);
let block = test_block(block_height.into(), relayer_da_height.into(), 0);
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/graphql_api/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use fuel_core_types::{
DaBlockHeight,
},
},
entities::message::{
entities::relayer::message::{
MerkleProof,
Message,
},
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/graphql_api/ports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use fuel_core_types::{
DaBlockHeight,
},
},
entities::message::{
entities::relayer::message::{
MerkleProof,
Message,
},
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/query/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ use fuel_core_storage::{
};
use fuel_core_types::{
blockchain::block::CompressedBlock,
entities::message::{
entities::relayer::message::{
MerkleProof,
Message,
MessageProof,
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/query/message/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use fuel_core_types::{
ConsensusHeader,
PartialBlockHeader,
},
entities::message::MerkleProof,
entities::relayer::message::MerkleProof,
fuel_tx::{
Script,
Transaction,
Expand Down
26 changes: 13 additions & 13 deletions crates/fuel-core/src/schema/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ use async_graphql::{
};
use fuel_core_types::entities;

pub struct Message(pub(crate) entities::message::Message);
pub struct Message(pub(crate) entities::relayer::message::Message);

#[Object]
impl Message {
Expand Down Expand Up @@ -158,7 +158,7 @@ impl MessageQuery {
Ok(status.into())
}
}
pub struct MerkleProof(pub(crate) entities::message::MerkleProof);
pub struct MerkleProof(pub(crate) entities::relayer::message::MerkleProof);

#[Object]
impl MerkleProof {
Expand All @@ -176,7 +176,7 @@ impl MerkleProof {
}
}

pub struct MessageProof(pub(crate) entities::message::MessageProof);
pub struct MessageProof(pub(crate) entities::relayer::message::MessageProof);

#[Object]
impl MessageProof {
Expand Down Expand Up @@ -217,19 +217,19 @@ impl MessageProof {
}
}

impl From<entities::message::Message> for Message {
fn from(message: entities::message::Message) -> Self {
impl From<entities::relayer::message::Message> for Message {
fn from(message: entities::relayer::message::Message) -> Self {
Message(message)
}
}

impl From<entities::message::MerkleProof> for MerkleProof {
fn from(proof: entities::message::MerkleProof) -> Self {
impl From<entities::relayer::message::MerkleProof> for MerkleProof {
fn from(proof: entities::relayer::message::MerkleProof) -> Self {
MerkleProof(proof)
}
}

pub struct MessageStatus(pub(crate) entities::message::MessageStatus);
pub struct MessageStatus(pub(crate) entities::relayer::message::MessageStatus);

#[derive(Enum, Copy, Clone, Eq, PartialEq)]
enum MessageState {
Expand All @@ -242,15 +242,15 @@ enum MessageState {
impl MessageStatus {
async fn state(&self) -> MessageState {
match self.0.state {
entities::message::MessageState::Unspent => MessageState::Unspent,
entities::message::MessageState::Spent => MessageState::Spent,
entities::message::MessageState::NotFound => MessageState::NotFound,
entities::relayer::message::MessageState::Unspent => MessageState::Unspent,
entities::relayer::message::MessageState::Spent => MessageState::Spent,
entities::relayer::message::MessageState::NotFound => MessageState::NotFound,
}
}
}

impl From<entities::message::MessageStatus> for MessageStatus {
fn from(status: entities::message::MessageStatus) -> Self {
impl From<entities::relayer::message::MessageStatus> for MessageStatus {
fn from(status: entities::relayer::message::MessageStatus) -> Self {
MessageStatus(status)
}
}
2 changes: 1 addition & 1 deletion crates/fuel-core/src/service/adapters/graphql_api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use fuel_core_txpool::{
types::TxId,
};
use fuel_core_types::{
entities::message::MerkleProof,
entities::relayer::message::MerkleProof,
fuel_tx::{
Bytes32,
Transaction,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use fuel_core_types::{
block::CompressedBlock,
primitives::DaBlockHeight,
},
entities::message::Message,
entities::relayer::message::Message,
fuel_tx::AssetId,
fuel_types::{
BlockHeight,
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/service/adapters/txpool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use fuel_core_txpool::{
use fuel_core_types::{
entities::{
coins::coin::CompressedCoin,
message::Message,
relayer::message::Message,
},
fuel_tx::{
Transaction,
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/service/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ use fuel_core_types::{
entities::{
coins::coin::Coin,
contract::ContractUtxoInfo,
message::Message,
relayer::message::Message,
},
fuel_tx::Contract,
fuel_types::{
Expand Down
2 changes: 1 addition & 1 deletion crates/fuel-core/src/service/genesis/off_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use fuel_core_txpool::types::TxId;
use fuel_core_types::{
entities::{
coins::coin::CompressedCoin,
message::Message,
Message,
},
fuel_tx::{
Transaction,
Expand Down
3 changes: 3 additions & 0 deletions crates/services/executor/src/executor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -750,6 +750,9 @@ where
.events
.push(ExecutorEvent::MessageImported(message));
}
Event::Transaction(_) => {
// TODO: implement handling of forced transactions in a later PR
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions crates/services/relayer/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ pub mod bridge {
MessageSent,
r#"[
event MessageSent(bytes32 indexed sender, bytes32 indexed recipient, uint256 indexed nonce, uint64 amount, bytes data)
event Transaction(uint64 max_gas, bytes canonically_serialized_tx)
]"#,
);
}
3 changes: 3 additions & 0 deletions crates/services/relayer/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ use std::{
pub(crate) static ETH_LOG_MESSAGE: Lazy<H256> =
Lazy::new(crate::abi::bridge::MessageSentFilter::signature);

pub(crate) static ETH_FORCED_TX: Lazy<H256> =
Lazy::new(crate::abi::bridge::TransactionFilter::signature);

// TODO: Move settlement fields into `ChainConfig` because it is part of the consensus.
#[derive(Clone, Debug)]
/// Configuration settings for the Relayer.
Expand Down
62 changes: 59 additions & 3 deletions crates/services/relayer/src/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@ use ethers_core::{
};
use fuel_core_types::{
blockchain::primitives::DaBlockHeight,
entities::message::{
Message,
MessageV1,
entities::{
relayer::{
message::{
Message,
MessageV1,
},
transaction::RelayedTransactionV1,
},
RelayedTransaction,
},
fuel_types::{
Address,
Expand All @@ -32,6 +38,13 @@ pub struct MessageLog {
pub da_height: DaBlockHeight,
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub struct TransactionLog {
pub max_gas: u64,
pub serialized_transaction: Vec<u8>,
pub da_height: DaBlockHeight,
}

impl From<&MessageLog> for Message {
fn from(message: &MessageLog) -> Self {
MessageV1 {
Expand All @@ -46,10 +59,22 @@ impl From<&MessageLog> for Message {
}
}

impl From<TransactionLog> for RelayedTransaction {
fn from(transaction: TransactionLog) -> Self {
RelayedTransactionV1 {
max_gas: transaction.max_gas,
serialized_transaction: transaction.serialized_transaction,
da_height: transaction.da_height,
}
.into()
}
}

#[derive(Debug, Clone, Eq, PartialEq)]
pub enum EthEventLog {
// Bridge message from da side
Message(MessageLog),
Transaction(TransactionLog),
Ignored,
}

Expand All @@ -63,6 +88,7 @@ impl TryFrom<&Log> for EthEventLog {

let log = match log.topics[0] {
n if n == *config::ETH_LOG_MESSAGE => {
// event has 3 indexed fields, so it should have 4 topics
if log.topics.len() != 4 {
return Err(anyhow!("Malformed topics for Message"))
}
Expand Down Expand Up @@ -97,6 +123,36 @@ impl TryFrom<&Log> for EthEventLog {
),
})
}
n if n == *config::ETH_FORCED_TX => {
// event has no indexed fields, so there is only 1 topic
if log.topics.len() != 1 {
return Err(anyhow!("Malformed topics for forced Transaction"))
}

let raw_log = RawLog {
topics: log.topics.clone(),
data: log.data.to_vec(),
};

let event = abi::bridge::TransactionFilter::decode_log(&raw_log)
.map_err(anyhow::Error::msg)?;

let max_gas = event.max_gas;
let serialized_transaction = event.canonically_serialized_tx;

Self::Transaction(TransactionLog {
max_gas,
serialized_transaction: serialized_transaction.to_vec(),
// Safety: logs without block numbers are rejected by
// FinalizationQueue::append_eth_log before the conversion to EthEventLog happens.
// If block_number is none, that means the log is pending.
da_height: DaBlockHeight::from(
log.block_number
.ok_or(anyhow!("Log missing block height"))?
.as_u64(),
),
})
}
_ => Self::Ignored,
};

Expand Down
Loading

0 comments on commit fb79894

Please sign in to comment.