Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: merge feature/v2.0.0 to develop #17

Merged
merged 7 commits into from
Sep 16, 2024
20 changes: 10 additions & 10 deletions addresses/mainnet.json
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
{
"Governance": "0xAc40E8dA38B5a381008059a38bb9bf45f0D3C4e2",
"BlockManager": "0x11aB70d78f1Dd2c3F967180d8A64858Db03A0aBa",
"CollectionManager": "0x367962d1462C568A0dDd0e2448311469451bF5a3",
"StakeManager": "0xe0bC695203d9C9f379bcdE9260B9F71B64B85298",
"RewardManager": "0x301779E4c95f951D2E17B4c3EdDC717551df2EBb",
"VoteManager": "0x641BAD0641eB5B94B19568C0a22a55AEbDAF1870",
"Delegator": "0xC74745eA5a3fac1864FAcd8f48d72C21A4ab883D",
"RAZOR": "0xcbf70914Fae03B3acB91E953De60CfDAaCA8145f",
"StakedTokenFactory": "0xEffA78888Dc1b6033286E5dF9b170bc5223178AB",
"RandomNoManager": "0xC6eF45F5Add040800D30FE6dEe01b4EBC4BfC467"
"Governance": "0xb3bFD9c67f0C58076Dc35d70C7A4Dae3640d0BFA",
"BlockManager": "0x8DEF3d7e68f32bB4d1247CA27847c1b2080247a8",
"CollectionManager": "0xCb537fA163873977035Aca160B9a1b23e6697f55",
"StakeManager": "0x66BFfDC1dfC6733503193eE0e2D493212362CD27",
"RewardManager": "0x6Dc96056A63F057B561C5841fE702a4582b320Da",
"VoteManager": "0x938157B936Edf416e52Ec0A1948E3ECd9C13B87B",
"Delegator": "0xB26FD23E7c20767fF5dCb883209b801f123C5060",
"RAZOR": "0x880e4aB635889b23c80179700D03c369b05fb500",
"StakedTokenFactory": "0x2fED450834aAEB618259619F975034fCBb04A6aF",
"RandomNoManager": "0xC3228f851fb49413F8100026c4085E02Bc6eBF06"
}
21 changes: 10 additions & 11 deletions addresses/testnet.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
{
"Governance": "0x0b9CC11E7f7D3D4f9bBc0cCaB85b73B96C322c78",
"BlockManager": "0x076df1c2d81C40D30DF115Ab68A13251fBD3FFA4",
"CollectionManager": "0x83f4D7ad6dD366c3F04Af45a1437c77636b03388",
"StakeManager": "0xf99a873a6afdF1b24388ac02ea0f1CFE3c70A80b",
"RewardManager": "0x522d2A51639332388dA4788DF59fB4E598278fAd",
"VoteManager": "0x2399D4d92b4D8762971605d0bC9597F780852CC4",
"Delegator": "0x81c72fB60d19Bfc3A0adDfE394501150d290cd66",
"RAZOR": "0x504C6635af1e7E6fdc586c8A89973783b9281A77",
"StakedTokenFactory": "0xf271bd91104946Cb8e43BC0e83423ed073ab136e",
"RandomNoManager": "0x2dc9E4663675c933f78D97cDD44463ee9C43144c",
"DelegatorV2": "0x4e9E5AE58Fb6d7Ca5b79A196b8d0FCF7CA15C100"
"Governance": "0x0C91e21D91510A1e95cd3507474c0ac1F620389d",
"BlockManager": "0x1eB1aD4C24cf2CA2027C05a28e78A117fDACD9F9",
"CollectionManager": "0xAFC593871Ab8EE89fd79B2ebd9F1f502268732b9",
"StakeManager": "0x7ce95141358FeF127d3F79f7a5C21C6c2afa1cA3",
"RewardManager": "0xbaa2e7509AdB5762f33064Ad762dF1136184Ef7D",
"VoteManager": "0x57a996015D831F6f4818ff962ffE405b6c6d4B21",
"Delegator": "0x63F82745aBe00c43a71ff2A48E65B281f72Bb54D",
"RAZOR": "0x91d07a181e2Fb787204Ae82B28c69e278C05ac70",
"StakedTokenFactory": "0x047f5865e666DCc278ad3bd8de8503D35d5278Ea",
"RandomNoManager": "0x3A6bbfBBe24F5F5D20F6a7265A0F602d155C2471"
}
65 changes: 26 additions & 39 deletions cache/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,17 @@ type cachedData struct {
}

