From c24ea00bd5d8ce62445a795fda177ea5f1e808a6 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 16 Jun 2023 16:04:19 +0100 Subject: [PATCH 01/12] Simplify ScError.Equals --- xdr/scval.go | 29 +---------------------------- 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/xdr/scval.go b/xdr/scval.go index a883bb67c8..351e276085 100644 --- a/xdr/scval.go +++ b/xdr/scval.go @@ -44,34 +44,7 @@ func (s ScContractExecutable) Equals(o ScContractExecutable) bool { } func (s ScError) Equals(o ScError) bool { - if s.Type != o.Type { - return false - } - - switch s.Type { - case ScErrorTypeSceContract: - return s.Code == o.Code - case ScErrorTypeSceWasmVm: - return s.Code == o.Code - case ScErrorTypeSceContext: - return s.Code == o.Code - case ScErrorTypeSceStorage: - return s.Code == o.Code - case ScErrorTypeSceObject: - return s.Code == o.Code - case ScErrorTypeSceCrypto: - return s.Code == o.Code - case ScErrorTypeSceEvents: - return s.Code == o.Code - case ScErrorTypeSceBudget: - return s.Code == o.Code - case ScErrorTypeSceValue: - return s.Code == o.Code - case ScErrorTypeSceAuth: - return s.Code == o.Code - default: - panic("unknown ScError type: " + s.Type.String()) - } + return s.Type == o.Type && s.Code == o.Code } func (s ScVal) Equals(o ScVal) bool { From 589b907bb87df13bc811f4e685b6579e8aa154f3 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 16 Jun 2023 16:04:37 +0100 Subject: [PATCH 02/12] Add missing case for ScVal.Equals --- xdr/scval.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xdr/scval.go b/xdr/scval.go index 351e276085..ce39e3fa55 100644 --- a/xdr/scval.go +++ b/xdr/scval.go @@ -97,6 +97,8 @@ func (s ScVal) Equals(o ScVal) bool { return true case ScValTypeScvLedgerKeyNonce: return s.MustNonceKey().Equals(o.MustNonceKey()) + case ScValTypeScvStorageType: + return s.MustStorageType() == o.MustStorageType() default: panic("unknown ScVal type: " + s.Type.String()) } From bae26674c6f8ec3b474de5a09b088747fcf1d999 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 16 Jun 2023 16:05:21 +0100 Subject: [PATCH 03/12] Add LedgerEntry.SetContractData and LedgerEntry.SetContractCode methods --- xdr/ledger_entry.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/xdr/ledger_entry.go b/xdr/ledger_entry.go index 89d837da86..d039635c20 100644 --- a/xdr/ledger_entry.go +++ b/xdr/ledger_entry.go @@ -174,3 +174,19 @@ func (entry *LedgerEntry) Normalize() *LedgerEntry { return entry } + +func (data *LedgerEntryData) SetContractData(entry *ContractDataEntry) error { + *data = LedgerEntryData{ + Type: LedgerEntryTypeContractData, + ContractData: entry, + } + return nil +} + +func (data *LedgerEntryData) SetContractCode(entry *ContractCodeEntry) error { + *data = LedgerEntryData{ + Type: LedgerEntryTypeContractCode, + ContractCode: entry, + } + return nil +} From ea554ca1edb25c0d977242607787a04d13e188b5 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 16 Jun 2023 16:23:30 +0100 Subject: [PATCH 04/12] update generated xdr to 0f5e556 --- Makefile | 2 +- xdr/Stellar-contract-config-setting.x | 49 ++++++++++++++++++++-- xdr/Stellar-contract.x | 14 ++++++- xdr/Stellar-ledger-entries.x | 42 ++++++++++++++++++- xdr/Stellar-ledger.x | 59 +++++++++++++++++++++++---- xdr/Stellar-transaction.x | 2 +- xdr/xdr_commit_generated.txt | 2 +- 7 files changed, 153 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index 3c01e78210..64b1737add 100644 --- a/Makefile +++ b/Makefile @@ -15,7 +15,7 @@ xdr/Stellar-internal.x \ xdr/Stellar-contract-config-setting.x XDRGEN_COMMIT=80e38ef2a96489f6b501d4db3a350406e5aa3bab -XDRNEXT_COMMIT=de264d81ea87dfaa19e089b60fed8eb0219b2ab4 +XDRNEXT_COMMIT=0f5e556bb8778a2da8930bc81d0ed21f08c14b80 .PHONY: xdr xdr-clean xdr-update diff --git a/xdr/Stellar-contract-config-setting.x b/xdr/Stellar-contract-config-setting.x index 04e28d2135..dfb5ef5b03 100644 --- a/xdr/Stellar-contract-config-setting.x +++ b/xdr/Stellar-contract-config-setting.x @@ -1,6 +1,13 @@ %#include "xdr/Stellar-types.h" namespace stellar { +// General “Soroban execution lane” settings +struct ConfigSettingContractExecutionLanesV0 +{ + // maximum number of Soroban transactions per ledger + uint32 ledgerMaxTxCount; +}; + // "Compute" settings for contracts (instructions and memory). struct ConfigSettingContractComputeV0 { @@ -125,14 +132,42 @@ enum ContractCostType { // Roundtrip cost of invoking a VM function from the host. InvokeVmFunction = 19, // Cost of charging a value to the budgeting system. - ChargeBudget = 20 + ChargeBudget = 20, + // Cost of computing a keccak256 hash from bytes. + ComputeKeccak256Hash = 21, + // Cost of computing an ECDSA secp256k1 pubkey from bytes. + ComputeEcdsaSecp256k1Key = 22, + // Cost of computing an ECDSA secp256k1 signature from bytes. + ComputeEcdsaSecp256k1Sig = 23, + // Cost of verifying an ECDSA secp256k1 signature. + VerifyEcdsaSecp256k1Sig = 24, + // Cost of recovering an ECDSA secp256k1 key from a signature. + RecoverEcdsaSecp256k1Key = 25 }; struct ContractCostParamEntry { - int64 constTerm; - int64 linearTerm; // use `ext` to add more terms (e.g. higher order polynomials) in the future ExtensionPoint ext; + + int64 constTerm; + int64 linearTerm; +}; + +struct StateExpirationSettings { + uint32 maxEntryExpiration; + uint32 minTempEntryExpiration; + uint32 minRestorableEntryExpiration; + uint32 autoBumpLedgers; + + // rent_fee = wfee_rate_average / rent_rate_denominator_for_type + int64 restorableRentRateDenominator; + int64 tempRentRateDenominator; + + union switch (int v) + { + case 0: + void; + } ext; }; // limits the ContractCostParams size to 20kB @@ -152,7 +187,9 @@ enum ConfigSettingID CONFIG_SETTING_CONTRACT_COST_PARAMS_CPU_INSTRUCTIONS = 6, CONFIG_SETTING_CONTRACT_COST_PARAMS_MEMORY_BYTES = 7, CONFIG_SETTING_CONTRACT_DATA_KEY_SIZE_BYTES = 8, - CONFIG_SETTING_CONTRACT_DATA_ENTRY_SIZE_BYTES = 9 + CONFIG_SETTING_CONTRACT_DATA_ENTRY_SIZE_BYTES = 9, + CONFIG_SETTING_STATE_EXPIRATION = 10, + CONFIG_SETTING_CONTRACT_EXECUTION_LANES = 11 }; union ConfigSettingEntry switch (ConfigSettingID configSettingID) @@ -177,5 +214,9 @@ case CONFIG_SETTING_CONTRACT_DATA_KEY_SIZE_BYTES: uint32 contractDataKeySizeBytes; case CONFIG_SETTING_CONTRACT_DATA_ENTRY_SIZE_BYTES: uint32 contractDataEntrySizeBytes; +case CONFIG_SETTING_STATE_EXPIRATION: + StateExpirationSettings stateExpirationSettings; +case CONFIG_SETTING_CONTRACT_EXECUTION_LANES: + ConfigSettingContractExecutionLanesV0 contractExecutionLanes; }; } \ No newline at end of file diff --git a/xdr/Stellar-contract.x b/xdr/Stellar-contract.x index 54a03643ce..a8353acb44 100644 --- a/xdr/Stellar-contract.x +++ b/xdr/Stellar-contract.x @@ -68,7 +68,9 @@ enum SCValType // symbolic SCVals used as the key for ledger entries for a contract's code // and an address' nonce, respectively. SCV_LEDGER_KEY_CONTRACT_EXECUTABLE = 20, - SCV_LEDGER_KEY_NONCE = 21 + SCV_LEDGER_KEY_NONCE = 21, + + SCV_STORAGE_TYPE = 22 }; enum SCErrorType @@ -165,6 +167,13 @@ case SC_ADDRESS_TYPE_CONTRACT: Hash contractId; }; +// Here due to circular dependency +enum ContractDataType { + TEMPORARY = 0, + MERGEABLE = 1, + EXCLUSIVE = 2 +}; + %struct SCVal; %struct SCMapEntry; @@ -240,6 +249,9 @@ case SCV_LEDGER_KEY_CONTRACT_EXECUTABLE: void; case SCV_LEDGER_KEY_NONCE: SCNonceKey nonce_key; + +case SCV_STORAGE_TYPE: + ContractDataType storageType; }; struct SCMapEntry diff --git a/xdr/Stellar-ledger-entries.x b/xdr/Stellar-ledger-entries.x index dea2c69d27..fb781ab46a 100644 --- a/xdr/Stellar-ledger-entries.x +++ b/xdr/Stellar-ledger-entries.x @@ -493,17 +493,52 @@ struct LiquidityPoolEntry body; }; +enum ContractLedgerEntryType { + DATA_ENTRY = 0, + EXPIRATION_EXTENSION = 1 +}; + +const MASK_CONTRACT_DATA_FLAGS_V20 = 0x1; + +enum ContractDataFlags { + // When set, the given entry does not recieve automatic expiration bumps + // on access. Note that entries can still be bumped manually via the footprint. + NO_AUTOBUMP = 0x1 +}; + struct ContractDataEntry { Hash contractID; SCVal key; - SCVal val; + ContractDataType type; + + union switch (ContractLedgerEntryType leType) + { + case DATA_ENTRY: + struct + { + uint32 flags; + SCVal val; + } data; + case EXPIRATION_EXTENSION: + void; + } body; + + uint32 expirationLedgerSeq; }; struct ContractCodeEntry { ExtensionPoint ext; Hash hash; - opaque code<>; + union switch (ContractLedgerEntryType leType) + { + case DATA_ENTRY: + opaque code<>; + case EXPIRATION_EXTENSION: + void; + } body; + + uint32 expirationLedgerSeq; }; @@ -602,11 +637,14 @@ case CONTRACT_DATA: { Hash contractID; SCVal key; + ContractDataType type; + ContractLedgerEntryType leType; } contractData; case CONTRACT_CODE: struct { Hash hash; + ContractLedgerEntryType leType; } contractCode; case CONFIG_SETTING: struct diff --git a/xdr/Stellar-ledger.x b/xdr/Stellar-ledger.x index 7b0e04a463..38532677e6 100644 --- a/xdr/Stellar-ledger.x +++ b/xdr/Stellar-ledger.x @@ -398,16 +398,13 @@ struct DiagnosticEvent ContractEvent event; }; -struct TransactionMetaV3 +struct SorobanTransactionMeta { - LedgerEntryChanges txChangesBefore; // tx level changes before operations - // are applied if any - OperationMeta operations<>; // meta for each operation - LedgerEntryChanges txChangesAfter; // tx level changes after operations are - // applied if any + ExtensionPoint ext; + ContractEvent events<>; // custom events populated by the // contracts themselves. - SCVal returnValue; // return value of the invocation. + SCVal returnValue; // return value of the host fn invocation // Diagnostics events that are not hashed. // This will contain all contract and diagnostic events. Even ones @@ -415,6 +412,19 @@ struct TransactionMetaV3 DiagnosticEvent diagnosticEvents<>; }; +struct TransactionMetaV3 +{ + ExtensionPoint ext; + + LedgerEntryChanges txChangesBefore; // tx level changes before operations + // are applied if any + OperationMeta operations<>; // meta for each operation + LedgerEntryChanges txChangesAfter; // tx level changes after operations are + // applied if any + SorobanTransactionMeta* sorobanMeta; // Soroban-specific meta (only for + // Soroban transactions). +}; + // This is in Stellar-ledger.x to due to a circular dependency struct InvokeHostFunctionSuccessPreImage { @@ -490,11 +500,46 @@ struct LedgerCloseMetaV1 SCPHistoryEntry scpInfo<>; }; +struct LedgerCloseMetaV2 +{ + // We forgot to add an ExtensionPoint in v1 but at least + // we can add one now in v2. + ExtensionPoint ext; + + LedgerHeaderHistoryEntry ledgerHeader; + + GeneralizedTransactionSet txSet; + + // NB: transactions are sorted in apply order here + // fees for all transactions are processed first + // followed by applying transactions + TransactionResultMeta txProcessing<>; + + // upgrades are applied last + UpgradeEntryMeta upgradesProcessing<>; + + // other misc information attached to the ledger close + SCPHistoryEntry scpInfo<>; + + // Size in bytes of BucketList, to support downstream + // systems calculating storage fees correctly. + uint64 totalByteSizeOfBucketList; + + // Expired temp keys that are being evicted at this ledger. + LedgerKey evictedTemporaryLedgerKeys<>; + + // Expired restorable ledger entries that are being + // evicted at this ledger. + LedgerEntry evictedRestorableLedgerEntries<>; +}; + union LedgerCloseMeta switch (int v) { case 0: LedgerCloseMetaV0 v0; case 1: LedgerCloseMetaV1 v1; +case 2: + LedgerCloseMetaV2 v2; }; } diff --git a/xdr/Stellar-transaction.x b/xdr/Stellar-transaction.x index 0a571b502e..d084585c37 100644 --- a/xdr/Stellar-transaction.x +++ b/xdr/Stellar-transaction.x @@ -789,10 +789,10 @@ struct SorobanResources // The transaction extension for Soroban. struct SorobanTransactionData { + ExtensionPoint ext; SorobanResources resources; // Portion of transaction `fee` allocated to refundable fees. int64 refundableFee; - ExtensionPoint ext; }; // TransactionV0 is a transaction with the AccountID discriminant stripped off, diff --git a/xdr/xdr_commit_generated.txt b/xdr/xdr_commit_generated.txt index 8b756e2890..121ff8e575 100644 --- a/xdr/xdr_commit_generated.txt +++ b/xdr/xdr_commit_generated.txt @@ -1 +1 @@ -de264d81ea87dfaa19e089b60fed8eb0219b2ab4 \ No newline at end of file +0f5e556bb8778a2da8930bc81d0ed21f08c14b80 \ No newline at end of file From f3cb530aeffc5ac0856093a96a4a06cf7a9f6b03 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 16 Jun 2023 16:22:50 +0100 Subject: [PATCH 05/12] Add LedgerCloseMetaV2 support --- xdr/ledger_close_meta.go | 45 +- xdr/ledger_entry.go | 4 +- xdr/xdr_generated.go | 2125 +++++++++++++++++++++++++++++++++----- 3 files changed, 1888 insertions(+), 286 deletions(-) diff --git a/xdr/ledger_close_meta.go b/xdr/ledger_close_meta.go index ee59848060..100a4d22a1 100644 --- a/xdr/ledger_close_meta.go +++ b/xdr/ledger_close_meta.go @@ -8,6 +8,8 @@ func (l LedgerCloseMeta) LedgerHeaderHistoryEntry() LedgerHeaderHistoryEntry { return l.MustV0().LedgerHeader case 1: return l.MustV1().LedgerHeader + case 2: + return l.MustV2().LedgerHeader default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) } @@ -39,6 +41,8 @@ func (l LedgerCloseMeta) CountTransactions() int { return len(l.MustV0().TxProcessing) case 1: return len(l.MustV1().TxProcessing) + case 2: + return len(l.MustV2().TxProcessing) default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) } @@ -48,10 +52,14 @@ func (l LedgerCloseMeta) TransactionEnvelopes() []TransactionEnvelope { switch l.V { case 0: return l.MustV0().TxSet.Txs - case 1: + case 1, 2: var envelopes = make([]TransactionEnvelope, 0, l.CountTransactions()) var phases []TransactionPhase - phases = l.MustV1().TxSet.V1TxSet.Phases + if l.V == 1 { + phases = l.MustV1().TxSet.V1TxSet.Phases + } else { + phases = l.MustV2().TxSet.V1TxSet.Phases + } for _, phase := range phases { for _, component := range *phase.V0Components { envelopes = append(envelopes, component.TxsMaybeDiscountedFee.Txs...) @@ -70,6 +78,8 @@ func (l LedgerCloseMeta) TransactionHash(i int) Hash { return l.MustV0().TxProcessing[i].Result.TransactionHash case 1: return l.MustV1().TxProcessing[i].Result.TransactionHash + case 2: + return l.MustV2().TxProcessing[i].Result.TransactionHash default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) } @@ -82,6 +92,11 @@ func (l LedgerCloseMeta) TransactionResultPair(i int) TransactionResultPair { return l.MustV0().TxProcessing[i].Result case 1: return l.MustV1().TxProcessing[i].Result + case 2: + if l.MustV2().TxProcessing[i].TxApplyProcessing.V != 3 { + panic("TransactionResult unavailable because LedgerCloseMeta.V = 2 and TransactionMeta.V != 3") + } + return l.MustV2().TxProcessing[i].Result default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) } @@ -94,6 +109,8 @@ func (l LedgerCloseMeta) FeeProcessing(i int) LedgerEntryChanges { return l.MustV0().TxProcessing[i].FeeProcessing case 1: return l.MustV1().TxProcessing[i].FeeProcessing + case 2: + return l.MustV2().TxProcessing[i].FeeProcessing default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) } @@ -106,6 +123,8 @@ func (l LedgerCloseMeta) TxApplyProcessing(i int) TransactionMeta { return l.MustV0().TxProcessing[i].TxApplyProcessing case 1: return l.MustV1().TxProcessing[i].TxApplyProcessing + case 2: + return l.MustV2().TxProcessing[i].TxApplyProcessing default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) } @@ -118,6 +137,28 @@ func (l LedgerCloseMeta) UpgradesProcessing() []UpgradeEntryMeta { return l.MustV0().UpgradesProcessing case 1: return l.MustV1().UpgradesProcessing + case 2: + return l.MustV2().UpgradesProcessing + default: + panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) + } +} + +// EvictedTemporaryLedgerKeys []LedgerKey +// EvictedRestorableLedgerEntries []LedgerEntry +// EvictedLedgerKeys returns the LedgerKeys for the EvictedTemporaryLedgerKeys +// and EvictedRestorableLedgerEntrues for ledger. +func (l LedgerCloseMeta) EvictedLedgerKeys() []LedgerKey { + switch l.V { + case 0, 1: + return nil + case 2: + var keys []LedgerKey + keys = append(keys, l.MustV2().EvictedTemporaryLedgerKeys...) + for _, entry := range l.MustV2().EvictedRestorableLedgerEntries { + keys = append(keys, entry.LedgerKey()) + } + return keys default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) } diff --git a/xdr/ledger_entry.go b/xdr/ledger_entry.go index d039635c20..5072b75c47 100644 --- a/xdr/ledger_entry.go +++ b/xdr/ledger_entry.go @@ -1,6 +1,8 @@ package xdr -import "fmt" +import ( + "fmt" +) // LedgerKey implements the `Keyer` interface func (entry *LedgerEntry) LedgerKey() LedgerKey { diff --git a/xdr/xdr_generated.go b/xdr/xdr_generated.go index 8455bbf863..9479a39aed 100644 --- a/xdr/xdr_generated.go +++ b/xdr/xdr_generated.go @@ -31,16 +31,16 @@ import ( // XdrFilesSHA256 is the SHA256 hashes of source files. var XdrFilesSHA256 = map[string]string{ "xdr/Stellar-SCP.x": "8f32b04d008f8bc33b8843d075e69837231a673691ee41d8b821ca229a6e802a", - "xdr/Stellar-contract-config-setting.x": "45dc460924dae4c150567c215b43f21977618b48e6667edd814da2c05dd05a7e", + "xdr/Stellar-contract-config-setting.x": "d653b5434b79b82ccf6252c2a9cfeef3c8c13537d59e9e0baa3c31a7524a5ef3", "xdr/Stellar-contract-env-meta.x": "928a30de814ee589bc1d2aadd8dd81c39f71b7e6f430f56974505ccb1f49654b", "xdr/Stellar-contract-meta.x": "f01532c11ca044e19d9f9f16fe373e9af64835da473be556b9a807ee3319ae0d", "xdr/Stellar-contract-spec.x": "739e2480ba197aa859f122632a93172668cb0dbe93e30a54c192b96878af207a", - "xdr/Stellar-contract.x": "697a478d4917ce3cb6f2f26a87a3705e63d71a8194eaae5129ba5ae75bc4196b", + "xdr/Stellar-contract.x": "71c38a756f77215c01b0b48e8e8c0a1ad6fc6a7ae4e69eb09f7084e9c39c34f6", "xdr/Stellar-internal.x": "368706dd6e2efafd16a8f63daf3374845b791d097b15c502aa7653a412b68b68", - "xdr/Stellar-ledger-entries.x": "bc33d9275d9a2282b5db14b5748aec0ce46d19bc951aa8ffed33c5ff3a7fd635", - "xdr/Stellar-ledger.x": "0c2b074a68fa9de41b72ba1574825e7ed172e4736ca29fa6f0c88eb70579b682", + "xdr/Stellar-ledger-entries.x": "5da753824fd0f3ca01499f54ded9736bc6991bd3e152fffb8299c4f04a959ee9", + "xdr/Stellar-ledger.x": "ac8c016a92e75e6ba29cccb00a3aa633f347ba15e5b4fcd0d6986d4eed52fe4e", "xdr/Stellar-overlay.x": "de3957c58b96ae07968b3d3aebea84f83603e95322d1fa336360e13e3aba737a", - "xdr/Stellar-transaction.x": "6b56f47d1c6aaad860e199a7a9f46d3083921937af2fb4028c08efdcf70edaef", + "xdr/Stellar-transaction.x": "fccdf397df717d4acc1601ff04fd5d8ccc1defabef931ebbd2f5e41e21539f65", "xdr/Stellar-types.x": "6e3b13f0d3e360b09fa5e2b0e55d43f4d974a769df66afb34e8aecbb329d3f15", } @@ -7480,17 +7480,422 @@ func (s LiquidityPoolEntry) xdrType() {} var _ xdrType = (*LiquidityPoolEntry)(nil) +// ContractLedgerEntryType is an XDR Enum defines as: +// +// enum ContractLedgerEntryType { +// DATA_ENTRY = 0, +// EXPIRATION_EXTENSION = 1 +// }; +type ContractLedgerEntryType int32 + +const ( + ContractLedgerEntryTypeDataEntry ContractLedgerEntryType = 0 + ContractLedgerEntryTypeExpirationExtension ContractLedgerEntryType = 1 +) + +var contractLedgerEntryTypeMap = map[int32]string{ + 0: "ContractLedgerEntryTypeDataEntry", + 1: "ContractLedgerEntryTypeExpirationExtension", +} + +// ValidEnum validates a proposed value for this enum. Implements +// the Enum interface for ContractLedgerEntryType +func (e ContractLedgerEntryType) ValidEnum(v int32) bool { + _, ok := contractLedgerEntryTypeMap[v] + return ok +} + +// String returns the name of `e` +func (e ContractLedgerEntryType) String() string { + name, _ := contractLedgerEntryTypeMap[int32(e)] + return name +} + +// EncodeTo encodes this value using the Encoder. +func (e ContractLedgerEntryType) EncodeTo(enc *xdr.Encoder) error { + if _, ok := contractLedgerEntryTypeMap[int32(e)]; !ok { + return fmt.Errorf("'%d' is not a valid ContractLedgerEntryType enum value", e) + } + _, err := enc.EncodeInt(int32(e)) + return err +} + +var _ decoderFrom = (*ContractLedgerEntryType)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (e *ContractLedgerEntryType) DecodeFrom(d *xdr.Decoder) (int, error) { + v, n, err := d.DecodeInt() + if err != nil { + return n, fmt.Errorf("decoding ContractLedgerEntryType: %s", err) + } + if _, ok := contractLedgerEntryTypeMap[v]; !ok { + return n, fmt.Errorf("'%d' is not a valid ContractLedgerEntryType enum value", v) + } + *e = ContractLedgerEntryType(v) + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s ContractLedgerEntryType) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *ContractLedgerEntryType) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*ContractLedgerEntryType)(nil) + _ encoding.BinaryUnmarshaler = (*ContractLedgerEntryType)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s ContractLedgerEntryType) xdrType() {} + +var _ xdrType = (*ContractLedgerEntryType)(nil) + +// MaskContractDataFlagsV20 is an XDR Const defines as: +// +// const MASK_CONTRACT_DATA_FLAGS_V20 = 0x1; +const MaskContractDataFlagsV20 = 0x1 + +// ContractDataFlags is an XDR Enum defines as: +// +// enum ContractDataFlags { +// // When set, the given entry does not recieve automatic expiration bumps +// // on access. Note that entries can still be bumped manually via the footprint. +// NO_AUTOBUMP = 0x1 +// }; +type ContractDataFlags int32 + +const ( + ContractDataFlagsNoAutobump ContractDataFlags = 1 +) + +var contractDataFlagsMap = map[int32]string{ + 1: "ContractDataFlagsNoAutobump", +} + +// ValidEnum validates a proposed value for this enum. Implements +// the Enum interface for ContractDataFlags +func (e ContractDataFlags) ValidEnum(v int32) bool { + _, ok := contractDataFlagsMap[v] + return ok +} + +// String returns the name of `e` +func (e ContractDataFlags) String() string { + name, _ := contractDataFlagsMap[int32(e)] + return name +} + +// EncodeTo encodes this value using the Encoder. +func (e ContractDataFlags) EncodeTo(enc *xdr.Encoder) error { + if _, ok := contractDataFlagsMap[int32(e)]; !ok { + return fmt.Errorf("'%d' is not a valid ContractDataFlags enum value", e) + } + _, err := enc.EncodeInt(int32(e)) + return err +} + +var _ decoderFrom = (*ContractDataFlags)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (e *ContractDataFlags) DecodeFrom(d *xdr.Decoder) (int, error) { + v, n, err := d.DecodeInt() + if err != nil { + return n, fmt.Errorf("decoding ContractDataFlags: %s", err) + } + if _, ok := contractDataFlagsMap[v]; !ok { + return n, fmt.Errorf("'%d' is not a valid ContractDataFlags enum value", v) + } + *e = ContractDataFlags(v) + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s ContractDataFlags) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *ContractDataFlags) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*ContractDataFlags)(nil) + _ encoding.BinaryUnmarshaler = (*ContractDataFlags)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s ContractDataFlags) xdrType() {} + +var _ xdrType = (*ContractDataFlags)(nil) + +// ContractDataEntryData is an XDR NestedStruct defines as: +// +// struct +// { +// uint32 flags; +// SCVal val; +// } +type ContractDataEntryData struct { + Flags Uint32 + Val ScVal +} + +// EncodeTo encodes this value using the Encoder. +func (s *ContractDataEntryData) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.Flags.EncodeTo(e); err != nil { + return err + } + if err = s.Val.EncodeTo(e); err != nil { + return err + } + return nil +} + +var _ decoderFrom = (*ContractDataEntryData)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *ContractDataEntryData) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + nTmp, err = s.Flags.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint32: %s", err) + } + nTmp, err = s.Val.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ScVal: %s", err) + } + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s ContractDataEntryData) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *ContractDataEntryData) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*ContractDataEntryData)(nil) + _ encoding.BinaryUnmarshaler = (*ContractDataEntryData)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s ContractDataEntryData) xdrType() {} + +var _ xdrType = (*ContractDataEntryData)(nil) + +// ContractDataEntryBody is an XDR NestedUnion defines as: +// +// union switch (ContractLedgerEntryType leType) +// { +// case DATA_ENTRY: +// struct +// { +// uint32 flags; +// SCVal val; +// } data; +// case EXPIRATION_EXTENSION: +// void; +// } +type ContractDataEntryBody struct { + LeType ContractLedgerEntryType + Data *ContractDataEntryData +} + +// SwitchFieldName returns the field name in which this union's +// discriminant is stored +func (u ContractDataEntryBody) SwitchFieldName() string { + return "LeType" +} + +// ArmForSwitch returns which field name should be used for storing +// the value for an instance of ContractDataEntryBody +func (u ContractDataEntryBody) ArmForSwitch(sw int32) (string, bool) { + switch ContractLedgerEntryType(sw) { + case ContractLedgerEntryTypeDataEntry: + return "Data", true + case ContractLedgerEntryTypeExpirationExtension: + return "", true + } + return "-", false +} + +// NewContractDataEntryBody creates a new ContractDataEntryBody. +func NewContractDataEntryBody(leType ContractLedgerEntryType, value interface{}) (result ContractDataEntryBody, err error) { + result.LeType = leType + switch ContractLedgerEntryType(leType) { + case ContractLedgerEntryTypeDataEntry: + tv, ok := value.(ContractDataEntryData) + if !ok { + err = fmt.Errorf("invalid value, must be ContractDataEntryData") + return + } + result.Data = &tv + case ContractLedgerEntryTypeExpirationExtension: + // void + } + return +} + +// MustData retrieves the Data value from the union, +// panicing if the value is not set. +func (u ContractDataEntryBody) MustData() ContractDataEntryData { + val, ok := u.GetData() + + if !ok { + panic("arm Data is not set") + } + + return val +} + +// GetData retrieves the Data value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u ContractDataEntryBody) GetData() (result ContractDataEntryData, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.LeType)) + + if armName == "Data" { + result = *u.Data + ok = true + } + + return +} + +// EncodeTo encodes this value using the Encoder. +func (u ContractDataEntryBody) EncodeTo(e *xdr.Encoder) error { + var err error + if err = u.LeType.EncodeTo(e); err != nil { + return err + } + switch ContractLedgerEntryType(u.LeType) { + case ContractLedgerEntryTypeDataEntry: + if err = (*u.Data).EncodeTo(e); err != nil { + return err + } + return nil + case ContractLedgerEntryTypeExpirationExtension: + // Void + return nil + } + return fmt.Errorf("LeType (ContractLedgerEntryType) switch value '%d' is not valid for union ContractDataEntryBody", u.LeType) +} + +var _ decoderFrom = (*ContractDataEntryBody)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (u *ContractDataEntryBody) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + nTmp, err = u.LeType.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractLedgerEntryType: %s", err) + } + switch ContractLedgerEntryType(u.LeType) { + case ContractLedgerEntryTypeDataEntry: + u.Data = new(ContractDataEntryData) + nTmp, err = (*u.Data).DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractDataEntryData: %s", err) + } + return n, nil + case ContractLedgerEntryTypeExpirationExtension: + // Void + return n, nil + } + return n, fmt.Errorf("union ContractDataEntryBody has invalid LeType (ContractLedgerEntryType) switch value '%d'", u.LeType) +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s ContractDataEntryBody) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *ContractDataEntryBody) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*ContractDataEntryBody)(nil) + _ encoding.BinaryUnmarshaler = (*ContractDataEntryBody)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s ContractDataEntryBody) xdrType() {} + +var _ xdrType = (*ContractDataEntryBody)(nil) + // ContractDataEntry is an XDR Struct defines as: // // struct ContractDataEntry { // Hash contractID; // SCVal key; -// SCVal val; +// ContractDataType type; +// +// union switch (ContractLedgerEntryType leType) +// { +// case DATA_ENTRY: +// struct +// { +// uint32 flags; +// SCVal val; +// } data; +// case EXPIRATION_EXTENSION: +// void; +// } body; +// +// uint32 expirationLedgerSeq; // }; type ContractDataEntry struct { - ContractId Hash - Key ScVal - Val ScVal + ContractId Hash + Key ScVal + Type ContractDataType + Body ContractDataEntryBody + ExpirationLedgerSeq Uint32 } // EncodeTo encodes this value using the Encoder. @@ -7502,7 +7907,13 @@ func (s *ContractDataEntry) EncodeTo(e *xdr.Encoder) error { if err = s.Key.EncodeTo(e); err != nil { return err } - if err = s.Val.EncodeTo(e); err != nil { + if err = s.Type.EncodeTo(e); err != nil { + return err + } + if err = s.Body.EncodeTo(e); err != nil { + return err + } + if err = s.ExpirationLedgerSeq.EncodeTo(e); err != nil { return err } return nil @@ -7524,10 +7935,20 @@ func (s *ContractDataEntry) DecodeFrom(d *xdr.Decoder) (int, error) { if err != nil { return n, fmt.Errorf("decoding ScVal: %s", err) } - nTmp, err = s.Val.DecodeFrom(d) + nTmp, err = s.Type.DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding ScVal: %s", err) + return n, fmt.Errorf("decoding ContractDataType: %s", err) + } + nTmp, err = s.Body.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractDataEntryBody: %s", err) + } + nTmp, err = s.ExpirationLedgerSeq.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint32: %s", err) } return n, nil } @@ -7559,18 +7980,174 @@ func (s ContractDataEntry) xdrType() {} var _ xdrType = (*ContractDataEntry)(nil) +// ContractCodeEntryBody is an XDR NestedUnion defines as: +// +// union switch (ContractLedgerEntryType leType) +// { +// case DATA_ENTRY: +// opaque code<>; +// case EXPIRATION_EXTENSION: +// void; +// } +type ContractCodeEntryBody struct { + LeType ContractLedgerEntryType + Code *[]byte +} + +// SwitchFieldName returns the field name in which this union's +// discriminant is stored +func (u ContractCodeEntryBody) SwitchFieldName() string { + return "LeType" +} + +// ArmForSwitch returns which field name should be used for storing +// the value for an instance of ContractCodeEntryBody +func (u ContractCodeEntryBody) ArmForSwitch(sw int32) (string, bool) { + switch ContractLedgerEntryType(sw) { + case ContractLedgerEntryTypeDataEntry: + return "Code", true + case ContractLedgerEntryTypeExpirationExtension: + return "", true + } + return "-", false +} + +// NewContractCodeEntryBody creates a new ContractCodeEntryBody. +func NewContractCodeEntryBody(leType ContractLedgerEntryType, value interface{}) (result ContractCodeEntryBody, err error) { + result.LeType = leType + switch ContractLedgerEntryType(leType) { + case ContractLedgerEntryTypeDataEntry: + tv, ok := value.([]byte) + if !ok { + err = fmt.Errorf("invalid value, must be []byte") + return + } + result.Code = &tv + case ContractLedgerEntryTypeExpirationExtension: + // void + } + return +} + +// MustCode retrieves the Code value from the union, +// panicing if the value is not set. +func (u ContractCodeEntryBody) MustCode() []byte { + val, ok := u.GetCode() + + if !ok { + panic("arm Code is not set") + } + + return val +} + +// GetCode retrieves the Code value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u ContractCodeEntryBody) GetCode() (result []byte, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.LeType)) + + if armName == "Code" { + result = *u.Code + ok = true + } + + return +} + +// EncodeTo encodes this value using the Encoder. +func (u ContractCodeEntryBody) EncodeTo(e *xdr.Encoder) error { + var err error + if err = u.LeType.EncodeTo(e); err != nil { + return err + } + switch ContractLedgerEntryType(u.LeType) { + case ContractLedgerEntryTypeDataEntry: + if _, err = e.EncodeOpaque((*u.Code)[:]); err != nil { + return err + } + return nil + case ContractLedgerEntryTypeExpirationExtension: + // Void + return nil + } + return fmt.Errorf("LeType (ContractLedgerEntryType) switch value '%d' is not valid for union ContractCodeEntryBody", u.LeType) +} + +var _ decoderFrom = (*ContractCodeEntryBody)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (u *ContractCodeEntryBody) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + nTmp, err = u.LeType.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractLedgerEntryType: %s", err) + } + switch ContractLedgerEntryType(u.LeType) { + case ContractLedgerEntryTypeDataEntry: + u.Code = new([]byte) + (*u.Code), nTmp, err = d.DecodeOpaque(0) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Code: %s", err) + } + return n, nil + case ContractLedgerEntryTypeExpirationExtension: + // Void + return n, nil + } + return n, fmt.Errorf("union ContractCodeEntryBody has invalid LeType (ContractLedgerEntryType) switch value '%d'", u.LeType) +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s ContractCodeEntryBody) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *ContractCodeEntryBody) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*ContractCodeEntryBody)(nil) + _ encoding.BinaryUnmarshaler = (*ContractCodeEntryBody)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s ContractCodeEntryBody) xdrType() {} + +var _ xdrType = (*ContractCodeEntryBody)(nil) + // ContractCodeEntry is an XDR Struct defines as: // // struct ContractCodeEntry { // ExtensionPoint ext; // // Hash hash; -// opaque code<>; +// union switch (ContractLedgerEntryType leType) +// { +// case DATA_ENTRY: +// opaque code<>; +// case EXPIRATION_EXTENSION: +// void; +// } body; +// +// uint32 expirationLedgerSeq; // }; type ContractCodeEntry struct { - Ext ExtensionPoint - Hash Hash - Code []byte + Ext ExtensionPoint + Hash Hash + Body ContractCodeEntryBody + ExpirationLedgerSeq Uint32 } // EncodeTo encodes this value using the Encoder. @@ -7582,7 +8159,10 @@ func (s *ContractCodeEntry) EncodeTo(e *xdr.Encoder) error { if err = s.Hash.EncodeTo(e); err != nil { return err } - if _, err = e.EncodeOpaque(s.Code[:]); err != nil { + if err = s.Body.EncodeTo(e); err != nil { + return err + } + if err = s.ExpirationLedgerSeq.EncodeTo(e); err != nil { return err } return nil @@ -7604,10 +8184,15 @@ func (s *ContractCodeEntry) DecodeFrom(d *xdr.Decoder) (int, error) { if err != nil { return n, fmt.Errorf("decoding Hash: %s", err) } - s.Code, nTmp, err = d.DecodeOpaque(0) + nTmp, err = s.Body.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractCodeEntryBody: %s", err) + } + nTmp, err = s.ExpirationLedgerSeq.DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding Code: %s", err) + return n, fmt.Errorf("decoding Uint32: %s", err) } return n, nil } @@ -9016,10 +9601,14 @@ var _ xdrType = (*LedgerKeyLiquidityPool)(nil) // { // Hash contractID; // SCVal key; +// ContractDataType type; +// ContractLedgerEntryType leType; // } type LedgerKeyContractData struct { ContractId Hash Key ScVal + Type ContractDataType + LeType ContractLedgerEntryType } // EncodeTo encodes this value using the Encoder. @@ -9031,6 +9620,12 @@ func (s *LedgerKeyContractData) EncodeTo(e *xdr.Encoder) error { if err = s.Key.EncodeTo(e); err != nil { return err } + if err = s.Type.EncodeTo(e); err != nil { + return err + } + if err = s.LeType.EncodeTo(e); err != nil { + return err + } return nil } @@ -9050,6 +9645,16 @@ func (s *LedgerKeyContractData) DecodeFrom(d *xdr.Decoder) (int, error) { if err != nil { return n, fmt.Errorf("decoding ScVal: %s", err) } + nTmp, err = s.Type.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractDataType: %s", err) + } + nTmp, err = s.LeType.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractLedgerEntryType: %s", err) + } return n, nil } @@ -9085,9 +9690,11 @@ var _ xdrType = (*LedgerKeyContractData)(nil) // struct // { // Hash hash; +// ContractLedgerEntryType leType; // } type LedgerKeyContractCode struct { - Hash Hash + Hash Hash + LeType ContractLedgerEntryType } // EncodeTo encodes this value using the Encoder. @@ -9096,6 +9703,9 @@ func (s *LedgerKeyContractCode) EncodeTo(e *xdr.Encoder) error { if err = s.Hash.EncodeTo(e); err != nil { return err } + if err = s.LeType.EncodeTo(e); err != nil { + return err + } return nil } @@ -9110,6 +9720,11 @@ func (s *LedgerKeyContractCode) DecodeFrom(d *xdr.Decoder) (int, error) { if err != nil { return n, fmt.Errorf("decoding Hash: %s", err) } + nTmp, err = s.LeType.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractLedgerEntryType: %s", err) + } return n, nil } @@ -9247,11 +9862,14 @@ var _ xdrType = (*LedgerKeyConfigSetting)(nil) // { // Hash contractID; // SCVal key; +// ContractDataType type; +// ContractLedgerEntryType leType; // } contractData; // case CONTRACT_CODE: // struct // { // Hash hash; +// ContractLedgerEntryType leType; // } contractCode; // case CONFIG_SETTING: // struct @@ -15181,48 +15799,32 @@ func (s DiagnosticEvent) xdrType() {} var _ xdrType = (*DiagnosticEvent)(nil) -// TransactionMetaV3 is an XDR Struct defines as: +// SorobanTransactionMeta is an XDR Struct defines as: // -// struct TransactionMetaV3 +// struct SorobanTransactionMeta // { -// LedgerEntryChanges txChangesBefore; // tx level changes before operations -// // are applied if any -// OperationMeta operations<>; // meta for each operation -// LedgerEntryChanges txChangesAfter; // tx level changes after operations are -// // applied if any +// ExtensionPoint ext; +// // ContractEvent events<>; // custom events populated by the // // contracts themselves. -// SCVal returnValue; // return value of the invocation. +// SCVal returnValue; // return value of the host fn invocation // // // Diagnostics events that are not hashed. // // This will contain all contract and diagnostic events. Even ones // // that were emitted in a failed contract call. // DiagnosticEvent diagnosticEvents<>; // }; -type TransactionMetaV3 struct { - TxChangesBefore LedgerEntryChanges - Operations []OperationMeta - TxChangesAfter LedgerEntryChanges +type SorobanTransactionMeta struct { + Ext ExtensionPoint Events []ContractEvent ReturnValue ScVal DiagnosticEvents []DiagnosticEvent } // EncodeTo encodes this value using the Encoder. -func (s *TransactionMetaV3) EncodeTo(e *xdr.Encoder) error { +func (s *SorobanTransactionMeta) EncodeTo(e *xdr.Encoder) error { var err error - if err = s.TxChangesBefore.EncodeTo(e); err != nil { - return err - } - if _, err = e.EncodeUint(uint32(len(s.Operations))); err != nil { - return err - } - for i := 0; i < len(s.Operations); i++ { - if err = s.Operations[i].EncodeTo(e); err != nil { - return err - } - } - if err = s.TxChangesAfter.EncodeTo(e); err != nil { + if err = s.Ext.EncodeTo(e); err != nil { return err } if _, err = e.EncodeUint(uint32(len(s.Events))); err != nil { @@ -15247,76 +15849,191 @@ func (s *TransactionMetaV3) EncodeTo(e *xdr.Encoder) error { return nil } -var _ decoderFrom = (*TransactionMetaV3)(nil) +var _ decoderFrom = (*SorobanTransactionMeta)(nil) // DecodeFrom decodes this value using the Decoder. -func (s *TransactionMetaV3) DecodeFrom(d *xdr.Decoder) (int, error) { +func (s *SorobanTransactionMeta) DecodeFrom(d *xdr.Decoder) (int, error) { var err error var n, nTmp int - nTmp, err = s.TxChangesBefore.DecodeFrom(d) + nTmp, err = s.Ext.DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding LedgerEntryChanges: %s", err) + return n, fmt.Errorf("decoding ExtensionPoint: %s", err) } var l uint32 l, nTmp, err = d.DecodeUint() n += nTmp if err != nil { - return n, fmt.Errorf("decoding OperationMeta: %s", err) + return n, fmt.Errorf("decoding ContractEvent: %s", err) } - s.Operations = nil + s.Events = nil if l > 0 { - s.Operations = make([]OperationMeta, l) + s.Events = make([]ContractEvent, l) for i := uint32(0); i < l; i++ { - nTmp, err = s.Operations[i].DecodeFrom(d) + nTmp, err = s.Events[i].DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding OperationMeta: %s", err) + return n, fmt.Errorf("decoding ContractEvent: %s", err) } } } - nTmp, err = s.TxChangesAfter.DecodeFrom(d) + nTmp, err = s.ReturnValue.DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding LedgerEntryChanges: %s", err) + return n, fmt.Errorf("decoding ScVal: %s", err) } l, nTmp, err = d.DecodeUint() n += nTmp if err != nil { - return n, fmt.Errorf("decoding ContractEvent: %s", err) + return n, fmt.Errorf("decoding DiagnosticEvent: %s", err) } - s.Events = nil + s.DiagnosticEvents = nil if l > 0 { - s.Events = make([]ContractEvent, l) + s.DiagnosticEvents = make([]DiagnosticEvent, l) for i := uint32(0); i < l; i++ { - nTmp, err = s.Events[i].DecodeFrom(d) + nTmp, err = s.DiagnosticEvents[i].DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding ContractEvent: %s", err) + return n, fmt.Errorf("decoding DiagnosticEvent: %s", err) } } } - nTmp, err = s.ReturnValue.DecodeFrom(d) + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s SorobanTransactionMeta) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *SorobanTransactionMeta) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*SorobanTransactionMeta)(nil) + _ encoding.BinaryUnmarshaler = (*SorobanTransactionMeta)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s SorobanTransactionMeta) xdrType() {} + +var _ xdrType = (*SorobanTransactionMeta)(nil) + +// TransactionMetaV3 is an XDR Struct defines as: +// +// struct TransactionMetaV3 +// { +// ExtensionPoint ext; +// +// LedgerEntryChanges txChangesBefore; // tx level changes before operations +// // are applied if any +// OperationMeta operations<>; // meta for each operation +// LedgerEntryChanges txChangesAfter; // tx level changes after operations are +// // applied if any +// SorobanTransactionMeta* sorobanMeta; // Soroban-specific meta (only for +// // Soroban transactions). +// }; +type TransactionMetaV3 struct { + Ext ExtensionPoint + TxChangesBefore LedgerEntryChanges + Operations []OperationMeta + TxChangesAfter LedgerEntryChanges + SorobanMeta *SorobanTransactionMeta +} + +// EncodeTo encodes this value using the Encoder. +func (s *TransactionMetaV3) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.Ext.EncodeTo(e); err != nil { + return err + } + if err = s.TxChangesBefore.EncodeTo(e); err != nil { + return err + } + if _, err = e.EncodeUint(uint32(len(s.Operations))); err != nil { + return err + } + for i := 0; i < len(s.Operations); i++ { + if err = s.Operations[i].EncodeTo(e); err != nil { + return err + } + } + if err = s.TxChangesAfter.EncodeTo(e); err != nil { + return err + } + if _, err = e.EncodeBool(s.SorobanMeta != nil); err != nil { + return err + } + if s.SorobanMeta != nil { + if err = (*s.SorobanMeta).EncodeTo(e); err != nil { + return err + } + } + return nil +} + +var _ decoderFrom = (*TransactionMetaV3)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *TransactionMetaV3) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + nTmp, err = s.Ext.DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding ScVal: %s", err) + return n, fmt.Errorf("decoding ExtensionPoint: %s", err) + } + nTmp, err = s.TxChangesBefore.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding LedgerEntryChanges: %s", err) } + var l uint32 l, nTmp, err = d.DecodeUint() n += nTmp if err != nil { - return n, fmt.Errorf("decoding DiagnosticEvent: %s", err) + return n, fmt.Errorf("decoding OperationMeta: %s", err) } - s.DiagnosticEvents = nil + s.Operations = nil if l > 0 { - s.DiagnosticEvents = make([]DiagnosticEvent, l) + s.Operations = make([]OperationMeta, l) for i := uint32(0); i < l; i++ { - nTmp, err = s.DiagnosticEvents[i].DecodeFrom(d) + nTmp, err = s.Operations[i].DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding DiagnosticEvent: %s", err) + return n, fmt.Errorf("decoding OperationMeta: %s", err) } } } + nTmp, err = s.TxChangesAfter.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding LedgerEntryChanges: %s", err) + } + var b bool + b, nTmp, err = d.DecodeBool() + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding SorobanTransactionMeta: %s", err) + } + s.SorobanMeta = nil + if b { + s.SorobanMeta = new(SorobanTransactionMeta) + nTmp, err = s.SorobanMeta.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding SorobanTransactionMeta: %s", err) + } + } return n, nil } @@ -16014,161 +16731,402 @@ func (s *LedgerCloseMetaV0) DecodeFrom(d *xdr.Decoder) (int, error) { } } } - return n, nil -} - -// MarshalBinary implements encoding.BinaryMarshaler. -func (s LedgerCloseMetaV0) MarshalBinary() ([]byte, error) { - b := bytes.Buffer{} - e := xdr.NewEncoder(&b) - err := s.EncodeTo(e) - return b.Bytes(), err -} - -// UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (s *LedgerCloseMetaV0) UnmarshalBinary(inp []byte) error { - r := bytes.NewReader(inp) - d := xdr.NewDecoder(r) - _, err := s.DecodeFrom(d) - return err -} - -var ( - _ encoding.BinaryMarshaler = (*LedgerCloseMetaV0)(nil) - _ encoding.BinaryUnmarshaler = (*LedgerCloseMetaV0)(nil) -) - -// xdrType signals that this type is an type representing -// representing XDR values defined by this package. -func (s LedgerCloseMetaV0) xdrType() {} - -var _ xdrType = (*LedgerCloseMetaV0)(nil) - -// LedgerCloseMetaV1 is an XDR Struct defines as: -// -// struct LedgerCloseMetaV1 -// { -// LedgerHeaderHistoryEntry ledgerHeader; -// -// GeneralizedTransactionSet txSet; -// -// // NB: transactions are sorted in apply order here -// // fees for all transactions are processed first -// // followed by applying transactions -// TransactionResultMeta txProcessing<>; -// -// // upgrades are applied last -// UpgradeEntryMeta upgradesProcessing<>; -// -// // other misc information attached to the ledger close -// SCPHistoryEntry scpInfo<>; -// }; -type LedgerCloseMetaV1 struct { - LedgerHeader LedgerHeaderHistoryEntry - TxSet GeneralizedTransactionSet - TxProcessing []TransactionResultMeta - UpgradesProcessing []UpgradeEntryMeta - ScpInfo []ScpHistoryEntry -} - -// EncodeTo encodes this value using the Encoder. -func (s *LedgerCloseMetaV1) EncodeTo(e *xdr.Encoder) error { - var err error - if err = s.LedgerHeader.EncodeTo(e); err != nil { - return err - } - if err = s.TxSet.EncodeTo(e); err != nil { - return err - } - if _, err = e.EncodeUint(uint32(len(s.TxProcessing))); err != nil { - return err - } - for i := 0; i < len(s.TxProcessing); i++ { - if err = s.TxProcessing[i].EncodeTo(e); err != nil { - return err - } - } - if _, err = e.EncodeUint(uint32(len(s.UpgradesProcessing))); err != nil { - return err - } - for i := 0; i < len(s.UpgradesProcessing); i++ { - if err = s.UpgradesProcessing[i].EncodeTo(e); err != nil { - return err - } - } - if _, err = e.EncodeUint(uint32(len(s.ScpInfo))); err != nil { - return err - } - for i := 0; i < len(s.ScpInfo); i++ { - if err = s.ScpInfo[i].EncodeTo(e); err != nil { - return err - } - } - return nil -} - -var _ decoderFrom = (*LedgerCloseMetaV1)(nil) - -// DecodeFrom decodes this value using the Decoder. -func (s *LedgerCloseMetaV1) DecodeFrom(d *xdr.Decoder) (int, error) { - var err error - var n, nTmp int - nTmp, err = s.LedgerHeader.DecodeFrom(d) + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s LedgerCloseMetaV0) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *LedgerCloseMetaV0) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*LedgerCloseMetaV0)(nil) + _ encoding.BinaryUnmarshaler = (*LedgerCloseMetaV0)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s LedgerCloseMetaV0) xdrType() {} + +var _ xdrType = (*LedgerCloseMetaV0)(nil) + +// LedgerCloseMetaV1 is an XDR Struct defines as: +// +// struct LedgerCloseMetaV1 +// { +// LedgerHeaderHistoryEntry ledgerHeader; +// +// GeneralizedTransactionSet txSet; +// +// // NB: transactions are sorted in apply order here +// // fees for all transactions are processed first +// // followed by applying transactions +// TransactionResultMeta txProcessing<>; +// +// // upgrades are applied last +// UpgradeEntryMeta upgradesProcessing<>; +// +// // other misc information attached to the ledger close +// SCPHistoryEntry scpInfo<>; +// }; +type LedgerCloseMetaV1 struct { + LedgerHeader LedgerHeaderHistoryEntry + TxSet GeneralizedTransactionSet + TxProcessing []TransactionResultMeta + UpgradesProcessing []UpgradeEntryMeta + ScpInfo []ScpHistoryEntry +} + +// EncodeTo encodes this value using the Encoder. +func (s *LedgerCloseMetaV1) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.LedgerHeader.EncodeTo(e); err != nil { + return err + } + if err = s.TxSet.EncodeTo(e); err != nil { + return err + } + if _, err = e.EncodeUint(uint32(len(s.TxProcessing))); err != nil { + return err + } + for i := 0; i < len(s.TxProcessing); i++ { + if err = s.TxProcessing[i].EncodeTo(e); err != nil { + return err + } + } + if _, err = e.EncodeUint(uint32(len(s.UpgradesProcessing))); err != nil { + return err + } + for i := 0; i < len(s.UpgradesProcessing); i++ { + if err = s.UpgradesProcessing[i].EncodeTo(e); err != nil { + return err + } + } + if _, err = e.EncodeUint(uint32(len(s.ScpInfo))); err != nil { + return err + } + for i := 0; i < len(s.ScpInfo); i++ { + if err = s.ScpInfo[i].EncodeTo(e); err != nil { + return err + } + } + return nil +} + +var _ decoderFrom = (*LedgerCloseMetaV1)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *LedgerCloseMetaV1) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + nTmp, err = s.LedgerHeader.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding LedgerHeaderHistoryEntry: %s", err) + } + nTmp, err = s.TxSet.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding GeneralizedTransactionSet: %s", err) + } + var l uint32 + l, nTmp, err = d.DecodeUint() + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding TransactionResultMeta: %s", err) + } + s.TxProcessing = nil + if l > 0 { + s.TxProcessing = make([]TransactionResultMeta, l) + for i := uint32(0); i < l; i++ { + nTmp, err = s.TxProcessing[i].DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding TransactionResultMeta: %s", err) + } + } + } + l, nTmp, err = d.DecodeUint() + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding UpgradeEntryMeta: %s", err) + } + s.UpgradesProcessing = nil + if l > 0 { + s.UpgradesProcessing = make([]UpgradeEntryMeta, l) + for i := uint32(0); i < l; i++ { + nTmp, err = s.UpgradesProcessing[i].DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding UpgradeEntryMeta: %s", err) + } + } + } + l, nTmp, err = d.DecodeUint() + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ScpHistoryEntry: %s", err) + } + s.ScpInfo = nil + if l > 0 { + s.ScpInfo = make([]ScpHistoryEntry, l) + for i := uint32(0); i < l; i++ { + nTmp, err = s.ScpInfo[i].DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ScpHistoryEntry: %s", err) + } + } + } + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s LedgerCloseMetaV1) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *LedgerCloseMetaV1) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*LedgerCloseMetaV1)(nil) + _ encoding.BinaryUnmarshaler = (*LedgerCloseMetaV1)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s LedgerCloseMetaV1) xdrType() {} + +var _ xdrType = (*LedgerCloseMetaV1)(nil) + +// LedgerCloseMetaV2 is an XDR Struct defines as: +// +// struct LedgerCloseMetaV2 +// { +// // We forgot to add an ExtensionPoint in v1 but at least +// // we can add one now in v2. +// ExtensionPoint ext; +// +// LedgerHeaderHistoryEntry ledgerHeader; +// +// GeneralizedTransactionSet txSet; +// +// // NB: transactions are sorted in apply order here +// // fees for all transactions are processed first +// // followed by applying transactions +// TransactionResultMeta txProcessing<>; +// +// // upgrades are applied last +// UpgradeEntryMeta upgradesProcessing<>; +// +// // other misc information attached to the ledger close +// SCPHistoryEntry scpInfo<>; +// +// // Size in bytes of BucketList, to support downstream +// // systems calculating storage fees correctly. +// uint64 totalByteSizeOfBucketList; +// +// // Expired temp keys that are being evicted at this ledger. +// LedgerKey evictedTemporaryLedgerKeys<>; +// +// // Expired restorable ledger entries that are being +// // evicted at this ledger. +// LedgerEntry evictedRestorableLedgerEntries<>; +// }; +type LedgerCloseMetaV2 struct { + Ext ExtensionPoint + LedgerHeader LedgerHeaderHistoryEntry + TxSet GeneralizedTransactionSet + TxProcessing []TransactionResultMeta + UpgradesProcessing []UpgradeEntryMeta + ScpInfo []ScpHistoryEntry + TotalByteSizeOfBucketList Uint64 + EvictedTemporaryLedgerKeys []LedgerKey + EvictedRestorableLedgerEntries []LedgerEntry +} + +// EncodeTo encodes this value using the Encoder. +func (s *LedgerCloseMetaV2) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.Ext.EncodeTo(e); err != nil { + return err + } + if err = s.LedgerHeader.EncodeTo(e); err != nil { + return err + } + if err = s.TxSet.EncodeTo(e); err != nil { + return err + } + if _, err = e.EncodeUint(uint32(len(s.TxProcessing))); err != nil { + return err + } + for i := 0; i < len(s.TxProcessing); i++ { + if err = s.TxProcessing[i].EncodeTo(e); err != nil { + return err + } + } + if _, err = e.EncodeUint(uint32(len(s.UpgradesProcessing))); err != nil { + return err + } + for i := 0; i < len(s.UpgradesProcessing); i++ { + if err = s.UpgradesProcessing[i].EncodeTo(e); err != nil { + return err + } + } + if _, err = e.EncodeUint(uint32(len(s.ScpInfo))); err != nil { + return err + } + for i := 0; i < len(s.ScpInfo); i++ { + if err = s.ScpInfo[i].EncodeTo(e); err != nil { + return err + } + } + if err = s.TotalByteSizeOfBucketList.EncodeTo(e); err != nil { + return err + } + if _, err = e.EncodeUint(uint32(len(s.EvictedTemporaryLedgerKeys))); err != nil { + return err + } + for i := 0; i < len(s.EvictedTemporaryLedgerKeys); i++ { + if err = s.EvictedTemporaryLedgerKeys[i].EncodeTo(e); err != nil { + return err + } + } + if _, err = e.EncodeUint(uint32(len(s.EvictedRestorableLedgerEntries))); err != nil { + return err + } + for i := 0; i < len(s.EvictedRestorableLedgerEntries); i++ { + if err = s.EvictedRestorableLedgerEntries[i].EncodeTo(e); err != nil { + return err + } + } + return nil +} + +var _ decoderFrom = (*LedgerCloseMetaV2)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *LedgerCloseMetaV2) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + nTmp, err = s.Ext.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ExtensionPoint: %s", err) + } + nTmp, err = s.LedgerHeader.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding LedgerHeaderHistoryEntry: %s", err) + } + nTmp, err = s.TxSet.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding GeneralizedTransactionSet: %s", err) + } + var l uint32 + l, nTmp, err = d.DecodeUint() + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding TransactionResultMeta: %s", err) + } + s.TxProcessing = nil + if l > 0 { + s.TxProcessing = make([]TransactionResultMeta, l) + for i := uint32(0); i < l; i++ { + nTmp, err = s.TxProcessing[i].DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding TransactionResultMeta: %s", err) + } + } + } + l, nTmp, err = d.DecodeUint() + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding UpgradeEntryMeta: %s", err) + } + s.UpgradesProcessing = nil + if l > 0 { + s.UpgradesProcessing = make([]UpgradeEntryMeta, l) + for i := uint32(0); i < l; i++ { + nTmp, err = s.UpgradesProcessing[i].DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding UpgradeEntryMeta: %s", err) + } + } + } + l, nTmp, err = d.DecodeUint() + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ScpHistoryEntry: %s", err) + } + s.ScpInfo = nil + if l > 0 { + s.ScpInfo = make([]ScpHistoryEntry, l) + for i := uint32(0); i < l; i++ { + nTmp, err = s.ScpInfo[i].DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ScpHistoryEntry: %s", err) + } + } + } + nTmp, err = s.TotalByteSizeOfBucketList.DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding LedgerHeaderHistoryEntry: %s", err) - } - nTmp, err = s.TxSet.DecodeFrom(d) - n += nTmp - if err != nil { - return n, fmt.Errorf("decoding GeneralizedTransactionSet: %s", err) - } - var l uint32 - l, nTmp, err = d.DecodeUint() - n += nTmp - if err != nil { - return n, fmt.Errorf("decoding TransactionResultMeta: %s", err) - } - s.TxProcessing = nil - if l > 0 { - s.TxProcessing = make([]TransactionResultMeta, l) - for i := uint32(0); i < l; i++ { - nTmp, err = s.TxProcessing[i].DecodeFrom(d) - n += nTmp - if err != nil { - return n, fmt.Errorf("decoding TransactionResultMeta: %s", err) - } - } + return n, fmt.Errorf("decoding Uint64: %s", err) } l, nTmp, err = d.DecodeUint() n += nTmp if err != nil { - return n, fmt.Errorf("decoding UpgradeEntryMeta: %s", err) + return n, fmt.Errorf("decoding LedgerKey: %s", err) } - s.UpgradesProcessing = nil + s.EvictedTemporaryLedgerKeys = nil if l > 0 { - s.UpgradesProcessing = make([]UpgradeEntryMeta, l) + s.EvictedTemporaryLedgerKeys = make([]LedgerKey, l) for i := uint32(0); i < l; i++ { - nTmp, err = s.UpgradesProcessing[i].DecodeFrom(d) + nTmp, err = s.EvictedTemporaryLedgerKeys[i].DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding UpgradeEntryMeta: %s", err) + return n, fmt.Errorf("decoding LedgerKey: %s", err) } } } l, nTmp, err = d.DecodeUint() n += nTmp if err != nil { - return n, fmt.Errorf("decoding ScpHistoryEntry: %s", err) + return n, fmt.Errorf("decoding LedgerEntry: %s", err) } - s.ScpInfo = nil + s.EvictedRestorableLedgerEntries = nil if l > 0 { - s.ScpInfo = make([]ScpHistoryEntry, l) + s.EvictedRestorableLedgerEntries = make([]LedgerEntry, l) for i := uint32(0); i < l; i++ { - nTmp, err = s.ScpInfo[i].DecodeFrom(d) + nTmp, err = s.EvictedRestorableLedgerEntries[i].DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding ScpHistoryEntry: %s", err) + return n, fmt.Errorf("decoding LedgerEntry: %s", err) } } } @@ -16176,7 +17134,7 @@ func (s *LedgerCloseMetaV1) DecodeFrom(d *xdr.Decoder) (int, error) { } // MarshalBinary implements encoding.BinaryMarshaler. -func (s LedgerCloseMetaV1) MarshalBinary() ([]byte, error) { +func (s LedgerCloseMetaV2) MarshalBinary() ([]byte, error) { b := bytes.Buffer{} e := xdr.NewEncoder(&b) err := s.EncodeTo(e) @@ -16184,7 +17142,7 @@ func (s LedgerCloseMetaV1) MarshalBinary() ([]byte, error) { } // UnmarshalBinary implements encoding.BinaryUnmarshaler. -func (s *LedgerCloseMetaV1) UnmarshalBinary(inp []byte) error { +func (s *LedgerCloseMetaV2) UnmarshalBinary(inp []byte) error { r := bytes.NewReader(inp) d := xdr.NewDecoder(r) _, err := s.DecodeFrom(d) @@ -16192,15 +17150,15 @@ func (s *LedgerCloseMetaV1) UnmarshalBinary(inp []byte) error { } var ( - _ encoding.BinaryMarshaler = (*LedgerCloseMetaV1)(nil) - _ encoding.BinaryUnmarshaler = (*LedgerCloseMetaV1)(nil) + _ encoding.BinaryMarshaler = (*LedgerCloseMetaV2)(nil) + _ encoding.BinaryUnmarshaler = (*LedgerCloseMetaV2)(nil) ) // xdrType signals that this type is an type representing // representing XDR values defined by this package. -func (s LedgerCloseMetaV1) xdrType() {} +func (s LedgerCloseMetaV2) xdrType() {} -var _ xdrType = (*LedgerCloseMetaV1)(nil) +var _ xdrType = (*LedgerCloseMetaV2)(nil) // LedgerCloseMeta is an XDR Union defines as: // @@ -16210,11 +17168,14 @@ var _ xdrType = (*LedgerCloseMetaV1)(nil) // LedgerCloseMetaV0 v0; // case 1: // LedgerCloseMetaV1 v1; +// case 2: +// LedgerCloseMetaV2 v2; // }; type LedgerCloseMeta struct { V int32 V0 *LedgerCloseMetaV0 V1 *LedgerCloseMetaV1 + V2 *LedgerCloseMetaV2 } // SwitchFieldName returns the field name in which this union's @@ -16231,6 +17192,8 @@ func (u LedgerCloseMeta) ArmForSwitch(sw int32) (string, bool) { return "V0", true case 1: return "V1", true + case 2: + return "V2", true } return "-", false } @@ -16253,6 +17216,13 @@ func NewLedgerCloseMeta(v int32, value interface{}) (result LedgerCloseMeta, err return } result.V1 = &tv + case 2: + tv, ok := value.(LedgerCloseMetaV2) + if !ok { + err = fmt.Errorf("invalid value, must be LedgerCloseMetaV2") + return + } + result.V2 = &tv } return } @@ -16307,6 +17277,31 @@ func (u LedgerCloseMeta) GetV1() (result LedgerCloseMetaV1, ok bool) { return } +// MustV2 retrieves the V2 value from the union, +// panicing if the value is not set. +func (u LedgerCloseMeta) MustV2() LedgerCloseMetaV2 { + val, ok := u.GetV2() + + if !ok { + panic("arm V2 is not set") + } + + return val +} + +// GetV2 retrieves the V2 value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u LedgerCloseMeta) GetV2() (result LedgerCloseMetaV2, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.V)) + + if armName == "V2" { + result = *u.V2 + ok = true + } + + return +} + // EncodeTo encodes this value using the Encoder. func (u LedgerCloseMeta) EncodeTo(e *xdr.Encoder) error { var err error @@ -16324,6 +17319,11 @@ func (u LedgerCloseMeta) EncodeTo(e *xdr.Encoder) error { return err } return nil + case 2: + if err = (*u.V2).EncodeTo(e); err != nil { + return err + } + return nil } return fmt.Errorf("V (int32) switch value '%d' is not valid for union LedgerCloseMeta", u.V) } @@ -16356,6 +17356,14 @@ func (u *LedgerCloseMeta) DecodeFrom(d *xdr.Decoder) (int, error) { return n, fmt.Errorf("decoding LedgerCloseMetaV1: %s", err) } return n, nil + case 2: + u.V2 = new(LedgerCloseMetaV2) + nTmp, err = (*u.V2).DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding LedgerCloseMetaV2: %s", err) + } + return n, nil } return n, fmt.Errorf("union LedgerCloseMeta has invalid V (int32) switch value '%d'", u.V) } @@ -28397,27 +29405,27 @@ var _ xdrType = (*SorobanResources)(nil) // // struct SorobanTransactionData // { +// ExtensionPoint ext; // SorobanResources resources; // // Portion of transaction `fee` allocated to refundable fees. // int64 refundableFee; -// ExtensionPoint ext; // }; type SorobanTransactionData struct { + Ext ExtensionPoint Resources SorobanResources RefundableFee Int64 - Ext ExtensionPoint } // EncodeTo encodes this value using the Encoder. func (s *SorobanTransactionData) EncodeTo(e *xdr.Encoder) error { var err error - if err = s.Resources.EncodeTo(e); err != nil { + if err = s.Ext.EncodeTo(e); err != nil { return err } - if err = s.RefundableFee.EncodeTo(e); err != nil { + if err = s.Resources.EncodeTo(e); err != nil { return err } - if err = s.Ext.EncodeTo(e); err != nil { + if err = s.RefundableFee.EncodeTo(e); err != nil { return err } return nil @@ -28429,6 +29437,11 @@ var _ decoderFrom = (*SorobanTransactionData)(nil) func (s *SorobanTransactionData) DecodeFrom(d *xdr.Decoder) (int, error) { var err error var n, nTmp int + nTmp, err = s.Ext.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ExtensionPoint: %s", err) + } nTmp, err = s.Resources.DecodeFrom(d) n += nTmp if err != nil { @@ -28439,11 +29452,6 @@ func (s *SorobanTransactionData) DecodeFrom(d *xdr.Decoder) (int, error) { if err != nil { return n, fmt.Errorf("decoding Int64: %s", err) } - nTmp, err = s.Ext.DecodeFrom(d) - n += nTmp - if err != nil { - return n, fmt.Errorf("decoding ExtensionPoint: %s", err) - } return n, nil } @@ -46921,7 +47929,9 @@ var _ xdrType = (*ScSpecEntry)(nil) // // symbolic SCVals used as the key for ledger entries for a contract's code // // and an address' nonce, respectively. // SCV_LEDGER_KEY_CONTRACT_EXECUTABLE = 20, -// SCV_LEDGER_KEY_NONCE = 21 +// SCV_LEDGER_KEY_NONCE = 21, +// +// SCV_STORAGE_TYPE = 22 // }; type ScValType int32 @@ -46948,6 +47958,7 @@ const ( ScValTypeScvAddress ScValType = 19 ScValTypeScvLedgerKeyContractExecutable ScValType = 20 ScValTypeScvLedgerKeyNonce ScValType = 21 + ScValTypeScvStorageType ScValType = 22 ) var scValTypeMap = map[int32]string{ @@ -46973,6 +47984,7 @@ var scValTypeMap = map[int32]string{ 19: "ScValTypeScvAddress", 20: "ScValTypeScvLedgerKeyContractExecutable", 21: "ScValTypeScvLedgerKeyNonce", + 22: "ScValTypeScvStorageType", } // ValidEnum validates a proposed value for this enum. Implements @@ -48137,6 +49149,91 @@ func (s ScAddress) xdrType() {} var _ xdrType = (*ScAddress)(nil) +// ContractDataType is an XDR Enum defines as: +// +// enum ContractDataType { +// TEMPORARY = 0, +// MERGEABLE = 1, +// EXCLUSIVE = 2 +// }; +type ContractDataType int32 + +const ( + ContractDataTypeTemporary ContractDataType = 0 + ContractDataTypeMergeable ContractDataType = 1 + ContractDataTypeExclusive ContractDataType = 2 +) + +var contractDataTypeMap = map[int32]string{ + 0: "ContractDataTypeTemporary", + 1: "ContractDataTypeMergeable", + 2: "ContractDataTypeExclusive", +} + +// ValidEnum validates a proposed value for this enum. Implements +// the Enum interface for ContractDataType +func (e ContractDataType) ValidEnum(v int32) bool { + _, ok := contractDataTypeMap[v] + return ok +} + +// String returns the name of `e` +func (e ContractDataType) String() string { + name, _ := contractDataTypeMap[int32(e)] + return name +} + +// EncodeTo encodes this value using the Encoder. +func (e ContractDataType) EncodeTo(enc *xdr.Encoder) error { + if _, ok := contractDataTypeMap[int32(e)]; !ok { + return fmt.Errorf("'%d' is not a valid ContractDataType enum value", e) + } + _, err := enc.EncodeInt(int32(e)) + return err +} + +var _ decoderFrom = (*ContractDataType)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (e *ContractDataType) DecodeFrom(d *xdr.Decoder) (int, error) { + v, n, err := d.DecodeInt() + if err != nil { + return n, fmt.Errorf("decoding ContractDataType: %s", err) + } + if _, ok := contractDataTypeMap[v]; !ok { + return n, fmt.Errorf("'%d' is not a valid ContractDataType enum value", v) + } + *e = ContractDataType(v) + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s ContractDataType) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *ContractDataType) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*ContractDataType)(nil) + _ encoding.BinaryUnmarshaler = (*ContractDataType)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s ContractDataType) xdrType() {} + +var _ xdrType = (*ContractDataType)(nil) + // ScsymbolLimit is an XDR Const defines as: // // const SCSYMBOL_LIMIT = 32; @@ -48580,29 +49677,33 @@ var _ xdrType = (*ScNonceKey)(nil) // void; // case SCV_LEDGER_KEY_NONCE: // SCNonceKey nonce_key; +// +// case SCV_STORAGE_TYPE: +// ContractDataType storageType; // }; type ScVal struct { - Type ScValType - B *bool - Error *ScError - U32 *Uint32 - I32 *Int32 - U64 *Uint64 - I64 *Int64 - Timepoint *TimePoint - Duration *Duration - U128 *UInt128Parts - I128 *Int128Parts - U256 *UInt256Parts - I256 *Int256Parts - Bytes *ScBytes - Str *ScString - Sym *ScSymbol - Vec **ScVec - Map **ScMap - Exec *ScContractExecutable - Address *ScAddress - NonceKey *ScNonceKey + Type ScValType + B *bool + Error *ScError + U32 *Uint32 + I32 *Int32 + U64 *Uint64 + I64 *Int64 + Timepoint *TimePoint + Duration *Duration + U128 *UInt128Parts + I128 *Int128Parts + U256 *UInt256Parts + I256 *Int256Parts + Bytes *ScBytes + Str *ScString + Sym *ScSymbol + Vec **ScVec + Map **ScMap + Exec *ScContractExecutable + Address *ScAddress + NonceKey *ScNonceKey + StorageType *ContractDataType } // SwitchFieldName returns the field name in which this union's @@ -48659,6 +49760,8 @@ func (u ScVal) ArmForSwitch(sw int32) (string, bool) { return "", true case ScValTypeScvLedgerKeyNonce: return "NonceKey", true + case ScValTypeScvStorageType: + return "StorageType", true } return "-", false } @@ -48811,6 +49914,13 @@ func NewScVal(aType ScValType, value interface{}) (result ScVal, err error) { return } result.NonceKey = &tv + case ScValTypeScvStorageType: + tv, ok := value.(ContractDataType) + if !ok { + err = fmt.Errorf("invalid value, must be ContractDataType") + return + } + result.StorageType = &tv } return } @@ -49315,6 +50425,31 @@ func (u ScVal) GetNonceKey() (result ScNonceKey, ok bool) { return } +// MustStorageType retrieves the StorageType value from the union, +// panicing if the value is not set. +func (u ScVal) MustStorageType() ContractDataType { + val, ok := u.GetStorageType() + + if !ok { + panic("arm StorageType is not set") + } + + return val +} + +// GetStorageType retrieves the StorageType value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u ScVal) GetStorageType() (result ContractDataType, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.Type)) + + if armName == "StorageType" { + result = *u.StorageType + ok = true + } + + return +} + // EncodeTo encodes this value using the Encoder. func (u ScVal) EncodeTo(e *xdr.Encoder) error { var err error @@ -49438,6 +50573,11 @@ func (u ScVal) EncodeTo(e *xdr.Encoder) error { return err } return nil + case ScValTypeScvStorageType: + if err = (*u.StorageType).EncodeTo(e); err != nil { + return err + } + return nil } return fmt.Errorf("Type (ScValType) switch value '%d' is not valid for union ScVal", u.Type) } @@ -49640,6 +50780,14 @@ func (u *ScVal) DecodeFrom(d *xdr.Decoder) (int, error) { return n, fmt.Errorf("decoding ScNonceKey: %s", err) } return n, nil + case ScValTypeScvStorageType: + u.StorageType = new(ContractDataType) + nTmp, err = (*u.StorageType).DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractDataType: %s", err) + } + return n, nil } return n, fmt.Errorf("union ScVal has invalid Type (ScValType) switch value '%d'", u.Type) } @@ -50344,6 +51492,67 @@ func (s PersistedScpState) xdrType() {} var _ xdrType = (*PersistedScpState)(nil) +// ConfigSettingContractExecutionLanesV0 is an XDR Struct defines as: +// +// struct ConfigSettingContractExecutionLanesV0 +// { +// // maximum number of Soroban transactions per ledger +// uint32 ledgerMaxTxCount; +// }; +type ConfigSettingContractExecutionLanesV0 struct { + LedgerMaxTxCount Uint32 +} + +// EncodeTo encodes this value using the Encoder. +func (s *ConfigSettingContractExecutionLanesV0) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.LedgerMaxTxCount.EncodeTo(e); err != nil { + return err + } + return nil +} + +var _ decoderFrom = (*ConfigSettingContractExecutionLanesV0)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *ConfigSettingContractExecutionLanesV0) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + nTmp, err = s.LedgerMaxTxCount.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint32: %s", err) + } + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s ConfigSettingContractExecutionLanesV0) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *ConfigSettingContractExecutionLanesV0) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*ConfigSettingContractExecutionLanesV0)(nil) + _ encoding.BinaryUnmarshaler = (*ConfigSettingContractExecutionLanesV0)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s ConfigSettingContractExecutionLanesV0) xdrType() {} + +var _ xdrType = (*ConfigSettingContractExecutionLanesV0)(nil) + // ConfigSettingContractComputeV0 is an XDR Struct defines as: // // struct ConfigSettingContractComputeV0 @@ -50929,32 +52138,47 @@ var _ xdrType = (*ConfigSettingContractBandwidthV0)(nil) // // Roundtrip cost of invoking a VM function from the host. // InvokeVmFunction = 19, // // Cost of charging a value to the budgeting system. -// ChargeBudget = 20 +// ChargeBudget = 20, +// // Cost of computing a keccak256 hash from bytes. +// ComputeKeccak256Hash = 21, +// // Cost of computing an ECDSA secp256k1 pubkey from bytes. +// ComputeEcdsaSecp256k1Key = 22, +// // Cost of computing an ECDSA secp256k1 signature from bytes. +// ComputeEcdsaSecp256k1Sig = 23, +// // Cost of verifying an ECDSA secp256k1 signature. +// VerifyEcdsaSecp256k1Sig = 24, +// // Cost of recovering an ECDSA secp256k1 key from a signature. +// RecoverEcdsaSecp256k1Key = 25 // }; type ContractCostType int32 const ( - ContractCostTypeWasmInsnExec ContractCostType = 0 - ContractCostTypeWasmMemAlloc ContractCostType = 1 - ContractCostTypeHostMemAlloc ContractCostType = 2 - ContractCostTypeHostMemCpy ContractCostType = 3 - ContractCostTypeHostMemCmp ContractCostType = 4 - ContractCostTypeInvokeHostFunction ContractCostType = 5 - ContractCostTypeVisitObject ContractCostType = 6 - ContractCostTypeValXdrConv ContractCostType = 7 - ContractCostTypeValSer ContractCostType = 8 - ContractCostTypeValDeser ContractCostType = 9 - ContractCostTypeComputeSha256Hash ContractCostType = 10 - ContractCostTypeComputeEd25519PubKey ContractCostType = 11 - ContractCostTypeMapEntry ContractCostType = 12 - ContractCostTypeVecEntry ContractCostType = 13 - ContractCostTypeGuardFrame ContractCostType = 14 - ContractCostTypeVerifyEd25519Sig ContractCostType = 15 - ContractCostTypeVmMemRead ContractCostType = 16 - ContractCostTypeVmMemWrite ContractCostType = 17 - ContractCostTypeVmInstantiation ContractCostType = 18 - ContractCostTypeInvokeVmFunction ContractCostType = 19 - ContractCostTypeChargeBudget ContractCostType = 20 + ContractCostTypeWasmInsnExec ContractCostType = 0 + ContractCostTypeWasmMemAlloc ContractCostType = 1 + ContractCostTypeHostMemAlloc ContractCostType = 2 + ContractCostTypeHostMemCpy ContractCostType = 3 + ContractCostTypeHostMemCmp ContractCostType = 4 + ContractCostTypeInvokeHostFunction ContractCostType = 5 + ContractCostTypeVisitObject ContractCostType = 6 + ContractCostTypeValXdrConv ContractCostType = 7 + ContractCostTypeValSer ContractCostType = 8 + ContractCostTypeValDeser ContractCostType = 9 + ContractCostTypeComputeSha256Hash ContractCostType = 10 + ContractCostTypeComputeEd25519PubKey ContractCostType = 11 + ContractCostTypeMapEntry ContractCostType = 12 + ContractCostTypeVecEntry ContractCostType = 13 + ContractCostTypeGuardFrame ContractCostType = 14 + ContractCostTypeVerifyEd25519Sig ContractCostType = 15 + ContractCostTypeVmMemRead ContractCostType = 16 + ContractCostTypeVmMemWrite ContractCostType = 17 + ContractCostTypeVmInstantiation ContractCostType = 18 + ContractCostTypeInvokeVmFunction ContractCostType = 19 + ContractCostTypeChargeBudget ContractCostType = 20 + ContractCostTypeComputeKeccak256Hash ContractCostType = 21 + ContractCostTypeComputeEcdsaSecp256k1Key ContractCostType = 22 + ContractCostTypeComputeEcdsaSecp256k1Sig ContractCostType = 23 + ContractCostTypeVerifyEcdsaSecp256k1Sig ContractCostType = 24 + ContractCostTypeRecoverEcdsaSecp256k1Key ContractCostType = 25 ) var contractCostTypeMap = map[int32]string{ @@ -50979,6 +52203,11 @@ var contractCostTypeMap = map[int32]string{ 18: "ContractCostTypeVmInstantiation", 19: "ContractCostTypeInvokeVmFunction", 20: "ContractCostTypeChargeBudget", + 21: "ContractCostTypeComputeKeccak256Hash", + 22: "ContractCostTypeComputeEcdsaSecp256k1Key", + 23: "ContractCostTypeComputeEcdsaSecp256k1Sig", + 24: "ContractCostTypeVerifyEcdsaSecp256k1Sig", + 25: "ContractCostTypeRecoverEcdsaSecp256k1Key", } // ValidEnum validates a proposed value for this enum. Implements @@ -51048,27 +52277,28 @@ var _ xdrType = (*ContractCostType)(nil) // ContractCostParamEntry is an XDR Struct defines as: // // struct ContractCostParamEntry { -// int64 constTerm; -// int64 linearTerm; // // use `ext` to add more terms (e.g. higher order polynomials) in the future // ExtensionPoint ext; +// +// int64 constTerm; +// int64 linearTerm; // }; type ContractCostParamEntry struct { + Ext ExtensionPoint ConstTerm Int64 LinearTerm Int64 - Ext ExtensionPoint } // EncodeTo encodes this value using the Encoder. func (s *ContractCostParamEntry) EncodeTo(e *xdr.Encoder) error { var err error - if err = s.ConstTerm.EncodeTo(e); err != nil { + if err = s.Ext.EncodeTo(e); err != nil { return err } - if err = s.LinearTerm.EncodeTo(e); err != nil { + if err = s.ConstTerm.EncodeTo(e); err != nil { return err } - if err = s.Ext.EncodeTo(e); err != nil { + if err = s.LinearTerm.EncodeTo(e); err != nil { return err } return nil @@ -51080,20 +52310,20 @@ var _ decoderFrom = (*ContractCostParamEntry)(nil) func (s *ContractCostParamEntry) DecodeFrom(d *xdr.Decoder) (int, error) { var err error var n, nTmp int - nTmp, err = s.ConstTerm.DecodeFrom(d) + nTmp, err = s.Ext.DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding Int64: %s", err) + return n, fmt.Errorf("decoding ExtensionPoint: %s", err) } - nTmp, err = s.LinearTerm.DecodeFrom(d) + nTmp, err = s.ConstTerm.DecodeFrom(d) n += nTmp if err != nil { return n, fmt.Errorf("decoding Int64: %s", err) } - nTmp, err = s.Ext.DecodeFrom(d) + nTmp, err = s.LinearTerm.DecodeFrom(d) n += nTmp if err != nil { - return n, fmt.Errorf("decoding ExtensionPoint: %s", err) + return n, fmt.Errorf("decoding Int64: %s", err) } return n, nil } @@ -51125,6 +52355,229 @@ func (s ContractCostParamEntry) xdrType() {} var _ xdrType = (*ContractCostParamEntry)(nil) +// StateExpirationSettingsExt is an XDR NestedUnion defines as: +// +// union switch (int v) +// { +// case 0: +// void; +// } +type StateExpirationSettingsExt struct { + V int32 +} + +// SwitchFieldName returns the field name in which this union's +// discriminant is stored +func (u StateExpirationSettingsExt) SwitchFieldName() string { + return "V" +} + +// ArmForSwitch returns which field name should be used for storing +// the value for an instance of StateExpirationSettingsExt +func (u StateExpirationSettingsExt) ArmForSwitch(sw int32) (string, bool) { + switch int32(sw) { + case 0: + return "", true + } + return "-", false +} + +// NewStateExpirationSettingsExt creates a new StateExpirationSettingsExt. +func NewStateExpirationSettingsExt(v int32, value interface{}) (result StateExpirationSettingsExt, err error) { + result.V = v + switch int32(v) { + case 0: + // void + } + return +} + +// EncodeTo encodes this value using the Encoder. +func (u StateExpirationSettingsExt) EncodeTo(e *xdr.Encoder) error { + var err error + if _, err = e.EncodeInt(int32(u.V)); err != nil { + return err + } + switch int32(u.V) { + case 0: + // Void + return nil + } + return fmt.Errorf("V (int32) switch value '%d' is not valid for union StateExpirationSettingsExt", u.V) +} + +var _ decoderFrom = (*StateExpirationSettingsExt)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (u *StateExpirationSettingsExt) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + u.V, nTmp, err = d.DecodeInt() + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Int: %s", err) + } + switch int32(u.V) { + case 0: + // Void + return n, nil + } + return n, fmt.Errorf("union StateExpirationSettingsExt has invalid V (int32) switch value '%d'", u.V) +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s StateExpirationSettingsExt) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *StateExpirationSettingsExt) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*StateExpirationSettingsExt)(nil) + _ encoding.BinaryUnmarshaler = (*StateExpirationSettingsExt)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s StateExpirationSettingsExt) xdrType() {} + +var _ xdrType = (*StateExpirationSettingsExt)(nil) + +// StateExpirationSettings is an XDR Struct defines as: +// +// struct StateExpirationSettings { +// uint32 maxEntryExpiration; +// uint32 minTempEntryExpiration; +// uint32 minRestorableEntryExpiration; +// uint32 autoBumpLedgers; +// +// // rent_fee = wfee_rate_average / rent_rate_denominator_for_type +// int64 restorableRentRateDenominator; +// int64 tempRentRateDenominator; +// +// union switch (int v) +// { +// case 0: +// void; +// } ext; +// }; +type StateExpirationSettings struct { + MaxEntryExpiration Uint32 + MinTempEntryExpiration Uint32 + MinRestorableEntryExpiration Uint32 + AutoBumpLedgers Uint32 + RestorableRentRateDenominator Int64 + TempRentRateDenominator Int64 + Ext StateExpirationSettingsExt +} + +// EncodeTo encodes this value using the Encoder. +func (s *StateExpirationSettings) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.MaxEntryExpiration.EncodeTo(e); err != nil { + return err + } + if err = s.MinTempEntryExpiration.EncodeTo(e); err != nil { + return err + } + if err = s.MinRestorableEntryExpiration.EncodeTo(e); err != nil { + return err + } + if err = s.AutoBumpLedgers.EncodeTo(e); err != nil { + return err + } + if err = s.RestorableRentRateDenominator.EncodeTo(e); err != nil { + return err + } + if err = s.TempRentRateDenominator.EncodeTo(e); err != nil { + return err + } + if err = s.Ext.EncodeTo(e); err != nil { + return err + } + return nil +} + +var _ decoderFrom = (*StateExpirationSettings)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *StateExpirationSettings) DecodeFrom(d *xdr.Decoder) (int, error) { + var err error + var n, nTmp int + nTmp, err = s.MaxEntryExpiration.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint32: %s", err) + } + nTmp, err = s.MinTempEntryExpiration.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint32: %s", err) + } + nTmp, err = s.MinRestorableEntryExpiration.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint32: %s", err) + } + nTmp, err = s.AutoBumpLedgers.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint32: %s", err) + } + nTmp, err = s.RestorableRentRateDenominator.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Int64: %s", err) + } + nTmp, err = s.TempRentRateDenominator.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Int64: %s", err) + } + nTmp, err = s.Ext.DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding StateExpirationSettingsExt: %s", err) + } + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s StateExpirationSettings) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *StateExpirationSettings) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + d := xdr.NewDecoder(r) + _, err := s.DecodeFrom(d) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*StateExpirationSettings)(nil) + _ encoding.BinaryUnmarshaler = (*StateExpirationSettings)(nil) +) + +// xdrType signals that this type is an type representing +// representing XDR values defined by this package. +func (s StateExpirationSettings) xdrType() {} + +var _ xdrType = (*StateExpirationSettings)(nil) + // ContractCostCountLimit is an XDR Const defines as: // // const CONTRACT_COST_COUNT_LIMIT = 1024; @@ -51223,7 +52676,9 @@ var _ xdrType = (*ContractCostParams)(nil) // CONFIG_SETTING_CONTRACT_COST_PARAMS_CPU_INSTRUCTIONS = 6, // CONFIG_SETTING_CONTRACT_COST_PARAMS_MEMORY_BYTES = 7, // CONFIG_SETTING_CONTRACT_DATA_KEY_SIZE_BYTES = 8, -// CONFIG_SETTING_CONTRACT_DATA_ENTRY_SIZE_BYTES = 9 +// CONFIG_SETTING_CONTRACT_DATA_ENTRY_SIZE_BYTES = 9, +// CONFIG_SETTING_STATE_EXPIRATION = 10, +// CONFIG_SETTING_CONTRACT_EXECUTION_LANES = 11 // }; type ConfigSettingId int32 @@ -51238,19 +52693,23 @@ const ( ConfigSettingIdConfigSettingContractCostParamsMemoryBytes ConfigSettingId = 7 ConfigSettingIdConfigSettingContractDataKeySizeBytes ConfigSettingId = 8 ConfigSettingIdConfigSettingContractDataEntrySizeBytes ConfigSettingId = 9 + ConfigSettingIdConfigSettingStateExpiration ConfigSettingId = 10 + ConfigSettingIdConfigSettingContractExecutionLanes ConfigSettingId = 11 ) var configSettingIdMap = map[int32]string{ - 0: "ConfigSettingIdConfigSettingContractMaxSizeBytes", - 1: "ConfigSettingIdConfigSettingContractComputeV0", - 2: "ConfigSettingIdConfigSettingContractLedgerCostV0", - 3: "ConfigSettingIdConfigSettingContractHistoricalDataV0", - 4: "ConfigSettingIdConfigSettingContractMetaDataV0", - 5: "ConfigSettingIdConfigSettingContractBandwidthV0", - 6: "ConfigSettingIdConfigSettingContractCostParamsCpuInstructions", - 7: "ConfigSettingIdConfigSettingContractCostParamsMemoryBytes", - 8: "ConfigSettingIdConfigSettingContractDataKeySizeBytes", - 9: "ConfigSettingIdConfigSettingContractDataEntrySizeBytes", + 0: "ConfigSettingIdConfigSettingContractMaxSizeBytes", + 1: "ConfigSettingIdConfigSettingContractComputeV0", + 2: "ConfigSettingIdConfigSettingContractLedgerCostV0", + 3: "ConfigSettingIdConfigSettingContractHistoricalDataV0", + 4: "ConfigSettingIdConfigSettingContractMetaDataV0", + 5: "ConfigSettingIdConfigSettingContractBandwidthV0", + 6: "ConfigSettingIdConfigSettingContractCostParamsCpuInstructions", + 7: "ConfigSettingIdConfigSettingContractCostParamsMemoryBytes", + 8: "ConfigSettingIdConfigSettingContractDataKeySizeBytes", + 9: "ConfigSettingIdConfigSettingContractDataEntrySizeBytes", + 10: "ConfigSettingIdConfigSettingStateExpiration", + 11: "ConfigSettingIdConfigSettingContractExecutionLanes", } // ValidEnum validates a proposed value for this enum. Implements @@ -51341,6 +52800,10 @@ var _ xdrType = (*ConfigSettingId)(nil) // uint32 contractDataKeySizeBytes; // case CONFIG_SETTING_CONTRACT_DATA_ENTRY_SIZE_BYTES: // uint32 contractDataEntrySizeBytes; +// case CONFIG_SETTING_STATE_EXPIRATION: +// StateExpirationSettings stateExpirationSettings; +// case CONFIG_SETTING_CONTRACT_EXECUTION_LANES: +// ConfigSettingContractExecutionLanesV0 contractExecutionLanes; // }; type ConfigSettingEntry struct { ConfigSettingId ConfigSettingId @@ -51354,6 +52817,8 @@ type ConfigSettingEntry struct { ContractCostParamsMemBytes *ContractCostParams ContractDataKeySizeBytes *Uint32 ContractDataEntrySizeBytes *Uint32 + StateExpirationSettings *StateExpirationSettings + ContractExecutionLanes *ConfigSettingContractExecutionLanesV0 } // SwitchFieldName returns the field name in which this union's @@ -51386,6 +52851,10 @@ func (u ConfigSettingEntry) ArmForSwitch(sw int32) (string, bool) { return "ContractDataKeySizeBytes", true case ConfigSettingIdConfigSettingContractDataEntrySizeBytes: return "ContractDataEntrySizeBytes", true + case ConfigSettingIdConfigSettingStateExpiration: + return "StateExpirationSettings", true + case ConfigSettingIdConfigSettingContractExecutionLanes: + return "ContractExecutionLanes", true } return "-", false } @@ -51464,6 +52933,20 @@ func NewConfigSettingEntry(configSettingId ConfigSettingId, value interface{}) ( return } result.ContractDataEntrySizeBytes = &tv + case ConfigSettingIdConfigSettingStateExpiration: + tv, ok := value.(StateExpirationSettings) + if !ok { + err = fmt.Errorf("invalid value, must be StateExpirationSettings") + return + } + result.StateExpirationSettings = &tv + case ConfigSettingIdConfigSettingContractExecutionLanes: + tv, ok := value.(ConfigSettingContractExecutionLanesV0) + if !ok { + err = fmt.Errorf("invalid value, must be ConfigSettingContractExecutionLanesV0") + return + } + result.ContractExecutionLanes = &tv } return } @@ -51718,6 +53201,56 @@ func (u ConfigSettingEntry) GetContractDataEntrySizeBytes() (result Uint32, ok b return } +// MustStateExpirationSettings retrieves the StateExpirationSettings value from the union, +// panicing if the value is not set. +func (u ConfigSettingEntry) MustStateExpirationSettings() StateExpirationSettings { + val, ok := u.GetStateExpirationSettings() + + if !ok { + panic("arm StateExpirationSettings is not set") + } + + return val +} + +// GetStateExpirationSettings retrieves the StateExpirationSettings value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u ConfigSettingEntry) GetStateExpirationSettings() (result StateExpirationSettings, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.ConfigSettingId)) + + if armName == "StateExpirationSettings" { + result = *u.StateExpirationSettings + ok = true + } + + return +} + +// MustContractExecutionLanes retrieves the ContractExecutionLanes value from the union, +// panicing if the value is not set. +func (u ConfigSettingEntry) MustContractExecutionLanes() ConfigSettingContractExecutionLanesV0 { + val, ok := u.GetContractExecutionLanes() + + if !ok { + panic("arm ContractExecutionLanes is not set") + } + + return val +} + +// GetContractExecutionLanes retrieves the ContractExecutionLanes value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u ConfigSettingEntry) GetContractExecutionLanes() (result ConfigSettingContractExecutionLanesV0, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.ConfigSettingId)) + + if armName == "ContractExecutionLanes" { + result = *u.ContractExecutionLanes + ok = true + } + + return +} + // EncodeTo encodes this value using the Encoder. func (u ConfigSettingEntry) EncodeTo(e *xdr.Encoder) error { var err error @@ -51775,6 +53308,16 @@ func (u ConfigSettingEntry) EncodeTo(e *xdr.Encoder) error { return err } return nil + case ConfigSettingIdConfigSettingStateExpiration: + if err = (*u.StateExpirationSettings).EncodeTo(e); err != nil { + return err + } + return nil + case ConfigSettingIdConfigSettingContractExecutionLanes: + if err = (*u.ContractExecutionLanes).EncodeTo(e); err != nil { + return err + } + return nil } return fmt.Errorf("ConfigSettingId (ConfigSettingId) switch value '%d' is not valid for union ConfigSettingEntry", u.ConfigSettingId) } @@ -51871,6 +53414,22 @@ func (u *ConfigSettingEntry) DecodeFrom(d *xdr.Decoder) (int, error) { return n, fmt.Errorf("decoding Uint32: %s", err) } return n, nil + case ConfigSettingIdConfigSettingStateExpiration: + u.StateExpirationSettings = new(StateExpirationSettings) + nTmp, err = (*u.StateExpirationSettings).DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding StateExpirationSettings: %s", err) + } + return n, nil + case ConfigSettingIdConfigSettingContractExecutionLanes: + u.ContractExecutionLanes = new(ConfigSettingContractExecutionLanesV0) + nTmp, err = (*u.ContractExecutionLanes).DecodeFrom(d) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ConfigSettingContractExecutionLanesV0: %s", err) + } + return n, nil } return n, fmt.Errorf("union ConfigSettingEntry has invalid ConfigSettingId (ConfigSettingId) switch value '%d'", u.ConfigSettingId) } From 2f79d88376364f3b5f5cc1373bc5e7aaf248edb6 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 16 Jun 2023 16:27:04 +0100 Subject: [PATCH 06/12] Update ledgerTransaction.GetOperationEvents --- ingest/ledger_transaction.go | 37 ++-- ingest/ledger_transaction_test.go | 274 +++++++++++++----------------- 2 files changed, 137 insertions(+), 174 deletions(-) diff --git a/ingest/ledger_transaction.go b/ingest/ledger_transaction.go index 9be801ec45..670b78a790 100644 --- a/ingest/ledger_transaction.go +++ b/ingest/ledger_transaction.go @@ -152,42 +152,43 @@ func operationChanges(ops []xdr.OperationMeta, index uint32) []Change { ) } -// GetDiagnosticEvents returns all contract events emitted by a given operation. -func (t *LedgerTransaction) GetDiagnosticEvents() ([]xdr.DiagnosticEvent, error) { +// GetOperationEvents returns all contract events emitted by a given operation. +func (t *LedgerTransaction) GetOperationEvents(operationIndex uint32) ([]xdr.DiagnosticEvent, error) { // Ignore operations meta if txInternalError https://github.com/stellar/go/issues/2111 if t.txInternalError() { return nil, nil } switch t.UnsafeMeta.V { - case 1: - return nil, nil - case 2: + case 1, 2: return nil, nil case 3: - diagnosticEvents := t.UnsafeMeta.MustV3().DiagnosticEvents - if len(diagnosticEvents) > 0 { - // all contract events and diag events for a single operation(by it's index in the tx) were available - // in tx meta's DiagnosticEvents, no need to look anywhere else for events - return diagnosticEvents, nil + if operationIndex != 0 { + // Soroban only supports a single invokeHostfunction operation by itself + // in the transaction. + return nil, nil } - - contractEvents := t.UnsafeMeta.MustV3().Events - if len(contractEvents) == 0 { - // no events were present in this tx meta + sorobanMeta := t.UnsafeMeta.MustV3().SorobanMeta + if sorobanMeta == nil { return nil, nil } + if len(sorobanMeta.DiagnosticEvents) > 0 { + // There are diagnostic events, so we can infer that they are enabled, + // and will include all events for the operation. + return sorobanMeta.DiagnosticEvents, nil + } // tx meta only provided contract events, no diagnostic events, we convert the contract // event to a diagnostic event, to fit the response interface. - convertedDiagnosticEvents := make([]xdr.DiagnosticEvent, len(contractEvents)) - for i, event := range contractEvents { - convertedDiagnosticEvents[i] = xdr.DiagnosticEvent{ + events := sorobanMeta.Events + diagnosticEvents := make([]xdr.DiagnosticEvent, len(events)) + for i, event := range events { + diagnosticEvents[i] = xdr.DiagnosticEvent{ InSuccessfulContractCall: true, Event: event, } } - return convertedDiagnosticEvents, nil + return diagnosticEvents, nil default: return nil, fmt.Errorf("unsupported TransactionMeta version: %v", t.UnsafeMeta.V) } diff --git a/ingest/ledger_transaction_test.go b/ingest/ledger_transaction_test.go index 9484f8e7e0..630a341022 100644 --- a/ingest/ledger_transaction_test.go +++ b/ingest/ledger_transaction_test.go @@ -21,70 +21,95 @@ func TestChangeAccountChangedExceptSignersInvalidType(t *testing.T) { require.NoError(t, err) } -func TestGetContractEventsEmpty(t *testing.T) { - tx := LedgerTransaction{ - FeeChanges: xdr.LedgerEntryChanges{}, - UnsafeMeta: xdr.TransactionMeta{ - V: 3, - V3: &xdr.TransactionMetaV3{ - Events: []xdr.ContractEvent{}, - }, - }, +func TestGetOperationEvents(t *testing.T) { + values := make([]xdr.Uint32, 3) + for i := range values { + values[i] = xdr.Uint32(i) } - - events, err := tx.GetDiagnosticEvents() - assert.NoError(t, err) - assert.Empty(t, events) -} - -func TestGetContractEventsSingle(t *testing.T) { - value := xdr.Uint32(1) tx := LedgerTransaction{ FeeChanges: xdr.LedgerEntryChanges{}, UnsafeMeta: xdr.TransactionMeta{ V: 3, V3: &xdr.TransactionMetaV3{ - Events: []xdr.ContractEvent{ - { - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &value}, + Events: []xdr.OperationEvents{ + {Events: []xdr.ContractEvent{ + { + Type: xdr.ContractEventTypeSystem, + Body: xdr.ContractEventBody{ + V: 0, + V0: &xdr.ContractEventV0{ + Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[0]}, + }, }, }, - }, + }}, + {Events: []xdr.ContractEvent{}}, + {Events: []xdr.ContractEvent{ + { + Type: xdr.ContractEventTypeSystem, + Body: xdr.ContractEventBody{ + V: 0, + V0: &xdr.ContractEventV0{ + Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[1]}, + }, + }, + }, + { + Type: xdr.ContractEventTypeSystem, + Body: xdr.ContractEventBody{ + V: 0, + V0: &xdr.ContractEventV0{ + Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[2]}, + }, + }, + }, + }}, }, }, - }, - } - - events, err := tx.GetDiagnosticEvents() + }} + events, err := tx.GetOperationEvents(0) + assert.NoError(t, err) assert.Len(t, events, 1) assert.True(t, events[0].InSuccessfulContractCall) - assert.Equal(t, *events[0].Event.Body.V0.Data.U32, value) + assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[0]) + + events, err = tx.GetOperationEvents(1) + assert.NoError(t, err) + assert.Empty(t, events) + + events, err = tx.GetOperationEvents(2) + assert.NoError(t, err) + assert.Len(t, events, 2) + assert.True(t, events[0].InSuccessfulContractCall) + assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[1]) + assert.True(t, events[1].InSuccessfulContractCall) + assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[2]) + + events, err = tx.GetOperationEvents(3) + assert.NoError(t, err) + assert.Empty(t, events) tx.UnsafeMeta.V = 0 - _, err = tx.GetDiagnosticEvents() + _, err = tx.GetOperationEvents(0) assert.EqualError(t, err, "unsupported TransactionMeta version: 0") tx.UnsafeMeta.V = 4 - _, err = tx.GetDiagnosticEvents() + _, err = tx.GetOperationEvents(0) assert.EqualError(t, err, "unsupported TransactionMeta version: 4") tx.UnsafeMeta.V = 1 - events, err = tx.GetDiagnosticEvents() + events, err = tx.GetOperationEvents(0) assert.NoError(t, err) assert.Empty(t, events) tx.UnsafeMeta.V = 2 - events, err = tx.GetDiagnosticEvents() + events, err = tx.GetOperationEvents(0) assert.NoError(t, err) assert.Empty(t, events) } -func TestGetContractEventsMultiple(t *testing.T) { - values := make([]xdr.Uint32, 2) +func TestGetDiagnosticEvents(t *testing.T) { + values := make([]xdr.Uint32, 3) for i := range values { values[i] = xdr.Uint32(i) } @@ -93,154 +118,91 @@ func TestGetContractEventsMultiple(t *testing.T) { UnsafeMeta: xdr.TransactionMeta{ V: 3, V3: &xdr.TransactionMetaV3{ - Events: []xdr.ContractEvent{ - { - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[0]}, - }, - }, - }, - { - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[1]}, + DiagnosticEvents: []xdr.OperationDiagnosticEvents{ + {Events: []xdr.DiagnosticEvent{ + { + InSuccessfulContractCall: false, + Event: xdr.ContractEvent{ + Type: xdr.ContractEventTypeSystem, + Body: xdr.ContractEventBody{ + V: 0, + V0: &xdr.ContractEventV0{ + Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[0]}, + }, + }, }, }, - }, + }}, + {Events: []xdr.DiagnosticEvent{}}, + {Events: []xdr.DiagnosticEvent{ + { + InSuccessfulContractCall: true, + + Event: xdr.ContractEvent{ + Type: xdr.ContractEventTypeSystem, + Body: xdr.ContractEventBody{ + V: 0, + V0: &xdr.ContractEventV0{ + Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[1]}, + }, + }, + }}, + { + InSuccessfulContractCall: true, + Event: xdr.ContractEvent{ + Type: xdr.ContractEventTypeSystem, + Body: xdr.ContractEventBody{ + V: 0, + V0: &xdr.ContractEventV0{ + Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[2]}, + }, + }, + }}, + }}, }, }, - }, - } - events, err := tx.GetDiagnosticEvents() + }} + events, err := tx.GetOperationEvents(0) assert.NoError(t, err) - assert.Len(t, events, 2) - assert.True(t, events[0].InSuccessfulContractCall) + assert.Len(t, events, 1) + assert.False(t, events[0].InSuccessfulContractCall) assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[0]) - assert.True(t, events[1].InSuccessfulContractCall) - assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[1]) -} - -func TestGetDiagnosticEventsEmpty(t *testing.T) { - tx := LedgerTransaction{ - FeeChanges: xdr.LedgerEntryChanges{}, - UnsafeMeta: xdr.TransactionMeta{ - V: 3, - V3: &xdr.TransactionMetaV3{ - DiagnosticEvents: []xdr.DiagnosticEvent{}, - }, - }, - } - events, err := tx.GetDiagnosticEvents() + events, err = tx.GetOperationEvents(1) assert.NoError(t, err) assert.Empty(t, events) -} -func TestGetDiagnosticEventsSingle(t *testing.T) { - value := xdr.Uint32(1) - tx := LedgerTransaction{ - FeeChanges: xdr.LedgerEntryChanges{}, - UnsafeMeta: xdr.TransactionMeta{ - V: 3, - V3: &xdr.TransactionMetaV3{ - DiagnosticEvents: []xdr.DiagnosticEvent{ - { - InSuccessfulContractCall: false, - Event: xdr.ContractEvent{ - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &value}, - }, - }, - }, - }, - }, - }, - }, - } + events, err = tx.GetOperationEvents(2) + assert.NoError(t, err) + assert.Len(t, events, 2) + assert.True(t, events[0].InSuccessfulContractCall) + assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[1]) + assert.True(t, events[1].InSuccessfulContractCall) + assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[2]) - events, err := tx.GetDiagnosticEvents() + events, err = tx.GetOperationEvents(3) assert.NoError(t, err) - assert.Len(t, events, 1) - assert.False(t, events[0].InSuccessfulContractCall) - assert.Equal(t, *events[0].Event.Body.V0.Data.U32, value) + assert.Empty(t, events) tx.UnsafeMeta.V = 0 - _, err = tx.GetDiagnosticEvents() + _, err = tx.GetOperationEvents(0) assert.EqualError(t, err, "unsupported TransactionMeta version: 0") tx.UnsafeMeta.V = 4 - _, err = tx.GetDiagnosticEvents() + _, err = tx.GetOperationEvents(0) assert.EqualError(t, err, "unsupported TransactionMeta version: 4") tx.UnsafeMeta.V = 1 - events, err = tx.GetDiagnosticEvents() + events, err = tx.GetOperationEvents(0) assert.NoError(t, err) assert.Empty(t, events) tx.UnsafeMeta.V = 2 - events, err = tx.GetDiagnosticEvents() + events, err = tx.GetOperationEvents(0) assert.NoError(t, err) assert.Empty(t, events) } -func TestGetDiagnosticEventsMultiple(t *testing.T) { - values := make([]xdr.Uint32, 2) - for i := range values { - values[i] = xdr.Uint32(i) - } - tx := LedgerTransaction{ - FeeChanges: xdr.LedgerEntryChanges{}, - UnsafeMeta: xdr.TransactionMeta{ - V: 3, - V3: &xdr.TransactionMetaV3{ - DiagnosticEvents: []xdr.DiagnosticEvent{ - { - InSuccessfulContractCall: true, - - Event: xdr.ContractEvent{ - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[0]}, - }, - }, - }, - }, - { - InSuccessfulContractCall: true, - Event: xdr.ContractEvent{ - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[1]}, - }, - }, - }, - }, - }, - }, - }, - } - - events, err := tx.GetDiagnosticEvents() - assert.NoError(t, err) - assert.Len(t, events, 2) - assert.True(t, events[0].InSuccessfulContractCall) - assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[0]) - assert.True(t, events[1].InSuccessfulContractCall) - assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[1]) -} - func TestFeeMetaAndOperationsChangesSeparate(t *testing.T) { tx := LedgerTransaction{ FeeChanges: xdr.LedgerEntryChanges{ From 30e4334692ad5541fd4bc6872b446bc26f2a024d Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 16 Jun 2023 16:27:25 +0100 Subject: [PATCH 07/12] Make LedgerChangeReader emit evictions --- ingest/change.go | 32 ++++++++++++++++++++++++++++++++ ingest/ledger_change_reader.go | 13 +++++++++++-- 2 files changed, 43 insertions(+), 2 deletions(-) diff --git a/ingest/change.go b/ingest/change.go index 11877cde61..6620a40f24 100644 --- a/ingest/change.go +++ b/ingest/change.go @@ -68,6 +68,38 @@ func GetChangesFromLedgerEntryChanges(ledgerEntryChanges xdr.LedgerEntryChanges) return changes } +// GetChangesFromLedgerEntryEvictions transforms evicted LedgerKeys to []Change. +// The generated changes always remove the entries. +func GetChangesFromLedgerEntryEvictions(keys []xdr.LedgerKey) []Change { + changes := []Change{} + + for _, key := range keys { + state := xdr.LedgerEntry{} + switch key.Type { + case xdr.LedgerEntryTypeContractData: + state.Data.SetContractData(&xdr.ContractDataEntry{ + ContractId: key.ContractData.ContractId, + Key: key.ContractData.Key, + }) + case xdr.LedgerEntryTypeContractCode: + state.Data.SetContractCode(&xdr.ContractCodeEntry{ + Hash: key.ContractCode.Hash, + }) + default: + // Currently only contractData and contractCode are evicted by core, so + // we only need to handle those two. + panic("Invalid LedgerEntry eviction type") + } + changes = append(changes, Change{ + Type: key.Type, + Pre: &state, + Post: nil, + }) + } + + return changes +} + // LedgerEntryChangeType returns type in terms of LedgerEntryChangeType. func (c *Change) LedgerEntryChangeType() xdr.LedgerEntryChangeType { switch { diff --git a/ingest/ledger_change_reader.go b/ingest/ledger_change_reader.go index 0425b63a94..5b10e8c68e 100644 --- a/ingest/ledger_change_reader.go +++ b/ingest/ledger_change_reader.go @@ -25,9 +25,11 @@ type ledgerChangeReaderState int const ( // feeChangesState is active when LedgerChangeReader is reading fee changes. feeChangesState ledgerChangeReaderState = iota - // feeChangesState is active when LedgerChangeReader is reading transaction meta changes. + // metaChangesState is active when LedgerChangeReader is reading transaction meta changes. metaChangesState - // feeChangesState is active when LedgerChangeReader is reading upgrade changes. + // evictionChangesState is active when LedgerChangeReader is reading ledger entry evictions. + evictionChangesState + // upgradeChanges is active when LedgerChangeReader is reading upgrade changes. upgradeChangesState ) @@ -122,6 +124,13 @@ func (r *LedgerChangeReader) Read() (Change, error) { r.pending = append(r.pending, metaChanges...) } return r.Read() + case evictionChangesState: + // Get contract ledgerEntry evictions + changes := GetChangesFromLedgerEntryEvictions( + r.LedgerTransactionReader.ledgerCloseMeta.EvictedLedgerKeys(), + ) + r.pending = append(r.pending, changes...) + return r.Read() case upgradeChangesState: // Get upgrade changes if r.upgradeIndex < len(r.LedgerTransactionReader.ledgerCloseMeta.UpgradesProcessing()) { From d5515f074841ba44413b775be8facc789cf7ffbf Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Wed, 28 Jun 2023 13:33:14 +0100 Subject: [PATCH 08/12] Fixing up after merge --- ingest/change.go | 3 +- ingest/ledger_change_reader.go | 1 + ingest/ledger_transaction.go | 26 ++---- ingest/ledger_transaction_test.go | 142 +----------------------------- xdr/ledger_close_meta.go | 39 +++++--- 5 files changed, 42 insertions(+), 169 deletions(-) diff --git a/ingest/change.go b/ingest/change.go index 6620a40f24..8f405bd2d4 100644 --- a/ingest/change.go +++ b/ingest/change.go @@ -78,8 +78,9 @@ func GetChangesFromLedgerEntryEvictions(keys []xdr.LedgerKey) []Change { switch key.Type { case xdr.LedgerEntryTypeContractData: state.Data.SetContractData(&xdr.ContractDataEntry{ - ContractId: key.ContractData.ContractId, + Contract: key.ContractData.Contract, Key: key.ContractData.Key, + Durability: key.ContractData.Durability, }) case xdr.LedgerEntryTypeContractCode: state.Data.SetContractCode(&xdr.ContractCodeEntry{ diff --git a/ingest/ledger_change_reader.go b/ingest/ledger_change_reader.go index 5b10e8c68e..93985c7104 100644 --- a/ingest/ledger_change_reader.go +++ b/ingest/ledger_change_reader.go @@ -130,6 +130,7 @@ func (r *LedgerChangeReader) Read() (Change, error) { r.LedgerTransactionReader.ledgerCloseMeta.EvictedLedgerKeys(), ) r.pending = append(r.pending, changes...) + r.state++ return r.Read() case upgradeChangesState: // Get upgrade changes diff --git a/ingest/ledger_transaction.go b/ingest/ledger_transaction.go index 2476501a8b..5c300216d2 100644 --- a/ingest/ledger_transaction.go +++ b/ingest/ledger_transaction.go @@ -152,15 +152,17 @@ func operationChanges(ops []xdr.OperationMeta, index uint32) []Change { ) } -// GetOperationEvents returns all contract events emitted by a given operation. -func (t *LedgerTransaction) GetOperationEvents(operationIndex uint32) ([]xdr.DiagnosticEvent, error) { +// GetDiagnosticEvents returns all contract events emitted by a given operation. +func (t *LedgerTransaction) GetDiagnosticEvents() ([]xdr.DiagnosticEvent, error) { // Ignore operations meta if txInternalError https://github.com/stellar/go/issues/2111 if t.txInternalError() { return nil, nil } switch t.UnsafeMeta.V { - case 1, 2: + case 1: + return nil, nil + case 2: return nil, nil case 3: var diagnosticEvents []xdr.DiagnosticEvent @@ -179,27 +181,17 @@ func (t *LedgerTransaction) GetOperationEvents(operationIndex uint32) ([]xdr.Dia return nil, nil } } - sorobanMeta := t.UnsafeMeta.MustV3().SorobanMeta - if sorobanMeta == nil { - return nil, nil - } - if len(sorobanMeta.DiagnosticEvents) > 0 { - // There are diagnostic events, so we can infer that they are enabled, - // and will include all events for the operation. - return sorobanMeta.DiagnosticEvents, nil - } // tx meta only provided contract events, no diagnostic events, we convert the contract // event to a diagnostic event, to fit the response interface. - events := sorobanMeta.Events - diagnosticEvents := make([]xdr.DiagnosticEvent, len(events)) - for i, event := range events { - diagnosticEvents[i] = xdr.DiagnosticEvent{ + convertedDiagnosticEvents := make([]xdr.DiagnosticEvent, len(contractEvents)) + for i, event := range contractEvents { + convertedDiagnosticEvents[i] = xdr.DiagnosticEvent{ InSuccessfulContractCall: true, Event: event, } } - return diagnosticEvents, nil + return convertedDiagnosticEvents, nil default: return nil, fmt.Errorf("unsupported TransactionMeta version: %v", t.UnsafeMeta.V) } diff --git a/ingest/ledger_transaction_test.go b/ingest/ledger_transaction_test.go index 16fb7f2549..9a4230d359 100644 --- a/ingest/ledger_transaction_test.go +++ b/ingest/ledger_transaction_test.go @@ -238,157 +238,19 @@ func TestGetDiagnosticEventsMultiple(t *testing.T) { }, }, }, - { - InSuccessfulContractCall: true, - Event: xdr.ContractEvent{ - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[2]}, - }, - }, - }, - }, }, }, }, }, } - events, err := tx.GetOperationEvents(0) - assert.NoError(t, err) - assert.Len(t, events, 1) - assert.True(t, events[0].InSuccessfulContractCall) - assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[0]) - - events, err = tx.GetOperationEvents(1) - assert.NoError(t, err) - assert.Empty(t, events) - events, err = tx.GetOperationEvents(2) + events, err := tx.GetDiagnosticEvents() assert.NoError(t, err) assert.Len(t, events, 2) assert.True(t, events[0].InSuccessfulContractCall) - assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[1]) - assert.True(t, events[1].InSuccessfulContractCall) - assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[2]) - - events, err = tx.GetOperationEvents(3) - assert.NoError(t, err) - assert.Empty(t, events) - - tx.UnsafeMeta.V = 0 - _, err = tx.GetOperationEvents(0) - assert.EqualError(t, err, "unsupported TransactionMeta version: 0") - - tx.UnsafeMeta.V = 4 - _, err = tx.GetOperationEvents(0) - assert.EqualError(t, err, "unsupported TransactionMeta version: 4") - - tx.UnsafeMeta.V = 1 - events, err = tx.GetOperationEvents(0) - assert.NoError(t, err) - assert.Empty(t, events) - - tx.UnsafeMeta.V = 2 - events, err = tx.GetOperationEvents(0) - assert.NoError(t, err) - assert.Empty(t, events) -} - -func TestGetDiagnosticEvents(t *testing.T) { - values := make([]xdr.Uint32, 3) - for i := range values { - values[i] = xdr.Uint32(i) - } - tx := LedgerTransaction{ - FeeChanges: xdr.LedgerEntryChanges{}, - UnsafeMeta: xdr.TransactionMeta{ - V: 3, - V3: &xdr.TransactionMetaV3{ - DiagnosticEvents: []xdr.OperationDiagnosticEvents{ - {Events: []xdr.DiagnosticEvent{ - { - InSuccessfulContractCall: false, - Event: xdr.ContractEvent{ - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[0]}, - }, - }, - }, - }, - }}, - {Events: []xdr.DiagnosticEvent{}}, - {Events: []xdr.DiagnosticEvent{ - { - InSuccessfulContractCall: true, - - Event: xdr.ContractEvent{ - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[1]}, - }, - }, - }}, - { - InSuccessfulContractCall: true, - Event: xdr.ContractEvent{ - Type: xdr.ContractEventTypeSystem, - Body: xdr.ContractEventBody{ - V: 0, - V0: &xdr.ContractEventV0{ - Data: xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &values[2]}, - }, - }, - }}, - }}, - }, - }, - }} - events, err := tx.GetOperationEvents(0) - assert.NoError(t, err) - assert.Len(t, events, 1) - assert.False(t, events[0].InSuccessfulContractCall) assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[0]) - - events, err = tx.GetOperationEvents(1) - assert.NoError(t, err) - assert.Empty(t, events) - - events, err = tx.GetOperationEvents(2) - assert.NoError(t, err) - assert.Len(t, events, 2) - assert.True(t, events[0].InSuccessfulContractCall) - assert.Equal(t, *events[0].Event.Body.V0.Data.U32, values[1]) assert.True(t, events[1].InSuccessfulContractCall) - assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[2]) - - events, err = tx.GetOperationEvents(3) - assert.NoError(t, err) - assert.Empty(t, events) - - tx.UnsafeMeta.V = 0 - _, err = tx.GetOperationEvents(0) - assert.EqualError(t, err, "unsupported TransactionMeta version: 0") - - tx.UnsafeMeta.V = 4 - _, err = tx.GetOperationEvents(0) - assert.EqualError(t, err, "unsupported TransactionMeta version: 4") - - tx.UnsafeMeta.V = 1 - events, err = tx.GetOperationEvents(0) - assert.NoError(t, err) - assert.Empty(t, events) - - tx.UnsafeMeta.V = 2 - events, err = tx.GetOperationEvents(0) - assert.NoError(t, err) - assert.Empty(t, events) + assert.Equal(t, *events[1].Event.Body.V0.Data.U32, values[1]) } func TestFeeMetaAndOperationsChangesSeparate(t *testing.T) { diff --git a/xdr/ledger_close_meta.go b/xdr/ledger_close_meta.go index b5244a1eee..b2d6153572 100644 --- a/xdr/ledger_close_meta.go +++ b/xdr/ledger_close_meta.go @@ -52,20 +52,14 @@ func (l LedgerCloseMeta) TransactionEnvelopes() []TransactionEnvelope { switch l.V { case 0: return l.MustV0().TxSet.Txs - case 1: + case 1, 2: var envelopes = make([]TransactionEnvelope, 0, l.CountTransactions()) var phases []TransactionPhase - phases = l.MustV1().TxSet.V1TxSet.Phases - for _, phase := range phases { - for _, component := range *phase.V0Components { - envelopes = append(envelopes, component.TxsMaybeDiscountedFee.Txs...) - } + if l.V == 1 { + phases = l.MustV1().TxSet.V1TxSet.Phases + } else { + phases = l.MustV2().TxSet.V1TxSet.Phases } - return envelopes - case 2: - var envelopes = make([]TransactionEnvelope, 0, l.CountTransactions()) - var phases []TransactionPhase - phases = l.MustV2().TxSet.V1TxSet.Phases for _, phase := range phases { for _, component := range *phase.V0Components { envelopes = append(envelopes, component.TxsMaybeDiscountedFee.Txs...) @@ -99,6 +93,9 @@ func (l LedgerCloseMeta) TransactionResultPair(i int) TransactionResultPair { case 1: return l.MustV1().TxProcessing[i].Result case 2: + if l.MustV2().TxProcessing[i].TxApplyProcessing.V != 3 { + panic("TransactionResult unavailable because LedgerCloseMeta.V = 2 and TransactionMeta.V != 3") + } return l.MustV2().TxProcessing[i].Result default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) @@ -146,3 +143,23 @@ func (l LedgerCloseMeta) UpgradesProcessing() []UpgradeEntryMeta { panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) } } + +// EvictedTemporaryLedgerKeys []LedgerKey +// EvictedPersistentLedgerEntries []LedgerEntry +// EvictedLedgerKeys returns the LedgerKeys for the EvictedTemporaryLedgerKeys +// and EvictedPersistentLedgerEntrues for ledger. +func (l LedgerCloseMeta) EvictedLedgerKeys() []LedgerKey { + switch l.V { + case 0, 1: + return nil + case 2: + var keys []LedgerKey + keys = append(keys, l.MustV2().EvictedTemporaryLedgerKeys...) + for _, entry := range l.MustV2().EvictedPersistentLedgerEntries { + keys = append(keys, entry.LedgerKey()) + } + return keys + default: + panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) + } +} From 8ee67ed79a0d5f89c01876caa808b4d269fe901b Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 30 Jun 2023 13:46:13 +0100 Subject: [PATCH 09/12] Add test for LedgerChangeReader extensions and evictions --- ingest/ledger_change_reader.go | 2 +- ingest/ledger_change_reader_test.go | 462 +++++++++++++++++++++++++--- 2 files changed, 413 insertions(+), 51 deletions(-) diff --git a/ingest/ledger_change_reader.go b/ingest/ledger_change_reader.go index 93985c7104..47b0b2db52 100644 --- a/ingest/ledger_change_reader.go +++ b/ingest/ledger_change_reader.go @@ -127,7 +127,7 @@ func (r *LedgerChangeReader) Read() (Change, error) { case evictionChangesState: // Get contract ledgerEntry evictions changes := GetChangesFromLedgerEntryEvictions( - r.LedgerTransactionReader.ledgerCloseMeta.EvictedLedgerKeys(), + r.ledgerCloseMeta.EvictedLedgerKeys(), ) r.pending = append(r.pending, changes...) r.state++ diff --git a/ingest/ledger_change_reader_test.go b/ingest/ledger_change_reader_test.go index c461ef28c3..a0a397f9e8 100644 --- a/ingest/ledger_change_reader_test.go +++ b/ingest/ledger_change_reader_test.go @@ -2,6 +2,7 @@ package ingest import ( "context" + "encoding/hex" "fmt" "io" "testing" @@ -77,16 +78,41 @@ func buildChange(account string, balance int64) xdr.LedgerEntryChange { } } -type balanceEntry struct { - address string - balance int64 +type changePredicate func(*testing.T, int, Change) + +func isBalance(address string, balance int64) changePredicate { + return func(t *testing.T, idx int, change Change) { + msg := fmt.Sprintf("change %d", idx) + assert.NotNil(t, change.Post, msg) + assert.Equal(t, xdr.LedgerEntryTypeAccount.String(), change.Post.Data.Type.String(), msg) + assert.Equal(t, address, change.Post.Data.Account.AccountId.Address(), msg) + assert.Equal(t, balance, int64(change.Post.Data.Account.Balance), msg) + } } -func parseChange(change Change) balanceEntry { - address := change.Post.Data.Account.AccountId.Address() - balance := int64(change.Post.Data.Account.Balance) +func isContractDataExtension(contract xdr.ScAddress, key xdr.ScVal, extension uint32) changePredicate { + return func(t *testing.T, idx int, change Change) { + msg := fmt.Sprintf("change %d", idx) + assert.NotNil(t, change.Post, msg) + assert.NotNil(t, change.Pre, msg) + assert.Equal(t, xdr.LedgerEntryTypeContractData.String(), change.Post.Data.Type.String(), msg) + assert.Equal(t, contract, change.Post.Data.ContractData.Contract, msg) + assert.Equal(t, key, change.Post.Data.ContractData.Key, msg) + newExpiry := change.Post.Data.ContractData.ExpirationLedgerSeq + oldExpiry := change.Pre.Data.ContractData.ExpirationLedgerSeq + assert.Equal(t, extension, uint32(newExpiry-oldExpiry), msg) + } +} - return balanceEntry{address, balance} +func isContractDataEviction(contract xdr.ScAddress, key xdr.ScVal) changePredicate { + return func(t *testing.T, idx int, change Change) { + msg := fmt.Sprintf("change %d", idx) + assert.NotNil(t, change.Pre, msg) + assert.Nil(t, change.Post, msg) + assert.Equal(t, xdr.LedgerEntryTypeContractData.String(), change.Pre.Data.Type.String(), msg) + assert.Equal(t, contract, change.Pre.Data.ContractData.Contract, msg) + assert.Equal(t, key, change.Pre.Data.ContractData.Key, msg) + } } func assertChangesEqual( @@ -94,12 +120,13 @@ func assertChangesEqual( ctx context.Context, sequence uint32, backend ledgerbackend.LedgerBackend, - expected []balanceEntry, + expectations []changePredicate, ) { reader, err := NewLedgerChangeReader(ctx, backend, network.TestNetworkPassphrase, sequence) assert.NoError(t, err) - changes := []balanceEntry{} + // Read all the changes + var changes []Change for { change, err := reader.Read() if err == io.EOF { @@ -108,11 +135,15 @@ func assertChangesEqual( if err != nil { t.Fatalf("unexpected error: %v", err) } - - changes = append(changes, parseChange(change)) + changes = append(changes, change) } - assert.Equal(t, expected, changes) + assert.Len(t, changes, len(expectations), "unexpected number of changes") + + // Check each change is what we expect + for i, change := range changes { + expectations[i](t, i+1, change) + } } func TestLedgerChangeReaderOrder(t *testing.T) { @@ -224,18 +255,18 @@ func TestLedgerChangeReaderOrder(t *testing.T) { } mock.On("GetLedger", ctx, seq).Return(ledger, nil).Once() - assertChangesEqual(t, ctx, seq, mock, []balanceEntry{ - {feeAddress, 100}, - {feeAddress, 200}, - {feeAddress, 300}, - {metaAddress, 300}, - {metaAddress, 400}, - {metaAddress, 600}, - {metaAddress, 700}, - {metaAddress, 800}, - {metaAddress, 900}, - {upgradeAddress, 2}, - {upgradeAddress, 3}, + assertChangesEqual(t, ctx, seq, mock, []changePredicate{ + isBalance(feeAddress, 100), + isBalance(feeAddress, 200), + isBalance(feeAddress, 300), + isBalance(metaAddress, 300), + isBalance(metaAddress, 400), + isBalance(metaAddress, 600), + isBalance(metaAddress, 700), + isBalance(metaAddress, 800), + isBalance(metaAddress, 900), + isBalance(upgradeAddress, 2), + isBalance(upgradeAddress, 3), }) mock.AssertExpectations(t) @@ -255,15 +286,15 @@ func TestLedgerChangeReaderOrder(t *testing.T) { ledger.V0.TxProcessing[1].FeeProcessing = xdr.LedgerEntryChanges{} mock.On("GetLedger", ctx, seq).Return(ledger, nil).Once() - assertChangesEqual(t, ctx, seq, mock, []balanceEntry{ - {metaAddress, 300}, - {metaAddress, 400}, - {metaAddress, 600}, - {metaAddress, 700}, - {metaAddress, 800}, - {metaAddress, 900}, - {upgradeAddress, 2}, - {upgradeAddress, 3}, + assertChangesEqual(t, ctx, seq, mock, []changePredicate{ + isBalance(metaAddress, 300), + isBalance(metaAddress, 400), + isBalance(metaAddress, 600), + isBalance(metaAddress, 700), + isBalance(metaAddress, 800), + isBalance(metaAddress, 900), + isBalance(upgradeAddress, 2), + isBalance(upgradeAddress, 3), }) mock.AssertExpectations(t) @@ -272,15 +303,15 @@ func TestLedgerChangeReaderOrder(t *testing.T) { ledger.V0.TxProcessing[1].FeeProcessing = xdr.LedgerEntryChanges{} mock.On("GetLedger", ctx, seq).Return(ledger, nil).Once() - assertChangesEqual(t, ctx, seq, mock, []balanceEntry{ - {metaAddress, 300}, - {metaAddress, 400}, - {metaAddress, 600}, - {metaAddress, 700}, - {metaAddress, 800}, - {metaAddress, 900}, - {upgradeAddress, 2}, - {upgradeAddress, 3}, + assertChangesEqual(t, ctx, seq, mock, []changePredicate{ + isBalance(metaAddress, 300), + isBalance(metaAddress, 400), + isBalance(metaAddress, 600), + isBalance(metaAddress, 700), + isBalance(metaAddress, 800), + isBalance(metaAddress, 900), + isBalance(upgradeAddress, 2), + isBalance(upgradeAddress, 3), }) mock.AssertExpectations(t) @@ -294,13 +325,13 @@ func TestLedgerChangeReaderOrder(t *testing.T) { } mock.On("GetLedger", ctx, seq).Return(ledger, nil).Once() - assertChangesEqual(t, ctx, seq, mock, []balanceEntry{ - {metaAddress, 300}, - {metaAddress, 400}, - {metaAddress, 600}, - {metaAddress, 700}, - {metaAddress, 800}, - {metaAddress, 900}, + assertChangesEqual(t, ctx, seq, mock, []changePredicate{ + isBalance(metaAddress, 300), + isBalance(metaAddress, 400), + isBalance(metaAddress, 600), + isBalance(metaAddress, 700), + isBalance(metaAddress, 800), + isBalance(metaAddress, 900), }) mock.AssertExpectations(t) @@ -318,6 +349,337 @@ func TestLedgerChangeReaderOrder(t *testing.T) { } mock.On("GetLedger", ctx, seq).Return(ledger, nil).Once() - assertChangesEqual(t, ctx, seq, mock, []balanceEntry{}) + assertChangesEqual(t, ctx, seq, mock, []changePredicate{}) + mock.AssertExpectations(t) +} + +func TestLedgerChangeLedgerCloseMetaV2(t *testing.T) { + ctx := context.Background() + mock := &ledgerbackend.MockDatabaseBackend{} + seq := uint32(123) + + src := xdr.MustAddress("GBXGQJWVLWOYHFLVTKWV5FGHA3LNYY2JQKM7OAJAUEQFU6LPCSEFVXON") + firstTx := xdr.TransactionEnvelope{ + Type: xdr.EnvelopeTypeEnvelopeTypeTx, + V1: &xdr.TransactionV1Envelope{ + Tx: xdr.Transaction{ + Fee: 1, + SourceAccount: src.ToMuxedAccount(), + }, + }, + } + firstTxHash, err := network.HashTransactionInEnvelope(firstTx, network.TestNetworkPassphrase) + assert.NoError(t, err) + + src = xdr.MustAddress("GCXKG6RN4ONIEPCMNFB732A436Z5PNDSRLGWK7GBLCMQLIFO4S7EYWVU") + secondTx := xdr.TransactionEnvelope{ + Type: xdr.EnvelopeTypeEnvelopeTypeTx, + V1: &xdr.TransactionV1Envelope{ + Tx: xdr.Transaction{ + Fee: 2, + SourceAccount: src.ToMuxedAccount(), + }, + }, + } + secondTxHash, err := network.HashTransactionInEnvelope(secondTx, network.TestNetworkPassphrase) + assert.NoError(t, err) + + baseFee := xdr.Int64(100) + tempKey := xdr.ScSymbol("TEMPKEY") + persistentKey := xdr.ScSymbol("TEMPVAL") + persistentVal := xdr.ScSymbol("PERSVAL") + contractIdBytes, err := hex.DecodeString("df06d62447fd25da07c0135eed7557e5a5497ee7d15b7fe345bd47e191d8f577") + assert.NoError(t, err) + var contractId xdr.Hash + copy(contractId[:], contractIdBytes) + contractAddress := xdr.ScAddress{ + Type: xdr.ScAddressTypeScAddressTypeContract, + ContractId: &contractId, + } + val := xdr.Uint32(123) + ledger := xdr.LedgerCloseMeta{ + V: 2, + V2: &xdr.LedgerCloseMetaV2{ + LedgerHeader: xdr.LedgerHeaderHistoryEntry{Header: xdr.LedgerHeader{LedgerVersion: 10}}, + TxSet: xdr.GeneralizedTransactionSet{ + V: 1, + V1TxSet: &xdr.TransactionSetV1{ + PreviousLedgerHash: xdr.Hash{1, 2, 3}, + Phases: []xdr.TransactionPhase{ + { + V0Components: &[]xdr.TxSetComponent{ + { + Type: xdr.TxSetComponentTypeTxsetCompTxsMaybeDiscountedFee, + TxsMaybeDiscountedFee: &xdr.TxSetComponentTxsMaybeDiscountedFee{ + BaseFee: &baseFee, + Txs: []xdr.TransactionEnvelope{ + secondTx, + firstTx, + }, + }, + }, + }, + }, + }, + }, + }, + TxProcessing: []xdr.TransactionResultMeta{ + { + Result: xdr.TransactionResultPair{TransactionHash: firstTxHash}, + FeeProcessing: xdr.LedgerEntryChanges{ + buildChange(feeAddress, 100), + buildChange(feeAddress, 200), + }, + TxApplyProcessing: xdr.TransactionMeta{ + V: 3, + V3: &xdr.TransactionMetaV3{ + Operations: []xdr.OperationMeta{ + { + Changes: xdr.LedgerEntryChanges{ + buildChange( + metaAddress, + 300, + ), + buildChange( + metaAddress, + 400, + ), + + // Add a couple changes simulating a ledger entry extension + { + Type: xdr.LedgerEntryChangeTypeLedgerEntryState, + State: &xdr.LedgerEntry{ + LastModifiedLedgerSeq: 1, + Data: xdr.LedgerEntryData{ + Type: xdr.LedgerEntryTypeContractData, + ContractData: &xdr.ContractDataEntry{ + Contract: contractAddress, + Key: xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &persistentKey, + }, + Durability: xdr.ContractDataDurabilityPersistent, + Body: xdr.ContractDataEntryBody{ + BodyType: xdr.ContractEntryBodyTypeDataEntry, + Data: &xdr.ContractDataEntryData{ + Flags: 0, + Val: xdr.ScVal{ + Type: xdr.ScValTypeScvU32, + U32: &val, + }, + }, + }, + ExpirationLedgerSeq: 4097, + }, + }, + }, + }, + { + Type: xdr.LedgerEntryChangeTypeLedgerEntryUpdated, + Updated: &xdr.LedgerEntry{ + LastModifiedLedgerSeq: 1, + Data: xdr.LedgerEntryData{ + Type: xdr.LedgerEntryTypeContractData, + ContractData: &xdr.ContractDataEntry{ + Contract: xdr.ScAddress{ + Type: xdr.ScAddressTypeScAddressTypeContract, + ContractId: &contractId, + }, + Key: xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &persistentKey, + }, + Durability: xdr.ContractDataDurabilityPersistent, + Body: xdr.ContractDataEntryBody{ + BodyType: xdr.ContractEntryBodyTypeDataEntry, + Data: &xdr.ContractDataEntryData{ + Flags: 0, + Val: xdr.ScVal{ + Type: xdr.ScValTypeScvU32, + U32: &val, + }, + }, + }, + ExpirationLedgerSeq: 10001, + }, + }, + }, + }, + }, + }, + }, + }, + }, + }, + { + Result: xdr.TransactionResultPair{TransactionHash: secondTxHash}, + FeeProcessing: xdr.LedgerEntryChanges{ + buildChange(feeAddress, 300), + }, + TxApplyProcessing: xdr.TransactionMeta{ + V: 3, + V3: &xdr.TransactionMetaV3{ + TxChangesBefore: xdr.LedgerEntryChanges{ + buildChange(metaAddress, 600), + }, + Operations: []xdr.OperationMeta{ + { + Changes: xdr.LedgerEntryChanges{ + buildChange(metaAddress, 700), + }, + }, + }, + TxChangesAfter: xdr.LedgerEntryChanges{ + buildChange(metaAddress, 800), + buildChange(metaAddress, 900), + }, + }, + }, + }, + }, + UpgradesProcessing: []xdr.UpgradeEntryMeta{ + { + Changes: xdr.LedgerEntryChanges{ + buildChange(upgradeAddress, 2), + }, + }, + { + Changes: xdr.LedgerEntryChanges{ + buildChange(upgradeAddress, 3), + }, + }, + }, + EvictedTemporaryLedgerKeys: []xdr.LedgerKey{ + { + Type: xdr.LedgerEntryTypeContractData, + ContractData: &xdr.LedgerKeyContractData{ + Contract: contractAddress, + Key: xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &tempKey, + }, + Durability: xdr.ContractDataDurabilityTemporary, + BodyType: xdr.ContractEntryBodyTypeDataEntry, + }, + }, + }, + EvictedPersistentLedgerEntries: []xdr.LedgerEntry{ + { + LastModifiedLedgerSeq: 123, + Data: xdr.LedgerEntryData{ + Type: xdr.LedgerEntryTypeContractData, + ContractData: &xdr.ContractDataEntry{ + Contract: contractAddress, + Key: xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &persistentKey, + }, + Durability: xdr.ContractDataDurabilityTemporary, + Body: xdr.ContractDataEntryBody{ + BodyType: xdr.ContractEntryBodyTypeDataEntry, + Data: &xdr.ContractDataEntryData{ + Val: xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &persistentVal, + }, + }, + }, + ExpirationLedgerSeq: xdr.Uint32(123), + }, + }, + }, + }, + }, + } + mock.On("GetLedger", ctx, seq).Return(ledger, nil).Once() + + // Check the changes are as expected + assertChangesEqual(t, ctx, seq, mock, []changePredicate{ + // First the first txn balance xfers + isBalance(feeAddress, 100), + isBalance(feeAddress, 200), + isBalance(feeAddress, 300), + isBalance(metaAddress, 300), + isBalance(metaAddress, 400), + // Then the first txn data entry extension + isContractDataExtension( + contractAddress, + xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &persistentKey, + }, + 5904, + ), + + // Second txn transfers + isBalance(metaAddress, 600), + isBalance(metaAddress, 700), + isBalance(metaAddress, 800), + isBalance(metaAddress, 900), + + // Evictions + isContractDataEviction( + contractAddress, + xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &tempKey, + }, + ), + isContractDataEviction( + contractAddress, + xdr.ScVal{ + Type: xdr.ScValTypeScvSymbol, + Sym: &persistentKey, + }, + ), + + // Upgrades last + isBalance(upgradeAddress, 2), + isBalance(upgradeAddress, 3), + }) + mock.AssertExpectations(t) + + mock.AssertExpectations(t) +} + +func TestLedgerChangeLedgerCloseMetaV2Empty(t *testing.T) { + ctx := context.Background() + mock := &ledgerbackend.MockDatabaseBackend{} + seq := uint32(123) + + baseFee := xdr.Int64(100) + ledger := xdr.LedgerCloseMeta{ + V: 2, + V2: &xdr.LedgerCloseMetaV2{ + LedgerHeader: xdr.LedgerHeaderHistoryEntry{Header: xdr.LedgerHeader{LedgerVersion: 10}}, + TxSet: xdr.GeneralizedTransactionSet{ + V: 1, + V1TxSet: &xdr.TransactionSetV1{ + PreviousLedgerHash: xdr.Hash{1, 2, 3}, + Phases: []xdr.TransactionPhase{ + { + V0Components: &[]xdr.TxSetComponent{ + { + Type: xdr.TxSetComponentTypeTxsetCompTxsMaybeDiscountedFee, + TxsMaybeDiscountedFee: &xdr.TxSetComponentTxsMaybeDiscountedFee{ + BaseFee: &baseFee, + Txs: []xdr.TransactionEnvelope{}, + }, + }, + }, + }, + }, + }, + }, + TxProcessing: []xdr.TransactionResultMeta{}, + UpgradesProcessing: []xdr.UpgradeEntryMeta{}, + EvictedTemporaryLedgerKeys: []xdr.LedgerKey{}, + EvictedPersistentLedgerEntries: []xdr.LedgerEntry{}, + }, + } + mock.On("GetLedger", ctx, seq).Return(ledger, nil).Once() + + // Check there are no changes + assertChangesEqual(t, ctx, seq, mock, []changePredicate{}) mock.AssertExpectations(t) } From 8685682e834ff6816872bff9858b033fc46bbc73 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 30 Jun 2023 13:50:55 +0100 Subject: [PATCH 10/12] Fix typo --- xdr/ledger_close_meta.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xdr/ledger_close_meta.go b/xdr/ledger_close_meta.go index b2d6153572..c018f9593d 100644 --- a/xdr/ledger_close_meta.go +++ b/xdr/ledger_close_meta.go @@ -144,16 +144,16 @@ func (l LedgerCloseMeta) UpgradesProcessing() []UpgradeEntryMeta { } } -// EvictedTemporaryLedgerKeys []LedgerKey -// EvictedPersistentLedgerEntries []LedgerEntry -// EvictedLedgerKeys returns the LedgerKeys for the EvictedTemporaryLedgerKeys -// and EvictedPersistentLedgerEntrues for ledger. +// EvictedLedgerKeys returns the LedgerKeys for both the +// EvictedTemporaryLedgerKeys and and the EvictedPersistentLedgerEntries in a +// ledger. func (l LedgerCloseMeta) EvictedLedgerKeys() []LedgerKey { switch l.V { case 0, 1: return nil case 2: - var keys []LedgerKey + v2 := l.MustV2() + keys := make([]LedgerKey, 0, len(v2.EvictedTemporaryLedgerKeys)+len(v2.EvictedPersistentLedgerEntries)) keys = append(keys, l.MustV2().EvictedTemporaryLedgerKeys...) for _, entry := range l.MustV2().EvictedPersistentLedgerEntries { keys = append(keys, entry.LedgerKey()) From 2d2db5ae0455c1d6e466930fe4b27fb6f05f7439 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Fri, 30 Jun 2023 14:00:00 +0100 Subject: [PATCH 11/12] Add xdr.LedgerEntryData.ExpirationLedgerSeq helper --- xdr/ledger_entry.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/xdr/ledger_entry.go b/xdr/ledger_entry.go index f58d2fd2ba..e1c9d3e4ae 100644 --- a/xdr/ledger_entry.go +++ b/xdr/ledger_entry.go @@ -192,3 +192,14 @@ func (data *LedgerEntryData) SetContractCode(entry *ContractCodeEntry) error { } return nil } + +func (data *LedgerEntryData) ExpirationLedgerSeq() (Uint32, bool) { + switch data.Type { + case LedgerEntryTypeContractData: + return data.ContractData.ExpirationLedgerSeq, true + case LedgerEntryTypeContractCode: + return data.ContractCode.ExpirationLedgerSeq, true + default: + return 0, false + } +} From 585f47febf724247380cf33a696f20c0f619c410 Mon Sep 17 00:00:00 2001 From: Paul Bellamy Date: Mon, 3 Jul 2023 11:45:36 +0100 Subject: [PATCH 12/12] review feedback --- ingest/change.go | 17 ++++++++++++----- ingest/ledger_change_reader.go | 7 ++++--- ingest/ledger_change_reader_test.go | 23 ++++++++++++----------- xdr/ledger_close_meta.go | 6 +++--- 4 files changed, 31 insertions(+), 22 deletions(-) diff --git a/ingest/change.go b/ingest/change.go index 8f405bd2d4..f809e62e97 100644 --- a/ingest/change.go +++ b/ingest/change.go @@ -2,6 +2,7 @@ package ingest import ( "bytes" + "fmt" "github.com/stellar/go/support/errors" "github.com/stellar/go/xdr" @@ -70,26 +71,32 @@ func GetChangesFromLedgerEntryChanges(ledgerEntryChanges xdr.LedgerEntryChanges) // GetChangesFromLedgerEntryEvictions transforms evicted LedgerKeys to []Change. // The generated changes always remove the entries. -func GetChangesFromLedgerEntryEvictions(keys []xdr.LedgerKey) []Change { +func GetChangesFromLedgerEntryEvictions(keys []xdr.LedgerKey) ([]Change, error) { changes := []Change{} for _, key := range keys { state := xdr.LedgerEntry{} switch key.Type { case xdr.LedgerEntryTypeContractData: - state.Data.SetContractData(&xdr.ContractDataEntry{ + err := state.Data.SetContractData(&xdr.ContractDataEntry{ Contract: key.ContractData.Contract, Key: key.ContractData.Key, Durability: key.ContractData.Durability, }) + if err != nil { + return nil, errors.Wrap(err, "error setting ContractDataEntry") + } case xdr.LedgerEntryTypeContractCode: - state.Data.SetContractCode(&xdr.ContractCodeEntry{ + err := state.Data.SetContractCode(&xdr.ContractCodeEntry{ Hash: key.ContractCode.Hash, }) + if err != nil { + return nil, errors.Wrap(err, "error setting ContractCodeEntry") + } default: // Currently only contractData and contractCode are evicted by core, so // we only need to handle those two. - panic("Invalid LedgerEntry eviction type") + return nil, fmt.Errorf("invalid LedgerEntry eviction type: %s", key.Type) } changes = append(changes, Change{ Type: key.Type, @@ -98,7 +105,7 @@ func GetChangesFromLedgerEntryEvictions(keys []xdr.LedgerKey) []Change { }) } - return changes + return changes, nil } // LedgerEntryChangeType returns type in terms of LedgerEntryChangeType. diff --git a/ingest/ledger_change_reader.go b/ingest/ledger_change_reader.go index 47b0b2db52..f61c684387 100644 --- a/ingest/ledger_change_reader.go +++ b/ingest/ledger_change_reader.go @@ -126,9 +126,10 @@ func (r *LedgerChangeReader) Read() (Change, error) { return r.Read() case evictionChangesState: // Get contract ledgerEntry evictions - changes := GetChangesFromLedgerEntryEvictions( - r.ledgerCloseMeta.EvictedLedgerKeys(), - ) + changes, err := GetChangesFromLedgerEntryEvictions(r.ledgerCloseMeta.EvictedLedgerKeys()) + if err != nil { + return Change{}, err + } r.pending = append(r.pending, changes...) r.state++ return r.Read() diff --git a/ingest/ledger_change_reader_test.go b/ingest/ledger_change_reader_test.go index a0a397f9e8..5e18c94e97 100644 --- a/ingest/ledger_change_reader_test.go +++ b/ingest/ledger_change_reader_test.go @@ -8,6 +8,7 @@ import ( "testing" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/stellar/go/ingest/ledgerbackend" "github.com/stellar/go/network" @@ -83,31 +84,31 @@ type changePredicate func(*testing.T, int, Change) func isBalance(address string, balance int64) changePredicate { return func(t *testing.T, idx int, change Change) { msg := fmt.Sprintf("change %d", idx) - assert.NotNil(t, change.Post, msg) + require.NotNil(t, change.Post, msg) assert.Equal(t, xdr.LedgerEntryTypeAccount.String(), change.Post.Data.Type.String(), msg) assert.Equal(t, address, change.Post.Data.Account.AccountId.Address(), msg) - assert.Equal(t, balance, int64(change.Post.Data.Account.Balance), msg) + assert.EqualValues(t, balance, change.Post.Data.Account.Balance, msg) } } func isContractDataExtension(contract xdr.ScAddress, key xdr.ScVal, extension uint32) changePredicate { return func(t *testing.T, idx int, change Change) { msg := fmt.Sprintf("change %d", idx) - assert.NotNil(t, change.Post, msg) - assert.NotNil(t, change.Pre, msg) + require.NotNil(t, change.Post, msg) + require.NotNil(t, change.Pre, msg) assert.Equal(t, xdr.LedgerEntryTypeContractData.String(), change.Post.Data.Type.String(), msg) assert.Equal(t, contract, change.Post.Data.ContractData.Contract, msg) assert.Equal(t, key, change.Post.Data.ContractData.Key, msg) newExpiry := change.Post.Data.ContractData.ExpirationLedgerSeq oldExpiry := change.Pre.Data.ContractData.ExpirationLedgerSeq - assert.Equal(t, extension, uint32(newExpiry-oldExpiry), msg) + assert.EqualValues(t, extension, newExpiry-oldExpiry, msg) } } func isContractDataEviction(contract xdr.ScAddress, key xdr.ScVal) changePredicate { return func(t *testing.T, idx int, change Change) { msg := fmt.Sprintf("change %d", idx) - assert.NotNil(t, change.Pre, msg) + require.NotNil(t, change.Pre, msg) assert.Nil(t, change.Post, msg) assert.Equal(t, xdr.LedgerEntryTypeContractData.String(), change.Pre.Data.Type.String(), msg) assert.Equal(t, contract, change.Pre.Data.ContractData.Contract, msg) @@ -388,13 +389,13 @@ func TestLedgerChangeLedgerCloseMetaV2(t *testing.T) { tempKey := xdr.ScSymbol("TEMPKEY") persistentKey := xdr.ScSymbol("TEMPVAL") persistentVal := xdr.ScSymbol("PERSVAL") - contractIdBytes, err := hex.DecodeString("df06d62447fd25da07c0135eed7557e5a5497ee7d15b7fe345bd47e191d8f577") + contractIDBytes, err := hex.DecodeString("df06d62447fd25da07c0135eed7557e5a5497ee7d15b7fe345bd47e191d8f577") assert.NoError(t, err) - var contractId xdr.Hash - copy(contractId[:], contractIdBytes) + var contractID xdr.Hash + copy(contractID[:], contractIDBytes) contractAddress := xdr.ScAddress{ Type: xdr.ScAddressTypeScAddressTypeContract, - ContractId: &contractId, + ContractId: &contractID, } val := xdr.Uint32(123) ledger := xdr.LedgerCloseMeta{ @@ -483,7 +484,7 @@ func TestLedgerChangeLedgerCloseMetaV2(t *testing.T) { ContractData: &xdr.ContractDataEntry{ Contract: xdr.ScAddress{ Type: xdr.ScAddressTypeScAddressTypeContract, - ContractId: &contractId, + ContractId: &contractID, }, Key: xdr.ScVal{ Type: xdr.ScValTypeScvSymbol, diff --git a/xdr/ledger_close_meta.go b/xdr/ledger_close_meta.go index c018f9593d..dbc21e2c7a 100644 --- a/xdr/ledger_close_meta.go +++ b/xdr/ledger_close_meta.go @@ -93,9 +93,6 @@ func (l LedgerCloseMeta) TransactionResultPair(i int) TransactionResultPair { case 1: return l.MustV1().TxProcessing[i].Result case 2: - if l.MustV2().TxProcessing[i].TxApplyProcessing.V != 3 { - panic("TransactionResult unavailable because LedgerCloseMeta.V = 2 and TransactionMeta.V != 3") - } return l.MustV2().TxProcessing[i].Result default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V)) @@ -124,6 +121,9 @@ func (l LedgerCloseMeta) TxApplyProcessing(i int) TransactionMeta { case 1: return l.MustV1().TxProcessing[i].TxApplyProcessing case 2: + if l.MustV2().TxProcessing[i].TxApplyProcessing.V != 3 { + panic("TransactionResult unavailable because LedgerCloseMeta.V = 2 and TransactionMeta.V != 3") + } return l.MustV2().TxProcessing[i].TxApplyProcessing default: panic(fmt.Sprintf("Unsupported LedgerCloseMeta.V: %d", l.V))