Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.util.List;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alipay.antchain.bridge.commons.core.base.CrossChainLane;
import com.alipay.antchain.bridge.ptc.committee.node.commons.exception.DataAccessLayerException;
Expand Down Expand Up @@ -86,6 +87,24 @@ public TpBtaWrapper getMatchedTpBta(CrossChainLane lane, int tpbtaVersion) {
}
}

@Override
public TpBtaWrapper getMatchedTpBta(CrossChainLane lane, int tpbtaVersion, int btaSubjectVersion) {
try {
var entityList = searchTpBta(lane, tpbtaVersion, btaSubjectVersion);
if (ObjectUtil.isEmpty(entityList)) {
return null;
}
return ConvertUtil.convertFrom(
entityList.stream().max(Comparator.comparingInt(TpBtaEntity::getTpbtaVersion)).get()
);
} catch (Exception e) {
throw new DataAccessLayerException(
e, "Failed to get tpbta for lane {}, version {} and bta subject version {}",
lane.getLaneKey(), tpbtaVersion, btaSubjectVersion
);
}
}

@Override
public TpBtaWrapper getExactTpBta(CrossChainLane lane) {
return getExactTpBta(lane, -1);
Expand Down Expand Up @@ -117,14 +136,23 @@ public TpBtaWrapper getExactTpBta(CrossChainLane lane, int tpbtaVersion) {

@Override
public void setTpBta(TpBtaWrapper tpBtaWrapper) {
var lane = tpBtaWrapper.getCrossChainLane();
var tpbtaVersion = tpBtaWrapper.getTpbta().getTpbtaVersion();
var existing = getExactTpBta(lane, tpbtaVersion);
if (ObjectUtil.isNotNull(existing)) {
assertSameTpBta(existing, tpBtaWrapper);
return;
}
try {
if (hasTpBta(tpBtaWrapper.getCrossChainLane(), tpBtaWrapper.getTpbta().getTpbtaVersion())) {
throw new RuntimeException("tpBta already exists");
}
tpBtaMapper.insert((TpBtaEntity) ConvertUtil.convertFrom(tpBtaWrapper));
} catch (Exception e) {
existing = getExactTpBta(lane, tpbtaVersion);
if (ObjectUtil.isNotNull(existing)) {
assertSameTpBta(existing, tpBtaWrapper);
return;
}
throw new DataAccessLayerException(
e, "Failed to save tpbta for lane {}", tpBtaWrapper.getCrossChainLane().getLaneKey()
e, "Failed to save tpbta for lane {}", lane.getLaneKey()
);
}
}
Expand Down Expand Up @@ -187,13 +215,45 @@ public BtaWrapper getBta(String domain, int subjectVersion) {
}

@Override
public void setBta(BtaWrapper btaWrapper) {
public BtaWrapper getBta(String domain, BigInteger initHeight, byte[] initBlockHash) {
try {
if (hasBta(btaWrapper.getDomain(), btaWrapper.getBtaVersion())) {
throw new RuntimeException("bta already exists");
var entityList = btaMapper.selectList(
new LambdaQueryWrapper<BtaEntity>()
.eq(BtaEntity::getDomain, domain)
);
if (ObjectUtil.isEmpty(entityList)) {
return null;
}
return entityList.stream()
.map(ConvertUtil::convertFrom)
.map(BtaWrapper.class::cast)
.filter(wrapper -> wrapper.getBta().getInitHeight().equals(initHeight))
.filter(wrapper -> ArrayUtil.equals(wrapper.getBta().getInitBlockHash(), initBlockHash))
.max(Comparator.comparingInt(BtaWrapper::getSubjectVersion))
.orElse(null);
} catch (Exception e) {
throw new DataAccessLayerException(
e, "Failed to get bta for domain {}, init height {} and init block hash {}",
domain, initHeight, initBlockHash
);
}
}

@Override
public void setBta(BtaWrapper btaWrapper) {
var existing = getBta(btaWrapper.getDomain(), btaWrapper.getSubjectVersion());
if (ObjectUtil.isNotNull(existing)) {
assertSameBta(existing, btaWrapper);
return;
}
try {
btaMapper.insert((BtaEntity) ConvertUtil.convertFrom(btaWrapper));
} catch (Exception e) {
existing = getBta(btaWrapper.getDomain(), btaWrapper.getSubjectVersion());
if (ObjectUtil.isNotNull(existing)) {
assertSameBta(existing, btaWrapper);
return;
}
throw new DataAccessLayerException(
e, "Failed to save bta for domain {} and subject version {}", btaWrapper.getDomain(), btaWrapper.getSubjectVersion()
);
Expand Down Expand Up @@ -270,12 +330,25 @@ public ValidatedConsensusStateWrapper getValidatedConsensusState(String domain,

@Override
public void setValidatedConsensusState(ValidatedConsensusStateWrapper validatedConsensusStateWrapper) {
var existing = getValidatedConsensusState(
validatedConsensusStateWrapper.getDomain(),
validatedConsensusStateWrapper.getHeight()
);
if (ObjectUtil.isNotNull(existing)) {
assertSameValidatedConsensusState(existing, validatedConsensusStateWrapper);
return;
}
try {
if (hasValidatedConsensusState(validatedConsensusStateWrapper.getDomain(), validatedConsensusStateWrapper.getHeight())) {
throw new RuntimeException("validated consensus state already exists");
}
validatedConsensusStatesMapper.insert((ValidatedConsensusStatesEntity) ConvertUtil.convertFrom(validatedConsensusStateWrapper));
} catch (Exception e) {
existing = getValidatedConsensusState(
validatedConsensusStateWrapper.getDomain(),
validatedConsensusStateWrapper.getHeight()
);
if (ObjectUtil.isNotNull(existing)) {
assertSameValidatedConsensusState(existing, validatedConsensusStateWrapper);
return;
}
throw new DataAccessLayerException(
e, "Failed to save validated consensus state for domain {} and height {}",
validatedConsensusStateWrapper.getDomain(),
Expand All @@ -300,12 +373,17 @@ public boolean hasValidatedConsensusState(String domain, BigInteger height) {
}

private List<TpBtaEntity> searchTpBta(CrossChainLane lane, int tpbtaVersion) {
return searchTpBta(lane, tpbtaVersion, null);
}

private List<TpBtaEntity> searchTpBta(CrossChainLane lane, int tpbtaVersion, Integer btaSubjectVersion) {
// search the blockchain level first
var wrapper = new LambdaQueryWrapper<TpBtaEntity>()
.eq(TpBtaEntity::getSenderDomain, lane.getSenderDomain().getDomain())
.eq(TpBtaEntity::getReceiverDomain, "")
.eq(TpBtaEntity::getSenderId, "")
.eq(TpBtaEntity::getReceiverId, "");
.eq(TpBtaEntity::getReceiverId, "")
.eq(ObjectUtil.isNotNull(btaSubjectVersion), TpBtaEntity::getBtaSubjectVersion, btaSubjectVersion);
var entityList = tpBtaMapper.selectList(
tpbtaVersion == -1 ? wrapper : wrapper.eq(TpBtaEntity::getTpbtaVersion, tpbtaVersion)
);
Expand All @@ -321,7 +399,8 @@ private List<TpBtaEntity> searchTpBta(CrossChainLane lane, int tpbtaVersion) {
.eq(TpBtaEntity::getSenderDomain, lane.getSenderDomain().getDomain())
.eq(TpBtaEntity::getReceiverDomain, lane.getReceiverDomain().getDomain())
.eq(TpBtaEntity::getSenderId, "")
.eq(TpBtaEntity::getReceiverId, "");
.eq(TpBtaEntity::getReceiverId, "")
.eq(ObjectUtil.isNotNull(btaSubjectVersion), TpBtaEntity::getBtaSubjectVersion, btaSubjectVersion);
entityList = tpBtaMapper.selectList(
tpbtaVersion == -1 ? wrapper : wrapper.eq(TpBtaEntity::getTpbtaVersion, tpbtaVersion)
);
Expand All @@ -338,7 +417,8 @@ private List<TpBtaEntity> searchTpBta(CrossChainLane lane, int tpbtaVersion) {
.eq(TpBtaEntity::getSenderDomain, lane.getSenderDomain().getDomain())
.eq(TpBtaEntity::getSenderId, lane.getSenderId().toHex())
.eq(TpBtaEntity::getReceiverDomain, lane.getReceiverDomain().getDomain())
.eq(TpBtaEntity::getReceiverId, lane.getReceiverId().toHex());
.eq(TpBtaEntity::getReceiverId, lane.getReceiverId().toHex())
.eq(ObjectUtil.isNotNull(btaSubjectVersion), TpBtaEntity::getBtaSubjectVersion, btaSubjectVersion);
entityList = tpBtaMapper.selectList(
tpbtaVersion == -1 ? wrapper : wrapper.eq(TpBtaEntity::getTpbtaVersion, tpbtaVersion)
);
Expand All @@ -348,4 +428,37 @@ private List<TpBtaEntity> searchTpBta(CrossChainLane lane, int tpbtaVersion) {

return ListUtil.empty();
}

private void assertSameTpBta(TpBtaWrapper existing, TpBtaWrapper incoming) {
if (!ArrayUtil.equals(existing.getTpbta().encode(), incoming.getTpbta().encode())) {
throw new DataAccessLayerException(
"Conflicting tpbta for lane {} and version {}",
incoming.getCrossChainLane().getLaneKey(), incoming.getTpbta().getTpbtaVersion()
);
}
}

private void assertSameBta(BtaWrapper existing, BtaWrapper incoming) {
if (!ArrayUtil.equals(existing.getBta().encode(), incoming.getBta().encode())) {
throw new DataAccessLayerException(
"Conflicting bta for domain {} and subject version {}",
incoming.getDomain(), incoming.getSubjectVersion()
);
}
}

private void assertSameValidatedConsensusState(
ValidatedConsensusStateWrapper existing,
ValidatedConsensusStateWrapper incoming
) {
if (!ArrayUtil.equals(
existing.getValidatedConsensusState().encode(),
incoming.getValidatedConsensusState().encode()
)) {
throw new DataAccessLayerException(
"Conflicting validated consensus state for domain {} and height {}",
incoming.getDomain(), incoming.getHeight()
);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import com.alipay.antchain.bridge.ptc.committee.node.dal.mapper.SystemConfigMapper;
import com.alipay.antchain.bridge.ptc.committee.node.dal.repository.interfaces.ISystemConfigRepository;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import jakarta.annotation.Resource;
import lombok.Synchronized;
import org.springframework.stereotype.Component;
Expand Down Expand Up @@ -79,14 +80,7 @@ public boolean hasSystemConfig(String key) {
@Override
public void setSystemConfig(Map<String, String> configs) {
try {
configs.forEach((key, value) -> {
systemConfigMapper.insert(
SystemConfigEntity.builder()
.confKey(key)
.confValue(value)
.build()
);
});
configs.forEach(this::setSystemConfig);
} catch (Exception e) {
throw new DataAccessLayerException(
e, "Failed to set system config with key: {}", JSON.toJSONString(configs)
Expand All @@ -98,13 +92,21 @@ public void setSystemConfig(Map<String, String> configs) {
@Synchronized
public void setSystemConfig(String key, String value) {
try {
if (hasSystemConfig(key)) {
updateSystemConfig(key, value);
return;
}
systemConfigMapper.insert(
SystemConfigEntity.builder()
.confKey(key)
.confValue(value)
.build()
);
} catch (Exception e) {
if (hasSystemConfig(key)) {
updateSystemConfig(key, value);
return;
}
throw new DataAccessLayerException(
e, "Failed to set system config with key: {}", key
);
Expand Down Expand Up @@ -135,4 +137,14 @@ public void setPtcTrustRoot(PTCTrustRoot ptcTrustRoot) {
public PTCTrustRoot getPtcTrustRoot() {
return PTCTrustRoot.decode(Base64.decode(getSystemConfig(CURRENT_PTC_TRUST_ROOT)));
}

private void updateSystemConfig(String key, String value) {
systemConfigMapper.update(
SystemConfigEntity.builder()
.confValue(value)
.build(),
new LambdaUpdateWrapper<SystemConfigEntity>()
.eq(SystemConfigEntity::getConfKey, key)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ public interface IEndorseServiceRepository {

TpBtaWrapper getMatchedTpBta(CrossChainLane lane, int tpbtaVersion);

TpBtaWrapper getMatchedTpBta(CrossChainLane lane, int tpbtaVersion, int btaSubjectVersion);

TpBtaWrapper getExactTpBta(CrossChainLane lane);

TpBtaWrapper getExactTpBta(CrossChainLane lane, int tpbtaVersion);
Expand All @@ -41,6 +43,8 @@ public interface IEndorseServiceRepository {

BtaWrapper getBta(String domain, int subjectVersion);

BtaWrapper getBta(String domain, BigInteger initHeight, byte[] initBlockHash);

void setBta(BtaWrapper btaWrapper);

boolean hasBta(String domain, int subjectVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,26 @@ public TpBtaWrapper verifyBta(AbstractCrossChainCertificate domainCert, IBlockch
throw new InvalidBtaException("tpbta intersection check failed");
}

var committeeEndorseRoot = verifyBtaExtension.getCommitteeEndorseRoot().encode();
var currentPtcAnchorVersion = systemConfigRepository.queryCurrentPtcAnchorVersion();
var latestTpBta = endorseServiceRepository.getExactTpBta(verifyBtaExtension.getCrossChainLane());
var tpbtaVersion = ObjectUtil.isNull(latestTpBta) ? 1 : latestTpBta.getTpbta().getTpbtaVersion() + 1;
if (
ObjectUtil.isNotNull(latestTpBta)
&& latestTpBta.getTpbta().getBtaSubjectVersion() == bta.getSubjectVersion()
&& ObjectUtil.equals(latestTpBta.getTpbta().getPtcVerifyAnchorVersion(), currentPtcAnchorVersion)
&& ArrayUtil.equals(latestTpBta.getTpbta().getEndorseRoot(), committeeEndorseRoot)
) {
tpbtaVersion = latestTpBta.getTpbta().getTpbtaVersion();
}
var tpbta = new ThirdPartyBlockchainTrustAnchorV1(
ObjectUtil.isNull(latestTpBta) ? 1 : latestTpBta.getTpbta().getTpbtaVersion() + 1,
systemConfigRepository.queryCurrentPtcAnchorVersion(),
tpbtaVersion,
currentPtcAnchorVersion,
(PTCCredentialSubject) ptcCrossChainCert.getCredentialSubjectInstance(),
verifyBtaExtension.getCrossChainLane(),
bta.getSubjectVersion(),
ucpHashAlgo,
verifyBtaExtension.getCommitteeEndorseRoot().encode(),
committeeEndorseRoot,
new byte[]{}
);
tpbta.setEndorseProof(
Expand Down Expand Up @@ -177,13 +188,27 @@ private boolean checkIfTpBTAIntersection(CrossChainLane tpbtaLane) {

@Override
public ValidatedConsensusState commitAnchorState(CrossChainLane crossChainLane, ConsensusState anchorState) {
var tpbta = endorseServiceRepository.getMatchedTpBta(crossChainLane);
if (ObjectUtil.isNull(tpbta)) {
throw new InvalidConsensusStateException("tpbta not found for {}", crossChainLane.getLaneKey());
if (!ObjectUtil.equals(crossChainLane.getSenderDomain(), anchorState.getDomain())) {
throw new InvalidConsensusStateException(
"cross-chain lane sender domain {} does not match anchor state domain {}",
crossChainLane.getSenderDomain().getDomain(), anchorState.getDomain().getDomain()
);
}
var bta = endorseServiceRepository.getBta(crossChainLane.getSenderDomain().getDomain(), tpbta.getTpbta().getBtaSubjectVersion());

var bta = endorseServiceRepository.getBta(
Comment thread
fengjy73 marked this conversation as resolved.
crossChainLane.getSenderDomain().getDomain(),
anchorState.getHeight(),
anchorState.getHash()
);
if (ObjectUtil.isNull(bta)) {
throw new InvalidConsensusStateException("bta not found for {}", crossChainLane.getSenderDomain().getDomain());
throw new InvalidConsensusStateException("bta not found for domain {}, height {} and hash {}",
anchorState.getDomain().getDomain(), anchorState.getHeight().toString(), anchorState.getHashHex());
}

var tpbta = endorseServiceRepository.getMatchedTpBta(crossChainLane, -1, bta.getSubjectVersion());
if (ObjectUtil.isNull(tpbta)) {
throw new InvalidConsensusStateException("tpbta not found for {} and bta subject version {}",
crossChainLane.getLaneKey(), bta.getSubjectVersion());
}

var hcdvs = hcdvsPluginService.getHCDVSService(bta.getProduct());
Expand Down
Loading