feat(rpc): add EthSigner trait (#1118)

Co-authored-by: Roman Krasiuk <rokrassyuk@gmail.com>
This commit is contained in:
Matthias Seitz
2023-02-01 21:33:45 +01:00
committed by GitHub
parent 5ee3cfe507
commit 51ab6fde9f
5 changed files with 71 additions and 3 deletions

1
Cargo.lock generated
View File

@@ -4541,6 +4541,7 @@ dependencies = [
"reth-rpc-engine-api",
"reth-rpc-types",
"reth-transaction-pool",
"secp256k1 0.24.3",
"serde",
"serde_json",
"thiserror",

View File

@@ -28,6 +28,11 @@ async-trait = "0.1"
tokio = { version = "1", features = ["sync"] }
# misc
secp256k1 = { version = "0.24", features = [
"global-context",
"rand-std",
"recovery",
] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
thiserror = "1.0"

View File

@@ -3,6 +3,7 @@
//! The entire implementation of the namespace is quite large, hence it is divided across several
//! files.
use crate::eth::signer::EthSigner;
use async_trait::async_trait;
use reth_interfaces::Result;
use reth_network_api::NetworkInfo;
@@ -38,7 +39,8 @@ pub trait EthApiSpec: Send + Sync {
/// are implemented separately in submodules. The rpc handler implementation can then delegate to
/// the main impls. This way [`EthApi`] is not limited to [`jsonrpsee`] and can be used standalone
/// or in other network handlers (for example ipc).
#[derive(Debug, Clone)]
#[derive(Clone)]
#[allow(missing_debug_implementations)]
pub struct EthApi<Pool, Client, Network> {
/// All nested fields bundled together.
inner: Arc<EthApiInner<Pool, Client, Network>>,
@@ -47,7 +49,7 @@ pub struct EthApi<Pool, Client, Network> {
impl<Pool, Client, Network> EthApi<Pool, Client, Network> {
/// Creates a new, shareable instance.
pub fn new(client: Arc<Client>, pool: Pool, network: Network) -> Self {
let inner = EthApiInner { client, pool, network };
let inner = EthApiInner { client, pool, network, signers: Default::default() };
Self { inner: Arc::new(inner) }
}
@@ -94,7 +96,6 @@ where
}
/// Container type `EthApi`
#[derive(Debug)]
struct EthApiInner<Pool, Client, Network> {
/// The transaction pool.
pool: Pool,
@@ -102,4 +103,6 @@ struct EthApiInner<Pool, Client, Network> {
client: Arc<Client>,
/// An interface to interact with the network
network: Network,
/// All configured Signers
signers: Vec<Box<dyn EthSigner>>,
}

View File

@@ -3,6 +3,7 @@
mod api;
pub(crate) mod error;
mod pubsub;
mod signer;
pub use api::{EthApi, EthApiSpec};
pub use pubsub::EthPubSub;

View File

@@ -0,0 +1,58 @@
//! An abstraction over ethereum signers.
use jsonrpsee::core::RpcResult as Result;
use reth_primitives::{Address, Signature, TransactionSigned};
use reth_rpc_types::TypedTransactionRequest;
use secp256k1::SecretKey;
use std::collections::HashMap;
/// An Ethereum Signer used via RPC.
#[async_trait::async_trait]
pub(crate) trait EthSigner: Send + Sync {
/// Returns the available accounts for this signer.
fn accounts(&self) -> Vec<Address>;
/// Returns `true` whether this signer can sign for this address
fn is_signer_for(&self, addr: &Address) -> bool {
self.accounts().contains(addr)
}
/// Returns the signature
async fn sign(&self, address: Address, message: &[u8]) -> Result<Signature>;
/// signs a transaction request using the given account in request
fn sign_transaction(
&self,
request: TypedTransactionRequest,
address: &Address,
) -> Result<TransactionSigned>;
}
/// Holds developer keys
pub(crate) struct DevSigner {
addresses: Vec<Address>,
accounts: HashMap<Address, SecretKey>,
}
#[async_trait::async_trait]
impl EthSigner for DevSigner {
fn accounts(&self) -> Vec<Address> {
self.addresses.clone()
}
fn is_signer_for(&self, addr: &Address) -> bool {
self.accounts.contains_key(addr)
}
async fn sign(&self, _address: Address, _message: &[u8]) -> Result<Signature> {
todo!()
}
fn sign_transaction(
&self,
_request: TypedTransactionRequest,
_address: &Address,
) -> Result<TransactionSigned> {
todo!()
}
}