Skip to content

Commit

Permalink
solution: implement missing rpc shortcuts to be on par with JS refere…
Browse files Browse the repository at this point in the history
…nce lib
  • Loading branch information
splix committed Jun 29, 2020
1 parent d710c64 commit c9d7943
Show file tree
Hide file tree
Showing 8 changed files with 384 additions and 12 deletions.
44 changes: 39 additions & 5 deletions docs/ref-01-api-commands.adoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
= Standard RPC Commands and Subscriptions

- <<calls>>
- <<subsriptions>>
[#calls]
== RPC Commands
:shortcut-base: StandardCommands.getInstance()

Expand All @@ -16,6 +20,7 @@
* State
- <<stateMetadata>>
- <<stateGetStorage>>
- <<stateGetReadProof>>
* System
- <<systemChain>>
- <<systemHealth>>
Expand Down Expand Up @@ -106,7 +111,10 @@ Get value under a specified storage key in a contract.

Shortcut:: `{shortcut-base}.contractsGetStorage(address, key, at)`
Command:: `contracts_getStorage`
Parameters:: `address` - contract address (`Address`), `key` - key (`Has256`), `at` - (optional) block reference (`Hash256`)
Parameters::
- `address` - contract address (`Address`),
- `key` - key (`Has256`),
- `at` - (optional) block reference (`Hash256`)
Java Object:: `ByteData`

[#contractsRentProjection]
Expand All @@ -116,7 +124,9 @@ Get projected time a given contract will be able to sustain paying its rent

Shortcut:: `{shortcut-base}.contractsRentProjection(address, at)`
Command:: `contracts_getStorage`
Parameters:: `address` - contract address (`Address`), `at` - (optional) block reference (`Hash256`)
Parameters::
- `address` - contract address (`Address`),
- `at` - (optional) block reference (`Hash256`)
Java Object:: `Long`


Expand Down Expand Up @@ -148,6 +158,18 @@ Command:: `state_getStorage`
Parameters:: `key` - bytes (`byte[]` or `ByteDate`)
Java Object:: `ByteData`

[#stateGetReadProof]
=== State Get Read Proof (`state_getReadProof`)

Get proof of storage entries at a specific block state

Shortcut:: `{shortcut-base}.stateGetReadProof(keys, at?)`
Command:: `state_getReadProof`
Parameters::
- `keys` - list of keys (`List<ByteDate>`)
- `at` - (optional) block reference (`Hash256`)
Java Object:: `ReadProofJson`

[#systemChain]
=== System Chain (`system_chain`)

Expand Down Expand Up @@ -234,12 +256,14 @@ Java Object:: `MethodsJson`
- `Integer getVersion()` - version of RPC
- `List<String> getMethods()` - list of methods
[#subsriptions]
== Subscriptions
:shortcut-base: StandardSubscriptions.getInstance()

- <<subFinalizedHeads>>
- <<subNewHeads>>
- <<subRuntimeVersion>>
- <<subStorage>>
[#subFinalizedHeads]
=== Finalized Heads (`chain_subscribeFinalizedHeads`)
Expand All @@ -262,11 +286,21 @@ Parameters:: none
Java Object:: `BlockJson.Header`

[#subRuntimeVersion]
=== Runtime Version (`chain_subscribeRuntimeVersion`)
=== Runtime Version (`state_subscribeRuntimeVersion`)

Subscribe to the changes to the Runtime Version.

Shortcut:: `{shortcut-base}.runtimeVersion()`
Command:: `chain_subscribeRuntimeVersion`
Command:: `state_subscribeRuntimeVersion`
Parameters:: none
Java Object:: `RuntimeVersion`
Java Object:: `RuntimeVersion`

[#subStorage]
=== Storage (`state_subscribeStorage`)

Subscribe to the changes to the Storage.

Shortcut:: `{shortcut-base}.storage(keys?)`
Command:: `state_subscribeRuntimeVersion`
Parameters:: `keys` - (optional) Storage Keys (`Hash256`)
Java Object:: `StorageChangeSetJson`
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import io.emeraldpay.polkaj.types.ByteData;
import io.emeraldpay.polkaj.types.Hash256;

import java.util.ArrayList;
import java.util.List;

/**
Expand Down Expand Up @@ -125,11 +126,133 @@ public RpcCall<ByteData> stateMetadata() {

/**
* Request data from storage
* @param request key (depending on the storage)
* @param key key (depending on the storage)
* @return command
*/
public RpcCall<ByteData> stateGetStorage(ByteData request) {
return RpcCall.create(ByteData.class, "state_getStorage", request.toString());
public RpcCall<ByteData> stateGetStorage(ByteData key) {
return RpcCall.create(ByteData.class, "state_getStorage", key.toString());
}

/**
* @deprecated Use RpcCall.create(Hash256.class, "state_getStorageHash", ...)
*/
@Deprecated(forRemoval = true)
public RpcCall<Hash256> stateGetStorageHash(ByteData key, Hash256 at) {
List<Object> params = at == null ? List.of(key) : List.of(key, at);
return RpcCall.create(Hash256.class, "state_getStorageHash", params);
}

/**
* @deprecated Use RpcCall.create(Hash256.class, "state_getStorageSize", ...)
*/
@Deprecated(forRemoval = true)
public RpcCall<Long> stateGetStorageSize(ByteData key, Hash256 at) {
List<Object> params = at == null ? List.of(key) : List.of(key, at);
return RpcCall.create(Long.class, "state_getStorageSize", params);
}

/**
* @deprecated Use RpcCall.create(ByteData.class, "state_call", ...)
*/
@Deprecated(forRemoval = true)
public RpcCall<ByteData> stateCall(String method, ByteData data, Hash256 at) {
List<Object> params = at == null ? List.of(method, data) : List.of(method, data, at);
return RpcCall.create(ByteData.class, "state_call", params);
}

/**
* @deprecated Use RpcCall.create(ByteData.class, "state_getChildKeys", ...).expectList()
*/
@Deprecated(forRemoval = true)
public RpcCall<List<ByteData>> stateGetChildKeys(ByteData childStorageKey, ByteData childDefinition, long childType, ByteData key, Hash256 at) {
List<Object> params = new ArrayList<>(List.of(childStorageKey, childDefinition, childType, key));
if (at != null) {
params.add(at);
}
return RpcCall.create(ByteData.class, "state_getChildKeys", params).expectList();
}

/**
* @deprecated Use RpcCall.create(ByteData.class, "state_getChildStorage", ...)
*/
@Deprecated(forRemoval = true)
public RpcCall<ByteData> stateGetStorageData(ByteData childStorageKey, ByteData childDefinition, long childType, ByteData key, Hash256 at) {
List<Object> params = new ArrayList<>(List.of(childStorageKey, childDefinition, childType, key));
if (at != null) {
params.add(at);
}
return RpcCall.create(ByteData.class, "state_getChildStorage", params);
}

/**
* @deprecated Use RpcCall.create(Hash256.class, "state_getChildStorageHash", ...)
*/
@Deprecated(forRemoval = true)
public RpcCall<Hash256> stateGetChildStorageHash(ByteData childStorageKey, ByteData childDefinition, long childType, ByteData key, Hash256 at) {
List<Object> params = new ArrayList<>(List.of(childStorageKey, childDefinition, childType, key));
if (at != null) {
params.add(at);
}
return RpcCall.create(Hash256.class, "state_getChildStorageHash", params);
}

/**
* @deprecated RpcCall.create(Long.class, "state_getChildStorageSize", ...)
*/
@Deprecated(forRemoval = true)
public RpcCall<Long> stateGetChildStorageSize(ByteData childStorageKey, ByteData childDefinition, long childType, ByteData key, Hash256 at) {
List<Object> params = new ArrayList<>(List.of(childStorageKey, childDefinition, childType, key));
if (at != null) {
params.add(at);
}
return RpcCall.create(Long.class, "state_getChildStorageSize", params);
}

/**
* @deprecated Use RpcCall.create(ByteData.class, "state_getKeysPaged", ...).expectList()
*/
@Deprecated(forRemoval = true)
public RpcCall<List<ByteData>> stateGetKeys(ByteData key, int count, ByteData startKey, Hash256 at) {
List<Object> params = new ArrayList<>(List.of(key, count));
if (startKey != null) {
params.add(startKey);
}
if (at != null) {
params.add(at);
}
return RpcCall.create(ByteData.class, "state_getKeysPaged", params).expectList();
}

public RpcCall<ReadProofJson> stateGetReadProof(List<ByteData> keys, Hash256 at) {
List<Object> params = new ArrayList<>(List.of(keys));
if (at != null) {
params.add(at);
}
return RpcCall.create(ReadProofJson.class, "state_getReadProof", params);
}

/**
* @deprecated Use RpcCall.create(ByteData.class, "state_queryStorage", ...).expectList()
*/
@Deprecated(forRemoval = true)
public RpcCall<List<ByteData>> stateQueryStorage(List<ByteData> keys, Hash256 fromBlock, Hash256 toBlock) {
List<Object> params = new ArrayList<>(List.of(keys, fromBlock));
if (toBlock != null) {
params.add(toBlock);
}
return RpcCall.create(ByteData.class, "state_queryStorage", params).expectList();
}

/**
* @deprecated Use RpcCall.create(ByteData.class, "state_queryStorageAt", ...).expectList()
*/
@Deprecated(forRemoval = true)
public RpcCall<List<ByteData>> stateQueryStorageAt(List<ByteData> keys, Hash256 at) {
List<Object> params = new ArrayList<>(List.of(keys));
if (at != null) {
params.add(at);
}
return RpcCall.create(ByteData.class, "state_queryStorageAt", params).expectList();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

import io.emeraldpay.polkaj.json.BlockJson;
import io.emeraldpay.polkaj.json.RuntimeVersionJson;
import io.emeraldpay.polkaj.json.StorageChangeSetJson;
import io.emeraldpay.polkaj.types.ByteData;

import java.util.List;

/**
* Standard/common Polkadot subscriptions
Expand Down Expand Up @@ -38,6 +42,17 @@ public SubscribeCall<BlockJson.Header> finalizedHeads() {
* @return command
*/
public SubscribeCall<RuntimeVersionJson> runtimeVersion() {
return SubscribeCall.create(RuntimeVersionJson.class, "chain_subscribeRuntimeVersion", "chain_unsubscribeRuntimeVersion");
return SubscribeCall.create(RuntimeVersionJson.class, "state_subscribeRuntimeVersion", "state_unsubscribeRuntimeVersion");
}

public SubscribeCall<StorageChangeSetJson> storage() {
return SubscribeCall.create(StorageChangeSetJson.class, "state_subscribeStorage", "state_unsubscribeStorage");
}

public SubscribeCall<StorageChangeSetJson> storage(List<ByteData> keys) {
if (keys == null || keys.isEmpty()) {
return storage();
}
return SubscribeCall.create(StorageChangeSetJson.class, "state_subscribeStorage", "state_unsubscribeStorage", List.of(keys));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.type.TypeFactory
import io.emeraldpay.polkaj.json.RuntimeVersionJson
import io.emeraldpay.polkaj.json.BlockJson
import io.emeraldpay.polkaj.json.StorageChangeSetJson
import io.emeraldpay.polkaj.json.jackson.PolkadotModule
import io.emeraldpay.polkaj.types.ByteData
import spock.lang.Specification

class StandardSubscriptionsSpec extends Specification {
Expand Down Expand Up @@ -34,13 +36,47 @@ class StandardSubscriptionsSpec extends Specification {
act.getResultType(typeFactory).getRawClass() == BlockJson.Header.class
}

def "chain subscribe runtime vesion"() {
def "state subscribe runtime version"() {
when:
def act = StandardSubscriptions.getInstance().runtimeVersion()
then:
act.method == "chain_subscribeRuntimeVersion"
act.method == "state_subscribeRuntimeVersion"
act.params.size() == 0
act.unsubscribe == "chain_unsubscribeRuntimeVersion"
act.unsubscribe == "state_unsubscribeRuntimeVersion"
act.getResultType(typeFactory).getRawClass() == RuntimeVersionJson.class
}

def "state subscribe storage"() {
when:
def act = StandardSubscriptions.getInstance().storage()
then:
act.method == "state_subscribeStorage"
act.params.size() == 0
act.unsubscribe == "state_unsubscribeStorage"
act.getResultType(typeFactory).getRawClass() == StorageChangeSetJson.class

when:
act = StandardSubscriptions.getInstance().storage(null)
then:
act.method == "state_subscribeStorage"
act.params.size() == 0
act.unsubscribe == "state_unsubscribeStorage"
act.getResultType(typeFactory).getRawClass() == StorageChangeSetJson.class

when:
act = StandardSubscriptions.getInstance().storage([])
then:
act.method == "state_subscribeStorage"
act.params.size() == 0
act.unsubscribe == "state_unsubscribeStorage"
act.getResultType(typeFactory).getRawClass() == StorageChangeSetJson.class

when:
act = StandardSubscriptions.getInstance().storage([ByteData.from("0x00")])
then:
act.method == "state_subscribeStorage"
act.params.toList() == [[ByteData.from("0x00")]]
act.unsubscribe == "state_unsubscribeStorage"
act.getResultType(typeFactory).getRawClass() == StorageChangeSetJson.class
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package io.emeraldpay.polkaj.json;

import io.emeraldpay.polkaj.types.ByteData;
import io.emeraldpay.polkaj.types.Hash256;

import java.util.List;
import java.util.Objects;

public class ReadProofJson {
private Hash256 at;
private List<ByteData> proof;

public Hash256 getAt() {
return at;
}

public void setAt(Hash256 at) {
this.at = at;
}

public List<ByteData> getProof() {
return proof;
}

public void setProof(List<ByteData> proof) {
this.proof = proof;
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ReadProofJson)) return false;
ReadProofJson that = (ReadProofJson) o;
return Objects.equals(at, that.at) &&
Objects.equals(proof, that.proof);
}

@Override
public int hashCode() {
return Objects.hash(at, proof);
}
}
Loading

0 comments on commit c9d7943

Please sign in to comment.