Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial draft of PBJ types for token state #263

Merged
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ba1af89
Add HCS state proto
tinker-michaelj Mar 1, 2023
214df5f
Add running hash, delete EntityNumber
tinker-michaelj Mar 1, 2023
b39dec9
add account and token
Neeharika-Sompalli Mar 24, 2023
f624257
add account and token
Neeharika-Sompalli Mar 24, 2023
5f39ec7
add token
Neeharika-Sompalli Mar 24, 2023
a5db1cc
add tokenRelation
Neeharika-Sompalli Mar 24, 2023
a718906
Merge branch 'main' into 05111-use-pbj-for-token-state
Neeharika-Sompalli Mar 29, 2023
3bd2503
add some javadocs
Neeharika-Sompalli Mar 29, 2023
f7ac736
add some javadocs
Neeharika-Sompalli Mar 30, 2023
6a8cb7e
Merge branch 'main' into 05111-use-pbj-for-token-state
Neeharika-Sompalli Mar 30, 2023
435cea9
address review comments
Neeharika-Sompalli Mar 30, 2023
ffb79b3
fix missing import
Neeharika-Sompalli Mar 30, 2023
bc3564e
address comments
Neeharika-Sompalli Apr 4, 2023
1a71497
address review comments
Neeharika-Sompalli Apr 5, 2023
db3e917
Update services/state/token/account.proto
Neeharika-Sompalli Apr 11, 2023
04d9470
Update services/state/token/account.proto
Neeharika-Sompalli Apr 11, 2023
f2158c3
address some review comments
Neeharika-Sompalli Apr 11, 2023
36ceb52
move back under services
Neeharika-Sompalli Apr 11, 2023
b65ba3b
change package name
Neeharika-Sompalli Apr 12, 2023
1ebc222
some docs and revert java package name
Neeharika-Sompalli Apr 12, 2023
8f54afe
revert docs
Neeharika-Sompalli Apr 12, 2023
1939032
add javadocs
Neeharika-Sompalli Apr 12, 2023
a871898
add javadocs
Neeharika-Sompalli Apr 12, 2023
1236702
re-order the first 16
Neeharika-Sompalli Apr 12, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
175 changes: 175 additions & 0 deletions services/state/token/account.proto
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
syntax = "proto3";

package proto;

/*-
* ‌
* Hedera Network Services Protobuf
* ​
* Copyright (C) 2018 - 2023 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

import "basic_types.proto";

option java_package = "com.hederahashgraph.api.proto.java";
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
// <<<pbj.java_package = "com.hedera.hapi.node.state.token">>> This comment is special code for setting PBJ Compiler java package
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
option java_multiple_files = true;

/**
* First-draft representation of a Hedera Token Service account entity in the network Merkle tree.
*
* As with all network entities, an account has a unique entity number, which is usually given along
* with the network's shard and realm in the form of a shard.realm.number id.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a blocker for this PR, but we really should have better docs here. These schemas will generate Java objects that we will use in our code. So if I'm working on some code and I want to understand the Account class, I'm going to be looking at and reading that javadoc. So It would be nice to describe more what an account is, how it fits into our system, etc. At least at a high level.

*/

