diff --git a/CHANGELOG.md b/CHANGELOG.md index 3a6be760e5..8af57a4887 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,15 +13,24 @@ Official project releases may be found here: https://github.com/stellar/go-stell ## Pending ### Breaking Changes +* xdr: Protocol 30 support (CAP-0084, CAP-0087, CAP-0088). Regenerated from stellar-xdr@4f524bba, where all three CAPs are ungated, so `XDR_FEATURES` is now empty. +* xdr: Contract spec UDT and event names are widened to `SC_SPEC_TYPE_NAME_LIMIT` (1024 bytes), and `ScSpecEventV0.Name` is now a `string` instead of an `ScSymbol` ([stellar/stellar-xdr#312](https://github.com/stellar/stellar-xdr/pull/312)). This arrives with the same regeneration but is not part of any CAP. * support/storage, historyarchive: Remove `OnDiskCache`, `MakeOnDiskCache`, `ConnectOptions.Wrap`, `ArchiveBucketCache` and `CacheOptions`. They have had no callers since lighthorizon was removed ([#5334](https://github.com/stellar/go-stellar-sdk/pull/5334)) and Horizon moved to fscache ([#5197](https://github.com/stellar/go-stellar-sdk/pull/5197)). An early exit from a bucket read left a partial file in `OnDiskCache` that later reads served as complete ([#6017](https://github.com/stellar/go-stellar-sdk/pull/6017)) ### New Features +* xdr: Add the CAP-0084 `ScAddressTypeScAddressTypeMuxedContract` arm of `ScAddress`. `ScAddress.String()` renders it as a `W...` muxed contract strkey. +* xdr: Add the CAP-0088 millisecond close-time arms of `StellarValue`: `StellarValueTypeStellarValueSignedMs` (`SignedMsValue`) and `StellarValueTypeStellarValueEmptyTxSetMs` (`ProposedMsValue`), and the `TimePointMs` type. Every ledger after the Protocol 30 upgrade ledger uses one of these arms, so earlier SDK versions cannot decode them. +* xdr: Add the CAP-0087 ML-DSA `ContractCostType` values 86–94 (`MlDsa{44,65,87}DecodeVerifyingKey`, `MlDsa{44,65,87}DecodeSignature`, `VerifyMlDsa{44,65,87}Sig`). These are names only; cost params are positional, so they decoded before. +* xdr: Add `StellarValueExt.LedgerCloseValueSignature()`, which returns the close-value signature from whichever `StellarValue` arm carries one: `SIGNED`, `EMPTY_TX_SET` (CAP-0083), `SIGNED_MS` or `EMPTY_TX_SET_MS` (CAP-0088). The generated `GetLcValueSignature()` only reads the `SIGNED` arm, so it finds no signature on any ledger after the Protocol 30 upgrade. +* strkey: Add `VersionByteMuxedContract` (`W...`), `MuxedContract`, `DecodeMuxedContract`, and `IsValidMuxedContractAddress`. +* protocols/horizon/effects: Add `ContractMuxed` (`contract_muxed`) and `ContractMuxedID` (`contract_muxed_id`) to `ContractCredited`, set when the credit went to a muxed contract address (CAP-0084). * xdr: Added `LedgerCloseMetaView.LedgerHeader()`, exposing the version-resolving header accessor that already backs `LedgerSequence`, `LedgerCloseTime`, `LedgerHash`, and `PreviousLedgerHash` ([#5982](https://github.com/stellar/go-stellar-sdk/pull/5982)) * xdr: Add `Stream.ResumeFrom`, which positions a new stream at the last record boundary of a failed one and continues its SHA-256 from there, so `ValidateHash` on the new stream covers both ([#6017](https://github.com/stellar/go-stellar-sdk/pull/6017)) * rpcclient: Add `Client.URL()` to expose the configured RPC server URL ([#5885](https://github.com/stellar/go-stellar-sdk/issues/5885)) * protocols/rpc: Add queryEvents wire types and request validation (`QueryEventsRequest`/`QueryEventsResponse`, `QueryEventsFilter`, scan statuses, typed `error.data` payloads), transcribed from the [accepted proposal](https://github.com/orgs/stellar/discussions/1872) ([#5971](https://github.com/stellar/go-stellar-sdk/pull/5971)) ### Bug Fixes +* support/contractevents: Read the amount from map event data (`{amount, to_muxed_id}`). A SAC transfer to a muxed destination (CAP-0067 `M...`, CAP-0084 `W...`) previously parsed as a transfer with `Amount` zero and no error. Event data with no amount now returns `ErrNotTransferEvent` instead of a zero-amount event. * support/datastore: Fix infinite loop in `LedgerFileIter` when the datastore contains directory placeholder objects, and reject a bucket path with empty, `.` or `..` segments at startup ([#6014](https://github.com/stellar/go-stellar-sdk/pull/6014)) * ingest: `CheckpointChangeReader` now resumes a failed bucket download from the last record boundary and continues the first download's SHA-256 from there, so the final hash check covers every record the reader returned. Before, the second download had its own hash and the records already returned from the first were not covered. A closed read channel now always means the producer has finished, so concurrent `Read()` callers cannot see `io.EOF` after a failure. `xdr.Stream.Close` is idempotent; a second close used to panic with the fscache-backed archive. `NewHotArchiveIterator` no longer blocks when the consumer stops early. `Progress()` returns 0 instead of NaN before the first bucket size is known ([#6017](https://github.com/stellar/go-stellar-sdk/pull/6017)) * processors/token_transfer: Accept a `to_muxed_id` bound to `Void` in V4 event data. CAP-0067 specifies that the key is simply absent when there is no muxed destination, and that form already parsed. `Void` is what a contract emits instead if it publishes its event data as a `#[contracttype]` struct with an `Option` field — the natural way to write it before CAP-0086's sparse maps, which omit the key. Such an event previously failed to parse and was dropped from the event stream entirely, silently ([#5983](https://github.com/stellar/go-stellar-sdk/pull/5983)) diff --git a/Makefile b/Makefile index 36b9874a38..a443e80b6f 100644 --- a/Makefile +++ b/Makefile @@ -17,9 +17,8 @@ xdr/Stellar-exporter.x XDRGEN_COMMIT=b423e1da9504239fb3136cbcc5f9beeb37795837 -# Protocol 28 GA: stellar-xdr@9c9c1459, the commit stellar-core 28.0.0 pins as -# src/protocol-curr/xdr (v28.0 tag pending; CAP-0083 + CAP-0085 are ungated here). -XDR_COMMIT=9c9c145953e80990d6ff1ae3a6a973a0ce6d0694 +# Protocol 30: stellar-xdr@4f524bba (main), with CAP-0084, CAP-0087 and CAP-0088 ungated upstream. +XDR_COMMIT=4f524bbac80c781c06e4fb5fc93a2d0d331d6705 .PHONY: xdr xdr-clean xdr-update diff --git a/gxdr/xdr_generated.go b/gxdr/xdr_generated.go index 5428f4e620..d59a79c57c 100644 --- a/gxdr/xdr_generated.go +++ b/gxdr/xdr_generated.go @@ -875,9 +875,11 @@ type UpgradeType = []byte // bound 128 type StellarValueType int32 const ( - STELLAR_VALUE_BASIC StellarValueType = 0 - STELLAR_VALUE_SIGNED StellarValueType = 1 - STELLAR_VALUE_EMPTY_TX_SET StellarValueType = 2 + STELLAR_VALUE_BASIC StellarValueType = 0 + STELLAR_VALUE_SIGNED StellarValueType = 1 + STELLAR_VALUE_EMPTY_TX_SET StellarValueType = 2 + STELLAR_VALUE_SIGNED_MS StellarValueType = 3 + STELLAR_VALUE_EMPTY_TX_SET_MS StellarValueType = 4 ) type LedgerCloseValueSignature struct { @@ -912,6 +914,10 @@ type XdrAnon_StellarValue_Ext struct { // LcValueSignature() *LedgerCloseValueSignature // STELLAR_VALUE_EMPTY_TX_SET: // ProposedValue() *XdrAnon_StellarValue_Ext_ProposedValue + // STELLAR_VALUE_SIGNED_MS: + // SignedMsValue() *XdrAnon_StellarValue_Ext_SignedMsValue + // STELLAR_VALUE_EMPTY_TX_SET_MS: + // ProposedMsValue() *XdrAnon_StellarValue_Ext_ProposedMsValue V StellarValueType _u interface{} } @@ -921,6 +927,19 @@ type XdrAnon_StellarValue_Ext_ProposedValue struct { PreviousLedgerVersion Uint32 LcValueSignature LedgerCloseValueSignature } +type XdrAnon_StellarValue_Ext_SignedMsValue struct { + // closeTime == closeTimeMs / 1000 + CloseTimeMs TimePointMs + LcValueSignature LedgerCloseValueSignature +} +type XdrAnon_StellarValue_Ext_ProposedMsValue struct { + // closeTime == closeTimeMs / 1000 + CloseTimeMs TimePointMs + TxSetHash Hash + PreviousLedgerHash Hash + PreviousLedgerVersion Uint32 + LcValueSignature LedgerCloseValueSignature +} const MASK_LEDGER_HEADER_FLAGS = 0x7 @@ -3902,6 +3921,9 @@ type TimePoint = Uint64 type Duration = Uint64 +// Milliseconds since the Unix epoch. TimePoint is whole seconds. +type TimePointMs = Uint64 + // An ExtensionPoint is always marshaled as a 32-bit 0 value. At a // later point, it can be replaced by a different union so as to // extend a structure. @@ -4079,6 +4101,8 @@ type SCMetaEntry struct { const SC_SPEC_DOC_LIMIT = 1024 +const SC_SPEC_TYPE_NAME_LIMIT = 1024 + type SCSpecType int32 const ( @@ -4140,7 +4164,7 @@ type SCSpecTypeBytesN struct { } type SCSpecTypeUDT struct { - Name string // bound 60 + Name string // bound SC_SPEC_TYPE_NAME_LIMIT } type SCSpecTypeDef struct { @@ -4174,7 +4198,7 @@ type SCSpecUDTStructFieldV0 struct { type SCSpecUDTStructV0 struct { Doc string // bound SC_SPEC_DOC_LIMIT Lib string // bound 80 - Name string // bound 60 + Name string // bound SC_SPEC_TYPE_NAME_LIMIT Fields []SCSpecUDTStructFieldV0 } @@ -4209,7 +4233,7 @@ type SCSpecUDTUnionCaseV0 struct { type SCSpecUDTUnionV0 struct { Doc string // bound SC_SPEC_DOC_LIMIT Lib string // bound 80 - Name string // bound 60 + Name string // bound SC_SPEC_TYPE_NAME_LIMIT Cases []SCSpecUDTUnionCaseV0 } @@ -4222,7 +4246,7 @@ type SCSpecUDTEnumCaseV0 struct { type SCSpecUDTEnumV0 struct { Doc string // bound SC_SPEC_DOC_LIMIT Lib string // bound 80 - Name string // bound 60 + Name string // bound SC_SPEC_TYPE_NAME_LIMIT Cases []SCSpecUDTEnumCaseV0 } @@ -4235,7 +4259,7 @@ type SCSpecUDTErrorEnumCaseV0 struct { type SCSpecUDTErrorEnumV0 struct { Doc string // bound SC_SPEC_DOC_LIMIT Lib string // bound 80 - Name string // bound 60 + Name string // bound SC_SPEC_TYPE_NAME_LIMIT Cases []SCSpecUDTErrorEnumCaseV0 } @@ -4275,9 +4299,9 @@ const ( ) type SCSpecEventV0 struct { - Doc string // bound SC_SPEC_DOC_LIMIT - Lib string // bound 80 - Name SCSymbol + Doc string // bound SC_SPEC_DOC_LIMIT + Lib string // bound 80 + Name string // bound SC_SPEC_TYPE_NAME_LIMIT PrefixTopics []SCSymbol // bound 2 Params []SCSpecEventParamV0 DataFormat SCSpecEventDataFormat @@ -4475,6 +4499,7 @@ const ( SC_ADDRESS_TYPE_MUXED_ACCOUNT SCAddressType = 2 SC_ADDRESS_TYPE_CLAIMABLE_BALANCE SCAddressType = 3 SC_ADDRESS_TYPE_LIQUIDITY_POOL SCAddressType = 4 + SC_ADDRESS_TYPE_MUXED_CONTRACT SCAddressType = 5 ) type MuxedEd25519Account struct { @@ -4482,6 +4507,11 @@ type MuxedEd25519Account struct { Ed25519 Uint256 } +type MuxedContract struct { + Id Uint64 + ContractId ContractID +} + type SCAddress struct { // The union discriminant Type selects among the following arms: // SC_ADDRESS_TYPE_ACCOUNT: @@ -4494,6 +4524,8 @@ type SCAddress struct { // ClaimableBalanceId() *ClaimableBalanceID // SC_ADDRESS_TYPE_LIQUIDITY_POOL: // LiquidityPoolId() *PoolID + // SC_ADDRESS_TYPE_MUXED_CONTRACT: + // MuxedContract() *MuxedContract Type SCAddressType _u interface{} } @@ -4905,6 +4937,24 @@ const ( Bn254FrInv ContractCostType = 84 // Cost of performing BN254 G1 multi-scalar multiplication (MSM) Bn254G1Msm ContractCostType = 85 + // Cost of decoding and expanding an ML-DSA-44 verifying key + MlDsa44DecodeVerifyingKey ContractCostType = 86 + // Cost of decoding and expanding an ML-DSA-65 verifying key + MlDsa65DecodeVerifyingKey ContractCostType = 87 + // Cost of decoding and expanding an ML-DSA-87 verifying key + MlDsa87DecodeVerifyingKey ContractCostType = 88 + // Cost of decoding an ML-DSA-44 signature + MlDsa44DecodeSignature ContractCostType = 89 + // Cost of decoding an ML-DSA-65 signature + MlDsa65DecodeSignature ContractCostType = 90 + // Cost of decoding an ML-DSA-87 signature + MlDsa87DecodeSignature ContractCostType = 91 + // Cost of verifying an ML-DSA-44 signature, linear in message + context length + VerifyMlDsa44Sig ContractCostType = 92 + // Cost of verifying an ML-DSA-65 signature, linear in message + context length + VerifyMlDsa65Sig ContractCostType = 93 + // Cost of verifying an ML-DSA-87 signature, linear in message + context length + VerifyMlDsa87Sig ContractCostType = 94 ) type ContractCostParamEntry struct { @@ -10038,14 +10088,18 @@ func (XdrType_UpgradeType) XdrTypeName() string { return "UpgradeType" } func (v XdrType_UpgradeType) XdrUnwrap() XdrType { return v.XdrVecOpaque } var _XdrNames_StellarValueType = map[int32]string{ - int32(STELLAR_VALUE_BASIC): "STELLAR_VALUE_BASIC", - int32(STELLAR_VALUE_SIGNED): "STELLAR_VALUE_SIGNED", - int32(STELLAR_VALUE_EMPTY_TX_SET): "STELLAR_VALUE_EMPTY_TX_SET", + int32(STELLAR_VALUE_BASIC): "STELLAR_VALUE_BASIC", + int32(STELLAR_VALUE_SIGNED): "STELLAR_VALUE_SIGNED", + int32(STELLAR_VALUE_EMPTY_TX_SET): "STELLAR_VALUE_EMPTY_TX_SET", + int32(STELLAR_VALUE_SIGNED_MS): "STELLAR_VALUE_SIGNED_MS", + int32(STELLAR_VALUE_EMPTY_TX_SET_MS): "STELLAR_VALUE_EMPTY_TX_SET_MS", } var _XdrValues_StellarValueType = map[string]int32{ - "STELLAR_VALUE_BASIC": int32(STELLAR_VALUE_BASIC), - "STELLAR_VALUE_SIGNED": int32(STELLAR_VALUE_SIGNED), - "STELLAR_VALUE_EMPTY_TX_SET": int32(STELLAR_VALUE_EMPTY_TX_SET), + "STELLAR_VALUE_BASIC": int32(STELLAR_VALUE_BASIC), + "STELLAR_VALUE_SIGNED": int32(STELLAR_VALUE_SIGNED), + "STELLAR_VALUE_EMPTY_TX_SET": int32(STELLAR_VALUE_EMPTY_TX_SET), + "STELLAR_VALUE_SIGNED_MS": int32(STELLAR_VALUE_SIGNED_MS), + "STELLAR_VALUE_EMPTY_TX_SET_MS": int32(STELLAR_VALUE_EMPTY_TX_SET_MS), } func (StellarValueType) XdrEnumNames() map[int32]string { @@ -10120,10 +10174,53 @@ func XDR_XdrAnon_StellarValue_Ext_ProposedValue(v *XdrAnon_StellarValue_Ext_Prop return v } +type XdrType_XdrAnon_StellarValue_Ext_SignedMsValue = *XdrAnon_StellarValue_Ext_SignedMsValue + +func (v *XdrAnon_StellarValue_Ext_SignedMsValue) XdrPointer() interface{} { return v } +func (XdrAnon_StellarValue_Ext_SignedMsValue) XdrTypeName() string { + return "XdrAnon_StellarValue_Ext_SignedMsValue" +} +func (v XdrAnon_StellarValue_Ext_SignedMsValue) XdrValue() interface{} { return v } +func (v *XdrAnon_StellarValue_Ext_SignedMsValue) XdrMarshal(x XDR, name string) { x.Marshal(name, v) } +func (v *XdrAnon_StellarValue_Ext_SignedMsValue) XdrRecurse(x XDR, name string) { + if name != "" { + name = x.Sprintf("%s.", name) + } + x.Marshal(x.Sprintf("%scloseTimeMs", name), XDR_TimePointMs(&v.CloseTimeMs)) + x.Marshal(x.Sprintf("%slcValueSignature", name), XDR_LedgerCloseValueSignature(&v.LcValueSignature)) +} +func XDR_XdrAnon_StellarValue_Ext_SignedMsValue(v *XdrAnon_StellarValue_Ext_SignedMsValue) *XdrAnon_StellarValue_Ext_SignedMsValue { + return v +} + +type XdrType_XdrAnon_StellarValue_Ext_ProposedMsValue = *XdrAnon_StellarValue_Ext_ProposedMsValue + +func (v *XdrAnon_StellarValue_Ext_ProposedMsValue) XdrPointer() interface{} { return v } +func (XdrAnon_StellarValue_Ext_ProposedMsValue) XdrTypeName() string { + return "XdrAnon_StellarValue_Ext_ProposedMsValue" +} +func (v XdrAnon_StellarValue_Ext_ProposedMsValue) XdrValue() interface{} { return v } +func (v *XdrAnon_StellarValue_Ext_ProposedMsValue) XdrMarshal(x XDR, name string) { x.Marshal(name, v) } +func (v *XdrAnon_StellarValue_Ext_ProposedMsValue) XdrRecurse(x XDR, name string) { + if name != "" { + name = x.Sprintf("%s.", name) + } + x.Marshal(x.Sprintf("%scloseTimeMs", name), XDR_TimePointMs(&v.CloseTimeMs)) + x.Marshal(x.Sprintf("%stxSetHash", name), XDR_Hash(&v.TxSetHash)) + x.Marshal(x.Sprintf("%spreviousLedgerHash", name), XDR_Hash(&v.PreviousLedgerHash)) + x.Marshal(x.Sprintf("%spreviousLedgerVersion", name), XDR_Uint32(&v.PreviousLedgerVersion)) + x.Marshal(x.Sprintf("%slcValueSignature", name), XDR_LedgerCloseValueSignature(&v.LcValueSignature)) +} +func XDR_XdrAnon_StellarValue_Ext_ProposedMsValue(v *XdrAnon_StellarValue_Ext_ProposedMsValue) *XdrAnon_StellarValue_Ext_ProposedMsValue { + return v +} + var _XdrTags_XdrAnon_StellarValue_Ext = map[int32]bool{ - XdrToI32(STELLAR_VALUE_BASIC): true, - XdrToI32(STELLAR_VALUE_SIGNED): true, - XdrToI32(STELLAR_VALUE_EMPTY_TX_SET): true, + XdrToI32(STELLAR_VALUE_BASIC): true, + XdrToI32(STELLAR_VALUE_SIGNED): true, + XdrToI32(STELLAR_VALUE_EMPTY_TX_SET): true, + XdrToI32(STELLAR_VALUE_SIGNED_MS): true, + XdrToI32(STELLAR_VALUE_EMPTY_TX_SET_MS): true, } func (_ XdrAnon_StellarValue_Ext) XdrValidTags() map[int32]bool { @@ -10159,9 +10256,39 @@ func (u *XdrAnon_StellarValue_Ext) ProposedValue() *XdrAnon_StellarValue_Ext_Pro return nil } } +func (u *XdrAnon_StellarValue_Ext) SignedMsValue() *XdrAnon_StellarValue_Ext_SignedMsValue { + switch u.V { + case STELLAR_VALUE_SIGNED_MS: + if v, ok := u._u.(*XdrAnon_StellarValue_Ext_SignedMsValue); ok { + return v + } else { + var zero XdrAnon_StellarValue_Ext_SignedMsValue + u._u = &zero + return &zero + } + default: + XdrPanic("XdrAnon_StellarValue_Ext.SignedMsValue accessed when V == %v", u.V) + return nil + } +} +func (u *XdrAnon_StellarValue_Ext) ProposedMsValue() *XdrAnon_StellarValue_Ext_ProposedMsValue { + switch u.V { + case STELLAR_VALUE_EMPTY_TX_SET_MS: + if v, ok := u._u.(*XdrAnon_StellarValue_Ext_ProposedMsValue); ok { + return v + } else { + var zero XdrAnon_StellarValue_Ext_ProposedMsValue + u._u = &zero + return &zero + } + default: + XdrPanic("XdrAnon_StellarValue_Ext.ProposedMsValue accessed when V == %v", u.V) + return nil + } +} func (u XdrAnon_StellarValue_Ext) XdrValid() bool { switch u.V { - case STELLAR_VALUE_BASIC, STELLAR_VALUE_SIGNED, STELLAR_VALUE_EMPTY_TX_SET: + case STELLAR_VALUE_BASIC, STELLAR_VALUE_SIGNED, STELLAR_VALUE_EMPTY_TX_SET, STELLAR_VALUE_SIGNED_MS, STELLAR_VALUE_EMPTY_TX_SET_MS: return true } return false @@ -10180,6 +10307,10 @@ func (u *XdrAnon_StellarValue_Ext) XdrUnionBody() XdrType { return XDR_LedgerCloseValueSignature(u.LcValueSignature()) case STELLAR_VALUE_EMPTY_TX_SET: return XDR_XdrAnon_StellarValue_Ext_ProposedValue(u.ProposedValue()) + case STELLAR_VALUE_SIGNED_MS: + return XDR_XdrAnon_StellarValue_Ext_SignedMsValue(u.SignedMsValue()) + case STELLAR_VALUE_EMPTY_TX_SET_MS: + return XDR_XdrAnon_StellarValue_Ext_ProposedMsValue(u.ProposedMsValue()) } return nil } @@ -10191,6 +10322,10 @@ func (u *XdrAnon_StellarValue_Ext) XdrUnionBodyName() string { return "LcValueSignature" case STELLAR_VALUE_EMPTY_TX_SET: return "ProposedValue" + case STELLAR_VALUE_SIGNED_MS: + return "SignedMsValue" + case STELLAR_VALUE_EMPTY_TX_SET_MS: + return "ProposedMsValue" } return "" } @@ -10215,6 +10350,12 @@ func (u *XdrAnon_StellarValue_Ext) XdrRecurse(x XDR, name string) { case STELLAR_VALUE_EMPTY_TX_SET: x.Marshal(x.Sprintf("%sproposedValue", name), XDR_XdrAnon_StellarValue_Ext_ProposedValue(u.ProposedValue())) return + case STELLAR_VALUE_SIGNED_MS: + x.Marshal(x.Sprintf("%ssignedMsValue", name), XDR_XdrAnon_StellarValue_Ext_SignedMsValue(u.SignedMsValue())) + return + case STELLAR_VALUE_EMPTY_TX_SET_MS: + x.Marshal(x.Sprintf("%sproposedMsValue", name), XDR_XdrAnon_StellarValue_Ext_ProposedMsValue(u.ProposedMsValue())) + return } XdrPanic("invalid V (%v) in XdrAnon_StellarValue_Ext", u.V) } @@ -26849,6 +26990,16 @@ func XDR_Duration(v *Duration) XdrType_Duration { func (XdrType_Duration) XdrTypeName() string { return "Duration" } func (v XdrType_Duration) XdrUnwrap() XdrType { return v.XdrType_Uint64 } +type XdrType_TimePointMs struct { + XdrType_Uint64 +} + +func XDR_TimePointMs(v *TimePointMs) XdrType_TimePointMs { + return XdrType_TimePointMs{XDR_Uint64(v)} +} +func (XdrType_TimePointMs) XdrTypeName() string { return "TimePointMs" } +func (v XdrType_TimePointMs) XdrUnwrap() XdrType { return v.XdrType_Uint64 } + var _XdrTags_ExtensionPoint = map[int32]bool{ XdrToI32(0): true, } @@ -28116,7 +28267,7 @@ func (v *SCSpecTypeUDT) XdrRecurse(x XDR, name string) { if name != "" { name = x.Sprintf("%s.", name) } - x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, 60}) + x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, SC_SPEC_TYPE_NAME_LIMIT}) } func XDR_SCSpecTypeUDT(v *SCSpecTypeUDT) *SCSpecTypeUDT { return v } @@ -28444,7 +28595,7 @@ func (v *SCSpecUDTStructV0) XdrRecurse(x XDR, name string) { } x.Marshal(x.Sprintf("%sdoc", name), XdrString{&v.Doc, SC_SPEC_DOC_LIMIT}) x.Marshal(x.Sprintf("%slib", name), XdrString{&v.Lib, 80}) - x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, 60}) + x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, SC_SPEC_TYPE_NAME_LIMIT}) x.Marshal(x.Sprintf("%sfields", name), (*_XdrVec_unbounded_SCSpecUDTStructFieldV0)(&v.Fields)) } func XDR_SCSpecUDTStructV0(v *SCSpecUDTStructV0) *SCSpecUDTStructV0 { return v } @@ -28748,7 +28899,7 @@ func (v *SCSpecUDTUnionV0) XdrRecurse(x XDR, name string) { } x.Marshal(x.Sprintf("%sdoc", name), XdrString{&v.Doc, SC_SPEC_DOC_LIMIT}) x.Marshal(x.Sprintf("%slib", name), XdrString{&v.Lib, 80}) - x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, 60}) + x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, SC_SPEC_TYPE_NAME_LIMIT}) x.Marshal(x.Sprintf("%scases", name), (*_XdrVec_unbounded_SCSpecUDTUnionCaseV0)(&v.Cases)) } func XDR_SCSpecUDTUnionV0(v *SCSpecUDTUnionV0) *SCSpecUDTUnionV0 { return v } @@ -28842,7 +28993,7 @@ func (v *SCSpecUDTEnumV0) XdrRecurse(x XDR, name string) { } x.Marshal(x.Sprintf("%sdoc", name), XdrString{&v.Doc, SC_SPEC_DOC_LIMIT}) x.Marshal(x.Sprintf("%slib", name), XdrString{&v.Lib, 80}) - x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, 60}) + x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, SC_SPEC_TYPE_NAME_LIMIT}) x.Marshal(x.Sprintf("%scases", name), (*_XdrVec_unbounded_SCSpecUDTEnumCaseV0)(&v.Cases)) } func XDR_SCSpecUDTEnumV0(v *SCSpecUDTEnumV0) *SCSpecUDTEnumV0 { return v } @@ -28940,7 +29091,7 @@ func (v *SCSpecUDTErrorEnumV0) XdrRecurse(x XDR, name string) { } x.Marshal(x.Sprintf("%sdoc", name), XdrString{&v.Doc, SC_SPEC_DOC_LIMIT}) x.Marshal(x.Sprintf("%slib", name), XdrString{&v.Lib, 80}) - x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, 60}) + x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, SC_SPEC_TYPE_NAME_LIMIT}) x.Marshal(x.Sprintf("%scases", name), (*_XdrVec_unbounded_SCSpecUDTErrorEnumCaseV0)(&v.Cases)) } func XDR_SCSpecUDTErrorEnumV0(v *SCSpecUDTErrorEnumV0) *SCSpecUDTErrorEnumV0 { return v } @@ -29337,7 +29488,7 @@ func (v *SCSpecEventV0) XdrRecurse(x XDR, name string) { } x.Marshal(x.Sprintf("%sdoc", name), XdrString{&v.Doc, SC_SPEC_DOC_LIMIT}) x.Marshal(x.Sprintf("%slib", name), XdrString{&v.Lib, 80}) - x.Marshal(x.Sprintf("%sname", name), XDR_SCSymbol(&v.Name)) + x.Marshal(x.Sprintf("%sname", name), XdrString{&v.Name, SC_SPEC_TYPE_NAME_LIMIT}) x.Marshal(x.Sprintf("%sprefixTopics", name), (*_XdrVec_2_SCSymbol)(&v.PrefixTopics)) x.Marshal(x.Sprintf("%sparams", name), (*_XdrVec_unbounded_SCSpecEventParamV0)(&v.Params)) x.Marshal(x.Sprintf("%sdataFormat", name), XDR_SCSpecEventDataFormat(&v.DataFormat)) @@ -30090,6 +30241,7 @@ var _XdrNames_SCAddressType = map[int32]string{ int32(SC_ADDRESS_TYPE_MUXED_ACCOUNT): "SC_ADDRESS_TYPE_MUXED_ACCOUNT", int32(SC_ADDRESS_TYPE_CLAIMABLE_BALANCE): "SC_ADDRESS_TYPE_CLAIMABLE_BALANCE", int32(SC_ADDRESS_TYPE_LIQUIDITY_POOL): "SC_ADDRESS_TYPE_LIQUIDITY_POOL", + int32(SC_ADDRESS_TYPE_MUXED_CONTRACT): "SC_ADDRESS_TYPE_MUXED_CONTRACT", } var _XdrValues_SCAddressType = map[string]int32{ "SC_ADDRESS_TYPE_ACCOUNT": int32(SC_ADDRESS_TYPE_ACCOUNT), @@ -30097,6 +30249,7 @@ var _XdrValues_SCAddressType = map[string]int32{ "SC_ADDRESS_TYPE_MUXED_ACCOUNT": int32(SC_ADDRESS_TYPE_MUXED_ACCOUNT), "SC_ADDRESS_TYPE_CLAIMABLE_BALANCE": int32(SC_ADDRESS_TYPE_CLAIMABLE_BALANCE), "SC_ADDRESS_TYPE_LIQUIDITY_POOL": int32(SC_ADDRESS_TYPE_LIQUIDITY_POOL), + "SC_ADDRESS_TYPE_MUXED_CONTRACT": int32(SC_ADDRESS_TYPE_MUXED_CONTRACT), } func (SCAddressType) XdrEnumNames() map[int32]string { @@ -30150,12 +30303,28 @@ func (v *MuxedEd25519Account) XdrRecurse(x XDR, name string) { } func XDR_MuxedEd25519Account(v *MuxedEd25519Account) *MuxedEd25519Account { return v } +type XdrType_MuxedContract = *MuxedContract + +func (v *MuxedContract) XdrPointer() interface{} { return v } +func (MuxedContract) XdrTypeName() string { return "MuxedContract" } +func (v MuxedContract) XdrValue() interface{} { return v } +func (v *MuxedContract) XdrMarshal(x XDR, name string) { x.Marshal(name, v) } +func (v *MuxedContract) XdrRecurse(x XDR, name string) { + if name != "" { + name = x.Sprintf("%s.", name) + } + x.Marshal(x.Sprintf("%sid", name), XDR_Uint64(&v.Id)) + x.Marshal(x.Sprintf("%scontractId", name), XDR_ContractID(&v.ContractId)) +} +func XDR_MuxedContract(v *MuxedContract) *MuxedContract { return v } + var _XdrTags_SCAddress = map[int32]bool{ XdrToI32(SC_ADDRESS_TYPE_ACCOUNT): true, XdrToI32(SC_ADDRESS_TYPE_CONTRACT): true, XdrToI32(SC_ADDRESS_TYPE_MUXED_ACCOUNT): true, XdrToI32(SC_ADDRESS_TYPE_CLAIMABLE_BALANCE): true, XdrToI32(SC_ADDRESS_TYPE_LIQUIDITY_POOL): true, + XdrToI32(SC_ADDRESS_TYPE_MUXED_CONTRACT): true, } func (_ SCAddress) XdrValidTags() map[int32]bool { @@ -30236,9 +30405,24 @@ func (u *SCAddress) LiquidityPoolId() *PoolID { return nil } } +func (u *SCAddress) MuxedContract() *MuxedContract { + switch u.Type { + case SC_ADDRESS_TYPE_MUXED_CONTRACT: + if v, ok := u._u.(*MuxedContract); ok { + return v + } else { + var zero MuxedContract + u._u = &zero + return &zero + } + default: + XdrPanic("SCAddress.MuxedContract accessed when Type == %v", u.Type) + return nil + } +} func (u SCAddress) XdrValid() bool { switch u.Type { - case SC_ADDRESS_TYPE_ACCOUNT, SC_ADDRESS_TYPE_CONTRACT, SC_ADDRESS_TYPE_MUXED_ACCOUNT, SC_ADDRESS_TYPE_CLAIMABLE_BALANCE, SC_ADDRESS_TYPE_LIQUIDITY_POOL: + case SC_ADDRESS_TYPE_ACCOUNT, SC_ADDRESS_TYPE_CONTRACT, SC_ADDRESS_TYPE_MUXED_ACCOUNT, SC_ADDRESS_TYPE_CLAIMABLE_BALANCE, SC_ADDRESS_TYPE_LIQUIDITY_POOL, SC_ADDRESS_TYPE_MUXED_CONTRACT: return true } return false @@ -30261,6 +30445,8 @@ func (u *SCAddress) XdrUnionBody() XdrType { return XDR_ClaimableBalanceID(u.ClaimableBalanceId()) case SC_ADDRESS_TYPE_LIQUIDITY_POOL: return XDR_PoolID(u.LiquidityPoolId()) + case SC_ADDRESS_TYPE_MUXED_CONTRACT: + return XDR_MuxedContract(u.MuxedContract()) } return nil } @@ -30276,6 +30462,8 @@ func (u *SCAddress) XdrUnionBodyName() string { return "ClaimableBalanceId" case SC_ADDRESS_TYPE_LIQUIDITY_POOL: return "LiquidityPoolId" + case SC_ADDRESS_TYPE_MUXED_CONTRACT: + return "MuxedContract" } return "" } @@ -30307,6 +30495,9 @@ func (u *SCAddress) XdrRecurse(x XDR, name string) { case SC_ADDRESS_TYPE_LIQUIDITY_POOL: x.Marshal(x.Sprintf("%sliquidityPoolId", name), XDR_PoolID(u.LiquidityPoolId())) return + case SC_ADDRESS_TYPE_MUXED_CONTRACT: + x.Marshal(x.Sprintf("%smuxedContract", name), XDR_MuxedContract(u.MuxedContract())) + return } XdrPanic("invalid Type (%v) in SCAddress", u.Type) } @@ -31792,6 +31983,15 @@ var _XdrNames_ContractCostType = map[int32]string{ int32(Bn254FrPow): "Bn254FrPow", int32(Bn254FrInv): "Bn254FrInv", int32(Bn254G1Msm): "Bn254G1Msm", + int32(MlDsa44DecodeVerifyingKey): "MlDsa44DecodeVerifyingKey", + int32(MlDsa65DecodeVerifyingKey): "MlDsa65DecodeVerifyingKey", + int32(MlDsa87DecodeVerifyingKey): "MlDsa87DecodeVerifyingKey", + int32(MlDsa44DecodeSignature): "MlDsa44DecodeSignature", + int32(MlDsa65DecodeSignature): "MlDsa65DecodeSignature", + int32(MlDsa87DecodeSignature): "MlDsa87DecodeSignature", + int32(VerifyMlDsa44Sig): "VerifyMlDsa44Sig", + int32(VerifyMlDsa65Sig): "VerifyMlDsa65Sig", + int32(VerifyMlDsa87Sig): "VerifyMlDsa87Sig", } var _XdrValues_ContractCostType = map[string]int32{ "WasmInsnExec": int32(WasmInsnExec), @@ -31880,6 +32080,15 @@ var _XdrValues_ContractCostType = map[string]int32{ "Bn254FrPow": int32(Bn254FrPow), "Bn254FrInv": int32(Bn254FrInv), "Bn254G1Msm": int32(Bn254G1Msm), + "MlDsa44DecodeVerifyingKey": int32(MlDsa44DecodeVerifyingKey), + "MlDsa65DecodeVerifyingKey": int32(MlDsa65DecodeVerifyingKey), + "MlDsa87DecodeVerifyingKey": int32(MlDsa87DecodeVerifyingKey), + "MlDsa44DecodeSignature": int32(MlDsa44DecodeSignature), + "MlDsa65DecodeSignature": int32(MlDsa65DecodeSignature), + "MlDsa87DecodeSignature": int32(MlDsa87DecodeSignature), + "VerifyMlDsa44Sig": int32(VerifyMlDsa44Sig), + "VerifyMlDsa65Sig": int32(VerifyMlDsa65Sig), + "VerifyMlDsa87Sig": int32(VerifyMlDsa87Sig), } func (ContractCostType) XdrEnumNames() map[int32]string { @@ -32005,6 +32214,15 @@ var _XdrComments_ContractCostType = map[int32]string{ int32(Bn254FrPow): "Cost of performing BN254 scalar element exponentiation", int32(Bn254FrInv): "Cost of performing BN254 scalar element inversion", int32(Bn254G1Msm): "Cost of performing BN254 G1 multi-scalar multiplication (MSM)", + int32(MlDsa44DecodeVerifyingKey): "Cost of decoding and expanding an ML-DSA-44 verifying key", + int32(MlDsa65DecodeVerifyingKey): "Cost of decoding and expanding an ML-DSA-65 verifying key", + int32(MlDsa87DecodeVerifyingKey): "Cost of decoding and expanding an ML-DSA-87 verifying key", + int32(MlDsa44DecodeSignature): "Cost of decoding an ML-DSA-44 signature", + int32(MlDsa65DecodeSignature): "Cost of decoding an ML-DSA-65 signature", + int32(MlDsa87DecodeSignature): "Cost of decoding an ML-DSA-87 signature", + int32(VerifyMlDsa44Sig): "Cost of verifying an ML-DSA-44 signature, linear in message + context length", + int32(VerifyMlDsa65Sig): "Cost of verifying an ML-DSA-65 signature, linear in message + context length", + int32(VerifyMlDsa87Sig): "Cost of verifying an ML-DSA-87 signature, linear in message + context length", } func (e ContractCostType) XdrEnumComments() map[int32]string { diff --git a/ingest/CHANGELOG.md b/ingest/CHANGELOG.md index a2cbb1f979..68924548f4 100644 --- a/ingest/CHANGELOG.md +++ b/ingest/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to this project will be documented in this file. This projec ## Pending +### Protocol 30 Support +* `ledger.NodeID` and `ledger.Signature` read the close-value signature from the CAP-0088 millisecond close-time arms (`STELLAR_VALUE_SIGNED_MS`, `STELLAR_VALUE_EMPTY_TX_SET_MS`), which every ledger after the Protocol 30 upgrade uses. Whole-second `CloseTime` is unchanged. + +### Bug Fixes +* `ledger.NodeID` and `ledger.Signature` now also read the signature from the `STELLAR_VALUE_EMPTY_TX_SET` arm (CAP-0083). Ledgers closed with an empty transaction set previously returned an error and an empty signature. + ### Breaking Changes * Removed the `ingest/cdp` pacakge and consolidated components into `github.com/stellar/go-stellar-sdk/ingest`. This affects references to a few components: - `ApplyLedgerMetadata` diff --git a/ingest/ledger/ledger.go b/ingest/ledger/ledger.go index 24b293fb66..f650d07c93 100644 --- a/ingest/ledger/ledger.go +++ b/ingest/ledger/ledger.go @@ -76,8 +76,12 @@ func TotalByteSizeOfLiveSorobanState(l xdr.LedgerCloseMeta) (uint64, bool) { return 0, false } +func scpValueSignature(l xdr.LedgerCloseMeta) (xdr.LedgerCloseValueSignature, bool) { + return l.LedgerHeaderHistoryEntry().Header.ScpValue.Ext.LedgerCloseValueSignature() +} + func NodeID(l xdr.LedgerCloseMeta) (string, error) { - LedgerCloseValueSignature, ok := l.LedgerHeaderHistoryEntry().Header.ScpValue.Ext.GetLcValueSignature() + LedgerCloseValueSignature, ok := scpValueSignature(l) if !ok { return "", fmt.Errorf("could not get LedgerCloseValueSignature") @@ -86,7 +90,7 @@ func NodeID(l xdr.LedgerCloseMeta) (string, error) { } func Signature(l xdr.LedgerCloseMeta) (string, bool) { - LedgerCloseValueSignature, ok := l.LedgerHeaderHistoryEntry().Header.ScpValue.Ext.GetLcValueSignature() + LedgerCloseValueSignature, ok := scpValueSignature(l) if !ok { return "", false } diff --git a/ingest/ledger/ledger_test.go b/ingest/ledger/ledger_test.go index e58a2020f0..6e7c02ec49 100644 --- a/ingest/ledger/ledger_test.go +++ b/ingest/ledger/ledger_test.go @@ -59,6 +59,71 @@ func TestLedger(t *testing.T) { assert.Equal(t, uint32(13), total) } +func TestNodeIDAndSignatureMsCloseTime(t *testing.T) { + ledger := ledgerTestInput() + header := &ledger.V1.LedgerHeader.Header + sig := header.ScpValue.Ext.LcValueSignature + header.ScpValue.Ext = xdr.StellarValueExt{ + V: xdr.StellarValueTypeStellarValueSignedMs, + SignedMsValue: &xdr.StellarValueSignedMsValue{ + CloseTimeMs: xdr.TimePointMs(1594584547000), + LcValueSignature: *sig, + }, + } + + nodeID, err := NodeID(ledger) + assert.NoError(t, err) + assert.Equal(t, "GARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA76O", nodeID) + + signature, ok := Signature(ledger) + assert.True(t, ok) + assert.Equal(t, "9g==", signature) + + // Whole-second close time is unchanged by CAP-0088. + assert.Equal(t, int64(1594584547), CloseTime(ledger)) + + // The zero-copy view path rejects unknown ext discriminants, so this fails + // unless xdr_views_generated.go carries the new arms. + raw, err := header.ScpValue.MarshalBinary() + assert.NoError(t, err) + view := xdr.StellarValueView(raw) + assert.NoError(t, view.ValidateFull()) + assert.Equal(t, uint64(1594584547), view.MustCloseTime().MustValue()) + assert.Equal(t, uint64(1594584547000), view.MustExt().MustSignedMsValue().MustCloseTimeMs().MustValue()) +} + +func TestNodeIDAndSignatureEmptyTxSet(t *testing.T) { + ledger := ledgerTestInput() + header := &ledger.V1.LedgerHeader.Header + sig := *header.ScpValue.Ext.LcValueSignature + + for name, ext := range map[string]xdr.StellarValueExt{ + "EMPTY_TX_SET": { + V: xdr.StellarValueTypeStellarValueEmptyTxSet, + ProposedValue: &xdr.StellarValueProposedValue{LcValueSignature: sig}, + }, + "EMPTY_TX_SET_MS": { + V: xdr.StellarValueTypeStellarValueEmptyTxSetMs, + ProposedMsValue: &xdr.StellarValueProposedMsValue{ + CloseTimeMs: xdr.TimePointMs(1594584547000), + LcValueSignature: sig, + }, + }, + } { + t.Run(name, func(t *testing.T) { + header.ScpValue.Ext = ext + + nodeID, err := NodeID(ledger) + assert.NoError(t, err) + assert.Equal(t, "GARAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA76O", nodeID) + + signature, ok := Signature(ledger) + assert.True(t, ok) + assert.Equal(t, "9g==", signature) + }) + } +} + func ledgerTestInput() (lcm xdr.LedgerCloseMeta) { lcm = xdr.LedgerCloseMeta{ V: 1, diff --git a/processors/token_transfer/contract_events_test.go b/processors/token_transfer/contract_events_test.go index b58445309a..36a38c7c32 100644 --- a/processors/token_transfer/contract_events_test.go +++ b/processors/token_transfer/contract_events_test.go @@ -24,6 +24,8 @@ var ( someContract2 = strkey.MustEncode(strkey.VersionByteContract, someContractId2[:]) + someMuxedContract1 = strkey.MustEncode(strkey.VersionByteMuxedContract, append(someContractId1[:], 0, 0, 0, 0, 0, 0, 0, 7)) + processor = &EventsProcessor{ networkPassphrase: someNetworkPassphrase, } @@ -60,6 +62,17 @@ func createAddress(address string) xdr.ScVal { scAddress.Type = xdr.ScAddressTypeScAddressTypeAccount scAddress.AccountId = xdr.MustAddressPtr(address) + case strkey.IsValidMuxedContractAddress(address) == true: + muxed, err := strkey.DecodeMuxedContract(address) + if err != nil { + panic(err) + } + scAddress.Type = xdr.ScAddressTypeScAddressTypeMuxedContract + scAddress.MuxedContract = &xdr.MuxedContract{ + Id: xdr.Uint64(muxed.ID()), + ContractId: muxed.Contract(), + } + default: panic(fmt.Errorf("unsupported address: %s", address)) } @@ -1211,6 +1224,24 @@ func TestValidSep41EventsWithExtraTopicsAndDataV4(t *testing.T) { assert.Equal(t, thousandStr, event.GetTransfer().Amount) assert.Nil(t, event.Meta.GetToMuxedInfo()) }, + }, { + name: "Transfer Event with muxed contract address in topics - Valid Sep-41 token", + setupEvent: func() xdr.ContractEvent { + topics := []xdr.ScVal{ + createSymbol(TransferEvent), + createAddress(randomAccount), // from + createAddress(someMuxedContract1), // to + } + data := createInt128(thousand) + return createContract(&someContractId1, topics, data) + }, + validateEvent: func(t *testing.T, event *TokenTransferEvent) { + assert.NotNil(t, event.GetTransfer()) + assert.Equal(t, randomAccount, event.GetTransfer().From) + assert.Equal(t, someMuxedContract1, event.GetTransfer().To) + assert.Equal(t, thousandStr, event.GetTransfer().Amount) + assert.Nil(t, event.Meta.GetToMuxedInfo()) + }, }, { @@ -1854,6 +1885,41 @@ func TestValidContractEventsV4(t *testing.T) { } } +// CAP-0084: the SAC reports a transfer or mint to a muxed contract (W...) the +// same way as one to a muxed account. The "to" topic is the plain contract +// address, and the multiplexing id is to_muxed_id in the data map. +func TestSacEventsToMuxedContractV4(t *testing.T) { + v4Tx := someTxV3() + v4Tx.UnsafeMeta.V = 4 + v4Tx.UnsafeMeta.V4 = &xdr.TransactionMetaV4{ + Operations: []xdr.OperationMetaV2{{}}, + } + asset := createString(xlmAsset.StringCanonical()) + data := createScMap("amount", createInt128(thousand), "to_muxed_id", uint64(7)) + + parse := func(topics ...xdr.ScVal) *TokenTransferEvent { + contractEvent := createContractEventFromTopicsAndData(contractIdFromAsset(xlmAsset), topics, data) + event, err := processor.parseEvent(v4Tx, &someOperationIndex, contractEvent) + require.NoError(t, err) + require.NotNil(t, event) + assert.NotNil(t, event.GetAsset()) + require.NotNil(t, event.Meta.ToMuxedInfo) + assert.Equal(t, uint64(7), event.Meta.ToMuxedInfo.GetId()) + return event + } + + transfer := parse(createSymbol(TransferEvent), createAddress(randomAccount), createAddress(someContract1), asset).GetTransfer() + require.NotNil(t, transfer) + assert.Equal(t, randomAccount, transfer.From) + assert.Equal(t, someContract1, transfer.To) + assert.Equal(t, thousandStr, transfer.Amount) + + mint := parse(createSymbol(MintEvent), createAddress(someContract1), asset).GetMint() + require.NotNil(t, mint) + assert.Equal(t, someContract1, mint.To) + assert.Equal(t, thousandStr, mint.Amount) +} + func TestV4FeeEventParsing(t *testing.T) { // Create V4 transaction v4Tx := someTxV3() diff --git a/processors/token_transfer/verify_events.go b/processors/token_transfer/verify_events.go index 7e57759289..51279ab2ec 100644 --- a/processors/token_transfer/verify_events.go +++ b/processors/token_transfer/verify_events.go @@ -20,7 +20,7 @@ type balanceKey struct { // updateBalanceMap updates the map and removes the entry if the value becomes 0 func updateBalanceMap(m map[balanceKey]*big.Int, key balanceKey, delta *big.Int) { // We dont include movement to/from contract address is balance delta tracking, since there is no standard way to derive/verify from contractData - if strkey.IsValidContractAddress(key.holder) { + if strkey.IsValidContractAddress(key.holder) || strkey.IsValidMuxedContractAddress(key.holder) { return } if delta.Sign() == 0 { diff --git a/processors/token_transfer/verify_events_test.go b/processors/token_transfer/verify_events_test.go index f6ca3b3787..2aecbd5ac4 100644 --- a/processors/token_transfer/verify_events_test.go +++ b/processors/token_transfer/verify_events_test.go @@ -28,6 +28,23 @@ func TestFindBalanceDeltasFromEvents_Int64Amounts(t *testing.T) { assert.Equal(t, big.NewInt(1000), deltas[toKey]) } +func TestFindBalanceDeltasFromEvents_SkipsContractHolders(t *testing.T) { + from := accountA.Address() + asset := xlmAsset + protoAsset := assetProto.NewProtoAsset(asset) + + meta := &EventMeta{TxHash: "abc123"} + toContract := NewTransferEvent(meta, from, someContract1, "1000", protoAsset) + toMuxedContract := NewTransferEvent(meta, from, someMuxedContract1, "500", protoAsset) + + deltas, err := findBalanceDeltasFromEvents([]*TokenTransferEvent{toContract, toMuxedContract}) + require.NoError(t, err) + + fromKey := balanceKey{holder: from, asset: asset.StringCanonical()} + assert.Equal(t, big.NewInt(-1500), deltas[fromKey]) + assert.Len(t, deltas, 1) +} + func TestFindBalanceDeltasFromEvents_AmountExceedingInt64(t *testing.T) { // This is the scenario from issue #5929: a SAC token balance that // exceeded int64 max through cumulative mints, then was fully burned. diff --git a/protocols/horizon/effects/main.go b/protocols/horizon/effects/main.go index 4fcb97da36..55f573efde 100644 --- a/protocols/horizon/effects/main.go +++ b/protocols/horizon/effects/main.go @@ -317,7 +317,10 @@ type ContractCredited struct { Base base.Asset Contract string `json:"contract"` - Amount string `json:"amount"` + // Set when the destination was a muxed contract (CAP-0084). + ContractMuxed string `json:"contract_muxed,omitempty"` + ContractMuxedID uint64 `json:"contract_muxed_id,omitempty,string"` + Amount string `json:"amount"` } type ContractDebited struct { diff --git a/strkey/decode_length_test.go b/strkey/decode_length_test.go index a47fea2bfc..33449e1839 100644 --- a/strkey/decode_length_test.go +++ b/strkey/decode_length_test.go @@ -21,6 +21,7 @@ func TestDecodeRejectsNonCanonicalPayloadLength(t *testing.T) { {"liquidity_pool", VersionByteLiquidityPool, 32}, {"claimable_balance", VersionByteClaimableBalance, 33}, {"muxed_account", VersionByteMuxedAccount, 40}, + {"muxed_contract", VersionByteMuxedContract, 40}, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/strkey/decode_test.go b/strkey/decode_test.go index 1736b45af3..ebee7f0db7 100644 --- a/strkey/decode_test.go +++ b/strkey/decode_test.go @@ -37,6 +37,18 @@ func TestDecode(t *testing.T) { 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }, }, + { + Name: "MuxedContract", + Address: "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IG", + ExpectedVersionByte: VersionByteMuxedContract, + ExpectedPayload: []byte{ + 0x36, 0x3e, 0xaa, 0x38, 0x67, 0x84, 0x1f, 0xba, + 0xd0, 0xf4, 0xed, 0x88, 0xc7, 0x79, 0xe4, 0xfe, + 0x66, 0xe5, 0x6a, 0x24, 0x70, 0xdc, 0x98, 0xc0, + 0xec, 0x9c, 0x07, 0x3d, 0x05, 0xc7, 0xb1, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe2, 0x40, + }, + }, { Name: "Seed", Address: "SBU2RRGLXH3E5CQHTD3ODLDF2BWDCYUSSBLLZ5GNW7JXHDIYKXZWHOKR", diff --git a/strkey/encode_test.go b/strkey/encode_test.go index a5d3a8dcac..14b31e021d 100644 --- a/strkey/encode_test.go +++ b/strkey/encode_test.go @@ -37,6 +37,18 @@ func TestEncode(t *testing.T) { }, Expected: "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK", }, + { + Name: "MuxedContract", + VersionByte: VersionByteMuxedContract, + Payload: []byte{ + 0x36, 0x3e, 0xaa, 0x38, 0x67, 0x84, 0x1f, 0xba, + 0xd0, 0xf4, 0xed, 0x88, 0xc7, 0x79, 0xe4, 0xfe, + 0x66, 0xe5, 0x6a, 0x24, 0x70, 0xdc, 0x98, 0xc0, + 0xec, 0x9c, 0x07, 0x3d, 0x05, 0xc7, 0xb1, 0x03, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xe2, 0x40, + }, + Expected: "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IG", + }, { Name: "Seed", VersionByte: VersionByteSeed, diff --git a/strkey/isvalid_length_test.go b/strkey/isvalid_length_test.go index 5bdd54a6b4..2043af1b3e 100644 --- a/strkey/isvalid_length_test.go +++ b/strkey/isvalid_length_test.go @@ -53,4 +53,18 @@ func TestIsValidRejectsNonCanonicalPayloadLength(t *testing.T) { require.NoError(t, err) require.True(t, strkey.IsValidMuxedAccountEd25519PublicKey(canonical)) }) + + t.Run("muxed_contract", func(t *testing.T) { + overlong, err := strkey.Encode(strkey.VersionByteMuxedContract, make([]byte, 44)) + require.NoError(t, err) + require.False(t, strkey.IsValidMuxedContractAddress(overlong)) + + short, err := strkey.Encode(strkey.VersionByteMuxedContract, make([]byte, 39)) + require.NoError(t, err) + require.False(t, strkey.IsValidMuxedContractAddress(short)) + + canonical, err := strkey.Encode(strkey.VersionByteMuxedContract, make([]byte, 40)) + require.NoError(t, err) + require.True(t, strkey.IsValidMuxedContractAddress(canonical)) + }) } diff --git a/strkey/main.go b/strkey/main.go index d8fb61730b..3862808c6e 100644 --- a/strkey/main.go +++ b/strkey/main.go @@ -47,6 +47,9 @@ const ( //VersionByteClaimableBalance is the version byte used for encoded stellar claimable balances VersionByteClaimableBalance = 1 << 3 + + //VersionByteMuxedContract is the version byte used for encoded stellar multiplexed contracts + VersionByteMuxedContract = 22 << 3 // Base32-encodes to 'W...' ) // maxPayloadSize is the maximum length of the payload for all versions. The @@ -155,6 +158,8 @@ func checkPayloadLength(version VersionByte, payload []byte) error { expected = 33 // 1-byte claimable balance type + 32-byte hash case VersionByteMuxedAccount: expected = 40 // 32-byte ed25519 key + 8-byte account id + case VersionByteMuxedContract: + expected = 40 // 32-byte contract id + 8-byte muxed id case VersionByteSignedPayload: return checkSignedPayload(payload) default: @@ -261,7 +266,8 @@ func checkValidVersionByte(version VersionByte) error { switch version { case VersionByteAccountID, VersionByteMuxedAccount, VersionByteSeed, VersionByteHashTx, VersionByteHashX, VersionByteSignedPayload, - VersionByteContract, VersionByteLiquidityPool, VersionByteClaimableBalance: + VersionByteContract, VersionByteLiquidityPool, VersionByteClaimableBalance, + VersionByteMuxedContract: return nil default: return ErrInvalidVersionByte @@ -375,6 +381,12 @@ func IsValidMuxedAccountEd25519PublicKey(s string) bool { return err == nil } +// IsValidMuxedContractAddress validates a Stellar muxed contract W-address. +func IsValidMuxedContractAddress(s string) bool { + _, err := Decode(VersionByteMuxedContract, s) + return err == nil +} + // IsValidEd25519SecretSeed validates a stellar secret key func IsValidEd25519SecretSeed(i interface{}) bool { enc, ok := i.(string) diff --git a/strkey/muxed_contract.go b/strkey/muxed_contract.go new file mode 100644 index 0000000000..49e5e37b40 --- /dev/null +++ b/strkey/muxed_contract.go @@ -0,0 +1,67 @@ +package strkey + +import ( + "encoding/binary" + + "github.com/stellar/go-stellar-sdk/support/errors" +) + +type MuxedContract struct { + id uint64 + contractID [32]byte +} + +// SetID populates the muxed contract ID. +func (m *MuxedContract) SetID(id uint64) { + m.id = id +} + +// SetContractID populates the muxed contract's underlying C-address. +func (m *MuxedContract) SetContractID(address string) error { + raw, err := Decode(VersionByteContract, address) + if err != nil { + return errors.New("invalid contract address") + } + + copy(m.contractID[:], raw) + + return nil +} + +// ID returns the muxed contract id. +func (m *MuxedContract) ID() uint64 { + return m.id +} + +// ContractID returns the muxed contract's underlying C-address. +func (m *MuxedContract) ContractID() (string, error) { + return Encode(VersionByteContract, m.contractID[:]) +} + +// Contract returns the muxed contract's raw 32-byte contract id. +func (m *MuxedContract) Contract() [32]byte { + return m.contractID +} + +// Address returns the muxed contract W-address. +func (m *MuxedContract) Address() (string, error) { + var raw [40]byte + copy(raw[:32], m.contractID[:]) + binary.BigEndian.PutUint64(raw[32:], m.id) + return Encode(VersionByteMuxedContract, raw[:]) +} + +// DecodeMuxedContract receives a muxed contract W-address and parses it into +// a MuxedContract object containing a contract id and a muxed id. +func DecodeMuxedContract(address string) (*MuxedContract, error) { + raw, err := Decode(VersionByteMuxedContract, address) + if err != nil { + return nil, errors.New("invalid muxed contract") + } + + var muxed MuxedContract + copy(muxed.contractID[:], raw[:32]) + muxed.id = binary.BigEndian.Uint64(raw[32:]) + + return &muxed, nil +} diff --git a/strkey/muxed_contract_test.go b/strkey/muxed_contract_test.go new file mode 100644 index 0000000000..ee41193b7f --- /dev/null +++ b/strkey/muxed_contract_test.go @@ -0,0 +1,136 @@ +package strkey + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +// Vectors generated with rs-stellar-strkey@80085faa. +var muxedContractVectors = []struct { + id uint64 + address string +}{ + {0, "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAAAAAMIU"}, + {1, "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAAAAE4ZU"}, + {123, "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAAAPPSEK"}, + {123456, "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IG"}, + {9223372036854775808, "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQHAAAAAAAAAAAACMXO"}, + {18446744073709551615, "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQH77777777777774SY"}, +} + +const muxedContractBase = "CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXE" + +func TestMuxedContract_Address(t *testing.T) { + for _, v := range muxedContractVectors { + muxed := MuxedContract{} + require.NoError(t, muxed.SetContractID(muxedContractBase)) + muxed.SetID(v.id) + address, err := muxed.Address() + require.NoError(t, err) + assert.Equal(t, v.address, address) + } + + address, err := (&MuxedContract{}).Address() + require.NoError(t, err) + assert.Equal(t, "WAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADCKU", address) +} + +func TestDecodeMuxedContract(t *testing.T) { + for _, v := range muxedContractVectors { + muxed, err := DecodeMuxedContract(v.address) + require.NoError(t, err) + assert.Equal(t, v.id, muxed.ID()) + contractID, err := muxed.ContractID() + require.NoError(t, err) + assert.Equal(t, muxedContractBase, contractID) + contract := muxed.Contract() + assert.Equal(t, MustDecode(VersionByteContract, muxedContractBase), contract[:]) + assert.True(t, IsValidMuxedContractAddress(v.address)) + } + + for _, invalid := range []string{ + muxedContractBase, + "MA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAAAJLK", + // non-canonical: differs from a valid address only in the unused padding bit + "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IH", + // bad checksum + "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IE", + // truncated + "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6", + "", + } { + muxed, err := DecodeMuxedContract(invalid) + assert.EqualError(t, err, "invalid muxed contract", invalid) + assert.Nil(t, muxed) + assert.False(t, IsValidMuxedContractAddress(invalid), invalid) + } +} + +func TestDecodeMuxedContractRejectionReasons(t *testing.T) { + _, err := Decode(VersionByteMuxedContract, "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IE") + require.Error(t, err) + assert.Contains(t, err.Error(), "invalid checksum") + + _, err = Decode(VersionByteMuxedContract, "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IH") + require.Error(t, err) + assert.Contains(t, err.Error(), "non-canonical") +} + +// Vectors from the SEP-23 muxed contract addition (stellar/stellar-protocol#2020). +func TestMuxedContractSEP23Vectors(t *testing.T) { + const contract = "CA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUWDA" + hash := []byte{ + 0x3f, 0x0c, 0x34, 0xbf, 0x93, 0xad, 0x0d, 0x99, + 0x71, 0xd0, 0x4c, 0xcc, 0x90, 0xf7, 0x05, 0x51, + 0x1c, 0x83, 0x8a, 0xad, 0x97, 0x34, 0xa4, 0xa2, + 0xfb, 0x0d, 0x7a, 0x03, 0xfc, 0x7f, 0xe8, 0x9a, + } + + for _, v := range []struct { + id uint64 + address string + }{ + {0, "WA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAAAWWC"}, + // id above the maximum signed 64-bit integer + {9223372036854775808, "WA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJVAAAAAAAAAAAACWJY"}, + } { + muxed, err := DecodeMuxedContract(v.address) + require.NoError(t, err, v.address) + assert.Equal(t, v.id, muxed.ID()) + contractBytes := muxed.Contract() + assert.Equal(t, hash, contractBytes[:]) + contractID, err := muxed.ContractID() + require.NoError(t, err) + assert.Equal(t, contract, contractID) + address, err := muxed.Address() + require.NoError(t, err) + assert.Equal(t, v.address, address) + } + + for _, invalid := range []string{ + // the unused trailing bit is not zero + "WA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAAAWWD", + // length congruent to 6 mod 8 + "WA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAAAWWCA", + // decodes to 44 bytes instead of 43 + "WA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAAAAIOUI", + // the low 3 bits of the version byte are 7 + "W47QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAADXHW", + // invalid checksum + "WA7QYNF7SOWQ3GLR2BGMZEHXAVIRZA4KVWLTJJFC7MGXUA74P7UJUAAAAAAAAAAAAAWWA", + } { + muxed, err := DecodeMuxedContract(invalid) + assert.EqualError(t, err, "invalid muxed contract", invalid) + assert.Nil(t, muxed) + assert.False(t, IsValidMuxedContractAddress(invalid), invalid) + } +} + +func TestMuxedContract_SetContractID(t *testing.T) { + muxed := MuxedContract{} + assert.EqualError(t, muxed.SetContractID(""), "invalid contract address") + assert.EqualError(t, muxed.SetContractID("GA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQHES5"), "invalid contract address") + assert.Equal(t, MuxedContract{}, muxed) +} diff --git a/support/contractevents/event_test.go b/support/contractevents/event_test.go index fe4f8a384e..3d5c039c34 100644 --- a/support/contractevents/event_test.go +++ b/support/contractevents/event_test.go @@ -51,6 +51,13 @@ func TestScValCreators(t *testing.T) { assert.True(t, ok) assert.EqualValues(t, 4, amt.Hi) assert.EqualValues(t, 1234, amt.Lo) + + muxedContract := "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IG" + val = makeAddress(muxedContract) + assert.Equal(t, xdr.ScAddressTypeScAddressTypeMuxedContract, val.MustAddress().Type) + str, err := val.MustAddress().String() + require.NoError(t, err) + assert.Equal(t, muxedContract, str) } func TestEventGenerator(t *testing.T) { @@ -96,6 +103,35 @@ func TestSACTransferEvent(t *testing.T) { require.EqualValues(t, 0, transferEvent.Amount.Hi) } +// TestSACTransferEventMapData covers the event data shape a SAC emits for a +// transfer to a muxed destination (CAP-0067 M addresses, CAP-0084 W addresses): +// the topics carry the plain address and the data is {amount, to_muxed_id}. +func TestSACTransferEventMapData(t *testing.T) { + xdrEvent := GenerateEvent(EventTypeTransfer, randomAccount, zeroContract, "", randomAsset, big.NewInt(1000), passphrase) + amount := xdrEvent.Body.V0.Data + mapData := xdr.ScMap{ + {Key: makeSymbol("amount"), Val: amount}, + {Key: makeSymbol("to_muxed_id"), Val: xdr.ScVal{Type: xdr.ScValTypeScvU64, U64: func() *xdr.Uint64 { v := xdr.Uint64(7); return &v }()}}, + } + mapPtr := &mapData + xdrEvent.Body.V0.Data = xdr.ScVal{Type: xdr.ScValTypeScvMap, Map: &mapPtr} + + sacEvent, err := NewStellarAssetContractEvent(&xdrEvent, passphrase) + require.NoError(t, err) + transferEvent := sacEvent.(*TransferEvent) + require.Equal(t, zeroContract, transferEvent.To) + require.EqualValues(t, 1000, transferEvent.Amount.Lo) + require.EqualValues(t, 0, transferEvent.Amount.Hi) + + // A map without an "amount" key is not a balance change; it must not + // parse as a zero-amount transfer. + noAmount := xdr.ScMap{mapData[1]} + noAmountPtr := &noAmount + xdrEvent.Body.V0.Data = xdr.ScVal{Type: xdr.ScValTypeScvMap, Map: &noAmountPtr} + _, err = NewStellarAssetContractEvent(&xdrEvent, passphrase) + require.Error(t, err) +} + func TestSACEventCreation(t *testing.T) { var xdrEvent xdr.ContractEvent resetEvent := func(from string, to string, asset xdr.Asset) { diff --git a/support/contractevents/generate.go b/support/contractevents/generate.go index fed898359d..3969f8a348 100644 --- a/support/contractevents/generate.go +++ b/support/contractevents/generate.go @@ -158,6 +158,16 @@ func makeAddress(address string) xdr.ScVal { Id: xdr.Uint64(acct.ID()), Ed25519: acct.Ed25519(), } + case 'W': + muxed, err := strkey.DecodeMuxedContract(address) + if err != nil { + panic(fmt.Errorf("address is not a valid muxed contract: %s", address)) + } + scAddress.Type = xdr.ScAddressTypeScAddressTypeMuxedContract + scAddress.MuxedContract = &xdr.MuxedContract{ + Id: xdr.Uint64(muxed.ID()), + ContractId: muxed.Contract(), + } case 'L': scAddress.Type = xdr.ScAddressTypeScAddressTypeLiquidityPool scAddress.LiquidityPoolId = &xdr.PoolId{} diff --git a/support/contractevents/utils.go b/support/contractevents/utils.go index 2722053bbe..730db08792 100644 --- a/support/contractevents/utils.go +++ b/support/contractevents/utils.go @@ -43,10 +43,29 @@ func parseBalanceChangeEvent(topics xdr.ScVec, value xdr.ScVal) ( return } - amount, ok = value.GetI128() + amount, ok = eventAmount(value) if !ok { - return + return first, second, amount, ErrNotBalanceChangeEvent } return first, second, amount, nil } + +// eventAmount reads the amount from SAC event data. The data is either a bare +// i128, or (CAP-0067, and CAP-0084 for muxed contract destinations) a map +// whose "amount" key holds the i128, alongside keys such as "to_muxed_id". +func eventAmount(value xdr.ScVal) (xdr.Int128Parts, bool) { + if amount, ok := value.GetI128(); ok { + return amount, true + } + entries, ok := value.GetMap() + if !ok || entries == nil { + return xdr.Int128Parts{}, false + } + for _, entry := range *entries { + if key, ok := entry.Key.GetSym(); ok && key == "amount" { + return entry.Val.GetI128() + } + } + return xdr.Int128Parts{}, false +} diff --git a/xdr/Stellar-contract-config-setting.x b/xdr/Stellar-contract-config-setting.x index 80c0d7fcf2..bab260a983 100644 --- a/xdr/Stellar-contract-config-setting.x +++ b/xdr/Stellar-contract-config-setting.x @@ -296,7 +296,25 @@ enum ContractCostType { // Cost of performing BN254 scalar element inversion Bn254FrInv = 84, // Cost of performing BN254 G1 multi-scalar multiplication (MSM) - Bn254G1Msm = 85 + Bn254G1Msm = 85, + // Cost of decoding and expanding an ML-DSA-44 verifying key + MlDsa44DecodeVerifyingKey = 86, + // Cost of decoding and expanding an ML-DSA-65 verifying key + MlDsa65DecodeVerifyingKey = 87, + // Cost of decoding and expanding an ML-DSA-87 verifying key + MlDsa87DecodeVerifyingKey = 88, + // Cost of decoding an ML-DSA-44 signature + MlDsa44DecodeSignature = 89, + // Cost of decoding an ML-DSA-65 signature + MlDsa65DecodeSignature = 90, + // Cost of decoding an ML-DSA-87 signature + MlDsa87DecodeSignature = 91, + // Cost of verifying an ML-DSA-44 signature, linear in message + context length + VerifyMlDsa44Sig = 92, + // Cost of verifying an ML-DSA-65 signature, linear in message + context length + VerifyMlDsa65Sig = 93, + // Cost of verifying an ML-DSA-87 signature, linear in message + context length + VerifyMlDsa87Sig = 94 }; struct ContractCostParamEntry { diff --git a/xdr/Stellar-contract-spec.x b/xdr/Stellar-contract-spec.x index 33c4cec1e2..d87e643e4f 100644 --- a/xdr/Stellar-contract-spec.x +++ b/xdr/Stellar-contract-spec.x @@ -12,6 +12,8 @@ namespace stellar const SC_SPEC_DOC_LIMIT = 1024; +const SC_SPEC_TYPE_NAME_LIMIT = 1024; + enum SCSpecType { SC_SPEC_TYPE_VAL = 0, @@ -82,7 +84,7 @@ struct SCSpecTypeBytesN struct SCSpecTypeUDT { - string name<60>; + string name; }; union SCSpecTypeDef switch (SCSpecType type) @@ -134,7 +136,7 @@ struct SCSpecUDTStructV0 { string doc; string lib<80>; - string name<60>; + string name; SCSpecUDTStructFieldV0 fields<>; }; @@ -169,7 +171,7 @@ struct SCSpecUDTUnionV0 { string doc; string lib<80>; - string name<60>; + string name; SCSpecUDTUnionCaseV0 cases<>; }; @@ -184,7 +186,7 @@ struct SCSpecUDTEnumV0 { string doc; string lib<80>; - string name<60>; + string name; SCSpecUDTEnumCaseV0 cases<>; }; @@ -199,7 +201,7 @@ struct SCSpecUDTErrorEnumV0 { string doc; string lib<80>; - string name<60>; + string name; SCSpecUDTErrorEnumCaseV0 cases<>; }; @@ -243,7 +245,7 @@ struct SCSpecEventV0 { string doc; string lib<80>; - SCSymbol name; + string name; SCSymbol prefixTopics<2>; SCSpecEventParamV0 params<>; SCSpecEventDataFormat dataFormat; diff --git a/xdr/Stellar-contract.x b/xdr/Stellar-contract.x index 9630ddf05e..ad04b1bc39 100644 --- a/xdr/Stellar-contract.x +++ b/xdr/Stellar-contract.x @@ -182,7 +182,8 @@ enum SCAddressType SC_ADDRESS_TYPE_CONTRACT = 1, SC_ADDRESS_TYPE_MUXED_ACCOUNT = 2, SC_ADDRESS_TYPE_CLAIMABLE_BALANCE = 3, - SC_ADDRESS_TYPE_LIQUIDITY_POOL = 4 + SC_ADDRESS_TYPE_LIQUIDITY_POOL = 4, + SC_ADDRESS_TYPE_MUXED_CONTRACT = 5 }; struct MuxedEd25519Account @@ -191,6 +192,11 @@ struct MuxedEd25519Account uint256 ed25519; }; +struct MuxedContract +{ + uint64 id; + ContractID contractId; +}; union SCAddress switch (SCAddressType type) { @@ -204,6 +210,8 @@ case SC_ADDRESS_TYPE_CLAIMABLE_BALANCE: ClaimableBalanceID claimableBalanceId; case SC_ADDRESS_TYPE_LIQUIDITY_POOL: PoolID liquidityPoolId; +case SC_ADDRESS_TYPE_MUXED_CONTRACT: + MuxedContract muxedContract; }; struct ContractExecutableExternalRef { diff --git a/xdr/Stellar-ledger.x b/xdr/Stellar-ledger.x index 9acf1d773c..47726e3fa5 100644 --- a/xdr/Stellar-ledger.x +++ b/xdr/Stellar-ledger.x @@ -14,7 +14,9 @@ enum StellarValueType { STELLAR_VALUE_BASIC = 0, STELLAR_VALUE_SIGNED = 1, - STELLAR_VALUE_EMPTY_TX_SET = 2 + STELLAR_VALUE_EMPTY_TX_SET = 2, + STELLAR_VALUE_SIGNED_MS = 3, + STELLAR_VALUE_EMPTY_TX_SET_MS = 4 }; struct LedgerCloseValueSignature @@ -52,6 +54,21 @@ struct StellarValue uint32 previousLedgerVersion; LedgerCloseValueSignature lcValueSignature; } proposedValue; + case STELLAR_VALUE_SIGNED_MS: + struct + { + TimePointMs closeTimeMs; // closeTime == closeTimeMs / 1000 + LedgerCloseValueSignature lcValueSignature; + } signedMsValue; + case STELLAR_VALUE_EMPTY_TX_SET_MS: + struct + { + TimePointMs closeTimeMs; // closeTime == closeTimeMs / 1000 + Hash txSetHash; + Hash previousLedgerHash; + uint32 previousLedgerVersion; + LedgerCloseValueSignature lcValueSignature; + } proposedMsValue; } ext; }; diff --git a/xdr/Stellar-types.x b/xdr/Stellar-types.x index 670be6fd9f..9385455d4c 100644 --- a/xdr/Stellar-types.x +++ b/xdr/Stellar-types.x @@ -16,6 +16,8 @@ typedef hyper int64; typedef uint64 TimePoint; typedef uint64 Duration; +// Milliseconds since the Unix epoch. TimePoint is whole seconds. +typedef uint64 TimePointMs; // An ExtensionPoint is always marshaled as a 32-bit 0 value. At a // later point, it can be replaced by a different union so as to diff --git a/xdr/scval.go b/xdr/scval.go index 38c9b336b4..c4c26373f1 100644 --- a/xdr/scval.go +++ b/xdr/scval.go @@ -2,6 +2,7 @@ package xdr import ( "bytes" + "encoding/binary" "encoding/hex" "fmt" "math/big" @@ -31,6 +32,12 @@ func (address ScAddress) String() (string, error) { }, } result, err = muxed.GetAddress() + case ScAddressTypeScAddressTypeMuxedContract: + payload := address.MustMuxedContract() + var raw [40]byte + copy(raw[:32], payload.ContractId[:]) + binary.BigEndian.PutUint64(raw[32:], uint64(payload.Id)) + result, err = strkey.Encode(strkey.VersionByteMuxedContract, raw[:]) case ScAddressTypeScAddressTypeLiquidityPool: poolID := address.MustLiquidityPoolId() result, err = strkey.Encode(strkey.VersionByteLiquidityPool, poolID[:]) @@ -163,6 +170,8 @@ func (s ScAddress) Equals(o ScAddress) bool { case ScAddressTypeScAddressTypeMuxedAccount: return s.MustMuxedAccount().Id == o.MustMuxedAccount().Id && s.MustMuxedAccount().Ed25519.Equals(o.MustMuxedAccount().Ed25519) + case ScAddressTypeScAddressTypeMuxedContract: + return s.MustMuxedContract() == o.MustMuxedContract() default: panic("unknown ScAddress type: " + s.Type.String()) } diff --git a/xdr/scval_test.go b/xdr/scval_test.go index 70bc8136ce..bc7291c6d3 100644 --- a/xdr/scval_test.go +++ b/xdr/scval_test.go @@ -93,6 +93,16 @@ func TestScAddressString(t *testing.T) { }, expected: strkey.MustEncode(strkey.VersionByteContract, contractID[:]), }, + { + address: ScAddress{ + Type: ScAddressTypeScAddressTypeMuxedContract, + MuxedContract: &MuxedContract{ + Id: 123456, + ContractId: ContractId(strkey.MustDecode(strkey.VersionByteContract, "CA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAXE")), + }, + }, + expected: "WA3D5KRYM6CB7OWQ6TWYRR3Z4T7GNZLKERYNZGGA5SOAOPIFY6YQGAAAAAAAAAPCIA6IG", + }, { address: ScAddress{ Type: ScAddressTypeScAddressTypeClaimableBalance, diff --git a/xdr/stellar_value.go b/xdr/stellar_value.go new file mode 100644 index 0000000000..a598adfea2 --- /dev/null +++ b/xdr/stellar_value.go @@ -0,0 +1,25 @@ +package xdr + +// LedgerCloseValueSignature returns the close-value signature from whichever +// StellarValue arm carries it: SIGNED, EMPTY_TX_SET (CAP-0083), or their +// millisecond close-time counterparts SIGNED_MS and EMPTY_TX_SET_MS +// (CAP-0088). Only BASIC has no signature. +// +// The generated GetLcValueSignature only reads the SIGNED arm, so it finds no +// signature on ledgers closed with an empty transaction set, or on any ledger +// after the Protocol 30 upgrade. +func (e StellarValueExt) LedgerCloseValueSignature() (LedgerCloseValueSignature, bool) { + if sig, ok := e.GetLcValueSignature(); ok { + return sig, true + } + if v, ok := e.GetProposedValue(); ok { + return v.LcValueSignature, true + } + if v, ok := e.GetSignedMsValue(); ok { + return v.LcValueSignature, true + } + if v, ok := e.GetProposedMsValue(); ok { + return v.LcValueSignature, true + } + return LedgerCloseValueSignature{}, false +} diff --git a/xdr/stellar_value_test.go b/xdr/stellar_value_test.go new file mode 100644 index 0000000000..208aae92e9 --- /dev/null +++ b/xdr/stellar_value_test.go @@ -0,0 +1,50 @@ +package xdr + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestStellarValueExtLedgerCloseValueSignature(t *testing.T) { + sig := LedgerCloseValueSignature{ + NodeId: NodeId{Type: PublicKeyTypePublicKeyTypeEd25519, Ed25519: &Uint256{1, 2, 3}}, + Signature: Signature{4, 5, 6}, + } + + for name, ext := range map[string]StellarValueExt{ + "SIGNED": { + V: StellarValueTypeStellarValueSigned, + LcValueSignature: &sig, + }, + "EMPTY_TX_SET": { + V: StellarValueTypeStellarValueEmptyTxSet, + ProposedValue: &StellarValueProposedValue{LcValueSignature: sig}, + }, + "SIGNED_MS": { + V: StellarValueTypeStellarValueSignedMs, + SignedMsValue: &StellarValueSignedMsValue{ + CloseTimeMs: TimePointMs(1594584547000), + LcValueSignature: sig, + }, + }, + "EMPTY_TX_SET_MS": { + V: StellarValueTypeStellarValueEmptyTxSetMs, + ProposedMsValue: &StellarValueProposedMsValue{ + CloseTimeMs: TimePointMs(1594584547000), + LcValueSignature: sig, + }, + }, + } { + t.Run(name, func(t *testing.T) { + got, ok := ext.LedgerCloseValueSignature() + assert.True(t, ok) + assert.Equal(t, sig, got) + }) + } + + t.Run("BASIC", func(t *testing.T) { + _, ok := StellarValueExt{V: StellarValueTypeStellarValueBasic}.LedgerCloseValueSignature() + assert.False(t, ok) + }) +} diff --git a/xdr/xdr_commit_generated.txt b/xdr/xdr_commit_generated.txt index 0b697893f4..3cb5e06af2 100644 --- a/xdr/xdr_commit_generated.txt +++ b/xdr/xdr_commit_generated.txt @@ -1 +1 @@ -9c9c145953e80990d6ff1ae3a6a973a0ce6d0694 \ No newline at end of file +4f524bbac80c781c06e4fb5fc93a2d0d331d6705 \ No newline at end of file diff --git a/xdr/xdr_generated.go b/xdr/xdr_generated.go index 4c358de0aa..f2d232b2df 100644 --- a/xdr/xdr_generated.go +++ b/xdr/xdr_generated.go @@ -33,18 +33,18 @@ import ( // XdrFilesSHA256 is the SHA256 hashes of source files. var XdrFilesSHA256 = map[string]string{ "xdr/Stellar-SCP.x": "6aed428fb6c2d000f5bc1eef0ba685d6108f3faa96208ffa588c0e2990813939", - "xdr/Stellar-contract-config-setting.x": "a034a3eb4d8b94f5c4c573fe14a1afc548aa316e1e897aa70e5a1688aada3c77", + "xdr/Stellar-contract-config-setting.x": "78327f22b47d931c92542d3b5543162dcf99830f409bd6cecc80410424742fb0", "xdr/Stellar-contract-env-meta.x": "75a271414d852096fea3283c63b7f2a702f2905f78fc28eb60ec7d7bd366a780", "xdr/Stellar-contract-meta.x": "f01532c11ca044e19d9f9f16fe373e9af64835da473be556b9a807ee3319ae0d", - "xdr/Stellar-contract-spec.x": "7d99679155f6ce029f4f2bd8e1bf09524ef2f3e4ca8973265085cfcfdbdae987", - "xdr/Stellar-contract.x": "a59c25f38b4705ae149a8f049eb686f6018712d792b9207318a644ea5b5f52b5", + "xdr/Stellar-contract-spec.x": "943e65a0a8f5e8a5b19738ca7d029ce7a38fea4b1f9f59cb7d4262094882e03d", + "xdr/Stellar-contract.x": "e92d679eb8682b59ad0262422ddca3a43ad5498702ae2e90210bc1f5cead7a8c", "xdr/Stellar-exporter.x": "a00c83d02e8c8382e06f79a191f1fb5abd097a4bbcab8481c67467e3270e0529", "xdr/Stellar-internal.x": "227835866c1b2122d1eaf28839ba85ea7289d1cb681dda4ca619c2da3d71fe00", "xdr/Stellar-ledger-entries.x": "65a24350a69f0d1c74c0dce61a68db2a657611ad9318cb2736860fd99a2db020", - "xdr/Stellar-ledger.x": "6bce772b73dba183dae8f87da2a5d97fb0d36ad3695aec5edd21b1d4e5c0dc55", + "xdr/Stellar-ledger.x": "b98cc304cb7c7966d6d17842bbe9d7eb7e2af3039d6dafe306e52fa99900d6dc", "xdr/Stellar-overlay.x": "8c9b9c13c86fa4672f03d741705b41e7221be0fc48e1ea6eeb1ba07d31ec0723", "xdr/Stellar-transaction.x": "8f7accb9d9e0c077e6c5b43fc32eb06badb1cd3e6e10733387836dd8804ce89f", - "xdr/Stellar-types.x": "3ba2eb53dad5c7f4f10441d1af7a95778bf31bbbbe2a802ddc3b981910d7c397", + "xdr/Stellar-types.x": "3c56d9553b4b273967c4330db1cbdac8fba333c46f44d650fcdf2fe10744c46a", } var ErrMaxDecodingDepthReached = errors.New("maximum decoding depth reached") @@ -12201,20 +12201,26 @@ var _ xdrType = (*UpgradeType)(nil) // { // STELLAR_VALUE_BASIC = 0, // STELLAR_VALUE_SIGNED = 1, -// STELLAR_VALUE_EMPTY_TX_SET = 2 +// STELLAR_VALUE_EMPTY_TX_SET = 2, +// STELLAR_VALUE_SIGNED_MS = 3, +// STELLAR_VALUE_EMPTY_TX_SET_MS = 4 // }; type StellarValueType int32 const ( - StellarValueTypeStellarValueBasic StellarValueType = 0 - StellarValueTypeStellarValueSigned StellarValueType = 1 - StellarValueTypeStellarValueEmptyTxSet StellarValueType = 2 + StellarValueTypeStellarValueBasic StellarValueType = 0 + StellarValueTypeStellarValueSigned StellarValueType = 1 + StellarValueTypeStellarValueEmptyTxSet StellarValueType = 2 + StellarValueTypeStellarValueSignedMs StellarValueType = 3 + StellarValueTypeStellarValueEmptyTxSetMs StellarValueType = 4 ) var stellarValueTypeMap = map[int32]string{ 0: "StellarValueTypeStellarValueBasic", 1: "StellarValueTypeStellarValueSigned", 2: "StellarValueTypeStellarValueEmptyTxSet", + 3: "StellarValueTypeStellarValueSignedMs", + 4: "StellarValueTypeStellarValueEmptyTxSetMs", } // ValidEnum validates a proposed value for this enum. Implements @@ -12456,6 +12462,186 @@ func (s StellarValueProposedValue) xdrType() {} var _ xdrType = (*StellarValueProposedValue)(nil) +// StellarValueSignedMsValue is an XDR NestedStruct defines as: +// +// struct +// { +// TimePointMs closeTimeMs; // closeTime == closeTimeMs / 1000 +// LedgerCloseValueSignature lcValueSignature; +// } +type StellarValueSignedMsValue struct { + CloseTimeMs TimePointMs + LcValueSignature LedgerCloseValueSignature +} + +// EncodeTo encodes this value using the Encoder. +func (s *StellarValueSignedMsValue) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.CloseTimeMs.EncodeTo(e); err != nil { + return err + } + if err = s.LcValueSignature.EncodeTo(e); err != nil { + return err + } + return nil +} + +var _ decoderFrom = (*StellarValueSignedMsValue)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *StellarValueSignedMsValue) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) { + if maxDepth == 0 { + return 0, fmt.Errorf("decoding StellarValueSignedMsValue: %w", ErrMaxDecodingDepthReached) + } + maxDepth -= 1 + var err error + var n, nTmp int + nTmp, err = s.CloseTimeMs.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding TimePointMs: %w", err) + } + nTmp, err = s.LcValueSignature.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding LedgerCloseValueSignature: %w", err) + } + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s StellarValueSignedMsValue) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *StellarValueSignedMsValue) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + o := xdr.DefaultDecodeOptions + o.MaxInputLen = len(inp) + d := xdr.NewDecoderWithOptions(r, o) + _, err := s.DecodeFrom(d, o.MaxDepth) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*StellarValueSignedMsValue)(nil) + _ encoding.BinaryUnmarshaler = (*StellarValueSignedMsValue)(nil) +) + +// xdrType signals that this type represents XDR values defined by this package. +func (s StellarValueSignedMsValue) xdrType() {} + +var _ xdrType = (*StellarValueSignedMsValue)(nil) + +// StellarValueProposedMsValue is an XDR NestedStruct defines as: +// +// struct +// { +// TimePointMs closeTimeMs; // closeTime == closeTimeMs / 1000 +// Hash txSetHash; +// Hash previousLedgerHash; +// uint32 previousLedgerVersion; +// LedgerCloseValueSignature lcValueSignature; +// } +type StellarValueProposedMsValue struct { + CloseTimeMs TimePointMs + TxSetHash Hash + PreviousLedgerHash Hash + PreviousLedgerVersion Uint32 + LcValueSignature LedgerCloseValueSignature +} + +// EncodeTo encodes this value using the Encoder. +func (s *StellarValueProposedMsValue) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.CloseTimeMs.EncodeTo(e); err != nil { + return err + } + if err = s.TxSetHash.EncodeTo(e); err != nil { + return err + } + if err = s.PreviousLedgerHash.EncodeTo(e); err != nil { + return err + } + if err = s.PreviousLedgerVersion.EncodeTo(e); err != nil { + return err + } + if err = s.LcValueSignature.EncodeTo(e); err != nil { + return err + } + return nil +} + +var _ decoderFrom = (*StellarValueProposedMsValue)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *StellarValueProposedMsValue) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) { + if maxDepth == 0 { + return 0, fmt.Errorf("decoding StellarValueProposedMsValue: %w", ErrMaxDecodingDepthReached) + } + maxDepth -= 1 + var err error + var n, nTmp int + nTmp, err = s.CloseTimeMs.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding TimePointMs: %w", err) + } + nTmp, err = s.TxSetHash.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Hash: %w", err) + } + nTmp, err = s.PreviousLedgerHash.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Hash: %w", err) + } + nTmp, err = s.PreviousLedgerVersion.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint32: %w", err) + } + nTmp, err = s.LcValueSignature.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding LedgerCloseValueSignature: %w", err) + } + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s StellarValueProposedMsValue) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *StellarValueProposedMsValue) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + o := xdr.DefaultDecodeOptions + o.MaxInputLen = len(inp) + d := xdr.NewDecoderWithOptions(r, o) + _, err := s.DecodeFrom(d, o.MaxDepth) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*StellarValueProposedMsValue)(nil) + _ encoding.BinaryUnmarshaler = (*StellarValueProposedMsValue)(nil) +) + +// xdrType signals that this type represents XDR values defined by this package. +func (s StellarValueProposedMsValue) xdrType() {} + +var _ xdrType = (*StellarValueProposedMsValue)(nil) + // StellarValueExt is an XDR NestedUnion defines as: // // union switch (StellarValueType v) @@ -12472,11 +12658,28 @@ var _ xdrType = (*StellarValueProposedValue)(nil) // uint32 previousLedgerVersion; // LedgerCloseValueSignature lcValueSignature; // } proposedValue; +// case STELLAR_VALUE_SIGNED_MS: +// struct +// { +// TimePointMs closeTimeMs; // closeTime == closeTimeMs / 1000 +// LedgerCloseValueSignature lcValueSignature; +// } signedMsValue; +// case STELLAR_VALUE_EMPTY_TX_SET_MS: +// struct +// { +// TimePointMs closeTimeMs; // closeTime == closeTimeMs / 1000 +// Hash txSetHash; +// Hash previousLedgerHash; +// uint32 previousLedgerVersion; +// LedgerCloseValueSignature lcValueSignature; +// } proposedMsValue; // } type StellarValueExt struct { V StellarValueType LcValueSignature *LedgerCloseValueSignature ProposedValue *StellarValueProposedValue + SignedMsValue *StellarValueSignedMsValue + ProposedMsValue *StellarValueProposedMsValue } // SwitchFieldName returns the field name in which this union's @@ -12495,6 +12698,10 @@ func (u StellarValueExt) ArmForSwitch(sw int32) (string, bool) { return "LcValueSignature", true case StellarValueTypeStellarValueEmptyTxSet: return "ProposedValue", true + case StellarValueTypeStellarValueSignedMs: + return "SignedMsValue", true + case StellarValueTypeStellarValueEmptyTxSetMs: + return "ProposedMsValue", true } return "-", false } @@ -12519,6 +12726,20 @@ func NewStellarValueExt(v StellarValueType, value interface{}) (result StellarVa return } result.ProposedValue = &tv + case StellarValueTypeStellarValueSignedMs: + tv, ok := value.(StellarValueSignedMsValue) + if !ok { + err = errors.New("invalid value, must be StellarValueSignedMsValue") + return + } + result.SignedMsValue = &tv + case StellarValueTypeStellarValueEmptyTxSetMs: + tv, ok := value.(StellarValueProposedMsValue) + if !ok { + err = errors.New("invalid value, must be StellarValueProposedMsValue") + return + } + result.ProposedMsValue = &tv } return } @@ -12573,6 +12794,56 @@ func (u StellarValueExt) GetProposedValue() (result StellarValueProposedValue, o return } +// MustSignedMsValue retrieves the SignedMsValue value from the union, +// panicing if the value is not set. +func (u StellarValueExt) MustSignedMsValue() StellarValueSignedMsValue { + val, ok := u.GetSignedMsValue() + + if !ok { + panic("arm SignedMsValue is not set") + } + + return val +} + +// GetSignedMsValue retrieves the SignedMsValue value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u StellarValueExt) GetSignedMsValue() (result StellarValueSignedMsValue, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.V)) + + if armName == "SignedMsValue" { + result = *u.SignedMsValue + ok = true + } + + return +} + +// MustProposedMsValue retrieves the ProposedMsValue value from the union, +// panicing if the value is not set. +func (u StellarValueExt) MustProposedMsValue() StellarValueProposedMsValue { + val, ok := u.GetProposedMsValue() + + if !ok { + panic("arm ProposedMsValue is not set") + } + + return val +} + +// GetProposedMsValue retrieves the ProposedMsValue value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u StellarValueExt) GetProposedMsValue() (result StellarValueProposedMsValue, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.V)) + + if armName == "ProposedMsValue" { + result = *u.ProposedMsValue + ok = true + } + + return +} + // EncodeTo encodes this value using the Encoder. func (u StellarValueExt) EncodeTo(e *xdr.Encoder) error { var err error @@ -12593,6 +12864,16 @@ func (u StellarValueExt) EncodeTo(e *xdr.Encoder) error { return err } return nil + case StellarValueTypeStellarValueSignedMs: + if err = (*u.SignedMsValue).EncodeTo(e); err != nil { + return err + } + return nil + case StellarValueTypeStellarValueEmptyTxSetMs: + if err = (*u.ProposedMsValue).EncodeTo(e); err != nil { + return err + } + return nil } return fmt.Errorf("V (StellarValueType) switch value '%d' is not valid for union StellarValueExt", u.V) } @@ -12638,6 +12919,28 @@ func (u *StellarValueExt) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) return n, fmt.Errorf("decoding StellarValueProposedValue: %w", err) } return n, nil + case StellarValueTypeStellarValueSignedMs: + if err = xdr.TrackOutputBytesOf[StellarValueSignedMsValue](d); err != nil { + return n, fmt.Errorf("decoding StellarValueSignedMsValue: %w", err) + } + u.SignedMsValue = new(StellarValueSignedMsValue) + nTmp, err = (*u.SignedMsValue).DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding StellarValueSignedMsValue: %w", err) + } + return n, nil + case StellarValueTypeStellarValueEmptyTxSetMs: + if err = xdr.TrackOutputBytesOf[StellarValueProposedMsValue](d); err != nil { + return n, fmt.Errorf("decoding StellarValueProposedMsValue: %w", err) + } + u.ProposedMsValue = new(StellarValueProposedMsValue) + nTmp, err = (*u.ProposedMsValue).DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding StellarValueProposedMsValue: %w", err) + } + return n, nil } return n, fmt.Errorf("union StellarValueExt has invalid V (StellarValueType) switch value '%d'", u.V) } @@ -12699,6 +13002,21 @@ var _ xdrType = (*StellarValueExt)(nil) // uint32 previousLedgerVersion; // LedgerCloseValueSignature lcValueSignature; // } proposedValue; +// case STELLAR_VALUE_SIGNED_MS: +// struct +// { +// TimePointMs closeTimeMs; // closeTime == closeTimeMs / 1000 +// LedgerCloseValueSignature lcValueSignature; +// } signedMsValue; +// case STELLAR_VALUE_EMPTY_TX_SET_MS: +// struct +// { +// TimePointMs closeTimeMs; // closeTime == closeTimeMs / 1000 +// Hash txSetHash; +// Hash previousLedgerHash; +// uint32 previousLedgerVersion; +// LedgerCloseValueSignature lcValueSignature; +// } proposedMsValue; // } // ext; // }; @@ -51126,6 +51444,66 @@ func (s Duration) xdrType() {} var _ xdrType = (*Duration)(nil) +// TimePointMs is an XDR Typedef defines as: +// +// typedef uint64 TimePointMs; +type TimePointMs Uint64 + +// EncodeTo encodes this value using the Encoder. +func (s TimePointMs) EncodeTo(e *xdr.Encoder) error { + var err error + if err = Uint64(s).EncodeTo(e); err != nil { + return err + } + return nil +} + +var _ decoderFrom = (*TimePointMs)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *TimePointMs) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) { + if maxDepth == 0 { + return 0, fmt.Errorf("decoding TimePointMs: %w", ErrMaxDecodingDepthReached) + } + maxDepth -= 1 + var err error + var n, nTmp int + nTmp, err = (*Uint64)(s).DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint64: %w", err) + } + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s TimePointMs) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *TimePointMs) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + o := xdr.DefaultDecodeOptions + o.MaxInputLen = len(inp) + d := xdr.NewDecoderWithOptions(r, o) + _, err := s.DecodeFrom(d, o.MaxDepth) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*TimePointMs)(nil) + _ encoding.BinaryUnmarshaler = (*TimePointMs)(nil) +) + +// xdrType signals that this type represents XDR values defined by this package. +func (s TimePointMs) xdrType() {} + +var _ xdrType = (*TimePointMs)(nil) + // ExtensionPoint is an XDR Union defines as: // // union ExtensionPoint switch (int v) @@ -53876,6 +54254,11 @@ var _ xdrType = (*ScMetaEntry)(nil) // const SC_SPEC_DOC_LIMIT = 1024; const ScSpecDocLimit = 1024 +// ScSpecTypeNameLimit is an XDR Const defines as: +// +// const SC_SPEC_TYPE_NAME_LIMIT = 1024; +const ScSpecTypeNameLimit = 1024 + // ScSpecType is an XDR Enum defines as: // // enum SCSpecType @@ -54490,10 +54873,10 @@ var _ xdrType = (*ScSpecTypeBytesN)(nil) // // struct SCSpecTypeUDT // { -// string name<60>; +// string name; // }; type ScSpecTypeUdt struct { - Name string `xdrmaxsize:"60"` + Name string `xdrmaxsize:"1024"` } // EncodeTo encodes this value using the Encoder. @@ -54515,7 +54898,7 @@ func (s *ScSpecTypeUdt) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) { maxDepth -= 1 var err error var n, nTmp int - s.Name, nTmp, err = d.DecodeString(60) + s.Name, nTmp, err = d.DecodeString(1024) n += nTmp if err != nil { return n, fmt.Errorf("decoding Name: %w", err) @@ -55313,13 +55696,13 @@ var _ xdrType = (*ScSpecUdtStructFieldV0)(nil) // { // string doc; // string lib<80>; -// string name<60>; +// string name; // SCSpecUDTStructFieldV0 fields<>; // }; type ScSpecUdtStructV0 struct { Doc string `xdrmaxsize:"1024"` Lib string `xdrmaxsize:"80"` - Name string `xdrmaxsize:"60"` + Name string `xdrmaxsize:"1024"` Fields []ScSpecUdtStructFieldV0 } @@ -55366,7 +55749,7 @@ func (s *ScSpecUdtStructV0) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, erro if err != nil { return n, fmt.Errorf("decoding Lib: %w", err) } - s.Name, nTmp, err = d.DecodeString(60) + s.Name, nTmp, err = d.DecodeString(1024) n += nTmp if err != nil { return n, fmt.Errorf("decoding Name: %w", err) @@ -55914,13 +56297,13 @@ var _ xdrType = (*ScSpecUdtUnionCaseV0)(nil) // { // string doc; // string lib<80>; -// string name<60>; +// string name; // SCSpecUDTUnionCaseV0 cases<>; // }; type ScSpecUdtUnionV0 struct { Doc string `xdrmaxsize:"1024"` Lib string `xdrmaxsize:"80"` - Name string `xdrmaxsize:"60"` + Name string `xdrmaxsize:"1024"` Cases []ScSpecUdtUnionCaseV0 } @@ -55967,7 +56350,7 @@ func (s *ScSpecUdtUnionV0) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error if err != nil { return n, fmt.Errorf("decoding Lib: %w", err) } - s.Name, nTmp, err = d.DecodeString(60) + s.Name, nTmp, err = d.DecodeString(1024) n += nTmp if err != nil { return n, fmt.Errorf("decoding Name: %w", err) @@ -56125,13 +56508,13 @@ var _ xdrType = (*ScSpecUdtEnumCaseV0)(nil) // { // string doc; // string lib<80>; -// string name<60>; +// string name; // SCSpecUDTEnumCaseV0 cases<>; // }; type ScSpecUdtEnumV0 struct { Doc string `xdrmaxsize:"1024"` Lib string `xdrmaxsize:"80"` - Name string `xdrmaxsize:"60"` + Name string `xdrmaxsize:"1024"` Cases []ScSpecUdtEnumCaseV0 } @@ -56178,7 +56561,7 @@ func (s *ScSpecUdtEnumV0) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) if err != nil { return n, fmt.Errorf("decoding Lib: %w", err) } - s.Name, nTmp, err = d.DecodeString(60) + s.Name, nTmp, err = d.DecodeString(1024) n += nTmp if err != nil { return n, fmt.Errorf("decoding Name: %w", err) @@ -56336,13 +56719,13 @@ var _ xdrType = (*ScSpecUdtErrorEnumCaseV0)(nil) // { // string doc; // string lib<80>; -// string name<60>; +// string name; // SCSpecUDTErrorEnumCaseV0 cases<>; // }; type ScSpecUdtErrorEnumV0 struct { Doc string `xdrmaxsize:"1024"` Lib string `xdrmaxsize:"80"` - Name string `xdrmaxsize:"60"` + Name string `xdrmaxsize:"1024"` Cases []ScSpecUdtErrorEnumCaseV0 } @@ -56389,7 +56772,7 @@ func (s *ScSpecUdtErrorEnumV0) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, e if err != nil { return n, fmt.Errorf("decoding Lib: %w", err) } - s.Name, nTmp, err = d.DecodeString(60) + s.Name, nTmp, err = d.DecodeString(1024) n += nTmp if err != nil { return n, fmt.Errorf("decoding Name: %w", err) @@ -56980,15 +57363,15 @@ var _ xdrType = (*ScSpecEventDataFormat)(nil) // { // string doc; // string lib<80>; -// SCSymbol name; +// string name; // SCSymbol prefixTopics<2>; // SCSpecEventParamV0 params<>; // SCSpecEventDataFormat dataFormat; // }; type ScSpecEventV0 struct { - Doc string `xdrmaxsize:"1024"` - Lib string `xdrmaxsize:"80"` - Name ScSymbol + Doc string `xdrmaxsize:"1024"` + Lib string `xdrmaxsize:"80"` + Name string `xdrmaxsize:"1024"` PrefixTopics []ScSymbol `xdrmaxsize:"2"` Params []ScSpecEventParamV0 DataFormat ScSpecEventDataFormat @@ -57003,7 +57386,7 @@ func (s *ScSpecEventV0) EncodeTo(e *xdr.Encoder) error { if _, err = e.EncodeString(string(s.Lib)); err != nil { return err } - if err = s.Name.EncodeTo(e); err != nil { + if _, err = e.EncodeString(string(s.Name)); err != nil { return err } if _, err = e.EncodeUint(uint32(len(s.PrefixTopics))); err != nil { @@ -57048,10 +57431,10 @@ func (s *ScSpecEventV0) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) { if err != nil { return n, fmt.Errorf("decoding Lib: %w", err) } - nTmp, err = s.Name.DecodeFrom(d, maxDepth) + s.Name, nTmp, err = d.DecodeString(1024) n += nTmp if err != nil { - return n, fmt.Errorf("decoding ScSymbol: %w", err) + return n, fmt.Errorf("decoding Name: %w", err) } var l uint32 l, nTmp, err = d.DecodeUint() @@ -59099,7 +59482,8 @@ var _ xdrType = (*ContractExecutableType)(nil) // SC_ADDRESS_TYPE_CONTRACT = 1, // SC_ADDRESS_TYPE_MUXED_ACCOUNT = 2, // SC_ADDRESS_TYPE_CLAIMABLE_BALANCE = 3, -// SC_ADDRESS_TYPE_LIQUIDITY_POOL = 4 +// SC_ADDRESS_TYPE_LIQUIDITY_POOL = 4, +// SC_ADDRESS_TYPE_MUXED_CONTRACT = 5 // }; type ScAddressType int32 @@ -59109,6 +59493,7 @@ const ( ScAddressTypeScAddressTypeMuxedAccount ScAddressType = 2 ScAddressTypeScAddressTypeClaimableBalance ScAddressType = 3 ScAddressTypeScAddressTypeLiquidityPool ScAddressType = 4 + ScAddressTypeScAddressTypeMuxedContract ScAddressType = 5 ) var scAddressTypeMap = map[int32]string{ @@ -59117,6 +59502,7 @@ var scAddressTypeMap = map[int32]string{ 2: "ScAddressTypeScAddressTypeMuxedAccount", 3: "ScAddressTypeScAddressTypeClaimableBalance", 4: "ScAddressTypeScAddressTypeLiquidityPool", + 5: "ScAddressTypeScAddressTypeMuxedContract", } // ValidEnum validates a proposed value for this enum. Implements @@ -59263,6 +59649,81 @@ func (s MuxedEd25519Account) xdrType() {} var _ xdrType = (*MuxedEd25519Account)(nil) +// MuxedContract is an XDR Struct defines as: +// +// struct MuxedContract +// { +// uint64 id; +// ContractID contractId; +// }; +type MuxedContract struct { + Id Uint64 + ContractId ContractId +} + +// EncodeTo encodes this value using the Encoder. +func (s *MuxedContract) EncodeTo(e *xdr.Encoder) error { + var err error + if err = s.Id.EncodeTo(e); err != nil { + return err + } + if err = s.ContractId.EncodeTo(e); err != nil { + return err + } + return nil +} + +var _ decoderFrom = (*MuxedContract)(nil) + +// DecodeFrom decodes this value using the Decoder. +func (s *MuxedContract) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) { + if maxDepth == 0 { + return 0, fmt.Errorf("decoding MuxedContract: %w", ErrMaxDecodingDepthReached) + } + maxDepth -= 1 + var err error + var n, nTmp int + nTmp, err = s.Id.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding Uint64: %w", err) + } + nTmp, err = s.ContractId.DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding ContractId: %w", err) + } + return n, nil +} + +// MarshalBinary implements encoding.BinaryMarshaler. +func (s MuxedContract) MarshalBinary() ([]byte, error) { + b := bytes.Buffer{} + e := xdr.NewEncoder(&b) + err := s.EncodeTo(e) + return b.Bytes(), err +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler. +func (s *MuxedContract) UnmarshalBinary(inp []byte) error { + r := bytes.NewReader(inp) + o := xdr.DefaultDecodeOptions + o.MaxInputLen = len(inp) + d := xdr.NewDecoderWithOptions(r, o) + _, err := s.DecodeFrom(d, o.MaxDepth) + return err +} + +var ( + _ encoding.BinaryMarshaler = (*MuxedContract)(nil) + _ encoding.BinaryUnmarshaler = (*MuxedContract)(nil) +) + +// xdrType signals that this type represents XDR values defined by this package. +func (s MuxedContract) xdrType() {} + +var _ xdrType = (*MuxedContract)(nil) + // ScAddress is an XDR Union defines as: // // union SCAddress switch (SCAddressType type) @@ -59277,6 +59738,8 @@ var _ xdrType = (*MuxedEd25519Account)(nil) // ClaimableBalanceID claimableBalanceId; // case SC_ADDRESS_TYPE_LIQUIDITY_POOL: // PoolID liquidityPoolId; +// case SC_ADDRESS_TYPE_MUXED_CONTRACT: +// MuxedContract muxedContract; // }; type ScAddress struct { Type ScAddressType @@ -59285,6 +59748,7 @@ type ScAddress struct { MuxedAccount *MuxedEd25519Account ClaimableBalanceId *ClaimableBalanceId LiquidityPoolId *PoolId + MuxedContract *MuxedContract } // SwitchFieldName returns the field name in which this union's @@ -59307,6 +59771,8 @@ func (u ScAddress) ArmForSwitch(sw int32) (string, bool) { return "ClaimableBalanceId", true case ScAddressTypeScAddressTypeLiquidityPool: return "LiquidityPoolId", true + case ScAddressTypeScAddressTypeMuxedContract: + return "MuxedContract", true } return "-", false } @@ -59350,6 +59816,13 @@ func NewScAddress(aType ScAddressType, value interface{}) (result ScAddress, err return } result.LiquidityPoolId = &tv + case ScAddressTypeScAddressTypeMuxedContract: + tv, ok := value.(MuxedContract) + if !ok { + err = errors.New("invalid value, must be MuxedContract") + return + } + result.MuxedContract = &tv } return } @@ -59479,6 +59952,31 @@ func (u ScAddress) GetLiquidityPoolId() (result PoolId, ok bool) { return } +// MustMuxedContract retrieves the MuxedContract value from the union, +// panicing if the value is not set. +func (u ScAddress) MustMuxedContract() MuxedContract { + val, ok := u.GetMuxedContract() + + if !ok { + panic("arm MuxedContract is not set") + } + + return val +} + +// GetMuxedContract retrieves the MuxedContract value from the union, +// returning ok if the union's switch indicated the value is valid. +func (u ScAddress) GetMuxedContract() (result MuxedContract, ok bool) { + armName, _ := u.ArmForSwitch(int32(u.Type)) + + if armName == "MuxedContract" { + result = *u.MuxedContract + ok = true + } + + return +} + // EncodeTo encodes this value using the Encoder. func (u ScAddress) EncodeTo(e *xdr.Encoder) error { var err error @@ -59511,6 +60009,11 @@ func (u ScAddress) EncodeTo(e *xdr.Encoder) error { return err } return nil + case ScAddressTypeScAddressTypeMuxedContract: + if err = (*u.MuxedContract).EncodeTo(e); err != nil { + return err + } + return nil } return fmt.Errorf("Type (ScAddressType) switch value '%d' is not valid for union ScAddress", u.Type) } @@ -59586,6 +60089,17 @@ func (u *ScAddress) DecodeFrom(d *xdr.Decoder, maxDepth uint) (int, error) { return n, fmt.Errorf("decoding PoolId: %w", err) } return n, nil + case ScAddressTypeScAddressTypeMuxedContract: + if err = xdr.TrackOutputBytesOf[MuxedContract](d); err != nil { + return n, fmt.Errorf("decoding MuxedContract: %w", err) + } + u.MuxedContract = new(MuxedContract) + nTmp, err = (*u.MuxedContract).DecodeFrom(d, maxDepth) + n += nTmp + if err != nil { + return n, fmt.Errorf("decoding MuxedContract: %w", err) + } + return n, nil } return n, fmt.Errorf("union ScAddress has invalid Type (ScAddressType) switch value '%d'", u.Type) } @@ -63393,7 +63907,25 @@ var _ xdrType = (*ConfigSettingContractBandwidthV0)(nil) // // Cost of performing BN254 scalar element inversion // Bn254FrInv = 84, // // Cost of performing BN254 G1 multi-scalar multiplication (MSM) -// Bn254G1Msm = 85 +// Bn254G1Msm = 85, +// // Cost of decoding and expanding an ML-DSA-44 verifying key +// MlDsa44DecodeVerifyingKey = 86, +// // Cost of decoding and expanding an ML-DSA-65 verifying key +// MlDsa65DecodeVerifyingKey = 87, +// // Cost of decoding and expanding an ML-DSA-87 verifying key +// MlDsa87DecodeVerifyingKey = 88, +// // Cost of decoding an ML-DSA-44 signature +// MlDsa44DecodeSignature = 89, +// // Cost of decoding an ML-DSA-65 signature +// MlDsa65DecodeSignature = 90, +// // Cost of decoding an ML-DSA-87 signature +// MlDsa87DecodeSignature = 91, +// // Cost of verifying an ML-DSA-44 signature, linear in message + context length +// VerifyMlDsa44Sig = 92, +// // Cost of verifying an ML-DSA-65 signature, linear in message + context length +// VerifyMlDsa65Sig = 93, +// // Cost of verifying an ML-DSA-87 signature, linear in message + context length +// VerifyMlDsa87Sig = 94 // }; type ContractCostType int32 @@ -63484,6 +64016,15 @@ const ( ContractCostTypeBn254FrPow ContractCostType = 83 ContractCostTypeBn254FrInv ContractCostType = 84 ContractCostTypeBn254G1Msm ContractCostType = 85 + ContractCostTypeMlDsa44DecodeVerifyingKey ContractCostType = 86 + ContractCostTypeMlDsa65DecodeVerifyingKey ContractCostType = 87 + ContractCostTypeMlDsa87DecodeVerifyingKey ContractCostType = 88 + ContractCostTypeMlDsa44DecodeSignature ContractCostType = 89 + ContractCostTypeMlDsa65DecodeSignature ContractCostType = 90 + ContractCostTypeMlDsa87DecodeSignature ContractCostType = 91 + ContractCostTypeVerifyMlDsa44Sig ContractCostType = 92 + ContractCostTypeVerifyMlDsa65Sig ContractCostType = 93 + ContractCostTypeVerifyMlDsa87Sig ContractCostType = 94 ) var contractCostTypeMap = map[int32]string{ @@ -63573,6 +64114,15 @@ var contractCostTypeMap = map[int32]string{ 83: "ContractCostTypeBn254FrPow", 84: "ContractCostTypeBn254FrInv", 85: "ContractCostTypeBn254G1Msm", + 86: "ContractCostTypeMlDsa44DecodeVerifyingKey", + 87: "ContractCostTypeMlDsa65DecodeVerifyingKey", + 88: "ContractCostTypeMlDsa87DecodeVerifyingKey", + 89: "ContractCostTypeMlDsa44DecodeSignature", + 90: "ContractCostTypeMlDsa65DecodeSignature", + 91: "ContractCostTypeMlDsa87DecodeSignature", + 92: "ContractCostTypeVerifyMlDsa44Sig", + 93: "ContractCostTypeVerifyMlDsa65Sig", + 94: "ContractCostTypeVerifyMlDsa87Sig", } // ValidEnum validates a proposed value for this enum. Implements diff --git a/xdr/xdr_views_generated.go b/xdr/xdr_views_generated.go index 032f3c9b1c..3559ea4e09 100644 --- a/xdr/xdr_views_generated.go +++ b/xdr/xdr_views_generated.go @@ -4099,7 +4099,7 @@ func (v ContractCostTypeView) Value() (ContractCostType, error) { } val := ContractCostType(int32(binary.BigEndian.Uint32(v[:4]))) switch val { - case ContractCostTypeWasmInsnExec, ContractCostTypeMemAlloc, ContractCostTypeMemCpy, ContractCostTypeMemCmp, ContractCostTypeDispatchHostFunction, ContractCostTypeVisitObject, ContractCostTypeValSer, ContractCostTypeValDeser, ContractCostTypeComputeSha256Hash, ContractCostTypeComputeEd25519PubKey, ContractCostTypeVerifyEd25519Sig, ContractCostTypeVmInstantiation, ContractCostTypeVmCachedInstantiation, ContractCostTypeInvokeVmFunction, ContractCostTypeComputeKeccak256Hash, ContractCostTypeDecodeEcdsaCurve256Sig, ContractCostTypeRecoverEcdsaSecp256k1Key, ContractCostTypeInt256AddSub, ContractCostTypeInt256Mul, ContractCostTypeInt256Div, ContractCostTypeInt256Pow, ContractCostTypeInt256Shift, ContractCostTypeChaCha20DrawBytes, ContractCostTypeParseWasmInstructions, ContractCostTypeParseWasmFunctions, ContractCostTypeParseWasmGlobals, ContractCostTypeParseWasmTableEntries, ContractCostTypeParseWasmTypes, ContractCostTypeParseWasmDataSegments, ContractCostTypeParseWasmElemSegments, ContractCostTypeParseWasmImports, ContractCostTypeParseWasmExports, ContractCostTypeParseWasmDataSegmentBytes, ContractCostTypeInstantiateWasmInstructions, ContractCostTypeInstantiateWasmFunctions, ContractCostTypeInstantiateWasmGlobals, ContractCostTypeInstantiateWasmTableEntries, ContractCostTypeInstantiateWasmTypes, ContractCostTypeInstantiateWasmDataSegments, ContractCostTypeInstantiateWasmElemSegments, ContractCostTypeInstantiateWasmImports, ContractCostTypeInstantiateWasmExports, ContractCostTypeInstantiateWasmDataSegmentBytes, ContractCostTypeSec1DecodePointUncompressed, ContractCostTypeVerifyEcdsaSecp256r1Sig, ContractCostTypeBls12381EncodeFp, ContractCostTypeBls12381DecodeFp, ContractCostTypeBls12381G1CheckPointOnCurve, ContractCostTypeBls12381G1CheckPointInSubgroup, ContractCostTypeBls12381G2CheckPointOnCurve, ContractCostTypeBls12381G2CheckPointInSubgroup, ContractCostTypeBls12381G1ProjectiveToAffine, ContractCostTypeBls12381G2ProjectiveToAffine, ContractCostTypeBls12381G1Add, ContractCostTypeBls12381G1Mul, ContractCostTypeBls12381G1Msm, ContractCostTypeBls12381MapFpToG1, ContractCostTypeBls12381HashToG1, ContractCostTypeBls12381G2Add, ContractCostTypeBls12381G2Mul, ContractCostTypeBls12381G2Msm, ContractCostTypeBls12381MapFp2ToG2, ContractCostTypeBls12381HashToG2, ContractCostTypeBls12381Pairing, ContractCostTypeBls12381FrFromU256, ContractCostTypeBls12381FrToU256, ContractCostTypeBls12381FrAddSub, ContractCostTypeBls12381FrMul, ContractCostTypeBls12381FrPow, ContractCostTypeBls12381FrInv, ContractCostTypeBn254EncodeFp, ContractCostTypeBn254DecodeFp, ContractCostTypeBn254G1CheckPointOnCurve, ContractCostTypeBn254G2CheckPointOnCurve, ContractCostTypeBn254G2CheckPointInSubgroup, ContractCostTypeBn254G1ProjectiveToAffine, ContractCostTypeBn254G1Add, ContractCostTypeBn254G1Mul, ContractCostTypeBn254Pairing, ContractCostTypeBn254FrFromU256, ContractCostTypeBn254FrToU256, ContractCostTypeBn254FrAddSub, ContractCostTypeBn254FrMul, ContractCostTypeBn254FrPow, ContractCostTypeBn254FrInv, ContractCostTypeBn254G1Msm: + case ContractCostTypeWasmInsnExec, ContractCostTypeMemAlloc, ContractCostTypeMemCpy, ContractCostTypeMemCmp, ContractCostTypeDispatchHostFunction, ContractCostTypeVisitObject, ContractCostTypeValSer, ContractCostTypeValDeser, ContractCostTypeComputeSha256Hash, ContractCostTypeComputeEd25519PubKey, ContractCostTypeVerifyEd25519Sig, ContractCostTypeVmInstantiation, ContractCostTypeVmCachedInstantiation, ContractCostTypeInvokeVmFunction, ContractCostTypeComputeKeccak256Hash, ContractCostTypeDecodeEcdsaCurve256Sig, ContractCostTypeRecoverEcdsaSecp256k1Key, ContractCostTypeInt256AddSub, ContractCostTypeInt256Mul, ContractCostTypeInt256Div, ContractCostTypeInt256Pow, ContractCostTypeInt256Shift, ContractCostTypeChaCha20DrawBytes, ContractCostTypeParseWasmInstructions, ContractCostTypeParseWasmFunctions, ContractCostTypeParseWasmGlobals, ContractCostTypeParseWasmTableEntries, ContractCostTypeParseWasmTypes, ContractCostTypeParseWasmDataSegments, ContractCostTypeParseWasmElemSegments, ContractCostTypeParseWasmImports, ContractCostTypeParseWasmExports, ContractCostTypeParseWasmDataSegmentBytes, ContractCostTypeInstantiateWasmInstructions, ContractCostTypeInstantiateWasmFunctions, ContractCostTypeInstantiateWasmGlobals, ContractCostTypeInstantiateWasmTableEntries, ContractCostTypeInstantiateWasmTypes, ContractCostTypeInstantiateWasmDataSegments, ContractCostTypeInstantiateWasmElemSegments, ContractCostTypeInstantiateWasmImports, ContractCostTypeInstantiateWasmExports, ContractCostTypeInstantiateWasmDataSegmentBytes, ContractCostTypeSec1DecodePointUncompressed, ContractCostTypeVerifyEcdsaSecp256r1Sig, ContractCostTypeBls12381EncodeFp, ContractCostTypeBls12381DecodeFp, ContractCostTypeBls12381G1CheckPointOnCurve, ContractCostTypeBls12381G1CheckPointInSubgroup, ContractCostTypeBls12381G2CheckPointOnCurve, ContractCostTypeBls12381G2CheckPointInSubgroup, ContractCostTypeBls12381G1ProjectiveToAffine, ContractCostTypeBls12381G2ProjectiveToAffine, ContractCostTypeBls12381G1Add, ContractCostTypeBls12381G1Mul, ContractCostTypeBls12381G1Msm, ContractCostTypeBls12381MapFpToG1, ContractCostTypeBls12381HashToG1, ContractCostTypeBls12381G2Add, ContractCostTypeBls12381G2Mul, ContractCostTypeBls12381G2Msm, ContractCostTypeBls12381MapFp2ToG2, ContractCostTypeBls12381HashToG2, ContractCostTypeBls12381Pairing, ContractCostTypeBls12381FrFromU256, ContractCostTypeBls12381FrToU256, ContractCostTypeBls12381FrAddSub, ContractCostTypeBls12381FrMul, ContractCostTypeBls12381FrPow, ContractCostTypeBls12381FrInv, ContractCostTypeBn254EncodeFp, ContractCostTypeBn254DecodeFp, ContractCostTypeBn254G1CheckPointOnCurve, ContractCostTypeBn254G2CheckPointOnCurve, ContractCostTypeBn254G2CheckPointInSubgroup, ContractCostTypeBn254G1ProjectiveToAffine, ContractCostTypeBn254G1Add, ContractCostTypeBn254G1Mul, ContractCostTypeBn254Pairing, ContractCostTypeBn254FrFromU256, ContractCostTypeBn254FrToU256, ContractCostTypeBn254FrAddSub, ContractCostTypeBn254FrMul, ContractCostTypeBn254FrPow, ContractCostTypeBn254FrInv, ContractCostTypeBn254G1Msm, ContractCostTypeMlDsa44DecodeVerifyingKey, ContractCostTypeMlDsa65DecodeVerifyingKey, ContractCostTypeMlDsa87DecodeVerifyingKey, ContractCostTypeMlDsa44DecodeSignature, ContractCostTypeMlDsa65DecodeSignature, ContractCostTypeMlDsa87DecodeSignature, ContractCostTypeVerifyMlDsa44Sig, ContractCostTypeVerifyMlDsa65Sig, ContractCostTypeVerifyMlDsa87Sig: return val, nil default: return 0, viewErrUnknownDiscriminant(0, int32(val)) @@ -8387,8 +8387,8 @@ func (v ScSpecTypeUdtNameOpaqueView) Value() ([]byte, error) { if err != nil { return nil, err } - if len(val) > 60 { - return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 60) + if len(val) > 1024 { + return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 1024) } return val, nil } @@ -9178,8 +9178,8 @@ func (v ScSpecUdtStructV0NameOpaqueView) Value() ([]byte, error) { if err != nil { return nil, err } - if len(val) > 60 { - return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 60) + if len(val) > 1024 { + return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 1024) } return val, nil } @@ -10553,8 +10553,8 @@ func (v ScSpecUdtUnionV0NameOpaqueView) Value() ([]byte, error) { if err != nil { return nil, err } - if len(val) > 60 { - return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 60) + if len(val) > 1024 { + return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 1024) } return val, nil } @@ -11377,8 +11377,8 @@ func (v ScSpecUdtEnumV0NameOpaqueView) Value() ([]byte, error) { if err != nil { return nil, err } - if len(val) > 60 { - return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 60) + if len(val) > 1024 { + return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 1024) } return val, nil } @@ -12209,8 +12209,8 @@ func (v ScSpecUdtErrorEnumV0NameOpaqueView) Value() ([]byte, error) { if err != nil { return nil, err } - if len(val) > 60 { - return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 60) + if len(val) > 1024 { + return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 1024) } return val, nil } @@ -14102,6 +14102,40 @@ func (v ScSpecEventV0LibOpaqueView) ValidateFull() error { retu func (v ScSpecEventV0LibOpaqueView) MustRaw() []byte { return must(v.Raw()) } func (v ScSpecEventV0LibOpaqueView) MustCopy() ScSpecEventV0LibOpaqueView { return must(v.Copy()) } +type ScSpecEventV0NameOpaqueView []byte + +func (v ScSpecEventV0NameOpaqueView) Value() ([]byte, error) { + val, err := VarOpaqueView(v).Value() + if err != nil { + return nil, err + } + if len(val) > 1024 { + return nil, viewErrOpaqueExceedsMax(0, uint32(len(val)), 1024) + } + return val, nil +} +func (v ScSpecEventV0NameOpaqueView) size(depth int) (int, error) { + return VarOpaqueView(v).size(depth) +} +func (v ScSpecEventV0NameOpaqueView) valid(_ int) (int, error) { + if _, err := v.Value(); err != nil { + return 0, err + } + return v.size(0) +} +func (v ScSpecEventV0NameOpaqueView) MustValue() []byte { return must(v.Value()) } + +// Raw returns the exact wire bytes for this view, trimmed from the fat slice. +func (v ScSpecEventV0NameOpaqueView) Raw() ([]byte, error) { return viewRaw(v) } + +// Copy returns an independent copy of this view that does not alias the original bytes. +func (v ScSpecEventV0NameOpaqueView) Copy() (ScSpecEventV0NameOpaqueView, error) { return viewCopy(v) } + +// ValidateFull checks that this view is well-formed: bounds, schema constraints, and depth limits. +func (v ScSpecEventV0NameOpaqueView) ValidateFull() error { return validate(v) } +func (v ScSpecEventV0NameOpaqueView) MustRaw() []byte { return must(v.Raw()) } +func (v ScSpecEventV0NameOpaqueView) MustCopy() ScSpecEventV0NameOpaqueView { return must(v.Copy()) } + type ScSpecEventV0PrefixTopicsView []byte func (v ScSpecEventV0PrefixTopicsView) Count() (int, error) { @@ -14381,7 +14415,7 @@ func (v ScSpecEventV0View) size(depth int) (int, error) { return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") } { - sz, err := ScSymbolView(v[off:]).size(depth + 1) + sz, err := ScSpecEventV0NameOpaqueView(v[off:]).size(depth + 1) if err != nil { return 0, err } @@ -14447,7 +14481,7 @@ func (v ScSpecEventV0View) Lib() (ScSpecEventV0LibOpaqueView, error) { return ScSpecEventV0LibOpaqueView(v[off:]), nil } func (v ScSpecEventV0View) MustLib() ScSpecEventV0LibOpaqueView { return must(v.Lib()) } -func (v ScSpecEventV0View) Name() (ScSymbolView, error) { +func (v ScSpecEventV0View) Name() (ScSpecEventV0NameOpaqueView, error) { off := int64(0) if off > int64(len(v)) { return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") @@ -14478,9 +14512,9 @@ func (v ScSpecEventV0View) Name() (ScSymbolView, error) { if off > int64(len(v)) { return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") } - return ScSymbolView(v[off:]), nil + return ScSpecEventV0NameOpaqueView(v[off:]), nil } -func (v ScSpecEventV0View) MustName() ScSymbolView { return must(v.Name()) } +func (v ScSpecEventV0View) MustName() ScSpecEventV0NameOpaqueView { return must(v.Name()) } func (v ScSpecEventV0View) PrefixTopics() (ScSpecEventV0PrefixTopicsView, error) { off := int64(0) if off > int64(len(v)) { @@ -14513,7 +14547,7 @@ func (v ScSpecEventV0View) PrefixTopics() (ScSpecEventV0PrefixTopicsView, error) return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") } { - sz, err := ScSymbolView(v[off:]).size(0) + sz, err := ScSpecEventV0NameOpaqueView(v[off:]).size(0) if err != nil { return nil, err } @@ -14562,7 +14596,7 @@ func (v ScSpecEventV0View) Params() (ScSpecEventV0ParamsView, error) { return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") } { - sz, err := ScSymbolView(v[off:]).size(0) + sz, err := ScSpecEventV0NameOpaqueView(v[off:]).size(0) if err != nil { return nil, err } @@ -14622,7 +14656,7 @@ func (v ScSpecEventV0View) DataFormat() (ScSpecEventDataFormatView, error) { return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") } { - sz, err := ScSymbolView(v[off:]).size(0) + sz, err := ScSpecEventV0NameOpaqueView(v[off:]).size(0) if err != nil { return nil, err } @@ -14689,7 +14723,7 @@ func (v ScSpecEventV0View) valid(depth int) (int, error) { } } { - sz, err := ScSymbolView(v[off:]).valid(depth + 1) + sz, err := ScSpecEventV0NameOpaqueView(v[off:]).valid(depth + 1) if err != nil { return 0, err } @@ -14747,7 +14781,7 @@ type ScSpecEventV0Fields struct { View ScSpecEventV0View Doc ScSpecEventV0DocOpaqueView Lib ScSpecEventV0LibOpaqueView - Name ScSymbolView + Name ScSpecEventV0NameOpaqueView PrefixTopics ScSpecEventV0PrefixTopicsView Params ScSpecEventV0ParamsView DataFormat ScSpecEventDataFormatView @@ -14790,7 +14824,7 @@ func locateScSpecEventV0(v ScSpecEventV0View) (ScSpecEventV0Fields, error) { return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") } { - sz, err := ScSymbolView(v[off:]).size(0) + sz, err := ScSpecEventV0NameOpaqueView(v[off:]).size(0) if err != nil { return f, err } @@ -14798,7 +14832,7 @@ func locateScSpecEventV0(v ScSpecEventV0View) (ScSpecEventV0Fields, error) { if off+fsz > int64(len(v)) { return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") } - f.Name = ScSymbolView(v[off : off+fsz]) + f.Name = ScSpecEventV0NameOpaqueView(v[off : off+fsz]) off += fsz } if off > int64(len(v)) { @@ -15811,7 +15845,7 @@ func (v ScAddressTypeView) Value() (ScAddressType, error) { } val := ScAddressType(int32(binary.BigEndian.Uint32(v[:4]))) switch val { - case ScAddressTypeScAddressTypeAccount, ScAddressTypeScAddressTypeContract, ScAddressTypeScAddressTypeMuxedAccount, ScAddressTypeScAddressTypeClaimableBalance, ScAddressTypeScAddressTypeLiquidityPool: + case ScAddressTypeScAddressTypeAccount, ScAddressTypeScAddressTypeContract, ScAddressTypeScAddressTypeMuxedAccount, ScAddressTypeScAddressTypeClaimableBalance, ScAddressTypeScAddressTypeLiquidityPool, ScAddressTypeScAddressTypeMuxedContract: return val, nil default: return 0, viewErrUnknownDiscriminant(0, int32(val)) @@ -15921,6 +15955,88 @@ func (v MuxedEd25519AccountView) Fields() (MuxedEd25519AccountFields, error) { return locateMuxedEd25519Account(v) } +type MuxedContractView []byte + +func (v MuxedContractView) size(_ int) (int, error) { return 40, nil } +func (v MuxedContractView) Id() (Uint64View, error) { + if len(v) < 40 { + return nil, viewErrShortBuffer(0, "need 40 bytes") + } + return Uint64View(v[0:]), nil +} +func (v MuxedContractView) MustId() Uint64View { return must(v.Id()) } +func (v MuxedContractView) ContractId() (ContractIdView, error) { + if len(v) < 40 { + return nil, viewErrShortBuffer(0, "need 40 bytes") + } + off := int64(0) + off += 8 + if off > int64(len(v)) { + return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + return ContractIdView(v[off:]), nil +} +func (v MuxedContractView) MustContractId() ContractIdView { return must(v.ContractId()) } +func (v MuxedContractView) valid(depth int) (int, error) { + if len(v) < 40 { + return 0, viewErrShortBuffer(0, "need 40 bytes") + } + off := int64(0) + { + sz, err := Uint64View(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + { + sz, err := ContractIdView(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + return int(off), nil +} + +// Raw returns the exact wire bytes for this view, trimmed from the fat slice. +func (v MuxedContractView) Raw() ([]byte, error) { return viewRaw(v) } + +// Copy returns an independent copy of this view that does not alias the original bytes. +func (v MuxedContractView) Copy() (MuxedContractView, error) { return viewCopy(v) } + +// ValidateFull checks that this view is well-formed: bounds, schema constraints, and depth limits. +func (v MuxedContractView) ValidateFull() error { return validate(v) } +func (v MuxedContractView) MustRaw() []byte { return must(v.Raw()) } +func (v MuxedContractView) MustCopy() MuxedContractView { return must(v.Copy()) } + +// MuxedContractFields is the located form of MuxedContractView: every field trimmed to its exact wire extent, all found in one walk. +type MuxedContractFields struct { + View MuxedContractView + Id Uint64View + ContractId ContractIdView +} + +func locateMuxedContract(v MuxedContractView) (MuxedContractFields, error) { + var f MuxedContractFields + if len(v) < 40 { + return f, viewErrShortBuffer(0, "need 40 bytes") + } + f.Id = Uint64View(v[0:8]) + f.ContractId = ContractIdView(v[8:40]) + f.View = MuxedContractView(v[:40]) + return f, nil +} + +// Fields locates every field of this node in a single walk, each trimmed to its exact wire extent. +func (v MuxedContractView) Fields() (MuxedContractFields, error) { return locateMuxedContract(v) } + type ScAddressView []byte func (v ScAddressView) size(depth int) (int, error) { @@ -15977,6 +16093,15 @@ func (v ScAddressView) size(depth int) (int, error) { return 0, viewErrShortBuffer(4, "arm exceeds data") } return 4 + sz, nil + case int32(ScAddressTypeScAddressTypeMuxedContract): + sz, err := MuxedContractView(v[4:]).size(depth + 1) + if err != nil { + return 0, err + } + if 4+sz > len(v) { + return 0, viewErrShortBuffer(4, "arm exceeds data") + } + return 4 + sz, nil default: return 0, viewErrUnknownDiscriminant(0, disc) } @@ -15987,7 +16112,7 @@ func (v ScAddressView) Type() (ScAddressType, error) { } val := ScAddressType(int32(binary.BigEndian.Uint32(v[:4]))) switch val { - case ScAddressTypeScAddressTypeAccount, ScAddressTypeScAddressTypeContract, ScAddressTypeScAddressTypeMuxedAccount, ScAddressTypeScAddressTypeClaimableBalance, ScAddressTypeScAddressTypeLiquidityPool: + case ScAddressTypeScAddressTypeAccount, ScAddressTypeScAddressTypeContract, ScAddressTypeScAddressTypeMuxedAccount, ScAddressTypeScAddressTypeClaimableBalance, ScAddressTypeScAddressTypeLiquidityPool, ScAddressTypeScAddressTypeMuxedContract: return val, nil default: return 0, viewErrUnknownDiscriminant(0, int32(val)) @@ -16061,6 +16186,19 @@ func (v ScAddressView) LiquidityPoolId() (PoolIdView, error) { return PoolIdView(v[4:]), nil } func (v ScAddressView) MustLiquidityPoolId() PoolIdView { return must(v.LiquidityPoolId()) } +func (v ScAddressView) MuxedContract() (MuxedContractView, error) { + if len(v) < 4 { + return nil, viewErrShortBuffer(0, "need 4 bytes for discriminant") + } + disc := int32(binary.BigEndian.Uint32(v[:4])) + switch disc { + case int32(ScAddressTypeScAddressTypeMuxedContract): + default: + return nil, viewErrWrongDiscriminant(0, disc, int32(ScAddressTypeScAddressTypeMuxedContract)) + } + return MuxedContractView(v[4:]), nil +} +func (v ScAddressView) MustMuxedContract() MuxedContractView { return must(v.MuxedContract()) } func (v ScAddressView) valid(depth int) (int, error) { if depth > maxDepth { return 0, viewErrMaxDepth(0) @@ -16115,6 +16253,15 @@ func (v ScAddressView) valid(depth int) (int, error) { return 0, viewErrShortBuffer(4, "arm exceeds data") } return 4 + sz, nil + case int32(ScAddressTypeScAddressTypeMuxedContract): + sz, err := MuxedContractView(v[4:]).valid(depth + 1) + if err != nil { + return 0, err + } + if 4+sz > len(v) { + return 0, viewErrShortBuffer(4, "arm exceeds data") + } + return 4 + sz, nil default: return 0, viewErrUnknownDiscriminant(0, disc) } @@ -30209,7 +30356,7 @@ func (v StellarValueTypeView) Value() (StellarValueType, error) { } val := StellarValueType(int32(binary.BigEndian.Uint32(v[:4]))) switch val { - case StellarValueTypeStellarValueBasic, StellarValueTypeStellarValueSigned, StellarValueTypeStellarValueEmptyTxSet: + case StellarValueTypeStellarValueBasic, StellarValueTypeStellarValueSigned, StellarValueTypeStellarValueEmptyTxSet, StellarValueTypeStellarValueSignedMs, StellarValueTypeStellarValueEmptyTxSetMs: return val, nil default: return 0, viewErrUnknownDiscriminant(0, int32(val)) @@ -30544,6 +30691,350 @@ func (v StellarValueProposedValueView) Fields() (StellarValueProposedValueFields return locateStellarValueProposedValue(v) } +type StellarValueSignedMsValueView []byte + +func (v StellarValueSignedMsValueView) size(depth int) (int, error) { + if depth > maxDepth { + return 0, viewErrMaxDepth(0) + } + off := int64(0) + off += 8 + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + { + sz, err := LedgerCloseValueSignatureView(v[off:]).size(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + return int(off), nil +} +func (v StellarValueSignedMsValueView) CloseTimeMs() (TimePointMsView, error) { + return TimePointMsView(v[0:]), nil +} +func (v StellarValueSignedMsValueView) MustCloseTimeMs() TimePointMsView { + return must(v.CloseTimeMs()) +} +func (v StellarValueSignedMsValueView) LcValueSignature() (LedgerCloseValueSignatureView, error) { + off := int64(0) + off += 8 + if off > int64(len(v)) { + return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + return LedgerCloseValueSignatureView(v[off:]), nil +} +func (v StellarValueSignedMsValueView) MustLcValueSignature() LedgerCloseValueSignatureView { + return must(v.LcValueSignature()) +} +func (v StellarValueSignedMsValueView) valid(depth int) (int, error) { + if depth > maxDepth { + return 0, viewErrMaxDepth(0) + } + off := int64(0) + { + sz, err := TimePointMsView(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + { + sz, err := LedgerCloseValueSignatureView(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + return int(off), nil +} + +// Raw returns the exact wire bytes for this view, trimmed from the fat slice. +func (v StellarValueSignedMsValueView) Raw() ([]byte, error) { return viewRaw(v) } + +// Copy returns an independent copy of this view that does not alias the original bytes. +func (v StellarValueSignedMsValueView) Copy() (StellarValueSignedMsValueView, error) { + return viewCopy(v) +} + +// ValidateFull checks that this view is well-formed: bounds, schema constraints, and depth limits. +func (v StellarValueSignedMsValueView) ValidateFull() error { return validate(v) } +func (v StellarValueSignedMsValueView) MustRaw() []byte { return must(v.Raw()) } +func (v StellarValueSignedMsValueView) MustCopy() StellarValueSignedMsValueView { + return must(v.Copy()) +} + +// StellarValueSignedMsValueFields is the located form of StellarValueSignedMsValueView: every field trimmed to its exact wire extent, all found in one walk. +type StellarValueSignedMsValueFields struct { + View StellarValueSignedMsValueView + CloseTimeMs TimePointMsView + LcValueSignature LedgerCloseValueSignatureView +} + +func locateStellarValueSignedMsValue(v StellarValueSignedMsValueView) (StellarValueSignedMsValueFields, error) { + var f StellarValueSignedMsValueFields + off := int64(0) + if off+8 > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.CloseTimeMs = TimePointMsView(v[off : off+8]) + off += 8 + if off > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + { + sz, err := LedgerCloseValueSignatureView(v[off:]).size(0) + if err != nil { + return f, err + } + fsz := int64(sz) + if off+fsz > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.LcValueSignature = LedgerCloseValueSignatureView(v[off : off+fsz]) + off += fsz + } + if off > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.View = StellarValueSignedMsValueView(v[:off]) + return f, nil +} + +// Fields locates every field of this node in a single walk, each trimmed to its exact wire extent. +func (v StellarValueSignedMsValueView) Fields() (StellarValueSignedMsValueFields, error) { + return locateStellarValueSignedMsValue(v) +} + +type StellarValueProposedMsValueView []byte + +func (v StellarValueProposedMsValueView) size(depth int) (int, error) { + if depth > maxDepth { + return 0, viewErrMaxDepth(0) + } + off := int64(0) + off += 8 + off += 32 + off += 32 + off += 4 + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + { + sz, err := LedgerCloseValueSignatureView(v[off:]).size(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + return int(off), nil +} +func (v StellarValueProposedMsValueView) CloseTimeMs() (TimePointMsView, error) { + return TimePointMsView(v[0:]), nil +} +func (v StellarValueProposedMsValueView) MustCloseTimeMs() TimePointMsView { + return must(v.CloseTimeMs()) +} +func (v StellarValueProposedMsValueView) TxSetHash() (HashView, error) { + off := int64(0) + off += 8 + if off > int64(len(v)) { + return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + return HashView(v[off:]), nil +} +func (v StellarValueProposedMsValueView) MustTxSetHash() HashView { return must(v.TxSetHash()) } +func (v StellarValueProposedMsValueView) PreviousLedgerHash() (HashView, error) { + off := int64(0) + off += 8 + off += 32 + if off > int64(len(v)) { + return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + return HashView(v[off:]), nil +} +func (v StellarValueProposedMsValueView) MustPreviousLedgerHash() HashView { + return must(v.PreviousLedgerHash()) +} +func (v StellarValueProposedMsValueView) PreviousLedgerVersion() (Uint32View, error) { + off := int64(0) + off += 8 + off += 32 + off += 32 + if off > int64(len(v)) { + return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + return Uint32View(v[off:]), nil +} +func (v StellarValueProposedMsValueView) MustPreviousLedgerVersion() Uint32View { + return must(v.PreviousLedgerVersion()) +} +func (v StellarValueProposedMsValueView) LcValueSignature() (LedgerCloseValueSignatureView, error) { + off := int64(0) + off += 8 + off += 32 + off += 32 + off += 4 + if off > int64(len(v)) { + return nil, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + return LedgerCloseValueSignatureView(v[off:]), nil +} +func (v StellarValueProposedMsValueView) MustLcValueSignature() LedgerCloseValueSignatureView { + return must(v.LcValueSignature()) +} +func (v StellarValueProposedMsValueView) valid(depth int) (int, error) { + if depth > maxDepth { + return 0, viewErrMaxDepth(0) + } + off := int64(0) + { + sz, err := TimePointMsView(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + { + sz, err := HashView(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + { + sz, err := HashView(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + { + sz, err := Uint32View(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + { + sz, err := LedgerCloseValueSignatureView(v[off:]).valid(depth + 1) + if err != nil { + return 0, err + } + off += int64(sz) + if off > int64(len(v)) { + return 0, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + } + return int(off), nil +} + +// Raw returns the exact wire bytes for this view, trimmed from the fat slice. +func (v StellarValueProposedMsValueView) Raw() ([]byte, error) { return viewRaw(v) } + +// Copy returns an independent copy of this view that does not alias the original bytes. +func (v StellarValueProposedMsValueView) Copy() (StellarValueProposedMsValueView, error) { + return viewCopy(v) +} + +// ValidateFull checks that this view is well-formed: bounds, schema constraints, and depth limits. +func (v StellarValueProposedMsValueView) ValidateFull() error { return validate(v) } +func (v StellarValueProposedMsValueView) MustRaw() []byte { return must(v.Raw()) } +func (v StellarValueProposedMsValueView) MustCopy() StellarValueProposedMsValueView { + return must(v.Copy()) +} + +// StellarValueProposedMsValueFields is the located form of StellarValueProposedMsValueView: every field trimmed to its exact wire extent, all found in one walk. +type StellarValueProposedMsValueFields struct { + View StellarValueProposedMsValueView + CloseTimeMs TimePointMsView + TxSetHash HashView + PreviousLedgerHash HashView + PreviousLedgerVersion Uint32View + LcValueSignature LedgerCloseValueSignatureView +} + +func locateStellarValueProposedMsValue(v StellarValueProposedMsValueView) (StellarValueProposedMsValueFields, error) { + var f StellarValueProposedMsValueFields + off := int64(0) + if off+8 > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.CloseTimeMs = TimePointMsView(v[off : off+8]) + off += 8 + if off+32 > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.TxSetHash = HashView(v[off : off+32]) + off += 32 + if off+32 > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.PreviousLedgerHash = HashView(v[off : off+32]) + off += 32 + if off+4 > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.PreviousLedgerVersion = Uint32View(v[off : off+4]) + off += 4 + if off > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + { + sz, err := LedgerCloseValueSignatureView(v[off:]).size(0) + if err != nil { + return f, err + } + fsz := int64(sz) + if off+fsz > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.LcValueSignature = LedgerCloseValueSignatureView(v[off : off+fsz]) + off += fsz + } + if off > int64(len(v)) { + return f, viewErrShortBuffer(uint32(off), "field offset exceeds data") + } + f.View = StellarValueProposedMsValueView(v[:off]) + return f, nil +} + +// Fields locates every field of this node in a single walk, each trimmed to its exact wire extent. +func (v StellarValueProposedMsValueView) Fields() (StellarValueProposedMsValueFields, error) { + return locateStellarValueProposedMsValue(v) +} + type StellarValueExtView []byte func (v StellarValueExtView) size(depth int) (int, error) { @@ -30575,6 +31066,24 @@ func (v StellarValueExtView) size(depth int) (int, error) { return 0, viewErrShortBuffer(4, "arm exceeds data") } return 4 + sz, nil + case int32(StellarValueTypeStellarValueSignedMs): + sz, err := StellarValueSignedMsValueView(v[4:]).size(depth + 1) + if err != nil { + return 0, err + } + if 4+sz > len(v) { + return 0, viewErrShortBuffer(4, "arm exceeds data") + } + return 4 + sz, nil + case int32(StellarValueTypeStellarValueEmptyTxSetMs): + sz, err := StellarValueProposedMsValueView(v[4:]).size(depth + 1) + if err != nil { + return 0, err + } + if 4+sz > len(v) { + return 0, viewErrShortBuffer(4, "arm exceeds data") + } + return 4 + sz, nil default: return 0, viewErrUnknownDiscriminant(0, disc) } @@ -30585,7 +31094,7 @@ func (v StellarValueExtView) V() (StellarValueType, error) { } val := StellarValueType(int32(binary.BigEndian.Uint32(v[:4]))) switch val { - case StellarValueTypeStellarValueBasic, StellarValueTypeStellarValueSigned, StellarValueTypeStellarValueEmptyTxSet: + case StellarValueTypeStellarValueBasic, StellarValueTypeStellarValueSigned, StellarValueTypeStellarValueEmptyTxSet, StellarValueTypeStellarValueSignedMs, StellarValueTypeStellarValueEmptyTxSetMs: return val, nil default: return 0, viewErrUnknownDiscriminant(0, int32(val)) @@ -30622,6 +31131,36 @@ func (v StellarValueExtView) ProposedValue() (StellarValueProposedValueView, err func (v StellarValueExtView) MustProposedValue() StellarValueProposedValueView { return must(v.ProposedValue()) } +func (v StellarValueExtView) SignedMsValue() (StellarValueSignedMsValueView, error) { + if len(v) < 4 { + return nil, viewErrShortBuffer(0, "need 4 bytes for discriminant") + } + disc := int32(binary.BigEndian.Uint32(v[:4])) + switch disc { + case int32(StellarValueTypeStellarValueSignedMs): + default: + return nil, viewErrWrongDiscriminant(0, disc, int32(StellarValueTypeStellarValueSignedMs)) + } + return StellarValueSignedMsValueView(v[4:]), nil +} +func (v StellarValueExtView) MustSignedMsValue() StellarValueSignedMsValueView { + return must(v.SignedMsValue()) +} +func (v StellarValueExtView) ProposedMsValue() (StellarValueProposedMsValueView, error) { + if len(v) < 4 { + return nil, viewErrShortBuffer(0, "need 4 bytes for discriminant") + } + disc := int32(binary.BigEndian.Uint32(v[:4])) + switch disc { + case int32(StellarValueTypeStellarValueEmptyTxSetMs): + default: + return nil, viewErrWrongDiscriminant(0, disc, int32(StellarValueTypeStellarValueEmptyTxSetMs)) + } + return StellarValueProposedMsValueView(v[4:]), nil +} +func (v StellarValueExtView) MustProposedMsValue() StellarValueProposedMsValueView { + return must(v.ProposedMsValue()) +} func (v StellarValueExtView) valid(depth int) (int, error) { if depth > maxDepth { return 0, viewErrMaxDepth(0) @@ -30651,6 +31190,24 @@ func (v StellarValueExtView) valid(depth int) (int, error) { return 0, viewErrShortBuffer(4, "arm exceeds data") } return 4 + sz, nil + case int32(StellarValueTypeStellarValueSignedMs): + sz, err := StellarValueSignedMsValueView(v[4:]).valid(depth + 1) + if err != nil { + return 0, err + } + if 4+sz > len(v) { + return 0, viewErrShortBuffer(4, "arm exceeds data") + } + return 4 + sz, nil + case int32(StellarValueTypeStellarValueEmptyTxSetMs): + sz, err := StellarValueProposedMsValueView(v[4:]).valid(depth + 1) + if err != nil { + return 0, err + } + if 4+sz > len(v) { + return 0, viewErrShortBuffer(4, "arm exceeds data") + } + return 4 + sz, nil default: return 0, viewErrUnknownDiscriminant(0, disc) } @@ -77836,6 +78393,7 @@ func (v Uint256View) MustCopy() Uint256View { return must(v.Copy()) } type TimePointView = Uint64View type DurationView = Uint64View +type TimePointMsView = Uint64View type ExtensionPointView []byte func (v ExtensionPointView) size(_ int) (int, error) { return 4, nil }