Move proposal payload in separate class

This commit is contained in:
Manfred Karrer 2016-12-13 13:12:35 +01:00
parent 1126c50a7c
commit 563fa3cc28
8 changed files with 273 additions and 216 deletions

View File

@ -261,9 +261,7 @@ public class BtcWalletService extends WalletService {
numInputs = resultTx.getInputs().size(); numInputs = resultTx.getInputs().size();
printTx("resultTx", resultTx);
txSize = resultTx.bitcoinSerialize().length + sigSizePerInput * numInputs; txSize = resultTx.bitcoinSerialize().length + sigSizePerInput * numInputs;
log.error("txSize " + txSize);
// We need min. 1 output beside op_return // We need min. 1 output beside op_return
// calculated fee must be inside of a tolerance range with tx fee // calculated fee must be inside of a tolerance range with tx fee
final int tolerance = 1000; final int tolerance = 1000;

View File

@ -17,122 +17,33 @@
package io.bitsquare.dao.proposals; package io.bitsquare.dao.proposals;
import io.bitsquare.p2p.NodeAddress; import io.bitsquare.app.Version;
import io.bitsquare.p2p.storage.payload.LazyProcessedStoragePayload; import io.bitsquare.common.persistance.Persistable;
import io.bitsquare.p2p.storage.payload.PersistedStoragePayload;
import org.bitcoinj.core.Coin; import org.bitcoinj.core.Coin;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.security.PublicKey; public class Proposal implements Persistable {
import java.util.Arrays; // That object is saved to disc. We need to take care of changes to not break deserialization.
import java.util.Date; private static final long serialVersionUID = Version.LOCAL_DB_VERSION;
import java.util.concurrent.TimeUnit;
public class Proposal implements LazyProcessedStoragePayload, PersistedStoragePayload {
private static final Logger log = LoggerFactory.getLogger(Proposal.class); private static final Logger log = LoggerFactory.getLogger(Proposal.class);
private final ProposalPayload proposalPayload;
///////////////////////////////////////////////////////////////////////////////////////////
// Enums
///////////////////////////////////////////////////////////////////////////////////////////
public enum Phase {
NEW,
OPEN_FOR_VOTING,
OPEN_FOR_FUNDING,
CLOSED
}
public static final long TTL = TimeUnit.DAYS.toMillis(30);
public final String uid;
public final String name;
public final String title;
public final String category;
public final String description;
public final String link;
public final Date startDate;
public final Date endDate;
public final Coin requestedBtc;
public final String btcAddress;
public final NodeAddress nodeAddress;
public final Date creationDate;
private PublicKey p2pStorageSignaturePubKey;
public final byte[] squPubKey;
// Signature of proposal data without signature, hash and feeTxId
public byte[] signature;
// Sha256Hash of proposal data including the signature but without feeTxId and hash
public byte[] hash;
// Set after we signed and set the hash. The hash is used in the OP_RETURN of the fee tx
public String feeTxId;
private boolean accepted; private boolean accepted;
private Coin fundsReceived; private Coin fundsReceived;
private int phaseAsOrdinal; private boolean inVotePeriod;
private boolean inFundingPeriod;
private boolean closed;
private boolean waitingForVotingPeriod;
public Proposal(String uid, public Proposal(ProposalPayload proposalPayload) {
String name, this.proposalPayload = proposalPayload;
String title,
String category,
String description,
String link,
Date startDate,
Date endDate,
Coin requestedBtc,
String btcAddress,
NodeAddress nodeAddress,
PublicKey p2pStorageSignaturePubKey,
byte[] squPubKey) {
creationDate = new Date();
this.uid = uid;
this.name = name;
this.title = title;
this.category = category;
this.description = description;
this.link = link;
this.startDate = startDate;
this.endDate = endDate;
this.requestedBtc = requestedBtc;
this.btcAddress = btcAddress;
this.nodeAddress = nodeAddress;
this.p2pStorageSignaturePubKey = p2pStorageSignaturePubKey;
this.squPubKey = squPubKey;
setPhase(Phase.NEW);
} }
@Override public ProposalPayload getProposalPayload() {
public long getTTL() { return proposalPayload;
return TTL;
}
@Override
public PublicKey getOwnerPubKey() {
return p2pStorageSignaturePubKey;
}
public void setSignature(byte[] signature) {
this.signature = signature;
}
public void setHash(byte[] hash) {
this.hash = hash;
}
// Called after tx is published
public void setFeeTxId(String feeTxId) {
this.feeTxId = feeTxId;
}
public Phase getPhase() {
return Phase.values()[phaseAsOrdinal];
}
public void setPhase(Phase phase) {
phaseAsOrdinal = phase.ordinal();
} }
public boolean isAccepted() { public boolean isAccepted() {
@ -151,77 +62,35 @@ public class Proposal implements LazyProcessedStoragePayload, PersistedStoragePa
this.fundsReceived = fundsReceived; this.fundsReceived = fundsReceived;
} }
public String shortId() { public boolean isInVotePeriod() {
return uid.substring(0, 8); return inVotePeriod;
} }
@Override public void setInVotePeriod(boolean inVotePeriod) {
public boolean equals(Object o) { this.inVotePeriod = inVotePeriod;
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Proposal proposal = (Proposal) o;
if (uid != null ? !uid.equals(proposal.uid) : proposal.uid != null) return false;
if (name != null ? !name.equals(proposal.name) : proposal.name != null) return false;
if (title != null ? !title.equals(proposal.title) : proposal.title != null) return false;
if (category != null ? !category.equals(proposal.category) : proposal.category != null) return false;
if (description != null ? !description.equals(proposal.description) : proposal.description != null)
return false;
if (link != null ? !link.equals(proposal.link) : proposal.link != null) return false;
if (startDate != null ? !startDate.equals(proposal.startDate) : proposal.startDate != null) return false;
if (endDate != null ? !endDate.equals(proposal.endDate) : proposal.endDate != null) return false;
if (requestedBtc != null ? !requestedBtc.equals(proposal.requestedBtc) : proposal.requestedBtc != null)
return false;
if (btcAddress != null ? !btcAddress.equals(proposal.btcAddress) : proposal.btcAddress != null) return false;
if (nodeAddress != null ? !nodeAddress.equals(proposal.nodeAddress) : proposal.nodeAddress != null)
return false;
if (creationDate != null ? !creationDate.equals(proposal.creationDate) : proposal.creationDate != null)
return false;
if (p2pStorageSignaturePubKey != null ? !p2pStorageSignaturePubKey.equals(proposal.p2pStorageSignaturePubKey) : proposal.p2pStorageSignaturePubKey != null)
return false;
return Arrays.equals(squPubKey, proposal.squPubKey);
} }
@Override public boolean isInFundingPeriod() {
public int hashCode() { return inFundingPeriod;
int result = uid != null ? uid.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + (category != null ? category.hashCode() : 0);
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + (link != null ? link.hashCode() : 0);
result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
result = 31 * result + (requestedBtc != null ? requestedBtc.hashCode() : 0);
result = 31 * result + (btcAddress != null ? btcAddress.hashCode() : 0);
result = 31 * result + (nodeAddress != null ? nodeAddress.hashCode() : 0);
result = 31 * result + (creationDate != null ? creationDate.hashCode() : 0);
result = 31 * result + (p2pStorageSignaturePubKey != null ? p2pStorageSignaturePubKey.hashCode() : 0);
result = 31 * result + (squPubKey != null ? Arrays.hashCode(squPubKey) : 0);
return result;
} }
@Override public void setInFundingPeriod(boolean inFundingPeriod) {
public String toString() { this.inFundingPeriod = inFundingPeriod;
return "Proposal{" +
"uid='" + uid + '\'' +
", text='" + name + '\'' +
", title='" + title + '\'' +
", category='" + category + '\'' +
", description='" + description + '\'' +
", link='" + link + '\'' +
", startDate=" + startDate +
", endDate=" + endDate +
", requestedBtc=" + requestedBtc +
", btcAddress='" + btcAddress + '\'' +
", nodeAddress=" + nodeAddress +
", pubKey=" + Arrays.toString(squPubKey) +
", signature=" + signature +
", hash=" + hash +
", feeTxId=" + feeTxId +
'}';
} }
public boolean isClosed() {
return closed;
}
public void setClosed(boolean closed) {
this.closed = closed;
}
public boolean isWaitingForVotingPeriod() {
return waitingForVotingPeriod;
}
public void setWaitingForVotingPeriod(boolean waitingForVotingPeriod) {
this.waitingForVotingPeriod = waitingForVotingPeriod;
}
} }

View File

@ -69,8 +69,8 @@ public class ProposalManager {
@Override @Override
public void onAdded(ProtectedStorageEntry data) { public void onAdded(ProtectedStorageEntry data) {
final StoragePayload storagePayload = data.getStoragePayload(); final StoragePayload storagePayload = data.getStoragePayload();
if (storagePayload instanceof Proposal) if (storagePayload instanceof ProposalPayload)
addToList((Proposal) storagePayload, true); addToList((ProposalPayload) storagePayload, true);
} }
@Override @Override
@ -82,18 +82,18 @@ public class ProposalManager {
// At startup the P2PDataStorage inits earlier, otherwise we ge the listener called. // At startup the P2PDataStorage inits earlier, otherwise we ge the listener called.
p2PService.getP2PDataStorage().getMap().values().forEach(e -> { p2PService.getP2PDataStorage().getMap().values().forEach(e -> {
final StoragePayload storagePayload = e.getStoragePayload(); final StoragePayload storagePayload = e.getStoragePayload();
if (storagePayload instanceof Proposal) if (storagePayload instanceof ProposalPayload)
addToList((Proposal) storagePayload, false); addToList((ProposalPayload) storagePayload, false);
}); });
} }
public void addToP2PNetwork(Proposal proposal) { public void addToP2PNetwork(ProposalPayload proposalPayload) {
p2PService.addData(proposal, true); p2PService.addData(proposalPayload, true);
} }
public void addToList(Proposal proposal, boolean storeLocally) { public void addToList(ProposalPayload proposalPayload, boolean storeLocally) {
if (!observableProposalsList.contains(proposal)) { if (!observableProposalsList.stream().filter(e -> e.getProposalPayload().equals(proposalPayload)).findAny().isPresent()) {
observableProposalsList.add(proposal); observableProposalsList.add(new Proposal(proposalPayload));
if (storeLocally) if (storeLocally)
proposalsStorage.queueUpForSave(new ArrayList<>(observableProposalsList), 500); proposalsStorage.queueUpForSave(new ArrayList<>(observableProposalsList), 500);
} else { } else {
@ -106,6 +106,6 @@ public class ProposalManager {
} }
public void fundProposal(Proposal proposal, Coin amount, FutureCallback<Transaction> callback) { public void fundProposal(Proposal proposal, Coin amount, FutureCallback<Transaction> callback) {
btcWalletService.fundProposal(amount, proposal.btcAddress, squWalletService.getSquAddressForProposalFunding(), callback); btcWalletService.fundProposal(amount, proposal.getProposalPayload().btcAddress, squWalletService.getSquAddressForProposalFunding(), callback);
} }
} }

View File

@ -0,0 +1,192 @@
/*
* This file is part of Bitsquare.
*
* Bitsquare is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* Bitsquare is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with Bitsquare. If not, see <http://www.gnu.org/licenses/>.
*/
package io.bitsquare.dao.proposals;
import io.bitsquare.app.Version;
import io.bitsquare.p2p.NodeAddress;
import io.bitsquare.p2p.storage.payload.LazyProcessedStoragePayload;
import io.bitsquare.p2p.storage.payload.PersistedStoragePayload;
import org.bitcoinj.core.Coin;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.security.PublicKey;
import java.util.Arrays;
import java.util.Date;
import java.util.concurrent.TimeUnit;
public class ProposalPayload implements LazyProcessedStoragePayload, PersistedStoragePayload {
// That object is sent over the wire, so we need to take care of version compatibility.
private static final long serialVersionUID = Version.P2P_NETWORK_VERSION;
private static final Logger log = LoggerFactory.getLogger(ProposalPayload.class);
public static final long TTL = TimeUnit.DAYS.toMillis(30);
public final String uid;
public final String name;
public final String title;
public final String category;
public final String description;
public final String link;
public final Date startDate;
public final Date endDate;
public final Coin requestedBtc;
public final String btcAddress;
public final NodeAddress nodeAddress;
public final Date creationDate;
//TODO store as byte array
public final PublicKey p2pStorageSignaturePubKey;
public final byte[] squPubKey;
// Signature of proposal data without signature, hash and feeTxId
public byte[] signature;
// Sha256Hash of proposal data including the signature but without feeTxId and hash
public byte[] hash;
// Set after we signed and set the hash. The hash is used in the OP_RETURN of the fee tx
public String feeTxId;
public ProposalPayload(String uid,
String name,
String title,
String category,
String description,
String link,
Date startDate,
Date endDate,
Coin requestedBtc,
String btcAddress,
NodeAddress nodeAddress,
PublicKey p2pStorageSignaturePubKey,
byte[] squPubKey) {
creationDate = new Date();
this.uid = uid;
this.name = name;
this.title = title;
this.category = category;
this.description = description;
this.link = link;
this.startDate = startDate;
this.endDate = endDate;
this.requestedBtc = requestedBtc;
this.btcAddress = btcAddress;
this.nodeAddress = nodeAddress;
this.p2pStorageSignaturePubKey = p2pStorageSignaturePubKey;
this.squPubKey = squPubKey;
}
@Override
public long getTTL() {
return TTL;
}
@Override
public PublicKey getOwnerPubKey() {
return p2pStorageSignaturePubKey;
}
public void setSignature(byte[] signature) {
this.signature = signature;
}
public void setHash(byte[] hash) {
this.hash = hash;
}
// Called after tx is published
public void setFeeTxId(String feeTxId) {
this.feeTxId = feeTxId;
}
public String getShortId() {
return uid.substring(0, 8);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ProposalPayload proposal = (ProposalPayload) o;
if (uid != null ? !uid.equals(proposal.uid) : proposal.uid != null) return false;
if (name != null ? !name.equals(proposal.name) : proposal.name != null) return false;
if (title != null ? !title.equals(proposal.title) : proposal.title != null) return false;
if (category != null ? !category.equals(proposal.category) : proposal.category != null) return false;
if (description != null ? !description.equals(proposal.description) : proposal.description != null)
return false;
if (link != null ? !link.equals(proposal.link) : proposal.link != null) return false;
if (startDate != null ? !startDate.equals(proposal.startDate) : proposal.startDate != null) return false;
if (endDate != null ? !endDate.equals(proposal.endDate) : proposal.endDate != null) return false;
if (requestedBtc != null ? !requestedBtc.equals(proposal.requestedBtc) : proposal.requestedBtc != null)
return false;
if (btcAddress != null ? !btcAddress.equals(proposal.btcAddress) : proposal.btcAddress != null) return false;
if (nodeAddress != null ? !nodeAddress.equals(proposal.nodeAddress) : proposal.nodeAddress != null)
return false;
if (creationDate != null ? !creationDate.equals(proposal.creationDate) : proposal.creationDate != null)
return false;
if (p2pStorageSignaturePubKey != null ? !p2pStorageSignaturePubKey.equals(proposal.p2pStorageSignaturePubKey) : proposal.p2pStorageSignaturePubKey != null)
return false;
return Arrays.equals(squPubKey, proposal.squPubKey);
}
@Override
public int hashCode() {
int result = uid != null ? uid.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (title != null ? title.hashCode() : 0);
result = 31 * result + (category != null ? category.hashCode() : 0);
result = 31 * result + (description != null ? description.hashCode() : 0);
result = 31 * result + (link != null ? link.hashCode() : 0);
result = 31 * result + (startDate != null ? startDate.hashCode() : 0);
result = 31 * result + (endDate != null ? endDate.hashCode() : 0);
result = 31 * result + (requestedBtc != null ? requestedBtc.hashCode() : 0);
result = 31 * result + (btcAddress != null ? btcAddress.hashCode() : 0);
result = 31 * result + (nodeAddress != null ? nodeAddress.hashCode() : 0);
result = 31 * result + (creationDate != null ? creationDate.hashCode() : 0);
result = 31 * result + (p2pStorageSignaturePubKey != null ? p2pStorageSignaturePubKey.hashCode() : 0);
result = 31 * result + (squPubKey != null ? Arrays.hashCode(squPubKey) : 0);
return result;
}
@Override
public String toString() {
return "Proposal{" +
"uid='" + uid + '\'' +
", text='" + name + '\'' +
", title='" + title + '\'' +
", category='" + category + '\'' +
", description='" + description + '\'' +
", link='" + link + '\'' +
", startDate=" + startDate +
", endDate=" + endDate +
", requestedBtc=" + requestedBtc +
", btcAddress='" + btcAddress + '\'' +
", nodeAddress=" + nodeAddress +
", pubKey=" + Arrays.toString(squPubKey) +
", signature=" + signature +
", hash=" + hash +
", feeTxId=" + feeTxId +
'}';
}
}

View File

@ -17,17 +17,17 @@
package io.bitsquare.gui.main.dao.proposals; package io.bitsquare.gui.main.dao.proposals;
import io.bitsquare.dao.proposals.Proposal; import io.bitsquare.dao.proposals.ProposalPayload;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.util.Layout; import io.bitsquare.gui.util.Layout;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane; import javafx.scene.layout.GridPane;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import java.util.Random; import java.util.Random;
import static io.bitsquare.gui.util.FormBuilder.*; import static io.bitsquare.gui.util.FormBuilder.addLabelInputTextField;
import static io.bitsquare.gui.util.FormBuilder.addTitledGroupBg;
public class ProposalDisplay { public class ProposalDisplay {
private static final Logger log = LoggerFactory.getLogger(ProposalDisplay.class); private static final Logger log = LoggerFactory.getLogger(ProposalDisplay.class);
@ -35,7 +35,6 @@ public class ProposalDisplay {
private GridPane gridPane; private GridPane gridPane;
public InputTextField nameTextField, titleTextField, categoryTextField, descriptionTextField, linkTextField, public InputTextField nameTextField, titleTextField, categoryTextField, descriptionTextField, linkTextField,
startDateTextField, endDateTextField, requestedBTCTextField, btcAddressTextField; startDateTextField, endDateTextField, requestedBTCTextField, btcAddressTextField;
private TextField phaseTextField;
private int gridRow = 0; private int gridRow = 0;
public ProposalDisplay(GridPane gridPane) { public ProposalDisplay(GridPane gridPane) {
@ -53,10 +52,9 @@ public class ProposalDisplay {
endDateTextField = addLabelInputTextField(gridPane, ++gridRow, "Delivery date:").second; endDateTextField = addLabelInputTextField(gridPane, ++gridRow, "Delivery date:").second;
requestedBTCTextField = addLabelInputTextField(gridPane, ++gridRow, "Requested funds in BTC:").second; requestedBTCTextField = addLabelInputTextField(gridPane, ++gridRow, "Requested funds in BTC:").second;
btcAddressTextField = addLabelInputTextField(gridPane, ++gridRow, "Bitcoin address:").second; btcAddressTextField = addLabelInputTextField(gridPane, ++gridRow, "Bitcoin address:").second;
phaseTextField = addLabelTextField(gridPane, ++gridRow, "Phase:").second;
} }
public void fillWithProposalData(Proposal proposal) { public void fillWithProposalData(ProposalPayload proposal) {
nameTextField.setText(proposal.name); nameTextField.setText(proposal.name);
titleTextField.setText(proposal.title); titleTextField.setText(proposal.title);
categoryTextField.setText(proposal.category); categoryTextField.setText(proposal.category);
@ -66,7 +64,6 @@ public class ProposalDisplay {
endDateTextField.setText(proposal.endDate.toString()); endDateTextField.setText(proposal.endDate.toString());
requestedBTCTextField.setText(proposal.requestedBtc.toPlainString()); requestedBTCTextField.setText(proposal.requestedBtc.toPlainString());
btcAddressTextField.setText(proposal.btcAddress.toString()); btcAddressTextField.setText(proposal.btcAddress.toString());
phaseTextField.setText(proposal.getPhase().name());
} }
public void clearForm() { public void clearForm() {
@ -79,7 +76,6 @@ public class ProposalDisplay {
endDateTextField.setText(""); endDateTextField.setText("");
requestedBTCTextField.setText(""); requestedBTCTextField.setText("");
btcAddressTextField.setText(""); btcAddressTextField.setText("");
phaseTextField.setText("");
} }
public void fillWithMock() { public void fillWithMock() {

View File

@ -174,20 +174,22 @@ public class ActiveProposalsView extends ActivatableView<SplitPane, Void> {
} }
proposalDisplay.removeAllFields(); proposalDisplay.removeAllFields();
proposalDisplay.createAllFields(); proposalDisplay.createAllFields();
proposal.setPhase(Proposal.Phase.OPEN_FOR_FUNDING);
proposal.setAccepted(true);
if (proposal.getPhase() == Proposal.Phase.NEW) {
} else if (proposal.getPhase() == Proposal.Phase.OPEN_FOR_VOTING) { //TODO
proposal.setInVotePeriod(true);
if (proposal.isWaitingForVotingPeriod()) {
addLabel(gridPane, proposalDisplay.incrementAndGetGridRow(), "This proposal is not open anymore for funding. Please wait until the next funding period starts.");
} else if (proposal.isInVotePeriod()) {
voteButton = addButtonAfterGroup(gridPane, proposalDisplay.incrementAndGetGridRow(), "Vote on proposal"); voteButton = addButtonAfterGroup(gridPane, proposalDisplay.incrementAndGetGridRow(), "Vote on proposal");
voteButton.setOnAction(event -> { voteButton.setOnAction(event -> {
navigation.navigateTo(MainView.class, DaoView.class, VotingView.class, VotingDashboardView.class); navigation.navigateTo(MainView.class, DaoView.class, VotingView.class, VotingDashboardView.class);
}); });
} else if (proposal.getPhase() == Proposal.Phase.OPEN_FOR_FUNDING) { } else if (proposal.isInFundingPeriod()) {
checkArgument(proposal.isAccepted(), "A proposal with state OPEN_FOR_FUNDING must be accepted."); checkArgument(proposal.isAccepted(), "A proposal with state OPEN_FOR_FUNDING must be accepted.");
fundButton = addButtonAfterGroup(gridPane, proposalDisplay.incrementAndGetGridRow(), "Fund proposal"); fundButton = addButtonAfterGroup(gridPane, proposalDisplay.incrementAndGetGridRow(), "Fund proposal");
fundButton.setOnAction(event -> { fundButton.setOnAction(event -> {
fundProposalWindow.applyProposal(proposal). fundProposalWindow.applyProposal(proposal.getProposalPayload()).
onAction(() -> { onAction(() -> {
Coin amount = btcFormatter.parseToCoin(fundProposalWindow.getAmount().getText()); Coin amount = btcFormatter.parseToCoin(fundProposalWindow.getAmount().getText());
proposalManager.fundProposal(proposal, amount, proposalManager.fundProposal(proposal, amount,
@ -205,12 +207,12 @@ public class ActiveProposalsView extends ActivatableView<SplitPane, Void> {
}); });
}).show(); }).show();
}); });
} else if (proposal.getPhase() == Proposal.Phase.CLOSED) { } else if (proposal.isClosed()) {
addLabel(gridPane, proposalDisplay.incrementAndGetGridRow(), "This proposal is not open anymore for funding. Please wait until the next funding period starts."); addLabel(gridPane, proposalDisplay.incrementAndGetGridRow(), "This proposal is not open anymore for funding. Please wait until the next funding period starts.");
} }
proposalDisplay.setAllFieldsEditable(false); proposalDisplay.setAllFieldsEditable(false);
proposalDisplay.fillWithProposalData(proposal); proposalDisplay.fillWithProposalData(proposal.getProposalPayload());
} }
} }
@ -233,14 +235,14 @@ public class ActiveProposalsView extends ActivatableView<SplitPane, Void> {
public void updateItem(final Proposal item, boolean empty) { public void updateItem(final Proposal item, boolean empty) {
super.updateItem(item, empty); super.updateItem(item, empty);
if (item != null) if (item != null)
setText(formatter.formatDateTime(item.creationDate)); setText(formatter.formatDateTime(item.getProposalPayload().creationDate));
else else
setText(""); setText("");
} }
}; };
} }
}); });
dateColumn.setComparator((o1, o2) -> o1.creationDate.compareTo(o2.creationDate)); dateColumn.setComparator((o1, o2) -> o1.getProposalPayload().creationDate.compareTo(o2.getProposalPayload().creationDate));
tableView.getColumns().add(dateColumn); tableView.getColumns().add(dateColumn);
tableView.getSortOrder().add(dateColumn); tableView.getSortOrder().add(dateColumn);
@ -258,14 +260,14 @@ public class ActiveProposalsView extends ActivatableView<SplitPane, Void> {
public void updateItem(final Proposal item, boolean empty) { public void updateItem(final Proposal item, boolean empty) {
super.updateItem(item, empty); super.updateItem(item, empty);
if (item != null) if (item != null)
setText(item.name); setText(item.getProposalPayload().name);
else else
setText(""); setText("");
} }
}; };
} }
}); });
nameColumn.setComparator((o1, o2) -> o1.name.compareTo(o2.name)); nameColumn.setComparator((o1, o2) -> o1.getProposalPayload().name.compareTo(o2.getProposalPayload().name));
tableView.getColumns().add(nameColumn); tableView.getColumns().add(nameColumn);
} }
} }

