diff --git a/CMakeLists.txt b/CMakeLists.txt index 01f60bbf5..912812947 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -292,12 +292,24 @@ else() set(QTQML 1) endif() +if(CRYPTOPP_ID) include_directories(${CRYPTOPP_ID}) +endif() +if(PYTHON_ID) include_directories(${PYTHON_ID}) +endif() +if(MINIUPNPC_ID) include_directories(${MINIUPNPC_ID}) +endif() +if(LEVELDB_ID) include_directories(${LEVELDB_ID}) +endif() +if(READLINE_ID) include_directories(${READLINE_ID}) -include_directories(${JSONRPC_ID}) +endif() +if(JSONRPC_ID) + include_directories(${JSONRPC_ID}) +endif() # if (NOT APPLE) # link_directories(${CRYPTOPP_LS}) diff --git a/eth/CMakeLists.txt b/eth/CMakeLists.txt index ba5f3e509..350c22f80 100644 --- a/eth/CMakeLists.txt +++ b/eth/CMakeLists.txt @@ -13,11 +13,17 @@ add_executable(${EXECUTABLE} ${SRC_LIST}) target_link_libraries(${EXECUTABLE} ethereum) target_link_libraries(${EXECUTABLE} secp256k1) target_link_libraries(${EXECUTABLE} gmp) -target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +if(MINIUPNPC_LS) + target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) +if(JSONRPC_LS) target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) +endif() +if(READLINE_LS) target_link_libraries(${EXECUTABLE} ${READLINE_LS}) +endif() if (${TARGET_PLATFORM} STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") diff --git a/exp/CMakeLists.txt b/exp/CMakeLists.txt index e894bc716..45a30adbc 100644 --- a/exp/CMakeLists.txt +++ b/exp/CMakeLists.txt @@ -9,12 +9,12 @@ set(EXECUTABLE exp) add_executable(${EXECUTABLE} ${SRC_LIST}) target_link_libraries(${EXECUTABLE} ethereum) +target_link_libraries(${EXECUTABLE} gmp) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) +if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} ${JSONRPC_LS}) -target_link_libraries(${EXECUTABLE} ${READLINE_LS}) -target_link_libraries(${EXECUTABLE} gmp) if (${TARGET_PLATFORM} STREQUAL "w64") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++") diff --git a/libethcore/CMakeLists.txt b/libethcore/CMakeLists.txt index 590b1b5e3..414201614 100644 --- a/libethcore/CMakeLists.txt +++ b/libethcore/CMakeLists.txt @@ -17,9 +17,11 @@ include_directories(..) target_link_libraries(${EXECUTABLE} ethential) target_link_libraries(${EXECUTABLE} secp256k1) +target_link_libraries(${EXECUTABLE} gmp) +if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) -target_link_libraries(${EXECUTABLE} gmp) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) if(${TARGET_PLATFORM} STREQUAL "w64") diff --git a/libethereum/CMakeLists.txt b/libethereum/CMakeLists.txt index ca298814f..9b0a507aa 100644 --- a/libethereum/CMakeLists.txt +++ b/libethereum/CMakeLists.txt @@ -21,7 +21,9 @@ target_link_libraries(${EXECUTABLE} evm) target_link_libraries(${EXECUTABLE} lll) target_link_libraries(${EXECUTABLE} ethcore) target_link_libraries(${EXECUTABLE} secp256k1) +if(MINIUPNPC_LS) target_link_libraries(${EXECUTABLE} ${MINIUPNPC_LS}) +endif() target_link_libraries(${EXECUTABLE} ${LEVELDB_LS}) target_link_libraries(${EXECUTABLE} ${CRYPTOPP_LS}) target_link_libraries(${EXECUTABLE} gmp) diff --git a/libethereum/Client.cpp b/libethereum/Client.cpp index 98d2899f9..2a3b3f29d 100644 --- a/libethereum/Client.cpp +++ b/libethereum/Client.cpp @@ -327,8 +327,73 @@ bytes Client::codeAt(Address _a, int _block) const return asOf(_block).code(_a); } +bool TransactionFilter::matches(State const& _s, unsigned _i) const +{ + Transaction t = _s.pending()[_i]; + if (!m_to.empty() && !m_to.count(t.receiveAddress)) + return false; + if (!m_from.empty() && !m_from.count(t.sender())) + return false; + if (m_stateAltered.empty() && m_altered.empty()) + return true; + StateDiff d = _s.pendingDiff(_i); + if (!m_stateAltered.empty()) + { + for (auto const& s: m_stateAltered) + if (d.accounts.count(s.first) && d.accounts.at(s.first).storage.count(s.second)) + goto OK; + return false; + OK:; + } + if (!m_altered.empty()) + { + for (auto const& s: m_altered) + if (d.accounts.count(s)) + goto OK2; + return false; + OK2:; + } + return true; +} + Transactions Client::transactions(TransactionFilter const& _f) const { Transactions ret; + unsigned begin = numberOf(_f.latest()); + unsigned end = min(begin, numberOf(_f.earliest())); + unsigned m = _f.max(); + unsigned s = _f.skip(); + + // Handle pending transactions differently as they're not on the block chain. + if (_f.latest() == 0) + { + for (unsigned i = m_postMine.pending().size(); i--;) + if (_f.matches(m_postMine, i)) + { + if (s) + s--; + else + ret.insert(ret.begin(), m_postMine.pending()[i]); + } + // Early exit here since we can't rely on begin/end, being out of the blockchain as we are. + if (_f.earliest() == 0) + return ret; + } + + auto h = m_bc.numberHash(begin); + for (unsigned n = begin; ret.size() != m; n--, h = m_bc.details(h).parent) + { + State st(m_stateDB, m_bc, h); + for (unsigned i = st.pending().size(); i--;) + if (_f.matches(st, i)) + { + if (s) + s--; + else + ret.insert(ret.begin(), st.pending()[i]); + } + if (n == end) + break; + } return ret; } diff --git a/libethereum/Client.h b/libethereum/Client.h index 9c8bf0e9c..8316e33c4 100644 --- a/libethereum/Client.h +++ b/libethereum/Client.h @@ -77,29 +77,39 @@ private: unsigned m_protocolVersion; }; +static const int GenesisBlock = INT_MIN; + class TransactionFilter { public: - TransactionFilter(int _blockFrom = 0, int _blockTo = -1, unsigned _max = 10): m_blockFrom(_blockFrom), m_blockTo(_blockTo), m_max(_max) {} + TransactionFilter(int _earliest = GenesisBlock, int _latest = 0, unsigned _max = 10, unsigned _skip = 0): m_earliest(_earliest), m_latest(_latest), m_max(_max), m_skip(_skip) {} + + int earliest() const { return m_earliest; } + int latest() const { return m_latest; } + unsigned max() const { return m_max; } + unsigned skip() const { return m_skip; } + bool matches(State const& _s, unsigned _i) const; TransactionFilter from(Address _a) { m_from.insert(_a); return *this; } TransactionFilter to(Address _a) { m_to.insert(_a); return *this; } TransactionFilter stateAltered(Address _a, u256 _l) { m_stateAltered.insert(std::make_pair(_a, _l)); return *this; } TransactionFilter stateAltered(Address _a) { m_altered.insert(_a); return *this; } TransactionFilter withMax(unsigned _m) { m_max = _m; return *this; } + TransactionFilter withSkip(unsigned _m) { m_skip = _m; return *this; } + TransactionFilter withEarliest(int _e) { m_earliest = _e; return *this; } + TransactionFilter withLatest(int _e) { m_latest = _e; return *this; } private: std::set
m_from; std::set m_to; std::set