| @@ -1,6 +1,7 @@ | |||||
| package com.jd.blockchain.ledger.core; | package com.jd.blockchain.ledger.core; | ||||
| import com.jd.blockchain.crypto.HashDigest; | import com.jd.blockchain.crypto.HashDigest; | ||||
| import com.jd.blockchain.ledger.Account; | |||||
| import com.jd.blockchain.ledger.BlockchainIdentity; | import com.jd.blockchain.ledger.BlockchainIdentity; | ||||
| import com.jd.blockchain.ledger.HashProof; | import com.jd.blockchain.ledger.HashProof; | ||||
| import com.jd.blockchain.ledger.MerkleSnapshot; | import com.jd.blockchain.ledger.MerkleSnapshot; | ||||
| @@ -8,11 +9,11 @@ import com.jd.blockchain.ledger.TypedValue; | |||||
| import com.jd.blockchain.utils.Bytes; | import com.jd.blockchain.utils.Bytes; | ||||
| import com.jd.blockchain.utils.Dataset; | import com.jd.blockchain.utils.Dataset; | ||||
| public class AccountDecorator implements LedgerAccount, HashProvable, MerkleSnapshot{ | |||||
| public class AccountDecorator implements Account, HashProvable, MerkleSnapshot{ | |||||
| private MerkleAccount mklAccount; | |||||
| private CompositeAccount mklAccount; | |||||
| public AccountDecorator(MerkleAccount mklAccount) { | |||||
| public AccountDecorator(CompositeAccount mklAccount) { | |||||
| this.mklAccount = mklAccount; | this.mklAccount = mklAccount; | ||||
| } | } | ||||
| @@ -0,0 +1,12 @@ | |||||
| package com.jd.blockchain.ledger.core; | |||||
| import com.jd.blockchain.ledger.Account; | |||||
| import com.jd.blockchain.ledger.MerkleSnapshot; | |||||
| import com.jd.blockchain.ledger.TypedValue; | |||||
| import com.jd.blockchain.utils.Dataset; | |||||
| public interface CompositeAccount extends Account, MerkleSnapshot, HashProvable{ | |||||
| Dataset<String, TypedValue> getHeaders(); | |||||
| } | |||||
| @@ -12,7 +12,7 @@ public class ContractAccount extends AccountDecorator implements ContractInfo { | |||||
| private static final String CHAIN_CODE_KEY = "CHAIN-CODE"; | private static final String CHAIN_CODE_KEY = "CHAIN-CODE"; | ||||
| public ContractAccount(MerkleAccount mklAccount) { | |||||
| public ContractAccount(CompositeAccount mklAccount) { | |||||
| super(mklAccount); | super(mklAccount); | ||||
| } | } | ||||
| @@ -67,7 +67,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||||
| @Override | @Override | ||||
| public ContractAccount getAccount(Bytes address) { | public ContractAccount getAccount(Bytes address) { | ||||
| MerkleAccount accBase = accountSet.getAccount(address); | |||||
| CompositeAccount accBase = accountSet.getAccount(address); | |||||
| return new ContractAccount(accBase); | return new ContractAccount(accBase); | ||||
| } | } | ||||
| @@ -78,7 +78,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||||
| @Override | @Override | ||||
| public ContractAccount getAccount(Bytes address, long version) { | public ContractAccount getAccount(Bytes address, long version) { | ||||
| MerkleAccount accBase = accountSet.getAccount(address, version); | |||||
| CompositeAccount accBase = accountSet.getAccount(address, version); | |||||
| return new ContractAccount(accBase); | return new ContractAccount(accBase); | ||||
| } | } | ||||
| @@ -93,7 +93,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: 校验和记录合约地址签名; | ||||
| MerkleAccount accBase = accountSet.register(address, pubKey); | |||||
| CompositeAccount 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; | ||||
| @@ -108,7 +108,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) { | ||||
| MerkleAccount accBase = accountSet.getAccount(address); | |||||
| CompositeAccount accBase = accountSet.getAccount(address); | |||||
| ContractAccount contractAcc = new ContractAccount(accBase); | ContractAccount contractAcc = new ContractAccount(accBase); | ||||
| return contractAcc.setChaincode(chaincode, version); | return contractAcc.setChaincode(chaincode, version); | ||||
| } | } | ||||
| @@ -1,16 +1,8 @@ | |||||
| package com.jd.blockchain.ledger.core; | package com.jd.blockchain.ledger.core; | ||||
| import com.jd.blockchain.binaryproto.BinaryProtocol; | |||||
| import com.jd.blockchain.ledger.BytesValue; | |||||
| import com.jd.blockchain.ledger.TypedKVEntry; | |||||
| import com.jd.blockchain.ledger.TypedKVData; | |||||
| import com.jd.blockchain.ledger.MerkleProof; | |||||
| import com.jd.blockchain.ledger.TypedValue; | |||||
| import com.jd.blockchain.utils.Bytes; | |||||
| public class DataAccount extends AccountDecorator { | public class DataAccount extends AccountDecorator { | ||||
| public DataAccount(MerkleAccount mklAccount) { | |||||
| public DataAccount(CompositeAccount mklAccount) { | |||||
| super(mklAccount); | super(mklAccount); | ||||
| } | } | ||||
| @@ -65,7 +65,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: 未实现对地址签名的校验和记录; | ||||
| MerkleAccount accBase = accountSet.register(address, pubKey); | |||||
| CompositeAccount accBase = accountSet.register(address, pubKey); | |||||
| return new DataAccount(accBase); | return new DataAccount(accBase); | ||||
| } | } | ||||
| @@ -83,7 +83,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||||
| */ | */ | ||||
| @Override | @Override | ||||
| public DataAccount getAccount(Bytes address) { | public DataAccount getAccount(Bytes address) { | ||||
| MerkleAccount accBase = accountSet.getAccount(address); | |||||
| CompositeAccount accBase = accountSet.getAccount(address); | |||||
| if (accBase == null) { | if (accBase == null) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -92,7 +92,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||||
| @Override | @Override | ||||
| public DataAccount getAccount(Bytes address, long version) { | public DataAccount getAccount(Bytes address, long version) { | ||||
| MerkleAccount accBase = accountSet.getAccount(address, version); | |||||
| CompositeAccount accBase = accountSet.getAccount(address, version); | |||||
| return new DataAccount(accBase); | return new DataAccount(accBase); | ||||
| } | } | ||||
| @@ -1,13 +0,0 @@ | |||||
| package com.jd.blockchain.ledger.core; | |||||
| import com.jd.blockchain.ledger.BlockchainIdentity; | |||||
| import com.jd.blockchain.ledger.TypedValue; | |||||
| import com.jd.blockchain.utils.Dataset; | |||||
| public interface LedgerAccount { | |||||
| BlockchainIdentity getID(); | |||||
| Dataset<String, TypedValue> getDataset(); | |||||
| } | |||||
| @@ -26,7 +26,7 @@ import com.jd.blockchain.utils.Transactional; | |||||
| * @author huanghaiquan | * @author huanghaiquan | ||||
| * | * | ||||
| */ | */ | ||||
| public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapshot, Transactional { | |||||
| public class MerkleAccount implements CompositeAccount, HashProvable, MerkleSnapshot, Transactional { | |||||
| private static final Bytes HEADER_PREFIX = Bytes.fromString("HD/"); | private static final Bytes HEADER_PREFIX = Bytes.fromString("HD/"); | ||||
| private static final Bytes DATA_PREFIX = Bytes.fromString("DT/"); | private static final Bytes DATA_PREFIX = Bytes.fromString("DT/"); | ||||
| @@ -179,7 +179,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho | |||||
| return accountID; | return accountID; | ||||
| } | } | ||||
| protected Dataset<String, TypedValue> getHeaders() { | |||||
| public Dataset<String, TypedValue> getHeaders() { | |||||
| return typedHeader; | return typedHeader; | ||||
| } | } | ||||
| @@ -20,7 +20,7 @@ import com.jd.blockchain.utils.Bytes; | |||||
| import com.jd.blockchain.utils.DataEntry; | import com.jd.blockchain.utils.DataEntry; | ||||
| import com.jd.blockchain.utils.Transactional; | import com.jd.blockchain.utils.Transactional; | ||||
| public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery<MerkleAccount> { | |||||
| public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery<CompositeAccount> { | |||||
| static { | static { | ||||
| DataContractRegistry.register(MerkleSnapshot.class); | DataContractRegistry.register(MerkleSnapshot.class); | ||||
| @@ -111,7 +111,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||||
| } | } | ||||
| @Override | @Override | ||||
| public MerkleAccount getAccount(String address) { | |||||
| public CompositeAccount getAccount(String address) { | |||||
| return getAccount(Bytes.fromBase58(address)); | return getAccount(Bytes.fromBase58(address)); | ||||
| } | } | ||||
| @@ -122,7 +122,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||||
| * @return | * @return | ||||
| */ | */ | ||||
| @Override | @Override | ||||
| public MerkleAccount getAccount(Bytes address) { | |||||
| public CompositeAccount getAccount(Bytes address) { | |||||
| return this.getAccount(address, -1); | return this.getAccount(address, -1); | ||||
| } | } | ||||
| @@ -174,7 +174,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||||
| * @param version 账户版本;如果指定为 -1,则返回最新版本; | * @param version 账户版本;如果指定为 -1,则返回最新版本; | ||||
| * @return | * @return | ||||
| */ | */ | ||||
| public MerkleAccount getAccount(Bytes address, long version) { | |||||
| public CompositeAccount getAccount(Bytes address, long version) { | |||||
| version = version < 0 ? -1 : version; | version = version < 0 ? -1 : version; | ||||
| InnerMerkleAccount acc = latestAccountsCache.get(address); | InnerMerkleAccount acc = latestAccountsCache.get(address); | ||||
| if (acc != null && version == -1) { | if (acc != null && version == -1) { | ||||
| @@ -206,9 +206,10 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||||
| // Now, be sure that "acc == null", so get account from storage; | // Now, be sure that "acc == null", so get account from storage; | ||||
| // Set readonly for the old version account; | // Set readonly for the old version account; | ||||
| boolean readonly = (version > -1 && version < latestVersion) || isReadonly(); | boolean readonly = (version > -1 && version < latestVersion) || isReadonly(); | ||||
| long qVersion = version == -1 ? latestVersion : version; | |||||
| // load account from storage; | // load account from storage; | ||||
| acc = loadAccount(address, readonly, version); | |||||
| acc = loadAccount(address, readonly, qVersion); | |||||
| if (acc == null) { | if (acc == null) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -220,7 +221,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||||
| return acc; | return acc; | ||||
| } | } | ||||
| public MerkleAccount register(Bytes address, PubKey pubKey) { | |||||
| public CompositeAccount register(Bytes address, PubKey pubKey) { | |||||
| return register(new BlockchainIdentityData(address, pubKey)); | return register(new BlockchainIdentityData(address, pubKey)); | ||||
| } | } | ||||
| @@ -235,7 +236,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||||
| * @param pubKey 公钥; | * @param pubKey 公钥; | ||||
| * @return 注册成功的账户对象; | * @return 注册成功的账户对象; | ||||
| */ | */ | ||||
| public MerkleAccount register(BlockchainIdentity accountId) { | |||||
| public CompositeAccount register(BlockchainIdentity accountId) { | |||||
| if (isReadonly()) { | if (isReadonly()) { | ||||
| throw new IllegalArgumentException("This AccountSet is readonly!"); | throw new IllegalArgumentException("This AccountSet is readonly!"); | ||||
| } | } | ||||
| @@ -281,6 +282,14 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||||
| return new InnerMerkleAccount(header, cryptoSetting, keyPrefix, baseExStorage, baseVerStorage); | return new InnerMerkleAccount(header, cryptoSetting, keyPrefix, baseExStorage, baseVerStorage); | ||||
| } | } | ||||
| /** | |||||
| * 加载指定版本的账户; | |||||
| * | |||||
| * @param address 账户地址; | |||||
| * @param readonly 是否只读; | |||||
| * @param version 账户的版本;大于等于 0 ; | |||||
| * @return | |||||
| */ | |||||
| private InnerMerkleAccount loadAccount(Bytes address, boolean readonly, long version) { | private InnerMerkleAccount loadAccount(Bytes address, boolean readonly, long version) { | ||||
| byte[] rootHashBytes = merkleDataset.getValue(address, version); | byte[] rootHashBytes = merkleDataset.getValue(address, version); | ||||
| if (rootHashBytes == null) { | if (rootHashBytes == null) { | ||||
| @@ -4,13 +4,11 @@ import java.util.Map; | |||||
| import com.jd.blockchain.crypto.HashDigest; | import com.jd.blockchain.crypto.HashDigest; | ||||
| import com.jd.blockchain.ledger.CryptoSetting; | import com.jd.blockchain.ledger.CryptoSetting; | ||||
| import com.jd.blockchain.ledger.MerkleProof; | |||||
| import com.jd.blockchain.ledger.MerkleSnapshot; | 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; | ||||
| import com.jd.blockchain.utils.Dataset; | |||||
| public class MerkleDataCluster implements Transactional, MerkleSnapshot { | public class MerkleDataCluster implements Transactional, MerkleSnapshot { | ||||
| @@ -1,12 +1,5 @@ | |||||
| package com.jd.blockchain.ledger.core; | package com.jd.blockchain.ledger.core; | ||||
| import java.util.Set; | |||||
| import com.jd.blockchain.ledger.BlockchainIdentity; | |||||
| import com.jd.blockchain.ledger.LedgerPermission; | |||||
| import com.jd.blockchain.ledger.LedgerSecurityException; | |||||
| import com.jd.blockchain.ledger.TransactionPermission; | |||||
| public class SecurityContext { | public class SecurityContext { | ||||
| private static ThreadLocal<SecurityPolicy> policyHolder = new ThreadLocal<SecurityPolicy>(); | private static ThreadLocal<SecurityPolicy> policyHolder = new ThreadLocal<SecurityPolicy>(); | ||||
| @@ -19,8 +19,8 @@ public class UserAccount extends AccountDecorator implements UserInfo { // imple | |||||
| private static final String DATA_PUB_KEY = "DATA-PUBKEY"; | private static final String DATA_PUB_KEY = "DATA-PUBKEY"; | ||||
| public UserAccount(MerkleAccount mklAccount) { | |||||
| super(mklAccount); | |||||
| public UserAccount(CompositeAccount baseAccount) { | |||||
| super(baseAccount); | |||||
| } | } | ||||
| private PubKey dataPubKey; | private PubKey dataPubKey; | ||||
| @@ -72,7 +72,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||||
| @Override | @Override | ||||
| public UserAccount getAccount(Bytes address) { | public UserAccount getAccount(Bytes address) { | ||||
| MerkleAccount baseAccount = accountSet.getAccount(address); | |||||
| CompositeAccount baseAccount = accountSet.getAccount(address); | |||||
| return new UserAccount(baseAccount); | return new UserAccount(baseAccount); | ||||
| } | } | ||||
| @@ -83,7 +83,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||||
| @Override | @Override | ||||
| public UserAccount getAccount(Bytes address, long version) { | public UserAccount getAccount(Bytes address, long version) { | ||||
| MerkleAccount baseAccount = accountSet.getAccount(address, version); | |||||
| CompositeAccount baseAccount = accountSet.getAccount(address, version); | |||||
| return new UserAccount(baseAccount); | return new UserAccount(baseAccount); | ||||
| } | } | ||||
| @@ -99,7 +99,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||||
| * @return 注册成功的用户对象; | * @return 注册成功的用户对象; | ||||
| */ | */ | ||||
| public UserAccount register(Bytes address, PubKey pubKey) { | public UserAccount register(Bytes address, PubKey pubKey) { | ||||
| MerkleAccount baseAccount = accountSet.register(address, pubKey); | |||||
| CompositeAccount 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.CompositeAccount; | |||||
| import com.jd.blockchain.ledger.core.CryptoConfig; | import com.jd.blockchain.ledger.core.CryptoConfig; | ||||
| import com.jd.blockchain.ledger.core.MerkleAccount; | |||||
| import com.jd.blockchain.ledger.core.MerkleAccountSet; | import com.jd.blockchain.ledger.core.MerkleAccountSet; | ||||
| 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; | ||||
| @@ -50,7 +50,7 @@ public class AccountSetTest { | |||||
| accset.register(userKey.getAddress(), userKey.getPubKey()); | accset.register(userKey.getAddress(), userKey.getPubKey()); | ||||
| //尚未提交之前,可以检索到账户的存在,但版本仍然标记为 -1; | //尚未提交之前,可以检索到账户的存在,但版本仍然标记为 -1; | ||||
| MerkleAccount userAcc = accset.getAccount(userKey.getAddress()); | |||||
| CompositeAccount userAcc = accset.getAccount(userKey.getAddress()); | |||||
| assertNotNull(userAcc); | assertNotNull(userAcc); | ||||
| assertTrue(accset.contains(userKey.getAddress())); | assertTrue(accset.contains(userKey.getAddress())); | ||||
| @@ -59,12 +59,12 @@ public class AccountSetTest { | |||||
| assertNotNull(rootHash); | assertNotNull(rootHash); | ||||
| MerkleAccountSet reloadAccSet = new MerkleAccountSet(rootHash, cryptoConf, Bytes.fromString(keyPrefix), storage, storage, true, accessPolicy); | MerkleAccountSet reloadAccSet = new MerkleAccountSet(rootHash, cryptoConf, Bytes.fromString(keyPrefix), storage, storage, true, accessPolicy); | ||||
| MerkleAccount reloadUserAcc = reloadAccSet.getAccount(userKey.getAddress()); | |||||
| CompositeAccount reloadUserAcc = reloadAccSet.getAccount(userKey.getAddress()); | |||||
| assertNotNull(reloadUserAcc); | assertNotNull(reloadUserAcc); | ||||
| assertTrue(reloadAccSet.contains(userKey.getAddress())); | assertTrue(reloadAccSet.contains(userKey.getAddress())); | ||||
| assertEquals(userAcc.getAddress(), reloadUserAcc.getAddress()); | |||||
| assertEquals(userAcc.getPubKey(), reloadUserAcc.getPubKey()); | |||||
| assertEquals(userAcc.getID().getAddress(), reloadUserAcc.getID().getAddress()); | |||||
| assertEquals(userAcc.getID().getPubKey(), reloadUserAcc.getID().getPubKey()); | |||||
| } | } | ||||
| } | } | ||||
| @@ -44,12 +44,18 @@ public class LedgerTestUtils { | |||||
| partiKeys[1] = BlockchainKeyGenerator.getInstance().generate(); | partiKeys[1] = BlockchainKeyGenerator.getInstance().generate(); | ||||
| return createLedgerInitSetting(partiKeys); | return createLedgerInitSetting(partiKeys); | ||||
| } | } | ||||
| public static LedgerInitSetting createLedgerInitSetting(BlockchainKeypair[] partiKeys) { | |||||
| public static CryptoProvider[] getContextProviders() { | |||||
| CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | ||||
| for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | ||||
| supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | ||||
| } | } | ||||
| return supportedProviders; | |||||
| } | |||||
| public static LedgerInitSetting createLedgerInitSetting(BlockchainKeypair[] partiKeys) { | |||||
| CryptoProvider[] supportedProviders =getContextProviders(); | |||||
| CryptoConfig defCryptoSetting = new CryptoConfig(); | CryptoConfig defCryptoSetting = new CryptoConfig(); | ||||
| defCryptoSetting.setSupportedProviders(supportedProviders); | defCryptoSetting.setSupportedProviders(supportedProviders); | ||||
| @@ -0,0 +1,58 @@ | |||||
| package test.com.jd.blockchain.ledger.core; | |||||
| import static org.junit.Assert.assertEquals; | |||||
| import static org.junit.Assert.assertNotNull; | |||||
| import org.junit.Test; | |||||
| import com.jd.blockchain.crypto.Crypto; | |||||
| import com.jd.blockchain.ledger.BlockchainKeyGenerator; | |||||
| import com.jd.blockchain.ledger.BlockchainKeypair; | |||||
| import com.jd.blockchain.ledger.TypedValue; | |||||
| import com.jd.blockchain.ledger.core.CompositeAccount; | |||||
| import com.jd.blockchain.ledger.core.CryptoConfig; | |||||
| import com.jd.blockchain.ledger.core.MerkleAccountSet; | |||||
| import com.jd.blockchain.ledger.core.OpeningAccessPolicy; | |||||
| import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | |||||
| import com.jd.blockchain.utils.Bytes; | |||||
| public class MerkleAccountSetTest { | |||||
| @Test | |||||
| public void testRegister() { | |||||
| final OpeningAccessPolicy POLICY = new OpeningAccessPolicy(); | |||||
| final MemoryKVStorage STORAGE = new MemoryKVStorage(); | |||||
| Bytes KEY_PREFIX = Bytes.fromString("/ACCOUNT"); | |||||
| CryptoConfig cryptoConfig = new CryptoConfig(); | |||||
| cryptoConfig.setSupportedProviders(LedgerTestUtils.getContextProviders()); | |||||
| cryptoConfig.setAutoVerifyHash(true); | |||||
| cryptoConfig.setHashAlgorithm(Crypto.getAlgorithm("SHA256")); | |||||
| MerkleAccountSet accountset = new MerkleAccountSet(cryptoConfig, KEY_PREFIX, STORAGE, STORAGE, POLICY); | |||||
| BlockchainKeypair key1 = BlockchainKeyGenerator.getInstance().generate(); | |||||
| accountset.register(key1.getIdentity()); | |||||
| accountset.commit(); | |||||
| CompositeAccount acc1 = accountset.getAccount(key1.getAddress()); | |||||
| assertNotNull(acc1); | |||||
| assertEquals(0, accountset.getVersion(key1.getAddress())); | |||||
| acc1.getDataset().setValue("K1", TypedValue.fromText("V0"), -1); | |||||
| TypedValue v1 = acc1.getDataset().getValue("K1"); | |||||
| assertNotNull(v1); | |||||
| assertEquals(0, acc1.getDataset().getVersion("K1")); | |||||
| accountset.commit(); | |||||
| v1 = acc1.getDataset().getValue("K1"); | |||||
| assertNotNull(v1); | |||||
| assertEquals(0, acc1.getDataset().getVersion("K1")); | |||||
| } | |||||
| } | |||||
| @@ -340,6 +340,7 @@ public class TransactionBatchProcessorTest { | |||||
| 0); | 0); | ||||
| BytesValue v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K3", | BytesValue v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K3", | ||||
| 0); | 0); | ||||
| assertNotNull(v1_0); | assertNotNull(v1_0); | ||||
| assertNotNull(v1_1); | assertNotNull(v1_1); | ||||
| @@ -0,0 +1,11 @@ | |||||
| package com.jd.blockchain.ledger; | |||||
| import com.jd.blockchain.utils.Dataset; | |||||
| public interface Account { | |||||
| BlockchainIdentity getID(); | |||||
| Dataset<String, TypedValue> getDataset(); | |||||
| } | |||||