Browse Source

Accounts Managemement

cl-refactor
yann300 10 years ago
parent
commit
63ae0faeb1
  1. 39
      mix/ClientModel.cpp
  2. 4
      mix/ClientModel.h
  3. 26
      mix/MixClient.cpp
  4. 6
      mix/MixClient.h
  5. 2
      mix/qml/DeploymentDialog.qml
  6. 4
      mix/qml/Ether.qml
  7. 48
      mix/qml/StateDialog.qml
  8. 32
      mix/qml/StateListModel.qml
  9. 2
      mix/qml/StatusPane.qml

39
mix/ClientModel.cpp

@ -47,8 +47,6 @@ namespace dev
namespace mix namespace mix
{ {
//const Secret c_defaultUserAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074");
class RpcConnector: public jsonrpc::AbstractServerConnector class RpcConnector: public jsonrpc::AbstractServerConnector
{ {
public: public:
@ -89,7 +87,7 @@ ClientModel::ClientModel(AppContext* _context):
connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection); connect(this, &ClientModel::runComplete, this, &ClientModel::showDebugger, Qt::QueuedConnection);
m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString())); m_client.reset(new MixClient(QStandardPaths::writableLocation(QStandardPaths::TempLocation).toStdString()));
m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), std::vector<dev::KeyPair> { m_client->userAccount() }, m_client.get())); m_web3Server.reset(new Web3Server(*m_rpcConnector.get(), m_client->userAccounts(), m_client.get()));
connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection); connect(m_web3Server.get(), &Web3Server::newTransaction, this, &ClientModel::onNewTransaction, Qt::DirectConnection);
_context->appEngine()->rootContext()->setContextProperty("clientModel", this); _context->appEngine()->rootContext()->setContextProperty("clientModel", this);
} }
@ -138,13 +136,10 @@ void ClientModel::mine()
}); });
} }
QString ClientModel::newAddress() const QString ClientModel::newAddress()
{ {
KeyPair a = KeyPair.create(); KeyPair a = KeyPair::create();
return toHex(a.secret().ref()); return QString::fromStdString(toHex(a.secret().ref()));
//m_client.addBalance(a.address(), _balance, 0);
//emit accountCreated;
//return QString::fromStdString(toHex(a.address().ref()));
} }
QVariantMap ClientModel::contractAddresses() const QVariantMap ClientModel::contractAddresses() const
@ -157,7 +152,7 @@ QVariantMap ClientModel::contractAddresses() const
void ClientModel::debugDeployment() void ClientModel::debugDeployment()
{ {
executeSequence(std::vector<TransactionSettings>(), 10000000 * ether); executeSequence(std::vector<TransactionSettings>(), std::map<Secret, u256>());
} }
void ClientModel::setupState(QVariantMap _state) void ClientModel::setupState(QVariantMap _state)
@ -165,6 +160,13 @@ void ClientModel::setupState(QVariantMap _state)
QVariantList balances = _state.value("balances").toList(); QVariantList balances = _state.value("balances").toList();
QVariantList transactions = _state.value("transactions").toList(); QVariantList transactions = _state.value("transactions").toList();
std::map<Secret, u256> accounts;
for (auto const& b: balances)
{
QVariantMap address = b.toMap();
accounts.insert(std::make_pair(Secret(address.value("secret").toString().toStdString()), (qvariant_cast<QEther*>(address.value("balance")))->toU256Wei()));
}
std::vector<TransactionSettings> transactionSequence; std::vector<TransactionSettings> transactionSequence;
for (auto const& t: transactions) for (auto const& t: transactions)
{ {
@ -205,10 +207,10 @@ void ClientModel::setupState(QVariantMap _state)
transactionSequence.push_back(transactionSettings); transactionSequence.push_back(transactionSettings);
} }
} }
executeSequence(transactionSequence, balances); executeSequence(transactionSequence, accounts);
} }
void ClientModel::executeSequence(std::vector<TransactionSettings> const& _sequence, QVariantList _balances) void ClientModel::executeSequence(std::vector<TransactionSettings> const& _sequence, std::map<Secret, u256> _balances)
{ {
if (m_running) if (m_running)
BOOST_THROW_EXCEPTION(ExecutionStateException()); BOOST_THROW_EXCEPTION(ExecutionStateException());
@ -222,14 +224,7 @@ void ClientModel::executeSequence(std::vector<TransactionSettings> const& _seque
{ {
try try
{ {
std::map balancesMap; m_client->resetState(_balances);
for (auto b: _balances)
{
QVariantMap address = b.toMap();
balancesMap.insert(std::make_pair(KeyPair(Secret(address.value("Secret").toString())).address(), Account(address.value("Balance").toString(), Account::NormalCreation)));
}
m_client->resetState(balancesMap);
onStateReset(); onStateReset();
for (TransactionSettings const& transaction: _sequence) for (TransactionSettings const& transaction: _sequence)
{ {
@ -363,13 +358,13 @@ void ClientModel::showDebugError(QString const& _error)
Address ClientModel::deployContract(bytes const& _code, TransactionSettings const& _ctrTransaction) Address ClientModel::deployContract(bytes const& _code, TransactionSettings const& _ctrTransaction)
{ {
Address newAddress = m_client->transact(m_client->userAccount().secret(), _ctrTransaction.value, _code, _ctrTransaction.gas, _ctrTransaction.gasPrice); Address newAddress = m_client->transact(_ctrTransaction.sender, _ctrTransaction.value, _code, _ctrTransaction.gas, _ctrTransaction.gasPrice);
return newAddress; return newAddress;
} }
void ClientModel::callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr) void ClientModel::callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr)
{ {
m_client->transact(m_client->userAccount().secret(), _tr.value, _contract, _data, _tr.gas, _tr.gasPrice); m_client->transact(_tr.sender, _tr.value, _contract, _data, _tr.gas, _tr.gasPrice);
} }
RecordLogEntry* ClientModel::lastBlock() const RecordLogEntry* ClientModel::lastBlock() const

4
mix/ClientModel.h

@ -66,6 +66,8 @@ struct TransactionSettings
QList<QVariableDefinition*> parameterValues; QList<QVariableDefinition*> parameterValues;
/// Standard contract url /// Standard contract url
QString stdContractUrl; QString stdContractUrl;
/// Sender
Secret sender;
}; };
@ -193,7 +195,7 @@ signals:
private: private:
RecordLogEntry* lastBlock() const; RecordLogEntry* lastBlock() const;
QVariantMap contractAddresses() const; QVariantMap contractAddresses() const;
void executeSequence(std::vector<TransactionSettings> const& _sequence, u256 _balance); void executeSequence(std::vector<TransactionSettings> const& _sequence, std::map<Secret, u256> _balances);
dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings()); dev::Address deployContract(bytes const& _code, TransactionSettings const& _tr = TransactionSettings());
void callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr); void callContract(Address const& _contract, bytes const& _data, TransactionSettings const& _tr);
void onNewTransaction(); void onNewTransaction();

26
mix/MixClient.cpp

@ -40,6 +40,7 @@ namespace dev
namespace mix namespace mix
{ {
const Secret c_defaultUserAccountSecret = Secret("cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074");
const u256 c_mixGenesisDifficulty = (u256) 1 << 4; const u256 c_mixGenesisDifficulty = (u256) 1 << 4;
class MixBlockChain: public dev::eth::BlockChain class MixBlockChain: public dev::eth::BlockChain
@ -61,16 +62,16 @@ public:
}; };
MixClient::MixClient(std::string const& _dbPath): MixClient::MixClient(std::string const& _dbPath):
m_userAccount(c_userAccountSecret), m_dbPath(_dbPath), m_minigThreads(0) m_dbPath(_dbPath), m_minigThreads(0)
{ {
resetState(10000000 * ether); //resetState();
} }
MixClient::~MixClient() MixClient::~MixClient()
{ {
} }
void MixClient::resetState(std::map<Address, Account> _genesisState) void MixClient::resetState(std::map<Secret, u256> _accounts)
{ {
WriteGuard l(x_state); WriteGuard l(x_state);
Guard fl(m_filterLock); Guard fl(m_filterLock);
@ -80,11 +81,26 @@ void MixClient::resetState(std::map<Address, Account> _genesisState)
m_stateDB = OverlayDB(); m_stateDB = OverlayDB();
TrieDB<Address, MemoryDB> accountState(&m_stateDB); TrieDB<Address, MemoryDB> accountState(&m_stateDB);
accountState.init(); accountState.init();
dev::eth::commit(_genesisState, static_cast<MemoryDB&>(m_stateDB), accountState);
std::map<Address, Account> genesisState;
if (_accounts.size() > 0)
for (auto account: _accounts)
{
KeyPair a = KeyPair(account.first);
m_userAccounts.push_back(a);
genesisState.insert(std::make_pair(a.address(), Account(account.second, Account::NormalCreation)));
}
else
{
KeyPair a = KeyPair(c_defaultUserAccountSecret);
m_userAccounts.push_back(a);
genesisState.insert(std::make_pair(a.address() , Account(u256(10000 * ether), Account::NormalCreation)));
}
dev::eth::commit(genesisState, static_cast<MemoryDB&>(m_stateDB), accountState);
h256 stateRoot = accountState.root(); h256 stateRoot = accountState.root();
m_bc.reset(); m_bc.reset();
m_bc.reset(new MixBlockChain(m_dbPath, stateRoot)); m_bc.reset(new MixBlockChain(m_dbPath, stateRoot));
m_state = eth::State(m_userAccount.address(), m_stateDB, BaseState::Empty); m_state = eth::State(genesisState.begin()->first , m_stateDB, BaseState::Empty);
m_state.sync(bc()); m_state.sync(bc());
m_startState = m_state; m_startState = m_state;
m_executions.clear(); m_executions.clear();

6
mix/MixClient.h

@ -42,8 +42,7 @@ public:
MixClient(std::string const& _dbPath); MixClient(std::string const& _dbPath);
virtual ~MixClient(); virtual ~MixClient();
/// Reset state to the empty state with given balance. /// Reset state to the empty state with given balance.
void resetState(u256 _balance); void resetState(std::map<Secret, u256> _accounts);
KeyPair const& userAccount() const { return m_userAccount; }
void mine(); void mine();
ExecutionResult const& lastExecution() const; ExecutionResult const& lastExecution() const;
ExecutionResults const& executions() const; ExecutionResults const& executions() const;
@ -91,6 +90,7 @@ public:
bool submitNonce(h256 const&) override { return false; } bool submitNonce(h256 const&) override { return false; }
/// @returns the last mined block information /// @returns the last mined block information
eth::BlockInfo blockInfo() const; eth::BlockInfo blockInfo() const;
std::vector<KeyPair> userAccounts() { return m_userAccounts; }
private: private:
void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call); void executeTransaction(dev::eth::Transaction const& _t, eth::State& _state, bool _call);
@ -99,7 +99,7 @@ private:
MixBlockChain& bc() { return *m_bc; } MixBlockChain& bc() { return *m_bc; }
MixBlockChain const& bc() const { return *m_bc; } MixBlockChain const& bc() const { return *m_bc; }
KeyPair m_userAccount; std::vector<KeyPair> m_userAccounts;
eth::State m_state; eth::State m_state;
eth::State m_startState; eth::State m_startState;
OverlayDB m_stateDB; OverlayDB m_stateDB;

2
mix/qml/DeploymentDialog.qml

@ -267,7 +267,7 @@ Window {
MessageDialog { MessageDialog {
id: errorDialog id: errorDialog
standardButtons: StandardButton.Ok standardButtons: StandardButton.Ok
icon: StandardIcon.Error icon: StandardIcon.Critical
} }
RowLayout RowLayout

4
mix/qml/Ether.qml

@ -20,7 +20,7 @@ RowLayout {
function update() function update()
{ {
if (value !== undefined) if (value)
{ {
etherValueEdit.text = value.value; etherValueEdit.text = value.value;
selectUnit(value.unit); selectUnit(value.unit);
@ -54,7 +54,7 @@ RowLayout {
id: units id: units
onCurrentTextChanged: onCurrentTextChanged:
{ {
if (value !== undefined) if (value)
{ {
value.setUnit(currentText); value.setUnit(currentText);
formattedValue.text = value.format(); formattedValue.text = value.format();

48
mix/qml/StateDialog.qml

@ -29,8 +29,8 @@ Window {
function open(index, item, setDefault) { function open(index, item, setDefault) {
stateIndex = index; stateIndex = index;
stateTitle = item.title; stateTitle = item.title;
//balanceField.value = item.balance;
transactionsModel.clear(); transactionsModel.clear();
stateTransactions = []; stateTransactions = [];
var transactions = item.transactions; var transactions = item.transactions;
for (var t = 0; t < transactions.length; t++) { for (var t = 0; t < transactions.length; t++) {
@ -38,8 +38,9 @@ Window {
stateTransactions.push(item.transactions[t]); stateTransactions.push(item.transactions[t]);
} }
accountsModel.clear();
stateAccounts = []; stateAccounts = [];
for (var k = 0; k < item.accounts; k++) for (var k = 0; k < item.accounts.length; k++)
{ {
accountsModel.append(item.accounts[k]); accountsModel.append(item.accounts[k]);
stateAccounts.push(item.accounts[k]); stateAccounts.push(item.accounts[k]);
@ -62,7 +63,6 @@ Window {
function getItem() { function getItem() {
var item = { var item = {
title: stateDialog.stateTitle, title: stateDialog.stateTitle,
//balance: stateDialog.stateBalance,
transactions: [], transactions: [],
accounts: [] accounts: []
} }
@ -105,24 +105,38 @@ Window {
text: qsTr("Accounts") text: qsTr("Accounts")
} }
Rectangle Button
{ {
Button { iconSource: "qrc:/qml/img/plus.png"
text: "add new accounts" action: newAccountAction
onClicked: accountsModel.newAccount("10000", QEther.Ether); width: 10
} height: 10
}
Action {
id: newAccountAction
tooltip: qsTr("Add new Account")
onTriggered: accountsModel.newAccount("10000", QEther.Ether);
} }
TableView TableView
{ {
Layout.fillWidth: true
model: accountsModel model: accountsModel
TableViewColumn { TableViewColumn {
role: "secret" role: "secret"
title: qsTr("Address") title: qsTr("Secret")
width: 100 width: 100
delegate: Item { delegate: Item {
DefaultLabel { Rectangle
text: styleData.value {
height: 25
DefaultLabel {
anchors.verticalCenter: parent.verticalCenter
text: {
return styleData.value.substring(0, 5) + '...';
}
}
} }
} }
} }
@ -135,11 +149,16 @@ Window {
Ether { Ether {
id: balanceField id: balanceField
edit: true edit: true
displayFormattedValue: true displayFormattedValue: false
value: styleData.value value: styleData.value
} }
} }
} }
rowDelegate:
Rectangle {
color: "transparent"
height: 40;
}
} }
} }
@ -242,8 +261,9 @@ Window {
function newAccount(_balance, _unit) function newAccount(_balance, _unit)
{ {
accountsModel.append({ secret: _secret, balance: QEtherHelper.createEther(_balance, _unit) }); var secret = clientModel.newAddress();
stateAccounts.push({ secret: _secret, balance: QEtherHelper.createEther(_balance, _unit) }); accountsModel.append({ secret: secret, balance: QEtherHelper.createEther(_balance, _unit) });
stateAccounts.push({ secret: secret, balance: QEtherHelper.createEther(_balance, _unit) });
} }
function removeAccount(_i) function removeAccount(_i)

32
mix/qml/StateListModel.qml

@ -15,8 +15,16 @@ Item {
function fromPlainStateItem(s) { function fromPlainStateItem(s) {
return { return {
title: s.title, title: s.title,
balance: QEtherHelper.createEther(s.balance.value, s.balance.unit), transactions: s.transactions.map(fromPlainTransactionItem),
transactions: s.transactions.map(fromPlainTransactionItem) accounts: s.accounts.map(fromPlainAccountItem)
};
}
function fromPlainAccountItem(t)
{
return {
secret: t.secret,
balance: QEtherHelper.createEther(t.balance.value, t.balance.unit)
}; };
} }
@ -26,7 +34,7 @@ Item {
functionId: t.functionId, functionId: t.functionId,
url: t.url, url: t.url,
value: QEtherHelper.createEther(t.value.value, t.value.unit), value: QEtherHelper.createEther(t.value.value, t.value.unit),
gas: QEtherHelper.createBigInt(t.gas.value), //t.gas,//QEtherHelper.createEther(t.gas.value, t.gas.unit), gas: QEtherHelper.createBigInt(t.gas.value),
gasPrice: QEtherHelper.createEther(t.gasPrice.value, t.gasPrice.unit), gasPrice: QEtherHelper.createEther(t.gasPrice.value, t.gasPrice.unit),
stdContract: t.stdContract, stdContract: t.stdContract,
parameters: {} parameters: {}
@ -65,8 +73,8 @@ Item {
function toPlainStateItem(s) { function toPlainStateItem(s) {
return { return {
title: s.title, title: s.title,
balance: { value: s.balance.value, unit: s.balance.unit }, transactions: s.transactions.map(toPlainTransactionItem),
transactions: s.transactions.map(toPlainTransactionItem) accounts: s.accounts.map(toPlainAccountItem)
}; };
} }
@ -80,6 +88,17 @@ Item {
return ''; return '';
} }
function toPlainAccountItem(t)
{
return {
secret: t.secret,
balance: {
value: t.balance.value,
unit: t.balance.unit
}
};
}
function toPlainTransactionItem(t) { function toPlainTransactionItem(t) {
var r = { var r = {
contractId: t.contractId, contractId: t.contractId,
@ -152,7 +171,7 @@ Item {
ListModel { ListModel {
id: stateListModel id: stateListModel
property string defaultSecret: "cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169074" property string defaultSecret: "cb73d9408c4720e230387d956eb0f829d8a4dd2c1055f96257167e14e7169075"
property int defaultStateIndex: 0 property int defaultStateIndex: 0
signal defaultStateChanged; signal defaultStateChanged;
signal stateListModelReady; signal stateListModelReady;
@ -198,7 +217,6 @@ Item {
ctorTr.contractId = c; ctorTr.contractId = c;
item.transactions.push(ctorTr); item.transactions.push(ctorTr);
} }
return item; return item;
} }

2
mix/qml/StatusPane.qml

@ -164,8 +164,6 @@ Rectangle {
RowLayout RowLayout
{ {
anchors.fill: parent anchors.fill: parent
anchors.top: statusHeader.top
anchors.right: statusHeader.right
Rectangle Rectangle
{ {
color: "transparent" color: "transparent"

Loading…
Cancel
Save