@@ -7,6 +7,8 @@ package com.jd.blockchain.consts; | |||||
* | * | ||||
*/ | */ | ||||
public interface DataCodes { | public interface DataCodes { | ||||
public static final int MERKLE_SNAPSHOT = 0x070; | |||||
public static final int BYTES_VALUE = 0x080; | public static final int BYTES_VALUE = 0x080; | ||||
@@ -57,13 +59,13 @@ public interface DataCodes { | |||||
public static final int TX_RESPONSE = 0x360; | public static final int TX_RESPONSE = 0x360; | ||||
public static final int TX_OP_RESULT = 0x370; | public static final int TX_OP_RESULT = 0x370; | ||||
public static final int TX_OP_ROLE_CONFIGURE = 0x371; | public static final int TX_OP_ROLE_CONFIGURE = 0x371; | ||||
public static final int TX_OP_ROLE_CONFIGURE_ENTRY = 0x372; | public static final int TX_OP_ROLE_CONFIGURE_ENTRY = 0x372; | ||||
public static final int TX_OP_USER_ROLES_AUTHORIZE = 0x373; | public static final int TX_OP_USER_ROLES_AUTHORIZE = 0x373; | ||||
public static final int TX_OP_USER_ROLE_AUTHORIZE_ENTRY = 0x374; | public static final int TX_OP_USER_ROLE_AUTHORIZE_ENTRY = 0x374; | ||||
// enum types of permissions; | // enum types of permissions; | ||||
@@ -74,11 +76,11 @@ public interface DataCodes { | |||||
public static final int PRIVILEGE_SET = 0x410; | public static final int PRIVILEGE_SET = 0x410; | ||||
public static final int ROLE_SET = 0x411; | public static final int ROLE_SET = 0x411; | ||||
public static final int SECURITY_INIT_SETTING = 0x420; | public static final int SECURITY_INIT_SETTING = 0x420; | ||||
public static final int SECURITY_ROLE_INIT_SETTING = 0x421; | public static final int SECURITY_ROLE_INIT_SETTING = 0x421; | ||||
public static final int SECURITY_USER_AUTH_INIT_SETTING = 0x422; | public static final int SECURITY_USER_AUTH_INIT_SETTING = 0x422; | ||||
// contract types of metadata; | // contract types of metadata; | ||||
@@ -103,7 +105,6 @@ public interface DataCodes { | |||||
// | // | ||||
// public static final int METADATA_CRYPTO_SETTING = 0x642; | // public static final int METADATA_CRYPTO_SETTING = 0x642; | ||||
// public static final int METADATA_CONSENSUS_NODE = 0x630; | // public static final int METADATA_CONSENSUS_NODE = 0x630; | ||||
public static final int METADATA_CONSENSUS_SETTING = 0x631; | public static final int METADATA_CONSENSUS_SETTING = 0x631; | ||||
@@ -113,10 +114,10 @@ public interface DataCodes { | |||||
public static final int METADATA_PARTICIPANT_STATE_INFO = 0x641; | public static final int METADATA_PARTICIPANT_STATE_INFO = 0x641; | ||||
public static final int METADATA_CRYPTO_SETTING = 0x642; | public static final int METADATA_CRYPTO_SETTING = 0x642; | ||||
public static final int METADATA_CRYPTO_SETTING_PROVIDER = 0x643; | public static final int METADATA_CRYPTO_SETTING_PROVIDER = 0x643; | ||||
// public static final int ACCOUNT = 0x700; | |||||
// public static final int ACCOUNT = 0x700; | |||||
public static final int ACCOUNT_HEADER = 0x710; | public static final int ACCOUNT_HEADER = 0x710; | ||||
@@ -194,5 +195,4 @@ public interface DataCodes { | |||||
public static final int CONSENSUS_MSGQUEUE_BLOCK_SETTINGS = CONSENSUS_MSGQUEUE | 0x05; | public static final int CONSENSUS_MSGQUEUE_BLOCK_SETTINGS = CONSENSUS_MSGQUEUE | 0x05; | ||||
} | } |
@@ -14,9 +14,9 @@ public class ContractAccount implements ContractInfo { | |||||
private static final Bytes CHAIN_CODE_KEY = Bytes.fromString("CHAIN-CODE"); | private static final Bytes CHAIN_CODE_KEY = Bytes.fromString("CHAIN-CODE"); | ||||
private BaseAccount accBase; | |||||
private MerkleAccount accBase; | |||||
public ContractAccount(BaseAccount accBase) { | |||||
public ContractAccount(MerkleAccount accBase) { | |||||
this.accBase = accBase; | this.accBase = accBase; | ||||
} | } | ||||
@@ -57,7 +57,7 @@ public class ContractAccount implements ContractInfo { | |||||
} | } | ||||
public long getChaincodeVersion() { | public long getChaincodeVersion() { | ||||
return accBase.getKeyVersion(CHAIN_CODE_KEY); | |||||
return accBase.getVersion(CHAIN_CODE_KEY); | |||||
} | } | ||||
public long setProperty(Bytes key, String value, long version) { | public long setProperty(Bytes key, String value, long version) { | ||||
@@ -13,22 +13,22 @@ import com.jd.blockchain.utils.Transactional; | |||||
public class ContractAccountSet implements Transactional, ContractAccountQuery { | public class ContractAccountSet implements Transactional, ContractAccountQuery { | ||||
private AccountSet accountSet; | |||||
private MerkleAccountSet accountSet; | |||||
public ContractAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, | public ContractAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, | ||||
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { | VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { | ||||
accountSet = new AccountSet(cryptoSetting, prefix, exStorage, verStorage, accessPolicy); | |||||
accountSet = new MerkleAccountSet(cryptoSetting, prefix, exStorage, verStorage, accessPolicy); | |||||
} | } | ||||
public ContractAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix, | public ContractAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix, | ||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | ||||
AccountAccessPolicy accessPolicy) { | AccountAccessPolicy accessPolicy) { | ||||
accountSet = new AccountSet(dataRootHash, cryptoSetting, prefix, exStorage, verStorage, readonly, accessPolicy); | |||||
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, prefix, exStorage, verStorage, readonly, accessPolicy); | |||||
} | } | ||||
@Override | @Override | ||||
public AccountHeader[] getHeaders(int fromIndex, int count) { | public AccountHeader[] getHeaders(int fromIndex, int count) { | ||||
return accountSet.getAccounts(fromIndex, count); | |||||
return accountSet.getHeaders(fromIndex, count); | |||||
} | } | ||||
public boolean isReadonly() { | public boolean isReadonly() { | ||||
@@ -51,7 +51,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||||
*/ | */ | ||||
@Override | @Override | ||||
public long getTotal() { | public long getTotal() { | ||||
return accountSet.getTotalCount(); | |||||
return accountSet.getTotal(); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -66,7 +66,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||||
@Override | @Override | ||||
public ContractAccount getAccount(Bytes address) { | public ContractAccount getAccount(Bytes address) { | ||||
BaseAccount accBase = accountSet.getAccount(address); | |||||
MerkleAccount accBase = accountSet.getAccount(address); | |||||
return new ContractAccount(accBase); | return new ContractAccount(accBase); | ||||
} | } | ||||
@@ -77,7 +77,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||||
@Override | @Override | ||||
public ContractAccount getAccount(Bytes address, long version) { | public ContractAccount getAccount(Bytes address, long version) { | ||||
BaseAccount accBase = accountSet.getAccount(address, version); | |||||
MerkleAccount accBase = accountSet.getAccount(address, version); | |||||
return new ContractAccount(accBase); | return new ContractAccount(accBase); | ||||
} | } | ||||
@@ -92,7 +92,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||||
*/ | */ | ||||
public ContractAccount deploy(Bytes address, PubKey pubKey, DigitalSignature addressSignature, byte[] chaincode) { | public ContractAccount deploy(Bytes address, PubKey pubKey, DigitalSignature addressSignature, byte[] chaincode) { | ||||
// TODO: 校验和记录合约地址签名; | // TODO: 校验和记录合约地址签名; | ||||
BaseAccount accBase = accountSet.register(address, pubKey); | |||||
MerkleAccount accBase = accountSet.register(address, pubKey); | |||||
ContractAccount contractAcc = new ContractAccount(accBase); | ContractAccount contractAcc = new ContractAccount(accBase); | ||||
contractAcc.setChaincode(chaincode, -1); | contractAcc.setChaincode(chaincode, -1); | ||||
return contractAcc; | return contractAcc; | ||||
@@ -107,7 +107,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||||
* @return 返回链码的新版本号; | * @return 返回链码的新版本号; | ||||
*/ | */ | ||||
public long update(Bytes address, byte[] chaincode, long version) { | public long update(Bytes address, byte[] chaincode, long version) { | ||||
BaseAccount accBase = accountSet.getAccount(address); | |||||
MerkleAccount accBase = accountSet.getAccount(address); | |||||
ContractAccount contractAcc = new ContractAccount(accBase); | ContractAccount contractAcc = new ContractAccount(accBase); | ||||
return contractAcc.setChaincode(chaincode, version); | return contractAcc.setChaincode(chaincode, version); | ||||
} | } | ||||
@@ -13,9 +13,9 @@ import com.jd.blockchain.utils.Bytes; | |||||
public class DataAccount implements AccountHeader, MerkleProvable { | public class DataAccount implements AccountHeader, MerkleProvable { | ||||
private BaseAccount baseAccount; | |||||
private MerkleAccount baseAccount; | |||||
public DataAccount(BaseAccount accBase) { | |||||
public DataAccount(MerkleAccount accBase) { | |||||
this.baseAccount = accBase; | this.baseAccount = accBase; | ||||
} | } | ||||
@@ -135,7 +135,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { | |||||
* @return | * @return | ||||
*/ | */ | ||||
public long getDataVersion(String key) { | public long getDataVersion(String key) { | ||||
return baseAccount.getKeyVersion(Bytes.fromString(key)); | |||||
return baseAccount.getVersion(Bytes.fromString(key)); | |||||
} | } | ||||
/** | /** | ||||
@@ -146,7 +146,7 @@ public class DataAccount implements AccountHeader, MerkleProvable { | |||||
* @return | * @return | ||||
*/ | */ | ||||
public long getDataVersion(Bytes key) { | public long getDataVersion(Bytes key) { | ||||
return baseAccount.getKeyVersion(key); | |||||
return baseAccount.getVersion(key); | |||||
} | } | ||||
/** | /** | ||||
@@ -13,22 +13,22 @@ import com.jd.blockchain.utils.Transactional; | |||||
public class DataAccountSet implements Transactional, DataAccountQuery { | public class DataAccountSet implements Transactional, DataAccountQuery { | ||||
private AccountSet accountSet; | |||||
private MerkleAccountSet accountSet; | |||||
public DataAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, | public DataAccountSet(CryptoSetting cryptoSetting, String prefix, ExPolicyKVStorage exStorage, | ||||
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { | VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { | ||||
accountSet = new AccountSet(cryptoSetting, prefix, exStorage, verStorage, accessPolicy); | |||||
accountSet = new MerkleAccountSet(cryptoSetting, prefix, exStorage, verStorage, accessPolicy); | |||||
} | } | ||||
public DataAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix, | public DataAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String prefix, | ||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | ||||
AccountAccessPolicy accessPolicy) { | AccountAccessPolicy accessPolicy) { | ||||
accountSet = new AccountSet(dataRootHash, cryptoSetting, prefix, exStorage, verStorage, readonly, accessPolicy); | |||||
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, prefix, exStorage, verStorage, readonly, accessPolicy); | |||||
} | } | ||||
@Override | @Override | ||||
public AccountHeader[] getHeaders(int fromIndex, int count) { | public AccountHeader[] getHeaders(int fromIndex, int count) { | ||||
return accountSet.getAccounts(fromIndex, count); | |||||
return accountSet.getHeaders(fromIndex, count); | |||||
} | } | ||||
public boolean isReadonly() { | public boolean isReadonly() { | ||||
@@ -46,7 +46,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||||
@Override | @Override | ||||
public long getTotal() { | public long getTotal() { | ||||
return accountSet.getTotalCount(); | |||||
return accountSet.getTotal(); | |||||
} | } | ||||
@Override | @Override | ||||
@@ -64,7 +64,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||||
public DataAccount register(Bytes address, PubKey pubKey, DigitalSignature addressSignature) { | public DataAccount register(Bytes address, PubKey pubKey, DigitalSignature addressSignature) { | ||||
// TODO: 未实现对地址签名的校验和记录; | // TODO: 未实现对地址签名的校验和记录; | ||||
BaseAccount accBase = accountSet.register(address, pubKey); | |||||
MerkleAccount accBase = accountSet.register(address, pubKey); | |||||
return new DataAccount(accBase); | return new DataAccount(accBase); | ||||
} | } | ||||
@@ -82,7 +82,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||||
*/ | */ | ||||
@Override | @Override | ||||
public DataAccount getAccount(Bytes address) { | public DataAccount getAccount(Bytes address) { | ||||
BaseAccount accBase = accountSet.getAccount(address); | |||||
MerkleAccount accBase = accountSet.getAccount(address); | |||||
if (accBase == null) { | if (accBase == null) { | ||||
return null; | return null; | ||||
} | } | ||||
@@ -91,7 +91,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||||
@Override | @Override | ||||
public DataAccount getAccount(Bytes address, long version) { | public DataAccount getAccount(Bytes address, long version) { | ||||
BaseAccount accBase = accountSet.getAccount(address, version); | |||||
MerkleAccount accBase = accountSet.getAccount(address, version); | |||||
return new DataAccount(accBase); | return new DataAccount(accBase); | ||||
} | } | ||||
@@ -20,7 +20,7 @@ import com.jd.blockchain.utils.Transactional; | |||||
* @author huanghaiquan | * @author huanghaiquan | ||||
* | * | ||||
*/ | */ | ||||
public class BaseAccount implements AccountHeader, MerkleProvable, Transactional { | |||||
public class MerkleAccount implements AccountHeader, MerkleProvable, Transactional { | |||||
private BlockchainIdentity bcid; | private BlockchainIdentity bcid; | ||||
@@ -38,7 +38,7 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional | |||||
* @param address | * @param address | ||||
* @param pubKey | * @param pubKey | ||||
*/ | */ | ||||
public BaseAccount(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, | |||||
public MerkleAccount(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, | |||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { | ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { | ||||
this(address, pubKey, null, cryptoSetting, keyPrefix, exStorage, verStorage, false); | this(address, pubKey, null, cryptoSetting, keyPrefix, exStorage, verStorage, false); | ||||
} | } | ||||
@@ -58,7 +58,7 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional | |||||
* @param verStorage | * @param verStorage | ||||
* @param accessPolicy | * @param accessPolicy | ||||
*/ | */ | ||||
public BaseAccount(BlockchainIdentity bcid, CryptoSetting cryptoSetting, String keyPrefix, | |||||
public MerkleAccount(BlockchainIdentity bcid, CryptoSetting cryptoSetting, String keyPrefix, | |||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { | ExPolicyKVStorage exStorage, VersioningKVStorage verStorage) { | ||||
this(bcid, null, cryptoSetting, keyPrefix, exStorage, verStorage, false); | this(bcid, null, cryptoSetting, keyPrefix, exStorage, verStorage, false); | ||||
} | } | ||||
@@ -78,13 +78,13 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional | |||||
* @param readonly | * @param readonly | ||||
* @param accessPolicy | * @param accessPolicy | ||||
*/ | */ | ||||
public BaseAccount(Bytes address, PubKey pubKey, HashDigest dataRootHash, CryptoSetting cryptoSetting, | |||||
public MerkleAccount(Bytes address, PubKey pubKey, HashDigest dataRootHash, CryptoSetting cryptoSetting, | |||||
String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { | String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { | ||||
this(new BlockchainIdentityData(address, pubKey), dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, | this(new BlockchainIdentityData(address, pubKey), dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, | ||||
readonly); | readonly); | ||||
} | } | ||||
public BaseAccount(BlockchainIdentity bcid, HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix, | |||||
public MerkleAccount(BlockchainIdentity bcid, HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix, | |||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { | ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly) { | ||||
this.bcid = bcid; | this.bcid = bcid; | ||||
this.dataset = new MerkleDataSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); | this.dataset = new MerkleDataSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); | ||||
@@ -169,7 +169,7 @@ public class BaseAccount implements AccountHeader, MerkleProvable, Transactional | |||||
* @param key | * @param key | ||||
* @return | * @return | ||||
*/ | */ | ||||
public long getKeyVersion(Bytes key) { | |||||
public long getVersion(Bytes key) { | |||||
return dataset.getVersion(key); | return dataset.getVersion(key); | ||||
} | } | ||||
@@ -13,14 +13,16 @@ import com.jd.blockchain.ledger.BytesValue; | |||||
import com.jd.blockchain.ledger.CryptoSetting; | import com.jd.blockchain.ledger.CryptoSetting; | ||||
import com.jd.blockchain.ledger.LedgerException; | import com.jd.blockchain.ledger.LedgerException; | ||||
import com.jd.blockchain.ledger.MerkleProof; | import com.jd.blockchain.ledger.MerkleProof; | ||||
import com.jd.blockchain.ledger.MerkleSnapshot; | |||||
import com.jd.blockchain.storage.service.ExPolicyKVStorage; | import com.jd.blockchain.storage.service.ExPolicyKVStorage; | ||||
import com.jd.blockchain.storage.service.VersioningKVStorage; | import com.jd.blockchain.storage.service.VersioningKVStorage; | ||||
import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
import com.jd.blockchain.utils.Transactional; | import com.jd.blockchain.utils.Transactional; | ||||
public class AccountSet implements Transactional, MerkleProvable { | |||||
public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery<MerkleAccount> { | |||||
static { | static { | ||||
DataContractRegistry.register(MerkleSnapshot.class); | |||||
DataContractRegistry.register(AccountHeader.class); | DataContractRegistry.register(AccountHeader.class); | ||||
} | } | ||||
@@ -34,7 +36,7 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
* | * | ||||
*/ | */ | ||||
// TODO:未考虑大数据量时,由于缺少过期策略,会导致内存溢出的问题; | // TODO:未考虑大数据量时,由于缺少过期策略,会导致内存溢出的问题; | ||||
private Map<Bytes, VersioningAccount> latestAccountsCache = new HashMap<>(); | |||||
private Map<Bytes, InnerVersioningAccount> latestAccountsCache = new HashMap<>(); | |||||
private ExPolicyKVStorage baseExStorage; | private ExPolicyKVStorage baseExStorage; | ||||
@@ -49,18 +51,19 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
public boolean isReadonly() { | public boolean isReadonly() { | ||||
return merkleDataset.isReadonly(); | return merkleDataset.isReadonly(); | ||||
} | } | ||||
void setReadonly() { | void setReadonly() { | ||||
merkleDataset.setReadonly(); | merkleDataset.setReadonly(); | ||||
} | } | ||||
public AccountSet(CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, | |||||
public MerkleAccountSet(CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, | |||||
VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { | VersioningKVStorage verStorage, AccountAccessPolicy accessPolicy) { | ||||
this(null, cryptoSetting, keyPrefix, exStorage, verStorage, false, accessPolicy); | this(null, cryptoSetting, keyPrefix, exStorage, verStorage, false, accessPolicy); | ||||
} | } | ||||
public AccountSet(HashDigest rootHash, CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage exStorage, | |||||
VersioningKVStorage verStorage, boolean readonly, AccountAccessPolicy accessPolicy) { | |||||
public MerkleAccountSet(HashDigest rootHash, CryptoSetting cryptoSetting, String keyPrefix, | |||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | |||||
AccountAccessPolicy accessPolicy) { | |||||
this.keyPrefix = keyPrefix; | this.keyPrefix = keyPrefix; | ||||
this.cryptoSetting = cryptoSetting; | this.cryptoSetting = cryptoSetting; | ||||
this.baseExStorage = exStorage; | this.baseExStorage = exStorage; | ||||
@@ -80,7 +83,7 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
return merkleDataset.getProof(key); | return merkleDataset.getProof(key); | ||||
} | } | ||||
public AccountHeader[] getAccounts(int fromIndex, int count) { | |||||
public AccountHeader[] getHeaders(int fromIndex, int count) { | |||||
byte[][] results = merkleDataset.getLatestValues(fromIndex, count); | byte[][] results = merkleDataset.getLatestValues(fromIndex, count); | ||||
AccountHeader[] accounts = new AccountHeader[results.length]; | AccountHeader[] accounts = new AccountHeader[results.length]; | ||||
@@ -110,17 +113,22 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
* | * | ||||
* @return | * @return | ||||
*/ | */ | ||||
public long getTotalCount() { | |||||
public long getTotal() { | |||||
return merkleDataset.getDataCount(); | return merkleDataset.getDataCount(); | ||||
} | } | ||||
@Override | |||||
public MerkleAccount getAccount(String address) { | |||||
return getAccount(Bytes.fromBase58(address)); | |||||
} | |||||
/** | /** | ||||
* 返回最新版本的 Account; | * 返回最新版本的 Account; | ||||
* | * | ||||
* @param address | * @param address | ||||
* @return | * @return | ||||
*/ | */ | ||||
public BaseAccount getAccount(Bytes address) { | |||||
public MerkleAccount getAccount(Bytes address) { | |||||
return this.getAccount(address, -1); | return this.getAccount(address, -1); | ||||
} | } | ||||
@@ -149,7 +157,7 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
* @return | * @return | ||||
*/ | */ | ||||
public long getVersion(Bytes address) { | public long getVersion(Bytes address) { | ||||
VersioningAccount acc = latestAccountsCache.get(address); | |||||
InnerVersioningAccount acc = latestAccountsCache.get(address); | |||||
if (acc != null) { | if (acc != null) { | ||||
// 已注册尚未提交,也返回 -1; | // 已注册尚未提交,也返回 -1; | ||||
return acc.version == -1 ? 0 : acc.version; | return acc.version == -1 ? 0 : acc.version; | ||||
@@ -163,15 +171,13 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
* | * | ||||
* 只有最新版本的账户才能可写的,其它都是只读; | * 只有最新版本的账户才能可写的,其它都是只读; | ||||
* | * | ||||
* @param address | |||||
* 账户地址; | |||||
* @param version | |||||
* 账户版本;如果指定为 -1,则返回最新版本; | |||||
* @param address 账户地址; | |||||
* @param version 账户版本;如果指定为 -1,则返回最新版本; | |||||
* @return | * @return | ||||
*/ | */ | ||||
public BaseAccount getAccount(Bytes address, long version) { | |||||
public MerkleAccount getAccount(Bytes address, long version) { | |||||
version = version < 0 ? -1 : version; | version = version < 0 ? -1 : version; | ||||
VersioningAccount acc = latestAccountsCache.get(address); | |||||
InnerVersioningAccount acc = latestAccountsCache.get(address); | |||||
if (acc != null && version == -1) { | if (acc != null && version == -1) { | ||||
return acc; | return acc; | ||||
} else if (acc != null && acc.version == version) { | } else if (acc != null && acc.version == version) { | ||||
@@ -233,14 +239,14 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
* @param pubKey 公钥; | * @param pubKey 公钥; | ||||
* @return 注册成功的账户对象; | * @return 注册成功的账户对象; | ||||
*/ | */ | ||||
public BaseAccount register(Bytes address, PubKey pubKey) { | |||||
public MerkleAccount register(Bytes address, PubKey pubKey) { | |||||
if (isReadonly()) { | if (isReadonly()) { | ||||
throw new IllegalArgumentException("This AccountSet is readonly!"); | throw new IllegalArgumentException("This AccountSet is readonly!"); | ||||
} | } | ||||
verifyAddressEncoding(address, pubKey); | verifyAddressEncoding(address, pubKey); | ||||
VersioningAccount cachedAcc = latestAccountsCache.get(address); | |||||
InnerVersioningAccount cachedAcc = latestAccountsCache.get(address); | |||||
if (cachedAcc != null) { | if (cachedAcc != null) { | ||||
if (cachedAcc.version < 0) { | if (cachedAcc.version < 0) { | ||||
// 同一个新账户已经注册,但尚未提交,所以重复注册不会引起任何变化; | // 同一个新账户已经注册,但尚未提交,所以重复注册不会引起任何变化; | ||||
@@ -267,7 +273,7 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
// accExStorage, accVerStorage); | // accExStorage, accVerStorage); | ||||
String prefix = keyPrefix + address; | String prefix = keyPrefix + address; | ||||
VersioningAccount acc = createInstance(address, pubKey, cryptoSetting, prefix, baseExStorage, baseVerStorage, | |||||
InnerVersioningAccount acc = createInstance(address, pubKey, cryptoSetting, prefix, baseExStorage, baseVerStorage, | |||||
-1); | -1); | ||||
latestAccountsCache.put(address, acc); | latestAccountsCache.put(address, acc); | ||||
updated = true; | updated = true; | ||||
@@ -282,15 +288,15 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
} | } | ||||
} | } | ||||
private VersioningAccount createInstance(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, | |||||
private InnerVersioningAccount createInstance(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, | |||||
String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, long version) { | String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, long version) { | ||||
return new VersioningAccount(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage, version); | |||||
return new InnerVersioningAccount(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage, version); | |||||
} | } | ||||
private VersioningAccount deserialize(byte[] bytes, CryptoSetting cryptoSetting, String keyPrefix, | |||||
private InnerVersioningAccount deserialize(byte[] bytes, CryptoSetting cryptoSetting, String keyPrefix, | |||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, long version) { | ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, long version) { | ||||
AccountHeader accInfo = BinaryProtocol.decode(bytes); | AccountHeader accInfo = BinaryProtocol.decode(bytes); | ||||
return new VersioningAccount(accInfo.getAddress(), accInfo.getPubKey(), accInfo.getRootHash(), cryptoSetting, | |||||
return new InnerVersioningAccount(accInfo.getAddress(), accInfo.getPubKey(), accInfo.getRootHash(), cryptoSetting, | |||||
keyPrefix, exStorage, verStorage, readonly, version); | keyPrefix, exStorage, verStorage, readonly, version); | ||||
} | } | ||||
@@ -309,7 +315,7 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
return; | return; | ||||
} | } | ||||
try { | try { | ||||
for (VersioningAccount acc : latestAccountsCache.values()) { | |||||
for (InnerVersioningAccount acc : latestAccountsCache.values()) { | |||||
// updated or new created; | // updated or new created; | ||||
if (acc.isUpdated() || acc.version < 0) { | if (acc.isUpdated() || acc.version < 0) { | ||||
// 提交更改,更新哈希; | // 提交更改,更新哈希; | ||||
@@ -337,7 +343,7 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
Bytes[] addresses = new Bytes[latestAccountsCache.size()]; | Bytes[] addresses = new Bytes[latestAccountsCache.size()]; | ||||
latestAccountsCache.keySet().toArray(addresses); | latestAccountsCache.keySet().toArray(addresses); | ||||
for (Bytes address : addresses) { | for (Bytes address : addresses) { | ||||
VersioningAccount acc = latestAccountsCache.remove(address); | |||||
InnerVersioningAccount acc = latestAccountsCache.remove(address); | |||||
// cancel; | // cancel; | ||||
if (acc.isUpdated()) { | if (acc.isUpdated()) { | ||||
acc.cancel(); | acc.cancel(); | ||||
@@ -375,7 +381,7 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
} | } | ||||
private class VersioningAccount extends BaseAccount { | |||||
private class InnerVersioningAccount extends MerkleAccount { | |||||
// private final BaseAccount account; | // private final BaseAccount account; | ||||
@@ -386,14 +392,14 @@ public class AccountSet implements Transactional, MerkleProvable { | |||||
// this.version = version; | // this.version = version; | ||||
// } | // } | ||||
public VersioningAccount(Bytes address, PubKey pubKey, HashDigest rootHash, CryptoSetting cryptoSetting, | |||||
public InnerVersioningAccount(Bytes address, PubKey pubKey, HashDigest rootHash, CryptoSetting cryptoSetting, | |||||
String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | String keyPrefix, ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | ||||
long version) { | long version) { | ||||
super(address, pubKey, rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); | super(address, pubKey, rootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly); | ||||
this.version = version; | this.version = version; | ||||
} | } | ||||
public VersioningAccount(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, | |||||
public InnerVersioningAccount(Bytes address, PubKey pubKey, CryptoSetting cryptoSetting, String keyPrefix, | |||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, long version) { | ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, long version) { | ||||
super(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage); | super(address, pubKey, cryptoSetting, keyPrefix, exStorage, verStorage); | ||||
this.version = version; | this.version = version; |
@@ -1,12 +1,10 @@ | |||||
package com.jd.blockchain.ledger.core; | package com.jd.blockchain.ledger.core; | ||||
import com.jd.blockchain.crypto.HashDigest; | |||||
import com.jd.blockchain.ledger.MerkleProof; | import com.jd.blockchain.ledger.MerkleProof; | ||||
import com.jd.blockchain.ledger.MerkleSnapshot; | |||||
import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
public interface MerkleProvable { | |||||
HashDigest getRootHash(); | |||||
public interface MerkleProvable extends MerkleSnapshot { | |||||
/** | /** | ||||
* Get the merkle proof of the latest version of specified key; <br> | * Get the merkle proof of the latest version of specified key; <br> | ||||
@@ -19,7 +19,7 @@ public class UserAccount implements UserInfo { | |||||
private static final Bytes DATA_PUB_KEY = Bytes.fromString("DATA-PUBKEY"); | private static final Bytes DATA_PUB_KEY = Bytes.fromString("DATA-PUBKEY"); | ||||
private BaseAccount baseAccount; | |||||
private MerkleAccount baseAccount; | |||||
@Override | @Override | ||||
public Bytes getAddress() { | public Bytes getAddress() { | ||||
@@ -36,7 +36,7 @@ public class UserAccount implements UserInfo { | |||||
return baseAccount.getRootHash(); | return baseAccount.getRootHash(); | ||||
} | } | ||||
public UserAccount(BaseAccount baseAccount) { | |||||
public UserAccount(MerkleAccount baseAccount) { | |||||
this.baseAccount = baseAccount; | this.baseAccount = baseAccount; | ||||
} | } | ||||
@@ -17,23 +17,23 @@ import com.jd.blockchain.utils.Transactional; | |||||
*/ | */ | ||||
public class UserAccountSet implements Transactional, UserAccountQuery { | public class UserAccountSet implements Transactional, UserAccountQuery { | ||||
private AccountSet accountSet; | |||||
private MerkleAccountSet accountSet; | |||||
public UserAccountSet(CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage simpleStorage, | public UserAccountSet(CryptoSetting cryptoSetting, String keyPrefix, ExPolicyKVStorage simpleStorage, | ||||
VersioningKVStorage versioningStorage, AccountAccessPolicy accessPolicy) { | VersioningKVStorage versioningStorage, AccountAccessPolicy accessPolicy) { | ||||
accountSet = new AccountSet(cryptoSetting, keyPrefix, simpleStorage, versioningStorage, accessPolicy); | |||||
accountSet = new MerkleAccountSet(cryptoSetting, keyPrefix, simpleStorage, versioningStorage, accessPolicy); | |||||
} | } | ||||
public UserAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix, | public UserAccountSet(HashDigest dataRootHash, CryptoSetting cryptoSetting, String keyPrefix, | ||||
ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | ExPolicyKVStorage exStorage, VersioningKVStorage verStorage, boolean readonly, | ||||
AccountAccessPolicy accessPolicy) { | AccountAccessPolicy accessPolicy) { | ||||
accountSet = new AccountSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly, | |||||
accountSet = new MerkleAccountSet(dataRootHash, cryptoSetting, keyPrefix, exStorage, verStorage, readonly, | |||||
accessPolicy); | accessPolicy); | ||||
} | } | ||||
@Override | @Override | ||||
public AccountHeader[] getHeaders(int fromIndex, int count) { | public AccountHeader[] getHeaders(int fromIndex, int count) { | ||||
return accountSet.getAccounts(fromIndex,count); | |||||
return accountSet.getHeaders(fromIndex,count); | |||||
} | } | ||||
/** | /** | ||||
@@ -43,7 +43,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||||
*/ | */ | ||||
@Override | @Override | ||||
public long getTotal() { | public long getTotal() { | ||||
return accountSet.getTotalCount(); | |||||
return accountSet.getTotal(); | |||||
} | } | ||||
public boolean isReadonly() { | public boolean isReadonly() { | ||||
@@ -71,7 +71,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||||
@Override | @Override | ||||
public UserAccount getAccount(Bytes address) { | public UserAccount getAccount(Bytes address) { | ||||
BaseAccount baseAccount = accountSet.getAccount(address); | |||||
MerkleAccount baseAccount = accountSet.getAccount(address); | |||||
return new UserAccount(baseAccount); | return new UserAccount(baseAccount); | ||||
} | } | ||||
@@ -82,7 +82,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||||
@Override | @Override | ||||
public UserAccount getAccount(Bytes address, long version) { | public UserAccount getAccount(Bytes address, long version) { | ||||
BaseAccount baseAccount = accountSet.getAccount(address, version); | |||||
MerkleAccount baseAccount = accountSet.getAccount(address, version); | |||||
return new UserAccount(baseAccount); | return new UserAccount(baseAccount); | ||||
} | } | ||||
@@ -100,7 +100,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||||
* @return 注册成功的用户对象; | * @return 注册成功的用户对象; | ||||
*/ | */ | ||||
public UserAccount register(Bytes address, PubKey pubKey) { | public UserAccount register(Bytes address, PubKey pubKey) { | ||||
BaseAccount baseAccount = accountSet.register(address, pubKey); | |||||
MerkleAccount baseAccount = accountSet.register(address, pubKey); | |||||
return new UserAccount(baseAccount); | return new UserAccount(baseAccount); | ||||
} | } | ||||
@@ -14,8 +14,8 @@ import com.jd.blockchain.crypto.service.classic.ClassicCryptoService; | |||||
import com.jd.blockchain.crypto.service.sm.SMCryptoService; | import com.jd.blockchain.crypto.service.sm.SMCryptoService; | ||||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | import com.jd.blockchain.ledger.BlockchainKeyGenerator; | ||||
import com.jd.blockchain.ledger.BlockchainKeypair; | import com.jd.blockchain.ledger.BlockchainKeypair; | ||||
import com.jd.blockchain.ledger.core.AccountSet; | |||||
import com.jd.blockchain.ledger.core.BaseAccount; | |||||
import com.jd.blockchain.ledger.core.MerkleAccountSet; | |||||
import com.jd.blockchain.ledger.core.MerkleAccount; | |||||
import com.jd.blockchain.ledger.core.CryptoConfig; | import com.jd.blockchain.ledger.core.CryptoConfig; | ||||
import com.jd.blockchain.ledger.core.OpeningAccessPolicy; | import com.jd.blockchain.ledger.core.OpeningAccessPolicy; | ||||
import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | ||||
@@ -43,12 +43,12 @@ public class AccountSetTest { | |||||
cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256); | cryptoConf.setHashAlgorithm(ClassicAlgorithm.SHA256); | ||||
String keyPrefix = ""; | String keyPrefix = ""; | ||||
AccountSet accset = new AccountSet(cryptoConf, keyPrefix, storage, storage, accessPolicy); | |||||
MerkleAccountSet accset = new MerkleAccountSet(cryptoConf, keyPrefix, storage, storage, accessPolicy); | |||||
BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | BlockchainKeypair userKey = BlockchainKeyGenerator.getInstance().generate(); | ||||
accset.register(userKey.getAddress(), userKey.getPubKey()); | accset.register(userKey.getAddress(), userKey.getPubKey()); | ||||
BaseAccount userAcc = accset.getAccount(userKey.getAddress()); | |||||
MerkleAccount userAcc = accset.getAccount(userKey.getAddress()); | |||||
assertNotNull(userAcc); | assertNotNull(userAcc); | ||||
assertTrue(accset.contains(userKey.getAddress())); | assertTrue(accset.contains(userKey.getAddress())); | ||||
@@ -56,8 +56,8 @@ public class AccountSetTest { | |||||
HashDigest rootHash = accset.getRootHash(); | HashDigest rootHash = accset.getRootHash(); | ||||
assertNotNull(rootHash); | assertNotNull(rootHash); | ||||
AccountSet reloadAccSet = new AccountSet(rootHash, cryptoConf, keyPrefix, storage, storage, true, accessPolicy); | |||||
BaseAccount reloadUserAcc = reloadAccSet.getAccount(userKey.getAddress()); | |||||
MerkleAccountSet reloadAccSet = new MerkleAccountSet(rootHash, cryptoConf, keyPrefix, storage, storage, true, accessPolicy); | |||||
MerkleAccount reloadUserAcc = reloadAccSet.getAccount(userKey.getAddress()); | |||||
assertNotNull(reloadUserAcc); | assertNotNull(reloadUserAcc); | ||||
assertTrue(reloadAccSet.contains(userKey.getAddress())); | assertTrue(reloadAccSet.contains(userKey.getAddress())); | ||||
@@ -13,7 +13,7 @@ import com.jd.blockchain.crypto.service.sm.SMCryptoService; | |||||
import com.jd.blockchain.ledger.BlockchainKeyGenerator; | import com.jd.blockchain.ledger.BlockchainKeyGenerator; | ||||
import com.jd.blockchain.ledger.BlockchainKeypair; | import com.jd.blockchain.ledger.BlockchainKeypair; | ||||
import com.jd.blockchain.ledger.BytesData; | import com.jd.blockchain.ledger.BytesData; | ||||
import com.jd.blockchain.ledger.core.BaseAccount; | |||||
import com.jd.blockchain.ledger.core.MerkleAccount; | |||||
import com.jd.blockchain.ledger.core.CryptoConfig; | import com.jd.blockchain.ledger.core.CryptoConfig; | ||||
import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | ||||
import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
@@ -48,7 +48,7 @@ public class BaseAccountTest { | |||||
BlockchainKeypair bck = BlockchainKeyGenerator.getInstance().generate(); | BlockchainKeypair bck = BlockchainKeyGenerator.getInstance().generate(); | ||||
// 新建账户; | // 新建账户; | ||||
BaseAccount baseAccount = new BaseAccount(bck.getIdentity(), cryptoConf, keyPrefix, testStorage, testStorage); | |||||
MerkleAccount baseAccount = new MerkleAccount(bck.getIdentity(), cryptoConf, keyPrefix, testStorage, testStorage); | |||||
assertFalse(baseAccount.isUpdated());// 空的账户; | assertFalse(baseAccount.isUpdated());// 空的账户; | ||||
assertFalse(baseAccount.isReadonly()); | assertFalse(baseAccount.isReadonly()); | ||||
@@ -15,7 +15,7 @@ import com.jd.blockchain.crypto.service.classic.ClassicAlgorithm; | |||||
import com.jd.blockchain.crypto.service.sm.SMAlgorithm; | import com.jd.blockchain.crypto.service.sm.SMAlgorithm; | ||||
import com.jd.blockchain.ledger.AccountHeader; | import com.jd.blockchain.ledger.AccountHeader; | ||||
import com.jd.blockchain.ledger.UserInfo; | import com.jd.blockchain.ledger.UserInfo; | ||||
import com.jd.blockchain.ledger.core.AccountSet; | |||||
import com.jd.blockchain.ledger.core.MerkleAccountSet; | |||||
import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
/** | /** | ||||
@@ -44,7 +44,7 @@ public class LedgerAccountTest { | |||||
String address = "xxxxxxxxxxxx"; | String address = "xxxxxxxxxxxx"; | ||||
PubKey pubKey = new PubKey(SMAlgorithm.SM2, rawDigestBytes); | PubKey pubKey = new PubKey(SMAlgorithm.SM2, rawDigestBytes); | ||||
HashDigest hashDigest = new HashDigest(ClassicAlgorithm.SHA256, rawDigestBytes); | HashDigest hashDigest = new HashDigest(ClassicAlgorithm.SHA256, rawDigestBytes); | ||||
AccountSet.AccountHeaderData accountHeaderData = new AccountSet.AccountHeaderData(Bytes.fromString(address), | |||||
MerkleAccountSet.AccountHeaderData accountHeaderData = new MerkleAccountSet.AccountHeaderData(Bytes.fromString(address), | |||||
pubKey, hashDigest); | pubKey, hashDigest); | ||||
// encode and decode | // encode and decode | ||||
@@ -4,20 +4,17 @@ import com.jd.blockchain.binaryproto.DataContract; | |||||
import com.jd.blockchain.binaryproto.DataField; | import com.jd.blockchain.binaryproto.DataField; | ||||
import com.jd.blockchain.binaryproto.PrimitiveType; | import com.jd.blockchain.binaryproto.PrimitiveType; | ||||
import com.jd.blockchain.consts.DataCodes; | import com.jd.blockchain.consts.DataCodes; | ||||
import com.jd.blockchain.crypto.HashDigest; | |||||
import com.jd.blockchain.crypto.PubKey; | import com.jd.blockchain.crypto.PubKey; | ||||
import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
@DataContract(code= DataCodes.ACCOUNT_HEADER) | @DataContract(code= DataCodes.ACCOUNT_HEADER) | ||||
public interface AccountHeader { | |||||
public interface AccountHeader extends MerkleSnapshot{ | |||||
@DataField(order=1, primitiveType = PrimitiveType.BYTES) | @DataField(order=1, primitiveType = PrimitiveType.BYTES) | ||||
Bytes getAddress(); | Bytes getAddress(); | ||||
@DataField(order=2, primitiveType = PrimitiveType.BYTES) | @DataField(order=2, primitiveType = PrimitiveType.BYTES) | ||||
PubKey getPubKey(); | PubKey getPubKey(); | ||||
@DataField(order=3, primitiveType = PrimitiveType.BYTES) | |||||
HashDigest getRootHash(); | |||||
} | } |
@@ -0,0 +1,15 @@ | |||||
package com.jd.blockchain.ledger; | |||||
import com.jd.blockchain.binaryproto.DataContract; | |||||
import com.jd.blockchain.binaryproto.DataField; | |||||
import com.jd.blockchain.binaryproto.PrimitiveType; | |||||
import com.jd.blockchain.consts.DataCodes; | |||||
import com.jd.blockchain.crypto.HashDigest; | |||||
@DataContract(code = DataCodes.MERKLE_SNAPSHOT) | |||||
public interface MerkleSnapshot { | |||||
@DataField(order = 0, primitiveType = PrimitiveType.BYTES) | |||||
HashDigest getRootHash(); | |||||
} |