Skip to content
This repository has been archived by the owner on Jan 15, 2024. It is now read-only.

Split out MerkleTree contract and emit CapeBlock as part of BlockCommitted event #1097

Merged
merged 22 commits into from
Jun 3, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
4 changes: 2 additions & 2 deletions contracts/contracts/CAPE.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ contract CAPE is RecordsMerkleTree, RootStore, AssetRegistry, ReentrancyGuard {
uint256 public constant MAX_NUM_PENDING_DEPOSIT = 10;

event FaucetInitialized(bytes roBytes);
event BlockCommitted(uint64 indexed height, uint256[] depositCommitments);
event BlockCommitted(uint64 indexed height, uint256[] depositCommitments, bytes blockBytes);
event Erc20TokensDeposited(bytes roBytes, address erc20TokenAddress, address from);

struct AuditMemo {
Expand Down Expand Up @@ -357,7 +357,7 @@ contract CAPE is RecordsMerkleTree, RootStore, AssetRegistry, ReentrancyGuard {
blockHeight += 1;

// Inform clients about the new block and the processed deposits.
emit BlockCommitted(blockHeight, pendingDeposits);
emit BlockCommitted(blockHeight, pendingDeposits, abi.encode(newBlock));

// Empty the queue now that the record commitments have been inserted
delete pendingDeposits;
Expand Down
8 changes: 4 additions & 4 deletions contracts/rust/src/cape/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
mod tests {
use crate::{
cape::{
submit_block::{fetch_cape_block, submit_cape_block_with_memos},
submit_block::{fetch_cape_memos, submit_cape_block_with_memos},
BlockWithMemos, CapeBlock,
},
ethereum::EthConnection,
Expand All @@ -32,7 +32,7 @@ mod tests {
use std::iter::repeat_with;

#[tokio::test]
async fn test_fetch_cape_block_from_event() -> Result<()> {
async fn test_fetch_cape_memos_from_event() -> Result<()> {
let connection = EthConnection::for_test().await;

let mut rng = ChaChaRng::from_seed([0x42u8; 32]);
Expand Down Expand Up @@ -100,11 +100,11 @@ mod tests {

let (_, meta) = events[0].clone();

let fetched_block_with_memos = fetch_cape_block(&query_connection, meta.transaction_hash)
let fetched_memos = fetch_cape_memos(&query_connection, meta.transaction_hash)
.await?
.unwrap();

assert_eq!(fetched_block_with_memos, block_with_memos);
assert_eq!(fetched_memos, memos_with_sigs);

Ok(())
}
Expand Down
16 changes: 7 additions & 9 deletions contracts/rust/src/cape/submit_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
// This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
// You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.

use crate::cape::CapeBlock;
use crate::deploy::EthMiddleware;
use crate::ethereum::EthConnection;
use crate::types::{self as sol, CAPE};
Expand All @@ -21,10 +20,10 @@ use super::{BlockMemos, BlockWithMemos};

/// Fetch a cape block given the (Ethereum) tx hash of the tx in which the block
/// was submitted.
pub async fn fetch_cape_block(
pub async fn fetch_cape_memos(
connection: &EthConnection,
tx_hash: TxHash,
) -> Result<Option<BlockWithMemos>, Error> {
) -> Result<Option<BlockMemos>, Error> {
// Fetch Ethereum transaction that emitted event
let tx = if let Some(tx) = connection.provider.get_transaction(tx_hash).await? {
tx
Expand All @@ -33,16 +32,14 @@ pub async fn fetch_cape_block(
};

// Decode the calldata (tx.input) into the function input types
let (decoded_calldata_block, fetched_memos_bytes) =
connection
.contract
.decode::<(sol::CapeBlock, Bytes), _>("submitCapeBlockWithMemos", tx.input)?;
let (_, fetched_memos_bytes) = connection
.contract
.decode::<(sol::CapeBlock, Bytes), _>("submitCapeBlockWithMemos", tx.input)?;

let decoded_cape_block = CapeBlock::from(decoded_calldata_block);
let decoded_memos: BlockMemos =
CanonicalDeserialize::deserialize(&fetched_memos_bytes.to_vec()[..])?;

Ok(Some(BlockWithMemos::new(decoded_cape_block, decoded_memos)))
Ok(Some(decoded_memos))
}

pub async fn submit_cape_block_with_memos(
Expand Down Expand Up @@ -108,6 +105,7 @@ mod tests {
use super::*;
use crate::{
assertion::Matcher,
cape::CapeBlock,
deploy::deploy_test_cape,
ledger::CapeLedger,
test_utils::PrintGas,
Expand Down
29 changes: 14 additions & 15 deletions eqs/src/eth_polling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use crate::state_persistence::StatePersistence;

use async_std::sync::{Arc, RwLock};
use cap_rust_sandbox::{
cape::submit_block::fetch_cape_block,
cape::submit_block::fetch_cape_memos,
ethereum::EthConnection,
ledger::{CapeTransactionKind, CapeTransition},
model::{CapeModelTxn, Erc20Code, EthereumAddr},
Expand Down Expand Up @@ -203,23 +203,23 @@ impl EthPolling {
}
}
match filter {
CAPEEvents::BlockCommittedFilter(_) => {
let fetched_block_with_memos =
fetch_cape_block(&self.connection, meta.transaction_hash)
.await
.unwrap()
.unwrap();

let model_txns = fetched_block_with_memos
.block
.clone()
CAPEEvents::BlockCommittedFilter(filter_data) => {
let memos = fetch_cape_memos(&self.connection, meta.transaction_hash)
.await
.unwrap()
.unwrap();

let cape_block: cap_rust_sandbox::types::CapeBlock =
AbiDecode::decode(filter_data.block_bytes).unwrap();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This fails at runtime

Unpacking universal parameters... done in 9791 ms
Sent funding tx to deployer
xfr: 987 bytes
mint: 971 bytes
freeze: 979 bytes
Event BlockCommittedFilter { height: 1, deposit_commitments: [], block_bytes: Bytes(b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xe0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\t\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\t \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\t@\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0 \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05@#\x99\xce\xbf\xc8N\x1e\xbc\xd7\xe4\xd9L\x9f\x03_'\xdaQ\xc28\xb1\x07/lt8\x0b\xbfq\x83\x07\xdd\x1b\x069\"R\xb0\x11l2\x0f\xe8\x8f\x07\xb8\x80\xb1\x8d\xc9\xae\xf8\x14\x92|l\x15\x9cV\x8c[\xd4\xeb\x8b\r_a\xce\xa3\xdf\xdc\x8f\xc7\x0fO\xeby\x8d\xc2\x18Lvp#Ya\x91h\xfc\x14\x99\xd1y\xc5H\xae\x07t/\xf6\x98\xd4\x08\x15D\xf5\x188'\xf2H\xb1\xc74\xfbD\x19\x83p\xf0IPIg\x17\x88\xa51\x06\xb6t\x14C7\x1fx_vY\xc1\xc7\xd2QQ\x8f\xe5\xb2iS\xf0X\xc3\x0e\xe9\xea\x07\x17\x93o\x11\x0f\x8a\x0e\xcbg\x11y\xd7x5\xcaL[Ak,\x1f\x07\xe0\x84\x80?\x9e\\Nxm\x03\x1a\xa0\xb3\xfa%#yK\xba\xfaWx\x93\0\xbdq8\x87\x88\xd6\xd2\xb8]\xca\x13(\xa8\x7f)\x86N\xfa\xf1v\xdb\x98\x15\x1bCN\x8ef\x1c3u\xc3\xdc\xec\xddpn\xbf\xb3^(2\x10\x95\xa2\xad\xda \x94\xe6\xb7>O)\x14\x8f\xd9\xf4<\xb3\xbcXI!\xc3\xad`\xaf4C\x12P\x82n{\x05[\xdc_\xf9\x03\x84\xad\xf1\xeb\xbc\x1d\x19E]\rf{\xcf\xd9\xc5\xf1<xM\xd4\x12\xcco\xf2l\x15A\xe1\x95U\xcay3\xc7_t|\x0e\xc2P\xe0n\xaf*7\x0f\xc9'\xf2\x07<h]\xf0y\xaa\xb2\xa5\xb4\xaby\xb2R[S\x0eL\xaaO\x0f[\"r<Yl=\xdb\x17\xab\xeb\xb8\x19\xbaUa\x9e\n\xd12A\xd0\x8f\xd7\xe0\xd4\xaa\xb42\xady\x02*\x82\x9cU\xa6\xd6|hgh\xafb\xbb\xa1\xa5\x87\xe4L\x9a\xabD1\xb2\x074\tl\xf5\x19k\xbf\x04\xab\x14\xdd;f\x82B\xe3N\x0f\xbb\xc5\xf8\xd4\xc5D\x0f\xc3\xb2\x16\xae\x11\xaa\x8d\xe8o\x83i'\x15W\x12E\xd8_\x83\x18\x0e\x01\xaf\xdf\xe8\xc3:\xe2K/G\x9b\xc6?Y\x1f\xde\x0f\xc5x\x83\x12\x96\x84\xeb\xf3\x19\x92ff3*\xea\xf8\xb5\x9d~Y\xb9\xb6\\\xdd\xf7\x0f\x0b60^\xb3\xf7\xf6t\x0e\xf1^\x96:\x1b07X\xb7\x9c\xd1\xb0b}\x07\x1e\xa7\xfbj\xa1\n\x1ckT\xd8\xee\x95\xe0\xad\xfa6\xb2 \x89\t'l\x02\xe8a\xce\xf5\xc2_\xdb4\x8a\xa3e\xd8RKx4\xe9\xb0c\xabCL\x1b\xc3hD\xdeN\t\x0e\xc4\t\xb2-\xe0\xfa\x0c\xd9\x82\xe9\x97?\xb3-\xf1\xd2\xbb\x99\0\x99\x1c\xb0Ve\xe70\\\x88$\xf5\tDF\x13\xa4\x15)l@9\x19\x85\xb9\xc6-\x823\x83\xfd\xf4\xfb\xb2\xf2t\xfc8\x93x\x9a\xe0n\xe7\x91\x95`\x03\x18\x1b\xe8\x11\xc5a\xad9z\x1e\xd5\xd1&u\xfbZ\xa3\x03>\x98\xd6\xd2\x95\xabc\xae\x10Ft^p\x1c\xc3\xbe\xdd\t\n\xea\x96\x17\xc3\xc1\xd9ci\0=\xee\xc5\xc0\x15\x12i\xb7\x96\xa6t\x9e\x89\x1b\xd9\x13\xc6-|\xe6\xcb1\x1c\xe0\x87\x05\xaeP\xcd\xd9\x11\x19\xb8\xd1\x18\xae<'\x065iZ\x99W \xbd\x02+\x88\x07\0'\x1f\r@\xefV\xee\xa2\x1a\x1f\xea\xac\xec\xf2L\xa4\xf9\xab\x06\xf4~V\xff\xe3\xc1\xc0\xa2\x83\xcb\xb9\x06\x01]R\xf9\x05\xfe\xce\xdc~w\x95<\x03\xfdM\x0b\xfd\xe9\xcb\x91N\\\x9dGG\x13\x88)\r\xc1\xb7\x10\xa45[t$\x91\x05`\xc4\xfd\xefN\xbb\xaa\x92\xf8\\%\x9c\xe3\xea\x1a\xbaz[\xd0\\\xf4\x06\xb4\x15\x0c\xb0p\x18f\x83\xbf\x02\xc1|b~\t\xc3\xe6\xe6H\x1b\xd6{\xbd\x92\xea\xff\xa9\x12\\\xa6\x9bX9\xb6\x11A\xd54\xa2\xd5\xd3)\x16abZ\xb43\\\x8c7\xe7\x83\xb9\xf3\x14U\xe0g\x1d\xa1&\xc9K\xc3d\x1c\x8a\x92x\xe9\xb7Q\x87\xabi\xa03\x9a\xc9rgNw\xf7\xf4\xf66Hw\xcc\x1a7\x13E*\xd4&\r\xe9ejI\xdeZ\xcc\xdf\xa6gT\x1d}\x1cO\x18\xcf\x88MB\xf1!k*\x80c'@d\xb4?\x10\xfd\x07\xc3\x9a&i!l\xf7\xc3\xf2\x9b'\xbbrY\x02wz\xd04\x1f/aTB\x85Xx\xf10)'\xfd\xd6\xdc\xb9\xdb\xe9z\x13\x8d\xae\x913\xf3\"g\n\xa9\x1f\xc0\xc0h\xa5\x92\xff\xc4\x02\x81q\x9d\x8f\x1c\x9b\\?\xa5\xed[\xf4\xe1\x9e\xa9\xeaLt\n\xb8\x0f'\xcc\xa2\xb01\xa6k%H/\xb3u\xbcI\xb3,\xc2t\xaf\x9a\xbb\xea\x93\xb3Fs\x90\xb7\xed\xca}k<o\xfd\xda\x0c\xd8\x99\xbd\xc9D<~\xffJr\x17\xc8\xc1\x85\xff3\x0cI\xa2\xb3\xd9\xbb_\x1f\x14\x17|t\x95\xb6\xc5\x16\x12M\xedg\xfe>\x11\xcd\xb4=\x17\x83Z\xa9N\xa9WU\xbc%\x9f\xf6\x11#\xaa\x07\x1a\x87\xe7\xfct\x06:\x16pa\xf0y\x81W\x1e\xb5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05\xa0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x06\xc0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01/u`\xbd{\x90lGM\x9b\xf3\x91\xd6\x8e\xf0a\xbctJm{\xd0:\xba>|;\x17\xa2\xbe\xa6\xf3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x02\x1d\"\x96\xce\x0f\x821\x1b\xc2YS$S.\xd2\xe8J'\xab\xce.1\xce\x7f\xcb\x7f\xda^![\xb8\xe7$\xd070\x17|1\xc0\x93O?\x10\xa3Q\x0bMvnd\xd9\xdd\xc0\x19\0\xb0\x14\x0bo_\x13Y\xa7 \xf6\xfe\x92\xb2?1Y+4?\x96\xdc\xb5\x11\xde\x80\xd6\xde\xc2\x0c\xb8\x06\xd6m\x14V\xd8\xf1\xc3\xd5\x86\x0e\xd3\xf6.\xf9e\x9d\xca_\xde\x19\xd6\xab\x12\x99`\xe5\x15\x9f_\xd6~\xe3Z\x97\x07\x03\x0b\xba-yk\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0`\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x05\x10\xd4}\xad\x13\xd8\xc1\x9aB*\xc8\xc224\x1d]\xd3\xc4\x98\xc4E\xfc\xee\xe9\x1b\x01\x9c\x984\x13w\xe4\x0f\x14R\x9fKlY\x80\x1bz\xc4D\xb0e\xc9Z\xa7\xc4\xe1\xf3\x1dp\xbd\xbc\xe5\xaa\xc3\xbb\xc7\xdcjC 6\xcd\xfc\xa9\x0e\xdd\x95\xbb%\x0f\xd1='!F\xc4\xe9N\xd1\xeb\r|[\xa3C\xcc\xfb\xeax\xdb\x0b'2V\xc1+W\xff\xc7\x88\xc2\xd9|\x18\xc5\x81\x9b\x8c\xc0\xfd\xa1Dg\xa7\xf1vH\x93\x81\xc1\xec\xd7\x0f+\xb3hg]\x0eRdL\x9b\xa6J\xd6U\xb1f\xb2\xd9\x94\xdf\xba%\xa9#\xd7\x18\xeb\x1f+\xe8ZX&\x95\x96{q\xd6\xc7Fw\xdb$\n9\x10*\xd3\xebq\x9e\r\xff\xd5)\xfd\x8d\x81^\x8b\xc29\x86\x12\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x01\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x0f\xff\xff\x15\xda']\xde\x83\xef\x1a\x98\x9ff\xae\\\x99\x87\xdd\x95r\xe2\x9f\xbc\xc8\xdchA\x16\xac\xfc\xba\xf5\xb7\xce$\xd3\xe7\xbe\x0fw\xc9\xffet\xa2\x06i\xca\x99\xab\xd4;\x8e\x0f\xc4\xc6\xfb\xdd\x0f\x0f\x1bFBV\x8cE\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\xc0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0") }
thread 'async-std/runtime' panicked at 'called `Result::unwrap()` on an `Err` value: DecodingError(InvalidData)', /home/lulu/r/EspressoSystems/cape/eqs/src/eth_polling.rs:214:76
stack backtrace:
   0: rust_begin_unwind
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/panicking.rs:143:14
   2: core::result::unwrap_failed
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/result.rs:1749:5
   3: eqs::eth_polling::EthPolling::check_range::{{closure}}
   4: eqs::entry::run::{{closure}}
   5: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   6: async_task::raw::RawTask<F,T,S>::run
   7: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   8: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
   9: async_io::driver::block_on
  10: async_global_executor::reactor::block_on
  11: async_global_executor::threading::thread_main_loop
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.


let model_txns = cap_rust_sandbox::cape::CapeBlock::from(cape_block)
.into_cape_transactions()
.unwrap()
.0;

// TODO Instead of panicking here we need to handle cases of missing memos gracefully
let num_txn = model_txns.len();
let num_txn_memo = fetched_block_with_memos.memos.len();
let num_txn_memo = memos.len();
if num_txn != num_txn_memo {
panic!(
"Different number of txns and txn memos: {} vs {}",
Expand Down Expand Up @@ -276,7 +276,7 @@ impl EthPolling {

let memos_sig_valid: Vec<_> = model_txns
.iter()
.zip(fetched_block_with_memos.memos.iter())
.zip(memos.iter())
.map(|(tx, (recv_memos, sig))| {
match tx {
CapeModelTxn::CAP(note) => note.clone(),
Expand All @@ -298,8 +298,7 @@ impl EthPolling {
// Create LedgerEvent::Memos if memo signature is valid, skip otherwise
let mut memo_events = Vec::new();
let mut index = 0;
fetched_block_with_memos
.memos
memos
.iter()
.enumerate()
.filter_map(|(txn_id, (txn_memo, _))| match memos_sig_valid[txn_id] {
Expand Down