Skip to content

Commit 40e86f0

Browse files
jbowen93sambukowskiSuperFluffyFraser999joroshiba
authoredOct 23, 2024··
Add sign and submit subcommands to sequencer CLI (#1696)
## Summary > [!NOTE] > Most of the code is copied from Sam (#1695) and Jordan's (#1694) PRs. Add two new subcommands `sign` and `submit` to the `sequencer` subcommand. ### `sign` 1. Reads a pbjson formatted `astria.protocol.transaction.v1.TransactionBody` from a file or `STDIN` (`file` is a positional argument; `STDIN` is read when providing `-` as the trailing argument). 2. Signs it with a given private key (`--private-key`). 3. Writes the pbjson formatted `astria.protocol.transaction.v1.Transaction` to `--output`/`-o`, if provided, or `STDOUT`. ### `submit` 1. 1. Reads a pbjson formatted `astria.protocol.transaction.v1.Transaction` from a file or `STDIN` (`file` is a positional argument; `STDIN` is read when providing `-` as the trailing argument). 2. Submits it to a sequencer's CometBFT url (`--sequencer-url`) ## Background We want to be able to test the submitting txs signed via FROST threshold signing (see #1654) but do not have a CLI command to submit already signed transactions. The `submit` command resolves this. To test the `submit` command it is desirable to have a corresponding `sign` command which creates a signed `Transaction` from a single private key. ## Changes - List changes which were made. ## Testing 1. Run a local sequencer network using `astria-cli-go` ``` just run dev purge all just run dev init just run dev run --network local ``` 2. Sign a `TransactionBody`: ``` cargo run -p astria-cli -- sequencer sign --private-key 2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90 - <<EOF { "params": { "nonce": 0, "chainId": "sequencer-test-chain-0" }, "actions": [ { "ibcRelayerChange": { "removal": { "bech32m": "astria13r24h8mj42sdfqflqyg2fycqf9mdqqzmm2xllj" } } } ] } EOF ``` 3. Submit the signed `Transaction` ``` cargo run -p astria-cli -- sequencer submit --sequencer-url http://127.0.0.1:26657 - <<EOF { "signature": "+hb4bd8kEM8/AQ3wJ2znXcF3Ds1iLZu6OieNOnxY7n1SZsiDr5NQP3lMK4s5134O629XjXhae/FsL+qtbXnBDw==", "publicKey": "1b9KP8znF7A4i8wnSevBSK2ZabI/Re4bYF/Vh3hXasQ=", "body": { "typeUrl": "/astria.protocol.transaction.v1.TransactionBody", "value": "ChgSFnNlcXVlbmNlci10ZXN0LWNoYWluLTASNKIDMRIvEi1hc3RyaWExM3IyNGg4bWo0MnNkZnFmbHF5ZzJmeWNxZjltZHFxem1tMnhsbGo=" } } EOF ``` > [!NOTE] > You can also do this is in a single command using `xargs -0` ``` cargo run -p astria-cli -- sequencer sign --private-key 2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90 - <<EOF { "params": { "nonce": 3, "chainId": "sequencer-test-chain-0" }, "actions": [ { "ibcRelayerChange": { "removal": { "bech32m": "astria13r24h8mj42sdfqflqyg2fycqf9mdqqzmm2xllj" } } } ] } EOF | xargs -0 cargo run -p astria-cli -- sequencer submit --sequencer-url http://127.0.0.1:26657 ``` ## Metrics - List out metrics added by PR, delete section if none. ## Breaking Changelist - Bulleted list of breaking changes, any notes on migration. Delete section if none. ## Related Issues Link any issues that are related, prefer full github links. closes <!-- list any issues closed here --> --------- Co-authored-by: Sam Bukowski <[email protected]> Co-authored-by: Richard Janis Goldschmidt <[email protected]> Co-authored-by: Fraser Hutchison <[email protected]> Co-authored-by: Jordan Oroshiba <[email protected]>
1 parent 3e16986 commit 40e86f0

File tree

18 files changed

+382
-92
lines changed

18 files changed

+382
-92
lines changed
 

‎Cargo.lock

+10
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎crates/astria-bridge-withdrawer/src/bridge_withdrawer/startup.rs

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use astria_core::{
1515
memos,
1616
transaction::v1::Action,
1717
},
18+
Protobuf as _,
1819
};
1920
use astria_eyre::eyre::{
2021
self,

‎crates/astria-bridge-withdrawer/tests/blackbox/helpers/mock_cometbft.rs

+1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::time::Duration;
33
use astria_core::{
44
primitive::v1::asset,
55
protocol::bridge::v1::BridgeAccountLastTxHashResponse,
6+
Protobuf as _,
67
};
78
use prost::Message as _;
89
use sequencer_client::{

‎crates/astria-cli/Cargo.toml

+4
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,12 @@ readme = "README.md"
88
repository = "https://github.com/astriaorg/astria"
99
homepage = "https://astria.org"
1010

11+
[[bin]]
12+
name = "astria-cli"
13+
1114
[dependencies]
1215
color-eyre = "0.6"
16+
clap-stdin = "0.5.1"
1317
# v2.0.0-rc.0 - can be updated once https://github.com/ZcashFoundation/frost/issues/755 is closed
1418
frost-ed25519 = { version = "2.0.0-rc.0", features = [] }
1519
serde_yaml = "0.9.25"

‎crates/astria-cli/src/sequencer/mod.rs

+13
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ mod block_height;
88
mod bridge_lock;
99
mod ics20_withdrawal;
1010
mod init_bridge_account;
11+
mod sign;
12+
mod submit;
1113
mod sudo;
1214
mod threshold;
1315
mod transfer;
@@ -31,6 +33,8 @@ impl Command {
3133
SubCommand::Transfer(transfer) => transfer.run().await,
3234
SubCommand::Threshold(threshold) => threshold.run().await,
3335
SubCommand::Ics20Withdrawal(ics20_withdrawal) => ics20_withdrawal.run().await,
36+
SubCommand::Submit(submit) => submit.run().await,
37+
SubCommand::Sign(sign) => sign.run(),
3438
}
3539
}
3640
}
@@ -59,4 +63,13 @@ enum SubCommand {
5963
Threshold(threshold::Command),
6064
/// Command for withdrawing an ICS20 asset
6165
Ics20Withdrawal(ics20_withdrawal::Command),
66+
/// Submit the signed pbjson formatted Transaction.
67+
Submit(submit::Command),
68+
/// Sign a pbjson formatted TransactionBody to produce a Transaction.
69+
#[expect(
70+
clippy::doc_markdown,
71+
reason = "doc comments are turned into CLI help strings which currently don't use \
72+
backticks"
73+
)]
74+
Sign(sign::Command),
6275
}
+99
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
use std::{
2+
io::Write,
3+
path::{
4+
Path,
5+
PathBuf,
6+
},
7+
};
8+
9+
use astria_core::{
10+
protocol::transaction::v1::TransactionBody,
11+
Protobuf,
12+
};
13+
use clap_stdin::FileOrStdin;
14+
use color_eyre::eyre::{
15+
self,
16+
WrapErr as _,
17+
};
18+
19+
use crate::utils::signing_key_from_private_key;
20+
21+
#[derive(clap::Args, Debug)]
22+
pub(super) struct Command {
23+
/// The private key of account being sent from
24+
#[arg(long, env = "SEQUENCER_PRIVATE_KEY")]
25+
// TODO: https://github.com/astriaorg/astria/issues/594
26+
// Don't use a plain text private, prefer wrapper like from
27+
// the secrecy crate with specialized `Debug` and `Drop` implementations
28+
// that overwrite the key on drop and don't reveal it when printing.
29+
private_key: String,
30+
/// Target to write the signed transaction in pbjson format (omit to write to STDOUT).
31+
#[arg(long, short)]
32+
output: Option<PathBuf>,
33+
/// Forces an overwrite of `--output` if a file at that location exists.
34+
#[arg(long, short)]
35+
force: bool,
36+
/// The source to read the pbjson formatted astra.protocol.transaction.v1.Transaction (use `-`
37+
/// to pass via STDIN).
38+
input: FileOrStdin,
39+
}
40+
41+
// The goal of the `sign` CLI command is to take in a `TransactionBody` and to sign with a private
42+
// key to create a `Transaction`. This signed `Transaction` should be printed to the console in
43+
// pbjson format.
44+
impl Command {
45+
pub(super) fn run(self) -> eyre::Result<()> {
46+
let key = signing_key_from_private_key(self.private_key.as_str())?;
47+
48+
let filename = self.input.filename().to_string();
49+
let transaction_body = read_transaction_body(self.input)
50+
.wrap_err_with(|| format!("failed to read transaction body from `{filename}`"))?;
51+
let transaction = transaction_body.sign(&key);
52+
53+
serde_json::to_writer(
54+
stdout_or_file(self.output.as_ref(), self.force)
55+
.wrap_err("failed to determine output target")?,
56+
&transaction.to_raw(),
57+
)
58+
.wrap_err("failed to write signed transaction")?;
59+
Ok(())
60+
}
61+
}
62+
63+
fn read_transaction_body(input: FileOrStdin) -> eyre::Result<TransactionBody> {
64+
let wire_body: <TransactionBody as Protobuf>::Raw = serde_json::from_reader(
65+
std::io::BufReader::new(input.into_reader()?),
66+
)
67+
.wrap_err_with(|| {
68+
format!(
69+
"failed to parse input as json `{}`",
70+
TransactionBody::full_name()
71+
)
72+
})?;
73+
TransactionBody::try_from_raw(wire_body).wrap_err("failed to validate transaction body")
74+
}
75+
76+
fn stdout_or_file<P: AsRef<Path>>(
77+
output: Option<P>,
78+
force_overwrite: bool,
79+
) -> eyre::Result<Box<dyn Write>> {
80+
let writer = match output {
81+
Some(path) => {
82+
let file = if force_overwrite {
83+
std::fs::File::options()
84+
.write(true)
85+
.truncate(true)
86+
.open(path)
87+
} else {
88+
std::fs::File::options()
89+
.create_new(true)
90+
.write(true)
91+
.open(path)
92+
}
93+
.wrap_err("failed to open file for writing")?;
94+
Box::new(file) as Box<dyn Write>
95+
}
96+
None => Box::new(std::io::stdout()),
97+
};
98+
Ok(writer)
99+
}
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use astria_core::{
2+
self,
3+
protocol::transaction::v1::Transaction,
4+
Protobuf,
5+
};
6+
use astria_sequencer_client::{
7+
HttpClient,
8+
SequencerClientExt as _,
9+
};
10+
use clap_stdin::FileOrStdin;
11+
use color_eyre::eyre::{
12+
self,
13+
ensure,
14+
WrapErr as _,
15+
};
16+
17+
#[derive(clap::Args, Debug)]
18+
pub(super) struct Command {
19+
/// The URL at which the Sequencer node is listening for ABCI commands.
20+
#[arg(
21+
long,
22+
env = "SEQUENCER_URL",
23+
default_value = crate::DEFAULT_SEQUENCER_RPC
24+
)]
25+
sequencer_url: String,
26+
/// The source to read the pbjson formatted astra.protocol.transaction.v1.Transaction (use `-`
27+
/// to pass via STDIN).
28+
input: FileOrStdin,
29+
}
30+
31+
// The 'submit' command takes a 'Transaction' in pbjson form and submits it to the sequencer
32+
impl Command {
33+
pub(super) async fn run(self) -> eyre::Result<()> {
34+
let sequencer_client = HttpClient::new(self.sequencer_url.as_str())
35+
.wrap_err("failed constructing http sequencer client")?;
36+
37+
let filename = self.input.filename().to_string();
38+
let transaction = read_transaction(self.input)
39+
.wrap_err_with(|| format!("to signed transaction from `{filename}`"))?;
40+
41+
let res = sequencer_client
42+
.submit_transaction_sync(transaction)
43+
.await
44+
.wrap_err("failed to submit transaction")?;
45+
46+
ensure!(res.code.is_ok(), "failed to check tx: {}", res.log);
47+
48+
let tx_response = sequencer_client.wait_for_tx_inclusion(res.hash).await;
49+
50+
ensure!(
51+
tx_response.tx_result.code.is_ok(),
52+
"failed to execute tx: {}",
53+
tx_response.tx_result.log
54+
);
55+
56+
println!("Submission completed!");
57+
println!("Included in block: {}", tx_response.height);
58+
Ok(())
59+
}
60+
}
61+
62+
fn read_transaction(input: FileOrStdin) -> eyre::Result<Transaction> {
63+
let wire_body: <Transaction as Protobuf>::Raw = serde_json::from_reader(
64+
std::io::BufReader::new(input.into_reader()?),
65+
)
66+
.wrap_err_with(|| {
67+
format!(
68+
"failed to parse input as json `{}`",
69+
Transaction::full_name()
70+
)
71+
})?;
72+
Transaction::try_from_raw(wire_body).wrap_err("failed to validate transaction body")
73+
}

