mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-13 18:55:52 +00:00
In UTXO property scriptBytes changed to class Script.
Property addressType deleted. FullPrunedBlockChain code re-formatted, changed UTXO class usage.
This commit is contained in:
parent
4e8f1bb153
commit
bee1873e1a
@ -47,7 +47,9 @@ import static com.google.common.base.Preconditions.checkState;
|
|||||||
public class FullPrunedBlockChain extends AbstractBlockChain {
|
public class FullPrunedBlockChain extends AbstractBlockChain {
|
||||||
private static final Logger log = LoggerFactory.getLogger(FullPrunedBlockChain.class);
|
private static final Logger log = LoggerFactory.getLogger(FullPrunedBlockChain.class);
|
||||||
|
|
||||||
/** Keeps a map of block hashes to StoredBlocks. */
|
/**
|
||||||
|
* Keeps a map of block hashes to StoredBlocks.
|
||||||
|
*/
|
||||||
protected final FullPrunedBlockStore blockStore;
|
protected final FullPrunedBlockStore blockStore;
|
||||||
|
|
||||||
// Whether or not to execute scriptPubKeys before accepting a transaction (i.e. check signatures).
|
// Whether or not to execute scriptPubKeys before accepting a transaction (i.e. check signatures).
|
||||||
@ -70,12 +72,16 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
this(Context.getOrCreate(params), wallet, blockStore);
|
this(Context.getOrCreate(params), wallet, blockStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Constructs a block chain connected to the given store. */
|
/**
|
||||||
|
* Constructs a block chain connected to the given store.
|
||||||
|
*/
|
||||||
public FullPrunedBlockChain(Context context, FullPrunedBlockStore blockStore) throws BlockStoreException {
|
public FullPrunedBlockChain(Context context, FullPrunedBlockStore blockStore) throws BlockStoreException {
|
||||||
this(context, new ArrayList<BlockChainListener>(), blockStore);
|
this(context, new ArrayList<BlockChainListener>(), blockStore);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link #FullPrunedBlockChain(Context, Wallet, FullPrunedBlockStore)} */
|
/**
|
||||||
|
* See {@link #FullPrunedBlockChain(Context, Wallet, FullPrunedBlockStore)}
|
||||||
|
*/
|
||||||
public FullPrunedBlockChain(NetworkParameters params, FullPrunedBlockStore blockStore) throws BlockStoreException {
|
public FullPrunedBlockChain(NetworkParameters params, FullPrunedBlockStore blockStore) throws BlockStoreException {
|
||||||
this(Context.getOrCreate(params), blockStore);
|
this(Context.getOrCreate(params), blockStore);
|
||||||
}
|
}
|
||||||
@ -90,7 +96,9 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
this.chainHead = blockStore.getVerifiedChainHead();
|
this.chainHead = blockStore.getVerifiedChainHead();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** See {@link #FullPrunedBlockChain(Context, List, FullPrunedBlockStore)} */
|
/**
|
||||||
|
* See {@link #FullPrunedBlockChain(Context, List, FullPrunedBlockStore)}
|
||||||
|
*/
|
||||||
public FullPrunedBlockChain(NetworkParameters params, List<BlockChainListener> listeners,
|
public FullPrunedBlockChain(NetworkParameters params, List<BlockChainListener> listeners,
|
||||||
FullPrunedBlockStore blockStore) throws BlockStoreException {
|
FullPrunedBlockStore blockStore) throws BlockStoreException {
|
||||||
this(Context.getOrCreate(params), listeners, blockStore);
|
this(Context.getOrCreate(params), listeners, blockStore);
|
||||||
@ -133,26 +141,30 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
this.runScripts = value;
|
this.runScripts = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: Remove lots of duplicated code in the two connectTransactions
|
// TODO: Remove lots of duplicated code in the two connectTransactions
|
||||||
|
|
||||||
// TODO: execute in order of largest transaction (by input count) first
|
// TODO: execute in order of largest transaction (by input count) first
|
||||||
ExecutorService scriptVerificationExecutor = Executors.newFixedThreadPool(
|
ExecutorService scriptVerificationExecutor = Executors.newFixedThreadPool(
|
||||||
Runtime.getRuntime().availableProcessors(), new ContextPropagatingThreadFactory("Script verification"));
|
Runtime.getRuntime().availableProcessors(), new ContextPropagatingThreadFactory("Script verification"));
|
||||||
|
|
||||||
/** A job submitted to the executor which verifies signatures. */
|
/**
|
||||||
|
* A job submitted to the executor which verifies signatures.
|
||||||
|
*/
|
||||||
private static class Verifier implements Callable<VerificationException> {
|
private static class Verifier implements Callable<VerificationException> {
|
||||||
final Transaction tx;
|
final Transaction tx;
|
||||||
final List<Script> prevOutScripts;
|
final List<Script> prevOutScripts;
|
||||||
final Set<VerifyFlag> verifyFlags;
|
final Set<VerifyFlag> verifyFlags;
|
||||||
|
|
||||||
public Verifier(final Transaction tx, final List<Script> prevOutScripts, final Set<VerifyFlag> verifyFlags) {
|
public Verifier(final Transaction tx, final List<Script> prevOutScripts, final Set<VerifyFlag> verifyFlags) {
|
||||||
this.tx = tx; this.prevOutScripts = prevOutScripts; this.verifyFlags = verifyFlags;
|
this.tx = tx;
|
||||||
|
this.prevOutScripts = prevOutScripts;
|
||||||
|
this.verifyFlags = verifyFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@Override
|
@Override
|
||||||
public VerificationException call() throws Exception {
|
public VerificationException call() throws Exception {
|
||||||
try{
|
try {
|
||||||
ListIterator<Script> prevOutIt = prevOutScripts.listIterator();
|
ListIterator<Script> prevOutIt = prevOutScripts.listIterator();
|
||||||
for (int index = 0; index < tx.getInputs().size(); index++) {
|
for (int index = 0; index < tx.getInputs().size(); index++) {
|
||||||
tx.getInputs().get(index).getScriptSig().correctlySpends(tx, index, prevOutIt.next(), verifyFlags);
|
tx.getInputs().get(index).getScriptSig().correctlySpends(tx, index, prevOutIt.next(), verifyFlags);
|
||||||
@ -164,18 +176,20 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the {@link Script} from the script bytes or null if it doesn't parse. */
|
/**
|
||||||
@Nullable
|
* Get the {@link Script} from the script bytes or null if it doesn't parse.
|
||||||
|
*/
|
||||||
private Script getScript(byte[] scriptBytes) {
|
private Script getScript(byte[] scriptBytes) {
|
||||||
try {
|
try {
|
||||||
return new Script(scriptBytes);
|
return new Script(scriptBytes);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
return null;
|
return new Script(new byte[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the address from the {@link Script} if it exists otherwise return empty string "".
|
* Get the address from the {@link Script} if it exists otherwise return empty string "".
|
||||||
|
*
|
||||||
* @param script The script.
|
* @param script The script.
|
||||||
* @return The address.
|
* @return The address.
|
||||||
*/
|
*/
|
||||||
@ -190,18 +204,6 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the {@link Script.ScriptType} of this script.
|
|
||||||
* @param script The script.
|
|
||||||
* @return The script type.
|
|
||||||
*/
|
|
||||||
private Script.ScriptType getScriptType(@Nullable Script script) {
|
|
||||||
if (script != null) {
|
|
||||||
return script.getScriptType();
|
|
||||||
}
|
|
||||||
return Script.ScriptType.NO_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected TransactionOutputChanges connectTransactions(int height, Block block)
|
protected TransactionOutputChanges connectTransactions(int height, Block block)
|
||||||
throws VerificationException, BlockStoreException {
|
throws VerificationException, BlockStoreException {
|
||||||
@ -266,16 +268,13 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
// TODO: Check we're not spending the genesis transaction here. Satoshis code won't allow it.
|
// TODO: Check we're not spending the genesis transaction here. Satoshis code won't allow it.
|
||||||
valueIn = valueIn.add(prevOut.getValue());
|
valueIn = valueIn.add(prevOut.getValue());
|
||||||
if (verifyFlags.contains(VerifyFlag.P2SH)) {
|
if (verifyFlags.contains(VerifyFlag.P2SH)) {
|
||||||
if (new Script(prevOut.getScriptBytes()).isPayToScriptHash())
|
if (prevOut.getScript().isPayToScriptHash())
|
||||||
sigOps += Script.getP2SHSigOpCount(in.getScriptBytes());
|
sigOps += Script.getP2SHSigOpCount(in.getScriptBytes());
|
||||||
if (sigOps > Block.MAX_BLOCK_SIGOPS)
|
if (sigOps > Block.MAX_BLOCK_SIGOPS)
|
||||||
throw new VerificationException("Too many P2SH SigOps in block");
|
throw new VerificationException("Too many P2SH SigOps in block");
|
||||||
}
|
}
|
||||||
|
|
||||||
prevOutScripts.add(new Script(prevOut.getScriptBytes()));
|
prevOutScripts.add(prevOut.getScript());
|
||||||
|
|
||||||
//in.getScriptSig().correctlySpends(tx, index, new Script(params, prevOut.getScriptBytes(), 0, prevOut.getScriptBytes().length));
|
|
||||||
|
|
||||||
blockStore.removeUnspentTransactionOutput(prevOut);
|
blockStore.removeUnspentTransactionOutput(prevOut);
|
||||||
txOutsSpent.add(prevOut);
|
txOutsSpent.add(prevOut);
|
||||||
}
|
}
|
||||||
@ -289,9 +288,8 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
out.getIndex(),
|
out.getIndex(),
|
||||||
out.getValue(),
|
out.getValue(),
|
||||||
height, isCoinBase,
|
height, isCoinBase,
|
||||||
out.getScriptBytes(),
|
script,
|
||||||
getScriptAddress(script),
|
getScriptAddress(script));
|
||||||
getScriptType(script).ordinal());
|
|
||||||
blockStore.addUnspentTransactionOutput(newOut);
|
blockStore.addUnspentTransactionOutput(newOut);
|
||||||
txOutsCreated.add(newOut);
|
txOutsCreated.add(newOut);
|
||||||
}
|
}
|
||||||
@ -369,7 +367,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
if (newBlock.getHeader().getTimeSeconds() >= NetworkParameters.BIP16_ENFORCE_TIME)
|
if (newBlock.getHeader().getTimeSeconds() >= NetworkParameters.BIP16_ENFORCE_TIME)
|
||||||
verifyFlags.add(VerifyFlag.P2SH);
|
verifyFlags.add(VerifyFlag.P2SH);
|
||||||
if (!params.isCheckpoint(newBlock.getHeight())) {
|
if (!params.isCheckpoint(newBlock.getHeight())) {
|
||||||
for(Transaction tx : transactions) {
|
for (Transaction tx : transactions) {
|
||||||
Sha256Hash hash = tx.getHash();
|
Sha256Hash hash = tx.getHash();
|
||||||
if (blockStore.hasUnspentOutputs(hash, tx.getOutputs().size()))
|
if (blockStore.hasUnspentOutputs(hash, tx.getOutputs().size()))
|
||||||
throw new VerificationException("Block failed BIP30 test!");
|
throw new VerificationException("Block failed BIP30 test!");
|
||||||
@ -381,7 +379,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
if (scriptVerificationExecutor.isShutdown())
|
if (scriptVerificationExecutor.isShutdown())
|
||||||
scriptVerificationExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
scriptVerificationExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||||
List<Future<VerificationException>> listScriptVerificationResults = new ArrayList<Future<VerificationException>>(transactions.size());
|
List<Future<VerificationException>> listScriptVerificationResults = new ArrayList<Future<VerificationException>>(transactions.size());
|
||||||
for(final Transaction tx : transactions) {
|
for (final Transaction tx : transactions) {
|
||||||
boolean isCoinBase = tx.isCoinBase();
|
boolean isCoinBase = tx.isCoinBase();
|
||||||
Coin valueIn = Coin.ZERO;
|
Coin valueIn = Coin.ZERO;
|
||||||
Coin valueOut = Coin.ZERO;
|
Coin valueOut = Coin.ZERO;
|
||||||
@ -397,14 +395,13 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
throw new VerificationException("Tried to spend coinbase at depth " + (newBlock.getHeight() - prevOut.getHeight()));
|
throw new VerificationException("Tried to spend coinbase at depth " + (newBlock.getHeight() - prevOut.getHeight()));
|
||||||
valueIn = valueIn.add(prevOut.getValue());
|
valueIn = valueIn.add(prevOut.getValue());
|
||||||
if (verifyFlags.contains(VerifyFlag.P2SH)) {
|
if (verifyFlags.contains(VerifyFlag.P2SH)) {
|
||||||
Script script = new Script(prevOut.getScriptBytes());
|
if (prevOut.getScript().isPayToScriptHash())
|
||||||
if (script.isPayToScriptHash())
|
|
||||||
sigOps += Script.getP2SHSigOpCount(in.getScriptBytes());
|
sigOps += Script.getP2SHSigOpCount(in.getScriptBytes());
|
||||||
if (sigOps > Block.MAX_BLOCK_SIGOPS)
|
if (sigOps > Block.MAX_BLOCK_SIGOPS)
|
||||||
throw new VerificationException("Too many P2SH SigOps in block");
|
throw new VerificationException("Too many P2SH SigOps in block");
|
||||||
}
|
}
|
||||||
|
|
||||||
prevOutScripts.add(new Script(prevOut.getScriptBytes()));
|
prevOutScripts.add(prevOut.getScript());
|
||||||
|
|
||||||
blockStore.removeUnspentTransactionOutput(prevOut);
|
blockStore.removeUnspentTransactionOutput(prevOut);
|
||||||
txOutsSpent.add(prevOut);
|
txOutsSpent.add(prevOut);
|
||||||
@ -419,9 +416,8 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
out.getValue(),
|
out.getValue(),
|
||||||
newBlock.getHeight(),
|
newBlock.getHeight(),
|
||||||
isCoinBase,
|
isCoinBase,
|
||||||
out.getScriptBytes(),
|
script,
|
||||||
getScriptAddress(script),
|
getScriptAddress(script));
|
||||||
getScriptType(script).ordinal());
|
|
||||||
blockStore.addUnspentTransactionOutput(newOut);
|
blockStore.addUnspentTransactionOutput(newOut);
|
||||||
txOutsCreated.add(newOut);
|
txOutsCreated.add(newOut);
|
||||||
}
|
}
|
||||||
@ -464,7 +460,7 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
} else {
|
} else {
|
||||||
txOutChanges = block.getTxOutChanges();
|
txOutChanges = block.getTxOutChanges();
|
||||||
if (!params.isCheckpoint(newBlock.getHeight()))
|
if (!params.isCheckpoint(newBlock.getHeight()))
|
||||||
for(UTXO out : txOutChanges.txOutsCreated) {
|
for (UTXO out : txOutChanges.txOutsCreated) {
|
||||||
Sha256Hash hash = out.getHash();
|
Sha256Hash hash = out.getHash();
|
||||||
if (blockStore.getTransactionOutput(hash, out.getIndex()) != null)
|
if (blockStore.getTransactionOutput(hash, out.getIndex()) != null)
|
||||||
throw new VerificationException("Block failed BIP30 test!");
|
throw new VerificationException("Block failed BIP30 test!");
|
||||||
@ -498,9 +494,9 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
StoredUndoableBlock undoBlock = blockStore.getUndoBlock(oldBlock.getHeader().getHash());
|
StoredUndoableBlock undoBlock = blockStore.getUndoBlock(oldBlock.getHeader().getHash());
|
||||||
if (undoBlock == null) throw new PrunedException(oldBlock.getHeader().getHash());
|
if (undoBlock == null) throw new PrunedException(oldBlock.getHeader().getHash());
|
||||||
TransactionOutputChanges txOutChanges = undoBlock.getTxOutChanges();
|
TransactionOutputChanges txOutChanges = undoBlock.getTxOutChanges();
|
||||||
for(UTXO out : txOutChanges.txOutsSpent)
|
for (UTXO out : txOutChanges.txOutsSpent)
|
||||||
blockStore.addUnspentTransactionOutput(out);
|
blockStore.addUnspentTransactionOutput(out);
|
||||||
for(UTXO out : txOutChanges.txOutsCreated)
|
for (UTXO out : txOutChanges.txOutsCreated)
|
||||||
blockStore.removeUnspentTransactionOutput(out);
|
blockStore.removeUnspentTransactionOutput(out);
|
||||||
} catch (PrunedException e) {
|
} catch (PrunedException e) {
|
||||||
blockStore.abortDatabaseBatchWrite();
|
blockStore.abortDatabaseBatchWrite();
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* Copyright 2012 Matt Corallo.
|
* Copyright 2012 Matt Corallo.
|
||||||
*
|
* <p/>
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
* <p/>
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
* <p/>
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.bitcoinj.core;
|
package org.bitcoinj.core;
|
||||||
|
|
||||||
|
import org.bitcoinj.script.Script;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -36,7 +37,7 @@ public class UTXO implements Serializable {
|
|||||||
* this output.
|
* this output.
|
||||||
*/
|
*/
|
||||||
private Coin value;
|
private Coin value;
|
||||||
private byte[] scriptBytes;
|
private Script script;
|
||||||
|
|
||||||
/** Hash of the transaction to which we refer. */
|
/** Hash of the transaction to which we refer. */
|
||||||
private Sha256Hash hash;
|
private Sha256Hash hash;
|
||||||
@ -48,8 +49,6 @@ public class UTXO implements Serializable {
|
|||||||
private boolean coinbase;
|
private boolean coinbase;
|
||||||
/** The address of this output */
|
/** The address of this output */
|
||||||
private String address;
|
private String address;
|
||||||
/** The type of this address */
|
|
||||||
private int addressType;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a stored transaction output.
|
* Creates a stored transaction output.
|
||||||
@ -58,22 +57,20 @@ public class UTXO implements Serializable {
|
|||||||
* @param value The value available.
|
* @param value The value available.
|
||||||
* @param height The height this output was created in.
|
* @param height The height this output was created in.
|
||||||
* @param coinbase The coinbase flag.
|
* @param coinbase The coinbase flag.
|
||||||
* @param scriptBytes The script bytes.
|
|
||||||
*/
|
*/
|
||||||
public UTXO(Sha256Hash hash,
|
public UTXO(Sha256Hash hash,
|
||||||
long index,
|
long index,
|
||||||
Coin value,
|
Coin value,
|
||||||
int height,
|
int height,
|
||||||
boolean coinbase,
|
boolean coinbase,
|
||||||
byte[] scriptBytes) {
|
Script script) {
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.height = height;
|
this.height = height;
|
||||||
this.scriptBytes = scriptBytes;
|
this.script = script;
|
||||||
this.coinbase = coinbase;
|
this.coinbase = coinbase;
|
||||||
this.address = "";
|
this.address = "";
|
||||||
this.addressType = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -83,21 +80,17 @@ public class UTXO implements Serializable {
|
|||||||
* @param value The value available.
|
* @param value The value available.
|
||||||
* @param height The height this output was created in.
|
* @param height The height this output was created in.
|
||||||
* @param coinbase The coinbase flag.
|
* @param coinbase The coinbase flag.
|
||||||
* @param scriptBytes The script bytes.
|
|
||||||
* @param address The address.
|
* @param address The address.
|
||||||
* @param addressType The address type.
|
|
||||||
*/
|
*/
|
||||||
public UTXO(Sha256Hash hash,
|
public UTXO(Sha256Hash hash,
|
||||||
long index,
|
long index,
|
||||||
Coin value,
|
Coin value,
|
||||||
int height,
|
int height,
|
||||||
boolean coinbase,
|
boolean coinbase,
|
||||||
byte[] scriptBytes,
|
Script script,
|
||||||
String address,
|
String address) {
|
||||||
int addressType) {
|
this(hash, index, value, height, coinbase, script);
|
||||||
this(hash, index, value, height, coinbase, scriptBytes);
|
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.addressType = addressType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public UTXO(InputStream in) throws IOException {
|
public UTXO(InputStream in) throws IOException {
|
||||||
@ -110,9 +103,10 @@ public class UTXO implements Serializable {
|
|||||||
((in.read() & 0xFF) << 8) |
|
((in.read() & 0xFF) << 8) |
|
||||||
((in.read() & 0xFF) << 16) |
|
((in.read() & 0xFF) << 16) |
|
||||||
((in.read() & 0xFF) << 24);
|
((in.read() & 0xFF) << 24);
|
||||||
scriptBytes = new byte[scriptBytesLength];
|
byte[] scriptBytes = new byte[scriptBytesLength];
|
||||||
if (in.read(scriptBytes) != scriptBytesLength)
|
if (in.read(scriptBytes) != scriptBytesLength)
|
||||||
throw new EOFException();
|
throw new EOFException();
|
||||||
|
script = new Script(scriptBytes);
|
||||||
|
|
||||||
byte[] hashBytes = new byte[32];
|
byte[] hashBytes = new byte[32];
|
||||||
if (in.read(hashBytes) != 32)
|
if (in.read(hashBytes) != 32)
|
||||||
@ -147,11 +141,11 @@ public class UTXO implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The backing script bytes which can be turned into a Script object.
|
* The Script object which you can use to get address, script bytes or script type.
|
||||||
* @return the scriptBytes.
|
* @return the script.
|
||||||
*/
|
*/
|
||||||
public byte[] getScriptBytes() {
|
public Script getScript() {
|
||||||
return scriptBytes;
|
return script;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -194,14 +188,6 @@ public class UTXO implements Serializable {
|
|||||||
return address;
|
return address;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The type of the address.
|
|
||||||
* @return The address type.
|
|
||||||
*/
|
|
||||||
public int getAddressType() {
|
|
||||||
return addressType;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return String.format("Stored TxOut of %s (%s:%d)", value.toFriendlyString(), hash.toString(), index);
|
return String.format("Stored TxOut of %s (%s:%d)", value.toFriendlyString(), hash.toString(), index);
|
||||||
@ -209,7 +195,7 @@ public class UTXO implements Serializable {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return hash.hashCode() + (int)index;
|
return hash.hashCode() + (int) index;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -224,6 +210,7 @@ public class UTXO implements Serializable {
|
|||||||
public void serializeToStream(OutputStream bos) throws IOException {
|
public void serializeToStream(OutputStream bos) throws IOException {
|
||||||
Utils.uint64ToByteStreamLE(BigInteger.valueOf(value.value), bos);
|
Utils.uint64ToByteStreamLE(BigInteger.valueOf(value.value), bos);
|
||||||
|
|
||||||
|
byte[] scriptBytes = script.getProgram();
|
||||||
bos.write(0xFF & scriptBytes.length >> 0);
|
bos.write(0xFF & scriptBytes.length >> 0);
|
||||||
bos.write(0xFF & scriptBytes.length >> 8);
|
bos.write(0xFF & scriptBytes.length >> 8);
|
||||||
bos.write(0xFF & (scriptBytes.length >> 16));
|
bos.write(0xFF & (scriptBytes.length >> 16));
|
||||||
@ -239,7 +226,7 @@ public class UTXO implements Serializable {
|
|||||||
bos.write(0xFF & (height >> 24));
|
bos.write(0xFF & (height >> 24));
|
||||||
|
|
||||||
byte[] coinbaseByte = new byte[1];
|
byte[] coinbaseByte = new byte[1];
|
||||||
if(coinbase) {
|
if (coinbase) {
|
||||||
coinbaseByte[0] = 1;
|
coinbaseByte[0] = 1;
|
||||||
} else {
|
} else {
|
||||||
coinbaseByte[0] = 0;
|
coinbaseByte[0] = 0;
|
||||||
|
@ -4006,7 +4006,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* @param output The stored output (free standing).
|
* @param output The stored output (free standing).
|
||||||
*/
|
*/
|
||||||
public FreeStandingTransactionOutput(NetworkParameters params, UTXO output, int chainHeight) {
|
public FreeStandingTransactionOutput(NetworkParameters params, UTXO output, int chainHeight) {
|
||||||
super(params, null, output.getValue(), output.getScriptBytes());
|
super(params, null, output.getValue(), output.getScript().getProgram());
|
||||||
this.output = output;
|
this.output = output;
|
||||||
this.chainHeight = chainHeight;
|
this.chainHeight = chainHeight;
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package org.bitcoinj.store;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.bitcoinj.core.*;
|
import org.bitcoinj.core.*;
|
||||||
|
import org.bitcoinj.script.Script;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
@ -929,15 +930,13 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto
|
|||||||
byte[] scriptBytes = results.getBytes(3);
|
byte[] scriptBytes = results.getBytes(3);
|
||||||
boolean coinbase = results.getBoolean(4);
|
boolean coinbase = results.getBoolean(4);
|
||||||
String address = results.getString(5);
|
String address = results.getString(5);
|
||||||
int addressType = results.getInt(6);
|
|
||||||
UTXO txout = new UTXO(hash,
|
UTXO txout = new UTXO(hash,
|
||||||
index,
|
index,
|
||||||
value,
|
value,
|
||||||
height,
|
height,
|
||||||
coinbase,
|
coinbase,
|
||||||
scriptBytes,
|
new Script(scriptBytes),
|
||||||
address,
|
address);
|
||||||
addressType);
|
|
||||||
return txout;
|
return txout;
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
throw new BlockStoreException(ex);
|
throw new BlockStoreException(ex);
|
||||||
@ -963,9 +962,9 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto
|
|||||||
s.setInt(2, (int) out.getIndex());
|
s.setInt(2, (int) out.getIndex());
|
||||||
s.setInt(3, out.getHeight());
|
s.setInt(3, out.getHeight());
|
||||||
s.setLong(4, out.getValue().value);
|
s.setLong(4, out.getValue().value);
|
||||||
s.setBytes(5, out.getScriptBytes());
|
s.setBytes(5, out.getScript().getProgram());
|
||||||
s.setString(6, out.getAddress());
|
s.setString(6, out.getAddress());
|
||||||
s.setInt(7, out.getAddressType());
|
s.setInt(7, out.getScript().getScriptType().ordinal());
|
||||||
s.setBoolean(8, out.isCoinbase());
|
s.setBoolean(8, out.isCoinbase());
|
||||||
s.executeUpdate();
|
s.executeUpdate();
|
||||||
s.close();
|
s.close();
|
||||||
@ -1173,15 +1172,13 @@ public abstract class DatabaseFullPrunedBlockStore implements FullPrunedBlockSto
|
|||||||
int index = rs.getInt(5);
|
int index = rs.getInt(5);
|
||||||
boolean coinbase = rs.getBoolean(6);
|
boolean coinbase = rs.getBoolean(6);
|
||||||
String toAddress = rs.getString(7);
|
String toAddress = rs.getString(7);
|
||||||
int addressType = rs.getInt(8);
|
|
||||||
UTXO output = new UTXO(hash,
|
UTXO output = new UTXO(hash,
|
||||||
index,
|
index,
|
||||||
amount,
|
amount,
|
||||||
height,
|
height,
|
||||||
coinbase,
|
coinbase,
|
||||||
scriptBytes,
|
new Script(scriptBytes),
|
||||||
toAddress,
|
toAddress);
|
||||||
addressType);
|
|
||||||
outputs.add(output);
|
outputs.add(output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user