message Account {
/**
* The unique entity number of the account.
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
*/
int64 account_number = 1;
/**
* The public key bytes to be used as the account's alias, if any.
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
*/
bytes alias = 2;
/**
* (Optional) The key to be used to sign transactions from the account, if any.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should describe a little better as to when having a key is optional and when it is not. Most accounts require it. Only special accounts like 0.0.800 permit an empty key. Maybe we should document that.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And hollow accounts ?

*/
Key key = 3;
/**
* The expiration time of the account, in seconds since the epoch.
*/
int64 expiry = 4;
/**
* The balance of the account, in tiny-bars.
*/
int64 hbar_balance = 5;
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* An optional description of the topic with UTF-8 encoding up to 100 bytes.
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
*/
string memo = 6;
/**
* A boolean marking if the account has been deleted.
*/
bool deleted = 7;
/**
* A boolean marking if the account is a smart contract.
*/
bool smart_contract = 8;
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* A boolean marking if the account requires a receiver signature.
*/
bool receiver_sig_required = 9;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These all look good. However there is one point worth making, which is that in protobuf serialization, false is represented by omitting the data from the data, whereas "true" is represented by a single byte. So wherever we can, we should make sure the "false" setting is more frequent than the "true". In these three cases, that is what we see. most accounts have deleted as false, most accounts are not smart contracts, and most accounts don't have receiver_sig_required set to true, so for most accounts these three fields will encode as 0 bytes. Which is great.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great insight. Thanks !

/**
* The number of NFTs owned by the account.
*/
int64 number_owned_nfts = 10;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any reason we use int64 here, but int32 in associations? Should we use int32 in all these places? I'm not sure if anybody is going to have more than 2 billion NFTs, but I guess it could happen... but maybe they should use multiple accounts at that point?

At the protobuf level int64 and int32 are just as efficient up until the limit of int32. But at the Java level it is a long vs. an int. Otherwise it wouldn't matter that much.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just used int64 where we were using long and int32 for int. Will revisit before these going to production.

/**
* The maximum number of tokens that can be auto-associated with the account.
*/
int32 max_auto_associations = 11;
/**
* The number of used auto-association slots.
*/
int32 used_auto_associations = 12;
/**
* The number of tokens associated with the account.
*/
int32 number_associations = 13;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if number_associations is maxed out at the int32 max value, but used_auto_associations are not maxed out, and somebody tries to then create a new auto_association? Do we error out, or do we end up overflowing on number_associations? Just queries.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, what do we use number_associations for? Is it just for a response to a query?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked with @tinker-michaelj . It is not only needed for query, but also for calculating fee for renewal.

/**
* The number of tokens with a positive balance associated with the account.
*/
int32 number_positive_balances = 14;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this only needed to answer some queries? Or do we use it during checking for solvency? Or something else?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is needed because account can't be deleted if there are any positive balances in it.

/**
* The nonce of the account, used for Ethereum interoperability.
*/
int64 ethereum_nonce = 15;
/**
* The amount of hbars staked to the account.
*/
int64 staked_to_me = 16;
/**
* If this account stakes to another account, its value will be -1. It will
* be set to the time when the account starts staking to a node.
*/
int64 stake_period_start = 17;
/**
* The node number or the account number this account is staked to.
* It is negative if staking to a node and positive if staking to an account and 0 if not staking to anyone.
* When staking to a node, it is stored as -node-1 to differentiate node 0.
*/
int64 staked_number = 18;
/**
* A boolean marking if the account declines rewards.
*/
bool decline_reward = 19;
/**
* The amount of hbars staked to the account at the start of the last rewarded period.
*/
int64 stake_at_start_of_last_rewarded_period = 20;
/**
* (Optional) The number of an auto-renew account, in the same shard and realm as the topic, that
* has signed a transaction allowing the network to use its balance to automatically extend the topic's
* expiration time when it passes.
*/
int64 auto_renew_account_number = 21;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we end up with shard and realm encoded in these files, we'll need it here as well. Otherwise we can leave it off.

/**
* The number of seconds the network should automatically extend the account's expiration by, if the
* account has a valid auto-renew account, and is not deleted upon expiration.
*/
int64 auto_renew_secs = 22;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the behavior if this is ever 0? Do we just make sure it never is?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah we are checking if auto renew seconds is in the range in precheck based on these properties

ledger.autoRenewPeriod.maxDuration=8000001
ledger.autoRenewPeriod.minDuration=2592000

/**
* If this account is a smart-contract, number of key-value pairs stored on the contract.
*/
int32 contract_kv_pairs_number = 23;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be the only field that is smart contract specific (other than the smart_contract boolean). I'm wondering why we need it? Is it again for the purposes of a query?

Copy link
Member Author

@Neeharika-Sompalli Neeharika-Sompalli Apr 12, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is needed for Storage rent and also for checking if number of KV pairs did not exceed the limit allowed.

/**
* (Optional) List of crypto allowances approved by the account.
*/
repeated CryptoAllowance crypto_allowances = 24;
/**
* (Optional) List of non-fungible token allowances approved by the account.
*/
repeated NftAllowance nft_allowances = 25;

/**
* (Optional) List of fungible token allowances approved by the account.
*/
repeated TokenAllowance token_allowances = 26;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure these are right. It seems like we should be using our "map of linked list nodes" concept here instead. It isn't a blocker for this PR, but we need to discuss this.

/**
* The token ID of the head of the linked list from token relations map for the account.
*/
uint64 head_token_number = 27;
/**
* The NftId of the head of the linked list from unique tokens map for the account.
*/
uint64 head_nft_id = 28;
/**
* The serial number of the head NftId of the linked list from unique tokens map for the account.
*/
uint64 head_nft_serial_number = 29;
xin-hedera marked this conversation as resolved.
Show resolved Hide resolved
/**
* The number of tokens for which this account is treasury
*/
uint32 number_treasury_titles = 30;
/**
* A flag indicating if the account is expired and pending removal.
* Only the entity expiration system task toggles this flag when it reaches this account
* and finds it expired. Before setting the flag the system task checks if the account has
* an auto-renew account with balance. This is done to prevent a zero-balance account with a funded
* auto-renew account from being treated as expired in the interval between its expiration
* and the time the system task actually auto-renews it.
*/
bool expired_and_pending_removal = 31;
}
144 changes: 144 additions & 0 deletions services/state/token/token.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
syntax = "proto3";

