diff --git a/CHANGELOG_PENDING.md b/CHANGELOG_PENDING.md index 74d81bd5f..e4105369a 100644 --- a/CHANGELOG_PENDING.md +++ b/CHANGELOG_PENDING.md @@ -19,6 +19,8 @@ Special thanks to external contributors on this release: ### FEATURES: ### IMPROVEMENTS: +- [rpc] Add `UnconfirmedTxs(limit)` and `NumUnconfirmedTxs()` methods to HTTP/Local clients (@danil-lashin) ### BUG FIXES: -- [kv indexer] \#2912 don't ignore key when executing CONTAINS \ No newline at end of file +- [kv indexer] \#2912 don't ignore key when executing CONTAINS +- [p2p] \#2715 fix a bug where seeds don't disconnect from a peer after 3h diff --git a/libs/log/testing_logger.go b/libs/log/testing_logger.go index 81482bef5..8914bd81f 100644 --- a/libs/log/testing_logger.go +++ b/libs/log/testing_logger.go @@ -1,6 +1,7 @@ package log import ( + "io" "os" "testing" @@ -19,12 +20,22 @@ var ( // inside a test (not in the init func) because // verbose flag only set at the time of testing. func TestingLogger() Logger { + return TestingLoggerWithOutput(os.Stdout) +} + +// TestingLoggerWOutput returns a TMLogger which writes to (w io.Writer) if testing being run +// with the verbose (-v) flag, NopLogger otherwise. +// +// Note that the call to TestingLoggerWithOutput(w io.Writer) must be made +// inside a test (not in the init func) because +// verbose flag only set at the time of testing. +func TestingLoggerWithOutput(w io.Writer) Logger { if _testingLogger != nil { return _testingLogger } if testing.Verbose() { - _testingLogger = NewTMLogger(NewSyncWriter(os.Stdout)) + _testingLogger = NewTMLogger(NewSyncWriter(w)) } else { _testingLogger = NewNopLogger() } diff --git a/mempool/mempool.go b/mempool/mempool.go index 8f70ec6c8..a64ce9188 100644 --- a/mempool/mempool.go +++ b/mempool/mempool.go @@ -108,6 +108,10 @@ func PostCheckMaxGas(maxGas int64) PostCheckFunc { if maxGas == -1 { return nil } + if res.GasWanted < 0 { + return fmt.Errorf("gas wanted %d is negative", + res.GasWanted) + } if res.GasWanted > maxGas { return fmt.Errorf("gas wanted %d is greater than max gas %d", res.GasWanted, maxGas) diff --git a/p2p/conn/connection.go b/p2p/conn/connection.go index c6aad038b..fb20c4775 100644 --- a/p2p/conn/connection.go +++ b/p2p/conn/connection.go @@ -160,6 +160,7 @@ func NewMConnectionWithConfig(conn net.Conn, chDescs []*ChannelDescriptor, onRec onReceive: onReceive, onError: onError, config: config, + created: time.Now(), } // Create channels diff --git a/rpc/client/httpclient.go b/rpc/client/httpclient.go index a1b59ffa0..1a1d88c47 100644 --- a/rpc/client/httpclient.go +++ b/rpc/client/httpclient.go @@ -109,6 +109,24 @@ func (c *HTTP) broadcastTX(route string, tx types.Tx) (*ctypes.ResultBroadcastTx return result, nil } +func (c *HTTP) UnconfirmedTxs(limit int) (*ctypes.ResultUnconfirmedTxs, error) { + result := new(ctypes.ResultUnconfirmedTxs) + _, err := c.rpc.Call("unconfirmed_txs", map[string]interface{}{"limit": limit}, result) + if err != nil { + return nil, errors.Wrap(err, "unconfirmed_txs") + } + return result, nil +} + +func (c *HTTP) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) { + result := new(ctypes.ResultUnconfirmedTxs) + _, err := c.rpc.Call("num_unconfirmed_txs", map[string]interface{}{}, result) + if err != nil { + return nil, errors.Wrap(err, "num_unconfirmed_txs") + } + return result, nil +} + func (c *HTTP) NetInfo() (*ctypes.ResultNetInfo, error) { result := new(ctypes.ResultNetInfo) _, err := c.rpc.Call("net_info", map[string]interface{}{}, result) diff --git a/rpc/client/interface.go b/rpc/client/interface.go index f34410c5b..7477225e9 100644 --- a/rpc/client/interface.go +++ b/rpc/client/interface.go @@ -93,3 +93,9 @@ type NetworkClient interface { type EventsClient interface { types.EventBusSubscriber } + +// MempoolClient shows us data about current mempool state. +type MempoolClient interface { + UnconfirmedTxs(limit int) (*ctypes.ResultUnconfirmedTxs, error) + NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) +} diff --git a/rpc/client/localclient.go b/rpc/client/localclient.go index 8d89b7150..ba8fb3f17 100644 --- a/rpc/client/localclient.go +++ b/rpc/client/localclient.go @@ -76,6 +76,14 @@ func (Local) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) { return core.BroadcastTxSync(tx) } +func (Local) UnconfirmedTxs(limit int) (*ctypes.ResultUnconfirmedTxs, error) { + return core.UnconfirmedTxs(limit) +} + +func (Local) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) { + return core.NumUnconfirmedTxs() +} + func (Local) NetInfo() (*ctypes.ResultNetInfo, error) { return core.NetInfo() } diff --git a/rpc/client/rpc_test.go b/rpc/client/rpc_test.go index b07b74a39..fa5080f90 100644 --- a/rpc/client/rpc_test.go +++ b/rpc/client/rpc_test.go @@ -281,6 +281,42 @@ func TestBroadcastTxCommit(t *testing.T) { } } +func TestUnconfirmedTxs(t *testing.T) { + _, _, tx := MakeTxKV() + + mempool := node.MempoolReactor().Mempool + _ = mempool.CheckTx(tx, nil) + + for i, c := range GetClients() { + mc, ok := c.(client.MempoolClient) + require.True(t, ok, "%d", i) + txs, err := mc.UnconfirmedTxs(1) + require.Nil(t, err, "%d: %+v", i, err) + assert.Exactly(t, types.Txs{tx}, types.Txs(txs.Txs)) + } + + mempool.Flush() +} + +func TestNumUnconfirmedTxs(t *testing.T) { + _, _, tx := MakeTxKV() + + mempool := node.MempoolReactor().Mempool + _ = mempool.CheckTx(tx, nil) + mempoolSize := mempool.Size() + + for i, c := range GetClients() { + mc, ok := c.(client.MempoolClient) + require.True(t, ok, "%d", i) + res, err := mc.NumUnconfirmedTxs() + require.Nil(t, err, "%d: %+v", i, err) + + assert.Equal(t, mempoolSize, res.N) + } + + mempool.Flush() +} + func TestTx(t *testing.T) { // first we broadcast a tx c := getHTTPClient()