Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FlowBlockSeal protobuf updates #122

Merged
merged 10 commits into from
Oct 25, 2024
63 changes: 58 additions & 5 deletions sdk/src/main/kotlin/org/onflow/flow/sdk/models.kt
Original file line number Diff line number Diff line change
Expand Up @@ -1201,27 +1201,80 @@ data class FlowCollectionGuarantee(
}

data class FlowBlockSeal(
val id: FlowId,
val blockId: FlowId,
val executionReceiptId: FlowId,
val executionReceiptSignatures: List<FlowSignature>,
val resultApprovalSignatures: List<FlowSignature>
val resultApprovalSignatures: List<FlowSignature>,
val finalState: ByteArray,
val resultId: FlowId,
val aggregatedApprovalSigs: List<FlowAggregatedSignature>,
) : Serializable {
companion object {
@JvmStatic
fun of(value: BlockSealOuterClass.BlockSeal) = FlowBlockSeal(
id = FlowId.of(value.blockId.toByteArray()),
blockId = FlowId.of(value.blockId.toByteArray()),
executionReceiptId = FlowId.of(value.executionReceiptId.toByteArray()),
executionReceiptSignatures = value.executionReceiptSignaturesList.map { FlowSignature(it.toByteArray()) },
resultApprovalSignatures = value.executionReceiptSignaturesList.map { FlowSignature(it.toByteArray()) }
resultApprovalSignatures = value.resultApprovalSignaturesList.map { FlowSignature(it.toByteArray()) },
finalState = value.finalState.toByteArray(),
resultId = FlowId.of(value.resultId.toByteArray()),
aggregatedApprovalSigs = value.aggregatedApprovalSigsList.map { FlowAggregatedSignature.of(it) },
)
}

@JvmOverloads
fun builder(builder: BlockSealOuterClass.BlockSeal.Builder = BlockSealOuterClass.BlockSeal.newBuilder()): BlockSealOuterClass.BlockSeal.Builder = builder
.setBlockId(id.byteStringValue)
.setBlockId(blockId.byteStringValue)
.setExecutionReceiptId(executionReceiptId.byteStringValue)
.addAllExecutionReceiptSignatures(executionReceiptSignatures.map { it.byteStringValue })
.addAllResultApprovalSignatures(resultApprovalSignatures.map { it.byteStringValue })
.setFinalState(UnsafeByteOperations.unsafeWrap(finalState))
.setResultId(resultId.byteStringValue)
.addAllAggregatedApprovalSigs(aggregatedApprovalSigs.map { it.builder().build() })

override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other !is FlowBlockSeal) return false

if (blockId != other.blockId) return false
if (executionReceiptId != other.executionReceiptId) return false
if (executionReceiptSignatures != other.executionReceiptSignatures) return false
if (resultApprovalSignatures != other.resultApprovalSignatures) return false
if (!finalState.contentEquals(other.finalState)) return false
if (resultId != other.resultId) return false
if (aggregatedApprovalSigs != other.aggregatedApprovalSigs) return false

return true
}

override fun hashCode(): Int {
var result = blockId.hashCode()
result = 31 * result + executionReceiptId.hashCode()
result = 31 * result + executionReceiptSignatures.hashCode()
result = 31 * result + resultApprovalSignatures.hashCode()
result = 31 * result + finalState.contentHashCode()
result = 31 * result + resultId.hashCode()
result = 31 * result + aggregatedApprovalSigs.hashCode()
return result
}
}

data class FlowAggregatedSignature(
val verifierSignatures: List<FlowSignature>,
val signerIds: List<FlowId>,
) : Serializable {
companion object {
@JvmStatic
fun of(value: BlockSealOuterClass.AggregatedSignature) = FlowAggregatedSignature(
verifierSignatures = value.verifierSignaturesList.map { FlowSignature(it.toByteArray()) },
signerIds = value.signerIdsList.map { FlowId.of(it.toByteArray()) }
)
}

@JvmOverloads
fun builder(builder: BlockSealOuterClass.AggregatedSignature.Builder = BlockSealOuterClass.AggregatedSignature.newBuilder()): BlockSealOuterClass.AggregatedSignature.Builder = builder
.addAllVerifierSignatures(verifierSignatures.map { it.byteStringValue })
.addAllSignerIds(signerIds.map { it.byteStringValue })
franklywatson marked this conversation as resolved.
Show resolved Hide resolved
}

