Skip to content

Commit

Permalink
Merge pull request #58 from stellar/update-Txn-rpc-with-events-data
Browse files Browse the repository at this point in the history
Update getTxn rpc with events data
  • Loading branch information
psheth9 authored Feb 12, 2024
2 parents e960236 + b6aeec2 commit 258cef7
Show file tree
Hide file tree
Showing 6 changed files with 174 additions and 6 deletions.
6 changes: 6 additions & 0 deletions cmd/soroban-rpc/internal/methods/get_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ type GetTransactionResponse struct {
Ledger uint32 `json:"ledger,omitempty"`
// LedgerCloseTime is the unix timestamp of when the transaction was included in the ledger.
LedgerCloseTime int64 `json:"createdAt,string,omitempty"`

// DiagnosticEventsXDR is present only if Status is equal to TransactionFailed.
// DiagnosticEventsXDR is a base64-encoded slice of xdr.DiagnosticEvent
DiagnosticEventsXDR []string `json:"diagnosticEventsXdr,omitempty"`
}

type GetTransactionRequest struct {
Expand Down Expand Up @@ -104,6 +108,8 @@ func GetTransaction(getter transactionGetter, request GetTransactionRequest) (Ge
response.ResultXdr = base64.StdEncoding.EncodeToString(tx.Result)
response.EnvelopeXdr = base64.StdEncoding.EncodeToString(tx.Envelope)
response.ResultMetaXdr = base64.StdEncoding.EncodeToString(tx.Meta)
response.DiagnosticEventsXDR = base64EncodeSlice(tx.Events)

if tx.Successful {
response.Status = TransactionStatusSuccess
} else {
Expand Down
80 changes: 80 additions & 0 deletions cmd/soroban-rpc/internal/methods/get_transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,44 @@ func txMeta(acctSeq uint32, successful bool) xdr.LedgerCloseMeta {
}
}

func txMetaWithEvents(acctSeq uint32, successful bool) xdr.LedgerCloseMeta {

meta := txMeta(acctSeq, successful)

contractIDBytes, _ := hex.DecodeString("df06d62447fd25da07c0135eed7557e5a5497ee7d15b7fe345bd47e191d8f577")
var contractID xdr.Hash
copy(contractID[:], contractIDBytes)
counter := xdr.ScSymbol("COUNTER")

meta.V1.TxProcessing[0].TxApplyProcessing.V3 = &xdr.TransactionMetaV3{
SorobanMeta: &xdr.SorobanTransactionMeta{
Events: []xdr.ContractEvent{{
ContractId: &contractID,
Type: xdr.ContractEventTypeContract,
Body: xdr.ContractEventBody{
V: 0,
V0: &xdr.ContractEventV0{
Topics: []xdr.ScVal{{
Type: xdr.ScValTypeScvSymbol,
Sym: &counter,
}},
Data: xdr.ScVal{
Type: xdr.ScValTypeScvSymbol,
Sym: &counter,
},
},
},
}},
ReturnValue: xdr.ScVal{
Type: xdr.ScValTypeScvSymbol,
Sym: &counter,
},
},
}

return meta
}

func txEnvelope(acctSeq uint32) xdr.TransactionEnvelope {
envelope, err := xdr.NewTransactionEnvelope(xdr.EnvelopeTypeEnvelopeTypeTx, xdr.TransactionV1Envelope{
Tx: xdr.Transaction{
Expand Down Expand Up @@ -154,6 +192,7 @@ func TestGetTransaction(t *testing.T) {
ResultMetaXdr: expectedTxMeta,
Ledger: 101,
LedgerCloseTime: 2625,
DiagnosticEventsXDR: []string{},
}, tx)

// ingest another (failed) transaction
Expand All @@ -177,6 +216,7 @@ func TestGetTransaction(t *testing.T) {
ResultMetaXdr: expectedTxMeta,
Ledger: 101,
LedgerCloseTime: 2625,
DiagnosticEventsXDR: []string{},
}, tx)

// the new transaction should also be there
Expand Down Expand Up @@ -206,5 +246,45 @@ func TestGetTransaction(t *testing.T) {
ResultMetaXdr: expectedTxMeta,
Ledger: 102,
LedgerCloseTime: 2650,
DiagnosticEventsXDR: []string{},
}, tx)

// Test Txn with events
meta = txMetaWithEvents(3, true)
err = store.IngestTransactions(meta)
require.NoError(t, err)

xdrHash = txHash(3)
hash = hex.EncodeToString(xdrHash[:])

expectedTxResult, err = xdr.MarshalBase64(meta.V1.TxProcessing[0].Result.Result)
require.NoError(t, err)
expectedEnvelope, err = xdr.MarshalBase64(txEnvelope(3))
require.NoError(t, err)
expectedTxMeta, err = xdr.MarshalBase64(meta.V1.TxProcessing[0].TxApplyProcessing)
require.NoError(t, err)

diagnosticEvents, err := meta.V1.TxProcessing[0].TxApplyProcessing.GetDiagnosticEvents()
require.NoError(t, err)
expectedEventsMeta, err := xdr.MarshalBase64(diagnosticEvents[0])

tx, err = GetTransaction(store, GetTransactionRequest{hash})
require.NoError(t, err)
require.NoError(t, err)
require.Equal(t, GetTransactionResponse{
Status: TransactionStatusSuccess,
LatestLedger: 103,
LatestLedgerCloseTime: 2675,
OldestLedger: 101,
OldestLedgerCloseTime: 2625,
ApplicationOrder: 1,
FeeBump: false,
EnvelopeXdr: expectedEnvelope,
ResultXdr: expectedTxResult,
ResultMetaXdr: expectedTxMeta,
Ledger: 103,
LedgerCloseTime: 2675,
DiagnosticEventsXDR: []string{expectedEventsMeta},
}, tx)

}
30 changes: 27 additions & 3 deletions cmd/soroban-rpc/internal/transactions/transactions.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,10 @@ type LedgerInfo struct {
}

type Transaction struct {
Result []byte // XDR encoded xdr.TransactionResult
Meta []byte // XDR encoded xdr.TransactionMeta
Envelope []byte // XDR encoded xdr.TransactionEnvelope
Result []byte // XDR encoded xdr.TransactionResult
Meta []byte // XDR encoded xdr.TransactionMeta
Envelope []byte // XDR encoded xdr.TransactionEnvelope
Events [][]byte // XDR encoded xdr.DiagnosticEvent
FeeBump bool
ApplicationOrder int32
Successful bool
Expand Down Expand Up @@ -198,10 +199,33 @@ func (m *MemoryStore) GetTransaction(hash xdr.Hash) (Transaction, bool, StoreRan
if !ok {
return Transaction{}, false, storeRange
}

var txMeta xdr.TransactionMeta
err := txMeta.UnmarshalBinary(internalTx.meta)
if err != nil {
return Transaction{}, false, storeRange
}

txEvents, err := txMeta.GetDiagnosticEvents()
if err != nil {
return Transaction{}, false, storeRange
}

events := make([][]byte, 0, len(txEvents))

for _, e := range txEvents {
diagnosticEventXDR, err := e.MarshalBinary()
if err != nil {
return Transaction{}, false, storeRange
}
events = append(events, diagnosticEventXDR)
}

tx := Transaction{
Result: internalTx.result,
Meta: internalTx.meta,
Envelope: internalTx.envelope,
Events: events,
FeeBump: internalTx.feeBump,
Successful: internalTx.successful,
ApplicationOrder: internalTx.applicationOrder,
Expand Down
58 changes: 58 additions & 0 deletions cmd/soroban-rpc/internal/transactions/transactions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ func expectedTransaction(t *testing.T, ledger uint32, feeBump bool) Transaction
FeeBump: feeBump,
ApplicationOrder: 1,
Ledger: expectedLedgerInfo(ledger),
Events: [][]byte{},
}
var err error
tx.Result, err = transactionResult(ledger, feeBump).MarshalBinary()
Expand Down Expand Up @@ -204,6 +205,42 @@ func txMeta(ledgerSequence uint32, feeBump bool) xdr.LedgerCloseMeta {
}
}

func txMetaWithEvents(ledgerSequence uint32, feeBump bool) xdr.LedgerCloseMeta {
tx := txMeta(ledgerSequence, feeBump)
contractIDBytes, _ := hex.DecodeString("df06d62447fd25da07c0135eed7557e5a5497ee7d15b7fe345bd47e191d8f577")
var contractID xdr.Hash
copy(contractID[:], contractIDBytes)
counter := xdr.ScSymbol("COUNTER")

tx.V1.TxProcessing[0].TxApplyProcessing.V3 = &xdr.TransactionMetaV3{
SorobanMeta: &xdr.SorobanTransactionMeta{
Events: []xdr.ContractEvent{{
ContractId: &contractID,
Type: xdr.ContractEventTypeContract,
Body: xdr.ContractEventBody{
V: 0,
V0: &xdr.ContractEventV0{
Topics: []xdr.ScVal{{
Type: xdr.ScValTypeScvSymbol,
Sym: &counter,
}},
Data: xdr.ScVal{
Type: xdr.ScValTypeScvSymbol,
Sym: &counter,
},
},
},
}},
ReturnValue: xdr.ScVal{
Type: xdr.ScValTypeScvSymbol,
Sym: &counter,
},
},
}

return tx
}

func txEnvelope(ledgerSequence uint32, feeBump bool) xdr.TransactionEnvelope {
var envelope xdr.TransactionEnvelope
var err error
Expand Down Expand Up @@ -311,6 +348,27 @@ func TestIngestTransactions(t *testing.T) {
require.Len(t, store.transactions, 3)
}

func TestGetTransactionsWithEventData(t *testing.T) {
store := NewMemoryStore(interfaces.MakeNoOpDeamon(), "passphrase", 100)

// Insert ledger 1
metaWithEvents := txMetaWithEvents(1, false)
require.NoError(t, store.IngestTransactions(metaWithEvents))
require.Len(t, store.transactions, 1)

// check events data
tx, ok, _ := store.GetTransaction(txHash(1, false))
require.True(t, ok)
require.NotNil(t, tx.Events)
require.Len(t, tx.Events, 1)

events, err := metaWithEvents.V1.TxProcessing[0].TxApplyProcessing.GetDiagnosticEvents()
require.NoError(t, err)
eventBytes, err := events[0].MarshalBinary()
require.NoError(t, err)
require.Equal(t, eventBytes, tx.Events[0])
}

func stableHeapInUse() int64 {
var (
m = runtime.MemStats{}
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ require (
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cobra v1.7.0
github.com/spf13/pflag v1.0.5
github.com/stellar/go v0.0.0-20240202231803-b0df9f046eb4
github.com/stellar/go v0.0.0-20240207003209-73de95c8eb55
github.com/stretchr/testify v1.8.4
golang.org/x/mod v0.13.0
gotest.tools/v3 v3.5.0
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -366,8 +366,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-20240202231803-b0df9f046eb4 h1:1DQT7eta18GSv+z6wF7AMUf7NqQ0qOrr2uJPGMRakRg=
github.com/stellar/go v0.0.0-20240202231803-b0df9f046eb4/go.mod h1:Ka4piwZT4Q9799f+BZeaKkAiYo4UpIWXyu0oSUbCVfM=
github.com/stellar/go v0.0.0-20240207003209-73de95c8eb55 h1:YBpAp7uPf/lzGxKPOGh1D05bX7uDVybA39BYoPXpRu4=
github.com/stellar/go v0.0.0-20240207003209-73de95c8eb55/go.mod h1:Ka4piwZT4Q9799f+BZeaKkAiYo4UpIWXyu0oSUbCVfM=
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=
Expand Down

0 comments on commit 258cef7

Please sign in to comment.