Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

services/horizon: return null txmeta in api model when SKIP_TXMETA enabled #5228

Merged
merged 7 commits into from Mar 6, 2024
2 changes: 1 addition & 1 deletion clients/horizonclient/main_test.go
Expand Up @@ -852,7 +852,7 @@ func TestSubmitTransactionXDRRequest(t *testing.T) {
assert.Equal(t, resp.Ledger, int32(354811))
assert.Equal(t, resp.EnvelopeXdr, txXdr)
assert.Equal(t, resp.ResultXdr, "AAAAAAAAAGQAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAA=")
assert.Equal(t, resp.ResultMetaXdr, `AAAAAQAAAAIAAAADAAVp+wAAAAAAAAAAEH3Rayw4M0iCLoEe96rPFNGYim8AVHJU0z4ebYZW4JwACBP/TuycHAAABD0AAuV+AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAVp+wAAAAAAAAAAEH3Rayw4M0iCLoEe96rPFNGYim8AVHJU0z4ebYZW4JwACBP/TuycHAAABD0AAuV/AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAMABWn7AAAAAAAAAAAQfdFrLDgzSIIugR73qs8U0ZiKbwBUclTTPh5thlbgnAAIE/9O7JwcAAAEPQAC5X8AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEABWn7AAAAAAAAAAAQfdFrLDgzSIIugR73qs8U0ZiKbwBUclTTPh5thlbgnAAIE+gGdbQcAAAEPQAC5X8AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAABWn7AAAAAAAAAADJMEbE6B9ICmmmxOdv9hGvqA5HxZPQtk2uEuHjLcUKCgAAABdIdugAAAVp+wAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA==`)
assert.Equal(t, *resp.ResultMetaXdr, `AAAAAQAAAAIAAAADAAVp+wAAAAAAAAAAEH3Rayw4M0iCLoEe96rPFNGYim8AVHJU0z4ebYZW4JwACBP/TuycHAAABD0AAuV+AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAVp+wAAAAAAAAAAEH3Rayw4M0iCLoEe96rPFNGYim8AVHJU0z4ebYZW4JwACBP/TuycHAAABD0AAuV/AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAwAAAAMABWn7AAAAAAAAAAAQfdFrLDgzSIIugR73qs8U0ZiKbwBUclTTPh5thlbgnAAIE/9O7JwcAAAEPQAC5X8AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAEABWn7AAAAAAAAAAAQfdFrLDgzSIIugR73qs8U0ZiKbwBUclTTPh5thlbgnAAIE+gGdbQcAAAEPQAC5X8AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAABWn7AAAAAAAAAADJMEbE6B9ICmmmxOdv9hGvqA5HxZPQtk2uEuHjLcUKCgAAABdIdugAAAVp+wAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAA==`)
}
}

Expand Down
2 changes: 2 additions & 0 deletions protocols/horizon/README.md
Expand Up @@ -17,6 +17,8 @@ For each new version we will only track changes from the previous version.

#### Changes

