Skip to content
Open
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 ethexe/common/src/db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ mod tests {
#[test]
fn ensure_types_unchanged() {
const EXPECTED_TYPE_INFO_HASH: &str =
"d43d8ab319fb6d934231dba55950c9825e28c6ecf603e8076a90e0cab3855671";
"75cc4a2bcd0cc559bad7a587812b336e4f44ea7b5d8576ebfe6426dbbef2ca8e";

let types = [
meta_type::<BlockMeta>(),
Expand Down
11 changes: 9 additions & 2 deletions ethexe/common/src/events/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// SPDX-License-Identifier: GPL-3.0-or-later WITH Classpath-exception-2.0

use crate::Digest;
use gprimitives::{ActorId, CodeId, H256};
use gprimitives::{ActorId, CodeId, H256, U256};
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;

Expand All @@ -22,6 +22,11 @@ pub struct MBCommittedEvent(pub H256);
#[derive(Clone, Debug, Encode, Decode, TypeInfo, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct EBCommittedEvent(pub H256);

#[derive(Clone, Debug, Encode, Decode, TypeInfo, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct ProtocolVersionChangedEvent {
pub new_protocol_version: U256,
}

#[derive(Clone, Debug, Encode, Decode, TypeInfo, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct CodeGotValidatedEvent {
pub code_id: CodeId,
Expand Down Expand Up @@ -74,6 +79,7 @@ pub enum Event {
// TODO: on review ask about backward compatibility
StorageSlotChanged(StorageSlotChangedEvent),
ValidatorsCommittedForEra(ValidatorsCommittedForEraEvent),
ProtocolVersionChanged(ProtocolVersionChangedEvent),
}

impl Event {
Expand All @@ -91,7 +97,8 @@ impl Event {
Self::CodeGotValidated { .. }
| Self::MBCommitted(_)
| Self::EBCommitted(_)
| Self::BatchCommitted { .. } => return None,
| Self::BatchCommitted { .. }
| Self::ProtocolVersionChanged { .. } => return None,
})
}
}
Expand Down
23 changes: 23 additions & 0 deletions ethexe/contracts/src/IRouter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,10 @@ interface IRouter {
* This extra fee is paid in WVARA ERC20 token.
*/
uint256 requestCodeValidationExtraFee;
/**
* @notice The version of the protocol, used by nodes.
*/
uint256 protocolVersion;
}

/**
Expand Down Expand Up @@ -143,6 +147,13 @@ interface IRouter {
*/
event EBCommitted(bytes32 ethBlockHash);

/**
* @notice Emitted when the protocol version is changed.
* @dev This is an *informational* event, signaling that the protocol version has been changed.
* @param newProtocolVersion The new version of the protocol.
*/
event ProtocolVersionChanged(uint256 newProtocolVersion);

/**
* @notice Emitted when a code, previously requested for validation, receives validation results, so its `Gear.CodeState` changed.
* @dev This is an *informational* event, signaling the results of code validation.
Expand Down Expand Up @@ -470,6 +481,12 @@ interface IRouter {
*/
function requestCodeValidationExtraFee() external view returns (uint256);

/**
* @dev Returns the current protocol version.
* @return protocolVersion The current protocol version.
*/
function protocolVersion() external view returns (uint256);

/**
* @dev Returns the timelines.
* @return timelines The timelines.
Expand Down Expand Up @@ -502,6 +519,12 @@ interface IRouter {
*/
function setRequestCodeValidationExtraFee(uint256 newExtraFee) external;

/**
* @dev Bumps the version of the protocol, used by nodes.
* Emits `ProtocolVersionChanged` event.
*/
function bumpProtocolVersion() external;

/**
* @dev Pauses the contract.
*/
Expand Down
27 changes: 26 additions & 1 deletion ethexe/contracts/src/Router.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ contract Router is
bytes32 private constant REQUEST_CODE_VALIDATION_ON_BEHALF_TYPEHASH =
0x375d2ef9b9e33c640a295f53873dc74833c3d019f349464ce2fe8899962b8097;

uint256 private constant PROTOCOL_VERSION = 1;

/**
* @custom:oz-upgrades-unsafe-allow constructor
*/
Expand Down Expand Up @@ -121,6 +123,8 @@ contract Router is
block.timestamp
);
// forge-lint: disable-end(block-timestamp)

router.protocolData.protocolVersion = PROTOCOL_VERSION;
}

