Skip to content

Commit

Permalink
SKALED-1878 Colorful logs
Browse files Browse the repository at this point in the history
  • Loading branch information
dimalit committed Apr 28, 2024
1 parent 913844f commit b44e87f
Show file tree
Hide file tree
Showing 10 changed files with 105 additions and 36 deletions.
1 change: 1 addition & 0 deletions libethcore/ChainOperationParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ struct ChainOperationParams {
u256 externalGasDifficulty = ~u256( 0 );
typedef std::vector< std::string > vecAdminOrigins_t;
vecAdminOrigins_t vecAdminOrigins; // wildcard based folters for IP addresses
int getLogsBlocksLimit = -1;

time_t getPatchTimestamp( SchainPatchEnum _patchEnum ) const;

Expand Down
3 changes: 3 additions & 0 deletions libethcore/Exceptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,5 +107,8 @@ DEV_SIMPLE_EXCEPTION( FailedToDownloadDaoForkBlockHeader );
DEV_SIMPLE_EXCEPTION( AccountLocked );
DEV_SIMPLE_EXCEPTION( TransactionRefused );
DEV_SIMPLE_EXCEPTION( UnknownAccount );

DEV_SIMPLE_EXCEPTION( TooBigResponse );

} // namespace eth
} // namespace dev
2 changes: 2 additions & 0 deletions libethereum/ChainParams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ ChainParams ChainParams::loadConfig(
cp.skaleDisableChainIdCheck = params.count( c_skaleDisableChainIdCheck ) ?
params[c_skaleDisableChainIdCheck].get_bool() :
false;
cp.getLogsBlocksLimit =
params.count( "getLogsBlocksLimit" ) ? params.at( "getLogsBlocksLimit" ).get_int() : -1;

if ( obj.count( c_skaleConfig ) ) {
processSkaleConfigItems( cp, obj );
Expand Down
15 changes: 3 additions & 12 deletions libethereum/ClientBase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,9 @@ LocalisedLogEntries ClientBase::logs( LogFilter const& _f ) const {
unsigned begin = min( bc().number() + 1, ( unsigned ) _f.latest() );
unsigned end = min( bc().number(), min( begin, ( unsigned ) _f.earliest() ) );

if ( begin >= end && begin - end > bc().chainParams().getLogsBlocksLimit )
BOOST_THROW_EXCEPTION( TooBigResponse() );

// Handle pending transactions differently as they're not on the block chain.
if ( begin > bc().number() ) {
Block temp = postSeal();
Expand Down Expand Up @@ -350,18 +353,6 @@ bool ClientBase::uninstallWatch( unsigned _i ) {
return true;
}

LocalisedLogEntries ClientBase::peekWatch( unsigned _watchId ) const {
Guard l( x_filtersWatches );

// LOG(m_loggerWatch) << "peekWatch" << _watchId;
auto& w = m_watches.at( _watchId );
// LOG(m_loggerWatch) << "lastPoll updated to " <<
// chrono::duration_cast<chrono::seconds>(chrono::system_clock::now().time_since_epoch()).count();
if ( w.lastPoll != chrono::system_clock::time_point::max() )
w.lastPoll = chrono::system_clock::now();
return w.get_changes();
}

LocalisedLogEntries ClientBase::checkWatch( unsigned _watchId ) {
Guard l( x_filtersWatches );
LocalisedLogEntries ret;
Expand Down
1 change: 0 additions & 1 deletion libethereum/ClientBase.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ class ClientBase : public Interface {
fnClientWatchHandlerMulti_t fnOnNewChanges = fnClientWatchHandlerMulti_t(),
bool isWS = false ) override;
bool uninstallWatch( unsigned _watchId ) override;
LocalisedLogEntries peekWatch( unsigned _watchId ) const override;
LocalisedLogEntries checkWatch( unsigned _watchId ) override;

using Interface::blockDetails;
Expand Down
9 changes: 0 additions & 9 deletions libethereum/Interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,21 +154,13 @@ class Interface {
fnClientWatchHandlerMulti_t fnOnNewChanges = fnClientWatchHandlerMulti_t(),
bool isWS = false ) = 0;
virtual bool uninstallWatch( unsigned _watchId ) = 0;
LocalisedLogEntries peekWatchSafe( unsigned _watchId ) const {
try {
return peekWatch( _watchId );
} catch ( ... ) {
return LocalisedLogEntries();
}
}
LocalisedLogEntries checkWatchSafe( unsigned _watchId ) {
try {
return checkWatch( _watchId );
} catch ( ... ) {
return LocalisedLogEntries();
}
}
virtual LocalisedLogEntries peekWatch( unsigned _watchId ) const = 0;
virtual LocalisedLogEntries checkWatch( unsigned _watchId ) = 0;

// [BLOCK QUERY API]
Expand Down Expand Up @@ -328,7 +320,6 @@ class Watch : public boost::noncopyable {
}

LocalisedLogEntries check() { return m_c ? m_c->checkWatch( m_id ) : LocalisedLogEntries(); }
LocalisedLogEntries peek() { return m_c ? m_c->peekWatch( m_id ) : LocalisedLogEntries(); }
LocalisedLogEntries logs() const { return m_c->logs( m_id ); }

private:
Expand Down
9 changes: 5 additions & 4 deletions libskutils/include/skutils/console_colors.h
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,13 @@ extern bool string2duration( const std::string& s, std::chrono::duration< uint64
const std::chrono::seconds& seconds = std::chrono::seconds::zero() );
extern std::string duration2string( std::chrono::nanoseconds time );
extern std::string time2string(
std::time_t tt, uint64_t nMicroSeconds, bool isUTC = false, bool isColored = true );
extern std::string time2string( const std::tm& aTm, uint64_t nMicroSeconds, bool isColored = true );
std::time_t tt, uint64_t nMicroSeconds, bool isUTC = false, bool isColored = false );
extern std::string time2string(
const std::tm& aTm, uint64_t nMicroSeconds, bool isColored = false );
extern std::string time2string( const default_clock_t::time_point& ptTime, bool isUTC = false,
bool isDaysInsteadOfYMD = false, bool isColored = true );
bool isDaysInsteadOfYMD = false, bool isColored = false );
extern std::string now2string(
bool isUTC = false, bool isDaysInsteadOfYMD = false, bool isColored = true );
bool isUTC = false, bool isDaysInsteadOfYMD = false, bool isColored = false );
extern std::string jsNow2string( bool isUTC = true );

inline std::string c() {
Expand Down
8 changes: 4 additions & 4 deletions libskutils/src/console_colors.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1185,12 +1185,12 @@ std::string duration2string( std::chrono::nanoseconds time ) {
}

std::string time2string(
std::time_t tt, uint64_t nMicroSeconds, bool isUTC, bool isColored /*= true*/ ) {
std::time_t tt, uint64_t nMicroSeconds, bool isUTC, bool isColored /*= false*/ ) {
std::lock_guard< std::mutex > lock( g_libcall_mutex );
struct std::tm aTm = isUTC ? ( *std::gmtime( &tt ) ) : ( *std::localtime( &tt ) );
return time2string( aTm, nMicroSeconds, isColored );
}
std::string time2string( const std::tm& aTm, uint64_t nMicroSeconds, bool isColored /*= true*/ ) {
std::string time2string( const std::tm& aTm, uint64_t nMicroSeconds, bool isColored /*= false*/ ) {
const std::tm& effective_tm = aTm;
std::stringstream ss;
ss << std::setfill( '0' );
Expand Down Expand Up @@ -1255,7 +1255,7 @@ inline time_t clock_2_time_t( const typename clock_type_t::time_point& ptTime )
}

std::string time2string( const default_clock_t::time_point& ptTime, bool isUTC,
bool isDaysInsteadOfYMD, bool isColored /*= true*/ ) {
bool isDaysInsteadOfYMD, bool isColored /*= false*/ ) {
std::stringstream ss;
typedef std::chrono::duration< int,
std::ratio_multiply< std::chrono::hours::period, std::ratio< 24 > >::type >
Expand Down Expand Up @@ -1363,7 +1363,7 @@ std::string time2string( const default_clock_t::time_point& ptTime, bool isUTC,
std::string s = ss.str();
return s;
}
std::string now2string( bool isUTC, bool isDaysInsteadOfYMD, bool isColored /*= true*/ ) {
std::string now2string( bool isUTC, bool isDaysInsteadOfYMD, bool isColored /*= false*/ ) {
default_clock_t::time_point ptTimeNow = default_clock_t::now();
std::string s = time2string( ptTimeNow, isUTC, isDaysInsteadOfYMD, isColored );
return s;
Expand Down
16 changes: 11 additions & 5 deletions libweb3jsonrpc/Eth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -487,11 +487,9 @@ string Eth::eth_call( TransactionSkeleton& t, string const&
if ( strRevertReason.empty() )
strRevertReason = "EVM revert instruction without description message";
std::string strTx = t.toString();
std::string strOut = cc::fatal( "Error message from eth_call():" ) + cc::error( " " ) +
cc::warn( strRevertReason ) + cc::error( ", with call arguments: " ) +
cc::j( strTx ) + cc::error( ", and using " ) +
cc::info( "blockNumber" ) + cc::error( "=" ) +
cc::bright( blockNumber );
std::string strOut = "Error message from eth_call(): " + strRevertReason +
", with call arguments: " + strTx +
", and using blockNumber=" + blockNumber;
cerror << strOut;
throw std::logic_error( strRevertReason );
}
Expand Down Expand Up @@ -820,6 +818,10 @@ Json::Value Eth::eth_getFilterChangesEx( string const& _filterId ) {
Json::Value Eth::eth_getFilterLogs( string const& _filterId ) {
try {
return toJson( client()->logs( static_cast< unsigned int >( jsToInt( _filterId ) ) ) );
} catch ( const TooBigResponse& ) {
BOOST_THROW_EXCEPTION( JsonRpcException( Errors::ERROR_RPC_INVALID_PARAMS,
"Log response size exceeded. Maximum allowed number of requested blocks is " +
to_string( this->client()->chainParams().getLogsBlocksLimit ) ) );
} catch ( ... ) {
BOOST_THROW_EXCEPTION( JsonRpcException( Errors::ERROR_RPC_INVALID_PARAMS ) );
}
Expand All @@ -837,6 +839,10 @@ Json::Value Eth::eth_getFilterLogs( string const& _filterId ) {
Json::Value Eth::eth_getLogs( Json::Value const& _json ) {
try {
return toJson( client()->logs( toLogFilter( _json ) ) );
} catch ( const TooBigResponse& ) {
BOOST_THROW_EXCEPTION( JsonRpcException( Errors::ERROR_RPC_INVALID_PARAMS,
"Log response size exceeded. Maximum allowed number of requested blocks is " +
to_string( this->client()->chainParams().getLogsBlocksLimit ) ) );
} catch ( ... ) {
BOOST_THROW_EXCEPTION( JsonRpcException( Errors::ERROR_RPC_INVALID_PARAMS ) );
}
Expand Down
77 changes: 76 additions & 1 deletion test/unittests/libweb3jsonrpc/jsonrpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,8 @@ ChainParams chainParams;

JsonRpcFixture( const std::string& _config = "", bool _owner = true,
bool _deploymentControl = true, bool _generation2 = false,
bool _mtmEnabled = false, bool _isSyncNode = false, int _emptyBlockIntervalMs = -1 ) {
bool _mtmEnabled = false, bool _isSyncNode = false, int _emptyBlockIntervalMs = -1,
const std::map<std::string, std::string>& params = std::map<std::string, std::string>() ) {


if ( _config != "" ) {
Expand Down Expand Up @@ -307,6 +308,9 @@ JsonRpcFixture( const std::string& _config = "", bool _owner = true,
chainParams.nodeInfo.port = chainParams.nodeInfo.port6 = rand_port;
chainParams.sChain.nodes[0].port = chainParams.sChain.nodes[0].port6 = rand_port;
chainParams.skaleDisableChainIdCheck = true;

if( params.count("getLogsBlocksLimit") && stoi( params.at( "getLogsBlocksLimit" ) ) )
chainParams.getLogsBlocksLimit = stoi( params.at( "getLogsBlocksLimit" ) );
}
chainParams.sChain.multiTransactionMode = _mtmEnabled;
chainParams.nodeInfo.syncNode = _isSyncNode;
Expand Down Expand Up @@ -2110,6 +2114,77 @@ contract Logger{
BOOST_REQUIRE_EQUAL(logs.size(), 24);
}

// limit on getLogs output
BOOST_AUTO_TEST_CASE( getLogs_limit ) {
JsonRpcFixture fixture( "", true, true, false, false, false, -1,
{{"getLogsBlocksLimit", "10"}} );

dev::eth::simulateMining( *( fixture.client ), 1 );

/*
// SPDX-License-Identifier: None
pragma solidity ^0.8;
contract Logger{
event DummyEvent(uint256, uint256);
fallback() external payable {
for(uint i=0; i<100; ++i)
emit DummyEvent(block.number, i);
}
}
*/

string bytecode = "6080604052348015600e575f80fd5b5060c080601a5f395ff3fe60806040525f5b6064811015604f577f90778767414a5c844b9d35a8745f67697ee3b8c2c3f4feafe5d9a3e234a5a3654382604051603d9291906067565b60405180910390a18060010190506006565b005b5f819050919050565b6061816051565b82525050565b5f60408201905060785f830185605a565b60836020830184605a565b939250505056fea264697066735822122040208e35f2706dd92c17579466ab671c308efec51f558a755ea2cf81105ab22964736f6c63430008190033";

Json::Value create;
create["code"] = bytecode;
create["gas"] = "180000"; // TODO or change global default of 90000?

string deployHash = fixture.rpcClient->eth_sendTransaction( create );
dev::eth::mineTransaction( *( fixture.client ), 1 );

Json::Value deployReceipt = fixture.rpcClient->eth_getTransactionReceipt( deployHash );
string contractAddress = deployReceipt["contractAddress"].asString();

// generate 10 blocks 10 logs each

Json::Value t;
t["from"] = toJS( fixture.coinbase.address() );
t["value"] = jsToDecimal( "0" );
t["to"] = contractAddress;
t["gas"] = "99000";

for(int i=0; i<11; ++i){

std::string txHash = fixture.rpcClient->eth_sendTransaction( t );
BOOST_REQUIRE( !txHash.empty() );
dev::eth::mineTransaction( *( fixture.client ), 1 );
Json::Value receipt = fixture.rpcClient->eth_getTransactionReceipt( txHash );
BOOST_REQUIRE_EQUAL(receipt["status"], "0x1");
}

// ask for logs
Json::Value req;
req["fromBlock"] = 1;
req["toBlock"] = 11;
req["topics"] = Json::Value(Json::arrayValue);

// 1 10 blocks
BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs(req) );

// 2 with topics
req["address"] = contractAddress;
BOOST_REQUIRE_NO_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs(req) );

// 3 11 blocks
req["toBlock"] = 12;
BOOST_REQUIRE_THROW( Json::Value logs = fixture.rpcClient->eth_getLogs(req), std::exception );

// 4 filter
string filterId = fixture.rpcClient->eth_newFilter( req );
BOOST_REQUIRE_THROW( Json::Value res = fixture.rpcClient->eth_getFilterLogs(filterId), std::exception );
BOOST_REQUIRE_NO_THROW( Json::Value res = fixture.rpcClient->eth_getFilterChanges(filterId) );
}

BOOST_AUTO_TEST_CASE( estimate_gas_low_gas_txn ) {
JsonRpcFixture fixture;
dev::eth::simulateMining( *( fixture.client ), 10 );
Expand Down

0 comments on commit b44e87f

Please sign in to comment.