-
Notifications
You must be signed in to change notification settings - Fork 245
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: refactor request builder workflow #431
Conversation
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.
good direction 🦺
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.
feature req:
/// Returns the transaction type that this builder will attempt to build. This does not imply
/// that the builder is ready to build.
pub fn output_tx_type(&self) -> TxType
/// Returns the transaction type that this builder will build. `Err` if the builder
/// is not ready to build, containing the attempt type and missing/conflicted information
pub fn output_tx_type_checked(&self) -> Result<TxType, Vec<TransactionRequestError>>;
@@ -38,6 +39,44 @@ impl TransactionBuilderError { | |||
} | |||
} | |||
|
|||
/// Wrapper for [`InvalidTransactionRequestError`]s. | |||
#[derive(Debug)] | |||
pub struct InvalidTransactionRequestErrors(pub Vec<InvalidTransactionRequestError>); |
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.
it seems like this newtype is not adding any functionality, or preventing any common mistakes. It can be omitted, with the buildererror variant containing an unwrapped Vec
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.
Mmm It's for the Display
impl, used on:
#[error("{0:?} transaction can't be built: {1}")]
InvalidTransactionRequest(TxType, InvalidTransactionRequestErrors),
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.
let's manually impl that display?
} | ||
} | ||
|
||
fn will_build_2930(request: &TransactionRequest) -> Result<bool, TransactionBuilderError> { |
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.
these can be pub
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.
Let's also add some docs
the more i look at this the more complexity I see. e.g. a I may do some work on this 🤔 |
@prestwich Did you have time to have a look at this? Or maybe you can give pointers on the remaining work needed? |
i'm still traveling for the next few days, so I don't have time to properly review :( I will be working on this and may take it over somewhat. sorry for taking so long and then stepping on your toes |
23ead62
to
5b5e7c9
Compare
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.
this flow makes sense, but I worry the preferred type detection has unexpected results
how to enforce build
will actually result in specific type?
I think form a builder pov, I'd also like to have something like
builder().
....
.ensure_type(ty: impl AsRef<u8>)?
.build_preferred(, ty: impl AsRef<u8>)
} else if self.access_list.is_some() { | ||
TxType::Eip2930 | ||
} else if self.gas_price.is_some() { | ||
TxType::Legacy | ||
} else { | ||
TxType::Eip1559 | ||
} |
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.
should 2930 only be if gas price is also set?
otherwise all txs with 1559 fee fields and an accesslist will be 2930
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.
my basic design approach here is to prefer the MOST specific (LEAST common) thing set, to try to conform to user intent in most cases. So preference order is basically as follows:
- Blobs are specific and critical to the tx, and have highest priority
- Access lists are specific and (almost always) not critical
- legacy gas is specific and never critical
- eip1559 is the default case if no more-specific intention has been specified
otherwise all txs with 1559 fee fields and an accesslist will be 2930
this seems like correct behavior to me, because if the user specified an access list it is a more-specific intention than specifying 1559 gas
@@ -227,8 +230,24 @@ pub trait TransactionBuilder<N: Network>: Default + Sized + Send + Sync + 'stati | |||
/// a valid transaction. | |||
fn can_build(&self) -> bool; | |||
|
|||
/// Returns the transaction type that this builder will attempt to build. | |||
/// This does not imply that the builder is ready to build. | |||
fn output_tx_type(&self) -> TxType; |
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, can we use the txtype in the trait here?
because txtypes are network specific
could operate on u8 or make txtype part of the network trait
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.
good catch, we cannot.
could operate on u8 or make txtype part of the network trait
I am partial to the idea of using TxType
on the network trait, but at that point, i would also want to incorporate into En/Decodable2718
, and make something like trait En/Decodable2718<T: Into<u8> + TryFrom<u8, Error = _>>
or similar so that we can enforce that the 2718 implementation uses the network TxType
via a type TxEnvelope: Encodable2718<Self::TxType>
bound
let me think about it a bit. most likely outcome is that this PR will operate on u8, and i will reserve network-assoc txtype for a later pr
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.
okay i made a network specific tx type because it felt right >.>
incorporating it into encodable/decodable can be later
f53e649
to
b06cd85
Compare
@mattsse i've added the following. I copied the pattern from other builders, but i couldn't tell you which ones because it's beena minute since I saw them
|
ok done |
* feat: refactor request builder workflow * feat: return all tx builder errors in one invocation * fix: avoid nesting * feat: move get_invalid_*_fields() to TransactionRequest * feat: Impl Display for TxType * feat: (wip) get info about transaction type currently building * wip: refactor refactor refactor * feat: tx type in trait * fix: core fmt * fix: tests passing * fix: no_std in consensus * feature: assert_preferred * fix: anytxtype --------- Co-authored-by: James <[email protected]>
Closes #423