Add validation to demo transaction builder.

This commit is contained in:
Kris Nuttycombe 2020-05-26 14:49:02 -06:00
parent 659c34a954
commit ca8e24eef5
2 changed files with 44 additions and 18 deletions

View File

@ -309,18 +309,28 @@ pub struct DemoBuilder<'a, B> {
extension_id: usize,
}
pub enum DemoBuildError<E> {
BaseBuilderError(E),
ExpectedOpen,
ExpectedClose,
PrevoutParseFailure(Error),
TransferMismatch { expected: [u8; 32], actual: [u8; 32] },
CloseMismatch { expected: [u8; 32], actual: [u8; 32] },
}
impl<'a, B: ExtensionTxBuilder<'a>> DemoBuilder<'a, B> {
pub fn demo_open(
&mut self,
value: Amount,
preimage_1: [u8; 32],
preimage_2: [u8; 32],
) -> Result<(), B::BuildError> {
) -> Result<(), DemoBuildError<B::BuildError>> {
let (hash_1, _) = builder_hashes(&preimage_1, &preimage_2);
// Call through to the generic builder.
self.txn_builder
.add_tze_output(self.extension_id, value, &Precondition::open(hash_1))
.map_err(DemoBuildError::BaseBuilderError)
}
pub fn demo_transfer_to_close(
@ -329,37 +339,63 @@ impl<'a, B: ExtensionTxBuilder<'a>> DemoBuilder<'a, B> {
transfer_amount: Amount,
preimage_1: [u8; 32],
preimage_2: [u8; 32],
) -> Result<(), B::BuildError> {
let (_, hash_2) = builder_hashes(&preimage_1, &preimage_2);
) -> Result<(), DemoBuildError<B::BuildError>> {
let (hash_1, hash_2) = builder_hashes(&preimage_1, &preimage_2);
// eagerly validate the relationship between prevout.1 and preimage_1
match Precondition::from_payload(prevout.1.precondition.mode, &prevout.1.precondition.payload) {
Ok(Precondition::Open(hash)) =>
if hash.0 != hash_1 {
Err(DemoBuildError::TransferMismatch { expected: hash.0, actual: hash_1})?
}
Ok(Precondition::Close(_)) =>
Err(DemoBuildError::ExpectedOpen)?,
Err(parse_failure) =>
Err(DemoBuildError::PrevoutParseFailure(parse_failure))?
}
// should we eagerly validate the relationship between prevout.1 and preimage_1?
self.txn_builder
.add_tze_input(self.extension_id, prevout, move |_| {
Ok(Witness::open(preimage_1))
})?;
})
.map_err(DemoBuildError::BaseBuilderError)?;
self.txn_builder.add_tze_output(
self.extension_id,
transfer_amount, // can this be > prevout.1.value?
&Precondition::close(hash_2),
)
.map_err(DemoBuildError::BaseBuilderError)
}
pub fn demo_close(
&mut self,
prevout: (OutPoint, TzeOut),
preimage: [u8; 32],
) -> Result<(), B::BuildError> {
preimage_2: [u8; 32],
) -> Result<(), DemoBuildError<B::BuildError>> {
let hash_2 = {
let mut hash = [0; 32];
hash.copy_from_slice(Params::new().hash_length(32).hash(&preimage).as_bytes());
hash.copy_from_slice(Params::new().hash_length(32).hash(&preimage_2).as_bytes());
hash
};
// eagerly validate the relationship between prevout.1 and preimage_2
match Precondition::from_payload(prevout.1.precondition.mode, &prevout.1.precondition.payload) {
Ok(Precondition::Open(_)) =>
Err(DemoBuildError::ExpectedClose)?,
Ok(Precondition::Close(hash)) =>
if hash.0 != hash_2 {
Err(DemoBuildError::CloseMismatch { expected: hash.0, actual: hash_2})?
}
Err(parse_failure) =>
Err(DemoBuildError::PrevoutParseFailure(parse_failure))?
}
self.txn_builder
.add_tze_input(self.extension_id, prevout, move |_| {
Ok(Witness::close(preimage_2))
})
.map_err(DemoBuildError::BaseBuilderError)
}
}
@ -483,8 +519,6 @@ mod tests {
precondition: tze::Precondition::from(0, &Precondition::open(hash_1)),
};
// println!("{:x?}", precondition.payload);
let mut mtx_a = TransactionData::nu4();
mtx_a.tze_outputs.push(out_a);
let tx_a = mtx_a.freeze().unwrap();

View File

@ -113,13 +113,6 @@ pub trait Extension<C> {
}
}
// pub trait WitnessBuilder<BuildCtx> {
// type Error;
// type Witness: ToPayload;
//
// fn build_witness(ctx: BuildCtx) -> Result<Witness, Self::Error>;
// }
// This extension trait is satisfied by the transaction::builder::Builder type. It provides a
// minimal contract for interacting with the transaction builder, that extension library authors
// can use to add extension-specific builder traits that may be used to interact with the
@ -138,7 +131,6 @@ pub trait ExtensionTxBuilder<'a> {
) -> Result<(), Self::BuildError>
where
WBuilder: 'a + (FnOnce(&Self::BuildCtx) -> Result<W, Self::BuildError>);
//where WBuilder: WitnessBuilder<Self::BuildCtx, Witness = W, Error = Self::BuildError>;
fn add_tze_output<P: ToPayload>(
&mut self,