Browse Source

Merge pull request #2414 from ethereum/gav

Cleanups, fixes and download viz.
cl-refactor
Gav Wood 10 years ago
parent
commit
61b27cc62d
  1. 105
      alethzero/DownloadView.cpp
  2. 13
      alethzero/DownloadView.h
  3. 10
      alethzero/Main.ui
  4. 15
      alethzero/MainWin.cpp
  5. 1
      alethzero/MainWin.h
  6. 2
      exp/main.cpp
  7. 3
      libdevcore/FixedHash.h
  8. 14
      libdevcore/RangeMask.h
  9. 12
      libdevcrypto/Common.cpp
  10. 22
      libethereum/BlockChain.cpp
  11. 3
      libethereum/BlockChain.h
  12. 2
      libethereum/BlockChainSync.cpp
  13. 4
      libethereum/BlockQueue.cpp
  14. 2
      libethereum/Client.h
  15. 4
      libethereum/ClientBase.cpp
  16. 2
      libethereum/ClientBase.h
  17. 10
      libethereum/DownloadMan.cpp
  18. 33
      libethereum/DownloadMan.h
  19. 26
      libethereum/EthereumHost.cpp
  20. 2
      libethereum/EthereumHost.h
  21. 3
      libethereum/Interface.cpp
  22. 2
      libethereum/Interface.h
  23. 4
      libethereum/State.cpp
  24. 4
      libweb3jsonrpc/AccountHolder.cpp
  25. 3
      mix/ClientModel.cpp
  26. 10
      mix/MixClient.cpp
  27. 4
      mix/MixClient.h
  28. 2
      neth/main.cpp

105
alethzero/DownloadView.cpp

