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
1 change: 1 addition & 0 deletions .github/actions/install-risc0/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ runs:

# Install RISC0 toolchain using specific version
$HOME/.risc0/bin/rzup install
$HOME/.risc0/bin/rzup install rust 1.81.0
$HOME/.risc0/bin/rzup install cargo-risczero ${{ inputs.version }}
$HOME/.risc0/bin/rzup install r0vm ${{ inputs.version }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
target
contract/src/Elf.sol
contract/src/ImageID.sol
contract/lib/
deployments/**/*.json
2 changes: 1 addition & 1 deletion contract/src/TopTradingCycle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ contract TopTradingCycle is ITopTradingCycle, ERC721Holder, Ownable, ReentrancyG
currentPhase = Phase.Trade;
} else if (currentPhase == Phase.Trade) {
// No duration check for Trade -> Withdraw
require(block.number - tradeInitiatedAtBlock > 250, "Can only manually set to Withdraw after 250 blocks with no proof");
//require(block.number - tradeInitiatedAtBlock > 250, "Can only manually set to Withdraw after 250 blocks with no proof");
currentPhase = Phase.Withdraw;
} else if (currentPhase == Phase.Withdraw) {
// Check that all NFTs have been withdrawn
Expand Down
78 changes: 55 additions & 23 deletions host/bin/demo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,22 @@ struct TestSetup {
fn make_token_preferences(
nft: Vec<Address>,
prefs: Preferences<U256>,
_max_preferences: usize,
) -> Preferences<ITopTradingCycle::Token> {
let mut rng = rand::thread_rng();
let m = prefs.prefs.keys().fold(HashMap::new(), |mut acc, k| {
let m: HashMap<&U256, Address> = prefs.prefs.keys().fold(HashMap::new(), |mut acc, k| {
let collection = nft.choose(&mut rng).unwrap();
acc.insert(k, *collection);
acc
});
prefs.clone().map(|v| {
let collection = m.get(&v).unwrap();
ITopTradingCycle::Token {
collection: *collection,
tokenId: v,
let collection = m.get(&v);
match collection {
None => panic!("No collection found for token id {:#}", v),
Some(c) => ITopTradingCycle::Token {
collection: *c,
tokenId: v,
},
}
})
}
Expand All @@ -68,7 +72,7 @@ impl TestSetup {
};
let addresses = checkpointer.load_deployed_contracts()?;
let actors = {
let prefs = make_token_preferences(addresses.nft, prefs);
let prefs = make_token_preferences(addresses.nft, prefs, config.max_preferences);
let actor_config = actor::Config {
node_url: node_url.clone(),
initial_balance: parse_ether(config.initial_balance.as_str()).unwrap(),
Expand All @@ -77,7 +81,9 @@ impl TestSetup {
};
actor::create_actors(actor_config, addresses.ttc, owner.clone(), prefs).await
}?;
let monitor = HttpClientBuilder::default().build(config.monitor_url()?)?;
let monitor = HttpClientBuilder::default()
.max_concurrent_requests(1)
.build(config.monitor_url()?)?;
Ok(Self {
config: config.clone(),
node_url: node_url.clone(),
Expand Down Expand Up @@ -115,14 +121,14 @@ impl TestSetup {

async fn deposit_tokens(&self) -> Result<()> {
// First do all approvals in parallel
let approval_futures = self
let mut approval_futures = self
.actors
.iter()
.map(|actor| {
let provider = create_provider(self.node_url.clone(), actor.wallet.clone());
let nft = TestNFT::new(actor.token.collection, provider.clone());
let ttc = ITopTradingCycle::new(self.ttc, provider);
async move {
Box::pin(async move {
let approval_tx = nft
.approve(self.ttc, actor.token.tokenId)
.send()
Expand All @@ -147,10 +153,17 @@ impl TestSetup {
})
.await;
Ok(())
}
})
})
.collect::<Vec<_>>();
futures::future::try_join_all(approval_futures).await?;

for chunk in approval_futures.chunks_mut(5) {
futures::future::try_join_all(chunk).await?;
info!(
"ApprovalFutures: Processed a chunk of 5 approvals, sleeping 3s before next chunk"
);
tokio::time::sleep(tokio::time::Duration::from_secs(3)).await;
}

for actor in self.actors.iter() {
let provider = create_provider(self.node_url.clone(), actor.wallet.clone());
Expand All @@ -168,13 +181,15 @@ impl TestSetup {
let token_owner = ttc.tokenOwners(actor.token.hash()).call().await?._0;
assert_eq!(token_owner, actor.address(), "Unexpected token owner!")
}
info!("ApprovalFutures: Checking matches, sleeping 100ms before next chunk");
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
}
Ok(())
}

// All of the actors set their preferences in the TTC contract
async fn set_preferences(&self) -> Result<()> {
let futures = self
let mut futures = self
.actors
.clone()
.into_iter()
Expand All @@ -186,7 +201,7 @@ impl TestSetup {
.iter()
.map(|t| t.hash())
.collect::<Vec<_>>();
async move {
Box::pin(async move {
let preferences_tx = ttc
.setPreferences(actor.token.hash(), prefs.clone())
.gas(self.config.base.max_gas)
Expand All @@ -199,6 +214,7 @@ impl TestSetup {
m.record_hist("setPreferences", preferences_tx.gas_used);
})
.await;
tokio::time::sleep(tokio::time::Duration::from_millis(100)).await;
let ps = ttc.getPreferences(actor.token.hash()).call().await?._0;
assert_eq!(ps, prefs, "Preferences not set correctly in contract!");
info!(
Expand All @@ -211,11 +227,18 @@ impl TestSetup {
.collect::<Vec<_>>()
);
Ok(())
}
})
})
.collect::<Vec<_>>();

futures::future::try_join_all(futures).await?;
for chunk in futures.chunks_mut(5) {
futures::future::try_join_all(chunk).await?;
info!(
"SetPreferences: Processed a chunk of 5 approvals, sleeping 2s before next chunk"
);
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
}

Ok(())
}

Expand Down Expand Up @@ -270,13 +293,13 @@ impl TestSetup {
async fn withraw(&self, trade_results: &TradeResults) -> Result<()> {
info!("assert that the stable actors kept their tokens");
{
let futures = trade_results
let mut futures = trade_results
.stable
.iter()
.map(|actor| {
let provider = create_provider(self.node_url.clone(), actor.wallet.clone());
let ttc = ITopTradingCycle::new(self.ttc, provider.clone());
async move {
Box::pin(async move {
info!(
"Withdrawing token {:#} for existing owner {:#}",
actor.token.hash(),
Expand All @@ -295,22 +318,26 @@ impl TestSetup {
})
.await;
Ok(())
}
})
})
.collect::<Vec<_>>();

futures::future::try_join_all(futures).await?;
for chunk in futures.chunks_mut(5) {
futures::future::try_join_all(chunk).await?;
info!("Withdraw: Processed a chunk of 5 approvals, sleeping 2s before next chunk");
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
}
}

info!("assert that the trading actors get their new tokens");
{
let futures = trade_results
let mut futures = trade_results
.traders
.iter()
.map(|(actor, new_token_hash)| {
let provider = create_provider(self.node_url.clone(), actor.wallet.clone());
let ttc = ITopTradingCycle::new(self.ttc, provider.clone());
async move {
Box::pin(async move {
info!(
"Withdrawing token {:#} for new owner {:#}",
new_token_hash,
Expand All @@ -329,11 +356,15 @@ impl TestSetup {
})
.await;
Ok(())
}
})
})
.collect::<Vec<_>>();

futures::future::try_join_all(futures).await?;
for chunk in futures.chunks_mut(5) {
futures::future::try_join_all(chunk).await?;
info!("Withdraw check: Processed a chunk of 5 approvals, sleeping 2s before next chunk");
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
}
}

Ok(())
Expand Down Expand Up @@ -474,6 +505,7 @@ async fn main() -> Result<()> {
let checkpointer_root_dir = Path::new(&config.base.artifacts_dir);
Checkpointer::new(checkpointer_root_dir, config.ttc_address)
};

let test_case = {
let mut runner = TestRunner::default();
let strategy = (Preferences::<u64>::arbitrary_with(Some(
Expand Down
16 changes: 12 additions & 4 deletions host/src/actor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,14 +117,14 @@ pub async fn create_actors(
let start_nonce = provider.get_transaction_count(owner.address()).await?;
let ds = make_actors_data(&config, prefs);

let futures: Vec<_> = ds
let mut futures: Vec<_> = ds
.into_iter()
.enumerate()
.map(|(i, actor_data)| {
let ttc = ITopTradingCycle::new(ttc, &provider);
let config = config.clone();
let owner = owner.clone();
async move {
Box::pin(async move {
let a = Actor::new(
config,
owner,
Expand All @@ -142,11 +142,19 @@ pub async fn create_actors(
);
}
Ok(a)
}
})
})
.collect();

futures::future::try_join_all(futures).await
let mut actors = Vec::new();
for chunk in futures.chunks_mut(5) {
let chunk_results = futures::future::try_join_all(chunk).await?;
actors.extend(chunk_results);
info!("CreateActor: Processed a chunk of 5 approvals, sleeping 2s before next chunk");
tokio::time::sleep(tokio::time::Duration::from_secs(2)).await;
}

Ok(actors)
}

#[derive(Clone)]
Expand Down
3 changes: 3 additions & 0 deletions host/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ pub struct DemoConfig {
#[arg(long, env = "NUM_ACTORS", default_value_t = 10)]
pub num_actors: usize,

#[arg(long, env = "MAX_PREFERENCES", default_value_t = 3)]
pub max_preferences: usize,

/// Initial ETH balance for new accounts
#[arg(long, env = "INITIAL_BALANCE", default_value = "5")]
pub initial_balance: String,
Expand Down
4 changes: 2 additions & 2 deletions ttc/src/strict.rs
Original file line number Diff line number Diff line change
Expand Up @@ -270,9 +270,9 @@ pub mod test_utils {
.prop_flat_map(|vertices| {
let vertices: Vec<V> = vertices.into_iter().collect();
let len = vertices.len();
let m = (3 * len) / 2;
let m = len / 5;
// we include more indices in order to increase the likelihood of trades
prop::collection::vec(prop::collection::vec(0..len, 0..=m), len).prop_map(
prop::collection::vec(prop::collection::vec(0..len, m..=m), len).prop_map(
move |subsets| Preferences {
prefs: vertices
.iter()
Expand Down
Loading