Browse Source

readd stateList, genesisContract, Startting parameters

cl-refactor
yann300 10 years ago
parent
commit
1aa2cbd180
  1. 18
      mix/ClientModel.cpp
  2. 8
      mix/qml/Application.qml
  3. 4
      mix/qml/Block.qml
  4. 52
      mix/qml/BlockChain.qml
  5. 3
      mix/qml/DeployContractStep.qml
  6. 5
      mix/qml/ScenarioExecution.qml
  7. 48
      mix/qml/ScenarioLoader.qml
  8. 241
      mix/qml/StateDialog.qml
  9. 15
      mix/qml/StateList.qml
  10. 29
      mix/qml/StateListModel.qml

18
mix/ClientModel.cpp

@ -81,7 +81,7 @@ ClientModel::ClientModel():
qRegisterMetaType<QInstruction*>("QInstruction"); qRegisterMetaType<QInstruction*>("QInstruction");
qRegisterMetaType<QCode*>("QCode"); qRegisterMetaType<QCode*>("QCode");
qRegisterMetaType<QCallData*>("QCallData"); qRegisterMetaType<QCallData*>("QCallData");
qRegisterMetaType<RecordLogEntry*>("RecordLogEntry*"); qRegisterMetaType<RecordLogEntry*>("RecordLogEntry*");
} }
ClientModel::~ClientModel() ClientModel::~ClientModel()
@ -236,6 +236,7 @@ void ClientModel::setupScenario(QVariantMap _scenario)
QVariantList blocks = _scenario.value("blocks").toList(); QVariantList blocks = _scenario.value("blocks").toList();
QVariantList stateAccounts = _scenario.value("accounts").toList(); QVariantList stateAccounts = _scenario.value("accounts").toList();
QVariantList stateContracts = _scenario.value("contracts").toList();
m_accounts.clear(); m_accounts.clear();
m_accountsSecret.clear(); m_accountsSecret.clear();
@ -258,6 +259,19 @@ void ClientModel::setupScenario(QVariantMap _scenario)
} }
m_ethAccounts->setAccounts(m_accountsSecret); m_ethAccounts->setAccounts(m_accountsSecret);
for (auto const& c: stateContracts)
{
QVariantMap contract = c.toMap();
Address address = Address(fromHex(contract.value("address").toString().toStdString()));
Account account(qvariant_cast<QEther*>(contract.value("balance"))->toU256Wei(), Account::ContractConception);
bytes code = fromHex(contract.value("code").toString().toStdString());
account.setCode(std::move(code));
QVariantMap storageMap = contract.value("storage").toMap();
for(auto s = storageMap.cbegin(); s != storageMap.cend(); ++s)
account.setStorage(fromBigEndian<u256>(fromHex(s.key().toStdString())), fromBigEndian<u256>(fromHex(s.value().toString().toStdString())));
m_accounts[address] = account;
}
bool trToExecute = false; bool trToExecute = false;
for (auto const& b: blocks) for (auto const& b: blocks)
{ {
@ -891,7 +905,7 @@ void ClientModel::onNewTransaction()
QVariantMap accountBalances; QVariantMap accountBalances;
for (auto const& ctr : m_contractAddresses) for (auto const& ctr : m_contractAddresses)
{ {
u256 wei = m_client->balanceAt(ctr.second, PendingBlock); u256 wei = m_client->balanceAt(ctr.second, PendingBlock);
accountBalances.insert("0x" + QString::fromStdString(ctr.second.hex()), QEther(wei, QEther::Wei).format()); accountBalances.insert("0x" + QString::fromStdString(ctr.second.hex()), QEther(wei, QEther::Wei).format());
} }
for (auto const& account : m_accounts) for (auto const& account : m_accounts)

8
mix/qml/Application.qml

@ -108,12 +108,14 @@ ApplicationWindow {
title: qsTr("Deploy") title: qsTr("Deploy")
MenuItem { action: mineAction } MenuItem { action: mineAction }
MenuSeparator {} MenuSeparator {}
MenuItem { action: editStatesAction }
MenuSeparator {}
MenuItem { action: deployViaRpcAction } MenuItem { action: deployViaRpcAction }
MenuSeparator {} MenuSeparator {}
MenuItem { action: toggleRunOnLoadAction } MenuItem { action: toggleRunOnLoadAction }
} }
Menu {
title: qsTr("Scenario")
MenuItem { action: editStatesAction }
}
Menu { Menu {
title: qsTr("Debug") title: qsTr("Debug")
MenuItem { action: debugRunAction } MenuItem { action: debugRunAction }
@ -184,7 +186,7 @@ ApplicationWindow {
Action { Action {
id: editStatesAction id: editStatesAction
text: qsTr("Edit States") text: qsTr("Edit Scenarii")
shortcut: "Ctrl+Alt+E" shortcut: "Ctrl+Alt+E"
onTriggered: stateList.open(); onTriggered: stateList.open();
} }

4
mix/qml/Block.qml

@ -22,6 +22,7 @@ ColumnLayout
property int blockIndex property int blockIndex
property variant scenario property variant scenario
property string labelColor: "#414141" property string labelColor: "#414141"
property int scenarioIndex
signal txSelected(var txIndex) signal txSelected(var txIndex)
function calculateHeight() function calculateHeight()
@ -105,13 +106,14 @@ ColumnLayout
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: 14 anchors.rightMargin: 14
visible: false visible: number === -2
MouseArea MouseArea
{ {
anchors.fill: parent anchors.fill: parent
onClicked: onClicked:
{ {
// load edit block panel // load edit block panel
projectModel.stateListModel.editState(scenarioIndex)
} }
} }
} }

52
mix/qml/BlockChain.qml

@ -16,6 +16,7 @@ ColumnLayout {
property alias trDialog: transactionDialog property alias trDialog: transactionDialog
property alias blockChainRepeater: blockChainRepeater property alias blockChainRepeater: blockChainRepeater
property variant model property variant model
property int scenarioIndex
property var states: ({}) property var states: ({})
spacing: 0 spacing: 0
property int previousWidth property int previousWidth
@ -26,6 +27,25 @@ ColumnLayout {
signal rebuilding signal rebuilding
signal accountAdded(string address, string amount) signal accountAdded(string address, string amount)
Connections
{
target: projectModel.stateListModel
onAccountsValidated:
{
if (rebuild.accountsSha3 !== codeModel.sha3(JSON.stringify(_accounts)))
rebuild.needRebuild("AccountsChanged")
else
rebuild.notNeedRebuild("AccountsChanged")
}
onContractsValidated:
{
if (rebuild.contractsSha3 !== codeModel.sha3(JSON.stringify(_contracts)))
rebuild.needRebuild("ContractsChanged")
else
rebuild.notNeedRebuild("ContractsChanged")
}
}
Connections Connections
{ {
target: codeModel target: codeModel
@ -94,13 +114,15 @@ ColumnLayout {
return states[record] return states[record]
} }
function load(scenario) function load(scenario, index)
{ {
if (!scenario) if (!scenario)
return; return;
if (model) if (model)
rebuild.startBlinking() rebuild.startBlinking()
model = scenario model = scenario
scenarioIndex = index
genesis.scenarioIndex = index
states = [] states = []
blockModel.clear() blockModel.clear()
for (var b in model.blocks) for (var b in model.blocks)
@ -138,6 +160,20 @@ ColumnLayout {
width: parent.width width: parent.width
spacing: 20 spacing: 20
Block
{
id: genesis
scenario: blockChainPanel.model
scenarioIndex: scenarioIndex
Layout.preferredWidth: blockChainScrollView.width
Layout.preferredHeight: 60
blockIndex: -1
transactions: []
status: ""
number: -2
trHeight: 60
}
Repeater // List of blocks Repeater // List of blocks
{ {
id: blockChainRepeater id: blockChainRepeater
@ -264,6 +300,8 @@ ColumnLayout {
roundRight: true roundRight: true
property variant contractsHex: ({}) property variant contractsHex: ({})
property variant txSha3: ({}) property variant txSha3: ({})
property variant accountsSha3
property variant contractsSha3
property variant txChanged: [] property variant txChanged: []
property var blinkReasons: [] property var blinkReasons: []
@ -352,10 +390,22 @@ ColumnLayout {
ensureNotFuturetime.start() ensureNotFuturetime.start()
takeCodeSnapshot() takeCodeSnapshot()
takeTxSnaphot() takeTxSnaphot()
takeAccountsSnapshot()
takeContractsSnapShot()
blinkReasons = [] blinkReasons = []
clientModel.setupScenario(model); clientModel.setupScenario(model);
} }
function takeContractsSnapShot()
{
contractsSha3 = codeModel.sha3(JSON.stringify(model.contracts))
}
function takeAccountsSnapshot()
{
accountsSha3 = codeModel.sha3(JSON.stringify(model.accounts))
}
function takeCodeSnapshot() function takeCodeSnapshot()
{ {
contractsHex = {} contractsHex = {}

3
mix/qml/DeployContractStep.qml

@ -490,7 +490,8 @@ Rectangle {
id: clearDeployAction id: clearDeployAction
onTriggered: { onTriggered: {
worker.forceStopPooling() worker.forceStopPooling()
fileIo.deleteDir(projectModel.deploymentDir) if (projectModel.deploymentDir && projectModel.deploymentDir !== "")
fileIo.deleteDir(projectModel.deploymentDir)
projectModel.cleanDeploymentStatus() projectModel.cleanDeploymentStatus()
deploymentDialog.steps.reset() deploymentDialog.steps.reset()
} }

5
mix/qml/ScenarioExecution.qml

@ -70,7 +70,7 @@ Rectangle {
onLoaded: onLoaded:
{ {
watchers.clear() watchers.clear()
blockChain.load(scenario) blockChain.load(scenario, loader.selectedScenarioIndex)
} }
} }
@ -91,7 +91,8 @@ Rectangle {
updateWatchers(blockIndex, txIndex) updateWatchers(blockIndex, txIndex)
} }
function updateWatchers(blockIndex, txIndex){ function updateWatchers(blockIndex, txIndex)
{
var tx = blockChain.model.blocks[blockIndex].transactions[txIndex] var tx = blockChain.model.blocks[blockIndex].transactions[txIndex]
var state = blockChain.getState(tx.recordIndex) var state = blockChain.getState(tx.recordIndex)
watchers.updateWidthTx(tx, state, blockIndex, txIndex) watchers.updateWidthTx(tx, state, blockIndex, txIndex)

48
mix/qml/ScenarioLoader.qml

@ -20,6 +20,7 @@ ColumnLayout
signal loaded(variant scenario) signal loaded(variant scenario)
signal renamed(variant scenario) signal renamed(variant scenario)
signal deleted() signal deleted()
property alias selectedScenarioIndex: scenarioList.currentIndex
spacing: 0 spacing: 0
function init() function init()
{ {
@ -80,15 +81,14 @@ ColumnLayout
} }
} }
Label Image {
{ source: "qrc:/qml/img/delete_sign.png"
anchors.left: editImg.right height: parent.height - 16
text: "X" fillMode: Image.PreserveAspectFit
height: parent.height
color: "#cccccc"
id: deleteImg id: deleteImg
anchors.left: editImg.right
anchors.top: parent.top anchors.top: parent.top
anchors.topMargin: 7 anchors.topMargin: 8
visible: projectModel.stateListModel.count > 1 visible: projectModel.stateListModel.count > 1
MouseArea MouseArea
{ {
@ -98,13 +98,37 @@ ColumnLayout
if (projectModel.stateListModel.count > 1) if (projectModel.stateListModel.count > 1)
{ {
projectModel.stateListModel.deleteState(scenarioList.currentIndex) projectModel.stateListModel.deleteState(scenarioList.currentIndex)
scenarioList.currentIndex = 0 scenarioList.init()
deleted() }
}
}
}
Label
{
MouseArea
{
anchors.fill: parent
onClicked:
{
if (projectModel.stateListModel.count > 1)
{
projectModel.stateListModel.deleteState(scenarioList.currentIndex)
scenarioList.init()
} }
} }
} }
} }
Connections
{
target: projectModel.stateListModel
onStateDeleted: {
scenarioList.init()
}
}
ComboBox ComboBox
{ {
id: scenarioList id: scenarioList
@ -122,6 +146,12 @@ ColumnLayout
restoreScenario.restore() restoreScenario.restore()
} }
function init()
{
scenarioList.currentIndex = 0
deleted()
}
function load() function load()
{ {
var state = projectModel.stateListModel.getState(currentIndex) var state = projectModel.stateListModel.getState(currentIndex)

241
mix/qml/StateDialog.qml

@ -18,12 +18,8 @@ Dialog {
title: qsTr("Edit State") title: qsTr("Edit State")
visible: false visible: false
property alias stateTitle: titleField.text
property alias isDefault: defaultCheckBox.checked property alias isDefault: defaultCheckBox.checked
property alias model: transactionsModel
property alias transactionDialog: transactionDialog
property alias minerComboBox: comboMiner property alias minerComboBox: comboMiner
property alias newAccAction: newAccountAction
property int stateIndex property int stateIndex
property var stateTransactions: [] property var stateTransactions: []
property var stateAccounts: [] property var stateAccounts: []
@ -36,16 +32,6 @@ Dialog {
function open(index, item, setDefault) { function open(index, item, setDefault) {
stateIndex = index stateIndex = index
stateTitle = item.title
transactionsModel.clear()
stateTransactions = []
var transactions = item.transactions
for (var t = 0; t < transactions.length; t++) {
transactionsModel.append(item.transactions[t])
stateTransactions.push(item.transactions[t])
}
accountsModel.clear() accountsModel.clear()
stateAccounts = [] stateAccounts = []
var miner = 0 var miner = 0
@ -66,8 +52,8 @@ Dialog {
visible = true visible = true
isDefault = setDefault isDefault = setDefault
titleField.focus = true console.log(isDefault)
defaultCheckBox.enabled = !isDefault defaultCheckBox.checked = isDefault
comboMiner.model = stateAccounts comboMiner.model = stateAccounts
comboMiner.currentIndex = miner comboMiner.currentIndex = miner
forceActiveFocus() forceActiveFocus()
@ -84,8 +70,6 @@ Dialog {
function getItem() { function getItem() {
var item = { var item = {
title: stateDialog.stateTitle,
transactions: stateTransactions,
accounts: stateAccounts, accounts: stateAccounts,
contracts: stateContracts contracts: stateContracts
} }
@ -95,6 +79,7 @@ Dialog {
break break
} }
} }
item.defaultState = defaultCheckBox.checked
return item return item
} }
@ -111,21 +96,6 @@ Dialog {
ColumnLayout { ColumnLayout {
id: dialogContent id: dialogContent
anchors.top: parent.top anchors.top: parent.top
RowLayout {
Layout.fillWidth: true
DefaultLabel {
Layout.preferredWidth: 85
text: qsTr("Title")
}
DefaultTextField {
id: titleField
Layout.fillWidth: true
}
}
CommonSeparator {
Layout.fillWidth: true
}
RowLayout { RowLayout {
Layout.fillWidth: true Layout.fillWidth: true
@ -258,30 +228,6 @@ Dialog {
Layout.preferredWidth: 85 Layout.preferredWidth: 85
text: qsTr("Accounts") text: qsTr("Accounts")
} }
Button {
id: newAccountButton
anchors.top: accountsLabel.bottom
anchors.topMargin: 10
iconSource: "qrc:/qml/img/plus.png"
action: newAccountAction
}
Action {
id: newAccountAction
tooltip: qsTr("Add new Account")
onTriggered: {
add()
}
function add() {
var account = stateListModel.newAccount(
"1000000", QEther.Ether)
stateAccounts.push(account)
accountsModel.append(account)
return account
}
}
} }
MessageDialog { MessageDialog {
@ -313,21 +259,8 @@ Dialog {
id: deleteAccountAction id: deleteAccountAction
tooltip: qsTr("Delete Account") tooltip: qsTr("Delete Account")
onTriggered: { onTriggered: {
if (transactionsModel.isUsed( stateAccounts.splice(styleData.row, 1)
stateAccounts[styleData.row].secret)) accountsView.model.remove(styleData.row)
alertAlreadyUsed.open()
else {
if (stateAccounts[styleData.row].name
=== comboMiner.currentText)
comboMiner.currentIndex = 0
stateAccounts.splice(
styleData.row,
1)
accountsModel.remove(
styleData.row)
comboMiner.model = stateAccounts //TODO: filter accounts wo private keys
comboMiner.update()
}
} }
} }
@ -405,115 +338,17 @@ Dialog {
Layout.fillWidth: true Layout.fillWidth: true
} }
RowLayout {
Layout.fillWidth: true
Rectangle {
Layout.preferredWidth: 85
DefaultLabel {
id: transactionsLabel
Layout.preferredWidth: 85
text: qsTr("Transactions")
}
Button {
anchors.top: transactionsLabel.bottom
anchors.topMargin: 10
iconSource: "qrc:/qml/img/plus.png"
action: newTrAction
}
Action {
id: newTrAction
tooltip: qsTr("Create a new transaction")
onTriggered: transactionsModel.addTransaction()
}
}
TableView {
id: transactionsView
Layout.fillWidth: true
model: transactionsModel
headerVisible: false
TableViewColumn {
role: "label"
title: qsTr("Name")
width: 150
delegate: Item {
RowLayout {
height: 30
width: parent.width
Button {
iconSource: "qrc:/qml/img/delete_sign.png"
action: deleteTransactionAction
}
Action {
id: deleteTransactionAction
tooltip: qsTr("Delete")
onTriggered: transactionsModel.deleteTransaction(
styleData.row)
}
Button {
iconSource: "qrc:/qml/img/edit.png"
action: editAction
visible: styleData.row
>= 0 ? !transactionsModel.get(
styleData.row).stdContract : false
width: 10
height: 10
Action {
id: editAction
tooltip: qsTr("Edit")
onTriggered: transactionsModel.editTransaction(
styleData.row)
}
}
DefaultLabel {
Layout.preferredWidth: 150
text: {
if (styleData.row >= 0)
return transactionsModel.get(
styleData.row).label
else
return ""
}
}
}
}
}
rowDelegate: Rectangle {
color: styleData.alternate ? "transparent" : "#f0f0f0"
height: 30
}
}
}
} }
RowLayout { RowLayout {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.right: parent.right anchors.right: parent.right
Button {
text: qsTr("Delete")
enabled: !modalStateDialog.isDefault
onClicked: {
projectModel.stateListModel.deleteState(stateIndex)
close()
}
}
Button { Button {
text: qsTr("OK") text: qsTr("OK")
onClicked: { onClicked: {
if (titleField.text === "") close()
alertDialog.open() accepted()
else
{
close()
accepted()
}
} }
} }
Button { Button {
@ -522,21 +357,6 @@ Dialog {
} }
} }
MessageDialog
{
id: alertDialog
text: qsTr("Please provide a name.")
}
ListModel {
id: accountsModel
function removeAccount(_i) {
accountsModel.remove(_i)
stateAccounts.splice(_i, 1)
}
}
ListModel { ListModel {
id: contractsModel id: contractsModel
@ -547,50 +367,11 @@ Dialog {
} }
ListModel { ListModel {
id: transactionsModel id: accountsModel
function editTransaction(index) {
transactionDialog.stateAccounts = stateAccounts
transactionDialog.open(index,
transactionsModel.get(index))
}
function addTransaction() {
// Set next id here to work around Qt bug
// https://bugreports.qt-project.org/browse/QTBUG-41327
// Second call to signal handler would just edit the item that was just created, no harm done
var item = TransactionHelper.defaultTransaction()
transactionDialog.stateAccounts = stateAccounts
transactionDialog.open(transactionsModel.count, item)
}
function deleteTransaction(index) {
stateTransactions.splice(index, 1)
transactionsModel.remove(index)
}
function isUsed(secret) {
for (var i in stateTransactions) {
if (stateTransactions[i].sender === secret)
return true
}
return false
}
}
TransactionDialog { function removeAccount(_i) {
id: transactionDialog accountsModel.remove(_i)
onAccepted: { stateAccounts.splice(_i, 1)
var item = transactionDialog.getItem()
if (transactionDialog.transactionIndex < transactionsModel.count) {
transactionsModel.set(
transactionDialog.transactionIndex,
item)
stateTransactions[transactionDialog.transactionIndex] = item
} else {
transactionsModel.append(item)
stateTransactions.push(item)
}
} }
} }
} }

15
mix/qml/StateList.qml

@ -27,7 +27,7 @@ Dialog {
frameVisible: false frameVisible: false
TableViewColumn { TableViewColumn {
role: "title" role: "title"
title: qsTr("State") title: qsTr("Scenario")
width: list.width width: list.width
} }
} }
@ -71,25 +71,12 @@ Dialog {
Layout.fillHeight: true Layout.fillHeight: true
onClicked: list.model.deleteState(styleData.row); onClicked: list.model.deleteState(styleData.row);
} }
ToolButton {
text: qsTr("Run");
Layout.fillHeight: true
onClicked: list.model.runState(styleData.row);
}
} }
} }
} }
Row Row
{ {
Action {
id: addStateAction
text: qsTr("Add State")
shortcut: "Ctrl+T"
enabled: codeModel.hasContract && !clientModel.running;
onTriggered: list.model.addState();
}
Action { Action {
id: closeAction id: closeAction
text: qsTr("Close") text: qsTr("Close")

29
mix/qml/StateListModel.qml

@ -222,20 +222,19 @@ Item {
function saveState(item) function saveState(item)
{ {
if (stateDialog.stateIndex < stateListModel.count) { stateList[stateDialog.stateIndex].accounts = item.accounts
if (stateDialog.isDefault) stateList[stateDialog.stateIndex].contracts = item.contracts
stateListModel.defaultStateIndex = stateIndex; stateListModel.get(stateDialog.stateIndex).accounts = item.accounts
stateList[stateDialog.stateIndex] = item; stateListModel.get(stateDialog.stateIndex).contracts = item.contracts
stateListModel.set(stateDialog.stateIndex, item); stateListModel.accountsValidated(item.accounts)
} else { stateListModel.contractsValidated(item.contracts)
if (stateDialog.isDefault) stateListModel.get(stateDialog.stateIndex).miner = item.miner
stateListModel.defaultStateIndex = 0; stateList[stateDialog.stateIndex].miner = item.miner
stateList.push(item); if (item.defaultState)
stateListModel.append(item); {
stateListModel.defaultStateIndex = stateDialog.stateIndex
stateListModel.defaultStateChanged()
} }
if (stateDialog.isDefault)
stateListModel.defaultStateChanged();
stateListModel.save();
} }
} }
@ -243,6 +242,8 @@ Item {
id: stateListModel id: stateListModel
property int defaultStateIndex: 0 property int defaultStateIndex: 0
property variant data property variant data
signal accountsValidated(var _accounts)
signal contractsValidated(var _contracts)
signal defaultStateChanged; signal defaultStateChanged;
signal stateListModelReady; signal stateListModelReady;
signal stateRun(int index) signal stateRun(int index)
@ -367,6 +368,8 @@ Item {
} }
function editState(index) { function editState(index) {
console.log(index)
console.log(defaultStateIndex)
stateDialog.open(index, stateList[index], defaultStateIndex === index); stateDialog.open(index, stateList[index], defaultStateIndex === index);
} }

Loading…
Cancel
Save