View File

@ -17,7 +17,7 @@
package io.bitsquare.gui.main.dao.proposals.active; package io.bitsquare.gui.main.dao.proposals.active;
import io.bitsquare.dao.proposals.Proposal; import io.bitsquare.dao.proposals.ProposalPayload;
import io.bitsquare.gui.components.InputTextField; import io.bitsquare.gui.components.InputTextField;
import io.bitsquare.gui.main.overlays.Overlay; import io.bitsquare.gui.main.overlays.Overlay;
import javafx.scene.Scene; import javafx.scene.Scene;
@ -33,7 +33,7 @@ import static io.bitsquare.gui.util.FormBuilder.addLabelTextField;
public class FundProposalWindow extends Overlay<FundProposalWindow> { public class FundProposalWindow extends Overlay<FundProposalWindow> {
private static final Logger log = LoggerFactory.getLogger(FundProposalWindow.class); private static final Logger log = LoggerFactory.getLogger(FundProposalWindow.class);
private Proposal proposal; private ProposalPayload proposal;
private InputTextField amount; private InputTextField amount;
private TextField info; private TextField info;
@ -76,7 +76,7 @@ public class FundProposalWindow extends Overlay<FundProposalWindow> {
} }
} }
public FundProposalWindow applyProposal(Proposal proposal) { public FundProposalWindow applyProposal(ProposalPayload proposal) {
this.proposal = proposal; this.proposal = proposal;
return this; return this;
} }
@ -89,7 +89,7 @@ public class FundProposalWindow extends Overlay<FundProposalWindow> {
info = addLabelTextField(gridPane, ++rowIndex, "Proposal ID:").second; info = addLabelTextField(gridPane, ++rowIndex, "Proposal ID:").second;
amount = addLabelInputTextField(gridPane, ++rowIndex, "Amount in BTC:").second; amount = addLabelInputTextField(gridPane, ++rowIndex, "Amount in BTC:").second;
info.setText(proposal.shortId()); info.setText(proposal.getShortId());
} }
@Override @Override