@ -30,29 +30,118 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
DownloadView::DownloadView(QWidget* _p): QWidget(_p)
SyncView::SyncView(QWidget* _p): QWidget(_p)
{
}
void DownloadView::paintEvent(QPaintEvent*)
void SyncView::paintEvent(QPaintEvent*)
{
QPainter p(this);
p.fillRect(rect(), Qt::white);
if (!m_man || m_man->chainEmpty() || !m_man->subCount())
if (!m_client)
return;
DownloadMan const* man = m_client->downloadMan();
BlockQueueStatus bqs = m_client->blockQueueStatus();
SyncStatus sync = m_client->syncStatus();
unsigned syncFrom = m_client->numberFromHash(PendingBlockHash);
unsigned syncImported = syncFrom;
unsigned syncImporting = syncImported + bqs.importing;
unsigned syncVerified = syncImporting + bqs.verified;
unsigned syncVerifying = syncVerified + bqs.verifying;
unsigned syncUnverified = syncVerifying + bqs.unverified;
unsigned syncCount = syncUnverified + bqs.unknown - syncFrom;
// best effort guess. assumes there's no forks.
unsigned downloadFrom = m_client->numberFromHash(m_client->isKnown(man->firstBlock()) ? man->firstBlock() : PendingBlockHash);
unsigned downloadCount = sync.blocksTotal;
DownloadMan::Overview overview = man->overview();
unsigned downloadDone = downloadFrom + overview.total;
unsigned downloadFlank = downloadFrom + overview.firstIncomplete;
unsigned downloadPoint = downloadFrom + overview.lastComplete;
unsigned hashFrom = sync.state == SyncState::Hashes ? m_client->numberFromHash(PendingBlockHash) : downloadFrom;
unsigned hashCount = sync.state == SyncState::Hashes ? sync.hashesTotal : downloadCount;
unsigned hashDone = hashFrom + (sync.state == SyncState::Hashes ? sync.hashesReceived : hashCount);
m_lastFrom = min(syncFrom, m_lastFrom);
m_lastTo = max(max(syncFrom + syncCount, hashFrom + hashCount), m_lastTo);
unsigned from = min(min(hashFrom, downloadFrom), min(syncFrom, m_lastFrom));
unsigned count = max(max(hashFrom + hashCount, downloadFrom + downloadCount), max(syncFrom + syncCount, m_lastTo)) - from;
m_lastFrom = (m_lastFrom * 99 + syncFrom * 1) / 100;
m_lastTo = (m_lastTo * 99 + max(syncFrom + syncCount, hashFrom + hashCount) * 1) / 100;
if (!count)
{
m_lastFrom = m_lastTo = (unsigned)-1;
return;
}
cnote << "Range " << from << "-" << (from + count) << "(" << hashFrom << "+" << hashCount << "," << downloadFrom << "+" << downloadCount << "," << syncFrom << "+" << syncCount << ")";
auto r = [&](unsigned u) {
return toString((u - from) * 100 / count) + "%";
};
if (count)
{
cnote << "Hashes:" << r(hashDone) << " Blocks:" << r(downloadFlank) << r(downloadDone) << r(downloadPoint);
cnote << "Importing:" << r(syncFrom) << r(syncImported) << r(syncImporting) << r(syncVerified) << r(syncVerifying) << r(syncUnverified);
}
float squareSize = min(rect().width(), rect().height());
QPen pen;
pen.setCapStyle(Qt::FlatCap);
pen.setWidthF(squareSize / 20);
auto middle = [&](float x) {
return QRectF(squareSize / 2 - squareSize / 2 * x, 0 + squareSize / 2 - squareSize / 2 * x, squareSize * x, squareSize * x);
};
auto arcLen = [&](unsigned x) {
return x * -5760.f / count;
};
auto arcPos = [&](unsigned x) {
return int(90 * 16.f + arcLen(x - from)) % 5760;
};
p.setPen(Qt::NoPen);
p.setBrush(QColor::fromHsv(0, 0, 210));
pen.setWidthF(0.f);
p.drawPie(middle(0.4f), arcPos(from), arcLen(hashDone - from));
auto progress = [&](unsigned h, unsigned s, unsigned v, float size, float thickness, unsigned nfrom, unsigned ncount) {
p.setBrush(Qt::NoBrush);
pen.setColor(QColor::fromHsv(h, s, v));
pen.setWidthF(squareSize * thickness);
p.setPen(pen);
p.drawArc(middle(size), arcPos(nfrom), arcLen(ncount));
};
progress(0, 50, 170, 0.4f, 0.12f, downloadFlank, downloadPoint - downloadFlank);
progress(0, 0, 150, 0.4f, 0.10f, from, downloadDone - from);
progress(0, 0, 230, 0.7f, 0.090f, from, syncUnverified - from);
progress(60, 25, 210, 0.7f, 0.08f, from, syncVerifying - from);
progress(120, 25, 190, 0.7f, 0.07f, from, syncVerified - from);
progress(0, 0, 220, 0.9f, 0.02f, from, count);
progress(0, 0, 100, 0.9f, 0.04f, from, syncFrom - from);
progress(0, 50, 100, 0.9f, 0.08f, syncFrom, syncImporting - syncFrom);
return;
double ratio = (double)rect().width() / rect().height();
if (ratio < 1)
ratio = 1 / ratio;
double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(m_man->chainSize() / ratio)));
double n = min(16.0, min(rect().width(), rect().height()) / ceil(sqrt(man->chainSize() / ratio)));
// QSizeF area(rect().width() / floor(rect().width() / n), rect().height() / floor(rect().height() / n));
QSizeF area(n, n);
QPointF pos(0, 0);
auto bg = m_man->blocksGot();
unsigned subCount = m_man->subCount();
auto bg = man->blocksGot();
unsigned subCount = man->subCount();
if (subCount == 0)
return;
unsigned dh = 360 / subCount;
@ -64,7 +153,7 @@ void DownloadView::paintEvent(QPaintEvent*)
else
{
unsigned h = 0;
m_man->foreachSub([&](DownloadSub const& sub)
man->foreachSub([&](DownloadSub const& sub)
{
if (sub.askedContains(i))
s = h;

13
alethzero/DownloadView.h

@ -32,21 +32,24 @@
#endif
namespace dev { namespace eth {
class DownloadMan;
class Client;
}}
class DownloadView: public QWidget
class SyncView: public QWidget
{
Q_OBJECT
public:
DownloadView(QWidget* _p = nullptr);
SyncView(QWidget* _p = nullptr);
void setDownloadMan(dev::eth::DownloadMan const* _man) { m_man = _man; }
void setEthereum(dev::eth::Client const* _c) { m_client = _c; }
protected:
virtual void paintEvent(QPaintEvent*);
private:
dev::eth::DownloadMan const* m_man = nullptr;
dev::eth::Client const* m_client = nullptr;
unsigned m_lastFrom = (unsigned)-1;
unsigned m_lastTo = (unsigned)-1;
};

10
alethzero/Main.ui

@ -199,6 +199,7 @@
<addaction name="usePrivate"/>
<addaction name="retryUnknown"/>
<addaction name="confirm"/>
<addaction name="rewindChain"/>
</widget>
<widget class="QMenu" name="menu_View">
<property name="title">
@ -1149,7 +1150,7 @@ font-size: 14pt</string>
<number>0</number>
</property>
<item>
<widget class="DownloadView" name="downloadView" native="true"/>
<widget class="SyncView" name="downloadView" native="true"/>
</item>
</layout>
</widget>
@ -1804,6 +1805,11 @@ font-size: 14pt</string>
<string>&amp;Sentinel...</string>
</property>
</action>
<action name="rewindChain">
<property name="text">
<string>&amp;Rewind Chain...</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
@ -1814,7 +1820,7 @@ font-size: 14pt</string>
<container>1</container>
</customwidget>
<customwidget>
<class>DownloadView</class>
<class>SyncView</class>
<extends>QWidget</extends>
<header>DownloadView.h</header>
<container>1</container>

15
alethzero/MainWin.cpp

@ -1044,6 +1044,17 @@ void Main::on_vmInterpreter_triggered() { VMFactory::setKind(VMKind::Interpreter
void Main::on_vmJIT_triggered() { VMFactory::setKind(VMKind::JIT); }
void Main::on_vmSmart_triggered() { VMFactory::setKind(VMKind::Smart); }
void Main::on_rewindChain_triggered()
{
bool ok;
int n = QInputDialog::getInt(this, "Rewind Chain", "Enter the number of the new chain head.", ethereum()->number() * 9 / 10, 1, ethereum()->number(), 1, &ok);
if (ok)
{
ethereum()->rewind(n);
refreshAll();
}
}
void Main::on_urlEdit_returnPressed()
{
QString s = ui->urlEdit->text();
@ -1993,12 +2004,12 @@ void Main::on_net_triggered()
web3()->setNetworkPreferences(netPrefs(), ui->dropPeers->isChecked());
ethereum()->setNetworkId(m_privateChain.size() ? sha3(m_privateChain.toStdString()) : h256());
web3()->startNetwork();
ui->downloadView->setDownloadMan(ethereum()->downloadMan());
ui->downloadView->setEthereum(ethereum());
ui->enode->setText(QString::fromStdString(web3()->enode()));
}
else
{
ui->downloadView->setDownloadMan(nullptr);
ui->downloadView->setEthereum(nullptr);
writeSettings();
web3()->stopNetwork();
}

1
alethzero/MainWin.h

@ -187,6 +187,7 @@ private slots:
void on_vmInterpreter_triggered();
void on_vmJIT_triggered();
void on_vmSmart_triggered();
void on_rewindChain_triggered();
// Debugger
void on_debugCurrent_triggered();

2
exp/main.cpp

@ -135,7 +135,7 @@ int main()
DownloadSub s0(man);
DownloadSub s1(man);
DownloadSub s2(man);
man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)}));
man.resetToChain(h256s({u256(0), u256(1), u256(2), u256(3), u256(4), u256(5), u256(6), u256(7), u256(8)}), 0);
assert((s0.nextFetch(2) == h256Set{(u256)7, (u256)8}));
assert((s1.nextFetch(2) == h256Set{(u256)5, (u256)6}));
assert((s2.nextFetch(2) == h256Set{(u256)3, (u256)4}));

3
libdevcore/FixedHash.h

@ -24,6 +24,7 @@
#pragma once
#include <array>
#include <cstdint>
#include <random>
#include <algorithm>
#include "CommonData.h"
@ -151,7 +152,7 @@ public:
{
FixedHash ret;
for (auto& i: ret.m_data)
i = std::uniform_int_distribution<uint16_t>(0, 255)(_eng);
i = (uint8_t)std::uniform_int_distribution<uint16_t>(0, 255)(_eng);
return ret;
}

14
libdevcore/RangeMask.h

@ -200,6 +200,20 @@ public:
return c;
}
size_t firstOut() const
{
if (m_ranges.empty() || !m_ranges.count(m_all.first))
return m_all.first;
return m_ranges.at(m_all.first);
}
size_t lastIn() const
{
if (m_ranges.empty())
return m_all.first;
return m_ranges.rbegin()->second - 1;
}
private:
/// The ground range.
UnsignedRange m_all;

12
libdevcrypto/Common.cpp

@ -22,6 +22,7 @@
#include "Common.h"
#include <random>
#include <cstdint>
#include <chrono>
#include <thread>
#include <mutex>
@ -262,16 +263,9 @@ bytes dev::scrypt(std::string const& _pass, bytes const& _salt, uint64_t _n, uin
KeyPair KeyPair::create()
{
static boost::thread_specific_ptr<mt19937_64> s_eng;
static unsigned s_id = 0;
if (!s_eng.get())
s_eng.reset(new mt19937_64(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count() + ++s_id));
uniform_int_distribution<uint16_t> d(0, 255);
for (int i = 0; i < 100; ++i)
{
KeyPair ret(FixedHash<32>::random(*s_eng.get()));
KeyPair ret(FixedHash<32>::random());
if (ret.address())
return ret;
}
@ -353,7 +347,7 @@ void Nonce::initialiseIfNeeded()
std::mt19937_64 s_eng(time(0) + chrono::high_resolution_clock::now().time_since_epoch().count());
std::uniform_int_distribution<uint16_t> d(0, 255);
for (unsigned i = 0; i < 32; ++i)
m_value[i] = byte(d(s_eng));
m_value[i] = (uint8_t)d(s_eng);
}
if (!m_value)
BOOST_THROW_EXCEPTION(InvalidState());

22
libethereum/BlockChain.cpp

@ -799,6 +799,25 @@ void BlockChain::clearBlockBlooms(unsigned _begin, unsigned _end)
}
}
void BlockChain::rewind(unsigned _newHead)
{
DEV_WRITE_GUARDED(x_lastBlockHash)
{
if (_newHead >= m_lastBlockNumber)
return;
m_lastBlockHash = numberHash(_newHead);
m_lastBlockNumber = _newHead;
auto o = m_extrasDB->Put(m_writeOptions, ldb::Slice("best"), ldb::Slice((char const*)&m_lastBlockHash, 32));
if (!o.ok())
{
cwarn << "Error writing to extras database: " << o.ToString();
cout << "Put" << toHex(bytesConstRef(ldb::Slice("best"))) << "=>" << toHex(bytesConstRef(ldb::Slice((char const*)&m_lastBlockHash, 32)));
cwarn << "Fail writing to extras database. Bombing out.";
exit(-1);
}
}
}
tuple<h256s, h256, unsigned> BlockChain::treeRoute(h256 const& _from, h256 const& _to, bool _common, bool _pre, bool _post) const
{
// cdebug << "treeRoute" << _from << "..." << _to;
@ -1070,7 +1089,8 @@ bool BlockChain::isKnown(h256 const& _hash) const
if (d.empty())
return false;
}
return true;
// return true;
return details(_hash).number <= m_lastBlockNumber; // to allow rewind functionality.
}
bytes BlockChain::block(h256 const& _hash) const

