Skip to content

Commit

Permalink
Merge pull request #1916 from oasislabs/pro-wh/feature/byzantine
Browse files Browse the repository at this point in the history
Tendermint state follower
  • Loading branch information
pro-wh authored Aug 21, 2019
2 parents 5c421e4 + 7060382 commit 0ce88d9
Show file tree
Hide file tree
Showing 23 changed files with 299 additions and 64 deletions.
2 changes: 1 addition & 1 deletion go/beacon/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ func New(ctx context.Context, timeSource epochtime.Backend, service service.Tend

// Initialize and register the tendermint service component.
app := app.New(timeSource, cfg)
if err := service.RegisterApplication(app, nil); err != nil {
if err := service.RegisterApplication(app); err != nil {
return nil, err
}

Expand Down
3 changes: 2 additions & 1 deletion go/common/crypto/signature/signers/file/file_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package file

import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
Expand Down Expand Up @@ -129,7 +130,7 @@ func (fac *Factory) doLoad(fn string) (signature.Signer, error) {
return nil, err
}
if fi.Mode().Perm() != filePerm {
return nil, errors.New("signature/signer/file: invalid PEM file permissions")
return nil, fmt.Errorf("signature/signer/file: invalid PEM file permissions %o on %s", fi.Mode(), fn)
}

buf, err := ioutil.ReadAll(f)
Expand Down
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)
}

ht := newHonestTendermint()
if err := ht.start(common.DataDir()); 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)
}
137 changes: 137 additions & 0 deletions go/ekiden/cmd/debug/byzantine/steps.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
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/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")
}

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

type honestTendermint struct {
service service.TendermintService
}

