Skip to content

Commit

Permalink
go: add byzantine subcommand
Browse files Browse the repository at this point in the history
  • Loading branch information
pro-wh committed Aug 19, 2019
1 parent 95fce87 commit 98785a6
Show file tree
Hide file tree
Showing 4 changed files with 193 additions and 1 deletion.
54 changes: 54 additions & 0 deletions go/ekiden/cmd/debug/byzantine/byzantine.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package byzantine

import (
"fmt"

"github.com/spf13/cobra"

"github.com/oasislabs/ekiden/go/common/logging"
"github.com/oasislabs/ekiden/go/ekiden/cmd/common"
"github.com/oasislabs/ekiden/go/genesis"
"github.com/oasislabs/ekiden/go/tendermint"
)

var (
logger = logging.GetLogger("cmd/byzantine")
byzantineCmd = &cobra.Command{
Use: "byzantine",
Short: "run some node behaviors for testing, often not honest",
}
computeHonestCmd = &cobra.Command{
Use: "compute-honest",
Short: "act as an honest compute worker",
Run: doComputeHonest,
}
)

func doComputeHonest(cmd *cobra.Command, args []string) {
if err := common.Init(); err != nil {
common.EarlyLogAndExit(err)
}

var ht honestTendermint
if err := ht.start(); err != nil {
panic(fmt.Sprintf("honest Tendermint start failed: %+v", err))
}
defer func() {
if err := ht.stop(); err != nil {
panic(fmt.Sprintf("honest Tendermint stop failed: %+v", err))
}
}()

logger.Warn("compute honest: mostly not implemented")
}

// Register registers the byzantine sub-command and all of its children.
func Register(parentCmd *cobra.Command) {
byzantineCmd.AddCommand(computeHonestCmd)
parentCmd.AddCommand(byzantineCmd)
}

func init() {
computeHonestCmd.Flags().AddFlagSet(genesis.Flags)
computeHonestCmd.Flags().AddFlagSet(tendermint.Flags)
}
136 changes: 136 additions & 0 deletions go/ekiden/cmd/debug/byzantine/steps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package byzantine

import (
"context"
"time"

"github.com/pkg/errors"

beacon "github.com/oasislabs/ekiden/go/beacon/api"
"github.com/oasislabs/ekiden/go/common/crypto/signature"
fileSigner "github.com/oasislabs/ekiden/go/common/crypto/signature/signers/file"
"github.com/oasislabs/ekiden/go/common/identity"
"github.com/oasislabs/ekiden/go/common/pubsub"
"github.com/oasislabs/ekiden/go/ekiden/cmd/common"
"github.com/oasislabs/ekiden/go/epochtime/api"
"github.com/oasislabs/ekiden/go/genesis"
registry "github.com/oasislabs/ekiden/go/registry/api"
scheduler "github.com/oasislabs/ekiden/go/scheduler/api"
"github.com/oasislabs/ekiden/go/tendermint"
beaconapp "github.com/oasislabs/ekiden/go/tendermint/apps/beacon"
keymanagerapp "github.com/oasislabs/ekiden/go/tendermint/apps/keymanager"
registryapp "github.com/oasislabs/ekiden/go/tendermint/apps/registry"
roothashapp "github.com/oasislabs/ekiden/go/tendermint/apps/roothash"
schedulerapp "github.com/oasislabs/ekiden/go/tendermint/apps/scheduler"
stakingapp "github.com/oasislabs/ekiden/go/tendermint/apps/staking"
"github.com/oasislabs/ekiden/go/tendermint/service"
)

var _ api.Backend = (*fakeTimeBackend)(nil)

// fakeTimeBackend is like TendermintBackend (of epochtime), but without
// any workers.
type fakeTimeBackend struct{}

// GetEpoch implements epochtime Backend.
func (*fakeTimeBackend) GetEpoch(ctx context.Context, height int64) (api.EpochTime, error) {
if height == 0 {
panic("0 height not supported")
}
return api.EpochTime(height / 30), nil
}

// GetEpochBlock implements epochtime Backend.
func (*fakeTimeBackend) GetEpochBlock(ctx context.Context, epoch api.EpochTime) (int64, error) {
panic("GetEpochBlock not supported")
// return int64(epoch) * 30, nil
}

// WatchEpochs implements epochtime Backend.
func (*fakeTimeBackend) WatchEpochs() (<-chan api.EpochTime, *pubsub.Subscription) {
panic("WatchEpochs not supported")
}

type honestTendermint struct {
service service.TendermintService
}

