use of com.hedera.services.state.merkle.MerkleToken in project hedera-services by hashgraph.
the class LedgerBalanceChangesTest method nonFungibleTokenWithTreasury.
private MerkleToken nonFungibleTokenWithTreasury(AccountID treasury) {
final var token = new MerkleToken();
token.setTreasury(new EntityId(treasury.getShardNum(), treasury.getRealmNum(), treasury.getAccountNum()));
token.setTokenType(TokenType.NON_FUNGIBLE_UNIQUE);
return token;
}
use of com.hedera.services.state.merkle.MerkleToken in project hedera-services by hashgraph.
the class LedgerBalanceChangesTest method fungibleTokenWithTreasury.
private MerkleToken fungibleTokenWithTreasury(AccountID treasury) {
final var token = new MerkleToken();
token.setTreasury(new EntityId(treasury.getShardNum(), treasury.getRealmNum(), treasury.getAccountNum()));
token.setTokenType(TokenType.FUNGIBLE_COMMON);
return token;
}
use of com.hedera.services.state.merkle.MerkleToken in project hedera-services by hashgraph.
the class TypedTokenStoreTest method savesTokenAsExpected.
/* --- Token saving --- */
@Test
void savesTokenAsExpected() {
// setup:
final var mintedSerialNo = 33L;
final var wipedSerialNo = 33L;
final var mintedSerialNo2 = 44;
final var burnedSerialNo = 44;
final var nftMeta = "abcdefgh".getBytes();
final var treasuryId = new EntityId(0, 0, treasuryAccountNum);
final var tokenEntityId = new EntityId(0, 0, tokenNum);
final var creationTime = new RichInstant(1_234_567L, 8);
final var modelTreasuryId = new Id(0, 0, treasuryAccountNum);
final var mintedToken = new UniqueToken(tokenId, mintedSerialNo, creationTime, Id.DEFAULT, nftMeta);
final var wipedToken = new UniqueToken(tokenId, wipedSerialNo, creationTime, modelTreasuryId, nftMeta);
final var mintedToken2 = new UniqueToken(tokenId, mintedSerialNo2, creationTime, Id.DEFAULT, nftMeta);
final var burnedToken = new UniqueToken(tokenId, burnedSerialNo, creationTime, modelTreasuryId, nftMeta);
// and:
final var expectedReplacementToken = new MerkleToken(expiry, tokenSupply * 2, 0, symbol, name, freezeDefault, true, new EntityId(0, 0, autoRenewAccountNum));
expectedReplacementToken.setAutoRenewAccount(treasuryId);
expectedReplacementToken.setSupplyKey(supplyKey);
expectedReplacementToken.setFreezeKey(freezeKey);
expectedReplacementToken.setKycKey(kycKey);
expectedReplacementToken.setPauseKey(pauseKey);
expectedReplacementToken.setAccountsFrozenByDefault(!freezeDefault);
expectedReplacementToken.setMemo(memo);
expectedReplacementToken.setAutoRenewPeriod(autoRenewPeriod);
// and:
final var expectedReplacementToken2 = new MerkleToken(expiry, tokenSupply * 4, 0, symbol, name, freezeDefault, true, new EntityId(0, 0, treasuryAccountNum));
expectedReplacementToken2.setAutoRenewAccount(treasuryId);
expectedReplacementToken2.setSupplyKey(supplyKey);
expectedReplacementToken2.setFreezeKey(freezeKey);
expectedReplacementToken2.setKycKey(kycKey);
expectedReplacementToken2.setPauseKey(pauseKey);
expectedReplacementToken2.setAccountsFrozenByDefault(!freezeDefault);
expectedReplacementToken2.setMemo(memo);
expectedReplacementToken2.setAutoRenewPeriod(autoRenewPeriod);
// and:
final var expectedNewUniqTokenId = NftId.withDefaultShardRealm(tokenEntityId.num(), mintedSerialNo);
final var expectedNewUniqTokenId2 = NftId.withDefaultShardRealm(tokenEntityId.num(), mintedSerialNo2);
final var expectedNewUniqToken = new MerkleUniqueToken(MISSING_ENTITY_ID, nftMeta, creationTime);
final var expectedPastUniqTokenId = NftId.withDefaultShardRealm(tokenEntityId.num(), wipedSerialNo);
final var expectedPastUniqTokenId2 = NftId.withDefaultShardRealm(tokenEntityId.num(), burnedSerialNo);
givenModifiableToken(merkleTokenId, merkleToken);
givenToken(merkleTokenId, merkleToken);
// when:
var modelToken = subject.loadToken(tokenId);
// and:
modelToken.setTotalSupply(tokenSupply * 2);
modelToken.setAutoRenewAccount(treasuryAccount);
modelToken.setTreasury(autoRenewAccount);
modelToken.setFrozenByDefault(!freezeDefault);
modelToken.mintedUniqueTokens().add(mintedToken);
modelToken.setIsDeleted(false);
modelToken.setExpiry(expiry);
modelToken.setAutoRenewPeriod(autoRenewPeriod);
modelToken.removedUniqueTokens().add(wipedToken);
modelToken.setAutoRenewPeriod(autoRenewPeriod);
modelToken.setCustomFees(List.of());
modelToken.setMemo(memo);
// and:
subject.commitToken(modelToken);
// then:
assertEquals(expectedReplacementToken, merkleToken);
// and:
verify(sideEffectsTracker).trackTokenChanges(modelToken);
verify(uniqueTokens).put(expectedNewUniqTokenId, expectedNewUniqToken);
verify(uniqueTokens).put(NftId.withDefaultShardRealm(tokenEntityId.num(), mintedSerialNo), expectedNewUniqToken);
verify(uniqueTokens).remove(expectedPastUniqTokenId);
// when:
modelToken = subject.loadToken(tokenId);
// and:
modelToken.setTotalSupply(tokenSupply * 4);
modelToken.setAutoRenewAccount(treasuryAccount);
modelToken.setTreasury(treasuryAccount);
modelToken.setFrozenByDefault(!freezeDefault);
modelToken.mintedUniqueTokens().add(mintedToken2);
modelToken.setIsDeleted(false);
modelToken.setExpiry(expiry);
modelToken.removedUniqueTokens().add(burnedToken);
modelToken.setCustomFees(List.of());
// and:
subject.commitToken(modelToken);
// then:
assertEquals(expectedReplacementToken2, merkleToken);
// and:
verify(sideEffectsTracker).trackTokenChanges(modelToken);
verify(uniqueTokens).put(expectedNewUniqTokenId2, expectedNewUniqToken);
verify(uniqueTokens).remove(expectedPastUniqTokenId2);
}
use of com.hedera.services.state.merkle.MerkleToken in project hedera-services by hashgraph.
the class WorldLedgersTest method wrapsAsExpectedWithoutCommitInterceptors.
@Test
void wrapsAsExpectedWithoutCommitInterceptors() {
final var liveTokenRels = new TransactionalLedger<>(TokenRelProperty.class, MerkleTokenRelStatus::new, new HashMapBackingTokenRels(), new ChangeSummaryManager<>());
final var liveAccounts = new TransactionalLedger<>(AccountProperty.class, MerkleAccount::new, new HashMapBackingAccounts(), new ChangeSummaryManager<>());
final var liveNfts = new TransactionalLedger<>(NftProperty.class, MerkleUniqueToken::new, new HashMapBackingNfts(), new ChangeSummaryManager<>());
final var liveTokens = new TransactionalLedger<>(TokenProperty.class, MerkleToken::new, new HashMapBackingTokens(), new ChangeSummaryManager<>());
final var liveAliases = new AliasManager();
final var source = new WorldLedgers(liveAliases, liveTokenRels, liveAccounts, liveNfts, liveTokens);
assertTrue(source.areMutable());
final var nullTokenRels = new WorldLedgers(liveAliases, null, liveAccounts, liveNfts, liveTokens);
final var nullAccounts = new WorldLedgers(liveAliases, liveTokenRels, null, liveNfts, liveTokens);
final var nullNfts = new WorldLedgers(liveAliases, liveTokenRels, liveAccounts, null, liveTokens);
final var nullTokens = new WorldLedgers(liveAliases, liveTokenRels, liveAccounts, liveNfts, null);
assertFalse(nullTokenRels.areMutable());
assertFalse(nullAccounts.areMutable());
assertFalse(nullNfts.areMutable());
assertFalse(nullTokens.areMutable());
final var wrappedUnusable = nullAccounts.wrapped();
assertSame(((StackedContractAliases) wrappedUnusable.aliases()).wrappedAliases(), nullAccounts.aliases());
assertFalse(wrappedUnusable.areMutable());
final var wrappedSource = source.wrapped();
assertSame(liveTokenRels, wrappedSource.tokenRels().getEntitiesLedger());
assertSame(liveAccounts, wrappedSource.accounts().getEntitiesLedger());
assertSame(liveNfts, wrappedSource.nfts().getEntitiesLedger());
assertSame(liveTokens, wrappedSource.tokens().getEntitiesLedger());
final var stackedAliases = (StackedContractAliases) wrappedSource.aliases();
assertSame(liveAliases, stackedAliases.wrappedAliases());
}
use of com.hedera.services.state.merkle.MerkleToken in project hedera-services by hashgraph.
the class TokenUpdateTransitionLogic method transitionFor.
private void transitionFor(TokenUpdateTransactionBody op) {
var id = store.resolve(op.getToken());
if (id == MISSING_TOKEN) {
txnCtx.setStatus(INVALID_TOKEN_ID);
return;
}
ResponseCodeEnum outcome;
MerkleToken token = store.get(id);
if (op.hasExpiry() && !validator.isValidExpiry(op.getExpiry())) {
txnCtx.setStatus(INVALID_EXPIRATION_TIME);
return;
}
if (token.adminKey().isEmpty() && !affectsExpiryOnly.test(op)) {
txnCtx.setStatus(TOKEN_IS_IMMUTABLE);
return;
}
if (token.isDeleted()) {
txnCtx.setStatus(TOKEN_WAS_DELETED);
return;
}
if (token.isPaused()) {
txnCtx.setStatus(TOKEN_IS_PAUSED);
return;
}
outcome = autoRenewAttachmentCheck(op, token);
if (outcome != OK) {
txnCtx.setStatus(outcome);
return;
}
Optional<AccountID> replacedTreasury = Optional.empty();
if (op.hasTreasury()) {
var newTreasury = op.getTreasury();
if (ledger.isDetached(newTreasury)) {
txnCtx.setStatus(ACCOUNT_EXPIRED_AND_PENDING_REMOVAL);
return;
}
if (!store.associationExists(newTreasury, id)) {
txnCtx.setStatus(INVALID_TREASURY_ACCOUNT_FOR_TOKEN);
return;
}
var existingTreasury = token.treasury().toGrpcAccountId();
if (!allowChangedTreasuryToOwnNfts && token.tokenType() == NON_FUNGIBLE_UNIQUE) {
var existingTreasuryBalance = ledger.getTokenBalance(existingTreasury, id);
if (existingTreasuryBalance > 0L) {
abortWith(CURRENT_TREASURY_STILL_OWNS_NFTS);
return;
}
}
if (!newTreasury.equals(existingTreasury)) {
if (ledger.isDetached(existingTreasury)) {
txnCtx.setStatus(ACCOUNT_EXPIRED_AND_PENDING_REMOVAL);
return;
}
outcome = prepNewTreasury(id, token, newTreasury);
if (outcome != OK) {
abortWith(outcome);
return;
}
replacedTreasury = Optional.of(token.treasury().toGrpcAccountId());
}
}
outcome = store.update(op, txnCtx.consensusTime().getEpochSecond());
if (outcome == OK && replacedTreasury.isPresent()) {
final var oldTreasury = replacedTreasury.get();
long replacedTreasuryBalance = ledger.getTokenBalance(oldTreasury, id);
if (replacedTreasuryBalance > 0) {
if (token.tokenType().equals(TokenType.FUNGIBLE_COMMON)) {
outcome = ledger.doTokenTransfer(id, oldTreasury, op.getTreasury(), replacedTreasuryBalance);
} else {
outcome = store.changeOwnerWildCard(new NftId(id.getShardNum(), id.getRealmNum(), id.getTokenNum(), -1), oldTreasury, op.getTreasury());
}
}
}
if (outcome != OK) {
abortWith(outcome);
return;
}
txnCtx.setStatus(SUCCESS);
sigImpactHistorian.markEntityChanged(id.getTokenNum());
}
Aggregations