/**
Expand Down Expand Up @@ -190,6 +194,7 @@ contract Router is
uint256 decimalsFactor = 10 ** IWrappedVara(router.implAddresses.wrappedVara).decimals();
router.protocolData.requestCodeValidationBaseFee = DEFAULT_REQUEST_CODE_VALIDATION_BASE_FEE * decimalsFactor;
router.protocolData.requestCodeValidationExtraFee = DEFAULT_REQUEST_CODE_VALIDATION_EXTRA_FEE * decimalsFactor;
router.protocolData.protocolVersion = PROTOCOL_VERSION;
}

/**
Expand Down Expand Up @@ -218,7 +223,8 @@ contract Router is
validatedCodesCount: router.protocolData.validatedCodesCount,
maxValidators: router.protocolData.maxValidators,
requestCodeValidationBaseFee: router.protocolData.requestCodeValidationBaseFee,
requestCodeValidationExtraFee: router.protocolData.requestCodeValidationExtraFee
requestCodeValidationExtraFee: router.protocolData.requestCodeValidationExtraFee,
protocolVersion: router.protocolData.protocolVersion
});
}

Expand Down Expand Up @@ -455,6 +461,14 @@ contract Router is
return _router().protocolData.requestCodeValidationExtraFee;
}

/**
* @dev Returns the current protocol version.
* @return protocolVersion The current protocol version.
*/
function protocolVersion() external view returns (uint256) {
return _router().protocolData.protocolVersion;
}

/**
* @dev Returns the timelines.
* @return timelines The timelines.
Expand Down Expand Up @@ -497,6 +511,17 @@ contract Router is
_router().protocolData.requestCodeValidationExtraFee = newExtraFee;
}

/**
* @dev Bumps the version of the protocol, used by nodes.
* Emits `ProtocolVersionChanged` event.
*/
function bumpProtocolVersion() external onlyOwner {
uint256 newProtocolVersion = _router().protocolData.protocolVersion + 1;
_router().protocolData.protocolVersion = newProtocolVersion;

emit ProtocolVersionChanged(newProtocolVersion);
}

/**
* @dev Pauses the contract.
*/
Expand Down
5 changes: 5 additions & 0 deletions ethexe/contracts/src/libraries/Gear.sol
Original file line number Diff line number Diff line change
Expand Up @@ -405,6 +405,11 @@ library Gear {
* This extra fee is paid in WVARA ERC20 token.
*/
uint256 requestCodeValidationExtraFee;
/**
* @notice The version of the protocol, used by nodes.
* @dev This contains the version of the protocol, which can be used by nodes.
*/
uint256 protocolVersion;
}

