/******************************************************************************
* Copyright © 2013-2016 The Nxt Core Developers. *
* *
* See the AUTHORS.txt, DEVELOPER-AGREEMENT.txt and LICENSE.txt files at *
* the top-level directory of this distribution for the individual copyright *
* holder information and the developer policies on copyright and licensing. *
* *
* Unless otherwise agreed in a custom licensing agreement, no part of the *
* Nxt software, including this file, may be copied, modified, propagated, *
* or distributed except according to the terms contained in the LICENSE.txt *
* file. *
* *
* Removal or modification of this copyright notice is prohibited. *
* *
******************************************************************************/
package nxt;
import nxt.util.Filter;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
class UnconfirmedTransaction implements Transaction {
private final TransactionImpl transaction;
private final long arrivalTimestamp;
private final long feePerByte;
UnconfirmedTransaction(TransactionImpl transaction, long arrivalTimestamp) {
this.transaction = transaction;
this.arrivalTimestamp = arrivalTimestamp;
this.feePerByte = transaction.getFeeNQT() / transaction.getFullSize();
}
UnconfirmedTransaction(ResultSet rs) throws SQLException {
try {
byte[] transactionBytes = rs.getBytes("transaction_bytes");
JSONObject prunableAttachments = null;
String prunableJSON = rs.getString("prunable_json");
if (prunableJSON != null) {
prunableAttachments = (JSONObject) JSONValue.parse(prunableJSON);
}
TransactionImpl.BuilderImpl builder = TransactionImpl.newTransactionBuilder(transactionBytes, prunableAttachments);
this.transaction = builder.build();
this.transaction.setHeight(rs.getInt("transaction_height"));
this.arrivalTimestamp = rs.getLong("arrival_timestamp");
this.feePerByte = rs.getLong("fee_per_byte");
} catch (NxtException.ValidationException e) {
throw new RuntimeException(e.toString(), e);
}
}
void save(Connection con) throws SQLException {
try (PreparedStatement pstmt = con.prepareStatement("INSERT INTO unconfirmed_transaction (id, transaction_height, "
+ "fee_per_byte, expiration, transaction_bytes, prunable_json, arrival_timestamp, height) "
+ "VALUES (?, ?, ?, ?, ?, ?, ?, ?)")) {
int i = 0;
pstmt.setLong(++i, transaction.getId());
pstmt.setInt(++i, transaction.getHeight());
pstmt.setLong(++i, feePerByte);
pstmt.setInt(++i, transaction.getExpiration());
pstmt.setBytes(++i, transaction.bytes());
JSONObject prunableJSON = transaction.getPrunableAttachmentJSON();
if (prunableJSON != null) {
pstmt.setString(++i, prunableJSON.toJSONString());
} else {
pstmt.setNull(++i, Types.VARCHAR);
}
pstmt.setLong(++i, arrivalTimestamp);
pstmt.setInt(++i, Nxt.getBlockchain().getHeight());
pstmt.executeUpdate();
}
}
TransactionImpl getTransaction() {
return transaction;
}
long getArrivalTimestamp() {
return arrivalTimestamp;
}
long getFeePerByte() {
return feePerByte;
}
@Override
public boolean equals(Object o) {
return o instanceof UnconfirmedTransaction && transaction.equals(((UnconfirmedTransaction)o).getTransaction());
}
@Override
public int hashCode() {
return transaction.hashCode();
}
@Override
public long getId() {
return transaction.getId();
}
@Override
public String getStringId() {
return transaction.getStringId();
}
@Override
public long getSenderId() {
return transaction.getSenderId();
}
@Override
public byte[] getSenderPublicKey() {
return transaction.getSenderPublicKey();
}
@Override
public long getRecipientId() {
return transaction.getRecipientId();
}
@Override
public int getHeight() {
return transaction.getHeight();
}
@Override
public long getBlockId() {
return transaction.getBlockId();
}
@Override
public Block getBlock() {
return transaction.getBlock();
}
@Override
public int getTimestamp() {
return transaction.getTimestamp();
}
@Override
public int getBlockTimestamp() {
return transaction.getBlockTimestamp();
}
@Override
public short getDeadline() {
return transaction.getDeadline();
}
@Override
public int getExpiration() {
return transaction.getExpiration();
}
@Override
public long getAmountNQT() {
return transaction.getAmountNQT();
}
@Override
public long getFeeNQT() {
return transaction.getFeeNQT();
}
@Override
public String getReferencedTransactionFullHash() {
return transaction.getReferencedTransactionFullHash();
}
@Override
public byte[] getSignature() {
return transaction.getSignature();
}
@Override
public String getFullHash() {
return transaction.getFullHash();
}
@Override
public TransactionType getType() {
return transaction.getType();
}
@Override
public Attachment getAttachment() {
return transaction.getAttachment();
}
@Override
public boolean verifySignature() {
return transaction.verifySignature();
}
@Override
public void validate() throws NxtException.ValidationException {
transaction.validate();
}
@Override
public byte[] getBytes() {
return transaction.getBytes();
}
@Override
public byte[] getUnsignedBytes() {
return transaction.getUnsignedBytes();
}
@Override
public JSONObject getJSONObject() {
return transaction.getJSONObject();
}
@Override
public JSONObject getPrunableAttachmentJSON() {
return transaction.getPrunableAttachmentJSON();
}
@Override
public byte getVersion() {
return transaction.getVersion();
}
@Override
public int getFullSize() {
return transaction.getFullSize();
}
@Override
public Appendix.Message getMessage() {
return transaction.getMessage();
}
@Override
public Appendix.PrunablePlainMessage getPrunablePlainMessage() {
return transaction.getPrunablePlainMessage();
}
@Override
public Appendix.EncryptedMessage getEncryptedMessage() {
return transaction.getEncryptedMessage();
}
@Override
public Appendix.PrunableEncryptedMessage getPrunableEncryptedMessage() {
return transaction.getPrunableEncryptedMessage();
}
public Appendix.EncryptToSelfMessage getEncryptToSelfMessage() {
return transaction.getEncryptToSelfMessage();
}
@Override
public Appendix.Phasing getPhasing() {
return transaction.getPhasing();
}
@Override
public List<? extends Appendix> getAppendages() {
return transaction.getAppendages();
}
@Override
public List<? extends Appendix> getAppendages(boolean includeExpiredPrunable) {
return transaction.getAppendages(includeExpiredPrunable);
}
@Override
public List<? extends Appendix> getAppendages(Filter<Appendix> filter, boolean includeExpiredPrunable) {
return transaction.getAppendages(filter, includeExpiredPrunable);
}
@Override
public int getECBlockHeight() {
return transaction.getECBlockHeight();
}
@Override
public long getECBlockId() {
return transaction.getECBlockId();
}
@Override
public short getIndex() {
return transaction.getIndex();
}
}