Skip to content

Commit

Permalink
Merge branch 'feat/tx-log-seq' into feat/maindb-v4-candidate-pre-logdb
Browse files Browse the repository at this point in the history
  • Loading branch information
darrenvechain committed Nov 8, 2024
2 parents ca14f79 + a2a74f8 commit 08def69
Show file tree
Hide file tree
Showing 12 changed files with 167 additions and 254 deletions.
66 changes: 9 additions & 57 deletions api/doc/thor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1009,8 +1009,6 @@ components:
enum:
- asc
- desc
optionalData:
$ref: '#/components/schemas/EventOptionalData'

EventLogsResponse:
type: array
Expand All @@ -1022,7 +1020,7 @@ components:
- $ref: '#/components/schemas/Event'
- properties:
meta:
$ref: '#/components/schemas/EventLogMeta'
$ref: '#/components/schemas/LogMeta'

TransferLogFilterRequest:
type: object
Expand Down Expand Up @@ -1327,65 +1325,13 @@ components:
description: The index of the clause in the transaction, from which the log was generated.
example: 0
nullable: false

EventLogMeta:
title: EventLogMeta
type: object
description: The event or transfer log metadata such as block number, block timestamp, etc.
properties:
blockID:
type: string
format: hex
description: The block identifier in which the log was included.
example: '0x0004f6cc88bb4626a92907718e82f255b8fa511453a78e8797eb8cea3393b215'
nullable: false
pattern: '^0x[0-9a-f]{64}$'
blockNumber:
type: integer
format: uint32
description: The block number (height) of the block in which the log was included.
example: 325324
nullable: false
blockTimestamp:
type: integer
format: uint64
description: The UNIX timestamp of the block in which the log was included.
example: 1533267900
nullable: false
txID:
type: string
format: hex
description: The transaction identifier, from which the log was generated.
example: '0x284bba50ef777889ff1a367ed0b38d5e5626714477c40de38d71cedd6f9fa477'
nullable: false
pattern: '^0x[0-9a-f]{64}$'
txOrigin:
type: string
description: The account from which the transaction was sent.
example: '0xdb4027477b2a8fe4c83c6dafe7f86678bb1b8a8d'
nullable: false
pattern: '^0x[0-9a-f]{40}$'
clauseIndex:
type: integer
format: uint32
description: The index of the clause in the transaction, from which the log was generated.
example: 0
nullable: false
extendedLogMeta:
$ref: '#/components/schemas/ExtendedLogMeta'

