1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
use xdr_codec::{Pack, Write, Result, pack_flex}; use ::xdr::ToXdr; use ::transaction::{Transaction, TransactionEnvelope, TaggedTransactionBuffer}; impl<W: Write> Pack<W> for Transaction { fn pack(&self, out: &mut W) -> Result<usize> { let seqnum = self.seqnum(); let op = self.operations(); Ok(self.source().pack(out)? + self.fee().pack(out)? + seqnum.pack(out)? + self.time_bounds().pack(out)? + self.memo().pack(out)? + pack_flex(&op, Some(100), out)? + (0 as i32).pack(out)?) } } impl ToXdr for Transaction { fn to_writer<W: Write>(&self, mut buf: W) -> ::error::Result<usize> { let r = self.pack(&mut buf)?; Ok(r) } } impl<W: Write> Pack<W> for TransactionEnvelope { fn pack(&self, out: &mut W) -> Result<usize> { let signatures = self.signatures(); Ok(self.transaction().pack(out)? + pack_flex(&signatures, Some(20), out)?) } } impl ToXdr for TransactionEnvelope { fn to_writer<W: Write>(&self, mut buf: W) -> ::error::Result<usize> { let r = self.pack(&mut buf)?; Ok(r) } } impl<W: Write> Pack<W> for TaggedTransactionBuffer { fn pack(&self, out: &mut W) -> Result<usize> { let tag = self.tag().clone() as i32; let size = tag.pack(out)?; let total = size + self.transaction_buffer().len(); out.write_all(&self.transaction_buffer())?; Ok(total) } } impl ToXdr for TaggedTransactionBuffer { fn to_writer<W: Write>(&self, mut buf: W) -> ::error::Result<usize> { let r = self.pack(&mut buf)?; Ok(r) } } #[cfg(test)] mod tests { use ::xdr::ToXdr; use KeyPair; use Account; use Memo; use Network; use TimeBounds; use TransactionBuilder; #[test] fn test_time_bounds() { let tb1 = TimeBounds::new(None, None); let s1 = tb1.to_base64().unwrap(); assert_eq!(s1, "AAAAAAAAAAAAAAAAAAAAAA=="); let tb2 = TimeBounds::new(Some(1515283530), None); let s2 = tb2.to_base64().unwrap(); assert_eq!(s2, "AAAAAFpRZEoAAAAAAAAAAA=="); let tb3 = TimeBounds::new(None, Some(1515283530)); let s3 = tb3.to_base64().unwrap(); assert_eq!(s3, "AAAAAAAAAAAAAAAAWlFkSg=="); let tb4 = TimeBounds::new(Some(1515283530), Some(1515283530)); let s4 = tb4.to_base64().unwrap(); assert_eq!(s4, "AAAAAFpRZEoAAAAAWlFkSg=="); } #[test] fn test_transaction_no_time_bounds() { let mut account = Account::from_account_id("GCLDNMHZTEY6PUYQBYOVERBBZ2W3RLMYOSZWHAMY5R4YW2N6MM4LFA72", 999) .unwrap(); let memo = Memo::Text("test post please ignore".to_string()); let tx = TransactionBuilder::new(&mut account) .with_memo(memo) .with_fee(200) .build() .unwrap(); let s = tx.to_base64().unwrap(); assert_eq!(s, "AAAAAJY2sPmZMefTEA4dUkQhzq24rZh0s2OBmOx5i2m+YziyAAAAAAAAAAAAAAPoAAAAAAAAAAEAAAAXdGVzdCBwb3N0IHBsZWFzZSBpZ25vcmUAAAAAAAAAAAA="); } #[test] fn test_transaction() { let mut account = Account::from_account_id("GCLDNMHZTEY6PUYQBYOVERBBZ2W3RLMYOSZWHAMY5R4YW2N6MM4LFA72", 999) .unwrap(); let memo = Memo::Text("test post please ignore".to_string()); let tx = TransactionBuilder::new(&mut account) .with_memo(memo) .with_fee(200) .with_lower_time_bound(0) .with_upper_time_bound(12345678) .build() .unwrap(); let s = tx.to_base64().unwrap(); assert_eq!(s, "AAAAAJY2sPmZMefTEA4dUkQhzq24rZh0s2OBmOx5i2m+YziyAAAAAAAAAAAAAAPoAAAAAQAAAAAAAAAAAAAAAAC8YU4AAAABAAAAF3Rlc3QgcG9zdCBwbGVhc2UgaWdub3JlAAAAAAAAAAAA"); } #[test] fn test_transaction_signatures() { let kp1 = KeyPair::from_secret("SASMDWFIDNQ23SWYZC5CLAIULQB65XK37XUX5SCAVJ3UTLCSLMCLSXNA") .unwrap(); let kp2 = KeyPair::from_secret("SAB4OGFUWU5IDNACQ7MIAELTZENUVKMIBMZ2D5QKI6N4EOBHAHWCZWJ6") .unwrap(); let pk = kp1.public_key(); let mut account = Account::new(&pk, 0).unwrap(); let memo = Memo::Text("test post please ignore".to_string()); let tx = TransactionBuilder::new(&mut account) .with_memo(memo) .build() .unwrap(); let mut sig_tx = tx.sign_with_network(&kp1, Network::test_network()).unwrap(); sig_tx.sign(&kp2).unwrap(); assert_eq!(sig_tx.to_base64().unwrap(), "AAAAAO7K8WLSyKYleTjmxO/WUGH4s53oedi6EOO2xeL1MmwbAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAXdGVzdCBwb3N0IHBsZWFzZSBpZ25vcmUAAAAAAAAAAAAAAAAC9TJsGwAAAEDAHLteLpJqU4T/zFp6dR+waNza2aZeNJ8e4Q9387vUf1IDZ2YBqXPZvuaSF8TQpKLpfoB83Akq8FSjDuGr3H0Fl7gdXQAAAEBDeS+OY7ezW06xToI0hSGJAqDc6Vfzg4PftYB54Gx7IMUgTwAioS7JamR87O0nZrX+EoGZEEHJ6ZoDBvdlmWwO"); } }