Skip to content
Merged
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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ When the DVF is finished, you can sign it using the following command:
dv sign new.dvf.json
```

If you do not wish to sign the DVF, you can instead finalize it by generating an ID:
DVFs automatically get an ID when they are created. When you change the contents of the DVF, the ID has to be regenerated. When signing, this is automatically done. However, in some circumstances, you might not want to sign the DVF. In that case, you can regenerate the ID as follows:

```
dv id new.dvf.json
Expand Down
157 changes: 61 additions & 96 deletions lib/dvf/parse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,29 +174,6 @@ impl fmt::Display for ValidationError {
}
}

pub trait BasicDVF: Serialize {
fn check_version(&self) -> Result<(), ValidationError> {
let version = self.get_version();
if version < &LOWEST_SUPPORTED_VERSION {
return Err(ValidationError::Error("DV Version too old.".to_string()));
}
if version > &HIGHEST_SUPPORTED_VERSION {
return Err(ValidationError::Error("DV Version too new.".to_string()));
}
Ok(())
}

fn get_version(&self) -> &Version;

fn write_to_file(&self, path: &Path) -> Result<(), ValidationError> {
let output = serde_json::to_string_pretty(&self)?;

let mut file = File::create(path)?;
file.write_all(output.as_bytes())?;
Ok(())
}
}

