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

Commit 183ce75

Browse files
committed
Use boost::variant
1 parent 70c7b5e commit 183ce75

File tree

4 files changed

+78
-29
lines changed

4 files changed

+78
-29
lines changed

libethereum/Block.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -864,7 +864,14 @@ bool Block::sealBlock(bytesConstRef _header)
864864
h256 Block::stateRootBeforeTx(unsigned _i) const
865865
{
866866
_i = min<unsigned>(_i, m_transactions.size());
867-
return (_i > 0 ? receipt(_i - 1).stateRoot() : m_previousBlock.stateRoot());
867+
try
868+
{
869+
return (_i > 0 ? receipt(_i - 1).stateRoot() : m_previousBlock.stateRoot());
870+
}
871+
catch(TransactionReceiptVersionError const&)
872+
{
873+
return {};
874+
}
868875
}
869876

870877
LogBloom Block::logBloom() const

libethereum/TransactionReceipt.cpp

Lines changed: 58 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@
2222
#include "TransactionReceipt.h"
2323
#include <libethcore/Exceptions.h>
2424

25+
#include <boost/variant/static_visitor.hpp>
26+
#include <boost/variant/get.hpp>
27+
28+
2529
using namespace std;
2630
using namespace dev;
2731
using namespace dev::eth;
@@ -35,12 +39,9 @@ TransactionReceipt::TransactionReceipt(bytesConstRef _rlp)
3539
if (!r[0].isData())
3640
BOOST_THROW_EXCEPTION(InvalidTransactionReceiptFormat());
3741
if (r[0].size() == 32)
38-
m_stateRoot = (h256)r[0];
42+
m_statusCodeOrStateRoot = (h256)r[0];
3943
else if (r[0].size() == 1)
40-
{
41-
m_statusCode = (uint8_t)r[0];
42-
m_hasStatusCode = true;
43-
}
44+
m_statusCodeOrStateRoot = (uint8_t)r[0];
4445

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

5253
TransactionReceipt::TransactionReceipt(h256 const& _root, u256 const& _gasUsed, LogEntries const& _log):
53-
m_hasStatusCode(false),
54-
m_stateRoot(_root),
54+
m_statusCodeOrStateRoot(_root),
5555
m_gasUsed(_gasUsed),
5656
m_bloom(eth::bloom(_log)),
5757
m_log(_log)
5858
{}
5959

6060
TransactionReceipt::TransactionReceipt(uint8_t _status, u256 const& _gasUsed, LogEntries const& _log):
61-
m_hasStatusCode(true),
62-
m_statusCode(_status),
61+
m_statusCodeOrStateRoot(_status),
6362
m_gasUsed(_gasUsed),
6463
m_bloom(eth::bloom(_log)),
6564
m_log(_log)
6665
{}
6766

6867
void TransactionReceipt::streamRLP(RLPStream& _s) const
6968
{
70-
_s.appendList(4);
71-
if (m_hasStatusCode)
72-
_s << m_statusCode;
73-
else
74-
_s << m_stateRoot;
69+
struct appenderVisitor : boost::static_visitor<void>
70+
{
71+
appenderVisitor(RLPStream& _s) : m_stream(_s) {}
72+
RLPStream& m_stream;
73+
void operator()(uint8_t _statusCode) const
74+
{
75+
m_stream << _statusCode;
76+
}
77+
void operator()(h256 _stateRoot) const
78+
{
79+
m_stream << _stateRoot;
80+
}
81+
};
7582

83+
_s.appendList(4);
84+
boost::apply_visitor(appenderVisitor(_s), m_statusCodeOrStateRoot);
7685
_s << m_gasUsed << m_bloom;
77-
7886
_s.appendList(m_log.size());
7987
for (LogEntry const& l: m_log)
8088
l.streamRLP(_s);
8189
}
8290

91+
bool TransactionReceipt::hasStatusCode() const
92+
{
93+
struct hasStatusCodeVisitor : boost::static_visitor<bool>
94+
{
95+
bool operator()(uint8_t) const
96+
{
97+
return true;
98+
}
99+
bool operator()(h256) const
100+
{
101+
return false;
102+
}
103+
};
104+
return boost::apply_visitor(hasStatusCodeVisitor(), m_statusCodeOrStateRoot);
105+
}
106+
83107
uint8_t TransactionReceipt::statusCode() const
84108
{
85-
if (!m_hasStatusCode)
86-
BOOST_THROW_EXCEPTION(TransactionReceiptVersionError());
87-
return m_statusCode;
109+
struct statusCodeVisitor : boost::static_visitor<uint8_t>
110+
{
111+
uint8_t operator()(uint8_t _statusCode) const
112+
{
113+
return _statusCode;
114+
}
115+
uint8_t operator()(h256) const
116+
{
117+
BOOST_THROW_EXCEPTION(TransactionReceiptVersionError());
118+
}
119+
};
120+
return boost::apply_visitor(statusCodeVisitor(), m_statusCodeOrStateRoot);
88121
}
89122

90123
h256 const& TransactionReceipt::stateRoot() const
91124
{
92-
if (m_hasStatusCode)
125+
try
126+
{
127+
return boost::get<h256>(m_statusCodeOrStateRoot);
128+
}
129+
catch(const boost::bad_get&)
130+
{
93131
BOOST_THROW_EXCEPTION(TransactionReceiptVersionError());
94-
return m_stateRoot;
132+
}
95133
}
96134

97135
std::ostream& dev::eth::operator<<(std::ostream& _out, TransactionReceipt const& _r)

libethereum/TransactionReceipt.h

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <libdevcore/RLP.h>
2727
#include <libevm/ExtVMFace.h>
2828

29+
#include <boost/variant/variant.hpp>
30+
2931
namespace dev
3032
{
3133

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

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

6062
private:
61-
bool m_hasStatusCode = false;
62-
union
63-
{
64-
uint8_t m_statusCode = 0;
65-
h256 m_stateRoot;
66-
};
63+
boost::variant<uint8_t,h256> m_statusCodeOrStateRoot;
6764
u256 m_gasUsed;
6865
LogBloom m_bloom;
6966
LogEntries m_log;

libweb3jsonrpc/JsonHelper.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,14 @@ Json::Value toJson(dev::eth::TransactionSkeleton const& _t)
185185
Json::Value toJson(dev::eth::TransactionReceipt const& _t)
186186
{
187187
Json::Value res;
188-
res["stateRoot"] = toJS(_t.stateRoot());
188+
try
189+
{
190+
res["stateRoot"] = toJS(_t.stateRoot());
191+
}
192+
catch (TransactionReceiptVersionError const&)
193+
{
194+
res["statusCode"] = toJS(_t.statusCode());
195+
}
189196
res["gasUsed"] = toJS(_t.gasUsed());
190197
res["bloom"] = toJS(_t.bloom());
191198
res["log"] = dev::toJson(_t.log());

0 commit comments

Comments
 (0)