3
libethereum/BlockChain.h

@ -215,6 +215,9 @@ public:
/// Will call _progress with the progress in this operation first param done, second total.
void rebuild(std::string const& _path, ProgressCallback const& _progress = std::function<void(unsigned, unsigned)>(), bool _prepPoW = false);
/// Alter the head of the chain to some prior block along it.
void rewind(unsigned _newHead);
/** @returns a tuple of:
* - an vector of hashes of all blocks between @a _from and @a _to, all blocks are ordered first by a number of
* blocks that are parent-to-child, then two sibling blocks, then a number of blocks that are child-to-parent;

2
libethereum/BlockChainSync.cpp

@ -80,7 +80,7 @@ DownloadMan& BlockChainSync::downloadMan()
void BlockChainSync::abortSync()
{
downloadMan().resetToChain(h256s());
downloadMan().reset();
}
void BlockChainSync::onPeerStatus(std::shared_ptr<EthereumPeer> _peer)

4
libethereum/BlockQueue.cpp

@ -215,8 +215,10 @@ ImportResult BlockQueue::import(bytesConstRef _block, BlockChain const& _bc, boo
return ImportResult::Malformed;
}
clog(BlockQueueTraceChannel) << "Block" << h << "is" << bi.number << "parent is" << bi.parentHash;
// Check block doesn't already exist first!
if (_bc.details(h))
if (_bc.isKnown(h))
{
cblockq << "Already known in chain.";
return ImportResult::AlreadyInChain;

2
libethereum/Client.h

@ -217,6 +217,8 @@ public:
std::string const& sentinel() const { return m_sentinel; }
/// Set the extra data that goes into mined blocks.
void setExtraData(bytes const& _extraData) { m_extraData = _extraData; }
/// Rewind to a prior head.
void rewind(unsigned _n) { m_bc.rewind(_n); }
protected:
/// InterfaceStub methods

4
libethereum/ClientBase.cpp

@ -45,7 +45,7 @@ State ClientBase::asOf(BlockNumber _h) const
return asOf(bc().numberHash(_h));
}
h256 ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret)
pair<h256, Address> ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const& _secret)
{
prepareForTransaction();
@ -59,7 +59,7 @@ h256 ClientBase::submitTransaction(TransactionSkeleton const& _t, Secret const&
StructuredLogger::transactionReceived(t.sha3().abridged(), t.sender().abridged());
cnote << "New transaction " << t;
return t.sha3();
return make_pair(t.sha3(), toAddress(ts.from, ts.nonce));
}
// TODO: remove try/catch, allow exceptions

2
libethereum/ClientBase.h

@ -77,7 +77,7 @@ public:
/// Submits the given transaction.
/// @returns the new transaction's hash.
virtual h256 submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override;
virtual std::pair<h256, Address> submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) override;
using Interface::submitTransaction;
/// Makes the given call. Nothing is recorded into the state.

10
libethereum/DownloadMan.cpp

@ -24,6 +24,16 @@ using namespace std;
using namespace dev;
using namespace dev::eth;
DownloadMan::Overview DownloadMan::overview() const
{
ReadGuard l(m_lock);
Overview ret;
ret.firstIncomplete = m_blocksGot.firstOut();
ret.lastComplete = ret.lastStarted = m_blocksGot.lastIn();// TODO: lastStarted properly
ret.total = m_blocksGot.size();
return ret;
}
DownloadSub::DownloadSub(DownloadMan& _man): m_man(&_man)
{
WriteGuard l(m_man->x_subs);

33
libethereum/DownloadMan.h

@ -82,6 +82,14 @@ class DownloadMan
friend class DownloadSub;
public:
struct Overview
{
size_t total;
size_t firstIncomplete;
size_t lastComplete;
size_t lastStarted;
};
~DownloadMan()
{
for (auto i: m_subs)
@ -97,11 +105,9 @@ public:
void resetToChain(h256s const& _chain)
{
{
ReadGuard l(x_subs);
DEV_READ_GUARDED(x_subs)
for (auto i: m_subs)
i->resetFetch();
}
WriteGuard l(m_lock);
m_chain.clear();
m_chain.reserve(_chain.size());
@ -112,11 +118,9 @@ public:
void reset()
{
{
ReadGuard l(x_subs);
DEV_READ_GUARDED(x_subs)
for (auto i: m_subs)
i->resetFetch();
}
WriteGuard l(m_lock);
m_chain.clear();
m_blocksGot.reset();
@ -127,11 +131,9 @@ public:
ReadGuard l(m_lock);
auto ret = m_blocksGot;
if (!_desperate)
{
ReadGuard l(x_subs);
for (auto i: m_subs)
ret += i->m_asked;
}
DEV_READ_GUARDED(x_subs)
for (auto i: m_subs)
ret += i->m_asked;
return ret;
}
@ -144,12 +146,15 @@ public:
h256s remaining() const
{
h256s ret;
ReadGuard l(m_lock);
for (auto i: m_blocksGot.inverted())
ret.push_back(m_chain[i]);
DEV_READ_GUARDED(m_lock)
for (auto i: m_blocksGot.inverted())
ret.push_back(m_chain[i]);
return ret;
}
h256 firstBlock() const { return m_chain.empty() ? h256() : m_chain[0]; }
Overview overview() const;
size_t chainSize() const { ReadGuard l(m_lock); return m_chain.size(); }
size_t chainEmpty() const { ReadGuard l(m_lock); return m_chain.empty(); }
void foreachSub(std::function<void(DownloadSub const&)> const& _f) const { ReadGuard l(x_subs); for(auto i: m_subs) _f(*i); }

26
libethereum/EthereumHost.cpp

@ -45,6 +45,12 @@ static unsigned const c_maxSendTransactions = 256;
char const* const EthereumHost::s_stateNames[static_cast<int>(SyncState::Size)] = {"Idle", "Waiting", "Hashes", "Blocks", "NewBlocks" };
#ifdef _WIN32
const char* EthereumHostTrace::name() { return EthPurple "^" EthGray " "; }
#else
const char* EthereumHostTrace::name() { return EthPurple "" EthGray " "; }
#endif
EthereumHost::EthereumHost(BlockChain const& _ch, TransactionQueue& _tq, BlockQueue& _bq, u256 _networkId):
HostCapability<EthereumPeer>(),
Worker ("ethsync"),
@ -67,7 +73,7 @@ bool EthereumHost::ensureInitialised()
{
// First time - just initialise.
m_latestBlockSent = m_chain.currentHash();
clog(NetNote) << "Initialising: latest=" << m_latestBlockSent;
clog(EthereumHostTrace) << "Initialising: latest=" << m_latestBlockSent;
Guard l(x_transactions);
m_transactionsSent = m_tq.knownTransactions();
@ -150,7 +156,7 @@ void EthereumHost::maintainTransactions()
RLPStream ts;
_p->prep(ts, TransactionsPacket, n).appendRaw(b, n);
_p->sealAndSend(ts);
cnote << "Sent" << n << "transactions to " << _p->session()->info().clientVersion;
clog(EthereumHostTrace) << "Sent" << n << "transactions to " << _p->session()->info().clientVersion;
}
_p->m_requireTransactions = false;
return true;
@ -206,11 +212,15 @@ void EthereumHost::maintainBlocks(h256 const& _currentHash)
if (diff(detailsFrom.number, detailsTo.number) < 20)
{
// don't be sending more than 20 "new" blocks. if there are any more we were probably waaaay behind.
clog(NetMessageSummary) << "Sending a new block (current is" << _currentHash << ", was" << m_latestBlockSent << ")";
clog(EthereumHostTrace) << "Sending a new block (current is" << _currentHash << ", was" << m_latestBlockSent << ")";
h256s blocks = get<0>(m_chain.treeRoute(m_latestBlockSent, _currentHash, false, false, true));
auto s = randomSelection(25, [&](EthereumPeer* p){ DEV_GUARDED(p->x_knownBlocks) return !p->m_knownBlocks.count(_currentHash); return false; });
auto s = randomSelection(25, [&](EthereumPeer* p){
DEV_GUARDED(p->x_knownBlocks)
return !p->m_knownBlocks.count(_currentHash);
return false;
});
for (shared_ptr<EthereumPeer> const& p: get<0>(s))
for (auto const& b: blocks)
{
@ -292,11 +302,11 @@ void EthereumHost::onPeerTransactions(std::shared_ptr<EthereumPeer> _peer, RLP c
{
if (_peer->isCriticalSyncing())
{
clog(NetAllDetail) << "Ignoring transaction from peer we are syncing with";
clog(EthereumHostTrace) << "Ignoring transaction from peer we are syncing with";
return;
}
unsigned itemCount = _r.itemCount();
clog(NetAllDetail) << "Transactions (" << dec << itemCount << "entries)";
clog(EthereumHostTrace) << "Transactions (" << dec << itemCount << "entries)";
m_tq.enqueue(_r, _peer->session()->id());
}
@ -351,10 +361,8 @@ void EthereumHost::onTransactionImported(ImportResult _ir, h256 const& _h, h512
break;
case ImportResult::AlreadyKnown:
// if we already had the transaction, then don't bother sending it on.
{
Guard l(x_transactions);
DEV_GUARDED(x_transactions)
m_transactionsSent.insert(_h);
}
peer->addRating(0);
break;
case ImportResult::Success:

2
libethereum/EthereumHost.h

@ -49,6 +49,8 @@ class TransactionQueue;
class BlockQueue;
class BlockChainSync;
struct EthereumHostTrace: public LogChannel { static const char* name(); static const int verbosity = 6; };
/**
* @brief The EthereumHost class
* @warning None of this is thread-safe. You have been warned.

3
libethereum/Interface.cpp

@ -46,6 +46,5 @@ Address Interface::submitTransaction(Secret const& _secret, u256 const& _endowme
ts.gas = _gas;
ts.gasPrice = _gasPrice;
ts.nonce = _nonce;
submitTransaction(ts, _secret);
return toAddress(toAddress(_secret), _nonce);
return submitTransaction(ts, _secret).second;
}

2
libethereum/Interface.h

@ -67,7 +67,7 @@ public:
/// Submits a new transaction.
/// @returns the transaction's hash.
virtual h256 submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0;
virtual std::pair<h256, Address> submitTransaction(TransactionSkeleton const& _t, Secret const& _secret) = 0;
/// Submits the given message-call transaction.
void submitTransaction(Secret const& _secret, u256 const& _value, Address const& _dest, bytes const& _data = bytes(), u256 const& _gas = 10000, u256 const& _gasPrice = 10 * szabo, u256 const& _nonce = UndefinedU256);

4
libethereum/State.cpp

@ -1212,7 +1212,7 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per
uncommitToMine();
// OK - transaction looks valid - execute.
u256 startGasUsed = gasUsed();
u256 startGasUsed = e.gasUsed();
#if ETH_PARANOIA
ctrace << "Executing" << e.t() << "on" << h;
ctrace << toHex(e.t().rlp());
@ -1262,7 +1262,7 @@ ExecutionResult State::execute(LastHashes const& _lh, Transaction const& _t, Per
// Add to the user-originated transactions that we've executed.
m_transactions.push_back(e.t());
m_receipts.push_back(TransactionReceipt(rootHash(), startGasUsed + (m_currentBlock.number >= 830000 ? e.gasUsedNoRefunds() : e.gasUsed()), e.logs()));
m_receipts.push_back(TransactionReceipt(rootHash(), startGasUsed + e.gasUsed(), e.logs()));
m_transactionSet.insert(e.t().sha3());
}

4
libweb3jsonrpc/AccountHolder.cpp

@ -109,7 +109,7 @@ AddressHash SimpleAccountHolder::realAccounts() const
h256 SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t)
{
if (isRealAccount(_t.from))
return m_client()->submitTransaction(_t, m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); }));
return m_client()->submitTransaction(_t, m_keyManager.secret(_t.from, [&](){ return m_getPassword(_t.from); })).first;
else if (isProxyAccount(_t.from))
queueTransaction(_t);
return h256();
@ -118,7 +118,7 @@ h256 SimpleAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t)
h256 FixedAccountHolder::authenticate(dev::eth::TransactionSkeleton const& _t)
{
if (isRealAccount(_t.from))
return m_client()->submitTransaction(_t, m_accounts[_t.from]);
return m_client()->submitTransaction(_t, m_accounts[_t.from]).first;
else if (isProxyAccount(_t.from))
queueTransaction(_t);
return h256();

3
mix/ClientModel.cpp

@ -674,8 +674,7 @@ void ClientModel::debugRecord(unsigned _index)
Address ClientModel::deployContract(bytes const& _code, TransactionSettings const& _ctrTransaction)
{
m_client->submitTransaction(_ctrTransaction.sender, _ctrTransaction.value, _code, _ctrTransaction.gas, _ctrTransaction.gasPrice, _ctrTransaction.gasAuto);
return m_client->lastCreatedContractAddr();
return m_client->submitTransaction(_ctrTransaction.sender, _ctrTransaction.value, _code, _ctrTransaction.gas, _ctrTransaction.gasPrice, _ctrTransaction.gasAuto);
}
void ClientModel::callAddress(Address const& _contract, bytes const& _data, TransactionSettings const& _tr)

10
mix/MixClient.cpp

@ -303,20 +303,14 @@ State MixClient::asOf(h256 const& _block) const
return ret;
}
h256 MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto)
pair<h256, Address> MixClient::submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto)
{
WriteGuard l(x_state);
TransactionSkeleton ts = _ts;
ts.nonce = m_state.transactionsFrom(toAddress(_secret));
eth::Transaction t(ts, _secret);
executeTransaction(t, m_state, false, _gasAuto, _secret);
return t.sha3();
}
Address MixClient::lastCreatedContractAddr() const
{
Transaction tr = m_state.pending().back();
return tr.isCreation() ? right160(sha3(rlpList(tr.sender(), tr.nonce()))) : Address();
return make_pair(t.sha3(), toAddress(ts.from, ts.nonce));
}
dev::eth::ExecutionResult MixClient::call(Address const& _from, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, BlockNumber _blockNumber, bool _gasAuto, FudgeFactor _ff)

4
mix/MixClient.h

@ -58,8 +58,8 @@ public:
dev::eth::ExecutionResult create(Address const& _secret, u256 _value, bytes const& _data = bytes(), u256 _gas = 10000, u256 _gasPrice = 10 * eth::szabo, eth::BlockNumber _blockNumber = eth::PendingBlock, eth::FudgeFactor _ff = eth::FudgeFactor::Strict) override;
using ClientBase::submitTransaction;
virtual h256 submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret) override { return submitTransaction(_ts, _secret, false); }
h256 submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto);
virtual std::pair<h256, Address> submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret) override { return submitTransaction(_ts, _secret, false); }
std::pair<h256, Address> submitTransaction(eth::TransactionSkeleton const& _ts, Secret const& _secret, bool _gasAuto);
dev::eth::ExecutionResult call(Address const& _secret, u256 _value, Address _dest, bytes const& _data, u256 _gas, u256 _gasPrice, eth::BlockNumber _blockNumber, bool _gasAuto, eth::FudgeFactor _ff = eth::FudgeFactor::Strict);
void setAddress(Address _us) override;

2
neth/main.cpp

@ -1057,9 +1057,7 @@ int main(int argc, char** argv)
else if (gas < minGas)
cwarn << "Minimum gas amount is" << minGas;
else
{
c->submitTransaction(us.secret(), endowment, init, gas);
}
}
}
else if (c && cmd == "inspect")

Loading…
Cancel
Save