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

Add LogIndex and TxIndex into logs/event response body #862

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 37 additions & 1 deletion api/doc/thor.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1325,6 +1325,16 @@ components:
description: The index of the clause in the transaction, from which the log was generated.
example: 0
nullable: false
txIndex:
paologalligit marked this conversation as resolved.
Show resolved Hide resolved
description: The index of the transaction in the block, from which the log was generated.
type: integer
nullable: true
example: 1
logIndex:
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

Block:
title: Block
Expand Down Expand Up @@ -1855,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 @@ -1865,7 +1880,8 @@ components:
{
"options": {
"offset": 0,
"limit": 10
"limit": 10,
"includeIndexes": true
}
}
```
Expand Down Expand Up @@ -1916,6 +1932,26 @@ components:
}
```
This refers to the range from block 10 to block 1000.

EventOptionalData:
nullable: true
type: object
title: EventOptionalData
properties:
txIndex:
type: boolean
example: true
nullable: true
description: |
Specifies whether to include in the response the event transaction index.
loglIndex:
type: boolean
example: true
nullable: true
description: |
Specifies whether to include in the response the event log index.
description: |
Specifies all the optional data that can be included in the response.

EventCriteria:
type: object
Expand Down
2 changes: 1 addition & 1 deletion 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)
fes[i] = convertEvent(e, filter.Options.IncludeIndexes)
}
return fes, nil
}
Expand Down
50 changes: 50 additions & 0 deletions api/events/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,56 @@ func TestEvents(t *testing.T) {
testEventWithBlocks(t, blocksToInsert)
}

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

testCases := []struct {
name string
includeIndexes bool
expected *uint32
}{
{
name: "do not include indexes",
includeIndexes: false,
expected: nil,
},
{
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, IncludeIndexes: tc.includeIndexes},
Order: logdb.DESC,
}

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 {
t.Fatal(err)
}
assert.Equal(t, http.StatusOK, statusCode)
assert.Equal(t, 5, len(tLogs))

for _, tLog := range tLogs {
assert.Equal(t, tc.expected, tLog.Meta.TxIndex)
assert.Equal(t, tc.expected, tLog.Meta.LogIndex)
}
})
}
}

