diff --git a/docker/Dockerfile b/docker/Dockerfile index f3081f3a..393d8f43 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -11,7 +11,7 @@ COPY . . RUN go build -v -o /usr/local/bin ./... # stage 2: runtime enviroment -FROM stellar/stellar-core:21.0.0-1872.c6f474133.focal +FROM stellar/unsafe-stellar-core:22.0.0-2126.rc3.92923c2db.focal WORKDIR /etl diff --git a/go.mod b/go.mod index fa83ff3a..718ca4e8 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/spf13/cobra v1.7.0 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.17.0 - github.com/stellar/go v0.0.0-20240906064426-eb4b2ab750b8 + github.com/stellar/go v0.0.0-20240905180041-acfaa0686213 github.com/stretchr/testify v1.9.0 github.com/xitongsys/parquet-go v1.6.2 github.com/xitongsys/parquet-go-source v0.0.0-20240122235623-d6294584ab18 diff --git a/go.sum b/go.sum index b7a6f73f..d16de7d9 100644 --- a/go.sum +++ b/go.sum @@ -641,8 +641,8 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.17.0 h1:I5txKw7MJasPL/BrfkbA0Jyo/oELqVmux4pR/UxOMfI= github.com/spf13/viper v1.17.0/go.mod h1:BmMMMLQXSbcHK6KAOiFLz0l5JHrU89OdIRHvsk0+yVI= -github.com/stellar/go v0.0.0-20240906064426-eb4b2ab750b8 h1:jbG9brYkKwfxB5yX4fKMzRodS8ZloF1HjPQWfj4oo+4= -github.com/stellar/go v0.0.0-20240906064426-eb4b2ab750b8/go.mod h1:rrFK7a8i2h9xad9HTfnSN/dTNEqXVHKAbkFeR7UxAgs= +github.com/stellar/go v0.0.0-20240905180041-acfaa0686213 h1:224VUCwV1xmmeTru1zCmTHxvi2RECoHdfdWgd9ni518= +github.com/stellar/go v0.0.0-20240905180041-acfaa0686213/go.mod h1:rrFK7a8i2h9xad9HTfnSN/dTNEqXVHKAbkFeR7UxAgs= github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2 h1:OzCVd0SV5qE3ZcDeSFCmOWLZfEWZ3Oe8KtmSOYKEVWE= github.com/stellar/go-xdr v0.0.0-20231122183749-b53fb00bcac2/go.mod h1:yoxyU/M8nl9LKeWIoBrbDPQ7Cy+4jxRcWcOayZ4BMps= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= diff --git a/internal/transform/operation.go b/internal/transform/operation.go index a3be4651..29d479f8 100644 --- a/internal/transform/operation.go +++ b/internal/transform/operation.go @@ -1029,8 +1029,6 @@ func extractOperationDetails(operation xdr.Operation, transaction ingest.LedgerT args = append(args, xdr.ScVal{Type: xdr.ScValTypeScvAddress, Address: &invokeArgs.ContractAddress}) args = append(args, xdr.ScVal{Type: xdr.ScValTypeScvSymbol, Sym: &invokeArgs.FunctionName}) args = append(args, invokeArgs.Args...) - params := make([]map[string]string, 0, len(args)) - paramsDecoded := make([]map[string]string, 0, len(args)) details["type"] = "invoke_contract" @@ -1044,28 +1042,7 @@ func extractOperationDetails(operation xdr.Operation, transaction ingest.LedgerT details["contract_id"] = contractId details["contract_code_hash"] = contractCodeHashFromTxEnvelope(transactionEnvelope) - for _, param := range args { - serializedParam := map[string]string{} - serializedParam["value"] = "n/a" - serializedParam["type"] = "n/a" - - serializedParamDecoded := map[string]string{} - serializedParamDecoded["value"] = "n/a" - serializedParamDecoded["type"] = "n/a" - - if scValTypeName, ok := param.ArmForSwitch(int32(param.Type)); ok { - serializedParam["type"] = scValTypeName - serializedParamDecoded["type"] = scValTypeName - if raw, err := param.MarshalBinary(); err == nil { - serializedParam["value"] = base64.StdEncoding.EncodeToString(raw) - serializedParamDecoded["value"] = param.String() - } - } - params = append(params, serializedParam) - paramsDecoded = append(paramsDecoded, serializedParamDecoded) - } - details["parameters"] = params - details["parameters_decoded"] = paramsDecoded + details["parameters"], details["parameters_decoded"] = serializeParameters(args) if balanceChanges, err := parseAssetBalanceChangesFromContractEvents(transaction, network); err != nil { return nil, err @@ -1082,26 +1059,38 @@ func extractOperationDetails(operation xdr.Operation, transaction ingest.LedgerT details["contract_id"] = contractIdFromTxEnvelope(transactionEnvelope) details["contract_code_hash"] = contractCodeHashFromTxEnvelope(transactionEnvelope) - switch args.ContractIdPreimage.Type { - case xdr.ContractIdPreimageTypeContractIdPreimageFromAddress: - fromAddress := args.ContractIdPreimage.MustFromAddress() - address, err := fromAddress.Address.String() - if err != nil { - panic(fmt.Errorf("error obtaining address for: %s", args.ContractIdPreimage.Type)) + preimageTypeMap := switchContractIdPreimageType(args.ContractIdPreimage) + for key, val := range preimageTypeMap { + if _, ok := preimageTypeMap[key]; ok { + details[key] = val } - details["from"] = "address" - details["address"] = address - case xdr.ContractIdPreimageTypeContractIdPreimageFromAsset: - details["from"] = "asset" - details["asset"] = args.ContractIdPreimage.MustFromAsset().StringCanonical() - default: - panic(fmt.Errorf("unknown contract id type: %s", args.ContractIdPreimage.Type)) } case xdr.HostFunctionTypeHostFunctionTypeUploadContractWasm: details["type"] = "upload_wasm" transactionEnvelope := getTransactionV1Envelope(transaction.Envelope) details["ledger_key_hash"] = ledgerKeyHashFromTxEnvelope(transactionEnvelope) details["contract_code_hash"] = contractCodeHashFromTxEnvelope(transactionEnvelope) + case xdr.HostFunctionTypeHostFunctionTypeCreateContractV2: + args := op.HostFunction.MustCreateContractV2() + details["type"] = "create_contract_v2" + + transactionEnvelope := getTransactionV1Envelope(transaction.Envelope) + details["ledger_key_hash"] = ledgerKeyHashFromTxEnvelope(transactionEnvelope) + details["contract_id"] = contractIdFromTxEnvelope(transactionEnvelope) + details["contract_code_hash"] = contractCodeHashFromTxEnvelope(transactionEnvelope) + + // ConstructorArgs is a list of ScVals + // This will initially be handled the same as InvokeContractParams until a different + // model is found necessary. + constructorArgs := args.ConstructorArgs + details["parameters"], details["parameters_decoded"] = serializeParameters(constructorArgs) + + preimageTypeMap := switchContractIdPreimageType(args.ContractIdPreimage) + for key, val := range preimageTypeMap { + if _, ok := preimageTypeMap[key]; ok { + details[key] = val + } + } default: panic(fmt.Errorf("unknown host function type: %s", op.HostFunction.Type)) } @@ -1637,8 +1626,6 @@ func (operation *transactionOperationWrapper) Details() (map[string]interface{}, args = append(args, xdr.ScVal{Type: xdr.ScValTypeScvAddress, Address: &invokeArgs.ContractAddress}) args = append(args, xdr.ScVal{Type: xdr.ScValTypeScvSymbol, Sym: &invokeArgs.FunctionName}) args = append(args, invokeArgs.Args...) - params := make([]map[string]string, 0, len(args)) - paramsDecoded := make([]map[string]string, 0, len(args)) details["type"] = "invoke_contract" @@ -1652,28 +1639,7 @@ func (operation *transactionOperationWrapper) Details() (map[string]interface{}, details["contract_id"] = contractId details["contract_code_hash"] = contractCodeHashFromTxEnvelope(transactionEnvelope) - for _, param := range args { - serializedParam := map[string]string{} - serializedParam["value"] = "n/a" - serializedParam["type"] = "n/a" - - serializedParamDecoded := map[string]string{} - serializedParamDecoded["value"] = "n/a" - serializedParamDecoded["type"] = "n/a" - - if scValTypeName, ok := param.ArmForSwitch(int32(param.Type)); ok { - serializedParam["type"] = scValTypeName - serializedParamDecoded["type"] = scValTypeName - if raw, err := param.MarshalBinary(); err == nil { - serializedParam["value"] = base64.StdEncoding.EncodeToString(raw) - serializedParamDecoded["value"] = param.String() - } - } - params = append(params, serializedParam) - paramsDecoded = append(paramsDecoded, serializedParamDecoded) - } - details["parameters"] = params - details["parameters_decoded"] = paramsDecoded + details["parameters"], details["parameters_decoded"] = serializeParameters(args) if balanceChanges, err := operation.parseAssetBalanceChangesFromContractEvents(); err != nil { return nil, err @@ -1690,26 +1656,38 @@ func (operation *transactionOperationWrapper) Details() (map[string]interface{}, details["contract_id"] = contractIdFromTxEnvelope(transactionEnvelope) details["contract_code_hash"] = contractCodeHashFromTxEnvelope(transactionEnvelope) - switch args.ContractIdPreimage.Type { - case xdr.ContractIdPreimageTypeContractIdPreimageFromAddress: - fromAddress := args.ContractIdPreimage.MustFromAddress() - address, err := fromAddress.Address.String() - if err != nil { - panic(fmt.Errorf("error obtaining address for: %s", args.ContractIdPreimage.Type)) + preimageTypeMap := switchContractIdPreimageType(args.ContractIdPreimage) + for key, val := range preimageTypeMap { + if _, ok := preimageTypeMap[key]; ok { + details[key] = val } - details["from"] = "address" - details["address"] = address - case xdr.ContractIdPreimageTypeContractIdPreimageFromAsset: - details["from"] = "asset" - details["asset"] = args.ContractIdPreimage.MustFromAsset().StringCanonical() - default: - panic(fmt.Errorf("unknown contract id type: %s", args.ContractIdPreimage.Type)) } case xdr.HostFunctionTypeHostFunctionTypeUploadContractWasm: details["type"] = "upload_wasm" transactionEnvelope := getTransactionV1Envelope(operation.transaction.Envelope) details["ledger_key_hash"] = ledgerKeyHashFromTxEnvelope(transactionEnvelope) details["contract_code_hash"] = contractCodeHashFromTxEnvelope(transactionEnvelope) + case xdr.HostFunctionTypeHostFunctionTypeCreateContractV2: + args := op.HostFunction.MustCreateContractV2() + details["type"] = "create_contract_v2" + + transactionEnvelope := getTransactionV1Envelope(operation.transaction.Envelope) + details["ledger_key_hash"] = ledgerKeyHashFromTxEnvelope(transactionEnvelope) + details["contract_id"] = contractIdFromTxEnvelope(transactionEnvelope) + details["contract_code_hash"] = contractCodeHashFromTxEnvelope(transactionEnvelope) + + // ConstructorArgs is a list of ScVals + // This will initially be handled the same as InvokeContractParams until a different + // model is found necessary. + constructorArgs := args.ConstructorArgs + details["parameters"], details["parameters_decoded"] = serializeParameters(constructorArgs) + + preimageTypeMap := switchContractIdPreimageType(args.ContractIdPreimage) + for key, val := range preimageTypeMap { + if _, ok := preimageTypeMap[key]; ok { + details[key] = val + } + } default: panic(fmt.Errorf("unknown host function type: %s", op.HostFunction.Type)) } @@ -2175,3 +2153,53 @@ func dedupeParticipants(in []xdr.AccountId) (out []xdr.AccountId) { } return } + +func serializeParameters(args []xdr.ScVal) ([]map[string]string, []map[string]string) { + params := make([]map[string]string, 0, len(args)) + paramsDecoded := make([]map[string]string, 0, len(args)) + + for _, param := range args { + serializedParam := map[string]string{} + serializedParam["value"] = "n/a" + serializedParam["type"] = "n/a" + + serializedParamDecoded := map[string]string{} + serializedParamDecoded["value"] = "n/a" + serializedParamDecoded["type"] = "n/a" + + if scValTypeName, ok := param.ArmForSwitch(int32(param.Type)); ok { + serializedParam["type"] = scValTypeName + serializedParamDecoded["type"] = scValTypeName + if raw, err := param.MarshalBinary(); err == nil { + serializedParam["value"] = base64.StdEncoding.EncodeToString(raw) + serializedParamDecoded["value"] = param.String() + } + } + params = append(params, serializedParam) + paramsDecoded = append(paramsDecoded, serializedParamDecoded) + } + + return params, paramsDecoded +} + +func switchContractIdPreimageType(contractIdPreimage xdr.ContractIdPreimage) map[string]interface{} { + details := map[string]interface{}{} + + switch contractIdPreimage.Type { + case xdr.ContractIdPreimageTypeContractIdPreimageFromAddress: + fromAddress := contractIdPreimage.MustFromAddress() + address, err := fromAddress.Address.String() + if err != nil { + panic(fmt.Errorf("error obtaining address for: %s", contractIdPreimage.Type)) + } + details["from"] = "address" + details["address"] = address + case xdr.ContractIdPreimageTypeContractIdPreimageFromAsset: + details["from"] = "asset" + details["asset"] = contractIdPreimage.MustFromAsset().StringCanonical() + default: + panic(fmt.Errorf("unknown contract id type: %s", contractIdPreimage.Type)) + } + + return details +} diff --git a/internal/transform/operation_test.go b/internal/transform/operation_test.go index 1bb74865..3dc33598 100644 --- a/internal/transform/operation_test.go +++ b/internal/transform/operation_test.go @@ -102,11 +102,12 @@ func makeOperationTestInput() (inputTransaction ingest.LedgerTransaction, err er return } - //var wasm []byte - //var contractHash xdr.Hash - //var salt [32]byte - //var assetCode [12]byte - //var assetIssuer xdr.Uint256 + contractHash := xdr.Hash{} + salt := [32]byte{} + assetCode := [12]byte{} + assetIssuer := xdr.Uint256{} + wasm := []byte{} + dummyBool := true hardCodedClearFlags := xdr.Uint32(3) hardCodedSetFlags := xdr.Uint32(4) @@ -515,111 +516,144 @@ func makeOperationTestInput() (inputTransaction ingest.LedgerTransaction, err er }, }, }, - //{ - // SourceAccount: nil, - // Body: xdr.OperationBody{ - // Type: xdr.OperationTypeInvokeHostFunction, - // InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ - // HostFunction: xdr.HostFunction{ - // Type: xdr.HostFunctionTypeHostFunctionTypeInvokeContract, - // InvokeContract: &xdr.InvokeContractArgs{ - // ContractAddress: xdr.ScAddress{ - // Type: xdr.ScAddressTypeScAddressTypeContract, - // ContractId: &contractHash, - // }, - // FunctionName: "test", - // Args: []xdr.ScVal{}, - // }, - // }, - // }, - // }, - //}, - //{ - // SourceAccount: nil, - // Body: xdr.OperationBody{ - // Type: xdr.OperationTypeInvokeHostFunction, - // InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ - // HostFunction: xdr.HostFunction{ - // Type: xdr.HostFunctionTypeHostFunctionTypeCreateContract, - // CreateContract: &xdr.CreateContractArgs{ - // ContractIdPreimage: xdr.ContractIdPreimage{ - // Type: xdr.ContractIdPreimageTypeContractIdPreimageFromAddress, - // FromAddress: &xdr.ContractIdPreimageFromAddress{ - // Address: xdr.ScAddress{ - // Type: xdr.ScAddressTypeScAddressTypeContract, - // ContractId: &contractHash, - // }, - // Salt: salt, - // }, - // }, - // Executable: xdr.ContractExecutable{}, - // }, - // }, - // }, - // }, - //}, - //{ - // SourceAccount: nil, - // Body: xdr.OperationBody{ - // Type: xdr.OperationTypeInvokeHostFunction, - // InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ - // HostFunction: xdr.HostFunction{ - // Type: xdr.HostFunctionTypeHostFunctionTypeCreateContract, - // CreateContract: &xdr.CreateContractArgs{ - // ContractIdPreimage: xdr.ContractIdPreimage{ - // Type: xdr.ContractIdPreimageTypeContractIdPreimageFromAsset, - // FromAsset: &xdr.Asset{ - // Type: xdr.AssetTypeAssetTypeCreditAlphanum12, - // AlphaNum12: &xdr.AlphaNum12{ - // AssetCode: assetCode, - // Issuer: xdr.AccountId{ - // Type: xdr.PublicKeyTypePublicKeyTypeEd25519, - // Ed25519: &assetIssuer, - // }, - // }, - // }, - // }, - // Executable: xdr.ContractExecutable{}, - // }, - // }, - // }, - // }, - //}, - //{ - // SourceAccount: nil, - // Body: xdr.OperationBody{ - // Type: xdr.OperationTypeInvokeHostFunction, - // InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ - // HostFunction: xdr.HostFunction{ - // Type: xdr.HostFunctionTypeHostFunctionTypeUploadContractWasm, - // Wasm: &wasm, - // }, - // }, - // }, - //}, - //{ - // SourceAccount: nil, - // Body: xdr.OperationBody{ - // Type: xdr.OperationTypeBumpFootprintExpiration, - // BumpFootprintExpirationOp: &xdr.BumpFootprintExpirationOp{ - // Ext: xdr.ExtensionPoint{ - // V: 0, - // }, - // LedgersToExpire: 1234, - // }, - // }, - //}, - //{ - // SourceAccount: nil, - // Body: xdr.OperationBody{ - // Type: xdr.OperationTypeRestoreFootprint, - // RestoreFootprintOp: &xdr.RestoreFootprintOp{ - // Ext: xdr.ExtensionPoint{ - // V: 0, - // }, - // }, - // }, - //}, + { + SourceAccount: nil, + Body: xdr.OperationBody{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ + HostFunction: xdr.HostFunction{ + Type: xdr.HostFunctionTypeHostFunctionTypeInvokeContract, + InvokeContract: &xdr.InvokeContractArgs{ + ContractAddress: xdr.ScAddress{ + Type: xdr.ScAddressTypeScAddressTypeContract, + ContractId: &contractHash, + }, + FunctionName: "test", + Args: []xdr.ScVal{}, + }, + }, + }, + }, + }, + { + SourceAccount: nil, + Body: xdr.OperationBody{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ + HostFunction: xdr.HostFunction{ + Type: xdr.HostFunctionTypeHostFunctionTypeCreateContract, + CreateContract: &xdr.CreateContractArgs{ + ContractIdPreimage: xdr.ContractIdPreimage{ + Type: xdr.ContractIdPreimageTypeContractIdPreimageFromAddress, + FromAddress: &xdr.ContractIdPreimageFromAddress{ + Address: xdr.ScAddress{ + Type: xdr.ScAddressTypeScAddressTypeContract, + ContractId: &contractHash, + }, + Salt: salt, + }, + }, + Executable: xdr.ContractExecutable{}, + }, + }, + }, + }, + }, + { + SourceAccount: nil, + Body: xdr.OperationBody{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ + HostFunction: xdr.HostFunction{ + Type: xdr.HostFunctionTypeHostFunctionTypeCreateContract, + CreateContract: &xdr.CreateContractArgs{ + ContractIdPreimage: xdr.ContractIdPreimage{ + Type: xdr.ContractIdPreimageTypeContractIdPreimageFromAsset, + FromAsset: &xdr.Asset{ + Type: xdr.AssetTypeAssetTypeCreditAlphanum12, + AlphaNum12: &xdr.AlphaNum12{ + AssetCode: assetCode, + Issuer: xdr.AccountId{ + Type: xdr.PublicKeyTypePublicKeyTypeEd25519, + Ed25519: &assetIssuer, + }, + }, + }, + }, + Executable: xdr.ContractExecutable{}, + }, + }, + }, + }, + }, + { + SourceAccount: nil, + Body: xdr.OperationBody{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ + HostFunction: xdr.HostFunction{ + Type: xdr.HostFunctionTypeHostFunctionTypeCreateContractV2, + CreateContractV2: &xdr.CreateContractArgsV2{ + ContractIdPreimage: xdr.ContractIdPreimage{ + Type: xdr.ContractIdPreimageTypeContractIdPreimageFromAsset, + FromAsset: &xdr.Asset{ + Type: xdr.AssetTypeAssetTypeCreditAlphanum12, + AlphaNum12: &xdr.AlphaNum12{ + AssetCode: assetCode, + Issuer: xdr.AccountId{ + Type: xdr.PublicKeyTypePublicKeyTypeEd25519, + Ed25519: &assetIssuer, + }, + }, + }, + }, + Executable: xdr.ContractExecutable{}, + ConstructorArgs: []xdr.ScVal{ + { + Type: xdr.ScValTypeScvBool, + B: &dummyBool, + }, + }, + }, + }, + }, + }, + }, + { + SourceAccount: nil, + Body: xdr.OperationBody{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionOp: &xdr.InvokeHostFunctionOp{ + HostFunction: xdr.HostFunction{ + Type: xdr.HostFunctionTypeHostFunctionTypeUploadContractWasm, + Wasm: &wasm, + }, + }, + }, + }, + { + SourceAccount: nil, + Body: xdr.OperationBody{ + Type: xdr.OperationTypeExtendFootprintTtl, + ExtendFootprintTtlOp: &xdr.ExtendFootprintTtlOp{ + Ext: xdr.ExtensionPoint{ + V: 0, + }, + ExtendTo: 1234, + }, + }, + }, + { + SourceAccount: nil, + Body: xdr.OperationBody{ + Type: xdr.OperationTypeRestoreFootprint, + RestoreFootprintOp: &xdr.RestoreFootprintOp{ + Ext: xdr.ExtensionPoint{ + V: 0, + }, + }, + }, + }, } inputEnvelope.Tx.Operations = inputOperations results := []xdr.OperationResult{ @@ -909,12 +943,69 @@ func makeOperationTestInput() (inputTransaction ingest.LedgerTransaction, err er }, }, }, - //{}, - //{}, - //{}, - //{}, - //{}, - //{}, + { + Code: xdr.OperationResultCodeOpInner, + Tr: &xdr.OperationResultTr{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionResult: &xdr.InvokeHostFunctionResult{ + Code: xdr.InvokeHostFunctionResultCodeInvokeHostFunctionSuccess, + }, + }, + }, + { + Code: xdr.OperationResultCodeOpInner, + Tr: &xdr.OperationResultTr{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionResult: &xdr.InvokeHostFunctionResult{ + Code: xdr.InvokeHostFunctionResultCodeInvokeHostFunctionSuccess, + }, + }, + }, + { + Code: xdr.OperationResultCodeOpInner, + Tr: &xdr.OperationResultTr{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionResult: &xdr.InvokeHostFunctionResult{ + Code: xdr.InvokeHostFunctionResultCodeInvokeHostFunctionSuccess, + }, + }, + }, + { + Code: xdr.OperationResultCodeOpInner, + Tr: &xdr.OperationResultTr{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionResult: &xdr.InvokeHostFunctionResult{ + Code: xdr.InvokeHostFunctionResultCodeInvokeHostFunctionSuccess, + }, + }, + }, + { + Code: xdr.OperationResultCodeOpInner, + Tr: &xdr.OperationResultTr{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionResult: &xdr.InvokeHostFunctionResult{ + Code: xdr.InvokeHostFunctionResultCodeInvokeHostFunctionSuccess, + }, + }, + }, + { + Code: xdr.OperationResultCodeOpInner, + Tr: &xdr.OperationResultTr{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionResult: &xdr.InvokeHostFunctionResult{ + Code: xdr.InvokeHostFunctionResultCodeInvokeHostFunctionSuccess, + }, + }, + }, + { + Code: xdr.OperationResultCodeOpInner, + Tr: &xdr.OperationResultTr{ + Type: xdr.OperationTypeInvokeHostFunction, + InvokeHostFunctionResult: &xdr.InvokeHostFunctionResult{ + Code: xdr.InvokeHostFunctionResultCodeInvokeHostFunctionSuccess, + }, + }, + }, } inputTransaction.Result.Result.Result.Results = &results inputTransaction.Envelope.V1 = &inputEnvelope @@ -925,6 +1016,8 @@ func makeOperationTestOutputs() (transformedOperations []OperationOutput) { hardCodedSourceAccountAddress := testAccount3Address hardCodedDestAccountAddress := testAccount4Address hardCodedLedgerClose := genericCloseTime.UTC() + var nilStringArray []string + transformedOperations = []OperationOutput{ { SourceAccount: hardCodedSourceAccountAddress, @@ -1737,93 +1830,248 @@ func makeOperationTestOutputs() (transformedOperations []OperationOutput) { "shares": 0.0000004, }, }, - //OperationOutput{ - // Type: 24, - // TypeString: "invoke_host_function", - // SourceAccount: hardCodedSourceAccountAddress, - // TransactionID: 4096, - // OperationID: 4128, - // OperationDetails: map[string]interface{}{ - // "function": "HostFunctionTypeHostFunctionTypeInvokeContract", - // "type": "invoke_contract", - // "contract_id": "", - // "contract_code_hash": "", - // "asset_balance_changes": []map[string]interface{}{}, - // }, - // ClosedAt: hardCodedLedgerClose, - //}, - //OperationOutput{ - // Type: 24, - // TypeString: "invoke_host_function", - // SourceAccount: hardCodedSourceAccountAddress, - // TransactionID: 4096, - // OperationID: 4129, - // OperationDetails: map[string]interface{}{ - // "function": "HostFunctionTypeHostFunctionTypeCreateContract", - // "type": "create_contract", - // "contract_id": "", - // "contract_code_hash": "", - // "from": "address", - // "address": "", - // }, - // ClosedAt: hardCodedLedgerClose, - //}, - //OperationOutput{ - // Type: 24, - // TypeString: "invoke_host_function", - // SourceAccount: hardCodedSourceAccountAddress, - // TransactionID: 4096, - // OperationID: 4130, - // OperationDetails: map[string]interface{}{ - // "function": "HostFunctionTypeHostFunctionTypeCreateContract", - // "type": "create_contract", - // "contract_id": "", - // "contract_code_hash": "", - // "from": "asset", - // "asset": "", - // }, - // ClosedAt: hardCodedLedgerClose, - //}, - //OperationOutput{ - // Type: 24, - // TypeString: "invoke_host_function", - // SourceAccount: hardCodedSourceAccountAddress, - // TransactionID: 4096, - // OperationID: 4131, - // OperationDetails: map[string]interface{}{ - // "function": "HostFunctionTypeHostFunctionTypeUploadContractWasm", - // "type": "upload_wasm", - // "contract_code_hash": "", - // }, - // ClosedAt: hardCodedLedgerClose, - //}, - //OperationOutput{ - // Type: 25, - // TypeString: "bump_footprint_expiration", - // SourceAccount: hardCodedSourceAccountAddress, - // TransactionID: 4096, - // OperationID: 4132, - // OperationDetails: map[string]interface{}{ - // "type": "bump_footprint_expiration", - // "ledgers_to_expire": 1234, - // "contract_id": "", - // "contract_code_hash": "", - // }, - // ClosedAt: hardCodedLedgerClose, - //}, - //OperationOutput{ - // Type: 26, - // TypeString: "restore_footprint", - // SourceAccount: hardCodedSourceAccountAddress, - // TransactionID: 4096, - // OperationID: 4133, - // OperationDetails: map[string]interface{}{ - // "type": "restore_footprint", - // "contract_id": "", - // "contract_code_hash": "", - // }, - // ClosedAt: hardCodedLedgerClose, - //}, + OperationOutput{ + Type: 24, + TypeString: "invoke_host_function", + SourceAccount: hardCodedSourceAccountAddress, + TransactionID: 4096, + OperationID: 4128, + OperationDetails: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeInvokeContract", + "type": "invoke_contract", + "contract_id": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", + "contract_code_hash": "", + "asset_balance_changes": []map[string]interface{}{}, + "ledger_key_hash": nilStringArray, + "parameters": []map[string]string{ + { + "type": "Address", + "value": "AAAAEgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + }, + { + "type": "Sym", + "value": "AAAADwAAAAR0ZXN0", + }, + }, + "parameters_decoded": []map[string]string{ + { + "type": "Address", + "value": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", + }, + { + "type": "Sym", + "value": "test", + }, + }, + }, + OperationResultCode: "OperationResultCodeOpInner", + OperationTraceCode: "InvokeHostFunctionResultCodeInvokeHostFunctionSuccess", + ClosedAt: hardCodedLedgerClose, + OperationDetailsJSON: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeInvokeContract", + "type": "invoke_contract", + "contract_id": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", + "contract_code_hash": "", + "asset_balance_changes": []map[string]interface{}{}, + "ledger_key_hash": nilStringArray, + "parameters": []map[string]string{ + { + "type": "Address", + "value": "AAAAEgAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", + }, + { + "type": "Sym", + "value": "AAAADwAAAAR0ZXN0", + }, + }, + "parameters_decoded": []map[string]string{ + { + "type": "Address", + "value": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", + }, + { + "type": "Sym", + "value": "test", + }, + }, + }, + }, + OperationOutput{ + Type: 24, + TypeString: "invoke_host_function", + SourceAccount: hardCodedSourceAccountAddress, + TransactionID: 4096, + OperationID: 4129, + OperationDetails: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeCreateContract", + "type": "create_contract", + "contract_id": "", + "contract_code_hash": "", + "from": "address", + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", + "ledger_key_hash": nilStringArray, + }, + ClosedAt: hardCodedLedgerClose, + OperationResultCode: "OperationResultCodeOpInner", + OperationTraceCode: "InvokeHostFunctionResultCodeInvokeHostFunctionSuccess", + OperationDetailsJSON: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeCreateContract", + "type": "create_contract", + "contract_id": "", + "contract_code_hash": "", + "from": "address", + "address": "CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4", + "ledger_key_hash": nilStringArray, + }, + }, + OperationOutput{ + Type: 24, + TypeString: "invoke_host_function", + SourceAccount: hardCodedSourceAccountAddress, + TransactionID: 4096, + OperationID: 4130, + OperationDetails: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeCreateContract", + "type": "create_contract", + "contract_id": "", + "contract_code_hash": "", + "from": "asset", + "asset": ":GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", + "ledger_key_hash": nilStringArray, + }, + OperationResultCode: "OperationResultCodeOpInner", + OperationTraceCode: "InvokeHostFunctionResultCodeInvokeHostFunctionSuccess", + ClosedAt: hardCodedLedgerClose, + OperationDetailsJSON: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeCreateContract", + "type": "create_contract", + "contract_id": "", + "contract_code_hash": "", + "from": "asset", + "asset": ":GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", + "ledger_key_hash": nilStringArray, + }, + }, + OperationOutput{ + Type: 24, + TypeString: "invoke_host_function", + SourceAccount: hardCodedSourceAccountAddress, + TransactionID: 4096, + OperationID: 4131, + OperationDetails: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeCreateContractV2", + "type": "create_contract_v2", + "contract_id": "", + "contract_code_hash": "", + "from": "asset", + "asset": ":GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", + "ledger_key_hash": nilStringArray, + "parameters": []map[string]string{ + { + "type": "B", + "value": "AAAAAAAAAAE=", + }, + }, + "parameters_decoded": []map[string]string{ + { + "type": "B", + "value": "true", + }, + }, + }, + OperationResultCode: "OperationResultCodeOpInner", + OperationTraceCode: "InvokeHostFunctionResultCodeInvokeHostFunctionSuccess", + ClosedAt: hardCodedLedgerClose, + OperationDetailsJSON: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeCreateContractV2", + "type": "create_contract_v2", + "contract_id": "", + "contract_code_hash": "", + "from": "asset", + "asset": ":GAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWHF", + "ledger_key_hash": nilStringArray, + "parameters": []map[string]string{ + { + "type": "B", + "value": "AAAAAAAAAAE=", + }, + }, + "parameters_decoded": []map[string]string{ + { + "type": "B", + "value": "true", + }, + }, + }, + }, + OperationOutput{ + Type: 24, + TypeString: "invoke_host_function", + SourceAccount: hardCodedSourceAccountAddress, + TransactionID: 4096, + OperationID: 4132, + OperationDetails: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeUploadContractWasm", + "type": "upload_wasm", + "contract_code_hash": "", + "ledger_key_hash": nilStringArray, + }, + ClosedAt: hardCodedLedgerClose, + OperationResultCode: "OperationResultCodeOpInner", + OperationTraceCode: "InvokeHostFunctionResultCodeInvokeHostFunctionSuccess", + OperationDetailsJSON: map[string]interface{}{ + "function": "HostFunctionTypeHostFunctionTypeUploadContractWasm", + "type": "upload_wasm", + "contract_code_hash": "", + "ledger_key_hash": nilStringArray, + }, + }, + OperationOutput{ + Type: 25, + TypeString: "extend_footprint_ttl", + SourceAccount: hardCodedSourceAccountAddress, + TransactionID: 4096, + OperationID: 4133, + OperationDetails: map[string]interface{}{ + "type": "extend_footprint_ttl", + "extend_to": xdr.Uint32(1234), + "contract_id": "", + "contract_code_hash": "", + "ledger_key_hash": nilStringArray, + }, + ClosedAt: hardCodedLedgerClose, + OperationResultCode: "OperationResultCodeOpInner", + OperationTraceCode: "InvokeHostFunctionResultCodeInvokeHostFunctionSuccess", + OperationDetailsJSON: map[string]interface{}{ + "type": "extend_footprint_ttl", + "extend_to": xdr.Uint32(1234), + "contract_id": "", + "contract_code_hash": "", + "ledger_key_hash": nilStringArray, + }, + }, + OperationOutput{ + Type: 26, + TypeString: "restore_footprint", + SourceAccount: hardCodedSourceAccountAddress, + TransactionID: 4096, + OperationID: 4134, + OperationDetails: map[string]interface{}{ + "type": "restore_footprint", + "contract_id": "", + "contract_code_hash": "", + "ledger_key_hash": nilStringArray, + }, + ClosedAt: hardCodedLedgerClose, + OperationResultCode: "OperationResultCodeOpInner", + OperationTraceCode: "InvokeHostFunctionResultCodeInvokeHostFunctionSuccess", + OperationDetailsJSON: map[string]interface{}{ + "type": "restore_footprint", + "contract_id": "", + "contract_code_hash": "", + "ledger_key_hash": nilStringArray, + }, + }, } return } diff --git a/internal/transform/test_variables_test.go b/internal/transform/test_variables_test.go index 43aadbcc..6fd421ca 100644 --- a/internal/transform/test_variables_test.go +++ b/internal/transform/test_variables_test.go @@ -33,6 +33,21 @@ var genericBumpOperationEnvelope = xdr.TransactionV1Envelope{ Operations: []xdr.Operation{ genericBumpOperation, }, + Ext: xdr.TransactionExt{ + V: 0, + SorobanData: &xdr.SorobanTransactionData{ + Ext: xdr.ExtensionPoint{ + V: 0, + }, + Resources: xdr.SorobanResources{ + Footprint: xdr.LedgerFootprint{ + ReadOnly: []xdr.LedgerKey{}, + ReadWrite: []xdr.LedgerKey{}, + }, + }, + ResourceFee: 100, + }, + }, }, } var genericBumpOperationForTransaction = xdr.Operation{ diff --git a/internal/utils/main.go b/internal/utils/main.go index 164fd563..4456f222 100644 --- a/internal/utils/main.go +++ b/internal/utils/main.go @@ -234,7 +234,7 @@ func AddCommonFlags(flags *pflag.FlagSet) { flags.Bool("testnet", false, "If set, will connect to Testnet instead of Mainnet.") flags.Bool("futurenet", false, "If set, will connect to Futurenet instead of Mainnet.") flags.StringToStringP("extra-fields", "u", map[string]string{}, "Additional fields to append to output jsons. Used for appending metadata") - flags.Bool("captive-core", false, "If set, run captive core to retrieve data. Otherwise use TxMeta file datastore.") + flags.Bool("captive-core", false, "(Deprecated; Will be removed in the Protocol 23 update) If set, run captive core to retrieve data. Otherwise use TxMeta file datastore.") flags.String("datastore-path", "sdf-ledger-close-meta/ledgers", "Datastore bucket path to read txmeta files from.") flags.Uint32("buffer-size", 200, "Buffer size sets the max limit for the number of txmeta files that can be held in memory.") flags.Uint32("num-workers", 10, "Number of workers to spawn that read txmeta files from the datastore.") @@ -344,6 +344,10 @@ func MustFlags(flags *pflag.FlagSet, logger *EtlLogger) FlagValues { if err != nil { logger.Fatal("could not get captive-core flag: ", err) } + // Deprecation warning + if useCaptiveCore { + logger.Warn("warning: the option to run with captive-core will be deprecated in the Protocol 23 update") + } datastorePath, err := flags.GetString("datastore-path") if err != nil { @@ -480,6 +484,9 @@ func MustCommonFlags(flags *pflag.FlagSet, logger *EtlLogger) CommonFlagValues { if err != nil { logger.Fatal("could not get captive-core flag: ", err) } + if useCaptiveCore { + logger.Warn("warning: the option to run with captive-core will be deprecated in the Protocol 23 update") + } datastorePath, err := flags.GetString("datastore-path") if err != nil {