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. 40
      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

40
alethzero/MainWin.cpp

@ -1097,7 +1097,7 @@ void Main::refreshBlockChain()
auto b = bc.block(h); auto b = bc.block(h);
for (auto const& i: RLP(b)[1]) for (auto const& i: RLP(b)[1])
{ {
Transaction t(i.data()); Transaction t(i.data(), CheckSignature::Sender);
if (bm || transactionMatch(filter, t)) if (bm || transactionMatch(filter, t))
{ {
QString s = t.receiveAddress() ? QString s = t.receiveAddress() ?
@ -1385,7 +1385,7 @@ void Main::on_blocks_currentItemChanged()
else else
{ {
unsigned txi = item->data(Qt::UserRole + 1).toInt(); 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(); auto ss = tx.safeSender();
h256 th = sha3(rlpList(ss, tx.nonce())); h256 th = sha3(rlpList(ss, tx.nonce()));
TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi]; TransactionReceipt receipt = ethereum()->blockChain().receipts(h).receipts[txi];
@ -1648,13 +1648,18 @@ static shh::Topic topicFromText(QString _s)
return ret; return ret;
} }
bool Main::sourceIsSolidity(string const& _source) bool Main::sourceIsSolidity(string const& _source)
{ {
// TODO: Improve this heuristic // TODO: Improve this heuristic
return (_source.substr(0, 8) == "contract" || _source.substr(0, 5) == "//sol"); 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 Main::getFunctionHashes(dev::solidity::CompilerStack const &_compiler,
string const& _contractName) string const& _contractName)
{ {
@ -1689,6 +1694,7 @@ void Main::on_data_textChanged()
dev::solidity::CompilerStack compiler; dev::solidity::CompilerStack compiler;
try try
{ {
// compiler.addSources(dev::solidity::StandardSources);
m_data = compiler.compile(src, m_enableOptimizer); m_data = compiler.compile(src, m_enableOptimizer);
solidity = "<h4>Solidity</h4>"; solidity = "<h4>Solidity</h4>";
solidity += "<pre>" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + "</pre>"; solidity += "<pre>" + QString::fromStdString(compiler.getInterface()).replace(QRegExp("\\s"), "").toHtmlEscaped() + "</pre>";
@ -1706,23 +1712,23 @@ void Main::on_data_textChanged()
solidity = "<h4>Solidity</h4><pre>Uncaught exception.</pre>"; solidity = "<h4>Solidity</h4><pre>Uncaught exception.</pre>";
} }
} }
else else if (sourceIsSerpent(src))
{ {
m_data = compileLLL(src, m_enableOptimizer, &errors); try
if (errors.size())
{ {
try m_data = dev::asBytes(::compile(src));
{ for (auto& i: errors)
m_data = dev::asBytes(::compile(src)); i = "(LLL " + i + ")";
for (auto& i: errors)
i = "(LLL " + i + ")";
}
catch (string err)
{
errors.push_back("Serpent " + err);
}
} }
else catch (string err)
{
errors.push_back("Serpent " + err);
}
}
else
{
m_data = compileLLL(src, m_enableOptimizer, &errors);
if (errors.empty())
{ {
auto asmcode = compileLLLToAsm(src, false); auto asmcode = compileLLLToAsm(src, false);
lll = "<h4>Pre</h4><pre>" + QString::fromStdString(asmcode).toHtmlEscaped() + "</pre>"; 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); auto bl = m_bc.block(_blockHash);
RLP b(bl); 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 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) bool Executive::setup(bytesConstRef _rlp)
{ {
// Entry point for a user-executed transaction. // Entry point for a user-executed transaction.
m_t = Transaction(_rlp); m_t = Transaction(_rlp, CheckSignature::Sender);
// Avoid invalid transactions. // Avoid invalid transactions.
auto nonceReq = m_s.transactionsFrom(m_t.sender()); auto nonceReq = m_s.transactionsFrom(m_t.sender());

2
libethereum/State.cpp

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

6
libethereum/Transaction.cpp

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

11
libethereum/Transaction.h

@ -37,6 +37,13 @@ enum IncludeSignature
WithSignature = 1, ///< Do include a signature. 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. /// Encodes a transaction, ready to be exported to or freshly imported from RLP.
class Transaction 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) {} 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. /// 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. /// 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. /// 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. // 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. // 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). // 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); UpgradeGuard ul(l);
// If valid, append to blocks. // If valid, append to blocks.
@ -69,14 +69,14 @@ void TransactionQueue::setFuture(std::pair<h256, bytes> const& _t)
if (m_current.count(_t.first)) if (m_current.count(_t.first))
{ {
m_current.erase(_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) void TransactionQueue::noteGood(std::pair<h256, bytes> const& _t)
{ {
WriteGuard l(m_lock); 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) for (auto it = r.first; it != r.second; ++it)
m_current.insert(it->second); m_current.insert(it->second);
m_unknown.erase(r.first, r.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); auto b = bc.block(h);
for (auto const& i: RLP(b)[1]) for (auto const& i: RLP(b)[1])
{ {
Transaction t(i.data()); Transaction t(i.data(), CheckSignature::Sender);
auto s = t.receiveAddress() ? auto s = t.receiveAddress() ?
boost::format(" %1% %2%> %3%: %4% [%5%]") % boost::format(" %1% %2%> %3%: %4% [%5%]") %
toString(t.safeSender()) % toString(t.safeSender()) %

Loading…
Cancel
Save