harsh jain 08cabab41f
fix: and optimising fetching membership events (#706)
* fix: and optimising fetching membership events

* fix: start from lastProcessedBlock+1

* test: fetching membership logic

* refactor: usage of rlnInstance,rootTracker,groupManager

rlnInstance, rootTrack were previously created while creating rlnRelay
but were assigned to groupManager on Start of rlnRelay. This created
unncessary dependency of passing them to static and dynamic group
manager.
Web3Config uses interface EthClientI for client, so that we can pass
mock client for testing MembershipFetcher.

* fix: failing test

* fix: lint error

* fix: account for PR suggestions

* fix: failing race test

* fix: dont' increase fromBlock on error

* nit: fix naming and add comments
2023-09-07 23:23:48 +07:00

82 lines
2.8 KiB
Go

package dynamic
import (
"encoding/binary"
"errors"
"math/big"
"github.com/ethereum/go-ethereum/common"
"github.com/waku-org/go-waku/waku/v2/protocol/rln/group_manager"
)
// RLNMetadata persists attributes in the RLN database
type RLNMetadata struct {
LastProcessedBlock uint64
ChainID *big.Int
ContractAddress common.Address
ValidRootsPerBlock []group_manager.RootsPerBlock
}
// Serialize converts a RLNMetadata into a binary format expected by zerokit's RLN
func (r RLNMetadata) Serialize() []byte {
chainID := r.ChainID
if chainID == nil {
chainID = big.NewInt(0)
}
var result []byte
result = binary.LittleEndian.AppendUint64(result, r.LastProcessedBlock)
result = binary.LittleEndian.AppendUint64(result, chainID.Uint64())
result = append(result, r.ContractAddress.Bytes()...)
result = binary.LittleEndian.AppendUint64(result, uint64(len(r.ValidRootsPerBlock)))
for _, v := range r.ValidRootsPerBlock {
result = append(result, v.Root[:]...)
result = binary.LittleEndian.AppendUint64(result, v.BlockNumber)
}
return result
}
const lastProcessedBlockOffset = 0
const chainIDOffset = lastProcessedBlockOffset + 8
const contractAddressOffset = chainIDOffset + 8
const validRootsLenOffset = contractAddressOffset + 20
const validRootsValOffset = validRootsLenOffset + 8
const metadataByteLen = 8 + 8 + 20 + 8 // uint64 + uint64 + ethAddress + uint64
// DeserializeMetadata converts a byte slice into a RLNMetadata instance
func DeserializeMetadata(b []byte) (RLNMetadata, error) {
if len(b) < metadataByteLen {
return RLNMetadata{}, errors.New("wrong size")
}
validRootLen := binary.LittleEndian.Uint64(b[validRootsLenOffset:validRootsValOffset])
if len(b) < int(metadataByteLen+validRootLen*(32+8)) { // len of a merkle node and len of a uint64 for the block number
return RLNMetadata{}, errors.New("wrong size")
}
validRoots := make([]group_manager.RootsPerBlock, 0, validRootLen)
for i := 0; i < int(validRootLen); i++ {
rootOffset := validRootsValOffset + (i * (32 + 8))
blockOffset := rootOffset + 32
root := group_manager.RootsPerBlock{
BlockNumber: binary.LittleEndian.Uint64(b[blockOffset : blockOffset+8]),
}
copy(root.Root[:], b[rootOffset:blockOffset])
validRoots = append(validRoots, root)
}
return RLNMetadata{
LastProcessedBlock: binary.LittleEndian.Uint64(b[lastProcessedBlockOffset:chainIDOffset]),
ChainID: new(big.Int).SetUint64(binary.LittleEndian.Uint64(b[chainIDOffset:contractAddressOffset])),
ContractAddress: common.BytesToAddress(b[contractAddressOffset:validRootsLenOffset]),
ValidRootsPerBlock: validRoots,
}, nil
}
// SetMetadata stores some metadata into the zerokit's RLN database
func (gm *DynamicGroupManager) SetMetadata(meta RLNMetadata) error {
b := meta.Serialize()
return gm.rln.SetMetadata(b)
}