feature: Decode + message_by_leaf

buddies-main-deployment
James Prestwich 4 years ago
parent afefc55138
commit 81707b3237
No known key found for this signature in database
GPG Key ID: 75A7F5C06D747046
  1. 2
      rust/optics-base/src/abis/Home.abi.json
  2. 11
      rust/optics-base/src/abis/mod.rs
  3. 78
      rust/optics-core/src/lib.rs
  4. 48
      rust/optics-core/src/traits/home.rs
  5. 15
      rust/optics-core/src/traits/mod.rs
  6. 2
      rust/optics-core/src/traits/replica.rs

@ -38,7 +38,7 @@
{
"indexed": true,
"internalType": "bytes32",
"name": "current",
"name": "leaf",
"type": "bytes32"
},
{

@ -280,7 +280,7 @@ impl<M> Home for HomeContract<M>
where
M: ethers_providers::Middleware + 'static,
{
async fn lookup_message(
async fn raw_message_by_sequence(
&self,
destination: u32,
sequence: u32,
@ -296,6 +296,15 @@ where
Ok(filters.into_iter().next().map(|f| f.message))
}
async fn raw_message_by_leaf(
&self,
leaf: H256,
) -> Result<Option<Vec<u8>>, ChainCommunicationError> {
let filters = self.contract.dispatch_filter().topic3(leaf).query().await?;
Ok(filters.into_iter().next().map(|f| f.message))
}
async fn sequences(&self, destination: u32) -> Result<u32, ChainCommunicationError> {
Ok(self.contract.sequences(destination).call().await?)
}

@ -4,6 +4,7 @@
#![forbid(unsafe_code)]
#![warn(missing_docs)]
#![warn(unused_extern_crates)]
#![forbid(where_clauses_object_safety)]
/// Accumulator management
pub mod accumulator;
@ -17,11 +18,12 @@ pub mod traits;
mod utils;
use ethers_core::{
types::{Address, Signature, H256},
types::{Address, Signature, SignatureError, H256},
utils::hash_message,
};
use ethers_signers::Signer;
use sha3::{Digest, Keccak256};
use std::convert::TryFrom;
use crate::utils::*;
@ -60,6 +62,18 @@ pub trait Encode {
}
}
/// Simple trait for types with a canonical encoding
pub trait Decode {
/// Error type
type Error;
/// Try to read from some source
fn read_from<R>(reader: &mut R) -> Result<Self, Self::Error>
where
R: std::io::Read,
Self: Sized;
}
impl Encode for Signature {
fn write_to<W>(&self, writer: &mut W) -> std::io::Result<usize>
where
@ -70,6 +84,24 @@ impl Encode for Signature {
}
}
impl Decode for Signature {
type Error = SignatureError;
fn read_from<R>(reader: &mut R) -> Result<Self, Self::Error>
where
R: std::io::Read,
{
let mut buf = [0u8; 65];
let len = reader
.read(&mut buf)
.map_err(|_| SignatureError::InvalidLength(0))?;
if len != 65 {
Err(SignatureError::InvalidLength(len))
} else {
Self::try_from(buf.as_ref())
}
}
}
/// An Optics message between chains
#[derive(Debug, Clone)]
pub struct Message {
@ -101,6 +133,50 @@ impl Encode for Message {
}
}
impl Decode for Message {
type Error = std::io::Error;
fn read_from<R>(reader: &mut R) -> Result<Self, Self::Error>
where
R: std::io::Read,
{
let mut origin = [0u8; 4];
reader.read_exact(&mut origin)?;
let mut sender = H256::zero();
reader.read_exact(sender.as_mut())?;
let mut destination = [0u8; 4];
reader.read_exact(&mut destination)?;
let mut recipient = H256::zero();
reader.read_exact(recipient.as_mut())?;
let mut sequence = [0u8; 4];
reader.read_exact(&mut sequence)?;
let mut body = vec![];
reader.read_to_end(&mut body)?;
Ok(Self {
origin: u32::from_be_bytes(origin),
sender,
destination: u32::from_be_bytes(destination),
recipient,
sequence: u32::from_be_bytes(sequence),
body,
})
}
}
impl Message {
/// Convert the message to a leaf
pub fn to_leaf(&self) -> H256 {
let mut k = Keccak256::new();
self.write_to(&mut k).expect("!write");
H256::from_slice(k.finalize().as_slice())
}
}
/// An Optics update message
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub struct Update {

@ -1,22 +1,64 @@
use async_trait::async_trait;
use ethers_core::types::H256;
use crate::{
traits::{ChainCommunicationError, Common, TxOutcome},
Message, SignedUpdate, Update,
Decode, Message, SignedUpdate, Update,
};
/// Interface for the Home chain contract. Allows abstraction over different
/// chains
#[async_trait]
pub trait Home: Common {
pub trait Home: Common + Send + Sync + std::fmt::Debug {
/// Fetch the message to destination at the sequence number (or error).
/// This should fetch events from the chain API.
///
/// Used by processors to get messages in order
async fn raw_message_by_sequence(
&self,
destination: u32,
sequence: u32,
) -> Result<Option<Vec<u8>>, ChainCommunicationError>;
/// Fetch the message to destination at the sequence number (or error).
/// This should fetch events from the chain API
async fn lookup_message(
async fn message_by_sequence(
&self,
destination: u32,
sequence: u32,
) -> Result<Option<Message>, ChainCommunicationError> {
self.raw_message_by_sequence(destination, sequence)
.await?
.map(|buf| {
Message::read_from(&mut &buf[..])
.map_err(|e| ChainCommunicationError::CustomError(Box::new(e)))
})
.transpose()
}
/// Look up a message by its hash.
/// This should fetch events from the chain API
async fn raw_message_by_leaf(
&self,
leaf: H256,
) -> Result<Option<Vec<u8>>, ChainCommunicationError>;
/// Look up a message by its hash.
/// This should fetch events from the chain API
async fn message_by_leaf(
&self,
leaf: H256,
) -> Result<Option<Message>, ChainCommunicationError> {
self.raw_message_by_leaf(leaf)
.await?
.map(|buf| {
Message::read_from(&mut &buf[..])
.map_err(|e| ChainCommunicationError::CustomError(Box::new(e)))
})
.transpose()
}
/// Fetch the sequence
async fn sequences(&self, destination: u32) -> Result<u32, ChainCommunicationError>;

@ -44,13 +44,13 @@ impl From<TransactionReceipt> for TxOutcome {
/// Error type for chain communication
pub enum ChainCommunicationError {
/// Provider Error
#[error(transparent)]
#[error("{0}")]
ProviderError(#[from] ethers_providers::ProviderError),
/// Contract Error
#[error(transparent)]
#[error("{0}")]
ContractError(Box<dyn std::error::Error>),
/// Custom error or contract error
#[error(transparent)]
#[error("{0}")]
CustomError(#[from] Box<dyn std::error::Error>),
}
@ -63,15 +63,6 @@ where
}
}
// impl<M> From<ethers_contract::ContractError<M>> for ChainCommunicationError
// where
// M: ethers_providers::Middleware + 'static,
// {
// fn from(e: ethers_contract::ContractError<M>) -> Self {
// Self::ContractError(Box::new(e))
// }
// }
/// Interface for attributes shared by Home and Replica
#[async_trait]
pub trait Common: Sync + Send + std::fmt::Debug {

@ -8,7 +8,7 @@ use crate::{
/// Interface for on-chain replicas
#[async_trait]
pub trait Replica: Common {
pub trait Replica: Common + Send + Sync + std::fmt::Debug {
/// Return the pending root and time, if any
async fn next_pending(&self) -> Result<Option<(H256, U256)>, ChainCommunicationError>;

Loading…
Cancel
Save