Skip to content

Commit

Permalink
feat: encode legacy signatures as script with one element
Browse files Browse the repository at this point in the history
  • Loading branch information
tmpolaczyk committed Aug 19, 2022
1 parent e6adc69 commit 5b8c089
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 14 deletions.
20 changes: 15 additions & 5 deletions data_structures/src/transaction.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
use serde::{Deserialize, Serialize};

use crate::stack::{Item, MyValue, ScriptError};
use crate::{
chain::{
Block, Bn256PublicKey, DataRequestOutput, Epoch, Hash, Hashable, Input, KeyedSignature,
Expand Down Expand Up @@ -199,13 +200,22 @@ pub fn mint(tx: &Transaction) -> Option<&MintTransaction> {
}

pub fn vtt_signature_to_witness(ks: &KeyedSignature) -> Vec<u8> {
// TODO: it would be nice to encode KeyedSignature as a script
// This way vtt.witness is always a valid script
ks.to_pb_bytes().unwrap()
let script = vec![Item::Value(MyValue::from_signature(ks))];

crate::stack::encode(&script).unwrap()
}

pub fn vtt_witness_to_signature(witness: &[u8]) -> KeyedSignature {
KeyedSignature::from_pb_bytes(witness).unwrap()
pub fn vtt_witness_to_signature(witness: &[u8]) -> Result<KeyedSignature, ScriptError> {
let script = crate::stack::decode(witness)?;

if script.len() != 1 {
return Err(ScriptError::InvalidSignature);
}

match &script[0] {
Item::Value(value) => value.to_signature(),
_ => Err(ScriptError::InvalidSignature),
}
}

#[derive(Debug, Default, Eq, PartialEq, Clone, Serialize, Deserialize, ProtobufConvert, Hash)]
Expand Down
12 changes: 4 additions & 8 deletions src/cli/node/json_rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -904,21 +904,17 @@ pub fn sign_tx(

match tx {
Transaction::ValueTransfer(ref mut vtt) => {
let signature_bytes = signature.to_pb_bytes()?;
// TODO: this only works if the witness field represents a script
// It could also represent a signature in the case of normal value transfer
// transactions. It would be nice to also support signing normal transactions here
let signature_bytes = MyValue::from_signature(&signature);
// This also works with normal transactions, because the signature is encoded as a
// script with one element.
let mut script = witnet_data_structures::stack::decode(&vtt.witness[input_index])?;

println!(
"-----------------------\nPrevious witness:\n-----------------------\n{}",
witnet_data_structures::stack::parser::script_to_string(&script)
);

script.insert(
signature_position_in_witness,
Item::Value(MyValue::Bytes(signature_bytes)),
);
script.insert(signature_position_in_witness, Item::Value(signature_bytes));

println!(
"-----------------------\nNew witness:\n-----------------------\n{}",
Expand Down
2 changes: 1 addition & 1 deletion validations/src/validations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1243,7 +1243,7 @@ pub fn validate_transaction_signatures(
if input.redeem_script.is_empty() {
// Validate that public key hash of the pointed output matches public
// key in the provided signature
let keyed_signature = vtt_witness_to_signature(witness);
let keyed_signature = vtt_witness_to_signature(witness)?;
validate_pkh_signature(input, &keyed_signature, utxo_set).map_err(fte)?;

// Validate the actual signature
Expand Down

0 comments on commit 5b8c089

Please sign in to comment.