-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(lib): add rpc eth_sendTransaction
#1984
Changes from all commits
073e132
b683b95
d33e9b9
0a72165
bbad429
3657fd0
40b0386
21d4b72
fbf9df9
8d7433a
86ba988
6004454
695ceb4
74b1742
392da28
1f01eae
acecd07
f28540c
8be5091
b5d52ca
fde4c9d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,99 @@ | ||||||||||||
use crate::bytes::Bytes; | ||||||||||||
use ethereum::{ | ||||||||||||
AccessListItem, EIP1559TransactionMessage, EIP2930TransactionMessage, LegacyTransactionMessage, | ||||||||||||
}; | ||||||||||||
use ethereum_types::{H160, U256}; | ||||||||||||
use serde::{Deserialize, Serialize}; | ||||||||||||
|
||||||||||||
pub enum TransactionMessage { | ||||||||||||
Legacy(LegacyTransactionMessage), | ||||||||||||
EIP2930(EIP2930TransactionMessage), | ||||||||||||
EIP1559(EIP1559TransactionMessage), | ||||||||||||
} | ||||||||||||
|
||||||||||||
/// Transaction request coming from RPC | ||||||||||||
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize, Deserialize)] | ||||||||||||
#[serde(deny_unknown_fields)] | ||||||||||||
#[serde(rename_all = "camelCase")] | ||||||||||||
pub struct TransactionRequest { | ||||||||||||
/// Sender | ||||||||||||
pub from: Option<H160>, | ||||||||||||
/// Recipient | ||||||||||||
pub to: Option<H160>, | ||||||||||||
/// Gas Price, legacy. | ||||||||||||
#[serde(default)] | ||||||||||||
pub gas_price: Option<U256>, | ||||||||||||
/// Max BaseFeePerGas the user is willing to pay. | ||||||||||||
#[serde(default)] | ||||||||||||
pub max_fee_per_gas: Option<U256>, | ||||||||||||
/// The miner's tip. | ||||||||||||
#[serde(default)] | ||||||||||||
pub max_priority_fee_per_gas: Option<U256>, | ||||||||||||
/// Gas | ||||||||||||
pub gas: Option<U256>, | ||||||||||||
/// Value of transaction in wei | ||||||||||||
pub value: Option<U256>, | ||||||||||||
/// Additional data sent with transaction | ||||||||||||
pub data: Option<Bytes>, | ||||||||||||
/// Transaction's nonce | ||||||||||||
pub nonce: Option<U256>, | ||||||||||||
/// Pre-pay to warm storage access. | ||||||||||||
#[serde(default)] | ||||||||||||
pub access_list: Option<Vec<AccessListItem>>, | ||||||||||||
/// EIP-2718 type | ||||||||||||
#[serde(rename = "type")] | ||||||||||||
pub transaction_type: Option<U256>, | ||||||||||||
} | ||||||||||||
|
||||||||||||
impl From<TransactionRequest> for Option<TransactionMessage> { | ||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Would be better to implement TryFrom here and have it return an error instead of None on last match arm There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. noted that.. its a great practice.. but we ady have error handling in another way round Lines 543 to 547 in fde4c9d
|
||||||||||||
fn from(req: TransactionRequest) -> Self { | ||||||||||||
match (req.gas_price, req.max_fee_per_gas, req.access_list.clone()) { | ||||||||||||
// Legacy | ||||||||||||
(Some(_), None, None) => Some(TransactionMessage::Legacy(LegacyTransactionMessage { | ||||||||||||
nonce: U256::zero(), | ||||||||||||
gas_price: req.gas_price.unwrap_or_default(), | ||||||||||||
gas_limit: req.gas.unwrap_or_default(), | ||||||||||||
value: req.value.unwrap_or_default(), | ||||||||||||
input: req.data.map(|s| s.into_vec()).unwrap_or_default(), | ||||||||||||
action: match req.to { | ||||||||||||
Some(to) => ethereum::TransactionAction::Call(to), | ||||||||||||
None => ethereum::TransactionAction::Create, | ||||||||||||
}, | ||||||||||||
chain_id: None, | ||||||||||||
})), | ||||||||||||
// EIP2930 | ||||||||||||
(_, None, Some(_)) => Some(TransactionMessage::EIP2930(EIP2930TransactionMessage { | ||||||||||||
nonce: U256::zero(), | ||||||||||||
gas_price: req.gas_price.unwrap_or_default(), | ||||||||||||
gas_limit: req.gas.unwrap_or_default(), | ||||||||||||
value: req.value.unwrap_or_default(), | ||||||||||||
input: req.data.map(|s| s.into_vec()).unwrap_or_default(), | ||||||||||||
action: match req.to { | ||||||||||||
Some(to) => ethereum::TransactionAction::Call(to), | ||||||||||||
None => ethereum::TransactionAction::Create, | ||||||||||||
}, | ||||||||||||
chain_id: 0, | ||||||||||||
access_list: req.access_list.unwrap_or_default(), | ||||||||||||
})), | ||||||||||||
// EIP1559 | ||||||||||||
(None, Some(_), _) | (None, None, None) => { | ||||||||||||
// Empty fields fall back to the canonical transaction schema. | ||||||||||||
Some(TransactionMessage::EIP1559(EIP1559TransactionMessage { | ||||||||||||
nonce: U256::zero(), | ||||||||||||
max_fee_per_gas: req.max_fee_per_gas.unwrap_or_default(), | ||||||||||||
max_priority_fee_per_gas: req.max_priority_fee_per_gas.unwrap_or_default(), | ||||||||||||
gas_limit: req.gas.unwrap_or_default(), | ||||||||||||
value: req.value.unwrap_or_default(), | ||||||||||||
input: req.data.map(|s| s.into_vec()).unwrap_or_default(), | ||||||||||||
action: match req.to { | ||||||||||||
Some(to) => ethereum::TransactionAction::Call(to), | ||||||||||||
None => ethereum::TransactionAction::Create, | ||||||||||||
}, | ||||||||||||
chain_id: 0, | ||||||||||||
access_list: req.access_list.unwrap_or_default(), | ||||||||||||
})) | ||||||||||||
} | ||||||||||||
_ => None, | ||||||||||||
} | ||||||||||||
} | ||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we re-use
CallRequest
or keep only this one instead ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm.. yea i have doubt on this earlier.. question.. why splitting 1 struct to 2 structs since they contain same field (slightly diff)..
btw i think current design is make more sense.. obviously splitting into 2 structs is to serve for own specific purpose.. readability and easier to maintain