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());
}
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);
}
});
}
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());
}
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);
}
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));
}
Aggregations