Skip to content

Commit

Permalink
upgrading
Browse files Browse the repository at this point in the history
  • Loading branch information
jberci committed Jan 29, 2020
1 parent c655130 commit 5720e6b
Show file tree
Hide file tree
Showing 16 changed files with 766 additions and 13 deletions.
7 changes: 7 additions & 0 deletions go/common/persistent/persistent.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,13 @@ func (ss *ServiceStore) PutCBOR(key []byte, value interface{}) error {
})
}

// Delete removes the specified key from the service store.
func (ss *ServiceStore) Delete(key []byte) error {
return ss.store.db.Update(func(tx *badger.Txn) error {
return tx.Delete(ss.dbKey(key))
})
}

func (ss *ServiceStore) dbKey(key []byte) []byte {
return bytes.Join([][]byte{ss.name, key}, []byte{'.'})
}
29 changes: 24 additions & 5 deletions go/consensus/tendermint/abci/mux.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import (
"github.com/oasislabs/oasis-core/go/consensus/tendermint/db"
epochtime "github.com/oasislabs/oasis-core/go/epochtime/api"
genesis "github.com/oasislabs/oasis-core/go/genesis/api"
upgrade "github.com/oasislabs/oasis-core/go/upgrade/api"
)

const (
Expand Down Expand Up @@ -270,12 +271,12 @@ func (a *ApplicationServer) EstimateGas(caller signature.PublicKey, tx *transact

// NewApplicationServer returns a new ApplicationServer, using the provided
// directory to persist state.
func NewApplicationServer(ctx context.Context, cfg *ApplicationConfig) (*ApplicationServer, error) {
func NewApplicationServer(ctx context.Context, upgrader upgrade.Backend, cfg *ApplicationConfig) (*ApplicationServer, error) {
metricsOnce.Do(func() {
prometheus.MustRegister(abciCollectors...)
})

mux, err := newABCIMux(ctx, cfg)
mux, err := newABCIMux(ctx, upgrader, cfg)
if err != nil {
return nil, err
}
Expand All @@ -290,8 +291,9 @@ type abciMux struct {
sync.RWMutex
types.BaseApplication

logger *logging.Logger
state *ApplicationState
logger *logging.Logger
upgrader upgrade.Backend
state *ApplicationState

appsByName map[string]Application
appsByMethod map[transaction.MethodName]Application
Expand Down Expand Up @@ -461,6 +463,11 @@ func (mux *abciMux) InitChain(req types.RequestInitChain) types.ResponseInitChai
return resp
}

func (s *ApplicationState) currentEpoch(ctx *Context) (epochtime.EpochTime, error) {
blockHeight := s.BlockHeight()
return s.GetEpoch(ctx.Ctx(), blockHeight+1)
}

func (s *ApplicationState) inHaltEpoch(ctx *Context) bool {
blockHeight := s.BlockHeight()

Expand Down Expand Up @@ -493,6 +500,7 @@ func (s *ApplicationState) afterHaltEpoch(ctx *Context) bool {

func (mux *abciMux) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginBlock {
blockHeight := mux.state.BlockHeight()

mux.logger.Debug("BeginBlock",
"req", req,
"block_height", blockHeight,
Expand All @@ -516,6 +524,16 @@ func (mux *abciMux) BeginBlock(req types.RequestBeginBlock) types.ResponseBeginB
ctx := NewContext(ContextBeginBlock, mux.currentTime, mux.state)
defer ctx.Close()

// Check if we need to halt for upgrade.
currentEpoch, err := mux.state.currentEpoch(ctx)
if err == nil && !mux.upgrader.IsEpochBeforeUpgrade(currentEpoch) {
panic("mux: reached upgrade epoch")
}
// Or perhaps if there are upgrades to do.
if err = mux.upgrader.ConsensusUpgrade(); err != nil {
panic("mux: error while trying to perform consensus upgrade")
}

switch mux.state.haltMode {
case false:
if !mux.state.inHaltEpoch(ctx) {
Expand Down Expand Up @@ -903,14 +921,15 @@ func (mux *abciMux) checkDependencies() error {
return nil
}

func newABCIMux(ctx context.Context, cfg *ApplicationConfig) (*abciMux, error) {
func newABCIMux(ctx context.Context, upgrader upgrade.Backend, cfg *ApplicationConfig) (*abciMux, error) {
state, err := newApplicationState(ctx, cfg)
if err != nil {
return nil, err
}

mux := &abciMux{
logger: logging.GetLogger("abci-mux"),
upgrader: upgrader,
state: state,
appsByName: make(map[string]Application),
appsByMethod: make(map[transaction.MethodName]Application),
Expand Down
7 changes: 5 additions & 2 deletions go/consensus/tendermint/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import (
roothashAPI "github.com/oasislabs/oasis-core/go/roothash/api"
schedulerAPI "github.com/oasislabs/oasis-core/go/scheduler/api"
stakingAPI "github.com/oasislabs/oasis-core/go/staking/api"
upgradeAPI "github.com/oasislabs/oasis-core/go/upgrade/api"
)

const (
Expand Down Expand Up @@ -164,6 +165,7 @@ type tendermintService struct {

ctx context.Context
svcMgr *cmbackground.ServiceManager
upgrader upgradeAPI.Backend
mux *abci.ApplicationServer
node *tmnode.Node
client tmcli.Client
Expand Down Expand Up @@ -880,7 +882,7 @@ func (t *tendermintService) lazyInit() error {
MinGasPrice: viper.GetUint64(CfgConsensusMinGasPrice),
OwnTxSigner: t.nodeSigner.Public(),
}
t.mux, err = abci.NewApplicationServer(t.ctx, appConfig)
t.mux, err = abci.NewApplicationServer(t.ctx, t.upgrader, appConfig)
if err != nil {
return err
}
Expand Down Expand Up @@ -1164,7 +1166,7 @@ func (t *tendermintService) worker() {
}

// New creates a new Tendermint service.
func New(ctx context.Context, dataDir string, identity *identity.Identity, genesisProvider genesisAPI.Provider) (service.TendermintService, error) {
func New(ctx context.Context, dataDir string, identity *identity.Identity, upgrader upgradeAPI.Backend, genesisProvider genesisAPI.Provider) (service.TendermintService, error) {
// Retrive the genesis document early so that it is possible to
// use it while initializing other things.
genesisDoc, err := genesisProvider.GetGenesisDocument()
Expand All @@ -1183,6 +1185,7 @@ func New(ctx context.Context, dataDir string, identity *identity.Identity, genes
t := &tendermintService{
BaseBackgroundService: *cmservice.NewBaseBackgroundService("tendermint"),
svcMgr: cmbackground.NewServiceManager(logging.GetLogger("tendermint/servicemanager")),
upgrader: upgrader,
blockNotifier: pubsub.NewBroker(false),
consensusSigner: identity.ConsensusSigner,
nodeSigner: identity.NodeSigner,
Expand Down
5 changes: 5 additions & 0 deletions go/control/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ type NodeController interface {
// IsSynced checks whether the node has finished syncing.
// TODO: These should be replaced with IsReady (see oasis-core#2130).
IsSynced(ctx context.Context) (bool, error)

// UpgradeBinary submits an upgrade descriptor to a running node.
// The node will wait for the appropriate epoch, then update its binaries
// and shut down.
UpgradeBinary(ctx context.Context, descriptor []byte) error
}

// Shutdownable is an interface the node presents for shutting itself down.
Expand Down
33 changes: 33 additions & 0 deletions go/control/api/grpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ var (
methodWaitSync = serviceName.NewMethod("WaitSync", nil)
// methodIsSynced is the IsSynced method.
methodIsSynced = serviceName.NewMethod("IsSynced", nil)
// methodUpgradeBinary is the UpgradeBinary method.
methodUpgradeBinary = serviceName.NewMethod("UpgradeBinary", []byte{})

// serviceDesc is the gRPC service descriptor.
serviceDesc = grpc.ServiceDesc{
Expand All @@ -36,6 +38,10 @@ var (
MethodName: methodIsSynced.ShortName(),
Handler: handlerIsSynced,
},
{
MethodName: methodUpgradeBinary.ShortName(),
Handler: handlerUpgradeBinary,
},
},
Streams: []grpc.StreamDesc{},
}
Expand Down Expand Up @@ -102,6 +108,29 @@ func handlerIsSynced( // nolint: golint
return interceptor(ctx, nil, info, handler)
}

func handlerUpgradeBinary( // nolint: golint
srv interface{},
ctx context.Context,
dec func(interface{}) error,
interceptor grpc.UnaryServerInterceptor,
) (interface{}, error) {
var descriptor []byte
if err := dec(&descriptor); err != nil {
return nil, err
}
if interceptor == nil {
return nil, srv.(NodeController).UpgradeBinary(ctx, descriptor)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: methodUpgradeBinary.FullName(),
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return nil, srv.(NodeController).UpgradeBinary(ctx, req.([]byte))
}
return interceptor(ctx, descriptor, info, handler)
}

// RegisterService registers a new node controller service with the given gRPC server.
func RegisterService(server *grpc.Server, service NodeController) {
server.RegisterService(&serviceDesc, service)
Expand All @@ -127,6 +156,10 @@ func (c *nodeControllerClient) IsSynced(ctx context.Context) (bool, error) {
return rsp, nil
}

func (c *nodeControllerClient) UpgradeBinary(ctx context.Context, descriptor []byte) error {
return c.conn.Invoke(ctx, methodUpgradeBinary.FullName(), descriptor, nil)
}

// NewNodeControllerClient creates a new gRPC node controller client service.
func NewNodeControllerClient(c *grpc.ClientConn) NodeController {
return &nodeControllerClient{c}
Expand Down
15 changes: 12 additions & 3 deletions go/control/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ package control

import (
"context"
"fmt"

consensus "github.com/oasislabs/oasis-core/go/consensus/api"
"github.com/oasislabs/oasis-core/go/control/api"
control "github.com/oasislabs/oasis-core/go/control/api"
upgrade "github.com/oasislabs/oasis-core/go/upgrade/api"
)

type nodeController struct {
node api.Shutdownable
node control.Shutdownable
consensus consensus.Backend
upgrader upgrade.Backend
}

func (c *nodeController) RequestShutdown(ctx context.Context, wait bool) error {
Expand Down Expand Up @@ -49,10 +52,16 @@ func (c *nodeController) IsSynced(ctx context.Context) (bool, error) {
}
}

func (c *nodeController) UpgradeBinary(ctx context.Context, descriptor []byte) error {
return c.upgrader.SubmitDescriptor(ctx, descriptor)
}

// New creates a new oasis-node controller.
func New(node api.Shutdownable, consensus consensus.Backend) api.NodeController {
func New(node control.Shutdownable, consensus consensus.Backend, upgrader upgrade.Backend) control.NodeController {
fmt.Println("node controller interface created")
return &nodeController{
node: node,
consensus: consensus,
upgrader: upgrader,
}
}
1 change: 1 addition & 0 deletions go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ require (
github.com/pelletier/go-toml v1.4.0 // indirect
github.com/pkg/errors v0.8.1
github.com/prometheus/client_golang v0.9.4
github.com/qri-io/jsonschema v0.1.1
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a // indirect
github.com/remyoudompheng/bigfft v0.0.0-20190512091148-babf20351dd7 // indirect
github.com/seccomp/libseccomp-golang v0.9.1
Expand Down
5 changes: 5 additions & 0 deletions go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,10 @@ github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7z
github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/qri-io/jsonpointer v0.1.0 h1:OcTtTmorodUCRc2CZhj/ZwOET8zVj6uo0ArEmzoThZI=
github.com/qri-io/jsonpointer v0.1.0/go.mod h1:DnJPaYgiKu56EuDp8TU5wFLdZIcAnb/uH9v37ZaMV64=
github.com/qri-io/jsonschema v0.1.1 h1:t//Doa/gvMqJ0bDhG7PGIKfaWGGxRVaffp+bcvBGGEk=
github.com/qri-io/jsonschema v0.1.1/go.mod h1:QpzJ6gBQ0GYgGmh7mDQ1YsvvhSgE4rYj0k8t5MBOmUY=
github.com/rcrowley/go-metrics v0.0.0-20180503174638-e2704e165165/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ=
github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
Expand All @@ -408,6 +412,7 @@ github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/seccomp/libseccomp-golang v0.9.1 h1:NJjM5DNFOs0s3kYE1WUOr6G8V97sdt46rlXTMfXGWBo=
github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
Expand Down
30 changes: 30 additions & 0 deletions go/oasis-node/cmd/control/control.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package control

import (
"context"
"io/ioutil"
"os"

"github.com/spf13/cobra"
Expand Down Expand Up @@ -40,6 +41,13 @@ var (
Run: doShutdown,
}

controlUpgradeBinaryCmd = &cobra.Command{
Use: "upgrade-binary <upgrade-descriptor>",
Short: "submit an upgrade descriptor to the node and request shutdown",
Args: cobra.ExactArgs(1),
Run: doUpgradeBinary,
}

logger = logging.GetLogger("cmd/control")
)

Expand Down Expand Up @@ -112,6 +120,27 @@ func doShutdown(cmd *cobra.Command, args []string) {
}
}

func doUpgradeBinary(cmd *cobra.Command, args []string) {
conn, client := DoConnect(cmd)
defer conn.Close()

descriptor, err := ioutil.ReadFile(args[0])
if err != nil {
logger.Error("failed to read upgrade descriptor",
"err", err,
)
os.Exit(1)
}

err = client.UpgradeBinary(context.Background(), descriptor)
if err != nil {
logger.Error("error while sending upgrade descriptor to the node",
"err", err,
)
os.Exit(1)
}
}

// Register registers the client sub-command and all of it's children.
func Register(parentCmd *cobra.Command) {
controlCmd.PersistentFlags().AddFlagSet(cmdGrpc.ClientFlags)
Expand All @@ -121,5 +150,6 @@ func Register(parentCmd *cobra.Command) {
controlCmd.AddCommand(controlIsSyncedCmd)
controlCmd.AddCommand(controlWaitSyncCmd)
controlCmd.AddCommand(controlShutdownCmd)
controlCmd.AddCommand(controlUpgradeBinaryCmd)
parentCmd.AddCommand(controlCmd)
}
2 changes: 1 addition & 1 deletion go/oasis-node/cmd/debug/byzantine/tendermint.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ func (ht *honestTendermint) start(id *identity.Identity, dataDir string) error {
}
genesisDoc.SetChainContext()

ht.service, err = tendermint.New(context.Background(), dataDir, id, genesis)
ht.service, err = tendermint.New(context.Background(), dataDir, id, nil, genesis) // XXX
if err != nil {
return errors.Wrap(err, "tendermint New")
}
Expand Down
Loading

0 comments on commit 5720e6b

Please sign in to comment.