Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,5 @@ testdata/
.idea/
.vscode/


# envs
envs/*
16 changes: 11 additions & 5 deletions cmd/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ func startCommand() *cobra.Command {
Run: startHandler,
}

nodeURL, privateKey, timelockAddress, callProxyAddress string
fromBlock, pollPeriod, eventListenerPollPeriod int64
eventListenerPollSize uint64
dryRun bool
nodeURL, privateKey, timelockAddress, callProxyAddress string
fromBlock, toBlock, pollPeriod, eventListenerPollPeriod int64
eventListenerPollSize uint64
dryRun bool
)

// Initialize timelock-worker configuration.
Expand All @@ -41,6 +41,7 @@ func startCommand() *cobra.Command {
startCmd.Flags().StringVarP(&callProxyAddress, "call-proxy-address", "f", timelockConf.CallProxyAddress, "Address of the target CallProxyAddress contract")
startCmd.Flags().StringVarP(&privateKey, "private-key", "k", timelockConf.PrivateKey, "Private key used to execute transactions")
startCmd.Flags().Int64Var(&fromBlock, "from-block", timelockConf.FromBlock, "Start watching from this block")
startCmd.Flags().Int64Var(&toBlock, "to-block", -1, "Stop watching at this block (default: watch until the end of the chain)")
startCmd.Flags().Int64Var(&pollPeriod, "poll-period", timelockConf.PollPeriod, "Poll period in seconds")
startCmd.Flags().Int64Var(&eventListenerPollPeriod, "event-listener-poll-period", timelockConf.EventListenerPollPeriod, "Event Listener poll period in seconds")
startCmd.Flags().Uint64Var(&eventListenerPollSize, "event-listener-poll-size", timelockConf.EventListenerPollSize, "Number of entries to fetch when polling logs")
Expand Down Expand Up @@ -83,6 +84,11 @@ func startTimelock(cmd *cobra.Command) {
slog.Fatalf("value of from-block not set: %s", err.Error())
}

toBlock, err := cmd.Flags().GetInt64("to-block")
if err != nil {
slog.Fatalf("value of to-block not set: %s", err.Error())
}

pollPeriod, err := cmd.Flags().GetInt64("poll-period")
if err != nil {
slog.Fatalf("value of poll-period not set: %s", err.Error())
Expand All @@ -104,7 +110,7 @@ func startTimelock(cmd *cobra.Command) {
}

tWorker, err := timelock.NewTimelockWorker(nodeURL, timelockAddress, callProxyAddress, privateKey,
big.NewInt(fromBlock), pollPeriod, eventListenerPollPeriod, eventListenerPollSize, dryRun, slog)
big.NewInt(fromBlock), big.NewInt((toBlock)), pollPeriod, eventListenerPollPeriod, eventListenerPollSize, dryRun, slog)
if err != nil {
slog.Fatalf("error creating the timelock-worker: %s", err.Error())
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/timelock/operations.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ func (tw *Worker) executeCallSchedule(ctx context.Context, c *contracts.RBACTime
txOpts.GasPrice = big.NewInt(1000000000) // gasPrice set to 1 gwei
}

if chainID.Cmp(new(big.Int).SetUint64(chainselectors.ETHEREUM_MAINNET_LINEA_1.EvmChainID)) == 0 {
tw.logger.Infof("Linea chain detected")
txOpts.GasFeeCap = big.NewInt(20000000000) // gasFeeCap set to 20 gwei
txOpts.GasTipCap = big.NewInt(20000000000) // gasTipCap set to 20 gwei
}

tw.logger.Infof("Calling execute Batch...")
// Execute the tx's with all the computed calls.
// Predecessor and salt are the same for all the tx's.
Expand Down
16 changes: 12 additions & 4 deletions pkg/timelock/timelock.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type Worker struct {
abi *abi.ABI
address []common.Address
fromBlock *big.Int
toBlock *big.Int
pollPeriod int64
listenerPollPeriod int64
pollSize uint64
Expand All @@ -50,7 +51,7 @@ var validNodeUrlSchemes = []string{"http", "https", "ws", "wss"}
// NewTimelockWorker initializes and returns a timelockWorker.
// It's a singleton, so further executions will retrieve the same timelockWorker.
func NewTimelockWorker(
nodeURL, timelockAddress, callProxyAddress, privateKey string, fromBlock *big.Int,
nodeURL, timelockAddress, callProxyAddress, privateKey string, fromBlock *big.Int, toBlock *big.Int,
pollPeriod int64, listenerPollPeriod int64, pollSize uint64, dryRun bool, logger *zap.SugaredLogger,
) (*Worker, error) {
// Sanity check on each provided variable before allocating more resources.
Expand Down Expand Up @@ -87,6 +88,10 @@ func NewTimelockWorker(
return nil, fmt.Errorf("from block can't be a negative number (minimum value 0): got %d", fromBlock.Int64())
}

if toBlock.Int64() < big.NewInt(0).Int64() {
return nil, fmt.Errorf("to block can't be a negative number (minimum value 0): got %d", toBlock.Int64())
}

if _, err := crypto.HexToECDSA(privateKey); err != nil {
return nil, fmt.Errorf("the provided private key is not valid: got %s", privateKey)
}
Expand Down Expand Up @@ -130,6 +135,7 @@ func NewTimelockWorker(
abi: timelockABI,
address: []common.Address{common.HexToAddress(timelockAddress)},
fromBlock: fromBlock,
toBlock: toBlock,
pollPeriod: pollPeriod,
listenerPollPeriod: listenerPollPeriod,
pollSize: pollSize,
Expand Down Expand Up @@ -224,7 +230,7 @@ func (tw *Worker) retrieveNewLogs(ctx context.Context) (<-chan struct{}, <-chan

// subscribeNewLogs subscribes to a Timelock contract and emit logs through the channel it returns.
func (tw *Worker) subscribeNewLogs(ctx context.Context) (<-chan struct{}, <-chan types.Log, error) {
query := tw.setupFilterQuery(tw.fromBlock, nil)
query := tw.setupFilterQuery(tw.fromBlock, tw.toBlock)
logCh := make(chan types.Log)
done := make(chan struct{})

Expand Down Expand Up @@ -287,6 +293,7 @@ func (tw *Worker) subscribeNewLogs(ctx context.Context) (<-chan struct{}, <-chan
// pollNewLogs periodically retrieves logs from the Timelock and emit them through the channel it returns.
func (tw *Worker) pollNewLogs(ctx context.Context) (<-chan struct{}, <-chan types.Log, error) {
lastBlock := tw.fromBlock
toBlock := tw.toBlock
logCh := make(chan types.Log)
done := make(chan struct{})

Expand All @@ -299,7 +306,7 @@ func (tw *Worker) pollNewLogs(ctx context.Context) (<-chan struct{}, <-chan type
defer ticker.Stop()

for {
lastBlock = tw.fetchAndDispatchLogs(ctx, logCh, lastBlock, nil)
lastBlock = tw.fetchAndDispatchLogs(ctx, logCh, lastBlock, toBlock)

select {
case <-ticker.C:
Expand All @@ -319,7 +326,7 @@ func (tw *Worker) pollNewLogs(ctx context.Context) (<-chan struct{}, <-chan type
// retrieveHistoricalLogs returns a types.Log channel and retrieves all the historical events of a given contract.
// Once all the logs have been sent into the channel the function returns and the channel is closed.
func (tw *Worker) retrieveHistoricalLogs(ctx context.Context) (<-chan struct{}, <-chan types.Log, error) {
query := tw.setupFilterQuery(tw.fromBlock, nil)
query := tw.setupFilterQuery(tw.fromBlock, tw.toBlock)
logCh := make(chan types.Log)
done := make(chan struct{})

Expand Down Expand Up @@ -585,6 +592,7 @@ func (tw *Worker) startLog() {

tw.logger.Infof("\tEOA address: %v", wallet)
tw.logger.Infof("\tStarting from block: %v", tw.fromBlock)
tw.logger.Infof("\tEnding at block: %v", tw.toBlock)
tw.logger.Infof("\tPoll Period: %v", time.Duration(tw.pollPeriod*int64(time.Second)).String())
tw.logger.Infof("\tEvent Listener Poll Period: %v", time.Duration(tw.listenerPollPeriod*int64(time.Second)).String())
tw.logger.Infof("\tEvent Listener Poll # Logs%v", tw.pollSize)
Expand Down