+/// Unsigned, 128-bit integer.
+///
+/// Because LLVM implements an incorrect ABI for 128-bit integers, a wrapper type is defined here.
+/// See https://github.com/rust-lang/rust/issues/54341 for more details.
+#[derive(PartialEq, Eq, Copy, Clone)]
+#[allow(non_camel_case_types)]
+#[repr(C)]
+pub struct U128 {
+ /// The 128-bit integer, as 16 little-endian bytes
+ pub le_bytes: [u8; 16],
+}
+
+#[no_mangle]
+/// Gets the 128-bit integer, as 16 little-endian bytes
+pub extern "C" fn U128_le_bytes(val: U128) -> SixteenBytes { SixteenBytes { data: val.le_bytes } }
+#[no_mangle]
+/// Constructs a new U128 from 16 little-endian bytes
+pub extern "C" fn U128_new(le_bytes: SixteenBytes) -> U128 { U128 { le_bytes: le_bytes.data } }
+
+impl From<u128> for U128 {
+ fn from(o: u128) -> Self { Self { le_bytes: o.to_le_bytes() } }
+}
+impl From<&mut u128> for U128 {
+ fn from(o: &mut u128) -> U128 { Self::from(*o) }
+}
+impl Into<u128> for U128 {
+ fn into(self) -> u128 { u128::from_le_bytes(self.le_bytes) }
+}
+
+/// Integer in the range `0..=16`
+#[derive(PartialEq, Eq, Copy, Clone)]
+#[repr(C)]
+pub struct WitnessVersion(u8);
+
+impl From<BitcoinWitnessVersion> for WitnessVersion {
+ fn from(o: BitcoinWitnessVersion) -> Self { Self(o.to_num()) }
+}
+impl Into<BitcoinWitnessVersion> for WitnessVersion {
+ fn into(self) -> BitcoinWitnessVersion {
+ BitcoinWitnessVersion::try_from(self.0).expect("WitnessVersion objects must be in the range 0..=16")
+ }
+}
+
+/// A segregated witness version byte and script bytes
+#[repr(C)]
+#[derive(Clone)]
+pub struct WitnessProgram {
+ version: WitnessVersion,
+ program: derived::CVec_u8Z,
+}
+impl WitnessProgram {
+ pub(crate) fn from_bitcoin(o: BitcoinWitnessProgram) -> Self {
+ Self {
+ version: o.version().into(),
+ program: o.program().as_bytes().to_vec().into(),
+ }
+ }
+ pub(crate) fn into_bitcoin(mut self) -> BitcoinWitnessProgram {
+ BitcoinWitnessProgram::new(
+ self.version.into(),
+ self.program.as_slice(),
+ ).expect("Program length was previously checked")
+ }
+}
+
+#[no_mangle]
+/// Constructs a new WitnessProgram given a version and program bytes.
+///
+/// The program MUST be at least 2 bytes and no longer than 40 bytes long.
+/// Further, if the version is 0, the program MUST be either exactly 20 or exactly 32 bytes long.
+pub extern "C" fn WitnessProgram_new(version: WitnessVersion, program: derived::CVec_u8Z) -> WitnessProgram {
+ assert!(program.datalen >= 2, "WitnessProgram program lengths must be at least 2 bytes long");
+ assert!(program.datalen <= 40, "WitnessProgram program lengths must be no longer than 40 bytes");
+ if version.0 == 0 {
+ assert!(program.datalen == 20 || program.datalen == 32, "WitnessProgram program length must be 20 or 32 for version-0 programs");
+ }
+ WitnessProgram { version, program }
+}
+#[no_mangle]
+/// Gets the `WitnessVersion` of the given `WitnessProgram`
+pub extern "C" fn WitnessProgram_get_version(prog: &WitnessProgram) -> WitnessVersion {
+ prog.version
+}
+#[no_mangle]
+/// Gets the witness program bytes of the given `WitnessProgram`
+pub extern "C" fn WitnessProgram_get_program(prog: &WitnessProgram) -> u8slice {
+ u8slice::from_vec(&prog.program)
+}
+#[no_mangle]
+/// Creates a new WitnessProgram which has the same data as `orig`
+pub extern "C" fn WitnessProgram_clone(orig: &WitnessProgram) -> WitnessProgram { orig.clone() }
+#[no_mangle]
+/// Releases any memory held by the given `WitnessProgram` (which is currently none)
+pub extern "C" fn WitnessProgram_free(o: WitnessProgram) { }
+