/**
Expand Down
2 changes: 1 addition & 1 deletion ethexe/ethereum/abi/BatchMulticall.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ethexe/ethereum/abi/DemoCaller.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ethexe/ethereum/abi/Gear.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ethexe/ethereum/abi/Middleware.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ethexe/ethereum/abi/Mirror.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ethexe/ethereum/abi/POAMiddleware.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ethexe/ethereum/abi/Router.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion ethexe/ethereum/abi/WrappedVara.json

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions ethexe/ethereum/src/abi/events/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,14 @@ impl From<IRouter::EBCommitted> for EBCommittedEvent {
}
}

impl From<IRouter::ProtocolVersionChanged> for ProtocolVersionChangedEvent {
fn from(value: IRouter::ProtocolVersionChanged) -> Self {
Self {
new_protocol_version: uint256_to_u256(value.newProtocolVersion),
}
}
}

impl From<IRouter::CodeGotValidated> for CodeGotValidatedEvent {
fn from(value: IRouter::CodeGotValidated) -> Self {
Self {
Expand Down
11 changes: 11 additions & 0 deletions ethexe/ethereum/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,9 @@ pub struct Ethereum {
}

impl Ethereum {
/// Client protocol version.
pub const CLIENT_PROTOCOL_VERSION: u64 = 1;

/// Default Ethereum RPC.
pub const DEFAULT_ETHEREUM_RPC: &str = "ws://localhost:8545";
/// Default Ethereum router contract address.
Expand Down Expand Up @@ -337,6 +340,14 @@ impl Ethereum {
let router_query = RouterQuery::from_provider(router_address, provider.root().clone());
let router = router_address.into();
let (wvara, middleware) = if initialize_addresses {
let protocol_version = router_query.protocol_version().await?;
if protocol_version > Self::CLIENT_PROTOCOL_VERSION {
return Err(anyhow!(
"Client protocol version mismatch. Expected {client_protocol_version}, got {protocol_version}. \
Please make sure to use compatible version of Ethereum client with `Router` contract.",
client_protocol_version = Self::CLIENT_PROTOCOL_VERSION,
));
}
(
router_query.wvara_address().await?.into(),
router_query.middleware_address().await?.into(),
Expand Down
14 changes: 1 addition & 13 deletions ethexe/ethereum/src/mirror/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use alloy::{
};
use anyhow::Result;
use ethexe_common::events::{
MirrorEvent, MirrorRequestEvent,
MirrorEvent,
mirror::{
ExecutableBalanceTopUpRequestedEvent, MessageCallFailedEvent, MessageEvent,
MessageQueueingRequestedEvent, OwnedBalanceTopUpRequestedEvent, ReplyCallFailedEvent,
Expand Down Expand Up @@ -107,18 +107,6 @@ pub fn try_extract_event(log: &Log) -> Result<Option<MirrorEvent>> {
Ok(Some(event))
}

pub fn try_extract_request_event(log: &Log) -> Result<Option<MirrorRequestEvent>> {
if log.topic0().filter(|&v| REQUESTS.contains(v)).is_none() {
return Ok(None);
}

let request_event = try_extract_event(log)?
.and_then(|v| v.to_request())
.expect("filtered above");

Ok(Some(request_event))
}

pub struct AllEventsBuilder<'a> {
query: &'a MirrorQuery,
}
Expand Down
18 changes: 5 additions & 13 deletions ethexe/ethereum/src/router/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use alloy::{
};
use anyhow::{Result, anyhow};
use ethexe_common::events::{
RouterEvent, RouterRequestEvent,
RouterEvent,
router::{
BatchCommittedEvent, CodeGotValidatedEvent, CodeValidationRequestedEvent,
ComputationSettingsChangedEvent, EBCommittedEvent, MBCommittedEvent, ProgramCreatedEvent,
Expand All @@ -35,6 +35,7 @@ pub mod signatures {
BATCH_COMMITTED: BatchCommitted,
MB_COMMITTED: MBCommitted,
EB_COMMITTED: EBCommitted,
PROTOCOL_VERSION_CHANGED: ProtocolVersionChanged,
CODE_GOT_VALIDATED: CodeGotValidated,
CODE_VALIDATION_REQUESTED: CodeValidationRequested,
COMPUTATION_SETTINGS_CHANGED: ComputationSettingsChanged,
Expand Down Expand Up @@ -63,6 +64,9 @@ pub fn try_extract_event(log: &Log) -> Result<Option<RouterEvent>> {
}
MB_COMMITTED => RouterEvent::MBCommitted(decode_log::<IRouter::MBCommitted>(log)?.into()),
EB_COMMITTED => RouterEvent::EBCommitted(decode_log::<IRouter::EBCommitted>(log)?.into()),
PROTOCOL_VERSION_CHANGED => RouterEvent::ProtocolVersionChanged(
decode_log::<IRouter::ProtocolVersionChanged>(log)?.into(),
),
CODE_GOT_VALIDATED => {
RouterEvent::CodeGotValidated(decode_log::<IRouter::CodeGotValidated>(log)?.into())
}
Expand Down Expand Up @@ -99,18 +103,6 @@ pub fn try_extract_event(log: &Log) -> Result<Option<RouterEvent>> {
Ok(Some(event))
}

pub fn try_extract_request_event(log: &Log) -> Result<Option<RouterRequestEvent>> {
if log.topic0().filter(|&v| REQUESTS.contains(v)).is_none() {
return Ok(None);
}

let request_event = try_extract_event(log)?
.and_then(|v| v.to_request())
.expect("filtered above");

Ok(Some(request_event))
}

pub struct AllEventsBuilder<'a> {
query: &'a RouterQuery,
}
Expand Down
9 changes: 9 additions & 0 deletions ethexe/ethereum/src/router/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -908,6 +908,15 @@ impl RouterQuery {
Ok(extra_fee.try_into().expect("infallible"))
}

pub async fn protocol_version(&self) -> Result<u64> {
self.instance
.protocolVersion()
.call()
.await
.map(|res| res.to())
.map_err(Into::into)
}

pub async fn timelines(&self) -> Result<Timelines> {
self.instance
.timelines()
Expand Down
7 changes: 7 additions & 0 deletions ethexe/observer/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,13 @@ impl Stream for ObserverService {
cx.waker().wake_by_ref();
return Poll::Pending;
}
Err(SyncError::ProtocolVersionMismatch { expected, got }) => {
return Poll::Ready(Some(Err(SyncError::ProtocolVersionMismatch {
expected,
got,
}
.into())));
}
Err(SyncError::Fatal(err)) => {
return Poll::Ready(Some(Err(err)));
}
Expand Down
Loading
Loading