Skip to content

Commit

Permalink
release: prepare release for v0.0.2
Browse files Browse the repository at this point in the history
release: prepare release for v0.0.2
  • Loading branch information
randyahx authored Jun 25, 2023
2 parents 9d32c1a + 92a3366 commit 8aba141
Show file tree
Hide file tree
Showing 24 changed files with 464 additions and 267 deletions.
5 changes: 5 additions & 0 deletions .github/CHANGELOG.md → CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
# Changelog

## v0.0.2
This is a maintenance release that updates the service to adapt to it's updated dependencies and code refactoring.
* [#47](https://github.com/bnb-chain/greenfield-challenger/pull/47) feat: adapt to new go-sdk and greenfield version

## v0.0.2-alpha.1
This is a pre-release. The go-sdk module and it's relevant dependencies are updated to use their pre-release alpha versions.
* [#44](https://github.com/bnb-chain/greenfield-challenger/pull/44) chore: upgrade dependencies
Expand Down
22 changes: 14 additions & 8 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"fmt"

"github.com/bnb-chain/greenfield-challenger/attest"

"github.com/bnb-chain/greenfield-challenger/config"
"github.com/bnb-chain/greenfield-challenger/db/dao"
"github.com/bnb-chain/greenfield-challenger/db/model"
Expand All @@ -27,7 +29,7 @@ type App struct {
voteBroadcaster *vote.VoteBroadcaster
voteCollator *vote.VoteCollator
txSubmitter *submitter.TxSubmitter
attestMonitor *submitter.AttestMonitor
attestMonitor *attest.AttestMonitor
dbWiper *wiper.DBWiper
}

Expand Down Expand Up @@ -71,19 +73,23 @@ func NewApp(cfg *config.Config) *App {

executor := executor.NewExecutor(cfg)

monitor := monitor.NewMonitor(executor, daoManager)
monitorDataHandler := monitor.NewDataHandler(daoManager)
monitor := monitor.NewMonitor(executor, monitorDataHandler)

hashVerifier := verifier.NewHashVerifier(cfg, daoManager, executor, cfg.GreenfieldConfig.DeduplicationInterval)
verifierDataHandler := verifier.NewDataHandler(daoManager)
hashVerifier := verifier.NewHashVerifier(cfg, executor, cfg.GreenfieldConfig.DeduplicationInterval, verifierDataHandler)

signer := vote.NewVoteSigner(executor.BlsPrivKey)
voteDataHandler := vote.NewDataHandler(daoManager, executor)
voteCollector := vote.NewVoteCollector(cfg, daoManager, executor, voteDataHandler)
voteBroadcaster := vote.NewVoteBroadcaster(cfg, daoManager, signer, executor, voteDataHandler)
voteCollator := vote.NewVoteCollator(cfg, daoManager, signer, executor, voteDataHandler)
voteCollector := vote.NewVoteCollector(cfg, executor, voteDataHandler)
voteBroadcaster := vote.NewVoteBroadcaster(cfg, signer, executor, voteDataHandler)
voteCollator := vote.NewVoteCollator(cfg, signer, executor, voteDataHandler)

txDataHandler := submitter.NewDataHandler(daoManager, executor)
txSubmitter := submitter.NewTxSubmitter(cfg, executor, daoManager, txDataHandler)
attestMonitor := submitter.NewAttestMonitor(executor, daoManager)
txSubmitter := submitter.NewTxSubmitter(cfg, executor, txDataHandler)

attestDataHandler := attest.NewDataHandler(daoManager)
attestMonitor := attest.NewAttestMonitor(executor, attestDataHandler)

dbWiper := wiper.NewDBWiper(daoManager)

Expand Down
82 changes: 82 additions & 0 deletions attest/attest_monitor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package attest

import (
"sync"
"time"

"github.com/bnb-chain/greenfield-challenger/db/model"
"github.com/bnb-chain/greenfield-challenger/executor"
"github.com/bnb-chain/greenfield-challenger/logging"
)

type AttestMonitor struct {
executor *executor.Executor
mtx sync.RWMutex
attestedChallengeIds map[uint64]bool // used to save the last attested challenge id
dataProvider DataProvider
}

func NewAttestMonitor(executor *executor.Executor, dataProvider DataProvider) *AttestMonitor {
return &AttestMonitor{
executor: executor,
mtx: sync.RWMutex{},
attestedChallengeIds: make(map[uint64]bool, 0),
dataProvider: dataProvider,
}
}

// UpdateAttestedChallengeIdLoop polls the blockchain for latest attested challengeIds and updates their status
func (a *AttestMonitor) UpdateAttestedChallengeIdLoop() {
ticker := time.NewTicker(QueryAttestedChallengeInterval)
queryCount := 0
for range ticker.C {
challengeIds, err := a.executor.QueryLatestAttestedChallengeIds()
// logging.Logger.Infof("latest attested challenge ids: %+v", challengeIds)
if err != nil {
logging.Logger.Errorf("update latest attested challenge error, err=%+v", err)
continue
}
logging.Logger.Infof("latest attested challenge ids: %+v", challengeIds)
a.mtx.Lock()
a.updateAttestedCacheAndEventStatus(a.attestedChallengeIds, challengeIds)
for _, id := range challengeIds {
a.attestedChallengeIds[id] = true
}
a.mtx.Unlock()

queryCount++
if queryCount > MaxQueryCount {
a.attestedChallengeIds = make(map[uint64]bool, 0)
}
}
}

// updateAttestedCacheAndEventStatus only updates new entries
func (a *AttestMonitor) updateAttestedCacheAndEventStatus(old map[uint64]bool, latest []uint64) {
for _, challengeId := range latest {
if _, ok := old[challengeId]; !ok {
go a.updateEventStatus(challengeId)
}
}
}

func (a *AttestMonitor) updateEventStatus(challengeId uint64) {
event, err := a.dataProvider.GetEventByChallengeId(challengeId)
if err != nil || event == nil {
logging.Logger.Errorf("attest monitor failed to get event by challengeId: %d, err=%+v", challengeId, err)
return
}
if event.Status == model.SelfAttested || event.Status == model.Attested {
return
}
var status model.EventStatus
if event.Status == model.Submitted {
status = model.SelfAttested
} else {
status = model.Attested
}
err = a.dataProvider.UpdateEventStatus(challengeId, status)
if err != nil {
logging.Logger.Errorf("update attested event status error, err=%s", err.Error())
}
}
8 changes: 8 additions & 0 deletions attest/const.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package attest

import "time"

const (
QueryAttestedChallengeInterval = 5 * time.Second // query last attested challenge id
MaxQueryCount = int((1 * time.Hour) / QueryAttestedChallengeInterval) // query last attested challenge id limit
)
29 changes: 29 additions & 0 deletions attest/data_provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package attest

import (
"github.com/bnb-chain/greenfield-challenger/db/dao"
"github.com/bnb-chain/greenfield-challenger/db/model"
)

type DataProvider interface {
GetEventByChallengeId(challengeId uint64) (*model.Event, error)
UpdateEventStatus(challengeId uint64, status model.EventStatus) error
}

type DataHandler struct {
daoManager *dao.DaoManager
}

func NewDataHandler(daoManager *dao.DaoManager) *DataHandler {
return &DataHandler{
daoManager: daoManager,
}
}

func (h *DataHandler) UpdateEventStatus(challengeId uint64, status model.EventStatus) error {
return h.daoManager.UpdateEventStatusByChallengeId(challengeId, status)
}

func (h *DataHandler) GetEventByChallengeId(challengeId uint64) (*model.Event, error) {
return h.daoManager.GetEventByChallengeId(challengeId)
}
57 changes: 56 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"cosmossdk.io/math"
"encoding/json"
"fmt"
"os"
Expand All @@ -25,10 +26,60 @@ type GreenfieldConfig struct {
GasLimit uint64 `json:"gas_limit"`
FeeAmount string `json:"fee_amount"`
FeeDenom string `json:"fee_denom"`
NoSimulate bool `json:"no_simulate"`
DeduplicationInterval uint64 `json:"deduplication_interval"`
}

func (cfg *GreenfieldConfig) Validate() {
if cfg.KeyType == "" {
panic("key_type should not be empty")
} else if cfg.KeyType == "aws_private_key" {
if cfg.AWSRegion == "" {
panic("aws_region should not be empty")
}
if cfg.AWSSecretName == "" {
panic("aws_secret_name should not be empty")
}
if cfg.AWSBlsSecretName == "" {
panic("aws_bls_secret_name should not be empty")
}
} else if cfg.KeyType == "local_private_key" {
if cfg.PrivateKey == "" {
panic("private_key should not be empty")
}
if cfg.BlsPrivateKey == "" {
panic("bls_private_key should not be empty")
}
} else {
panic(fmt.Sprintf("key_type %s is not supported", cfg.KeyType))
}

if cfg.RPCAddrs == nil || len(cfg.RPCAddrs) == 0 {
panic("rpc_addrs should not be empty")
}
if cfg.ChainIdString == "" {
panic("chain_id_string should not be empty")
}
if cfg.GasLimit == 0 {
panic("gas_limit should not be 0")
}
if cfg.FeeAmount == "" {
panic("fee_amount should not be empty")
}
if cfg.FeeDenom == "" {
panic("fee_denom should not be empty")
}
if cfg.DeduplicationInterval == 0 {
panic("deduplication_interval should not be 0")
}
feeAmount, ok := math.NewIntFromString(cfg.FeeAmount)
if !ok {
panic("error converting fee_amount to math.Int")
}
if !feeAmount.IsPositive() {
panic("fee_amount should not be negative")
}
}

type LogConfig struct {
Level string `json:"level"`
Filename string `json:"filename"`
Expand Down Expand Up @@ -79,13 +130,17 @@ func (cfg *DBConfig) Validate() {
func (cfg *Config) Validate() {
cfg.LogConfig.Validate()
cfg.DBConfig.Validate()
cfg.GreenfieldConfig.Validate()
}

func ParseConfigFromJson(content string) *Config {
var config Config
if err := json.Unmarshal([]byte(content), &config); err != nil {
panic(err)
}

config.Validate()

return &config
}

Expand Down
1 change: 0 additions & 1 deletion config/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
"gas_limit": 1000,
"fee_amount": "5000000000000",
"fee_denom": "BNB",
"no_simulate": true,
"deduplication_interval": 100
},
"log_config": {
Expand Down
2 changes: 1 addition & 1 deletion db/model/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ const (
Submitted
SelfAttested
Attested // Event has been submitted for tx
Expired // Event has been expired
Duplicated
)

Expand All @@ -52,4 +51,5 @@ const (
Unknown VerifyResult = iota // Event not been verified
HashMatched // The challenge failed, hashes are matched
HashMismatched // The challenge succeed, hashed are not matched
BucketDeleted
)
1 change: 0 additions & 1 deletion executor/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
const (
UpdateCachedValidatorsInterval = 1 * time.Minute
QueryHeartbeatIntervalInterval = 120 * time.Minute // blockchain challenge heartbeat interval only changed by governance
QueryAttestedChallengeInterval = 5 * time.Second // query last attested challenge id

VotePoolBroadcastMethodName = "broadcast_vote"
VotePoolBroadcastParameterKey = "vote"
Expand Down
43 changes: 18 additions & 25 deletions executor/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,10 @@ import (
"github.com/bnb-chain/greenfield-challenger/config"
"github.com/bnb-chain/greenfield-challenger/logging"
"github.com/bnb-chain/greenfield-go-sdk/types"
tm "github.com/bnb-chain/greenfield/sdk/client"
types2 "github.com/bnb-chain/greenfield/sdk/types"
challangetypes "github.com/bnb-chain/greenfield/x/challenge/types"
sdktypes "github.com/bnb-chain/greenfield/sdk/types"
challengetypes "github.com/bnb-chain/greenfield/x/challenge/types"
coretypes "github.com/cometbft/cometbft/rpc/core/types"
ctypes "github.com/cometbft/cometbft/rpc/core/types"
tmjsonrpcclient "github.com/cometbft/cometbft/rpc/jsonrpc/client"
tmtypes "github.com/cometbft/cometbft/types"
"github.com/cometbft/cometbft/votepool"
sdk "github.com/cosmos/cosmos-sdk/types"
Expand Down Expand Up @@ -79,20 +77,6 @@ func NewExecutor(cfg *config.Config) *Executor {
}
}

func NewTendermintRPCClient(provider string) *tm.TendermintClient {
rpcClient := tm.NewTendermintClient(provider)
return &rpcClient
}

func NewTendermintJsonRPCClient(provider string) (*tmjsonrpcclient.Client, error) {
rpcClient, err := tmjsonrpcclient.New(provider)
if err != nil {
logging.Logger.Errorf("executor failed to initiate with tendermint json rpc client, err=%s", err.Error())
return nil, err
}
return rpcClient, nil
}

func getGreenfieldPrivateKey(cfg *config.GreenfieldConfig) string {
if cfg.KeyType == config.KeyTypeAWSPrivateKey {
result, err := config.GetSecret(cfg.AWSSecretName, cfg.AWSRegion)
Expand Down Expand Up @@ -227,22 +211,26 @@ func (e *Executor) GetValidatorsBlsPublicKey() ([]string, error) {
return keys, nil
}

func (e *Executor) QueryInturnAttestationSubmitter() (*challangetypes.QueryInturnAttestationSubmitterResponse, error) {
func (e *Executor) QueryInturnAttestationSubmitter() (*challengetypes.QueryInturnAttestationSubmitterResponse, error) {
client := e.clients.GetClient().Client
res, err := client.InturnAttestationSubmitter(context.Background(), &challangetypes.QueryInturnAttestationSubmitterRequest{})
res, err := client.InturnAttestationSubmitter(context.Background(), &challengetypes.QueryInturnAttestationSubmitterRequest{})
if err != nil {
logging.Logger.Errorf("executor failed to get inturn attestation submitter, err=%+v", err.Error())
return nil, err
}
return res, nil
}

func (e *Executor) AttestChallenge(submitterAddress, challengerAddress, spOperatorAddress string, challengeId uint64, objectId sdkmath.Uint, voteResult challangetypes.VoteResult, voteValidatorSet []uint64, VoteAggSignature []byte, txOption types2.TxOption) (bool, error) {
func (e *Executor) AttestChallenge(submitterAddress, challengerAddress, spOperatorAddress string, challengeId uint64, objectId sdkmath.Uint, voteResult challengetypes.VoteResult, voteValidatorSet []uint64, VoteAggSignature []byte, txOption sdktypes.TxOption) (bool, error) {
client := e.clients.GetClient().Client
logging.Logger.Infof("attest challenge params: submitterAddress=%s, challengerAddress=%s, spOperatorAddress=%s, challengeId=%d, objectId=%s, voteResult=%s, voteValidatorSet=%+v, VoteAggSignature=%+v, txOption=%+v", submitterAddress, challengerAddress, spOperatorAddress, challengeId, objectId.String(), voteResult.String(), voteValidatorSet, VoteAggSignature, txOption)
res, err := client.AttestChallenge(context.Background(), submitterAddress, challengerAddress, spOperatorAddress, challengeId, objectId, voteResult, voteValidatorSet, VoteAggSignature, txOption)
if err != nil {
logging.Logger.Infof("challengeId: %d attest failed, code=%d, log=%s, txhash=%s, timestamp: %s, err=%s", challengeId, res.Code, res.RawLog, res.TxHash, time.Now().Format("15:04:05.000000"), err.Error())
if res == nil {
logging.Logger.Infof("attest failed for challengeId: %d, res is nil", challengeId)
} else {
logging.Logger.Infof("challengeId: %d attest failed, code=%d, log=%s, txhash=%s, timestamp: %s, err=%s", challengeId, res.Code, res.RawLog, res.TxHash, time.Now().Format("15:04:05.000000"), err.Error())
}
return false, err
}
if res.Code != 0 {
Expand All @@ -256,18 +244,23 @@ func (e *Executor) AttestChallenge(submitterAddress, challengerAddress, spOperat
func (e *Executor) QueryLatestAttestedChallengeIds() ([]uint64, error) {
client := e.clients.GetClient().Client

res, err := client.LatestAttestedChallenges(context.Background(), &challangetypes.QueryLatestAttestedChallengesRequest{})
res, err := client.LatestAttestedChallenges(context.Background(), &challengetypes.QueryLatestAttestedChallengesRequest{})
if err != nil {
logging.Logger.Errorf("executor failed to get latest attested challenge, err=%+v", err.Error())
return nil, err
}

return res, nil
var challengeIds []uint64
for _, v := range res.GetChallenges() {
challengeIds = append(challengeIds, v.GetId())
}

return challengeIds, nil
}

func (e *Executor) queryChallengeHeartbeatInterval() (uint64, error) {
client := e.clients.GetClient().Client
q := challangetypes.QueryParamsRequest{}
q := challengetypes.QueryParamsRequest{}
res, err := client.ChallengeParams(context.Background(), &q)
if err != nil {
logging.Logger.Errorf("executor failed to get latest heartbeat interval, err=%+v", err.Error())
Expand Down
Loading

0 comments on commit 8aba141

Please sign in to comment.