From c85258154165ca155dd7f3fc569c3ab3eed4461f Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Fri, 22 Nov 2024 10:01:56 -0800 Subject: [PATCH 01/11] refactor: rename field --- .../main/java/org/dashj/platform/dashpay/BlockchainIdentity.kt | 2 +- dpp/src/main/java/org/dashj/platform/dpp/voting/Contenders.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dpp/src/main/java/org/dashj/platform/dashpay/BlockchainIdentity.kt b/dpp/src/main/java/org/dashj/platform/dashpay/BlockchainIdentity.kt index 09f250c..157826a 100644 --- a/dpp/src/main/java/org/dashj/platform/dashpay/BlockchainIdentity.kt +++ b/dpp/src/main/java/org/dashj/platform/dashpay/BlockchainIdentity.kt @@ -839,7 +839,7 @@ class BlockchainIdentity { val documentWithVotes = contenders.map[uniqueIdentifier] ?: error("$username does not have $uniqueIdentifier as a contender") - val recoveredDocument = documentWithVotes.seralizedDocument?.let { + val recoveredDocument = documentWithVotes.serializedDocument?.let { platform.names.deserialize(it) } diff --git a/dpp/src/main/java/org/dashj/platform/dpp/voting/Contenders.kt b/dpp/src/main/java/org/dashj/platform/dpp/voting/Contenders.kt index 9638b60..d472680 100644 --- a/dpp/src/main/java/org/dashj/platform/dpp/voting/Contenders.kt +++ b/dpp/src/main/java/org/dashj/platform/dpp/voting/Contenders.kt @@ -12,7 +12,7 @@ typealias RustContestedResources = org.dashj.platform.sdk.ContestedResources typealias RustContestedResource = org.dashj.platform.sdk.ContestedResource -data class ContenderWithSerializedDocument(val identityId: Identifier, val seralizedDocument: ByteArray?, val votes: Int) { +data class ContenderWithSerializedDocument(val identityId: Identifier, val serializedDocument: ByteArray?, val votes: Int) { constructor(contenderWithSerializedDocument: RustContenderWithSerializedDocument) : this( Identifier.from(contenderWithSerializedDocument.v0._0.identity_id.bytes), contenderWithSerializedDocument.v0._0.serialized_document, From ea0fc14c9e0579c437f362224a5b1dc606fcaf3a Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Fri, 22 Nov 2024 10:05:05 -0800 Subject: [PATCH 02/11] fix: improve get vote polls related methods --- .../java/org/dashj/platform/sdk/VoteTest.java | 9 +- .../dashj/platform/dapiclient/DapiClient.kt | 28 ++++- .../org/dashj/platform/dpp/voting/Vote.kt | 7 +- .../dashj/platform/sdk/platform/Documents.kt | 104 +++++++++++++++++- .../org/dashj/platform/sdk/platform/Names.kt | 27 ++--- platform-mobile/src/voting.rs | 23 +++- 6 files changed, 162 insertions(+), 36 deletions(-) diff --git a/dash-sdk-java/src/test/java/org/dashj/platform/sdk/VoteTest.java b/dash-sdk-java/src/test/java/org/dashj/platform/sdk/VoteTest.java index b5839d9..ebc85cd 100644 --- a/dash-sdk-java/src/test/java/org/dashj/platform/sdk/VoteTest.java +++ b/dash-sdk-java/src/test/java/org/dashj/platform/sdk/VoteTest.java @@ -129,15 +129,14 @@ public void getContestedResources() throws Exception { @Test public void getVotePoolsTest() throws Exception { - Identifier dpnsContractid = new Identifier(dpnsContractId); - - //SWIGTYPE_p_DashSdk mainnetSdk = dashsdk.platformMobileSdkCreateDashSdk(BigInteger.ZERO, BigInteger.ZERO, false); - - Result result = dashsdk.platformMobileVotingGetVotepolls( + Result result = dashsdk.platformMobileVotingGetVotePolls( sdk, new TimestampMillis(System.currentTimeMillis()), true, new TimestampMillis(System.currentTimeMillis() + 14 * 24 * 3600 * 1000), + true, + 100, + 0, true ); diff --git a/dpp/src/main/java/org/dashj/platform/dapiclient/DapiClient.kt b/dpp/src/main/java/org/dashj/platform/dapiclient/DapiClient.kt index 2743ed5..d2293eb 100644 --- a/dpp/src/main/java/org/dashj/platform/dapiclient/DapiClient.kt +++ b/dpp/src/main/java/org/dashj/platform/dapiclient/DapiClient.kt @@ -99,6 +99,7 @@ class DapiClient( const val DEFAULT_WAIT_FOR_NODES = 5 const val DEFAULT_HTTP_TIMEOUT = 10L const val REQUIRED_SUCCESS_RATE = 0.50 // 50% + const val DEFAULT_LIMIT = 100 } var contextProvider = object : ContextProvider() { override fun getQuorumPublicKey( @@ -1125,13 +1126,34 @@ class DapiClient( return Vote(result.unwrap()) } - fun getVotePolls(startTime: Long, startTimeIncluded: Boolean = true, endTime:Long, endTimeIncluded: Boolean = true): VotePollsGroupedByTimestamp { - val result = dashsdk.platformMobileVotingGetVotepolls( + /** + * Get vote polls within a specific time frame + * + * @param startTime + * @param startTimeIncluded + * @param endTime + * @param endTimeIncluded + * @param limit Number of records to return (default = 100) + * @param orderAscending + * @return [VotePollsGroupedByTimestamp] + */ + fun getVotePolls( + startTime: Long, + startTimeIncluded: Boolean = true, + endTime:Long, + endTimeIncluded: Boolean = true, + limit: Int = DEFAULT_LIMIT, + orderAscending: Boolean = true + ): VotePollsGroupedByTimestamp { + val result = dashsdk.platformMobileVotingGetVotePolls( rustSdk, startTime.toTimestampMillis(), startTimeIncluded, endTime.toTimestampMillis(), - endTimeIncluded + endTimeIncluded, + limit, + 0, + orderAscending ) return VotePollsGroupedByTimestamp(result.unwrap()); } diff --git a/dpp/src/main/java/org/dashj/platform/dpp/voting/Vote.kt b/dpp/src/main/java/org/dashj/platform/dpp/voting/Vote.kt index 93e2a22..04c517c 100644 --- a/dpp/src/main/java/org/dashj/platform/dpp/voting/Vote.kt +++ b/dpp/src/main/java/org/dashj/platform/dpp/voting/Vote.kt @@ -1,6 +1,7 @@ package org.dashj.platform.dpp.voting import org.dashj.platform.dpp.identifier.Identifier +import org.dashj.platform.dpp.util.convertPlatformValue import org.dashj.platform.dpp.util.convertToPlatformValue import org.dashj.platform.sdk.ResourceVoteV0 @@ -101,17 +102,17 @@ abstract class VotePoll { typealias RustContestedDocumentResourceVotePoll = org.dashj.platform.sdk.ContestedDocumentResourceVotePoll -class ContestedDocumentResourceVotePoll( +data class ContestedDocumentResourceVotePoll( val dataContractId: Identifier, val documentTypeName: String, val indexName: String, - val indexValues: List + val indexValues: List ): VotePoll() { constructor(votePoll: RustContestedDocumentResourceVotePoll) : this( Identifier.from(votePoll.contract_id.bytes), votePoll.document_type_name, votePoll.index_name, - votePoll.index_values + votePoll.index_values.map { convertPlatformValue(it).toString() } ) override fun toNative(): RustVotePoll { diff --git a/dpp/src/main/java/org/dashj/platform/sdk/platform/Documents.kt b/dpp/src/main/java/org/dashj/platform/sdk/platform/Documents.kt index cb55f37..b1b9bca 100644 --- a/dpp/src/main/java/org/dashj/platform/sdk/platform/Documents.kt +++ b/dpp/src/main/java/org/dashj/platform/sdk/platform/Documents.kt @@ -6,15 +6,19 @@ */ package org.dashj.platform.sdk.platform +import com.google.common.base.Preconditions import io.grpc.StatusRuntimeException import org.bitcoinj.core.ECKey +import org.bitcoinj.core.NetworkParameters import org.bitcoinj.core.Sha256Hash +import org.dashj.platform.dapiclient.DapiClient import org.dashj.platform.dapiclient.model.DocumentQuery import org.dashj.platform.dpp.document.Document import org.dashj.platform.dpp.errors.DriveErrorMetadata import org.dashj.platform.dpp.identifier.Identifier import org.dashj.platform.dpp.identity.Identity import org.dashj.platform.dpp.identity.IdentityPublicKey +import org.dashj.platform.dpp.voting.Contenders import org.dashj.platform.dpp.voting.ContestedDocumentResourceVotePoll import org.dashj.platform.dpp.voting.ResourceVote import org.dashj.platform.dpp.voting.ResourceVoteChoice @@ -23,12 +27,16 @@ import org.dashj.platform.dpp.voting.VotePoll import org.dashj.platform.sdk.callbacks.Signer import org.slf4j.Logger import org.slf4j.LoggerFactory +import java.util.concurrent.TimeUnit class Documents(val platform: Platform) { companion object { - const val DOCUMENT_LIMIT = 100 + const val DOCUMENT_LIMIT = DapiClient.DEFAULT_LIMIT private val log: Logger = LoggerFactory.getLogger(Documents::class.java) + + fun votingPeriod(params: NetworkParameters): Long = if (params.id == NetworkParameters.ID_MAINNET) TimeUnit.DAYS.toMillis(14) else TimeUnit.MINUTES.toMillis(90) + } fun broadcast(identity: Identity, privateKey: ECKey, create: List?, replace: List? = null, delete: List? = null) { @@ -186,12 +194,29 @@ class Documents(val platform: Platform) { ) } + fun getVoteContenders( + dataContractId: Identifier, + documentType: String, + indexName: String, + indexes: List, + ): Contenders { + Preconditions.checkArgument(documentType.isNotEmpty()) + Preconditions.checkArgument(indexName.isNotEmpty()) + Preconditions.checkArgument(indexes.isNotEmpty()) + return platform.client.getVoteContenders( + dataContractId, + documentType, + indexName, + indexes + ) + } + fun broadcastVote( resourceVoteChoice: ResourceVoteChoice, dataContractId: Identifier, documentType: String, indexName: String, - indexValues: List, + indexValues: List, voterProTxHash: Sha256Hash, identityPublicKey: IdentityPublicKey, signerCallback: Signer @@ -208,8 +233,21 @@ class Documents(val platform: Platform) { fun getVotePolls( dataContractId: Identifier, documentType: String, - startTime: Long, startTimeIncluded: Boolean = true, endTime:Long, endTimeIncluded: Boolean = true): List { - val votePollsGroupedByTimestamp = platform.client.getVotePolls(startTime, startTimeIncluded, endTime, endTimeIncluded) + startTime: Long, + startTimeIncluded: Boolean = true, + endTime:Long, + endTimeIncluded: Boolean = true, + limit: Int = DOCUMENT_LIMIT, + orderAscending: Boolean = true + ): List { + val votePollsGroupedByTimestamp = platform.client.getVotePolls( + startTime, + startTimeIncluded, + endTime, + endTimeIncluded, + limit, + orderAscending + ) val result = arrayListOf() votePollsGroupedByTimestamp.list.forEach { votePollGroup -> @@ -227,6 +265,64 @@ class Documents(val platform: Platform) { return result } + fun getAllVotePolls( + dataContractId: Identifier, + documentType: String, + startTime: Long, + startTimeIncluded: Boolean = true, + endTime:Long, + endTimeIncluded: Boolean = true, + orderAscending: Boolean = true + ): List { + var count = 0 + var currentStartTime = startTime + var currentStartTimeIncluded = startTimeIncluded + val results = arrayListOf() + do { + val batch = getVotePolls( + dataContractId, + documentType, + currentStartTime, + currentStartTimeIncluded, + endTime, + endTimeIncluded, DOCUMENT_LIMIT, orderAscending) + count = batch.size + val lastVotePoll = batch.last() + currentStartTime = when (lastVotePoll) { + is ContestedDocumentResourceVotePoll -> { + val voteContenders = getVoteContenders( + lastVotePoll.dataContractId, + lastVotePoll.documentTypeName, + lastVotePoll.indexName, + lastVotePoll.indexValues + ) + val createdAt = voteContenders.map.minOf { contenders -> + val document = deserialize( + contenders.value.serializedDocument!!, + lastVotePoll.dataContractId, + lastVotePoll.documentTypeName + ) + document.createdAt ?: 0 + } + createdAt + votingPeriod(platform.params) + } + else -> -1L + } + currentStartTimeIncluded = true + results.addAll( + batch.filter { + when (it) { + is ContestedDocumentResourceVotePoll -> { + it.dataContractId == dataContractId && it.documentTypeName == documentType + } + else -> false + } + } + ) + } while (count == 100 && currentStartTime != -1L) + return results + } + fun getVoteFromMasternode(proTxHash: Sha256Hash, dataContractId: Identifier, documentType: String, indexName: String, indexes: List) { platform.client.getLastVoteFromMasternode(proTxHash, dataContractId, documentType, indexName, indexes) } diff --git a/dpp/src/main/java/org/dashj/platform/sdk/platform/Names.kt b/dpp/src/main/java/org/dashj/platform/sdk/platform/Names.kt index 41cf664..2693278 100644 --- a/dpp/src/main/java/org/dashj/platform/sdk/platform/Names.kt +++ b/dpp/src/main/java/org/dashj/platform/sdk/platform/Names.kt @@ -102,8 +102,6 @@ class Names(val platform: Platform) { val regex = Regex("^[a-zA-Z01-]{3,19}$") return regex.matches(username) } - - fun votingPeriod(params: NetworkParameters): Long = if (params.id == NetworkParameters.ID_MAINNET) TimeUnit.DAYS.toMillis(14) else TimeUnit.MINUTES.toMillis(90) } fun register( @@ -435,18 +433,12 @@ class Names(val platform: Platform) { if (it.dataContractId == SystemIds.dpnsDataContractId && it.indexName == CONTESTED_INDEX && it.indexValues.get(0) == DEFAULT_PARENT_DOMAIN) { - when (val normalizedLabelValue = it.indexValues[1]) { - is PlatformValue -> { - if (normalizedLabelValue.tag == PlatformValue.Tag.Text) { - resources.add(normalizedLabelValue.text) - } - } - is String -> resources.add(normalizedLabelValue) - else -> error("invalid type") - } - } + val normalizedLabelValue = it.indexValues[1] + resources.add(normalizedLabelValue) } + } + else -> { + // ignore unknown Vote Poll type } - else -> {} } } return resources @@ -489,14 +481,19 @@ class Names(val platform: Platform) { return if (documents.isNotEmpty()) documents[0] else null } + /** + * Get current vote polls for contested names + * + * @return list of active vote polls for contested names + */ fun getCurrentVotePolls() : List { val currentTime = System.currentTimeMillis() - return platform.documents.getVotePolls( + return platform.documents.getAllVotePolls( SystemIds.dpnsDataContractId, DOMAIN_DOCUMENT, currentTime, true, - currentTime + votingPeriod(platform.params) + currentTime + Documents.votingPeriod(platform.params) ) } diff --git a/platform-mobile/src/voting.rs b/platform-mobile/src/voting.rs index 560e04b..6683a43 100644 --- a/platform-mobile/src/voting.rs +++ b/platform-mobile/src/voting.rs @@ -330,7 +330,10 @@ fn get_contested_resources_test() { let resources_result = get_contested_resources( &mut sdk, "domain".to_string(), - contract_id + contract_id, + 100, + None, + false ); match resources_result { Ok(resources) => println!("contested resources = {:?}", resources), @@ -405,28 +408,30 @@ fn get_votes_test() { /// `normalizedLabel` of the `domain` document of the DPNS contract. [start_time] should be set to /// the current time and the [end_time] should be set to 14 days from the [start_time]. #[ferment_macro::export] -pub fn get_votepolls( +pub fn get_vote_polls( rust_sdk: * mut DashSdk, start_time: TimestampMillis, start_time_included: bool, end_time: TimestampMillis, - end_time_included: bool + end_time_included: bool, + limit: u16, + offset: u16, + order_ascending: bool ) -> Result{ let rt = unsafe { (*rust_sdk).get_runtime() }.clone(); rt.block_on(async { let sdk = unsafe { (*rust_sdk).get_sdk() }; - let settings = unsafe { (*rust_sdk).get_request_settings() }; tracing::info!("get_vote_polls({}, {})", start_time, end_time); let query = VotePollsByEndDateDriveQuery { start_time: Some((start_time, start_time_included)), end_time: Some((end_time, end_time_included)), - limit: None, + limit: Some(limit), offset: None, - order_ascending: true, + order_ascending, }; match VotePoll::fetch_many(&sdk, query.clone()).await { @@ -454,6 +459,9 @@ fn get_votepolls_test() { start_mills, true, start_mills + 14 * 24 * 3600 * 1000, + true, + 100, + 0, true ); match resources_result { @@ -477,6 +485,9 @@ fn get_votepolls_mainnet_test() { start_mills, true, start_mills + 14 * 24 * 3600 * 1000, + true, + 100, + 0, true ); match resources_result { From f56b047a2ad166c4986e2efa96d6b7c34c68d917 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Fri, 22 Nov 2024 10:06:04 -0800 Subject: [PATCH 03/11] feat: add ContestedNames example --- .../dashj/org/platform/ContestedNames.kt | 53 +++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 examples/src/main/kotlin/dashj/org/platform/ContestedNames.kt diff --git a/examples/src/main/kotlin/dashj/org/platform/ContestedNames.kt b/examples/src/main/kotlin/dashj/org/platform/ContestedNames.kt new file mode 100644 index 0000000..d630dde --- /dev/null +++ b/examples/src/main/kotlin/dashj/org/platform/ContestedNames.kt @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2024-present, Dash Core Group + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +package dashj.org.platform + +import org.dashj.platform.dapiclient.SystemIds +import org.dashj.platform.dpp.voting.ContestedDocumentResourceVotePoll +import org.dashj.platform.sdk.Client +import org.dashj.platform.sdk.client.ClientOptions +import org.dashj.platform.sdk.platform.Documents + +/** + * ContestedNames - Display all of the currently contested usernames + */ +class ContestedNames { + companion object { + lateinit var sdk: Client + + @JvmStatic + fun main(args: Array) { + sdk = Client(ClientOptions(network = args[0])) + sdk.platform.useValidNodes() + getDocuments() + } + + private fun getDocuments() { + val platform = sdk.platform + + val votePolls = platform.documents.getAllVotePolls( + SystemIds.dpnsDataContractId, + "domain", + System.currentTimeMillis(), + true, + System.currentTimeMillis() + Documents.votingPeriod(platform.params), + true, + orderAscending = true + ) + + println("${votePolls.size} results returned") + votePolls.forEach { + when(it) { + is ContestedDocumentResourceVotePoll -> { + println(it.indexValues[1]) + } + else -> println("unknown vote poll type") + } + } + } + } +} \ No newline at end of file From f75128854fe4de18f71ca9eb5e64717eda3c1153 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Sat, 23 Nov 2024 09:29:57 -0800 Subject: [PATCH 04/11] refactor: rename get_votepolls to get_vote_polls --- platform-mobile/src/voting.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/platform-mobile/src/voting.rs b/platform-mobile/src/voting.rs index 6683a43..d4f07d5 100644 --- a/platform-mobile/src/voting.rs +++ b/platform-mobile/src/voting.rs @@ -454,7 +454,7 @@ fn get_votepolls_test() { .expect("Time went backwards"); let start_mills = since_the_epoch.as_millis() as u64; - let resources_result = get_votepolls( + let resources_result = get_vote_polls( &mut sdk, start_mills, true, @@ -480,7 +480,7 @@ fn get_votepolls_mainnet_test() { .expect("Time went backwards"); let start_mills = since_the_epoch.as_millis() as u64; - let resources_result = get_votepolls( + let resources_result = get_vote_polls( &mut sdk, start_mills, true, From 7c26d1d990abea6c73c0e24d887cb4f26a112ef2 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Sat, 23 Nov 2024 11:18:58 -0800 Subject: [PATCH 05/11] feat: add field id constant to Document --- dpp/src/main/java/org/dashj/platform/dpp/document/Document.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dpp/src/main/java/org/dashj/platform/dpp/document/Document.kt b/dpp/src/main/java/org/dashj/platform/dpp/document/Document.kt index 81aa5b8..0153dd6 100644 --- a/dpp/src/main/java/org/dashj/platform/dpp/document/Document.kt +++ b/dpp/src/main/java/org/dashj/platform/dpp/document/Document.kt @@ -23,7 +23,9 @@ import kotlin.collections.HashMap typealias RustDocument = org.dashj.platform.sdk.Document class Document : BaseObject { - + companion object { + const val FIELD_ID = "\$id" + } var dataContract: DataContract? = null var id: Identifier var type: String? = null From 0f5e35224c9ed470ea8be2112acbed9c2fe5ad68 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Sat, 23 Nov 2024 11:19:57 -0800 Subject: [PATCH 06/11] fix: improve error text for Documents.get --- .../main/java/org/dashj/platform/sdk/platform/Documents.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dpp/src/main/java/org/dashj/platform/sdk/platform/Documents.kt b/dpp/src/main/java/org/dashj/platform/sdk/platform/Documents.kt index b1b9bca..98b8b2c 100644 --- a/dpp/src/main/java/org/dashj/platform/sdk/platform/Documents.kt +++ b/dpp/src/main/java/org/dashj/platform/sdk/platform/Documents.kt @@ -176,12 +176,12 @@ class Documents(val platform: Platform) { } catch (e: StatusRuntimeException) { log.error( "Document query: unable to get documents of $dataContractId: " + - "${DriveErrorMetadata(e.trailers.toString())}", + "${DriveErrorMetadata(e.trailers.toString())} with $opts", e ) throw e } catch (e: Exception) { - log.error("Document query: unable to get documents of $dataContractId", e) + log.error("Document query: unable to get documents of $dataContractId with $opts", e) throw e } } From c99494ffb43caf4599149ca3c4b68b42758b157d Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Sat, 23 Nov 2024 11:20:24 -0800 Subject: [PATCH 07/11] fix: set default DocumentQuery limit to 100 --- .../java/org/dashj/platform/dapiclient/model/DocumentQuery.kt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dpp/src/main/java/org/dashj/platform/dapiclient/model/DocumentQuery.kt b/dpp/src/main/java/org/dashj/platform/dapiclient/model/DocumentQuery.kt index b0e7929..df5ac44 100644 --- a/dpp/src/main/java/org/dashj/platform/dapiclient/model/DocumentQuery.kt +++ b/dpp/src/main/java/org/dashj/platform/dapiclient/model/DocumentQuery.kt @@ -13,6 +13,7 @@ import org.dashj.platform.dpp.util.convertToPlatformValue import org.dashj.platform.sdk.OrderClause import org.dashj.platform.sdk.WhereClause import org.dashj.platform.sdk.WhereOperator +import org.dashj.platform.sdk.platform.Documents import org.json.JSONArray /** @@ -26,7 +27,7 @@ import org.json.JSONArray class DocumentQuery private constructor( var where: List? = null, var orderBy: List>? = null, - var limit: Int = -1, + var limit: Int = Documents.DOCUMENT_LIMIT, var startAt: Identifier? = null, var startAfter: Identifier? = null ) : BaseObject() { From c135bdf5d7492084a106c0e9c0c3f68c4d40d9a9 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Sat, 23 Nov 2024 11:21:03 -0800 Subject: [PATCH 08/11] fix: obtain page 2+ successfully with document queries --- .../org/dashj/platform/sdk/DocumentTest.java | 49 +++++++++++++++++-- .../dashj/org/platform/RegisteredNames.kt | 11 +++-- platform-mobile/src/fetch_document.rs | 8 +-- .../dashj/platform/tools/NetworkActivity.kt | 14 +++--- 4 files changed, 67 insertions(+), 15 deletions(-) diff --git a/dash-sdk-java/src/test/java/org/dashj/platform/sdk/DocumentTest.java b/dash-sdk-java/src/test/java/org/dashj/platform/sdk/DocumentTest.java index 7f26d98..e4821ef 100644 --- a/dash-sdk-java/src/test/java/org/dashj/platform/sdk/DocumentTest.java +++ b/dash-sdk-java/src/test/java/org/dashj/platform/sdk/DocumentTest.java @@ -1,11 +1,9 @@ package org.dashj.platform.sdk; +import org.bitcoinj.core.Base58; import org.dashj.platform.sdk.base.Result; -import org.junit.AfterClass; -import org.junit.BeforeClass; import org.junit.Test; -import java.math.BigInteger; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -14,6 +12,7 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; public class DocumentTest extends SdkBaseTest { @@ -259,6 +258,50 @@ public void queryTestFail() { } } + @Test + public void queryAllTest() { + try { + Identifier dpnsId = new Identifier(dpnsContractId); + ArrayList where = new ArrayList<>(); + ArrayList orderBy = new ArrayList<>(); + // where.add(new WhereClause("normalizedLabel", WhereOperator.StartsWith, new PlatformValue("test"))); + where.add(new WhereClause("normalizedParentDomainName", WhereOperator.Equal, new PlatformValue("dash"))); + orderBy.add(new OrderClause("normalizedLabel")); + int count = 0; + Start startAfter = null; + do { + + Result, String> result = dashsdk.platformMobileFetchDocumentFetchDocumentsWithQueryAndSdk( + sdk, + dpnsId, + "domain", + where, + orderBy, + 100, + startAfter + ); + List docs = result.unwrap(); + System.out.println("------ query ------"); + System.out.println("items: " + docs.size()); + docs.forEach(document -> { + Map props = document.getV0().get_0().getProperties(); + System.out.println(props.get("label").getText()); + System.out.println(" id: : " + Base58.encode(document.getV0().get_0().getId().getBytes())); + System.out.println(" identity: " + Base58.encode(props.get("records").getMap().get_0().get(new PlatformValue("identity")).getIdentifier().getBytes())); + + }); + count = docs.size(); + if (count > 0) { + startAfter = new Start(docs.get(docs.size() -1).getV0().get_0().getId().getBytes(), true); + System.out.println("start after: " + Base58.encode(startAfter.getStart_after().get_0())); + } + } while (count == 100); + } catch (Exception e) { + e.printStackTrace(); + fail(e.getMessage()); + } + } + @Test public void startsWithQueryTest() { try { diff --git a/examples/src/main/kotlin/dashj/org/platform/RegisteredNames.kt b/examples/src/main/kotlin/dashj/org/platform/RegisteredNames.kt index 7cff9b7..3e93f18 100644 --- a/examples/src/main/kotlin/dashj/org/platform/RegisteredNames.kt +++ b/examples/src/main/kotlin/dashj/org/platform/RegisteredNames.kt @@ -12,6 +12,7 @@ import org.dashj.platform.dpp.document.Document import org.dashj.platform.dpp.identifier.Identifier import org.dashj.platform.sdk.Client import org.dashj.platform.sdk.client.ClientOptions +import org.dashj.platform.sdk.platform.Documents class RegisteredNames { companion object { @@ -30,8 +31,8 @@ class RegisteredNames { var lastItem = Identifier.from(Sha256Hash.ZERO_HASH) var documents: List? = null var requests = 0 - val limit = 100 - var queryOpts = DocumentQuery.Builder().limit(limit).build() + val limit = Documents.DOCUMENT_LIMIT + var queryOpts = DocumentQuery.Builder().limit(limit).orderBy("normalizedLabel").build() do { println(queryOpts.toJSON()) @@ -51,7 +52,11 @@ class RegisteredNames { lastItem = documents.last().id if (documents.size == 100) { - queryOpts = DocumentQuery.Builder().startAfter(lastItem).limit(100).build() + queryOpts = DocumentQuery.Builder() + .startAfter(lastItem) + .orderBy("normalizedLabel") + .limit(100) + .build() } } catch (e: Exception) { println("\nError retrieving results (startAt = $lastItem)") diff --git a/platform-mobile/src/fetch_document.rs b/platform-mobile/src/fetch_document.rs index 7bb94d2..ba22912 100644 --- a/platform-mobile/src/fetch_document.rs +++ b/platform-mobile/src/fetch_document.rs @@ -338,13 +338,15 @@ fn docs_get_all_query_sdk_test() { contract_id, "domain".to_string(), vec![], - vec![], + vec![OrderClause { field: "normalizedLabel".into(), ascending: true }], 100, - Some(StartPoint::StartAt(docs.last().unwrap().id().to_vec())) + Some(StartPoint::StartAfter(docs.last().unwrap().id().to_vec())) ) }; match docs_result2 { - Ok(docuemnts) => { }, + Ok(documents) => { + println!("query results: {}", documents.len()); + }, Err(e) => { panic!("error: {}", e)} } for document in docs { diff --git a/tools/src/main/kotlin/org/dashj/platform/tools/NetworkActivity.kt b/tools/src/main/kotlin/org/dashj/platform/tools/NetworkActivity.kt index 726982b..f5a92a4 100644 --- a/tools/src/main/kotlin/org/dashj/platform/tools/NetworkActivity.kt +++ b/tools/src/main/kotlin/org/dashj/platform/tools/NetworkActivity.kt @@ -84,12 +84,12 @@ class NetworkActivity { } // TODO: This could use Documents.getAll - private fun getAllDocuments(contractDocument: String): List { + private fun getAllDocuments(contractDocument: String, orderBy: String): List { var startAfter: Identifier? = null var documents: List? = null val allDocuments = arrayListOf() var requests = 0 - var queryOpts = DocumentQuery.Builder().build() + var queryOpts = DocumentQuery.Builder().orderBy(orderBy).build() do { try { documents = platform.documents.get(contractDocument, queryOpts) @@ -99,7 +99,9 @@ class NetworkActivity { startAfter = documents.last().id queryOpts = DocumentQuery.Builder() - .startAfter(startAfter) + .startAt(startAfter) + .limit(100) + .orderBy(orderBy) .build() } catch (e: Exception) { println("\nError retrieving results (startAfter = $startAfter)") @@ -111,7 +113,7 @@ class NetworkActivity { } private fun getNameDocuments(): List { - val allNameDocuments = getAllDocuments(Names.DPNS_DOMAIN_DOCUMENT) + val allNameDocuments = getAllDocuments(Names.DPNS_DOMAIN_DOCUMENT, "normalizedLabel") val nameDocuments = arrayListOf() allNameDocuments.forEach { @@ -124,7 +126,7 @@ class NetworkActivity { } private fun getContactRequests(): List { - val allDocuments = getAllDocuments(ContactRequests.CONTACTREQUEST_DOCUMENT) + val allDocuments = getAllDocuments(ContactRequests.CONTACTREQUEST_DOCUMENT, Document.FIELD_ID) return allDocuments.map { ContactRequest(it) } } @@ -147,7 +149,7 @@ class NetworkActivity { } fun getProfileDocuments(): List { - val allDocuments = getAllDocuments(Profiles.DOCUMENT) + val allDocuments = getAllDocuments(Profiles.DOCUMENT, Document.FIELD_ID) return allDocuments.map { Profile(it) } } From e5784f658f287bb1198c86e3e2bc7a59a57d39ca Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Sat, 23 Nov 2024 11:21:25 -0800 Subject: [PATCH 09/11] feat: add ContestedNames example --- .../main/kotlin/dashj/org/platform/ContestedNames.kt | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/src/main/kotlin/dashj/org/platform/ContestedNames.kt b/examples/src/main/kotlin/dashj/org/platform/ContestedNames.kt index d630dde..3130afe 100644 --- a/examples/src/main/kotlin/dashj/org/platform/ContestedNames.kt +++ b/examples/src/main/kotlin/dashj/org/platform/ContestedNames.kt @@ -6,11 +6,13 @@ */ package dashj.org.platform +import com.google.common.base.Stopwatch import org.dashj.platform.dapiclient.SystemIds import org.dashj.platform.dpp.voting.ContestedDocumentResourceVotePoll import org.dashj.platform.sdk.Client import org.dashj.platform.sdk.client.ClientOptions import org.dashj.platform.sdk.platform.Documents +import java.util.concurrent.TimeUnit /** * ContestedNames - Display all of the currently contested usernames @@ -28,6 +30,7 @@ class ContestedNames { private fun getDocuments() { val platform = sdk.platform + val watch = Stopwatch.createStarted() val votePolls = platform.documents.getAllVotePolls( SystemIds.dpnsDataContractId, @@ -39,15 +42,22 @@ class ContestedNames { orderAscending = true ) - println("${votePolls.size} results returned") + println("${votePolls.size} results returned in ${watch.elapsed(TimeUnit.MILLISECONDS)}") + val names = arrayListOf() votePolls.forEach { when(it) { is ContestedDocumentResourceVotePoll -> { println(it.indexValues[1]) + names.add(it.indexValues[1]) } else -> println("unknown vote poll type") } } + val watch2 = Stopwatch.createStarted() + val voteContenders = names.map { + platform.names.getVoteContenders(it) + } + println("get vote contenders ${voteContenders.size} results returned in ${watch2.elapsed(TimeUnit.MILLISECONDS)}") } } } \ No newline at end of file From 212a633f878ef2353f2529915bf049e709ac0ff0 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Sat, 23 Nov 2024 11:22:07 -0800 Subject: [PATCH 10/11] chore: remove commented lines --- dash-sdk-java/build.gradle | 4 ---- 1 file changed, 4 deletions(-) diff --git a/dash-sdk-java/build.gradle b/dash-sdk-java/build.gradle index 51afb5b..8878859 100644 --- a/dash-sdk-java/build.gradle +++ b/dash-sdk-java/build.gradle @@ -9,8 +9,6 @@ plugins { id 'signing' } -//version '1.0-SNAPSHOT' - repositories { mavenLocal() mavenCentral() @@ -19,8 +17,6 @@ repositories { dependencies { implementation 'org.jetbrains:annotations:20.1.0' testImplementation 'junit:junit:4.13.2' // Latest JUnit 4 - //testImplementation 'org.junit.jupiter:junit-jupiter-api:5.8.1' - //testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.8.1' testImplementation 'org.dashj:dashj-core:21.1.1' testImplementation 'com.google.guava:guava:32.0.0-android' } From 312831c1d97170e4f4fbe60da33ce4a6714b8087 Mon Sep 17 00:00:00 2001 From: HashEngineering Date: Sat, 23 Nov 2024 11:22:22 -0800 Subject: [PATCH 11/11] chore: update Cargo.lock --- platform-mobile/Cargo.lock | 50 ++++++++++++++++++++++++++++++++------ 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/platform-mobile/Cargo.lock b/platform-mobile/Cargo.lock index 1f61351..7eda39e 100644 --- a/platform-mobile/Cargo.lock +++ b/platform-mobile/Cargo.lock @@ -221,9 +221,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "axum" -version = "0.7.7" +version = "0.7.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "504e3947307ac8326a5437504c517c4b56716c9d98fac0028c2acc7ca47d70ae" +checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f" dependencies = [ "async-trait", "axum-core", @@ -758,6 +758,16 @@ dependencies = [ "libc", ] +[[package]] +name = "core-foundation" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "core-foundation-sys" version = "0.8.7" @@ -2458,7 +2468,7 @@ dependencies = [ "openssl-probe", "openssl-sys", "schannel", - "security-framework", + "security-framework 2.11.1", "security-framework-sys", "tempfile", ] @@ -3407,6 +3417,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "rustls-native-certs" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3" +dependencies = [ + "openssl-probe", + "rustls-pki-types", + "schannel", + "security-framework 3.0.1", +] + [[package]] name = "rustls-pemfile" version = "2.2.0" @@ -3418,9 +3440,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e696e35370c65c9c541198af4543ccd580cf17fc25d8e05c5a242b202488c55" +checksum = "16f1201b3c9a7ee8039bcadc17b7e605e2945b27eee7631788c1bd2b0643674b" [[package]] name = "rustls-webpki" @@ -3524,7 +3546,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +dependencies = [ + "bitflags 2.6.0", + "core-foundation 0.10.0", "core-foundation-sys", "libc", "security-framework-sys", @@ -3866,7 +3901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ "bitflags 2.6.0", - "core-foundation", + "core-foundation 0.9.4", "system-configuration-sys", ] @@ -4191,6 +4226,7 @@ dependencies = [ "percent-encoding", "pin-project", "prost 0.13.3", + "rustls-native-certs", "rustls-pemfile", "socket2", "tokio",