* In ["Transaction"](https://developers.stellar.org/api/horizon/resources/transactions/object),
`result_meta_xdr` field is [now nullable](https://github.com/stellar/go/pull/5228), and will be `null` when Horizon has `SKIP_TXMETA=true` set, otherwise if Horizon is configured with `SKIP_TXMETA=false` which is default, then `result_meta_xdr` will be the same value of base64 encoded xdr.
* Operations responses may include a `transaction` field which represents the transaction that created the operation.

### 0.15.0
Expand Down
2 changes: 1 addition & 1 deletion protocols/horizon/main.go
Expand Up @@ -518,7 +518,7 @@ type Transaction struct {
OperationCount int32 `json:"operation_count"`
EnvelopeXdr string `json:"envelope_xdr"`
ResultXdr string `json:"result_xdr"`
ResultMetaXdr string `json:"result_meta_xdr"`
ResultMetaXdr *string `json:"result_meta_xdr"`
sreuland marked this conversation as resolved.
Show resolved Hide resolved
FeeMetaXdr string `json:"fee_meta_xdr"`
MemoType string `json:"memo_type"`
MemoBytes string `json:"memo_bytes,omitempty"`
Expand Down
5 changes: 5 additions & 0 deletions services/horizon/CHANGELOG.md
Expand Up @@ -3,6 +3,11 @@
All notable changes to this project will be documented in this
file. This project adheres to [Semantic Versioning](http://semver.org/).

## Unreleased

### Breaking Changes
- The Horizon API Transaction resource field `result_meta_xdr` is now nullable and Horizon API will set it to `null` when Horizon has been configured with `SKIP_TXMETA=true`, otherwise if Horizon is configured with `SKIP_TXMETA=false` which is default, then the API Transaction field `result_meta_xdr` will remain as-is, being the base64 encoded xdr [5228](https://github.com/stellar/go/pull/5228).

## 2.28.3

### Fixed
Expand Down
2 changes: 1 addition & 1 deletion services/horizon/internal/actions/transaction_test.go
Expand Up @@ -144,7 +144,7 @@ func checkOuterHashResponse(
tt.Assert.Equal(fixture.Transaction.TransactionHash, transactionResponse.Hash)
tt.Assert.Equal(fixture.Transaction.TxEnvelope, transactionResponse.EnvelopeXdr)
tt.Assert.Equal(fixture.Transaction.TxFeeMeta, transactionResponse.FeeMetaXdr)
tt.Assert.Equal(fixture.Transaction.TxMeta, transactionResponse.ResultMetaXdr)
tt.Assert.Equal(fixture.Transaction.TxMeta, *transactionResponse.ResultMetaXdr)
tt.Assert.Equal(fixture.Transaction.TxResult, transactionResponse.ResultXdr)
}

Expand Down
4 changes: 2 additions & 2 deletions services/horizon/internal/actions_transaction_test.go
Expand Up @@ -378,7 +378,7 @@ func TestPostFeeBumpTransaction(t *testing.T) {
ht.Assert.NoError(err)

ht.Assert.Equal(fixture.Transaction.TxResult, response.ResultXdr)
ht.Assert.Equal(fixture.Transaction.TxMeta, response.ResultMetaXdr)
ht.Assert.Equal(fixture.Transaction.TxMeta, *response.ResultMetaXdr)
ht.Assert.Equal(fixture.Transaction.TransactionHash, response.Hash)
ht.Assert.Equal(fixture.Transaction.TxEnvelope, response.EnvelopeXdr)
ht.Assert.Equal(fixture.Transaction.LedgerSequence, response.Ledger)
Expand All @@ -392,7 +392,7 @@ func TestPostFeeBumpTransaction(t *testing.T) {
ht.Assert.NoError(err)

ht.Assert.Equal(fixture.Transaction.TxResult, response.ResultXdr)
ht.Assert.Equal(fixture.Transaction.TxMeta, response.ResultMetaXdr)
ht.Assert.Equal(fixture.Transaction.TxMeta, *response.ResultMetaXdr)
ht.Assert.Equal(fixture.InnerHash, response.Hash)
ht.Assert.Equal(fixture.Transaction.TxEnvelope, response.EnvelopeXdr)
ht.Assert.Equal(fixture.Transaction.LedgerSequence, response.Ledger)
Expand Down
3 changes: 3 additions & 0 deletions services/horizon/internal/app.go
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/stellar/go/services/horizon/internal/operationfeestats"
"github.com/stellar/go/services/horizon/internal/paths"
"github.com/stellar/go/services/horizon/internal/reap"
"github.com/stellar/go/services/horizon/internal/resourceadapter"
"github.com/stellar/go/services/horizon/internal/txsub"
"github.com/stellar/go/support/app"
"github.com/stellar/go/support/db"
Expand Down Expand Up @@ -74,6 +75,8 @@ func NewApp(config Config) (*App, error) {
done: make(chan struct{}),
}

resourceadapter.SetResourceAdapter(resourceadapter.ResourceAdapter{SkipTxmeta: config.SkipTxmeta})

if err := a.init(); err != nil {
return nil, err
}
Expand Down
Expand Up @@ -213,7 +213,7 @@ func TestContractInvokeHostFunctionInvokeStatelessContractFn(t *testing.T) {
invokeResult := xdr.Uint64(9)
expectedScVal := xdr.ScVal{Type: xdr.ScValTypeScvU64, U64: &invokeResult}
var transactionMeta xdr.TransactionMeta
assert.NoError(t, xdr.SafeUnmarshalBase64(tx.ResultMetaXdr, &transactionMeta))
assert.NoError(t, xdr.SafeUnmarshalBase64(*tx.ResultMetaXdr, &transactionMeta))
assert.True(t, expectedScVal.Equals(transactionMeta.V3.SorobanMeta.ReturnValue))

clientInvokeOp, err := itest.Client().Operations(horizonclient.OperationRequest{
Expand Down Expand Up @@ -309,7 +309,7 @@ func TestContractInvokeHostFunctionInvokeStatefulContractFn(t *testing.T) {
invokeResult := xdr.Uint32(1)
expectedScVal := xdr.ScVal{Type: xdr.ScValTypeScvU32, U32: &invokeResult}
var transactionMeta xdr.TransactionMeta
assert.NoError(t, xdr.SafeUnmarshalBase64(clientTx.ResultMetaXdr, &transactionMeta))
assert.NoError(t, xdr.SafeUnmarshalBase64(*clientTx.ResultMetaXdr, &transactionMeta))
assert.True(t, expectedScVal.Equals(transactionMeta.V3.SorobanMeta.ReturnValue))

clientInvokeOp, err := itest.Client().Operations(horizonclient.OperationRequest{
Expand Down
2 changes: 1 addition & 1 deletion services/horizon/internal/integration/sac_test.go
Expand Up @@ -1401,7 +1401,7 @@ func assertInvokeHostFnSucceeds(itest *integration.Test, signer *keypair.Full, o
require.NoError(itest.CurrentTest(), err)

var txMetaResult xdr.TransactionMeta
err = xdr.SafeUnmarshalBase64(clientTx.ResultMetaXdr, &txMetaResult)
err = xdr.SafeUnmarshalBase64(*clientTx.ResultMetaXdr, &txMetaResult)
require.NoError(itest.CurrentTest(), err)

opResults, ok := txResult.OperationResults()
Expand Down
21 changes: 4 additions & 17 deletions services/horizon/internal/integration/transaction_test.go
Expand Up @@ -33,7 +33,7 @@ func TestP19MetaTransaction(t *testing.T) {
clientTx := itest.MustSubmitOperations(&masterAccount, itest.Master(), op)

var txMetaResult xdr.TransactionMeta
err = xdr.SafeUnmarshalBase64(clientTx.ResultMetaXdr, &txMetaResult)
err = xdr.SafeUnmarshalBase64(*clientTx.ResultMetaXdr, &txMetaResult)
require.NoError(t, err)

assert.Greater(t, len(txMetaResult.MustV2().Operations), 0)
Expand Down Expand Up @@ -63,13 +63,7 @@ func TestP19MetaDisabledTransaction(t *testing.T) {

clientTx := itest.MustSubmitOperations(&masterAccount, itest.Master(), op)

var txMetaResult xdr.TransactionMeta
err = xdr.SafeUnmarshalBase64(clientTx.ResultMetaXdr, &txMetaResult)
require.NoError(t, err)

assert.Equal(t, len(txMetaResult.MustV2().Operations), 0)
assert.Equal(t, len(txMetaResult.MustV2().TxChangesAfter), 0)
assert.Equal(t, len(txMetaResult.MustV2().TxChangesBefore), 0)
assert.Nil(t, clientTx.ResultMetaXdr)
}

func TestP20MetaTransaction(t *testing.T) {
Expand All @@ -93,7 +87,7 @@ func TestP20MetaTransaction(t *testing.T) {
clientTx := itest.MustSubmitOperationsWithFee(&sourceAccount, itest.Master(), minFee+txnbuild.MinBaseFee, &preFlightOp)

var txMetaResult xdr.TransactionMeta
err = xdr.SafeUnmarshalBase64(clientTx.ResultMetaXdr, &txMetaResult)
err = xdr.SafeUnmarshalBase64(*clientTx.ResultMetaXdr, &txMetaResult)
require.NoError(t, err)

assert.Greater(t, len(txMetaResult.MustV3().Operations), 0)
Expand Down Expand Up @@ -123,12 +117,5 @@ func TestP20MetaDisabledTransaction(t *testing.T) {
preFlightOp, minFee := itest.PreflightHostFunctions(&sourceAccount, *installContractOp)
clientTx := itest.MustSubmitOperationsWithFee(&sourceAccount, itest.Master(), minFee+txnbuild.MinBaseFee, &preFlightOp)

var txMetaResult xdr.TransactionMeta
err = xdr.SafeUnmarshalBase64(clientTx.ResultMetaXdr, &txMetaResult)
require.NoError(t, err)

assert.Equal(t, len(txMetaResult.MustV3().Operations), 0)
assert.Nil(t, txMetaResult.MustV3().SorobanMeta)
assert.Equal(t, len(txMetaResult.MustV3().TxChangesAfter), 0)
assert.Equal(t, len(txMetaResult.MustV3().TxChangesBefore), 0)
assert.Nil(t, clientTx.ResultMetaXdr)
}
16 changes: 16 additions & 0 deletions services/horizon/internal/resourceadapter/main.go
@@ -0,0 +1,16 @@
package resourceadapter

type ResourceAdapter struct {
SkipTxmeta bool
}

var resourceAdapterInstance ResourceAdapter

// provide a singleton reference to resource adapter runtime state
func GetResourceAdapter() ResourceAdapter {
return resourceAdapterInstance
}

func SetResourceAdapter(instance ResourceAdapter) {
resourceAdapterInstance = instance
}
6 changes: 5 additions & 1 deletion services/horizon/internal/resourceadapter/transaction.go
Expand Up @@ -43,7 +43,11 @@ func PopulateTransaction(
dest.OperationCount = row.OperationCount
dest.EnvelopeXdr = row.TxEnvelope
dest.ResultXdr = row.TxResult
dest.ResultMetaXdr = row.TxMeta
if GetResourceAdapter().SkipTxmeta {
sreuland marked this conversation as resolved.
Show resolved Hide resolved
dest.ResultMetaXdr = nil
} else {
dest.ResultMetaXdr = &row.TxMeta
}
dest.FeeMetaXdr = row.TxFeeMeta
dest.MemoType = row.MemoType
dest.Memo = row.Memo.String
Expand Down
41 changes: 41 additions & 0 deletions services/horizon/internal/resourceadapter/transaction_test.go
Expand Up @@ -46,6 +46,39 @@

assert.NoError(t, PopulateTransaction(ctx, row.TransactionHash, &dest, row))
assert.False(t, dest.Successful)
assert.NotNil(t, dest.ResultMetaXdr)
}

func TestPopulateTransactionSuccessfulWhenSkipMeta(t *testing.T) {
ctx, _ := test.ContextWithLogBuffer()

SetResourceAdapter(ResourceAdapter{SkipTxmeta: true})
defer SetResourceAdapter(ResourceAdapter{SkipTxmeta: false})
var (
dest Transaction

Check failure on line 58 in services/horizon/internal/resourceadapter/transaction_test.go

View workflow job for this annotation

GitHub Actions / golangci

undefined: Transaction (typecheck)
row history.Transaction
)

dest = Transaction{}

Check failure on line 62 in services/horizon/internal/resourceadapter/transaction_test.go

View workflow job for this annotation

GitHub Actions / golangci

undefined: Transaction (typecheck)
row = history.Transaction{
TransactionWithoutLedger: history.TransactionWithoutLedger{
Successful: true,
},
}

assert.NoError(t, PopulateTransaction(ctx, row.TransactionHash, &dest, row))
assert.True(t, dest.Successful)

dest = Transaction{}

Check failure on line 72 in services/horizon/internal/resourceadapter/transaction_test.go

View workflow job for this annotation

GitHub Actions / golangci

undefined: Transaction (typecheck)
row = history.Transaction{
TransactionWithoutLedger: history.TransactionWithoutLedger{
Successful: false,
},
}

assert.NoError(t, PopulateTransaction(ctx, row.TransactionHash, &dest, row))
assert.False(t, dest.Successful)
assert.Nil(t, dest.ResultMetaXdr)
}

func TestPopulateTransaction_HashMemo(t *testing.T) {
Expand All @@ -61,6 +94,7 @@
assert.Equal(t, "hash", dest.MemoType)
assert.Equal(t, "abcdef", dest.Memo)
assert.Equal(t, "", dest.MemoBytes)
assert.NotNil(t, dest.ResultMetaXdr)
}

func TestPopulateTransaction_TextMemo(t *testing.T) {
Expand Down Expand Up @@ -131,6 +165,7 @@
assert.Equal(t, "text", dest.MemoType)
assert.Equal(t, "sample", dest.Memo)
assert.Equal(t, base64.StdEncoding.EncodeToString(rawMemo), dest.MemoBytes)
assert.NotNil(t, dest.ResultMetaXdr)
}
}

Expand All @@ -154,6 +189,7 @@
assert.NoError(t, PopulateTransaction(ctx, row.TransactionHash, &dest, row))
assert.Equal(t, int64(100), dest.FeeCharged)
assert.Equal(t, int64(10000), dest.MaxFee)
assert.NotNil(t, dest.ResultMetaXdr)
}

// TestPopulateTransaction_Preconditions tests transaction object population.
Expand Down Expand Up @@ -192,6 +228,7 @@
}

assert.NoError(t, PopulateTransaction(ctx, row.TransactionHash, &dest, row))
assert.NotNil(t, dest.ResultMetaXdr)
p := dest.Preconditions
assert.Equal(t, validAfter.Format(time.RFC3339), dest.ValidAfter)
assert.Equal(t, validBefore.Format(time.RFC3339), dest.ValidBefore)
Expand Down Expand Up @@ -287,6 +324,7 @@

var dest Transaction
assert.NoError(t, PopulateTransaction(ctx, row.TransactionHash, &dest, row))
assert.NotNil(t, dest.ResultMetaXdr)

gotTimebounds := dest.Preconditions.TimeBounds
assert.Equal(t, "5", gotTimebounds.MinTime)
Expand Down Expand Up @@ -354,6 +392,7 @@
// exist entirely.
tx.MinAccountSequenceLedgerGap = null.IntFromPtr(nil)
dest, js = jsonifyTx(tx)
assert.NotNil(t, dest.ResultMetaXdr)
tt.NotContains(js, "preconditions")
}
}
Expand All @@ -379,6 +418,7 @@
}

assert.NoError(t, PopulateTransaction(ctx, row.TransactionHash, &dest, row))
assert.NotNil(t, dest.ResultMetaXdr)
assert.Equal(t, row.TransactionHash, dest.Hash)
assert.Equal(t, row.TransactionHash, dest.ID)
assert.Equal(t, row.FeeAccount.String, dest.FeeAccount)
Expand All @@ -398,6 +438,7 @@
assert.Equal(t, "/transactions/"+row.TransactionHash, dest.Links.Transaction.Href)

assert.NoError(t, PopulateTransaction(ctx, row.InnerTransactionHash.String, &dest, row))
assert.NotNil(t, dest.ResultMetaXdr)
assert.Equal(t, row.InnerTransactionHash.String, dest.Hash)
assert.Equal(t, row.InnerTransactionHash.String, dest.ID)
assert.Equal(t, row.FeeAccount.String, dest.FeeAccount)
Expand Down