@@ -4,16 +4,17 @@ use crate::{
44 log:: extract_events,
55 xdr:: {
66 Error as XdrError , ExtensionPoint , LedgerEntry , LedgerEntryChange , LedgerEntryData ,
7- LedgerFootprint , Limits , Memo , Operation , OperationBody , OperationMeta , Preconditions ,
8- RestoreFootprintOp , SequenceNumber , SorobanResources , SorobanTransactionData ,
9- SorobanTransactionDataExt , Transaction , TransactionExt , TransactionMeta , TransactionMetaV3 ,
7+ LedgerFootprint , Limits , Memo , Operation , OperationBody , Preconditions , RestoreFootprintOp ,
8+ SequenceNumber , SorobanResources , SorobanTransactionData , SorobanTransactionDataExt ,
9+ Transaction , TransactionExt , TransactionMeta , TransactionMetaV3 , TransactionMetaV4 ,
1010 TtlEntry , WriteXdr ,
1111 } ,
1212} ;
1313use clap:: { command, Parser } ;
1414use stellar_strkey:: DecodeError ;
1515
1616use crate :: {
17+ assembled:: simulate_and_assemble_transaction,
1718 commands:: {
1819 contract:: extend,
1920 global,
@@ -164,7 +165,7 @@ impl NetworkRunnable for Cmd {
164165 resources : SorobanResources {
165166 footprint : LedgerFootprint {
166167 read_only : vec ! [ ] . try_into ( ) ?,
167- read_write : entry_keys. try_into ( ) ?,
168+ read_write : entry_keys. clone ( ) . try_into ( ) ?,
168169 } ,
169170 instructions : self . fee . instructions . unwrap_or_default ( ) ,
170171 disk_read_bytes : 0 ,
@@ -176,8 +177,12 @@ impl NetworkRunnable for Cmd {
176177 if self . fee . build_only {
177178 return Ok ( TxnResult :: Txn ( tx) ) ;
178179 }
180+ let tx = simulate_and_assemble_transaction ( & client, & tx)
181+ . await ?
182+ . transaction ( )
183+ . clone ( ) ;
179184 let res = client
180- . send_transaction_polling ( & config. sign ( * tx) . await ?)
185+ . send_transaction_polling ( & config. sign ( tx) . await ?)
181186 . await ?;
182187 if args. is_none_or ( |a| !a. no_cache ) {
183188 data:: write ( res. clone ( ) . try_into ( ) ?, & network. rpc_uri ( ) ?) ?;
@@ -196,33 +201,57 @@ impl NetworkRunnable for Cmd {
196201
197202 // The transaction from core will succeed regardless of whether it actually found &
198203 // restored the entry, so we have to inspect the result meta to tell if it worked or not.
199- let TransactionMeta :: V3 ( TransactionMetaV3 { operations, .. } ) = meta else {
200- return Err ( Error :: LedgerEntryNotFound ) ;
204+ let changes = match meta {
205+ TransactionMeta :: V4 ( TransactionMetaV4 { operations, .. } ) => {
206+ // Simply check if there is exactly one entry here. We only support restoring a single
207+ // entry via this command (which we should fix separately, but).
208+ if operations. is_empty ( ) {
209+ return Err ( Error :: LedgerEntryNotFound ) ;
210+ }
211+
212+ operations[ 0 ] . changes . clone ( )
213+ }
214+ TransactionMeta :: V3 ( TransactionMetaV3 { operations, .. } ) => {
215+ // Simply check if there is exactly one entry here. We only support restoring a single
216+ // entry via this command (which we should fix separately, but).
217+ if operations. is_empty ( ) {
218+ return Err ( Error :: LedgerEntryNotFound ) ;
219+ }
220+
221+ operations[ 0 ] . changes . clone ( )
222+ }
223+ _ => return Err ( Error :: LedgerEntryNotFound ) ,
201224 } ;
202- tracing:: debug!( "Operations :\n len:{}\n {operations :#?}" , operations . len( ) ) ;
225+ tracing:: debug!( "Changes :\n len:{}\n {changes :#?}" , changes . len( ) ) ;
203226
204- // Simply check if there is exactly one entry here. We only support extending a single
205- // entry via this command (which we should fix separately, but).
206- if operations. is_empty ( ) {
207- return Err ( Error :: LedgerEntryNotFound ) ;
208- }
227+ if changes. is_empty ( ) {
228+ let entry = client. get_full_ledger_entries ( & entry_keys) . await ?;
229+ let extension = entry. entries [ 0 ] . live_until_ledger_seq ;
209230
210- if operations. len ( ) != 1 {
211- tracing:: warn!(
212- "Unexpected number of operations: {}. Currently only handle one." ,
213- operations[ 0 ] . changes. len( )
214- ) ;
231+ if entry. latest_ledger < i64:: from ( extension) {
232+ return Ok ( TxnResult :: Res ( extension) ) ;
233+ }
215234 }
235+
216236 Ok ( TxnResult :: Res (
217- parse_operations ( & operations . to_vec ( ) ) . ok_or ( Error :: MissingOperationResult ) ?,
237+ parse_changes ( & changes . to_vec ( ) ) . ok_or ( Error :: LedgerEntryNotFound ) ?,
218238 ) )
219239 }
220240}
221241
222- fn parse_operations ( ops : & [ OperationMeta ] ) -> Option < u32 > {
223- ops. first ( ) . and_then ( |op| {
224- op. changes . iter ( ) . find_map ( |entry| match entry {
225- LedgerEntryChange :: Updated ( LedgerEntry {
242+ fn parse_changes ( changes : & [ LedgerEntryChange ] ) -> Option < u32 > {
243+ match ( & changes[ 0 ] , & changes[ 1 ] ) {
244+ (
245+ LedgerEntryChange :: State ( _) ,
246+ LedgerEntryChange :: Restored ( LedgerEntry {
247+ data :
248+ LedgerEntryData :: Ttl ( TtlEntry {
249+ live_until_ledger_seq,
250+ ..
251+ } ) ,
252+ ..
253+ } )
254+ | LedgerEntryChange :: Updated ( LedgerEntry {
226255 data :
227256 LedgerEntryData :: Ttl ( TtlEntry {
228257 live_until_ledger_seq,
@@ -237,8 +266,8 @@ fn parse_operations(ops: &[OperationMeta]) -> Option<u32> {
237266 ..
238267 } ) ,
239268 ..
240- } ) => Some ( * live_until_ledger_seq ) ,
241- _ => None ,
242- } )
243- } )
269+ } ) ,
270+ ) => Some ( * live_until_ledger_seq ) ,
271+ _ => None ,
272+ }
244273}
0 commit comments