use of com.hedera.mirror.common.domain.balance.AccountBalance in project hedera-mirror-node by hashgraph.
the class AccountBalanceLineParserV2Test method parse.
@DisplayName("Parse account balance line")
@ParameterizedTest(name = "from \"{0}\"")
@CsvSource(value = { "'0,0,123,700,CggKAxjsBxCEBwoHCgMY7QcQGQoKCgMY7gcQwKilBAoICgMY8gcQhAcKBwoDGPMHEBkKCgoDGPQHEMCopQQ';false;" + "0;123;700;1004=900,1005=25,1006=9000000,1010=900,1011=25,1012=9000000", "'0,0,123,700,';false;" + "0;123;700;;", "'0,0,123,700,CggKAxjsBxCEBwoHCgMY7QcQGQoKCgMY7gcQwKilBAoICgMY8gcQhAcKBwoDGPMHEBkKCgo';true;;;;", "' 0,0,123,700,CggKAxjsBxCEBwoHCgMY7QcQGQoKCgMY7gcQwKilBAoICgMY8gcQhAcKBwoDGPMHEBkKCgoDGPQHEMCopQQ';" + "false;0;123;700;1004=900,1005=25,1006=9000000,1010=900,1011=25,1012=9000000", "'0, 0,123,700,CggKAxjsBxCEBwoHCgMY7QcQGQoKCgMY7gcQwKilBAoICgMY8gcQhAcKBwoDGPMHEBkKCgoDGPQHEMCopQQ';" + "false;0;123;700;1004=900,1005=25,1006=9000000,1010=900,1011=25,1012=9000000", "'0,0, 123,700,CggKAxjsBxCEBwoHCgMY7QcQGQoKCgMY7gcQwKilBAoICgMY8gcQhAcKBwoDGPMHEBkKCgoDGPQHEMCopQQ';" + "false;0;123;700;1004=900,1005=25,1006=9000000,1010=900,1011=25,1012=9000000", "'0,0,123, 700,CggKAxjsBxCEBwoHCgMY7QcQGQoKCgMY7gcQwKilBAoICgMY8gcQhAcKBwoDGPMHEBkKCgoDGPQHEMCopQQ';" + "false;0;123;700;1004=900,1005=25,1006=9000000,1010=900,1011=25,1012=9000000", "'0,0,123,700, CggKAxjsBxCEBwoHCgMY7QcQGQoKCgMY7gcQwKilBAoICgMY8gcQhAcKBwoDGPMHEBkKCgoDGPQHEMCopQQ';" + "false;0;123;700;1004=900,1005=25,1006=9000000,1010=900,1011=25,1012=9000000", "'0,0,123,700,CggKAxjsBxCEBwoHCgMY7QcQGQoKCgMY7gcQwKilBAoICgMY8gcQhAcKBwoDGPMHEBkKCgoDGPQHEMCopQQ ';" + "false;0;123;700;1004=900,1005=25,1006=9000000,1010=900,1011=25,1012=9000000", "'1,0,123,700,';true;;;;", "'x,0,123,700,';true;;;;", "'0,x,123,700,';true;;;;", "'0,0,x,700,';true;;;;", "'0,0,123,a00,';true;;;;", "'1000000000000000000000000000,0,123,700,';true;;;;", "'0,1000000000000000000000000000,123,700,';true;;;;", "'0,0,1000000000000000000000000000,700,';true;;;;", "'0,0,123,1000000000000000000000000000,';true;;;;", "'-1,0,123,700,';true;;;;", "'0,-1,123,700,';true;;;;", "'0,0,-1,700,';true;;;;", "'0,0,123,-1,';true;;;;", "'foobar';true;;;;", "'';true;;;;", ";true;;;;" }, delimiter = ';')
void parse(String line, boolean expectThrow, Long expectedRealm, Long expectedAccount, Long expectedBalance, String tokenBalances) throws IOException {
if (!expectThrow) {
AccountBalance accountBalance = parser.parse(line, timestamp);
var id = accountBalance.getId();
assertThat(accountBalance.getBalance()).isEqualTo(expectedBalance);
assertThat(id).isNotNull();
assertThat(id.getAccountId().getRealmNum()).isEqualTo(expectedRealm);
assertThat(id.getAccountId().getEntityNum()).isEqualTo(expectedAccount);
assertThat(id.getConsensusTimestamp()).isEqualTo(timestamp);
List<TokenBalance> actualTokenBalanceList = accountBalance.getTokenBalances();
if (StringUtils.isNotBlank(tokenBalances)) {
Map<Long, Long> expectedTokenBalances = Splitter.on(',').withKeyValueSeparator('=').split(tokenBalances).entrySet().stream().collect(Collectors.toMap(entry -> Long.parseLong(entry.getKey()), entry -> Long.parseLong(entry.getValue())));
assertThat(actualTokenBalanceList.size()).isEqualTo(expectedTokenBalances.size());
for (int i = 0; i < actualTokenBalanceList.size(); i++) {
TokenBalance actualTokenBalance = actualTokenBalanceList.get(i);
TokenBalance.Id actualId = actualTokenBalance.getId();
assertThat(expectedTokenBalances).containsKey(actualId.getTokenId().getEntityNum());
assertThat(actualTokenBalance.getBalance()).isEqualTo(expectedTokenBalances.get(actualId.getTokenId().getEntityNum()));
assertThat(actualId).isNotNull();
assertThat(actualId.getConsensusTimestamp()).isEqualTo(timestamp);
assertThat(actualId.getAccountId().getShardNum()).isEqualTo(mirrorProperties.getShard());
assertThat(actualId.getAccountId().getRealmNum()).isEqualTo(expectedRealm);
assertThat(actualId.getAccountId().getEntityNum()).isEqualTo(expectedAccount);
assertThat(actualId.getTokenId().getShardNum()).isEqualTo(mirrorProperties.getShard());
assertThat(actualId.getTokenId().getRealmNum()).isEqualTo(expectedRealm);
assertThat(actualId.getTokenId().getType()).isEqualTo(EntityType.TOKEN);
}
} else {
assertThat(actualTokenBalanceList.size()).isEqualTo(0);
}
} else {
assertThrows(InvalidDatasetException.class, () -> {
parser.parse(line, timestamp);
});
}
}
use of com.hedera.mirror.common.domain.balance.AccountBalance in project hedera-mirror-node by hashgraph.
the class CsvBalanceFileReader method read.
@Override
public AccountBalanceFile read(StreamFileData streamFileData) {
MessageDigest messageDigest = DigestUtils.getSha384Digest();
int bufferSize = balanceParserProperties.getFileBufferSize();
try (InputStream inputStream = new DigestInputStream(streamFileData.getInputStream(), messageDigest);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, CHARSET), bufferSize)) {
long consensusTimestamp = parseConsensusTimestamp(reader);
AtomicLong count = new AtomicLong(0L);
List<AccountBalance> items = new ArrayList<>();
AccountBalanceFile accountBalanceFile = new AccountBalanceFile();
accountBalanceFile.setBytes(streamFileData.getBytes());
accountBalanceFile.setConsensusTimestamp(consensusTimestamp);
accountBalanceFile.setLoadStart(Instant.now().getEpochSecond());
accountBalanceFile.setName(streamFileData.getFilename());
reader.lines().map(line -> {
try {
AccountBalance accountBalance = parser.parse(line, consensusTimestamp);
count.incrementAndGet();
return accountBalance;
} catch (InvalidDatasetException ex) {
log.error(ex);
return null;
}
}).filter(Objects::nonNull).forEachOrdered(items::add);
accountBalanceFile.setCount(count.get());
accountBalanceFile.setFileHash(DomainUtils.bytesToHex(messageDigest.digest()));
accountBalanceFile.setItems(Flux.fromIterable(items));
return accountBalanceFile;
} catch (IOException ex) {
throw new InvalidDatasetException("Error reading account balance file", ex);
}
}
use of com.hedera.mirror.common.domain.balance.AccountBalance in project hedera-mirror-node by hashgraph.
the class ProtoBalanceFileReader method toAccountBalance.
private AccountBalance toAccountBalance(long consensusTimestamp, SingleAccountBalances balances) {
EntityId accountId = EntityId.of(balances.getAccountID());
List<TokenBalance> tokenBalances = balances.getTokenUnitBalancesList().stream().map(tokenBalance -> {
EntityId tokenId = EntityId.of(tokenBalance.getTokenId());
TokenBalance.Id id = new TokenBalance.Id(consensusTimestamp, accountId, tokenId);
return new TokenBalance(tokenBalance.getBalance(), id);
}).collect(Collectors.toList());
return new AccountBalance(balances.getHbarBalance(), tokenBalances, new AccountBalance.Id(consensusTimestamp, accountId));
}
use of com.hedera.mirror.common.domain.balance.AccountBalance in project hedera-mirror-node by hashgraph.
the class AccountBalanceLineParserV1 method parse.
/**
* Parses an account balance line to extract shard, realm, account, and balance. If the shard matches
* systemShardNum, creates and returns an {@code AccountBalance} entity object. The account balance line should be
* in the format of "shard,realm,account,balance"
*
* @param line The account balance line
* @param consensusTimestamp The consensus timestamp of the account balance line
* @return {@code AccountBalance} entity object
* @throws InvalidDatasetException if the line is malformed or the shard does not match {@code systemShardNum}
*/
@Override
public AccountBalance parse(String line, long consensusTimestamp) {
try {
if (line == null) {
throw new InvalidDatasetException("Null line cannot be parsed");
}
List<String> parts = SPLITTER.splitToList(line);
if (parts.size() != 4) {
throw new InvalidDatasetException("Invalid account balance line: " + line);
}
long shardNum = Long.parseLong(parts.get(0));
int realmNum = Integer.parseInt(parts.get(1));
int accountNum = Integer.parseInt(parts.get(2));
long balance = Long.parseLong(parts.get(3));
if (shardNum < 0 || realmNum < 0 || accountNum < 0 || balance < 0) {
throw new InvalidDatasetException("Invalid account balance line: " + line);
}
if (shardNum != mirrorProperties.getShard()) {
throw new InvalidDatasetException(String.format("Invalid account balance line: %s. Expect " + "shard (%d), got shard (%d)", line, mirrorProperties.getShard(), shardNum));
}
return new AccountBalance(balance, Collections.emptyList(), new AccountBalance.Id(consensusTimestamp, EntityId.of(shardNum, realmNum, accountNum, EntityType.ACCOUNT)));
} catch (NumberFormatException ex) {
throw new InvalidDatasetException("Invalid account balance line: " + line, ex);
}
}
use of com.hedera.mirror.common.domain.balance.AccountBalance in project hedera-mirror-node by hashgraph.
the class AccountBalanceLineParserV2 method parse.
/**
* Parses an account balance line to extract shard, realm, account, balance, and token balances. If the shard
* matches systemShardNum, creates and returns an {@code AccountBalance} entity object. The account balance line
* should be in the format of "shard,realm,account,balance"
*
* @param line The account balance line
* @param consensusTimestamp The consensus timestamp of the account balance line
* @return {@code AccountBalance} entity object
* @throws InvalidDatasetException if the line is malformed or the shard does not match {@code systemShardNum}
*/
@Override
public AccountBalance parse(String line, long consensusTimestamp) {
try {
if (line == null) {
throw new InvalidDatasetException("Null line cannot be parsed");
}
List<String> parts = SPLITTER.splitToList(line);
boolean hasTokenBalance;
if (parts.size() == 5) {
hasTokenBalance = true;
} else if (parts.size() == 4) {
hasTokenBalance = false;
} else {
throw new InvalidDatasetException("Invalid account balance line: " + line);
}
long shardNum = Long.parseLong(parts.get(0));
int realmNum = Integer.parseInt(parts.get(1));
int accountNum = Integer.parseInt(parts.get(2));
long balance = Long.parseLong(parts.get(3));
if (shardNum < 0 || realmNum < 0 || accountNum < 0 || balance < 0) {
throw new InvalidDatasetException("Invalid account balance line: " + line);
}
if (shardNum != mirrorProperties.getShard()) {
throw new InvalidDatasetException(String.format("Invalid account balance line: %s. Expect " + "shard (%d), got shard (%d)", line, mirrorProperties.getShard(), shardNum));
}
EntityId accountId = EntityId.of(shardNum, realmNum, accountNum, EntityType.ACCOUNT);
List<TokenBalance> tokenBalances = hasTokenBalance ? parseTokenBalanceList(parts.get(4), consensusTimestamp, accountId) : Collections.emptyList();
return new AccountBalance(balance, tokenBalances, new AccountBalance.Id(consensusTimestamp, accountId));
} catch (NumberFormatException | InvalidProtocolBufferException ex) {
throw new InvalidDatasetException("Invalid account balance line: " + line, ex);
}
}
Aggregations