mirror of
https://github.com/Qortal/qortal.git
synced 2025-04-01 17:55:54 +00:00
Merge b0c3496cde5560fbf18cb3e849a078de32dbb62b into 8ffb0625a1edcf0b3d1ec2498b15a31ec38ade3c
This commit is contained in:
commit
d5f084edf0
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user