type LocalCache struct {
stop chan struct{}

wg sync.WaitGroup
mu sync.RWMutex
URLs map[string]cachedData //URLs
}

func NewLocalCache(cleanupInterval time.Duration) *LocalCache {
lc := &LocalCache{
// NewLocalCache creates a new LocalCache instance
func NewLocalCache() *LocalCache {
return &LocalCache{
URLs: make(map[string]cachedData),
stop: make(chan struct{}),
}

lc.wg.Add(1)
go func(cleanupInterval time.Duration) {
defer lc.wg.Done()
lc.cleanupLoop(cleanupInterval)
}(cleanupInterval)

return lc
}

func (lc *LocalCache) cleanupLoop(interval time.Duration) {
t := time.NewTicker(interval)
defer t.Stop()

for {
select {
case <-lc.stop:
return
case <-t.C:
lc.mu.Lock()
for url, cu := range lc.URLs {
if cu.expireAtTimestamp <= time.Now().Unix() {
delete(lc.URLs, url)
}
}
lc.mu.Unlock()
}
}
}

func (lc *LocalCache) StopCleanup() {
close(lc.stop)
lc.wg.Wait()
}

func (lc *LocalCache) Update(data []byte, url string, expireAtTimestamp int64) {
lc.mu.Lock()
defer lc.mu.Unlock()
Expand All @@ -80,3 +44,26 @@ func (lc *LocalCache) Read(url string) ([]byte, bool) {

return cacheData.Result, true
}

// ClearAll deletes all entries in the cache
func (lc *LocalCache) ClearAll() {
lc.mu.Lock()
defer lc.mu.Unlock()

for key := range lc.URLs {
delete(lc.URLs, key)
}
}

// Cleanup removes expired cache entries
func (lc *LocalCache) Cleanup() {
lc.mu.Lock()
defer lc.mu.Unlock()

for url, data := range lc.URLs {
// Remove expired data after the expireAtTimestamp is passed
if data.expireAtTimestamp <= time.Now().Unix() {
delete(lc.URLs, url)
}
}
}
4 changes: 4 additions & 0 deletions cmd/cmd-utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ func (*UtilsStruct) GetEpochAndState(client *ethclient.Client) (uint32, int64, e
if err != nil {
return 0, 0, err
}
err = ValidateBufferPercentLimit(client, bufferPercent)
if err != nil {
return 0, 0, err
}
latestHeader, err := clientUtils.GetLatestBlockWithRetry(client)
if err != nil {
log.Error("Error in fetching block: ", err)
Expand Down
31 changes: 31 additions & 0 deletions cmd/cmd-utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ func TestGetEpochAndState(t *testing.T) {
latestHeaderErr error
bufferPercent int32
bufferPercentErr error
stateBuffer uint64
stateBufferErr error
state int64
stateErr error
stateName string
Expand All @@ -37,6 +39,7 @@ func TestGetEpochAndState(t *testing.T) {
epoch: 4,
latestHeader: &Types.Header{},
bufferPercent: 20,
stateBuffer: 5,
state: 0,
stateName: "commit",
},
Expand All @@ -50,6 +53,7 @@ func TestGetEpochAndState(t *testing.T) {
epochErr: errors.New("epoch error"),
latestHeader: &Types.Header{},
bufferPercent: 20,
stateBuffer: 5,
state: 0,
stateName: "commit",
},
Expand All @@ -76,6 +80,7 @@ func TestGetEpochAndState(t *testing.T) {
epoch: 4,
latestHeader: &Types.Header{},
bufferPercent: 20,
stateBuffer: 5,
stateErr: errors.New("state error"),
},
wantEpoch: 0,
Expand All @@ -88,20 +93,46 @@ func TestGetEpochAndState(t *testing.T) {
epoch: 4,
latestHeaderErr: errors.New("header error"),
bufferPercent: 20,
stateBuffer: 5,
state: 0,
stateName: "commit",
},
wantEpoch: 0,
wantState: 0,
wantErr: errors.New("header error"),
},
{
name: "Test 6: When validating buffer percent limit fails",
args: args{
epoch: 4,
latestHeader: &Types.Header{},
bufferPercent: 50,
stateBuffer: 10,
},
wantEpoch: 0,
wantState: 0,
wantErr: errors.New("buffer percent exceeds limit"),
},
{
name: "Test 7: When there is an error in validating buffer percent limit",
args: args{
epoch: 4,
latestHeader: &Types.Header{},
bufferPercent: 50,
stateBufferErr: errors.New("state buffer error"),
},
wantEpoch: 0,
wantState: 0,
wantErr: errors.New("state buffer error"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
SetUpMockInterfaces()

utilsMock.On("GetEpoch", mock.AnythingOfType("*ethclient.Client")).Return(tt.args.epoch, tt.args.epochErr)
cmdUtilsMock.On("GetBufferPercent").Return(tt.args.bufferPercent, tt.args.bufferPercentErr)
utilsMock.On("GetStateBuffer", mock.Anything).Return(tt.args.stateBuffer, tt.args.stateBufferErr)
clientUtilsMock.On("GetLatestBlockWithRetry", mock.Anything).Return(tt.args.latestHeader, tt.args.latestHeaderErr)
utilsMock.On("GetBufferedState", mock.Anything, mock.Anything, mock.Anything).Return(tt.args.state, tt.args.stateErr)

Expand Down
12 changes: 3 additions & 9 deletions cmd/commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,13 @@ package cmd
import (
"encoding/hex"
"errors"
Types "github.com/ethereum/go-ethereum/core/types"
"math/big"
"razor/cache"
"razor/core"
"razor/core/types"
"razor/pkg/bindings"
"razor/utils"
"sync"
"time"

Types "github.com/ethereum/go-ethereum/core/types"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/ethclient"
Expand Down Expand Up @@ -79,8 +76,8 @@ func (*UtilsStruct) HandleCommitState(client *ethclient.Client, epoch uint32, se

var wg sync.WaitGroup

log.Debug("Creating a local cache which will store API result and expire at the end of commit state")
commitParams.LocalCache = cache.NewLocalCache(time.Second * time.Duration(core.StateLength))
// Clean up any expired API results cache data before performing the commit
commitParams.LocalCache.Cleanup()

log.Debug("Iterating over all the collections...")
for i := 0; i < int(numActiveCollections); i++ {
Expand Down Expand Up @@ -129,7 +126,6 @@ func (*UtilsStruct) HandleCommitState(client *ethclient.Client, epoch uint32, se
if err != nil {
// Returning the first error from the error channel
log.Error("Error in getting collection data: ", err)
commitParams.LocalCache.StopCleanup()
return types.CommitData{}, err
}
}
Expand All @@ -139,8 +135,6 @@ func (*UtilsStruct) HandleCommitState(client *ethclient.Client, epoch uint32, se
log.Debug("HandleCommitState: SeqAllottedCollections: ", seqAllottedCollections)
log.Debug("HandleCommitState: Leaves: ", leavesOfTree)

commitParams.LocalCache.StopCleanup()

return types.CommitData{
AssignedCollections: assignedCollections,
SeqAllottedCollections: seqAllottedCollections,
Expand Down
5 changes: 2 additions & 3 deletions cmd/commit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ import (
"razor/utils"
"reflect"
"testing"
"time"
)

func TestCommit(t *testing.T) {
Expand Down Expand Up @@ -226,7 +225,7 @@ func TestHandleCommitState(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
localCache := cache.NewLocalCache(time.Second * 10)
localCache := cache.NewLocalCache()
commitParams := &types.CommitParams{
LocalCache: localCache,
}
Expand Down Expand Up @@ -396,7 +395,7 @@ func BenchmarkHandleCommitState(b *testing.B) {
for _, v := range table {
b.Run(fmt.Sprintf("Number_Of_Active_Collections%d", v.numActiveCollections), func(b *testing.B) {
for i := 0; i < b.N; i++ {
localCache := cache.NewLocalCache(time.Second * 10)
localCache := cache.NewLocalCache()
commitParams := &types.CommitParams{
LocalCache: localCache,
}
Expand Down
51 changes: 34 additions & 17 deletions cmd/config-utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cmd

import (
"errors"
"github.com/ethereum/go-ethereum/ethclient"
"github.com/sirupsen/logrus"
"razor/client"
"razor/core"
Expand Down Expand Up @@ -207,28 +208,17 @@ func (*UtilsStruct) GetMultiplier() (float32, error) {

//This function returns the buffer percent
func (*UtilsStruct) GetBufferPercent() (int32, error) {
const (
MinBufferPercent = 0
MaxBufferPercent = 30
)

bufferPercent, err := getConfigValue("buffer", "int32", core.DefaultBufferPercent, "buffer")
if err != nil {
return core.DefaultBufferPercent, err
}

bufferPercentInt32 := bufferPercent.(int32)

// Check if bufferPercent is explicitly set and not within the valid range.
if bufferPercentInt32 < MinBufferPercent || bufferPercentInt32 > MaxBufferPercent {
log.Infof("BufferPercent %d is out of the valid range (%d-%d), using default value %d", bufferPercentInt32, MinBufferPercent, MaxBufferPercent, core.DefaultBufferPercent)
return core.DefaultBufferPercent, nil
}

// If bufferPercent is 0, use the default value.
if bufferPercentInt32 == 0 {
log.Debugf("BufferPercent is unset or set to 0, using its default %d value", core.DefaultBufferPercent)
return core.DefaultBufferPercent, nil
// bufferPercent cannot be less than core.DefaultBufferPercent else through an error
if bufferPercentInt32 < core.DefaultBufferPercent {
log.Infof("BufferPercent should be greater than or equal to %v", core.DefaultBufferPercent)
return core.DefaultBufferPercent, errors.New("invalid buffer percent")
}

return bufferPercentInt32, nil
Expand Down Expand Up @@ -334,7 +324,7 @@ func (*UtilsStruct) GetGasLimitOverride() (uint64, error) {
func (*UtilsStruct) GetRPCTimeout() (int64, error) {
const (
MinRPCTimeout = 10 // Minimum RPC timeout in seconds
MaxRPCTimeout = 60 // Maximum RPC timeout in seconds
MaxRPCTimeout = 20 // Maximum RPC timeout in seconds
)

rpcTimeout, err := getConfigValue("rpcTimeout", "int64", core.DefaultRPCTimeout, "rpcTimeout")
Expand All @@ -356,7 +346,7 @@ func (*UtilsStruct) GetRPCTimeout() (int64, error) {
func (*UtilsStruct) GetHTTPTimeout() (int64, error) {
const (
MinHTTPTimeout = 10 // Minimum HTTP timeout in seconds
MaxHTTPTimeout = 60 // Maximum HTTP timeout in seconds
MaxHTTPTimeout = 20 // Maximum HTTP timeout in seconds
)

httpTimeout, err := getConfigValue("httpTimeout", "int64", core.DefaultHTTPTimeout, "httpTimeout")
Expand Down Expand Up @@ -413,3 +403,30 @@ func setLogLevel(config types.Configurations) {
log.Debugf("Log File Max Age (max number of days to retain old log files): %d", config.LogFileMaxAge)
}
}

func ValidateBufferPercentLimit(client *ethclient.Client, bufferPercent int32) error {
stateBuffer, err := razorUtils.GetStateBuffer(client)
if err != nil {
return err
}
maxBufferPercent := calculateMaxBufferPercent(stateBuffer, core.StateLength)
if bufferPercent >= maxBufferPercent {
log.Errorf("Buffer percent %v is greater than or equal to maximum possible buffer percent", maxBufferPercent)
return errors.New("buffer percent exceeds limit")
}
return nil
}

// calculateMaxBuffer calculates the maximum buffer percent value.
func calculateMaxBufferPercent(stateBuffer, stateLength uint64) int32 {
if stateLength == 0 {
return 0
}

// The formula is derived from the condition:
// 2(maxBuffer % stateLength) < (stateLength - 2*StateBuffer)

// Perform the calculation with float64 for precision
maxBufferPercent := 50 * (1 - (float64(2*stateBuffer) / float64(stateLength)))
return int32(maxBufferPercent)
}
Loading
Loading