Skip to content

Commit c6eba60

Browse files
fix: make MockSignature signature field public (#1595)
* fix: make MockSignature signature field public * Update codec.rs * add rest of code * fix build stuff * fix: cargo fmt --------- Co-authored-by: Hugo CAILLARD <[email protected]>
1 parent 84914a6 commit c6eba60

File tree

1 file changed

+100
-4
lines changed

1 file changed

+100
-4
lines changed

components/stacks-codec/src/codec.rs

+100-4
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,14 @@ use clarity::types::chainstate::{
1414
};
1515
use clarity::types::chainstate::{StacksAddress, StacksPublicKey};
1616
use clarity::types::{PrivateKey, StacksEpochId};
17-
use clarity::util::hash::{Hash160, Sha512Trunc256Sum};
17+
use clarity::util::hash::{Hash160, Sha256Sum, Sha512Trunc256Sum};
1818
use clarity::util::retry::BoundReader;
1919
use clarity::util::secp256k1::{
2020
MessageSignature, Secp256k1PrivateKey, Secp256k1PublicKey, MESSAGE_SIGNATURE_ENCODED_SIZE,
2121
};
2222
use clarity::util::vrf::VRFProof;
2323
use clarity::vm::types::{
24-
PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, Value,
24+
PrincipalData, QualifiedContractIdentifier, StandardPrincipalData, TupleData, Value,
2525
};
2626
use clarity::vm::ClarityVersion;
2727
use clarity::vm::{ClarityName, ContractName};
@@ -4222,7 +4222,7 @@ impl SignerMessageMetadata {
42224222
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
42234223
pub struct MockSignature {
42244224
/// The signer's signature across the mock proposal
4225-
signature: MessageSignature,
4225+
pub signature: MessageSignature,
42264226
/// The mock block proposal that was signed across
42274227
pub mock_proposal: MockProposal,
42284228
/// The signature metadata
@@ -4316,7 +4316,103 @@ pub struct MockProposal {
43164316
/// The view of the stacks node peer information at the time of the mock proposal
43174317
pub peer_info: PeerInfo,
43184318
/// The miner's signature across the peer info
4319-
signature: MessageSignature,
4319+
pub signature: MessageSignature,
4320+
}
4321+
4322+
// Helper function to generate domain for structured data hash
4323+
pub fn make_structured_data_domain(name: &str, version: &str, chain_id: u32) -> Value {
4324+
Value::Tuple(
4325+
TupleData::from_data(vec![
4326+
(
4327+
"name".into(),
4328+
Value::string_ascii_from_bytes(name.into()).unwrap(),
4329+
),
4330+
(
4331+
"version".into(),
4332+
Value::string_ascii_from_bytes(version.into()).unwrap(),
4333+
),
4334+
("chain-id".into(), Value::UInt(chain_id.into())),
4335+
])
4336+
.unwrap(),
4337+
)
4338+
}
4339+
4340+
/// Message prefix for signed structured data. "SIP018" in ascii
4341+
pub const STRUCTURED_DATA_PREFIX: [u8; 6] = [0x53, 0x49, 0x50, 0x30, 0x31, 0x38];
4342+
4343+
pub fn structured_data_hash(value: Value) -> Sha256Sum {
4344+
let mut bytes = vec![];
4345+
value.serialize_write(&mut bytes).unwrap();
4346+
Sha256Sum::from_data(bytes.as_slice())
4347+
}
4348+
4349+
/// Generate a message hash for signing structured Clarity data.
4350+
/// Reference [SIP018](https://github.com/stacksgov/sips/blob/main/sips/sip-018/sip-018-signed-structured-data.md) for more information.
4351+
pub fn structured_data_message_hash(structured_data: Value, domain: Value) -> Sha256Sum {
4352+
let message = [
4353+
STRUCTURED_DATA_PREFIX.as_ref(),
4354+
structured_data_hash(domain).as_bytes(),
4355+
structured_data_hash(structured_data).as_bytes(),
4356+
]
4357+
.concat();
4358+
4359+
Sha256Sum::from_data(&message)
4360+
}
4361+
4362+
impl MockProposal {
4363+
/// The signature hash for the mock proposal
4364+
pub fn miner_signature_hash(&self) -> Sha256Sum {
4365+
let domain_tuple =
4366+
make_structured_data_domain("mock-miner", "1.0.0", self.peer_info.network_id);
4367+
let data_tuple = Value::Tuple(
4368+
TupleData::from_data(vec![
4369+
(
4370+
"stacks-tip-consensus-hash".into(),
4371+
Value::buff_from((*self.peer_info.stacks_tip_consensus_hash.as_bytes()).into())
4372+
.unwrap(),
4373+
),
4374+
(
4375+
"stacks-tip".into(),
4376+
Value::buff_from((*self.peer_info.stacks_tip.as_bytes()).into()).unwrap(),
4377+
),
4378+
(
4379+
"stacks-tip-height".into(),
4380+
Value::UInt(self.peer_info.stacks_tip_height.into()),
4381+
),
4382+
(
4383+
"server-version".into(),
4384+
Value::string_ascii_from_bytes(self.peer_info.server_version.clone().into())
4385+
.unwrap(),
4386+
),
4387+
(
4388+
"pox-consensus".into(),
4389+
Value::buff_from((*self.peer_info.pox_consensus.as_bytes()).into()).unwrap(),
4390+
),
4391+
])
4392+
.expect("Error creating signature hash"),
4393+
);
4394+
structured_data_message_hash(data_tuple, domain_tuple)
4395+
}
4396+
4397+
/// The signature hash including the miner's signature. Used by signers.
4398+
pub fn signer_signature_hash(&self) -> Sha256Sum {
4399+
let domain_tuple =
4400+
make_structured_data_domain("mock-signer", "1.0.0", self.peer_info.network_id);
4401+
let data_tuple = Value::Tuple(
4402+
TupleData::from_data(vec![
4403+
(
4404+
"miner-signature-hash".into(),
4405+
Value::buff_from((*self.miner_signature_hash().as_bytes()).into()).unwrap(),
4406+
),
4407+
(
4408+
"miner-signature".into(),
4409+
Value::buff_from((*self.signature.as_bytes()).into()).unwrap(),
4410+
),
4411+
])
4412+
.expect("Error creating signature hash"),
4413+
);
4414+
structured_data_message_hash(data_tuple, domain_tuple)
4415+
}
43204416
}
43214417

43224418
impl StacksMessageCodec for MockProposal {

0 commit comments

Comments
 (0)