mirror of
https://github.com/status-im/go-waku.git
synced 2025-01-15 16:24:50 +00:00
08cabab41f
* 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
82 lines
2.8 KiB
Go
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)
|
|
}
|