-
Notifications
You must be signed in to change notification settings - Fork 159
feat: no shard realm encoding in long zero #19349
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Luke Lee <[email protected]>
…nto 19181-no-shard-realm-in-long-zero
…nto 19181-no-shard-realm-in-long-zero
Signed-off-by: Luke Lee <[email protected]>
…nto 19181-no-shard-realm-in-long-zero
Coverage summary from CodacySee diff coverage on Codacy
Coverage variation details
Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch: Diff coverage details
Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified: See your quality gate settings Change summary preferences |
Signed-off-by: Luke Lee <[email protected]>
…nto 19181-no-shard-realm-in-long-zero
Signed-off-by: Luke Lee <[email protected]>
Signed-off-by: Luke Lee <[email protected]>
Signed-off-by: Luke Lee <[email protected]>
Signed-off-by: Luke Lee <[email protected]>
…nto 19181-no-shard-realm-in-long-zero
Signed-off-by: Luke Lee <[email protected]>
…encoded Signed-off-by: Luke Lee <[email protected]>
Signed-off-by: Luke Lee <[email protected]>
Signed-off-by: Luke Lee <[email protected]>
Signed-off-by: Luke Lee <[email protected]>
Signed-off-by: Luke Lee <[email protected]>
…nto 19181-no-shard-realm-in-long-zero
Signed-off-by: Luke Lee <[email protected]>
Signed-off-by: Luke Lee <[email protected]>
…nto 19181-no-shard-realm-in-long-zero
@Inject | ||
public TokenAirdropDecoder() { | ||
// Dagger2 | ||
} | ||
|
||
public TransactionBody decodeAirdrop(@NonNull final HtsCallAttempt attempt) { | ||
this.attempt = requireNonNull(attempt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
put attempt.nativeOperations().entityIdFactory()
to bodyForAirdrop
function instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A couple of general things:
-
I'm not fond of passing
entityIdFactory
everywhere in order to resolve the shard/realm, at least not by that name. Its meaning is too close to the incremental entity ID counter stored in state. -
Not sure why we're not also stripping the
0.0
shard/realm out of long zero encodings, but there very well could be nuance here I'm not aware of.
Aside from these, the changes overall make sense. This is a lot of slog work–thanks @lukelee-sl!!
(spec) -> toAddressStringWithShardAndRealm((int) spec.shard(), spec.realm(), "1117d0"); | ||
(spec) -> toAddressStringWithShardAndRealm(0, 0, "1117d0"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the purpose of this PR is to remove shard/realm encoding in the address string, why wouldn't shard/realm be removed entirely? Should toAddressStringWithShardAndRealm()
exist at all anymore?
final long shard = 0L; | ||
final long realm = 0L; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like these shouldn't be needed at all anymore, right?
assertEquals(0, tokenId.shardNum()); | ||
assertEquals(0, tokenId.realmNum()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again I'm confused–if we're removing shard/realm from the address string, how can we assert anything about a token ID's shard/realm?
final var tokenNum = numberOfLongZero(explicit); | ||
return tokenNum == 0 ? TokenID.DEFAULT : entityIdFactory.newTokenId(tokenNum); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to look at EntityIdFactory
to figure out why it's being used here (and many other places). Imo it's much more straightforward for this static method (and others like it) to explicitly require a shard
and realm
parameter to make clear what the code itself is doing. Two things made this confusing on first read: first, using entityIdFactory
simply because it already has the configured shard/realm embedded inside; and second, the newTokenId
method makes it sound like a new entity ID is being generated, not just instantiated.
I do understand it's easier to pass one object than it is to pass two, but it has thrown me for a loop the past hal hour or so to understand why this object is suddenly necessary in a bunch of places.
P.S.:
* <p><b>IMPORTANT:</b> Mono-service ignores the shard and realm, c.f. De
* codingFacade#convertAddressBytesToTokenID(), so we continue to do that here; might
* want to revisit this later
This doc seems to be incorrect
return decoder.decodeCryptoTransfer(attempt.inputBytes(), attempt.addressIdConverter()); | ||
return decoder.decodeCryptoTransfer(attempt.inputBytes(), attempt); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, why are both the entityIdFactory
and the addressIdConverter
necessary inside of decodeCryptoTransfer(...)
? From a purely conceptual standpoint, it seems like addressIdConverter
alone could handle the translation (including shard/realm). Maybe its job is more specific than this, though?
final var tokenId = ConversionUtils.asTokenId(attempt.nativeOperations().entityIdFactory(), address); | ||
return useHbarsForPayment | ||
|| tokenId.equals( | ||
attempt.nativeOperations().entityIdFactory().newTokenId(0)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like unnecessary work to convert address
to a fully-qualified tokenId, convert 0
to a token ID, and then compare them. What about something similar to this?
final var tokenId = ConversionUtils.asTokenId(attempt.nativeOperations().entityIdFactory(), address); | |
return useHbarsForPayment | |
|| tokenId.equals( | |
attempt.nativeOperations().entityIdFactory().newTokenId(0)) | |
final var tokenNum = ConversionUtils.extractTokenNum(address); | |
return useHbarsForPayment || tokenNum == 0 |
return ConversionUtils.asTokenId(attempt.nativeOperations().entityIdFactory(), tokenAddress) | ||
.equals(TokenID.DEFAULT) | ||
&& amount == 0 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change itself makes sense, but is the method's logic actually correct? It could end up comparing token 5.6.0
to token 0.0.0
, which would evaluate to false, but seems like maybe the intent is actually just to compare the token numbers?
For more context, I'm not quite clear on TokenID.DEFAULT
's semantic meaning when the shard/realm aren't 0.0
. Is TokenID.DEFAULT
the only sentinel value, i.e. for shard=realm=0 (0.0.0
), or is 1.2.0
also considered a sentinel value for a node using shard=1,realm=2?
* based on the entity number, the first 12 bytes will be defined to be zero which indicates the current networks | ||
* shard and realm, while the last 8 bytes represent the entity number. Because the shard and realm are zero, this | ||
* prefix is all zeros, which is why it is sometimes known as the "long-zero" alias. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To check my understanding, I read here that a prefix of all zeros indicates the current network's shard/realm is 0.0
...but isn't the whole point of this PR to not encode shard/realm in this alias? Seems like a contradiction to me, and one that could easily cause bugs
void extractRealmFromAddressAliasReturnsZeroForZeroRealm() { | ||
var alias = Bytes.wrap(HexFormat.of().parseHex(TEST_ENTITY_NUM_ALIAS)); | ||
assertEquals(0L, AliasUtils.extractRealmFromAddressAlias(alias)); | ||
assertEquals(20L, AliasUtils.extractRealmFromAddressAlias(alias, 20)); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should extractRealmFromAddressAlias(...)
even exist if we're removing the shard/realm encoding from the alias? At least the test name should probably change
Description:
Remove the encoding of the shard and realm in the long zero(account number alias) addresses
Related issue(s):
Fixes #19181