@@ -1,6 +1,7 @@ | |||
package com.jd.blockchain.ledger.core; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.Account; | |||
import com.jd.blockchain.ledger.BlockchainIdentity; | |||
import com.jd.blockchain.ledger.HashProof; | |||
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.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; | |||
} | |||
@@ -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"; | |||
public ContractAccount(MerkleAccount mklAccount) { | |||
public ContractAccount(CompositeAccount mklAccount) { | |||
super(mklAccount); | |||
} | |||
@@ -67,7 +67,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||
@Override | |||
public ContractAccount getAccount(Bytes address) { | |||
MerkleAccount accBase = accountSet.getAccount(address); | |||
CompositeAccount accBase = accountSet.getAccount(address); | |||
return new ContractAccount(accBase); | |||
} | |||
@@ -78,7 +78,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||
@Override | |||
public ContractAccount getAccount(Bytes address, long version) { | |||
MerkleAccount accBase = accountSet.getAccount(address, version); | |||
CompositeAccount accBase = accountSet.getAccount(address, version); | |||
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) { | |||
// TODO: 校验和记录合约地址签名; | |||
MerkleAccount accBase = accountSet.register(address, pubKey); | |||
CompositeAccount accBase = accountSet.register(address, pubKey); | |||
ContractAccount contractAcc = new ContractAccount(accBase); | |||
contractAcc.setChaincode(chaincode, -1); | |||
return contractAcc; | |||
@@ -108,7 +108,7 @@ public class ContractAccountSet implements Transactional, ContractAccountQuery { | |||
* @return 返回链码的新版本号; | |||
*/ | |||
public long update(Bytes address, byte[] chaincode, long version) { | |||
MerkleAccount accBase = accountSet.getAccount(address); | |||
CompositeAccount accBase = accountSet.getAccount(address); | |||
ContractAccount contractAcc = new ContractAccount(accBase); | |||
return contractAcc.setChaincode(chaincode, version); | |||
} | |||
@@ -1,16 +1,8 @@ | |||
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 DataAccount(MerkleAccount mklAccount) { | |||
public DataAccount(CompositeAccount mklAccount) { | |||
super(mklAccount); | |||
} | |||
@@ -65,7 +65,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||
public DataAccount register(Bytes address, PubKey pubKey, DigitalSignature addressSignature) { | |||
// TODO: 未实现对地址签名的校验和记录; | |||
MerkleAccount accBase = accountSet.register(address, pubKey); | |||
CompositeAccount accBase = accountSet.register(address, pubKey); | |||
return new DataAccount(accBase); | |||
} | |||
@@ -83,7 +83,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||
*/ | |||
@Override | |||
public DataAccount getAccount(Bytes address) { | |||
MerkleAccount accBase = accountSet.getAccount(address); | |||
CompositeAccount accBase = accountSet.getAccount(address); | |||
if (accBase == null) { | |||
return null; | |||
} | |||
@@ -92,7 +92,7 @@ public class DataAccountSet implements Transactional, DataAccountQuery { | |||
@Override | |||
public DataAccount getAccount(Bytes address, long version) { | |||
MerkleAccount accBase = accountSet.getAccount(address, version); | |||
CompositeAccount accBase = accountSet.getAccount(address, version); | |||
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 | |||
* | |||
*/ | |||
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 DATA_PREFIX = Bytes.fromString("DT/"); | |||
@@ -179,7 +179,7 @@ public class MerkleAccount implements LedgerAccount, HashProvable, MerkleSnapsho | |||
return accountID; | |||
} | |||
protected Dataset<String, TypedValue> getHeaders() { | |||
public Dataset<String, TypedValue> getHeaders() { | |||
return typedHeader; | |||
} | |||
@@ -20,7 +20,7 @@ import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.DataEntry; | |||
import com.jd.blockchain.utils.Transactional; | |||
public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery<MerkleAccount> { | |||
public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQuery<CompositeAccount> { | |||
static { | |||
DataContractRegistry.register(MerkleSnapshot.class); | |||
@@ -111,7 +111,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||
} | |||
@Override | |||
public MerkleAccount getAccount(String address) { | |||
public CompositeAccount getAccount(String address) { | |||
return getAccount(Bytes.fromBase58(address)); | |||
} | |||
@@ -122,7 +122,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||
* @return | |||
*/ | |||
@Override | |||
public MerkleAccount getAccount(Bytes address) { | |||
public CompositeAccount getAccount(Bytes address) { | |||
return this.getAccount(address, -1); | |||
} | |||
@@ -174,7 +174,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||
* @param version 账户版本;如果指定为 -1,则返回最新版本; | |||
* @return | |||
*/ | |||
public MerkleAccount getAccount(Bytes address, long version) { | |||
public CompositeAccount getAccount(Bytes address, long version) { | |||
version = version < 0 ? -1 : version; | |||
InnerMerkleAccount acc = latestAccountsCache.get(address); | |||
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; | |||
// Set readonly for the old version account; | |||
boolean readonly = (version > -1 && version < latestVersion) || isReadonly(); | |||
long qVersion = version == -1 ? latestVersion : version; | |||
// load account from storage; | |||
acc = loadAccount(address, readonly, version); | |||
acc = loadAccount(address, readonly, qVersion); | |||
if (acc == null) { | |||
return null; | |||
} | |||
@@ -220,7 +221,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||
return acc; | |||
} | |||
public MerkleAccount register(Bytes address, PubKey pubKey) { | |||
public CompositeAccount register(Bytes address, PubKey pubKey) { | |||
return register(new BlockchainIdentityData(address, pubKey)); | |||
} | |||
@@ -235,7 +236,7 @@ public class MerkleAccountSet implements Transactional, MerkleProvable, AccountQ | |||
* @param pubKey 公钥; | |||
* @return 注册成功的账户对象; | |||
*/ | |||
public MerkleAccount register(BlockchainIdentity accountId) { | |||
public CompositeAccount register(BlockchainIdentity accountId) { | |||
if (isReadonly()) { | |||
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); | |||
} | |||
/** | |||
* 加载指定版本的账户; | |||
* | |||
* @param address 账户地址; | |||
* @param readonly 是否只读; | |||
* @param version 账户的版本;大于等于 0 ; | |||
* @return | |||
*/ | |||
private InnerMerkleAccount loadAccount(Bytes address, boolean readonly, long version) { | |||
byte[] rootHashBytes = merkleDataset.getValue(address, version); | |||
if (rootHashBytes == null) { | |||
@@ -4,13 +4,11 @@ import java.util.Map; | |||
import com.jd.blockchain.crypto.HashDigest; | |||
import com.jd.blockchain.ledger.CryptoSetting; | |||
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.VersioningKVStorage; | |||
import com.jd.blockchain.utils.Bytes; | |||
import com.jd.blockchain.utils.Transactional; | |||
import com.jd.blockchain.utils.Dataset; | |||
public class MerkleDataCluster implements Transactional, MerkleSnapshot { | |||
@@ -1,12 +1,5 @@ | |||
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 { | |||
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"; | |||
public UserAccount(MerkleAccount mklAccount) { | |||
super(mklAccount); | |||
public UserAccount(CompositeAccount baseAccount) { | |||
super(baseAccount); | |||
} | |||
private PubKey dataPubKey; | |||
@@ -72,7 +72,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||
@Override | |||
public UserAccount getAccount(Bytes address) { | |||
MerkleAccount baseAccount = accountSet.getAccount(address); | |||
CompositeAccount baseAccount = accountSet.getAccount(address); | |||
return new UserAccount(baseAccount); | |||
} | |||
@@ -83,7 +83,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||
@Override | |||
public UserAccount getAccount(Bytes address, long version) { | |||
MerkleAccount baseAccount = accountSet.getAccount(address, version); | |||
CompositeAccount baseAccount = accountSet.getAccount(address, version); | |||
return new UserAccount(baseAccount); | |||
} | |||
@@ -99,7 +99,7 @@ public class UserAccountSet implements Transactional, UserAccountQuery { | |||
* @return 注册成功的用户对象; | |||
*/ | |||
public UserAccount register(Bytes address, PubKey pubKey) { | |||
MerkleAccount baseAccount = accountSet.register(address, pubKey); | |||
CompositeAccount baseAccount = accountSet.register(address, pubKey); | |||
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.ledger.BlockchainKeyGenerator; | |||
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.MerkleAccount; | |||
import com.jd.blockchain.ledger.core.MerkleAccountSet; | |||
import com.jd.blockchain.ledger.core.OpeningAccessPolicy; | |||
import com.jd.blockchain.storage.service.utils.MemoryKVStorage; | |||
@@ -50,7 +50,7 @@ public class AccountSetTest { | |||
accset.register(userKey.getAddress(), userKey.getPubKey()); | |||
//尚未提交之前,可以检索到账户的存在,但版本仍然标记为 -1; | |||
MerkleAccount userAcc = accset.getAccount(userKey.getAddress()); | |||
CompositeAccount userAcc = accset.getAccount(userKey.getAddress()); | |||
assertNotNull(userAcc); | |||
assertTrue(accset.contains(userKey.getAddress())); | |||
@@ -59,12 +59,12 @@ public class AccountSetTest { | |||
assertNotNull(rootHash); | |||
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); | |||
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(); | |||
return createLedgerInitSetting(partiKeys); | |||
} | |||
public static LedgerInitSetting createLedgerInitSetting(BlockchainKeypair[] partiKeys) { | |||
public static CryptoProvider[] getContextProviders() { | |||
CryptoProvider[] supportedProviders = new CryptoProvider[SUPPORTED_PROVIDERS.length]; | |||
for (int i = 0; i < SUPPORTED_PROVIDERS.length; i++) { | |||
supportedProviders[i] = Crypto.getProvider(SUPPORTED_PROVIDERS[i]); | |||
} | |||
return supportedProviders; | |||
} | |||
public static LedgerInitSetting createLedgerInitSetting(BlockchainKeypair[] partiKeys) { | |||
CryptoProvider[] supportedProviders =getContextProviders(); | |||
CryptoConfig defCryptoSetting = new CryptoConfig(); | |||
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); | |||
BytesValue v3 = ledgerRepo.getDataAccountSet().getAccount(dataAccountKeypair.getAddress()).getDataset().getValue("K3", | |||
0); | |||
assertNotNull(v1_0); | |||
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(); | |||
} |