mirror of
https://github.com/status-im/go-waku.git
synced 2025-02-14 14:37:05 +00:00
* 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
141 lines
3.7 KiB
Go
141 lines
3.7 KiB
Go
package web3
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"math/big"
|
|
|
|
"github.com/ethereum/go-ethereum"
|
|
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
|
"github.com/ethereum/go-ethereum/common"
|
|
"github.com/ethereum/go-ethereum/core/types"
|
|
"github.com/ethereum/go-ethereum/ethclient"
|
|
"github.com/waku-org/go-waku/waku/v2/protocol/rln/contracts"
|
|
)
|
|
|
|
// RegistryContract contains an instance of the RLN Registry contract and its address
|
|
type RegistryContract struct {
|
|
*contracts.RLNRegistry
|
|
Address common.Address
|
|
}
|
|
|
|
// RLNContract contains an instance of the RLN contract, its address and the storage index within the registry
|
|
// that represents this contract
|
|
type RLNContract struct {
|
|
*contracts.RLN
|
|
Address common.Address
|
|
StorageIndex uint16
|
|
DeployedBlockNumber uint64
|
|
}
|
|
|
|
// EthClient is an interface for the ethclient.Client, so that we can pass mock client for testing
|
|
type EthClient interface {
|
|
bind.ContractBackend
|
|
TransactionReceipt(ctx context.Context, txHash common.Hash) (*types.Receipt, error)
|
|
BlockByNumber(ctx context.Context, number *big.Int) (*types.Block, error)
|
|
SubscribeNewHead(ctx context.Context, ch chan<- *types.Header) (ethereum.Subscription, error)
|
|
Close()
|
|
}
|
|
|
|
// Config is a helper struct that contains attributes for interaction with RLN smart contracts
|
|
type Config struct {
|
|
configured bool
|
|
|
|
ETHClientAddress string
|
|
ETHClient EthClient
|
|
ChainID *big.Int
|
|
RegistryContract RegistryContract
|
|
RLNContract RLNContract
|
|
}
|
|
|
|
// NewConfig creates an instance of web3 Config
|
|
func NewConfig(ethClientAddress string, registryAddress common.Address) *Config {
|
|
return &Config{
|
|
ETHClientAddress: ethClientAddress,
|
|
RegistryContract: RegistryContract{
|
|
Address: registryAddress,
|
|
},
|
|
}
|
|
}
|
|
|
|
// BuildConfig returns an instance of Web3Config with all the required elements for interaction with the RLN smart contracts
|
|
func BuildConfig(ctx context.Context, ethClientAddress string, registryAddress common.Address) (*Config, error) {
|
|
ethClient, err := ethclient.DialContext(ctx, ethClientAddress)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
chainID, err := ethClient.ChainID(ctx)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rlnRegistry, err := contracts.NewRLNRegistry(registryAddress, ethClient)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
storageIndex, err := rlnRegistry.UsingStorageIndex(&bind.CallOpts{Context: ctx})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rlnContractAddress, err := rlnRegistry.Storages(&bind.CallOpts{Context: ctx}, storageIndex)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
rlnContract, err := contracts.NewRLN(rlnContractAddress, ethClient)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
deploymentBlockNumber, err := rlnContract.DeployedBlockNumber(&bind.CallOpts{Context: ctx})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &Config{
|
|
configured: true,
|
|
ETHClientAddress: ethClientAddress,
|
|
ETHClient: ethClient,
|
|
ChainID: chainID,
|
|
RegistryContract: RegistryContract{
|
|
RLNRegistry: rlnRegistry,
|
|
Address: registryAddress,
|
|
},
|
|
RLNContract: RLNContract{
|
|
RLN: rlnContract,
|
|
Address: rlnContractAddress,
|
|
StorageIndex: storageIndex,
|
|
DeployedBlockNumber: uint64(deploymentBlockNumber),
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// Build sets up the Config object by instantiating the eth client and contracts
|
|
func (w *Config) Build(ctx context.Context) error {
|
|
if w.configured {
|
|
return errors.New("already configured")
|
|
}
|
|
|
|
if w.ETHClientAddress == "" {
|
|
return errors.New("no eth client address")
|
|
}
|
|
|
|
var zeroAddr common.Address
|
|
if w.RegistryContract.Address == zeroAddr {
|
|
return errors.New("no registry contract address")
|
|
}
|
|
|
|
newW, err := BuildConfig(ctx, w.ETHClientAddress, w.RegistryContract.Address)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*w = *newW
|
|
w.configured = true
|
|
|
|
return nil
|
|
}
|