Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
Exemplo n.º 3
0
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;
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
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);
		}
	}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
0
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);
}
Exemplo n.º 8
0
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;
}
Exemplo n.º 9
0
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
}
Exemplo n.º 10
0
WhisperPeer::WhisperPeer(Session* _s, HostCapabilityFace* _h): Capability(_s, _h)
{
	RLPStream s;
	prep(s);
	sealAndSend(s.appendList(2) << StatusPacket << host()->protocolVersion());
}
Exemplo n.º 11
0
void TrieLeafNode::makeRLP(RLPStream& _intoStream) const
{
	_intoStream.appendList(2) << hexPrefixEncode(m_ext, true) << m_value;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
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;
    }
}
Exemplo n.º 14
0
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;
}
Exemplo n.º 15
0
void Pong::streamRLP(RLPStream& _s) const
{
	_s.appendList(3);
	destination.streamRLP(_s);
	_s << echo << ts;
}
Exemplo n.º 16
0
void LogFilter::streamRLP(RLPStream& _s) const
{
	_s.appendList(4) << m_addresses << m_topics << m_earliest << m_latest;
}