Search in sources :

Example 1 with NftId

use of com.hedera.services.store.models.NftId in project hedera-services by hashgraph.

the class BalanceChangeTest method ownershipChangeFactoryWorks.

@Test
void ownershipChangeFactoryWorks() {
    // setup:
    final var xfer = NftTransfer.newBuilder().setSenderAccountID(a).setReceiverAccountID(b).setSerialNumber(serialNo).setIsApproval(true).build();
    // given:
    final var nftChange = changingNftOwnership(t, t.asGrpcToken(), xfer, payer);
    // expect:
    assertEquals(a, nftChange.accountId());
    assertEquals(b, nftChange.counterPartyAccountId());
    assertEquals(t.asGrpcToken(), nftChange.tokenId());
    assertEquals(serialNo, nftChange.serialNo());
    // and:
    assertTrue(nftChange.isForNft());
    assertTrue(nftChange.isApprovedAllowance());
    assertEquals(new NftId(t.shard(), t.realm(), t.num(), serialNo), nftChange.nftId());
}
Also used : NftId(com.hedera.services.store.models.NftId) Test(org.junit.jupiter.api.Test)

Example 2 with NftId

use of com.hedera.services.store.models.NftId in project hedera-services by hashgraph.

the class HederaTokenStoreTest method setup.