func newHonestTendermint() *honestTendermint {
return &honestTendermint{}
}

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

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
2 changes: 1 addition & 1 deletion go/epochtime/tendermint_mock/tendermint_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ func (t *tendermintMockBackend) updateCached(height int64, epoch api.EpochTime)
func New(ctx context.Context, service service.TendermintService) (api.SetableBackend, error) {
// Initialze and register the tendermint service component.
app := app.New()
if err := service.RegisterApplication(app, nil); err != nil {
if err := service.RegisterApplication(app); err != nil {
return nil, err
}

Expand Down
16 changes: 10 additions & 6 deletions go/genesis/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package genesis

import (
"github.com/spf13/cobra"
flag "github.com/spf13/pflag"
"github.com/spf13/viper"

"github.com/oasislabs/ekiden/go/common/identity"
Expand All @@ -11,6 +12,9 @@ import (

const cfgGenesisFile = "genesis.file"

// Flags has our flags.
var Flags = flag.NewFlagSet("", flag.ContinueOnError)

// New creates a new genesis document provider.
func New(identity *identity.Identity) (api.Provider, error) {
filename := viper.GetString(cfgGenesisFile)
Expand All @@ -22,12 +26,12 @@ func New(identity *identity.Identity) (api.Provider, error) {
// command.
func RegisterFlags(cmd *cobra.Command) {
if !cmd.Flags().Parsed() {
cmd.Flags().String(cfgGenesisFile, "genesis.json", "path to genesis file")
cmd.Flags().AddFlagSet(Flags)
}
}

for _, v := range []string{
cfgGenesisFile,
} {
viper.BindPFlag(v, cmd.Flags().Lookup(v)) //nolint: errcheck
}
func init() {
Flags.String(cfgGenesisFile, "genesis.json", "path to genesis file")

viper.BindPFlags(Flags) // nolint: errcheck
}
3 changes: 1 addition & 2 deletions go/keymanager/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"github.com/oasislabs/ekiden/go/keymanager/api"
tmapi "github.com/oasislabs/ekiden/go/tendermint/api"
app "github.com/oasislabs/ekiden/go/tendermint/apps/keymanager"
registryapp "github.com/oasislabs/ekiden/go/tendermint/apps/registry"
"github.com/oasislabs/ekiden/go/tendermint/service"
)

Expand Down Expand Up @@ -136,7 +135,7 @@ func (r *tendermintBackend) onEventDataNewBlock(ev tmtypes.EventDataNewBlock) {
// instance.
func New(ctx context.Context, timeSource epochtime.Backend, service service.TendermintService) (api.Backend, error) {
app := app.New(timeSource)
if err := service.RegisterApplication(app, []string{registryapp.AppName}); err != nil {
if err := service.RegisterApplication(app); err != nil {
return nil, errors.Wrap(err, "keymanager/tendermint: failed to register app")
}

Expand Down
3 changes: 1 addition & 2 deletions go/registry/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (
"github.com/oasislabs/ekiden/go/registry/api"
tmapi "github.com/oasislabs/ekiden/go/tendermint/api"
app "github.com/oasislabs/ekiden/go/tendermint/apps/registry"
stakingapp "github.com/oasislabs/ekiden/go/tendermint/apps/staking"
"github.com/oasislabs/ekiden/go/tendermint/service"
)

Expand Down Expand Up @@ -435,7 +434,7 @@ func (r *tendermintBackend) getNodeList(ctx context.Context, height int64) (*api
func New(ctx context.Context, timeSource epochtime.Backend, service service.TendermintService, cfg *api.Config) (api.Backend, error) {
// Initialize and register the tendermint service component.
app := app.New(timeSource, cfg)
if err := service.RegisterApplication(app, []string{stakingapp.AppName}); err != nil {
if err := service.RegisterApplication(app); err != nil {
return nil, err
}

Expand Down
3 changes: 1 addition & 2 deletions go/roothash/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/oasislabs/ekiden/go/roothash/api/commitment"
tmapi "github.com/oasislabs/ekiden/go/tendermint/api"
app "github.com/oasislabs/ekiden/go/tendermint/apps/roothash"
schedulerapp "github.com/oasislabs/ekiden/go/tendermint/apps/scheduler"
"github.com/oasislabs/ekiden/go/tendermint/service"
)

Expand Down Expand Up @@ -538,7 +537,7 @@ func New(
) (api.Backend, error) {
// Initialize and register the tendermint service component.
app := app.New(ctx, timeSource, beac, roundTimeout)
if err := service.RegisterApplication(app, []string{schedulerapp.AppName}); err != nil {
if err := service.RegisterApplication(app); err != nil {
return nil, err
}

Expand Down
5 changes: 1 addition & 4 deletions go/scheduler/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ import (
epochtime "github.com/oasislabs/ekiden/go/epochtime/api"
"github.com/oasislabs/ekiden/go/scheduler/api"
tmapi "github.com/oasislabs/ekiden/go/tendermint/api"
beaconapp "github.com/oasislabs/ekiden/go/tendermint/apps/beacon"
registryapp "github.com/oasislabs/ekiden/go/tendermint/apps/registry"
app "github.com/oasislabs/ekiden/go/tendermint/apps/scheduler"
stakingapp "github.com/oasislabs/ekiden/go/tendermint/apps/staking"
"github.com/oasislabs/ekiden/go/tendermint/service"
)

Expand Down Expand Up @@ -169,7 +166,7 @@ func New(ctx context.Context,
) (api.Backend, error) {
// Initialze and register the tendermint service component.
app := app.New(timeSource, cfg)
if err := service.RegisterApplication(app, []string{beaconapp.AppName, registryapp.AppName, stakingapp.AppName}); err != nil {
if err := service.RegisterApplication(app); err != nil {
return nil, err
}

Expand Down
2 changes: 1 addition & 1 deletion go/staking/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -344,7 +344,7 @@ func (b *tendermintBackend) onEventDataTx(ctx context.Context, ev tmtypes.EventD
func New(ctx context.Context, debugGenesisState *api.Genesis, service service.TendermintService) (api.Backend, error) {
// Initialize and register the tendermint service component.
app := app.New(debugGenesisState)
if err := service.RegisterApplication(app, nil); err != nil {
if err := service.RegisterApplication(app); err != nil {
return nil, err
}

Expand Down
Loading

0 comments on commit 0ce88d9

Please sign in to comment.