From 3c88140f057af4647bc2c55dd315db2ff6b1ec33 Mon Sep 17 00:00:00 2001 From: Kostas Andriopoulos Date: Sat, 25 Mar 2023 14:20:58 +0100 Subject: [PATCH 1/3] detoks: Add dependencies on `build.gradle` Add a number of dependencies that we use in our lightweight implementation of the `detoks` application. Through the lightweight implementation, we are able to test our transactions engine (which we will introduce in a following commit) easily and quickly. --- detoks/build.gradle | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/detoks/build.gradle b/detoks/build.gradle index 16e19ba57..0bfe89e03 100644 --- a/detoks/build.gradle +++ b/detoks/build.gradle @@ -39,6 +39,11 @@ android { dependencies { implementation project(':common') + api(project(':ipv8-jvm')) { + exclude group: 'net.java.dev.jna' + exclude group: 'org.slf4j' + exclude group: 'com.goterl' + } // AndroidX implementation 'androidx.appcompat:appcompat:1.6.1' @@ -83,6 +88,7 @@ dependencies { implementation files('../common/libs/jlibtorrent-android-x86_64-' + jlibtorrent_version + '.jar') implementation 'com.devbrackets.android:exomedia:4.3.0' + implementation "com.squareup.sqldelight:sqlite-driver:$sqldelight_version" } tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all { From 64c71403d71022c54e20c5c5149bd2c24ca40b0a Mon Sep 17 00:00:00 2001 From: Kostas Andriopoulos Date: Sun, 26 Mar 2023 14:21:38 +0200 Subject: [PATCH 2/3] detoks: Add `TransactionEngine` Add `TransactionEngine` which will serve as the main API class for transactions. The already existing `DeToksCommunity` will now inherit all of `TransactionEngine`'s member functions related to transactions. The `TransactionEngine` also serves as a lightweight implementation of the `DeToksCommunity`, so that we can use it in our lightweight version of our Detoks app. --- .../trustchain/detoks/DeToksCommunity.kt | 8 +- .../trustchain/detoks/TransactionEngine.kt | 114 ++++++++++++++++++ 2 files changed, 117 insertions(+), 5 deletions(-) create mode 100644 detoks/src/main/java/nl/tudelft/trustchain/detoks/TransactionEngine.kt diff --git a/detoks/src/main/java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt b/detoks/src/main/java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt index 1fb1563bf..6328c90c1 100644 --- a/detoks/src/main/java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt +++ b/detoks/src/main/java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt @@ -3,7 +3,6 @@ package nl.tudelft.trustchain.detoks import android.content.Context import android.util.Log import com.frostwire.jlibtorrent.Sha1Hash -import nl.tudelft.ipv8.Community import nl.tudelft.ipv8.Overlay import nl.tudelft.ipv8.Peer import nl.tudelft.ipv8.messaging.Packet @@ -11,7 +10,9 @@ import nl.tudelft.ipv8.messaging.Serializable import nl.tudelft.trustchain.detoks.gossiper.* -class DeToksCommunity(private val context: Context) : Community() { +class DeToksCommunity( + private val context: Context + ) : TransactionEngine("c86a7db45eb3563ae047639817baec4db2bc7c25") { private val walletManager = WalletManager(context) private val visitedPeers = mutableListOf() @@ -36,9 +37,6 @@ class DeToksCommunity(private val context: Context) : Community() { const val MESSAGE_BOOT_RESPONSE = 6 } - override val serviceId = "c86a7db45eb3563ae047639817baec4db2bc7c25" - - fun sendTokens(amount: Int, recipientMid: String) { val senderWallet = walletManager.getOrCreateWallet(myPeer.mid) diff --git a/detoks/src/main/java/nl/tudelft/trustchain/detoks/TransactionEngine.kt b/detoks/src/main/java/nl/tudelft/trustchain/detoks/TransactionEngine.kt new file mode 100644 index 000000000..749f4a04e --- /dev/null +++ b/detoks/src/main/java/nl/tudelft/trustchain/detoks/TransactionEngine.kt @@ -0,0 +1,114 @@ +package nl.tudelft.trustchain.detoks + +import nl.tudelft.ipv8.Community +import nl.tudelft.ipv8.Overlay +import nl.tudelft.ipv8.Peer +import nl.tudelft.ipv8.attestation.trustchain.BlockBuilder +import nl.tudelft.ipv8.attestation.trustchain.TrustChainBlock +import nl.tudelft.ipv8.attestation.trustchain.payload.HalfBlockBroadcastPayload +import nl.tudelft.ipv8.attestation.trustchain.payload.HalfBlockPayload +import nl.tudelft.ipv8.messaging.Packet +import nl.tudelft.ipv8.util.random +import java.util.* +import mu.KotlinLogging + + +open class TransactionEngine (override val serviceId: String): Community() { + private val broadcastFanOut = 25 + private val ttl = 100 + private val logger = KotlinLogging.logger {} + + object MessageId { + const val HALF_BLOCK: Int = 11 + const val HALF_BLOCK_ENCRYPTED: Int = 12 + const val HALF_BLOCK_BROADCAST: Int = 13 + const val HALF_BLOCK_BROADCAST_ENCRYPTED: Int = 14 + } + + init { + messageHandlers[MessageId.HALF_BLOCK] = ::onHalfBlockPacket + messageHandlers[MessageId.HALF_BLOCK_BROADCAST] = ::onHalfBlockBroadcastPacket + messageHandlers[MessageId.HALF_BLOCK_ENCRYPTED] = ::onHalfBlockPacket + messageHandlers[MessageId.HALF_BLOCK_BROADCAST_ENCRYPTED] = ::onHalfBlockBroadcastPacket + } + + fun sendTransaction(blockBuilder: BlockBuilder, peer: Peer?, encrypt: Boolean = false) { + logger.info { "Sending transaction..." } + val block = blockBuilder.sign() + + if (peer != null) { + sendBlockToRecipient(peer, block, encrypt) + } else { + sendBlockBroadcast(block, encrypt) + } + } + + private fun sendBlockToRecipient(peer: Peer, block: TrustChainBlock, encrypt: Boolean) { + val payload = HalfBlockPayload.fromHalfBlock(block) + + val data = if (encrypt) { + serializePacket(MessageId.HALF_BLOCK_ENCRYPTED, payload, false, encrypt = true, recipient = peer) + } else { + serializePacket(MessageId.HALF_BLOCK, payload, false) + } + + send(peer, data) + } + + private fun sendBlockBroadcast(block: TrustChainBlock, encrypt: Boolean) { + val payload = HalfBlockBroadcastPayload.fromHalfBlock(block, ttl.toUInt()) + val randomPeers = getPeers().random(broadcastFanOut) + for (randomPeer in randomPeers) { + val data = if (encrypt) { + serializePacket(MessageId.HALF_BLOCK_BROADCAST_ENCRYPTED, payload, false, encrypt = true, recipient = randomPeer) + } else { + serializePacket(MessageId.HALF_BLOCK_BROADCAST, payload, false) + } + send(randomPeer, data) + } + } + + private fun onHalfBlockPacket(packet: Packet) { + logger.info { ("Half block packet received from: " + packet.source.toString()) } + } + + private fun onHalfBlockBroadcastPacket(packet: Packet) { + logger.info { ("Half block packet received from broadcast from: " + packet.source.toString()) } + } + + override fun onPacket(packet: Packet) { + val sourceAddress = packet.source + val data = packet.data + + val probablePeer = network.getVerifiedByAddress(sourceAddress) + if (probablePeer != null) { + probablePeer.lastResponse = Date() + } + + val packetPrefix = data.copyOfRange(0, prefix.size) + if (!packetPrefix.contentEquals(prefix)) { + // logger.debug("prefix not matching") + return + } + + val msgId = data[prefix.size].toUByte().toInt() + + val handler = messageHandlers[msgId] + + if (handler != null) { + try { + handler(packet) + } catch (e: Exception) { + e.printStackTrace() + } + } else { + logger.info { "Received unknown message $msgId from $sourceAddress" } + } + } + + class Factory(private val serviceId: String) : Overlay.Factory(TransactionEngine::class.java) { + override fun create(): TransactionEngine { + return TransactionEngine(serviceId) + } + } +} From c142deec100fe21a8e86c5255cf0ce0ca3a77894 Mon Sep 17 00:00:00 2001 From: Kostas Andriopoulos Date: Wed, 29 Mar 2023 16:36:23 +0200 Subject: [PATCH 3/3] detoks: Add `DetoksConfig` class Add the `DetoksConfig` class as a single place to store global properties that configure the Detoks application. --- .../java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt | 2 +- .../main/java/nl/tudelft/trustchain/detoks/DetoksConfig.kt | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 detoks/src/main/java/nl/tudelft/trustchain/detoks/DetoksConfig.kt diff --git a/detoks/src/main/java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt b/detoks/src/main/java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt index 6328c90c1..8ee14f5ca 100644 --- a/detoks/src/main/java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt +++ b/detoks/src/main/java/nl/tudelft/trustchain/detoks/DeToksCommunity.kt @@ -12,7 +12,7 @@ import nl.tudelft.trustchain.detoks.gossiper.* class DeToksCommunity( private val context: Context - ) : TransactionEngine("c86a7db45eb3563ae047639817baec4db2bc7c25") { + ) : TransactionEngine(DetoksConfig.DETOKS_SERVICE_ID) { private val walletManager = WalletManager(context) private val visitedPeers = mutableListOf() diff --git a/detoks/src/main/java/nl/tudelft/trustchain/detoks/DetoksConfig.kt b/detoks/src/main/java/nl/tudelft/trustchain/detoks/DetoksConfig.kt new file mode 100644 index 000000000..ed7e990cf --- /dev/null +++ b/detoks/src/main/java/nl/tudelft/trustchain/detoks/DetoksConfig.kt @@ -0,0 +1,7 @@ +package nl.tudelft.trustchain.detoks + +class DetoksConfig() { + companion object { + const val DETOKS_SERVICE_ID = "c86a7db45eb3563ae047639817baec4db2bc7c25" + } +}