Skip to content

Commit

Permalink
[FUN-877] make persisting allowlist compatible with older contract (#…
Browse files Browse the repository at this point in the history
…11907)

* feat: make persisting allowlist compatible with older contract

* feat: check tos contract version instead of a config feature flag

* extract contract version comparison to helper function

* fix: use semver to compare versions
  • Loading branch information
agparadiso authored Feb 22, 2024
1 parent 0b9dc18 commit 85cc590
Show file tree
Hide file tree
Showing 6 changed files with 467 additions and 96 deletions.
58 changes: 47 additions & 11 deletions core/services/gateway/handlers/functions/allowlist/allowlist.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@ import (
"encoding/hex"
"fmt"
"math/big"
"regexp"
"sync"
"sync/atomic"
"time"

"github.com/ethereum/go-ethereum/accounts/abi/bind"
"github.com/ethereum/go-ethereum/common"
"github.com/pkg/errors"
"golang.org/x/mod/semver"

"github.com/smartcontractkit/chainlink-common/pkg/services"
evmclient "github.com/smartcontractkit/chainlink/v2/core/chains/evm/client"
Expand All @@ -23,9 +25,10 @@ import (
)

const (
defaultStoredAllowlistBatchSize = 1000
defaultOnchainAllowlistBatchSize = 100
defaultFetchingDelayInRangeSec = 1
defaultStoredAllowlistBatchSize = 1000
defaultOnchainAllowlistBatchSize = 100
defaultFetchingDelayInRangeSec = 1
tosContractMinBatchProcessingVersion = "v1.1.0"
)

type OnchainAllowlistConfig struct {
Expand All @@ -38,8 +41,6 @@ type OnchainAllowlistConfig struct {
UpdateTimeoutSec uint `json:"updateTimeoutSec"`
StoredAllowlistBatchSize uint `json:"storedAllowlistBatchSize"`
OnchainAllowlistBatchSize uint `json:"onchainAllowlistBatchSize"`
// StoreAllowedSendersEnabled is a feature flag that enables storing in db a copy of the allowlist.
StoreAllowedSendersEnabled bool `json:"storeAllowedSendersEnabled"`
// FetchingDelayInRangeSec prevents RPC client being rate limited when fetching the allowlist in ranges.
FetchingDelayInRangeSec uint `json:"fetchingDelayInRangeSec"`
}
Expand Down Expand Up @@ -210,7 +211,31 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b
}

var allowedSenderList []common.Address
if !a.config.StoreAllowedSendersEnabled {
typeAndVersion, err := tosContract.TypeAndVersion(&bind.CallOpts{
Pending: false,
BlockNumber: blockNum,
Context: ctx,
})
if err != nil {
return errors.Wrap(err, "failed to fetch the tos contract type and version")
}

currentVersion, err := ExtractContractVersion(typeAndVersion)
if err != nil {
return fmt.Errorf("failed to extract version: %w", err)
}

if semver.Compare(tosContractMinBatchProcessingVersion, currentVersion) <= 0 {
err = a.syncBlockedSenders(ctx, tosContract, blockNum)
if err != nil {
return errors.Wrap(err, "failed to sync the stored allowed and blocked senders")
}

allowedSenderList, err = a.getAllowedSendersBatched(ctx, tosContract, blockNum)
if err != nil {
return errors.Wrap(err, "failed to get allowed senders in rage")
}
} else {
allowedSenderList, err = tosContract.GetAllAllowedSenders(&bind.CallOpts{
Pending: false,
BlockNumber: blockNum,
Expand All @@ -219,15 +244,15 @@ func (a *onchainAllowlist) updateFromContractV1(ctx context.Context, blockNum *b
if err != nil {
return errors.Wrap(err, "error calling GetAllAllowedSenders")
}
} else {
err = a.syncBlockedSenders(ctx, tosContract, blockNum)

err = a.orm.PurgeAllowedSenders()
if err != nil {
return errors.Wrap(err, "failed to sync the stored allowed and blocked senders")
a.lggr.Errorf("failed to purge allowedSenderList: %w", err)
}

allowedSenderList, err = a.getAllowedSendersBatched(ctx, tosContract, blockNum)
err = a.orm.CreateAllowedSenders(allowedSenderList)
if err != nil {
return errors.Wrap(err, "failed to get allowed senders in rage")
a.lggr.Errorf("failed to update stored allowedSenderList: %w", err)
}
}

Expand Down Expand Up @@ -344,3 +369,14 @@ func (a *onchainAllowlist) loadStoredAllowedSenderList() {

a.update(allowedList)
}

func ExtractContractVersion(str string) (string, error) {
pattern := `v(\d+).(\d+).(\d+)`
re := regexp.MustCompile(pattern)

match := re.FindStringSubmatch(str)
if len(match) != 4 {
return "", fmt.Errorf("version not found in string: %s", str)
}
return fmt.Sprintf("v%s.%s.%s", match[1], match[2], match[3]), nil
}
Loading

0 comments on commit 85cc590

Please sign in to comment.