Merge b0c3496cde5560fbf18cb3e849a078de32dbb62b into 8ffb0625a1edcf0b3d1ec2498b15a31ec38ade3c

This commit is contained in:
cwd.systems | 0KN 2024-11-27 16:27:14 +00:00 committed by GitHub
commit d5f084edf0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -220,29 +220,34 @@ public class Block {
} }
public long distribute(long accountAmount, Map<String, Long> balanceChanges) { public long distribute(long accountAmount, Map<String, Long> balanceChanges) {
if (this.isRecipientAlsoMinter) {
// minter & recipient the same - simpler case // Check if the minter and recipient are the same
LOGGER.trace(() -> String.format("Minter/recipient account %s share: %s", this.mintingAccount.getAddress(), Amounts.prettyAmount(accountAmount))); if (this.isRecipientAlsoMinter) {
if (accountAmount != 0) // Log and directly update the minter's account
balanceChanges.merge(this.mintingAccount.getAddress(), accountAmount, Long::sum); LOGGER.trace(() -> String.format("Minter/recipient account %s share: %s",
} else { this.mintingAccount.getAddress(), Amounts.prettyAmount(accountAmount)));
// minter & recipient different - extra work needed
long recipientAmount = (accountAmount * this.sharePercent) / 100L / 100L; // because scaled by 2dp and 'percent' means "per 100" balanceChanges.merge(this.mintingAccount.getAddress(), accountAmount, Long::sum);
long minterAmount = accountAmount - recipientAmount; } else {
// Calculate the recipient's share using precise scaling to avoid rounding errors
long recipientAmount = Math.round((double) accountAmount * this.sharePercent / 10000.0);
long minterAmount = accountAmount - recipientAmount;
LOGGER.trace(() -> String.format("Minter account %s share: %s", this.mintingAccount.getAddress(), Amounts.prettyAmount(minterAmount))); // Log and update the minter's account balance
if (minterAmount != 0) LOGGER.trace(() -> String.format("Minter account %s share: %s",
balanceChanges.merge(this.mintingAccount.getAddress(), minterAmount, Long::sum); this.mintingAccount.getAddress(), Amounts.prettyAmount(minterAmount)));
balanceChanges.merge(this.mintingAccount.getAddress(), minterAmount, Long::sum);
LOGGER.trace(() -> String.format("Recipient account %s share: %s", this.recipientAccount.getAddress(), Amounts.prettyAmount(recipientAmount))); // Log and update the recipient's account balance
if (recipientAmount != 0) LOGGER.trace(() -> String.format("Recipient account %s share: %s",
balanceChanges.merge(this.recipientAccount.getAddress(), recipientAmount, Long::sum); this.recipientAccount.getAddress(), Amounts.prettyAmount(recipientAmount)));
} balanceChanges.merge(this.recipientAccount.getAddress(), recipientAmount, Long::sum);
}
// The entire amount has been distributed
return accountAmount;
}
// We always distribute all of the amount
return accountAmount;
}
}
/** Always use getExpandedAccounts() to access this, as it's lazy-instantiated. */ /** Always use getExpandedAccounts() to access this, as it's lazy-instantiated. */
private List<ExpandedAccount> cachedExpandedAccounts = null; private List<ExpandedAccount> cachedExpandedAccounts = null;
@ -523,56 +528,78 @@ public class Block {
* @throws DataException * @throws DataException
*/ */
public Block remint(PrivateKeyAccount minter) throws DataException { public Block remint(PrivateKeyAccount minter) throws DataException {
Block newBlock = new Block(this.repository, this.blockData); if (minter == null) {
newBlock.minter = minter; LOGGER.error("Minter cannot be null");
return null;
}
BlockData parentBlockData = this.getParent(); // Create a new block instance based on the current block data
Block newBlock = new Block(this.repository, this.blockData);
newBlock.minter = minter;
// Copy AT state data // Fetch the parent block data
newBlock.ourAtStates = this.ourAtStates; BlockData parentBlockData = this.getParent();
newBlock.atStates = newBlock.ourAtStates; if (parentBlockData == null) {
newBlock.ourAtFees = this.ourAtFees; LOGGER.error("Parent block data is null");
return null;
}
// Calculate new block timestamp // Copy AT state data
int version = this.blockData.getVersion(); newBlock.ourAtStates = this.ourAtStates;
byte[] reference = this.blockData.getReference(); newBlock.atStates = this.ourAtStates; // Same reference as ourAtStates
newBlock.ourAtFees = this.ourAtFees;
byte[] minterSignature = minter.sign(BlockTransformer.getBytesForMinterSignature(parentBlockData, // Block version and reference
minter.getPublicKey(), this.blockData.getEncodedOnlineAccounts())); int version = this.blockData.getVersion();
byte[] reference = this.blockData.getReference();
// Qortal: minter is always a reward-share, so find actual minter and get their effective minting level // Generate minter's signature for the new block
int minterLevel = Account.getRewardShareEffectiveMintingLevel(repository, minter.getPublicKey()); byte[] minterSignature = minter.sign(BlockTransformer.getBytesForMinterSignature(
if (minterLevel == 0){ parentBlockData, minter.getPublicKey(), this.blockData.getEncodedOnlineAccounts()));
LOGGER.error("Minter effective level returned zero?");
return null;
}
long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel); // Find the effective minting level of the minter
int minterLevel = Account.getRewardShareEffectiveMintingLevel(repository, minter.getPublicKey());
if (minterLevel <= 0) {
LOGGER.error("Invalid minter effective minting level: {}", minterLevel);
return null;
}
newBlock.transactions = this.transactions; // Calculate the new block timestamp
int transactionCount = this.blockData.getTransactionCount(); long timestamp = calcTimestamp(parentBlockData, minter.getPublicKey(), minterLevel);
long totalFees = this.blockData.getTotalFees(); if (timestamp <= 0) {
byte[] transactionsSignature = null; // We'll calculate this later LOGGER.error("Invalid timestamp calculated for new block");
Integer height = this.blockData.getHeight(); return null;
}
int atCount = newBlock.ourAtStates.size(); // Copy transactions and associated data
long atFees = newBlock.ourAtFees; newBlock.transactions = this.transactions;
int transactionCount = this.blockData.getTransactionCount();
long totalFees = this.blockData.getTotalFees();
byte[] encodedOnlineAccounts = this.blockData.getEncodedOnlineAccounts(); // Copy AT-related data
int onlineAccountsCount = this.blockData.getOnlineAccountsCount(); int atCount = this.ourAtStates.size();
Long onlineAccountsTimestamp = this.blockData.getOnlineAccountsTimestamp(); long atFees = this.ourAtFees;
byte[] onlineAccountsSignatures = this.blockData.getOnlineAccountsSignatures();
newBlock.blockData = new BlockData(version, reference, transactionCount, totalFees, transactionsSignature, height, timestamp, // Online accounts data
minter.getPublicKey(), minterSignature, atCount, atFees, encodedOnlineAccounts, onlineAccountsCount, onlineAccountsTimestamp, onlineAccountsSignatures); byte[] encodedOnlineAccounts = this.blockData.getEncodedOnlineAccounts();
int onlineAccountsCount = this.blockData.getOnlineAccountsCount();
Long onlineAccountsTimestamp = this.blockData.getOnlineAccountsTimestamp();
byte[] onlineAccountsSignatures = this.blockData.getOnlineAccountsSignatures();
// Resign to update transactions signature // Create new block data with updated timestamp and signature
newBlock.sign(); newBlock.blockData = new BlockData(
version, reference, transactionCount, totalFees, null, // Transactions signature calculated later
this.blockData.getHeight(), timestamp, minter.getPublicKey(), minterSignature,
atCount, atFees, encodedOnlineAccounts, onlineAccountsCount, onlineAccountsTimestamp, onlineAccountsSignatures);
return newBlock; // Resign the block to calculate transactions signature
} newBlock.sign();
// Getters/setters // Return the newly reminted block
return newBlock;
}
// Getters/setters
public BlockData getBlockData() { public BlockData getBlockData() {
return this.blockData; return this.blockData;