Skip to content

Commit

Permalink
Serialize/Deserialize joinDaoPayload
Browse files Browse the repository at this point in the history
  • Loading branch information
JoepMulder committed May 1, 2024
1 parent c19036b commit eb9be9e
Show file tree
Hide file tree
Showing 4 changed files with 197 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package nl.tudelft.trustchain.currencyii
import android.app.Activity
import android.content.Context
import android.util.Log
import android.widget.Toast
import nl.tudelft.ipv8.Community
import nl.tudelft.ipv8.Overlay
import nl.tudelft.ipv8.Peer
Expand Down Expand Up @@ -56,6 +57,8 @@ open class CoinCommunity constructor(
messageHandlers[MessageId.ELECTED_RESPONSE] = ::onElectedResponsePacket
messageHandlers[MessageId.ALIVE_RESPONSE] = ::onAliveResponsePacket
messageHandlers[MessageId.SIGNATURE_ASK] = ::onSignPayloadResponsePacket
messageHandlers[MessageId.JOIN_DAO_DATA] = ::onDaoJoinDataPacket

}

private fun getTrustChainCommunity(): TrustChainCommunity {
Expand Down Expand Up @@ -298,6 +301,29 @@ open class CoinCommunity constructor(
this.onSignPayloadResponse(peer, payload)
}

private fun onDaoJoinDataPacket(packet: Packet) {
Log.d("LEADER", "Received data from Peer wanting to join")

val (peer, payload) =
packet.getAuthPayload(
SignPayload.Deserializer
)
try {
Log.d("LEADER", "Peer wanting to join: ${peer.publicKey}")
joinBitcoinWallet(
payload.mostRecentSWBlock.transaction,
payload.proposeBlockData,
payload.signatures,
this.context
)
// Add new nonceKey after joining a DAO
WalletManagerAndroid.getInstance()
.addNewNonceKey(payload.proposeBlockData.SW_UNIQUE_ID, this.context)
} catch (t: Throwable) {
Log.e("LEADER", "Joining failed. ${t.message ?: "No further information"}.")
}
}

fun onSignPayloadResponse(
peer: Peer,
payload: SignPayload
Expand All @@ -318,6 +344,8 @@ open class CoinCommunity constructor(
}
}



fun onAliveResponse(
peer: Peer,
payload: AlivePayload
Expand Down Expand Up @@ -444,7 +472,25 @@ open class CoinCommunity constructor(
Thread.sleep(1000)
}
Log.d("LEADER", "Leader found.")
Log.d("LEADER", "sending proposal to leader...")



val currentLeader = getCurrentLeader()[publicKeyBlock.decodeToString()]!!
Log.d("LEADER", "sending dao join transaction data to leader ${currentLeader.publicKey}")
val payload = SignPayload(
getServiceIdNew().toByteArray(),
mostRecentSWBlock,
proposeBlockData,
signatures);
val packet = serializePacket(MessageId.JOIN_DAO_DATA, payload)
send(currentLeader, packet)

Toast.makeText(
context,
"Sending DAO join data to ${currentLeader.publicKey}",
Toast.LENGTH_SHORT
).show()

sendPayload(
getCurrentLeader()[publicKeyBlock.decodeToString()]!!,
SignPayload(
Expand Down Expand Up @@ -651,6 +697,8 @@ open class CoinCommunity constructor(
const val ELECTED_RESPONSE = 2
const val ALIVE_RESPONSE = 3
const val SIGNATURE_ASK = 4
const val JOIN_DAO_DATA = 5

}

companion object {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package nl.tudelft.trustchain.currencyii.payload
import nl.tudelft.ipv8.messaging.*
import nl.tudelft.trustchain.currencyii.sharedWallet.SWSignatureAskBlockTD
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import nl.tudelft.ipv8.attestation.trustchain.TrustChainBlock
import nl.tudelft.ipv8.messaging.Deserializable
import nl.tudelft.ipv8.messaging.SERIALIZED_USHORT_SIZE
import nl.tudelft.ipv8.messaging.Serializable
import nl.tudelft.ipv8.messaging.deserializeUInt
import nl.tudelft.ipv8.messaging.deserializeUShort
import nl.tudelft.ipv8.messaging.serializeUInt
import nl.tudelft.ipv8.messaging.serializeUShort
import nl.tudelft.trustchain.currencyii.sharedWallet.SWResponseSignatureBlockTD
import nl.tudelft.trustchain.currencyii.sharedWallet.SWSignatureAskBlockTD
import java.util.Date

class SignPayload(
val DAOid: ByteArray,
Expand All @@ -13,13 +20,32 @@ class SignPayload(
val signatures: List<SWResponseSignatureBlockTD>
) : Serializable {
override fun serialize(): ByteArray {
val gson = Gson()
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create();

val daoIdSizeBytes = serializeUShort(DAOid.size)

val mostRecentSWBlockJson = gson.toJson(mostRecentSWBlock)
val mostRecentSWBlockBytes = mostRecentSWBlockJson.toByteArray()
val mostRecentSWBlockSizeBytes = serializeUShort(mostRecentSWBlockBytes.size)
// serialize each property seperately for mostRecentSWBlock
val trustBlockTypeBytes = mostRecentSWBlock.type.toByteArray()
val trustBlockTypeSizeBytes = serializeUShort(trustBlockTypeBytes.size)

val trustBlockRawTransactionSizeBytes = serializeUShort(mostRecentSWBlock.rawTransaction.size)
val trustBlockPublicKeySizeBytes = serializeUShort(mostRecentSWBlock.publicKey.size)

val sequenceBytes = serializeUInt(mostRecentSWBlock.sequenceNumber)
val sequenceSizeBytes = serializeUShort(sequenceBytes.size)

val linkPublicKeySizeBytes = serializeUShort(mostRecentSWBlock.linkPublicKey.size)

val linkSequenceNumberBytes = serializeUInt(mostRecentSWBlock.linkSequenceNumber)
val linkSequenceNumberSizeBytes = serializeUShort(linkSequenceNumberBytes.size)

val prevHashSizeBytes = serializeUShort(mostRecentSWBlock.previousHash.size)
val signatureSizeBytes = serializeUShort(mostRecentSWBlock.signature.size)

val timeStampBytes = gson.toJson(mostRecentSWBlock.timestamp).toByteArray()
val timeStampSizeBytes = serializeUShort(timeStampBytes.size)



val proposeBlockDataJson = gson.toJson(proposeBlockData)
val proposeBlockDataBytes = proposeBlockDataJson.toByteArray()
Expand All @@ -30,13 +56,21 @@ class SignPayload(
val signaturesSizeBytes = serializeUShort(signaturesBytes.size)

return daoIdSizeBytes + DAOid +
mostRecentSWBlockSizeBytes + mostRecentSWBlockBytes +
trustBlockTypeSizeBytes + trustBlockTypeBytes +
trustBlockRawTransactionSizeBytes + mostRecentSWBlock.rawTransaction +
trustBlockPublicKeySizeBytes + mostRecentSWBlock.publicKey +
sequenceSizeBytes + sequenceBytes +
linkPublicKeySizeBytes + mostRecentSWBlock.linkPublicKey +
linkSequenceNumberSizeBytes + linkSequenceNumberBytes +
prevHashSizeBytes + mostRecentSWBlock.previousHash +
signatureSizeBytes + mostRecentSWBlock.signature +
timeStampSizeBytes + timeStampBytes +
proposeBlockDataSizeBytes + proposeBlockDataBytes +
signaturesSizeBytes + signaturesBytes
}

companion object Deserializer : Deserializable<SignPayload> {
val gson = Gson()
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ").create();

override fun deserialize(
buffer: ByteArray,
Expand All @@ -52,17 +86,55 @@ class SignPayload(
)
localOffset += daoIdSize

val mostRecentSWBlockSize = deserializeUShort(buffer, offset + localOffset)
val typeSize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val mostRecentSWBlock =
gson.fromJson(
buffer.copyOfRange(
offset + localOffset,
offset + localOffset + mostRecentSWBlockSize
).decodeToString(),
TrustChainBlock::class.java
)
localOffset += mostRecentSWBlockSize
val type = buffer.copyOfRange(offset + localOffset, offset + localOffset + typeSize)
localOffset += typeSize

val rawTransactionSize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val rawTransaction = buffer.copyOfRange(offset + localOffset, offset + localOffset + rawTransactionSize)
localOffset += rawTransactionSize

val publicKeySize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val publicKey = buffer.copyOfRange(offset + localOffset, offset + localOffset + publicKeySize)
localOffset += publicKeySize

val sequenceNumberSize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val sequenceNumber = buffer.copyOfRange(offset + localOffset, offset + localOffset + sequenceNumberSize)
localOffset += sequenceNumberSize

val linkPublicKeySize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val linkPublicKey = buffer.copyOfRange(offset + localOffset, offset + localOffset + linkPublicKeySize)
localOffset += linkPublicKeySize

val linkSequenceNumberSize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val linkSequenceNumber = buffer.copyOfRange(offset + localOffset, offset + localOffset + linkSequenceNumberSize)
localOffset += linkSequenceNumberSize

val previousHashSize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val previousHash = buffer.copyOfRange(offset + localOffset, offset + localOffset + previousHashSize)
localOffset += previousHashSize

val signatureSize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val signature = buffer.copyOfRange(offset + localOffset, offset + localOffset + signatureSize)
localOffset += signatureSize

val timestampSize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
val timestamp = buffer.copyOfRange(offset + localOffset, offset + localOffset + timestampSize)
localOffset += timestampSize

val date = gson.fromJson(timestamp.decodeToString(), Date::class.java)
val mostRecentSWBlock = TrustChainBlock(type.decodeToString(), rawTransaction, publicKey, deserializeUInt(sequenceNumber),
linkPublicKey, deserializeUInt(linkSequenceNumber), previousHash, signature, date)


val proposeBlockDataSize = deserializeUShort(buffer, offset + localOffset)
localOffset += SERIALIZED_USHORT_SIZE
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import nl.tudelft.ipv8.attestation.trustchain.TrustChainBlock
import nl.tudelft.ipv8.util.toHex
import nl.tudelft.trustchain.currencyii.CoinCommunity
import nl.tudelft.trustchain.currencyii.R
import nl.tudelft.trustchain.currencyii.coin.WalletManagerAndroid
import nl.tudelft.trustchain.currencyii.databinding.FragmentJoinNetworkBinding
import nl.tudelft.trustchain.currencyii.sharedWallet.SWJoinBlockTransactionData
import nl.tudelft.trustchain.currencyii.sharedWallet.SWResponseSignatureBlockTD
Expand Down Expand Up @@ -235,20 +234,21 @@ class JoinDAOFragment : BaseFragment(R.layout.fragment_join_network) {
signatures,
latestHash
)
try {
getCoinCommunity().joinBitcoinWallet(
mostRecentSWBlock.transaction,
proposeBlockData,
signatures,
context
)
// Add new nonceKey after joining a DAO
WalletManagerAndroid.getInstance()
.addNewNonceKey(proposeBlockData.SW_UNIQUE_ID, context)
} catch (t: Throwable) {
Log.e("Coin", "Joining failed. ${t.message ?: "No further information"}.")
setAlertText(t.message ?: "Unexpected error occurred. Try again")
}

// try {
// getCoinCommunity().joinBitcoinWallet(
// mostRecentSWBlock.transaction,
// proposeBlockData,
// signatures,
// context
// )
// // Add new nonceKey after joining a DAO
// WalletManagerAndroid.getInstance()
// .addNewNonceKey(proposeBlockData.SW_UNIQUE_ID, context)
// } catch (t: Throwable) {
// Log.e("Coin", "Joining failed. ${t.message ?: "No further information"}.")
// setAlertText(t.message ?: "Unexpected error occurred. Try again")
// }

// Update wallets UI list
fetchSharedWalletsAndUpdateUI()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import nl.tudelft.trustchain.currencyii.sharedWallet.SWSignatureAskBlockTD
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeAll
import org.junit.jupiter.api.Test
import java.util.Calendar

class PayloadTest {

Expand Down Expand Up @@ -84,12 +85,12 @@ class PayloadTest {
}

@Test
fun electionPayloadRequestTest() {
fun electionPayloadSerializeTest() {

val context = mockk<Context>()
val coinCommunity = CoinCommunity(context)
val dAOid = "Dao_id"
val me = mockk<Peer>()

val meKey = mockk<PublicKey>()

coinCommunity.myPeer = me
Expand All @@ -101,11 +102,47 @@ class PayloadTest {
every { me.updateClock(any<ULong>()) } returns Unit
every { me.key } returns mockk<Key>()

val sig1 = SWResponseSignatureBlockTD("SignatureId1", "ProposalId", "SignatureId1Serialized", "BTC_PK1", "NONCE1")
val sig2 = SWResponseSignatureBlockTD("SignatureId2", "ProposalId", "SignatureId2Serialized", "BTC_PK2", "NONCE2")
val sig3 = SWResponseSignatureBlockTD("SignatureId3", "ProposalId", "SignatureId3Serialized", "BTC_PK3", "NONCE3")

val daoIdBytes = dAOid.toByteArray()
val packet = coinCommunity.createElectionRequest(daoIdBytes)
val packetLastElements = packet.takeLast(daoIdBytes.size)
val signatures = listOf(sig1, sig2, sig3)
val trustChainBlock = TrustChainBlock("type", "rawTransaction".toByteArray(), "publicKey".toByteArray(), 42U, "linkPublicKey".toByteArray(),
12U, "previousHash".toByteArray(), "signature".toByteArray(), Calendar.getInstance().time)
val proposeBlockData = SWSignatureAskBlockTD("SW_UNIQUE_ID", "SW_UNIQUE_PROPOSAL_ID",
"SW_TRANSACTION_SERIALIZED", "SW_PREVIOUS_BLOCK_HASH", 5, "SW_RECEIVER_PK")

val payload = SignPayload(daoIdBytes, trustChainBlock, proposeBlockData, signatures)
val serialized = payload.serialize()
val deserialized = SignPayload.deserialize(serialized)


assertEquals(payload.DAOid.decodeToString(), deserialized.first.DAOid.decodeToString())
assertEquals(payload.mostRecentSWBlock.type, deserialized.first.mostRecentSWBlock.type)
assertEquals(payload.mostRecentSWBlock.rawTransaction.decodeToString(), deserialized.first.mostRecentSWBlock.rawTransaction.decodeToString())
assertEquals(payload.mostRecentSWBlock.publicKey.decodeToString(), deserialized.first.mostRecentSWBlock.publicKey.decodeToString())
assertEquals(payload.mostRecentSWBlock.sequenceNumber, deserialized.first.mostRecentSWBlock.sequenceNumber)
assertEquals(payload.mostRecentSWBlock.linkPublicKey.decodeToString(), deserialized.first.mostRecentSWBlock.linkPublicKey.decodeToString())
assertEquals(payload.mostRecentSWBlock.linkSequenceNumber, deserialized.first.mostRecentSWBlock.linkSequenceNumber)
assertEquals(payload.mostRecentSWBlock.previousHash.decodeToString(), deserialized.first.mostRecentSWBlock.previousHash.decodeToString())
assertEquals(payload.mostRecentSWBlock.signature.decodeToString(), deserialized.first.mostRecentSWBlock.signature.decodeToString())
assertEquals(payload.mostRecentSWBlock.timestamp.time, deserialized.first.mostRecentSWBlock.timestamp.time)

assertEquals(payload.signatures.first().SW_UNIQUE_ID, deserialized.first.signatures.first().SW_UNIQUE_ID)
assertEquals(payload.signatures.first().SW_BITCOIN_PK, deserialized.first.signatures.first().SW_BITCOIN_PK)
assertEquals(payload.signatures.last().SW_NONCE, deserialized.first.signatures.last().SW_NONCE)
assertEquals(payload.signatures.size, deserialized.first.signatures.size)
assertEquals(payload.signatures.last().SW_UNIQUE_PROPOSAL_ID, deserialized.first.signatures.last().SW_UNIQUE_PROPOSAL_ID)

assertEquals(payload.proposeBlockData.SW_UNIQUE_PROPOSAL_ID, deserialized.first.proposeBlockData.SW_UNIQUE_PROPOSAL_ID)
assertEquals(payload.proposeBlockData.SW_TRANSACTION_SERIALIZED, deserialized.first.proposeBlockData.SW_TRANSACTION_SERIALIZED)
assertEquals(payload.proposeBlockData.SW_SIGNATURES_REQUIRED, deserialized.first.proposeBlockData.SW_SIGNATURES_REQUIRED)
assertEquals(payload.proposeBlockData.SW_PREVIOUS_BLOCK_HASH, deserialized.first.proposeBlockData.SW_PREVIOUS_BLOCK_HASH)
assertEquals(payload.proposeBlockData.SW_UNIQUE_ID, deserialized.first.proposeBlockData.SW_UNIQUE_ID)
assertEquals(payload.proposeBlockData.SW_RECEIVER_PK, deserialized.first.proposeBlockData.SW_RECEIVER_PK)


assertEquals(daoIdBytes.toList(), packetLastElements)
}
}

Expand Down

0 comments on commit eb9be9e

Please sign in to comment.