waku-org/go-waku

View on GitHub
waku/v2/protocol/rln/group_manager/dynamic/mock_blockchain.go

Summary

Maintainability
A
0 mins
Test Coverage
B
86%
package dynamic

import (
    "math/big"
    "strings"

    "github.com/ethereum/go-ethereum/common"
    "github.com/ethereum/go-ethereum/core/types"
    "github.com/ethereum/go-ethereum/crypto"
)

// MockBlockChain  is currently a chain of events for different block numbers
// it is used internal by mock client for returning events for a given block number or range in FilterLog rpc call.
type MockBlockChain struct {
    Blocks map[int64]*MockBlock `json:"blocks"`
}

type MockBlock []MockEvent

func containsEntry[T common.Hash | common.Address](topics []T, topicA T) bool {
    for _, topic := range topics {
        if topic == topicA {
            return true
        }
    }
    return false
}

func Topic(topic string) common.Hash {
    return crypto.Keccak256Hash([]byte(topic))
}
func (b MockBlock) getLogs(blockNum uint64, addrs []common.Address, topicA []common.Hash) (txLogs []types.Log) {
    for ind, event := range b {
        txLog := event.GetLog()
        if containsEntry(addrs, txLog.Address) && (len(topicA) == 0 || containsEntry(topicA, txLog.Topics[0])) {
            txLog.BlockNumber = blockNum
            txLog.Index = uint(ind)
            txLogs = append(txLogs, txLog)
        }
    }
    return
}

type MockEvent struct {
    Address common.Address `json:"address"`
    Topics  []string       `json:"topics"`
    Txhash  common.Hash    `json:"txhash"`
    Data    []string       `json:"data"`
}

func (e MockEvent) GetLog() types.Log {
    topics := []common.Hash{Topic(e.Topics[0])}
    for _, topic := range e.Topics[1:] {
        topics = append(topics, parseData(topic))
    }
    //
    var data []byte
    for _, entry := range e.Data {
        data = append(data, parseData(entry).Bytes()...)
    }
    return types.Log{
        Address: e.Address,
        Topics:  topics,
        TxHash:  e.Txhash,
        Data:    data,
    }
}

func parseData(data string) common.Hash {
    splits := strings.Split(data, ":")
    switch splits[0] {
    case "bigint":
        bigInt, ok := new(big.Int).SetString(splits[1], 10)
        if !ok {
            panic("invalid big int")
        }
        return common.BytesToHash(bigInt.Bytes())
    default:
        panic("invalid data type")
    }
}