-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: extracting transaction witness (#327)
* feat: extract witness from tx * fix: format * fix: add word to dic * fix: add witness to block data and add utils file * fix: add babbage block test * fix: new babbage block + fix name * fix: update babbage block data * fix: babbage block data slot 67749703 * fix: move utils blake * fix: cargo toml * fix: update test data
- Loading branch information
Showing
6 changed files
with
180 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -224,6 +224,7 @@ upnp | |
utimensat | ||
vitss | ||
vkey | ||
vkeywitness | ||
VKEYS | ||
voteplan | ||
voteplans | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
//! Transaction Witness | ||
use std::fmt::{Display, Formatter}; | ||
|
||
use dashmap::DashMap; | ||
use pallas::{codec::utils::Bytes, ledger::traverse::MultiEraTx}; | ||
|
||
use crate::utils::blake2b_244; | ||
|
||
/// `WitnessMap` type of `DashMap` with | ||
/// key as [u8; 28] = (`blake2b_244` hash of the public key) | ||
/// value as (Bytes, Vec<u8>) = (public key, tx index within the block) | ||
#[allow(dead_code)] | ||
pub(crate) type WitnessMap = DashMap<[u8; 28], (Bytes, Vec<u8>)>; | ||
|
||
#[derive(Debug)] | ||
#[allow(dead_code)] | ||
/// `TxWitness` struct to store the witness data. | ||
pub(crate) struct TxWitness(WitnessMap); | ||
|
||
#[allow(dead_code)] | ||
impl TxWitness { | ||
/// Create a new `TxWitness` from a list of `MultiEraTx`. | ||
pub(crate) fn new(txs: &[MultiEraTx]) -> anyhow::Result<Self> { | ||
let map: WitnessMap = DashMap::new(); | ||
for (i, tx) in txs.iter().enumerate() { | ||
match tx { | ||
MultiEraTx::AlonzoCompatible(tx, _) => { | ||
let witness_set = &tx.transaction_witness_set; | ||
if let Some(vkey_witness_set) = witness_set.vkeywitness.clone() { | ||
for vkey_witness in vkey_witness_set { | ||
let vkey_hash = blake2b_244(&vkey_witness.vkey)?; | ||
let tx_num = u8::try_from(i)?; | ||
map.entry(vkey_hash) | ||
.and_modify(|entry: &mut (_, Vec<u8>)| entry.1.push(tx_num)) | ||
.or_insert((vkey_witness.vkey.clone(), vec![tx_num])); | ||
} | ||
}; | ||
}, | ||
MultiEraTx::Babbage(tx) => { | ||
let witness_set = &tx.transaction_witness_set; | ||
if let Some(vkey_witness_set) = witness_set.vkeywitness.clone() { | ||
for vkey_witness in vkey_witness_set { | ||
let vkey_hash = blake2b_244(&vkey_witness.vkey)?; | ||
let tx_num = u8::try_from(i)?; | ||
map.entry(vkey_hash) | ||
.and_modify(|entry: &mut (_, Vec<u8>)| entry.1.push(tx_num)) | ||
.or_insert((vkey_witness.vkey.clone(), vec![tx_num])); | ||
} | ||
} | ||
}, | ||
MultiEraTx::Conway(tx) => { | ||
let witness_set = &tx.transaction_witness_set; | ||
if let Some(vkey_witness_set) = &witness_set.vkeywitness.clone() { | ||
for vkey_witness in vkey_witness_set { | ||
let vkey_hash = blake2b_244(&vkey_witness.vkey)?; | ||
let tx_num = u8::try_from(i)?; | ||
map.entry(vkey_hash) | ||
.and_modify(|entry: &mut (_, Vec<u8>)| entry.1.push(tx_num)) | ||
.or_insert((vkey_witness.vkey.clone(), vec![tx_num])); | ||
} | ||
} | ||
}, | ||
_ => {}, | ||
}; | ||
} | ||
Ok(Self(map)) | ||
} | ||
|
||
/// Check whether the public key hash is in the given transaction number. | ||
pub(crate) fn check_witness_in_tx(&self, vkey_hash: &[u8; 28], tx_num: u8) -> bool { | ||
self.0 | ||
.get(vkey_hash) | ||
.map_or(false, |entry| entry.1.contains(&tx_num)) | ||
} | ||
|
||
/// Get the actual address from the given public key hash. | ||
pub(crate) fn get_witness_pk_addr(&self, vkey_hash: &[u8; 28]) -> Option<Bytes> { | ||
self.0.get(vkey_hash).map(|entry| entry.0.clone()) | ||
} | ||
} | ||
|
||
impl Display for TxWitness { | ||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { | ||
for data in &self.0 { | ||
let vkey_hash = hex::encode(data.key()); | ||
let vkey: Vec<u8> = data.0.clone().into(); | ||
let vkey_encoded = hex::encode(&vkey); | ||
writeln!( | ||
f, | ||
"Key Hash: {}, PublicKey: {}, Tx: {:?}", | ||
vkey_hash, vkey_encoded, data.1 | ||
)?; | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
#[cfg(test)] | ||
mod tests { | ||
|
||
use super::*; | ||
use crate::multi_era_block_data::tests::{alonzo_block, babbage_block}; | ||
|
||
#[test] | ||
fn tx_witness() { | ||
let alonzo = alonzo_block(); | ||
let alonzo_block = pallas::ledger::traverse::MultiEraBlock::decode(&alonzo) | ||
.expect("Failed to decode MultiEraBlock"); | ||
let txs_alonzo = alonzo_block.txs(); | ||
let tx_witness_alonzo = TxWitness::new(&txs_alonzo).expect("Failed to create TxWitness"); | ||
let vkey1_hash: [u8; 28] = | ||
hex::decode("6082eb618d161a704207a0b3a9609e820111570d94d1e711b005386c") | ||
.expect("Failed to decode vkey1_hash") | ||
.try_into() | ||
.expect("Invalid length of vkey1_hash"); | ||
println!("{tx_witness_alonzo}"); | ||
assert!(tx_witness_alonzo.get_witness_pk_addr(&vkey1_hash).is_some()); | ||
assert!(tx_witness_alonzo.check_witness_in_tx(&vkey1_hash, 0)); | ||
|
||
let babbage = babbage_block(); | ||
let babbage_block = pallas::ledger::traverse::MultiEraBlock::decode(&babbage) | ||
.expect("Failed to decode MultiEraBlock"); | ||
let txs_babbage = babbage_block.txs(); | ||
let tx_witness_babbage = TxWitness::new(&txs_babbage).expect("Failed to create TxWitness"); | ||
let vkey2_hash: [u8; 28] = | ||
hex::decode("ba4ab50bdecca85162f3b8114739bc5ba3aaa6490e2b1d15ad0f9c66") | ||
.expect("Failed to decode vkey2_hash") | ||
.try_into() | ||
.expect("Invalid length of vkey2_hash"); | ||
println!("{tx_witness_babbage}"); | ||
assert!(tx_witness_babbage | ||
.get_witness_pk_addr(&vkey2_hash) | ||
.is_some()); | ||
assert!(tx_witness_babbage.check_witness_in_tx(&vkey2_hash, 0)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
820685828a1a002751831a0409c74758208f359d2ca9a3e513b574cc88c93346506e2520f9939eadfc2e02e6c251a94769582069b5785508a9898605833a7c346c9fa294eb9e6793e0887a0230a1e026ebd1fa5820e9fff58586a4a588f15f371b4d7bfc04344b6a281bce39a7ab81fe5b6751cbac825840df4ca9e1e98212e3bfa0356274e63890304710237e92973de89d8dfba015f3eb8e925557cadcb70031cd644fe84b043f260e81342bf865d811409ae2aefb528458509aab92e40a5c75252e190d6860fbe0274ee6f7de16d12256df1dbd1f08b0f835fc0f333395d8d94464e5181e72c3fd935573005f03656191e9e95855f8fbcfd3456a6c268df905c805c9e510dff0df0f190c505820e6aebff5e8b2049914014d88821ef94b873b219ea32b44a50161b7bd2442deb5845820356e1f77552adeab6d94c2383cb4f7a5fb1b644858a6639cf9f71da339ad1e17081901ff5840fc25623ba50cf9f2858463dca7a3b1c703b97bd49d54e965d2df9602424986bf26e29ab4dac9b82f185cb825cd4a0b6dbc90374defd9ca20206cd25f47dc01058209015901c07d47377a4d51a9ed20b203308e73c500db49947189f6c92e951ab0d24b131d20d0f157fdf10a90aad4c8c6173dcd8d16b834ff47f1914556ae14b8015d7edc0ea0c33c70c7867e06a2952efe9066ceae6e1b9b23c59c76148f01917099657153af53c0cb5bb0a601d6e7e504033c2522fe069dda3a488d189032fd4ff59273526b263cabf7966326054aa26bb3d3e24010aa1edec3a545c80a1e1e357b0bea164c6663240e865cff3e29d30862b99f1ce52ca042f5d7d065bc29cc7d4ccce45acce31cc0da588c4ddec1fd4e3444ace1bf583df247ba168e0375862090fa4f49fa95fd28df6ce88f72e303d1f9cd4353abdd2d1a4472164d15220142e922b03eb6657152f340cf460514bbe57e892b81fe633d395773c00b91025237ed84ef5c6541d6bccb5a56f736b294fc6500aaa9e958c7b41bd422200545efbf0e5eb0ff95fc2394ab22cb543854aab426f60ab5dc04fa9ca3d9cc71a2abcf00c1ef8287f9bd9f7508fc5cc6a4513faac33b05b06304883ec50acb9c1ee3033604ce4eebe75beba7e97a731f92c6e779ecf700c3220ec992752b49708cab9d9a079803a01832cb14da7c59d069c4538cadd38c90b6502ce3b311424eaba7676f3dbc720b84ab008382582022d427bf2262a44dc3a3a2c9555696a741d779eb89afecf624e91a1ebdf3335400825820533e9251fd0ed7ac8613fe3d05813ce3bde7d96a6e446019a93421a0c6b785a50282582090b06350ad57403e8dcdb49d4f9fad5de1b244668fd5a0c98cd08b78d5f343b3010183a300581d704e3b75eb68829ca9e63b541f3645f78afe8d119932a7a2528171e74901821a001e8480a1581c5cf48c225e057f8da0787eae1e2bc62a1cf1d2ee34c7e2a9498b19b5a1484e6f64654665656401028201d8185840d87a9fd8799f581cba4ab50bdecca85162f3b8114739bc5ba3aaa6490e2b1d15ad0f9c66d8799fd8799f1b0000000da0e77c201b00000191449a86f5ffffffff82581d60ba4ab50bdecca85162f3b8114739bc5ba3aaa6490e2b1d15ad0f9c661a0089544082581d60ba4ab50bdecca85162f3b8114739bc5ba3aaa6490e2b1d15ad0f9c661a00ac398c021a00044c8c031a0409c766081a0409c6ee0b5820dbf505c29f869273f15ea579723e9ca9bcf31fdb8c4cb4e4085268f3714b99b90d818258206f8ebcf2a2b04f5cb5f977aa1e41001301634e64a532a8de1e98147cc84e6502010e81581cba4ab50bdecca85162f3b8114739bc5ba3aaa6490e2b1d15ad0f9c661082581d60ba4ab50bdecca85162f3b8114739bc5ba3aaa6490e2b1d15ad0f9c661a00524801111a00370c3f1281825820efd8a48f69e5270cb73b438067e1b566d39758329a45e5d6d36755f2c732618400ab00838258201df5c710d3251bea8457e05813101bd7f8defaba978114939ffa38035d42672a02825820e04bce69a5659295c235502d5fdb62b29e43f773e698c97e533e394d92d9228001825820ec4b6e2455e84a8aaa365cdc4c41ee446314ea74c209e698f1785c94c9952910000183a300581d704e3b75eb68829ca9e63b541f3645f78afe8d119932a7a2528171e74901821a001e8480a1581c5cf48c225e057f8da0787eae1e2bc62a1cf1d2ee34c7e2a9498b19b5a1484e6f64654665656401028201d8185840d87a9fd8799f581c3f2728ec78ef8b0f356e91a5662ff3124add324a7b7f5aeed69362f4d8799fd8799f1b0000000da0cc2bf01b00000191449a8523ffffffff82581d603f2728ec78ef8b0f356e91a5662ff3124add324a7b7f5aeed69362f41a0089544082581d603f2728ec78ef8b0f356e91a5662ff3124add324a7b7f5aeed69362f41a00a1cf51021a0004529a031a0409c766081a0409c6ee0b5820ed60fdd0e4e9cc43b5fa9a601a3d013c6a8f26916ff80e9b5c5a41813493f04e0d8182582040d412944923070bbdeca4887e30983b497e455e62a150209d522c4f2eec82f5020e81581c3f2728ec78ef8b0f356e91a5662ff3124add324a7b7f5aeed69362f41082581d603f2728ec78ef8b0f356e91a5662ff3124add324a7b7f5aeed69362f41a00455948111a00370c3f1281825820efd8a48f69e5270cb73b438067e1b566d39758329a45e5d6d36755f2c732618400ab00838258203efd5491b62cec43b8421eeb9978d9544a451cf938b454278dabfe508a867175008258204d1deb722bdab493e69840eca2fbb2af5eed36a82d2cd196754ce4af2618ecb902825820f1883a3368b6baa87f5d051d3e7fedb0c571519333f38860b54ec7b4dec3253e010183a300581d704e3b75eb68829ca9e63b541f3645f78afe8d119932a7a2528171e74901821a001e8480a1581c5cf48c225e057f8da0787eae1e2bc62a1cf1d2ee34c7e2a9498b19b5a1484e6f64654665656401028201d8185840d87a9fd8799f581c17942ff3849b623d24e31ec709c1c94c53b9240311820a9601ad4af0d8799fd8799f1b0000000da0cc2bf01b00000191449a8522ffffffff82581d6017942ff3849b623d24e31ec709c1c94c53b9240311820a9601ad4af01a0089544082581d6017942ff3849b623d24e31ec709c1c94c53b9240311820a9601ad4af01a0073c968021a00044c8c031a0409c766081a0409c6ee0b5820dbf505c29f869273f15ea579723e9ca9bcf31fdb8c4cb4e4085268f3714b99b90d818258204c6d1cb7cba6122de41fb91be0f78b61316399096d6f54bd7e3f2f76dd63b92e020e81581c17942ff3849b623d24e31ec709c1c94c53b9240311820a9601ad4af01082581d6017942ff3849b623d24e31ec709c1c94c53b9240311820a9601ad4af01a004df567111a00370c3f1281825820efd8a48f69e5270cb73b438067e1b566d39758329a45e5d6d36755f2c732618400a50081825820aa7bbea2a5101b867d969ad7e6ff7d95d440199ef4ba6621751d25521566101400018182583900eb21979c03eed7207020b2a0b47565b5aafb1a2c3849b59a1fa8e6c5e075be10ec5c575caffb68b08c31470666d4fe1aeea07c16d64739031b00000002525569af021a00032471075820420e72fc38474ce192fc9ba39380a11ddf9e5ac96a814d3fdb68c24cbf81e4600f0084a200818258209a12ec259e59bd8fc60244062f294f11555539f5fd45e77d8a57f16b5987dc4458401944ed87d70eb6646aa840b9914c462b1e4e3513831d1f5ec817a6966d00c0b6f12bf24b0576ea9593ed4f9c9dac2f0d9e15473088e64f688f3dea4416dbe90d0581840000d87980821a0012a1311a15d0fa8ba20081825820499300f082db931c561f42b9ca7d5ea4b288ae74cf1969d1fbd7bf41e7b02e8e5840504c78c1fe246730ca7c2469ba6731cf7e0aff42bd027091283568fe25d2a9f35da1593fb89e5bfd2f7d2db58316ee86ed1c8380e8fb77d61362c78f64374a010581840002d87980821a0012eff61a1622a0d4a20081825820ae01a85ba5eb8e67830cf6b422cb819cac1eaf0c7f62dbc496f12d9735b170d7584004dd05c7ea8b1ab964f67bfe4515e18451b23ee7950c8224f9b355aa1005ba1c7051951e82883c9cb25be7ada388fe2b708eaa6d9f1590516f2782f8b5ff20050581840000d87980821a0012a1311a15d0fa8ba100818258208469288efa6f9cb49040b43dcff93f40969d72433f751afde50235012c01602058401d84bfa159ac070a11834e2a41b38f205ce1628ccdc693fe2000e21c680e6ead1a23a23043bb99ac1de8460fee2f5b40d3a736566b9434d1b551b115956b5004a103a11901fda50050ca7a1457ef9f4c7f9c747f8c4a4cfa6c0150152a368b96d95f61ae69513dd5f6e92a0258204d3f576f26db29139981a69443c2325daa812cc353a31b5a4db794a5bcbb06c20b8c58401b3d030866084fcb259de07496d3197e913a39fd628a3db0a4ed6839261a00c51cb0a5b9c16194064132ace375ea23c75c60659400cba304d0d689c00086195d5840ff28714da02c35e7295815ba58b77f227e576fa254c464e2f9c6f9dfa900a0208250033c054a468c38e08819601d073c034a4727a524ff39995477443c1fca235840839c927599b253887f50487c1caf757c0aaf79bc3fcacd42252b8f2ae1f1a8b282929ca22bb5c2885cc23a66005c0cc1ca20142b82310c3a137d44c1943e40995840a7a7ce5c3475b5887a3765ede2ff3b7bfea90f255e2edf37fd44e27f26b8e6cf408aef4b20bebf7257b3dabc7eda65fff4ed278b50219f0a52367ff5b80e46b758403875f55a394d17a5d9a6b1a1deff5b2206e9e9734e9fbefa6a1cdfeb7a104546dfb6e46c46feaeb65a7f4648c276e29e87b27bc053bffef79359300220d0c3875840f2a05cc4880317358e19c758fd9ab9917551ce3987af2e35d73b6958a0f5732784621b0c92f68a93537f16f48445424890f955d7a597c13c2eb54a82b39f0307584097507df5fef916fabb6dafdfb516fb9184783e2cb4e89d048a6c1e5c04818bdb76ffb5cbef1fbe452658d904cd152ee72a3bfc6efe1199fb3b51f1979629cd4e5840fdb7df511723d4cead3d2b2eb9c1f18cbbfcf9f5cc8eac46dc03cd55fcac3303c391437f50400923e65c02e981af5461b6867a47fb25ebe9b0fb4d9e41ec210e58404b9011000206414523c0990f9ee20b5d8a745393d3febaf6413a448b994f1567eb7945df7a0ab44afd55561e0190b376d411026c5d7a4a49a19e0bd3f5addd6c5840492fde46eee8d75b587286291dfeb6a78fdf59c1a6bfa2717b1f41dfa878756140ce7c77504b64b094b870ade78569566eec66369133af5aa8c8eab9f95e29df58409ec10be251547101b24c495c8ff4fa55378dbb4a5c6e89b18a12ac033343d61c3b7f5fba725b51536d92a5cbfaef9be6d24a3e5b3d75a1c0e29e42f523567fac4d0f8200811c822d2210b97f5708186358407b322d37df11460b98e13f6c3c4d5d4985ad984768d09f77516e8e0f61ed24e646c466a995c2bf2b547302b96d4582be9b65f8d52f9fbc4857e7bef79948860180 |