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