Skip to content

Commit

Permalink
Merge pull request #22 from XYOracleNetwork/feature/previous-hash-bw
Browse files Browse the repository at this point in the history
include previous hash in boundwitnesses
  • Loading branch information
jonesmac authored Nov 19, 2024
2 parents e5bdb54 + 4afea98 commit 508fc1b
Show file tree
Hide file tree
Showing 15 changed files with 84 additions and 63 deletions.
21 changes: 16 additions & 5 deletions sdk/src/androidTest/java/network/xyo/client/NodeClientTest.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package network.xyo.client

import android.content.Context
import androidx.test.platform.app.InstrumentationRegistry
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import network.xyo.client.account.Account
import network.xyo.client.archivist.wrapper.ArchivistWrapper
import network.xyo.client.node.client.NodeClient
import network.xyo.client.payload.XyoPayload
import org.junit.Before
import org.junit.Test
import org.junit.jupiter.api.Assertions.*

Expand All @@ -16,15 +19,23 @@ class DiscoverPayload(): XyoPayload() {
class NodeClientTest {
private val apiDomainBeta = "${TestConstants.nodeUrlBeta}/Archivist"

private lateinit var appContext: Context

@Before
fun useAppContext() {
// Context of the app under test.
this.appContext = InstrumentationRegistry.getInstrumentation().targetContext
}

@OptIn(ExperimentalCoroutinesApi::class)
@Test
fun discoverTestBeta() {
val account = Account.random()
val client = NodeClient(TestConstants.nodeUrlBeta, account)
val client = NodeClient(TestConstants.nodeUrlBeta, account, appContext)
val query = DiscoverPayload()

runBlocking {
val postResult = client.query(query, null, null)
val postResult = client.query(query, null)
assertEquals(null, postResult.errors)
}
}
Expand All @@ -46,12 +57,12 @@ class NodeClientTest {

@Test
fun archivistInsertTest() {
val archivist = ArchivistWrapper(NodeClient(apiDomainBeta, TestConstants.TestAccount))
val archivist = ArchivistWrapper(NodeClient(apiDomainBeta, TestConstants.TestAccount, appContext))

val payloads = arrayListOf(TestConstants.debugPayload)

runBlocking {
val (response, errors) = archivist.insert(payloads, null)
val (response, errors) = archivist.insert(payloads)
assertNotEquals(response, null)
assertEquals(errors, null)

Expand All @@ -63,7 +74,7 @@ class NodeClientTest {
}

runBlocking {
val getResult = archivist.get(arrayListOf(TestConstants.debugPayloadHash), null)
val getResult = archivist.get(arrayListOf(TestConstants.debugPayloadHash))
assertNotEquals(getResult.response, null)

val response = getResult.response
Expand Down
22 changes: 19 additions & 3 deletions sdk/src/androidTest/java/network/xyo/client/XyoBoundWitnessTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import network.xyo.client.account.Account
import network.xyo.client.boundwitness.XyoBoundWitnessBuilder
import network.xyo.client.datastore.previous_hash_store.PreviousHashStorePrefsRepository
import network.xyo.client.node.client.NodeClient
import network.xyo.client.payload.XyoPayload
import org.junit.Before
Expand Down Expand Up @@ -34,9 +35,14 @@ class XyoBoundWitnessTest {
this.appContext = InstrumentationRegistry.getInstrumentation().targetContext
}

@Before
fun setupAccount() {
Account.previousHashStore = PreviousHashStorePrefsRepository.getInstance(InstrumentationRegistry.getInstrumentation().targetContext)
}

fun generateQuery(nodeUrl: String): RequestDependencies {
val account = Account.random()
val client = NodeClient(nodeUrl, account)
val client = NodeClient(nodeUrl, account, appContext)
val query = DiscoverPayload()
val payloads = mutableListOf<XyoPayload>()
payloads.add(TestPayload1())
Expand All @@ -47,7 +53,7 @@ class XyoBoundWitnessTest {
fun testSendQueryBW(nodeUrl: String) {
runBlocking {
val(client, query, payloads) = generateQuery(nodeUrl)
val postResult = client.query(query, payloads, null)
val postResult = client.query(query, payloads)
assertEquals(null, postResult.errors)
}
}
Expand All @@ -66,11 +72,21 @@ class XyoBoundWitnessTest {
@Test
fun testBoundWitnessHash() {
runBlocking {
val bw = XyoBoundWitnessBuilder().signer(Account.random()).payloads(listOf(TestPayload1())).build()
val bw = XyoBoundWitnessBuilder(appContext).signer(Account.random()).payloads(listOf(TestPayload1())).build()
val hashableFields = bw.getBodyJson()
assert(bw._hash !== null)
assert(bw._hash!! == XyoSerializable.sha256String(hashableFields))
assert(bw._hash!! == hashableFields.hash())
}
}

@Test
fun testBoundWitnessPreviousHash() {
runBlocking {
val testAccount = Account.random()
val bw = XyoBoundWitnessBuilder(appContext).signer(testAccount).payloads(listOf(TestPayload1())).build()
val bw2 = XyoBoundWitnessBuilder(appContext).signer(testAccount).payloads(listOf(TestPayload1())).build()
assert(bw2.previous_hashes.contains(bw._hash))
}
}
}
4 changes: 2 additions & 2 deletions sdk/src/androidTest/java/network/xyo/client/XyoPanelTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ class XyoPanelTest {
runBlocking {
val witnessAccount = Account.fromPrivateKey("9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08")
val witness2Account = Account.fromPrivateKey("5a95531488b4d0d3645aea49678297ae9e2034879ce0389b80eb788e8b533592")
val witness = XyoWitness(witnessAccount, fun(_: Context, _: String?): List<XyoPayload> {
val witness = XyoWitness(witnessAccount, fun(_: Context): List<XyoPayload> {
return listOf(BasicPayload())
})
val panel = XyoPanel(appContext, Account.random(), arrayListOf(Pair(nodeUrl, Account.random())), listOf(witness, XyoSystemInfoWitness(witness2Account), XyoLocationWitness()))
Expand Down Expand Up @@ -94,7 +94,7 @@ class XyoPanelTest {
@Test
fun testSimplePanelReport() {
runBlocking {
val panel = XyoPanel(appContext, Account.random(), fun(_:Context, _: String?): List<XyoEventPayload> {
val panel = XyoPanel(appContext, Account.random(), fun(_:Context): List<XyoEventPayload> {
return listOf(XyoEventPayload("test_event"))
})
val result = panel.reportAsyncQuery()
Expand Down
4 changes: 2 additions & 2 deletions sdk/src/androidTest/java/network/xyo/client/XyoPayloadTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,14 @@ class XyoPayloadTest {
@Test
fun testRoundTripPanel() {
val address = Account.fromPrivateKey("5a95531488b4d0d3645aea49678297ae9e2034879ce0389b80eb788e8b533592")
val witness = XyoWitness(address, fun(_: Context, _: String?): List<XyoPayload> {
val witness = XyoWitness(address, fun(_: Context): List<XyoPayload> {
return listOf(BasicPayload())
})

CoroutineScope(Dispatchers.Main).launch {
val response = arrayListOf(witness.observe(appContext))
val payloads = response.mapNotNull { payload -> payload }.flatten()
val bwJson = XyoBoundWitnessBuilder()
val bwJson = XyoBoundWitnessBuilder(appContext)
.payloads(payloads)
.signer(Account.random())
.build()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ class AccountPrefsRepositoryTest {
assertEquals(firstAccount.privateKey.toHexString(), testAccount.privateKey.toHexString())

// Sign with the test account
val firstBw = XyoBoundWitnessBuilder().signer(firstAccount).payloads(listOf(
val firstBw = XyoBoundWitnessBuilder(appContext).signer(firstAccount).payloads(listOf(
TestConstants.debugPayload
)).build()
val firstAddress = firstBw.addresses.first()
Expand All @@ -141,7 +141,7 @@ class AccountPrefsRepositoryTest {
val secondAccount = secondInstance.getAccount()

// Sign with the test account
val secondBw = XyoBoundWitnessBuilder().signer(secondAccount).payloads(listOf(
val secondBw = XyoBoundWitnessBuilder(appContext).signer(secondAccount).payloads(listOf(
TestConstants.debugPayload
)).build()
val secondAddress = secondBw.addresses.first()
Expand Down
17 changes: 7 additions & 10 deletions sdk/src/main/java/network/xyo/client/XyoPanel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ class XyoPanel(
private val witnesses: List<XyoWitness<XyoPayload>>?,
private val nodeUrlsAndAccounts: ArrayList<Pair<String, AccountInstance?>>?
) {
var previousHash: String? = null
private var nodes: MutableList<NodeClient>? = null
var defaultAccount: AccountInstance? = null

Expand Down Expand Up @@ -80,7 +79,7 @@ class XyoPanel(
constructor(
context: Context,
account: AccountInstance,
observe: ((context: Context, previousHash: String?) -> List<XyoEventPayload>?)?
observe: ((context: Context) -> List<XyoEventPayload>?)?
): this(
context,
account,
Expand All @@ -96,7 +95,7 @@ class XyoPanel(
this@XyoPanel.nodeUrlsAndAccounts.forEach { pair ->
val nodeUrl = pair.first
val account = pair.second ?: defaultAccount
it.add(NodeClient(nodeUrl, account))
it.add(NodeClient(nodeUrl, account, context))
}
it
}
Expand All @@ -114,7 +113,7 @@ class XyoPanel(
suspend fun eventAsync(event: String): XyoPanelReportResult {
val adhocWitnessList = listOf(
XyoWitness({
_, previousHash -> listOf(XyoEventPayload(event))
_, -> listOf(XyoEventPayload(event))
})
)
return this.reportAsync(adhocWitnessList)
Expand All @@ -124,7 +123,7 @@ class XyoPanel(
suspend fun eventAsyncQuery(event: String): XyoPanelReportQueryResult {
val adhocWitnessList = listOf(
XyoWitness({
_, previousHash -> listOf(XyoEventPayload(event))
_, -> listOf(XyoEventPayload(event))
})
)
return reportAsyncQuery(adhocWitnessList)
Expand All @@ -147,10 +146,10 @@ class XyoPanel(
private suspend fun generateBoundWitnessJson(adhocWitnesses: List<XyoWitness<XyoPayload>> = emptyList()): XyoBoundWitnessJson {
val witnesses: List<XyoWitness<XyoPayload>> = (this.witnesses ?: emptyList()).plus(adhocWitnesses)
val payloads = generatePayloads()
return XyoBoundWitnessBuilder()
return XyoBoundWitnessBuilder(context)
.payloads(payloads)
.signer(account)
.build(previousHash)
.build()
}


Expand All @@ -167,7 +166,6 @@ class XyoPanel(
@kotlinx.coroutines.ExperimentalCoroutinesApi
suspend fun reportAsync(adhocWitnesses: List<XyoWitness<XyoPayload>> = emptyList()): XyoPanelReportResult {
val bw = generateBoundWitnessJson(adhocWitnesses)
previousHash = bw._hash
val results = mutableListOf<PostBoundWitnessesResult>()
archivists?.forEach { archivist ->
results.add(archivist.postBoundWitnessAsync(bw))
Expand All @@ -179,7 +177,6 @@ class XyoPanel(
suspend fun reportAsyncQuery(adhocWitnesses: List<XyoWitness<XyoPayload>> = emptyList()): XyoPanelReportQueryResult {
if (nodes == null) resolveNodes()
val bw = generateBoundWitnessJson()
previousHash = bw._hash
val payloads = generatePayloads(adhocWitnesses)
val results = mutableListOf<PostQueryResult>()

Expand All @@ -190,7 +187,7 @@ class XyoPanel(
nodes?.forEach { node ->
val archivist = ArchivistWrapper(node)
val payloadsWithBoundWitness = payloads.plus(bw)
val queryResult = archivist.insert(payloadsWithBoundWitness, previousHash)
val queryResult = archivist.insert(payloadsWithBoundWitness)
results.add(queryResult)
}
return XyoPanelReportQueryResult(bw, results, payloads)
Expand Down
17 changes: 7 additions & 10 deletions sdk/src/main/java/network/xyo/client/XyoWitness.kt
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,34 @@ import network.xyo.client.account.model.AccountInstance
import network.xyo.client.payload.XyoPayload

abstract class DeferredObserver<out T: XyoPayload> {
abstract suspend fun deferredDetect(context: Context, previousHash: String?): List<T>?
abstract suspend fun deferredDetect(context: Context): List<T>?
}

@RequiresApi(Build.VERSION_CODES.M)
open class XyoWitness<out T: XyoPayload> (
val address: AccountInstance = Account.random(),
private val observer: ((context: Context, previousHash: String) -> List<T>?)? = null,
var previousHash: String = "",
private val observer: ((context: Context) -> List<T>?)? = null,
val deferredObserver: DeferredObserver<T>? = null
) {

constructor(
observer: ((context: Context, previousHash: String) -> List<T>?)?,
previousHash: String = "",
observer: ((context: Context) -> List<T>?)?,
account: AccountInstance = Account.random()
): this(account, observer, previousHash, null)
): this(account, observer)

constructor(
observer: DeferredObserver<T>?,
previousHash: String = "",
account: AccountInstance = Account.random()
): this(account, null, previousHash, observer)
): this(account, null, observer)

open suspend fun observe(context: Context): List<T>? {
val appContext = context.applicationContext
if (deferredObserver !== null) {
val payload = deferredObserver.deferredDetect(appContext, previousHash)
val payload = deferredObserver.deferredDetect(appContext)
return payload
}
observer?.let {
val payloads = it(appContext, previousHash)
val payloads = it(appContext)
return payloads
}
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,15 @@ import network.xyo.client.payload.XyoPayload
open class ArchivistWrapper(private val nodeClient: NodeClient) {
@OptIn(ExperimentalCoroutinesApi::class)
@RequiresApi(Build.VERSION_CODES.M)
suspend fun get(hashes: List<String>, previousHash: String?): PostQueryResult {
suspend fun get(hashes: List<String>): PostQueryResult {
val query = ArchivistGetQueryPayload(hashes)
return nodeClient.query(query, null, previousHash)
return nodeClient.query(query, null)
}

@OptIn(ExperimentalCoroutinesApi::class)
@RequiresApi(Build.VERSION_CODES.M)
suspend fun insert(payloads: List<XyoPayload>, previousHash: String?): PostQueryResult {
suspend fun insert(payloads: List<XyoPayload>): PostQueryResult {
val query = ArchivistInsertQueryPayload()
return nodeClient.query(query, payloads, previousHash)
return nodeClient.query(query, payloads)
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package network.xyo.client.boundwitness

import android.content.Context
import android.os.Build
import androidx.annotation.RequiresApi
import network.xyo.client.XyoSerializable
Expand All @@ -8,7 +9,7 @@ import network.xyo.client.payload.XyoPayload


@RequiresApi(Build.VERSION_CODES.M)
class QueryBoundWitnessBuilder : XyoBoundWitnessBuilder() {
class QueryBoundWitnessBuilder(context: Context) : XyoBoundWitnessBuilder(context) {
private lateinit var queryHash: String

fun query(query: XyoPayload): QueryBoundWitnessBuilder {
Expand All @@ -27,13 +28,12 @@ class QueryBoundWitnessBuilder : XyoBoundWitnessBuilder() {
return this
}

override suspend fun build(previousHash: String?): QueryBoundWitnessJson {
override suspend fun build(): QueryBoundWitnessJson {
bw = QueryBoundWitnessJson()
// override to support additional properties for query bound witnesses
return bw.let {
val qbw = it as QueryBoundWitnessJson
qbw.query = this.queryHash
qbw._previous_hash = previousHash
constructFields()
it
}
Expand Down
Loading

0 comments on commit 508fc1b

Please sign in to comment.