@BeforeEach
void setup() {
    token = mock(MerkleToken.class);
    given(token.expiry()).willReturn(expiry);
    given(token.symbol()).willReturn(symbol);
    given(token.hasAutoRenewAccount()).willReturn(true);
    given(token.adminKey()).willReturn(Optional.of(TOKEN_ADMIN_KT.asJKeyUnchecked()));
    given(token.name()).willReturn(name);
    given(token.hasAdminKey()).willReturn(true);
    given(token.hasFeeScheduleKey()).willReturn(true);
    given(token.treasury()).willReturn(EntityId.fromGrpcAccountId(treasury));
    given(token.tokenType()).willReturn(TokenType.FUNGIBLE_COMMON);
    given(token.decimals()).willReturn(2);
    nonfungibleToken = mock(MerkleToken.class);
    given(nonfungibleToken.hasAdminKey()).willReturn(true);
    given(nonfungibleToken.tokenType()).willReturn(TokenType.NON_FUNGIBLE_UNIQUE);
    ids = mock(EntityIdSource.class);
    given(ids.newTokenId(sponsor)).willReturn(created);
    hederaLedger = mock(HederaLedger.class);
    nftsLedger = (TransactionalLedger<NftId, NftProperty, MerkleUniqueToken>) mock(TransactionalLedger.class);
    given(nftsLedger.get(aNft, NftProperty.OWNER)).willReturn(EntityId.fromGrpcAccountId(sponsor));
    given(nftsLedger.get(tNft, NftProperty.OWNER)).willReturn(EntityId.fromGrpcAccountId(primaryTreasury));
    given(nftsLedger.exists(aNft)).willReturn(true);
    given(nftsLedger.exists(tNft)).willReturn(true);
    accountsLedger = (TransactionalLedger<AccountID, AccountProperty, MerkleAccount>) mock(TransactionalLedger.class);
    given(accountsLedger.exists(treasury)).willReturn(true);
    given(accountsLedger.exists(anotherFeeCollector)).willReturn(true);
    given(accountsLedger.exists(autoRenewAccount)).willReturn(true);
    given(accountsLedger.exists(newAutoRenewAccount)).willReturn(true);
    given(accountsLedger.exists(primaryTreasury)).willReturn(true);
    given(accountsLedger.exists(sponsor)).willReturn(true);
    given(accountsLedger.exists(counterparty)).willReturn(true);
    given(accountsLedger.get(treasury, IS_DELETED)).willReturn(false);
    given(accountsLedger.get(autoRenewAccount, IS_DELETED)).willReturn(false);
    given(accountsLedger.get(newAutoRenewAccount, IS_DELETED)).willReturn(false);
    given(accountsLedger.get(sponsor, IS_DELETED)).willReturn(false);
    given(accountsLedger.get(counterparty, IS_DELETED)).willReturn(false);
    given(accountsLedger.get(primaryTreasury, IS_DELETED)).willReturn(false);
    backingTokens = mock(BackingTokens.class);
    given(backingTokens.contains(misc)).willReturn(true);
    given(backingTokens.contains(nonfungible)).willReturn(true);
    given(backingTokens.getRef(created)).willReturn(token);
    given(backingTokens.getImmutableRef(created)).willReturn(token);
    given(backingTokens.getRef(misc)).willReturn(token);
    given(backingTokens.getImmutableRef(misc)).willReturn(token);
    given(backingTokens.getRef(nonfungible)).willReturn(nonfungibleToken);
    given(backingTokens.getImmutableRef(tNft.tokenId())).willReturn(nonfungibleToken);
    given(backingTokens.getImmutableRef(tNft.tokenId()).treasury()).willReturn(EntityId.fromGrpcAccountId(primaryTreasury));
    given(backingTokens.idSet()).willReturn(Set.of(created));
    tokenRelsLedger = mock(TransactionalLedger.class);
    given(tokenRelsLedger.exists(sponsorMisc)).willReturn(true);
    given(tokenRelsLedger.exists(treasuryNft)).willReturn(true);
    given(tokenRelsLedger.exists(sponsorNft)).willReturn(true);
    given(tokenRelsLedger.exists(counterpartyNft)).willReturn(true);
    given(tokenRelsLedger.get(sponsorMisc, TOKEN_BALANCE)).willReturn(sponsorBalance);
    given(tokenRelsLedger.get(sponsorMisc, IS_FROZEN)).willReturn(false);
    given(tokenRelsLedger.get(sponsorMisc, IS_KYC_GRANTED)).willReturn(true);
    given(tokenRelsLedger.exists(treasuryMisc)).willReturn(true);
    given(tokenRelsLedger.exists(anotherFeeCollectorMisc)).willReturn(true);
    given(tokenRelsLedger.get(treasuryMisc, TOKEN_BALANCE)).willReturn(treasuryBalance);
    given(tokenRelsLedger.get(treasuryMisc, IS_FROZEN)).willReturn(false);
    given(tokenRelsLedger.get(treasuryMisc, IS_KYC_GRANTED)).willReturn(true);
    given(tokenRelsLedger.get(treasuryNft, TOKEN_BALANCE)).willReturn(123L);
    given(tokenRelsLedger.get(treasuryNft, IS_FROZEN)).willReturn(false);
    given(tokenRelsLedger.get(treasuryNft, IS_KYC_GRANTED)).willReturn(true);
    given(tokenRelsLedger.get(sponsorNft, TOKEN_BALANCE)).willReturn(123L);
    given(tokenRelsLedger.get(sponsorNft, IS_FROZEN)).willReturn(false);
    given(tokenRelsLedger.get(sponsorNft, IS_KYC_GRANTED)).willReturn(true);
    given(tokenRelsLedger.get(counterpartyNft, TOKEN_BALANCE)).willReturn(123L);
    given(tokenRelsLedger.get(counterpartyNft, IS_FROZEN)).willReturn(false);
    given(tokenRelsLedger.get(counterpartyNft, IS_KYC_GRANTED)).willReturn(true);
    given(tokenRelsLedger.get(newTreasuryNft, TOKEN_BALANCE)).willReturn(1L);
    properties = mock(GlobalDynamicProperties.class);
    given(properties.maxTokensPerAccount()).willReturn(MAX_TOKENS_PER_ACCOUNT);
    given(properties.maxTokenSymbolUtf8Bytes()).willReturn(MAX_TOKEN_SYMBOL_UTF8_BYTES);
    given(properties.maxTokenNameUtf8Bytes()).willReturn(MAX_TOKEN_NAME_UTF8_BYTES);
    given(properties.maxCustomFeesAllowed()).willReturn(maxCustomFees);
    sideEffectsTracker = new SideEffectsTracker();
    subject = new HederaTokenStore(ids, TEST_VALIDATOR, sideEffectsTracker, properties, tokenRelsLedger, nftsLedger, backingTokens);
    subject.setAccountsLedger(accountsLedger);
    subject.setHederaLedger(hederaLedger);
    subject.knownTreasuries.put(treasury, new HashSet<>() {

        {
            add(misc);
        }
    });
}
Also used : BackingTokens(com.hedera.services.ledger.backing.BackingTokens) EntityIdSource(com.hedera.services.ledger.ids.EntityIdSource) AccountID(com.hederahashgraph.api.proto.java.AccountID) HederaLedger(com.hedera.services.ledger.HederaLedger) SideEffectsTracker(com.hedera.services.context.SideEffectsTracker) MerkleToken(com.hedera.services.state.merkle.MerkleToken) MerkleAccount(com.hedera.services.state.merkle.MerkleAccount) GlobalDynamicProperties(com.hedera.services.context.properties.GlobalDynamicProperties) NftId(com.hedera.services.store.models.NftId) NftProperty(com.hedera.services.ledger.properties.NftProperty) AccountProperty(com.hedera.services.ledger.properties.AccountProperty) TransactionalLedger(com.hedera.services.ledger.TransactionalLedger) MerkleUniqueToken(com.hedera.services.state.merkle.MerkleUniqueToken) BeforeEach(org.junit.jupiter.api.BeforeEach)

Example 3 with NftId

use of com.hedera.services.store.models.NftId 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)

Example 4 with NftId

use of com.hedera.services.store.models.NftId in project hedera-services by hashgraph.

the class AdjustAllowanceChecksTest method validateRepeatedSerials.

