diff --git a/altchain-plugins/src/main/kotlin/org/veriblock/alt/plugins/ethereum/EthereumFamilyChain.kt b/altchain-plugins/src/main/kotlin/org/veriblock/alt/plugins/ethereum/EthereumFamilyChain.kt index df68a1802..1be879230 100644 --- a/altchain-plugins/src/main/kotlin/org/veriblock/alt/plugins/ethereum/EthereumFamilyChain.kt +++ b/altchain-plugins/src/main/kotlin/org/veriblock/alt/plugins/ethereum/EthereumFamilyChain.kt @@ -325,22 +325,10 @@ class EthereumFamilyChain( } override suspend fun getVbkBlock(hash: String): VbkBlockResponse? { - val response = rpcRequest( + return rpcRequest( method="pop_getVbkBlockByHash", params = listOf(hash), version = "2.0") - - return VbkBlockResponse( - chainWork = response.chainWork, - containingEndorsements = response.containingEndorsements, - endorsedBy = response.endorsedBy, - blockOfProofEndorsements = response.blockOfProofEndorsements, - height = response.height, - header = response.header.toVbkBlock(), - status = response.status, - altrefs = response.altrefs, - stored = StoredInVbkBlockData(response.stored.vtbids) - ) } override suspend fun getVbkBlockHash(height: Int): String? { diff --git a/nodecore-spv/nodecore-spv-standalone/src/main/kotlin/org/veriblock/spv/standalone/commands/SpvCommands.kt b/nodecore-spv/nodecore-spv-standalone/src/main/kotlin/org/veriblock/spv/standalone/commands/SpvCommands.kt index de9845126..38c1e803f 100644 --- a/nodecore-spv/nodecore-spv-standalone/src/main/kotlin/org/veriblock/spv/standalone/commands/SpvCommands.kt +++ b/nodecore-spv/nodecore-spv-standalone/src/main/kotlin/org/veriblock/spv/standalone/commands/SpvCommands.kt @@ -3,7 +3,6 @@ package org.veriblock.spv.standalone.commands import com.google.gson.GsonBuilder import com.google.gson.JsonPrimitive import com.google.gson.JsonSerializer -import kotlinx.coroutines.runBlocking import org.jline.utils.AttributedStyle import org.veriblock.core.WalletException import org.veriblock.core.utilities.Utility @@ -17,7 +16,6 @@ import org.veriblock.shell.command import org.veriblock.shell.core.failure import org.veriblock.shell.core.success import org.veriblock.spv.SpvContext -import org.veriblock.spv.model.Output import org.veriblock.spv.model.asLightAddress fun CommandFactory.spvCommands( diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/SpvContext.kt b/nodecore-spv/src/main/java/org/veriblock/spv/SpvContext.kt index cfe332a60..b14e252ec 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/SpvContext.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/SpvContext.kt @@ -65,7 +65,7 @@ class SpvContext( val addressManager: AddressManager val transactionService: TransactionService val pendingTransactionContainer: PendingTransactionContainer - val pendingTransactionDownloadedListener: PendingTransactionDownloadedListener +// val pendingTransactionDownloadedListener: PendingTransactionDownloadedListener private val addressState: ConcurrentHashMap = ConcurrentHashMap() @@ -96,7 +96,7 @@ class SpvContext( addressManager = AddressManager() val walletFile = File(directory, filePrefix + FILE_EXTENSION) addressManager.load(walletFile) - pendingTransactionDownloadedListener = PendingTransactionDownloadedListener(this) +// pendingTransactionDownloadedListener = PendingTransactionDownloadedListener(this) val externalPeerEndpoints = config.connectDirectlyTo.map { try { diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/model/FullBlock.kt b/nodecore-spv/src/main/java/org/veriblock/spv/model/FullBlock.kt deleted file mode 100644 index a5a1e5dca..000000000 --- a/nodecore-spv/src/main/java/org/veriblock/spv/model/FullBlock.kt +++ /dev/null @@ -1,34 +0,0 @@ -// VeriBlock Blockchain Project -// Copyright 2017-2018 VeriBlock, Inc -// Copyright 2018-2021 Xenios SEZC -// All rights reserved. -// https://www.veriblock.org -// Distributed under the MIT software license, see the accompanying -// file LICENSE or http://www.opensource.org/licenses/mit-license.php. -package org.veriblock.spv.model - -import org.veriblock.core.crypto.PreviousBlockVbkHash -import org.veriblock.core.crypto.PreviousKeystoneVbkHash -import org.veriblock.core.crypto.MerkleRoot -import org.veriblock.core.crypto.TruncatedMerkleRoot -import org.veriblock.sdk.models.VeriBlockBlock - -class FullBlock( - height: Int, - version: Short, - previousBlock: PreviousBlockVbkHash, - previousKeystone: PreviousKeystoneVbkHash, - secondPreviousKeystone: PreviousKeystoneVbkHash, - merkleRoot: TruncatedMerkleRoot, - timestamp: Int, - difficulty: Int, - nonce: Long -) : VeriBlockBlock( - height, version, previousBlock, previousKeystone, secondPreviousKeystone, merkleRoot, timestamp, difficulty, nonce -) { - var normalTransactions: List? = null - - var popTransactions: List? = null - - var metaPackage: BlockMetaPackage? = null -} diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/model/Output.kt b/nodecore-spv/src/main/java/org/veriblock/spv/model/Output.kt deleted file mode 100644 index 7a74168ca..000000000 --- a/nodecore-spv/src/main/java/org/veriblock/spv/model/Output.kt +++ /dev/null @@ -1,38 +0,0 @@ -// VeriBlock Blockchain Project -// Copyright 2017-2018 VeriBlock, Inc -// Copyright 2018-2021 Xenios SEZC -// All rights reserved. -// https://www.veriblock.org -// Distributed under the MIT software license, see the accompanying -// file LICENSE or http://www.opensource.org/licenses/mit-license.php. -package org.veriblock.spv.model - -import org.veriblock.sdk.models.Coin -import org.veriblock.sdk.services.SerializeDeserializeService -import java.io.OutputStream -import java.util.Objects - -class Output( - val address: AddressLight, - val amount: Coin -) { - fun serializeToStream(stream: OutputStream) { - address.serializeToStream(stream) - SerializeDeserializeService.serialize(amount, stream) - } - - override fun equals(other: Any?): Boolean { - if (this === other) { - return true - } - if (other !is Output) { - return false - } - return address == other.address && - amount == other.amount - } - - override fun hashCode(): Int { - return Objects.hash(address, amount) - } -} diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/model/PopTransactionLight.kt b/nodecore-spv/src/main/java/org/veriblock/spv/model/PopTransactionLight.kt deleted file mode 100644 index a728dfad9..000000000 --- a/nodecore-spv/src/main/java/org/veriblock/spv/model/PopTransactionLight.kt +++ /dev/null @@ -1,72 +0,0 @@ -// VeriBlock Blockchain Project -// Copyright 2017-2018 VeriBlock, Inc -// Copyright 2018-2021 Xenios SEZC -// All rights reserved. -// https://www.veriblock.org -// Distributed under the MIT software license, see the accompanying -// file LICENSE or http://www.opensource.org/licenses/mit-license.php. -package org.veriblock.spv.model - -import nodecore.api.grpc.RpcSignedTransaction -import org.veriblock.core.utilities.SerializerUtility -import org.veriblock.sdk.models.BitcoinBlock -import org.veriblock.sdk.models.BitcoinTransaction -import org.veriblock.sdk.models.MerklePath -import org.veriblock.core.crypto.Sha256Hash -import org.veriblock.core.crypto.VbkTxId -import org.veriblock.core.params.NetworkParameters -import org.veriblock.sdk.models.VeriBlockBlock -import org.veriblock.sdk.services.SerializeDeserializeService -import java.io.ByteArrayOutputStream -import java.io.IOException -import java.io.OutputStream -import java.util.ArrayList - -class PopTransactionLight( - txId: VbkTxId, - val endorsedBlock: VeriBlockBlock, - val bitcoinTx: BitcoinTransaction, - val bitcoinMerklePath: MerklePath, - val blockOfProof: BitcoinBlock -) : StandardTransaction(txId) { - private val blockOfProofContext: MutableList = ArrayList() - - fun getContextBitcoinBlocks(): List = - blockOfProofContext - - fun addContextBitcoinBlocks(contextBitcoinBlock: BitcoinBlock) { - blockOfProofContext.add(contextBitcoinBlock) - } - - override fun toByteArray(networkParameters: NetworkParameters): ByteArray { - return calculateHash() - } - - override fun getSignedMessageBuilder(networkParameters: NetworkParameters): RpcSignedTransaction.Builder { - TODO() // SPV-48 - } - - private fun calculateHash(): ByteArray { - ByteArrayOutputStream().use { stream -> - serializeToStream(stream) - return stream.toByteArray() - } - } - - override val transactionTypeIdentifier: TransactionTypeIdentifier - get() = TransactionTypeIdentifier.PROOF_OF_PROOF - - @Throws(IOException::class) - private fun serializeToStream(stream: OutputStream) { - stream.write(transactionTypeIdentifier.id.toInt()) - inputAddress!!.serializeToStream(stream) - SerializeDeserializeService.serialize(endorsedBlock, stream) - SerializeDeserializeService.serialize(bitcoinTx, stream) - SerializeDeserializeService.serialize(bitcoinMerklePath, stream) - SerializeDeserializeService.serialize(blockOfProof, stream) - SerializerUtility.writeVariableLengthValueToStream(stream, getContextBitcoinBlocks().size) - for (block in getContextBitcoinBlocks()) { - SerializeDeserializeService.serialize(block, stream) - } - } -} diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/model/SigningResult.kt b/nodecore-spv/src/main/java/org/veriblock/spv/model/SigningResult.kt index af63be5f2..5d8148ed5 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/model/SigningResult.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/model/SigningResult.kt @@ -7,11 +7,6 @@ package org.veriblock.spv.model class SigningResult( - private val succeeded: Boolean, - val signature: ByteArray?, - val publicKey: ByteArray? -) { - fun succeeded(): Boolean { - return succeeded - } -} + val signature: ByteArray, + val publicKey: ByteArray +) diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/model/StandardTransaction.kt b/nodecore-spv/src/main/java/org/veriblock/spv/model/StandardTransaction.kt index f442cc977..448332ded 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/model/StandardTransaction.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/model/StandardTransaction.kt @@ -20,6 +20,7 @@ import org.veriblock.core.crypto.Sha256Hash import org.veriblock.core.crypto.VbkTxId import org.veriblock.core.crypto.asVbkTxId import org.veriblock.core.params.NetworkParameters +import org.veriblock.sdk.models.VeriBlockTransaction import org.veriblock.sdk.models.asCoin import org.veriblock.sdk.services.SerializeDeserializeService import java.io.ByteArrayOutputStream @@ -29,150 +30,7 @@ import java.util.ArrayList private val logger = createLogger {} -open class StandardTransaction : Transaction { - var inputAmount: Coin? = null - private val outputs: MutableList = ArrayList() - private var signatureIndex: Long = 0 - private var transactionFee: Long = 0 - override var data: ByteArray? = null - - constructor(txId: VbkTxId) : super(txId) - - constructor( - inputAddress: String, - inputAmount: Long, - outputs: List, - signatureIndex: Long, - networkParameters: NetworkParameters - ) : this( - null, inputAddress, inputAmount, outputs, signatureIndex, ByteArray(0), networkParameters - ) - - constructor( - txId: VbkTxId?, - inputAddress: String, - inputAmount: Long, - outputs: List, - signatureIndex: Long, - data: ByteArray?, - networkParameters: NetworkParameters - ) { - var totalOutput = 0L - for (o in outputs) { - totalOutput += o.amount.atomicUnits - } - val fee = inputAmount - totalOutput - - // Only for Alt Chain Endorsement Transactions - this.data = data - this.signatureIndex = signatureIndex - addAllOutput(outputs) - this.inputAmount = inputAmount.asCoin() - this.inputAddress = StandardAddress(inputAddress) - transactionFee = fee - if (txId == null) { - this.txId = calculateTxId(networkParameters) - } else { - this.txId = txId - } - } - - override fun toByteArray(networkParameters: NetworkParameters): ByteArray { - ByteArrayOutputStream().use { stream -> - serializeToStream(stream, networkParameters) - return stream.toByteArray() - } - } - - override fun getSignedMessageBuilder(networkParameters: NetworkParameters): RpcSignedTransaction.Builder { - val transaction = getTransactionMessageBuilder(networkParameters).build() - val builder = RpcSignedTransaction.newBuilder() - builder.transaction = transaction - builder.signatureIndex = signatureIndex - builder.publicKey = ByteString.copyFrom(publicKey) - builder.signature = ByteString.copyFrom(signature) - return builder - } - - private fun getTransactionMessageBuilder(networkParameters: NetworkParameters): RpcTransaction.Builder { - val builder = RpcTransaction.newBuilder() - builder.timestamp = Utility.getCurrentTimeSeconds() - builder.transactionFee = transactionFee - builder.txId = txId.toString().asHexByteString() - if (transactionTypeIdentifier == TransactionTypeIdentifier.STANDARD) { - builder.type = RpcTransaction.Type.STANDARD - } else if (transactionTypeIdentifier == TransactionTypeIdentifier.MULTISIG) { - builder.type = RpcTransaction.Type.MULTISIG - } - builder.sourceAmount = inputAmount!!.atomicUnits - builder.sourceAddress = ByteString.copyFrom(inputAddress!!.toByteArray()) - builder.data = ByteString.copyFrom(data) - builder.size = toByteArray(networkParameters).size - for (output in getOutputs()) { - val outputBuilder = builder.addOutputsBuilder() - outputBuilder.address = ByteString.copyFrom(output.address.toByteArray()) - outputBuilder.amount = output.amount.atomicUnits - } - return builder - } - - @Throws(IOException::class) - private fun serializeToStream(stream: OutputStream, networkParameters: NetworkParameters) { - val magicByte = networkParameters.transactionPrefix - if (magicByte != null) { - stream.write(magicByte.toInt()) - } - - // Write type - stream.write(transactionTypeIdentifier.id.toInt()) - - // Write source address - inputAddress!!.serializeToStream(stream) - - // Write source amount - SerializeDeserializeService.serialize(inputAmount!!, stream) - - // Write destinations - stream.write(getOutputs().size) - for (output in getOutputs()) { - output.serializeToStream(stream) - } - SerializerUtility.writeVariableLengthValueToStream(stream, signatureIndex) - SerializerUtility.writeVariableLengthValueToStream(stream, data) - } - - override fun getOutputs(): List { - return outputs - } - - fun addOutput(o: Output) { - outputs.add(o) - } - - fun addAllOutput(o: Collection) { - outputs.addAll(o) - } - - override fun getSignatureIndex(): Long = - signatureIndex - - fun setSignatureIndex(signatureIndex: Long) { - this.signatureIndex = signatureIndex - } - - override fun getTransactionFee(): Long = - transactionFee - - override val transactionTypeIdentifier: TransactionTypeIdentifier - get() = TransactionTypeIdentifier.STANDARD - - private fun calculateTxId( - networkParameters: NetworkParameters - ): VbkTxId { - return calculateTxIDBytes(toByteArray(networkParameters)).asVbkTxId() - } - - private fun calculateTxIDBytes(rawTx: ByteArray): ByteArray { - return Crypto().SHA256ReturnBytes(rawTx) - } -} +class StandardTransaction( + val tx: VeriBlockTransaction, + val meta: TransactionMeta +) diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/model/Transaction.kt b/nodecore-spv/src/main/java/org/veriblock/spv/model/Transaction.kt deleted file mode 100644 index 93759a4d8..000000000 --- a/nodecore-spv/src/main/java/org/veriblock/spv/model/Transaction.kt +++ /dev/null @@ -1,42 +0,0 @@ -// VeriBlock Blockchain Project -// Copyright 2017-2018 VeriBlock, Inc -// Copyright 2018-2021 Xenios SEZC -// All rights reserved. -// https://www.veriblock.org -// Distributed under the MIT software license, see the accompanying -// file LICENSE or http://www.opensource.org/licenses/mit-license.php. -package org.veriblock.spv.model - -import nodecore.api.grpc.RpcSignedTransaction -import org.veriblock.core.crypto.Sha256Hash -import org.veriblock.core.crypto.VbkTxId -import org.veriblock.core.params.NetworkParameters - -abstract class Transaction { - lateinit var txId: VbkTxId - var inputAddress: AddressLight? = null - var transactionMeta: TransactionMeta? = null - var signature: ByteArray? = null - var publicKey: ByteArray? = null - - constructor() - - constructor(txId: VbkTxId) { - this.txId = txId - transactionMeta = TransactionMeta(txId) - } - - abstract fun getOutputs(): List - abstract fun getSignatureIndex(): Long - abstract fun getTransactionFee(): Long - abstract fun toByteArray(networkParameters: NetworkParameters): ByteArray? - abstract fun getSignedMessageBuilder(networkParameters: NetworkParameters): RpcSignedTransaction.Builder? - - abstract val data: ByteArray? - abstract val transactionTypeIdentifier: TransactionTypeIdentifier - - fun addSignature(signature: ByteArray?, publicKey: ByteArray?) { - this.signature = signature - this.publicKey = publicKey - } -} diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/model/TransactionMeta.kt b/nodecore-spv/src/main/java/org/veriblock/spv/model/TransactionMeta.kt index cc4efe2af..f982d8220 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/model/TransactionMeta.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/model/TransactionMeta.kt @@ -14,9 +14,7 @@ import org.veriblock.spv.util.SpvEventBus import java.util.ArrayList import java.util.HashSet -class TransactionMeta( - val txId: VbkTxId -) { +class TransactionMeta { private val appearsInBlock: MutableList = ArrayList() var appearsAtChainHeight = -1 var depth = 0 diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/model/TransactionPool.kt b/nodecore-spv/src/main/java/org/veriblock/spv/model/TransactionPool.kt index 3d5fe3c5d..39a663b9b 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/model/TransactionPool.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/model/TransactionPool.kt @@ -19,11 +19,10 @@ import kotlin.concurrent.withLock class TransactionPool { private class WeakPoolReference( + val id: VbkTxId, meta: TransactionMeta, queue: ReferenceQueue? - ) : WeakReference(meta, queue) { - var hash: Sha256Hash? = meta.txId - } + ) : WeakReference(meta, queue) private val lock = ReentrantLock(true) private val referenceQueue = ReferenceQueue() @@ -53,20 +52,20 @@ class TransactionPool { return transactionMeta } } - val tx = TransactionMeta(txId) - pool[txId] = WeakPoolReference(tx, referenceQueue) + val tx = TransactionMeta() + pool[txId] = WeakPoolReference(txId, tx, referenceQueue) tx } - fun insert(meta: TransactionMeta) = lock.withLock { - pool[meta.txId] = WeakPoolReference(meta, referenceQueue) + fun insert(id: VbkTxId, meta: TransactionMeta) = lock.withLock { + pool[id] = WeakPoolReference(id, meta, referenceQueue) } private fun purge() = lock.withLock { var reference: Reference? = referenceQueue.poll() while (reference != null) { val txReference = reference as WeakPoolReference - pool.remove(txReference.hash) + pool.remove(txReference.id) reference = referenceQueue.poll() } } diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/net/PeerEventListener.kt b/nodecore-spv/src/main/java/org/veriblock/spv/net/PeerEventListener.kt index 57b2c299f..b24eaf1c4 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/net/PeerEventListener.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/net/PeerEventListener.kt @@ -51,9 +51,7 @@ import org.veriblock.sdk.models.VeriBlockBlock import org.veriblock.sdk.services.SerializeDeserializeService import org.veriblock.spv.SpvContext import org.veriblock.spv.SpvState -import org.veriblock.spv.model.Transaction import org.veriblock.spv.model.TransactionTypeIdentifier -import org.veriblock.spv.serialization.MessageSerializer import org.veriblock.spv.service.Blockchain import org.veriblock.spv.service.NetworkBlock import org.veriblock.spv.service.PendingTransactionContainer diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/serialization/MessageSerializer.kt b/nodecore-spv/src/main/java/org/veriblock/spv/serialization/MessageSerializer.kt deleted file mode 100644 index 7f525509f..000000000 --- a/nodecore-spv/src/main/java/org/veriblock/spv/serialization/MessageSerializer.kt +++ /dev/null @@ -1,147 +0,0 @@ -// VeriBlock Blockchain Project -// Copyright 2017-2018 VeriBlock, Inc -// Copyright 2018-2021 Xenios SEZC -// All rights reserved. -// https://www.veriblock.org -// Distributed under the MIT software license, see the accompanying -// file LICENSE or http://www.opensource.org/licenses/mit-license.php. -package org.veriblock.spv.serialization - -import com.google.protobuf.InvalidProtocolBufferException -import nodecore.api.grpc.RpcBlock -import nodecore.api.grpc.RpcBlockHeader -import nodecore.api.grpc.RpcEvent -import nodecore.api.grpc.RpcSignedMultisigTransaction -import nodecore.api.grpc.RpcSignedTransaction -import nodecore.api.grpc.RpcTransactionUnion -import nodecore.api.grpc.utilities.ByteStringAddressUtility -import nodecore.api.grpc.utilities.ByteStringUtility -import nodecore.api.grpc.utilities.extensions.asVbkPreviousBlockHash -import nodecore.api.grpc.utilities.extensions.asVbkPreviousKeystoneHash -import org.veriblock.core.utilities.createLogger -import org.veriblock.sdk.models.BitcoinTransaction -import org.veriblock.sdk.models.MerklePath -import org.veriblock.core.crypto.asVbkHash -import org.veriblock.core.crypto.asBtcHash -import org.veriblock.core.crypto.asTruncatedMerkleRoot -import org.veriblock.core.crypto.asVbkTxId -import org.veriblock.sdk.models.VeriBlockBlock -import org.veriblock.sdk.models.asCoin -import org.veriblock.sdk.services.SerializeDeserializeService -import org.veriblock.spv.model.BlockMetaPackage -import org.veriblock.spv.model.FullBlock -import org.veriblock.spv.model.MultisigTransaction -import org.veriblock.spv.model.OutputFactory.create -import org.veriblock.spv.model.PopTransactionLight -import org.veriblock.spv.model.StandardTransaction -import org.veriblock.spv.model.asLightAddress - -private val logger = createLogger {} - -object MessageSerializer { - fun deserialize(blockHeaderMessage: RpcBlockHeader, trustHash: Boolean = false): VeriBlockBlock { - return if (trustHash) { - SerializeDeserializeService.parseVeriBlockBlock(blockHeaderMessage.header.toByteArray(), blockHeaderMessage.hash.toByteArray().asVbkHash()) - } else { - SerializeDeserializeService.parseVeriBlockBlock(blockHeaderMessage.header.toByteArray()) - } - } - - @JvmStatic - fun deserializeNormalTransaction(transactionUnionMessage: RpcTransactionUnion): StandardTransaction { - return when (transactionUnionMessage.transactionCase) { - RpcTransactionUnion.TransactionCase.SIGNED -> deserializeStandardTransaction( - transactionUnionMessage.signed - ) - RpcTransactionUnion.TransactionCase.SIGNED_MULTISIG -> deserializeMultisigTransaction( - transactionUnionMessage.signedMultisig - ) - else -> - // Should be impossible - error("Unhandled transaction type: ${transactionUnionMessage.transactionCase}") - } - } - - fun deserializePopTransaction(transactionUnionMessage: RpcTransactionUnion): PopTransactionLight { - val signed = transactionUnionMessage.signed - val txMessage = signed.transaction - val tx = PopTransactionLight( - txId = txMessage.txId.toByteArray().asVbkTxId(), - endorsedBlock = SerializeDeserializeService.parseVeriBlockBlock(txMessage.endorsedBlockHeader.toByteArray()), - bitcoinTx = BitcoinTransaction(txMessage.bitcoinTransaction.toByteArray()), - bitcoinMerklePath = MerklePath(txMessage.merklePath), - blockOfProof = SerializeDeserializeService.parseBitcoinBlock(txMessage.bitcoinBlockHeaderOfProof.header.toByteArray()) - ) - tx.inputAddress = ByteStringAddressUtility.parseProperAddressTypeAutomatically(txMessage.sourceAddress).asLightAddress() - txMessage.contextBitcoinBlockHeadersList.map { - SerializeDeserializeService.parseBitcoinBlock(it.header.toByteArray()) - }.forEach { - tx.addContextBitcoinBlocks(it) - } - return tx - } - - fun deserialize(blockMessage: RpcBlock): FullBlock { - val block = FullBlock( - blockMessage.number, - blockMessage.version.toShort(), - blockMessage.previousHash.asVbkPreviousBlockHash(), - blockMessage.secondPreviousHash.asVbkPreviousKeystoneHash(), - blockMessage.thirdPreviousHash.asVbkPreviousKeystoneHash(), - ByteStringUtility.byteStringToHex(blockMessage.merkleRoot).asTruncatedMerkleRoot(), - blockMessage.timestamp, - blockMessage.encodedDifficulty, - blockMessage.winningNonce - ) - block.normalTransactions = blockMessage.regularTransactionsList.map { - deserializeNormalTransaction(it) - } - block.popTransactions = blockMessage.popTransactionsList.map { - deserializePopTransaction(it) - } - block.metaPackage = BlockMetaPackage( - blockMessage.blockContentMetapackage.hash.toByteArray().asBtcHash() - ) - return block - } - - private fun deserializeStandardTransaction(signedTransaction: RpcSignedTransaction): StandardTransaction { - val txMessage = signedTransaction.transaction - val tx = StandardTransaction(txMessage.txId.toByteArray().asVbkTxId()) - tx.inputAddress = ByteStringAddressUtility.parseProperAddressTypeAutomatically(txMessage.sourceAddress).asLightAddress() - tx.inputAmount = txMessage.sourceAmount.asCoin() - txMessage.outputsList.map { - create(ByteStringAddressUtility.parseProperAddressTypeAutomatically(it.address), it.amount) - }.forEach { - tx.addOutput(it) - } - tx.setSignatureIndex(signedTransaction.signatureIndex) - tx.data = txMessage.data.toByteArray() - return tx - } - - private fun deserializeMultisigTransaction(signedTransaction: RpcSignedMultisigTransaction): StandardTransaction { - val txMessage = signedTransaction.transaction - val tx: StandardTransaction = MultisigTransaction(txMessage.txId.toByteArray().asVbkTxId()) - tx.inputAddress = ByteStringAddressUtility.parseProperAddressTypeAutomatically(txMessage.sourceAddress).asLightAddress() - tx.inputAmount = txMessage.sourceAmount.asCoin() - txMessage.outputsList.map { - create(ByteStringAddressUtility.parseProperAddressTypeAutomatically(it.address), it.amount) - }.forEach { - tx.addOutput(it) - } - tx.setSignatureIndex(signedTransaction.signatureIndex) - tx.data = txMessage.data.toByteArray() - return tx - } - - @JvmStatic - fun deserialize(raw: ByteArray?): RpcEvent? { - try { - return RpcEvent.parseFrom(raw) - } catch (e: InvalidProtocolBufferException) { - logger.error("Unable to parse message", e) - } - return null - } -} diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/service/Model.kt b/nodecore-spv/src/main/java/org/veriblock/spv/service/Model.kt index 24bfb663a..7d0ec3aa7 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/service/Model.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/service/Model.kt @@ -1,15 +1,14 @@ package org.veriblock.spv.service import nodecore.p2p.Peer -import org.veriblock.core.crypto.Sha256Hash import org.veriblock.core.crypto.VbkTxId import org.veriblock.sdk.models.Address import org.veriblock.sdk.models.Coin +import org.veriblock.sdk.models.Output import org.veriblock.sdk.models.VeriBlockBlock +import org.veriblock.sdk.models.VeriBlockTransaction import org.veriblock.spv.model.AddressLight -import org.veriblock.spv.model.Output import org.veriblock.spv.model.StandardTransaction -import org.veriblock.spv.model.Transaction enum class BlockchainState { LOADING, @@ -78,7 +77,7 @@ data class WalletBalance( ) data class AltChainEndorsement( - val transaction: StandardTransaction, + val transaction: VeriBlockTransaction, val signatureIndex: Long ) diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/service/PendingTransactionContainer.kt b/nodecore-spv/src/main/java/org/veriblock/spv/service/PendingTransactionContainer.kt index d98e60f63..212d06b35 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/service/PendingTransactionContainer.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/service/PendingTransactionContainer.kt @@ -12,7 +12,6 @@ import org.veriblock.core.utilities.createLogger import org.veriblock.sdk.models.Address import org.veriblock.sdk.models.VeriBlockBlock import org.veriblock.spv.SpvContext -import org.veriblock.spv.model.Transaction import org.veriblock.spv.util.SpvEventBus import org.veriblock.spv.util.Threading diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/service/SpvService.kt b/nodecore-spv/src/main/java/org/veriblock/spv/service/SpvService.kt index 673500310..666cc3b55 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/service/SpvService.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/service/SpvService.kt @@ -8,22 +8,26 @@ package org.veriblock.spv.service import com.google.protobuf.ByteString -import kotlinx.coroutines.flow.asFlow -import kotlinx.coroutines.flow.map -import kotlinx.coroutines.flow.onEach -import kotlinx.coroutines.flow.toList import nodecore.api.grpc.RpcAdvertiseTransaction import nodecore.api.grpc.RpcBlockHeader -import nodecore.api.grpc.RpcBlockHeadersByHashesRequest -import nodecore.api.grpc.RpcBlockInfo import nodecore.api.grpc.RpcGetVeriBlockPublicationsReply import nodecore.api.grpc.RpcGetVeriBlockPublicationsRequest +import nodecore.api.grpc.RpcGetVtbsForBtcBlocksReply +import nodecore.api.grpc.RpcGetVtbsForBtcBlocksRequest import nodecore.api.grpc.RpcTransactionAnnounce +import nodecore.p2p.PeerCapabilities import nodecore.p2p.PeerTable import nodecore.p2p.buildMessage -import org.veriblock.core.* +import org.veriblock.core.AddressCreationException +import org.veriblock.core.EndorsementCreationException +import org.veriblock.core.ImportException +import org.veriblock.core.SendCoinsException +import org.veriblock.core.WalletException +import org.veriblock.core.WalletLockedException import org.veriblock.core.crypto.AnyVbkHash import org.veriblock.core.crypto.Sha256Hash +import org.veriblock.core.crypto.VbkHash +import org.veriblock.core.crypto.VbkTxId import org.veriblock.core.types.Pair import org.veriblock.core.utilities.createLogger import org.veriblock.core.utilities.debugError @@ -33,6 +37,10 @@ import org.veriblock.core.utilities.extensions.toHex import org.veriblock.core.wallet.AddressManager import org.veriblock.core.wallet.AddressPubKey import org.veriblock.sdk.models.Address +import org.veriblock.sdk.models.FullBlock +import org.veriblock.sdk.models.Output +import org.veriblock.sdk.models.VeriBlockPopTransaction +import org.veriblock.sdk.models.VeriBlockTransaction import org.veriblock.sdk.models.asCoin import org.veriblock.sdk.services.SerializeDeserializeService import org.veriblock.spv.SpvConstants @@ -44,24 +52,14 @@ import org.veriblock.spv.model.BlockHeader import org.veriblock.spv.model.DownloadStatus import org.veriblock.spv.model.DownloadStatusResponse import org.veriblock.spv.model.LedgerContext -import org.veriblock.spv.model.Output -import org.veriblock.spv.model.StandardTransaction import org.veriblock.spv.model.StoredVeriBlockBlock -import org.veriblock.spv.model.Transaction import org.veriblock.spv.model.TransactionTypeIdentifier import org.veriblock.spv.model.asLightAddress import org.veriblock.spv.net.AMOUNT_OF_BLOCKS_WHEN_WE_CAN_START_WORKING import org.veriblock.spv.service.TransactionService.Companion.predictAltChainEndorsementTransactionSize import java.io.File import java.io.IOException -import java.util.* -import nodecore.api.grpc.RpcGetVtbsForBtcBlocksReply -import nodecore.api.grpc.RpcGetVtbsForBtcBlocksRequest -import nodecore.p2p.PeerCapabilities -import org.veriblock.core.crypto.VbkHash -import org.veriblock.core.crypto.VbkTxId -import org.veriblock.sdk.models.FullBlock -import org.veriblock.spv.serialization.MessageSerializer + private val logger = createLogger {} @@ -145,7 +143,7 @@ class SpvService( pendingTransactionContainer.addTransaction(it) peerTable.advertise(it) }.map { - it.txId + it.id }.toList() } @@ -163,7 +161,7 @@ class SpvService( } } - suspend fun submitTransactions(transactions: List) { + suspend fun submitTransactions(transactions: List) { for (transaction in transactions) { pendingTransactionContainer.addTransaction(transaction) peerTable.advertise(transaction) @@ -204,9 +202,8 @@ class SpvService( val privateKeyLength = privateKey[0].toInt() val privateKeyBytes = privateKey.copyOfRange(1, privateKeyLength + 1) val publicKeyBytes = privateKey.copyOfRange(privateKeyLength + 1, privateKey.size) - val importedAddress = addressManager.importKeyPair(publicKeyBytes, privateKeyBytes) + return addressManager.importKeyPair(publicKeyBytes, privateKeyBytes) ?: throw ImportException("The private key ${privateKey.toHex()} is invalid or corrupted!") - return importedAddress } fun encryptWallet(passphrase: String) { @@ -339,7 +336,7 @@ class SpvService( val tx = transactionService.createUnsignedAltChainEndorsementTransaction( sourceAddress.address, fee, publicationData, signatureIndex ) - return AltChainEndorsement((tx as StandardTransaction), signatureIndex) + return AltChainEndorsement(tx, signatureIndex) } catch (e: Exception) { logger.debugWarn(e) { "Failed to create alt chain endorsement" } throw EndorsementCreationException("Failed to create alt chain endorsement") @@ -477,26 +474,18 @@ class SpvService( event = request ) { if (it.block == null) -1 else 1 }.block - val block = MessageSerializer.deserialize(rpcBlock) - logger.warn { block.toString() } - + // TODO(warchant): Deserialize RpcBlock -> FullBlock return null } } -fun PeerTable.advertise(transaction: Transaction) { +private fun PeerTable.advertiseTx(id: ByteArray, type: RpcTransactionAnnounce.Type) { val advertise = buildMessage { advertiseTx = RpcAdvertiseTransaction.newBuilder() .addTransactions( RpcTransactionAnnounce.newBuilder() - .setType( - if (transaction.transactionTypeIdentifier === TransactionTypeIdentifier.PROOF_OF_PROOF) { - RpcTransactionAnnounce.Type.PROOF_OF_PROOF - } else { - RpcTransactionAnnounce.Type.NORMAL - } - ) - .setTxId(ByteString.copyFrom(transaction.txId.bytes)) + .setType(type) + .setTxId(ByteString.copyFrom(id)) .build() ) .build() @@ -509,3 +498,11 @@ fun PeerTable.advertise(transaction: Transaction) { } } } + +fun PeerTable.advertise(transaction: VeriBlockTransaction) { + this.advertiseTx(transaction.id.bytes, RpcTransactionAnnounce.Type.NORMAL) +} + +fun PeerTable.advertise(transaction: VeriBlockPopTransaction) { + this.advertiseTx(transaction.id.bytes, RpcTransactionAnnounce.Type.PROOF_OF_PROOF) +} diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/service/TransactionService.kt b/nodecore-spv/src/main/java/org/veriblock/spv/service/TransactionService.kt index 3605ed1ba..91fdbef24 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/service/TransactionService.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/service/TransactionService.kt @@ -7,8 +7,6 @@ // file LICENSE or http://www.opensource.org/licenses/mit-license.php. package org.veriblock.spv.service -import com.google.protobuf.ByteString -import nodecore.api.grpc.RpcTransaction import org.veriblock.core.types.Pair import org.veriblock.core.utilities.AddressUtility import org.veriblock.core.utilities.Utility @@ -16,12 +14,14 @@ import org.veriblock.sdk.models.Coin import org.veriblock.core.crypto.Sha256Hash import org.veriblock.core.params.NetworkParameters import org.veriblock.core.wallet.AddressManager +import org.veriblock.sdk.models.Address +import org.veriblock.sdk.models.Output +import org.veriblock.sdk.models.VeriBlockPopTransaction +import org.veriblock.sdk.models.VeriBlockTransaction import org.veriblock.sdk.models.asCoin import org.veriblock.spv.model.AddressCoinsIndex -import org.veriblock.spv.model.Output import org.veriblock.spv.model.SigningResult import org.veriblock.spv.model.StandardTransaction -import org.veriblock.spv.model.Transaction import java.util.ArrayList class TransactionService( @@ -46,11 +46,11 @@ class TransactionService( fun createTransactionsByOutputList( addressCoinsIndexList: List, outputList: List - ): List { - val transactions: MutableList = ArrayList() + ): List { + val transactions: MutableList = ArrayList() var sortedOutputs = outputList.sortedBy { it.amount.atomicUnits }.toMutableList() val sortedAddressCoinsIndexList = addressCoinsIndexList.filter { it.coins > 0 }.sortedBy { it.coins } - val totalOutputAmount = sortedOutputs.map { it.amount.atomicUnits }.sum() + val totalOutputAmount = sortedOutputs.sumOf { it.amount.atomicUnits } for (sourceAddressesIndex in sortedAddressCoinsIndexList) { val fee = calculateFee(sourceAddressesIndex.address, totalOutputAmount, sortedOutputs, sourceAddressesIndex.index) val fulfillAndForPay = splitOutPutsAccordingBalance( @@ -117,7 +117,7 @@ class TransactionService( inputAmount: Long, outputs: List, signatureIndex: Long - ): Transaction { + ): VeriBlockTransaction { require(AddressUtility.isValidStandardAddress(inputAddress)) { "createStandardTransaction cannot be called with an invalid inputAddress ($inputAddress)!" } @@ -137,10 +137,20 @@ class TransactionService( "createStandardTransaction cannot be called with an output total which is larger than the inputAmount" + " (outputTotal = $outputTotal, inputAmount = $inputAmount)!" } - val transaction: Transaction = StandardTransaction(inputAddress, inputAmount, outputs, signatureIndex, networkParameters) - val signingResult = signTransaction(transaction.txId, inputAddress) - if (signingResult.succeeded()) { - transaction.addSignature(signingResult.signature, signingResult.publicKey) + val transaction = VeriBlockTransaction( + networkByte=networkParameters.transactionPrefix, + sourceAddress = Address(inputAddress), + sourceAmount = Coin(inputAmount), + outputs = outputs, + signatureIndex = signatureIndex, + signature = ByteArray(0), + publicKey = ByteArray(0), + publicationData = null + ) + val signingResult = signTransaction(transaction.id, inputAddress) + if (signingResult != null) { + transaction.signature = signingResult.signature + transaction.publicKey = signingResult.publicKey } return transaction } @@ -148,13 +158,14 @@ class TransactionService( // TODO(warchant): use Address instead of String for all addresses fun createUnsignedAltChainEndorsementTransaction( inputAddress: String, fee: Long, publicationData: ByteArray?, signatureIndex: Long - ): Transaction { + ): VeriBlockTransaction { require(AddressUtility.isValidStandardAddress(inputAddress)) { "createAltChainEndorsementTransaction cannot be called with an invalid inputAddress ($inputAddress)!" } require(Utility.isPositive(fee)) { "createAltChainEndorsementTransaction cannot be called with a non-positiveinputAmount ($fee)!" } + return VeriBlockTransaction() return StandardTransaction(null, inputAddress, fee, emptyList(), signatureIndex, publicationData, networkParameters) } @@ -191,12 +202,12 @@ class TransactionService( return totalSize } - fun signTransaction(txId: Sha256Hash, address: String): SigningResult { + fun signTransaction(txId: Sha256Hash, address: String): SigningResult? { val signature = addressManager.signMessage(txId.bytes, address) - ?: return SigningResult(false, null, null) + ?: return null val publicKey = addressManager.getPublicKeyForAddress(address) - ?: return SigningResult(false, null, null) - return SigningResult(true, signature, publicKey.encoded) + ?: return null + return SigningResult(signature, publicKey.encoded) } companion object { @@ -225,25 +236,6 @@ class TransactionService( totalSize += dataLength return totalSize } - - @JvmStatic - fun getRegularTransactionMessageBuilder(tx: StandardTransaction): RpcTransaction.Builder { - val builder = RpcTransaction.newBuilder() - builder.transactionFee = tx.getTransactionFee() - builder.txId = ByteString.copyFrom(tx.txId.bytes) - builder.type = RpcTransaction.Type.STANDARD - builder.sourceAmount = tx.inputAmount!!.atomicUnits - builder.sourceAddress = ByteString.copyFrom(tx.inputAddress!!.toByteArray()) - builder.data = ByteString.copyFrom(tx.data) - // builder.setTimestamp(getTimeStamp()); - // builder.setSize(tx.getSize()); - for (output in tx.getOutputs()) { - val outputBuilder = builder.addOutputsBuilder() - outputBuilder.address = ByteString.copyFrom(output.address.toByteArray()) - outputBuilder.amount = output.amount.atomicUnits - } - return builder - } } } diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/service/task/PendingTransactionsUpdateTask.kt b/nodecore-spv/src/main/java/org/veriblock/spv/service/task/PendingTransactionsUpdateTask.kt index b0e698ac4..bf40cb98b 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/service/task/PendingTransactionsUpdateTask.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/service/task/PendingTransactionsUpdateTask.kt @@ -50,7 +50,7 @@ suspend fun SpvContext.requestPendingTransactions() { } else { val transaction = pendingTransactionContainer.getTransaction(txId) if (transaction != null) { - peerTable.advertise(transaction) + peerTable.advertise(transaction.) } } } catch (e: Exception) { diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/wallet/Ledger.kt b/nodecore-spv/src/main/java/org/veriblock/spv/wallet/Ledger.kt index 26706b093..6105b6767 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/wallet/Ledger.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/wallet/Ledger.kt @@ -8,11 +8,11 @@ package org.veriblock.spv.wallet import org.veriblock.sdk.models.Coin +import org.veriblock.sdk.models.VeriBlockTransaction import org.veriblock.spv.model.StandardTransaction import org.veriblock.spv.model.TransactionMeta import java.util.ArrayList import java.util.HashMap -import java.util.function.Consumer class Ledger { private val entries: MutableMap = HashMap() @@ -52,21 +52,21 @@ class Ledger { private fun createLedgerEntriesFrom(tx: StandardTransaction): List { val ledgerEntries = ArrayList() - val status = if (tx.transactionMeta!!.state === TransactionMeta.MetaState.CONFIRMED) { + val status = if (tx.meta.state === TransactionMeta.MetaState.CONFIRMED) { LedgerEntry.Status.CONFIRMED } else { LedgerEntry.Status.PENDING } - if (entries.containsKey(tx.inputAddress!!.get())) { + if (entries.containsKey(tx.tx.sourceAddress.address)) { ledgerEntries.add( - LedgerEntry(tx.inputAddress!!.get(), tx.txId, tx.inputAmount!!, Coin.ZERO, tx.getSignatureIndex(), 0, status) + LedgerEntry(tx.tx.sourceAddress.address, tx.tx.id, tx.tx.sourceAmount, Coin.ZERO, tx.tx.signatureIndex, 0, status) ) } - for (i in tx.getOutputs().indices) { - val o = tx.getOutputs()[i] - if (entries.containsKey(o.address.get())) { + for (i in tx.tx.outputs.indices) { + val o = tx.tx.outputs[i] + if (entries.containsKey(o.address.address)) { ledgerEntries.add( - LedgerEntry(o.address.get(), tx.txId, Coin.ZERO, o.amount, -1, i, status) + LedgerEntry(o.address.address, tx.tx.id, Coin.ZERO, o.amount, -1, i, status) ) } } diff --git a/nodecore-spv/src/main/java/org/veriblock/spv/wallet/PendingTransactionDownloadedListener.kt b/nodecore-spv/src/main/java/org/veriblock/spv/wallet/PendingTransactionDownloadedListener.kt index 14c16699f..602e5d458 100644 --- a/nodecore-spv/src/main/java/org/veriblock/spv/wallet/PendingTransactionDownloadedListener.kt +++ b/nodecore-spv/src/main/java/org/veriblock/spv/wallet/PendingTransactionDownloadedListener.kt @@ -18,17 +18,17 @@ class PendingTransactionDownloadedListener( fun loadTransactions(toLoad: List) { for (tx in toLoad) { - transactions[tx.txId] = tx - spvContext.transactionPool.insert(tx.transactionMeta!!) + transactions[tx.tx.id] = tx + spvContext.transactionPool.insert(tx.tx.id, tx.meta) } } fun commitTx(tx: StandardTransaction) = lock.withLock { - if (transactions.containsKey(tx.txId)) { + if (transactions.containsKey(tx.tx.id)) { return } - tx.transactionMeta!!.setState(TransactionMeta.MetaState.PENDING) - transactions[tx.txId] = tx + tx.meta.setState(TransactionMeta.MetaState.PENDING) + transactions[tx.tx.id] = tx ledger.record(tx) } @@ -40,20 +40,20 @@ class PendingTransactionDownloadedListener( Collections.unmodifiableCollection(transactions.values) private fun isTransactionRelevant(tx: StandardTransaction): Boolean { - if (transactions.containsKey(tx.txId)) { + if (transactions.containsKey(tx.tx.id)) { return true } - return if (keyRing.contains(tx.inputAddress!!.get())) { + return if (keyRing.contains(tx.tx.sourceAddress.address)) { true } else { - tx.getOutputs().any { - keyRing.contains(it.address.get()) + tx.tx.outputs.any { + keyRing.contains(it.address.address) } } } private fun addTransaction(tx: StandardTransaction) = lock.withLock { - transactions.putIfAbsent(tx.txId, tx) + transactions.putIfAbsent(tx.tx.id, tx) ledger.record(tx) //save(); } diff --git a/nodecore-spv/src/test/java/org/veriblock/spv/admin/service/impl/AdminApiServiceTest.kt b/nodecore-spv/src/test/java/org/veriblock/spv/admin/service/impl/AdminApiServiceTest.kt index e37e82b2f..efbca5e60 100644 --- a/nodecore-spv/src/test/java/org/veriblock/spv/admin/service/impl/AdminApiServiceTest.kt +++ b/nodecore-spv/src/test/java/org/veriblock/spv/admin/service/impl/AdminApiServiceTest.kt @@ -25,15 +25,13 @@ import org.veriblock.core.wallet.AddressManager import org.veriblock.core.wallet.AddressPubKey import org.veriblock.sdk.models.Address import org.veriblock.sdk.models.Coin +import org.veriblock.sdk.models.Output import org.veriblock.sdk.models.asCoin import org.veriblock.spv.SpvConfig import org.veriblock.spv.SpvContext import org.veriblock.spv.model.LedgerContext import org.veriblock.spv.model.LedgerValue -import org.veriblock.spv.model.Output import org.veriblock.spv.model.StandardAddress -import org.veriblock.spv.model.StandardTransaction -import org.veriblock.spv.model.Transaction import org.veriblock.spv.model.asLightAddress import org.veriblock.spv.service.SpvService import org.veriblock.spv.service.Blockchain @@ -92,7 +90,7 @@ class AdminApiServiceTest { address.asLightAddress(), listOf( Output( - "VDBt3GuwPe1tA5m4duTPkBq5vF22rw".asLightAddress(), + Address("VDBt3GuwPe1tA5m4duTPkBq5vF22rw"), 100.asCoin() ) ) @@ -150,7 +148,7 @@ class AdminApiServiceTest { "VcspPDtJNpNmLV8qFTqb2F5157JNHS".asLightAddress(), listOf( Output( - "VDBt3GuwPe1tA5m4duTPkBq5vF22rw".asLightAddress(), + Address("VDBt3GuwPe1tA5m4duTPkBq5vF22rw"), 100.asCoin() ) ) @@ -176,7 +174,7 @@ class AdminApiServiceTest { address.asLightAddress(), listOf( Output( - "VDBt3GuwPe1tA5m4duTPkBq5vF22rw".asLightAddress(), + Address("VDBt3GuwPe1tA5m4duTPkBq5vF22rw"), 100.asCoin() ) ) @@ -196,7 +194,7 @@ class AdminApiServiceTest { "VcspPDtJNpNmLV8qFTqb2F5157JNHS".asLightAddress(), listOf( Output( - "VDBt3GuwPe1tA5m4duTPkBq5vF22rw".asLightAddress(), + Output("VDBt3GuwPe1tA5m4duTPkBq5vF22rw"), 100.asCoin() ) ) diff --git a/nodecore-spv/src/test/java/org/veriblock/spv/lite/core/StandardTransactionTest.kt b/nodecore-spv/src/test/java/org/veriblock/spv/lite/core/StandardTransactionTest.kt index d409cb618..2ab89a463 100644 --- a/nodecore-spv/src/test/java/org/veriblock/spv/lite/core/StandardTransactionTest.kt +++ b/nodecore-spv/src/test/java/org/veriblock/spv/lite/core/StandardTransactionTest.kt @@ -10,8 +10,6 @@ import org.veriblock.core.utilities.Utility import org.veriblock.sdk.models.asCoin import org.veriblock.spv.SpvConfig import org.veriblock.spv.SpvContext -import org.veriblock.spv.model.Output -import org.veriblock.spv.model.StandardTransaction import org.veriblock.spv.model.asStandardAddress import java.io.File diff --git a/nodecore-spv/src/test/java/org/veriblock/spv/net/impl/PeerEventListenerTest.kt b/nodecore-spv/src/test/java/org/veriblock/spv/net/impl/PeerEventListenerTest.kt index 8a593808e..efc8722d1 100644 --- a/nodecore-spv/src/test/java/org/veriblock/spv/net/impl/PeerEventListenerTest.kt +++ b/nodecore-spv/src/test/java/org/veriblock/spv/net/impl/PeerEventListenerTest.kt @@ -18,8 +18,6 @@ import org.veriblock.core.params.defaultTestNetParameters import org.veriblock.sdk.models.asCoin import org.veriblock.spv.SpvConfig import org.veriblock.spv.SpvContext -import org.veriblock.spv.model.Output -import org.veriblock.spv.model.StandardTransaction import org.veriblock.spv.model.asStandardAddress import org.veriblock.spv.net.PeerEventListener import org.veriblock.spv.service.PendingTransactionContainer diff --git a/nodecore-spv/src/test/java/org/veriblock/spv/service/TransactionServiceTest.kt b/nodecore-spv/src/test/java/org/veriblock/spv/service/TransactionServiceTest.kt index 9f622de79..c1d3f2ebf 100644 --- a/nodecore-spv/src/test/java/org/veriblock/spv/service/TransactionServiceTest.kt +++ b/nodecore-spv/src/test/java/org/veriblock/spv/service/TransactionServiceTest.kt @@ -12,7 +12,6 @@ import org.veriblock.sdk.models.asCoinDecimal import org.veriblock.spv.SpvConfig import org.veriblock.spv.SpvContext import org.veriblock.spv.model.AddressCoinsIndex -import org.veriblock.spv.model.Output import org.veriblock.spv.model.StandardAddress class TransactionServiceTest : TestCase() { diff --git a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/api/controller/WalletController.kt b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/api/controller/WalletController.kt index 83d86a995..0984996e8 100644 --- a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/api/controller/WalletController.kt +++ b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/api/controller/WalletController.kt @@ -20,7 +20,6 @@ import org.veriblock.miners.pop.api.dto.WithdrawRequest import org.veriblock.miners.pop.api.dto.WithdrawResponse import org.veriblock.miners.pop.service.AltchainPopMinerService import org.veriblock.sdk.models.asCoin -import org.veriblock.spv.model.Output import org.veriblock.spv.model.asStandardAddress class WalletController( diff --git a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/net/SpvGateway.kt b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/net/SpvGateway.kt index cc8ccbe45..261419cec 100644 --- a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/net/SpvGateway.kt +++ b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/net/SpvGateway.kt @@ -26,13 +26,13 @@ import org.veriblock.miners.pop.serialization.deserialize import org.veriblock.miners.pop.serialization.deserializeStandardTransaction import org.veriblock.sdk.models.* import org.veriblock.sdk.services.SerializeDeserializeService -import org.veriblock.spv.model.StandardTransaction import org.veriblock.spv.service.NetworkState import org.veriblock.spv.service.SpvService import org.veriblock.spv.service.TransactionInfo import org.veriblock.core.crypto.VbkHash import org.veriblock.core.crypto.VbkTxId + private val logger = createLogger {} class SpvGateway( @@ -198,17 +198,14 @@ class SpvGateway( private fun signTransaction( addressManager: AddressManager, - unsignedTransaction: StandardTransaction - ): StandardTransaction { - val sourceAddress = unsignedTransaction.inputAddress!!.get() + unsignedTransaction: VeriBlockTransaction + ): VeriBlockTransaction { + val sourceAddress = unsignedTransaction.sourceAddress.address requireNotNull(addressManager.get(sourceAddress)) { "The address $sourceAddress is not contained in the specified wallet file!" } - val transactionId = unsignedTransaction.txId.bytes - val signature = addressManager.signMessage(transactionId, sourceAddress) - val publicKey = addressManager.getPublicKeyForAddress(sourceAddress).encoded - - unsignedTransaction.addSignature(signature, publicKey) + unsignedTransaction.signature = addressManager.signMessage(unsignedTransaction.id.bytes, sourceAddress) + unsignedTransaction.publicKey = addressManager.getPublicKeyForAddress(sourceAddress).encoded return unsignedTransaction } diff --git a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/securityinheriting/SecurityInheritingMonitor.kt b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/securityinheriting/SecurityInheritingMonitor.kt index b26de22b0..564e4dbb0 100644 --- a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/securityinheriting/SecurityInheritingMonitor.kt +++ b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/securityinheriting/SecurityInheritingMonitor.kt @@ -30,7 +30,6 @@ import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch -import nodecore.api.grpc.RpcVeriBlockPublication import org.veriblock.core.MineException import org.veriblock.core.crypto.asBtcHash import org.veriblock.core.crypto.asVbkHash @@ -40,7 +39,6 @@ import org.veriblock.core.utilities.createLogger import org.veriblock.core.utilities.debugError import org.veriblock.core.utilities.debugInfo import org.veriblock.core.utilities.debugWarn -import org.veriblock.core.utilities.extensions.asHexBytes import org.veriblock.miners.pop.core.ApmContext import org.veriblock.miners.pop.util.Threading import org.veriblock.miners.pop.EventBus @@ -65,7 +63,6 @@ import org.veriblock.miners.pop.util.CheckResult import org.veriblock.sdk.alt.model.VbkBlockResponse import org.veriblock.sdk.alt.model.VbkHeader import org.veriblock.sdk.models.VeriBlockBlock -import java.time.LocalDate import kotlin.concurrent.withLock private val logger = createLogger {} @@ -498,12 +495,21 @@ class SecurityInheritingMonitor( return 0 } - val fullVbk = miner.gateway.getFullBlock(vbk.header.hash) - if (fullVbk == null) { - logger.info {"Cannot get full VBK block ${vbk.header.hash}"} - return 0 + var cursorHash = vbk.header.hash + while(true) { + var fullVbk: FullBlock? = miner.gateway.getFullBlock(cursorHash) + if (fullVbk == null) { + logger.error { "Cannot get full block ${cursorHash}" } + return 0 + } + + fullVbk.popTransactions.forEach { tx -> + + } } + + return 0 // context gap of bigger size than maxGapSize } diff --git a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/serialization/MessageSerializer.kt b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/serialization/MessageSerializer.kt index 7e024668a..922c53bb2 100644 --- a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/serialization/MessageSerializer.kt +++ b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/serialization/MessageSerializer.kt @@ -34,7 +34,6 @@ import org.veriblock.sdk.models.VeriBlockPublication import org.veriblock.sdk.models.VeriBlockTransaction import org.veriblock.sdk.models.asCoin import org.veriblock.sdk.services.SerializeDeserializeService -import org.veriblock.spv.model.StandardTransaction private val logger = createLogger {} diff --git a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/shell/commands/WalletCommands.kt b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/shell/commands/WalletCommands.kt index fb8df638a..e4501ff44 100644 --- a/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/shell/commands/WalletCommands.kt +++ b/pop-miners/altchain-pop-miner/src/main/kotlin/org/veriblock/miners/pop/shell/commands/WalletCommands.kt @@ -18,7 +18,6 @@ import org.veriblock.shell.CommandParameter import org.veriblock.shell.CommandParameterMappers import org.veriblock.shell.command import org.veriblock.shell.core.success -import org.veriblock.spv.model.Output import org.veriblock.spv.model.asStandardAddress fun CommandFactory.walletCommands( diff --git a/veriblock-core/src/main/java/org/veriblock/core/crypto/Sha256Hash.kt b/veriblock-core/src/main/java/org/veriblock/core/crypto/Sha256Hash.kt index c94ea37db..a070ba52e 100644 --- a/veriblock-core/src/main/java/org/veriblock/core/crypto/Sha256Hash.kt +++ b/veriblock-core/src/main/java/org/veriblock/core/crypto/Sha256Hash.kt @@ -105,7 +105,7 @@ class MerkleRoot(bytes: ByteArray) : Sha256Hash(bytes) { class TruncatedMerkleRoot(bytes: ByteArray) : Sha256Hash(trimBytes(bytes, TRUNCATED_MERKLE_ROOT_LENGTH)) { init { - check(bytes.size == TRUNCATED_MERKLE_ROOT_LENGTH || bytes.size == TRUNCATED_MERKLE_ROOT_LENGTH * 2) { + check(bytes.size == TRUNCATED_MERKLE_ROOT_LENGTH || bytes.size == 24) { "Trying to create a truncated merkle root hash with invalid amount of bytes: ${bytes.size} (${bytes.toHex()})" } } diff --git a/veriblock-core/src/main/java/org/veriblock/sdk/models/VeriBlockPopTransaction.kt b/veriblock-core/src/main/java/org/veriblock/sdk/models/VeriBlockPopTransaction.kt index 5e30bce07..e41842c30 100644 --- a/veriblock-core/src/main/java/org/veriblock/sdk/models/VeriBlockPopTransaction.kt +++ b/veriblock-core/src/main/java/org/veriblock/sdk/models/VeriBlockPopTransaction.kt @@ -20,11 +20,11 @@ class VeriBlockPopTransaction( val merklePath: MerklePath, val blockOfProof: BitcoinBlock, val blockOfProofContext: List, - val signature: ByteArray, - val publicKey: ByteArray, + var signature: ByteArray, + var publicKey: ByteArray, val networkByte: Byte? ) { - val id: Sha256Hash = getId(this) + val id by lazy { getId(this) } init { check(signature.isNotEmpty()) { diff --git a/veriblock-core/src/main/java/org/veriblock/sdk/models/VeriBlockTransaction.kt b/veriblock-core/src/main/java/org/veriblock/sdk/models/VeriBlockTransaction.kt index 5ea6c96b4..e7048eb5b 100644 --- a/veriblock-core/src/main/java/org/veriblock/sdk/models/VeriBlockTransaction.kt +++ b/veriblock-core/src/main/java/org/veriblock/sdk/models/VeriBlockTransaction.kt @@ -15,7 +15,7 @@ import java.util.Arrays import java.util.Collections open class VeriBlockTransaction( - type: Byte, + type: Byte = 1, /* vbk tx == 1 */ sourceAddress: Address, sourceAmount: Coin, outputs: List?, @@ -25,15 +25,17 @@ open class VeriBlockTransaction( publicKey: ByteArray, networkByte: Byte? ) { - val id: VbkTxId + val id: VbkTxId by lazy { + SerializeDeserializeService.getId(this) + } val type: Byte val sourceAddress: Address val sourceAmount: Coin val outputs: List val signatureIndex: Long val publicationData: PublicationData? - val signature: ByteArray - val publicKey: ByteArray + var signature: ByteArray + var publicKey: ByteArray val networkByte: Byte? init { @@ -55,7 +57,6 @@ open class VeriBlockTransaction( this.signature = signature this.publicKey = publicKey this.networkByte = networkByte - id = SerializeDeserializeService.getId(this) } override fun equals(other: Any?): Boolean {