View File

@ -27,8 +27,8 @@ import io.bitsquare.btc.wallet.ChangeBelowDustException;
import io.bitsquare.btc.wallet.SquWalletService; import io.bitsquare.btc.wallet.SquWalletService;
import io.bitsquare.common.ByteArrayUtils; import io.bitsquare.common.ByteArrayUtils;
import io.bitsquare.common.crypto.KeyRing; import io.bitsquare.common.crypto.KeyRing;
import io.bitsquare.dao.proposals.Proposal;
import io.bitsquare.dao.proposals.ProposalManager; import io.bitsquare.dao.proposals.ProposalManager;
import io.bitsquare.dao.proposals.ProposalPayload;
import io.bitsquare.gui.common.view.ActivatableView; import io.bitsquare.gui.common.view.ActivatableView;
import io.bitsquare.gui.common.view.FxmlView; import io.bitsquare.gui.common.view.FxmlView;
import io.bitsquare.gui.main.dao.proposals.ProposalDisplay; import io.bitsquare.gui.main.dao.proposals.ProposalDisplay;
@ -60,7 +60,7 @@ public class CreateProposalView extends ActivatableView<GridPane, Void> {
private ProposalDisplay proposalDisplay; private ProposalDisplay proposalDisplay;
private Button createButton; private Button createButton;
private final NodeAddress nodeAddress; private final NodeAddress nodeAddress;
private final PublicKey p2pStorageSignaturePubKey; private final PublicKey p2pStorageSignaturePubKey;
private final SquWalletService squWalletService; private final SquWalletService squWalletService;
@ -106,7 +106,7 @@ public class CreateProposalView extends ActivatableView<GridPane, Void> {
Date startDate = new Date(); Date startDate = new Date();
Date endDate = new Date(); Date endDate = new Date();
Proposal proposal = new Proposal(UUID.randomUUID().toString(), ProposalPayload proposalPayload = new ProposalPayload(UUID.randomUUID().toString(),
proposalDisplay.nameTextField.getText(), proposalDisplay.nameTextField.getText(),
proposalDisplay.titleTextField.getText(), proposalDisplay.titleTextField.getText(),
proposalDisplay.categoryTextField.getText(), proposalDisplay.categoryTextField.getText(),
@ -120,10 +120,10 @@ public class CreateProposalView extends ActivatableView<GridPane, Void> {
p2pStorageSignaturePubKey, p2pStorageSignaturePubKey,
squKeyPair.getPubKey() squKeyPair.getPubKey()
); );
Sha256Hash hash = Sha256Hash.of(ByteArrayUtils.objectToByteArray(proposal)); Sha256Hash hash = Sha256Hash.of(ByteArrayUtils.objectToByteArray(proposalPayload));
proposal.setSignature(squKeyPair.sign(hash).encodeToDER()); proposalPayload.setSignature(squKeyPair.sign(hash).encodeToDER());
hash = Sha256Hash.of(ByteArrayUtils.objectToByteArray(proposal)); hash = Sha256Hash.of(ByteArrayUtils.objectToByteArray(proposalPayload));
proposal.setHash(hash.getBytes()); proposalPayload.setHash(hash.getBytes());
try { try {
Coin createProposalFee = feeService.getCreateProposalFee(); Coin createProposalFee = feeService.getCreateProposalFee();
@ -133,10 +133,10 @@ public class CreateProposalView extends ActivatableView<GridPane, Void> {
@Override @Override
public void onSuccess(@Nullable Transaction transaction) { public void onSuccess(@Nullable Transaction transaction) {
checkNotNull(transaction, "Transaction must not be null at signAndBroadcastProposalFeeTx callback."); checkNotNull(transaction, "Transaction must not be null at signAndBroadcastProposalFeeTx callback.");
proposal.setFeeTxId(transaction.getHashAsString()); proposalPayload.setFeeTxId(transaction.getHashAsString());
publishToP2PNetwork(proposal); publishToP2PNetwork(proposalPayload);
proposalDisplay.clearForm(); proposalDisplay.clearForm();
new Popup<>().confirmation("Your proposal has been successfully published.").show(); new Popup<>().confirmation("Your proposalPayload has been successfully published.").show();
} }
@Override @Override
@ -154,8 +154,8 @@ public class CreateProposalView extends ActivatableView<GridPane, Void> {
}); });
} }
private void publishToP2PNetwork(Proposal proposal) { private void publishToP2PNetwork(ProposalPayload proposalPayload) {
proposalManager.addToP2PNetwork(proposal); proposalManager.addToP2PNetwork(proposalPayload);
} }
@Override @Override