package proto;

/*-
* ‌
* Hedera Network Services Protobuf
* ​
* Copyright (C) 2018 - 2023 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

import "basic_types.proto";
import "custom_fees.proto";

option java_package = "com.hederahashgraph.api.proto.java";
// <<<pbj.java_package = "com.hedera.hapi.node.state.token">>> This comment is special code for setting PBJ Compiler java package
option java_multiple_files = true;

/**
* First-draft representation of a Hedera Token Service token entity in the network Merkle tree.
*
* As with all network entities, a token has a unique entity number, which is usually given along
* with the network's shard and realm in the form of a shard.realm.number id.
*/

message Token {
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* The unique entity number of this token.
*/
int64 token_number = 1;
/**
* The name of this token.
*/
string name = 2;
/**
* The symbol of this token.
*/
string symbol = 3;
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* The number of decimal places of this token.
*/
int32 decimals = 4;
/**
* The total supply of this token.
*/
int64 total_supply = 5;
/**
* The treasury account number of this token.
*/
int64 treasury_account_number = 6;
/**
* (Optional) The admin key of this token.
*/
Key admin_key = 7;
/**
* (Optional) The kyc key of this token.
*/
Key kyc_key = 8;
/**
* (Optional) The freeze key of this token.
*/
Key freeze_key = 9;
/**
* (Optional) The wipe key of this token.
*/
Key wipe_key = 10;
/**
* (Optional) The supply key of this token.
*/
Key supply_key = 11;
/**
* (Optional) The fee schedule key of this token.
*/
Key fee_schedule_key = 12;
/**
* (Optional) The pause key of this token.
*/
Key pause_key = 13;
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* The last used serial number of this token.
*/
int64 last_used_serial_number = 14;
/**
* The flag indicating if this token is deleted.
*/
bool deleted = 15;
/**
* The auto renew account number of this token.
*/
int64 auto_renew_account_number = 16;
/**
* The auto renew period of this token.
*/
int64 auto_renew_secs = 17;
/**
* The expiration time of the token, in seconds since the epoch.
*/
int64 expiry = 18;
/**
* An optional description of the token with UTF-8 encoding up to 100 bytes.
*/
string memo = 19;
/**
* The maximum supply of this token.
*/
int64 max_supply = 20;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be in the first 16 fields?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all keys should also be in first 16 fields , so the fields are already filled in. 🙂

/**
* The flag indicating if this token is paused.
*/
bool paused = 21;
/**
* The flag indicating if this token has accounts associated to it that are frozen by default.
*/
bool accounts_frozen_by_default = 22;
/**
* The flag indicating if this token has accounts associated to it that are KYC granted by default.
*/
bool accounts_kyc_granted_by_default = 23;
/**
* The type of this token.
*/
TokenType token_type = 24;
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* The supply type of this token.
*/
TokenSupplyType supply_type = 25;
/**
* (Optional) The custom fees of this token.
*/
repeated CustomFee custom_fees = 26;
}
73 changes: 73 additions & 0 deletions services/state/token/token_relation.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
syntax = "proto3";

package proto;

/*-
* ‌
* Hedera Network Services Protobuf
* ​
* Copyright (C) 2018 - 2023 Hedera Hashgraph, LLC
* ​
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

import "basic_types.proto";

option java_package = "com.hederahashgraph.api.proto.java";
// <<<pbj.java_package = "com.hedera.hapi.node.state.token">>> This comment is special code for setting PBJ Compiler java package
option java_multiple_files = true;
/**
* First-draft representation of a Hedera Token Service token relationship entity in the network Merkle tree.
*
* As with all network entities, a token relationship has a unique entity number pair, which is represented
* with the account and the token involved in the relationship.
*/
message TokenRelation {
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* The token involved in this relation.
*/
uint64 token_number = 1;
/**
* The account involved in this association.
*/
uint64 account_number = 2;
xin-hedera marked this conversation as resolved.
Show resolved Hide resolved
/**
* The balance of the token relationship.
*/
int64 balance = 3;
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* The flags of the token relationship.
*/
bool frozen = 4;
/**
* The flag indicating if the token relationship has been granted KYC.
*/
bool kyc_granted = 5;
/**
* The flag indicating if the token relationship was deleted.
*/
bool deleted = 6;
/**
* The flag indicating if the token relationship was created using automatic association.
*/
bool automatic_association = 8;
Neeharika-Sompalli marked this conversation as resolved.
Show resolved Hide resolved
/**
* The previous token number of account's association linked list
*/
uint64 previous_token = 9;
/**
* The next token number of account's association linked list
*/
uint64 next_token = 10;
xin-hedera marked this conversation as resolved.
Show resolved Hide resolved
}