synapsecns/sanguine

View on GitHub
services/scribe/backend/backend_test.go

Summary

Maintainability
A
1 hr
Test Coverage
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)
    }
}