From f53ab5c6041bb9ac249179912e11a94b9d5a884d Mon Sep 17 00:00:00 2001 From: Roman Bylbas Date: Wed, 26 Jul 2023 11:13:43 +0300 Subject: [PATCH] Added new RPC endpoint (speculative_exec, query_balance, info_get_chainspec) Signed-off-by: Roman Bylbas --- .github/workflows/ci.yml | 2 +- docs/API/RpcClientAPI.md | 36 ++++++++++ docs/Entity/BlockRange.md | 10 +++ docs/Entity/ChainspecRegistryBytes.md | 18 +++++ docs/Entity/Status.md | 29 ++++++++ src/Entity/BlockRange.php | 26 +++++++ src/Entity/ChainspecRegistryBytes.php | 38 ++++++++++ src/Entity/DeployExecutionResult.php | 26 +++++++ src/Entity/DeployExecutionResultData.php | 50 +++++++++++++ src/Entity/Effect.php | 32 +++++++++ src/Entity/Operation.php | 26 +++++++ src/Entity/Status.php | 47 +++++++++++- src/Entity/Transform.php | 27 +++++++ src/Rpc/RpcClient.php | 72 ++++++++++++++++++- src/Serializer/BlockRangeSerializer.php | 24 +++++++ .../ChainspecRegistryBytesSerializer.php | 29 ++++++++ .../DeployExecutionResultDataSerializer.php | 42 +++++++++++ .../DeployExecutionResultSerializer.php | 27 +++++++ src/Serializer/EffectSerializer.php | 27 +++++++ src/Serializer/OperationSerializer.php | 24 +++++++ src/Serializer/StatusSerializer.php | 12 +++- src/Serializer/TransformSerializer.php | 24 +++++++ tests/Functional/Rpc/RpcClientTest.php | 27 +++++++ 23 files changed, 670 insertions(+), 5 deletions(-) create mode 100644 docs/Entity/BlockRange.md create mode 100644 docs/Entity/ChainspecRegistryBytes.md create mode 100644 src/Entity/BlockRange.php create mode 100644 src/Entity/ChainspecRegistryBytes.php create mode 100644 src/Entity/DeployExecutionResult.php create mode 100644 src/Entity/DeployExecutionResultData.php create mode 100644 src/Entity/Effect.php create mode 100644 src/Entity/Operation.php create mode 100644 src/Entity/Transform.php create mode 100644 src/Serializer/BlockRangeSerializer.php create mode 100644 src/Serializer/ChainspecRegistryBytesSerializer.php create mode 100644 src/Serializer/DeployExecutionResultDataSerializer.php create mode 100644 src/Serializer/DeployExecutionResultSerializer.php create mode 100644 src/Serializer/EffectSerializer.php create mode 100644 src/Serializer/OperationSerializer.php create mode 100644 src/Serializer/TransformSerializer.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8e75f41..0d3ddc6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -47,4 +47,4 @@ jobs: - name: Run test suite run: composer run-script test env: - CASPER_PHP_SDK_TEST_NODE_URL: "136.243.187.84:7777" + CASPER_PHP_SDK_TEST_NODE_URL: "65.21.237.160:7777" diff --git a/docs/API/RpcClientAPI.md b/docs/API/RpcClientAPI.md index dd21450..bc26e8a 100644 --- a/docs/API/RpcClientAPI.md +++ b/docs/API/RpcClientAPI.md @@ -118,6 +118,23 @@ Returns purse's balance from the network | `$stateRootHash` | `string` | Hex-encoded hash of the state root | Yes | | `$balanceUref` | `CLURef` | Balance URef object | Yes | +--- +## Query balance +```php +queryBalance( + string $purseIdentifierType, + string $purseIdentifier, + string $stateRootHash = null +): \GMP +``` +Returns a purse’s balance from global state at a given [Block](../Entity/Block.md) or state root hash. +### Parameters +| Name | Type | Description | Required | +|---|----------|-----------------------------------------------------------------------------------------------------------------------|----------| +| `$purseIdentifierType` | `string` | Purse identifier type. Available values: `purse_uref`, `main_purse_under_public_key`, `main_purse_under_account_hash` | Yes | +| `$purseIdentifier` | `string` | Purse identifier | Yes | +| `$stateRootHash` | `string` | Hex-encoded hash of the state root | No | + --- ## Get account balance URef by account hash ```php @@ -238,3 +255,22 @@ Returns an [GlobalState](../Entity/GlobalState.md) object by the given state roo | `$stateRootHash` | `string` | Hex-encoded hash of the state root | Yes | | `$key` | `string` | `casper_types::Key` as formatted string | Yes | | `$path` | `array` | The path components starting from the key as base | No | + +--- +## Get chainspec info +```php +getChainspecInfo(): ChainspecRegistryBytes +``` +Returns a [ChainspecRegistryBytes](../Entity/ChainspecRegistryBytes.md) object + +--- +## Speculative deploy +```php +speculativeDeploy(Deploy $signedDeploy, string $blockHash) +``` +Puts a [Deploy](../Entity/Deploy.md) to a single node for speculative execution on that node only. +### Parameters +| Name | Type | Description | Required | +|---|------|-------------|----| +| `$signedDeploy` | `Deploy` | Signed [Deploy](../Entity/Deploy.md) object | Yes | +| `$blockHash` | `string` | Hex-encoded hash of the block | Yes | diff --git a/docs/Entity/BlockRange.md b/docs/Entity/BlockRange.md new file mode 100644 index 0000000..ad7f356 --- /dev/null +++ b/docs/Entity/BlockRange.md @@ -0,0 +1,10 @@ +# BlockRange + +```php +getLow(): int +``` + +--- +```php +getHigh(): int +``` diff --git a/docs/Entity/ChainspecRegistryBytes.md b/docs/Entity/ChainspecRegistryBytes.md new file mode 100644 index 0000000..553debc --- /dev/null +++ b/docs/Entity/ChainspecRegistryBytes.md @@ -0,0 +1,18 @@ +# ChainspecRegistryBytes + +```php +getChainspecBytes(): string +``` +Returns Chainspec.toml bytes + +--- +```php +getGenesisAccountsBytes(): ?string +``` +Returns Accounts.toml bytes or `null` + +--- +```php +getGlobalStateBytes(): ?string +``` +Returns GlobalState.toml bytes or `null` diff --git a/docs/Entity/Status.md b/docs/Entity/Status.md index 70ee3a4..b30d1dc 100644 --- a/docs/Entity/Status.md +++ b/docs/Entity/Status.md @@ -1,5 +1,10 @@ # Status +```php +getApiVersion(): string +``` +Returns node's RPC API version + ```php getChainspecName(): string ``` @@ -46,3 +51,27 @@ Returns [NextUpgrade](NextUpgrade.md) object or `null` getPeers(): array ``` Returns a list of [Peer](Peer.md) objects that connected to the network + +--- +```php +getUptime(): string +``` +Returns time that passed since the node has started. + +--- +```php +getReactorState(): string +``` +Returns node's reactor state + +--- +```php +getLastProgress(): \DateTime +``` +Returns node's last progress + +--- +```php +getLastProgress(): BlockRange +``` +Returns [BlockRange](BlockRange.md) object diff --git a/src/Entity/BlockRange.php b/src/Entity/BlockRange.php new file mode 100644 index 0000000..e0285f6 --- /dev/null +++ b/src/Entity/BlockRange.php @@ -0,0 +1,26 @@ +low = $low; + $this->high = $high; + } + + public function getLow(): int + { + return $this->low; + } + + public function getHigh(): int + { + return $this->high; + } +} diff --git a/src/Entity/ChainspecRegistryBytes.php b/src/Entity/ChainspecRegistryBytes.php new file mode 100644 index 0000000..e28367b --- /dev/null +++ b/src/Entity/ChainspecRegistryBytes.php @@ -0,0 +1,38 @@ +chainspecBytes = $chainspecBytes; + $this->genesisAccountsBytes = $genesisAccountsBytes; + $this->globalStateBytes = $globalStateBytes; + } + + public function getChainspecBytes(): string + { + return $this->chainspecBytes; + } + + public function getGenesisAccountsBytes(): ?string + { + return $this->genesisAccountsBytes; + } + + public function getGlobalStateBytes(): ?string + { + return $this->globalStateBytes; + } +} diff --git a/src/Entity/DeployExecutionResult.php b/src/Entity/DeployExecutionResult.php new file mode 100644 index 0000000..25a6b30 --- /dev/null +++ b/src/Entity/DeployExecutionResult.php @@ -0,0 +1,26 @@ +blockHash = $blockHash; + $this->data = $data; + } + + public function getBlockHash(): string + { + return $this->blockHash; + } + + public function getData(): DeployExecutionResultData + { + return $this->data; + } +} diff --git a/src/Entity/DeployExecutionResultData.php b/src/Entity/DeployExecutionResultData.php new file mode 100644 index 0000000..bede82a --- /dev/null +++ b/src/Entity/DeployExecutionResultData.php @@ -0,0 +1,50 @@ +status = $status; + $this->effect = $effect; + $this->transfers = $transfers; + $this->cost = $cost; + $this->errorMessage = $errorMessage; + } + + public function getStatus(): string + { + return $this->status; + } + + public function getEffect(): Effect + { + return $this->effect; + } + + public function getTransfers(): array + { + return $this->transfers; + } + + public function getCost(): \GMP + { + return $this->cost; + } + + public function getErrorMessage(): ?string + { + return $this->errorMessage; + } +} diff --git a/src/Entity/Effect.php b/src/Entity/Effect.php new file mode 100644 index 0000000..949975a --- /dev/null +++ b/src/Entity/Effect.php @@ -0,0 +1,32 @@ +operations = $operations; + $this->transforms = $transforms; + } + + public function getOperations(): array + { + return $this->operations; + } + + public function getTransforms(): array + { + return $this->transforms; + } +} diff --git a/src/Entity/Operation.php b/src/Entity/Operation.php new file mode 100644 index 0000000..4d8d2d4 --- /dev/null +++ b/src/Entity/Operation.php @@ -0,0 +1,26 @@ +key = $key; + $this->kind = $kind; + } + + public function getKey(): string + { + return $this->key; + } + + public function getKind(): string + { + return $this->kind; + } +} diff --git a/src/Entity/Status.php b/src/Entity/Status.php index b23a463..51b9c41 100644 --- a/src/Entity/Status.php +++ b/src/Entity/Status.php @@ -6,6 +6,8 @@ class Status { + private string $apiVersion; + private string $chainspecName; private string $startingStateRootHash; // Hash @@ -20,12 +22,21 @@ class Status private ?NextUpgrade $nextUpgrade; + private string $uptime; + + private string $reactorState; + + private \DateTime $lastProgress; + + private BlockRange $availableBlockRange; + /** * @var Peer[] */ private array $peers; public function __construct( + string $apiVersion, string $chainspecName, string $startingStateRootHash, BlockInfo $lastAddedBlockInfo, @@ -33,9 +44,14 @@ public function __construct( ?string $roundLength, string $buildVersion, ?NextUpgrade $nextUpgrade, - array $peers + array $peers, + string $uptime, + string $reactorState, + \DateTime $lastProgress, + BlockRange $availableBlockRange ) { + $this->apiVersion = $apiVersion; $this->chainspecName = $chainspecName; $this->startingStateRootHash = $startingStateRootHash; $this->lastAddedBlockInfo = $lastAddedBlockInfo; @@ -44,6 +60,15 @@ public function __construct( $this->buildVersion = $buildVersion; $this->nextUpgrade = $nextUpgrade; $this->peers = $peers; + $this->uptime = $uptime; + $this->reactorState = $reactorState; + $this->lastProgress = $lastProgress; + $this->availableBlockRange = $availableBlockRange; + } + + public function getApiVersion(): string + { + return $this->apiVersion; } public function getChainspecName(): string @@ -85,4 +110,24 @@ public function getPeers(): array { return $this->peers; } + + public function getUptime(): string + { + return $this->uptime; + } + + public function getReactorState(): string + { + return $this->reactorState; + } + + public function getLastProgress(): \DateTime + { + return $this->lastProgress; + } + + public function getAvailableBlockRange(): BlockRange + { + return $this->availableBlockRange; + } } diff --git a/src/Entity/Transform.php b/src/Entity/Transform.php new file mode 100644 index 0000000..19b1f55 --- /dev/null +++ b/src/Entity/Transform.php @@ -0,0 +1,27 @@ +key = $key; + $this->transform = $transform; + } + + public function getKey(): string + { + return $this->key; + } + + public function getTransform() + { + return $this->transform; + } +} diff --git a/src/Rpc/RpcClient.php b/src/Rpc/RpcClient.php index 6bfdcdb..f37be30 100644 --- a/src/Rpc/RpcClient.php +++ b/src/Rpc/RpcClient.php @@ -4,9 +4,11 @@ use Casper\Serializer\AccountSerializer; use Casper\Serializer\AuctionStateSerializer; +use Casper\Serializer\ChainspecRegistryBytesSerializer; use Casper\Serializer\CLAccountHashSerializer; use Casper\Serializer\CLPublicKeySerializer; use Casper\Serializer\CLURefSerializer; +use Casper\Serializer\DeployExecutionResultSerializer; use Casper\Serializer\EraSummarySerializer; use Casper\Serializer\GlobalStateSerializer; use Casper\Serializer\PeerSerializer; @@ -23,7 +25,9 @@ use Casper\Entity\Account; use Casper\Entity\AuctionState; use Casper\Entity\Block; +use Casper\Entity\ChainspecRegistryBytes; use Casper\Entity\Deploy; +use Casper\Entity\DeployExecutionResult; use Casper\Entity\EraSummary; use Casper\Entity\GlobalState; use Casper\Entity\Peer; @@ -53,6 +57,13 @@ class RpcClient private const RPC_METHOD_GET_ERA_INFO_BY_SWITCH_BLOCK = 'chain_get_era_info_by_switch_block'; private const RPC_METHOD_GET_DICTIONARY_ITEM = 'state_get_dictionary_item'; private const RPC_METHOD_QUERY_GLOBAL_STATE = 'query_global_state'; + private const RPC_METHOD_SPECULATIVE_EXEC = 'speculative_exec'; + private const RPC_METHOD_QUERY_BALANCE = 'query_balance'; + private const RPC_METHOD_INFO_GET_CHAINSPEC = 'info_get_chainspec'; + + public const PURSE_IDENTIFIER_TYPE_UREF = 'purse_uref'; + public const PURSE_IDENTIFIER_TYPE_MAIN_PURSE_UNDER_PUBLIC_KEY = 'main_purse_under_public_key'; + public const PURSE_IDENTIFIER_TYPE_MAIN_PURSE_UNDER_ACCOUNT_HASH = 'main_purse_under_account_hash'; private string $nodeUrl; @@ -198,7 +209,7 @@ public function getStateRootHash(string $blockHash = ''): string { $response = $this->rpcCallMethod( self::RPC_METHOD_GET_STATE_ROOT_HASH, - array('block_hash' => $blockHash) + $blockHash ? [array('Hash' => $blockHash)] : [] ); return $response['state_root_hash']; @@ -228,13 +239,37 @@ public function getAccountBalance(string $stateRootHash, CLURef $balanceUref): \ self::RPC_METHOD_GET_ACCOUNT_BALANCE, array( 'state_root_hash' => $stateRootHash, - 'purse_uref' => CLURefSerializer::toString($balanceUref), + self::PURSE_IDENTIFIER_TYPE_UREF => CLURefSerializer::toString($balanceUref), ) ); return gmp_init($response['balance_value']); } + /** + * @throws RpcError + */ + public function queryBalance( + string $purseIdentifierType, + string $purseIdentifier, + string $stateRootHash = null + ): \GMP + { + $response = $this->rpcCallMethod( + self::RPC_METHOD_QUERY_BALANCE, + array( + 'purse_identifier' => array( + $purseIdentifierType => $purseIdentifier + ), + 'state_identifier' => $stateRootHash + ? array('StateRootHash' => $stateRootHash) + : null + ) + ); + + return gmp_init($response['balance']); + } + /** * @throws RpcError */ @@ -370,6 +405,9 @@ public function getGlobalStateByBlock(string $blockHash, string $key, array $pat return GlobalStateSerializer::fromJson($response); } + /** + * @throws RpcError + */ public function getGlobalStateByStateRootHash(string $stateRootHash, string $key, array $path = []): GlobalState { $response = $this->rpcCallMethod( @@ -386,6 +424,36 @@ public function getGlobalStateByStateRootHash(string $stateRootHash, string $key return GlobalStateSerializer::fromJson($response); } + /** + * @throws RpcError + */ + public function getChainspecInfo(): ChainspecRegistryBytes + { + return ChainspecRegistryBytesSerializer::fromJson( + $this->rpcCallMethod(self::RPC_METHOD_INFO_GET_CHAINSPEC)['chainspec_bytes'] + ); + } + + /** + * @throws RpcError + */ + public function speculativeDeploy(Deploy $signedDeploy, string $blockHash = null): DeployExecutionResult + { + $params = array( + 'deploy' => DeploySerializer::toJson($signedDeploy) + ); + + if ($blockHash !== null) { + $params['block_identifier'] = array( + 'Hash' => $blockHash + ); + } + + return DeployExecutionResultSerializer::fromJson( + $this->rpcCallMethod(self::RPC_METHOD_SPECULATIVE_EXEC, $params) + ); + } + /** * @throws RpcError */ diff --git a/src/Serializer/BlockRangeSerializer.php b/src/Serializer/BlockRangeSerializer.php new file mode 100644 index 0000000..ca4c1bd --- /dev/null +++ b/src/Serializer/BlockRangeSerializer.php @@ -0,0 +1,24 @@ + $blockRange->getLow(), + 'high' => $blockRange->getHigh(), + ); + } + + public static function fromJson(array $json): BlockRange + { + return new BlockRange($json['low'], $json['high']); + } +} diff --git a/src/Serializer/ChainspecRegistryBytesSerializer.php b/src/Serializer/ChainspecRegistryBytesSerializer.php new file mode 100644 index 0000000..d590a5b --- /dev/null +++ b/src/Serializer/ChainspecRegistryBytesSerializer.php @@ -0,0 +1,29 @@ + $chainspecRegistryBytes->getChainspecBytes(), + 'maybe_genesis_accounts_bytes' => $chainspecRegistryBytes->getGenesisAccountsBytes(), + 'maybe_global_state_bytes' => $chainspecRegistryBytes->getGlobalStateBytes(), + ); + } + + public static function fromJson(array $json): ChainspecRegistryBytes + { + return new ChainspecRegistryBytes( + $json['chainspec_bytes'], + $json['maybe_genesis_accounts_bytes'], + $json['maybe_global_state_bytes'] + ); + } +} diff --git a/src/Serializer/DeployExecutionResultDataSerializer.php b/src/Serializer/DeployExecutionResultDataSerializer.php new file mode 100644 index 0000000..8d36c9f --- /dev/null +++ b/src/Serializer/DeployExecutionResultDataSerializer.php @@ -0,0 +1,42 @@ +getStatus() => array( + 'effect' => EffectSerializer::toJson($deployExecutionResultData->getEffect()), + 'transfers' => $deployExecutionResultData->getTransfers(), + 'cost' => (string) $deployExecutionResultData->getCost(), + ) + ); + + if ($deployExecutionResultData->getErrorMessage() !== null) { + $result[$deployExecutionResultData->getStatus()]['error_message'] = + $deployExecutionResultData->getErrorMessage(); + } + + return $result; + } + + public static function fromJson(array $json): DeployExecutionResultData + { + $status = array_key_first($json); + + return new DeployExecutionResultData( + $status, + EffectSerializer::fromJson($json[$status]['effect']), + $json[$status]['transfers'], + gmp_init($json[$status]['cost']), + $json[$status]['error_message'] ?? null + ); + } +} diff --git a/src/Serializer/DeployExecutionResultSerializer.php b/src/Serializer/DeployExecutionResultSerializer.php new file mode 100644 index 0000000..fc7c604 --- /dev/null +++ b/src/Serializer/DeployExecutionResultSerializer.php @@ -0,0 +1,27 @@ + $deployExecutionResult->getBlockHash(), + 'execution_result' => DeployExecutionResultDataSerializer::toJson($deployExecutionResult->getData()) + ); + } + + public static function fromJson(array $json): DeployExecutionResult + { + return new DeployExecutionResult( + $json['block_hash'], + DeployExecutionResultDataSerializer::fromJson($json['execution_result']) + ); + } +} diff --git a/src/Serializer/EffectSerializer.php b/src/Serializer/EffectSerializer.php new file mode 100644 index 0000000..8eb3ed6 --- /dev/null +++ b/src/Serializer/EffectSerializer.php @@ -0,0 +1,27 @@ + OperationSerializer::toJsonArray($effect->getOperations()), + 'transforms' => TransformSerializer::toJsonArray($effect->getTransforms()), + ); + } + + public static function fromJson(array $json): Effect + { + return new Effect( + OperationSerializer::fromJsonArray($json['operations']), + TransformSerializer::fromJsonArray($json['transforms']) + ); + } +} diff --git a/src/Serializer/OperationSerializer.php b/src/Serializer/OperationSerializer.php new file mode 100644 index 0000000..6306f9d --- /dev/null +++ b/src/Serializer/OperationSerializer.php @@ -0,0 +1,24 @@ + $operation->getKey(), + 'kind' => $operation->getKind(), + ); + } + + public static function fromJson(array $json): Operation + { + return new Operation($json['key'], $json['kind']); + } +} diff --git a/src/Serializer/StatusSerializer.php b/src/Serializer/StatusSerializer.php index 4b6e836..341c55e 100644 --- a/src/Serializer/StatusSerializer.php +++ b/src/Serializer/StatusSerializer.php @@ -12,6 +12,7 @@ class StatusSerializer extends JsonSerializer public static function toJson($status): array { return array( + 'api_version' => $status->getApiVersion(), 'chainspec_name' => $status->getChainspecName(), 'starting_state_root_hash' => $status->getStartingStateRootHash(), 'last_added_block_info' => BlockInfoSerializer::toJson($status->getLastAddedBlockInfo()), @@ -20,6 +21,10 @@ public static function toJson($status): array 'build_version' => $status->getBuildVersion(), 'next_upgrade' => $status->getNextUpgrade() ? NextUpgradeSerializer::toJson($status->getNextUpgrade()) : null, 'peers' => PeerSerializer::toJsonArray($status->getPeers()), + 'uptime' => $status->getUptime(), + 'reactor_state' => $status->getReactorState(), + 'last_progress' => $status->getLastProgress()->format('Y-m-d\TH:i:s.v\Z'), + 'available_block_range' => BlockRangeSerializer::toJson($status->getAvailableBlockRange()), ); } @@ -29,6 +34,7 @@ public static function toJson($status): array public static function fromJson(array $json): Status { return new Status( + $json['api_version'], $json['chainspec_name'], $json['starting_state_root_hash'], BlockInfoSerializer::fromJson($json['last_added_block_info']), @@ -36,7 +42,11 @@ public static function fromJson(array $json): Status $json['round_length'], $json['build_version'], isset($json['next_upgrade']) ? NextUpgradeSerializer::fromJson($json['next_upgrade']) : null, - PeerSerializer::fromJsonArray($json['peers']) + PeerSerializer::fromJsonArray($json['peers']), + $json['uptime'], + $json['reactor_state'], + new \DateTime($json['last_progress']), + BlockRangeSerializer::fromJson($json['available_block_range']) ); } } diff --git a/src/Serializer/TransformSerializer.php b/src/Serializer/TransformSerializer.php new file mode 100644 index 0000000..b3425b2 --- /dev/null +++ b/src/Serializer/TransformSerializer.php @@ -0,0 +1,24 @@ + $transform->getKey(), + 'transform' => $transform->getTransform(), + ); + } + + public static function fromJson(array $json): Transform + { + return new Transform($json['key'], $json['transform']); + } +} diff --git a/tests/Functional/Rpc/RpcClientTest.php b/tests/Functional/Rpc/RpcClientTest.php index 5c0649a..7086974 100644 --- a/tests/Functional/Rpc/RpcClientTest.php +++ b/tests/Functional/Rpc/RpcClientTest.php @@ -124,11 +124,16 @@ public function testGetPeers(): void public function testGetStatus(): void { $status = $this->rpcClient->getStatus(); + $this->assertNotEmpty($status->getApiVersion()); $this->assertNotEmpty($status->getChainspecName()); $this->assertNotEmpty($status->getStartingStateRootHash()); $this->assertNotEmpty($status->getLastAddedBlockInfo()->getHash()); $this->assertNotEmpty($status->getOurPublicSigningKey()->parsedValue()); $this->assertNotEmpty($status->getBuildVersion()); + $this->assertNotEmpty($status->getUptime()); + $this->assertNotEmpty($status->getReactorState()); + $this->assertNotEmpty($status->getLastProgress()); + $this->assertNotEmpty($status->getAvailableBlockRange()); } public function testGetAuctionState(): void @@ -178,6 +183,20 @@ public function testGetAccountBalance(string $stateRootHash, Account $account): $this->assertGreaterThanOrEqual(0, gmp_cmp($accountBalance, 0)); } + /** + * @depends testGetStateRootHash + * @depends testGetAccount + */ + public function testQueryBalance(string $stateRootHash, Account $account): void + { + $accountBalance = $this->rpcClient->queryBalance( + RpcClient::PURSE_IDENTIFIER_TYPE_UREF, + $account->getMainPurse()->parsedValue(), + $stateRootHash + ); + $this->assertGreaterThanOrEqual(0, gmp_cmp($accountBalance, 0)); + } + /** * @depends testGetStateRootHash * @depends testGetAccount @@ -259,4 +278,12 @@ public function testGetGlobalStateByStateRootHash(): void $globalState = $this->rpcClient->getGlobalStateByStateRootHash($stateRootHash, $deployHashFromTheTestnet); $this->assertEquals($deployHashFromTheTestnet, 'deploy-' . $globalState->getStoredValue()->getDeployInfo()->getDeployHash()); } + + public function testGetChainspecInfo(): void + { + $chainspecInfo = $this->rpcClient->getChainspecInfo(); + $this->assertNotEmpty($chainspecInfo->getChainspecBytes()); + } + + //TODO: Add test for speculative_exec RPC method }