From 83ae5bcee289a8001b2dbfb2f9a9e48e42b55a12 Mon Sep 17 00:00:00 2001 From: Michael Vines Date: Mon, 17 Sep 2018 21:09:11 -0700 Subject: [PATCH] Detect binary changes in serialized contract userdata --- src/budget_contract.rs | 89 +++++++++++++++++++++++++++++++++++++++++- src/system_contract.rs | 64 +++++++++++++++++++++++++++++- src/transaction.rs | 43 ++++++++++++++++++++ 3 files changed, 193 insertions(+), 3 deletions(-) diff --git a/src/budget_contract.rs b/src/budget_contract.rs index b62cc0351..a7c9a90f3 100644 --- a/src/budget_contract.rs +++ b/src/budget_contract.rs @@ -273,9 +273,9 @@ mod test { use bank::Account; use bincode::serialize; use budget_contract::{BudgetContract, BudgetError}; - use chrono::prelude::Utc; + use chrono::prelude::{DateTime, NaiveDate, Utc}; use hash::Hash; - use signature::{Keypair, KeypairUtil}; + use signature::{GenKeys, Keypair, KeypairUtil, Pubkey, Signature}; use transaction::Transaction; #[test] fn test_serializer() { @@ -466,4 +466,89 @@ mod test { Some(BudgetError::ContractNotPending(contract.pubkey())) ); } + + /// Detect binary changes in the serialized contract userdata, which could have a downstream + /// affect on SDKs and DApps + #[test] + fn test_sdk_serialize() { + let keypair = &GenKeys::new([0u8; 32]).gen_n_keypairs(1)[0]; + let to = Pubkey::new(&[ + 1, 1, 1, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, 6, 5, 4, + 1, 1, 1, + ]); + let contract = Pubkey::new(&[ + 2, 2, 2, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, + 2, 2, 2, + ]); + let signature = Signature::new(&[ + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, + 6, 5, 4, 3, 2, 1, + ]); + let date = + DateTime::::from_utc(NaiveDate::from_ymd(2016, 7, 8).and_hms(9, 10, 11), Utc); + + // NewContract(Contract) + let tx = Transaction::budget_new(&keypair, to, 192, Hash::default()); + assert_eq!( + tx.userdata, + vec![ + 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 1, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 8, 7, + 6, 5, 4, 1, 1, 1 + ] + ); + + // NewContract(Contract) + let tx = + Transaction::budget_new_on_date(&keypair, to, contract, date, 192, Hash::default()); + assert_eq!( + tx.userdata, + vec![ + 0, 0, 0, 0, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, + 0, 0, 0, 0, 0, 50, 48, 49, 54, 45, 48, 55, 45, 48, 56, 84, 48, 57, 58, 49, 48, 58, + 49, 49, 90, 32, 253, 186, 201, 177, 11, 117, 135, 187, 167, 181, 188, 22, 59, 206, + 105, 231, 150, 215, 30, 78, 212, 76, 16, 252, 180, 72, 134, 137, 247, 161, 68, 192, + 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 8, 7, 6, 5, 4, 1, 1, 1, 1, 0, 0, 0, 32, 253, 186, 201, 177, 11, 117, 135, + 187, 167, 181, 188, 22, 59, 206, 105, 231, 150, 215, 30, 78, 212, 76, 16, 252, 180, + 72, 134, 137, 247, 161, 68, 192, 0, 0, 0, 0, 0, 0, 0, 32, 253, 186, 201, 177, 11, + 117, 135, 187, 167, 181, 188, 22, 59, 206, 105, 231, 150, 215, 30, 78, 212, 76, 16, + 252, 180, 72, 134, 137, 247, 161, 68 + ] + ); + + // ApplyTimestamp + let tx = Transaction::budget_new_timestamp( + &keypair, + keypair.pubkey(), + to, + date, + Hash::default(), + ); + assert_eq!( + tx.userdata, + vec![ + 1, 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, 0, 50, 48, 49, 54, 45, 48, 55, 45, 48, 56, 84, + 48, 57, 58, 49, 48, 58, 49, 49, 90 + ] + ); + + // ApplySignature + let tx = Transaction::budget_new_signature( + &keypair, + keypair.pubkey(), + to, + signature, + Hash::default(), + ); + assert_eq!( + tx.userdata, + vec![ + 2, 0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 + ] + ); + } } diff --git a/src/system_contract.rs b/src/system_contract.rs index 72faf8bc8..d821863c7 100644 --- a/src/system_contract.rs +++ b/src/system_contract.rs @@ -82,7 +82,7 @@ impl SystemContract { mod test { use bank::Account; use hash::Hash; - use signature::{Keypair, KeypairUtil}; + use signature::{Keypair, KeypairUtil, Pubkey}; use system_contract::SystemContract; use transaction::Transaction; #[test] @@ -187,4 +187,66 @@ mod test { assert_eq!(accounts[0].tokens, 0); assert_eq!(accounts[1].tokens, 1); } + + /// Detect binary changes in the serialized contract userdata, which could have a downstream + /// affect on SDKs and DApps + #[test] + fn test_sdk_serialize() { + let keypair = Keypair::new(); + use budget_contract::BUDGET_CONTRACT_ID; + + // CreateAccount + let tx = Transaction::system_create( + &keypair, + keypair.pubkey(), + Hash::default(), + 111, + 222, + Some(Pubkey::new(&BUDGET_CONTRACT_ID)), + 0, + ); + + assert_eq!( + tx.userdata, + vec![ + 0, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ] + ); + + // CreateAccount + let tx = Transaction::system_create( + &keypair, + keypair.pubkey(), + Hash::default(), + 111, + 222, + None, + 0, + ); + + assert_eq!( + tx.userdata, + vec![0, 0, 0, 0, 111, 0, 0, 0, 0, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 0] + ); + + // Assign + let tx = Transaction::system_assign( + &keypair, + Hash::default(), + Pubkey::new(&BUDGET_CONTRACT_ID), + 0, + ); + assert_eq!( + tx.userdata, + vec![ + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0 + ] + ); + + // Move + let tx = Transaction::system_move(&keypair, keypair.pubkey(), 123, Hash::default(), 0); + assert_eq!(tx.userdata, vec![2, 0, 0, 0, 123, 0, 0, 0, 0, 0, 0, 0]); + } } diff --git a/src/transaction.rs b/src/transaction.rs index 5fe1ae814..c9bce3945 100644 --- a/src/transaction.rs +++ b/src/transaction.rs @@ -328,6 +328,7 @@ mod tests { use super::*; use bincode::{deserialize, serialize}; use packet::PACKET_DATA_SIZE; + use signature::GenKeys; #[test] fn test_claim() { @@ -478,4 +479,46 @@ mod tests { tx.userdata = serialize(&instruction).unwrap(); assert!(!tx.verify_plan()); } + + /// Detect binary changes in the serialized contract userdata, which could have a downstream + /// affect on SDKs and DApps + #[test] + fn test_sdk_serialize() { + let keypair = &GenKeys::new([0u8; 32]).gen_n_keypairs(1)[0]; + let to = Pubkey::new(&[ + 1, 1, 1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, + 1, 1, 1, + ]); + + let contract = Pubkey::new(&[ + 2, 2, 2, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, + 2, 2, 2, + ]); + + let tx = Transaction::new_with_userdata( + keypair, + &[keypair.pubkey(), to], + contract, + vec![1, 2, 3], + Hash::default(), + 99, + ); + assert_eq!( + serialize(&tx).unwrap(), + vec![ + 88, 1, 212, 176, 31, 197, 35, 156, 135, 24, 30, 57, 204, 253, 224, 28, 89, 189, 53, + 64, 27, 148, 42, 199, 43, 236, 85, 182, 150, 64, 96, 53, 255, 235, 90, 197, 228, 6, + 105, 22, 140, 209, 206, 221, 85, 117, 125, 126, 11, 1, 176, 130, 57, 236, 7, 155, + 127, 58, 130, 92, 230, 219, 254, 0, 3, 0, 0, 0, 0, 0, 0, 0, 32, 253, 186, 201, 177, + 11, 117, 135, 187, 167, 181, 188, 22, 59, 206, 105, 231, 150, 215, 30, 78, 212, 76, + 16, 252, 180, 72, 134, 137, 247, 161, 68, 32, 253, 186, 201, 177, 11, 117, 135, + 187, 167, 181, 188, 22, 59, 206, 105, 231, 150, 215, 30, 78, 212, 76, 16, 252, 180, + 72, 134, 137, 247, 161, 68, 1, 1, 1, 4, 5, 6, 7, 8, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 8, 7, 6, 5, 4, 1, 1, 1, 2, 2, 2, 4, 5, 6, 7, 8, 9, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 8, 7, 6, 5, 4, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, + 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3 + ], + ); + } }