@Test
void validateRepeatedSerials() {
    given(payer.getId()).willReturn(Id.fromGrpcAccount(ownerId));
    var serials = List.of(1L, 10L, 1L);
    var validity = subject.validateSerialNums(serials, payer, token2Model, existingSerials);
    assertEquals(REPEATED_SERIAL_NUMS_IN_NFT_ALLOWANCES, validity);
    serials = List.of(10L, 4L);
    validity = subject.validateSerialNums(serials, payer, token2Model, existingSerials);
    assertEquals(INVALID_TOKEN_NFT_SERIAL_NUMBER, validity);
    final NftId token1Nft1 = new NftId(0, 0, token2.getTokenNum(), 20L);
    final NftId tokenNft2 = new NftId(0, 0, token2.getTokenNum(), 4L);
    given(nftsMap.get(EntityNumPair.fromNftId(token1Nft1))).willReturn(token);
    given(nftsMap.get(EntityNumPair.fromNftId(tokenNft2))).willReturn(token);
    given(nftsMap.get(EntityNumPair.fromNftId(token1Nft1)).getOwner()).willReturn(EntityId.fromGrpcAccountId(ownerId));
    given(nftsMap.get(EntityNumPair.fromNftId(tokenNft2)).getOwner()).willReturn(EntityId.fromGrpcAccountId(ownerId));
    given(nftsMap.containsKey(EntityNumPair.fromNftId(token1Nft1))).willReturn(true);
    given(nftsMap.containsKey(EntityNumPair.fromNftId(tokenNft2))).willReturn(true);
    serials = List.of(20L, 4L);
    validity = subject.validateSerialNums(serials, payer, token2Model, existingSerials);
    assertEquals(OK, validity);
}
Also used : NftId(com.hedera.services.store.models.NftId) Test(org.junit.jupiter.api.Test)

Example 5 with NftId

use of com.hedera.services.store.models.NftId in project hedera-services by hashgraph.

the class ApproveAllowanceChecksTest method fungibleInNFTAllowances.

@Test
void fungibleInNFTAllowances() {
    given(owner.getId()).willReturn(Id.fromGrpcAccount(ownerId1));
    given(tokenStore.loadPossiblyPausedToken(token2Model.getId())).willReturn(token2Model);
    given(tokenStore.loadPossiblyPausedToken(token1Model.getId())).willReturn(token1Model);
    given(owner.isAssociatedWith(token2Model.getId())).willReturn(true);
    given(nftsMap.containsKey(EntityNumPair.fromNftId(token2Nft1))).willReturn(true);
    given(nftsMap.containsKey(EntityNumPair.fromNftId(token2Nft2))).willReturn(true);
    final NftId token1Nft1 = new NftId(0, 0, token2.getTokenNum(), 1L);
    final NftId tokenNft2 = new NftId(0, 0, token2.getTokenNum(), 10L);
    given(nftsMap.get(EntityNumPair.fromNftId(token1Nft1))).willReturn(token);
    given(nftsMap.get(EntityNumPair.fromNftId(tokenNft2))).willReturn(token);
    given(nftsMap.get(EntityNumPair.fromNftId(token1Nft1)).getOwner()).willReturn(EntityId.fromGrpcAccountId(ownerId1));
    given(nftsMap.get(EntityNumPair.fromNftId(tokenNft2)).getOwner()).willReturn(EntityId.fromGrpcAccountId(ownerId1));
    final var badNftAllowance = NftAllowance.newBuilder().setSpender(spender2).addAllSerialNumbers(List.of(1L)).setTokenId(token1).setOwner(ownerId1).setApprovedForAll(BoolValue.of(false)).build();
    nftAllowances.add(badNftAllowance);
    assertEquals(FUNGIBLE_TOKEN_IN_NFT_ALLOWANCES, subject.validateNftAllowances(nftAllowances, owner));
}
Also used : NftId(com.hedera.services.store.models.NftId) Test(org.junit.jupiter.api.Test)

Aggregations

NftId (com.hedera.services.store.models.NftId)10 Test (org.junit.jupiter.api.Test)5 MerkleToken (com.hedera.services.state.merkle.MerkleToken)2 AccountID (com.hederahashgraph.api.proto.java.AccountID)2 SideEffectsTracker (com.hedera.services.context.SideEffectsTracker)1 GlobalDynamicProperties (com.hedera.services.context.properties.GlobalDynamicProperties)1 HederaLedger (com.hedera.services.ledger.HederaLedger)1 TransactionalLedger (com.hedera.services.ledger.TransactionalLedger)1 BackingTokens (com.hedera.services.ledger.backing.BackingTokens)1 EntityIdSource (com.hedera.services.ledger.ids.EntityIdSource)1 AccountProperty (com.hedera.services.ledger.properties.AccountProperty)1 NftProperty (com.hedera.services.ledger.properties.NftProperty)1 MerkleAccount (com.hedera.services.state.merkle.MerkleAccount)1 MerkleUniqueToken (com.hedera.services.state.merkle.MerkleUniqueToken)1 ResponseCodeEnum (com.hederahashgraph.api.proto.java.ResponseCodeEnum)1 BeforeEach (org.junit.jupiter.api.BeforeEach)1