void Transaction::streamRLP(RLPStream& _s, IncludeSignature _sig) const { if (m_type == NullTransaction) return; _s.appendList((_sig ? 3 : 0) + 6); _s << m_nonce << m_gasPrice << m_gas; if (m_type == MessageCall) _s << m_receiveAddress; else _s << ""; _s << m_value << m_data; if (_sig) _s << (m_vrs.v + 27) << (u256)m_vrs.r << (u256)m_vrs.s; }
bytes Raft::authBytes() { bytes ret; RLPStream authListStream; authListStream.appendList(m_idVoted.size()*2); for(auto it : m_idVoted){ authListStream << it.first; authListStream << it.second; } authListStream.swapOut(ret); return ret;
void Raft::voteBlockEnd() { uint64_t now = utcTime(); if(m_idUnVoted.size() >= (nodeCount()+1)/2 || now > m_consensusTimeOut){ LOG(TRACE) << "m_idUnVoted.size()=" << m_idUnVoted.size() << ",m_idVoted.size()=" << m_idVoted.size() << ",nodeCount()=" << nodeCount(); reSet(); return; } if(raftFinished != m_consensusState && m_idVoted.size() > nodeCount()/2){ LOG(TRACE) << "Vote succed, m_blockBytes.size() = " << m_blockBytes.size(); try{ if(m_onSealGenerated){ std::vector<std::pair<u256, Signature>> sig_list; for(size_t i = 0; i < m_miner_list.size(); i++){ if(m_idVoted.count(m_miner_list[i])){ sig_list.push_back(std::make_pair(u256(i), m_idVoted[m_miner_list[i]])); } } BlockHeader header(m_blockBytes); RLP r(m_blockBytes); RLPStream rs; rs.appendList(5); rs.appendRaw(r[0].data()); // header rs.appendRaw(r[1].data()); // tx rs.appendRaw(r[2].data()); // uncles rs.append(header.hash()); // hash rs.appendVector(sig_list); // sign_list bytes blockBytes; rs.swapOut(blockBytes); LOG(TRACE) << "Vote_succed: idx.count blockBytes.size() = " << blockBytes.size() << ",header.number()=" << header.number() << ",header.hash()=" << header.hash(WithoutSeal) << ",generl_id = " << (m_votedId == NodeID() ? id() : m_votedId) << ",m_node_idx=" << static_cast<uint64_t>(m_node_idx); m_onSealGenerated(blockBytes, m_votedId == NodeID()); } }catch(...){ LOG(ERROR) << "m_consensusFinishedFunc run err"; } m_consensusState = raftFinished; m_consensusTimeOut = utcTime() + m_consensusTimeInterval; return;
void TransactionBase::streamRLP(RLPStream &_s, IncludeSignature _sig, bool _forEip155hash) const { if (m_type == NullTransaction) return; _s.appendList((_sig || _forEip155hash ? 3 : 0) + 6); _s << m_nonce << m_gasPrice << m_gas; if (m_type == MessageCall) _s << m_receiveAddress; else _s << ""; _s << m_value << m_data; if (_sig) { int vOffset = m_chainId * 2 + 35; _s << (m_vrs.v + vOffset) << (u256)m_vrs.r << (u256)m_vrs.s; } else if (_forEip155hash) _s << m_chainId << 0 << 0; }
static void buildRLP(js::mValue& _v, RLPStream& _rlp) { if (_v.type() == js::array_type) { RLPStream s; for (auto& i: _v.get_array()) buildRLP(i, s); _rlp.appendList(s.out()); } else if (_v.type() == js::int_type) _rlp.append(_v.get_uint64()); else if (_v.type() == js::str_type) { auto s = _v.get_str(); if (s.size() && s[0] == '#') _rlp.append(bigint(s.substr(1))); else _rlp.append(s); } }
void State::completeMine() { cdebug << "Completing mine!"; // Got it! // Compile block: RLPStream ret; ret.appendList(3); m_currentBlock.streamRLP(ret, WithNonce); ret.appendRaw(m_currentTxs); ret.appendRaw(m_currentUncles); ret.swapOut(m_currentBytes); m_currentBlock.hash = sha3(RLP(m_currentBytes)[0].data()); cnote << "Mined " << m_currentBlock.hash.abridged() << "(parent: " << m_currentBlock.parentHash.abridged() << ")"; // Quickly reset the transactions. // TODO: Leave this in a better state than this limbo, or at least record that it's in limbo. m_transactions.clear(); m_receipts.clear(); m_transactionSet.clear(); m_lastTx = m_db; }
void WhisperPeer::sendMessages() { RLPStream amalg; unsigned n = 0; Guard l(x_unseen); while (m_unseen.size()) { auto p = *m_unseen.begin(); m_unseen.erase(m_unseen.begin()); host()->streamMessage(p.second, amalg); n++; } // pause before sending if no messages to send if (!n) this_thread::sleep_for(chrono::milliseconds(100)); RLPStream s; prep(s); s.appendList(n + 1) << MessagesPacket; s.appendRaw(amalg.out(), n); sealAndSend(s); }
bool State::amIJustParanoid(BlockChain const& _bc) { commitToMine(_bc); // Update difficulty according to timestamp. m_currentBlock.difficulty = m_currentBlock.calculateDifficulty(m_previousBlock); // Compile block: RLPStream block; block.appendList(3); m_currentBlock.streamRLP(block, WithNonce); block.appendRaw(m_currentTxs); block.appendRaw(m_currentUncles); State s(*this); s.resetCurrent(); try { cnote << "PARANOIA root:" << s.rootHash(); // s.m_currentBlock.populate(&block.out(), false); // s.m_currentBlock.verifyInternals(&block.out()); s.enact(&block.out(), _bc, false); // don't check nonce for this since we haven't mined it yet. s.cleanup(false); return true; } catch (Exception const& _e) { cwarn << "Bad block: " << diagnostic_information(_e); } catch (std::exception const& _e) { cwarn << "Bad block: " << _e.what(); } return false; }
void hash256rlp(HexMap const& _s, HexMap::const_iterator _begin, HexMap::const_iterator _end, unsigned _preLen, RLPStream& _rlp) { #if ENABLE_DEBUG_PRINT static std::string s_indent; if (_preLen) s_indent += " "; #endif if (_begin == _end) _rlp << ""; // NULL else if (std::next(_begin) == _end) { // only one left - terminate with the pair. _rlp.appendList(2) << hexPrefixEncode(_begin->first, true, _preLen) << _begin->second; #if ENABLE_DEBUG_PRINT if (g_hashDebug) std::cerr << s_indent << toHex(bytesConstRef(_begin->first.data() + _preLen, _begin->first.size() - _preLen), 1) << ": " << _begin->second << " = " << sha3(_rlp.out()) << std::endl; #endif } else { // find the number of common prefix nibbles shared // i.e. the minimum number of nibbles shared at the beginning between the first hex string and each successive. uint sharedPre = (uint)-1; uint c = 0; for (auto i = std::next(_begin); i != _end && sharedPre; ++i, ++c) { uint x = std::min(sharedPre, std::min((uint)_begin->first.size(), (uint)i->first.size())); uint shared = _preLen; for (; shared < x && _begin->first[shared] == i->first[shared]; ++shared) {} sharedPre = std::min(shared, sharedPre); } if (sharedPre > _preLen) { // if they all have the same next nibble, we also want a pair. #if ENABLE_DEBUG_PRINT if (g_hashDebug) std::cerr << s_indent << toHex(bytesConstRef(_begin->first.data() + _preLen, sharedPre), 1) << ": " << std::endl; #endif _rlp.appendList(2) << hexPrefixEncode(_begin->first, false, _preLen, (int)sharedPre); hash256aux(_s, _begin, _end, (unsigned)sharedPre, _rlp); #if ENABLE_DEBUG_PRINT if (g_hashDebug) std::cerr << s_indent << "= " << hex << sha3(_rlp.out()) << dec << std::endl; #endif } else { // otherwise enumerate all 16+1 entries. _rlp.appendList(17); auto b = _begin; if (_preLen == b->first.size()) { #if ENABLE_DEBUG_PRINT if (g_hashDebug) std::cerr << s_indent << "@: " << b->second << std::endl; #endif ++b; } for (auto i = 0; i < 16; ++i) { auto n = b; for (; n != _end && n->first[_preLen] == i; ++n) {} if (b == n) _rlp << ""; else { #if ENABLE_DEBUG_PRINT if (g_hashDebug) std::cerr << s_indent << std::hex << i << ": " << std::dec << std::endl; #endif hash256aux(_s, b, n, _preLen + 1, _rlp); } b = n; } if (_preLen == _begin->first.size()) _rlp << _begin->second; else _rlp << ""; #if ENABLE_DEBUG_PRINT if (g_hashDebug) std::cerr << s_indent << "= " << hex << sha3(_rlp.out()) << dec << std::endl; #endif } } #if ENABLE_DEBUG_PRINT if (_preLen) s_indent.resize(s_indent.size() - 2); #endif }
WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h): Capability(_s, _h) { RLPStream s; prep(s); sealAndSend(s.appendList(2) << StatusPacket << host()->protocolVersion()); }
void TrieLeafNode::makeRLP(RLPStream& _intoStream) const { _intoStream.appendList(2) << hexPrefixEncode(m_ext, true) << m_value; }
bool PeerServer::sync(BlockChain& _bc, TransactionQueue& _tq, Overlay& _o) { bool ret = ensureInitialised(_bc, _tq); if (sync()) ret = true; if (m_mode == NodeMode::Full) { for (auto it = m_incomingTransactions.begin(); it != m_incomingTransactions.end(); ++it) if (_tq.import(*it)) {}//ret = true; // just putting a transaction in the queue isn't enough to change the state - it might have an invalid nonce... else m_transactionsSent.insert(sha3(*it)); // if we already had the transaction, then don't bother sending it on. m_incomingTransactions.clear(); auto h = _bc.currentHash(); bool resendAll = (h != m_latestBlockSent); // Send any new transactions. for (auto j: m_peers) if (auto p = j.second.lock()) { bytes b; uint n = 0; for (auto const& i: _tq.transactions()) if ((!m_transactionsSent.count(i.first) && !p->m_knownTransactions.count(i.first)) || p->m_requireTransactions || resendAll) { b += i.second; ++n; m_transactionsSent.insert(i.first); } if (n) { RLPStream ts; PeerSession::prep(ts); ts.appendList(n + 1) << TransactionsPacket; ts.appendRaw(b, n).swapOut(b); seal(b); p->send(&b); } p->m_knownTransactions.clear(); p->m_requireTransactions = false; } // Send any new blocks. if (h != m_latestBlockSent) { // TODO: find where they diverge and send complete new branch. RLPStream ts; PeerSession::prep(ts); ts.appendList(2) << BlocksPacket; bytes b; ts.appendRaw(_bc.block(_bc.currentHash())).swapOut(b); seal(b); for (auto j: m_peers) if (auto p = j.second.lock()) { if (!p->m_knownBlocks.count(_bc.currentHash())) p->send(&b); p->m_knownBlocks.clear(); } } m_latestBlockSent = h; for (int accepted = 1, n = 0; accepted; ++n) { accepted = 0; if (m_incomingBlocks.size()) for (auto it = prev(m_incomingBlocks.end());; --it) { try { _bc.import(*it, _o); it = m_incomingBlocks.erase(it); ++accepted; ret = true; } catch (UnknownParent) { // Don't (yet) know its parent. Leave it for later. m_unknownParentBlocks.push_back(*it); it = m_incomingBlocks.erase(it); } catch (...) { // Some other error - erase it. it = m_incomingBlocks.erase(it); } if (it == m_incomingBlocks.begin()) break; } if (!n && accepted) { for (auto i: m_unknownParentBlocks) m_incomingBlocks.push_back(i); m_unknownParentBlocks.clear(); } } // Connect to additional peers while (m_peers.size() < m_idealPeerCount) { if (m_freePeers.empty()) { if (chrono::steady_clock::now() > m_lastPeersRequest + chrono::seconds(10)) { RLPStream s; bytes b; (PeerSession::prep(s).appendList(1) << GetPeersPacket).swapOut(b); seal(b); for (auto const& i: m_peers) if (auto p = i.second.lock()) if (p->isOpen()) p->send(&b); m_lastPeersRequest = chrono::steady_clock::now(); } if (!m_accepting) ensureAccepting(); break; } auto x = time(0) % m_freePeers.size(); m_incomingPeers[m_freePeers[x]].second++; connect(m_incomingPeers[m_freePeers[x]].first); m_freePeers.erase(m_freePeers.begin() + x); } } // platform for consensus of social contract. // restricts your freedom but does so fairly. and that's the value proposition. // guarantees that everyone else respect the rules of the system. (i.e. obeys laws). // We'll keep at most twice as many as is ideal, halfing what counts as "too young to kill" until we get there. for (uint old = 15000; m_peers.size() > m_idealPeerCount * 2 && old > 100; old /= 2) while (m_peers.size() > m_idealPeerCount) { // look for worst peer to kick off // first work out how many are old enough to kick off. shared_ptr<PeerSession> worst; unsigned agedPeers = 0; for (auto i: m_peers) if (auto p = i.second.lock()) if ((m_mode != NodeMode::PeerServer || p->m_caps != 0x01) && chrono::steady_clock::now() > p->m_connect + chrono::milliseconds(old)) // don't throw off new peers; peer-servers should never kick off other peer-servers. { ++agedPeers; if ((!worst || p->m_rating < worst->m_rating || (p->m_rating == worst->m_rating && p->m_connect > worst->m_connect))) // kill older ones worst = p; } if (!worst || agedPeers <= m_idealPeerCount) break; worst->disconnect(TooManyPeers); } return ret; }
void EthereumCapability::maintainBlocks(h256 const& _currentHash) { // Send any new blocks. auto detailsFrom = m_chain.details(m_latestBlockSent); auto detailsTo = m_chain.details(_currentHash); if (detailsFrom.totalDifficulty < detailsTo.totalDifficulty) { if (diff(detailsFrom.number, detailsTo.number) < 20) { // don't be sending more than 20 "new" blocks. if there are any more we were probably waaaay behind. LOG(m_logger) << "Sending new blocks (current is " << _currentHash << ", was " << m_latestBlockSent << ")"; h256s blocks = get<0>(m_chain.treeRoute(m_latestBlockSent, _currentHash, false, false, true)); auto const peersWithoutBlock = selectPeers( [&](EthereumPeer const& _peer) { return !_peer.isBlockKnown(_currentHash); }); auto const peersToSendNumber = std::max<std::size_t>(c_minBlockBroadcastPeers, std::sqrt(m_peers.size())); std::vector<NodeID> peersToSend; std::vector<NodeID> peersToAnnounce; std::tie(peersToSend, peersToAnnounce) = randomPartitionPeers(peersWithoutBlock, peersToSendNumber); for (NodeID const& peerID : peersToSend) for (auto const& b: blocks) { RLPStream ts; m_host->prep(peerID, name(), ts, NewBlockPacket, 2) .appendRaw(m_chain.block(b), 1) .append(m_chain.details(b).totalDifficulty); auto itPeer = m_peers.find(peerID); if (itPeer != m_peers.end()) { m_host->sealAndSend(peerID, ts); itPeer->second.clearKnownBlocks(); } } if (!peersToSend.empty()) LOG(m_logger) << "Sent " << blocks.size() << " block(s) to " << peersToSend.size() << " peers"; for (NodeID const& peerID : peersToAnnounce) { RLPStream ts; m_host->prep(peerID, name(), ts, NewBlockHashesPacket, blocks.size()); for (auto const& b: blocks) { ts.appendList(2); ts.append(b); ts.append(m_chain.number(b)); } auto itPeer = m_peers.find(peerID); if (itPeer != m_peers.end()) { m_host->sealAndSend(peerID, ts); itPeer->second.clearKnownBlocks(); } } if (!peersToAnnounce.empty()) LOG(m_logger) << "Announced " << blocks.size() << " block(s) to " << peersToAnnounce.size() << " peers"; } m_latestBlockSent = _currentHash; } }
void State::commitToMine(BlockChain const& _bc) { uncommitToMine(); // cnote << "Committing to mine on block" << m_previousBlock.hash.abridged(); #ifdef ETH_PARANOIA commit(); cnote << "Pre-reward stateRoot:" << m_state.root(); #endif m_lastTx = m_db; Addresses uncleAddresses; RLPStream unclesData; unsigned unclesCount = 0; if (m_previousBlock.number != 0) { // Find great-uncles (or second-cousins or whatever they are) - children of great-grandparents, great-great-grandparents... that were not already uncles in previous generations. // cout << "Checking " << m_previousBlock.hash << ", parent=" << m_previousBlock.parentHash << endl; set<h256> knownUncles = _bc.allUnclesFrom(m_currentBlock.parentHash); auto p = m_previousBlock.parentHash; for (unsigned gen = 0; gen < 6 && p != _bc.genesisHash(); ++gen, p = _bc.details(p).parent) { auto us = _bc.details(p).children; assert(us.size() >= 1); // must be at least 1 child of our grandparent - it's our own parent! for (auto const& u: us) if (!knownUncles.count(u)) // ignore any uncles/mainline blocks that we know about. { BlockInfo ubi(_bc.block(u)); ubi.streamRLP(unclesData, WithNonce); ++unclesCount; uncleAddresses.push_back(ubi.coinbaseAddress); } } } MemoryDB tm; GenericTrieDB<MemoryDB> transactionsTrie(&tm); transactionsTrie.init(); MemoryDB rm; GenericTrieDB<MemoryDB> receiptsTrie(&rm); receiptsTrie.init(); RLPStream txs; txs.appendList(m_transactions.size()); for (unsigned i = 0; i < m_transactions.size(); ++i) { RLPStream k; k << i; RLPStream receiptrlp; m_receipts[i].streamRLP(receiptrlp); receiptsTrie.insert(&k.out(), &receiptrlp.out()); RLPStream txrlp; m_transactions[i].streamRLP(txrlp); transactionsTrie.insert(&k.out(), &txrlp.out()); txs.appendRaw(txrlp.out()); } txs.swapOut(m_currentTxs); RLPStream(unclesCount).appendRaw(unclesData.out(), unclesCount).swapOut(m_currentUncles); m_currentBlock.transactionsRoot = transactionsTrie.root(); m_currentBlock.receiptsRoot = receiptsTrie.root(); m_currentBlock.logBloom = logBloom(); m_currentBlock.sha3Uncles = sha3(m_currentUncles); // Apply rewards last of all. applyRewards(uncleAddresses); // Commit any and all changes to the trie that are in the cache, then update the state root accordingly. commit(); // cnote << "Post-reward stateRoot:" << m_state.root().abridged(); // cnote << m_state; // cnote << *this; m_currentBlock.gasUsed = gasUsed(); m_currentBlock.stateRoot = m_state.root(); m_currentBlock.parentHash = m_previousBlock.hash; }
void Pong::streamRLP(RLPStream& _s) const { _s.appendList(3); destination.streamRLP(_s); _s << echo << ts; }
void LogFilter::streamRLP(RLPStream& _s) const { _s.appendList(4) << m_addresses << m_topics << m_earliest << m_latest; }