fn bytes_to_hex<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
where
T: AsRef<[u8]>,
Expand Down Expand Up @@ -351,48 +328,82 @@ pub struct Unvalidated {
implementation_address: Option<Address>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct DumpedDVF {
version: Version,
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DVFSignature {
pub sig_data: Option<String>,
pub signer: Address,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct NamedReference {
pub id: String,
pub contract_name: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CompleteDVF {
pub version: Version,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub contract_name: String,
pub address: Address,
pub chain_id: u64,
pub deployment_block_num: u64,
pub init_block_num: u64,
pub deployment_tx: String,
pub codehash: String,
pub insecure: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub insecure: Option<bool>,
pub immutables: Vec<DVFImmutableEntry>,
pub constructor_args: Vec<DVFConstructorArg>,
pub critical_storage_variables: Vec<DVFStorageEntry>,
pub critical_events: Vec<DVFEventEntry>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expiry_in_epoch_seconds: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub references: Option<Vec<NamedReference>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unvalidated_metadata: Option<Unvalidated>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature: Option<DVFSignature>,
}

impl DumpedDVF {
impl CompleteDVF {
pub fn from_path(path: &Path) -> Result<Self, ValidationError> {
let mut file = File::open(path)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
debug!("{}", content);

let filled: CompleteDVF = serde_json::from_str(&content)?;
filled.check_version()?;

Ok(filled)
}

pub fn from_cli(matches: &ArgMatches) -> Result<Self, ValidationError> {
let immutables: Vec<DVFImmutableEntry> = vec![];
let critical_storage_variables: Vec<DVFStorageEntry> = vec![];
let critical_events: Vec<DVFEventEntry> = vec![];
let constructor_args: Vec<DVFConstructorArg> = vec![];
let implementation_name = matches.get_one::<String>("implementation").cloned();
let dumped = DumpedDVF {
let dumped = CompleteDVF {
version: CURRENT_VERSION,
id: None,
contract_name: matches.get_one::<String>("contractname").unwrap().clone(),
address: *matches.get_one::<Address>("address").unwrap(),
chain_id: *matches.get_one("chainid").unwrap(),
codehash: String::new(),
deployment_tx: String::new(),
deployment_block_num: 0,
init_block_num: 0,
insecure: false,
insecure: Some(false),
immutables,
constructor_args,
critical_storage_variables,
critical_events,
expiry_in_epoch_seconds: None,
references: None,
unvalidated_metadata: Some(Unvalidated {
author_name: Some(String::from("Author")),
description: Some(String::from("System Description")),
Expand All @@ -403,15 +414,12 @@ impl DumpedDVF {
implementation_name,
implementation_address: None, // currently no source for this
}),
signature: None,
};
dumped.check_version()?;
Ok(dumped)
}

pub fn get_fname(&self) -> String {
format!("dumped_{:?}.dvf.json", &self.address)
}

pub fn copy_immutables(&mut self, project_info: &ProjectInfo, pretty_printer: &PrettyPrinter) {
self.immutables = project_info
.immutables
Expand Down Expand Up @@ -460,66 +468,6 @@ impl DumpedDVF {
})
.collect::<Vec<DVFConstructorArg>>();
}
}

impl BasicDVF for DumpedDVF {
fn get_version(&self) -> &Version {
&self.version
}
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DVFSignature {
pub sig_data: Option<String>,
pub signer: Address,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct NamedReference {
pub id: String,
pub contract_name: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct CompleteDVF {
pub version: Version,
#[serde(skip_serializing_if = "Option::is_none")]
pub id: Option<String>,
pub contract_name: String,
pub address: Address,
pub chain_id: u64,
pub deployment_block_num: u64,
pub init_block_num: u64,
pub deployment_tx: String,
pub codehash: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub insecure: Option<bool>,
pub immutables: Vec<DVFImmutableEntry>,
pub constructor_args: Vec<DVFConstructorArg>,
pub critical_storage_variables: Vec<DVFStorageEntry>,
pub critical_events: Vec<DVFEventEntry>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expiry_in_epoch_seconds: Option<u64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub references: Option<Vec<NamedReference>>,
#[serde(skip_serializing_if = "Option::is_none")]
pub unvalidated_metadata: Option<Unvalidated>,
#[serde(skip_serializing_if = "Option::is_none")]
pub signature: Option<DVFSignature>,
}

impl CompleteDVF {
pub fn from_path(path: &Path) -> Result<Self, ValidationError> {
let mut file = File::open(path)?;
let mut content = String::new();
file.read_to_string(&mut content)?;
debug!("{}", content);

let filled: CompleteDVF = serde_json::from_str(&content)?;
filled.check_version()?;

Ok(filled)
}

pub fn add_reference(&mut self, new_ref_id: &str, new_ref_name: &str) {
let named_ref = NamedReference {
Expand Down Expand Up @@ -688,9 +636,26 @@ impl CompleteDVF {
None => String::from("generated.dvf.json"),
}
}
}

impl BasicDVF for CompleteDVF {
fn check_version(&self) -> Result<(), ValidationError> {
let version = self.get_version();
if version < &LOWEST_SUPPORTED_VERSION {
return Err(ValidationError::Error("DV Version too old.".to_string()));
}
if version > &HIGHEST_SUPPORTED_VERSION {
return Err(ValidationError::Error("DV Version too new.".to_string()));
}
Ok(())
}

pub fn write_to_file(&self, path: &Path) -> Result<(), ValidationError> {
let output = serde_json::to_string_pretty(&self)?;

let mut file = File::create(path)?;
file.write_all(output.as_bytes())?;
Ok(())
}

fn get_version(&self) -> &Version {
&self.version
}
Expand Down
5 changes: 3 additions & 2 deletions src/dvf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use dvf_libs::bytecode_verification::compare_bytecodes::{CompareBytecode, Compar
use dvf_libs::bytecode_verification::parse_json::{Environment, ProjectInfo};
use dvf_libs::bytecode_verification::verify_bytecode;
use dvf_libs::dvf::config::{replace_tilde, DVFConfig};
use dvf_libs::dvf::parse::{self, BasicDVF, ValidationError, CURRENT_VERSION_STRING};
use dvf_libs::dvf::parse::{self, ValidationError, CURRENT_VERSION_STRING};
use dvf_libs::dvf::registry::{self, Registry};
use dvf_libs::state::contract_state::ContractState;
use dvf_libs::state::forge_inspect::{self, StateVariable, TypeDescription};
Expand Down Expand Up @@ -998,7 +998,7 @@ fn process(matches: ArgMatches) -> Result<(), ValidationError> {
user_output_path
};

let mut dumped = parse::DumpedDVF::from_cli(sub_m)?;
let mut dumped = parse::CompleteDVF::from_cli(sub_m)?;
config.set_chain_id(dumped.chain_id)?;

let registry = registry::Registry::from_config(&config)?;
Expand Down Expand Up @@ -1388,6 +1388,7 @@ fn process(matches: ArgMatches) -> Result<(), ValidationError> {
"{}. Decide if this validation should have an expiry date. Also you can fill in additional, unvalidated metadata.", pc
);

dumped.generate_id()?;
dumped.write_to_file(output_path)?;
println!("Wrote DVF to {}!", output_path.display());
exit(0);
Expand Down
1 change: 0 additions & 1 deletion src/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,6 @@ fn fetch(matches: &ArgMatches) -> Result<(), ValidationError> {
let forge_init_out = Command::new("forge")
.current_dir(foundry_path)
.arg("init")
.arg("--no-commit")
.output()
.unwrap();
if !forge_init_out.status.success() {
Expand Down
10 changes: 5 additions & 5 deletions tests/expected_dvfs/AllValueTypes.dvf.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"version": "0.9.1",
"id": "0x75b09431c899db2042cfe484d8db8442ab7d6f0c39851b8c79ec02d22b0852ca",
"contract_name": "AllValueTypes",
"address": "0x5fbdb2315678afecb367f032d93f642f64180aa3",
"chain_id": 31337,
"deployment_block_num": 1,
"chain_id": 1337,
"deployment_block_num": 2,
"init_block_num": 4,
"deployment_tx": "0x4c0eda23fa858c9ec88a7004c80c78a606561025d2d8b2c85f825957cab8fc9b",
"deployment_tx": "0xa4d8274d878bbd569325fa0f6ff44503319eea7c8f8debae356e4c4e9e4ecf2a",
"codehash": "0xc5f9a009f6b4fe853fa6d949876dedd2594d797a7aa57fcf9c58031f7911dfe5",
"insecure": false,
"immutables": [],
Expand Down Expand Up @@ -1722,7 +1723,6 @@
}
],
"critical_events": [],
"expiry_in_epoch_seconds": null,
"unvalidated_metadata": {
"author_name": "Author",
"description": "System Description",
Expand All @@ -1734,4 +1734,4 @@
"source_url": "https://github.com/source/code",
"security_contact": "security@example.org"
}
}
}
8 changes: 4 additions & 4 deletions tests/expected_dvfs/CrazyHiddenStruct.dvf.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"version": "0.9.1",
"id": "0xae089608b66548be52d5d573af2f46bf32591d45b990f1945ec879c1d9fa3766",
"contract_name": "CrazyHiddenStruct",
"address": "0x5fbdb2315678afecb367f032d93f642f64180aa3",
"chain_id": 31337,
"deployment_block_num": 1,
"chain_id": 1337,
"deployment_block_num": 2,
"init_block_num": 4,
"deployment_tx": "0x63940866317040d31a0739fe1bbf6199eed3bddc5ae96e0944c00620fa3bbf60",
"deployment_tx": "0x43a6f8eca22724591b2256ccbb6969d99ccf29b120b611cbd86aeb408b51d76a",
"codehash": "0xc5f9a009f6b4fe853fa6d949876dedd2594d797a7aa57fcf9c58031f7911dfe5",
"insecure": false,
"immutables": [],
Expand Down Expand Up @@ -532,7 +533,6 @@
}
],
"critical_events": [],
"expiry_in_epoch_seconds": null,
"unvalidated_metadata": {
"author_name": "Author",
"description": "System Description",
Expand Down
10 changes: 5 additions & 5 deletions tests/expected_dvfs/Deploy_0.dvf.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"version": "0.9.1",
"id": "0xd5c2ba6466b7c6138861f139a9c71fc2c62202a847c354eed6084bbb8fd93c0c",
"contract_name": "BytesMapping",
"address": "0x5fbdb2315678afecb367f032d93f642f64180aa3",
"chain_id": 31337,
"deployment_block_num": 1,
"chain_id": 1337,
"deployment_block_num": 2,
"init_block_num": 4,
"deployment_tx": "0x59c8b137812162541e4fdcc68f3072ce16a5ed7793565af73af88cced3ce20e6",
"deployment_tx": "0x11819f70620f7d3a7a69eee5e9ad55cedec78c9fc5a83ab743fdec42a77ab504",
"codehash": "0x3867a08d0f6ad7f18a522cb18383fa3eb688bbde257d84652a614fda9167b190",
"insecure": false,
"immutables": [],
Expand Down Expand Up @@ -76,7 +77,6 @@
]
}
],
"expiry_in_epoch_seconds": null,
"unvalidated_metadata": {
"author_name": "Author",
"description": "System Description",
Expand All @@ -88,4 +88,4 @@
"source_url": "https://github.com/source/code",
"security_contact": "security@example.org"
}
}
}
10 changes: 5 additions & 5 deletions tests/expected_dvfs/Deploy_0_b1.dvf.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
{
"version": "0.9.1",
"id": "0x4904d0056d9b5ffe89e7e2daeeb7134331ccc30b933f6a94f63867dc08686439",
"contract_name": "BytesMapping",
"address": "0x5fbdb2315678afecb367f032d93f642f64180aa3",
"chain_id": 31337,
"deployment_block_num": 1,
"chain_id": 1337,
"deployment_block_num": 2,
"init_block_num": 2,
"deployment_tx": "0x59c8b137812162541e4fdcc68f3072ce16a5ed7793565af73af88cced3ce20e6",
"deployment_tx": "0x11819f70620f7d3a7a69eee5e9ad55cedec78c9fc5a83ab743fdec42a77ab504",
"codehash": "0x3867a08d0f6ad7f18a522cb18383fa3eb688bbde257d84652a614fda9167b190",
"insecure": false,
"immutables": [],
Expand Down Expand Up @@ -51,7 +52,6 @@
"occurrences": []
}
],
"expiry_in_epoch_seconds": null,
"unvalidated_metadata": {
"author_name": "Author",
"description": "System Description",
Expand All @@ -63,4 +63,4 @@
"source_url": "https://github.com/source/code",
"security_contact": "security@example.org"
}
}
}
Loading
Loading