Conversation
onbjerg
left a comment
There was a problem hiding this comment.
hmm, is this not an rpc type? alternatively, is this even a TransactionRequest type? is it not just TypedTransaction? common for the TransactionRequest types is that almost all the fields are optional
basically, does this belong in the consensus crate?
|
Hmm, I don't think this should be an RPC type? How I see it is that:
I'm not sure we're on the same page on how we'd sign transactions on the provider without this type—could you please elaborate @onbjerg ? I think we could also follow reth's approach, and keep this |
2742961 to
82db26e
Compare
consensus): TypedTransactionRequestconsensus): TypedTransaction
this is an intermediary step that might no longer be required, need to revisit this again but @onbjerg the general idea is you start out with a general purpose CallRequest, convert that into a signable |
| async fn sign_dyn_tx_test(tx: &mut SignableTx, chain_id: Option<ChainId>) -> Result<Signature> { | ||
| let mut wallet: Wallet<SigningKey> = | ||
| "4c0883a69102937d6231471b5dbb6204fe5129617082792ae468d01a3f362318".parse().unwrap(); | ||
| wallet.set_chain_id(chain_id); |
There was a problem hiding this comment.
Can we make it not require the SigningKey generic? We had type LocalWallet for that before.
|
|
||
| fn into_signed(self, _signature: Signature) -> alloy_network::Signed<Self, Self::Signature> | ||
| where | ||
| Self: Sized, | ||
| { | ||
| unimplemented!(); | ||
| } |
There was a problem hiding this comment.
it is, but it is probably not what you want, right? As this would return a Signed<TypedTransaction>, and what you actually want to do is extract the actual variant contained, use into_signed on it and get a Signed<TxLegacy/TxEip2930/TxEip1559>.
| where | ||
| Self: Sized, | ||
| { | ||
| unimplemented!(); |
There was a problem hiding this comment.
same reasoning as above—you want to decode a signed enveloped tx with TxEnvelope, not with this type
|
Actually after some thought about how to design this I find myself liking the reth approach a bit more though @mattsse . Having TypedTransaction as an RPC type instead of a consensus type, means we can go from TransactionRequest to TypedTransaction easily with a conversion. To go from TypedTransaction to an actual consensus transaction e.g when signing, we can simply convert to the contained variant with a helper function e.g .into_consensus_tx, which will result in an alloy-consensus tx type which implements Transaction , and is signable. This means i slide a bit more with @Bjerg 's original criticisms on the pr. I think this is nice because: EDIT: Discussed offline, disregard. Reth also needs to be updated to a newer approach |
|
i have some strong feelings here, obv. |
|
even then, the |
|
@prestwich i think part of the problem is naming IMO. Reth calls this type
Ok, and how do we go from the json request to signing? This is the part that i think we are not thinking clearly about. At some point, this needs to become a signable tx, no? |
This is the sticking point. We don't sign basically |
|
and our signing needs to be flexible enough to all non-secp256k1 sigs :) |
This comment was marked as spam.
This comment was marked as spam.
Agreed, and here's how I view this:
Here's how I'm thinking about the full interaction: An user uses Therefore, the interaction would look like:
This is what alloy-contract would be for—the tx can also be built manually with the I think we'll probably need to diagram this, as I think we're running the risk of making this more complex than it needs to be. |
|
we're once again running ahead of ourselves by building alloy-contract before we have a full Tx model 😮💨 |
yeah so the main (unresolved) question is what's the
this applies to all endpoints besides The distinction between
A what this PR adds is the This trait: trait TxBuilder<N> {
fn gas(mut self, gas: U256) -> Self;
fn data(mut self, data: Bytes) -> Self;
// etc
fn build_req(self) -> N::TransactionRequest;
fn sign<S>(self, signer: S) -> Result<N::TransactionEnvelope>;
}could be implemented on but the conversion from
I think it's necessary because we want a clean way to get the signature hash we're signing. This step is just easier if we have a typed representation of the transaction |
note that when i rebase i'll add eip-4844 too |
We don't want a signable representation of a typed transaction. We want a builder that either (coordinates signing and constructs a tx envelope) or (outputs a json request object). The builder should not |
|
yeah, my point is that this step
is easier if you have the actual transaction types, which will happen inside |
The builder needs type knowledge of the inner transactions so it can convert itself into them during the envelope instantiation process, but almost all other parts of the API should never have that. They should operate only on builders and envelopes. It is a mistake to make a |
|
I'd like to agree on a direction soon—this is blocking for further foundry work.
how would this look? and in the case of sending an unsigned transaction, how would we disambiguate between the different transaction types properly? I'm struggling to look how this would work without this |
|
ping @mattsse / @prestwich |
|
This is possibly also blocking paradigmxyz/reth#6364 since a typed tx repr is used in reth, and that PR is a prerequisite for #178 getting merged which is a prerequisite for me being able to rename the provider and add a network generic for both the provider and |
|
then we should really make sure we get this right before it gets into the internals of everything 😅 what would you think about having the builder be RPC request format? I.e. reth desers a builder |
|
@Evalir i'm gonna noodle around with this today and try to get things unblocked |
|
Closing in favor of #190 per telegram discussion. |
Motivation
There is no proper concrete type which contains all ethereum transaction types implemented (legacy/eip2930/eip1559), which can be used by a
alloy-providersoralloy-contractfor remote/local signing and sending txs to the network. We haveTransactionRequest/CallRequest, but it is an RPC type, and does not support encoding / signing.Solution
Adds
TypedTransactiontoalloy-consensus—an enum which represents the unsigned version ofTxEnvelope, which can contain any of the ethereum transaction types.The rationale behind this type is for it to be the built-in concrete type used in providers to either use for remote account signing (
send_transaction), or for signing locally and sending through the network (send_raw_transaction).In the case of
send_raw_transaction, it is expected for theTypedTransactionto be signed, and to then be converted into aTxEnvelopethroughto_enveloped, which can then be encoded and sent through the network. Decoding is not implemented, as this type is not meant be used in this manner.With #178, we should also be able to implement a conversion from
TransactionRequest->TypedTransaction, which currently exists in ethers withinto_typed_tx.The enum implements
Transaction, meaning it is signable by the alloy signers.PR Checklist