Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
N
nebula
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
exchain
nebula
Commits
51da1fcf
Commit
51da1fcf
authored
Oct 27, 2023
by
clabby
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
:broom:
parent
b2bc5430
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
34 additions
and
29 deletions
+34
-29
lib.rs
op-service/rethdb-reader/src/lib.rs
+34
-29
No files found.
op-service/rethdb-reader/src/lib.rs
View file @
51da1fcf
use
reth
::{
use
reth
::{
blockchain_tree
::
noop
::
NoopBlockchainTree
,
blockchain_tree
::
noop
::
NoopBlockchainTree
,
primitives
::{
primitives
::{
BlockHashOrNumber
,
ChainSpecBuilder
,
Receipt
,
TransactionMeta
,
TransactionSigned
,
U128
,
BlockHashOrNumber
,
Receipt
,
TransactionKind
,
TransactionMeta
,
TransactionSigned
,
MAINNET
,
U256
,
U64
,
U
128
,
U
256
,
U64
,
},
},
providers
::{
providers
::
BlockchainProvider
,
BlockReader
,
ProviderFactory
,
ReceiptProvider
},
providers
::{
providers
::
BlockchainProvider
,
BlockReader
,
ProviderFactory
,
ReceiptProvider
},
revm
::
primitives
::
calc_blob_gasprice
,
rpc
::
types
::{
Log
,
TransactionReceipt
},
rpc
::
types
::{
Log
,
TransactionReceipt
},
utils
::
db
::
open_db_read_only
,
utils
::
db
::
open_db_read_only
,
};
};
use
std
::{
os
::
raw
::
c_char
,
path
::
Path
,
sync
::
Arc
};
use
std
::{
os
::
raw
::
c_char
,
path
::
Path
};
#[repr(C)]
#[repr(C)]
pub
struct
ReceiptsResult
{
pub
struct
ReceiptsResult
{
...
@@ -38,45 +37,51 @@ impl ReceiptsResult {
...
@@ -38,45 +37,51 @@ impl ReceiptsResult {
/// Read the receipts for a blockhash from the RETH database directly.
/// Read the receipts for a blockhash from the RETH database directly.
///
///
/// WARNING: Will panic on error.
/// # Safety
/// TODO: Gracefully return OK status.
/// - All possible nil pointer dereferences are checked, and the function will return a
/// failing [ReceiptsResult] if any are found.
#[no_mangle]
#[no_mangle]
pub
extern
"C"
fn
read_receipts
(
pub
unsafe
extern
"C"
fn
read_receipts
(
block_hash
:
*
const
u8
,
block_hash
:
*
const
u8
,
block_hash_len
:
usize
,
block_hash_len
:
usize
,
db_path
:
*
const
c_char
,
db_path
:
*
const
c_char
,
)
->
ReceiptsResult
{
)
->
ReceiptsResult
{
// Convert the raw pointer and length back to a Rust slice
// Convert the raw pointer and length back to a Rust slice
let
Ok
(
block_hash
):
Result
<
[
u8
;
32
],
_
>
=
let
Ok
(
block_hash
):
Result
<
[
u8
;
32
],
_
>
=
{
unsafe
{
std
::
slice
::
from_raw_parts
(
block_hash
,
block_hash_len
)
}
.try_into
()
if
block_hash
.is_null
()
{
else
{
return
ReceiptsResult
::
fail
();
}
std
::
slice
::
from_raw_parts
(
block_hash
,
block_hash_len
)
}
.try_into
()
else
{
return
ReceiptsResult
::
fail
();
return
ReceiptsResult
::
fail
();
};
};
// Convert the *const c_char to a Rust &str
// Convert the *const c_char to a Rust &str
let
Ok
(
db_path_str
)
=
unsafe
{
let
Ok
(
db_path_str
)
=
{
assert
!
(
!
db_path
.is_null
(),
"Null pointer for database path"
);
if
db_path
.is_null
()
{
return
ReceiptsResult
::
fail
();
}
std
::
ffi
::
CStr
::
from_ptr
(
db_path
)
std
::
ffi
::
CStr
::
from_ptr
(
db_path
)
}
}
.to_str
()
else
{
.to_str
()
else
{
return
ReceiptsResult
::
fail
();
return
ReceiptsResult
::
fail
();
};
};
let
Ok
(
db
)
=
open_db_read_only
(
&
Path
::
new
(
db_path_str
),
None
)
else
{
let
Ok
(
db
)
=
open_db_read_only
(
Path
::
new
(
db_path_str
),
None
)
else
{
return
ReceiptsResult
::
fail
();
return
ReceiptsResult
::
fail
();
};
};
let
spec
=
Arc
::
new
(
ChainSpecBuilder
::
mainnet
()
.build
());
let
factory
=
ProviderFactory
::
new
(
db
,
MAINNET
.clone
());
let
factory
=
ProviderFactory
::
new
(
db
,
spec
.clone
());
// Create a read-only BlockChainProvider
// Create a read-only BlockChainProvider
let
Ok
(
provider
)
=
BlockchainProvider
::
new
(
factory
,
NoopBlockchainTree
::
default
())
else
{
let
Ok
(
provider
)
=
BlockchainProvider
::
new
(
factory
,
NoopBlockchainTree
::
default
())
else
{
return
ReceiptsResult
::
fail
();
return
ReceiptsResult
::
fail
();
};
};
// Fetch the block and the receipts within it
let
Ok
(
block
)
=
provider
.block_by_hash
(
block_hash
.into
())
else
{
let
Ok
(
block
)
=
provider
.block_by_hash
(
block_hash
.into
())
else
{
return
ReceiptsResult
::
fail
();
return
ReceiptsResult
::
fail
();
};
};
let
Ok
(
receipts
)
=
provider
.receipts_by_block
(
BlockHashOrNumber
::
Hash
(
block_hash
.into
()))
let
Ok
(
receipts
)
=
provider
.receipts_by_block
(
BlockHashOrNumber
::
Hash
(
block_hash
.into
()))
else
{
else
{
return
ReceiptsResult
::
fail
();
return
ReceiptsResult
::
fail
();
...
@@ -86,7 +91,6 @@ pub extern "C" fn read_receipts(
...
@@ -86,7 +91,6 @@ pub extern "C" fn read_receipts(
let
block_number
=
block
.number
;
let
block_number
=
block
.number
;
let
base_fee
=
block
.base_fee_per_gas
;
let
base_fee
=
block
.base_fee_per_gas
;
let
block_hash
=
block
.hash_slow
();
let
block_hash
=
block
.hash_slow
();
let
excess_blob_gas
=
block
.excess_blob_gas
;
let
Some
(
receipts
)
=
block
let
Some
(
receipts
)
=
block
.body
.body
.into_iter
()
.into_iter
()
...
@@ -99,7 +103,7 @@ pub extern "C" fn read_receipts(
...
@@ -99,7 +103,7 @@ pub extern "C" fn read_receipts(
block_hash
,
block_hash
,
block_number
,
block_number
,
base_fee
,
base_fee
,
excess_blob_gas
,
excess_blob_gas
:
None
,
};
};
build_transaction_receipt_with_block_receipts
(
tx
,
meta
,
receipt
,
&
receipts
)
build_transaction_receipt_with_block_receipts
(
tx
,
meta
,
receipt
,
&
receipts
)
})
})
...
@@ -127,14 +131,15 @@ pub extern "C" fn read_receipts(
...
@@ -127,14 +131,15 @@ pub extern "C" fn read_receipts(
}
}
/// Free a string that was allocated in Rust and passed to C.
/// Free a string that was allocated in Rust and passed to C.
///
/// # Safety
/// - All possible nil pointer dereferences are checked.
#[no_mangle]
#[no_mangle]
pub
extern
"C"
fn
free_string
(
string
:
*
mut
c_char
)
{
pub
unsafe
extern
"C"
fn
free_string
(
string
:
*
mut
c_char
)
{
unsafe
{
// Convert the raw pointer back to a CString and let it go out of scope,
// Convert the raw pointer back to a CString and let it go out of scope,
// which will deallocate the memory.
// which will deallocate the memory.
if
!
string
.is_null
()
{
if
!
string
.is_null
()
{
let
_
=
std
::
ffi
::
CString
::
from_raw
(
string
);
let
_
=
std
::
ffi
::
CString
::
from_raw
(
string
);
}
}
}
}
}
...
@@ -181,16 +186,16 @@ fn build_transaction_receipt_with_block_receipts(
...
@@ -181,16 +186,16 @@ fn build_transaction_receipt_with_block_receipts(
},
},
// EIP-4844 fields
// EIP-4844 fields
blob_gas_price
:
meta
.excess_blob_gas
.map
(
calc_blob_gasprice
)
.map
(
U128
::
from
)
,
blob_gas_price
:
None
,
blob_gas_used
:
transaction
.transaction
.blob_gas_used
()
.map
(
U128
::
from
)
,
blob_gas_used
:
None
,
};
};
match
tx
.transaction
.kind
()
{
match
tx
.transaction
.kind
()
{
reth
::
primitives
::
TransactionKind
::
Create
=>
{
TransactionKind
::
Create
=>
{
res_receipt
.contract_address
=
res_receipt
.contract_address
=
Some
(
transaction
.signer
()
.create
(
tx
.transaction
.nonce
()));
Some
(
transaction
.signer
()
.create
(
tx
.transaction
.nonce
()));
}
}
reth
::
primitives
::
TransactionKind
::
Call
(
addr
)
=>
{
TransactionKind
::
Call
(
addr
)
=>
{
res_receipt
.to
=
Some
(
*
addr
);
res_receipt
.to
=
Some
(
*
addr
);
}
}
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment