Skip to content

Commit 426dbf4

Browse files
committed
refactor(admin): adopt SignedAction and log parse/handle failures
1 parent db7a51c commit 426dbf4

File tree

5 files changed

+66
-49
lines changed

5 files changed

+66
-49
lines changed

crates/subprotocols/admin/src/authority.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use std::num::NonZero;
22

33
use ssz_derive::{Decode, Encode};
44
use strata_asm_params::Role;
5-
use strata_asm_txs_admin::{actions::Sighash, parser::SignedPayload};
5+
use strata_asm_txs_admin::{actions::Sighash, signed_action::SignedAction};
66
use strata_crypto::threshold_signature::{ThresholdConfig, verify_threshold_signatures};
77

88
use crate::error::AdministrationError;
@@ -65,7 +65,7 @@ impl MultisigAuthority {
6565
// could be added in the future if multiple signature schemes are needed.
6666
pub fn verify_action_signature(
6767
&self,
68-
payload: &SignedPayload,
68+
payload: &SignedAction,
6969
max_seqno_gap: NonZero<u8>,
7070
) -> Result<SeqNoToken, AdministrationError> {
7171
if payload.seqno <= self.last_seqno {

crates/subprotocols/admin/src/handler.rs

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use strata_asm_common::{
55
};
66
use strata_asm_txs_admin::{
77
actions::{MultisigAction, UpdateAction, updates::predicate::ProofType},
8-
parser::SignedPayload,
8+
signed_action::SignedAction,
99
};
1010
use strata_identifiers::{Buf32, L1Height};
1111
use strata_predicate::{PredicateKey, PredicateTypeId};
@@ -99,7 +99,7 @@ pub(crate) fn handle_pending_updates(
9999
/// * `Err(AdministrationError)` if validation failed or the action could not be processed
100100
pub(crate) fn handle_action(
101101
state: &mut AdministrationSubprotoState,
102-
payload: SignedPayload,
102+
payload: SignedAction,
103103
current_height: L1Height,
104104
relayer: &mut impl MsgRelayer,
105105
) -> Result<(), AdministrationError> {
@@ -192,7 +192,7 @@ mod tests {
192192
seq::SequencerUpdate,
193193
},
194194
},
195-
parser::SignedPayload,
195+
signed_action::SignedAction,
196196
test_utils::create_signature_set,
197197
};
198198
use strata_crypto::{
@@ -318,7 +318,7 @@ mod tests {
318318
let action = MultisigAction::Update(update.clone());
319319
let sighash = action.compute_sighash(seqno);
320320
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
321-
let payload = SignedPayload::new(seqno, action, sig_set);
321+
let payload = SignedAction::new(seqno, action, sig_set);
322322
handle_action(&mut state, payload, current_height, &mut relayer).unwrap();
323323

324324
// Verify state changes after processing
@@ -371,7 +371,7 @@ mod tests {
371371
let action = MultisigAction::Update(update.clone());
372372
let sighash = action.compute_sighash(valid_seqno);
373373
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
374-
let payload = SignedPayload::new(valid_seqno, action, sig_set);
374+
let payload = SignedAction::new(valid_seqno, action, sig_set);
375375
let res = handle_action(&mut state, payload, current_height, &mut relayer);
376376
assert!(res.is_ok());
377377

@@ -380,7 +380,7 @@ mod tests {
380380
let sighash = action.compute_sighash(1);
381381
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
382382

383-
let payload = SignedPayload::new(1, action, sig_set);
383+
let payload = SignedAction::new(1, action, sig_set);
384384
let res = handle_action(&mut state, payload, current_height, &mut relayer);
385385

386386
assert!(res.is_err());
@@ -397,7 +397,7 @@ mod tests {
397397
let action = MultisigAction::Update(update.clone());
398398
let sighash = action.compute_sighash(0);
399399
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
400-
let payload = SignedPayload::new(0, action, sig_set);
400+
let payload = SignedAction::new(0, action, sig_set);
401401
let res = handle_action(&mut state, payload, current_height, &mut relayer);
402402
assert!(matches!(res, Err(AdministrationError::InvalidSeqno { .. })));
403403
}
@@ -438,7 +438,7 @@ mod tests {
438438
let sighash = action.compute_sighash(payload_seqno);
439439
let sig_set = create_signature_set(&seq_manager_sks, &signer_indices, sighash);
440440

441-
let payload = SignedPayload::new(payload_seqno, action, sig_set);
441+
let payload = SignedAction::new(payload_seqno, action, sig_set);
442442
handle_action(&mut state, payload, current_height, &mut relayer).unwrap();
443443

444444
// Verify state changes after processing
@@ -531,7 +531,7 @@ mod tests {
531531
let sighash = update_action.compute_sighash(payload_seqno);
532532
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
533533

534-
let payload = SignedPayload::new(payload_seqno, update_action, sig_set);
534+
let payload = SignedAction::new(payload_seqno, update_action, sig_set);
535535
handle_action(&mut state, payload, current_height, &mut relayer).unwrap();
536536
}
537537

@@ -552,7 +552,7 @@ mod tests {
552552
let sighash = cancel_action.compute_sighash(payload_seqno);
553553
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
554554

555-
let payload = SignedPayload::new(payload_seqno, cancel_action, sig_set);
555+
let payload = SignedAction::new(payload_seqno, cancel_action, sig_set);
556556
handle_action(&mut state, payload, current_height, &mut relayer).unwrap();
557557

558558
// Verify state changes after cancellation
@@ -587,7 +587,7 @@ mod tests {
587587
let cancel_action: CancelAction = arb.generate();
588588
let cancel_action = MultisigAction::Cancel(cancel_action);
589589

590-
let payload = SignedPayload::new(arb.generate(), cancel_action, sig_set);
590+
let payload = SignedAction::new(arb.generate(), cancel_action, sig_set);
591591
let res = handle_action(&mut state, payload, current_height, &mut relayer);
592592

593593
assert!(matches!(res, Err(AdministrationError::UnknownAction(_))));
@@ -621,7 +621,7 @@ mod tests {
621621
let sighash = update_action.compute_sighash(update_seqno);
622622
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
623623

624-
let payload = SignedPayload::new(update_seqno, update_action, sig_set);
624+
let payload = SignedAction::new(update_seqno, update_action, sig_set);
625625
handle_action(&mut state, payload, current_height, &mut relayer).unwrap();
626626

627627
// Cancel the update action (authority seqno is now 1, use seqno 2)
@@ -630,7 +630,7 @@ mod tests {
630630
let sighash = cancel_action.compute_sighash(cancel_seqno);
631631
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
632632

633-
let payload = SignedPayload::new(cancel_seqno, cancel_action, sig_set);
633+
let payload = SignedAction::new(cancel_seqno, cancel_action, sig_set);
634634
let res = handle_action(&mut state, payload, current_height, &mut relayer);
635635

636636
assert!(res.is_ok());
@@ -640,7 +640,7 @@ mod tests {
640640
let retry_seqno = last_seqno + 3;
641641
let sighash = cancel_action.compute_sighash(retry_seqno);
642642
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
643-
let payload = SignedPayload::new(retry_seqno, cancel_action, sig_set);
643+
let payload = SignedAction::new(retry_seqno, cancel_action, sig_set);
644644
let res = handle_action(&mut state, payload, current_height, &mut relayer);
645645
assert!(res.is_err());
646646
assert!(matches!(res, Err(AdministrationError::UnknownAction(_))));
@@ -662,15 +662,15 @@ mod tests {
662662
let action = MultisigAction::Update(updates[0].clone());
663663
let sighash = action.compute_sighash(1);
664664
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
665-
let payload = SignedPayload::new(1, action, sig_set);
665+
let payload = SignedAction::new(1, action, sig_set);
666666
handle_action(&mut state, payload, current_height, &mut relayer).unwrap();
667667

668668
// Second action at seqno 11 (last_seqno is 1, gap = 10 = max_seqno_gap)
669669
let gap_seqno = 1 + state.max_seqno_gap().get() as u64;
670670
let action = MultisigAction::Update(updates[1].clone());
671671
let sighash = action.compute_sighash(gap_seqno);
672672
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
673-
let payload = SignedPayload::new(gap_seqno, action, sig_set);
673+
let payload = SignedAction::new(gap_seqno, action, sig_set);
674674
let res = handle_action(&mut state, payload, current_height, &mut relayer);
675675

676676
assert!(
@@ -695,7 +695,7 @@ mod tests {
695695
let action = MultisigAction::Update(update);
696696
let sighash = action.compute_sighash(too_far_seqno);
697697
let sig_set = create_signature_set(&admin_sks, &signer_indices, sighash);
698-
let payload = SignedPayload::new(too_far_seqno, action, sig_set);
698+
let payload = SignedAction::new(too_far_seqno, action, sig_set);
699699
let res = handle_action(&mut state, payload, current_height, &mut relayer);
700700

701701
assert!(res.is_err());

crates/subprotocols/admin/src/subprotocol.rs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
//! with the Strata Anchor State Machine (ASM) for managing protocol governance and updates.
55
66
use strata_asm_common::{
7-
MsgRelayer, NullMsg, Subprotocol, SubprotocolId, TxInputRef, VerifiedAuxData,
7+
MsgRelayer, NullMsg, Subprotocol, SubprotocolId, TxInputRef, VerifiedAuxData, logging::warn,
88
};
99
use strata_asm_params::AdministrationInitConfig;
1010
use strata_asm_txs_admin::{constants::ADMINISTRATION_SUBPROTOCOL_ID, parser::parse_tx};
@@ -55,10 +55,26 @@ impl Subprotocol for AdministrationSubprotocol {
5555

5656
// Phase 2: Process incoming administration transactions
5757
for tx in txs {
58-
if let Ok(signed_payload) = parse_tx(tx) {
59-
let _ = handle_action(state, signed_payload, current_height, relayer);
58+
match parse_tx(tx) {
59+
Ok(signed_action) => {
60+
if let Err(error) = handle_action(state, signed_action, current_height, relayer)
61+
{
62+
warn!(
63+
tx_id = %tx.tx().compute_txid(),
64+
error = %error,
65+
"Failed to process admin tx; skipping",
66+
);
67+
}
68+
}
69+
Err(error) => {
70+
warn!(
71+
tx_id = %tx.tx().compute_txid(),
72+
raw_tx_type = tx.tag().tx_type(),
73+
error = %error,
74+
"Failed to parse admin tx; skipping",
75+
);
76+
}
6077
}
61-
// Transaction parsing failures are silently ignored to maintain system resilience
6278
}
6379
}
6480

tests/asm/admin.rs

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,11 @@ use harness::{
3535
};
3636
use integration_tests::harness;
3737
use rand::rngs::OsRng;
38-
use ssz::Encode;
3938
use strata_asm_params::Role;
4039
use strata_asm_txs_admin::{
4140
actions::{updates::predicate::ProofType, Sighash},
4241
constants::ADMINISTRATION_SUBPROTOCOL_ID,
43-
parser::SignedPayload,
42+
signed_action::SignedAction,
4443
test_utils::create_signature_set,
4544
};
4645
use strata_crypto::{
@@ -350,11 +349,11 @@ async fn test_wrong_key_rejected() {
350349
let seqno = 1;
351350
let sighash = action.compute_sighash(seqno);
352351
let sig_set = create_signature_set(&[wrong_privkey], &[0u8], sighash);
353-
let signed = SignedPayload::new(seqno, action.clone(), sig_set);
354-
let payload = signed.as_ssz_bytes();
352+
let signed_action = SignedAction::new(seqno, action.clone(), sig_set);
353+
let payload = signed_action.payload_bytes();
355354

356355
let tx = harness
357-
.build_envelope_tx(action.tag(), payload)
356+
.build_envelope_tx(signed_action.tag(), payload)
358357
.await
359358
.unwrap();
360359

@@ -401,11 +400,11 @@ async fn test_corrupted_signature_rejected() {
401400
}
402401

403402
let corrupted_sig_set = SignatureSet::new(indexed_sigs).unwrap();
404-
let signed = SignedPayload::new(seqno, action.clone(), corrupted_sig_set);
405-
let payload = signed.as_ssz_bytes();
403+
let signed_action = SignedAction::new(seqno, action.clone(), corrupted_sig_set);
404+
let payload = signed_action.payload_bytes();
406405

407406
let tx = harness
408-
.build_envelope_tx(action.tag(), payload)
407+
.build_envelope_tx(signed_action.tag(), payload)
409408
.await
410409
.unwrap();
411410

@@ -474,20 +473,20 @@ async fn test_multiple_updates_same_block() {
474473
let action2 = sequencer_update([8u8; 32]);
475474
let action3 = sequencer_update([9u8; 32]);
476475

477-
let payload1 = ctx.sign(&action1);
478-
let payload2 = ctx.sign(&action2);
479-
let payload3 = ctx.sign(&action3);
476+
let signed_action_1 = ctx.sign(&action1);
477+
let signed_action_2 = ctx.sign(&action2);
478+
let signed_action_3 = ctx.sign(&action3);
480479

481480
let tx1 = harness
482-
.build_envelope_tx(action1.tag(), payload1)
481+
.build_envelope_tx(signed_action_1.tag(), signed_action_1.payload_bytes())
483482
.await
484483
.unwrap();
485484
let tx2 = harness
486-
.build_envelope_tx(action2.tag(), payload2)
485+
.build_envelope_tx(signed_action_2.tag(), signed_action_2.payload_bytes())
487486
.await
488487
.unwrap();
489488
let tx3 = harness
490-
.build_envelope_tx(action3.tag(), payload3)
489+
.build_envelope_tx(signed_action_3.tag(), signed_action_3.payload_bytes())
491490
.await
492491
.unwrap();
493492

tests/harness/admin.rs

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use bitcoin::{
2323
secp256k1::{PublicKey, Secp256k1, SecretKey},
2424
BlockHash,
2525
};
26-
use ssz::Encode;
2726
use strata_asm_common::{AnchorState, Subprotocol};
2827
use strata_asm_params::{AdministrationInitConfig, Role};
2928
use strata_asm_proto_administration::{AdministrationSubprotoState, AdministrationSubprotocol};
@@ -37,7 +36,7 @@ use strata_asm_txs_admin::{
3736
},
3837
CancelAction, MultisigAction, Sighash, UpdateAction,
3938
},
40-
parser::SignedPayload,
39+
signed_action::SignedAction,
4140
test_utils::create_signature_set,
4241
};
4342
use strata_crypto::{
@@ -97,10 +96,10 @@ impl AdminContext {
9796
}
9897
}
9998

100-
/// Sign an action and return the serialized payload.
99+
/// Sign an action and return the signed admin payload.
101100
///
102101
/// Auto-increments the appropriate role's sequence number after signing.
103-
pub fn sign(&mut self, action: &MultisigAction) -> Vec<u8> {
102+
pub fn sign(&mut self, action: &MultisigAction) -> SignedAction {
104103
let role = Self::role_for_action(action);
105104
let seqno = *self.seqnos.entry(role).or_insert(1);
106105
let result = self.sign_impl(action, seqno);
@@ -111,7 +110,7 @@ impl AdminContext {
111110
/// Sign an action with a specific sequence number (for replay attack testing).
112111
///
113112
/// Does NOT auto-increment the internal sequence number.
114-
pub fn sign_with_seqno(&self, action: &MultisigAction, seqno: u64) -> Vec<u8> {
113+
pub fn sign_with_seqno(&self, action: &MultisigAction, seqno: u64) -> SignedAction {
115114
self.sign_impl(action, seqno)
116115
}
117116

@@ -133,10 +132,10 @@ impl AdminContext {
133132
}
134133
}
135134

136-
fn sign_impl(&self, action: &MultisigAction, seqno: u64) -> Vec<u8> {
135+
fn sign_impl(&self, action: &MultisigAction, seqno: u64) -> SignedAction {
137136
let sighash = action.compute_sighash(seqno);
138137
let sig_set = create_signature_set(&self.privkeys, &self.signer_indices, sighash);
139-
SignedPayload::new(seqno, action.clone(), sig_set).as_ssz_bytes()
138+
SignedAction::new(seqno, action.clone(), sig_set)
140139
}
141140
}
142141

@@ -242,8 +241,10 @@ impl AdminExt for AsmTestHarness {
242241
ctx: &mut AdminContext,
243242
action: MultisigAction,
244243
) -> anyhow::Result<BlockHash> {
245-
let payload = ctx.sign(&action);
246-
let tx = self.build_envelope_tx(action.tag(), payload).await?;
244+
let signed_action = ctx.sign(&action);
245+
let tx = self
246+
.build_envelope_tx(signed_action.tag(), signed_action.payload_bytes())
247+
.await?;
247248
self.submit_and_mine_tx(&tx).await
248249
}
249250

@@ -253,9 +254,10 @@ impl AdminExt for AsmTestHarness {
253254
action: MultisigAction,
254255
seqno: u64,
255256
) -> anyhow::Result<BlockHash> {
256-
let tag = action.tag();
257-
let payload = ctx.sign_with_seqno(&action, seqno);
258-
let tx = self.build_envelope_tx(tag, payload).await?;
257+
let signed_action = ctx.sign_with_seqno(&action, seqno);
258+
let tx = self
259+
.build_envelope_tx(signed_action.tag(), signed_action.payload_bytes())
260+
.await?;
259261
self.submit_and_mine_tx(&tx).await
260262
}
261263
}

0 commit comments

Comments
 (0)