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<QCode*>("QCode");
qRegisterMetaType<QCallData*>("QCallData");
qRegisterMetaType<RecordLogEntry*>("RecordLogEntry*");
qRegisterMetaType<RecordLogEntry*>("RecordLogEntry*");
}
ClientModel::~ClientModel()
@ -236,6 +236,7 @@ void ClientModel::setupScenario(QVariantMap _scenario)
QVariantList blocks = _scenario.value("blocks").toList();
QVariantList stateAccounts = _scenario.value("accounts").toList();
QVariantList stateContracts = _scenario.value("contracts").toList();
m_accounts.clear();
m_accountsSecret.clear();
@ -258,6 +259,19 @@ void ClientModel::setupScenario(QVariantMap _scenario)
}
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;
for (auto const& b: blocks)
{
@ -891,7 +905,7 @@ void ClientModel::onNewTransaction()
QVariantMap accountBalances;
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());
}
for (auto const& account : m_accounts)

8
mix/qml/Application.qml

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

4
mix/qml/Block.qml

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

52
mix/qml/BlockChain.qml

@ -16,6 +16,7 @@ ColumnLayout {
property alias trDialog: transactionDialog
property alias blockChainRepeater: blockChainRepeater
property variant model
property int scenarioIndex
property var states: ({})
spacing: 0
property int previousWidth
@ -26,6 +27,25 @@ ColumnLayout {
signal rebuilding
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
{
target: codeModel
@ -94,13 +114,15 @@ ColumnLayout {
return states[record]
}
function load(scenario)
function load(scenario, index)
{
if (!scenario)
return;
if (model)
rebuild.startBlinking()
model = scenario
scenarioIndex = index
genesis.scenarioIndex = index
states = []
blockModel.clear()
for (var b in model.blocks)
@ -138,6 +160,20 @@ ColumnLayout {
width: parent.width
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
{
id: blockChainRepeater
@ -264,6 +300,8 @@ ColumnLayout {
roundRight: true
property variant contractsHex: ({})
property variant txSha3: ({})
property variant accountsSha3
property variant contractsSha3
property variant txChanged: []
property var blinkReasons: []
@ -352,10 +390,22 @@ ColumnLayout {
ensureNotFuturetime.start()
takeCodeSnapshot()
takeTxSnaphot()
takeAccountsSnapshot()
takeContractsSnapShot()
blinkReasons = []
clientModel.setupScenario(model);
}
function takeContractsSnapShot()
{
contractsSha3 = codeModel.sha3(JSON.stringify(model.contracts))
}
function takeAccountsSnapshot()
{
accountsSha3 = codeModel.sha3(JSON.stringify(model.accounts))
}
function takeCodeSnapshot()
{
contractsHex = {}

3
mix/qml/DeployContractStep.qml

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

5
mix/qml/ScenarioExecution.qml

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

48
mix/qml/ScenarioLoader.qml

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

241
mix/qml/StateDialog.qml

@ -18,12 +18,8 @@ Dialog {
title: qsTr("Edit State")
visible: false
property alias stateTitle: titleField.text
property alias isDefault: defaultCheckBox.checked
property alias model: transactionsModel
property alias transactionDialog: transactionDialog
property alias minerComboBox: comboMiner
property alias newAccAction: newAccountAction
property int stateIndex
property var stateTransactions: []
property var stateAccounts: []
@ -36,16 +32,6 @@ Dialog {
function open(index, item, setDefault) {
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()
stateAccounts = []
var miner = 0
@ -66,8 +52,8 @@ Dialog {
visible = true
isDefault = setDefault
titleField.focus = true
defaultCheckBox.enabled = !isDefault
console.log(isDefault)
defaultCheckBox.checked = isDefault
comboMiner.model = stateAccounts
comboMiner.currentIndex = miner
forceActiveFocus()
@ -84,8 +70,6 @@ Dialog {
function getItem() {
var item = {
title: stateDialog.stateTitle,
transactions: stateTransactions,
accounts: stateAccounts,
contracts: stateContracts
}
@ -95,6 +79,7 @@ Dialog {
break
}
}
item.defaultState = defaultCheckBox.checked
return item
}
@ -111,21 +96,6 @@ Dialog {
ColumnLayout {
id: dialogContent
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 {
Layout.fillWidth: true
@ -258,30 +228,6 @@ Dialog {
Layout.preferredWidth: 85
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 {
@ -313,21 +259,8 @@ Dialog {
id: deleteAccountAction
tooltip: qsTr("Delete Account")
onTriggered: {
if (transactionsModel.isUsed(
stateAccounts[styleData.row].secret))
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()
}
stateAccounts.splice(styleData.row, 1)
accountsView.model.remove(styleData.row)
}
}
@ -405,115 +338,17 @@ Dialog {
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 {
anchors.bottom: parent.bottom
anchors.right: parent.right
Button {
text: qsTr("Delete")
enabled: !modalStateDialog.isDefault
onClicked: {
projectModel.stateListModel.deleteState(stateIndex)
close()
}
}
Button {
text: qsTr("OK")
onClicked: {
if (titleField.text === "")
alertDialog.open()
else
{
close()
accepted()
}
close()
accepted()
}
}
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 {
id: contractsModel
@ -547,50 +367,11 @@ Dialog {
}
ListModel {
id: transactionsModel
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
}
}
id: accountsModel
TransactionDialog {
id: transactionDialog
onAccepted: {
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)
}
function removeAccount(_i) {
accountsModel.remove(_i)
stateAccounts.splice(_i, 1)
}
}
}

15
mix/qml/StateList.qml

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

29
mix/qml/StateListModel.qml

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

Loading…
Cancel
Save