ExtendedLogMeta:
title: ExtendedLogMeta
type: object
nullable: true
properties:
txIndex:
description: The index of the transaction in the block, from which the log was generated.
type: integer
nullable: true
example: 1
logIndex:
descrption: The index of the log in the receipt's outputs.
description: The index of the log in the receipt's outputs. This is an overall index among all clauses.
type: integer
nullable: true
example: 1
Expand Down Expand Up @@ -1919,6 +1865,11 @@ components:
The limit of records to be included in the output. Use this parameter for pagination.
Default's to all results.
includeIndexes:
type: boolean
example: true
nullable: true
description: Include both transaction and log index in the response.
description: |
Include these parameters to receive filtered results in a paged format.
Expand All @@ -1929,7 +1880,8 @@ components:
{
"options": {
"offset": 0,
"limit": 10
"limit": 10,
"includeIndexes": true
}
}
```
Expand Down
9 changes: 5 additions & 4 deletions api/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (e *Events) filter(ctx context.Context, ef *EventFilter) ([]*FilteredEvent,
}
fes := make([]*FilteredEvent, len(events))
for i, e := range events {
fes[i] = convertEvent(e, ef.OptionalData)
fes[i] = convertEvent(e, ef.Options.IncludeIndexes)
}
return fes, nil
}
Expand All @@ -60,9 +60,10 @@ func (e *Events) handleFilter(w http.ResponseWriter, req *http.Request) error {
if filter.Options == nil {
// if filter.Options is nil, set to the default limit +1
// to detect whether there are more logs than the default limit
filter.Options = &logdb.Options{
Offset: 0,
Limit: e.limit + 1,
filter.Options = &Options{
Offset: 0,
Limit: e.limit + 1,
IncludeIndexes: false,
}
}

Expand Down
67 changes: 22 additions & 45 deletions api/events/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,64 +56,40 @@ func TestEvents(t *testing.T) {
testEventWithBlocks(t, blocksToInsert)
}

func TestOptionalData(t *testing.T) {
db := createDb(t)
initEventServer(t, db, defaultLogLimit)
func TestOptionalIndexes(t *testing.T) {
thorChain := initEventServer(t, defaultLogLimit)
defer ts.Close()
insertBlocks(t, db, 5)
insertBlocks(t, thorChain.LogDB(), 5)
tclient = thorclient.New(ts.URL)

testCases := []struct {
name string
optData *events.EventOptionalData
expected *events.ExtendedLogMeta
name string
includeIndexes bool
expected *uint32
}{
{
name: "empty optional data",
optData: &events.EventOptionalData{},
expected: nil,
},
{
name: "optional data with txIndex",
optData: &events.EventOptionalData{
TxIndex: true,
},
expected: &events.ExtendedLogMeta{
TxIndex: new(uint32),
},
name: "do not include indexes",
includeIndexes: false,
expected: nil,
},
{
name: "optional data with logIndex",
optData: &events.EventOptionalData{
LogIndex: true,
},
expected: &events.ExtendedLogMeta{
LogIndex: new(uint32),
},
},
{
name: "optional data with txIndex and logIndex",
optData: &events.EventOptionalData{
TxIndex: true,
LogIndex: true,
},
expected: &events.ExtendedLogMeta{
TxIndex: new(uint32),
LogIndex: new(uint32),
},
name: "include indexes",
includeIndexes: true,
expected: new(uint32),
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
filter := events.EventFilter{
CriteriaSet: make([]*events.EventCriteria, 0),
Range: nil,
Options: &logdb.Options{Limit: 6},
Order: logdb.DESC,
OptionalData: tc.optData,
CriteriaSet: make([]*events.EventCriteria, 0),
Range: nil,
Options: &events.Options{Limit: 6, IncludeIndexes: tc.includeIndexes},
Order: logdb.DESC,
}

res, statusCode := httpPost(t, ts.URL+"/events", filter)
res, statusCode, err := tclient.RawHTTPClient().RawHTTPPost("/logs/event", filter)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, statusCode)
var tLogs []*events.FilteredEvent
if err := json.Unmarshal(res, &tLogs); err != nil {
Expand All @@ -123,7 +99,8 @@ func TestOptionalData(t *testing.T) {
assert.Equal(t, 5, len(tLogs))

for _, tLog := range tLogs {
assert.Equal(t, tc.expected, tLog.Meta.ExtendedLogMeta)
assert.Equal(t, tc.expected, tLog.Meta.TxIndex)
assert.Equal(t, tc.expected, tLog.Meta.LogIndex)
}
})
}
Expand All @@ -138,7 +115,7 @@ func TestOption(t *testing.T) {
filter := events.EventFilter{
CriteriaSet: make([]*events.EventCriteria, 0),
Range: nil,
Options: &logdb.Options{Limit: 6},
Options: &events.Options{Limit: 6},
Order: logdb.DESC,
}

Expand Down
116 changes: 29 additions & 87 deletions api/events/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
package events

import (
"fmt"
"math"

"github.com/ethereum/go-ethereum/common/hexutil"
Expand All @@ -17,33 +16,14 @@ import (
)

type LogMeta struct {
BlockID thor.Bytes32 `json:"blockID"`
BlockNumber uint32 `json:"blockNumber"`
BlockTimestamp uint64 `json:"blockTimestamp"`
TxID thor.Bytes32 `json:"txID"`
TxOrigin thor.Address `json:"txOrigin"`
ClauseIndex uint32 `json:"clauseIndex"`
ExtendedLogMeta *ExtendedLogMeta `json:"extendedLogMeta,omitempty"`
}

type ExtendedLogMeta struct {
TxIndex *uint32 `json:"txIndex,omitempty"`
LogIndex *uint32 `json:"logIndex,omitempty"`
}

func (opt *ExtendedLogMeta) Empty() bool {
return opt == nil || (opt.TxIndex == nil && opt.LogIndex == nil)
}

func (opt *ExtendedLogMeta) String() string {
var parts []string
if opt.TxIndex != nil {
parts = append(parts, fmt.Sprintf("txIndex: %v", *opt.TxIndex))
}
if opt.LogIndex != nil {
parts = append(parts, fmt.Sprintf("logIndex: %v", *opt.LogIndex))
}
return fmt.Sprintf("%v", parts)
BlockID thor.Bytes32 `json:"blockID"`
BlockNumber uint32 `json:"blockNumber"`
BlockTimestamp uint64 `json:"blockTimestamp"`
TxID thor.Bytes32 `json:"txID"`
TxOrigin thor.Address `json:"txOrigin"`
ClauseIndex uint32 `json:"clauseIndex"`
TxIndex *uint32 `json:"txIndex,omitempty"`
LogIndex *uint32 `json:"logIndex,omitempty"`
}

type TopicSet struct {
Expand All @@ -63,7 +43,7 @@ type FilteredEvent struct {
}

// convert a logdb.Event into a json format Event
func convertEvent(event *logdb.Event, eventOptionalData *EventOptionalData) *FilteredEvent {
func convertEvent(event *logdb.Event, addIndexes bool) *FilteredEvent {
fe := &FilteredEvent{
Address: event.Address,
Data: hexutil.Encode(event.Data),
Expand All @@ -76,7 +56,11 @@ func convertEvent(event *logdb.Event, eventOptionalData *EventOptionalData) *Fil
ClauseIndex: event.ClauseIndex,
},
}
fe = addOptionalData(fe, event, eventOptionalData)

if addIndexes {
fe.Meta.TxIndex = &event.TxIndex
fe.Meta.LogIndex = &event.LogIndex
}

fe.Topics = make([]*thor.Bytes32, 0)
for i := 0; i < 5; i++ {
Expand All @@ -87,67 +71,22 @@ func convertEvent(event *logdb.Event, eventOptionalData *EventOptionalData) *Fil
return fe
}

func addOptionalData(fe *FilteredEvent, event *logdb.Event, eventOptionalData *EventOptionalData) *FilteredEvent {
if eventOptionalData != nil {
opt := &ExtendedLogMeta{}

if eventOptionalData.LogIndex {
opt.LogIndex = &event.Index
}
if eventOptionalData.TxIndex {
opt.TxIndex = &event.TxIndex
}

if !opt.Empty() {
fe.Meta.ExtendedLogMeta = opt
}
}
return fe
}

func (e *FilteredEvent) String() string {
return fmt.Sprintf(`
Event(
address: %v,
topics: %v,
data: %v,
meta: (blockID %v,
blockNumber %v,
blockTimestamp %v),
txID %v,
txOrigin %v,
clauseIndex %v,
optionalData (%v))
)`,
e.Address,
e.Topics,
e.Data,
e.Meta.BlockID,
e.Meta.BlockNumber,
e.Meta.BlockTimestamp,
e.Meta.TxID,
e.Meta.TxOrigin,
e.Meta.ClauseIndex,
e.Meta.ExtendedLogMeta,
)
}

type EventCriteria struct {
Address *thor.Address `json:"address"`
TopicSet
}

type EventFilter struct {
CriteriaSet []*EventCriteria `json:"criteriaSet"`
Range *Range `json:"range"`
Options *logdb.Options `json:"options"`
Order logdb.Order `json:"order"`
OptionalData *EventOptionalData `json:"optionalData,omitempty"`
type Options struct {
Offset uint64
Limit uint64
IncludeIndexes bool
}

type EventOptionalData struct {
LogIndex bool `json:"logIndex,omitempty"`
TxIndex bool `json:"txIndex,omitempty"`
type EventFilter struct {
CriteriaSet []*EventCriteria
Range *Range
Options *Options
Order logdb.Order // default asc
}

func convertEventFilter(chain *chain.Chain, filter *EventFilter) (*logdb.EventFilter, error) {
Expand All @@ -156,9 +95,12 @@ func convertEventFilter(chain *chain.Chain, filter *EventFilter) (*logdb.EventFi
return nil, err
}
f := &logdb.EventFilter{
Range: rng,
Options: filter.Options,
Order: filter.Order,
Range: rng,
Options: &logdb.Options{
Offset: filter.Options.Offset,
Limit: filter.Options.Limit,
},
Order: filter.Order,
}
if len(filter.CriteriaSet) > 0 {
f.CriteriaSet = make([]*logdb.EventCriteria, len(filter.CriteriaSet))
Expand Down
Loading

0 comments on commit 08def69

Please sign in to comment.