func TestOption(t *testing.T) {
thorChain := initEventServer(t, 5)
defer ts.Close()
Expand Down
20 changes: 16 additions & 4 deletions api/events/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ type LogMeta struct {
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 @@ -42,8 +44,8 @@ type FilteredEvent struct {
}

// convert a logdb.Event into a json format Event
func convertEvent(event *logdb.Event) *FilteredEvent {
fe := FilteredEvent{
func convertEvent(event *logdb.Event, addIndexes bool) *FilteredEvent {
fe := &FilteredEvent{
Address: event.Address,
Data: hexutil.Encode(event.Data),
Meta: LogMeta{
Expand All @@ -55,13 +57,19 @@ func convertEvent(event *logdb.Event) *FilteredEvent {
ClauseIndex: event.ClauseIndex,
},
}

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

fe.Topics = make([]*thor.Bytes32, 0)
for i := 0; i < 5; i++ {
if event.Topics[i] != nil {
fe.Topics = append(fe.Topics, event.Topics[i])
}
}
return &fe
return fe
}

func (e *FilteredEvent) String() string {
Expand All @@ -75,7 +83,9 @@ func (e *FilteredEvent) String() string {
blockTimestamp %v),
txID %v,
txOrigin %v,
clauseIndex %v)
clauseIndex %v,
txIndex: %v,
logIndex: %v)
)`,
e.Address,
e.Topics,
Expand All @@ -86,6 +96,8 @@ func (e *FilteredEvent) String() string {
e.Meta.TxID,
e.Meta.TxOrigin,
e.Meta.ClauseIndex,
e.Meta.TxIndex,
e.Meta.LogIndex,
)
}

Expand Down
71 changes: 57 additions & 14 deletions api/events/types_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@
// Distributed under the GNU Lesser General Public License v3.0 software license, see the accompanying
// file LICENSE or <https://www.gnu.org/licenses/lgpl-3.0.html>

package events_test
package events

import (
"math"
"testing"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/stretchr/testify/assert"
"github.com/vechain/thor/v2/api/events"
"github.com/vechain/thor/v2/chain"
"github.com/vechain/thor/v2/genesis"
"github.com/vechain/thor/v2/logdb"
"github.com/vechain/thor/v2/muxdb"
"github.com/vechain/thor/v2/state"
"github.com/vechain/thor/v2/thor"
)

func TestEventsTypes(t *testing.T) {
Expand All @@ -33,22 +34,22 @@ func TestEventsTypes(t *testing.T) {
}

func testConvertRangeWithBlockRangeType(t *testing.T, chain *chain.Chain) {
rng := &events.Range{
Unit: events.BlockRangeType,
rng := &Range{
Unit: BlockRangeType,
From: 1,
To: 2,
}

convertedRng, err := events.ConvertRange(chain, rng)
convertedRng, err := ConvertRange(chain, rng)

assert.NoError(t, err)
assert.Equal(t, uint32(rng.From), convertedRng.From)
assert.Equal(t, uint32(rng.To), convertedRng.To)
}

func testConvertRangeWithTimeRangeTypeLessThenGenesis(t *testing.T, chain *chain.Chain) {
rng := &events.Range{
Unit: events.TimeRangeType,
rng := &Range{
Unit: TimeRangeType,
From: 1,
To: 2,
}
Expand All @@ -57,7 +58,7 @@ func testConvertRangeWithTimeRangeTypeLessThenGenesis(t *testing.T, chain *chain
To: math.MaxUint32,
}

convRng, err := events.ConvertRange(chain, rng)
convRng, err := ConvertRange(chain, rng)

assert.NoError(t, err)
assert.Equal(t, expectedEmptyRange, convRng)
Expand All @@ -68,8 +69,8 @@ func testConvertRangeWithTimeRangeType(t *testing.T, chain *chain.Chain) {
if err != nil {
t.Fatal(err)
}
rng := &events.Range{
Unit: events.TimeRangeType,
rng := &Range{
Unit: TimeRangeType,
From: 1,
To: genesis.Timestamp(),
}
Expand All @@ -78,7 +79,7 @@ func testConvertRangeWithTimeRangeType(t *testing.T, chain *chain.Chain) {
To: 0,
}

convRng, err := events.ConvertRange(chain, rng)
convRng, err := ConvertRange(chain, rng)

assert.NoError(t, err)
assert.Equal(t, expectedZeroRange, convRng)
Expand All @@ -89,8 +90,8 @@ func testConvertRangeWithFromGreaterThanGenesis(t *testing.T, chain *chain.Chain
if err != nil {
t.Fatal(err)
}
rng := &events.Range{
Unit: events.TimeRangeType,
rng := &Range{
Unit: TimeRangeType,
From: genesis.Timestamp() + 1_000,
To: genesis.Timestamp() + 10_000,
}
Expand All @@ -99,7 +100,7 @@ func testConvertRangeWithFromGreaterThanGenesis(t *testing.T, chain *chain.Chain
To: math.MaxUint32,
}

convRng, err := events.ConvertRange(chain, rng)
convRng, err := ConvertRange(chain, rng)

assert.NoError(t, err)
assert.Equal(t, expectedEmptyRange, convRng)
Expand All @@ -123,3 +124,45 @@ func initChain(t *testing.T) *chain.Chain {

return repo.NewBestChain()
}

func TestConvertEvent(t *testing.T) {
event := &logdb.Event{
Address: thor.Address{0x01},
Data: []byte{0x02, 0x03},
BlockID: thor.Bytes32{0x04},
BlockNumber: 5,
BlockTime: 6,
TxID: thor.Bytes32{0x07},
TxIndex: 8,
Index: 9,
TxOrigin: thor.Address{0x0A},
ClauseIndex: 10,
Topics: [5]*thor.Bytes32{
{0x0B},
{0x0C},
nil,
nil,
nil,
},
}

expectedTopics := []*thor.Bytes32{
{0x0B},
{0x0C},
}
expectedData := hexutil.Encode(event.Data)

result := convertEvent(event, true)

assert.Equal(t, event.Address, result.Address)
assert.Equal(t, expectedData, result.Data)
assert.Equal(t, event.BlockID, result.Meta.BlockID)
assert.Equal(t, event.BlockNumber, result.Meta.BlockNumber)
assert.Equal(t, event.BlockTime, result.Meta.BlockTimestamp)
assert.Equal(t, event.TxID, result.Meta.TxID)
assert.Equal(t, event.TxIndex, *result.Meta.TxIndex)
assert.Equal(t, event.Index, *result.Meta.LogIndex)
assert.Equal(t, event.TxOrigin, result.Meta.TxOrigin)
assert.Equal(t, event.ClauseIndex, result.Meta.ClauseIndex)
assert.Equal(t, expectedTopics, result.Topics)
}
2 changes: 1 addition & 1 deletion api/transfers/transfers.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func (t *Transfers) filter(ctx context.Context, filter *TransferFilter) ([]*Filt
}
tLogs := make([]*FilteredTransfer, len(transfers))
for i, trans := range transfers {
tLogs[i] = convertTransfer(trans)
tLogs[i] = convertTransfer(trans, filter.Options.IncludeIndexes)
}
return tLogs, nil
}
Expand Down
Loading
Loading