From a74728d200a0d816d7c447af88e57f3ac296ff49 Mon Sep 17 00:00:00 2001 From: Silas Davis <silas@monax.io> Date: Thu, 12 Apr 2018 10:16:06 -0400 Subject: [PATCH] Update to Tendermint 0.18.0 Signed-off-by: Silas Davis <silas@monax.io> --- Gopkg.lock | 2 +- Makefile | 1 + consensus/tendermint/abci/app.go | 29 +-- consensus/tendermint/config.go | 10 +- consensus/tendermint/query/node_view.go | 46 +--- consensus/tendermint/tendermint.go | 11 +- .../validator/priv_validator_memory.go | 10 +- consensus/tendermint/validator/sign_info.go | 240 ------------------ core/integration/test_wrapper.go | 1 + core/kernel.go | 4 +- execution/execution_test.go | 2 +- execution/state.go | 22 +- rpc/config.go | 4 +- rpc/result.go | 4 +- rpc/service.go | 4 +- rpc/tm/integration/websocket_helpers.go | 2 +- rpc/v0/server/config.go | 2 +- scripts/deps/bos.sh | 2 +- 18 files changed, 68 insertions(+), 328 deletions(-) delete mode 100644 consensus/tendermint/validator/sign_info.go diff --git a/Gopkg.lock b/Gopkg.lock index 89237cd1..afab6930 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -458,6 +458,6 @@ [solve-meta] analyzer-name = "dep" analyzer-version = 1 - inputs-digest = "f0aa0969c9ce0681dbbfa39ad409d574c3942cb4dcefcdec50e5ff4c5ffe908b" + inputs-digest = "0618ffbeb3a7333a1d9e7b24f256ac5b7719f25957d07cfd935156b355b2e5e2" solver-name = "gps-cdcl" solver-version = 1 diff --git a/Makefile b/Makefile index b932a961..a9575ca5 100644 --- a/Makefile +++ b/Makefile @@ -163,6 +163,7 @@ test_integration: .PHONY: test_integration_bosmarmot test_integration_bosmarmot: bos build_db cd "${BOSMARMOT_CHECKOUT}" &&\ + make npm_install && \ GOPATH="${BOSMARMOT_GOPATH}" \ burrow_bin="${REPO}/bin/burrow" \ make test_integration_no_burrow diff --git a/consensus/tendermint/abci/app.go b/consensus/tendermint/abci/app.go index 22cb095a..3a51a902 100644 --- a/consensus/tendermint/abci/app.go +++ b/consensus/tendermint/abci/app.go @@ -12,6 +12,7 @@ import ( "github.com/hyperledger/burrow/logging/structure" "github.com/hyperledger/burrow/project" "github.com/hyperledger/burrow/txs" + "github.com/pkg/errors" abci_types "github.com/tendermint/abci/types" "github.com/tendermint/go-wire" ) @@ -206,27 +207,19 @@ func (app *App) Commit() abci_types.ResponseCommit { appHash, err := app.committer.Commit() if err != nil { - return abci_types.ResponseCommit{ - Code: codes.CommitErrorCode, - Log: fmt.Sprintf("Could not commit transactions in block to execution state: %s", err), - } + panic(errors.Wrap(err, "Could not commit transactions in block to execution state")) + } // Commit to our blockchain state err = app.blockchain.CommitBlock(time.Unix(int64(app.block.Header.Time), 0), app.block.Hash, appHash) if err != nil { - return abci_types.ResponseCommit{ - Code: codes.CommitErrorCode, - Log: fmt.Sprintf("Could not commit block to blockchain state: %s", err), - } + panic(errors.Wrap(err, "could not commit block to blockchain state")) } err = app.checker.Reset() if err != nil { - return abci_types.ResponseCommit{ - Code: codes.CommitErrorCode, - Log: fmt.Sprintf("Could not reset check cache during commit: %s", err), - } + panic(errors.Wrap(err, "could not reset check cache during commit")) } // Perform a sanity check our block height @@ -235,16 +228,12 @@ func (app *App) Commit() abci_types.ResponseCommit { structure.ScopeKey, "Commit()", "burrow_height", app.blockchain.LastBlockHeight(), "tendermint_height", app.block.Header.Height) - return abci_types.ResponseCommit{ - Code: codes.CommitErrorCode, - Log: fmt.Sprintf("Burrow has recorded a block height of %v, "+ - "but Tendermint reports a block height of %v, and the two should agree.", - app.blockchain.LastBlockHeight(), app.block.Header.Height), - } + + panic(fmt.Errorf("burrow has recorded a block height of %v, "+ + "but Tendermint reports a block height of %v, and the two should agree", + app.blockchain.LastBlockHeight(), app.block.Header.Height)) } return abci_types.ResponseCommit{ - Code: codes.TxExecutionSuccessCode, Data: appHash, - Log: "Success - AppHash in data", } } diff --git a/consensus/tendermint/config.go b/consensus/tendermint/config.go index 304c5051..40491dcb 100644 --- a/consensus/tendermint/config.go +++ b/consensus/tendermint/config.go @@ -1,8 +1,6 @@ package tendermint import ( - "path" - tm_config "github.com/tendermint/tendermint/config" ) @@ -29,13 +27,13 @@ func (btc *BurrowTendermintConfig) TendermintConfig() *tm_config.Config { if btc != nil { // We may need to expose more of the P2P/Consensus/Mempool options, but I'd like to keep the configuration // minimal + conf.RootDir = btc.TendermintRoot + conf.Consensus.RootDir = btc.TendermintRoot + conf.Mempool.RootDir = btc.TendermintRoot + conf.P2P.RootDir = btc.TendermintRoot conf.P2P.Seeds = btc.Seeds conf.P2P.ListenAddress = btc.ListenAddress - conf.P2P.AddrBook = path.Join(btc.TendermintRoot, conf.P2P.AddrBook) conf.Moniker = btc.Moniker - conf.DBPath = path.Join(btc.TendermintRoot, conf.DBPath) - conf.Mempool.WalPath = path.Join(btc.TendermintRoot, conf.Mempool.WalPath) - conf.Consensus.WalPath = path.Join(btc.TendermintRoot, conf.Consensus.WalPath) } // Disable Tendermint RPC conf.RPC.ListenAddress = "" diff --git a/consensus/tendermint/query/node_view.go b/consensus/tendermint/query/node_view.go index 2d33ea53..566a93e3 100644 --- a/consensus/tendermint/query/node_view.go +++ b/consensus/tendermint/query/node_view.go @@ -12,66 +12,44 @@ import ( "github.com/tendermint/tendermint/types" ) -// You're like the interface I never had -type NodeView interface { - // PrivValidator public key - PrivValidatorPublicKey() (acm.PublicKey, error) - // NodeInfo for this node broadcast to other nodes (including ephemeral STS ED25519 public key) - NodeInfo() *p2p.NodeInfo - // Whether the Tendermint node is listening - IsListening() bool - // Current listeners - Listeners() []p2p.Listener - // Known Tendermint peers - Peers() p2p.IPeerSet - // Read-only BlockStore - BlockStore() types.BlockStoreRPC - // Get the currently unconfirmed but not known to be invalid transactions from the Node's mempool - MempoolTransactions(maxTxs int) ([]txs.Tx, error) - // Get the validator's consensus RoundState - RoundState() *ctypes.RoundState - // Get the validator's peer's consensus RoundState - PeerRoundStates() ([]*ctypes.PeerRoundState, error) -} - -type nodeView struct { +type NodeView struct { tmNode *tendermint.Node txDecoder txs.Decoder } -func NewNodeView(tmNode *tendermint.Node, txDecoder txs.Decoder) NodeView { - return &nodeView{ +func NewNodeView(tmNode *tendermint.Node, txDecoder txs.Decoder) *NodeView { + return &NodeView{ tmNode: tmNode, txDecoder: txDecoder, } } -func (nv *nodeView) PrivValidatorPublicKey() (acm.PublicKey, error) { +func (nv *NodeView) PrivValidatorPublicKey() (acm.PublicKey, error) { return acm.PublicKeyFromGoCryptoPubKey(nv.tmNode.PrivValidator().GetPubKey()) } -func (nv *nodeView) NodeInfo() *p2p.NodeInfo { +func (nv *NodeView) NodeInfo() p2p.NodeInfo { return nv.tmNode.NodeInfo() } -func (nv *nodeView) IsListening() bool { +func (nv *NodeView) IsListening() bool { return nv.tmNode.Switch().IsListening() } -func (nv *nodeView) Listeners() []p2p.Listener { +func (nv *NodeView) Listeners() []p2p.Listener { return nv.tmNode.Switch().Listeners() } -func (nv *nodeView) Peers() p2p.IPeerSet { +func (nv *NodeView) Peers() p2p.IPeerSet { return nv.tmNode.Switch().Peers() } -func (nv *nodeView) BlockStore() types.BlockStoreRPC { +func (nv *NodeView) BlockStore() types.BlockStoreRPC { return nv.tmNode.BlockStore() } // Pass -1 to get all available transactions -func (nv *nodeView) MempoolTransactions(maxTxs int) ([]txs.Tx, error) { +func (nv *NodeView) MempoolTransactions(maxTxs int) ([]txs.Tx, error) { var transactions []txs.Tx for _, txBytes := range nv.tmNode.MempoolReactor().Mempool.Reap(maxTxs) { tx, err := nv.txDecoder.DecodeTx(txBytes) @@ -83,11 +61,11 @@ func (nv *nodeView) MempoolTransactions(maxTxs int) ([]txs.Tx, error) { return transactions, nil } -func (nv *nodeView) RoundState() *ctypes.RoundState { +func (nv *NodeView) RoundState() *ctypes.RoundState { return nv.tmNode.ConsensusState().GetRoundState() } -func (nv *nodeView) PeerRoundStates() ([]*ctypes.PeerRoundState, error) { +func (nv *NodeView) PeerRoundStates() ([]*ctypes.PeerRoundState, error) { peers := nv.tmNode.Switch().Peers().List() peerRoundStates := make([]*ctypes.PeerRoundState, len(peers)) for i, peer := range peers { diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go index c66c9699..261bba24 100644 --- a/consensus/tendermint/tendermint.go +++ b/consensus/tendermint/tendermint.go @@ -5,6 +5,9 @@ import ( "context" + "os" + "path" + bcm "github.com/hyperledger/burrow/blockchain" "github.com/hyperledger/burrow/consensus/tendermint/abci" "github.com/hyperledger/burrow/event" @@ -31,7 +34,7 @@ type Node struct { // Since Tendermint doesn't close its DB connections func (n *Node) DBProvider(ctx *node.DBContext) (dbm.DB, error) { - db := dbm.NewDB(ctx.ID, ctx.Config.DBBackend, ctx.Config.DBDir()) + db := dbm.NewDB(ctx.ID, dbm.DBBackendType(ctx.Config.DBBackend), ctx.Config.DBDir()) n.closers = append(n.closers, db) return db, nil } @@ -55,8 +58,14 @@ func NewNode( // disable Tendermint's RPC conf.RPC.ListenAddress = "" + err = os.MkdirAll(path.Dir(conf.NodeKeyFile()), 0777) + if err != nil { + return nil, err + } + nde := &Node{} app := abci.NewApp(blockchain, checker, committer, logger) + conf.NodeKeyFile() nde.Node, err = node.NewNode(conf, privValidator, proxy.NewLocalClientCreator(app), func() (*tm_types.GenesisDoc, error) { diff --git a/consensus/tendermint/validator/priv_validator_memory.go b/consensus/tendermint/validator/priv_validator_memory.go index 9e450bb7..50c6fdd9 100644 --- a/consensus/tendermint/validator/priv_validator_memory.go +++ b/consensus/tendermint/validator/priv_validator_memory.go @@ -3,14 +3,14 @@ package validator import ( acm "github.com/hyperledger/burrow/account" "github.com/tendermint/go-crypto" - "github.com/tendermint/go-wire/data" tm_types "github.com/tendermint/tendermint/types" + val_types "github.com/tendermint/tendermint/types/priv_validator" ) type privValidatorMemory struct { acm.Addressable tm_types.Signer - lastSignedInfo *LastSignedInfo + lastSignedInfo *val_types.LastSignedInfo } var _ tm_types.PrivValidator = &privValidatorMemory{} @@ -21,11 +21,11 @@ func NewPrivValidatorMemory(addressable acm.Addressable, signer acm.Signer) *pri return &privValidatorMemory{ Addressable: addressable, Signer: asTendermintSigner(signer), - lastSignedInfo: NewLastSignedInfo(), + lastSignedInfo: val_types.NewLastSignedInfo(), } } -func (pvm *privValidatorMemory) GetAddress() data.Bytes { +func (pvm *privValidatorMemory) GetAddress() tm_types.Address { return pvm.Address().Bytes() } @@ -44,7 +44,7 @@ func (pvm *privValidatorMemory) SignProposal(chainID string, proposal *tm_types. func (pvm *privValidatorMemory) SignHeartbeat(chainID string, heartbeat *tm_types.Heartbeat) error { var err error - heartbeat.Signature, err = pvm.Signer.Sign(tm_types.SignBytes(chainID, heartbeat)) + heartbeat.Signature, err = pvm.Signer.Sign(heartbeat.SignBytes(chainID)) return err } diff --git a/consensus/tendermint/validator/sign_info.go b/consensus/tendermint/validator/sign_info.go deleted file mode 100644 index 12f7cbbe..00000000 --- a/consensus/tendermint/validator/sign_info.go +++ /dev/null @@ -1,240 +0,0 @@ -package validator - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "time" - - crypto "github.com/tendermint/go-crypto" - data "github.com/tendermint/go-wire/data" - "github.com/tendermint/tendermint/types" -) - -// This file is copy and pasted from (and pending): https://github.com/tendermint/tendermint/pull/1044 - -// TODO: type ? -const ( - stepNone int8 = 0 // Used to distinguish the initial state - stepPropose int8 = 1 - stepPrevote int8 = 2 - stepPrecommit int8 = 3 -) - -func voteToStep(vote *types.Vote) int8 { - switch vote.Type { - case types.VoteTypePrevote: - return stepPrevote - case types.VoteTypePrecommit: - return stepPrecommit - default: - panic("Unknown vote type") - } -} - -//------------------------------------- - -// LastSignedInfo contains information about the latest -// data signed by a validator to help prevent double signing. -type LastSignedInfo struct { - Height int64 `json:"height"` - Round int `json:"round"` - Step int8 `json:"step"` - Signature crypto.Signature `json:"signature,omitempty"` // so we dont lose signatures - SignBytes data.Bytes `json:"signbytes,omitempty"` // so we dont lose signatures -} - -func NewLastSignedInfo() *LastSignedInfo { - return &LastSignedInfo{ - Step: stepNone, - } -} - -func (info *LastSignedInfo) String() string { - return fmt.Sprintf("LH:%v, LR:%v, LS:%v", info.Height, info.Round, info.Step) -} - -// Verify returns an error if there is a height/round/step regression -// or if the HRS matches but there are no LastSignBytes. -// It returns true if HRS matches exactly and the LastSignature exists. -// It panics if the HRS matches, the LastSignBytes are not empty, but the LastSignature is empty. -func (info LastSignedInfo) Verify(height int64, round int, step int8) (bool, error) { - if info.Height > height { - return false, errors.New("Height regression") - } - - if info.Height == height { - if info.Round > round { - return false, errors.New("Round regression") - } - - if info.Round == round { - if info.Step > step { - return false, errors.New("Step regression") - } else if info.Step == step { - if info.SignBytes != nil { - if info.Signature.Empty() { - panic("info: LastSignature is nil but LastSignBytes is not!") - } - return true, nil - } - return false, errors.New("No LastSignature found") - } - } - } - return false, nil -} - -// Set height/round/step and signature on the info -func (info *LastSignedInfo) Set(height int64, round int, step int8, - signBytes []byte, sig crypto.Signature) { - - info.Height = height - info.Round = round - info.Step = step - info.Signature = sig - info.SignBytes = signBytes -} - -// Reset resets all the values. -// XXX: Unsafe. -func (info *LastSignedInfo) Reset() { - info.Height = 0 - info.Round = 0 - info.Step = 0 - info.Signature = crypto.Signature{} - info.SignBytes = nil -} - -// SignVote checks the height/round/step (HRS) are greater than the latest state of the LastSignedInfo. -// If so, it signs the vote, updates the LastSignedInfo, and sets the signature on the vote. -// If the HRS are equal and the only thing changed is the timestamp, it sets the vote.Timestamp to the previous -// value and the Signature to the LastSignedInfo.Signature. -// Else it returns an error. -func (lsi *LastSignedInfo) SignVote(signer types.Signer, chainID string, vote *types.Vote) error { - height, round, step := vote.Height, vote.Round, voteToStep(vote) - signBytes := types.SignBytes(chainID, vote) - - sameHRS, err := lsi.Verify(height, round, step) - if err != nil { - return err - } - - // We might crash before writing to the wal, - // causing us to try to re-sign for the same HRS. - // If signbytes are the same, use the last signature. - // If they only differ by timestamp, use last timestamp and signature - // Otherwise, return error - if sameHRS { - if bytes.Equal(signBytes, lsi.SignBytes) { - vote.Signature = lsi.Signature - } else if timestamp, ok := checkVotesOnlyDifferByTimestamp(lsi.SignBytes, signBytes); ok { - vote.Timestamp = timestamp - vote.Signature = lsi.Signature - } else { - err = fmt.Errorf("Conflicting data") - } - return err - } - sig, err := signer.Sign(signBytes) - if err != nil { - return err - } - lsi.Set(height, round, step, signBytes, sig) - vote.Signature = sig - return nil -} - -// SignProposal checks if the height/round/step (HRS) are greater than the latest state of the LastSignedInfo. -// If so, it signs the proposal, updates the LastSignedInfo, and sets the signature on the proposal. -// If the HRS are equal and the only thing changed is the timestamp, it sets the timestamp to the previous -// value and the Signature to the LastSignedInfo.Signature. -// Else it returns an error. -func (lsi *LastSignedInfo) SignProposal(signer types.Signer, chainID string, proposal *types.Proposal) error { - height, round, step := proposal.Height, proposal.Round, stepPropose - signBytes := types.SignBytes(chainID, proposal) - - sameHRS, err := lsi.Verify(height, round, step) - if err != nil { - return err - } - - // We might crash before writing to the wal, - // causing us to try to re-sign for the same HRS. - // If signbytes are the same, use the last signature. - // If they only differ by timestamp, use last timestamp and signature - // Otherwise, return error - if sameHRS { - if bytes.Equal(signBytes, lsi.SignBytes) { - proposal.Signature = lsi.Signature - } else if timestamp, ok := checkProposalsOnlyDifferByTimestamp(lsi.SignBytes, signBytes); ok { - proposal.Timestamp = timestamp - proposal.Signature = lsi.Signature - } else { - err = fmt.Errorf("Conflicting data") - } - return err - } - sig, err := signer.Sign(signBytes) - if err != nil { - return err - } - lsi.Set(height, round, step, signBytes, sig) - proposal.Signature = sig - return nil -} - -//------------------------------------- - -// returns the timestamp from the lastSignBytes. -// returns true if the only difference in the votes is their timestamp. -func checkVotesOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) { - var lastVote, newVote types.CanonicalJSONOnceVote - if err := json.Unmarshal(lastSignBytes, &lastVote); err != nil { - panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into vote: %v", err)) - } - if err := json.Unmarshal(newSignBytes, &newVote); err != nil { - panic(fmt.Sprintf("signBytes cannot be unmarshalled into vote: %v", err)) - } - - lastTime, err := time.Parse(time.RFC3339Nano, lastVote.Vote.Timestamp) - if err != nil { - panic(err) - } - - // set the times to the same value and check equality - now := types.CanonicalTime(time.Now()) - lastVote.Vote.Timestamp = now - newVote.Vote.Timestamp = now - lastVoteBytes, _ := json.Marshal(lastVote) - newVoteBytes, _ := json.Marshal(newVote) - - return lastTime, bytes.Equal(newVoteBytes, lastVoteBytes) -} - -// returns the timestamp from the lastSignBytes. -// returns true if the only difference in the proposals is their timestamp -func checkProposalsOnlyDifferByTimestamp(lastSignBytes, newSignBytes []byte) (time.Time, bool) { - var lastProposal, newProposal types.CanonicalJSONOnceProposal - if err := json.Unmarshal(lastSignBytes, &lastProposal); err != nil { - panic(fmt.Sprintf("LastSignBytes cannot be unmarshalled into proposal: %v", err)) - } - if err := json.Unmarshal(newSignBytes, &newProposal); err != nil { - panic(fmt.Sprintf("signBytes cannot be unmarshalled into proposal: %v", err)) - } - - lastTime, err := time.Parse(time.RFC3339Nano, lastProposal.Proposal.Timestamp) - if err != nil { - panic(err) - } - - // set the times to the same value and check equality - now := types.CanonicalTime(time.Now()) - lastProposal.Proposal.Timestamp = now - newProposal.Proposal.Timestamp = now - lastProposalBytes, _ := json.Marshal(lastProposal) - newProposalBytes, _ := json.Marshal(newProposal) - - return lastTime, bytes.Equal(newProposalBytes, lastProposalBytes) -} diff --git a/core/integration/test_wrapper.go b/core/integration/test_wrapper.go index 960dd5d5..7d0940d1 100644 --- a/core/integration/test_wrapper.go +++ b/core/integration/test_wrapper.go @@ -55,6 +55,7 @@ func TestWrapper(privateAccounts []acm.PrivateAccount, genesisDoc *genesis.Genes os.Chdir(testDir) tmConf := tm_config.DefaultConfig() + os.MkdirAll("config", 0777) logger := logging.NewNoopLogger() if debugLogging { var err error diff --git a/core/kernel.go b/core/kernel.go index 70fc3a71..4f3df68b 100644 --- a/core/kernel.go +++ b/core/kernel.go @@ -71,7 +71,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t logger = logger.WithScope("NewKernel()").With(structure.TimeKey, kitlog.DefaultTimestampUTC) tmLogger := logger.With(structure.CallerKey, kitlog.Caller(LoggingCallerDepth+1)) logger = logger.WithInfo(structure.CallerKey, kitlog.Caller(LoggingCallerDepth)) - stateDB := dbm.NewDB("burrow_state", dbm.GoLevelDBBackendStr, tmConf.DBDir()) + stateDB := dbm.NewDB("burrow_state", dbm.GoLevelDBBackend, tmConf.DBDir()) blockchain, err := bcm.LoadOrNewBlockchain(stateDB, genesisDoc, logger) if err != nil { @@ -158,7 +158,7 @@ func NewKernel(ctx context.Context, keyClient keys.KeyClient, privValidator tm_t select { case <-ctx.Done(): return ctx.Err() - case <-tmNode.Quit: + case <-tmNode.Quit(): logger.InfoMsg("Tendermint Node has quit, closing DB connections...") // Close tendermint database connections using our wrapper tmNode.Close() diff --git a/execution/execution_test.go b/execution/execution_test.go index 50ce4767..d1aa9454 100644 --- a/execution/execution_test.go +++ b/execution/execution_test.go @@ -45,7 +45,7 @@ import ( ) var ( - dbBackend = dbm.MemDBBackendStr + dbBackend = dbm.MemDBBackend dbDir = "" permissionsContract = evm.SNativeContracts()["Permissions"] ) diff --git a/execution/state.go b/execution/state.go index 7b98a32a..af168650 100644 --- a/execution/state.go +++ b/execution/state.go @@ -68,7 +68,7 @@ type State struct { func NewState(db dbm.DB) *State { return &State{ db: db, - tree: iavl.NewVersionedTree(defaultCacheCapacity, db), + tree: iavl.NewVersionedTree(db, defaultCacheCapacity), } } @@ -136,28 +136,32 @@ func LoadState(db dbm.DB, hash []byte) (*State, error) { if versionBytes == nil { return nil, fmt.Errorf("could not retrieve version corresponding to state hash '%X' in database", hash) } - state := NewState(db) - state.version = binary.GetUint64BE(versionBytes) - err := state.tree.Load() + s := NewState(db) + s.version = binary.GetUint64BE(versionBytes) + treeVersion, err := s.tree.Load() if err != nil { return nil, fmt.Errorf("could not load versioned state tree") } - if state.tree.LatestVersion() != state.version { - return nil, fmt.Errorf("state tree version %v expected for state hash %X but latest state tree version "+ - "loaded is %v", state.version, hash, state.tree.LatestVersion()) + if uint64(treeVersion) != s.version { + return nil, fmt.Errorf("LoadState expects tree version %v for state hash %X but latest state tree version "+ + "loaded is %v", s.version, hash, treeVersion) } - return state, nil + return s, nil } func (s *State) Save() error { s.Lock() defer s.Unlock() s.version++ - hash, err := s.tree.SaveVersion(s.version) + hash, treeVersion, err := s.tree.SaveVersion() if err != nil { return err } + if uint64(treeVersion) != s.version { + return fmt.Errorf("Save expects state tree version %v for state hash %X tree saved as version %v", + s.version, hash, treeVersion) + } versionBytes := make([]byte, 8) binary.PutUint64BE(versionBytes, s.version) s.db.SetSync(prefixedKey(versionPrefix, hash), versionBytes) diff --git a/rpc/config.go b/rpc/config.go index 89936dec..eba0b7ed 100644 --- a/rpc/config.go +++ b/rpc/config.go @@ -38,13 +38,13 @@ func DefaultV0Config() *V0Config { func DefaultTMConfig() *TMConfig { return &TMConfig{ - ListenAddress: ":46657", + ListenAddress: "tcp://localhost:46657", } } func DefaultProfilerConfig() *ProfilerConfig { return &ProfilerConfig{ Disabled: true, - ListenAddress: ":6060", + ListenAddress: "tcp://localhost:6060", } } diff --git a/rpc/result.go b/rpc/result.go index 2e51a2e6..440a152a 100644 --- a/rpc/result.go +++ b/rpc/result.go @@ -72,7 +72,7 @@ type ResultGetBlock struct { } type ResultStatus struct { - NodeInfo *p2p.NodeInfo + NodeInfo p2p.NodeInfo GenesisHash []byte PubKey acm.PublicKey LatestBlockHash []byte @@ -97,7 +97,7 @@ type ResultUnsubscribe struct { } type Peer struct { - NodeInfo *p2p.NodeInfo + NodeInfo p2p.NodeInfo IsOutbound bool } diff --git a/rpc/service.go b/rpc/service.go index ed1b1062..0ec8291c 100644 --- a/rpc/service.go +++ b/rpc/service.go @@ -49,13 +49,13 @@ type Service struct { subscribable event.Subscribable blockchain bcm.Blockchain transactor *execution.Transactor - nodeView query.NodeView + nodeView *query.NodeView logger *logging.Logger } func NewService(ctx context.Context, state state.Iterable, nameReg execution.NameRegIterable, checker state.Reader, subscribable event.Subscribable, blockchain bcm.Blockchain, keyClient keys.KeyClient, - transactor *execution.Transactor, nodeView query.NodeView, logger *logging.Logger) *Service { + transactor *execution.Transactor, nodeView *query.NodeView, logger *logging.Logger) *Service { return &Service{ ctx: ctx, diff --git a/rpc/tm/integration/websocket_helpers.go b/rpc/tm/integration/websocket_helpers.go index cbaa5749..11fbf9d9 100644 --- a/rpc/tm/integration/websocket_helpers.go +++ b/rpc/tm/integration/websocket_helpers.go @@ -197,7 +197,7 @@ func waitForEvent(t *testing.T, wsc *rpcclient.WSClient, eventID string, runner eventsCh <- resultEvent } } - case <-wsc.Quit: + case <-wsc.Quit(): return } } diff --git a/rpc/v0/server/config.go b/rpc/v0/server/config.go index 7a67645c..f5b8130c 100644 --- a/rpc/v0/server/config.go +++ b/rpc/v0/server/config.go @@ -63,7 +63,7 @@ func DefaultServerConfig() *ServerConfig { kp := "" return &ServerConfig{ Bind: Bind{ - Address: "", + Address: "localhost", Port: 1337, }, TLS: TLS{TLS: false, diff --git a/scripts/deps/bos.sh b/scripts/deps/bos.sh index 6cded7e4..550f98b0 100755 --- a/scripts/deps/bos.sh +++ b/scripts/deps/bos.sh @@ -1,4 +1,4 @@ #!/usr/bin/env bash # The git revision of Bosmarmot/bos we will build and install into ./bin/ for integration tests -echo "9da71e7278d340ecfdf47e72eb9e9e2bba8d3e7a" \ No newline at end of file +echo "b6f5208284f54006b22955b8fcd5c86df1675c7f" -- GitLab