Skip to content

Commit

Permalink
CSDK/implement_state_get_package_rpc (#124)
Browse files Browse the repository at this point in the history
Implement state_get_package RPC mthod
  • Loading branch information
ZhmakAS authored Dec 17, 2024
1 parent 70c7bc7 commit eb3b640
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 8 deletions.
17 changes: 13 additions & 4 deletions rpc/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,24 @@ type ClientInformational interface {
// If the param stateRootHash is nil, the client will make an additional RPC call to retrieve the latest stateRootHash.
QueryGlobalStateByStateHash(ctx context.Context, stateRootHash *string, key string, path []string) (QueryGlobalStateResult, error)

// GetAccountInfoByBlochHash returns a JSON representation of an Account from the network.
// GetAccountInfoByBlockHash returns a JSON representation of an Account from the network.
// The blockHash must refer to a Block after the Account's creation, or the method will return an empty response.
GetAccountInfoByBlochHash(ctx context.Context, blockHash string, pub keypair.PublicKey) (StateGetAccountInfo, error)
// GetAccountInfoByBlochHeight returns a JSON representation of an Account from the network.
GetAccountInfoByBlockHash(ctx context.Context, blockHash string, pub keypair.PublicKey) (StateGetAccountInfo, error)
// GetAccountInfoByBlockHeight returns a JSON representation of an Account from the network.
// The blockHeight must refer to a Block after the Account's creation, or the method will return an empty response.
GetAccountInfoByBlochHeight(ctx context.Context, blockHeight uint64, pub keypair.PublicKey) (StateGetAccountInfo, error)
GetAccountInfoByBlockHeight(ctx context.Context, blockHeight uint64, pub keypair.PublicKey) (StateGetAccountInfo, error)
// GetAccountInfo returns a JSON representation of an Account from the network.
// This is the most generic interface.
GetAccountInfo(ctx context.Context, blockIdentifier *ParamBlockIdentifier, accountIdentifier AccountIdentifier) (StateGetAccountInfo, error)
// GetPackageByBlockHeight returns a Package from the network by BlockHeight
// The blockHeight must refer to a Block after the Package's creation, or the method will return an empty response.
GetPackageByBlockHeight(ctx context.Context, packageHash string, blockHeight uint64) (StateGetPackage, error)
// GetPackageByBlockHash returns a Package from the network by BlockHash
// The blockHash must refer to a Block after the Package's creation, or the method will return an empty response.
GetPackageByBlockHash(ctx context.Context, packageHash string, blockHash string) (StateGetPackage, error)
// GetPackage returns a Package from the network
// This is the most generic interface.
GetPackage(ctx context.Context, packageIdentifier PackageIdentifier, blockIdentifier *ParamBlockIdentifier) (StateGetPackage, error)

// GetLatestEntity returns latest AddressableEntity from the network.
GetLatestEntity(ctx context.Context, entityIdentifier EntityIdentifier) (StateGetEntityResult, error)
Expand Down
23 changes: 23 additions & 0 deletions rpc/request.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package rpc
import (
"context"
"strconv"
"strings"

"github.com/make-software/casper-go-sdk/v2/types"
"github.com/make-software/casper-go-sdk/v2/types/key"
Expand Down Expand Up @@ -38,6 +39,7 @@ const (
MethodGetDictionaryItem Method = "state_get_dictionary_item"
MethodGetStateBalance Method = "state_get_balance"
MethodGetStateAccount Method = "state_get_account_info"
MethodGetStatePackage Method = "state_get_package"
MethodGetStateEntity Method = "state_get_entity"
MethodGetEraInfo Method = "chain_get_era_info_by_switch_block"
MethodGetBlock Method = "chain_get_block"
Expand Down Expand Up @@ -211,6 +213,27 @@ type SpeculativeExecParams struct {
BlockIdentifier *BlockIdentifier `json:"block_identifier,omitempty"`
}

type ParamStateGetPackage struct {
PackageIdentifier PackageIdentifier `json:"package_identifier"`
ParamBlockIdentifier
}

type PackageIdentifier struct {
PackageAddr *string `json:"PackageAddr,omitempty"`
ContractPackageHash *string `json:"ContractPackageHash,omitempty"`
}

func NewPackageIdentifierFromHash(hash string) PackageIdentifier {
if strings.HasPrefix(hash, "package-") {
return PackageIdentifier{
PackageAddr: &hash,
}
}
return PackageIdentifier{
ContractPackageHash: &hash,
}
}

type PurseIdentifier struct {
MainPurseUnderPublicKey *keypair.PublicKey `json:"main_purse_under_public_key,omitempty"`
MainPurseUnderAccountHash *key.AccountHash `json:"main_purse_under_account_hash,omitempty"`
Expand Down
18 changes: 18 additions & 0 deletions rpc/response.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,24 @@ func (b StateGetBalanceResult) GetRawJSON() json.RawMessage {
return b.rawJSON
}

type StateGetPackage struct {
ApiVersion string `json:"api_version"`
Package Package `json:"package"`
//MerkleProof is a construction created using a merkle trie that allows verification of the associated hashes.
MerkleProof json.RawMessage `json:"merkle_proof"`

rawJSON json.RawMessage
}

type Package struct {
ContractPackage *types.ContractPackage `json:"ContractPackage"`
Package *types.Package `json:"Package"`
}

func (b StateGetPackage) GetRawJSON() json.RawMessage {
return b.rawJSON
}

type StateGetAccountInfo struct {
ApiVersion string `json:"api_version"`
Account types.Account `json:"account"`
Expand Down
43 changes: 41 additions & 2 deletions rpc/rpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,7 @@ func (c *client) GetEntityByBlockHeight(ctx context.Context, entityIdentifier En
return result, nil
}

func (c *client) GetAccountInfoByBlochHash(ctx context.Context, blockHash string, pub keypair.PublicKey) (StateGetAccountInfo, error) {
func (c *client) GetAccountInfoByBlockHash(ctx context.Context, blockHash string, pub keypair.PublicKey) (StateGetAccountInfo, error) {
var result StateGetAccountInfo

resp, err := c.processRequest(ctx, MethodGetStateAccount, ParamGetAccountInfoBalance{AccountIdentifier: pub.String(), ParamBlockIdentifier: NewParamBlockByHash(blockHash)}, &result)
Expand All @@ -265,7 +265,7 @@ func (c *client) GetAccountInfoByBlochHash(ctx context.Context, blockHash string
return result, nil
}

func (c *client) GetAccountInfoByBlochHeight(ctx context.Context, blockHeight uint64, pub keypair.PublicKey) (StateGetAccountInfo, error) {
func (c *client) GetAccountInfoByBlockHeight(ctx context.Context, blockHeight uint64, pub keypair.PublicKey) (StateGetAccountInfo, error) {
var result StateGetAccountInfo
resp, err := c.processRequest(ctx, MethodGetStateAccount, ParamGetAccountInfoBalance{AccountIdentifier: pub.String(), ParamBlockIdentifier: NewParamBlockByHeight(blockHeight)}, &result)
if err != nil {
Expand Down Expand Up @@ -299,6 +299,45 @@ func (c *client) GetAccountInfo(ctx context.Context, blockIdentifier *ParamBlock
return result, nil
}

func (c *client) GetPackageByBlockHeight(ctx context.Context, packageHash string, blockHeight uint64) (StateGetPackage, error) {
var result StateGetPackage

resp, err := c.processRequest(ctx, MethodGetStatePackage, ParamStateGetPackage{PackageIdentifier: NewPackageIdentifierFromHash(packageHash), ParamBlockIdentifier: NewParamBlockByHeight(blockHeight)}, &result)
if err != nil {
return StateGetPackage{}, err
}

result.rawJSON = resp.Result
return result, nil
}

func (c *client) GetPackageByBlockHash(ctx context.Context, packageHash string, blockHash string) (StateGetPackage, error) {
var result StateGetPackage

resp, err := c.processRequest(ctx, MethodGetStatePackage, ParamStateGetPackage{PackageIdentifier: NewPackageIdentifierFromHash(packageHash), ParamBlockIdentifier: NewParamBlockByHash(blockHash)}, &result)
if err != nil {
return StateGetPackage{}, err
}

result.rawJSON = resp.Result
return result, nil
}

func (c *client) GetPackage(ctx context.Context, packageIdentifier PackageIdentifier, blockIdentifier *ParamBlockIdentifier) (StateGetPackage, error) {
if blockIdentifier == nil {
blockIdentifier = &ParamBlockIdentifier{}
}

var result StateGetPackage
resp, err := c.processRequest(ctx, MethodGetStatePackage, ParamStateGetPackage{PackageIdentifier: packageIdentifier, ParamBlockIdentifier: *blockIdentifier}, &result)
if err != nil {
return StateGetPackage{}, err
}

result.rawJSON = resp.Result
return result, nil
}

func (c *client) GetDictionaryItem(ctx context.Context, stateRootHash *string, uref, key string) (StateGetDictionaryResult, error) {
return c.GetDictionaryItemByIdentifier(ctx, stateRootHash, ParamDictionaryIdentifier{
URef: &ParamDictionaryIdentifierURef{
Expand Down
23 changes: 23 additions & 0 deletions tests/data/package/get-package-result-contract-package-v200.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"api_version": "2.0.0",
"package": {
"ContractPackage": {
"access_key": "uref-6fc684fea74b278cbb18b546a6d9242b810ce58a2ff05d17493b19aa08f540e0-007",
"versions": [
{
"protocol_version_major": 2,
"contract_version": 1,
"contract_hash": "contract-25aa2d3cc62a302746c08ae885454d6e8a9c8609aaa7468b24284e5d29c5d2f1"
}
],
"disabled_versions": [],
"groups": [],
"lock_status": "Unlocked"
}
},
"merkle_proof": "010000000116aa0d0ad73d3534ba543a574f2a521fd770e4cb436ca0741e8a02eae8fdbf08046fc684fea74b278cbb18b546a6d9242b810ce58a2ff05d17493b19aa08f540e00701000000020000000100000025aa2d3cc62a302746c08ae885454d6e8a9c8609aaa7468b24284e5d29c5d2f1000000000000000000020000000016080000002500309ea1908b14a258eb4246b0b4cf2181f9a079e97571bb5cf5edf2cc6b1dd26848001b5a6e381c3fd5e9983555281b928e75ee6e6b17eb4ca779581b2073313e9e7d5300162d2614d188e62d6b8d8148b9455feedb784c39230ef2df6610f4706da05a466300d25c1b5580816475df74470a0c397baf8c4c5ea1016f9742414fc145d048aca3a600f91a5d4a604d79b244b83c89716caf516e75e951f4e32995101916fdeea30721ae00a77ba4e92715b5285ff5bbda6cfc1a75fb6160d9f8c237abe9c7eef3aa0d448abb0032729b6868c15a80e2315f291020073922c81a445f3220e6214262823e7690a7e3000264f63a177c0d3bdf4501f85fc99ef7a25335f15cf01c7e5092e101eb13c8810001090000000001a3595f9802a8c4ecc4f74cbbcf6ea4cd484fb643ee6ed49f6d6a8ad4816f123002013ba7feb38dc3c94f0fc6dd8eefa88b87e0a6d0fb6372d8c166c0861812efa0970601fbbff6ca6374c82315ce70bd07ad0b6e503aab81fb9eedf4eee2806cdb44f5310a0062e02bef4f516c7bf650d0e7a7f92c3278515b193eb2067cea0b40f8208626d40b00b7aac0f3f6692862b38c63e0df2a381945f48c00f7dba20994dde801b102e3eb0d004cc57d085abe7a34c1c509178c52296cedf995770f0023a195cbf3b713494a9c0e0043d39741a6e7b395eace3b1fbbbd5bbf288f7a788e80745a2e2bb0f2173a8b4f0f01951506a8635a859363abd1c96f88d1b972d2b8be5b8620c9e01d9cf0933a477b1500cb808b7d2846894f16ea158ab0df1e92b8ce3bf9e19d1e06e66662f424906cb9"
}
}
24 changes: 24 additions & 0 deletions tests/data/package/get-package-result-package-v200.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"jsonrpc": "2.0",
"id": "1",
"result": {
"api_version": "2.0.0",
"package": {
"Package": {
"versions": [
{
"entity_version_key": {
"protocol_version_major": 2,
"entity_version": 1
},
"addressable_entity_hash": "addressable-entity-e51af99d88fd26a282de00271c49a6c256232b344aa7907d2c8603b2bd5217c9"
}
],
"disabled_versions": [],
"groups": [],
"lock_status": "Unlocked"
}
},
"merkle_proof": "010000000116aa0d0ad73d3534ba543a574f2a521fd770e4cb436ca0741e8a02eae8fdbf08046fc684fea74b278cbb18b546a6d9242b810ce58a2ff05d17493b19aa08f540e00701000000020000000100000025aa2d3cc62a302746c08ae885454d6e8a9c8609aaa7468b24284e5d29c5d2f1000000000000000000020000000016080000002500309ea1908b14a258eb4246b0b4cf2181f9a079e97571bb5cf5edf2cc6b1dd26848001b5a6e381c3fd5e9983555281b928e75ee6e6b17eb4ca779581b2073313e9e7d5300162d2614d188e62d6b8d8148b9455feedb784c39230ef2df6610f4706da05a466300d25c1b5580816475df74470a0c397baf8c4c5ea1016f9742414fc145d048aca3a600f91a5d4a604d79b244b83c89716caf516e75e951f4e32995101916fdeea30721ae00a77ba4e92715b5285ff5bbda6cfc1a75fb6160d9f8c237abe9c7eef3aa0d448abb0032729b6868c15a80e2315f291020073922c81a445f3220e6214262823e7690a7e3000264f63a177c0d3bdf4501f85fc99ef7a25335f15cf01c7e5092e101eb13c8810001090000000001a3595f9802a8c4ecc4f74cbbcf6ea4cd484fb643ee6ed49f6d6a8ad4816f123002013ba7feb38dc3c94f0fc6dd8eefa88b87e0a6d0fb6372d8c166c0861812efa0970601fbbff6ca6374c82315ce70bd07ad0b6e503aab81fb9eedf4eee2806cdb44f5310a0062e02bef4f516c7bf650d0e7a7f92c3278515b193eb2067cea0b40f8208626d40b00b7aac0f3f6692862b38c63e0df2a381945f48c00f7dba20994dde801b102e3eb0d004cc57d085abe7a34c1c509178c52296cedf995770f0023a195cbf3b713494a9c0e0043d39741a6e7b395eace3b1fbbbd5bbf288f7a788e80745a2e2bb0f2173a8b4f0f01951506a8635a859363abd1c96f88d1b972d2b8be5b8620c9e01d9cf0933a477b1500cb808b7d2846894f16ea158ab0df1e92b8ce3bf9e19d1e06e66662f424906cb9"
}
}
35 changes: 33 additions & 2 deletions tests/rpc/rpc_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,37 @@ func Test_DefaultClient_GetDeploy_Example(t *testing.T) {
}
}

func Test_DefaultClient_GetPackage_Example(t *testing.T) {
tests := []struct {
filePath string
isPackage bool
}{
{
filePath: "../data/package/get-package-result-contract-package-v200.json",
},
{
filePath: "../data/package/get-package-result-package-v200.json",
isPackage: true,
},
}
for _, tt := range tests {
t.Run("GetTransaction", func(t *testing.T) {
server := SetupServer(t, tt.filePath)
defer server.Close()
client := casper.NewRPCClient(casper.NewRPCHandler(server.URL, http.DefaultClient))
result, err := client.GetPackageByBlockHeight(context.Background(), "package-0009ea4441f4700325d9c38b0b6df415537596e1204abe4f6a94b6996aebf2f1", 0)
require.NoError(t, err)
require.NotEmpty(t, result)

if tt.isPackage {
require.NotEmpty(t, result.Package.Package)
} else {
require.NotEmpty(t, result.Package.ContractPackage)
}
})
}
}

func Test_DefaultClient_GetTransaction_Example(t *testing.T) {
tests := []struct {
filePath string
Expand Down Expand Up @@ -467,7 +498,7 @@ func Test_DefaultClient_GetAccountInfoByBlochHash(t *testing.T) {
pubKey, err := casper.NewPublicKey("01018525deae6091abccab6704a0fa44e12c495eec9e8fe6929862e1b75580e715")
require.NoError(t, err)
blockHash := "bf06bdb1616050cea5862333d1f4787718f1011c95574ba92378419eefeeee59"
res, err := client.GetAccountInfoByBlochHash(context.Background(), blockHash, pubKey)
res, err := client.GetAccountInfoByBlockHash(context.Background(), blockHash, pubKey)
require.NoError(t, err)
assert.Equal(t, "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c", res.Account.AccountHash.ToPrefixedString())
}
Expand All @@ -478,7 +509,7 @@ func Test_DefaultClient_GetAccountInfoByBlochHeight(t *testing.T) {
client := casper.NewRPCClient(casper.NewRPCHandler(server.URL, http.DefaultClient))
pubKey, err := casper.NewPublicKey("01018525deae6091abccab6704a0fa44e12c495eec9e8fe6929862e1b75580e715")
require.NoError(t, err)
res, err := client.GetAccountInfoByBlochHeight(context.Background(), 185, pubKey)
res, err := client.GetAccountInfoByBlockHeight(context.Background(), 185, pubKey)
require.NoError(t, err)
assert.Equal(t, "account-hash-e94daaff79c2ab8d9c31d9c3058d7d0a0dd31204a5638dc1451fa67b2e3fb88c", res.Account.AccountHash.ToPrefixedString())
}
Expand Down

0 comments on commit eb3b640

Please sign in to comment.