@nomicfoundation/edr 0.2.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.cargo/config.toml +8 -0
- package/.mocharc.json +4 -0
- package/Cargo.toml +50 -0
- package/LICENSE +1 -0
- package/artifacts/bindings-aarch64-apple-darwin/edr.darwin-arm64.node +0 -0
- package/artifacts/bindings-aarch64-pc-windows-msvc/edr.win32-arm64-msvc.node +0 -0
- package/artifacts/bindings-aarch64-unknown-linux-gnu/edr.linux-arm64-gnu.node +0 -0
- package/artifacts/bindings-aarch64-unknown-linux-musl/edr.linux-arm64-musl.node +0 -0
- package/artifacts/bindings-i686-pc-windows-msvc/edr.win32-ia32-msvc.node +0 -0
- package/artifacts/bindings-x86_64-apple-darwin/edr.darwin-x64.node +0 -0
- package/artifacts/bindings-x86_64-pc-windows-msvc/edr.win32-x64-msvc.node +0 -0
- package/artifacts/bindings-x86_64-unknown-linux-gnu/edr.linux-x64-gnu.node +0 -0
- package/artifacts/bindings-x86_64-unknown-linux-musl/edr.linux-x64-musl.node +0 -0
- package/build.rs +3 -0
- package/index.d.ts +383 -0
- package/index.js +264 -0
- package/npm/darwin-arm64/README.md +3 -0
- package/npm/darwin-arm64/edr.darwin-arm64.node +0 -0
- package/npm/darwin-arm64/package.json +22 -0
- package/npm/darwin-x64/README.md +3 -0
- package/npm/darwin-x64/edr.darwin-x64.node +0 -0
- package/npm/darwin-x64/package.json +22 -0
- package/npm/linux-arm64-gnu/README.md +3 -0
- package/npm/linux-arm64-gnu/edr.linux-arm64-gnu.node +0 -0
- package/npm/linux-arm64-gnu/package.json +25 -0
- package/npm/linux-arm64-musl/README.md +3 -0
- package/npm/linux-arm64-musl/edr.linux-arm64-musl.node +0 -0
- package/npm/linux-arm64-musl/package.json +25 -0
- package/npm/linux-x64-gnu/README.md +3 -0
- package/npm/linux-x64-gnu/edr.linux-x64-gnu.node +0 -0
- package/npm/linux-x64-gnu/package.json +25 -0
- package/npm/linux-x64-musl/README.md +3 -0
- package/npm/linux-x64-musl/edr.linux-x64-musl.node +0 -0
- package/npm/linux-x64-musl/package.json +25 -0
- package/npm/win32-arm64-msvc/README.md +3 -0
- package/npm/win32-arm64-msvc/edr.win32-arm64-msvc.node +0 -0
- package/npm/win32-arm64-msvc/package.json +22 -0
- package/npm/win32-ia32-msvc/README.md +3 -0
- package/npm/win32-ia32-msvc/edr.win32-ia32-msvc.node +0 -0
- package/npm/win32-ia32-msvc/package.json +22 -0
- package/npm/win32-x64-msvc/README.md +3 -0
- package/npm/win32-x64-msvc/edr.win32-x64-msvc.node +0 -0
- package/npm/win32-x64-msvc/package.json +22 -0
- package/package.json +61 -0
- package/src/account.rs +28 -0
- package/src/block.rs +110 -0
- package/src/cast.rs +119 -0
- package/src/config.rs +70 -0
- package/src/context.rs +74 -0
- package/src/debug_trace.rs +38 -0
- package/src/lib.rs +18 -0
- package/src/log.rs +41 -0
- package/src/logger.rs +1277 -0
- package/src/provider/config.rs +271 -0
- package/src/provider.rs +185 -0
- package/src/result.rs +254 -0
- package/src/subscribe.rs +60 -0
- package/src/sync.rs +85 -0
- package/src/threadsafe_function.rs +305 -0
- package/src/trace.rs +168 -0
- package/test/provider.ts +104 -0
- package/tsconfig.json +17 -0
package/src/block.rs
ADDED
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
use edr_eth::{Address, Bytes, B256, B64};
|
|
2
|
+
use napi::bindgen_prelude::{BigInt, Buffer};
|
|
3
|
+
use napi_derive::napi;
|
|
4
|
+
|
|
5
|
+
use crate::cast::TryCast;
|
|
6
|
+
|
|
7
|
+
#[napi(object)]
|
|
8
|
+
pub struct BlockOptions {
|
|
9
|
+
/// The parent block's hash
|
|
10
|
+
pub parent_hash: Option<Buffer>,
|
|
11
|
+
/// The block's beneficiary
|
|
12
|
+
pub beneficiary: Option<Buffer>,
|
|
13
|
+
/// The state's root hash
|
|
14
|
+
pub state_root: Option<Buffer>,
|
|
15
|
+
/// The block's difficulty
|
|
16
|
+
pub difficulty: Option<BigInt>,
|
|
17
|
+
/// The block's number
|
|
18
|
+
pub number: Option<BigInt>,
|
|
19
|
+
/// The block's gas limit
|
|
20
|
+
pub gas_limit: Option<BigInt>,
|
|
21
|
+
/// The block's timestamp
|
|
22
|
+
pub timestamp: Option<BigInt>,
|
|
23
|
+
/// The block's extra data
|
|
24
|
+
pub extra_data: Option<Buffer>,
|
|
25
|
+
/// The block's mix hash (or prevrandao)
|
|
26
|
+
pub mix_hash: Option<Buffer>,
|
|
27
|
+
/// The block's nonce
|
|
28
|
+
pub nonce: Option<Buffer>,
|
|
29
|
+
/// The block's base gas fee
|
|
30
|
+
pub base_fee: Option<BigInt>,
|
|
31
|
+
/// The block's withdrawals root
|
|
32
|
+
pub withdrawals_root: Option<Buffer>,
|
|
33
|
+
/// The hash tree root of the parent beacon block for the given execution
|
|
34
|
+
/// block (EIP-4788).
|
|
35
|
+
pub parent_beacon_block_root: Option<Buffer>,
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
impl TryFrom<BlockOptions> for edr_eth::block::BlockOptions {
|
|
39
|
+
type Error = napi::Error;
|
|
40
|
+
|
|
41
|
+
#[cfg_attr(feature = "tracing", tracing::instrument(skip_all))]
|
|
42
|
+
fn try_from(value: BlockOptions) -> Result<Self, Self::Error> {
|
|
43
|
+
Ok(Self {
|
|
44
|
+
parent_hash: value
|
|
45
|
+
.parent_hash
|
|
46
|
+
.map(TryCast::<B256>::try_cast)
|
|
47
|
+
.transpose()?,
|
|
48
|
+
beneficiary: value
|
|
49
|
+
.beneficiary
|
|
50
|
+
.map(TryCast::<Address>::try_cast)
|
|
51
|
+
.transpose()?,
|
|
52
|
+
state_root: value
|
|
53
|
+
.state_root
|
|
54
|
+
.map(TryCast::<B256>::try_cast)
|
|
55
|
+
.transpose()?,
|
|
56
|
+
difficulty: value
|
|
57
|
+
.difficulty
|
|
58
|
+
.map_or(Ok(None), |difficulty| difficulty.try_cast().map(Some))?,
|
|
59
|
+
number: value
|
|
60
|
+
.number
|
|
61
|
+
.map_or(Ok(None), |number| number.try_cast().map(Some))?,
|
|
62
|
+
gas_limit: value
|
|
63
|
+
.gas_limit
|
|
64
|
+
.map_or(Ok(None), |gas_limit| gas_limit.try_cast().map(Some))?,
|
|
65
|
+
timestamp: value
|
|
66
|
+
.timestamp
|
|
67
|
+
.map_or(Ok(None), |timestamp| timestamp.try_cast().map(Some))?,
|
|
68
|
+
extra_data: value
|
|
69
|
+
.extra_data
|
|
70
|
+
.map(|extra_data| Bytes::copy_from_slice(&extra_data)),
|
|
71
|
+
mix_hash: value.mix_hash.map(TryCast::<B256>::try_cast).transpose()?,
|
|
72
|
+
nonce: value.nonce.map(TryCast::<B64>::try_cast).transpose()?,
|
|
73
|
+
base_fee: value
|
|
74
|
+
.base_fee
|
|
75
|
+
.map_or(Ok(None), |basefee| basefee.try_cast().map(Some))?,
|
|
76
|
+
withdrawals_root: value
|
|
77
|
+
.withdrawals_root
|
|
78
|
+
.map(TryCast::<B256>::try_cast)
|
|
79
|
+
.transpose()?,
|
|
80
|
+
parent_beacon_block_root: value
|
|
81
|
+
.parent_beacon_block_root
|
|
82
|
+
.map(TryCast::<B256>::try_cast)
|
|
83
|
+
.transpose()?,
|
|
84
|
+
})
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/// Information about the blob gas used in a block.
|
|
89
|
+
#[napi(object)]
|
|
90
|
+
pub struct BlobGas {
|
|
91
|
+
/// The total amount of blob gas consumed by the transactions within the
|
|
92
|
+
/// block.
|
|
93
|
+
pub gas_used: BigInt,
|
|
94
|
+
/// The running total of blob gas consumed in excess of the target, prior to
|
|
95
|
+
/// the block. Blocks with above-target blob gas consumption increase this
|
|
96
|
+
/// value, blocks with below-target blob gas consumption decrease it
|
|
97
|
+
/// (bounded at 0).
|
|
98
|
+
pub excess_gas: BigInt,
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
impl TryFrom<BlobGas> for edr_eth::block::BlobGas {
|
|
102
|
+
type Error = napi::Error;
|
|
103
|
+
|
|
104
|
+
fn try_from(value: BlobGas) -> Result<Self, Self::Error> {
|
|
105
|
+
Ok(Self {
|
|
106
|
+
gas_used: BigInt::try_cast(value.gas_used)?,
|
|
107
|
+
excess_gas: BigInt::try_cast(value.excess_gas)?,
|
|
108
|
+
})
|
|
109
|
+
}
|
|
110
|
+
}
|
package/src/cast.rs
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
use edr_eth::{Address, B256, B64, U256};
|
|
2
|
+
use napi::{
|
|
3
|
+
bindgen_prelude::{BigInt, Buffer},
|
|
4
|
+
Status,
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
/// An attempted conversion that consumes `self`, which may or may not be
|
|
8
|
+
/// expensive. It is identical to [`TryInto`], but it allows us to implement
|
|
9
|
+
/// the trait for external types.
|
|
10
|
+
pub trait TryCast<T>: Sized {
|
|
11
|
+
/// The type returned in the event of a conversion error.
|
|
12
|
+
type Error;
|
|
13
|
+
|
|
14
|
+
/// Performs the conversion.
|
|
15
|
+
fn try_cast(self) -> Result<T, Self::Error>;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
impl TryCast<Address> for Buffer {
|
|
19
|
+
type Error = napi::Error;
|
|
20
|
+
|
|
21
|
+
fn try_cast(self) -> std::result::Result<Address, Self::Error> {
|
|
22
|
+
if self.len() != 20 {
|
|
23
|
+
return Err(napi::Error::new(
|
|
24
|
+
Status::InvalidArg,
|
|
25
|
+
"Buffer was expected to be 20 bytes.".to_string(),
|
|
26
|
+
));
|
|
27
|
+
}
|
|
28
|
+
Ok(Address::from_slice(&self))
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
impl TryCast<B64> for Buffer {
|
|
33
|
+
type Error = napi::Error;
|
|
34
|
+
|
|
35
|
+
fn try_cast(self) -> std::result::Result<B64, Self::Error> {
|
|
36
|
+
if self.len() != 8 {
|
|
37
|
+
return Err(napi::Error::new(
|
|
38
|
+
Status::InvalidArg,
|
|
39
|
+
"Buffer was expected to be 8 bytes.".to_string(),
|
|
40
|
+
));
|
|
41
|
+
}
|
|
42
|
+
Ok(B64::from_slice(&self))
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
impl TryCast<B256> for Buffer {
|
|
47
|
+
type Error = napi::Error;
|
|
48
|
+
|
|
49
|
+
fn try_cast(self) -> std::result::Result<B256, Self::Error> {
|
|
50
|
+
if self.len() != 32 {
|
|
51
|
+
return Err(napi::Error::new(
|
|
52
|
+
Status::InvalidArg,
|
|
53
|
+
"Buffer was expected to be 32 bytes.".to_string(),
|
|
54
|
+
));
|
|
55
|
+
}
|
|
56
|
+
Ok(B256::from_slice(&self))
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
impl TryCast<u64> for BigInt {
|
|
61
|
+
type Error = napi::Error;
|
|
62
|
+
|
|
63
|
+
fn try_cast(self) -> std::result::Result<u64, Self::Error> {
|
|
64
|
+
let (signed, value, lossless) = self.get_u64();
|
|
65
|
+
|
|
66
|
+
if signed {
|
|
67
|
+
return Err(napi::Error::new(
|
|
68
|
+
Status::InvalidArg,
|
|
69
|
+
"BigInt was expected to be unsigned.".to_string(),
|
|
70
|
+
));
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if !lossless {
|
|
74
|
+
return Err(napi::Error::new(
|
|
75
|
+
Status::InvalidArg,
|
|
76
|
+
"BigInt was expected to fit within 64 bits.".to_string(),
|
|
77
|
+
));
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
Ok(value)
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
impl TryCast<usize> for BigInt {
|
|
85
|
+
type Error = napi::Error;
|
|
86
|
+
|
|
87
|
+
fn try_cast(self) -> std::result::Result<usize, Self::Error> {
|
|
88
|
+
let size: u64 = BigInt::try_cast(self)?;
|
|
89
|
+
usize::try_from(size).map_err(|e| napi::Error::new(Status::InvalidArg, e.to_string()))
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
impl TryCast<U256> for BigInt {
|
|
94
|
+
type Error = napi::Error;
|
|
95
|
+
|
|
96
|
+
fn try_cast(mut self) -> std::result::Result<U256, Self::Error> {
|
|
97
|
+
let num_words = self.words.len();
|
|
98
|
+
match num_words.cmp(&4) {
|
|
99
|
+
std::cmp::Ordering::Less => self.words.append(&mut vec![0u64; 4 - num_words]),
|
|
100
|
+
std::cmp::Ordering::Equal => (),
|
|
101
|
+
std::cmp::Ordering::Greater => {
|
|
102
|
+
return Err(napi::Error::new(
|
|
103
|
+
Status::InvalidArg,
|
|
104
|
+
"BigInt cannot have more than 4 words.".to_owned(),
|
|
105
|
+
));
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
Ok(U256::from_limbs(self.words.try_into().unwrap()))
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
impl<T> TryCast<T> for T {
|
|
114
|
+
type Error = napi::Error;
|
|
115
|
+
|
|
116
|
+
fn try_cast(self) -> std::result::Result<T, Self::Error> {
|
|
117
|
+
Ok(self)
|
|
118
|
+
}
|
|
119
|
+
}
|
package/src/config.rs
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
use napi_derive::napi;
|
|
2
|
+
|
|
3
|
+
/// Identifier for the Ethereum spec.
|
|
4
|
+
#[napi]
|
|
5
|
+
pub enum SpecId {
|
|
6
|
+
/// Frontier
|
|
7
|
+
Frontier = 0,
|
|
8
|
+
/// Frontier Thawing
|
|
9
|
+
FrontierThawing = 1,
|
|
10
|
+
/// Homestead
|
|
11
|
+
Homestead = 2,
|
|
12
|
+
/// DAO Fork
|
|
13
|
+
DaoFork = 3,
|
|
14
|
+
/// Tangerine
|
|
15
|
+
Tangerine = 4,
|
|
16
|
+
/// Spurious Dragon
|
|
17
|
+
SpuriousDragon = 5,
|
|
18
|
+
/// Byzantium
|
|
19
|
+
Byzantium = 6,
|
|
20
|
+
/// Constantinople
|
|
21
|
+
Constantinople = 7,
|
|
22
|
+
/// Petersburg
|
|
23
|
+
Petersburg = 8,
|
|
24
|
+
/// Istanbul
|
|
25
|
+
Istanbul = 9,
|
|
26
|
+
/// Muir Glacier
|
|
27
|
+
MuirGlacier = 10,
|
|
28
|
+
/// Berlin
|
|
29
|
+
Berlin = 11,
|
|
30
|
+
/// London
|
|
31
|
+
London = 12,
|
|
32
|
+
/// Arrow Glacier
|
|
33
|
+
ArrowGlacier = 13,
|
|
34
|
+
/// Gray Glacier
|
|
35
|
+
GrayGlacier = 14,
|
|
36
|
+
/// Merge
|
|
37
|
+
Merge = 15,
|
|
38
|
+
/// Shanghai
|
|
39
|
+
Shanghai = 16,
|
|
40
|
+
/// Cancun
|
|
41
|
+
Cancun = 17,
|
|
42
|
+
/// Latest
|
|
43
|
+
Latest = 18,
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
impl From<SpecId> for edr_evm::SpecId {
|
|
47
|
+
fn from(value: SpecId) -> Self {
|
|
48
|
+
match value {
|
|
49
|
+
SpecId::Frontier => edr_evm::SpecId::FRONTIER,
|
|
50
|
+
SpecId::FrontierThawing => edr_evm::SpecId::FRONTIER_THAWING,
|
|
51
|
+
SpecId::Homestead => edr_evm::SpecId::HOMESTEAD,
|
|
52
|
+
SpecId::DaoFork => edr_evm::SpecId::DAO_FORK,
|
|
53
|
+
SpecId::Tangerine => edr_evm::SpecId::TANGERINE,
|
|
54
|
+
SpecId::SpuriousDragon => edr_evm::SpecId::SPURIOUS_DRAGON,
|
|
55
|
+
SpecId::Byzantium => edr_evm::SpecId::BYZANTIUM,
|
|
56
|
+
SpecId::Constantinople => edr_evm::SpecId::CONSTANTINOPLE,
|
|
57
|
+
SpecId::Petersburg => edr_evm::SpecId::PETERSBURG,
|
|
58
|
+
SpecId::Istanbul => edr_evm::SpecId::ISTANBUL,
|
|
59
|
+
SpecId::MuirGlacier => edr_evm::SpecId::MUIR_GLACIER,
|
|
60
|
+
SpecId::Berlin => edr_evm::SpecId::BERLIN,
|
|
61
|
+
SpecId::London => edr_evm::SpecId::LONDON,
|
|
62
|
+
SpecId::ArrowGlacier => edr_evm::SpecId::ARROW_GLACIER,
|
|
63
|
+
SpecId::GrayGlacier => edr_evm::SpecId::GRAY_GLACIER,
|
|
64
|
+
SpecId::Merge => edr_evm::SpecId::MERGE,
|
|
65
|
+
SpecId::Shanghai => edr_evm::SpecId::SHANGHAI,
|
|
66
|
+
SpecId::Cancun => edr_evm::SpecId::CANCUN,
|
|
67
|
+
SpecId::Latest => edr_evm::SpecId::LATEST,
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
package/src/context.rs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
use std::{io, ops::Deref, sync::Arc};
|
|
2
|
+
|
|
3
|
+
use napi::Status;
|
|
4
|
+
use napi_derive::napi;
|
|
5
|
+
use tracing_subscriber::{prelude::*, EnvFilter, Registry};
|
|
6
|
+
|
|
7
|
+
#[napi]
|
|
8
|
+
#[derive(Debug)]
|
|
9
|
+
pub struct EdrContext {
|
|
10
|
+
inner: Arc<Context>,
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
impl Deref for EdrContext {
|
|
14
|
+
type Target = Arc<Context>;
|
|
15
|
+
|
|
16
|
+
fn deref(&self) -> &Self::Target {
|
|
17
|
+
&self.inner
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
#[napi]
|
|
22
|
+
impl EdrContext {
|
|
23
|
+
#[doc = "Creates a new [`EdrContext`] instance. Should only be called once!"]
|
|
24
|
+
#[napi(constructor)]
|
|
25
|
+
pub fn new() -> napi::Result<Self> {
|
|
26
|
+
let context =
|
|
27
|
+
Context::new().map_err(|e| napi::Error::new(Status::GenericFailure, e.to_string()))?;
|
|
28
|
+
|
|
29
|
+
Ok(Self {
|
|
30
|
+
inner: Arc::new(context),
|
|
31
|
+
})
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#[derive(Debug)]
|
|
36
|
+
pub struct Context {
|
|
37
|
+
#[cfg(feature = "tracing")]
|
|
38
|
+
_tracing_write_guard: tracing_flame::FlushGuard<std::io::BufWriter<std::fs::File>>,
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
impl Context {
|
|
42
|
+
/// Creates a new [`Context`] instance. Should only be called once!
|
|
43
|
+
pub fn new() -> io::Result<Self> {
|
|
44
|
+
let fmt_layer = tracing_subscriber::fmt::layer()
|
|
45
|
+
.with_file(true)
|
|
46
|
+
.with_line_number(true)
|
|
47
|
+
.with_thread_ids(true)
|
|
48
|
+
.with_target(false)
|
|
49
|
+
.with_level(true)
|
|
50
|
+
.with_filter(EnvFilter::from_default_env());
|
|
51
|
+
|
|
52
|
+
let subscriber = Registry::default().with(fmt_layer);
|
|
53
|
+
|
|
54
|
+
#[cfg(feature = "tracing")]
|
|
55
|
+
let (flame_layer, guard) = {
|
|
56
|
+
let (flame_layer, guard) =
|
|
57
|
+
tracing_flame::FlameLayer::with_file("tracing.folded").unwrap();
|
|
58
|
+
|
|
59
|
+
let flame_layer = flame_layer.with_empty_samples(false);
|
|
60
|
+
(flame_layer, guard)
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
#[cfg(feature = "tracing")]
|
|
64
|
+
let subscriber = subscriber.with(flame_layer);
|
|
65
|
+
|
|
66
|
+
tracing::subscriber::set_global_default(subscriber)
|
|
67
|
+
.expect("Could not set global default tracing subscriber");
|
|
68
|
+
|
|
69
|
+
Ok(Self {
|
|
70
|
+
#[cfg(feature = "tracing")]
|
|
71
|
+
_tracing_write_guard: guard,
|
|
72
|
+
})
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
use std::collections::HashMap;
|
|
2
|
+
|
|
3
|
+
use napi::bindgen_prelude::{BigInt, Buffer};
|
|
4
|
+
use napi_derive::napi;
|
|
5
|
+
|
|
6
|
+
#[napi(object)]
|
|
7
|
+
pub struct DebugTraceResult {
|
|
8
|
+
pub pass: bool,
|
|
9
|
+
pub gas_used: BigInt,
|
|
10
|
+
pub output: Option<Buffer>,
|
|
11
|
+
pub struct_logs: Vec<DebugTraceLogItem>,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
#[napi(object)]
|
|
15
|
+
pub struct DebugTraceLogItem {
|
|
16
|
+
/// Program Counter
|
|
17
|
+
pub pc: BigInt,
|
|
18
|
+
// Op code
|
|
19
|
+
pub op: u8,
|
|
20
|
+
/// Gas left before executing this operation as hex number.
|
|
21
|
+
pub gas: String,
|
|
22
|
+
/// Gas cost of this operation as hex number.
|
|
23
|
+
pub gas_cost: String,
|
|
24
|
+
/// Array of all values (hex numbers) on the stack
|
|
25
|
+
pub stack: Option<Vec<String>>,
|
|
26
|
+
/// Depth of the call stack
|
|
27
|
+
pub depth: BigInt,
|
|
28
|
+
/// Size of memory array
|
|
29
|
+
pub mem_size: BigInt,
|
|
30
|
+
/// Name of the operation
|
|
31
|
+
pub op_name: String,
|
|
32
|
+
/// Description of an error as a hex string.
|
|
33
|
+
pub error: Option<String>,
|
|
34
|
+
/// Array of all allocated values as hex strings.
|
|
35
|
+
pub memory: Option<Vec<String>>,
|
|
36
|
+
/// Map of all stored values with keys and values encoded as hex strings.
|
|
37
|
+
pub storage: Option<HashMap<String, String>>,
|
|
38
|
+
}
|
package/src/lib.rs
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#![warn(missing_docs)]
|
|
2
|
+
|
|
3
|
+
//! NAPI bindings for the EDR EVM
|
|
4
|
+
|
|
5
|
+
mod account;
|
|
6
|
+
mod block;
|
|
7
|
+
mod cast;
|
|
8
|
+
mod config;
|
|
9
|
+
mod context;
|
|
10
|
+
mod debug_trace;
|
|
11
|
+
mod log;
|
|
12
|
+
mod logger;
|
|
13
|
+
mod provider;
|
|
14
|
+
mod result;
|
|
15
|
+
mod subscribe;
|
|
16
|
+
mod sync;
|
|
17
|
+
mod threadsafe_function;
|
|
18
|
+
mod trace;
|
package/src/log.rs
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
use std::mem;
|
|
2
|
+
|
|
3
|
+
use napi::{bindgen_prelude::Buffer, Env, JsBuffer, JsBufferValue};
|
|
4
|
+
use napi_derive::napi;
|
|
5
|
+
|
|
6
|
+
/// Ethereum execution log.
|
|
7
|
+
#[napi(object)]
|
|
8
|
+
pub struct ExecutionLog {
|
|
9
|
+
pub address: Buffer,
|
|
10
|
+
pub topics: Vec<Buffer>,
|
|
11
|
+
pub data: JsBuffer,
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
impl ExecutionLog {
|
|
15
|
+
pub fn new(env: &Env, log: &edr_evm::Log) -> napi::Result<Self> {
|
|
16
|
+
let topics = log
|
|
17
|
+
.topics
|
|
18
|
+
.iter()
|
|
19
|
+
.map(|topic| Buffer::from(topic.as_slice()))
|
|
20
|
+
.collect();
|
|
21
|
+
|
|
22
|
+
let data = log.data.clone();
|
|
23
|
+
let data = unsafe {
|
|
24
|
+
env.create_buffer_with_borrowed_data(
|
|
25
|
+
data.as_ptr(),
|
|
26
|
+
data.len(),
|
|
27
|
+
data,
|
|
28
|
+
|data: edr_eth::Bytes, _env| {
|
|
29
|
+
mem::drop(data);
|
|
30
|
+
},
|
|
31
|
+
)
|
|
32
|
+
}
|
|
33
|
+
.map(JsBufferValue::into_raw)?;
|
|
34
|
+
|
|
35
|
+
Ok(Self {
|
|
36
|
+
address: Buffer::from(log.address.as_slice()),
|
|
37
|
+
topics,
|
|
38
|
+
data,
|
|
39
|
+
})
|
|
40
|
+
}
|
|
41
|
+
}
|