fix(solc): consistent serde for linked and unlinked bytecode (#948)
This commit is contained in:
parent
1f822e47e6
commit
60515d9404
|
@ -1592,6 +1592,7 @@ pub enum BytecodeObject {
|
|||
#[serde(deserialize_with = "serde_helpers::deserialize_bytes")]
|
||||
Bytecode(Bytes),
|
||||
/// Bytecode as hex string that's not fully linked yet and contains library placeholders
|
||||
#[serde(with = "serde_helpers::string_bytes")]
|
||||
Unlinked(String),
|
||||
}
|
||||
|
||||
|
@ -1612,6 +1613,13 @@ impl BytecodeObject {
|
|||
BytecodeObject::Unlinked(_) => None,
|
||||
}
|
||||
}
|
||||
/// Returns a reference to the underlying `String` if the object is unlinked
|
||||
pub fn as_str(&self) -> Option<&str> {
|
||||
match self {
|
||||
BytecodeObject::Bytecode(_) => None,
|
||||
BytecodeObject::Unlinked(s) => Some(s.as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the unlinked `String` if the object is unlinked or empty
|
||||
pub fn into_unlinked(self) -> Option<String> {
|
||||
|
@ -1715,10 +1723,10 @@ impl BytecodeObject {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns a not deployable bytecode by default as "0x"
|
||||
// Returns a not deployable bytecode by default as empty
|
||||
impl Default for BytecodeObject {
|
||||
fn default() -> Self {
|
||||
BytecodeObject::Unlinked("0x".to_string())
|
||||
BytecodeObject::Unlinked("".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -77,6 +77,34 @@ pub mod json_string_opt {
|
|||
}
|
||||
}
|
||||
|
||||
/// serde support for string
|
||||
pub mod string_bytes {
|
||||
use serde::{Deserialize, Deserializer, Serializer};
|
||||
|
||||
pub fn serialize<S>(value: &String, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
if value.starts_with("0x") {
|
||||
serializer.serialize_str(value.as_str())
|
||||
} else {
|
||||
serializer.serialize_str(&format!("0x{}", value))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D>(deserializer: D) -> Result<String, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let value = String::deserialize(deserializer)?;
|
||||
if let Some(rem) = value.strip_prefix("0x") {
|
||||
Ok(rem.to_string())
|
||||
} else {
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub mod display_from_str_opt {
|
||||
use serde::{de, Deserialize, Deserializer, Serializer};
|
||||
use std::{fmt, str::FromStr};
|
||||
|
|
|
@ -496,7 +496,7 @@ fn can_detect_type_error() {
|
|||
fn can_compile_single_files() {
|
||||
let tmp = TempProject::dapptools().unwrap();
|
||||
|
||||
let foo = tmp
|
||||
let f = tmp
|
||||
.add_contract(
|
||||
"examples/Foo",
|
||||
r#"
|
||||
|
@ -507,7 +507,7 @@ fn can_compile_single_files() {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let compiled = tmp.project().compile_file(foo.clone()).unwrap();
|
||||
let compiled = tmp.project().compile_file(f.clone()).unwrap();
|
||||
assert!(!compiled.has_compiler_errors());
|
||||
assert!(compiled.find("Foo").is_some());
|
||||
|
||||
|
@ -522,8 +522,43 @@ fn can_compile_single_files() {
|
|||
)
|
||||
.unwrap();
|
||||
|
||||
let compiled = tmp.project().compile_files(vec![foo, bar]).unwrap();
|
||||
let compiled = tmp.project().compile_files(vec![f, bar]).unwrap();
|
||||
assert!(!compiled.has_compiler_errors());
|
||||
assert!(compiled.find("Foo").is_some());
|
||||
assert!(compiled.find("Bar").is_some());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn consistent_bytecode() {
|
||||
let tmp = TempProject::dapptools().unwrap();
|
||||
|
||||
tmp.add_source(
|
||||
"LinkTest",
|
||||
r#"
|
||||
// SPDX-License-Identifier: MIT
|
||||
library LibTest {
|
||||
function foobar(uint256 a) public view returns (uint256) {
|
||||
return a * 100;
|
||||
}
|
||||
}
|
||||
contract LinkTest {
|
||||
function foo() public returns (uint256) {
|
||||
return LibTest.foobar(1);
|
||||
}
|
||||
}
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let compiled = tmp.compile().unwrap();
|
||||
assert!(!compiled.has_compiler_errors());
|
||||
|
||||
let contract = compiled.find("LinkTest").unwrap();
|
||||
let bytecode = &contract.bytecode.as_ref().unwrap().object;
|
||||
assert!(bytecode.is_unlinked());
|
||||
let s = bytecode.as_str().unwrap();
|
||||
assert!(!s.starts_with("0x"));
|
||||
|
||||
let s = serde_json::to_string(&bytecode).unwrap();
|
||||
assert_eq!(bytecode.clone(), serde_json::from_str(&s).unwrap());
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue