Fabcoin Core  0.16.2
P2P Digital Currency
fascstate.cpp
Go to the documentation of this file.
1 #include <sstream>
2 #include <util.h>
3 #include <validation.h>
4 #include <chainparams.h>
5 #include <fasc/fascstate.h>
6 
7 using namespace std;
8 using namespace dev;
9 using namespace dev::eth;
10 
11 FascState::FascState(u256 const& _accountStartNonce, OverlayDB const& _db, const string& _path, BaseState _bs) :
12  State(_accountStartNonce, _db, _bs) {
13  dbUTXO = FascState::openDB(_path + "/fascDB", sha3(rlp("")), WithExisting::Trust);
14  stateUTXO = SecureTrieDB<Address, OverlayDB>(&dbUTXO);
15 }
16 
18  dbUTXO = OverlayDB();
20 }
21 
22 ResultExecute FascState::execute(EnvInfo const& _envInfo, SealEngineFace const& _sealEngine, FascTransaction const& _t, Permanence _p, OnOpFunc const& _onOp) {
23 
25 
26  addBalance(_t.sender(), _t.value() + (_t.gas() * _t.gasPrice()));
28 
29  _sealEngine.deleteAddresses.insert({_t.sender(), _envInfo.author()});
30 
31  h256 oldStateRoot = rootHash();
32  bool voutLimit = false;
33 
34  auto onOp = _onOp;
35 #if ETH_VMTRACE
36  if (isChannelVisible<VMTraceChannel>())
37  onOp = Executive::simpleTrace(); // override tracer
38 #endif
39  // Create and initialize the executive. This will throw fairly cheaply and quickly if the
40  // transaction is bad in any way.
41  Executive e(*this, _envInfo, _sealEngine);
42  ExecutionResult res;
43  e.setResultRecipient(res);
44 
45  CTransactionRef tx;
46  u256 startGasUsed;
47  try {
48  if (_t.isCreation() && _t.value())
49  BOOST_THROW_EXCEPTION(CreateWithValue());
50 
51  e.initialize(_t);
52  // OK - transaction looks valid - execute.
53  startGasUsed = _envInfo.gasUsed();
54  if (!e.execute()) {
55  e.go(onOp);
56  } else {
57 
58  e.revert();
59  throw Exception();
60  }
61  e.finalize();
62  if (_p == Permanence::Reverted) {
63  m_cache.clear();
64  cacheUTXO.clear();
65  } else {
66  deleteAccounts(_sealEngine.deleteAddresses);
67  if(res.excepted == TransactionException::None) {
68  CondensingTX ctx(this, transfers, _t, _sealEngine.deleteAddresses);
69  tx = MakeTransactionRef(ctx.createCondensingTX());
70  if(ctx.reachedVoutLimit()) {
71 
72  voutLimit = true;
73  e.revert();
74  throw Exception();
75  }
76  std::unordered_map<dev::Address, Vin> vins = ctx.createVin(*tx);
77  updateUTXO(vins);
78  } else {
80  }
81 
83  cacheUTXO.clear();
84  bool removeEmptyAccounts = _envInfo.number() >= _sealEngine.chainParams().u256Param("EIP158ForkBlock");
85  commit(removeEmptyAccounts ? State::CommitBehaviour::RemoveEmptyAccounts : State::CommitBehaviour::KeepEmptyAccounts);
86  }
87  }
88  catch(Exception const& _e) {
89 
92  res.gasUsed = _t.gas();
93  const Consensus::Params& consensusParams = Params().GetConsensus();
94  if(chainActive.Height() < consensusParams.nFixUTXOCacheHFHeight && _p != Permanence::Reverted){
95  deleteAccounts(_sealEngine.deleteAddresses);
97  } else {
98  m_cache.clear();
99  cacheUTXO.clear();
100  }
101  }
102 
103  if(!_t.isCreation())
104  res.newAddress = _t.receiveAddress();
106  transfers.clear();
107  if(voutLimit) {
108  //use old and empty states to create virtual Out Of Gas exception
109  LogEntries logs;
110  u256 gas = _t.gas();
111  ExecutionResult ex;
112  ex.gasRefunded=0;
113  ex.gasUsed=gas;
115  //create a refund tx to send back any coins that were suppose to be sent to the contract
116  CMutableTransaction refund;
117  if(_t.value() > 0) {
118  refund.vin.push_back(CTxIn(h256Touint(_t.getHashWith()), _t.getNVout(), CScript() << OP_SPEND));
119  //note, if sender was a non-standard tx, this will send the coins to pubkeyhash 0x00, effectively destroying the coins
120  CScript script(CScript() << OP_DUP << OP_HASH160 << _t.sender().asBytes() << OP_EQUALVERIFY << OP_CHECKSIG);
121  refund.vout.push_back(CTxOut(CAmount(_t.value().convert_to<uint64_t>()), script));
122  }
123  //make sure to use empty transaction if no vouts made
124  return ResultExecute{ex, dev::eth::TransactionReceipt(oldStateRoot, gas, e.logs()), refund.vout.empty() ? CTransaction() : CTransaction(refund)};
125  } else {
126  return ResultExecute{res, dev::eth::TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs()), tx ? *tx : CTransaction()};
127  }
128 }
129 
130 std::unordered_map<dev::Address, Vin> FascState::vins() const // temp
131 {
132  std::unordered_map<dev::Address, Vin> ret;
133  for (auto& i: cacheUTXO)
134  if (i.second.alive)
135  ret[i.first] = i.second;
136  auto addrs = addresses();
137  for (auto& i : addrs) {
138  if (cacheUTXO.find(i.first) == cacheUTXO.end() && vin(i.first))
139  ret[i.first] = *vin(i.first);
140  }
141  return ret;
142 }
143 
144 void FascState::transferBalance(dev::Address const& _from, dev::Address const& _to, dev::u256 const& _value) {
145  subBalance(_from, _value);
146  addBalance(_to, _value);
147  if (_value > 0)
148  transfers.push_back({_from, _to, _value});
149 }
150 
151 Vin const* FascState::vin(dev::Address const& _a) const
152 {
153  return const_cast<FascState*>(this)->vin(_a);
154 }
155 
157 {
158  auto it = cacheUTXO.find(_addr);
159  if (it == cacheUTXO.end()) {
160  std::string stateBack = stateUTXO.at(_addr);
161  if (stateBack.empty())
162  return nullptr;
163 
164  dev::RLP state(stateBack);
165  auto i = cacheUTXO.emplace(
166  std::piecewise_construct,
167  std::forward_as_tuple(_addr),
168  std::forward_as_tuple(Vin{state[0].toHash<dev::h256>(), state[1].toInt<uint32_t>(), state[2].toInt<dev::u256>(), state[3].toInt<uint8_t>()})
169  );
170  return &i.first->second;
171  }
172  return &it->second;
173 }
174 
175 // void FascState::commit(CommitBehaviour _commitBehaviour)
176 // {
177 // if (_commitBehaviour == CommitBehaviour::RemoveEmptyAccounts)
178 // removeEmptyAccounts();
179 
180 // fasc::commit(cacheUTXO, stateUTXO, m_cache);
181 // cacheUTXO.clear();
182 
183 // m_touched += dev::eth::commit(m_cache, m_state);
184 // m_changeLog.clear();
185 // m_cache.clear();
186 // m_unchangedCacheEntries.clear();
187 // }
188 
190 {
191  // If the account is not in the db, nothing to kill.
192  if (auto a = account(_addr))
193  a->kill();
194  if (auto v = vin(_addr))
195  v->alive = 0;
196 }
197 
198 void FascState::addBalance(dev::Address const& _id, dev::u256 const& _amount)
199 {
200  if (dev::eth::Account* a = account(_id))
201  {
202  // Log empty account being touched. Empty touched accounts are cleared
203  // after the transaction, so this event must be also reverted.
204  // We only log the first touch (not dirty yet), and only for empty
205  // accounts, as other accounts does not matter.
206  // TODO: to save space we can combine this event with Balance by having
207  // Balance and Balance+Touch events.
208  if (!a->isDirty() && a->isEmpty())
209  m_changeLog.emplace_back(dev::eth::detail::Change::Touch, _id);
210 
211  // Increase the account balance. This also is done for value 0 to mark
212  // the account as dirty. Dirty account are not removed from the cache
213  // and are cleared if empty at the end of the transaction.
214  a->addBalance(_amount);
215  }
216  else
217  {
219  const_cast<dev::Address&>(_id) = newAddress;
221  }
222  createAccount(_id, {requireAccountStartNonce(), _amount});
223  }
224 
225  if (_amount)
226  m_changeLog.emplace_back(dev::eth::detail::Change::Balance, _id, _amount);
227 }
228 
230  uint256 hashTXid(h256Touint(hashTx));
231  std::vector<unsigned char> txIdAndVout(hashTXid.begin(), hashTXid.end());
232  std::vector<unsigned char> voutNumberChrs;
233  if (voutNumberChrs.size() < sizeof(voutNumber))voutNumberChrs.resize(sizeof(voutNumber));
234  std::memcpy(voutNumberChrs.data(), &voutNumber, sizeof(voutNumber));
235  txIdAndVout.insert(txIdAndVout.end(),voutNumberChrs.begin(),voutNumberChrs.end());
236 
237  std::vector<unsigned char> SHA256TxVout(32);
238  CSHA256().Write(txIdAndVout.data(), txIdAndVout.size()).Finalize(SHA256TxVout.data());
239 
240  std::vector<unsigned char> hashTxIdAndVout(20);
241  CRIPEMD160().Write(SHA256TxVout.data(), SHA256TxVout.size()).Finalize(hashTxIdAndVout.data());
242 
243  return dev::Address(hashTxIdAndVout);
244 }
245 
246 void FascState::deleteAccounts(std::set<dev::Address>& addrs) {
247  for(dev::Address addr : addrs) {
248  dev::eth::Account* acc = const_cast<dev::eth::Account*>(account(addr));
249  if(acc)
250  acc->kill();
251  Vin* in = const_cast<Vin*>(vin(addr));
252  if(in)
253  in->alive = 0;
254  }
255 }
256 
257 void FascState::updateUTXO(const std::unordered_map<dev::Address, Vin>& vins) {
258  for(auto& v : vins) {
259  Vin* vi = const_cast<Vin*>(vin(v.first));
260 
261  if(vi) {
262  vi->hash = v.second.hash;
263  vi->nVout = v.second.nVout;
264  vi->value = v.second.value;
265  vi->alive = v.second.alive;
266  } else if(v.second.alive > 0) {
267  cacheUTXO[v.first] = v.second;
268  }
269  }
270 }
271 
273  std::stringstream ss;
274  ss << er;
275  clog(ExecutiveWarnChannel) << "VM exception:" << ss.str();
276 }
277 
280  selectionVin();
281  calculatePlusAndMinus();
282  if(!createNewBalances())
283  return CTransaction();
285  tx.vin = createVins();;
286  tx.vout = createVout();
287  return !tx.vin.size() || !tx.vout.size() ? CTransaction() : CTransaction(tx);
288 }
289 
290 std::unordered_map<dev::Address, Vin> CondensingTX::createVin(const CTransaction& tx) {
291  std::unordered_map<dev::Address, Vin> vins;
292  for(auto& b : balances) {
293  if(b.first == transaction.sender())
294  continue;
295 
296  if(b.second > 0) {
297  vins[b.first] = Vin{uintToh256(tx.GetHash()), nVouts[b.first], b.second, 1};
298  } else {
299  vins[b.first] = Vin{uintToh256(tx.GetHash()), 0, 0, 0};
300  }
301  }
302  return vins;
303 }
304 
306  for(const TransferInfo& ti : transfers) {
307  if(!vins.count(ti.from)) {
308  if(auto a = state->vin(ti.from))
309  vins[ti.from] = *a;
310  if(ti.from == transaction.sender() && transaction.value() > 0) {
311  vins[ti.from] = Vin{transaction.getHashWith(), transaction.getNVout(), transaction.value(), 1};
312  }
313  }
314 
315  if(!vins.count(ti.to)) {
316  if(auto a = state->vin(ti.to))
317  vins[ti.to] = *a;
318  }
319  }
320 }
321 
323  for(const TransferInfo& ti : transfers) {
324  if(!plusMinusInfo.count(ti.from)) {
325  plusMinusInfo[ti.from] = std::make_pair(0, ti.value);
326  } else {
327  plusMinusInfo[ti.from] = std::make_pair(plusMinusInfo[ti.from].first, plusMinusInfo[ti.from].second + ti.value);
328  }
329 
330  if(!plusMinusInfo.count(ti.to)) {
331  plusMinusInfo[ti.to] = std::make_pair(ti.value, 0);
332  } else {
333  plusMinusInfo[ti.to] = std::make_pair(plusMinusInfo[ti.to].first + ti.value, plusMinusInfo[ti.to].second);
334  }
335  }
336 }
337 
339  for(auto& p : plusMinusInfo) {
340  dev::u256 balance = 0;
341  if((vins.count(p.first) && vins[p.first].alive) || (!vins[p.first].alive && !checkDeleteAddress(p.first))) {
342  balance = vins[p.first].value;
343  }
344  balance += p.second.first;
345  if(balance < p.second.second)
346  return false;
347  balance -= p.second.second;
348  balances[p.first] = balance;
349  }
350  return true;
351 }
352 
353 std::vector<CTxIn> CondensingTX::createVins() {
354  std::vector<CTxIn> ins;
355  for(auto& v : vins) {
356  if((v.second.value > 0 && v.second.alive) || (v.second.value > 0 && !vins[v.first].alive && !checkDeleteAddress(v.first)))
357  ins.push_back(CTxIn(h256Touint(v.second.hash), v.second.nVout, CScript() << OP_SPEND));
358  }
359  return ins;
360 }
361 
362 std::vector<CTxOut> CondensingTX::createVout() {
363  size_t count = 0;
364  std::vector<CTxOut> outs;
365  for(auto& b : balances) {
366  if(b.second > 0) {
367  CScript script;
368  auto* a = state->account(b.first);
369  if(a && a->isAlive()) {
370  //create a no-exec contract output
371  script = CScript() << valtype{0} << valtype{0} << valtype{0} << valtype{0} << b.first.asBytes() << OP_CALL;
372  } else {
373  script = CScript() << OP_DUP << OP_HASH160 << b.first.asBytes() << OP_EQUALVERIFY << OP_CHECKSIG;
374  }
375  outs.push_back(CTxOut(CAmount(b.second), script));
376  nVouts[b.first] = count;
377  count++;
378  }
379  if(count > MAX_CONTRACT_VOUTS) {
380  voutOverflow=true;
381  return outs;
382  }
383  }
384  return outs;
385 }
386 
388  return deleteAddresses.count(addr) != 0;
389 }
bool addressInUse(Address const &_address) const
Check if the address is in use.
Definition: State.cpp:245
u256 balance(Address const &_id) const
Get an account&#39;s balance.
Definition: State.cpp:266
CSHA256 & Write(const unsigned char *data, size_t len)
Definition: sha256.cpp:201
void updateUTXO(const std::unordered_map< dev::Address, Vin > &vins)
Definition: fascstate.cpp:257
Adapted from code found on http://stackoverflow.com/questions/180947/base64-decode-snippet-in-c Origi...
Definition: Arith256.cpp:15
void commit(CommitBehaviour _commitBehaviour)
Commit all changes waiting in the address cache to the DB.
Definition: State.cpp:210
ChainOperationParams const & chainParams() const
Definition: SealEngine.h:75
bytes rlp(_T _t)
Export a single item in RLP format, returning a byte array.
Definition: RLP.h:467
Vin const * vin(dev::Address const &_a) const
Definition: fascstate.cpp:151
u256 gasUsed() const
Definition: Executive.cpp:183
dev::OverlayDB dbUTXO
Definition: fascstate.h:122
std::vector< CTxIn > vin
Definition: transaction.h:392
static OverlayDB openDB(std::string const &_path, h256 const &_genesisHash, WithExisting _we=WithExisting::Trust)
Open a DB - useful for passing into the constructor & keeping for other states that are necessary...
Definition: State.cpp:74
Models the state of a single Ethereum account.
Definition: Account.h:67
size_t count
Definition: ExecStats.cpp:37
static VersionVM GetEVMDefault()
const Consensus::Params & GetConsensus() const
Definition: chainparams.h:60
h160 Address
An Ethereum address: 20 bytes.
Definition: Common.h:62
Address const & author() const
Definition: ExtVMFace.h:238
void addBalance(dev::Address const &_id, dev::u256 const &_amount)
Add some amount to balance.
Definition: fascstate.cpp:198
Address const & sender() const
dev::Address newAddress
Definition: fascstate.h:118
std::hash for asio::adress
Definition: Common.h:323
bool reachedVoutLimit()
Definition: fascstate.h:169
assert(len-trim+(2 *lenIndices)<=WIDTH)
void kill(dev::Address _addr)
Delete an account (used for processing suicides).
Definition: fascstate.cpp:189
Different view on a GenericTrieDB that can use different key types.
Definition: TrieDB.h:320
u256 const & gasUsed() const
Definition: ExtVMFace.h:243
std::vector< CTxIn > createVins()
Definition: fascstate.cpp:353
Description of the result of executing a transaction.
Definition: Transaction.h:69
u256 const & number() const
Definition: ExtVMFace.h:237
Model of an Ethereum state, essentially a facade for the trie.
Definition: State.h:161
unsigned char * begin()
Definition: uint256.h:65
std::shared_ptr< const CTransaction > CTransactionRef
Definition: transaction.h:437
bool go(OnOpFunc const &_onOp=OnOpFunc())
Executes (or continues execution of) the VM.
Definition: Executive.cpp:386
u256 const & requireAccountStartNonce() const
Definition: State.cpp:121
Definition: fascstate.h:25
void revert()
Revert all changes made to the state by this execution.
Definition: Executive.cpp:503
int nFixUTXOCacheHFHeight
Definition: params.h:88
unsigned char * end()
Definition: uint256.h:70
void removeEmptyAccounts()
Turns all "touched" empty accounts into non-alive accounts.
Definition: State.cpp:136
void createAccount(Address const &_address, Account const &&_account)
Definition: State.cpp:330
int64_t CAmount
Amount in lius (Can be negative)
Definition: amount.h:15
dev::Address createFascAddress(dev::h256 hashTx, uint32_t voutNumber)
Definition: fascstate.cpp:229
std::vector< TransferInfo > transfers
Definition: fascstate.h:120
std::unordered_map< dev::Address, Vin > createVin(const CTransaction &tx)
Definition: fascstate.cpp:290
#define a(i)
bool isCreation() const
Definition: Transaction.h:101
_N toHash(int _flags=Strict) const
Definition: RLP.h:298
int Height() const
Return the maximal height in the chain.
Definition: chain.h:543
Base class for all exceptions.
Definition: Exceptions.h:39
dev::h256 uintToh256(const uint256 &in)
Definition: uint256.h:171
dev::u256 value
Definition: fascstate.h:28
uint32_t toRaw()
An input of a transaction.
Definition: transaction.h:61
BaseState
Definition: State.h:76
void deleteAccounts(std::set< dev::Address > &addrs)
Definition: fascstate.cpp:246
void finalize()
Finalise a transaction previously set up with initialize().
Definition: Executive.cpp:466
std::vector< detail::Change > m_changeLog
Definition: State.h:339
std::unordered_map< dev::Address, Vin > cacheUTXO
Definition: fascstate.h:126
const u256 Invalid256
Definition: Common.cpp:38
Fixed-size raw-byte array container type, with an API optimised for storing hashes.
Definition: FixedHash.h:47
std::function< void(uint64_t, uint64_t, Instruction, bigint, bigint, bigint, VM *, ExtVMFace const *)> OnOpFunc
Definition: ExtVMFace.h:193
std::unordered_map< Address, u256 > addresses() const
Definition: State.cpp:220
An output of a transaction.
Definition: transaction.h:131
CChain chainActive
The currently-connected chain of blocks (protected by cs_main).
Definition: validation.cpp:80
Message-call/contract-creation executor; useful for executing transactions.
Definition: Executive.h:106
boost::multiprecision::number< boost::multiprecision::cpp_int_backend< 256, 256, boost::multiprecision::unsigned_magnitude, boost::multiprecision::unchecked, void >> u256
Definition: Common.h:125
Parameters that influence chain consensus.
Definition: params.h:39
uint8_t alive
Definition: fascstate.h:29
std::unordered_map< Address, Account > m_cache
Our address cache. This stores the states of each address that has (or at least might have) been chan...
Definition: State.h:331
std::vector< CTxOut > vout
Definition: transaction.h:393
LogEntries const & logs() const
Definition: Executive.h:148
TransactionException excepted
Definition: Transaction.h:72
#define b(i, j)
CRIPEMD160 & Write(const unsigned char *data, size_t len)
Definition: ripemd160.cpp:247
h256 rootHash() const
The hash of the root of our state tree.
Definition: State.h:288
bytes asBytes() const
Definition: FixedHash.h:145
std::unordered_map< dev::Address, Vin > vins() const
Definition: fascstate.cpp:130
void kill()
Kill this account. Useful for the suicide opcode. Following this call, isAlive() returns false...
Definition: Account.h:92
void initialize(bytesConstRef _transaction)
Initializes the executive for evaluating a transaction. You must call finalize() at some point follow...
Definition: Executive.h:135
256-bit opaque blob.
Definition: uint256.h:132
u256 u256Param(std::string const &_name) const
Convenience method to get an otherParam as a u256 int.
void selectionVin()
Definition: fascstate.cpp:305
std::vector< CTxOut > createVout()
Definition: fascstate.cpp:362
bool createNewBalances()
Definition: fascstate.cpp:338
std::set< Address > deleteAddresses
Definition: SealEngine.h:96
bool execute()
Begins execution of a transaction.
Definition: Executive.cpp:247
const CChainParams & Params()
Return the currently selected parameters.
Serialized script, used inside transaction inputs and outputs.
Definition: script.h:417
void * memcpy(void *a, const void *b, size_t c)
CTransaction createCondensingTX()
Definition: fascstate.cpp:279
void calculatePlusAndMinus()
Definition: fascstate.cpp:322
dev::eth::SecureTrieDB< dev::Address, dev::OverlayDB > stateUTXO
Definition: fascstate.h:124
ResultExecute execute(dev::eth::EnvInfo const &_envInfo, dev::eth::SealEngineFace const &_sealEngine, FascTransaction const &_t, dev::eth::Permanence _p=dev::eth::Permanence::Committed, dev::eth::OnOpFunc const &_onOp=OnOpFunc())
Definition: fascstate.cpp:22
bool sha3(bytesConstRef _input, bytesRef o_output)
Calculate SHA3-256 hash of the given input and load it into the given output.
Definition: SHA3.cpp:214
VersionVM getVersion() const
void transferBalance(dev::Address const &_from, dev::Address const &_to, dev::u256 const &_value)
Transfers "the balance _value between two accounts.
Definition: fascstate.cpp:144
#define clog(X)
Definition: Log.h:295
#define e(i)
Definition: sha.cpp:733
Account balance changed.
Definition: State.h:110
dev::h256 hash
Definition: fascstate.h:26
A mutable version of CTransaction.
Definition: transaction.h:390
const uint256 & GetHash() const
Definition: transaction.h:325
std::vector< unsigned char > valtype
Definition: fascstate.h:17
Permanence
Definition: State.h:82
The basic transaction that is broadcasted on the network and contained in blocks. ...
Definition: transaction.h:275
Account const * account(Address const &_addr) const
Definition: State.cpp:158
Account was touched for the first time.
Definition: State.h:126
A hasher class for SHA-256.
Definition: sha256.h:13
dev::h256 getHashWith() const
void printfErrorLog(const dev::eth::TransactionException er)
Definition: fascstate.cpp:272
Class for interpreting Recursive Linear-Prefix Data.
Definition: RLP.h:64
uint32_t nVout
Definition: fascstate.h:27
void subBalance(Address const &_addr, u256 const &_value)
Subtract the _value amount from the balance of _addr account.
Definition: State.cpp:311
TransactionException
Definition: Transaction.h:35
uint256 h256Touint(const dev::h256 &in)
Definition: uint256.h:178
uint32_t getNVout() const
dev::AddressHash commit(std::unordered_map< dev::Address, Vin > const &_cache, dev::eth::SecureTrieDB< dev::Address, DB > &_state, std::unordered_map< dev::Address, dev::eth::Account > const &_cacheAcc)
Definition: fascstate.h:40
std::vector< LogEntry > LogEntries
Definition: ExtVMFace.h:110
A hasher class for RIPEMD-160.
Definition: ripemd160.h:12
Definition: script.h:100
void setResultRecipient(ExecutionResult &_res)
Collect execution results in the result storage provided.
Definition: Executive.h:184
Address receiveAddress() const
Definition: Transaction.h:122
bool checkDeleteAddress(dev::Address addr)
Definition: fascstate.cpp:387
TransactionException toTransactionException(Exception const &_e)
Definition: Transaction.cpp:42