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
2 changes: 2 additions & 0 deletions client/cmd/kcoin/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,9 @@ func makeConfigNode(ctx *cli.Context) (*node.Node, kcoinConfig) {
if err != nil {
utils.Fatalf("Failed to create the protocol stack: %v", err)
}

utils.SetKowalaConfig(ctx, stack, &cfg.Kowala)

if ctx.GlobalIsSet(utils.KowalaStatsURLFlag.Name) {
cfg.Stats.URL = ctx.GlobalString(utils.KowalaStatsURLFlag.Name)
}
Expand Down
4 changes: 2 additions & 2 deletions client/cmd/kcoin/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ import (
"github.com/kowala-tech/kcoin/client/log"
"github.com/kowala-tech/kcoin/client/metrics"
"github.com/kowala-tech/kcoin/client/node"
"gopkg.in/urfave/cli.v1"
"github.com/kowala-tech/kcoin/client/version"
"github.com/kowala-tech/kcoin/client/params"
"github.com/kowala-tech/kcoin/client/version"
"gopkg.in/urfave/cli.v1"
)

const (
Expand Down
10 changes: 7 additions & 3 deletions client/cmd/utils/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,11 @@ import (
"strings"
"time"

"github.com/kowala-tech/kcoin/client/consensus/konsensus"
"github.com/kowala-tech/kcoin/client/stats"

"github.com/kowala-tech/kcoin/client/accounts"
"github.com/kowala-tech/kcoin/client/accounts/keystore"
"github.com/kowala-tech/kcoin/client/common"
"github.com/kowala-tech/kcoin/client/common/fdlimit"
"github.com/kowala-tech/kcoin/client/consensus/konsensus"
"github.com/kowala-tech/kcoin/client/core"
"github.com/kowala-tech/kcoin/client/core/state"
"github.com/kowala-tech/kcoin/client/core/vm"
Expand All @@ -26,6 +24,7 @@ import (
"github.com/kowala-tech/kcoin/client/knode"
"github.com/kowala-tech/kcoin/client/knode/downloader"
"github.com/kowala-tech/kcoin/client/knode/gasprice"
"github.com/kowala-tech/kcoin/client/knode/validator"
"github.com/kowala-tech/kcoin/client/log"
"github.com/kowala-tech/kcoin/client/metrics"
"github.com/kowala-tech/kcoin/client/metrics/influxdb"
Expand All @@ -36,6 +35,7 @@ import (
"github.com/kowala-tech/kcoin/client/p2p/nat"
"github.com/kowala-tech/kcoin/client/p2p/netutil"
"github.com/kowala-tech/kcoin/client/params"
"github.com/kowala-tech/kcoin/client/stats"

"gopkg.in/urfave/cli.v1"
)
Expand Down Expand Up @@ -1006,6 +1006,10 @@ func SetKowalaConfig(ctx *cli.Context, stack *node.Node, cfg *knode.Config) {
if gen := ctx.GlobalInt(TrieCacheGenFlag.Name); gen > 0 {
state.MaxTrieCacheGen = uint16(gen)
}

cfg.ValidatorConfig = &validator.Config{
LogDir: filepath.Join(stack.DataDir(), "log"),
}
}

// RegisterKowalaService adds a Kowala client to the stack.
Expand Down
3 changes: 3 additions & 0 deletions client/knode/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
"github.com/kowala-tech/kcoin/client/knode/currency"
"github.com/kowala-tech/kcoin/client/knode/downloader"
"github.com/kowala-tech/kcoin/client/knode/gasprice"
"github.com/kowala-tech/kcoin/client/knode/validator"
"github.com/kowala-tech/kcoin/client/params"
)

Expand Down Expand Up @@ -73,6 +74,8 @@ type Config struct {
DocRoot string `toml:"-"`

Currency string

ValidatorConfig *validator.Config
}

type configMarshaling struct {
Expand Down
7 changes: 7 additions & 0 deletions client/knode/gen_config.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion client/knode/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Kowala, error) {
if !config.SyncMode.IsValid() {
return nil, fmt.Errorf("invalid sync mode %d", config.SyncMode)
}

chainDb, err := CreateDB(ctx, config, "chaindata")
if err != nil {
return nil, err
Expand Down Expand Up @@ -196,7 +197,7 @@ func New(ctx *node.ServiceContext, config *Config) (*Kowala, error) {
}
kcoin.apiBackend.gpo = gasprice.NewOracle(kcoin.apiBackend, gpoParams)

kcoin.validator = validator.New(kcoin, kcoin.consensus, kcoin.chainConfig, kcoin.EventMux(), kcoin.engine, vmConfig)
kcoin.validator = validator.New(kcoin.config.ValidatorConfig, kcoin, kcoin.consensus, kcoin.chainConfig, kcoin.EventMux(), kcoin.engine, vmConfig)
kcoin.validator.SetExtra(makeExtraData(config.ExtraData))

if kcoin.protocolManager, err = NewProtocolManager(kcoin.chainConfig, config.SyncMode, config.NetworkId, kcoin.eventMux, kcoin.txPool, kcoin.engine, kcoin.blockchain, chainDb, kcoin.validator); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions client/knode/validator/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package validator

type Config struct {
LogDir string
}
61 changes: 30 additions & 31 deletions client/knode/validator/states.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/kowala-tech/kcoin/client/core"
"github.com/kowala-tech/kcoin/client/core/state"
"github.com/kowala-tech/kcoin/client/core/types"
"github.com/kowala-tech/kcoin/client/log"
"github.com/kowala-tech/kcoin/client/params"

"github.com/davecgh/go-spew/spew"
Expand All @@ -33,7 +32,7 @@ func (val *validator) genesisNotLoggedInState() stateFn {
// no need to make a deposit if the block number is 0
// since these validators will be marked as voters from the start
if val.isBlockZero() {
log.Info("Deposit is not necessary for a genesis validator (first block)")
val.logger.Info("Deposit is not necessary for a genesis validator (first block)")
return val.startValidating
}
return val.notLoggedInState
Expand All @@ -42,12 +41,12 @@ func (val *validator) genesisNotLoggedInState() stateFn {
func (val *validator) notLoggedInState() stateFn {
isValidator, err := val.consensus.IsValidator(val.walletAccount.Account().Address)
if err != nil {
log.Crit("Failed to verify if account is already a validator")
val.logger.Crit("Failed to verify if account is already a validator")
}

if !isValidator {
if err := val.makeDeposit(); err != nil {
log.Error("Failed to make deposit", "err", err)
val.logger.Error("Failed to make deposit", "err", err)
return nil
}
}
Expand All @@ -58,26 +57,26 @@ func (val *validator) notLoggedInState() stateFn {
func (val *validator) makeDeposit() error {
txHash, err := val.consensus.Join(val.walletAccount, val.deposit)
if err != nil {
log.Error("Error joining validators network", "err", err)
val.logger.Error("Error joining validators network", "err", err)
return nil
}
log.Info("Waiting confirmation to participate in the consensus")
val.logger.Info("Waiting confirmation to participate in the consensus")

receipt, err := tx.WaitMinedWithTimeout(val.backend, txHash, txConfirmationTimeout)
if err != nil {
log.Crit("Failed to verify the voter registration", "err", err)
val.logger.Crit("Failed to verify the voter registration", "err", err)
}
if receipt.Status == types.ReceiptStatusFailed {
log.Crit("Failed to register the validator - receipt status failed")
val.logger.Crit("Failed to register the validator - receipt status failed")
}
return nil
}

func (val *validator) startValidating() stateFn {
log.Info("Starting validation operation")
val.logger.Info("Starting validation operation")
atomic.StoreInt32(&val.validating, 1)

log.Info("Voter has been accepted in the election", "enode", val.walletAccount.Account().Address.String())
val.logger.Info("Voter has been accepted in the election", "enode", val.walletAccount.Account().Address.String())
val.restoreLastCommit()

return val.newElectionState
Expand All @@ -88,7 +87,7 @@ func (val *validator) isBlockZero() bool {
}

func (val *validator) newElectionState() stateFn {
log.Info("Starting a new election")
val.logger.Info("Starting a new election")
// update state machine based on current state
if err := val.init(); err != nil {
return nil
Expand All @@ -100,7 +99,7 @@ func (val *validator) newElectionState() stateFn {
if val.blockNumber.Cmp(big.NewInt(1)) == 0 {
numTxs, _ := val.backend.TxPool().Stats() //
if val.round == 0 && numTxs == 0 {
log.Info("Waiting for a TX")
val.logger.Info("Waiting for a TX")
txCh := make(chan core.NewTxsEvent)
txSub := val.backend.TxPool().SubscribeNewTxsEvent(txCh)
defer txSub.Unsubscribe()
Expand All @@ -112,7 +111,7 @@ func (val *validator) newElectionState() stateFn {
}

func (val *validator) newRoundState() stateFn {
log.Info("Starting a new voting round", "start time", val.start, "block number", val.blockNumber, "round", val.round)
val.logger.Info("Starting a new voting round", "start time", val.start, "block number", val.blockNumber, "round", val.round)

val.voters.NextProposer()

Expand All @@ -132,10 +131,10 @@ func (val *validator) newRoundState() stateFn {
func (val *validator) newProposalState() stateFn {
proposer := val.voters.NextProposer()
if proposer.Address() == val.walletAccount.Account().Address {
log.Info("Proposing a new block")
val.logger.Info("Proposing a new block")
val.propose()
} else {
log.Info("Waiting for the proposal", "addr", proposer.Address())
val.logger.Info("Waiting for the proposal", "addr", proposer.Address())
val.waitForProposal()
}
return val.preVoteState
Expand All @@ -146,62 +145,62 @@ func (val *validator) waitForProposal() {
select {
case block := <-val.blockCh:
val.block = block
log.Info("Received the block", "hash", val.block.Hash())
val.logger.Info("Received the block", "hash", val.block.Hash())
case <-time.After(timeout):
log.Info("Timeout expired", "duration", timeout)
val.logger.Info("Timeout expired", "duration", timeout)
}
}

func (val *validator) preVoteState() stateFn {
log.Info("Pre vote sub-election")
val.logger.Info("Pre vote sub-election")
val.preVote()

return val.preVoteWaitState
}

func (val *validator) preVoteWaitState() stateFn {
log.Info("Waiting for a majority in the pre-vote sub-election")
val.logger.Info("Waiting for a majority in the pre-vote sub-election")
timeout := time.Duration(params.PreVoteDuration+val.round*params.PreVoteDeltaDuration) * time.Millisecond

select {
case <-val.majority.Chan():
log.Info("There's a majority in the pre-vote sub-election!")
val.logger.Info("There's a majority in the pre-vote sub-election!")
// fixme shall we do something here with current stateDB?
case <-time.After(timeout):
log.Info("Timeout expired", "duration", timeout)
val.logger.Info("Timeout expired", "duration", timeout)
}

return val.preCommitState
}

func (val *validator) preCommitState() stateFn {
log.Info("Pre commit sub-election")
val.logger.Info("Pre commit sub-election")
val.preCommit()

return val.preCommitWaitState
}

func (val *validator) preCommitWaitState() stateFn {
log.Info("Waiting for a majority in the pre-commit sub-election")
val.logger.Info("Waiting for a majority in the pre-commit sub-election")
timeout := time.Duration(params.PreCommitDuration+val.round+params.PreCommitDeltaDuration) * time.Millisecond
defer val.majority.Unsubscribe()

select {
case event := <-val.majority.Chan():
log.Info("There's a majority in the pre-commit sub-election!", "event", spew.Sdump(event))
val.logger.Info("There's a majority in the pre-commit sub-election!", "event", spew.Sdump(event))
if val.block == nil || bytes.Equal(val.block.Hash().Bytes(), common.Hash{}.Bytes()) {
log.Debug("No one block wins!")
val.logger.Debug("No one block wins!")
return val.newRoundState
}
return val.commitState
case <-time.After(timeout):
log.Info("Timeout expired", "duration", timeout)
val.logger.Info("Timeout expired", "duration", timeout)
return val.newRoundState
}
}

func (val *validator) commitState() stateFn {
log.Info("Commit state")
val.logger.Info("Commit state")

blockHash := val.block.Hash()

Expand All @@ -218,7 +217,7 @@ func (val *validator) commitState() stateFn {

_, err := val.chain.WriteBlockWithState(val.block, val.work.receipts, val.work.state)
if err != nil {
log.Error("Failed writing block to chain", "err", err)
val.logger.Error("Failed writing block to chain", "err", err)
return nil
}

Expand All @@ -237,18 +236,18 @@ func (val *validator) commitState() stateFn {

voter, err := val.consensus.IsValidator(val.walletAccount.Account().Address)
if err != nil {
log.Crit("Failed to verify if the validator is a voter", "err", err)
val.logger.Crit("Failed to verify if the validator is a voter", "err", err)
}
if !voter {
log.Info(fmt.Sprintf("Logging out. Account %q is not a validator", val.walletAccount.Account().Address.String()))
val.logger.Info(fmt.Sprintf("Logging out. Account %q is not a validator", val.walletAccount.Account().Address.String()))
return val.loggedOutState
}

return val.newElectionState
}

func (val *validator) loggedOutState() stateFn {
log.Info("Logged out")
val.logger.Info("Logged out")

atomic.StoreInt32(&val.validating, 0)

Expand Down
Loading