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
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ dv init --project <PROJECT_PATH> --address <ADDRESS> --contractname <NAME> --ini

Please note that `<B>` must be equal to or larger than the deployment block of the contract. Additionally, it is recommended to use only block numbers of **finalized blocks** in order to prevent the DVF containing wrong data due to possible re-orgs in the future.

By default, `dv` looks at all transactions starting from the deployment block. If you want to restrict the transaction lookup to a later starting block (e.g., to skip transactions before a contract upgrade), you can pass the desired block number with `--startblock`:

```
dv init --project <PROJECT_PATH> --address <ADDRESS> --contractname <NAME> --startblock <S> new.dvf.json
```

`<S>` must be equal to or larger than the deployment block and equal to or smaller than the init block.

Sometimes, you might want to know when a storage variable has been initialized before but then reset back to zero. You can add such variables to the DVF with the `--zerovalue` flag:

```
Expand Down
23 changes: 14 additions & 9 deletions lib/dvf/discovery.rs
Original file line number Diff line number Diff line change
Expand Up @@ -484,16 +484,21 @@ pub fn get_tx_hashes(
let mut seen_events: Vec<Log> = vec![];
let tx_hashes: Vec<String> = if let Some(event_topics) = &event_topics {
print_progress("Obtaining past events and transactions.", pc, progress_mode);
seen_events = web3::get_eth_events(
config,
address,
start_block_num,
end_block_num,
event_topics,
)?;
for topic in event_topics {
let mut topic_events = web3::get_eth_events_paginated(
config,
address,
start_block_num,
end_block_num,
&vec![*topic],
)?;
seen_events.append(&mut topic_events);
}
let mut seen_hashes = HashSet::new();
seen_events
.iter()
.filter_map(|e| e.transaction_hash.map(|h| format!("{h:#x}")))
.filter(|h| seen_hashes.insert(h.clone()))
.collect()
} else {
print_progress("Obtaining past transactions.", pc, progress_mode);
Expand All @@ -506,7 +511,7 @@ pub fn get_tx_hashes(
pub fn create_discovery_params_for_init<'a>(
config: &'a DVFConfig,
dumped: &'a parse::CompleteDVF,
deployment_block_num: u64,
start_block_num: u64,
init_block_num: u64,
project: &'a PathBuf,
artifacts: &'a str,
Expand All @@ -523,7 +528,7 @@ pub fn create_discovery_params_for_init<'a>(
config,
contract_name: &dumped.contract_name,
address: &dumped.address,
start_block_num: deployment_block_num,
start_block_num,
end_block_num: init_block_num,
project: Some(project),
artifacts,
Expand Down
4 changes: 3 additions & 1 deletion lib/state/contract_state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,9 @@ impl<'a> ContractState<'a> {
fn memory_as_string(memory: &Vec<String>) -> String {
let mut mem_string = String::new();
for mem in memory {
mem_string += mem;
// Some RPC nodes (e.g., Anvil) return memory chunks with a "0x" prefix;
// strip it so the concatenated string is pure hex.
mem_string += mem.strip_prefix("0x").unwrap_or(mem);
}

mem_string
Expand Down
34 changes: 32 additions & 2 deletions src/dvf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,11 @@ fn main() {
.help("The block number at which the state snapshot should be taken.")
.value_parser(is_valid_blocknum),
)
.arg(
arg!(--startblock <BLOCK>)
.help("The first block to look at for transactions (defaults to deployment block).")
.value_parser(is_valid_blocknum),
)
.arg(
arg!(--project <PATH>)
.help("Path to the root folder of the source code project")
Expand Down Expand Up @@ -763,6 +768,12 @@ fn main() {
.help("Folder containing the artifacts")
.default_value("artifacts"),
)
.arg(
arg!(--libraries <LIBRARY> ...)
.help("Library specifiers in the form Path:Name:Address. Accepts comma-separated values or repeated flags")
.value_delimiter(',')
.action(clap::ArgAction::Append),
)
.arg(arg!(--buildcache <PATH>).help("Folder containing build-info files")),
)
.subcommand(
Expand Down Expand Up @@ -932,9 +943,28 @@ fn process(matches: ArgMatches) -> Result<(), ValidationError> {
dumped.deployment_block_num = deployment_block_num;
dumped.deployment_tx = deployment_tx;

let start_block_num = *sub_m
.get_one::<u64>("startblock")
.unwrap_or(&deployment_block_num);
if start_block_num < deployment_block_num {
return Err(ValidationError::from(
"Start block must be greater than or equal to the deployment block.",
));
}

let default_init_block = if sub_m.contains_id("startblock") {
start_block_num
} else {
deployment_block_num + 1
};
let init_block_num = *sub_m
.get_one::<u64>("initblock")
.unwrap_or(&(deployment_block_num + 1));
.unwrap_or(&default_init_block);
if init_block_num < start_block_num {
return Err(ValidationError::from(
"Init block must be greater than or equal to the start block.",
));
}
dumped.init_block_num = init_block_num;

let mut pc = 1_u64;
Expand Down Expand Up @@ -1030,7 +1060,7 @@ fn process(matches: ArgMatches) -> Result<(), ValidationError> {
} = discover_storage_and_events(create_discovery_params_for_init(
&config,
&dumped,
deployment_block_num,
start_block_num,
init_block_num,
project,
artifacts,
Expand Down
53 changes: 0 additions & 53 deletions test1.json

This file was deleted.