Browse Source

Make sure Transaction constructor checks sender whereever it makes sense

(which is pretty much everywhere).
cl-refactor
Gav Wood 10 years ago
parent
commit
668e5cc852
  1. 20
      alethzero/MainWin.cpp
  2. 2
      libethereum/Client.cpp
  3. 2
      libethereum/Executive.cpp
  4. 2
      libethereum/State.cpp
  5. 6
      libethereum/Transaction.cpp
  6. 11
      libethereum/Transaction.h
  7. 6
      libethereum/TransactionQueue.cpp
  8. 2
      neth/main.cpp

20
alethzero/MainWin.cpp

@ -1097,7 +1097,7 @@ void Main::refreshBlockChain()
auto b = bc.block(h);
for (auto const& i: RLP(b)[1])
{
Transaction t(i.data());
Transaction t(i.data(), CheckSignature::Sender);
if (bm || transactionMatch(filter, t))
{
QString s = t.receiveAddress() ?
@ -1385,7 +1385,7 @@ void Main::on_blocks_currentItemChanged()
else
{
unsigned txi = item->data(Qt::UserRole + 1).toInt();
Transaction tx(block[1][txi].data());
Transaction tx(block[1][txi].data(), CheckSignature::Sender);
auto ss = tx.safeSender();
h256 th = sha3(rlpList(ss, tx.nonce()));
TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi];
@ -1648,13 +1648,18 @@ static shh::Topic topicFromText(QString _s)
return ret;
}
bool Main::sourceIsSolidity(string const& _source)
{
// TODO: Improve this heuristic
return (_source.substr(0, 8) == "contract" || _source.substr(0, 5) == "//sol");
}
static bool sourceIsSerpent(string const& _source)
{
// TODO: Improve this heuristic
return (_source.substr(0, 5) == "//ser");
}
string const Main::getFunctionHashes(dev::solidity::CompilerStack const &_compiler,
string const& _contractName)
{
@ -1689,6 +1694,7 @@ void Main::on_data_textChanged()
dev::solidity::CompilerStack compiler;
try
{
// compiler.addSources(dev::solidity::StandardSources);
m_data = compiler.compile(src, m_enableOptimizer);
solidity = "<h4>Solidity</h4>";
solidity += "<pre>" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + "</pre>";
@ -1706,10 +1712,7 @@ void Main::on_data_textChanged()
solidity = "<h4>Solidity</h4><pre>Uncaught exception.</pre>";
}
}
else
{
m_data = compileLLL(src, m_enableOptimizer, &errors);
if (errors.size())
else if (sourceIsSerpent(src))
{
try
{
@ -1723,6 +1726,9 @@ void Main::on_data_textChanged()
}
}
else
{
m_data = compileLLL(src, m_enableOptimizer, &errors);
if (errors.empty())
{
auto asmcode = compileLLLToAsm(src, false);
lll = "<h4>Pre</h4><pre>" + QString::fromStdString(asmcode).toHtmlEscaped() + "</pre>";

2
libethereum/Client.cpp

@ -642,7 +642,7 @@ Transaction Client::transaction(h256 _blockHash, unsigned _i) const
{
auto bl = m_bc.block(_blockHash);
RLP b(bl);
return Transaction(b[1][_i].data());
return Transaction(b[1][_i].data(), CheckSignature::Range);
}
BlockInfo Client::uncle(h256 _blockHash, unsigned _i) const

2
libethereum/Executive.cpp

@ -53,7 +53,7 @@ void Executive::accrueSubState(SubState& _parentContext)
bool Executive::setup(bytesConstRef _rlp)
{
// Entry point for a user-executed transaction.
m_t = Transaction(_rlp);
m_t = Transaction(_rlp, CheckSignature::Sender);
// Avoid invalid transactions.
auto nonceReq = m_s.transactionsFrom(m_t.sender());

2
libethereum/State.cpp

@ -395,7 +395,7 @@ bool State::cull(TransactionQueue& _tq) const
{
try
{
Transaction t(i.second);
Transaction t(i.second, CheckSignature::Sender);
if (t.nonce() <= transactionsFrom(t.sender()))
{
_tq.drop(i.first);

6
libethereum/Transaction.cpp

@ -30,7 +30,7 @@ using namespace dev::eth;
#define ETH_ADDRESS_DEBUG 0
Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender)
Transaction::Transaction(bytesConstRef _rlpData, CheckSignature _checkSig)
{
int field = 0;
RLP rlp(_rlpData);
@ -47,7 +47,9 @@ Transaction::Transaction(bytesConstRef _rlpData, bool _checkSender)
h256 r = rlp[field = 7].toInt<u256>();
h256 s = rlp[field = 8].toInt<u256>();
m_vrs = SignatureStruct{ r, s, v };
if (_checkSender)
if (_checkSig >= CheckSignature::Range && !m_vrs.isValid())
BOOST_THROW_EXCEPTION(InvalidSignature());
if (_checkSig == CheckSignature::Sender)
m_sender = sender();
}
catch (Exception& _e)

11
libethereum/Transaction.h

@ -37,6 +37,13 @@ enum IncludeSignature
WithSignature = 1, ///< Do include a signature.
};
enum class CheckSignature
{
None,
Range,
Sender
};
/// Encodes a transaction, ready to be exported to or freshly imported from RLP.
class Transaction
{
@ -57,10 +64,10 @@ public:
Transaction(u256 _value, u256 _gasPrice, u256 _gas, bytes const& _data): m_type(ContractCreation), m_value(_value), m_gasPrice(_gasPrice), m_gas(_gas), m_data(_data) {}
/// Constructs a transaction from the given RLP.
explicit Transaction(bytesConstRef _rlp, bool _checkSender = false);
explicit Transaction(bytesConstRef _rlp, CheckSignature _checkSig);
/// Constructs a transaction from the given RLP.
explicit Transaction(bytes const& _rlp, bool _checkSender = false): Transaction(&_rlp, _checkSender) {}
explicit Transaction(bytes const& _rlp, CheckSignature _checkSig): Transaction(&_rlp, _checkSig) {}
/// Checks equality of transactions.

6
libethereum/TransactionQueue.cpp

@ -42,7 +42,7 @@ bool TransactionQueue::import(bytesConstRef _transactionRLP)
// Check validity of _transactionRLP as a transaction. To do this we just deserialise and attempt to determine the sender.
// If it doesn't work, the signature is bad.
// The transaction's nonce may yet be invalid (or, it could be "valid" but we may be missing a marginally older transaction).
Transaction t(_transactionRLP, true);
Transaction t(_transactionRLP, CheckSignature::Sender);
UpgradeGuard ul(l);
// If valid, append to blocks.
@ -69,14 +69,14 @@ void TransactionQueue::setFuture(std::pair<h256, bytes> const& _t)
if (m_current.count(_t.first))
{
m_current.erase(_t.first);
m_unknown.insert(make_pair(Transaction(_t.second).sender(), _t));
m_unknown.insert(make_pair(Transaction(_t.second, CheckSignature::Sender).sender(), _t));
}
}
void TransactionQueue::noteGood(std::pair<h256, bytes> const& _t)
{
WriteGuard l(m_lock);
auto r = m_unknown.equal_range(Transaction(_t.second).sender());
auto r = m_unknown.equal_range(Transaction(_t.second, CheckSignature::Sender).sender());
for (auto it = r.first; it != r.second; ++it)
m_current.insert(it->second);
m_unknown.erase(r.first, r.second);

2
neth/main.cpp

@ -886,7 +886,7 @@ int main(int argc, char** argv)
auto b = bc.block(h);
for (auto const& i: RLP(b)[1])
{
Transaction t(i.data());
Transaction t(i.data(), CheckSignature::Sender);
auto s = t.receiveAddress() ?
boost::format(" %1% %2%> %3%: %4% [%5%]") %
toString(t.safeSender()) %

Loading…
Cancel
Save