data class FlowCollection(
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package org.onflow.flow.sdk.models

import org.onflow.flow.sdk.FlowAggregatedSignature
import org.onflow.flow.sdk.FlowId
import org.onflow.flow.sdk.FlowSignature
import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import org.mockito.Mockito
import org.onflow.protobuf.entities.BlockSealOuterClass

class FlowAggregatedSignatureTest {
@Test
fun `test FlowAggregatedSignature equals and hashCode`() {
val signature1 = FlowSignature("signature1".toByteArray())
val signature2 = FlowSignature("signature2".toByteArray())

val signerId1 = FlowId.of("signerId1".toByteArray())
val signerId2 = FlowId.of("signerId2".toByteArray())

val aggregatedSignature1 = FlowAggregatedSignature(
verifierSignatures = listOf(signature1),
signerIds = listOf(signerId1)
)

val aggregatedSignature2 = FlowAggregatedSignature(
verifierSignatures = listOf(signature1),
signerIds = listOf(signerId1)
)

val aggregatedSignature3 = FlowAggregatedSignature(
verifierSignatures = listOf(signature2),
signerIds = listOf(signerId2)
)

// Test equality
assertEquals(aggregatedSignature1, aggregatedSignature2)
assertNotEquals(aggregatedSignature1, aggregatedSignature3)

// Test hashCode
assertEquals(aggregatedSignature1.hashCode(), aggregatedSignature2.hashCode())
assertNotEquals(aggregatedSignature1.hashCode(), aggregatedSignature3.hashCode())
}

@Test
fun `test FlowAggregatedSignature of function`() {
// Mock BlockSealOuterClass.AggregatedSignature
val aggregatedSignatureProto = Mockito.mock(BlockSealOuterClass.AggregatedSignature::class.java)

val signatureBytes = "signature".toByteArray()
val signerIdBytes = "signerId".toByteArray()

Mockito.`when`(aggregatedSignatureProto.verifierSignaturesList).thenReturn(
listOf(
com.google.protobuf.ByteString
.copyFrom(signatureBytes)
)
)
Mockito.`when`(aggregatedSignatureProto.signerIdsList).thenReturn(
listOf(
com.google.protobuf.ByteString
.copyFrom(signerIdBytes)
)
)

val flowAggregatedSignature = FlowAggregatedSignature.of(aggregatedSignatureProto)

assertEquals(1, flowAggregatedSignature.verifierSignatures.size)
assertEquals(FlowSignature(signatureBytes), flowAggregatedSignature.verifierSignatures[0])

assertEquals(1, flowAggregatedSignature.signerIds.size)
assertEquals(FlowId.of(signerIdBytes), flowAggregatedSignature.signerIds[0])
}

@Test
fun `test FlowAggregatedSignature builder function`() {
val signature1 = FlowSignature("signature1".toByteArray())
val signerId1 = FlowId.of("signerId1".toByteArray())

val aggregatedSignature = FlowAggregatedSignature(
verifierSignatures = listOf(signature1),
signerIds = listOf(signerId1)
)

val builderResult = aggregatedSignature.builder()

assertEquals(listOf(signature1.byteStringValue), builderResult.verifierSignaturesList)
assertEquals(listOf(signerId1.byteStringValue), builderResult.signerIdsList)
}
}
140 changes: 140 additions & 0 deletions sdk/src/test/kotlin/org/onflow/flow/sdk/models/FlowBlockSealTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
package org.onflow.flow.sdk.models

import org.junit.jupiter.api.Assertions.*
import org.junit.jupiter.api.Test
import org.mockito.Mockito
import org.onflow.flow.sdk.FlowAggregatedSignature
import org.onflow.flow.sdk.FlowBlockSeal
import org.onflow.flow.sdk.FlowId
import org.onflow.flow.sdk.FlowSignature
import org.onflow.protobuf.entities.BlockSealOuterClass

class FlowBlockSealTest {
@Test
fun `test FlowBlockSeal equals and hashCode`() {
val blockId = FlowId.of("blockId".toByteArray())
val executionReceiptId = FlowId.of("executionReceiptId".toByteArray())
val resultId = FlowId.of("resultId".toByteArray())
val finalState = "finalState".toByteArray()

val signature1 = FlowSignature("signature1".toByteArray())
val signature2 = FlowSignature("signature2".toByteArray())

val aggregatedSignature1 = FlowAggregatedSignature(
verifierSignatures = listOf(signature1),
signerIds = listOf(blockId)
)

val seal1 = FlowBlockSeal(
blockId = blockId,
executionReceiptId = executionReceiptId,
executionReceiptSignatures = listOf(signature1),
resultApprovalSignatures = listOf(signature2),
finalState = finalState,
resultId = resultId,
aggregatedApprovalSigs = listOf(aggregatedSignature1)
)

val seal2 = FlowBlockSeal(
blockId = blockId,
executionReceiptId = executionReceiptId,
executionReceiptSignatures = listOf(signature1),
resultApprovalSignatures = listOf(signature2),
finalState = finalState,
resultId = resultId,
aggregatedApprovalSigs = listOf(aggregatedSignature1)
)

// Testing equals
assertEquals(seal1, seal2)

// Testing hashCode
assertEquals(seal1.hashCode(), seal2.hashCode())
}

@Test
fun `test FlowBlockSeal of function`() {
// Mock BlockSealOuterClass.BlockSeal
val blockSealProto = Mockito.mock(BlockSealOuterClass.BlockSeal::class.java)

val blockIdBytes = "blockId".toByteArray()
val executionReceiptIdBytes = "executionReceiptId".toByteArray()
val resultIdBytes = "resultId".toByteArray()
val finalStateBytes = "finalState".toByteArray()

Mockito.`when`(blockSealProto.blockId).thenReturn(
com.google.protobuf.ByteString
.copyFrom(blockIdBytes)
)
Mockito.`when`(blockSealProto.executionReceiptId).thenReturn(
com.google.protobuf.ByteString
.copyFrom(executionReceiptIdBytes)
)
Mockito.`when`(blockSealProto.resultId).thenReturn(
com.google.protobuf.ByteString
.copyFrom(resultIdBytes)
)
Mockito.`when`(blockSealProto.finalState).thenReturn(
com.google.protobuf.ByteString
.copyFrom(finalStateBytes)
)
Mockito.`when`(blockSealProto.executionReceiptSignaturesList).thenReturn(
listOf(
com.google.protobuf.ByteString
.copyFrom("signature1".toByteArray())
)
)
Mockito.`when`(blockSealProto.resultApprovalSignaturesList).thenReturn(
listOf(
com.google.protobuf.ByteString
.copyFrom("signature2".toByteArray())
)
)
Mockito.`when`(blockSealProto.aggregatedApprovalSigsList).thenReturn(
listOf(
BlockSealOuterClass.AggregatedSignature.newBuilder().build()
)
)

val flowBlockSeal = FlowBlockSeal.of(blockSealProto)

assertEquals(FlowId.of(blockIdBytes), flowBlockSeal.blockId)
assertEquals(FlowId.of(executionReceiptIdBytes), flowBlockSeal.executionReceiptId)
assertEquals(FlowId.of(resultIdBytes), flowBlockSeal.resultId)
assertArrayEquals(finalStateBytes, flowBlockSeal.finalState)
}

@Test
fun `test FlowBlockSeal builder function`() {
val blockId = FlowId.of("blockId".toByteArray())
val executionReceiptId = FlowId.of("executionReceiptId".toByteArray())
val resultId = FlowId.of("resultId".toByteArray())
val finalState = "finalState".toByteArray()

val signature1 = FlowSignature("signature1".toByteArray())
val signature2 = FlowSignature("signature2".toByteArray())
val aggregatedSignature1 = FlowAggregatedSignature(
verifierSignatures = listOf(signature1),
signerIds = listOf(blockId)
)

val seal = FlowBlockSeal(
blockId = blockId,
executionReceiptId = executionReceiptId,
executionReceiptSignatures = listOf(signature1),
resultApprovalSignatures = listOf(signature2),
finalState = finalState,
resultId = resultId,
aggregatedApprovalSigs = listOf(aggregatedSignature1)
)

val builderResult = seal.builder()

assertEquals(blockId.byteStringValue, builderResult.blockId)
assertEquals(executionReceiptId.byteStringValue, builderResult.executionReceiptId)
assertEquals(resultId.byteStringValue, builderResult.resultId)
assertEquals(finalState.toList(), builderResult.finalState.toByteArray().toList())
assertEquals(listOf(signature1.byteStringValue), builderResult.executionReceiptSignaturesList)
assertEquals(listOf(signature2.byteStringValue), builderResult.resultApprovalSignaturesList)
}
}
Loading