func (ht *honestTendermint) start() error {
if ht.service != nil {
return errors.New("honest Tendermint service already started")
}

dataDir := common.DataDir()
signerFactory := fileSigner.NewFactory(dataDir, signature.SignerNode, signature.SignerP2P, signature.SignerEntity)
identity, err := identity.LoadOrGenerate(dataDir, signerFactory)
if err != nil {
return errors.Wrap(err, "identity LoadOrGenerate")
}
genesis, err := genesis.New(identity)
if err != nil {
return errors.Wrap(err, "genesis New")
}
ht.service = tendermint.New(context.Background(), dataDir, identity, genesis)

if err := ht.service.ForceInitialize(); err != nil {
return errors.Wrap(err, "honest Tendermint service ForceInitialize")
}

// Register honest mux apps.
// This isn't very flexible. It's configured to match what we use in end-to-end tests.
// And we do that mostly by hardcoding options. We could make this more flexible with command
// line flags in future work.
timeSource := &fakeTimeBackend{}
// Tendermint epochtime has no registration
if err := ht.service.RegisterApplication(beaconapp.New(timeSource, &beacon.Config{
DebugDeterministic: true,
})); err != nil {
return errors.Wrap(err, "honest Tendermint service RegisterApplication beacon")
}
if err := ht.service.RegisterApplication(stakingapp.New(nil)); err != nil {
return errors.Wrap(err, "honest Tendermint service RegisterApplication staking")
}
if err := ht.service.RegisterApplication(registryapp.New(timeSource, &registry.Config{
DebugAllowRuntimeRegistration: false,
DebugBypassStake: false,
})); err != nil {
return errors.Wrap(err, "honest Tendermint service RegisterApplication registry")
}
if err := ht.service.RegisterApplication(keymanagerapp.New(timeSource)); err != nil {
return errors.Wrap(err, "honest Tendermint service RegisterApplication keymanager")
}
if err := ht.service.RegisterApplication(schedulerapp.New(timeSource, &scheduler.Config{
DebugBypassStake: false,
})); err != nil {
return errors.Wrap(err, "honest Tendermint service RegisterApplication scheduler")
}
// storage has no registration
if err := ht.service.RegisterApplication(roothashapp.New(context.Background(), timeSource, nil, 10*time.Second)); err != nil {
return errors.Wrap(err, "honest Tendermint service RegisterApplication roothash")
}

if err := ht.service.Start(); err != nil {
return errors.Wrap(err, "honest Tendermint service Start")
}
logger.Debug("honest Tendermint service waiting for Tendermint start")
<-ht.service.Started()
logger.Debug("honest Tendermint service waiting for Tendermint sync")
<-ht.service.Synced()
logger.Debug("honest Tendermint service sync done")

return nil
}

func (ht honestTendermint) stop() error {
if ht.service == nil {
return errors.New("honest Tendermint service not started")
}

ht.service.Stop()
logger.Debug("honest Tendermint service waiting for quit")
<-ht.service.Quit()
logger.Debug("honest Tendermint service quit done")
ht.service = nil

return nil
}
2 changes: 2 additions & 0 deletions go/ekiden/cmd/debug/debug.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package debug
import (
"github.com/spf13/cobra"

"github.com/oasislabs/ekiden/go/ekiden/cmd/debug/byzantine"
"github.com/oasislabs/ekiden/go/ekiden/cmd/debug/client"
"github.com/oasislabs/ekiden/go/ekiden/cmd/debug/dummy"
"github.com/oasislabs/ekiden/go/ekiden/cmd/debug/roothash"
Expand All @@ -21,6 +22,7 @@ func Register(parentCmd *cobra.Command) {
dummy.Register(debugCmd)
roothash.Register(debugCmd)
tendermint.Register(debugCmd)
byzantine.Register(debugCmd)

parentCmd.AddCommand(debugCmd)
}
2 changes: 1 addition & 1 deletion go/ekiden/cmd/debug/dummy/dummy.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func doWaitNodes(cmd *cobra.Command, args []string) {
logger.Info("enough nodes have been registered")
}

// Register registers the dummy sub-command and all of it's children.
// Register registers the dummy sub-command and all of its children.
func Register(parentCmd *cobra.Command) {
cmdGrpc.RegisterClientFlags(dummyCmd, true)
dummySetEpochCmd.Flags().Uint64VarP(&epoch, "epoch", "e", 0, "set epoch to given value")
Expand Down

0 comments on commit 98785a6

Please sign in to comment.