diff --git a/consensus/tendermint/config.go b/consensus/tendermint/config.go index 20fad4cdabd521d4aadf70471966fbff9217d902..1bbb74bd6aa35be73c28c7bb75adea040cfddfbb 100644 --- a/consensus/tendermint/config.go +++ b/consensus/tendermint/config.go @@ -73,7 +73,7 @@ func (tmintConfig *TendermintConfig) AssertTendermintDefaults(chainId, workDir, tmintConfig.SetDefault("db_backend", "leveldb") tmintConfig.SetDefault("db_dir", dataDir) tmintConfig.SetDefault("log_level", "info") - tmintConfig.SetDefault("rpc_laddr", "0.0.0.0:46657") + tmintConfig.SetDefault("rpc_laddr", "") tmintConfig.SetDefault("prof_laddr", "") tmintConfig.SetDefault("revision_file", path.Join(workDir, "revision")) tmintConfig.SetDefault("cswal", path.Join(dataDir, "cswal")) @@ -103,6 +103,7 @@ func (tmintConfig *TendermintConfig) AssertTendermintConsistency( tmintConfig.Set("genesis_file", consensusConfig.GenesisFile) // private validator file tmintConfig.Set("priv_validator_file", privateValidatorFilePath) + } // implement interface github.com/tendermint/go-config/config.Config diff --git a/consensus/tendermint/tendermint.go b/consensus/tendermint/tendermint.go index 507e63518269e1c2d6e079b7239ac00ac6090579..e9815347dff3244eeb3ac0dc91c75583c87ce832 100644 --- a/consensus/tendermint/tendermint.go +++ b/consensus/tendermint/tendermint.go @@ -111,6 +111,16 @@ func NewTendermint(moduleConfig *config.ModuleConfig, path.Join(moduleConfig.RootDir, moduleConfig.Config.GetString("private_validator_file"))) + // TODO: [Silas] we want to something better than this like not not have it in + // the config at all, but for now I think it's much safer to make sure we are + // not running the tendermint RPC as it could lead to unexpected behaviour, + // not least if we accidentally try to run it on the same address as our own + if tmintConfig.GetString("rpc_laddr") != "" { + log.Warnf("Force disabling Tendermint's native RPC, which had been set to " + + "run on '%s' in the Tendermint config.", tmintConfig.GetString("rpc_laddr")) + tmintConfig.Set("rpc_laddr", "") + } + newNode := node.NewNode(tmintConfig, privateValidator, func(_, _ string, hash []byte) proxy.AppConn { return NewLocalClient(new(sync.Mutex), application) diff --git a/manager/eris-mint/eris-mint.go b/manager/eris-mint/eris-mint.go index 55d7374d175569234d9254301204f180e2502229..2c08757c1a2b6539992a51bd1eb22c6043b1ea04 100644 --- a/manager/eris-mint/eris-mint.go +++ b/manager/eris-mint/eris-mint.go @@ -18,14 +18,11 @@ package erismint import ( "bytes" - "encoding/hex" "fmt" "sync" tendermint_events "github.com/tendermint/go-events" - rpcclient "github.com/tendermint/go-rpc/client" wire "github.com/tendermint/go-wire" - ctypes "github.com/tendermint/tendermint/rpc/core/types" tmsp "github.com/tendermint/tmsp/types" log "github.com/eris-ltd/eris-logger" @@ -50,10 +47,6 @@ type ErisMint struct { evc *tendermint_events.EventCache evsw *tendermint_events.EventSwitch - // client to the tendermint core rpc - client *rpcclient.ClientURI - host string // tendermint core endpoint - nTxs int // count txs in a block } @@ -78,31 +71,6 @@ func (app *ErisMint) GetCheckCache() *sm.BlockCache { return app.checkCache } -func (app *ErisMint) SetHostAddress(host string) { - app.host = host - app.client = rpcclient.NewClientURI(host) //fmt.Sprintf("http://%s", host)) -} - -// Broadcast a tx to the tendermint core -// NOTE: this assumes we know the address of core -func (app *ErisMint) BroadcastTx(tx txs.Tx) error { - buf := new(bytes.Buffer) - var n int - var err error - wire.WriteBinary(struct{ txs.Tx }{tx}, buf, &n, &err) - if err != nil { - return err - } - - params := map[string]interface{}{ - "tx": hex.EncodeToString(buf.Bytes()), - } - - var result ctypes.TMResult - _, err = app.client.Call("broadcast_tx_sync", params, &result) - return err -} - func NewErisMint(s *sm.State, evsw *tendermint_events.EventSwitch) *ErisMint { return &ErisMint{ state: s, diff --git a/manager/eris-mint/pipe.go b/manager/eris-mint/pipe.go index 490a613b468b98ab1dd1193addd29328a0f4a04b..dc9b64875319a7fb50c6fb6c269778f2d9272d5a 100644 --- a/manager/eris-mint/pipe.go +++ b/manager/eris-mint/pipe.go @@ -87,26 +87,20 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig, // start the application erisMint := NewErisMint(startedState, eventSwitch) - // NOTE: [ben] Set Host opens an RPC pipe to Tendermint; this is a remnant - // of the old Eris-DB / Tendermint and should be considered as an in-process - // call when possible - tendermintHost := moduleConfig.Config.GetString("tendermint_host") - erisMint.SetHostAddress(tendermintHost) - // initialise the components of the pipe events := edb_event.NewEvents(eventSwitch) accounts := newAccounts(erisMint) namereg := newNameReg(erisMint) - transactor := newTransactor(moduleConfig.ChainId, eventSwitch, erisMint, - events) - return &erisMintPipe{ + pipe := &erisMintPipe{ erisMintState: startedState, erisMint: erisMint, accounts: accounts, events: events, namereg: namereg, - transactor: transactor, + // We need to set transactor later since we are introducing a mutual dependency + // NOTE: this will be cleaned up when the RPC is unified + transactor: nil, // genesis cache genesisDoc: genesisDoc, genesisState: nil, @@ -114,7 +108,26 @@ func NewErisMintPipe(moduleConfig *config.ModuleConfig, // authority - this is a sort of dependency injection pattern consensusEngine: nil, blockchain: nil, - }, nil + } + + // NOTE: [Silas] + // This is something of a loopback, but seems like a nicer option than + // transactor calling the Tendermint native RPC (as it was before), + // or indeed calling this RPC over the wire given that we have direct access. + // + // We could just hand transactor a copy of Pipe, but doing it this way seems + // like a reasonably minimal and flexible way of providing transactor with the + // broadcast function it needs, without making it explicitly + // aware of/depend on Pipe. + transactor := newTransactor(moduleConfig.ChainId, eventSwitch, erisMint, + events, + func(tx txs.Tx) error { + _, err := pipe.BroadcastTxSync(tx) + return err + }) + + pipe.transactor = transactor + return pipe, nil } //------------------------------------------------------------------------------ diff --git a/manager/eris-mint/transactor.go b/manager/eris-mint/transactor.go index 3480d16a0dc7c02e49e1137f7b84183158072c29..953c519f45a77caac632cbcefb0b5b35dacc9e2b 100644 --- a/manager/eris-mint/transactor.go +++ b/manager/eris-mint/transactor.go @@ -38,23 +38,25 @@ import ( ) type transactor struct { - chainID string - eventSwitch tEvents.Fireable - erisMint *ErisMint - eventEmitter event.EventEmitter - txMtx *sync.Mutex + chainID string + eventSwitch tEvents.Fireable + erisMint *ErisMint + eventEmitter event.EventEmitter + txMtx *sync.Mutex + txBroadcaster func(tx txs.Tx) error } func newTransactor(chainID string, eventSwitch tEvents.Fireable, - erisMint *ErisMint, eventEmitter event.EventEmitter) *transactor { - txs := &transactor{ + erisMint *ErisMint, eventEmitter event.EventEmitter, + txBroadcaster func(tx txs.Tx) error) *transactor { + return &transactor{ chainID, eventSwitch, erisMint, eventEmitter, &sync.Mutex{}, + txBroadcaster, } - return txs } // Run a contract's code on an isolated and unpersisted state @@ -132,8 +134,8 @@ func (this *transactor) CallCode(fromAddress, code, data []byte) ( // Broadcast a transaction. func (this *transactor) BroadcastTx(tx txs.Tx) (*txs.Receipt, error) { + err := this.txBroadcaster(tx) - err := this.erisMint.BroadcastTx(tx) if err != nil { return nil, fmt.Errorf("Error broadcasting transaction: %v", err) } diff --git a/rpc/tendermint/test/config.go b/rpc/tendermint/test/config.go index e4b60a9de7808b714dbdb8a6d138c566aed424df..ff33cb30f4aca019aea9a400e434e7539a786bb9 100644 --- a/rpc/tendermint/test/config.go +++ b/rpc/tendermint/test/config.go @@ -173,7 +173,7 @@ private_validator_file = "priv_validator.json" # rpc local address # NOTE: value is ignored when run in-process as RPC is # handled by [servers.tendermint] - rpc_laddr = "0.0.0.0:36657" + rpc_laddr = "" # proxy application address - used for tmsp connections, # and this port should not be exposed for in-process Tendermint proxy_app = "tcp://127.0.0.1:46658" @@ -217,6 +217,4 @@ private_validator_file = "priv_validator.json" [erismint] # Database backend to use for ErisMint state database. db_backend = "leveldb" -# tendermint host address needs to correspond to tendermints configuration -# of the rpc local address -tendermint_host = "0.0.0.0:36657"` +` diff --git a/rpc/tendermint/test/shared.go b/rpc/tendermint/test/shared.go index 16dbf7abaf869e0cbc54460657ff7f078b8b6bc0..d211bd5d11c6fd7c078ce12665366f0a48d0a134 100644 --- a/rpc/tendermint/test/shared.go +++ b/rpc/tendermint/test/shared.go @@ -64,9 +64,8 @@ func initGlobalVariables(ffs *fixtures.FileFixtures) error { } chainID = testConfig.GetString("chain.assert_chain_id") - rpcAddr := testConfig.GetString("erismint.tendermint_host") + rpcAddr := config.Tendermint.RpcLocalAddress websocketAddr = rpcAddr - config.Tendermint.RpcLocalAddress = rpcAddr websocketEndpoint = "/websocket" consensusConfig, err := core.LoadModuleConfig(testConfig, rootWorkDir, diff --git a/server_config.toml b/server_config.toml index d680ede702d49c35c2c92b594b3db192d24d7ee2..80e88a933e6a90972156beb0ec3738b0be191416 100644 --- a/server_config.toml +++ b/server_config.toml @@ -101,10 +101,10 @@ genesis_file = "genesis.json" read_buffer_size = 4096 write_buffer_size = 4096 - [servers.tendermint] - # Multiple listeners can be separated with a comma - rpc_local_address = "0.0.0.0:46657" - endpoint = "/websocket" + [servers.tendermint] + # Multiple listeners can be separated with a comma + rpc_local_address = "0.0.0.0:46657" + endpoint = "/websocket" [servers.logging] console_log_level = "info" @@ -172,9 +172,9 @@ private_validator_file = "priv_validator.json" # node local address node_laddr = "0.0.0.0:46656" # rpc local address - # NOTE: value is ignored when run in-process as RPC is - # handled by [servers.tendermint] - rpc_laddr = "0.0.0.0:46657" + # NOTE: value is ignored when run in-process as RPC is + # handled by [servers.tendermint] + rpc_laddr = "" # proxy application address - used for tmsp connections, # and this port should not be exposed for in-process Tendermint proxy_app = "tcp://127.0.0.1:46658" @@ -239,6 +239,3 @@ private_validator_file = "priv_validator.json" # Database backend to use for ErisMint state database. # Supported `leveldb` and `memdb`. db_backend = "leveldb" -# tendermint host address needs to correspond to tendermints configuration -# of the rpc local address -tendermint_host = "0.0.0.0:46657"