‎crates/astria-composer/src/executor/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use astria_core::{
2626
Transaction,
2727
},
2828
},
29+
Protobuf as _,
2930
};
3031
use astria_eyre::eyre::{
3132
self,

‎crates/astria-composer/tests/blackbox/helper/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ use astria_core::{
2626
abci::AbciErrorCode,
2727
transaction::v1::Transaction,
2828
},
29+
Protobuf as _,
2930
};
3031
use astria_eyre::eyre;
3132
use ethers::prelude::Transaction as EthersTransaction;

‎crates/astria-core/src/protocol/test_utils.rs

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use crate::{
2020
block::Deposit,
2121
SequencerBlock,
2222
},
23+
Protobuf as _,
2324
};
2425

2526
#[derive(Default)]

‎crates/astria-core/src/protocol/transaction/v1/mod.rs

+155-80
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
TransactionId,
1717
ADDRESS_LEN,
1818
},
19-
Protobuf as _,
19+
Protobuf,
2020
};
2121

2222
pub mod action;
@@ -81,34 +81,69 @@ pub struct Transaction {
8181
body_bytes: bytes::Bytes,
8282
}
8383

84-
impl Transaction {
85-
pub fn address_bytes(&self) -> &[u8; ADDRESS_LEN] {
86-
self.verification_key.address_bytes()
84+
impl Protobuf for Transaction {
85+
type Error = TransactionError;
86+
type Raw = raw::Transaction;
87+
88+
fn try_from_raw_ref(raw: &Self::Raw) -> Result<Self, Self::Error> {
89+
let Self::Raw {
90+
signature,
91+
public_key,
92+
body,
93+
} = raw;
94+
let signature = Signature::try_from(&**signature).map_err(TransactionError::signature)?;
95+
let verification_key =
96+
VerificationKey::try_from(&**public_key).map_err(TransactionError::verification_key)?;
97+
let Some(body) = body else {
98+
return Err(TransactionError::unset_body());
99+
};
100+
let bytes = body.value.clone();
101+
verification_key
102+
.verify(&signature, &bytes)
103+
.map_err(TransactionError::verification)?;
104+
let transaction =
105+
TransactionBody::try_from_any(body.clone()).map_err(TransactionError::body)?;
106+
Ok(Self {
107+
signature,
108+
verification_key,
109+
body: transaction,
110+
body_bytes: bytes,
111+
})
87112
}
88113

89-
/// Returns the transaction ID, containing the transaction hash.
90-
///
91-
/// The transaction hash is calculated by protobuf-encoding the transaction
92-
/// and hashing the resulting bytes with sha256.
93-
#[must_use]
94-
pub fn id(&self) -> TransactionId {
95-
use sha2::{
96-
Digest as _,
97-
Sha256,
114+
fn try_from_raw(raw: Self::Raw) -> Result<Self, TransactionError> {
115+
let Self::Raw {
116+
signature,
117+
public_key,
118+
body,
119+
} = raw;
120+
let signature = Signature::try_from(&*signature).map_err(TransactionError::signature)?;
121+
let verification_key =
122+
VerificationKey::try_from(&*public_key).map_err(TransactionError::verification_key)?;
123+
let Some(body) = body else {
124+
return Err(TransactionError::unset_body());
98125
};
99-
let bytes = self.to_raw().encode_to_vec();
100-
TransactionId::new(Sha256::digest(bytes).into())
126+
let bytes = body.value.clone();
127+
verification_key
128+
.verify(&signature, &bytes)
129+
.map_err(TransactionError::verification)?;
130+
let transaction = TransactionBody::try_from_any(body).map_err(TransactionError::body)?;
131+
Ok(Self {
132+
signature,
133+
verification_key,
134+
body: transaction,
135+
body_bytes: bytes,
136+
})
101137
}
102138

103-
#[must_use]
104-
pub fn into_raw(self) -> raw::Transaction {
139+
fn into_raw(self) -> raw::Transaction {
105140
let Self {
106141
signature,
107142
verification_key,
108143
body_bytes: transaction_bytes,
109144
..
110145
} = self;
111-
raw::Transaction {
146+
Self::Raw {
112147
signature: Bytes::copy_from_slice(&signature.to_bytes()),
113148
public_key: Bytes::copy_from_slice(&verification_key.to_bytes()),
114149
body: Some(pbjson_types::Any {
@@ -118,15 +153,14 @@ impl Transaction {
118153
}
119154
}
120155

121-
#[must_use]
122-
pub fn to_raw(&self) -> raw::Transaction {
156+
fn to_raw(&self) -> raw::Transaction {
123157
let Self {
124158
signature,
125159
verification_key,
126160
body_bytes: transaction_bytes,
127161
..
128162
} = self;
129-
raw::Transaction {
163+
Self::Raw {
130164
signature: Bytes::copy_from_slice(&signature.to_bytes()),
131165
public_key: Bytes::copy_from_slice(&verification_key.to_bytes()),
132166
body: Some(pbjson_types::Any {
@@ -135,39 +169,25 @@ impl Transaction {
135169
}),
136170
}
137171
}
172+
}
138173

139-
/// Attempt to convert from a raw, unchecked protobuf [`raw::Transaction`].
140-
///
141-
/// # Errors
174+
impl Transaction {
175+
pub fn address_bytes(&self) -> &[u8; ADDRESS_LEN] {
176+
self.verification_key.address_bytes()
177+
}
178+
179+
/// Returns the transaction ID, containing the transaction hash.
142180
///
143-
/// Will return an error if signature or verification key cannot be reconstructed from the bytes
144-
/// contained in the raw input, if the transaction field was empty (meaning it was mapped to
145-
/// `None`), if the inner transaction could not be verified given the key and signature, or
146-
/// if the native [`Body`] could not be created from the inner raw
147-
/// [`raw::Body`].
148-
pub fn try_from_raw(proto: raw::Transaction) -> Result<Self, TransactionError> {
149-
let raw::Transaction {
150-
signature,
151-
public_key,
152-
body,
153-
} = proto;
154-
let signature = Signature::try_from(&*signature).map_err(TransactionError::signature)?;
155-
let verification_key =
156-
VerificationKey::try_from(&*public_key).map_err(TransactionError::verification_key)?;
157-
let Some(body) = body else {
158-
return Err(TransactionError::unset_body());
181+
/// The transaction hash is calculated by protobuf-encoding the transaction
182+
/// and hashing the resulting bytes with sha256.
183+
#[must_use]
184+
pub fn id(&self) -> TransactionId {
185+
use sha2::{
186+
Digest as _,
187+
Sha256,
159188
};
160-
let bytes = body.value.clone();
161-
verification_key
162-
.verify(&signature, &bytes)
163-
.map_err(TransactionError::verification)?;
164-
let transaction = TransactionBody::try_from_any(body).map_err(TransactionError::body)?;
165-
Ok(Self {
166-
signature,
167-
verification_key,
168-
body: transaction,
169-
body_bytes: bytes,
170-
})
189+
let bytes = self.to_raw().encode_to_vec();
190+
TransactionId::new(Sha256::digest(bytes).into())
171191
}
172192

173193
#[must_use]
@@ -215,12 +235,82 @@ impl Transaction {
215235
}
216236
}
217237

238+
impl From<Transaction> for raw::Transaction {
239+
fn from(value: Transaction) -> Self {
240+
value.into_raw()
241+
}
242+
}
243+
244+
impl TryFrom<raw::Transaction> for Transaction {
245+
type Error = TransactionError;
246+
247+
fn try_from(value: raw::Transaction) -> Result<Self, Self::Error> {
248+
Self::try_from_raw(value)
249+
}
250+
}
251+
218252
#[derive(Clone, Debug)]
219253
pub struct TransactionBody {
220254
actions: Actions,
221255
params: TransactionParams,
222256
}
223257

258+
impl Protobuf for TransactionBody {
259+
type Error = TransactionBodyError;
260+
type Raw = raw::TransactionBody;
261+
262+
fn try_from_raw_ref(raw: &Self::Raw) -> Result<Self, Self::Error> {
263+
let raw::TransactionBody {
264+
actions,
265+
params,
266+
} = raw;
267+
268+
let Some(params) = params else {
269+
return Err(TransactionBodyError::unset_params());
270+
};
271+
let params = TransactionParams::from_raw_ref(params);
272+
let actions: Vec<_> = actions
273+
.iter()
274+
.map(Action::try_from_raw_ref)
275+
.collect::<Result<_, _>>()
276+
.map_err(TransactionBodyError::action)?;
277+
278+
TransactionBody::builder()
279+
.actions(actions)
280+
.chain_id(params.chain_id)
281+
.nonce(params.nonce)
282+
.try_build()
283+
.map_err(TransactionBodyError::group)
284+
}
285+
286+
fn try_from_raw(proto: Self::Raw) -> Result<Self, TransactionBodyError> {
287+
let raw::TransactionBody {
288+
actions,
289+
params,
290+
} = proto;
291+
let Some(params) = params else {
292+
return Err(TransactionBodyError::unset_params());
293+
};
294+
let params = TransactionParams::from_raw(params);
295+
let actions: Vec<_> = actions
296+
.into_iter()
297+
.map(Action::try_from_raw)
298+
.collect::<Result<_, _>>()
299+
.map_err(TransactionBodyError::action)?;
300+
301+
TransactionBody::builder()
302+
.actions(actions)
303+
.chain_id(params.chain_id)
304+
.nonce(params.nonce)
305+
.try_build()
306+
.map_err(TransactionBodyError::group)
307+
}
308+
309+
fn to_raw(&self) -> Self::Raw {
310+
todo!()
311+
}
312+
}
313+
224314
impl TransactionBody {
225315
#[must_use]
226316
pub fn builder() -> TransactionBodyBuilder {
@@ -303,35 +393,6 @@ impl TransactionBody {
303393
self.clone().into_any()
304394
}
305395

306-
/// Attempt to convert from a raw, unchecked protobuf [`raw::Body`].
307-
///
308-
/// # Errors
309-
///
310-
/// Returns an error if one of the inner raw actions could not be converted to a native
311-
/// [`Action`].
312-
pub fn try_from_raw(proto: raw::TransactionBody) -> Result<Self, TransactionBodyError> {
313-
let raw::TransactionBody {
314-
actions,
315-
params,
316-
} = proto;
317-
let Some(params) = params else {
318-
return Err(TransactionBodyError::unset_params());
319-
};
320-
let params = TransactionParams::from_raw(params);
321-
let actions: Vec<_> = actions
322-
.into_iter()
323-
.map(Action::try_from_raw)
324-
.collect::<Result<_, _>>()
325-
.map_err(TransactionBodyError::action)?;
326-
327-
TransactionBody::builder()
328-
.actions(actions)
329-
.chain_id(params.chain_id)
330-
.nonce(params.nonce)
331-
.try_build()
332-
.map_err(TransactionBodyError::group)
333-
}
334-
335396
/// Attempt to convert from a protobuf [`pbjson_types::Any`].
336397
///
337398
/// # Errors
@@ -493,6 +554,20 @@ impl TransactionParams {
493554
chain_id,
494555
}
495556
}
557+
558+
/// Convert from a raw protobuf [`raw::Body`].
559+
#[must_use]
560+
pub fn from_raw_ref(proto: &raw::TransactionParams) -> Self {
561+
let raw::TransactionParams {
562+
nonce,
563+
chain_id,
564+
} = proto;
565+
566+
Self {
567+
nonce: *nonce,
568+
chain_id: chain_id.clone(),
569+
}
570+
}
496571
}
497572

498573
#[cfg(test)]

‎crates/astria-sequencer-client/src/extension_trait.rs

+12-9
Original file line numberDiff line numberDiff line change
@@ -33,15 +33,6 @@ use std::{
3333
sync::Arc,
3434
};
3535

36-
use astria_core::protocol::{
37-
asset::v1::AllowedFeeAssetsResponse,
38-
bridge::v1::{
39-
BridgeAccountInfoResponse,
40-
BridgeAccountLastTxHashResponse,
41-
},
42-
fees::v1::TransactionFeeResponse,
43-
transaction::v1::TransactionBody,
44-
};
4536
pub use astria_core::{
4637
primitive::v1::Address,
4738
protocol::{
@@ -56,6 +47,18 @@ pub use astria_core::{
5647
SequencerBlock,
5748
},
5849
};
50+
use astria_core::{
51+
protocol::{
52+
asset::v1::AllowedFeeAssetsResponse,
53+
bridge::v1::{
54+
BridgeAccountInfoResponse,
55+
BridgeAccountLastTxHashResponse,
56+
},
57+
fees::v1::TransactionFeeResponse,
58+
transaction::v1::TransactionBody,
59+
},
60+
Protobuf as _,
61+
};
5962
use async_trait::async_trait;
6063
use futures::Stream;
6164
use prost::{

‎crates/astria-sequencer/src/app/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ use astria_core::{
3434
},
3535
},
3636
sequencerblock::v1::block::SequencerBlock,
37+
Protobuf as _,
3738
};
3839
use astria_eyre::{
3940
anyhow_to_eyre,

‎crates/astria-sequencer/src/app/tests_block_ordering.rs

+6-3
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@ use std::{
33
ops::Deref,
44
};
55

6-
use astria_core::protocol::transaction::v1::{
7-
action::group::Group,
8-
Transaction,
6+
use astria_core::{
7+
protocol::transaction::v1::{
8+
action::group::Group,
9+
Transaction,
10+
},
11+
Protobuf as _,
912
};
1013
use bytes::Bytes;
1114
use prost::Message;

‎crates/astria-sequencer/src/fees/query.rs

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use astria_core::{
1111
TransactionBody,
1212
},
1313
},
14+
Protobuf as _,
1415
};
1516
use astria_eyre::eyre::{
1617
self,

‎crates/astria-sequencer/src/service/consensus.rs

+1
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ mod tests {
213213
action::RollupDataSubmission,
214214
TransactionBody,
215215
},
216+
Protobuf as _,
216217
};
217218
use bytes::Bytes;
218219
use prost::Message as _;

‎crates/astria-sequencer/src/service/mempool/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ use astria_core::{
1616
abci::AbciErrorCode,
1717
transaction::v1::Transaction,
1818
},
19+
Protobuf as _,
1920
};
2021
use astria_eyre::eyre::WrapErr as _;
2122
use bytes::Bytes;

‎crates/astria-sequencer/src/service/mempool/tests.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::num::NonZeroU32;
22

3+
use astria_core::Protobuf as _;
34
use prost::Message as _;
45
use telemetry::Metrics;
56
use tendermint::{

0 commit comments

Comments
 (0)
Please sign in to comment.