diff --git a/.github/workflows/soroban-rpc.yml b/.github/workflows/soroban-rpc.yml index 4ce3313fa..d4f6040e0 100644 --- a/.github/workflows/soroban-rpc.yml +++ b/.github/workflows/soroban-rpc.yml @@ -110,7 +110,7 @@ jobs: env: SOROBAN_RPC_INTEGRATION_TESTS_ENABLED: true SOROBAN_RPC_INTEGRATION_TESTS_CAPTIVE_CORE_BIN: /usr/bin/stellar-core - PROTOCOL_20_CORE_DEBIAN_PKG_VERSION: 19.12.1-1419.0ad2053d5.focal~soroban + PROTOCOL_20_CORE_DEBIAN_PKG_VERSION: 19.12.1-1425.df613c240.focal~soroban runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 diff --git a/Cargo.lock b/Cargo.lock index 84912b376..d4941a302 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2492,7 +2492,7 @@ dependencies = [ [[package]] name = "soroban-env-common" version = "0.0.17" -source = "git+https://github.com/stellar/rs-soroban-env?rev=63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c#63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c" +source = "git+https://github.com/stellar/rs-soroban-env?rev=c5607a2e9e296b2636b46dc910387aa3446b3e29#c5607a2e9e296b2636b46dc910387aa3446b3e29" dependencies = [ "arbitrary", "crate-git-revision 0.0.6", @@ -2510,7 +2510,7 @@ dependencies = [ [[package]] name = "soroban-env-guest" version = "0.0.17" -source = "git+https://github.com/stellar/rs-soroban-env?rev=63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c#63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c" +source = "git+https://github.com/stellar/rs-soroban-env?rev=c5607a2e9e296b2636b46dc910387aa3446b3e29#c5607a2e9e296b2636b46dc910387aa3446b3e29" dependencies = [ "soroban-env-common", "static_assertions", @@ -2519,7 +2519,7 @@ dependencies = [ [[package]] name = "soroban-env-host" version = "0.0.17" -source = "git+https://github.com/stellar/rs-soroban-env?rev=63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c#63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c" +source = "git+https://github.com/stellar/rs-soroban-env?rev=c5607a2e9e296b2636b46dc910387aa3446b3e29#c5607a2e9e296b2636b46dc910387aa3446b3e29" dependencies = [ "backtrace", "curve25519-dalek", @@ -2545,7 +2545,7 @@ dependencies = [ [[package]] name = "soroban-env-macros" version = "0.0.17" -source = "git+https://github.com/stellar/rs-soroban-env?rev=63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c#63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c" +source = "git+https://github.com/stellar/rs-soroban-env?rev=c5607a2e9e296b2636b46dc910387aa3446b3e29#c5607a2e9e296b2636b46dc910387aa3446b3e29" dependencies = [ "itertools", "proc-macro2", @@ -2564,7 +2564,7 @@ version = "0.9.4" [[package]] name = "soroban-ledger-snapshot" version = "0.9.2" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=b1cec10b79cee3c1ecf63079b1088ce97b32c68a#b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=5943aa66baf85ebb70d946c37e297abc80d13a78#5943aa66baf85ebb70d946c37e297abc80d13a78" dependencies = [ "serde", "serde_json", @@ -2576,7 +2576,7 @@ dependencies = [ [[package]] name = "soroban-native-sdk-macros" version = "0.0.17" -source = "git+https://github.com/stellar/rs-soroban-env?rev=63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c#63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c" +source = "git+https://github.com/stellar/rs-soroban-env?rev=c5607a2e9e296b2636b46dc910387aa3446b3e29#c5607a2e9e296b2636b46dc910387aa3446b3e29" dependencies = [ "itertools", "proc-macro2", @@ -2587,7 +2587,7 @@ dependencies = [ [[package]] name = "soroban-sdk" version = "0.9.2" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=b1cec10b79cee3c1ecf63079b1088ce97b32c68a#b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=5943aa66baf85ebb70d946c37e297abc80d13a78#5943aa66baf85ebb70d946c37e297abc80d13a78" dependencies = [ "arbitrary", "bytes-lit", @@ -2604,7 +2604,7 @@ dependencies = [ [[package]] name = "soroban-sdk-macros" version = "0.9.2" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=b1cec10b79cee3c1ecf63079b1088ce97b32c68a#b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=5943aa66baf85ebb70d946c37e297abc80d13a78#5943aa66baf85ebb70d946c37e297abc80d13a78" dependencies = [ "crate-git-revision 0.0.6", "darling", @@ -2623,7 +2623,7 @@ dependencies = [ [[package]] name = "soroban-spec" version = "0.9.2" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=b1cec10b79cee3c1ecf63079b1088ce97b32c68a#b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=5943aa66baf85ebb70d946c37e297abc80d13a78#5943aa66baf85ebb70d946c37e297abc80d13a78" dependencies = [ "base64 0.13.1", "stellar-xdr", @@ -2648,7 +2648,7 @@ dependencies = [ [[package]] name = "soroban-spec-rust" version = "0.9.2" -source = "git+https://github.com/stellar/rs-soroban-sdk?rev=b1cec10b79cee3c1ecf63079b1088ce97b32c68a#b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +source = "git+https://github.com/stellar/rs-soroban-sdk?rev=5943aa66baf85ebb70d946c37e297abc80d13a78#5943aa66baf85ebb70d946c37e297abc80d13a78" dependencies = [ "prettyplease", "proc-macro2", @@ -2784,7 +2784,7 @@ dependencies = [ [[package]] name = "stellar-xdr" version = "0.0.17" -source = "git+https://github.com/stellar/rs-stellar-xdr?rev=4eaf2388c1de6fc295ed5f7df8174c199923df5b#4eaf2388c1de6fc295ed5f7df8174c199923df5b" +source = "git+https://github.com/stellar/rs-stellar-xdr?rev=d6e02584ac9f4046bf38eaf445ced0d4f33631fd#d6e02584ac9f4046bf38eaf445ced0d4f33631fd" dependencies = [ "arbitrary", "base64 0.13.1", diff --git a/Cargo.toml b/Cargo.toml index ca0b2d4ad..2a60ea106 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,18 +16,18 @@ version = "0.9.4" [workspace.dependencies.soroban-env-host] version = "0.0.17" git = "https://github.com/stellar/rs-soroban-env" -rev = "63cf7fe3d5ffc60db57fba97e9fc9c5778cd559c" +rev = "c5607a2e9e296b2636b46dc910387aa3446b3e29" [workspace.dependencies.soroban-spec] version = "0.9.1" git = "https://github.com/stellar/rs-soroban-sdk" -rev = "b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +rev = "5943aa66baf85ebb70d946c37e297abc80d13a78" # path = "../rs-soroban-sdk/soroban-spec" [workspace.dependencies.soroban-spec-rust] version = "0.9.1" git = "https://github.com/stellar/rs-soroban-sdk" -rev = "b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +rev = "5943aa66baf85ebb70d946c37e297abc80d13a78" # path = "../rs-soroban-sdk/soroban-spec-rust" [workspace.dependencies.soroban-spec-json] @@ -45,12 +45,12 @@ path = "./cmd/crates/soroban-spec-tools" [workspace.dependencies.soroban-sdk] version = "0.9.1" git = "https://github.com/stellar/rs-soroban-sdk" -rev = "b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +rev = "5943aa66baf85ebb70d946c37e297abc80d13a78" [workspace.dependencies.soroban-ledger-snapshot] version = "0.9.1" git = "https://github.com/stellar/rs-soroban-sdk" -rev = "b1cec10b79cee3c1ecf63079b1088ce97b32c68a" +rev = "5943aa66baf85ebb70d946c37e297abc80d13a78" [workspace.dependencies.soroban-cli] version = "0.9.4" @@ -59,7 +59,7 @@ path = "cmd/soroban-cli" [workspace.dependencies.stellar-xdr] version = "0.0.17" git = "https://github.com/stellar/rs-stellar-xdr" -rev = "4eaf2388c1de6fc295ed5f7df8174c199923df5b" +rev = "d6e02584ac9f4046bf38eaf445ced0d4f33631fd" default-features = false [workspace.dependencies] diff --git a/cmd/soroban-cli/src/commands/contract/bump.rs b/cmd/soroban-cli/src/commands/contract/bump.rs index da5935b73..9760a2ee0 100644 --- a/cmd/soroban-cli/src/commands/contract/bump.rs +++ b/cmd/soroban-cli/src/commands/contract/bump.rs @@ -164,7 +164,7 @@ impl Cmd { instructions: 0, read_bytes: 0, write_bytes: 0, - extended_meta_data_size_bytes: 0, + contract_events_size_bytes: 0, }, refundable_fee: 0, }), diff --git a/cmd/soroban-cli/src/commands/contract/invoke.rs b/cmd/soroban-cli/src/commands/contract/invoke.rs index b53125964..f1f90f45a 100644 --- a/cmd/soroban-cli/src/commands/contract/invoke.rs +++ b/cmd/soroban-cli/src/commands/contract/invoke.rs @@ -8,6 +8,8 @@ use std::{fmt::Debug, fs, io, rc::Rc}; use clap::{arg, command, value_parser, Parser}; use heck::ToKebabCase; +use soroban_env_host::e2e_invoke::get_ledger_changes; +use soroban_env_host::xdr::ReadXdr; use soroban_env_host::{ budget::Budget, events::HostEvent, @@ -403,7 +405,8 @@ impl Cmd { root_invocation: payload.invocation, }) .collect(); - let (storage, budget, events, expiration_ledger_bumps) = h.try_finish().map_err(|h| h.1)?; + let budget = h.budget_cloned(); + let (storage, events) = h.try_finish()?; let footprint = &create_ledger_footprint(&storage.footprint); log_events( footprint, @@ -412,6 +415,14 @@ impl Cmd { Some(&budget), ); + let ledger_changes = get_ledger_changes(&budget, &storage, &state)?; + let mut expiration_ledger_bumps: HashMap = HashMap::new(); + for ledger_entry_change in ledger_changes { + if let Some(exp_change) = ledger_entry_change.expiration_change { + let key = xdr::LedgerKey::from_xdr(ledger_entry_change.encoded_key)?; + expiration_ledger_bumps.insert(key, exp_change.new_expiration_ledger); + } + } utils::bump_ledger_entry_expirations(&mut state.ledger_entries, &expiration_ledger_bumps); self.config.set_state(&mut state)?; diff --git a/cmd/soroban-cli/src/commands/contract/restore.rs b/cmd/soroban-cli/src/commands/contract/restore.rs index f73f84525..37acb7883 100644 --- a/cmd/soroban-cli/src/commands/contract/restore.rs +++ b/cmd/soroban-cli/src/commands/contract/restore.rs @@ -171,7 +171,7 @@ impl Cmd { instructions: 0, read_bytes: 0, write_bytes: 0, - extended_meta_data_size_bytes: 0, + contract_events_size_bytes: 0, }, refundable_fee: 0, }), diff --git a/cmd/soroban-cli/src/commands/events.rs b/cmd/soroban-cli/src/commands/events.rs index ad9055e2d..16a097334 100644 --- a/cmd/soroban-cli/src/commands/events.rs +++ b/cmd/soroban-cli/src/commands/events.rs @@ -344,6 +344,7 @@ mod tests { max_entry_expiration: 6, min_persistent_entry_expiration: 7, min_temp_entry_expiration: 8, + autobump_ledgers: 16, }; events_file.commit(&events, &ledger_info, &temp).unwrap(); diff --git a/cmd/soroban-cli/src/rpc/transaction.rs b/cmd/soroban-cli/src/rpc/transaction.rs index 5b438a000..0419c0ff1 100644 --- a/cmd/soroban-cli/src/rpc/transaction.rs +++ b/cmd/soroban-cli/src/rpc/transaction.rs @@ -110,7 +110,7 @@ mod tests { instructions: 0, read_bytes: 5, write_bytes: 0, - extended_meta_data_size_bytes: 0, + contract_events_size_bytes: 0, }, refundable_fee: 0, ext: ExtensionPoint::V0, diff --git a/cmd/soroban-cli/src/utils.rs b/cmd/soroban-cli/src/utils.rs index d2b3705b1..be49aebcc 100644 --- a/cmd/soroban-cli/src/utils.rs +++ b/cmd/soroban-cli/src/utils.rs @@ -1,3 +1,4 @@ +use std::hash::BuildHasher; use std::{collections::HashMap, io::ErrorKind, path::Path}; use ed25519_dalek::Signer; @@ -5,7 +6,6 @@ use sha2::{Digest, Sha256}; use soroban_env_host::{ budget::Budget, - expiration_ledger_bumps::ExpirationLedgerBumps, storage::{AccessType, Footprint, Storage}, xdr::{ AccountEntry, AccountEntryExt, AccountId, Asset, ContractCodeEntry, ContractCodeEntryBody, @@ -134,15 +134,10 @@ pub fn add_contract_to_ledger_entries( entries.push((Box::new(contract_key), Box::new(contract_entry))); } -pub fn bump_ledger_entry_expirations( +pub fn bump_ledger_entry_expirations( entries: &mut [(Box, Box)], - bumps: &ExpirationLedgerBumps, + lookup: &HashMap, ) { - // let lookup: HashMap = bumps - let lookup = bumps - .iter() - .map(|b| (b.key.as_ref().clone(), b.min_expiration)) - .collect::>(); for (k, e) in entries.iter_mut() { if let Some(min_expiration) = lookup.get(k.as_ref()) { if let LedgerEntryData::ContractData(entry) = &mut e.data { diff --git a/cmd/soroban-rpc/internal/db/ledgerentry.go b/cmd/soroban-rpc/internal/db/ledgerentry.go index c4e10c9b8..2a0d08a1d 100644 --- a/cmd/soroban-rpc/internal/db/ledgerentry.go +++ b/cmd/soroban-rpc/internal/db/ledgerentry.go @@ -253,7 +253,7 @@ func (l *ledgerEntryReadTx) GetLedgerEntry(key xdr.LedgerKey, includeExpired boo if err != nil { return false, xdr.LedgerEntry{}, err } - if expirationLedgerSeq <= xdr.Uint32(latestClosedLedger) { + if expirationLedgerSeq < xdr.Uint32(latestClosedLedger) { return false, xdr.LedgerEntry{}, nil } } diff --git a/cmd/soroban-rpc/internal/db/ledgerentry_test.go b/cmd/soroban-rpc/internal/db/ledgerentry_test.go index 3dae49f32..46655760e 100644 --- a/cmd/soroban-rpc/internal/db/ledgerentry_test.go +++ b/cmd/soroban-rpc/internal/db/ledgerentry_test.go @@ -357,8 +357,9 @@ func TestGetLedgerEntryHidesExpiredContractDataEntries(t *testing.T) { }{ {21, true}, {22, true}, - {23, false}, + {23, true}, {24, false}, + {25, false}, } { // ffwd to the ledger sequence tx, err := NewReadWriter(db, 0, 15).NewTx(context.Background()) @@ -403,8 +404,9 @@ func TestGetLedgerEntryHidesExpiredContractCodeEntries(t *testing.T) { }{ {21, true}, {22, true}, - {23, false}, + {23, true}, {24, false}, + {25, false}, } { // ffwd to the ledger sequence tx, err := NewReadWriter(db, 0, 15).NewTx(context.Background()) diff --git a/cmd/soroban-rpc/internal/ingest/service.go b/cmd/soroban-rpc/internal/ingest/service.go index 1ffe4c5d6..7de5e398f 100644 --- a/cmd/soroban-rpc/internal/ingest/service.go +++ b/cmd/soroban-rpc/internal/ingest/service.go @@ -218,7 +218,7 @@ func (s *Service) fillEntriesFromCheckpoint(ctx context.Context, archive history func (s *Service) ingest(ctx context.Context, sequence uint32) error { startTime := time.Now() - s.logger.Infof("Applying txmeta for ledger %d", sequence) + s.logger.Infof("Ingesting ledger %d", sequence) ledgerCloseMeta, err := s.ledgerBackend.GetLedger(ctx, sequence) if err != nil { return err @@ -251,6 +251,7 @@ func (s *Service) ingest(ctx context.Context, sequence uint32) error { if err := tx.Commit(sequence); err != nil { return err } + s.logger.Debugf("Ingested ledger %d", sequence) s.ingestionDurationMetric. With(prometheus.Labels{"type": "total"}).Observe(time.Since(startTime).Seconds()) diff --git a/cmd/soroban-rpc/internal/preflight/preflight.go b/cmd/soroban-rpc/internal/preflight/preflight.go index cc419f358..d00457002 100644 --- a/cmd/soroban-rpc/internal/preflight/preflight.go +++ b/cmd/soroban-rpc/internal/preflight/preflight.go @@ -151,11 +151,17 @@ func getFootprintExpirationPreflight(params PreflightParameters) (Preflight, err handle := cgo.NewHandle(snapshotSourceHandle{params.LedgerEntryReadTx, params.Logger}) defer handle.Delete() + latestLedger, err := params.LedgerEntryReadTx.GetLatestLedgerSequence() + if err != nil { + return Preflight{}, err + } + res := C.preflight_footprint_expiration_op( C.uintptr_t(handle), C.uint64_t(params.BucketListSize), opBodyCString, footprintCString, + C.uint32_t(latestLedger), ) C.free(unsafe.Pointer(opBodyCString)) @@ -188,26 +194,26 @@ func getInvokeHostFunctionPreflight(params PreflightParameters) (Preflight, erro if err != nil { return Preflight{}, err } - minTempEntryExpiration := uint32(0) - minPersistentEntryExpiration := uint32(0) - maxEntryExpiration := uint32(0) - if hasConfig { - setting := stateExpirationConfig.Data.MustConfigSetting().MustStateExpirationSettings() - minTempEntryExpiration = uint32(setting.MinTempEntryExpiration) - minPersistentEntryExpiration = uint32(setting.MinPersistentEntryExpiration) - maxEntryExpiration = uint32(setting.MaxEntryExpiration) + if !hasConfig { + return Preflight{}, errors.New("state expiration config setting missing in ledger storage") } + stateExpiration := stateExpirationConfig.Data.MustConfigSetting().MustStateExpirationSettings() + // It's of utmost importance to simulate the transactions like we were on the next ledger. + // Otherwise, users would need to wait for an extra ledger to close in order to observe the effects of the latest ledger + // transaction submission. + sequenceNumber := latestLedger + 1 li := C.CLedgerInfo{ network_passphrase: C.CString(params.NetworkPassphrase), - sequence_number: C.uint(latestLedger), + sequence_number: C.uint32_t(sequenceNumber), protocol_version: 20, timestamp: C.uint64_t(time.Now().Unix()), // Current base reserve is 0.5XLM (in stroops) base_reserve: 5_000_000, - min_temp_entry_expiration: C.uint(minTempEntryExpiration), - min_persistent_entry_expiration: C.uint(minPersistentEntryExpiration), - max_entry_expiration: C.uint(maxEntryExpiration), + min_temp_entry_expiration: C.uint(stateExpiration.MinTempEntryExpiration), + min_persistent_entry_expiration: C.uint(stateExpiration.MinPersistentEntryExpiration), + max_entry_expiration: C.uint(stateExpiration.MaxEntryExpiration), + auto_bump_ledgers: C.uint(stateExpiration.AutoBumpLedgers), } sourceAccountCString := C.CString(sourceAccountB64) diff --git a/cmd/soroban-rpc/internal/preflight/preflight_test.go b/cmd/soroban-rpc/internal/preflight/preflight_test.go index 70d69feee..44bfcee26 100644 --- a/cmd/soroban-rpc/internal/preflight/preflight_test.go +++ b/cmd/soroban-rpc/internal/preflight/preflight_test.go @@ -137,10 +137,10 @@ var mockLedgerEntries = []xdr.LedgerEntry{ Data: xdr.LedgerEntryData{ Type: xdr.LedgerEntryTypeConfigSetting, ConfigSetting: &xdr.ConfigSettingEntry{ - ConfigSettingId: xdr.ConfigSettingIdConfigSettingContractMetaDataV0, - ContractMetaData: &xdr.ConfigSettingContractMetaDataV0{ - TxMaxExtendedMetaDataSizeBytes: 100, - FeeExtendedMetaData1Kb: 100, + ConfigSettingId: xdr.ConfigSettingIdConfigSettingContractEventsV0, + ContractEvents: &xdr.ConfigSettingContractEventsV0{ + TxMaxContractEventsSizeBytes: 10000, + FeeContractEvents1Kb: 1, }, }, }, @@ -152,9 +152,9 @@ var mockLedgerEntries = []xdr.LedgerEntry{ ConfigSetting: &xdr.ConfigSettingEntry{ ConfigSettingId: xdr.ConfigSettingIdConfigSettingContractBandwidthV0, ContractBandwidth: &xdr.ConfigSettingContractBandwidthV0{ - LedgerMaxPropagateSizeBytes: 100, - TxMaxSizeBytes: 100, - FeePropagateData1Kb: 100, + LedgerMaxTxsSizeBytes: 100000, + TxMaxSizeBytes: 1000, + FeeTxSize1Kb: 1, }, }, }, diff --git a/cmd/soroban-rpc/internal/test/docker-compose.yml b/cmd/soroban-rpc/internal/test/docker-compose.yml index ce848f7e4..548715ed0 100644 --- a/cmd/soroban-rpc/internal/test/docker-compose.yml +++ b/cmd/soroban-rpc/internal/test/docker-compose.yml @@ -15,7 +15,7 @@ services: # Note: Please keep the image pinned to an immutable tag matching the Captive Core version. # This avoid implicit updates which break compatibility between # the Core container and captive core. - image: ${CORE_IMAGE:-2opremio/stellar-core:19.12.1-1419.0ad2053d5.focal-soroban} + image: ${CORE_IMAGE:-2opremio/stellar-core:19.12.1-1425.df613c240.focal-soroban} depends_on: - core-postgres restart: on-failure diff --git a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go index e68edfa26..7d9d589f5 100644 --- a/cmd/soroban-rpc/internal/test/simulate_transaction_test.go +++ b/cmd/soroban-rpc/internal/test/simulate_transaction_test.go @@ -146,12 +146,10 @@ func preflightTransactionParams(t *testing.T, client *jrpc2.Client, params txnbu } var transactionData xdr.SorobanTransactionData err = xdr.SafeUnmarshalBase64(response.TransactionData, &transactionData) + require.NoError(t, err) require.Len(t, response.Results, 1) - // Hack until we start including rent fees in the preflight computation - transactionData.RefundableFee = 10000 - op := params.Operations[0] switch v := op.(type) { case *txnbuild.InvokeHostFunction: @@ -240,12 +238,12 @@ func TestSimulateTransactionSucceeds(t *testing.T) { }, }, }, - Instructions: 74350, - ReadBytes: 1040, - WriteBytes: 112, - ExtendedMetaDataSizeBytes: 1152, + Instructions: 88144, + ReadBytes: 40, + WriteBytes: 112, + ContractEventsSizeBytes: 0, }, - RefundableFee: 10225, + RefundableFee: 1, } // First, decode and compare the transaction data so we get a decent diff if it fails. @@ -277,6 +275,7 @@ func TestSimulateTransactionSucceeds(t *testing.T) { }, }) require.NoError(t, err) + txB64, err = tx.Base64() require.NoError(t, err) request = methods.SimulateTransactionRequest{Transaction: txB64} @@ -451,7 +450,7 @@ func TestSimulateInvokeContractTransactionSucceeds(t *testing.T) { assert.NoError(t, err) assert.NotZero(t, obtainedTransactionData.RefundableFee) - assert.NotZero(t, obtainedTransactionData.Resources.ExtendedMetaDataSizeBytes) + assert.NotZero(t, obtainedTransactionData.Resources.ContractEventsSizeBytes) assert.NotZero(t, obtainedTransactionData.Resources.Instructions) assert.NotZero(t, obtainedTransactionData.Resources.ReadBytes) assert.NotZero(t, obtainedTransactionData.Resources.WriteBytes) @@ -500,7 +499,7 @@ func TestSimulateInvokeContractTransactionSucceeds(t *testing.T) { require.Contains(t, metrics, "soroban_rpc_json_rpc_request_duration_seconds_count{endpoint=\"simulateTransaction\",status=\"ok\"} 3") require.Contains(t, metrics, "soroban_rpc_preflight_pool_request_ledger_get_duration_seconds_count{status=\"ok\",type=\"db\"} 3") require.Contains(t, metrics, "soroban_rpc_preflight_pool_request_ledger_get_duration_seconds_count{status=\"ok\",type=\"all\"} 3") - require.Contains(t, metrics, "soroban_rpc_preflight_pool_request_ledger_entries_fetched_sum 42") + require.Contains(t, metrics, "soroban_rpc_preflight_pool_request_ledger_entries_fetched_sum 48") } func TestSimulateTransactionError(t *testing.T) { @@ -771,13 +770,19 @@ func TestSimulateTransactionBumpAndRestoreFootprint(t *testing.T) { assert.Greater(t, newExpirationSeq, initialExpirationSeq) // Wait until it expires + expired := false for i := 0; i < 50; i++ { err = client.CallResult(context.Background(), "getLedgerEntry", getLedgerEntryrequest, &result) if err != nil { + expired = true + t.Logf("ledger entry expired") break } + assert.NoError(t, xdr.SafeUnmarshalBase64(result.XDR, &entry)) + t.Log("waiting for ledger entry to expire at ledger", entry.MustContractData().ExpirationLedgerSeq+1) time.Sleep(time.Second) } + require.True(t, expired) // and restore it params = preflightTransactionParams(t, client, txnbuild.TransactionParams{ diff --git a/cmd/soroban-rpc/internal/test/transaction_test.go b/cmd/soroban-rpc/internal/test/transaction_test.go index 99675f589..9c1437f54 100644 --- a/cmd/soroban-rpc/internal/test/transaction_test.go +++ b/cmd/soroban-rpc/internal/test/transaction_test.go @@ -259,6 +259,7 @@ func sendSuccessfulTransaction(t *testing.T, client *jrpc2.Client, kp *keypair.F assert.NoError(t, err) fmt.Printf("meta: %#v\n", txMeta) } + require.NotNil(t, response.ResultXdr) assert.Greater(t, response.Ledger, result.LatestLedger) assert.Greater(t, response.LedgerCloseTime, result.LatestLedgerCloseTime) diff --git a/cmd/soroban-rpc/lib/preflight.h b/cmd/soroban-rpc/lib/preflight.h index e4395a384..176f77172 100644 --- a/cmd/soroban-rpc/lib/preflight.h +++ b/cmd/soroban-rpc/lib/preflight.h @@ -12,6 +12,7 @@ typedef struct CLedgerInfo { uint32_t min_temp_entry_expiration; uint32_t min_persistent_entry_expiration; uint32_t max_entry_expiration; + uint32_t auto_bump_ledgers; } CLedgerInfo; typedef struct CPreflightResult { @@ -34,7 +35,8 @@ CPreflightResult *preflight_invoke_hf_op(uintptr_t handle, // Go Handle to forwa CPreflightResult *preflight_footprint_expiration_op(uintptr_t handle, // Go Handle to forward to SnapshotSourceGet and SnapshotSourceHas uint64_t bucket_list_size, // Bucket list size of current ledger const char *op_body, // OperationBody XDR in base64 - const char *footprint); // LedgerFootprint XDR in base64 + const char *footprint, // LedgerFootprint XDR in base64 + uint32_t current_ledger_seq); // Current ledger sequence // LedgerKey XDR in base64 string to LedgerEntry XDR in base64 string extern char *SnapshotSourceGet(uintptr_t handle, char *ledger_key, int include_expired); @@ -45,4 +47,3 @@ extern int SnapshotSourceHas(uintptr_t handle, char *ledger_key); void free_preflight_result(CPreflightResult *result); extern void FreeGoCString(char *str); - diff --git a/cmd/soroban-rpc/lib/preflight/src/fees.rs b/cmd/soroban-rpc/lib/preflight/src/fees.rs index 8cace9ca6..49fa28a71 100644 --- a/cmd/soroban-rpc/lib/preflight/src/fees.rs +++ b/cmd/soroban-rpc/lib/preflight/src/fees.rs @@ -1,17 +1,22 @@ use ledger_storage; +use ledger_storage::LedgerStorage; use soroban_env_host::budget::Budget; +use soroban_env_host::e2e_invoke::{extract_rent_changes, get_ledger_changes, LedgerEntryChange}; use soroban_env_host::fees::{ - compute_transaction_resource_fee, compute_write_fee_per_1kb, FeeConfiguration, - TransactionResources, WriteFeeConfiguration, + compute_rent_fee, compute_transaction_resource_fee, compute_write_fee_per_1kb, + FeeConfiguration, LedgerEntryRentChange, RentFeeConfiguration, TransactionResources, + WriteFeeConfiguration, }; -use soroban_env_host::storage::{AccessType, Footprint, Storage, StorageMap}; +use soroban_env_host::storage::{AccessType, Footprint, Storage}; use soroban_env_host::xdr; +use soroban_env_host::xdr::ContractDataDurability::Persistent; use soroban_env_host::xdr::{ - BumpFootprintExpirationOp, ConfigSettingEntry, ConfigSettingId, DecoratedSignature, - DiagnosticEvent, ExtensionPoint, InvokeHostFunctionOp, LedgerFootprint, LedgerKey, Memo, - MuxedAccount, MuxedAccountMed25519, Operation, OperationBody, Preconditions, - RestoreFootprintOp, SequenceNumber, Signature, SignatureHint, SorobanResources, - SorobanTransactionData, Transaction, TransactionExt, TransactionV1Envelope, Uint256, WriteXdr, + BumpFootprintExpirationOp, ConfigSettingEntry, ConfigSettingId, ContractDataDurability, + DecoratedSignature, DiagnosticEvent, ExtensionPoint, InvokeHostFunctionOp, LedgerEntry, + LedgerEntryData, LedgerFootprint, LedgerKey, Memo, MuxedAccount, MuxedAccountMed25519, + Operation, OperationBody, Preconditions, RestoreFootprintOp, SequenceNumber, Signature, + SignatureHint, SorobanResources, SorobanTransactionData, Transaction, TransactionExt, + TransactionV1Envelope, Uint256, WriteXdr, }; use std::cmp::max; use std::convert::{TryFrom, TryInto}; @@ -19,19 +24,21 @@ use std::error; pub(crate) fn compute_host_function_transaction_data_and_min_fee( op: &InvokeHostFunctionOp, - snapshot_source: &ledger_storage::LedgerStorage, - storage: &Storage, + pre_storage: &ledger_storage::LedgerStorage, + post_storage: &Storage, budget: &Budget, events: &Vec, bucket_list_size: u64, + current_ledger_seq: u32, ) -> Result<(SorobanTransactionData, i64), Box> { - let soroban_resources = hack_soroban_resources(calculate_host_function_soroban_resources( - snapshot_source, - storage, + let ledger_changes = get_ledger_changes(budget, post_storage, pre_storage)?; + let soroban_resources = calculate_host_function_soroban_resources( + &ledger_changes, + pre_storage, + post_storage, budget, events, - )?); - let fee_configuration = get_fee_configuration(snapshot_source, bucket_list_size)?; + )?; let read_write_entries = u32::try_from(soroban_resources.footprint.read_write.as_vec().len())?; @@ -42,21 +49,23 @@ pub(crate) fn compute_host_function_transaction_data_and_min_fee( write_entries: read_write_entries, read_bytes: soroban_resources.read_bytes, write_bytes: soroban_resources.write_bytes, - metadata_size_bytes: soroban_resources.extended_meta_data_size_bytes, // Note: we could get a better transaction size if the full transaction was passed down to libpreflight transaction_size_bytes: estimate_max_transaction_size_for_operation( &OperationBody::InvokeHostFunction(op.clone()), &soroban_resources.footprint, )?, + contract_events_size_bytes: soroban_resources.contract_events_size_bytes, }; - let (min_fee, ref_fee) = - compute_transaction_resource_fee_wrapper(&transaction_resources, &fee_configuration); - let transaction_data = SorobanTransactionData { - resources: soroban_resources, - refundable_fee: ref_fee, - ext: ExtensionPoint::V0, - }; - Ok((transaction_data, min_fee)) + let rent_changes = extract_rent_changes(&ledger_changes); + + finalize_transaction_data_and_min_fee( + &pre_storage, + &transaction_resources, + soroban_resources, + &rent_changes, + current_ledger_seq, + bucket_list_size, + ) } fn estimate_max_transaction_size_for_operation( @@ -95,7 +104,7 @@ fn estimate_max_transaction_size_for_operation( instructions: 0, read_bytes: 0, write_bytes: 0, - extended_meta_data_size_bytes: 0, + contract_events_size_bytes: 0, }, refundable_fee: 0, ext: ExtensionPoint::V0, @@ -113,26 +122,37 @@ fn estimate_max_transaction_size_for_operation( } fn calculate_host_function_soroban_resources( - snapshot_source: &ledger_storage::LedgerStorage, - storage: &Storage, + ledger_changes: &Vec, + pre_storage: &LedgerStorage, + post_storage: &Storage, budget: &Budget, events: &Vec, ) -> Result> { - let fp = storage_footprint_to_ledger_footprint(&storage.footprint)?; - /* - readBytes = size(footprint.readOnly) + size(footprint.readWrite) - writeBytes = size(storage.map[rw entries]) - metadataSize = readBytes(footprint.readWrite) + writeBytes + eventsSize - */ - let original_write_ledger_entry_bytes = - calculate_unmodified_ledger_entry_bytes(fp.read_write.as_vec(), snapshot_source, false)?; - let read_bytes = - calculate_unmodified_ledger_entry_bytes(fp.read_only.as_vec(), snapshot_source, false)? - + original_write_ledger_entry_bytes; - let write_bytes = - calculate_modified_read_write_ledger_entry_bytes(&storage.footprint, &storage.map, budget)?; - let meta_data_size_bytes = - original_write_ledger_entry_bytes + write_bytes + calculate_event_size_bytes(events)?; + let ledger_footprint = storage_footprint_to_ledger_footprint(&post_storage.footprint)?; + // FIXME: This hack is needed due to a bug in recording mode which prevents get_ledger_changes() from + // including unmodified ledger entries. + // Remove once this is fixed upstream. + let mut unmodified_ledger_keys: Vec = Vec::new(); + for k in ledger_footprint.read_only.as_vec() { + if !post_storage.map.contains_key::(k, budget)? { + unmodified_ledger_keys.push(k.clone()); + } + } + let unmodified_entries_read_bytes = + calculate_unmodified_ledger_entry_bytes(&unmodified_ledger_keys, pre_storage, false)?; + let modified_entries_read_bytes: u32 = ledger_changes + .iter() + .map(|c| c.encoded_key.len() as u32 + c.old_entry_size_bytes) + .sum(); + + let write_bytes: u32 = ledger_changes + .iter() + .map(|c| { + c.encoded_key.len() as u32 + c.encoded_new_value.as_ref().map_or(0, |v| v.len()) as u32 + }) + .sum(); + + let contract_events_size_bytes = calculate_event_size_bytes(events)?; // Add a 15% leeway with a minimum of 50k instructions let instructions = max( @@ -140,18 +160,18 @@ fn calculate_host_function_soroban_resources( budget.get_cpu_insns_consumed()? * 115 / 100, ); Ok(SorobanResources { - footprint: fp, + footprint: ledger_footprint, instructions: u32::try_from(instructions)?, - read_bytes, + read_bytes: unmodified_entries_read_bytes + modified_entries_read_bytes, write_bytes, - extended_meta_data_size_bytes: meta_data_size_bytes, + contract_events_size_bytes, }) } -fn get_fee_configuration( +fn get_fee_configurations( ledger_storage: &ledger_storage::LedgerStorage, bucket_list_size: u64, -) -> Result> { +) -> Result<(FeeConfiguration, RentFeeConfiguration), Box> { let ConfigSettingEntry::ContractComputeV0(compute) = ledger_storage.get_configuration_setting(ConfigSettingId::ContractComputeV0)? else { @@ -177,11 +197,11 @@ fn get_fee_configuration( ); }; - let ConfigSettingEntry::ContractMetaDataV0(metadata) = - ledger_storage.get_configuration_setting(ConfigSettingId::ContractMetaDataV0)? + let ConfigSettingEntry::ContractEventsV0(events) = + ledger_storage.get_configuration_setting(ConfigSettingId::ContractEventsV0)? else { return Err( - "get_fee_configuration(): unexpected config setting entry for MetaDataV0 key".into(), + "get_fee_configuration(): unexpected config setting entry for ContractEventsV0 key".into(), ); }; @@ -193,6 +213,14 @@ fn get_fee_configuration( ); }; + let ConfigSettingEntry::StateExpiration(state_expiration) = + ledger_storage.get_configuration_setting(ConfigSettingId::StateExpiration)? + else { + return Err( + "get_fee_configuration(): unexpected config setting entry for StateExpiration key".into(), + ); + }; + let write_fee_configuration = WriteFeeConfiguration { bucket_list_target_size_bytes: ledger_cost.bucket_list_target_size_bytes, write_fee_1kb_bucket_list_low: ledger_cost.write_fee1_kb_bucket_list_low, @@ -200,72 +228,39 @@ fn get_fee_configuration( bucket_list_write_fee_growth_factor: ledger_cost.bucket_list_write_fee_growth_factor, }; - // Taken from Stellar Core's InitialSorobanNetworkConfig in NetworkConfig.h + let write_fee_per_1kb = + compute_write_fee_per_1kb(bucket_list_size as i64, &write_fee_configuration); + let fee_configuration = FeeConfiguration { fee_per_instruction_increment: compute.fee_rate_per_instructions_increment, fee_per_read_entry: ledger_cost.fee_read_ledger_entry, fee_per_write_entry: ledger_cost.fee_write_ledger_entry, fee_per_read_1kb: ledger_cost.fee_read1_kb, - fee_per_write_1kb: compute_write_fee_per_1kb( - bucket_list_size as i64, - &write_fee_configuration, - ), + fee_per_write_1kb: write_fee_per_1kb, fee_per_historical_1kb: historical_data.fee_historical1_kb, - fee_per_metadata_1kb: metadata.fee_extended_meta_data1_kb, - fee_per_propagate_1kb: bandwidth.fee_propagate_data1_kb, + fee_per_contract_event_1kb: events.fee_contract_events1_kb, + fee_per_transaction_size_1kb: bandwidth.fee_tx_size1_kb, }; - Ok(fee_configuration) -} - -fn calculate_modified_read_write_ledger_entry_bytes( - footprint: &Footprint, - storage_map: &StorageMap, - budget: &Budget, -) -> Result> { - let mut res: u32 = 0; - for (lk, ole) in storage_map { - match footprint.0.get::(lk, budget)? { - Some(AccessType::ReadOnly) => (), - Some(AccessType::ReadWrite) => { - if let Some(le) = ole { - let entry_bytes = le.to_xdr()?; - let key_bytes = lk.to_xdr()?; - res += u32::try_from(entry_bytes.len() + key_bytes.len())?; - } - } - None => return Err("storage ledger entry not found in footprint".into()), - } - } - Ok(res) + let rent_fee_configuration = RentFeeConfiguration { + fee_per_write_1kb: write_fee_per_1kb, + persistent_rent_rate_denominator: state_expiration.persistent_rent_rate_denominator, + temporary_rent_rate_denominator: state_expiration.temp_rent_rate_denominator, + }; + Ok((fee_configuration, rent_fee_configuration)) } fn calculate_unmodified_ledger_entry_bytes( ledger_entries: &Vec, - snapshot_source: &ledger_storage::LedgerStorage, + pre_storage: &ledger_storage::LedgerStorage, include_expired: bool, ) -> Result> { - let mut res: u32 = 0; + let mut res: usize = 0; for lk in ledger_entries { - res += u32::try_from(lk.to_xdr()?.len())?; - match snapshot_source.get_xdr(lk, include_expired) { - Ok(entry_bytes) => { - res += u32::try_from(entry_bytes.len())?; - } - Err(e) => { - match e { - ledger_storage::Error::NotFound => - // The entry is not present in the unmodified ledger storage. - // We assume it to be due to the entry being created by a host function invocation. - // Thus, we shouldn't count it in as unmodified. - { - continue; - } - _ => return Err(e)?, - } - } - }; + let key_size = lk.to_xdr()?.len(); + let entry_size = pre_storage.get_xdr(lk, include_expired)?.len(); + res += key_size + entry_size; } - Ok(res) + Ok(res as u32) } fn calculate_event_size_bytes(events: &Vec) -> Result> { @@ -292,31 +287,76 @@ fn storage_footprint_to_ledger_footprint(foot: &Footprint) -> Result, + current_ledger_seq: u32, + bucket_list_size: u64, +) -> Result<(SorobanTransactionData, i64), Box> { + let (fee_configuration, rent_fee_configuration) = + get_fee_configurations(pre_storage, bucket_list_size)?; + let (non_refundable_fee, refundable_fee) = + compute_transaction_resource_fee(transaction_resources, &fee_configuration); + let rent_fee = compute_rent_fee(&rent_changes, &rent_fee_configuration, current_ledger_seq); + let transaction_data = SorobanTransactionData { + resources: soroban_resources, + refundable_fee: refundable_fee + rent_fee, + ext: ExtensionPoint::V0, + }; + let res = ( + transaction_data, + refundable_fee + non_refundable_fee + rent_fee, + ); + Ok(res) +} + pub(crate) fn compute_bump_footprint_exp_transaction_data_and_min_fee( footprint: LedgerFootprint, ledgers_to_expire: u32, - snapshot_source: &ledger_storage::LedgerStorage, + ledger_storage: &ledger_storage::LedgerStorage, bucket_list_size: u64, + current_ledger_seq: u32, ) -> Result<(SorobanTransactionData, i64), Box> { + let mut rent_changes: Vec = Vec::new(); + for key in (&footprint).read_only.as_vec() { + let unmodified_entry = ledger_storage.get(key, false)?; + let (expiration_ledger, durability) = + get_bumpable_entry_expiration_and_durability(&unmodified_entry)?; + let new_expiration_ledger = current_ledger_seq + ledgers_to_expire; + if new_expiration_ledger <= expiration_ledger { + // The bump would be innefective + continue; + } + let size = (key.to_xdr()?.len() + unmodified_entry.to_xdr()?.len()) as u32; + let rent_change = LedgerEntryRentChange { + is_persistent: durability == Persistent, + old_size_bytes: size, + new_size_bytes: size, + old_expiration_ledger: expiration_ledger, + new_expiration_ledger, + }; + rent_changes.push(rent_change); + } let read_bytes = calculate_unmodified_ledger_entry_bytes( footprint.read_only.as_vec(), - snapshot_source, + ledger_storage, false, )?; - let soroban_resources = hack_soroban_resources(SorobanResources { + let soroban_resources = SorobanResources { footprint, instructions: 0, read_bytes, write_bytes: 0, - extended_meta_data_size_bytes: 2 * read_bytes, - }); + contract_events_size_bytes: 0, + }; let transaction_resources = TransactionResources { instructions: 0, read_entries: u32::try_from(soroban_resources.footprint.read_only.as_vec().len())?, write_entries: 0, read_bytes: soroban_resources.read_bytes, write_bytes: 0, - metadata_size_bytes: soroban_resources.extended_meta_data_size_bytes, transaction_size_bytes: estimate_max_transaction_size_for_operation( &OperationBody::BumpFootprintExpiration(BumpFootprintExpirationOp { ext: ExtensionPoint::V0, @@ -324,37 +364,86 @@ pub(crate) fn compute_bump_footprint_exp_transaction_data_and_min_fee( }), &soroban_resources.footprint, )?, + contract_events_size_bytes: 0, }; - let fee_configuration = get_fee_configuration(snapshot_source, bucket_list_size)?; - let (min_fee, ref_fee) = - compute_transaction_resource_fee_wrapper(&transaction_resources, &fee_configuration); - let transaction_data = SorobanTransactionData { - resources: soroban_resources, - refundable_fee: ref_fee, - ext: ExtensionPoint::V0, + finalize_transaction_data_and_min_fee( + &ledger_storage, + &transaction_resources, + soroban_resources, + &rent_changes, + current_ledger_seq, + bucket_list_size, + ) +} + +fn get_bumpable_entry_expiration_and_durability( + ledger_entry: &LedgerEntry, +) -> Result<(u32, ContractDataDurability), Box> { + let res = match ledger_entry.data { + LedgerEntryData::ContractData(ref cd) => (cd.expiration_ledger_seq, cd.durability), + LedgerEntryData::ContractCode(ref cc) => (cc.expiration_ledger_seq, Persistent), + _ => { + let err = format!( + "Incorrect ledger entry type ({}) in footprint", + ledger_entry.data.name() + ) + .into(); + return Err(err); + } }; - Ok((transaction_data, min_fee)) + Ok(res) } pub(crate) fn compute_restore_footprint_transaction_data_and_min_fee( footprint: LedgerFootprint, - snapshot_source: &ledger_storage::LedgerStorage, + ledger_storage: &ledger_storage::LedgerStorage, bucket_list_size: u64, + current_ledger_seq: u32, ) -> Result<(SorobanTransactionData, i64), Box> { + let ConfigSettingEntry::StateExpiration(state_expiration) = + ledger_storage.get_configuration_setting(ConfigSettingId::StateExpiration)? + else { + return Err( + "get_fee_configuration(): unexpected config setting entry for StateExpiration key".into(), + ); + }; + let mut rent_changes: Vec = Vec::new(); + for key in footprint.read_write.as_vec() { + let unmodified_entry = ledger_storage.get(key, true)?; + let (expiration_ledger, durability) = + get_bumpable_entry_expiration_and_durability(&unmodified_entry)?; + if durability != Persistent { + let err = format!("Non-persistent key ({:?}) in footprint", key).into(); + return Err(err); + } + if current_ledger_seq <= expiration_ledger { + // noop (the entry hadn't expired) + continue; + } + let new_expiration_ledger = + current_ledger_seq + state_expiration.min_persistent_entry_expiration - 1; + let size = (key.to_xdr()?.len() + unmodified_entry.to_xdr()?.len()) as u32; + let rent_change = LedgerEntryRentChange { + is_persistent: true, + old_size_bytes: 0, + new_size_bytes: size, + old_expiration_ledger: 0, + new_expiration_ledger, + }; + rent_changes.push(rent_change); + } let write_bytes = calculate_unmodified_ledger_entry_bytes( footprint.read_write.as_vec(), - snapshot_source, + ledger_storage, true, )?; - let soroban_resources = hack_soroban_resources(SorobanResources { + let soroban_resources = SorobanResources { footprint, instructions: 0, - // FIXME(fons): this seems to be a workaround a bug in code (the fix is to also count bytes read but not written in readBytes). - // we should review it in preview 11. read_bytes: write_bytes, write_bytes, - extended_meta_data_size_bytes: 2 * write_bytes, - }); + contract_events_size_bytes: 0, + }; let entry_count = u32::try_from(soroban_resources.footprint.read_write.as_vec().len())?; let transaction_resources = TransactionResources { instructions: 0, @@ -362,48 +451,20 @@ pub(crate) fn compute_restore_footprint_transaction_data_and_min_fee( write_entries: entry_count, read_bytes: soroban_resources.read_bytes, write_bytes: soroban_resources.write_bytes, - metadata_size_bytes: soroban_resources.extended_meta_data_size_bytes, transaction_size_bytes: estimate_max_transaction_size_for_operation( &OperationBody::RestoreFootprint(RestoreFootprintOp { ext: ExtensionPoint::V0, }), &soroban_resources.footprint, )?, + contract_events_size_bytes: 0, }; - let fee_configuration = get_fee_configuration(snapshot_source, bucket_list_size)?; - let (min_fee, ref_fee) = - compute_transaction_resource_fee_wrapper(&transaction_resources, &fee_configuration); - let transaction_data = SorobanTransactionData { - resources: soroban_resources, - refundable_fee: ref_fee, - ext: ExtensionPoint::V0, - }; - Ok((transaction_data, min_fee)) -} - -fn hack_soroban_resources(resources: SorobanResources) -> SorobanResources { - // FIXME: Hack suggested by the core team until they include expiration ledger bumps - return SorobanResources { - footprint: resources.footprint, - instructions: resources.instructions, - read_bytes: max( - resources.read_bytes + 1000, - resources.read_bytes * 120 / 100, - ), - write_bytes: resources.write_bytes, - extended_meta_data_size_bytes: max( - resources.extended_meta_data_size_bytes + 1000, - resources.extended_meta_data_size_bytes * 120 / 100, - ), - }; -} - -fn compute_transaction_resource_fee_wrapper( - tx_resources: &TransactionResources, - fee_config: &FeeConfiguration, -) -> (i64, i64) { - let (min_fee, ref_fee) = compute_transaction_resource_fee(tx_resources, fee_config); - // FIXME: Hack suggested by the core team, until we compute rent fees properly - // and include expiration ledger bumps - return (min_fee + 10000 + 10000, ref_fee + 10000); + finalize_transaction_data_and_min_fee( + &ledger_storage, + &transaction_resources, + soroban_resources, + &rent_changes, + current_ledger_seq, + bucket_list_size, + ) } diff --git a/cmd/soroban-rpc/lib/preflight/src/lib.rs b/cmd/soroban-rpc/lib/preflight/src/lib.rs index fe5c81f14..56609207c 100644 --- a/cmd/soroban-rpc/lib/preflight/src/lib.rs +++ b/cmd/soroban-rpc/lib/preflight/src/lib.rs @@ -36,6 +36,7 @@ pub struct CLedgerInfo { pub min_temp_entry_expiration: u32, pub min_persistent_entry_expiration: u32, pub max_entry_expiration: u32, + pub autobump_ledgers: u32, } impl From for LedgerInfo { @@ -50,6 +51,7 @@ impl From for LedgerInfo { min_temp_entry_expiration: c.min_temp_entry_expiration, min_persistent_entry_expiration: c.min_persistent_entry_expiration, max_entry_expiration: c.max_entry_expiration, + autobump_ledgers: c.autobump_ledgers, } } } @@ -128,9 +130,9 @@ fn preflight_invoke_hf_op_or_maybe_panic( // Run the preflight. let result = host.invoke_function(invoke_hf_op.host_function.clone())?; let auths = host.get_recorded_auth_payloads()?; - + let budget = host.budget_cloned(); // Recover, convert and return the storage footprint and other values to C. - let (storage, budget, events, _expiration_ledger_bumps) = host.try_finish().unwrap(); + let (storage, events) = host.try_finish()?; let diagnostic_events = host_events_to_diagnostic_events(&events); let (transaction_data, min_fee) = fees::compute_host_function_transaction_data_and_min_fee( @@ -145,6 +147,7 @@ fn preflight_invoke_hf_op_or_maybe_panic( &budget, &diagnostic_events, bucket_list_size, + ledger_info.sequence_number, )?; let transaction_data_cstr = CString::new(transaction_data.to_xdr_base64()?)?; Ok(CPreflightResult { @@ -201,6 +204,7 @@ pub extern "C" fn preflight_footprint_expiration_op( bucket_list_size: u64, // Bucket list size for current ledger op_body: *const libc::c_char, // OperationBody XDR in base64 footprint: *const libc::c_char, // LedgerFootprint XDR in base64 + current_ledger_seq: u32, ) -> *mut CPreflightResult { catch_preflight_panic(Box::new(move || { preflight_footprint_expiration_op_or_maybe_panic( @@ -208,6 +212,7 @@ pub extern "C" fn preflight_footprint_expiration_op( bucket_list_size, op_body, footprint, + current_ledger_seq, ) })) } @@ -217,24 +222,29 @@ fn preflight_footprint_expiration_op_or_maybe_panic( bucket_list_size: u64, op_body: *const libc::c_char, footprint: *const libc::c_char, + current_ledger_seq: u32, ) -> Result> { let op_body_cstr = unsafe { CStr::from_ptr(op_body) }; let op_body = OperationBody::from_xdr_base64(op_body_cstr.to_str()?)?; let footprint_cstr = unsafe { CStr::from_ptr(footprint) }; let ledger_footprint = LedgerFootprint::from_xdr_base64(footprint_cstr.to_str()?)?; - let snapshot_source = &ledger_storage::LedgerStorage { + let ledger_storage = &ledger_storage::LedgerStorage { golang_handle: handle, }; match op_body { OperationBody::BumpFootprintExpiration(op) => preflight_bump_footprint_expiration( ledger_footprint, op.ledgers_to_expire, - snapshot_source, + ledger_storage, bucket_list_size, + current_ledger_seq, + ), + OperationBody::RestoreFootprint(_) => preflight_restore_footprint( + ledger_footprint, + ledger_storage, + bucket_list_size, + current_ledger_seq, ), - OperationBody::RestoreFootprint(_) => { - preflight_restore_footprint(ledger_footprint, snapshot_source, bucket_list_size) - } op => Err(format!( "preflight_footprint_expiration_op(): unsupported operation type {}", op.name() @@ -246,15 +256,17 @@ fn preflight_footprint_expiration_op_or_maybe_panic( fn preflight_bump_footprint_expiration( footprint: LedgerFootprint, ledgers_to_expire: u32, - snapshot_source: &LedgerStorage, + ledger_storage: &LedgerStorage, bucket_list_size: u64, + current_ledger_seq: u32, ) -> Result> { let (transaction_data, min_fee) = fees::compute_bump_footprint_exp_transaction_data_and_min_fee( footprint, ledgers_to_expire, - snapshot_source, + ledger_storage, bucket_list_size, + current_ledger_seq, )?; let transaction_data_cstr = CString::new(transaction_data.to_xdr_base64()?)?; Ok(CPreflightResult { @@ -271,13 +283,15 @@ fn preflight_bump_footprint_expiration( fn preflight_restore_footprint( footprint: LedgerFootprint, - snapshot_source: &LedgerStorage, + ledger_storage: &LedgerStorage, bucket_list_size: u64, + current_ledger_seq: u32, ) -> Result> { let (transaction_data, min_fee) = fees::compute_restore_footprint_transaction_data_and_min_fee( footprint, - snapshot_source, + ledger_storage, bucket_list_size, + current_ledger_seq, )?; let transaction_data_cstr = CString::new(transaction_data.to_xdr_base64()?)?; Ok(CPreflightResult { @@ -335,15 +349,13 @@ fn recorded_auth_payload_to_xdr(payload: &RecordedAuthPayload) -> SorobanAuthori }), root_invocation: payload.invocation.clone(), }, - _ => SorobanAuthorizationEntry { + (None, None) => SorobanAuthorizationEntry { credentials: SorobanCredentials::SourceAccount, root_invocation: payload.invocation.clone(), }, - // TODO: there is a bug in the host library which prevents us from - // doing this check. It should be fixed in preview 11. // the address and the nonce can't be present independently - // (a,n) => - // panic!("recorded_auth_payload_to_xdr: address and nonce present independently (address: {:?}, nonce: {:?})", a, n), + (a,n) => + panic!("recorded_auth_payload_to_xdr: address and nonce present independently (address: {:?}, nonce: {:?})", a, n), } } diff --git a/docs/soroban-cli-full-docs.md b/docs/soroban-cli-full-docs.md index 922e97d25..f189a8a99 100644 --- a/docs/soroban-cli-full-docs.md +++ b/docs/soroban-cli-full-docs.md @@ -833,7 +833,7 @@ Decode XDR * `--type ` — XDR type to decode to - Possible values: `Value`, `ScpBallot`, `ScpStatementType`, `ScpNomination`, `ScpStatement`, `ScpStatementPledges`, `ScpStatementPrepare`, `ScpStatementConfirm`, `ScpStatementExternalize`, `ScpEnvelope`, `ScpQuorumSet`, `ConfigSettingContractExecutionLanesV0`, `ConfigSettingContractComputeV0`, `ConfigSettingContractLedgerCostV0`, `ConfigSettingContractHistoricalDataV0`, `ConfigSettingContractMetaDataV0`, `ConfigSettingContractBandwidthV0`, `ContractCostType`, `ContractCostParamEntry`, `StateExpirationSettings`, `ContractCostParams`, `ConfigSettingId`, `ConfigSettingEntry`, `ScEnvMetaKind`, `ScEnvMetaEntry`, `ScMetaV0`, `ScMetaKind`, `ScMetaEntry`, `ScSpecType`, `ScSpecTypeOption`, `ScSpecTypeResult`, `ScSpecTypeVec`, `ScSpecTypeMap`, `ScSpecTypeSet`, `ScSpecTypeTuple`, `ScSpecTypeBytesN`, `ScSpecTypeUdt`, `ScSpecTypeDef`, `ScSpecUdtStructFieldV0`, `ScSpecUdtStructV0`, `ScSpecUdtUnionCaseVoidV0`, `ScSpecUdtUnionCaseTupleV0`, `ScSpecUdtUnionCaseV0Kind`, `ScSpecUdtUnionCaseV0`, `ScSpecUdtUnionV0`, `ScSpecUdtEnumCaseV0`, `ScSpecUdtEnumV0`, `ScSpecUdtErrorEnumCaseV0`, `ScSpecUdtErrorEnumV0`, `ScSpecFunctionInputV0`, `ScSpecFunctionV0`, `ScSpecEntryKind`, `ScSpecEntry`, `ScValType`, `ScErrorType`, `ScErrorCode`, `ScError`, `UInt128Parts`, `Int128Parts`, `UInt256Parts`, `Int256Parts`, `ContractExecutableType`, `ContractExecutable`, `ScAddressType`, `ScAddress`, `ScVec`, `ScMap`, `ScBytes`, `ScString`, `ScSymbol`, `ScNonceKey`, `ScContractInstance`, `ScVal`, `ScMapEntry`, `StoredTransactionSet`, `PersistedScpStateV0`, `PersistedScpStateV1`, `PersistedScpState`, `Thresholds`, `String32`, `String64`, `SequenceNumber`, `DataValue`, `PoolId`, `AssetCode4`, `AssetCode12`, `AssetType`, `AssetCode`, `AlphaNum4`, `AlphaNum12`, `Asset`, `Price`, `Liabilities`, `ThresholdIndexes`, `LedgerEntryType`, `Signer`, `AccountFlags`, `SponsorshipDescriptor`, `AccountEntryExtensionV3`, `AccountEntryExtensionV2`, `AccountEntryExtensionV2Ext`, `AccountEntryExtensionV1`, `AccountEntryExtensionV1Ext`, `AccountEntry`, `AccountEntryExt`, `TrustLineFlags`, `LiquidityPoolType`, `TrustLineAsset`, `TrustLineEntryExtensionV2`, `TrustLineEntryExtensionV2Ext`, `TrustLineEntry`, `TrustLineEntryExt`, `TrustLineEntryV1`, `TrustLineEntryV1Ext`, `OfferEntryFlags`, `OfferEntry`, `OfferEntryExt`, `DataEntry`, `DataEntryExt`, `ClaimPredicateType`, `ClaimPredicate`, `ClaimantType`, `Claimant`, `ClaimantV0`, `ClaimableBalanceIdType`, `ClaimableBalanceId`, `ClaimableBalanceFlags`, `ClaimableBalanceEntryExtensionV1`, `ClaimableBalanceEntryExtensionV1Ext`, `ClaimableBalanceEntry`, `ClaimableBalanceEntryExt`, `LiquidityPoolConstantProductParameters`, `LiquidityPoolEntry`, `LiquidityPoolEntryBody`, `LiquidityPoolEntryConstantProduct`, `ContractEntryBodyType`, `ContractDataFlags`, `ContractDataDurability`, `ContractDataEntry`, `ContractDataEntryBody`, `ContractDataEntryData`, `ContractCodeEntry`, `ContractCodeEntryBody`, `LedgerEntryExtensionV1`, `LedgerEntryExtensionV1Ext`, `LedgerEntry`, `LedgerEntryData`, `LedgerEntryExt`, `LedgerKey`, `LedgerKeyAccount`, `LedgerKeyTrustLine`, `LedgerKeyOffer`, `LedgerKeyData`, `LedgerKeyClaimableBalance`, `LedgerKeyLiquidityPool`, `LedgerKeyContractData`, `LedgerKeyContractCode`, `LedgerKeyConfigSetting`, `EnvelopeType`, `UpgradeType`, `StellarValueType`, `LedgerCloseValueSignature`, `StellarValue`, `StellarValueExt`, `LedgerHeaderFlags`, `LedgerHeaderExtensionV1`, `LedgerHeaderExtensionV1Ext`, `LedgerHeader`, `LedgerHeaderExt`, `LedgerUpgradeType`, `ConfigUpgradeSetKey`, `LedgerUpgrade`, `ConfigUpgradeSet`, `BucketEntryType`, `BucketMetadata`, `BucketMetadataExt`, `BucketEntry`, `TxSetComponentType`, `TxSetComponent`, `TxSetComponentTxsMaybeDiscountedFee`, `TransactionPhase`, `TransactionSet`, `TransactionSetV1`, `GeneralizedTransactionSet`, `TransactionResultPair`, `TransactionResultSet`, `TransactionHistoryEntry`, `TransactionHistoryEntryExt`, `TransactionHistoryResultEntry`, `TransactionHistoryResultEntryExt`, `LedgerHeaderHistoryEntry`, `LedgerHeaderHistoryEntryExt`, `LedgerScpMessages`, `ScpHistoryEntryV0`, `ScpHistoryEntry`, `LedgerEntryChangeType`, `LedgerEntryChange`, `LedgerEntryChanges`, `OperationMeta`, `TransactionMetaV1`, `TransactionMetaV2`, `ContractEventType`, `ContractEvent`, `ContractEventBody`, `ContractEventV0`, `DiagnosticEvent`, `SorobanTransactionMeta`, `TransactionMetaV3`, `InvokeHostFunctionSuccessPreImage`, `TransactionMeta`, `TransactionResultMeta`, `UpgradeEntryMeta`, `LedgerCloseMetaV0`, `LedgerCloseMetaV1`, `LedgerCloseMetaV2`, `LedgerCloseMeta`, `ErrorCode`, `SError`, `SendMore`, `SendMoreExtended`, `AuthCert`, `Hello`, `Auth`, `IpAddrType`, `PeerAddress`, `PeerAddressIp`, `MessageType`, `DontHave`, `SurveyMessageCommandType`, `SurveyMessageResponseType`, `SurveyRequestMessage`, `SignedSurveyRequestMessage`, `EncryptedBody`, `SurveyResponseMessage`, `SignedSurveyResponseMessage`, `PeerStats`, `PeerStatList`, `TopologyResponseBodyV0`, `TopologyResponseBodyV1`, `SurveyResponseBody`, `TxAdvertVector`, `FloodAdvert`, `TxDemandVector`, `FloodDemand`, `StellarMessage`, `AuthenticatedMessage`, `AuthenticatedMessageV0`, `LiquidityPoolParameters`, `MuxedAccount`, `MuxedAccountMed25519`, `DecoratedSignature`, `OperationType`, `CreateAccountOp`, `PaymentOp`, `PathPaymentStrictReceiveOp`, `PathPaymentStrictSendOp`, `ManageSellOfferOp`, `ManageBuyOfferOp`, `CreatePassiveSellOfferOp`, `SetOptionsOp`, `ChangeTrustAsset`, `ChangeTrustOp`, `AllowTrustOp`, `ManageDataOp`, `BumpSequenceOp`, `CreateClaimableBalanceOp`, `ClaimClaimableBalanceOp`, `BeginSponsoringFutureReservesOp`, `RevokeSponsorshipType`, `RevokeSponsorshipOp`, `RevokeSponsorshipOpSigner`, `ClawbackOp`, `ClawbackClaimableBalanceOp`, `SetTrustLineFlagsOp`, `LiquidityPoolDepositOp`, `LiquidityPoolWithdrawOp`, `HostFunctionType`, `ContractIdPreimageType`, `ContractIdPreimage`, `ContractIdPreimageFromAddress`, `CreateContractArgs`, `InvokeContractArgs`, `HostFunction`, `SorobanAuthorizedFunctionType`, `SorobanAuthorizedFunction`, `SorobanAuthorizedInvocation`, `SorobanAddressCredentials`, `SorobanCredentialsType`, `SorobanCredentials`, `SorobanAuthorizationEntry`, `InvokeHostFunctionOp`, `BumpFootprintExpirationOp`, `RestoreFootprintOp`, `Operation`, `OperationBody`, `HashIdPreimage`, `HashIdPreimageOperationId`, `HashIdPreimageRevokeId`, `HashIdPreimageContractId`, `HashIdPreimageSorobanAuthorization`, `MemoType`, `Memo`, `TimeBounds`, `LedgerBounds`, `PreconditionsV2`, `PreconditionType`, `Preconditions`, `LedgerFootprint`, `SorobanResources`, `SorobanTransactionData`, `TransactionV0`, `TransactionV0Ext`, `TransactionV0Envelope`, `Transaction`, `TransactionExt`, `TransactionV1Envelope`, `FeeBumpTransaction`, `FeeBumpTransactionInnerTx`, `FeeBumpTransactionExt`, `FeeBumpTransactionEnvelope`, `TransactionEnvelope`, `TransactionSignaturePayload`, `TransactionSignaturePayloadTaggedTransaction`, `ClaimAtomType`, `ClaimOfferAtomV0`, `ClaimOfferAtom`, `ClaimLiquidityAtom`, `ClaimAtom`, `CreateAccountResultCode`, `CreateAccountResult`, `PaymentResultCode`, `PaymentResult`, `PathPaymentStrictReceiveResultCode`, `SimplePaymentResult`, `PathPaymentStrictReceiveResult`, `PathPaymentStrictReceiveResultSuccess`, `PathPaymentStrictSendResultCode`, `PathPaymentStrictSendResult`, `PathPaymentStrictSendResultSuccess`, `ManageSellOfferResultCode`, `ManageOfferEffect`, `ManageOfferSuccessResult`, `ManageOfferSuccessResultOffer`, `ManageSellOfferResult`, `ManageBuyOfferResultCode`, `ManageBuyOfferResult`, `SetOptionsResultCode`, `SetOptionsResult`, `ChangeTrustResultCode`, `ChangeTrustResult`, `AllowTrustResultCode`, `AllowTrustResult`, `AccountMergeResultCode`, `AccountMergeResult`, `InflationResultCode`, `InflationPayout`, `InflationResult`, `ManageDataResultCode`, `ManageDataResult`, `BumpSequenceResultCode`, `BumpSequenceResult`, `CreateClaimableBalanceResultCode`, `CreateClaimableBalanceResult`, `ClaimClaimableBalanceResultCode`, `ClaimClaimableBalanceResult`, `BeginSponsoringFutureReservesResultCode`, `BeginSponsoringFutureReservesResult`, `EndSponsoringFutureReservesResultCode`, `EndSponsoringFutureReservesResult`, `RevokeSponsorshipResultCode`, `RevokeSponsorshipResult`, `ClawbackResultCode`, `ClawbackResult`, `ClawbackClaimableBalanceResultCode`, `ClawbackClaimableBalanceResult`, `SetTrustLineFlagsResultCode`, `SetTrustLineFlagsResult`, `LiquidityPoolDepositResultCode`, `LiquidityPoolDepositResult`, `LiquidityPoolWithdrawResultCode`, `LiquidityPoolWithdrawResult`, `InvokeHostFunctionResultCode`, `InvokeHostFunctionResult`, `BumpFootprintExpirationResultCode`, `BumpFootprintExpirationResult`, `RestoreFootprintResultCode`, `RestoreFootprintResult`, `OperationResultCode`, `OperationResult`, `OperationResultTr`, `TransactionResultCode`, `InnerTransactionResult`, `InnerTransactionResultResult`, `InnerTransactionResultExt`, `InnerTransactionResultPair`, `TransactionResult`, `TransactionResultResult`, `TransactionResultExt`, `Hash`, `Uint256`, `Uint32`, `Int32`, `Uint64`, `Int64`, `TimePoint`, `Duration`, `ExtensionPoint`, `CryptoKeyType`, `PublicKeyType`, `SignerKeyType`, `PublicKey`, `SignerKey`, `SignerKeyEd25519SignedPayload`, `Signature`, `SignatureHint`, `NodeId`, `AccountId`, `Curve25519Secret`, `Curve25519Public`, `HmacSha256Key`, `HmacSha256Mac` + Possible values: `Value`, `ScpBallot`, `ScpStatementType`, `ScpNomination`, `ScpStatement`, `ScpStatementPledges`, `ScpStatementPrepare`, `ScpStatementConfirm`, `ScpStatementExternalize`, `ScpEnvelope`, `ScpQuorumSet`, `ConfigSettingContractExecutionLanesV0`, `ConfigSettingContractComputeV0`, `ConfigSettingContractLedgerCostV0`, `ConfigSettingContractHistoricalDataV0`, `ConfigSettingContractEventsV0`, `ConfigSettingContractBandwidthV0`, `ContractCostType`, `ContractCostParamEntry`, `StateExpirationSettings`, `ContractCostParams`, `ConfigSettingId`, `ConfigSettingEntry`, `ScEnvMetaKind`, `ScEnvMetaEntry`, `ScMetaV0`, `ScMetaKind`, `ScMetaEntry`, `ScSpecType`, `ScSpecTypeOption`, `ScSpecTypeResult`, `ScSpecTypeVec`, `ScSpecTypeMap`, `ScSpecTypeSet`, `ScSpecTypeTuple`, `ScSpecTypeBytesN`, `ScSpecTypeUdt`, `ScSpecTypeDef`, `ScSpecUdtStructFieldV0`, `ScSpecUdtStructV0`, `ScSpecUdtUnionCaseVoidV0`, `ScSpecUdtUnionCaseTupleV0`, `ScSpecUdtUnionCaseV0Kind`, `ScSpecUdtUnionCaseV0`, `ScSpecUdtUnionV0`, `ScSpecUdtEnumCaseV0`, `ScSpecUdtEnumV0`, `ScSpecUdtErrorEnumCaseV0`, `ScSpecUdtErrorEnumV0`, `ScSpecFunctionInputV0`, `ScSpecFunctionV0`, `ScSpecEntryKind`, `ScSpecEntry`, `ScValType`, `ScErrorType`, `ScErrorCode`, `ScError`, `UInt128Parts`, `Int128Parts`, `UInt256Parts`, `Int256Parts`, `ContractExecutableType`, `ContractExecutable`, `ScAddressType`, `ScAddress`, `ScVec`, `ScMap`, `ScBytes`, `ScString`, `ScSymbol`, `ScNonceKey`, `ScContractInstance`, `ScVal`, `ScMapEntry`, `StoredTransactionSet`, `PersistedScpStateV0`, `PersistedScpStateV1`, `PersistedScpState`, `Thresholds`, `String32`, `String64`, `SequenceNumber`, `DataValue`, `PoolId`, `AssetCode4`, `AssetCode12`, `AssetType`, `AssetCode`, `AlphaNum4`, `AlphaNum12`, `Asset`, `Price`, `Liabilities`, `ThresholdIndexes`, `LedgerEntryType`, `Signer`, `AccountFlags`, `SponsorshipDescriptor`, `AccountEntryExtensionV3`, `AccountEntryExtensionV2`, `AccountEntryExtensionV2Ext`, `AccountEntryExtensionV1`, `AccountEntryExtensionV1Ext`, `AccountEntry`, `AccountEntryExt`, `TrustLineFlags`, `LiquidityPoolType`, `TrustLineAsset`, `TrustLineEntryExtensionV2`, `TrustLineEntryExtensionV2Ext`, `TrustLineEntry`, `TrustLineEntryExt`, `TrustLineEntryV1`, `TrustLineEntryV1Ext`, `OfferEntryFlags`, `OfferEntry`, `OfferEntryExt`, `DataEntry`, `DataEntryExt`, `ClaimPredicateType`, `ClaimPredicate`, `ClaimantType`, `Claimant`, `ClaimantV0`, `ClaimableBalanceIdType`, `ClaimableBalanceId`, `ClaimableBalanceFlags`, `ClaimableBalanceEntryExtensionV1`, `ClaimableBalanceEntryExtensionV1Ext`, `ClaimableBalanceEntry`, `ClaimableBalanceEntryExt`, `LiquidityPoolConstantProductParameters`, `LiquidityPoolEntry`, `LiquidityPoolEntryBody`, `LiquidityPoolEntryConstantProduct`, `ContractEntryBodyType`, `ContractDataFlags`, `ContractDataDurability`, `ContractDataEntry`, `ContractDataEntryBody`, `ContractDataEntryData`, `ContractCodeEntry`, `ContractCodeEntryBody`, `LedgerEntryExtensionV1`, `LedgerEntryExtensionV1Ext`, `LedgerEntry`, `LedgerEntryData`, `LedgerEntryExt`, `LedgerKey`, `LedgerKeyAccount`, `LedgerKeyTrustLine`, `LedgerKeyOffer`, `LedgerKeyData`, `LedgerKeyClaimableBalance`, `LedgerKeyLiquidityPool`, `LedgerKeyContractData`, `LedgerKeyContractCode`, `LedgerKeyConfigSetting`, `EnvelopeType`, `UpgradeType`, `StellarValueType`, `LedgerCloseValueSignature`, `StellarValue`, `StellarValueExt`, `LedgerHeaderFlags`, `LedgerHeaderExtensionV1`, `LedgerHeaderExtensionV1Ext`, `LedgerHeader`, `LedgerHeaderExt`, `LedgerUpgradeType`, `ConfigUpgradeSetKey`, `LedgerUpgrade`, `ConfigUpgradeSet`, `BucketEntryType`, `BucketMetadata`, `BucketMetadataExt`, `BucketEntry`, `TxSetComponentType`, `TxSetComponent`, `TxSetComponentTxsMaybeDiscountedFee`, `TransactionPhase`, `TransactionSet`, `TransactionSetV1`, `GeneralizedTransactionSet`, `TransactionResultPair`, `TransactionResultSet`, `TransactionHistoryEntry`, `TransactionHistoryEntryExt`, `TransactionHistoryResultEntry`, `TransactionHistoryResultEntryExt`, `LedgerHeaderHistoryEntry`, `LedgerHeaderHistoryEntryExt`, `LedgerScpMessages`, `ScpHistoryEntryV0`, `ScpHistoryEntry`, `LedgerEntryChangeType`, `LedgerEntryChange`, `LedgerEntryChanges`, `OperationMeta`, `TransactionMetaV1`, `TransactionMetaV2`, `ContractEventType`, `ContractEvent`, `ContractEventBody`, `ContractEventV0`, `DiagnosticEvent`, `SorobanTransactionMeta`, `TransactionMetaV3`, `InvokeHostFunctionSuccessPreImage`, `TransactionMeta`, `TransactionResultMeta`, `UpgradeEntryMeta`, `LedgerCloseMetaV0`, `LedgerCloseMetaV1`, `LedgerCloseMetaV2`, `LedgerCloseMeta`, `ErrorCode`, `SError`, `SendMore`, `SendMoreExtended`, `AuthCert`, `Hello`, `Auth`, `IpAddrType`, `PeerAddress`, `PeerAddressIp`, `MessageType`, `DontHave`, `SurveyMessageCommandType`, `SurveyMessageResponseType`, `SurveyRequestMessage`, `SignedSurveyRequestMessage`, `EncryptedBody`, `SurveyResponseMessage`, `SignedSurveyResponseMessage`, `PeerStats`, `PeerStatList`, `TopologyResponseBodyV0`, `TopologyResponseBodyV1`, `SurveyResponseBody`, `TxAdvertVector`, `FloodAdvert`, `TxDemandVector`, `FloodDemand`, `StellarMessage`, `AuthenticatedMessage`, `AuthenticatedMessageV0`, `LiquidityPoolParameters`, `MuxedAccount`, `MuxedAccountMed25519`, `DecoratedSignature`, `OperationType`, `CreateAccountOp`, `PaymentOp`, `PathPaymentStrictReceiveOp`, `PathPaymentStrictSendOp`, `ManageSellOfferOp`, `ManageBuyOfferOp`, `CreatePassiveSellOfferOp`, `SetOptionsOp`, `ChangeTrustAsset`, `ChangeTrustOp`, `AllowTrustOp`, `ManageDataOp`, `BumpSequenceOp`, `CreateClaimableBalanceOp`, `ClaimClaimableBalanceOp`, `BeginSponsoringFutureReservesOp`, `RevokeSponsorshipType`, `RevokeSponsorshipOp`, `RevokeSponsorshipOpSigner`, `ClawbackOp`, `ClawbackClaimableBalanceOp`, `SetTrustLineFlagsOp`, `LiquidityPoolDepositOp`, `LiquidityPoolWithdrawOp`, `HostFunctionType`, `ContractIdPreimageType`, `ContractIdPreimage`, `ContractIdPreimageFromAddress`, `CreateContractArgs`, `InvokeContractArgs`, `HostFunction`, `SorobanAuthorizedFunctionType`, `SorobanAuthorizedFunction`, `SorobanAuthorizedInvocation`, `SorobanAddressCredentials`, `SorobanCredentialsType`, `SorobanCredentials`, `SorobanAuthorizationEntry`, `InvokeHostFunctionOp`, `BumpFootprintExpirationOp`, `RestoreFootprintOp`, `Operation`, `OperationBody`, `HashIdPreimage`, `HashIdPreimageOperationId`, `HashIdPreimageRevokeId`, `HashIdPreimageContractId`, `HashIdPreimageSorobanAuthorization`, `MemoType`, `Memo`, `TimeBounds`, `LedgerBounds`, `PreconditionsV2`, `PreconditionType`, `Preconditions`, `LedgerFootprint`, `SorobanResources`, `SorobanTransactionData`, `TransactionV0`, `TransactionV0Ext`, `TransactionV0Envelope`, `Transaction`, `TransactionExt`, `TransactionV1Envelope`, `FeeBumpTransaction`, `FeeBumpTransactionInnerTx`, `FeeBumpTransactionExt`, `FeeBumpTransactionEnvelope`, `TransactionEnvelope`, `TransactionSignaturePayload`, `TransactionSignaturePayloadTaggedTransaction`, `ClaimAtomType`, `ClaimOfferAtomV0`, `ClaimOfferAtom`, `ClaimLiquidityAtom`, `ClaimAtom`, `CreateAccountResultCode`, `CreateAccountResult`, `PaymentResultCode`, `PaymentResult`, `PathPaymentStrictReceiveResultCode`, `SimplePaymentResult`, `PathPaymentStrictReceiveResult`, `PathPaymentStrictReceiveResultSuccess`, `PathPaymentStrictSendResultCode`, `PathPaymentStrictSendResult`, `PathPaymentStrictSendResultSuccess`, `ManageSellOfferResultCode`, `ManageOfferEffect`, `ManageOfferSuccessResult`, `ManageOfferSuccessResultOffer`, `ManageSellOfferResult`, `ManageBuyOfferResultCode`, `ManageBuyOfferResult`, `SetOptionsResultCode`, `SetOptionsResult`, `ChangeTrustResultCode`, `ChangeTrustResult`, `AllowTrustResultCode`, `AllowTrustResult`, `AccountMergeResultCode`, `AccountMergeResult`, `InflationResultCode`, `InflationPayout`, `InflationResult`, `ManageDataResultCode`, `ManageDataResult`, `BumpSequenceResultCode`, `BumpSequenceResult`, `CreateClaimableBalanceResultCode`, `CreateClaimableBalanceResult`, `ClaimClaimableBalanceResultCode`, `ClaimClaimableBalanceResult`, `BeginSponsoringFutureReservesResultCode`, `BeginSponsoringFutureReservesResult`, `EndSponsoringFutureReservesResultCode`, `EndSponsoringFutureReservesResult`, `RevokeSponsorshipResultCode`, `RevokeSponsorshipResult`, `ClawbackResultCode`, `ClawbackResult`, `ClawbackClaimableBalanceResultCode`, `ClawbackClaimableBalanceResult`, `SetTrustLineFlagsResultCode`, `SetTrustLineFlagsResult`, `LiquidityPoolDepositResultCode`, `LiquidityPoolDepositResult`, `LiquidityPoolWithdrawResultCode`, `LiquidityPoolWithdrawResult`, `InvokeHostFunctionResultCode`, `InvokeHostFunctionResult`, `BumpFootprintExpirationResultCode`, `BumpFootprintExpirationResult`, `RestoreFootprintResultCode`, `RestoreFootprintResult`, `OperationResultCode`, `OperationResult`, `OperationResultTr`, `TransactionResultCode`, `InnerTransactionResult`, `InnerTransactionResultResult`, `InnerTransactionResultExt`, `InnerTransactionResultPair`, `TransactionResult`, `TransactionResultResult`, `TransactionResultExt`, `Hash`, `Uint256`, `Uint32`, `Int32`, `Uint64`, `Int64`, `TimePoint`, `Duration`, `ExtensionPoint`, `CryptoKeyType`, `PublicKeyType`, `SignerKeyType`, `PublicKey`, `SignerKey`, `SignerKeyEd25519SignedPayload`, `Signature`, `SignatureHint`, `NodeId`, `AccountId`, `Curve25519Secret`, `Curve25519Public`, `HmacSha256Key`, `HmacSha256Mac` * `--xdr ` — XDR (base64 encoded) to decode * `--output ` — Type of output diff --git a/go.mod b/go.mod index f4bf5c6bd..20fec33f2 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/sirupsen/logrus v1.4.1 github.com/spf13/cobra v0.0.0-20160830174925-9c28e4bbd74e github.com/spf13/pflag v1.0.5 - github.com/stellar/go v0.0.0-20230729101930-aa90ee32989a + github.com/stellar/go v0.0.0-20230804153331-498d556f4dd7 github.com/stretchr/testify v1.8.0 golang.org/x/mod v0.6.0 ) diff --git a/go.sum b/go.sum index 4eb982c65..8648d3593 100644 --- a/go.sum +++ b/go.sum @@ -169,8 +169,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v0.0.0-20150621231900-db7ff930a189 h1:fvB1AFbBd6SfI9Rd0ooAJp8uLkZDbZaLFHi7ZnNP6uI= github.com/spf13/viper v0.0.0-20150621231900-db7ff930a189/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/stellar/go v0.0.0-20230729101930-aa90ee32989a h1:ZSbKdLGgleFc5DaqrrJrtoAGM5RQik8GiBTpWQ5aSG0= -github.com/stellar/go v0.0.0-20230729101930-aa90ee32989a/go.mod h1:m9ABBUAExq/TfafyQrLie0owyyAR6IYCRhujttELLHU= +github.com/stellar/go v0.0.0-20230804153331-498d556f4dd7 h1:EhQ8kQko3rFE9GP8lH5/R1IDkeWyyZKTEjJ7Wiu5pz4= +github.com/stellar/go v0.0.0-20230804153331-498d556f4dd7/go.mod h1:m9ABBUAExq/TfafyQrLie0owyyAR6IYCRhujttELLHU= github.com/stellar/go-xdr v0.0.0-20211103144802-8017fc4bdfee h1:fbVs0xmXpBvVS4GBeiRmAE3Le70ofAqFMch1GTiq/e8= github.com/stellar/go-xdr v0.0.0-20211103144802-8017fc4bdfee/go.mod h1:yoxyU/M8nl9LKeWIoBrbDPQ7Cy+4jxRcWcOayZ4BMps= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=