Search in sources :

Example 1 with MerkleToken

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;
}
Also used : EntityId(com.hedera.services.state.submerkle.EntityId) MerkleToken(com.hedera.services.state.merkle.MerkleToken)

Example 2 with MerkleToken

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;
}
Also used : EntityId(com.hedera.services.state.submerkle.EntityId) MerkleToken(com.hedera.services.state.merkle.MerkleToken)

Example 3 with MerkleToken

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);
}
Also used : EntityId(com.hedera.services.state.submerkle.EntityId) UniqueToken(com.hedera.services.store.models.UniqueToken) MerkleUniqueToken(com.hedera.services.state.merkle.MerkleUniqueToken) MerkleToken(com.hedera.services.state.merkle.MerkleToken) MerkleUniqueToken(com.hedera.services.state.merkle.MerkleUniqueToken) EntityId(com.hedera.services.state.submerkle.EntityId) Id(com.hedera.services.store.models.Id) NftId(com.hedera.services.store.models.NftId) RichInstant(com.hedera.services.state.submerkle.RichInstant) Test(org.junit.jupiter.api.Test)

Example 4 with MerkleToken

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());
}
Also used : HashMapBackingTokenRels(com.hedera.services.ledger.backing.HashMapBackingTokenRels) MerkleToken(com.hedera.services.state.merkle.MerkleToken) MerkleAccount(com.hedera.services.state.merkle.MerkleAccount) TransactionalLedger(com.hedera.services.ledger.TransactionalLedger) MerkleTokenRelStatus(com.hedera.services.state.merkle.MerkleTokenRelStatus) HashMapBackingNfts(com.hedera.services.ledger.backing.HashMapBackingNfts) AliasManager(com.hedera.services.ledger.accounts.AliasManager) StackedContractAliases(com.hedera.services.ledger.accounts.StackedContractAliases) HashMapBackingTokens(com.hedera.services.ledger.backing.HashMapBackingTokens) MerkleUniqueToken(com.hedera.services.state.merkle.MerkleUniqueToken) HashMapBackingAccounts(com.hedera.services.ledger.backing.HashMapBackingAccounts) Test(org.junit.jupiter.api.Test)

Example 5 with MerkleToken

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());
}
Also used : ResponseCodeEnum(com.hederahashgraph.api.proto.java.ResponseCodeEnum) AccountID(com.hederahashgraph.api.proto.java.AccountID) MerkleToken(com.hedera.services.state.merkle.MerkleToken) NftId(com.hedera.services.store.models.NftId)

Aggregations

MerkleToken (com.hedera.services.state.merkle.MerkleToken)16 Test (org.junit.jupiter.api.Test)9 EntityId (com.hedera.services.state.submerkle.EntityId)8 MerkleAccount (com.hedera.services.state.merkle.MerkleAccount)6 MerkleTokenRelStatus (com.hedera.services.state.merkle.MerkleTokenRelStatus)5 MerkleUniqueToken (com.hedera.services.state.merkle.MerkleUniqueToken)5 TransactionalLedger (com.hedera.services.ledger.TransactionalLedger)4 HashMapBackingAccounts (com.hedera.services.ledger.backing.HashMapBackingAccounts)4 HashMapBackingNfts (com.hedera.services.ledger.backing.HashMapBackingNfts)4 HashMapBackingTokenRels (com.hedera.services.ledger.backing.HashMapBackingTokenRels)4 HashMapBackingTokens (com.hedera.services.ledger.backing.HashMapBackingTokens)4 EntityNum (com.hedera.services.utils.EntityNum)3 AliasManager (com.hedera.services.ledger.accounts.AliasManager)2 StackedContractAliases (com.hedera.services.ledger.accounts.StackedContractAliases)2 NftId (com.hedera.services.store.models.NftId)2 AccountID (com.hederahashgraph.api.proto.java.AccountID)2 MerkleMap (com.swirlds.merkle.map.MerkleMap)2 ByteString (com.google.protobuf.ByteString)1 NetworkInfo (com.hedera.services.config.NetworkInfo)1 MutableStateChildren (com.hedera.services.context.MutableStateChildren)1