use of com.hedera.mirror.importer.exception.InvalidDatasetException in project hedera-mirror-node by hashgraph.
the class EntityRecordItemListener method insertCustomFees.
/**
* Inserts custom fees. Returns the list of collectors automatically associated with the newly created token if the
* custom fees are from a token create transaction
*
* @param customFeeList protobuf custom fee list
* @param consensusTimestamp consensus timestamp of the corresponding transaction
* @param isTokenCreate if the transaction with the custom fees is a token create
* @param tokenId the token id the custom fees are attached to
* @return A list of collectors automatically associated with the token if it's a token create transaction
*/
private Set<EntityId> insertCustomFees(List<com.hederahashgraph.api.proto.java.CustomFee> customFeeList, long consensusTimestamp, boolean isTokenCreate, EntityId tokenId) {
Set<EntityId> autoAssociatedAccounts = new HashSet<>();
CustomFee.Id id = new CustomFee.Id(consensusTimestamp, tokenId);
for (var protoCustomFee : customFeeList) {
EntityId collector = EntityId.of(protoCustomFee.getFeeCollectorAccountId());
CustomFee customFee = new CustomFee();
customFee.setId(id);
customFee.setCollectorAccountId(collector);
var feeCase = protoCustomFee.getFeeCase();
boolean chargedInAttachedToken;
switch(feeCase) {
case FIXED_FEE:
chargedInAttachedToken = parseFixedFee(customFee, protoCustomFee.getFixedFee(), tokenId);
break;
case FRACTIONAL_FEE:
// only FT can have fractional fee
parseFractionalFee(customFee, protoCustomFee.getFractionalFee());
chargedInAttachedToken = true;
break;
case ROYALTY_FEE:
// only NFT can have royalty fee, and fee can't be paid in NFT. Thus though royalty fee has a
// fixed fee fallback, the denominating token of the fixed fee can't be the NFT itself
parseRoyaltyFee(customFee, protoCustomFee.getRoyaltyFee(), tokenId);
chargedInAttachedToken = false;
break;
default:
log.error("Invalid CustomFee FeeCase {}", feeCase);
throw new InvalidDatasetException(String.format("Invalid CustomFee FeeCase %s", feeCase));
}
if (isTokenCreate && chargedInAttachedToken) {
// if it's from a token create transaction, and the fee is charged in the attached token, the attached
// token and the collector should have been auto associated
autoAssociatedAccounts.add(collector);
}
entityListener.onCustomFee(customFee);
}
if (customFeeList.isEmpty()) {
// for empty custom fees, add a single row with only the timestamp and tokenId.
CustomFee customFee = new CustomFee();
customFee.setId(id);
entityListener.onCustomFee(customFee);
}
return autoAssociatedAccounts;
}
use of com.hedera.mirror.importer.exception.InvalidDatasetException in project hedera-mirror-node by hashgraph.
the class BalanceFileReaderImplV2 method parseConsensusTimestamp.
@Override
protected long parseConsensusTimestamp(BufferedReader reader) {
String line = null;
try {
line = reader.readLine();
if (!supports(line)) {
throw new InvalidDatasetException("Version number not found in account balance file");
}
line = reader.readLine();
if (!StringUtils.startsWith(line, TIMESTAMP_HEADER_PREFIX)) {
throw new InvalidDatasetException("Timestamp not found in account balance file");
}
long consensusTimestamp = convertTimestamp(line.substring(TIMESTAMP_HEADER_PREFIX.length()));
line = reader.readLine();
if (!StringUtils.startsWith(line, COLUMN_HEADER_PREFIX)) {
throw new InvalidDatasetException("Column header not found in account balance file");
}
return consensusTimestamp;
} catch (DateTimeParseException ex) {
throw new InvalidDatasetException("Invalid timestamp header line: " + line, ex);
} catch (IOException ex) {
throw new InvalidDatasetException("Error reading account balance file", ex);
}
}
use of com.hedera.mirror.importer.exception.InvalidDatasetException in project hedera-mirror-node by hashgraph.
the class AddressBookServiceImpl method combinePreviousFileDataContents.
/**
* Concatenates byte arrays of first fileCreate/fileUpdate transaction and intermediate fileAppend entries that make
* up the potential addressBook
*
* @param fileData file data entry containing address book bytes
* @return
*/
private byte[] combinePreviousFileDataContents(FileData fileData) {
FileData firstPartialAddressBook = fileDataRepository.findLatestMatchingFile(fileData.getConsensusTimestamp(), fileData.getEntityId().getId(), List.of(TransactionType.FILECREATE.getProtoId(), TransactionType.FILEUPDATE.getProtoId())).orElseThrow(() -> new IllegalStateException("Missing FileData entry. FileAppend expects a corresponding FileCreate/FileUpdate entry"));
List<FileData> appendFileDataEntries = fileDataRepository.findFilesInRange(getAddressBookStartConsensusTimestamp(firstPartialAddressBook), fileData.getConsensusTimestamp() - 1, firstPartialAddressBook.getEntityId().getId(), TransactionType.FILEAPPEND.getProtoId());
try (var bos = new ByteArrayOutputStream(firstPartialAddressBook.getFileData().length)) {
bos.write(firstPartialAddressBook.getFileData());
for (var i = 0; i < appendFileDataEntries.size(); i++) {
bos.write(appendFileDataEntries.get(i).getFileData());
}
bos.write(fileData.getFileData());
return bos.toByteArray();
} catch (IOException ex) {
throw new InvalidDatasetException("Error concatenating partial address book fileData entries", ex);
}
}
use of com.hedera.mirror.importer.exception.InvalidDatasetException in project hedera-mirror-node by hashgraph.
the class CsvBalanceFileReaderTest method verifySuccess.
protected void verifySuccess(File file, AccountBalanceFile accountBalanceFile, int skipLines) throws IOException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), CsvBalanceFileReader.CHARSET))) {
while (skipLines > 0) {
reader.readLine();
skipLines--;
}
List<AccountBalance> accountBalances = accountBalanceFile.getItems().collectList().block();
var lineIter = reader.lines().iterator();
var accountBalanceIter = accountBalances.iterator();
while (lineIter.hasNext()) {
String line = lineIter.next();
line = line.trim();
if (line.isEmpty()) {
continue;
}
try {
AccountBalance expectedItem = parser.parse(line, consensusTimestamp);
AccountBalance actualItem = accountBalanceIter.next();
assertThat(actualItem).isEqualTo(expectedItem);
} catch (InvalidDatasetException ex) {
}
}
assertThat(accountBalanceIter.hasNext()).isFalse();
}
}
use of com.hedera.mirror.importer.exception.InvalidDatasetException in project hedera-mirror-node by hashgraph.
the class EntityRecordItemListener method insertTransactionSignatures.
private void insertTransactionSignatures(EntityId entityId, long consensusTimestamp, List<SignaturePair> signaturePairList) {
Set<ByteString> publicKeyPrefixes = new HashSet<>();
signaturePairList.forEach(signaturePair -> {
ByteString prefix = signaturePair.getPubKeyPrefix();
ByteString signature = null;
var signatureCase = signaturePair.getSignatureCase();
int type = signatureCase.getNumber();
switch(signatureCase) {
case CONTRACT:
signature = signaturePair.getContract();
break;
case ECDSA_384:
signature = signaturePair.getECDSA384();
break;
case ECDSA_SECP256K1:
signature = signaturePair.getECDSASecp256K1();
break;
case ED25519:
signature = signaturePair.getEd25519();
break;
case RSA_3072:
signature = signaturePair.getRSA3072();
break;
case SIGNATURE_NOT_SET:
Map<Integer, UnknownFieldSet.Field> unknownFields = signaturePair.getUnknownFields().asMap();
// field that has exactly one length-delimited value and assume it's our new signature bytes.
for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.entrySet()) {
UnknownFieldSet.Field field = entry.getValue();
if (field.getLengthDelimitedList().size() == 1) {
signature = field.getLengthDelimitedList().get(0);
type = entry.getKey();
break;
}
}
if (signature == null) {
throw new InvalidDatasetException("Unsupported signature: " + unknownFields);
}
break;
default:
throw new InvalidDatasetException("Unsupported signature: " + signaturePair.getSignatureCase());
}
// Handle potential public key prefix collisions by taking first occurrence only ignoring duplicates
if (publicKeyPrefixes.add(prefix)) {
TransactionSignature transactionSignature = new TransactionSignature();
transactionSignature.setConsensusTimestamp(consensusTimestamp);
transactionSignature.setEntityId(entityId);
transactionSignature.setPublicKeyPrefix(DomainUtils.toBytes(prefix));
transactionSignature.setSignature(DomainUtils.toBytes(signature));
transactionSignature.setType(type);
entityListener.onTransactionSignature(transactionSignature);
}
});
}
Aggregations