Browse Source

Refactored MerkleAccountSet to prevent calls to Account with Transactional interface;

tags/1.1.2^2
huanghaiquan 5 years ago
parent
commit
4aedf9c4b5
18 changed files with 132 additions and 64 deletions
  1. +4
    -3
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java
  2. +12
    -0
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CompositeAccount.java
  3. +1
    -1
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccount.java
  4. +4
    -4
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java
  5. +1
    -9
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java
  6. +3
    -3
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java
  7. +0
    -13
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java
  8. +2
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java
  9. +17
    -8
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java
  10. +0
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java
  11. +0
    -7
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SecurityContext.java
  12. +2
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccount.java
  13. +3
    -3
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccountSet.java
  14. +5
    -5
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java
  15. +8
    -2
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerTestUtils.java
  16. +58
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleAccountSetTest.java
  17. +1
    -0
      source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java
  18. +11
    -0
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Account.java

+ 4
- 3
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/AccountDecorator.java View File

@@ -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;
}


+ 12
- 0
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/CompositeAccount.java View File

@@ -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();
}

+ 1
- 1
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccount.java View File

@@ -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);
}


+ 4
- 4
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/ContractAccountSet.java View File

@@ -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
- 9
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccount.java View File

@@ -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);
}


+ 3
- 3
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/DataAccountSet.java View File

@@ -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);
}


+ 0
- 13
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/LedgerAccount.java View File

@@ -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();
}

+ 2
- 2
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccount.java View File

@@ -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;
}



+ 17
- 8
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleAccountSet.java View File

@@ -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) {


+ 0
- 2
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/MerkleDataCluster.java View File

@@ -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 {



+ 0
- 7
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/SecurityContext.java View File

@@ -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>();


+ 2
- 2
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccount.java View File

@@ -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;


+ 3
- 3
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/UserAccountSet.java View File

@@ -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);
}


+ 5
- 5
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/AccountSetTest.java View File

@@ -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());
}

}

+ 8
- 2
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/LedgerTestUtils.java View File

@@ -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);


+ 58
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/MerkleAccountSetTest.java View File

@@ -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"));
}

}

+ 1
- 0
source/ledger/ledger-core/src/test/java/test/com/jd/blockchain/ledger/core/TransactionBatchProcessorTest.java View File

@@ -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);


+ 11
- 0
source/ledger/ledger-model/src/main/java/com/jd/blockchain/ledger/Account.java View File

@@ -0,0 +1,11 @@
package com.jd.blockchain.ledger;

import com.jd.blockchain.utils.Dataset;

public interface Account {
BlockchainIdentity getID();
Dataset<String, TypedValue> getDataset();
}

Loading…
Cancel
Save