@@ -13,7 +13,7 @@ pub const PUB_KEY_OFFSET: usize = 80;
1313pub const MAX_ALLOWED_INSTRUCTIONS : usize = 20 ;
1414// The biggest current instruction is a Budget with a payment plan of 'Or' with two
1515// datetime 'Condition' branches. This is the serialized size of that instruction
16- pub const MAX_INSTRUCTION_SIZE : usize = 314 ;
16+ pub const MAX_INSTRUCTION_SIZE : usize = 352 ;
1717// Serialized size of everything in the transaction excluding the instructions
1818pub const BASE_TRANSACTION_SIZE : usize = 168 ;
1919pub const FEE_PER_INSTRUCTION : usize = 0 ;
@@ -86,7 +86,7 @@ pub struct Vote {
8686#[ derive( Serialize , Deserialize , Debug , PartialEq , Eq , Clone ) ]
8787pub enum Instruction {
8888 /// Declare and instanstansiate `Contract`.
89- NewContract ( Contract ) ,
89+ NewContract ( Box < Contract > ) ,
9090
9191 /// Tell a payment plan acknowledge the given `DateTime` has past.
9292 ApplyTimestamp ( DateTime < Utc > ) ,
@@ -150,7 +150,7 @@ impl Transaction {
150150 let budget = Budget :: Pay ( payment) ;
151151 let plan = Plan :: Budget ( budget) ;
152152 let contract = Contract :: new ( tokens, plan) ;
153- let instruction = Instruction :: NewContract ( contract) ;
153+ let instruction = Instruction :: NewContract ( Box :: new ( contract) ) ;
154154 Self :: new_from_instructions ( from_keypair, vec ! [ instruction] , last_id, fee)
155155 }
156156
@@ -195,7 +195,7 @@ impl Transaction {
195195 ) ;
196196 let plan = Plan :: Budget ( budget) ;
197197 let contract = Contract :: new ( tokens, plan) ;
198- let instructions = vec ! [ Instruction :: NewContract ( contract) ] ;
198+ let instructions = vec ! [ Instruction :: NewContract ( Box :: new ( contract) ) ] ;
199199 Self :: new_from_instructions ( from_keypair, instructions, last_id, 0 )
200200 }
201201
@@ -230,8 +230,8 @@ impl Transaction {
230230 }
231231
232232 for i in & self . instructions {
233- if let Instruction :: NewContract ( contract ) = i {
234- if !contract . plan . verify ( contract . tokens ) {
233+ if let Instruction :: NewContract ( contract_box ) = i {
234+ if !contract_box . plan . verify ( contract_box . tokens ) {
235235 return false ;
236236 }
237237 }
@@ -310,7 +310,7 @@ mod tests {
310310 } ) ;
311311 let plan = Plan :: Budget ( budget) ;
312312 let contract = Contract :: new ( 0 , plan) ;
313- let instruction = Instruction :: NewContract ( contract) ;
313+ let instruction = Instruction :: NewContract ( Box :: new ( contract) ) ;
314314 let claim0 = Transaction {
315315 instructions : vec ! [ instruction] ,
316316 from : Default :: default ( ) ,
@@ -329,10 +329,11 @@ mod tests {
329329 let keypair = KeyPair :: new ( ) ;
330330 let pubkey = keypair. pubkey ( ) ;
331331 let mut tx = Transaction :: new ( & keypair, pubkey, 42 , zero) ;
332- if let Instruction :: NewContract ( contract) = & mut tx. instructions [ 0 ] {
333- contract. tokens = 1_000_000 ; // <-- attack, part 1!
334- if let Plan :: Budget ( Budget :: Pay ( ref mut payment) ) = contract. plan {
335- payment. tokens = contract. tokens ; // <-- attack, part 2!
332+ if let Instruction :: NewContract ( contract_box) = & mut tx. instructions [ 0 ] {
333+ let tokens = 1_000_000 ; // <-- attack, part 1!
334+ contract_box. tokens = tokens;
335+ if let Plan :: Budget ( Budget :: Pay ( ref mut payment) ) = contract_box. plan {
336+ payment. tokens = tokens; // <-- attack, part 2!
336337 }
337338 }
338339 assert ! ( tx. verify_plan( ) ) ;
@@ -347,8 +348,8 @@ mod tests {
347348 let pubkey1 = keypair1. pubkey ( ) ;
348349 let zero = Hash :: default ( ) ;
349350 let mut tx = Transaction :: new ( & keypair0, pubkey1, 42 , zero) ;
350- if let Instruction :: NewContract ( contract ) = & mut tx. instructions [ 0 ] {
351- if let Plan :: Budget ( Budget :: Pay ( ref mut payment) ) = contract . plan {
351+ if let Instruction :: NewContract ( contract_box ) = & mut tx. instructions [ 0 ] {
352+ if let Plan :: Budget ( Budget :: Pay ( ref mut payment) ) = contract_box . plan {
352353 payment. to = thief_keypair. pubkey ( ) ; // <-- attack!
353354 }
354355 }
@@ -371,16 +372,16 @@ mod tests {
371372 let keypair1 = KeyPair :: new ( ) ;
372373 let zero = Hash :: default ( ) ;
373374 let mut tx = Transaction :: new ( & keypair0, keypair1. pubkey ( ) , 1 , zero) ;
374- if let Instruction :: NewContract ( contract ) = & mut tx. instructions [ 0 ] {
375- if let Plan :: Budget ( Budget :: Pay ( ref mut payment) ) = contract . plan {
375+ if let Instruction :: NewContract ( contract_box ) = & mut tx. instructions [ 0 ] {
376+ if let Plan :: Budget ( Budget :: Pay ( ref mut payment) ) = contract_box . plan {
376377 payment. tokens = 2 ; // <-- attack!
377378 }
378379 }
379380 assert ! ( !tx. verify_plan( ) ) ;
380381
381382 // Also, ensure all branchs of the plan spend all tokens
382- if let Instruction :: NewContract ( contract ) = & mut tx. instructions [ 0 ] {
383- if let Plan :: Budget ( Budget :: Pay ( ref mut payment) ) = contract . plan {
383+ if let Instruction :: NewContract ( contract_box ) = & mut tx. instructions [ 0 ] {
384+ if let Plan :: Budget ( Budget :: Pay ( ref mut payment) ) = contract_box . plan {
384385 payment. tokens = 0 ; // <-- whoops!
385386 }
386387 }
0 commit comments