forked from Qortal/qortal
Fixed old Qora v1 "GenesisAccount" by replacing with NullAccount
NullAccount has 'empty' public key (32 bytes of zeros) compared with GenesisAccount's vague sometimes 8 bytes, sometimes 32 bytes public key. NullAccount has static public key and address, plus overridden methods to speed up pointless calls like verify(). Genesis Block also tidied up, dropping old Qora v1 compatibility and using proper block signature and public key to generate minter's block signature. Genesis Block transaction processing also simplified, with no need to access repository to handle fake references, due to new last-reference code (which will need to be merged). Dropped support for old, broken RMD160 code.
This commit is contained in:
parent
2602bb01e1
commit
9e2663b11b
@ -3,6 +3,9 @@ package org.qortal.account;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.qortal.block.BlockChain;
|
import org.qortal.block.BlockChain;
|
||||||
@ -15,6 +18,7 @@ import org.qortal.repository.Repository;
|
|||||||
import org.qortal.transaction.Transaction;
|
import org.qortal.transaction.Transaction;
|
||||||
import org.qortal.utils.Base58;
|
import org.qortal.utils.Base58;
|
||||||
|
|
||||||
|
@XmlAccessorType(XmlAccessType.NONE) // Stops JAX-RS errors when unmarshalling blockchain config
|
||||||
public class Account {
|
public class Account {
|
||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(Account.class);
|
private static final Logger LOGGER = LogManager.getLogger(Account.class);
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
package org.qortal.account;
|
|
||||||
|
|
||||||
import org.qortal.repository.Repository;
|
|
||||||
|
|
||||||
public final class GenesisAccount extends PublicKeyAccount {
|
|
||||||
|
|
||||||
public static final byte[] PUBLIC_KEY = new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
|
|
||||||
|
|
||||||
public GenesisAccount(Repository repository) {
|
|
||||||
super(repository, PUBLIC_KEY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
24
src/main/java/org/qortal/account/NullAccount.java
Normal file
24
src/main/java/org/qortal/account/NullAccount.java
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
package org.qortal.account;
|
||||||
|
|
||||||
|
import org.qortal.crypto.Crypto;
|
||||||
|
import org.qortal.repository.Repository;
|
||||||
|
|
||||||
|
public final class NullAccount extends PublicKeyAccount {
|
||||||
|
|
||||||
|
public static final byte[] PUBLIC_KEY = new byte[32];
|
||||||
|
public static final String ADDRESS = Crypto.toAddress(PUBLIC_KEY);
|
||||||
|
|
||||||
|
public NullAccount(Repository repository) {
|
||||||
|
super(repository, PUBLIC_KEY, ADDRESS);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected NullAccount() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean verify(byte[] signature, byte[] message) {
|
||||||
|
// Can't sign, hence can't verify.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -22,6 +22,18 @@ public class PublicKeyAccount extends Account {
|
|||||||
this.publicKey = edPublicKeyParams.getEncoded();
|
this.publicKey = edPublicKeyParams.getEncoded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected PublicKeyAccount(Repository repository, byte[] publicKey, String address) {
|
||||||
|
super(repository, address);
|
||||||
|
|
||||||
|
this.publicKey = publicKey;
|
||||||
|
this.edPublicKeyParams = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected PublicKeyAccount() {
|
||||||
|
this.publicKey = null;
|
||||||
|
this.edPublicKeyParams = null;
|
||||||
|
}
|
||||||
|
|
||||||
public byte[] getPublicKey() {
|
public byte[] getPublicKey() {
|
||||||
return this.publicKey;
|
return this.publicKey;
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ import org.ciyam.at.MachineState;
|
|||||||
import org.ciyam.at.OpCode;
|
import org.ciyam.at.OpCode;
|
||||||
import org.ciyam.at.Timestamp;
|
import org.ciyam.at.Timestamp;
|
||||||
import org.qortal.account.Account;
|
import org.qortal.account.Account;
|
||||||
import org.qortal.account.GenesisAccount;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.account.PublicKeyAccount;
|
import org.qortal.account.PublicKeyAccount;
|
||||||
import org.qortal.asset.Asset;
|
import org.qortal.asset.Asset;
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
@ -270,7 +270,7 @@ public class QortalATAPI extends API {
|
|||||||
byte[] reference = this.getLastReference();
|
byte[] reference = this.getLastReference();
|
||||||
BigDecimal amount = BigDecimal.valueOf(unscaledAmount, 8);
|
BigDecimal amount = BigDecimal.valueOf(unscaledAmount, 8);
|
||||||
|
|
||||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, NullAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||||
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
||||||
recipient.getAddress(), amount, this.atData.getAssetId(), new byte[0]);
|
recipient.getAddress(), amount, this.atData.getAssetId(), new byte[0]);
|
||||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||||
@ -289,7 +289,7 @@ public class QortalATAPI extends API {
|
|||||||
long timestamp = this.getNextTransactionTimestamp();
|
long timestamp = this.getNextTransactionTimestamp();
|
||||||
byte[] reference = this.getLastReference();
|
byte[] reference = this.getLastReference();
|
||||||
|
|
||||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, NullAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||||
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
||||||
recipient.getAddress(), BigDecimal.ZERO, this.atData.getAssetId(), message);
|
recipient.getAddress(), BigDecimal.ZERO, this.atData.getAssetId(), message);
|
||||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||||
@ -316,7 +316,7 @@ public class QortalATAPI extends API {
|
|||||||
byte[] reference = this.getLastReference();
|
byte[] reference = this.getLastReference();
|
||||||
BigDecimal amount = BigDecimal.valueOf(finalBalance, 8);
|
BigDecimal amount = BigDecimal.valueOf(finalBalance, 8);
|
||||||
|
|
||||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, reference, NullAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||||
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
ATTransactionData atTransactionData = new ATTransactionData(baseTransactionData, this.atData.getATAddress(),
|
||||||
creator.getAddress(), amount, this.atData.getAssetId(), new byte[0]);
|
creator.getAddress(), amount, this.atData.getAssetId(), new byte[0]);
|
||||||
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
AtTransaction atTransaction = new AtTransaction(this.repository, atTransactionData);
|
||||||
|
@ -7,27 +7,21 @@ import java.util.ArrayList;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
import org.qortal.account.Account;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.account.GenesisAccount;
|
|
||||||
import org.qortal.account.PublicKeyAccount;
|
|
||||||
import org.qortal.crypto.Crypto;
|
import org.qortal.crypto.Crypto;
|
||||||
import org.qortal.data.asset.AssetData;
|
import org.qortal.data.asset.AssetData;
|
||||||
import org.qortal.data.block.BlockData;
|
import org.qortal.data.block.BlockData;
|
||||||
import org.qortal.data.transaction.IssueAssetTransactionData;
|
|
||||||
import org.qortal.data.transaction.TransactionData;
|
import org.qortal.data.transaction.TransactionData;
|
||||||
import org.qortal.group.Group;
|
|
||||||
import org.qortal.repository.DataException;
|
import org.qortal.repository.DataException;
|
||||||
import org.qortal.repository.Repository;
|
import org.qortal.repository.Repository;
|
||||||
import org.qortal.transaction.Transaction;
|
import org.qortal.transaction.Transaction;
|
||||||
import org.qortal.transaction.Transaction.ApprovalStatus;
|
import org.qortal.transaction.Transaction.ApprovalStatus;
|
||||||
import org.qortal.transaction.Transaction.TransactionType;
|
|
||||||
import org.qortal.transform.TransformationException;
|
import org.qortal.transform.TransformationException;
|
||||||
import org.qortal.transform.transaction.TransactionTransformer;
|
import org.qortal.transform.transaction.TransactionTransformer;
|
||||||
|
|
||||||
@ -39,9 +33,8 @@ public class GenesisBlock extends Block {
|
|||||||
|
|
||||||
private static final Logger LOGGER = LogManager.getLogger(GenesisBlock.class);
|
private static final Logger LOGGER = LogManager.getLogger(GenesisBlock.class);
|
||||||
|
|
||||||
private static final byte[] GENESIS_REFERENCE = new byte[] {
|
private static final byte[] GENESIS_BLOCK_REFERENCE = new byte[128];
|
||||||
1, 1, 1, 1, 1, 1, 1, 1
|
private static final byte[] GENESIS_TRANSACTION_REFERENCE = new byte[64];
|
||||||
}; // NOTE: Neither 64 nor 128 bytes!
|
|
||||||
|
|
||||||
@XmlAccessorType(XmlAccessType.FIELD)
|
@XmlAccessorType(XmlAccessType.FIELD)
|
||||||
public static class GenesisInfo {
|
public static class GenesisInfo {
|
||||||
@ -96,37 +89,16 @@ public class GenesisBlock extends Block {
|
|||||||
transactionData.setFee(BigDecimal.ZERO.setScale(8));
|
transactionData.setFee(BigDecimal.ZERO.setScale(8));
|
||||||
|
|
||||||
if (transactionData.getCreatorPublicKey() == null)
|
if (transactionData.getCreatorPublicKey() == null)
|
||||||
transactionData.setCreatorPublicKey(GenesisAccount.PUBLIC_KEY);
|
transactionData.setCreatorPublicKey(NullAccount.PUBLIC_KEY);
|
||||||
|
|
||||||
if (transactionData.getTimestamp() == 0)
|
if (transactionData.getTimestamp() == 0)
|
||||||
transactionData.setTimestamp(info.timestamp);
|
transactionData.setTimestamp(info.timestamp);
|
||||||
});
|
});
|
||||||
|
|
||||||
// For version 1, extract any ISSUE_ASSET transactions into initialAssets and only allow GENESIS transactions
|
byte[] reference = GENESIS_BLOCK_REFERENCE;
|
||||||
if (info.version == 1) {
|
|
||||||
List<TransactionData> issueAssetTransactions = transactionsData.stream()
|
|
||||||
.filter(transactionData -> transactionData.getType() == TransactionType.ISSUE_ASSET).collect(Collectors.toList());
|
|
||||||
transactionsData.removeAll(issueAssetTransactions);
|
|
||||||
|
|
||||||
// There should be only GENESIS transactions left;
|
|
||||||
if (transactionsData.stream().anyMatch(transactionData -> transactionData.getType() != TransactionType.GENESIS)) {
|
|
||||||
LOGGER.error("Version 1 genesis block only allowed to contain GENESIS transctions (after issue-asset processing)");
|
|
||||||
throw new RuntimeException("Version 1 genesis block only allowed to contain GENESIS transctions (after issue-asset processing)");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert ISSUE_ASSET transactions into initial assets
|
|
||||||
initialAssets = issueAssetTransactions.stream().map(transactionData -> {
|
|
||||||
IssueAssetTransactionData issueAssetTransactionData = (IssueAssetTransactionData) transactionData;
|
|
||||||
|
|
||||||
return new AssetData(issueAssetTransactionData.getOwner(), issueAssetTransactionData.getAssetName(), issueAssetTransactionData.getDescription(),
|
|
||||||
issueAssetTransactionData.getQuantity(), issueAssetTransactionData.getIsDivisible(), "", false, Group.NO_GROUP, issueAssetTransactionData.getReference());
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
byte[] reference = GENESIS_REFERENCE;
|
|
||||||
int transactionCount = transactionsData.size();
|
int transactionCount = transactionsData.size();
|
||||||
BigDecimal totalFees = BigDecimal.ZERO.setScale(8);
|
BigDecimal totalFees = BigDecimal.ZERO.setScale(8);
|
||||||
byte[] minterPublicKey = GenesisAccount.PUBLIC_KEY;
|
byte[] minterPublicKey = NullAccount.PUBLIC_KEY;
|
||||||
byte[] bytesForSignature = getBytesForMinterSignature(info.timestamp, reference, minterPublicKey);
|
byte[] bytesForSignature = getBytesForMinterSignature(info.timestamp, reference, minterPublicKey);
|
||||||
byte[] minterSignature = calcGenesisMinterSignature(bytesForSignature);
|
byte[] minterSignature = calcGenesisMinterSignature(bytesForSignature);
|
||||||
byte[] transactionsSignature = calcGenesisTransactionsSignature();
|
byte[] transactionsSignature = calcGenesisTransactionsSignature();
|
||||||
@ -212,24 +184,16 @@ public class GenesisBlock extends Block {
|
|||||||
try {
|
try {
|
||||||
// Passing expected size to ByteArrayOutputStream avoids reallocation when adding more bytes than default 32.
|
// Passing expected size to ByteArrayOutputStream avoids reallocation when adding more bytes than default 32.
|
||||||
// See below for explanation of some of the values used to calculated expected size.
|
// See below for explanation of some of the values used to calculated expected size.
|
||||||
ByteArrayOutputStream bytes = new ByteArrayOutputStream(8 + 64 + 8 + 32);
|
ByteArrayOutputStream bytes = new ByteArrayOutputStream(8 + 128 + 32);
|
||||||
|
|
||||||
/*
|
// Genesis block timestamp
|
||||||
* NOTE: Historic code had genesis block using Longs.toByteArray(version) compared to standard block's Ints.toByteArray. The subsequent
|
|
||||||
* Bytes.ensureCapacity(versionBytes, 0, 4) did not truncate versionBytes back to 4 bytes either. This means 8 bytes were used even though
|
|
||||||
* VERSION_LENGTH is set to 4. Correcting this historic bug will break genesis block signatures!
|
|
||||||
*/
|
|
||||||
// For Qortal, we use genesis timestamp instead
|
|
||||||
bytes.write(Longs.toByteArray(timestamp));
|
bytes.write(Longs.toByteArray(timestamp));
|
||||||
|
|
||||||
/*
|
// Block's reference
|
||||||
* NOTE: Historic code had the reference expanded to only 64 bytes whereas standard block references are 128 bytes. Correcting this historic bug
|
bytes.write(reference);
|
||||||
* will break genesis block signatures!
|
|
||||||
*/
|
|
||||||
bytes.write(Bytes.ensureCapacity(reference, 64, 0));
|
|
||||||
|
|
||||||
// NOTE: Genesis account's public key is only 8 bytes, not the usual 32, so we have to pad.
|
// Minting account's public key (typically NullAccount)
|
||||||
bytes.write(Bytes.ensureCapacity(minterPublicKey, 32, 0));
|
bytes.write(minterPublicKey);
|
||||||
|
|
||||||
return bytes.toByteArray();
|
return bytes.toByteArray();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -295,26 +259,18 @@ public class GenesisBlock extends Block {
|
|||||||
public void process() throws DataException {
|
public void process() throws DataException {
|
||||||
LOGGER.info(String.format("Using genesis block timestamp of %d", this.blockData.getTimestamp()));
|
LOGGER.info(String.format("Using genesis block timestamp of %d", this.blockData.getTimestamp()));
|
||||||
|
|
||||||
// If we're a version 1 genesis block, create assets now
|
|
||||||
if (this.blockData.getVersion() == 1)
|
|
||||||
for (AssetData assetData : initialAssets)
|
|
||||||
repository.getAssetRepository().save(assetData);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Some transactions will be missing references and signatures,
|
* Some transactions will be missing references and signatures,
|
||||||
* so we generate them by trial-processing transactions and using
|
* so we generate them by using <tt>GENESIS_TRANSACTION_REFERENCE</tt>
|
||||||
* account's last-reference to fill in the gaps for reference,
|
|
||||||
* and a duplicated SHA256 digest for signature
|
* and a duplicated SHA256 digest for signature
|
||||||
*/
|
*/
|
||||||
this.repository.setSavepoint();
|
|
||||||
try {
|
try {
|
||||||
for (Transaction transaction : this.getTransactions()) {
|
for (Transaction transaction : this.getTransactions()) {
|
||||||
TransactionData transactionData = transaction.getTransactionData();
|
TransactionData transactionData = transaction.getTransactionData();
|
||||||
Account creator = new PublicKeyAccount(this.repository, transactionData.getCreatorPublicKey());
|
|
||||||
|
|
||||||
// Missing reference?
|
// Missing reference?
|
||||||
if (transactionData.getReference() == null)
|
if (transactionData.getReference() == null)
|
||||||
transactionData.setReference(creator.getLastReference());
|
transactionData.setReference(GENESIS_TRANSACTION_REFERENCE);
|
||||||
|
|
||||||
// Missing signature?
|
// Missing signature?
|
||||||
if (transactionData.getSignature() == null) {
|
if (transactionData.getSignature() == null) {
|
||||||
@ -324,18 +280,11 @@ public class GenesisBlock extends Block {
|
|||||||
transactionData.setSignature(signature);
|
transactionData.setSignature(signature);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Missing approval status (not used in V1)
|
// Approval status
|
||||||
transactionData.setApprovalStatus(ApprovalStatus.NOT_REQUIRED);
|
transactionData.setApprovalStatus(ApprovalStatus.NOT_REQUIRED);
|
||||||
|
|
||||||
// Ask transaction to update references, etc.
|
|
||||||
transaction.processReferencesAndFees();
|
|
||||||
|
|
||||||
creator.setLastReference(transactionData.getSignature());
|
|
||||||
}
|
}
|
||||||
} catch (TransformationException e) {
|
} catch (TransformationException e) {
|
||||||
throw new RuntimeException("Can't process genesis block transaction", e);
|
throw new RuntimeException("Can't process genesis block transaction", e);
|
||||||
} finally {
|
|
||||||
this.repository.rollbackToSavepoint();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save transactions into repository ready for processing
|
// Save transactions into repository ready for processing
|
||||||
|
@ -6,7 +6,7 @@ import javax.xml.bind.Unmarshaller;
|
|||||||
import javax.xml.bind.annotation.XmlAccessType;
|
import javax.xml.bind.annotation.XmlAccessType;
|
||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
import org.qortal.account.GenesisAccount;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.transaction.Transaction.TransactionType;
|
import org.qortal.transaction.Transaction.TransactionType;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
@ -31,14 +31,14 @@ public class ATTransactionData extends TransactionData {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
public void afterUnmarshal(Unmarshaller u, Object parent) {
|
||||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
this.creatorPublicKey = NullAccount.PUBLIC_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** From repository */
|
/** From repository */
|
||||||
public ATTransactionData(BaseTransactionData baseTransactionData, String atAddress, String recipient, BigDecimal amount, Long assetId, byte[] message) {
|
public ATTransactionData(BaseTransactionData baseTransactionData, String atAddress, String recipient, BigDecimal amount, Long assetId, byte[] message) {
|
||||||
super(TransactionType.AT, baseTransactionData);
|
super(TransactionType.AT, baseTransactionData);
|
||||||
|
|
||||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
this.creatorPublicKey = NullAccount.PUBLIC_KEY;
|
||||||
this.atAddress = atAddress;
|
this.atAddress = atAddress;
|
||||||
this.recipient = recipient;
|
this.recipient = recipient;
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
|
@ -6,7 +6,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
|||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
||||||
import org.qortal.account.GenesisAccount;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.block.GenesisBlock;
|
import org.qortal.block.GenesisBlock;
|
||||||
import org.qortal.transaction.Transaction.TransactionType;
|
import org.qortal.transaction.Transaction.TransactionType;
|
||||||
|
|
||||||
@ -36,10 +36,10 @@ public class AccountFlagsTransactionData extends TransactionData {
|
|||||||
/*
|
/*
|
||||||
* If we're being constructed as part of the genesis block info inside blockchain config
|
* If we're being constructed as part of the genesis block info inside blockchain config
|
||||||
* and no specific creator's public key is supplied
|
* and no specific creator's public key is supplied
|
||||||
* then use genesis account's public key.
|
* then use null account's public key.
|
||||||
*/
|
*/
|
||||||
if (parent instanceof GenesisBlock.GenesisInfo && this.creatorPublicKey == null)
|
if (parent instanceof GenesisBlock.GenesisInfo && this.creatorPublicKey == null)
|
||||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
this.creatorPublicKey = NullAccount.PUBLIC_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** From repository */
|
/** From repository */
|
||||||
|
@ -6,7 +6,7 @@ import javax.xml.bind.annotation.XmlAccessorType;
|
|||||||
import javax.xml.bind.annotation.XmlElement;
|
import javax.xml.bind.annotation.XmlElement;
|
||||||
|
|
||||||
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
||||||
import org.qortal.account.GenesisAccount;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.block.GenesisBlock;
|
import org.qortal.block.GenesisBlock;
|
||||||
import org.qortal.transaction.Transaction.TransactionType;
|
import org.qortal.transaction.Transaction.TransactionType;
|
||||||
|
|
||||||
@ -33,10 +33,10 @@ public class AccountLevelTransactionData extends TransactionData {
|
|||||||
/*
|
/*
|
||||||
* If we're being constructed as part of the genesis block info inside blockchain config
|
* If we're being constructed as part of the genesis block info inside blockchain config
|
||||||
* and no specific creator's public key is supplied
|
* and no specific creator's public key is supplied
|
||||||
* then use genesis account's public key.
|
* then use null account's public key.
|
||||||
*/
|
*/
|
||||||
if (parent instanceof GenesisBlock.GenesisInfo && this.creatorPublicKey == null)
|
if (parent instanceof GenesisBlock.GenesisInfo && this.creatorPublicKey == null)
|
||||||
this.creatorPublicKey = GenesisAccount.PUBLIC_KEY;
|
this.creatorPublicKey = NullAccount.PUBLIC_KEY;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** From repository, network/API */
|
/** From repository, network/API */
|
||||||
|
@ -34,10 +34,8 @@ public class GenesisTransactionData extends TransactionData {
|
|||||||
super(TransactionType.GENESIS);
|
super(TransactionType.GENESIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** From repository (V2) */
|
/** From repository */
|
||||||
public GenesisTransactionData(BaseTransactionData baseTransactionData, String recipient, BigDecimal amount, long assetId) {
|
public GenesisTransactionData(BaseTransactionData baseTransactionData, String recipient, BigDecimal amount, long assetId) {
|
||||||
// No groupID, null reference, zero fee, no approval required, height always 1
|
|
||||||
// super(TransactionType.GENESIS, timestamp, Group.NO_GROUP, null, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, ApprovalStatus.NOT_REQUIRED, 1, signature);
|
|
||||||
super(TransactionType.GENESIS, baseTransactionData);
|
super(TransactionType.GENESIS, baseTransactionData);
|
||||||
|
|
||||||
this.recipient = recipient;
|
this.recipient = recipient;
|
||||||
@ -45,7 +43,7 @@ public class GenesisTransactionData extends TransactionData {
|
|||||||
this.assetId = assetId;
|
this.assetId = assetId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** From repository (V1, where asset locked to QORT) */
|
/** From repository (where asset locked to QORT) */
|
||||||
public GenesisTransactionData(BaseTransactionData baseTransactionData, String recipient, BigDecimal amount) {
|
public GenesisTransactionData(BaseTransactionData baseTransactionData, String recipient, BigDecimal amount) {
|
||||||
this(baseTransactionData, recipient, amount, Asset.QORT);
|
this(baseTransactionData, recipient, amount, Asset.QORT);
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import javax.xml.bind.annotation.XmlAccessType;
|
|||||||
import javax.xml.bind.annotation.XmlAccessorType;
|
import javax.xml.bind.annotation.XmlAccessorType;
|
||||||
|
|
||||||
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
import org.eclipse.persistence.oxm.annotations.XmlDiscriminatorValue;
|
||||||
import org.qortal.account.GenesisAccount;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.block.GenesisBlock;
|
import org.qortal.block.GenesisBlock;
|
||||||
import org.qortal.transaction.Transaction.TransactionType;
|
import org.qortal.transaction.Transaction.TransactionType;
|
||||||
|
|
||||||
@ -51,10 +51,10 @@ public class IssueAssetTransactionData extends TransactionData {
|
|||||||
/*
|
/*
|
||||||
* If we're being constructed as part of the genesis block info inside blockchain config
|
* If we're being constructed as part of the genesis block info inside blockchain config
|
||||||
* and no specific issuer's public key is supplied
|
* and no specific issuer's public key is supplied
|
||||||
* then use genesis account's public key.
|
* then use null account's public key.
|
||||||
*/
|
*/
|
||||||
if (parent instanceof GenesisBlock.GenesisInfo && this.issuerPublicKey == null)
|
if (parent instanceof GenesisBlock.GenesisInfo && this.issuerPublicKey == null)
|
||||||
this.issuerPublicKey = GenesisAccount.PUBLIC_KEY;
|
this.issuerPublicKey = NullAccount.PUBLIC_KEY;
|
||||||
|
|
||||||
this.creatorPublicKey = this.issuerPublicKey;
|
this.creatorPublicKey = this.issuerPublicKey;
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.qortal.account.Account;
|
import org.qortal.account.Account;
|
||||||
import org.qortal.account.GenesisAccount;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.asset.Asset;
|
import org.qortal.asset.Asset;
|
||||||
import org.qortal.data.transaction.AccountFlagsTransactionData;
|
import org.qortal.data.transaction.AccountFlagsTransactionData;
|
||||||
import org.qortal.data.transaction.TransactionData;
|
import org.qortal.data.transaction.TransactionData;
|
||||||
@ -68,8 +68,8 @@ public class AccountFlagsTransaction extends Transaction {
|
|||||||
public ValidationResult isValid() throws DataException {
|
public ValidationResult isValid() throws DataException {
|
||||||
Account creator = getCreator();
|
Account creator = getCreator();
|
||||||
|
|
||||||
// Only genesis account can modify flags
|
// Only null account can modify flags
|
||||||
if (!creator.getAddress().equals(new GenesisAccount(repository).getAddress()))
|
if (!creator.getAddress().equals(NullAccount.ADDRESS))
|
||||||
return ValidationResult.NO_FLAG_PERMISSION;
|
return ValidationResult.NO_FLAG_PERMISSION;
|
||||||
|
|
||||||
// Check fee is zero or positive
|
// Check fee is zero or positive
|
||||||
|
@ -5,7 +5,7 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.qortal.account.Account;
|
import org.qortal.account.Account;
|
||||||
import org.qortal.account.GenesisAccount;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.asset.Asset;
|
import org.qortal.asset.Asset;
|
||||||
import org.qortal.block.BlockChain;
|
import org.qortal.block.BlockChain;
|
||||||
import org.qortal.data.transaction.AccountLevelTransactionData;
|
import org.qortal.data.transaction.AccountLevelTransactionData;
|
||||||
@ -70,7 +70,7 @@ public class AccountLevelTransaction extends Transaction {
|
|||||||
Account creator = getCreator();
|
Account creator = getCreator();
|
||||||
|
|
||||||
// Only genesis account can modify level
|
// Only genesis account can modify level
|
||||||
if (!creator.getAddress().equals(new GenesisAccount(repository).getAddress()))
|
if (!creator.getAddress().equals(new NullAccount(repository).getAddress()))
|
||||||
return ValidationResult.NO_FLAG_PERMISSION;
|
return ValidationResult.NO_FLAG_PERMISSION;
|
||||||
|
|
||||||
// Check fee is zero or positive
|
// Check fee is zero or positive
|
||||||
|
@ -5,7 +5,7 @@ import java.io.IOException;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
import org.qortal.account.GenesisAccount;
|
import org.qortal.account.NullAccount;
|
||||||
import org.qortal.data.transaction.BaseTransactionData;
|
import org.qortal.data.transaction.BaseTransactionData;
|
||||||
import org.qortal.data.transaction.GenesisTransactionData;
|
import org.qortal.data.transaction.GenesisTransactionData;
|
||||||
import org.qortal.data.transaction.TransactionData;
|
import org.qortal.data.transaction.TransactionData;
|
||||||
@ -49,7 +49,7 @@ public class GenesisTransactionTransformer extends TransactionTransformer {
|
|||||||
|
|
||||||
long assetId = byteBuffer.getLong();
|
long assetId = byteBuffer.getLong();
|
||||||
|
|
||||||
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, null, GenesisAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
BaseTransactionData baseTransactionData = new BaseTransactionData(timestamp, Group.NO_GROUP, null, NullAccount.PUBLIC_KEY, BigDecimal.ZERO, null);
|
||||||
|
|
||||||
return new GenesisTransactionData(baseTransactionData, recipient, amount, assetId);
|
return new GenesisTransactionData(baseTransactionData, recipient, amount, assetId);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user