diff --git a/test-specifications/crypto-service/accountUpdateTransaction.md b/test-specifications/crypto-service/accountUpdateTransaction.md index 9f05002..93ea5ef 100644 --- a/test-specifications/crypto-service/accountUpdateTransaction.md +++ b/test-specifications/crypto-service/accountUpdateTransaction.md @@ -1,12 +1,10 @@ # AccountUpdateTransaction - Test specification ## Description: - -This test specification for the AccountUpdateTransaction is to be one of many for testing the functionality of the Hedera SDKs. The SDK under test will use the language specific JSON-RPC server return responses back to the test driver. +This test specification for AccountUpdateTransaction is to be one of many for testing the functionality of the Hedera SDKs. The SDK under test will use the language specific JSON-RPC server return responses back to the test driver. ## Design: - -Each test within the test specification is linked to one of the properties within AccountUpdateTransaction. Each property is tested with a mix of boundaries. The inputs for each test are a range of valid, minimum, maximum, negative and invalid values for the method. The expected response of a passed test can be a correct error or a results of node queries. Success on the consensus node can be obtained by a queries such as AccountInfoQuery or AccountBalanceQuery, and on the mirror node through the rest API. Error codes are obtained from the response code proto files. +Each test within the test specification is linked to one of the properties within AccountUpdateTransaction. Each property is tested with a mix of boundaries. The inputs for each test are a range of valid, minimum, maximum, negative and invalid values for the method. The expected response of a passed test can be a correct error response code or seen as the result of node queries. A successful transaction (the transaction reached consensus and was applied to state) can be determined by getting a `TransactionReceipt` or `TransactionRecord`, or can be determined by using queries such as `AccountInfoQuery` or `AccountBalanceQuery` and investigating for the required changes (creations, updates, etc.). The mirror node can also be used to determine if a transaction was successful via its rest API. Error codes are obtained from the response code proto files. **Transaction properties:** @@ -19,111 +17,440 @@ https://github.com/hashgraph/hedera-protobufs/blob/main/services/crypto_update.p **Response codes:** https://github.com/hashgraph/hedera-protobufs/blob/main/services/response_code.proto -## Initialisation: -```jsx -new AccountUpdateTransaction(); +**Mirror Node APIs:** -//example +https://docs.hedera.com/hedera/sdks-and-apis/rest-api -const transaction = new AccountUpdateTransaction().setAccountId(accountId).setKey(publicKey); -``` +## JSON-RPC API Endpoint Documentation + +### Method Name + +`updateAccount` + +### Input Parameters + +| Parameter Name | Type | Required/Optional | Description/Notes | +|---------------------------|--------------------------------------------------|-------------------|--------------------------------------------------------------------------------------------------------------------------------------------| +| accountId | string | optional | The ID of the account to update. | +| key | string | optional | DER-encoded hex string representation for private or public keys. KeyLists and ThresholdKeys are the hex of the serialized protobuf bytes. | +| autoRenewPeriod | int64 | optional | Units of seconds | +| expirationTime | int64 | optional | Epoch time | +| receiverSignatureRequired | bool | optional | | +| memo | string | optional | | +| maxAutoTokenAssociations | int32 | optional | | +| stakedAccountId | string | optional | | +| stakedNodeId | int64 | optional | | +| declineStakingReward | bool | optional | | +| commonTransactionParams | [json object](../commonTransactionParameters.md) | optional | | + +### Output Parameters + +| Parameter Name | Type | Description/Notes | +|----------------|--------|---------------------------------------------------------------------------------------| +| status | string | The status of the submitted `AccountUpdateTransaction` (from a `TransactionReceipt`). | + +### Additional Notes -## Properties +The tests contained in this specification will assume that a valid account was already successfully created. Assume that the account was created with default values, unless specified otherwise. Any `` tag will be the account ID of this created account. Any `` is the DER-encoded hex string of the private key of the account. -### **AccountId:** +## Property Tests + +### **Account ID:** - The ID of the account to update. -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|----------------------------------------------------------------------------------|-----------------------|---------------------------------------------------------------|-------------------| -| 1 | Update an account with no updates | accountId, privateKey | The account update succeeds | N | -| 2 | Update an account with no updates without signing with the account's private key | accountId | The account update fails with response code INVALID_SIGNATURE | N | +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|-----------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------|-------------------| +| 1 | Updates an account with no updates | accountId=, commonTransactionParams.signers=[] | The account update succeeds. | N | +| 2 | Updates an account with no updates without signing with the account's private key | accountId= | The account update fails with an INVALID_SIGNATURE response code from the network. | N | +| 3 | Updates an account with no account ID | | The account update fails with an INVALID_ACCOUNT_ID response code from the network. | N | + +#### JSON Request Example + +```json +{ + "jsonrpc": "2.0", + "id": 541, + "method": "updateAccount", + "params": { + "accountId": "0.0.15432" + } +} +``` +#### JSON Response Example + +```json +{ + "jsonrpc": "2.0", + "id": 541, + "result": { + "status": "SUCCESS" + } +} +``` ### **Key:** -- The public key to update on the account. +- The desired new key of the account. + +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------|-------------------| +| 1 | Updates the key of an account to a new valid ED25519 public key | accountId=, key=, commonTransactionParams.signers=[, ] | The account update succeeds and the account has the new ED25519 key. | N | +| 2 | Updates the key of an account to a new valid ECDSAsecp256k1 public key | accountId=, key=, commonTransactionParams.signers=[, ] | The account update succeeds and the account has the new ECDSAsecp256k1 key. | N | +| 3 | Updates the key of an account to a new valid ED25519 private key | accountId=, key=, commonTransactionParams.signers=[, ] | The account update succeeds and the account has the new ED25519 key. | N | +| 4 | Updates the key of an account to a new valid ECDSAsecp256k1 private key | accountId=, key=, commonTransactionParams.signers=[, ] | The account update succeeds and the account has the new ECDSAsecp256k1 key. | N | +| 5 | Updates the key of an account to a new valid valid KeyList of ED25519 and ECDSAsecp256k1 private and public keys | accountId=, key=, commonTransactionParams.signers=[, ] | The account update succeeds and the account has the new KeyList. | N | +| 6 | Updates the key of an account to a new valid KeyList of nested KeyLists (three levels) | accountId=, key=, commonTransactionParams.signers=[, ] | The account update succeeds and the account has the new nested KeyList. | N | +| 7 | Updates the key of an account to a new valid ThresholdKey of ED25519 and ECDSAsecp256k1 private and public keys | accountId=, key=, commonTransactionParams.signers=[, ] | The account update succeeds and the account has the new ThresholdKey. | N | +| 8 | Updates the key of an account to a new valid key without signing with the new key | accountId=, key=, commonTransactionParams.signers=[] | The account update fails with a INVALID_SIGNATURE response code from the network. | N | +| 9 | Updates the key of an account to a new valid public key and signs with an incorrect private key | accountId=, key=, commonTransactionParams.signers=[, ] | The account update fails with response code INVALID_SIGNATURE | N | + +#### JSON Request Example + +```json +{ + "jsonrpc": "2.0", + "id": 538, + "method": "updateAccount", + "params": { + "accountId": "0.0.768", + "key": "302A300506032B6570032100EA746B07CFA75F9273BDC3F2495A43DE15720719DA6ED70AEC2D829ACC6A4ECD", + "commonTransactionParams": { + "signers": [ + "302E020100300506032B657004220420DE6788D0A09F20DED806F446C02FB929D8CD8D17022374AFB3739A1D50BA72C8", + "302E020100300506032B657004220420C212D124233D70BA8F6F07BF01A44E98418799E3F8ABD2B42C69EC03B53A4E1B" + ] + } + } +} +``` -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------|----------------------------------------------------------------------------------|-------------------| -| 1 | Update an account with a new public ED25519 key | accountId, oldPrivateKey, newPrivateKey, newPublicKey | The account update succeeds and the account has the new key | N | -| 2 | Update an account with a new public ECDSA key | accountId, oldPrivateKey, newPrivateKey, newPublicKey | The account update succeeds and the account has the new key | N | -| 3 | Update an account key without signing with new private key | accountId, oldPrivateKey, newPublicKey | The account update fails with response code INVALID_SIGNATURE | N | -| 4 | Update an account key and sign with incorrect private key | accountId, oldPrivateKey, wrongPrivateKey, newPublicKey | The account update fails with response code INVALID_SIGNATURE | N | -| 5 | Update an account key to an ECDSA threshold key and sign with the old key + threshold key | accountId, oldPrivateKey, thresholdPrivateKey, newThresholdPublicKey | The account update succeeds and the account has an ECDSA threshold key | N | -| 6 | Update an account key to an ED25519 threshold key and sign with the old key + threshold key | accountId, oldPrivateKey, thresholdPrivateKey, newThresholdPublicKey | The account update succeeds and the account has an ED25519 threshold key | N | -| 7 | Update an account key that is composed of both ED25519 + ECSDA threshold key and sign with the old key + threshold key | accountId, oldPrivateKey, thresholdPrivateKey, newThresholdPublicKey | The account update succeeds and the account has an ED25519 + ECSDA threshold key | N | +#### JSON Response Example + +```json +{ + "jsonrpc": "2.0", + "id": 538, + "result": { + "status": "SUCCESS" + } +} +``` ### **Auto Renew Period:** -- The account is charged to extend its expiration date every period of time. If it doesn't have enough balance, it extends as long as possible. If it is empty when it expires, then it is deleted. +- The desired new auto-renew period for the account. The account is charged to extend its expiration date every ‘this many’ seconds. If it doesn't have enough balance, it extends as long as possible. If it is empty when it expires, then it is deleted. + +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|-------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------|-------------------| +| 1 | Updates the auto-renew period of an account to 60 days (5,184,000 seconds) | accountId=, autoRenewPeriod=5184000, commonTransactionParams.signers=[] | The account update succeeds and the account's auto renew period should equal 5,184,000 seconds. | N | +| 2 | Updates the auto-renew period of an account to -1 seconds | accountId=, autoRenewPeriod=-1, commonTransactionParams.signers=[] | The account update fails with an INVALID_RENEWAL_PERIOD response code from the network. | N | +| 3 | Updates the auto-renew period of an account to the minimum period of 30 days (2,592,000 seconds) | accountId=, autoRenewPeriod=2592000, commonTransactionParams.signers=[] | The account update succeeds and the account's auto renew period should equal 2,592,000 seconds. | N | +| 4 | Updates the auto-renew period of an account to the minimum period of 30 days minus one second (2,591,999 seconds) | accountId=, autoRenewPeriod=2591999, commonTransactionParams.signers=[] | The account update fails with an AUTORENEW_DURATION_NOT_IN_RANGE response code from the network. | N | +| 5 | Updates the auto-renew period of an account to the maximum period of 8,000,001 seconds | accountId=, autoRenewPeriod=8000001, commonTransactionParams.signers=[] | The account update succeeds and the account's auto renew period should equal 8,000,001 seconds. | N | +| 6 | Updates the auto-renew period of an account to the maximum period plus one second (8,000,002 seconds) | accountId=, autoRenewPeriod=8000002, commonTransactionParams.signers=[] | The account update fails with an AUTORENEW_DURATION_NOT_IN_RANGE response code from the network. | N | + +#### JSON Request Example + +```json +{ + "jsonrpc": "2.0", + "id": 6412, + "method": "updateAccount", + "params": { + "accountId": "0.0.32511", + "autoRenewPeriod": 5184000, + "commonTransactionParams": { + "signers": [ + "302E020100300506032B657004220420DE6788D0A09F20DED806F446C02FB929D8CD8D17022374AFB3739A1D50BA72C8" + ] + } + } +} +``` + +#### JSON Response Example -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|----------------------------------------------------------------------------|------------------------------------------------|-----------------------------------------------------------------------------|-------------------| -| 1 | Update an account with an auto renew period of 2,592,000 seconds (30 days) | accountId, privateKey, autoRenewPeriod=2592000 | The account update succeeds and the account has the new auto-renew period | N | -| 2 | Update an account with an auto renew period of -1 seconds | accountId, privateKey, autoRenewPeriod=-1 | The account update fails with response code INVALID_RENEWAL_PERIOD | N | -| 3 | Update an account with an auto renew period of 864,000 seconds (10 days) | accountId, privateKey, autoRenewPeriod=864000 | The account update fails with response code AUTORENEW_DURATION_NOT_IN_RANGE | N | +```json +{ + "jsonrpc": "2.0", + "id": 6412, + "result": { + "status": "SUCCESS" + } +} +``` ### **Expiration Time:** -- The time at which the account will expire and attempt to extend its expiration date. +- The desired new expiration time of the account. This is the time at which the account will expire and attempt to extend its expiration date. + +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|---------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------|-------------------| +| 1 | Updates the expiration time of an account to 60 days (5,184,000 seconds) from the current time | accountId=, expirationTime= + 5184000, commonTransactionParams.signers=[] | The account update succeeds and the account's expiration time should equal 5,184,000 seconds from the current time. | N | +| 2 | Updates the expiration time of an account to -1 seconds from the current time | accountId=, expirationTime= -1, commonTransactionParams.signers=[] | The account update fails with an EXPIRATION_REDUCTION_NOT_ALLOWED response code from the network. | N | +| 3 | Updates the expiration time of an account to the minimum period of 30 days (2,592,000 seconds) from the current time | accountId=, expirationTime= + 2592000, commonTransactionParams.signers=[] | The account update succeeds and the account's auto renew period should equal 2,592,000 seconds from the current time. | N | +| 4 | Updates the expiration time of an account to the minimum period of 30 days minus one second (2,591,999 seconds) from the current time | accountId=, expirationTime= + 2591999, commonTransactionParams.signers=[] | The account update fails with an INVALID_EXPIRATION_TIME response code from the network. | N | +| 5 | Updates the expiration time of an account to the maximum period of 8,000,001 seconds from the current time | accountId=, expirationTime= + 8000001, commonTransactionParams.signers=[] | The account update succeeds and the account's auto renew period should equal 8,000,001 seconds from the current time. | N | +| 6 | Updates the expiration time of an account to the maximum period plus one second (8,000,002 seconds) from the current time | accountId=, expirationTime= + 8000002, commonTransactionParams.signers=[] | The account update fails with an INVALID_EXPIRATION_TIME response code from the network. | N | + +#### JSON Request Example + +```json +{ + "jsonrpc": "2.0", + "id": 12137, + "method": "updateAccount", + "params": { + "accountId": "0.0.8993", + "expirationTime": 5184000, + "commonTransactionParams": { + "signers": [ + "302E020100300506032B657004220420C212D124233D70BA8F6F07BF01A44E98418799E3F8ABD2B42C69EC03B53A4E1B" + ] + } + } +} +``` -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|---------------------------------------------------------------------------------------|-----------------------------------------------|--------------------------------------------------------------------------|-------------------| -| 1 | Update an account with an expiration time of 2,592,000 seconds (30 days) from runtime | accountId, privateKey, expirationTime=2592000 | The account update succeeds and the account has the new expiration time | N | -| 2 | Update an account with an expiration time of -1 seconds from runtime | accountId, privateKey, expirationTime=-1 | The account update fails with response code INVALID_EXPIRATION_TIME | N | +#### JSON Response Example + +```json +{ + "jsonrpc": "2.0", + "id": 12137, + "result": { + "status": "SUCCESS" + } +} +``` ### **Receiver Signature Required:** -- If true, the account's key must sign any transaction depositing into the account (in addition to all withdrawals). +- The desired new receiver signature required policy for the account. If true, this account's key must sign any transaction depositing into this account (in addition to all withdrawals). + +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|---------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------|-------------------| +| 1 | Updates the receiver signature required policy of an account to require a receiving signature | accountId=, receiverSignatureRequired=true, commonTransactionParams.signers=[] | The account update succeeds and the account requires a receiving signature. | N | +| 2 | Updates the receiver signature required policy of an account to not require a receiving signature | accountId=, receiverSignatureRequired=false, commonTransactionParams.signers=[] | The account update succeeds and the account doesn't require a receiving signature. | N | + +#### JSON Request Example + +```json +{ + "jsonrpc": "2.0", + "id": 7546, + "method": "updateAccount", + "params": { + "accountId": "0.0.5483", + "receiverSignatureRequired": true, + "commonTransactionParams": { + "signers": [ + "302e020100300506032b65700422042031f8eb3e77a04ebe599c51570976053009e619414f26bdd39676a5d3b2782a1d" + ] + } + } +} +``` -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|--------------------------------------------------------|--------------------------------------------------------|------------------------------------------------------------------------------------------|-------------------| -| 1 | Update an account to require a receiving signature | accountId, privateKey, receiverSignatureRequired=true | The account update succeeds and the account has receiverSignatureRequired equal to true | N | -| 2 | Update an account to not require a receiving signature | accountId, privateKey, receiverSignatureRequired=false | The account update succeeds and the account has receiverSignatureRequired equal to false | N | +#### JSON Response Example +```json +{ + "jsonrpc": "2.0", + "id": 7546, + "result": { + "status": "SUCCESS" + } +} +``` ### **Memo:** -- The memo associated with the account (UTF-8 encoding max 100 bytes). +- The desired new memo of the account (UTF-8 encoding max 100 bytes). + +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|--------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------|-------------------| +| 1 | Updates the memo of an account to a memo that is a valid length | accountId=, memo="testmemo", commonTransactionParams.signers=[] | The account update succeeds and the account's memo equals “testmemo”. | N | +| 2 | Updates the memo of an account to a memo that is the minimum length | accountId=, memo="", commonTransactionParams.signers=[] | The account update succeeds and the account's memo is empty. | N | +| 3 | Updates the memo of an account to a memo that is the maximum length | accountId=, memo="This is a really long memo but it is still valid because it is 100 characters exactly on the money!!", commonTransactionParams.signers=[] | The account update succeeds and the account's memo equals "This is a really long memo but it is still valid because it is 100 characters exactly on the money!!". | N | +| 4 | Updates the memo of an account to a memo that exceeds the maximum length | accountId=, memo="This is a long memo that is not valid because it exceeds 100 characters and it should fail the test!!", commonTransactionParams.signers=[] | The account update fails with a MEMO_TOO_LONG response code from the network. | N | + +#### JSON Request Example + +```json +{ + "jsonrpc": "2.0", + "id": 5429, + "method": "updateAccount", + "params": { + "accountId": "0.0.553", + "memo": "testmemo", + "commonTransactionParams": { + "signers": [ + "302e020100300506032b65700422042031f8eb3e77a04ebe599c51570976053009e619414f26bdd39676a5d3b2782a1d" + ] + } + } +} +``` -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|-----------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------|-------------------| -| 1 | Update an account with a valid length memo | accountId, privateKey, memo="test memo" | The account update succeeds and the account has the new memo | N | -| 2 | Update an account with a memo that exceeds 100 characters | accountId, privateKey, memo="this is a very long test memo that should not work and should cause the test to fail and return an error response" | The account update fails and returns error response MEMO_TOO_LONG | N | +#### JSON Response Example + +```json +{ + "jsonrpc": "2.0", + "id": 5429, + "result": { + "status": "SUCCESS" + } +} +``` ### **Max Automatic Token Associations:** -- The maximum number of tokens with which the account can be implicitly associated. Defaults to 0 and up to a maximum value of 1000. +- The new desired max automatic token associations for the account. The maximum number of tokens with which an account can be implicitly associated. Defaults to 0 and up to a maximum value of 5000. + +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|---------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------|-------------------| +| 1 | Updates the max automatic token associations of an account to a valid amount | accountId=, maxAutoTokenAssociations=100, commonTransactionParams.signers=[] | The account update succeeds and the account has 100 automatic token associations. | N | +| 2 | Updates the max automatic token associations of an account to the minimum amount | accountId=, maxAutoTokenAssociations=0, commonTransactionParams.signers=[] | The account update succeeds and the account has 0 automatic token associations. | N | +| 3 | Updates the max automatic token associations of an account to the maximum amount | accountId=, maxAutoTokenAssociations=5000, commonTransactionParams.signers=[] | The account update succeeds and the account has 5000 automatic token associations. | N | +| 4 | Updates the max automatic token associations of an account to an amount that exceeds the maximum amount | accountId=, maxAutoTokenAssociations=5001, commonTransactionParams.signers=[] | The account update fails with a REQUESTED_NUM_AUTOMATIC_ASSOCIATIONS_EXCEEDS_ASSOCIATION_LIMIT response code from the network. | N | + +#### JSON Request Example + +```json +{ + "jsonrpc": "2.0", + "id": 12116, + "method": "updateAccount", + "params": { + "accountId": "0.0.53671", + "maxAutoTokenAssociations": 100, + "commonTransactionParams": { + "signers": [ + "302e020100300506032b65700422042031f8eb3e77a04ebe599c51570976053009e619414f26bdd39676a5d3b2782a1d" + ] + } + } +} +``` -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|-------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------|-------------------| -| 1 | Update an account to a valid association amount (500) | accountId, privateKey, maxAutomaticTokenAssociations=500 | The account update succeeds and the account maxAutomaticTokenAssociations equals 500 | N | -| 2 | Update an account to the maximum max token association set to maximum value | accountId, privateKey, maxAutomaticTokenAssociations=1000 | The account update succeeds and the account maxAutomaticTokenAssociations equals 1000 | N | -| 3 | Update an account with a token association over the maximum value | accountId, privateKey, maxAutomaticTokenAssociations=1001 | The account update fails and returns error response REQUESTED_NUM_AUTOMATIC_ASSOCIATIONS_EXCEEDS_ASSOCIATION_LIMIT | N | -| 4 | Update an account with a token association (0) under the number of token associations the account already has (1) | accountId, privateKey, maxAutomaticTokenAssociations=0 | The account update fails and returns error response EXISTING_AUTOMATIC_ASSOCIATIONS_EXCEED_GIVEN_LIMIT | N | | +#### JSON Response Example +```json +{ + "jsonrpc": "2.0", + "id": 12116, + "result": { + "status": "SUCCESS" + } +} +``` ### **Staked ID:** -- The ID of the account or node to which the account is staking. +- The ID of the new desired account to which the account is staked. + - OR +- The ID of the new desired node to which this account is staked. + +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------|-------------------| +| 1 | Updates the staked account ID of an account to the operators account ID | accountId=, stakedAccountId=, commonTransactionParams.signers=[] | The account update succeeds and the account has a staking account ID equal to the input account ID. | N | +| 2 | Updates the staked node ID of an account to a valid node ID | accountId=, stakedNodeId=, commonTransactionParams.signers=[] | The account update succeeds and the account has a staking node ID equal to the input node ID. | N | +| 3 | Updates the staked account ID of an account to an account ID that doesn't exist | accountId=, stakedAccountId="123.456.789", commonTransactionParams.signers=[] | The account update fails with an INVALID_STAKING_ID response code from the network. | N | +| 4 | Updates the staked account ID of an account to a node ID that doesn't exist | accountId=, stakedNodeId=123456789, commonTransactionParams.signers=[] | The account update fails with an INVALID_STAKING_ID response code from the network. | N | +| 5 | Updates the staked account ID of an account to an empty account ID | accountId=, stakedAccountId="", commonTransactionParams.signers=[] | The account update fails with and SDK internal error. | N | +| 6 | Updates the staked account ID of an account to an invalid node ID | accountId=, stakedNodeId=-100, commonTransactionParams.signers=[] | The account update fails with an INVALID_STAKING_ID response code from the network. | N | +| 7 | Updates the staked account ID and staked node ID of an account | accountId=, stakedAccountId=, stakedNodeId=, commonTransactionParams.signers=[] | The account update fails with an INVALID_STAKING_ID response code from the network. | N | + +#### JSON Request Examples + +```json +{ + "jsonrpc": "2.0", + "id": 78190, + "method": "updateAccount", + "params": { + "accountId": "0.0.7388", + "stakedAccountId": "0.0.3", + "commonTransactionParams": { + "signers": [ + "302e020100300506032b65700422042031f8eb3e77a04ebe599c51570976053009e619414f26bdd39676a5d3b2782a1d" + ] + } + } +} +``` -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|-------------------------------------------------------------------------------|---------------------------------------------------|--------------------------------------------------------------------------------------|-------------------| -| 1 | Update the staked account ID of an account to the operator's account ID | accountId, privateKey, operatorAccountId | The account update succeeds and has the operator account ID as its staked ID | N | -| 2 | Update the staked node ID of an account to the testing node's ID | accountId, privateKey, nodeId | The account update succeeds and has the testing node ID as its staked ID | N | -| 3 | Update the staked account ID of an account to the sentinel account ID (0.0.0) | accountId, privateKey, sentinelAccountId=0.0.0 | The account update succeeds and has no staked ID | N | -| 4 | Update the staked node ID of an account to the sentinel node ID (-1) | accountId, privateKey, sentinelNodeId=-1 | The account update succeeds and has no staked ID | N | -| 5 | Update the staked account ID of an account to an invalid ID | accountId, privateKey, invalidAccountId=10000.0.0 | The account update fails and returns error response INVALID_STAKING_ID | N | -| 6 | Update the staked node ID of an account to an invalid ID | accountId, privateKey, invalidNodeId=10000 | The account update fails and returns error response INVALID_STAKING_ID | N | -| 7 | Update the staked account ID of an account to its own account ID | accountId, privateKey | The account update fails and returns error response SELF_STAKING_IS_NOT_ALLOWED | N | +```json +{ + "jsonrpc": "2.0", + "id": 78190, + "method": "updateAccount", + "params": { + "accountId": "0.0.7388", + "stakedNodeId": 10, + "commonTransactionParams": { + "signers": [ + "302e020100300506032b65700422042031f8eb3e77a04ebe599c51570976053009e619414f26bdd39676a5d3b2782a1d" + ] + } + } +} +``` + +#### JSON Response Example + +```json +{ + "jsonrpc": "2.0", + "id": 78190, + "result": { + "status": "SUCCESS" + } +} +``` ### **Decline Reward:** -- If true, the account declines receiving a staking reward. +- The new desired decline rewards policy for the account. If true, the account declines receiving a staking reward. + +| Test no | Name | Input | Expected response | Implemented (Y/N) | +|---------|--------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------|-------------------| +| 1 | Updates the decline reward policy of an account to decline staking rewards | accountId=, declineStakingRewards=true, commonTransactionParams.signers=[] | The account update succeeds and the account declines staking rewards. | N | +| 2 | Updates the decline reward policy of an account to not decline staking rewards | accountId=, declineStakingRewards=false, commonTransactionParams.signers=[] | The account update succeeds and the account doesn't decline staking rewards. | N | + +#### JSON Request Example + +```json +{ + "jsonrpc": "2.0", + "id": 6539, + "method": "updateAccount", + "params": { + "accountId": "0.0.983", + "declineStakingRewards": true, + "commonTransactionParams": { + "signers": [ + "302e020100300506032b65700422042031f8eb3e77a04ebe599c51570976053009e619414f26bdd39676a5d3b2782a1d" + ] + } + } +} +``` + +#### JSON Response Example -| Test no | Name | Input | Expected response | Implemented (Y/N) | -|---------|------------------------------------------------------------|--------------------------------------------------------|-------------------------------------------------------------------------------|-------------------| -| 1 | Update an account to decline receiving staking rewards | accountId, privateKey, declineReward=true | The account update succeeds and the account has declineReward equal to true | N | -| 2 | Update an account to not decline receiving staking rewards | accountId, privateKey, declineReward=false | The account update succeeds and the account has declineReward equal to false | N | +```json +{ + "jsonrpc": "2.0", + "id": 6539, + "result": { + "status": "SUCCESS" + } +} +``` diff --git a/test-specifications/utility.md b/test-specifications/utility.md index cf81704..c79ba7d 100644 --- a/test-specifications/utility.md +++ b/test-specifications/utility.md @@ -106,19 +106,20 @@ Method used to generate a Hedera Key. #### Input Parameters -| Parameter Name | Type | Required/Optional | Description/Notes | -|----------------|--------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| type | string | optional | The type of Key to generate. If provided, it MUST be one of `ed25519PrivateKey`, `ed25519PublicKey`, `ecdsaSecp256k1PrivateKey`, `ecdsaSecp256k1PublicKey`, `keyList`, `thresholdKey`, `privateKey`, or `publicKey`. If not provided, the returned key will be of type `ed25519PrivateKey`, `ed25519PublicKey`, `ecdsaSecp256k1PrivateKey`, or `ecdsaSecp256k1PublicKey`. `privateKey` and `publicKey` types are used when any private or public key type (respectively) is required but the specific type doesn't matter. | -| privateKey | string | optional | The DER-encoded hex string private key from which to generate a public key. This should only be provided for types `ed25519PublicKey` and `ecdsaSecp256k1PublicKey` if the public keys would like to be generated from a specific private key, but still not required if a random public key is desired. | -| protobufBytes | bool | optional | For `ed25519PublicKey` and `ecdsaSecp256k1PublicKey` types, `true` if instead of the DER-encoded hex string of the generated key, the serialized Key protobuf bytes are desired. Useful for generating aliases. | -| threshold | int | optional | Required for `thresholdKey` types. The number of keys that must sign for a threshold key. | -| keys | list | optional | Required for `keyList` and `thresholdKey` types. Specify the types of keys to be generated and put in the `keyList` or `thresholdKey`. All keys should contain the same parameters as this `generateKey` method (see examples below), if required. | +| Parameter Name | Type | Required/Optional | Description/Notes | +|----------------|-------------------|-------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| type | string | optional | The type of Key to generate. If provided, it MUST be one of `ed25519PrivateKey`, `ed25519PublicKey`, `ecdsaSecp256k1PrivateKey`, `ecdsaSecp256k1PublicKey`, `keyList`, `thresholdKey`, `privateKey`, or `publicKey`. If not provided, the returned key will be of type `ed25519PrivateKey`, `ed25519PublicKey`, `ecdsaSecp256k1PrivateKey`, or `ecdsaSecp256k1PublicKey`. `privateKey` and `publicKey` types are used when any private or public key type (respectively) is required but the specific type doesn't matter. | +| privateKey | string | optional | The DER-encoded hex string private key from which to generate a public key. This should only be provided for types `ed25519PublicKey` and `ecdsaSecp256k1PublicKey` if the public keys would like to be generated from a specific private key, but still not required if a random public key is desired. | +| protobufBytes | bool | optional | For `ed25519PublicKey` and `ecdsaSecp256k1PublicKey` types, `true` if instead of the DER-encoded hex string of the generated key, the serialized Key protobuf bytes are desired. Useful for generating aliases. | +| threshold | int | optional | Required for `thresholdKey` types. The number of keys that must sign for a threshold key. | +| keys | list | optional | Required for `keyList` and `thresholdKey` types. Specify the types of keys to be generated and put in the `keyList` or `thresholdKey`. All keys should contain the same parameters as this `generateKey` method (see examples below), if required. | #### Output Parameters -| Parameter Name | Type | Description/Notes | -|----------------|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| key | string | The DER-encoded hex string of the generated ECDSA or ED25519 private or public key (compressed if ECDSAsecp256k1 public key). If the type was `keyList` or `thresholdKey`, the hex string of the respective serialized protobuf. | +| Parameter Name | Type | Required/Optional | Description/Notes | +|----------------|--------------|-------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| key | string | required | The DER-encoded hex string of the generated ECDSA or ED25519 private or public key (compressed if ECDSAsecp256k1 public key). If the type was `keyList` or `thresholdKey`, the hex string of the respective serialized protobuf. | +| privateKeys | list | optional | For `keyList` and `thresholdKey` types, the DER-encoded hex strings of the private keys of the keys in the list. Useful if needing to sign with the `keyList` or `thresholdKey`. This list MUST match sequentially with the order of the keys that were input into the method, despite any nested `keyList` or `thresholdKey` types. Any generated `ed25519PublicKey`, `ecdsaSecp256k1PublicKey`, or `publicKey` type which contains a `fromKey` WILL NOT have its private key included in this list. | #### JSON Request/Response Examples @@ -237,7 +238,11 @@ Method used to generate a Hedera Key. "jsonrpc": "2.0", "id": 5, "result": { - "key": "2A710802126D0A2212209181CA10AA3166E56755D5F5A7D0A80DABB17A5699B1185F6E85B0F7F450669E0A2212205C7F51463FF9444951E878EEB7161EE7250691684DE0DFE048B68BDF1602D05F0A233A210339A36013301597DAEF41FBE593A02CC513D0B55527EC2DF1050E2E8FF49C85C2" + "key": "326D0A221220AAEF24C83ADDBDB2C41A0F04A0CFC1AFA08631F4CEB770E39E96C6A115435A070A22122078A1AE1B1153E8A0F04B0E25F08A0EFF598D5AAD2B4481540DE37D5DCA7750E20A233A210339A36013301597DAEF41FBE593A02CC513D0B55527EC2DF1050E2E8FF49C85C2", + "privateKeys": [ + "302E020100300506032B65700422042047A291D1E8C0F4F30718E4FF521DBF825AE396AA33FCA086E8B444E6047676CD", + "302E020100300506032B65700422042021F97AC9A86CAA55AB6920D33AD444C6D547B15CE652345CC120FFE4EF0DC1DF" + ] } } ``` @@ -295,7 +300,15 @@ Method used to generate a Hedera Key. "jsonrpc": "2.0", "id": 6, "result": { - "key": "328D020A6F326D0A22122056E73F6802877166FD611D421F8AAC8D24527E0A657AFFF28DC7167CAB838B690A221220202D875F498B407BBBF5B5358A1F73D326419B4BA5AF7A3A8C2FA03F39C9628B0A233A210339A36013301597DAEF41FBE593A02CC513D0B55527EC2DF1050E2E8FF49C85C20A99013296010A233A2103936FE869DB7187AC18E19E002B5EAE47EA6A02F51E9F02E190D1EF8F0B5DB2A50A6F326D0A233A210220C3866F3C42DFB0C530351A35274FE2BD9531B89A770D6336638D88C18150950A22122077F49D8D6F82DA4BC0AC9BD55B36571022E85812A25AEAF80B7AF4502F1CC3E70A22122008530EA4B75F639032EDA3C18F41A296CF631D1828697E4F052297553139F347" + "key": "32B6020A6F326D0A221220E3323F1BD634EC07E6445EE242324008AEAB7E8A2F60F57BBB23057A84FE61420A221220803670AE4EE66946DE543DEA9A6F948BD0C8F427C2117B6CE2BFEBC78261045C0A233A210339A36013301597DAEF41FBE593A02CC513D0B55527EC2DF1050E2E8FF49C85C20AC20132BF010A233A21024B233A25673203BA73A55FCCC68760DFFDEDC1DA380B028D862E1906E2CAEB850A742A720802126E0A233A21039CD512F3D4E52EC3755763304043944F67DD1080400FC767A653843C4156B4350A233A210355397F5E80ED0A2430CB4AD6797A43347F96D85048FC09FA52499FB11619B7380A22122008530EA4B75F639032EDA3C18F41A296CF631D1828697E4F052297553139F3470A2212200C5ECEECF4E8A93578AEA7170155A7437F1772D168A0B0479CC7569754FC520D", + "privateKeys": [ + "302E020100300506032B65700422042050B7D130743835696F54C370F92C6C9C3E2098BF449D180EAA10525B76A7E893", + "302E020100300506032B657004220420D641C31B4E7B8D97A997927BFD242EFF4588B461067C107E77E4C92102CF0526", + "3030020100300706052B8104000A04220420B5B1FD92969FECAFEE3832C209D3886B688A7FEBB672EF1D75D7D6AA13CC2DC6", + "3030020100300706052B8104000A04220420D96FB02456CE191D842FFD4DB3F5360B9069CC1A21EA2DD9B8DC1A2F63D12D23", + "3030020100300706052B8104000A04220420EA1C1DDE52627EF52070618697E24A02DF35F85B927F10C2E6A61D9C2DFBB1E6", + "302E020100300506032B65700422042030D82141CECFE42A1008737C7B801D1F39AC0DC4C39B3CF2781C97938757CAB2" + ] } } ```