refactor: move brother_node development artifact to dev/test-nodes subdirectory
Development Artifact Cleanup: ✅ BROTHER_NODE REORGANIZATION: Moved development test node to appropriate location - dev/test-nodes/brother_node/: Moved from root directory for better organization - Contains development configuration, test logs, and test chain data - No impact on production systems - purely development/testing artifact ✅ DEVELOPMENT ARTIFACTS IDENTIFIED: - Chain ID: aitbc-brother-chain (test/development chain) - Ports: 8010 (P2P) and 8011 (RPC) - different from production - Environment: .env file with test configuration - Logs: rpc.log and node.log from development testing session (March 15, 2026) ✅ ROOT DIRECTORY CLEANUP: Removed development clutter from production directory - brother_node/ moved to dev/test-nodes/brother_node/ - Root directory now contains only production-ready components - Development artifacts properly organized in dev/ subdirectory DIRECTORY STRUCTURE IMPROVEMENT: 📁 dev/test-nodes/: Development and testing node configurations 🏗️ Root Directory: Clean production structure with only essential components 🧪 Development Isolation: Test environments separated from production BENEFITS: ✅ Clean Production Directory: No development artifacts in root ✅ Better Organization: Development nodes grouped in dev/ subdirectory ✅ Clear Separation: Production vs development environments clearly distinguished ✅ Maintainability: Easier to identify and manage development components RESULT: Successfully moved brother_node development artifact to dev/test-nodes/ subdirectory, cleaning up the root directory while preserving development testing environment for future use.
This commit is contained in:
61
dev/env/node_modules/@nomicfoundation/edr/src/trace/debug.rs
generated
vendored
Executable file
61
dev/env/node_modules/@nomicfoundation/edr/src/trace/debug.rs
generated
vendored
Executable file
@@ -0,0 +1,61 @@
|
||||
//! Port of `hardhat-network/stack-traces/debug.ts` from Hardhat.
|
||||
|
||||
use napi::bindgen_prelude::Either25;
|
||||
use napi_derive::napi;
|
||||
|
||||
use super::solidity_stack_trace::{RevertErrorStackTraceEntry, SolidityStackTrace};
|
||||
use crate::trace::return_data::ReturnData;
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
fn print_stack_trace(trace: SolidityStackTrace) -> napi::Result<()> {
|
||||
let entry_values = trace
|
||||
.into_iter()
|
||||
.map(|entry| match entry {
|
||||
Either25::A(entry) => serde_json::to_value(entry),
|
||||
Either25::B(entry) => serde_json::to_value(entry),
|
||||
Either25::C(entry) => serde_json::to_value(entry),
|
||||
Either25::D(entry) => serde_json::to_value(entry),
|
||||
Either25::F(entry) => serde_json::to_value(entry),
|
||||
Either25::G(entry) => serde_json::to_value(entry),
|
||||
Either25::H(entry) => serde_json::to_value(entry),
|
||||
Either25::I(entry) => serde_json::to_value(entry),
|
||||
Either25::J(entry) => serde_json::to_value(entry),
|
||||
Either25::K(entry) => serde_json::to_value(entry),
|
||||
Either25::L(entry) => serde_json::to_value(entry),
|
||||
Either25::M(entry) => serde_json::to_value(entry),
|
||||
Either25::N(entry) => serde_json::to_value(entry),
|
||||
Either25::O(entry) => serde_json::to_value(entry),
|
||||
Either25::P(entry) => serde_json::to_value(entry),
|
||||
Either25::Q(entry) => serde_json::to_value(entry),
|
||||
Either25::R(entry) => serde_json::to_value(entry),
|
||||
Either25::S(entry) => serde_json::to_value(entry),
|
||||
Either25::T(entry) => serde_json::to_value(entry),
|
||||
Either25::U(entry) => serde_json::to_value(entry),
|
||||
Either25::V(entry) => serde_json::to_value(entry),
|
||||
Either25::W(entry) => serde_json::to_value(entry),
|
||||
Either25::X(entry) => serde_json::to_value(entry),
|
||||
Either25::Y(entry) => serde_json::to_value(entry),
|
||||
// Decode the error message from the return data
|
||||
Either25::E(entry @ RevertErrorStackTraceEntry { .. }) => {
|
||||
use serde::de::Error;
|
||||
|
||||
let decoded_error_msg = ReturnData::new(entry.return_data.clone())
|
||||
.decode_error()
|
||||
.map_err(|e| {
|
||||
serde_json::Error::custom(format_args!("Error decoding return data: {e}"))
|
||||
})?;
|
||||
|
||||
let mut value = serde_json::to_value(entry)?;
|
||||
if let Some(obj) = value.as_object_mut() {
|
||||
obj.insert("message".to_string(), decoded_error_msg.into());
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
})
|
||||
.collect::<Result<Vec<_>, _>>()
|
||||
.map_err(|e| napi::Error::from_reason(format!("Error converting to JSON: {e}")))?;
|
||||
|
||||
println!("{}", serde_json::to_string_pretty(&entry_values)?);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
89
dev/env/node_modules/@nomicfoundation/edr/src/trace/exit.rs
generated
vendored
Executable file
89
dev/env/node_modules/@nomicfoundation/edr/src/trace/exit.rs
generated
vendored
Executable file
@@ -0,0 +1,89 @@
|
||||
//! Naive rewrite of `hardhat-network/provider/vm/exit.ts` from Hardhat.
|
||||
//! Used together with `VmTracer`.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use edr_chain_spec::EvmHaltReason;
|
||||
use napi_derive::napi;
|
||||
|
||||
#[napi]
|
||||
pub struct Exit(pub(crate) ExitCode);
|
||||
|
||||
#[napi]
|
||||
/// Represents the exit code of the EVM.
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
#[allow(clippy::upper_case_acronyms, non_camel_case_types)] // These are exported and mapped 1:1 to existing JS enum
|
||||
pub enum ExitCode {
|
||||
/// Execution was successful.
|
||||
SUCCESS = 0,
|
||||
/// Execution was reverted.
|
||||
REVERT,
|
||||
/// Execution ran out of gas.
|
||||
OUT_OF_GAS,
|
||||
/// Execution encountered an internal error.
|
||||
INTERNAL_ERROR,
|
||||
/// Execution encountered an invalid opcode.
|
||||
INVALID_OPCODE,
|
||||
/// Execution encountered a stack underflow.
|
||||
STACK_UNDERFLOW,
|
||||
/// Create init code size exceeds limit (runtime).
|
||||
CODESIZE_EXCEEDS_MAXIMUM,
|
||||
/// Create collision.
|
||||
CREATE_COLLISION,
|
||||
/// Unknown halt reason.
|
||||
UNKNOWN_HALT_REASON,
|
||||
}
|
||||
|
||||
impl fmt::Display for ExitCode {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
ExitCode::SUCCESS => write!(f, "Success"),
|
||||
ExitCode::REVERT => write!(f, "Reverted"),
|
||||
ExitCode::OUT_OF_GAS => write!(f, "Out of gas"),
|
||||
ExitCode::INTERNAL_ERROR => write!(f, "Internal error"),
|
||||
ExitCode::INVALID_OPCODE => write!(f, "Invalid opcode"),
|
||||
ExitCode::STACK_UNDERFLOW => write!(f, "Stack underflow"),
|
||||
ExitCode::CODESIZE_EXCEEDS_MAXIMUM => write!(f, "Codesize exceeds maximum"),
|
||||
ExitCode::CREATE_COLLISION => write!(f, "Create collision"),
|
||||
ExitCode::UNKNOWN_HALT_REASON => write!(f, "Unknown halt reason"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::fallible_impl_from)] // naively ported for now
|
||||
impl From<edr_solidity::exit_code::ExitCode<EvmHaltReason>> for ExitCode {
|
||||
fn from(code: edr_solidity::exit_code::ExitCode<EvmHaltReason>) -> Self {
|
||||
use edr_solidity::exit_code::ExitCode;
|
||||
|
||||
match code {
|
||||
ExitCode::Success => Self::SUCCESS,
|
||||
ExitCode::Revert => Self::REVERT,
|
||||
ExitCode::Halt(EvmHaltReason::OutOfGas(_)) => Self::OUT_OF_GAS,
|
||||
ExitCode::Halt(EvmHaltReason::OpcodeNotFound | EvmHaltReason::InvalidFEOpcode
|
||||
// Returned when an opcode is not implemented for the hardfork
|
||||
| EvmHaltReason::NotActivated) => Self::INVALID_OPCODE,
|
||||
ExitCode::Halt(EvmHaltReason::StackUnderflow) => Self::STACK_UNDERFLOW,
|
||||
ExitCode::Halt(EvmHaltReason::CreateContractSizeLimit) => Self::CODESIZE_EXCEEDS_MAXIMUM,
|
||||
ExitCode::Halt(EvmHaltReason::CreateCollision) => Self::CREATE_COLLISION,
|
||||
_ => Self::UNKNOWN_HALT_REASON,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[napi]
|
||||
impl Exit {
|
||||
#[napi(catch_unwind, getter)]
|
||||
pub fn kind(&self) -> ExitCode {
|
||||
self.0
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn is_error(&self) -> bool {
|
||||
!matches!(self.0, ExitCode::SUCCESS)
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn get_reason(&self) -> String {
|
||||
self.0.to_string()
|
||||
}
|
||||
}
|
||||
11
dev/env/node_modules/@nomicfoundation/edr/src/trace/library_utils.rs
generated
vendored
Executable file
11
dev/env/node_modules/@nomicfoundation/edr/src/trace/library_utils.rs
generated
vendored
Executable file
@@ -0,0 +1,11 @@
|
||||
use napi_derive::napi;
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn link_hex_string_bytecode(
|
||||
code: String,
|
||||
address: String,
|
||||
position: u32,
|
||||
) -> napi::Result<String> {
|
||||
edr_solidity::library_utils::link_hex_string_bytecode(code, &address, position)
|
||||
.map_err(|err| napi::Error::from_reason(err.to_string()))
|
||||
}
|
||||
59
dev/env/node_modules/@nomicfoundation/edr/src/trace/model.rs
generated
vendored
Executable file
59
dev/env/node_modules/@nomicfoundation/edr/src/trace/model.rs
generated
vendored
Executable file
@@ -0,0 +1,59 @@
|
||||
use std::rc::Rc;
|
||||
|
||||
use edr_solidity::build_model::ContractMetadata;
|
||||
use napi_derive::napi;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Opaque handle to the `Bytecode` struct.
|
||||
/// Only used on the JS side by the `VmTraceDecoder` class.
|
||||
// NOTE: Needed, because we store the resolved `Bytecode` in the MessageTrace
|
||||
// JS plain objects and those need a dedicated (class) type.
|
||||
#[napi]
|
||||
pub struct BytecodeWrapper(pub(crate) Rc<ContractMetadata>);
|
||||
|
||||
impl BytecodeWrapper {
|
||||
pub fn new(bytecode: Rc<ContractMetadata>) -> Self {
|
||||
Self(bytecode)
|
||||
}
|
||||
|
||||
pub fn inner(&self) -> &Rc<ContractMetadata> {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for BytecodeWrapper {
|
||||
type Target = ContractMetadata;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize)]
|
||||
#[allow(non_camel_case_types)] // intentionally mimicks the original case in TS
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[napi]
|
||||
// Mimicks [`edr_solidity::build_model::ContractFunctionType`].
|
||||
pub enum ContractFunctionType {
|
||||
CONSTRUCTOR,
|
||||
FUNCTION,
|
||||
FALLBACK,
|
||||
RECEIVE,
|
||||
GETTER,
|
||||
MODIFIER,
|
||||
FREE_FUNCTION,
|
||||
}
|
||||
|
||||
impl From<edr_solidity::build_model::ContractFunctionType> for ContractFunctionType {
|
||||
fn from(value: edr_solidity::build_model::ContractFunctionType) -> Self {
|
||||
match value {
|
||||
edr_solidity::build_model::ContractFunctionType::Constructor => Self::CONSTRUCTOR,
|
||||
edr_solidity::build_model::ContractFunctionType::Function => Self::FUNCTION,
|
||||
edr_solidity::build_model::ContractFunctionType::Fallback => Self::FALLBACK,
|
||||
edr_solidity::build_model::ContractFunctionType::Receive => Self::RECEIVE,
|
||||
edr_solidity::build_model::ContractFunctionType::Getter => Self::GETTER,
|
||||
edr_solidity::build_model::ContractFunctionType::Modifier => Self::MODIFIER,
|
||||
edr_solidity::build_model::ContractFunctionType::FreeFunction => Self::FREE_FUNCTION,
|
||||
}
|
||||
}
|
||||
}
|
||||
96
dev/env/node_modules/@nomicfoundation/edr/src/trace/return_data.rs
generated
vendored
Executable file
96
dev/env/node_modules/@nomicfoundation/edr/src/trace/return_data.rs
generated
vendored
Executable file
@@ -0,0 +1,96 @@
|
||||
//! Rewrite of `hardhat-network/provider/return-data.ts` from Hardhat.
|
||||
|
||||
use alloy_sol_types::SolError;
|
||||
use napi::bindgen_prelude::{BigInt, Uint8Array};
|
||||
use napi_derive::napi;
|
||||
|
||||
// Built-in error types
|
||||
// See <https://docs.soliditylang.org/en/v0.8.26/control-structures.html#error-handling-assert-require-revert-and-exceptions>
|
||||
alloy_sol_types::sol! {
|
||||
error Error(string);
|
||||
error Panic(uint256);
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub struct ReturnData {
|
||||
#[napi(readonly)]
|
||||
pub value: Uint8Array,
|
||||
selector: Option<[u8; 4]>,
|
||||
}
|
||||
|
||||
#[napi]
|
||||
impl ReturnData {
|
||||
#[napi(catch_unwind, constructor)]
|
||||
pub fn new(value: Uint8Array) -> Self {
|
||||
let selector = value
|
||||
.get(0..4)
|
||||
.map(|selector| selector.try_into().expect("selector is 4 bytes"));
|
||||
|
||||
Self { value, selector }
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.value.is_empty()
|
||||
}
|
||||
|
||||
pub fn matches_selector(&self, selector: impl AsRef<[u8]>) -> bool {
|
||||
self.selector
|
||||
.is_some_and(|value| value == selector.as_ref())
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn is_error_return_data(&self) -> bool {
|
||||
self.selector == Some(Error::SELECTOR)
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn is_panic_return_data(&self) -> bool {
|
||||
self.selector == Some(Panic::SELECTOR)
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn decode_error(&self) -> napi::Result<String> {
|
||||
if self.is_empty() {
|
||||
return Ok(String::new());
|
||||
}
|
||||
|
||||
if !self.is_error_return_data() {
|
||||
return Err(napi::Error::new(
|
||||
napi::Status::InvalidArg,
|
||||
"VM Exception while processing transaction: Expected return data to be a Error(string)",
|
||||
));
|
||||
}
|
||||
|
||||
let result = Error::abi_decode(&self.value[..]).map_err(|_err| {
|
||||
napi::Error::new(
|
||||
napi::Status::InvalidArg,
|
||||
"VM Exception while processing transaction: Expected return data to contain a valid string",
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(result.0)
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn decode_panic(&self) -> napi::Result<BigInt> {
|
||||
if !self.is_panic_return_data() {
|
||||
return Err(napi::Error::new(
|
||||
napi::Status::InvalidArg,
|
||||
"VM Exception while processing transaction: Expected return data to be a Panic(uint256)",
|
||||
));
|
||||
}
|
||||
|
||||
let result = Panic::abi_decode(&self.value[..]).map_err(|_err| {
|
||||
napi::Error::new(
|
||||
napi::Status::InvalidArg,
|
||||
"VM Exception while processing transaction: Expected return data to contain a valid uint256",
|
||||
)
|
||||
})?;
|
||||
|
||||
Ok(BigInt {
|
||||
sign_bit: false,
|
||||
words: result.0.as_limbs().to_vec(),
|
||||
})
|
||||
}
|
||||
}
|
||||
883
dev/env/node_modules/@nomicfoundation/edr/src/trace/solidity_stack_trace.rs
generated
vendored
Executable file
883
dev/env/node_modules/@nomicfoundation/edr/src/trace/solidity_stack_trace.rs
generated
vendored
Executable file
@@ -0,0 +1,883 @@
|
||||
//! Naive rewrite of `hardhat-network/stack-traces/solidity-stack-traces.ts`
|
||||
//! from Hardhat.
|
||||
|
||||
use std::convert::Infallible;
|
||||
|
||||
use edr_primitives::{hex, U256};
|
||||
use napi::bindgen_prelude::{BigInt, Either25, FromNapiValue, ToNapiValue, Uint8Array, Undefined};
|
||||
use napi_derive::napi;
|
||||
use serde::{Serialize, Serializer};
|
||||
|
||||
use super::model::ContractFunctionType;
|
||||
use crate::{
|
||||
cast::TryCast, solidity_tests::cheatcode_errors::CheatcodeErrorDetails, trace::u256_to_bigint,
|
||||
};
|
||||
|
||||
#[napi]
|
||||
#[repr(u8)]
|
||||
#[allow(non_camel_case_types)] // intentionally mimicks the original case in TS
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, strum::FromRepr, strum::IntoStaticStr, Serialize)]
|
||||
pub enum StackTraceEntryType {
|
||||
CALLSTACK_ENTRY = 0,
|
||||
UNRECOGNIZED_CREATE_CALLSTACK_ENTRY,
|
||||
UNRECOGNIZED_CONTRACT_CALLSTACK_ENTRY,
|
||||
PRECOMPILE_ERROR,
|
||||
REVERT_ERROR,
|
||||
PANIC_ERROR,
|
||||
CUSTOM_ERROR,
|
||||
FUNCTION_NOT_PAYABLE_ERROR,
|
||||
INVALID_PARAMS_ERROR,
|
||||
FALLBACK_NOT_PAYABLE_ERROR,
|
||||
FALLBACK_NOT_PAYABLE_AND_NO_RECEIVE_ERROR,
|
||||
UNRECOGNIZED_FUNCTION_WITHOUT_FALLBACK_ERROR, /* TODO: Should trying to call a
|
||||
* private/internal be a special case of
|
||||
* this? */
|
||||
MISSING_FALLBACK_OR_RECEIVE_ERROR,
|
||||
RETURNDATA_SIZE_ERROR,
|
||||
NONCONTRACT_ACCOUNT_CALLED_ERROR,
|
||||
CALL_FAILED_ERROR,
|
||||
DIRECT_LIBRARY_CALL_ERROR,
|
||||
UNRECOGNIZED_CREATE_ERROR,
|
||||
UNRECOGNIZED_CONTRACT_ERROR,
|
||||
OTHER_EXECUTION_ERROR,
|
||||
// This is a special case to handle a regression introduced in solc 0.6.3
|
||||
// For more info: https://github.com/ethereum/solidity/issues/9006
|
||||
UNMAPPED_SOLC_0_6_3_REVERT_ERROR,
|
||||
CONTRACT_TOO_LARGE_ERROR,
|
||||
INTERNAL_FUNCTION_CALLSTACK_ENTRY,
|
||||
CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR,
|
||||
CHEATCODE_ERROR,
|
||||
}
|
||||
|
||||
#[napi(catch_unwind)]
|
||||
pub fn stack_trace_entry_type_to_string(val: StackTraceEntryType) -> &'static str {
|
||||
val.into()
|
||||
}
|
||||
|
||||
#[napi]
|
||||
pub const FALLBACK_FUNCTION_NAME: &str = "<fallback>";
|
||||
#[napi]
|
||||
pub const RECEIVE_FUNCTION_NAME: &str = "<receive>";
|
||||
#[napi]
|
||||
pub const CONSTRUCTOR_FUNCTION_NAME: &str = "constructor";
|
||||
#[napi]
|
||||
pub const UNRECOGNIZED_FUNCTION_NAME: &str = "<unrecognized-selector>";
|
||||
#[napi]
|
||||
pub const UNKNOWN_FUNCTION_NAME: &str = "<unknown>";
|
||||
#[napi]
|
||||
pub const PRECOMPILE_FUNCTION_NAME: &str = "<precompile>";
|
||||
#[napi]
|
||||
pub const UNRECOGNIZED_CONTRACT_NAME: &str = "<UnrecognizedContract>";
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, PartialEq, Serialize)]
|
||||
pub struct SourceReference {
|
||||
pub source_name: String,
|
||||
pub source_content: String,
|
||||
pub contract: Option<String>,
|
||||
pub function: Option<String>,
|
||||
pub line: u32,
|
||||
// [number, number] tuple
|
||||
pub range: Vec<u32>,
|
||||
}
|
||||
|
||||
impl From<edr_solidity::solidity_stack_trace::SourceReference> for SourceReference {
|
||||
fn from(value: edr_solidity::solidity_stack_trace::SourceReference) -> Self {
|
||||
let (range_start, range_end) = value.range;
|
||||
Self {
|
||||
source_name: value.source_name,
|
||||
source_content: value.source_content,
|
||||
contract: value.contract,
|
||||
function: value.function,
|
||||
line: value.line,
|
||||
range: vec![range_start, range_end],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<edr_solidity::return_data::CheatcodeErrorDetails> for CheatcodeErrorDetails {
|
||||
fn from(value: edr_solidity::return_data::CheatcodeErrorDetails) -> Self {
|
||||
Self {
|
||||
code: value.code.into(),
|
||||
cheatcode: value.cheatcode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`StackTraceEntryType`] constant that is convertible to/from a
|
||||
/// `napi_value`.
|
||||
///
|
||||
/// Since Rust does not allow constants directly as members, we use this wrapper
|
||||
/// to allow the `StackTraceEntryType` to be used as a member of an interface
|
||||
/// when defining the N-API bindings.
|
||||
// NOTE: It's currently not possible to use an enum as const generic parameter,
|
||||
// so we use the underlying `u8` repr used by the enum.
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct StackTraceEntryTypeConst<const ENTRY_TYPE: u8>;
|
||||
impl<const ENTRY_TYPE: u8> FromNapiValue for StackTraceEntryTypeConst<ENTRY_TYPE> {
|
||||
unsafe fn from_napi_value(
|
||||
env: napi::sys::napi_env,
|
||||
napi_val: napi::sys::napi_value,
|
||||
) -> napi::Result<Self> {
|
||||
// SAFETY: The safety concern is propagated in the function signature.
|
||||
let inner: u8 = unsafe { FromNapiValue::from_napi_value(env, napi_val) }?;
|
||||
|
||||
if inner != ENTRY_TYPE {
|
||||
return Err(napi::Error::new(
|
||||
napi::Status::InvalidArg,
|
||||
format!("Expected StackTraceEntryType value: {ENTRY_TYPE}, got: {inner}"),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(StackTraceEntryTypeConst)
|
||||
}
|
||||
}
|
||||
impl<const ENTRY_TYPE: u8> ToNapiValue for StackTraceEntryTypeConst<ENTRY_TYPE> {
|
||||
unsafe fn to_napi_value(
|
||||
env: napi::sys::napi_env,
|
||||
_val: Self,
|
||||
) -> napi::Result<napi::sys::napi_value> {
|
||||
// SAFETY: The safety concern is propagated in the function signature.
|
||||
unsafe { u8::to_napi_value(env, ENTRY_TYPE) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<const ENTRY_TYPE: u8> Serialize for StackTraceEntryTypeConst<ENTRY_TYPE> {
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
let inner = StackTraceEntryType::from_repr(ENTRY_TYPE).ok_or_else(|| {
|
||||
serde::ser::Error::custom(format!("Invalid StackTraceEntryType value: {ENTRY_TYPE}"))
|
||||
})?;
|
||||
|
||||
inner.serialize(serializer)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct CallstackEntryStackTraceEntry {
|
||||
#[napi(js_name = "type", ts_type = "StackTraceEntryType.CALLSTACK_ENTRY")]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::CALLSTACK_ENTRY as u8 }>,
|
||||
pub source_reference: SourceReference,
|
||||
pub function_type: ContractFunctionType,
|
||||
}
|
||||
|
||||
impl From<CallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: CallstackEntryStackTraceEntry) -> Self {
|
||||
Either25::A(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct UnrecognizedCreateCallstackEntryStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.UNRECOGNIZED_CREATE_CALLSTACK_ENTRY"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<
|
||||
{ StackTraceEntryType::UNRECOGNIZED_CREATE_CALLSTACK_ENTRY as u8 },
|
||||
>,
|
||||
pub source_reference: Option<Undefined>,
|
||||
}
|
||||
|
||||
impl From<UnrecognizedCreateCallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: UnrecognizedCreateCallstackEntryStackTraceEntry) -> Self {
|
||||
Either25::B(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct UnrecognizedContractCallstackEntryStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.UNRECOGNIZED_CONTRACT_CALLSTACK_ENTRY"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<
|
||||
{ StackTraceEntryType::UNRECOGNIZED_CONTRACT_CALLSTACK_ENTRY as u8 },
|
||||
>,
|
||||
#[serde(serialize_with = "serialize_uint8array_to_hex")]
|
||||
pub address: Uint8Array,
|
||||
pub source_reference: Option<Undefined>,
|
||||
}
|
||||
|
||||
impl From<UnrecognizedContractCallstackEntryStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: UnrecognizedContractCallstackEntryStackTraceEntry) -> Self {
|
||||
Either25::C(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct PrecompileErrorStackTraceEntry {
|
||||
#[napi(js_name = "type", ts_type = "StackTraceEntryType.PRECOMPILE_ERROR")]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::PRECOMPILE_ERROR as u8 }>,
|
||||
pub precompile: u32,
|
||||
pub source_reference: Option<Undefined>,
|
||||
}
|
||||
|
||||
impl From<PrecompileErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: PrecompileErrorStackTraceEntry) -> Self {
|
||||
Either25::D(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct RevertErrorStackTraceEntry {
|
||||
#[napi(js_name = "type", ts_type = "StackTraceEntryType.REVERT_ERROR")]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::REVERT_ERROR as u8 }>,
|
||||
#[serde(serialize_with = "serialize_uint8array_to_hex")]
|
||||
pub return_data: Uint8Array,
|
||||
pub source_reference: SourceReference,
|
||||
pub is_invalid_opcode_error: bool,
|
||||
}
|
||||
|
||||
impl From<RevertErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: RevertErrorStackTraceEntry) -> Self {
|
||||
Either25::E(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct PanicErrorStackTraceEntry {
|
||||
#[napi(js_name = "type", ts_type = "StackTraceEntryType.PANIC_ERROR")]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::PANIC_ERROR as u8 }>,
|
||||
#[serde(serialize_with = "serialize_evm_value_bigint_using_u256")]
|
||||
pub error_code: BigInt,
|
||||
pub source_reference: Option<SourceReference>,
|
||||
}
|
||||
|
||||
impl From<PanicErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: PanicErrorStackTraceEntry) -> Self {
|
||||
Either25::F(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct CustomErrorStackTraceEntry {
|
||||
#[napi(js_name = "type", ts_type = "StackTraceEntryType.CUSTOM_ERROR")]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::CUSTOM_ERROR as u8 }>,
|
||||
// unlike RevertErrorStackTraceEntry, this includes the message already parsed
|
||||
pub message: String,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<CustomErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: CustomErrorStackTraceEntry) -> Self {
|
||||
Either25::G(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct FunctionNotPayableErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.FUNCTION_NOT_PAYABLE_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::FUNCTION_NOT_PAYABLE_ERROR as u8 }>,
|
||||
#[serde(serialize_with = "serialize_evm_value_bigint_using_u256")]
|
||||
pub value: BigInt,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<FunctionNotPayableErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: FunctionNotPayableErrorStackTraceEntry) -> Self {
|
||||
Either25::H(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct InvalidParamsErrorStackTraceEntry {
|
||||
#[napi(js_name = "type", ts_type = "StackTraceEntryType.INVALID_PARAMS_ERROR")]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::INVALID_PARAMS_ERROR as u8 }>,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<InvalidParamsErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: InvalidParamsErrorStackTraceEntry) -> Self {
|
||||
Either25::I(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct FallbackNotPayableErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.FALLBACK_NOT_PAYABLE_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::FALLBACK_NOT_PAYABLE_ERROR as u8 }>,
|
||||
#[serde(serialize_with = "serialize_evm_value_bigint_using_u256")]
|
||||
pub value: BigInt,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<FallbackNotPayableErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: FallbackNotPayableErrorStackTraceEntry) -> Self {
|
||||
Either25::J(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct FallbackNotPayableAndNoReceiveErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.FALLBACK_NOT_PAYABLE_AND_NO_RECEIVE_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<
|
||||
{ StackTraceEntryType::FALLBACK_NOT_PAYABLE_AND_NO_RECEIVE_ERROR as u8 },
|
||||
>,
|
||||
#[serde(serialize_with = "serialize_evm_value_bigint_using_u256")]
|
||||
pub value: BigInt,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<FallbackNotPayableAndNoReceiveErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: FallbackNotPayableAndNoReceiveErrorStackTraceEntry) -> Self {
|
||||
Either25::K(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.UNRECOGNIZED_FUNCTION_WITHOUT_FALLBACK_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<
|
||||
{ StackTraceEntryType::UNRECOGNIZED_FUNCTION_WITHOUT_FALLBACK_ERROR as u8 },
|
||||
>,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry) -> Self {
|
||||
Either25::L(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct MissingFallbackOrReceiveErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.MISSING_FALLBACK_OR_RECEIVE_ERROR"
|
||||
)]
|
||||
pub type_:
|
||||
StackTraceEntryTypeConst<{ StackTraceEntryType::MISSING_FALLBACK_OR_RECEIVE_ERROR as u8 }>,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<MissingFallbackOrReceiveErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: MissingFallbackOrReceiveErrorStackTraceEntry) -> Self {
|
||||
Either25::M(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct ReturndataSizeErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.RETURNDATA_SIZE_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::RETURNDATA_SIZE_ERROR as u8 }>,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<ReturndataSizeErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: ReturndataSizeErrorStackTraceEntry) -> Self {
|
||||
Either25::N(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct NonContractAccountCalledErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.NONCONTRACT_ACCOUNT_CALLED_ERROR"
|
||||
)]
|
||||
pub type_:
|
||||
StackTraceEntryTypeConst<{ StackTraceEntryType::NONCONTRACT_ACCOUNT_CALLED_ERROR as u8 }>,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<NonContractAccountCalledErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: NonContractAccountCalledErrorStackTraceEntry) -> Self {
|
||||
Either25::O(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct CallFailedErrorStackTraceEntry {
|
||||
#[napi(js_name = "type", ts_type = "StackTraceEntryType.CALL_FAILED_ERROR")]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::CALL_FAILED_ERROR as u8 }>,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<CallFailedErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: CallFailedErrorStackTraceEntry) -> Self {
|
||||
Either25::P(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct DirectLibraryCallErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.DIRECT_LIBRARY_CALL_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::DIRECT_LIBRARY_CALL_ERROR as u8 }>,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<DirectLibraryCallErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: DirectLibraryCallErrorStackTraceEntry) -> Self {
|
||||
Either25::Q(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct UnrecognizedCreateErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.UNRECOGNIZED_CREATE_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::UNRECOGNIZED_CREATE_ERROR as u8 }>,
|
||||
#[serde(serialize_with = "serialize_uint8array_to_hex")]
|
||||
pub return_data: Uint8Array,
|
||||
pub source_reference: Option<Undefined>,
|
||||
pub is_invalid_opcode_error: bool,
|
||||
}
|
||||
|
||||
impl From<UnrecognizedCreateErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: UnrecognizedCreateErrorStackTraceEntry) -> Self {
|
||||
Either25::R(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct UnrecognizedContractErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.UNRECOGNIZED_CONTRACT_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::UNRECOGNIZED_CONTRACT_ERROR as u8 }>,
|
||||
#[serde(serialize_with = "serialize_uint8array_to_hex")]
|
||||
pub address: Uint8Array,
|
||||
#[serde(serialize_with = "serialize_uint8array_to_hex")]
|
||||
pub return_data: Uint8Array,
|
||||
pub source_reference: Option<Undefined>,
|
||||
pub is_invalid_opcode_error: bool,
|
||||
}
|
||||
|
||||
impl From<UnrecognizedContractErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: UnrecognizedContractErrorStackTraceEntry) -> Self {
|
||||
Either25::S(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct OtherExecutionErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.OTHER_EXECUTION_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::OTHER_EXECUTION_ERROR as u8 }>,
|
||||
pub source_reference: Option<SourceReference>,
|
||||
}
|
||||
|
||||
impl From<OtherExecutionErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: OtherExecutionErrorStackTraceEntry) -> Self {
|
||||
Either25::T(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct UnmappedSolc063RevertErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.UNMAPPED_SOLC_0_6_3_REVERT_ERROR"
|
||||
)]
|
||||
pub type_:
|
||||
StackTraceEntryTypeConst<{ StackTraceEntryType::UNMAPPED_SOLC_0_6_3_REVERT_ERROR as u8 }>,
|
||||
pub source_reference: Option<SourceReference>,
|
||||
}
|
||||
|
||||
impl From<UnmappedSolc063RevertErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: UnmappedSolc063RevertErrorStackTraceEntry) -> Self {
|
||||
Either25::U(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct ContractTooLargeErrorStackTraceEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.CONTRACT_TOO_LARGE_ERROR"
|
||||
)]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::CONTRACT_TOO_LARGE_ERROR as u8 }>,
|
||||
pub source_reference: Option<SourceReference>,
|
||||
}
|
||||
|
||||
impl From<ContractTooLargeErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: ContractTooLargeErrorStackTraceEntry) -> Self {
|
||||
Either25::V(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct InternalFunctionCallStackEntry {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.INTERNAL_FUNCTION_CALLSTACK_ENTRY"
|
||||
)]
|
||||
pub type_:
|
||||
StackTraceEntryTypeConst<{ StackTraceEntryType::INTERNAL_FUNCTION_CALLSTACK_ENTRY as u8 }>,
|
||||
pub pc: u32,
|
||||
pub source_reference: SourceReference,
|
||||
}
|
||||
|
||||
impl From<InternalFunctionCallStackEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: InternalFunctionCallStackEntry) -> Self {
|
||||
Either25::W(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct ContractCallRunOutOfGasError {
|
||||
#[napi(
|
||||
js_name = "type",
|
||||
ts_type = "StackTraceEntryType.CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR"
|
||||
)]
|
||||
pub type_:
|
||||
StackTraceEntryTypeConst<{ StackTraceEntryType::CONTRACT_CALL_RUN_OUT_OF_GAS_ERROR as u8 }>,
|
||||
pub source_reference: Option<SourceReference>,
|
||||
}
|
||||
|
||||
impl From<ContractCallRunOutOfGasError> for SolidityStackTraceEntry {
|
||||
fn from(val: ContractCallRunOutOfGasError) -> Self {
|
||||
Either25::X(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[napi(object)]
|
||||
#[derive(Clone, Serialize)]
|
||||
pub struct CheatcodeErrorStackTraceEntry {
|
||||
#[napi(js_name = "type", ts_type = "StackTraceEntryType.CHEATCODE_ERROR")]
|
||||
pub type_: StackTraceEntryTypeConst<{ StackTraceEntryType::CHEATCODE_ERROR as u8 }>,
|
||||
// The parsed cheatcode error message that can be displayed to the user
|
||||
pub message: String,
|
||||
pub source_reference: SourceReference,
|
||||
pub details: Option<CheatcodeErrorDetails>,
|
||||
}
|
||||
|
||||
impl From<CheatcodeErrorStackTraceEntry> for SolidityStackTraceEntry {
|
||||
fn from(val: CheatcodeErrorStackTraceEntry) -> Self {
|
||||
Either25::Y(val)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
// NOTE: This ported directly from JS for completeness and is used in the Rust
|
||||
// side of the bindings. However, napi-rs does not support exporting Rust type
|
||||
// aliases to the index.d.ts file, and it does not store the type definitions
|
||||
// when expanding the macros, so to use it we would have to specify this type
|
||||
// literally (all 26 lines of it) at every #[napi]-exported function, which is
|
||||
// not ideal.
|
||||
// Rather, we just bite the bullet for now and use the type alias directly
|
||||
// (which falls back to `any` as it's not recognized in the context of the
|
||||
// index.d.ts file) until we finish the porting work.
|
||||
pub type SolidityStackTraceEntry = Either25<
|
||||
CallstackEntryStackTraceEntry,
|
||||
UnrecognizedCreateCallstackEntryStackTraceEntry,
|
||||
UnrecognizedContractCallstackEntryStackTraceEntry,
|
||||
PrecompileErrorStackTraceEntry,
|
||||
RevertErrorStackTraceEntry,
|
||||
PanicErrorStackTraceEntry,
|
||||
CustomErrorStackTraceEntry,
|
||||
FunctionNotPayableErrorStackTraceEntry,
|
||||
InvalidParamsErrorStackTraceEntry,
|
||||
FallbackNotPayableErrorStackTraceEntry,
|
||||
FallbackNotPayableAndNoReceiveErrorStackTraceEntry,
|
||||
UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry,
|
||||
MissingFallbackOrReceiveErrorStackTraceEntry,
|
||||
ReturndataSizeErrorStackTraceEntry,
|
||||
NonContractAccountCalledErrorStackTraceEntry,
|
||||
CallFailedErrorStackTraceEntry,
|
||||
DirectLibraryCallErrorStackTraceEntry,
|
||||
UnrecognizedCreateErrorStackTraceEntry,
|
||||
UnrecognizedContractErrorStackTraceEntry,
|
||||
OtherExecutionErrorStackTraceEntry,
|
||||
UnmappedSolc063RevertErrorStackTraceEntry,
|
||||
ContractTooLargeErrorStackTraceEntry,
|
||||
InternalFunctionCallStackEntry,
|
||||
ContractCallRunOutOfGasError,
|
||||
CheatcodeErrorStackTraceEntry,
|
||||
>;
|
||||
|
||||
impl TryCast<SolidityStackTraceEntry> for edr_solidity::solidity_stack_trace::StackTraceEntry {
|
||||
type Error = Infallible;
|
||||
|
||||
fn try_cast(self) -> Result<SolidityStackTraceEntry, Self::Error> {
|
||||
use edr_solidity::solidity_stack_trace::StackTraceEntry;
|
||||
let result = match self {
|
||||
StackTraceEntry::CallstackEntry {
|
||||
source_reference,
|
||||
function_type,
|
||||
} => CallstackEntryStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.into(),
|
||||
function_type: function_type.into(),
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::UnrecognizedCreateCallstackEntry => {
|
||||
UnrecognizedCreateCallstackEntryStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: None,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::UnrecognizedContractCallstackEntry { address } => {
|
||||
UnrecognizedContractCallstackEntryStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
address: Uint8Array::with_data_copied(address),
|
||||
source_reference: None,
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::PrecompileError { precompile } => PrecompileErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
precompile,
|
||||
source_reference: None,
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::RevertError {
|
||||
return_data,
|
||||
source_reference,
|
||||
is_invalid_opcode_error,
|
||||
} => RevertErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
return_data: return_data.into(),
|
||||
source_reference: source_reference.into(),
|
||||
is_invalid_opcode_error,
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::PanicError {
|
||||
error_code,
|
||||
source_reference,
|
||||
} => PanicErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
error_code: u256_to_bigint(&error_code),
|
||||
source_reference: source_reference.map(std::convert::Into::into),
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::CheatCodeError {
|
||||
message,
|
||||
source_reference,
|
||||
details,
|
||||
} => CheatcodeErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
message,
|
||||
source_reference: source_reference.into(),
|
||||
details: details.map(std::convert::Into::into),
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::CustomError {
|
||||
message,
|
||||
source_reference,
|
||||
} => CustomErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
message,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::FunctionNotPayableError {
|
||||
value,
|
||||
source_reference,
|
||||
} => FunctionNotPayableErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
value: u256_to_bigint(&value),
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::InvalidParamsError { source_reference } => {
|
||||
InvalidParamsErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::FallbackNotPayableError {
|
||||
value,
|
||||
source_reference,
|
||||
} => FallbackNotPayableErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
value: u256_to_bigint(&value),
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::FallbackNotPayableAndNoReceiveError {
|
||||
value,
|
||||
source_reference,
|
||||
} => FallbackNotPayableAndNoReceiveErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
value: u256_to_bigint(&value),
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::UnrecognizedFunctionWithoutFallbackError { source_reference } => {
|
||||
UnrecognizedFunctionWithoutFallbackErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::MissingFallbackOrReceiveError { source_reference } => {
|
||||
MissingFallbackOrReceiveErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::ReturndataSizeError { source_reference } => {
|
||||
ReturndataSizeErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::NoncontractAccountCalledError { source_reference } => {
|
||||
NonContractAccountCalledErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::CallFailedError { source_reference } => {
|
||||
CallFailedErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::DirectLibraryCallError { source_reference } => {
|
||||
DirectLibraryCallErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::UnrecognizedCreateError {
|
||||
return_data,
|
||||
is_invalid_opcode_error,
|
||||
} => UnrecognizedCreateErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
return_data: return_data.into(),
|
||||
is_invalid_opcode_error,
|
||||
source_reference: None,
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::UnrecognizedContractError {
|
||||
address,
|
||||
return_data,
|
||||
is_invalid_opcode_error,
|
||||
} => UnrecognizedContractErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
address: Uint8Array::with_data_copied(address),
|
||||
return_data: return_data.into(),
|
||||
is_invalid_opcode_error,
|
||||
source_reference: None,
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::OtherExecutionError { source_reference } => {
|
||||
OtherExecutionErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.map(std::convert::Into::into),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::UnmappedSolc0_6_3RevertError { source_reference } => {
|
||||
UnmappedSolc063RevertErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.map(std::convert::Into::into),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::ContractTooLargeError { source_reference } => {
|
||||
ContractTooLargeErrorStackTraceEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.map(std::convert::Into::into),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
StackTraceEntry::InternalFunctionCallstackEntry {
|
||||
pc,
|
||||
source_reference,
|
||||
} => InternalFunctionCallStackEntry {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
pc,
|
||||
source_reference: source_reference.into(),
|
||||
}
|
||||
.into(),
|
||||
StackTraceEntry::ContractCallRunOutOfGasError { source_reference } => {
|
||||
ContractCallRunOutOfGasError {
|
||||
type_: StackTraceEntryTypeConst,
|
||||
source_reference: source_reference.map(std::convert::Into::into),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
};
|
||||
Ok(result)
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(dead_code)]
|
||||
// Same as above, but for the `SolidityStackTrace` type.
|
||||
pub type SolidityStackTrace = Vec<SolidityStackTraceEntry>;
|
||||
|
||||
const _: () = {
|
||||
const fn assert_to_from_napi_value<T: FromNapiValue + ToNapiValue>() {}
|
||||
assert_to_from_napi_value::<SolidityStackTraceEntry>();
|
||||
};
|
||||
|
||||
/// Serializes a [`BigInt`] that represents an EVM value as a
|
||||
/// [`edr_primitives::U256`].
|
||||
fn serialize_evm_value_bigint_using_u256<S>(bigint: &BigInt, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let val = U256::from_limbs_slice(&bigint.words);
|
||||
|
||||
val.serialize(s)
|
||||
}
|
||||
|
||||
fn serialize_uint8array_to_hex<S>(uint8array: &Uint8Array, s: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
let hex = hex::encode(uint8array.as_ref());
|
||||
|
||||
hex.serialize(s)
|
||||
}
|
||||
Reference in New Issue
Block a user