services/scribe/backend/backend_test.go
package backend_test
import (
"github.com/synapsecns/sanguine/services/scribe/backend"
"github.com/synapsecns/sanguine/services/scribe/testutil"
"math/big"
"sync"
"testing"
. "github.com/stretchr/testify/assert"
"github.com/synapsecns/sanguine/ethergo/backends/geth"
"github.com/synapsecns/sanguine/ethergo/util"
"k8s.io/apimachinery/pkg/util/sets"
)
func (b *BackendSuite) TestLogsInRange() {
const desiredBlockHeight = 10
var testChainHandler *testutil.TestChainHandler
var err error
var wg sync.WaitGroup
wg.Add(2)
testBackend := geth.NewEmbeddedBackend(b.GetTestContext(), b.T())
go func() {
defer wg.Done()
testChainHandler, err = testutil.PopulateWithLogs(b.GetTestContext(), b.T(), testBackend, desiredBlockHeight, []*testutil.DeployManager{b.manager})
Nil(b.T(), err)
}()
var host string
go func() {
defer wg.Done()
host = testutil.StartOmnirpcServer(b.GetTestContext(), b.T(), testBackend)
}()
wg.Wait()
scribeBackend, err := backend.DialBackend(b.GetTestContext(), host, b.metrics)
Nil(b.T(), err)
chainID, err := scribeBackend.ChainID(b.GetTestContext())
Nil(b.T(), err)
lastBlock, err := testBackend.BlockNumber(b.GetTestContext())
Nil(b.T(), err)
iterator := util.NewChunkIterator(big.NewInt(int64(1)), big.NewInt(int64(lastBlock)), 1, true)
var blockRanges []*util.Chunk
blockRange := iterator.NextChunk()
for blockRange != nil {
blockRanges = append(blockRanges, blockRange)
blockRange = iterator.NextChunk()
}
res, err := backend.GetLogsInRange(b.GetTestContext(), scribeBackend, testChainHandler.Addresses, chainID.Uint64(), blockRanges, nil)
Nil(b.T(), err)
// use to make sure we don't double use values
intSet := sets.NewInt64()
itr := res.Iterator()
numLogs := 0
for !itr.Done() {
index, chunk := itr.Next()
Falsef(b.T(), intSet.Has(int64(index)), "%d appears at least twice", index)
intSet.Insert(int64(index))
NotNil(b.T(), chunk)
for range *chunk {
numLogs++
}
}
Equal(b.T(), int(testChainHandler.EventsEmitted[testChainHandler.Addresses[0]]), numLogs)
}
func (b *BackendSuite) TestLogsInRangeWithMultipleContracts() {
const desiredBlockHeight = 10
var testChainHandler *testutil.TestChainHandler
var err error
var wg sync.WaitGroup
wg.Add(2)
testBackend := geth.NewEmbeddedBackend(b.GetTestContext(), b.T())
managerB := testutil.NewDeployManager(b.T())
managerC := testutil.NewDeployManager(b.T())
managers := []*testutil.DeployManager{b.manager, managerB, managerC}
go func() {
defer wg.Done()
testChainHandler, err = testutil.PopulateWithLogs(b.GetTestContext(), b.T(), testBackend, desiredBlockHeight, managers)
Nil(b.T(), err)
}()
var host string
go func() {
defer wg.Done()
host = testutil.StartOmnirpcServer(b.GetTestContext(), b.T(), testBackend)
}()
wg.Wait()
scribeBackend, err := backend.DialBackend(b.GetTestContext(), host, b.metrics)
Nil(b.T(), err)
chainID, err := scribeBackend.ChainID(b.GetTestContext())
Nil(b.T(), err)
iterator := util.NewChunkIterator(big.NewInt(int64(1)), big.NewInt(int64(desiredBlockHeight)), 1, true)
var blockRanges []*util.Chunk
blockRange := iterator.NextChunk()
for blockRange != nil {
blockRanges = append(blockRanges, blockRange)
blockRange = iterator.NextChunk()
}
res, err := backend.GetLogsInRange(b.GetTestContext(), scribeBackend, testChainHandler.Addresses, chainID.Uint64(), blockRanges, nil)
Nil(b.T(), err)
// use to make sure we don't double use values
intSet := sets.NewInt64()
itr := res.Iterator()
numLogs := 0
logs := make(map[string]int)
for !itr.Done() {
index, chunk := itr.Next()
Falsef(b.T(), intSet.Has(int64(index)), "%d appears at least twice", index)
intSet.Insert(int64(index))
NotNil(b.T(), chunk)
for i := range *chunk {
logAddr := (*chunk)[i].Address.String()
logs[logAddr]++
numLogs++
}
}
Equal(b.T(), len(managers), numLogs)
// Check if there's a log for each of the contracts
for i := range testChainHandler.Addresses {
Equal(b.T(), int(testChainHandler.EventsEmitted[testChainHandler.Addresses[i]]), logs[testChainHandler.Addresses[i].String()])
}
}
func TestMakeRange(t *testing.T) {
testIntRange := backend.MakeRange(0, 4)
Equal(t, []int{0, 1, 2, 3, 4}, testIntRange)
testUintRange := backend.MakeRange(uint16(10), uint16(12))
Equal(t, testUintRange, []uint16{10, 11, 12})
}
func (b *BackendSuite) TestBlockHashesInRange() {
testBackend := geth.NewEmbeddedBackend(b.GetTestContext(), b.T())
// start an omnirpc proxy and run 10 test tranactions so we can batch call blocks
// 1-10
var wg sync.WaitGroup
wg.Add(2)
const desiredBlockHeight = 10
go func() {
defer wg.Done()
err := testutil.ReachBlockHeight(b.GetTestContext(), b.T(), testBackend, desiredBlockHeight)
Nil(b.T(), err)
}()
var host string
go func() {
defer wg.Done()
host = testutil.StartOmnirpcServer(b.GetTestContext(), b.T(), testBackend)
}()
wg.Wait()
scribeBackend, err := backend.DialBackend(b.GetTestContext(), host, b.metrics)
Nil(b.T(), err)
res, err := backend.BlockHashesInRange(b.GetTestContext(), scribeBackend, 1, 10)
Nil(b.T(), err)
// use to make sure we don't double use values
intSet := sets.NewInt64()
itr := res.Iterator()
for !itr.Done() {
index, _, _ := itr.Next()
Falsef(b.T(), intSet.Has(int64(index)), "%d appears at least twice", index)
}
}