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

Incorporate generics into Light Horizon code #4537

Merged
merged 4 commits into from
Aug 12, 2022
Merged
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
29 changes: 13 additions & 16 deletions exp/lighthorizon/archive/ingest_archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/stellar/go/ingest"
"github.com/stellar/go/ingest/ledgerbackend"
"github.com/stellar/go/metaarchive"
"github.com/stellar/go/support/collections/set"
"github.com/stellar/go/support/errors"
"github.com/stellar/go/support/log"
"github.com/stellar/go/support/storage"
Expand Down Expand Up @@ -95,30 +96,26 @@ func (a ingestArchive) NewLedgerTransactionReaderFromLedgerCloseMeta(networkPass
return &ingestTransactionReaderAdaption{ingestReader}, nil
}

func (a ingestArchive) GetTransactionParticipants(transaction LedgerTransaction) (map[string]struct{}, error) {
participants, err := index.GetTransactionParticipants(a.ingestTx(transaction))
func (a ingestArchive) GetTransactionParticipants(tx LedgerTransaction) (set.Set[string], error) {
participants, err := index.GetTransactionParticipants(a.ingestTx(tx))
if err != nil {
return nil, err
}
set := make(map[string]struct{})
exists := struct{}{}
for _, participant := range participants {
set[participant] = exists
}
return set, nil

s := set.NewSet[string](len(participants))
s.AddSlice(participants)
return s, nil
}

func (a ingestArchive) GetOperationParticipants(transaction LedgerTransaction, operation xdr.Operation, opIndex int) (map[string]struct{}, error) {
participants, err := index.GetOperationParticipants(a.ingestTx(transaction), operation, opIndex)
func (a ingestArchive) GetOperationParticipants(tx LedgerTransaction, op xdr.Operation, opIndex int) (set.Set[string], error) {
participants, err := index.GetOperationParticipants(a.ingestTx(tx), op, opIndex)
if err != nil {
return nil, err
}
set := make(map[string]struct{})
exists := struct{}{}
for _, participant := range participants {
set[participant] = exists
}
return set, nil

s := set.NewSet[string](len(participants))
s.AddSlice(participants)
return s, nil
}

func (ingestArchive) ingestTx(transaction LedgerTransaction) ingest.LedgerTransaction {
Expand Down
5 changes: 3 additions & 2 deletions exp/lighthorizon/archive/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package archive
import (
"context"

"github.com/stellar/go/support/collections/set"
"github.com/stellar/go/xdr"
)

Expand Down Expand Up @@ -49,10 +50,10 @@ type Archive interface {

// GetTransactionParticipants - takes a LedgerTransaction and returns a set of all
// participants(accounts) in the transaction. If there is any error, it will return nil and the error.
GetTransactionParticipants(transaction LedgerTransaction) (map[string]struct{}, error)
GetTransactionParticipants(tx LedgerTransaction) (set.Set[string], error)

// GetOperationParticipants - takes a LedgerTransaction, the Operation within the transaction, and
// the 0 based index of the operation within the transaction. It will return a set of all participants(accounts)
// in the operation. If there is any error, it will return nil and the error.
GetOperationParticipants(transaction LedgerTransaction, operation xdr.Operation, opIndex int) (map[string]struct{}, error)
GetOperationParticipants(tx LedgerTransaction, op xdr.Operation, opIndex int) (set.Set[string], error)
}
13 changes: 7 additions & 6 deletions exp/lighthorizon/archive/mock_archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package archive
import (
"context"

"github.com/stellar/go/support/collections/set"
"github.com/stellar/go/xdr"
"github.com/stretchr/testify/mock"
)
Expand Down Expand Up @@ -35,12 +36,12 @@ func (m *MockArchive) NewLedgerTransactionReaderFromLedgerCloseMeta(networkPassp
return args.Get(0).(LedgerTransactionReader), args.Error(1)
}

func (m *MockArchive) GetTransactionParticipants(transaction LedgerTransaction) (map[string]struct{}, error) {
args := m.Called(transaction)
return args.Get(0).(map[string]struct{}), args.Error(1)
func (m *MockArchive) GetTransactionParticipants(tx LedgerTransaction) (set.Set[string], error) {
args := m.Called(tx)
return args.Get(0).(set.Set[string]), args.Error(1)
}

func (m *MockArchive) GetOperationParticipants(transaction LedgerTransaction, operation xdr.Operation, opIndex int) (map[string]struct{}, error) {
args := m.Called(transaction, operation, opIndex)
return args.Get(0).(map[string]struct{}), args.Error(1)
func (m *MockArchive) GetOperationParticipants(tx LedgerTransaction, op xdr.Operation, opIndex int) (set.Set[string], error) {
args := m.Called(tx, op, opIndex)
return args.Get(0).(set.Set[string]), args.Error(1)
}
7 changes: 4 additions & 3 deletions exp/lighthorizon/index/backend/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

types "github.com/stellar/go/exp/lighthorizon/index/types"

"github.com/stellar/go/support/collections/set"
"github.com/stellar/go/support/errors"
"github.com/stellar/go/support/log"
)
Expand Down Expand Up @@ -157,7 +158,7 @@ func (s *FileBackend) ReadAccounts() ([]string, error) {
// Note that this will never be too large, but may be too small.
preallocationSize = int(info.Size()) / (gAddressSize + 1) // +1 for \n
}
accountMap := make(map[string]struct{}, preallocationSize)
accountMap := set.NewSet[string](preallocationSize)
accounts := make([]string, 0, preallocationSize)

reader := bufio.NewReaderSize(f, 100*gAddressSize) // reasonable buffer size
Expand All @@ -173,8 +174,8 @@ func (s *FileBackend) ReadAccounts() ([]string, error) {

// The account list is very unlikely to be unique (especially if it was made
// w/ parallel flushes), so let's ensure that that's the case.
if _, ok := accountMap[account]; !ok {
accountMap[account] = struct{}{}
if !accountMap.Contains(account) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice, fluent.

accountMap.Add(account)
accounts = append(accounts, account)
}
}
Expand Down
35 changes: 9 additions & 26 deletions exp/lighthorizon/index/cmd/mapreduce_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import (
"github.com/stellar/go/exp/lighthorizon/index"
"github.com/stellar/go/historyarchive"
"github.com/stellar/go/network"
"github.com/stellar/go/support/collections/maps"
"github.com/stellar/go/support/collections/set"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -53,7 +55,7 @@ func TestReduce(t *testing.T) {
require.NoError(t, err)
stores := []index.Store{indexStore} // to reuse code: same as array of 1 store

assertParticipantsEqual(t, keysU32(participants), stores)
assertParticipantsEqual(t, maps.Keys(participants), stores)
for account, checkpoints := range participants {
assertParticipantCheckpointsEqual(t, account, checkpoints, stores)
}
Expand Down Expand Up @@ -138,7 +140,7 @@ func RunMapTest(t *testing.T) (uint32, uint32, string) {
t.Logf("Connected to index #%d at %s", i+1, indexUrl)
}

assertParticipantsEqual(t, keysU32(participants), stores)
assertParticipantsEqual(t, maps.Keys(participants), stores)
for account, checkpoints := range participants {
assertParticipantCheckpointsEqual(t, account, checkpoints, stores)
}
Expand All @@ -152,20 +154,17 @@ func assertParticipantsEqual(t *testing.T,
expectedAccountSet []string,
indexGroup []index.Store,
) {
indexGroupAccountSet := make(map[string]struct{}, len(expectedAccountSet))
indexGroupAccountSet := set.NewSet[string](len(expectedAccountSet))
for _, store := range indexGroup {
accounts, err := store.ReadAccounts()
require.NoError(t, err)

for _, account := range accounts {
indexGroupAccountSet[account] = struct{}{}
}
indexGroupAccountSet.AddSlice(accounts)
}

assert.Lenf(t, indexGroupAccountSet, len(expectedAccountSet),
"quantity of accounts across indices doesn't match")

mappedAccountSet := keysSet(indexGroupAccountSet)
mappedAccountSet := maps.Keys(indexGroupAccountSet)
require.ElementsMatch(t, expectedAccountSet, mappedAccountSet)
}

Expand All @@ -177,7 +176,7 @@ func assertParticipantCheckpointsEqual(t *testing.T,
// Ensure that all of the active checkpoints reported by the index match
// the ones we tracked while ingesting the range ourselves.

foundCheckpoints := make(map[uint32]struct{}, len(expected))
foundCheckpoints := set.NewSet[uint32](len(expected))
for _, store := range indexGroup {
var err error
var lastActiveCheckpoint uint32 = 0
Expand All @@ -188,7 +187,7 @@ func assertParticipantCheckpointsEqual(t *testing.T,
}
require.NoError(t, err) // still an error since it shouldn't happen

foundCheckpoints[lastActiveCheckpoint] = struct{}{}
foundCheckpoints.Add(lastActiveCheckpoint)
lastActiveCheckpoint += 1 // hit next active one
}
}
Expand Down Expand Up @@ -231,19 +230,3 @@ func assertTOIDsEqual(t *testing.T, toids map[string]int64, stores []index.Store
require.Truef(t, found, "TOID for tx 0x%s not found in stores", hash)
}
}

func keysU32(dict map[string][]uint32) []string {
result := make([]string, 0, len(dict))
for key := range dict {
result = append(result, key)
}
return result
}

func keysSet(dict map[string]struct{}) []string {
result := make([]string, 0, len(dict))
for key := range dict {
result = append(result, key)
}
return result
}
11 changes: 6 additions & 5 deletions exp/lighthorizon/services/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (

"github.com/stellar/go/exp/lighthorizon/archive"
"github.com/stellar/go/exp/lighthorizon/index"
"github.com/stellar/go/support/collections/set"
"github.com/stellar/go/toid"
"github.com/stellar/go/xdr"
"github.com/stretchr/testify/mock"
Expand Down Expand Up @@ -128,12 +129,12 @@ func mockArchiveAndIndex(ctx context.Context, passphrase string) (archive.Archiv
On("NewLedgerTransactionReaderFromLedgerCloseMeta", passphrase, expectedLedger3).Return(mockReaderLedger3, nil).
On("NewLedgerTransactionReaderFromLedgerCloseMeta", passphrase, mock.Anything).Return(mockReaderLedgerTheRest, nil)

partialParticipants := make(map[string]struct{})
partialParticipants[source.Address()] = struct{}{}
partialParticipants := set.Set[string]{}
partialParticipants.Add(source.Address())

allParticipants := make(map[string]struct{})
allParticipants[source.Address()] = struct{}{}
allParticipants[source2.Address()] = struct{}{}
allParticipants := set.Set[string]{}
allParticipants.Add(source.Address())
allParticipants.Add(source2.Address())

mockArchive.
On("GetTransactionParticipants", expectedLedger1Tx1).Return(partialParticipants, nil).
Expand Down
17 changes: 17 additions & 0 deletions support/collections/maps/map.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package maps

func Keys[T comparable, U any](m map[T]U) []T {
keys := make([]T, 0, len(m))
for key := range m {
keys = append(keys, key)
}
return keys
}

func Values[T comparable, U any](m map[T]U) []U {
values := make([]U, 0, len(m))
for _, value := range m {
values = append(values, value)
}
return values
}
26 changes: 26 additions & 0 deletions support/collections/maps/map_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package maps

import (
"testing"

"github.com/stellar/go/support/collections/set"
"github.com/stretchr/testify/require"
)

func TestSanity(t *testing.T) {
m := map[int]float32{1: 10, 2: 20, 3: 30}
for k, v := range m {
require.Contains(t, Keys(m), k)
require.Contains(t, Values(m), v)
}

// compatibility with collections/set.Set
s := set.Set[float32]{}
s.Add(1)
s.Add(2)
s.Add(3)

for item := range s {
require.Contains(t, Keys(s), item)
}
}
6 changes: 6 additions & 0 deletions support/collections/set/set.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ func (set Set[T]) Add(item T) {
set[item] = struct{}{}
}

func (set Set[T]) AddSlice(items []T) {
for _, item := range items {
set[item] = struct{}{}
}
}

func (set Set[T]) Remove(item T) {
delete(set, item)
}
Expand Down