From 27801f6a93f8a4bf5defc9eacd86b6bfb1464923 Mon Sep 17 00:00:00 2001 From: Antioch Peverell Date: Tue, 8 Jan 2019 16:07:38 +0000 Subject: [PATCH] Implement kernel and output features as enums (#2312) * use enums for kernel and output features * rustfmt * add test coverage around deserializing kernel features --- Cargo.lock | 2 +- api/src/handlers/utils.rs | 4 +- core/Cargo.toml | 2 +- core/src/core/transaction.rs | 149 +++++++++++++++++++------------ core/src/genesis.rs | 8 +- core/src/lib.rs | 4 +- core/src/libtx/aggsig.rs | 8 +- core/src/libtx/build.rs | 6 +- core/src/libtx/reward.rs | 6 +- core/tests/block.rs | 4 +- core/tests/core.rs | 2 +- core/tests/transaction.rs | 4 +- core/tests/verifier_cache.rs | 2 +- wallet/src/test_framework/mod.rs | 4 +- wallet/tests/libwallet.rs | 2 +- 15 files changed, 120 insertions(+), 87 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 758a772c..67c09198 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -771,11 +771,11 @@ dependencies = [ name = "grin_core" version = "0.5.1" dependencies = [ - "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)", "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 1.2.7 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", "croaring 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", + "enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "failure 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "failure_derive 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", "grin_keychain 0.5.1", diff --git a/api/src/handlers/utils.rs b/api/src/handlers/utils.rs index 3b5c9d0d..e0cfa57e 100644 --- a/api/src/handlers/utils.rs +++ b/api/src/handlers/utils.rs @@ -44,8 +44,8 @@ pub fn get_output( // For now we can just try both (but this probably needs to be part of the api // params) let outputs = [ - OutputIdentifier::new(OutputFeatures::PLAIN, &commit), - OutputIdentifier::new(OutputFeatures::COINBASE, &commit), + OutputIdentifier::new(OutputFeatures::Plain, &commit), + OutputIdentifier::new(OutputFeatures::Coinbase, &commit), ]; for x in outputs.iter() { diff --git a/core/Cargo.toml b/core/Cargo.toml index 9539fd70..a0e14134 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -10,10 +10,10 @@ workspace = ".." edition = "2018" [dependencies] -bitflags = "1" blake2-rfc = "0.2" byteorder = "1" croaring = "=0.3" +enum_primitive = "0.1" failure = "0.1" failure_derive = "0.1" lazy_static = "1" diff --git a/core/src/core/transaction.rs b/core/src/core/transaction.rs index 80269dfe..5842ad2f 100644 --- a/core/src/core/transaction.rs +++ b/core/src/core/transaction.rs @@ -28,32 +28,43 @@ use crate::util::secp; use crate::util::secp::pedersen::{Commitment, RangeProof}; use crate::util::static_secp_instance; use crate::util::RwLock; +use enum_primitive::FromPrimitive; use std::cmp::max; use std::cmp::Ordering; use std::collections::HashSet; use std::sync::Arc; use std::{error, fmt}; -bitflags! { - /// Options for a kernel's structure or use - #[derive(Serialize, Deserialize)] - pub struct KernelFeatures: u8 { - /// plain kernel has fee, but no lock_height - const PLAIN = 0; - /// coinbase kernel has neither fee nor lock_height (both zero) - const COINBASE = 1; - /// absolute height locked kernel; has fee and lock_height - const HEIGHT_LOCKED = 2; +/// Enum of various supported kernel "features". +enum_from_primitive! { + /// Various flavors of tx kernel. + #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] + #[repr(u8)] + pub enum KernelFeatures { + /// Plain kernel (the default for Grin txs). + Plain = 0, + /// A coinbase kernel. + Coinbase = 1, + /// A kernel with an expicit lock height. + HeightLocked = 2, } } impl Writeable for KernelFeatures { fn write(&self, writer: &mut W) -> Result<(), ser::Error> { - writer.write_u8(self.bits())?; + writer.write_u8(*self as u8)?; Ok(()) } } +impl Readable for KernelFeatures { + fn read(reader: &mut dyn Reader) -> Result { + let features = + KernelFeatures::from_u8(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?; + Ok(features) + } +} + /// Errors thrown by Transaction validation #[derive(Clone, Eq, Debug, PartialEq)] pub enum Error { @@ -181,10 +192,8 @@ impl Writeable for TxKernel { impl Readable for TxKernel { fn read(reader: &mut dyn Reader) -> Result { - let features = - KernelFeatures::from_bits(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?; Ok(TxKernel { - features, + features: KernelFeatures::read(reader)?, fee: reader.read_u64()?, lock_height: reader.read_u64()?, excess: Commitment::read(reader)?, @@ -205,17 +214,17 @@ impl PMMRable for TxKernel { impl KernelFeatures { /// Is this a coinbase kernel? pub fn is_coinbase(&self) -> bool { - self.contains(KernelFeatures::COINBASE) + *self == KernelFeatures::Coinbase } /// Is this a plain kernel? pub fn is_plain(&self) -> bool { - !self.is_coinbase() && !self.is_height_locked() + *self == KernelFeatures::Plain } /// Is this a height locked kernel? pub fn is_height_locked(&self) -> bool { - self.contains(KernelFeatures::HEIGHT_LOCKED) + *self == KernelFeatures::HeightLocked } } @@ -278,7 +287,7 @@ impl TxKernel { /// Build an empty tx kernel with zero values. pub fn empty() -> TxKernel { TxKernel { - features: KernelFeatures::PLAIN, + features: KernelFeatures::Plain, fee: 0, lock_height: 0, excess: Commitment::from_vec(vec![0; 33]), @@ -1073,7 +1082,7 @@ impl ::std::hash::Hash for Input { /// an Input as binary. impl Writeable for Input { fn write(&self, writer: &mut W) -> Result<(), ser::Error> { - writer.write_u8(self.features.bits())?; + self.features.write(writer)?; self.commit.write(writer)?; Ok(()) } @@ -1083,11 +1092,8 @@ impl Writeable for Input { /// an Input from a binary stream. impl Readable for Input { fn read(reader: &mut dyn Reader) -> Result { - let features = - OutputFeatures::from_bits(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?; - + let features = OutputFeatures::read(reader)?; let commit = Commitment::read(reader)?; - Ok(Input::new(features, commit)) } } @@ -1122,14 +1128,31 @@ impl Input { } } -bitflags! { - /// Options for block validation - #[derive(Serialize, Deserialize)] - pub struct OutputFeatures: u8 { - /// No flags - const PLAIN = 0; - /// Output is a coinbase output, must not be spent until maturity - const COINBASE = 1; +/// Enum of various supported kernel "features". +enum_from_primitive! { + /// Various flavors of tx kernel. + #[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)] + #[repr(u8)] + pub enum OutputFeatures { + /// Plain output (the default for Grin txs). + Plain = 0, + /// A coinbase output. + Coinbase = 1, + } +} + +impl Writeable for OutputFeatures { + fn write(&self, writer: &mut W) -> Result<(), ser::Error> { + writer.write_u8(*self as u8)?; + Ok(()) + } +} + +impl Readable for OutputFeatures { + fn read(reader: &mut dyn Reader) -> Result { + let features = + OutputFeatures::from_u8(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?; + Ok(features) } } @@ -1164,7 +1187,7 @@ impl ::std::hash::Hash for Output { /// an Output as binary. impl Writeable for Output { fn write(&self, writer: &mut W) -> Result<(), ser::Error> { - writer.write_u8(self.features.bits())?; + self.features.write(writer)?; self.commit.write(writer)?; // The hash of an output doesn't include the range proof, which // is committed to separately @@ -1179,11 +1202,8 @@ impl Writeable for Output { /// an Output from a binary stream. impl Readable for Output { fn read(reader: &mut dyn Reader) -> Result { - let features = - OutputFeatures::from_bits(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?; - Ok(Output { - features, + features: OutputFeatures::read(reader)?, commit: Commitment::read(reader)?, proof: RangeProof::read(reader)?, }) @@ -1202,12 +1222,12 @@ impl PMMRable for Output { impl OutputFeatures { /// Is this a coinbase output? pub fn is_coinbase(&self) -> bool { - self.contains(OutputFeatures::COINBASE) + *self == OutputFeatures::Coinbase } /// Is this a plain output? pub fn is_plain(&self) -> bool { - !self.contains(OutputFeatures::COINBASE) + *self == OutputFeatures::Plain } } @@ -1308,7 +1328,7 @@ impl OutputIdentifier { pub fn to_hex(&self) -> String { format!( "{:b}{}", - self.features.bits(), + self.features as u8, util::to_hex(self.commit.0.to_vec()), ) } @@ -1320,7 +1340,7 @@ impl FixedLength for OutputIdentifier { impl Writeable for OutputIdentifier { fn write(&self, writer: &mut W) -> Result<(), ser::Error> { - writer.write_u8(self.features.bits())?; + self.features.write(writer)?; self.commit.write(writer)?; Ok(()) } @@ -1328,10 +1348,8 @@ impl Writeable for OutputIdentifier { impl Readable for OutputIdentifier { fn read(reader: &mut dyn Reader) -> Result { - let features = - OutputFeatures::from_bits(reader.read_u8()?).ok_or(ser::Error::CorruptedData)?; Ok(OutputIdentifier { - features, + features: OutputFeatures::read(reader)?, commit: Commitment::read(reader)?, }) } @@ -1358,18 +1376,17 @@ pub fn kernel_sig_msg( features: KernelFeatures, ) -> Result { let valid_features = match features { - KernelFeatures::COINBASE => fee == 0 && lock_height == 0, - KernelFeatures::PLAIN => lock_height == 0, - KernelFeatures::HEIGHT_LOCKED => true, - _ => false, + KernelFeatures::Coinbase => fee == 0 && lock_height == 0, + KernelFeatures::Plain => lock_height == 0, + KernelFeatures::HeightLocked => true, }; if !valid_features { return Err(Error::InvalidKernelFeatures); } let hash = match features { - KernelFeatures::COINBASE => (features).hash(), - KernelFeatures::PLAIN => (features, fee).hash(), - _ => (features, fee, lock_height).hash(), + KernelFeatures::Coinbase => (features).hash(), + KernelFeatures::Plain => (features, fee).hash(), + KernelFeatures::HeightLocked => (features, fee, lock_height).hash(), }; Ok(secp::Message::from_slice(&hash.as_bytes())?) } @@ -1377,9 +1394,9 @@ pub fn kernel_sig_msg( /// kernel features as determined by lock height pub fn kernel_features(lock_height: u64) -> KernelFeatures { if lock_height > 0 { - KernelFeatures::HEIGHT_LOCKED + KernelFeatures::HeightLocked } else { - KernelFeatures::PLAIN + KernelFeatures::Plain } } @@ -1401,7 +1418,7 @@ mod test { let sig = secp::Signature::from_raw_data(&[0; 64]).unwrap(); let kernel = TxKernel { - features: KernelFeatures::PLAIN, + features: KernelFeatures::Plain, lock_height: 0, excess: commit, excess_sig: sig.clone(), @@ -1411,7 +1428,7 @@ mod test { let mut vec = vec![]; ser::serialize(&mut vec, &kernel).expect("serialized failed"); let kernel2: TxKernel = ser::deserialize(&mut &vec[..]).unwrap(); - assert_eq!(kernel2.features, KernelFeatures::PLAIN); + assert_eq!(kernel2.features, KernelFeatures::Plain); assert_eq!(kernel2.lock_height, 0); assert_eq!(kernel2.excess, commit); assert_eq!(kernel2.excess_sig, sig.clone()); @@ -1419,7 +1436,7 @@ mod test { // now check a kernel with lock_height serialize/deserialize correctly let kernel = TxKernel { - features: KernelFeatures::HEIGHT_LOCKED, + features: KernelFeatures::HeightLocked, lock_height: 100, excess: commit, excess_sig: sig.clone(), @@ -1429,7 +1446,7 @@ mod test { let mut vec = vec![]; ser::serialize(&mut vec, &kernel).expect("serialized failed"); let kernel2: TxKernel = ser::deserialize(&mut &vec[..]).unwrap(); - assert_eq!(kernel2.features, KernelFeatures::HEIGHT_LOCKED); + assert_eq!(kernel2.features, KernelFeatures::HeightLocked); assert_eq!(kernel2.lock_height, 100); assert_eq!(kernel2.excess, commit); assert_eq!(kernel2.excess_sig, sig.clone()); @@ -1456,7 +1473,7 @@ mod test { let commit = keychain.commit(5, &key_id).unwrap(); let input = Input { - features: OutputFeatures::PLAIN, + features: OutputFeatures::Plain, commit: commit, }; @@ -1472,11 +1489,27 @@ mod test { // now generate the short_id for a *very* similar output (single feature flag // different) and check it generates a different short_id let input = Input { - features: OutputFeatures::COINBASE, + features: OutputFeatures::Coinbase, commit: commit, }; let short_id = input.short_id(&block_hash, nonce); assert_eq!(short_id, ShortId::from_hex("3f0377c624e9").unwrap()); } + + #[test] + fn kernel_features_serialization() { + let features = KernelFeatures::from_u8(0).unwrap(); + assert_eq!(features, KernelFeatures::Plain); + + let features = KernelFeatures::from_u8(1).unwrap(); + assert_eq!(features, KernelFeatures::Coinbase); + + let features = KernelFeatures::from_u8(2).unwrap(); + assert_eq!(features, KernelFeatures::HeightLocked); + + // Verify we cannot deserialize an unexpected kernel feature + let features = KernelFeatures::from_u8(3); + assert_eq!(features, None); + } } diff --git a/core/src/genesis.rs b/core/src/genesis.rs index bfbb6541..c8a87b14 100644 --- a/core/src/genesis.rs +++ b/core/src/genesis.rs @@ -93,7 +93,7 @@ pub fn genesis_floo() -> core::Block { ..Default::default() }); let kernel = core::TxKernel { - features: core::KernelFeatures::COINBASE, + features: core::KernelFeatures::Coinbase, fee: 0, lock_height: 0, excess: Commitment::from_vec( @@ -111,7 +111,7 @@ pub fn genesis_floo() -> core::Block { .unwrap(), }; let output = core::Output { - features: core::OutputFeatures::COINBASE, + features: core::OutputFeatures::Coinbase, commit: Commitment::from_vec( util::from_hex( "08c12007af16d1ee55fffe92cef808c77e318dae70c3bc70cb6361f49d517f1b68".to_string(), @@ -190,14 +190,14 @@ pub fn genesis_main() -> core::Block { ..Default::default() }); let kernel = core::TxKernel { - features: core::KernelFeatures::COINBASE, + features: core::KernelFeatures::Coinbase, fee: 0, lock_height: 0, excess: Commitment::from_vec(vec![]), // REPLACE excess_sig: Signature::from_raw_data(&[0; 64]).unwrap(), //REPLACE }; let output = core::Output { - features: core::OutputFeatures::COINBASE, + features: core::OutputFeatures::Coinbase, commit: Commitment::from_vec(vec![]), // REPLACE proof: RangeProof { plen: SINGLE_BULLET_PROOF_SIZE, diff --git a/core/src/lib.rs b/core/src/lib.rs index 77963c8a..d471822b 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -21,9 +21,9 @@ #![deny(unused_mut)] #![warn(missing_docs)] -#[macro_use] -extern crate bitflags; use blake2_rfc as blake2; +#[macro_use] +extern crate enum_primitive; use grin_keychain as keychain; use grin_util as util; #[macro_use] diff --git a/core/src/libtx/aggsig.rs b/core/src/libtx/aggsig.rs index 4dea7f76..f7d8f5cd 100644 --- a/core/src/libtx/aggsig.rs +++ b/core/src/libtx/aggsig.rs @@ -241,14 +241,14 @@ pub fn verify_partial_sig( /// let commit = keychain.commit(value, &key_id).unwrap(); /// let rproof = proof::create(&keychain, value, &key_id, commit, None).unwrap(); /// let output = Output { -/// features: OutputFeatures::COINBASE, +/// features: OutputFeatures::Coinbase, /// commit: commit, /// proof: rproof, /// }; /// let height = 20; /// let over_commit = secp.commit_value(reward(fees)).unwrap(); /// let out_commit = output.commitment(); -/// let msg = kernel_sig_msg(0, height, KernelFeatures::HEIGHT_LOCKED).unwrap(); +/// let msg = kernel_sig_msg(0, height, KernelFeatures::HeightLocked).unwrap(); /// let excess = secp.commit_sum(vec![out_commit], vec![over_commit]).unwrap(); /// let pubkey = excess.to_pubkey(&secp).unwrap(); /// let sig = aggsig::sign_from_key_id(&secp, &keychain, &msg, value, &key_id, Some(&pubkey)).unwrap(); @@ -306,14 +306,14 @@ where /// let commit = keychain.commit(value, &key_id).unwrap(); /// let rproof = proof::create(&keychain, value, &key_id, commit, None).unwrap(); /// let output = Output { -/// features: OutputFeatures::COINBASE, +/// features: OutputFeatures::Coinbase, /// commit: commit, /// proof: rproof, /// }; /// let height = 20; /// let over_commit = secp.commit_value(reward(fees)).unwrap(); /// let out_commit = output.commitment(); -/// let msg = kernel_sig_msg(0, height, KernelFeatures::HEIGHT_LOCKED).unwrap(); +/// let msg = kernel_sig_msg(0, height, KernelFeatures::HeightLocked).unwrap(); /// let excess = secp.commit_sum(vec![out_commit], vec![over_commit]).unwrap(); /// let pubkey = excess.to_pubkey(&secp).unwrap(); /// let sig = aggsig::sign_from_key_id(&secp, &keychain, &msg, value, &key_id, Some(&pubkey)).unwrap(); diff --git a/core/src/libtx/build.rs b/core/src/libtx/build.rs index 6b59be3a..851e7dba 100644 --- a/core/src/libtx/build.rs +++ b/core/src/libtx/build.rs @@ -73,7 +73,7 @@ where "Building input (spending regular output): {}, {}", value, key_id ); - build_input(value, OutputFeatures::PLAIN, key_id) + build_input(value, OutputFeatures::Plain, key_id) } /// Adds a coinbase input spending a coinbase output. @@ -82,7 +82,7 @@ where K: Keychain, { debug!("Building input (spending coinbase): {}, {}", value, key_id); - build_input(value, OutputFeatures::COINBASE, key_id) + build_input(value, OutputFeatures::Coinbase, key_id) } /// Adds an output with the provided value and key identifier from the @@ -101,7 +101,7 @@ where ( tx.with_output(Output { - features: OutputFeatures::PLAIN, + features: OutputFeatures::Plain, commit: commit, proof: rproof, }), diff --git a/core/src/libtx/reward.rs b/core/src/libtx/reward.rs index ab161f95..822d5652 100644 --- a/core/src/libtx/reward.rs +++ b/core/src/libtx/reward.rs @@ -35,7 +35,7 @@ where let rproof = proof::create(keychain, value, key_id, commit, None)?; let output = Output { - features: OutputFeatures::COINBASE, + features: OutputFeatures::Coinbase, commit: commit, proof: rproof, }; @@ -49,11 +49,11 @@ where // NOTE: Remember we sign the fee *and* the lock_height. // For a coinbase output the fee is 0 and the lock_height is 0 - let msg = kernel_sig_msg(0, 0, KernelFeatures::COINBASE)?; + let msg = kernel_sig_msg(0, 0, KernelFeatures::Coinbase)?; let sig = aggsig::sign_from_key_id(&secp, keychain, &msg, value, &key_id, Some(&pubkey))?; let proof = TxKernel { - features: KernelFeatures::COINBASE, + features: KernelFeatures::Coinbase, excess: excess, excess_sig: sig, fee: 0, diff --git a/core/tests/block.rs b/core/tests/block.rs index 8f813b47..e7c11173 100644 --- a/core/tests/block.rs +++ b/core/tests/block.rs @@ -162,7 +162,7 @@ fn remove_coinbase_output_flag() { let mut b = new_block(vec![], &keychain, &prev, &key_id); assert!(b.outputs()[0].is_coinbase()); - b.outputs_mut()[0].features = OutputFeatures::PLAIN; + b.outputs_mut()[0].features = OutputFeatures::Plain; assert_eq!(b.verify_coinbase(), Err(Error::CoinbaseSumMismatch)); assert!(b @@ -184,7 +184,7 @@ fn remove_coinbase_kernel_flag() { let mut b = new_block(vec![], &keychain, &prev, &key_id); assert!(b.kernels()[0].is_coinbase()); - b.kernels_mut()[0].features = KernelFeatures::PLAIN; + b.kernels_mut()[0].features = KernelFeatures::Plain; // Flipping the coinbase flag results in kernels not summing correctly. assert_eq!( diff --git a/core/tests/core.rs b/core/tests/core.rs index 8c6641ad..b1e4942a 100644 --- a/core/tests/core.rs +++ b/core/tests/core.rs @@ -122,7 +122,7 @@ fn build_tx_kernel() { let kern = &tx.kernels()[0]; kern.verify().unwrap(); - assert_eq!(kern.features, KernelFeatures::PLAIN); + assert_eq!(kern.features, KernelFeatures::Plain); assert_eq!(kern.fee, tx.fee()); } diff --git a/core/tests/transaction.rs b/core/tests/transaction.rs index 285913dd..d215507c 100644 --- a/core/tests/transaction.rs +++ b/core/tests/transaction.rs @@ -31,7 +31,7 @@ fn test_output_ser_deser() { let proof = proof::create(&keychain, 5, &key_id, commit, None).unwrap(); let out = Output { - features: OutputFeatures::PLAIN, + features: OutputFeatures::Plain, commit: commit, proof: proof, }; @@ -40,7 +40,7 @@ fn test_output_ser_deser() { ser::serialize(&mut vec, &out).expect("serialized failed"); let dout: Output = ser::deserialize(&mut &vec[..]).unwrap(); - assert_eq!(dout.features, OutputFeatures::PLAIN); + assert_eq!(dout.features, OutputFeatures::Plain); assert_eq!(dout.commit, out.commit); assert_eq!(dout.proof, out.proof); } diff --git a/core/tests/verifier_cache.rs b/core/tests/verifier_cache.rs index de59b6aa..81905767 100644 --- a/core/tests/verifier_cache.rs +++ b/core/tests/verifier_cache.rs @@ -38,7 +38,7 @@ fn test_verifier_cache_rangeproofs() { let proof = proof::create(&keychain, 5, &key_id, commit, None).unwrap(); let out = Output { - features: OutputFeatures::PLAIN, + features: OutputFeatures::Plain, commit: commit, proof: proof, }; diff --git a/wallet/src/test_framework/mod.rs b/wallet/src/test_framework/mod.rs index 69f62772..98f2b4a0 100644 --- a/wallet/src/test_framework/mod.rs +++ b/wallet/src/test_framework/mod.rs @@ -45,8 +45,8 @@ pub use self::{testclient::LocalWalletClient, testclient::WalletProxy}; /// Get an output from the chain locally and present it back as an API output fn get_output_local(chain: &chain::Chain, commit: &pedersen::Commitment) -> Option { let outputs = [ - OutputIdentifier::new(OutputFeatures::PLAIN, commit), - OutputIdentifier::new(OutputFeatures::COINBASE, commit), + OutputIdentifier::new(OutputFeatures::Plain, commit), + OutputIdentifier::new(OutputFeatures::Coinbase, commit), ]; for x in outputs.iter() { diff --git a/wallet/tests/libwallet.rs b/wallet/tests/libwallet.rs index 0d72d44c..b5595f3f 100644 --- a/wallet/tests/libwallet.rs +++ b/wallet/tests/libwallet.rs @@ -26,7 +26,7 @@ use grin_wallet as wallet; use rand::thread_rng; fn kernel_sig_msg() -> secp::Message { - transaction::kernel_sig_msg(0, 0, transaction::KernelFeatures::PLAIN).unwrap() + transaction::kernel_sig_msg(0, 0, transaction::KernelFeatures::Plain).unwrap() } #[test]