Skip to content
This repository has been archived by the owner on Oct 28, 2021. It is now read-only.

Commit

Permalink
Use boost::variant
Browse files Browse the repository at this point in the history
  • Loading branch information
pirapira committed Jul 19, 2017
1 parent 70c7b5e commit 183ce75
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 29 deletions.
9 changes: 8 additions & 1 deletion libethereum/Block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -864,7 +864,14 @@ bool Block::sealBlock(bytesConstRef _header)
h256 Block::stateRootBeforeTx(unsigned _i) const
{
_i = min<unsigned>(_i, m_transactions.size());
return (_i > 0 ? receipt(_i - 1).stateRoot() : m_previousBlock.stateRoot());
try
{
return (_i > 0 ? receipt(_i - 1).stateRoot() : m_previousBlock.stateRoot());
}
catch(TransactionReceiptVersionError const&)
{
return {};
}
}

LogBloom Block::logBloom() const
Expand Down
78 changes: 58 additions & 20 deletions libethereum/TransactionReceipt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
#include "TransactionReceipt.h"
#include <libethcore/Exceptions.h>

#include <boost/variant/static_visitor.hpp>
#include <boost/variant/get.hpp>


using namespace std;
using namespace dev;
using namespace dev::eth;
Expand All @@ -35,12 +39,9 @@ TransactionReceipt::TransactionReceipt(bytesConstRef _rlp)
if (!r[0].isData())
BOOST_THROW_EXCEPTION(InvalidTransactionReceiptFormat());
if (r[0].size() == 32)
m_stateRoot = (h256)r[0];
m_statusCodeOrStateRoot = (h256)r[0];
else if (r[0].size() == 1)
{
m_statusCode = (uint8_t)r[0];
m_hasStatusCode = true;
}
m_statusCodeOrStateRoot = (uint8_t)r[0];

m_gasUsed = (u256)r[1];
m_bloom = (LogBloom)r[2];
Expand All @@ -50,48 +51,85 @@ TransactionReceipt::TransactionReceipt(bytesConstRef _rlp)
}

TransactionReceipt::TransactionReceipt(h256 const& _root, u256 const& _gasUsed, LogEntries const& _log):
m_hasStatusCode(false),
m_stateRoot(_root),
m_statusCodeOrStateRoot(_root),
m_gasUsed(_gasUsed),
m_bloom(eth::bloom(_log)),
m_log(_log)
{}

TransactionReceipt::TransactionReceipt(uint8_t _status, u256 const& _gasUsed, LogEntries const& _log):
m_hasStatusCode(true),
m_statusCode(_status),
m_statusCodeOrStateRoot(_status),
m_gasUsed(_gasUsed),
m_bloom(eth::bloom(_log)),
m_log(_log)
{}

void TransactionReceipt::streamRLP(RLPStream& _s) const
{
_s.appendList(4);
if (m_hasStatusCode)
_s << m_statusCode;
else
_s << m_stateRoot;
struct appenderVisitor : boost::static_visitor<void>
{
appenderVisitor(RLPStream& _s) : m_stream(_s) {}
RLPStream& m_stream;
void operator()(uint8_t _statusCode) const
{
m_stream << _statusCode;
}
void operator()(h256 _stateRoot) const
{
m_stream << _stateRoot;
}
};

_s.appendList(4);
boost::apply_visitor(appenderVisitor(_s), m_statusCodeOrStateRoot);
_s << m_gasUsed << m_bloom;

_s.appendList(m_log.size());
for (LogEntry const& l: m_log)
l.streamRLP(_s);
}

bool TransactionReceipt::hasStatusCode() const
{
struct hasStatusCodeVisitor : boost::static_visitor<bool>
{
bool operator()(uint8_t) const
{
return true;
}
bool operator()(h256) const
{
return false;
}
};
return boost::apply_visitor(hasStatusCodeVisitor(), m_statusCodeOrStateRoot);
}

uint8_t TransactionReceipt::statusCode() const
{
if (!m_hasStatusCode)
BOOST_THROW_EXCEPTION(TransactionReceiptVersionError());
return m_statusCode;
struct statusCodeVisitor : boost::static_visitor<uint8_t>
{
uint8_t operator()(uint8_t _statusCode) const
{
return _statusCode;
}
uint8_t operator()(h256) const
{
BOOST_THROW_EXCEPTION(TransactionReceiptVersionError());
}
};
return boost::apply_visitor(statusCodeVisitor(), m_statusCodeOrStateRoot);
}

h256 const& TransactionReceipt::stateRoot() const
{
if (m_hasStatusCode)
try
{
return boost::get<h256>(m_statusCodeOrStateRoot);
}
catch(const boost::bad_get&)
{
BOOST_THROW_EXCEPTION(TransactionReceiptVersionError());
return m_stateRoot;
}
}

std::ostream& dev::eth::operator<<(std::ostream& _out, TransactionReceipt const& _r)
Expand Down
11 changes: 4 additions & 7 deletions libethereum/TransactionReceipt.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@
#include <libdevcore/RLP.h>
#include <libevm/ExtVMFace.h>

#include <boost/variant/variant.hpp>

namespace dev
{

Expand All @@ -42,7 +44,7 @@ class TransactionReceipt
TransactionReceipt(h256 const& _root, u256 const& _gasUsed, LogEntries const& _log);
TransactionReceipt(uint8_t _status, u256 const& _gasUsed, LogEntries const& _log);

bool hasStatusCode() const { return m_hasStatusCode; }
bool hasStatusCode() const;
/// @returns the state root.
/// @throw TransactionReceiptVersionError when m_hasStatusCode is true.
h256 const& stateRoot() const;
Expand All @@ -58,12 +60,7 @@ class TransactionReceipt
bytes rlp() const { RLPStream s; streamRLP(s); return s.out(); }

private:
bool m_hasStatusCode = false;
union
{
uint8_t m_statusCode = 0;
h256 m_stateRoot;
};
boost::variant<uint8_t,h256> m_statusCodeOrStateRoot;
u256 m_gasUsed;
LogBloom m_bloom;
LogEntries m_log;
Expand Down
9 changes: 8 additions & 1 deletion libweb3jsonrpc/JsonHelper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,14 @@ Json::Value toJson(dev::eth::TransactionSkeleton const& _t)
Json::Value toJson(dev::eth::TransactionReceipt const& _t)
{
Json::Value res;
res["stateRoot"] = toJS(_t.stateRoot());
try
{
res["stateRoot"] = toJS(_t.stateRoot());
}
catch (TransactionReceiptVersionError const&)
{
res["statusCode"] = toJS(_t.statusCode());
}
res["gasUsed"] = toJS(_t.gasUsed());
res["bloom"] = toJS(_t.bloom());
res["log"] = dev::toJson(_t.log());
Expand Down

0 comments on commit 183ce75

Please sign in to comment.