Browse Source

Merge pull request #451 from VerusCoin/dev

0.9.4-2
master
Asher Dawes 2 years ago
committed by GitHub
parent
commit
dbf2c30a9d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 196
      .gitlab-ci.yml
  2. 2
      README.md
  3. 2
      doc/man/verus-cli/linux/README.txt
  4. 2
      doc/man/verus-cli/mac/README.txt
  5. 2
      doc/man/verus-cli/windows/README.txt
  6. 2
      src/chainparams.cpp
  7. 9
      src/chainparamsbase.cpp
  8. 2
      src/core_write.cpp
  9. 2
      src/deprecation.h
  10. 21
      src/init.cpp
  11. 4
      src/komodo_utils.h
  12. 18
      src/params.cpp
  13. 2
      src/pbaas/crosschainrpc.h
  14. 102
      src/pbaas/notarization.cpp
  15. 88
      src/pbaas/pbaas.cpp
  16. 5
      src/pbaas/pbaas.h
  17. 248
      src/pbaas/reserves.cpp
  18. 2
      src/rpc/misc.cpp
  19. 4
      src/rpc/pbaasrpc.cpp
  20. 24
      src/rpc/rawtransaction.cpp
  21. 12
      src/script/script.cpp
  22. 2
      src/script/serverchecker.cpp
  23. 2
      src/version.h

196
.gitlab-ci.yml

@ -7,7 +7,7 @@ stages:
########################################################################################################################
variables:
VERSION: 0.9.4-1
VERSION: 0.9.4-2
VERUS_CLI_ARM64_LINUX: Verus-CLI-Linux-v${VERSION}-arm64.tar.gz
VERUS_CLI_LINUX_X86_64: Verus-CLI-Linux-v${VERSION}-x86_64.tar.gz
@ -30,6 +30,7 @@ variables:
####START#### LINUX ####START####
########################################################################################################################
build:linux:
tags: [ "verusd" ]
image: asherd/verus-builders:verus-debian-10
variables:
DOCKER_DRIVER: overlay2
@ -58,12 +59,6 @@ build:linux:
- tar -czvf ${VERUS_CLI_LINUX_X86_64} verus-cli
- sha256sum ${VERUS_CLI_LINUX_X86_64} > ${VERUS_CLI_LINUX_X86_64}.sha256
- git status
after_script:
- curl -F file=@"${VERUS_CLI_LINUX_X86_64}"
-F channels="${CLI_POST_CHANNEL}"
-F initial_comment="${POST_MESSAGE}"
-H "${SLACK_BOT_AUTH}"
"https://slack.com/api/files.upload"
artifacts:
paths:
- ${VERUS_CLI_LINUX_X86_64}
@ -72,6 +67,7 @@ build:linux:
build:linux:arm64:
tags: [ "verusd" ]
image: asherd/verus-builders:cross-arm
variables:
DOCKER_DRIVER: overlay2
@ -100,13 +96,6 @@ build:linux:arm64:
- chmod +x verus-cli/fetch-bootstrap
- tar -czvf ${VERUS_CLI_ARM64_LINUX} verus-cli
- sha256sum ${VERUS_CLI_ARM64_LINUX} > ${VERUS_CLI_ARM64_LINUX}.sha256
- git status
after_script:
- curl -F file=@"${VERUS_CLI_ARM64_LINUX}"
-F channels="${CLI_POST_CHANNEL}"
-F initial_comment="${POST_MESSAGE}"
-H "${SLACK_BOT_AUTH}"
"https://slack.com/api/files.upload"
artifacts:
paths:
- ${VERUS_CLI_ARM64_LINUX}
@ -118,6 +107,7 @@ build:linux:arm64:
####START#### WINDOWS ####START####
########################################################################################################################
build:windows:
tags: [ "verusd" ]
image: asherd/verus-builders:verus-windows
variables:
DOCKER_DRIVER: overlay2
@ -139,11 +129,6 @@ build:windows:
- if [ "${STRIP_BINARIES}" = "true" ]; then strip --strip-unneeded verus-cli/verusd.exe && strip --strip-unneeded verus-cli/verus.exe; fi
- zip -r ${VERUS_CLI_WINDOWS} verus-cli
- sha256sum ${VERUS_CLI_WINDOWS} > ${VERUS_CLI_WINDOWS}.sha256
- curl -F file=@"${VERUS_CLI_WINDOWS}"
-F channels="${CLI_POST_CHANNEL}"
-F initial_comment="${POST_MESSAGE}"
-H "${SLACK_BOT_AUTH}"
"https://slack.com/api/files.upload"
artifacts:
paths:
- ${VERUS_CLI_WINDOWS}
@ -155,10 +140,10 @@ build:windows:
####START#### MACOS ####START####
########################################################################################################################
build:mac:
tags: [ "MacOS" ]
variables:
CONFIGURE_FLAGS: --with-gcc-arch=x86-64
stage: build
tags: ["Mojave"]
cache:
key: "${CI_JOB_NAME}${CI_COMMIT_REF_NAME}"
paths:
@ -180,11 +165,6 @@ build:mac:
- chmod +x verus-cli/verusd
- tar -czvf ${VERUS_CLI_MACOS} verus-cli
- shasum -a 256 ${VERUS_CLI_MACOS} > ${VERUS_CLI_MACOS}.sha256
- curl -F file=@"${VERUS_CLI_MACOS}"
-F channels="${CLI_POST_CHANNEL}"
-F initial_comment="${POST_MESSAGE}"
-H "${SLACK_BOT_AUTH}"
"https://slack.com/api/files.upload"
artifacts:
paths:
- ${VERUS_CLI_MACOS}
@ -197,174 +177,10 @@ build:mac:
####END#### Build Stage ####END####
########################################################################################################################
########################################################################################################################
########################################################################################################################
########################################################################################################################
####START#### Test stage: Test functionality of komodo binaries. Produce code quality and SAST reports. ####START####
########################################################################################################################
########################################################################################################################
########################################################################################################################
####START#### Code Quality ####START####
########################################################################################################################
.code_quality:
image: docker:stable
variables:
DOCKER_DRIVER: overlay2
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [gl-code-quality-report.json]
########################################################################################################################
####END#### Code Quality ####END####
########################################################################################################################
########################################################################################################################
####START#### Static Application Security Tests ####START####
########################################################################################################################
.sast:
image: docker:stable
variables:
DOCKER_DRIVER: overlay2
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SAST_CONFIDENCE_LEVEL="${SAST_CONFIDENCE_LEVEL:-3}"
--volume "$PWD:/code"
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/sast:$SP_VERSION" /app/bin/run /code
artifacts:
paths: [gl-sast-report.json]
########################################################################################################################
####END#### Static Application Security Tests ####END####
########################################################################################################################
########################################################################################################################
####START#### Run Verus CLI on Ubuntu Xenial (16.04) ####START####
########################################################################################################################
.ubuntu:xenial:
image: ubuntu:xenial
variables:
DOCKER_DRIVER: overlay2
stage: test
before_script:
- apt update && apt install -y wget libgomp1 python
- rm -rf /root/.komodo || true
- mv .komodo /root/ || true
script:
- tar -xzvf ${VERUS_CLI_LINUX_X86_64}
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
after_script:
- mv /root/.komodo ./ || true
cache:
key: ${CI_JOB_NAME}
paths: [.komodo]
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:linux
########################################################################################################################
####END#### Run Verus CLI on Ubuntu Xenial (16.04) ####END####
########################################################################################################################
########################################################################################################################
####START#### Run Verus CLI on Ubuntu Bionic (18.04) ####START####
########################################################################################################################
.ubuntu:bionic:
image: ubuntu:bionic
variables:
DOCKER_DRIVER: overlay2
stage: test
before_script:
- apt update && apt install -y wget libgomp1 python
- rm -rf /root/.komodo || true
- mv .komodo /root/ || true
script:
- tar -xzvf ${VERUS_CLI_LINUX_X86_64}
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
after_script:
- mv /root/.komodo ./ || true
cache:
key: ${CI_JOB_NAME}
paths: [.komodo]
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:linux
########################################################################################################################
####END#### Run Verus CLI on Ubuntu Bionic (18.04) ####END####
########################################################################################################################
########################################################################################################################
####START#### Run Verus CLI on MacOS Sierra (10.12.6) ####START####
########################################################################################################################
.macos:sierra:
stage: test
tags: ["Sierra"]
script:
- tar -xzvf $VERUS_CLI_MACOS
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:mac
########################################################################################################################
####END#### Run Verus CLI on MacOS Sierra (10.12.6) ####END####
########################################################################################################################
########################################################################################################################
####START#### Run Verus CLI on MacOS High Sierra (10.12.6) ####START####
########################################################################################################################
.macos:high-sierra:
stage: test
tags: ["High Sierra"]
script:
- tar -xzvf ${VERUS_CLI_MACOS}
- export PATH=$PATH:$CI_PROJECT_DIR/verus-cli
- python qa/verus-cli-tests/verus-cli-tester.py
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:mac
########################################################################################################################
####START#### Run Verus CLI on MacOS High Sierra (10.12.6) ####START####
########################################################################################################################
########################################################################################################################
####START#### Run Verus CLI on Windows 10 ####START####
########################################################################################################################
.windows:10:
stage: test
tags: ["Windows 10"]
script:
- PowerShell Expand-Archive -Path %VERUS_CLI_WINDOWS% -DestinationPath %CI_PROJECT_DIR%
- set PATH=%PATH%;%CI_PROJECT_DIR%\verus-cli
- qa\verus-cli-tests\verus-cli-tester.py
artifacts:
paths: [log.txt]
expire_in: 1 week
dependencies:
- build:windows
########################################################################################################################
####END#### Run Verus CLI on Windows 10 ####END####
########################################################################################################################
########################################################################################################################
####END#### Test Stage ####END####
########################################################################################################################
########################################################################################################################
####START#### Deploy ####START####
########################################################################################################################
deploy:
tags: [ "verusd" ]
stage: deploy
image: google/cloud-sdk:alpine
variables:

2
README.md

@ -1,5 +1,5 @@
## VerusCoin version 0.9.4-1
## VerusCoin version 0.9.4-2
Arguably the world's most advanced technology, zero knowledge privacy-centric blockchain, Verus Coin brings Sapling performance and zero knowledge features to an intelligent system with interchain smart contracts and a completely original, combined proof of stake/proof of work consensus algorithm that solves the nothing at stake problem. With this and its approach towards CPU mining and ASICs, Verus Coin strives to be one of the most naturally decentralizing and attack resistant blockchains in existence.

2
doc/man/verus-cli/linux/README.txt

@ -1,5 +1,5 @@
VerusCoin Command Line Tools v0.9.4-1
VerusCoin Command Line Tools v0.9.4-2
Contents:
verusd - VerusCoin daemon

2
doc/man/verus-cli/mac/README.txt

@ -1,5 +1,5 @@
VerusCoin Command Line Tools v0.9.4-1
VerusCoin Command Line Tools v0.9.4-2
Contents:
verusd - VerusCoin daemon.

2
doc/man/verus-cli/windows/README.txt

@ -1,5 +1,5 @@
VerusCoin Command Line Tools v0.9.4-1
VerusCoin Command Line Tools v0.9.4-2
Contents:
verusd.exe - VerusCoin daemon

2
src/chainparams.cpp

@ -91,7 +91,7 @@ public:
CMainParams()
{
strNetworkID = "main";
strCurrencyUnits = "KMD";
strCurrencyUnits = "VRSC";
bip44CoinType = 133; // As registered in https://github.com/satoshilabs/slips/blob/master/slip-0044.md (ZCASH, should be VRSC)
consensus.fCoinbaseMustBeProtected = false; // true this is only true wuth Verus and enforced after block 12800 (enforcement ending at solution V3)
consensus.nSubsidySlowStartInterval = 20000;

9
src/chainparamsbase.cpp

@ -93,15 +93,6 @@ void SelectBaseParams(CBaseChainParams::Network network)
CBaseChainParams::Network NetworkIdFromCommandLine()
{
bool fRegTest = GetBoolArg("-regtest", false);
bool fTestNet = GetBoolArg("-testnet", false);
if (fTestNet && fRegTest)
return CBaseChainParams::MAX_NETWORK_TYPES;
if (fRegTest)
return CBaseChainParams::REGTEST;
if (fTestNet)
return CBaseChainParams::TESTNET;
return CBaseChainParams::MAIN;
}

2
src/core_write.cpp

@ -839,8 +839,8 @@ UniValue CPBaaSNotarization::ToUniValue() const
obj.push_back(Pair("currencystate", currencyState.ToUniValue()));
obj.push_back(Pair("prevnotarizationtxid", prevNotarization.hash.GetHex()));
obj.push_back(Pair("prevnotarizationout", (int64_t)prevNotarization.n));
obj.push_back(Pair("hashprevnotarizationobject", hashPrevNotarization.GetHex()));
obj.push_back(Pair("prevheight", (int64_t)prevHeight));
obj.push_back(Pair("hashprevcrossnotarization", hashPrevCrossNotarization.GetHex()));
// now get states and roots, of which there may be multiple
UniValue curStateArr(UniValue::VARR);

2
src/deprecation.h

@ -9,7 +9,7 @@
// * Shut down 20 weeks' worth of blocks after the estimated release block height.
// * A warning is shown during the 2 weeks' worth of blocks prior to shut down.
static const int APPROX_RELEASE_HEIGHT = 2183000;
static const int APPROX_RELEASE_HEIGHT = 2191000;
static const int WEEKS_UNTIL_DEPRECATION = 20;
static const int DEPRECATION_HEIGHT = APPROX_RELEASE_HEIGHT + (WEEKS_UNTIL_DEPRECATION * 7 * 60 * 24);

21
src/init.cpp

@ -346,16 +346,6 @@ std::string HelpMessage(HelpMessageMode mode)
// When adding new options to the categories, please keep and ensure alphabetical ordering.
// Do not translate _(...) -help-debug options, many technical terms, and only a very small audience, so is unnecessary stress to translators
// TODO: HARDENING - edit this help information before final mainnet release, remove irrelevant switches, include:
// -mineraddress
// -pubkey
// -defaultid
// -cheatcatcher
// -miningdistribution
// -miningdistributionpassthrough
// -chain=
// more...
string strUsage = HelpMessageGroup(_("Options:"));
strUsage += HelpMessageOpt("-?", _("This help message"));
strUsage += HelpMessageOpt("-alerts", strprintf(_("Receive and display P2P network alerts (default: %u)"), DEFAULT_ALERTS));
@ -516,7 +506,16 @@ std::string HelpMessage(HelpMessageMode mode)
"This is intended for regression testing tools and app development.");
}
// strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)"));
strUsage += HelpMessageOpt("-testnet", _("Use the test network"));
strUsage += HelpMessageOpt("-mineraddress=<address>", _("Mining rewards will go to this address"));
strUsage += HelpMessageOpt("-pubkey=<hexpubkey>", _("If set, mining and staking rewards will go to this address by default"));
strUsage += HelpMessageOpt("-defaultid=<i-address>", _("VerusID used for default change out and staking reward recipient"));
strUsage += HelpMessageOpt("-defaultzaddr=<sapling-address>", _("sapling address to receive fraud proof rewards and if used with \"-privatechange=1\", z-change address for the sendcurrency command"));
strUsage += HelpMessageOpt("-cheatcatcher=<sapling-address>", _("same as \"-defaultzaddr\""));
strUsage += HelpMessageOpt("-privatechange", _("directs all change from sendcurency or z_sendmany APIs to the defaultzaddr set, if it is a valid sapling address"));
strUsage += HelpMessageOpt("-miningdistribution={\"addressorid\":<n>,...}", _("destination addresses and relative amounts used as ratios to divide total rewards + fees"));
strUsage += HelpMessageOpt("-miningdistributionpassthrough", _("uses the same miningdistribution values and addresses/IDs as Verus when merge mining"));
strUsage += HelpMessageOpt("-chain=pbaaschainname", _("loads either mainnet or resolves and loads a PBaaS chain if not vrsc or vrsctest"));
strUsage += HelpMessageOpt("-testnet", _("loads PBaaS network in testmode"));
strUsage += HelpMessageGroup(_("Node relay options:"));
strUsage += HelpMessageOpt("-datacarrier", strprintf(_("Relay and mine data carrier transactions (default: %u)"), 1));

4
src/komodo_utils.h

@ -1766,7 +1766,7 @@ void komodo_args(char *argv0)
*/
// either the testmode parameter or calling this chain VRSCTEST will put us into testmode
PBAAS_TESTMODE = GetBoolArg("-testmode", false);
PBAAS_TESTMODE = GetBoolArg("-testnet", false);
// setting test mode also prevents the name of this chain from being set to VRSC
@ -1778,7 +1778,7 @@ void komodo_args(char *argv0)
std::string lowerName = boost::to_lower_copy(name);
// TODO: HARDENING - right now, all PBaaS chains assume testmode. change before mainnet
// TODO: POST HARDENING - right now, all PBaaS chains assume testmode. change before mainnet
if (lowerName != "vrsc")
{
PBAAS_TESTMODE = true;

18
src/params.cpp

@ -92,15 +92,6 @@ static int xferinfo(void *p,
void initalizeMapParamBootstrap() {
mapParams.clear();
ParamFile bootFile;
bootFile.name = "bootstrap";
bootFile.URL = "https://bootstrap.verus.io/VRSC-bootstrap.tar.gz";
bootFile.verified = false;
bootFile.path = GetDataDir() / "VRSC-bootstrap.tar.gz";
bootFile.dlnow = 0;
bootFile.dltotal = 0;
mapParams[bootFile.URL] = bootFile;
ParamFile bootSigFile;
bootSigFile.name = "bootstrap-signature";
bootSigFile.URL = "https://bootstrap.verus.io/VRSC-bootstrap.tar.gz.verusid";
@ -109,6 +100,15 @@ void initalizeMapParamBootstrap() {
bootSigFile.dlnow = 0;
bootSigFile.dltotal = 0;
mapParams[bootSigFile.URL] = bootSigFile;
ParamFile bootFile;
bootFile.name = "bootstrap";
bootFile.URL = "https://bootstrap.verus.io/VRSC-bootstrap.tar.gz";
bootFile.verified = false;
bootFile.path = GetDataDir() / "VRSC-bootstrap.tar.gz";
bootFile.dlnow = 0;
bootFile.dltotal = 0;
mapParams[bootFile.URL] = bootFile;
}

2
src/pbaas/crosschainrpc.h

@ -1474,7 +1474,7 @@ private:
CKeccack256Writer *hw_keccack;
};
nativeHashWriter state;
public:
CNativeHashWriter(CCurrencyDefinition::EProofProtocol proofProtocol=CCurrencyDefinition::EProofProtocol::PROOF_PBAASMMR,
const unsigned char *personal=nullptr)

102
src/pbaas/notarization.cpp

@ -727,7 +727,7 @@ CPBaaSNotarization::CPBaaSNotarization(const UniValue &obj)
notarizationHeight = (uint32_t)uni_get_int64(find_value(obj, "notarizationheight"));
currencyState = CCoinbaseCurrencyState(find_value(obj, "currencystate"));
prevNotarization = CUTXORef(uint256S(uni_get_str(find_value(obj, "prevnotarizationtxid"))), (uint32_t)uni_get_int(find_value(obj, "prevnotarizationout")));
hashPrevNotarization = uint256S(uni_get_str(find_value(obj, "hashprevnotarizationobject")));
hashPrevCrossNotarization = uint256S(uni_get_str(find_value(obj, "hashprevcrossnotarization")));
prevHeight = (uint32_t)uni_get_int64(find_value(obj, "prevheight"));
auto curStateArr = find_value(obj, "currencystates");
@ -962,7 +962,7 @@ bool CPBaaSNotarization::NextNotarizationInfo(const CCurrencyDefinition &sourceS
uint160 externalSystemID = sourceSystem.SystemOrGatewayID() == ASSETCHAINS_CHAINID ?
((destSystemID == ASSETCHAINS_CHAINID) ? uint160() : destSystemID) :
ASSETCHAINS_CHAINID;
sourceSystem.GetID();
CCurrencyDefinition externalSystemDef;
if (externalSystemID.IsNull() || externalSystemID == ASSETCHAINS_CHAINID)
@ -997,9 +997,9 @@ bool CPBaaSNotarization::NextNotarizationInfo(const CCurrencyDefinition &sourceS
hashType = (CCurrencyDefinition::EProofProtocol)externalSystemDef.proofProtocol;
}
CNativeHashWriter hwPrevNotarization(hashType);
CNativeHashWriter hwPrevNotarization;
hwPrevNotarization << *this;
newNotarization.hashPrevNotarization = hwPrevNotarization.GetHash();
newNotarization.hashPrevCrossNotarization = hwPrevNotarization.GetHash();
CNativeHashWriter hw(hashType);
@ -1318,13 +1318,16 @@ bool CPBaaSNotarization::NextNotarizationInfo(const CCurrencyDefinition &sourceS
}
newNotarization.currencyState.SetLaunchClear(false);
CCurrencyDefinition destSystem = newNotarization.IsRefunding() ? ConnectedChains.GetCachedCurrency(destCurrency.launchSystemID) :
ConnectedChains.GetCachedCurrency(destCurrency.SystemOrGatewayID());
// calculate new state from processing all transfers
// we are not refunding, and it is possible that we also have
// normal conversions in addition to pre-conversions. add any conversions that may
// be present into the new currency state
CCoinbaseCurrencyState intermediateState = newNotarization.currencyState;
bool isValidExport = rtxd.AddReserveTransferImportOutputs(newNotarization.IsRefunding() ? externalSystemDef : sourceSystem,
newNotarization.IsRefunding() ? sourceSystem : externalSystemDef,
bool isValidExport = rtxd.AddReserveTransferImportOutputs(sourceSystem,
destSystem,
destCurrency,
intermediateState,
exportTransfers,
@ -1349,8 +1352,8 @@ bool CPBaaSNotarization::NextNotarizationInfo(const CCurrencyDefinition &sourceS
tempCurState.conversionPrice = newNotarization.currencyState.conversionPrice;
tempCurState.viaConversionPrice = newNotarization.currencyState.viaConversionPrice;
rtxd = CReserveTransactionDescriptor();
isValidExport = rtxd.AddReserveTransferImportOutputs(newNotarization.IsRefunding() ? externalSystemDef : sourceSystem,
newNotarization.IsRefunding() ? sourceSystem : externalSystemDef,
isValidExport = rtxd.AddReserveTransferImportOutputs(sourceSystem,
destSystem,
destCurrency,
tempCurState,
exportTransfers,
@ -2838,6 +2841,24 @@ bool CPBaaSNotarization::CreateEarnedNotarization(const CRPCChainData &externalS
return state.Error(errorPrefix + "invalid or missing currency state data from notary");
}
params = UniValue(UniValue::VARR);
params.push_back(EncodeDestination(CIdentityID(ASSETCHAINS_CHAINID)));
try
{
result = find_value(RPCCallRoot("getnotarizationdata", params), "result");
} catch (exception e)
{
result = NullUniValue;
}
CChainNotarizationData crosschainCND;
if (result.isNull() ||
!(crosschainCND = CChainNotarizationData(result)).IsValid() ||
(!externalSystem.chainDefinition.IsGateway() && !crosschainCND.IsConfirmed()))
{
LogPrint("notarization", "Unable to get notarization data from %s\n", EncodeDestination(CIdentityID(externalSystem.GetID())).c_str());
return state.Error("invalid crosschain notarization data");
}
// take the lock again, now that we're back from calling out
LOCK2(cs_main, mempool.cs);
@ -2847,6 +2868,45 @@ bool CPBaaSNotarization::CreateEarnedNotarization(const CRPCChainData &externalS
return state.Error("stale-block");
}
if (crosschainCND.vtx.size())
{
int prevNotarizationIdx;
CPBaaSNotarization lastPBN;
for (prevNotarizationIdx = crosschainCND.vtx.size() - 1; prevNotarizationIdx >= 0; prevNotarizationIdx--)
{
lastPBN = crosschainCND.vtx[prevNotarizationIdx].second;
// TODO: HARDENING check all currency states on this chain in last valid as well
std::map<uint160, CProofRoot>::iterator pIT = lastPBN.proofRoots.find(ASSETCHAINS_CHAINID);
if (pIT != lastPBN.proofRoots.end() &&
(!priorNotarization.proofRoots.count(ASSETCHAINS_CHAINID) ||
pIT->second.rootHeight <= priorNotarization.proofRoots.find(ASSETCHAINS_CHAINID)->second.rootHeight) &&
CProofRoot::GetProofRoot(pIT->second.rootHeight) == pIT->second)
{
break;
}
else if (pIT == crosschainCND.vtx[prevNotarizationIdx].second.proofRoots.end() &&
!prevNotarizationIdx &&
(crosschainCND.vtx[prevNotarizationIdx].second.IsDefinitionNotarization() || crosschainCND.vtx[prevNotarizationIdx].second.IsLaunchCleared()))
{
// use the 0th element if no proof root and it is definition or start, since it has no proof root to be wrong
break;
}
}
if (prevNotarizationIdx >= 0 &&
lastPBN.SetMirror(false) &&
!lastPBN.IsMirror())
{
CNativeHashWriter hw;
hw << lastPBN;
notarization.hashPrevCrossNotarization = hw.GetHash();
}
else
{
notarization.hashPrevCrossNotarization.SetNull();
}
}
notarization.currencyStates.clear();
for (int i = 0; i < currencyStatesUni.size(); i++)
{
@ -2913,9 +2973,6 @@ bool CPBaaSNotarization::CreateEarnedNotarization(const CRPCChainData &externalS
notarization.nodes = GetGoodNodes(CPBaaSNotarization::MAX_NODES);
notarization.prevNotarization = cnd.vtx[notaryIdx].first;
CNativeHashWriter hw;
hw << cnd.vtx[notaryIdx].second;
notarization.hashPrevNotarization = hw.GetHash();
notarization.prevHeight = cnd.vtx[notaryIdx].second.notarizationHeight;
CCcontract_info CC;
@ -4325,7 +4382,9 @@ std::vector<uint256> CPBaaSNotarization::SubmitFinalizedNotarizations(const CRPC
{
CAddressIndexDbEntry tmpIndexEntry;
CObjectFinalization finalizationObj;
if (crosschainCND.vtx[i].second.FindEarnedNotarization(finalizationObj, &tmpIndexEntry) && finalizationObj.IsConfirmed())
if (crosschainCND.vtx[i].second.proofRoots.count(ASSETCHAINS_CHAINID) &&
crosschainCND.vtx[i].second.FindEarnedNotarization(finalizationObj, &tmpIndexEntry) &&
finalizationObj.IsConfirmed())
{
earnedNotarizationIndexEntry = tmpIndexEntry;
confirmingIdx = i;
@ -4343,7 +4402,8 @@ std::vector<uint256> CPBaaSNotarization::SubmitFinalizedNotarizations(const CRPC
uint256 blockHash;
CTransaction confirmedNTx;
CBlockIndex *pIndex;
if (!myGetTransaction(cnd.vtx[confirmingIdx].first.hash, confirmedNTx, blockHash) ||
if (earnedNotarizationIndexEntry.first.txhash.IsNull() ||
!myGetTransaction(earnedNotarizationIndexEntry.first.txhash, confirmedNTx, blockHash) ||
!mapBlockIndex.count(blockHash) ||
!chainActive.Contains(pIndex = mapBlockIndex[blockHash]))
{
@ -4351,14 +4411,14 @@ std::vector<uint256> CPBaaSNotarization::SubmitFinalizedNotarizations(const CRPC
printf("Unable to get confirmed notarization transaction for %s\n", EncodeDestination(CIdentityID(systemID)).c_str());
return retVal;
}
CPartialTransactionProof firstProof(notarizationTxes[confirmingIdx].first,
CPartialTransactionProof firstProof(confirmedNTx,
std::vector<int>(),
std::vector<int>({(int)cnd.vtx[confirmingIdx].first.n}),
std::vector<int>({(int)earnedNotarizationIndexEntry.first.index}),
pIndex,
cnd.vtx[cnd.lastConfirmed].second.proofRoots[ASSETCHAINS_CHAINID].rootHeight);
notarizationTxInfo = std::make_pair(CInputDescriptor(notarizationTxes[confirmingIdx].first.vout[cnd.vtx[confirmingIdx].first.n].scriptPubKey,
notarizationTxes[confirmingIdx].first.vout[cnd.vtx[confirmingIdx].first.n].nValue,
CTxIn(cnd.vtx[confirmingIdx].first)),
crosschainCND.vtx[confirmingIdx].second.proofRoots[ASSETCHAINS_CHAINID].rootHeight);
notarizationTxInfo = std::make_pair(CInputDescriptor(confirmedNTx.vout[earnedNotarizationIndexEntry.first.index].scriptPubKey,
confirmedNTx.vout[earnedNotarizationIndexEntry.first.index].nValue,
CTxIn(earnedNotarizationIndexEntry.first.txhash, earnedNotarizationIndexEntry.first.index)),
firstProof);
}
}
@ -4590,7 +4650,8 @@ std::vector<uint256> CPBaaSNotarization::SubmitFinalizedNotarizations(const CRPC
*/
bool ValidateAcceptedNotarization(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn, bool fulfilled)
{
// TODO: this validates the spending transaction
// TODO: HARDENING
// the spending transaction must be a notarization in the same thread of notarizations
// check the following things:
// 1. It represents a valid PoS or merge mined block on the other chain, and contains the header in the opret
// 2. The MMR and proof provided for the currently asserted block can prove the provided header. The provided
@ -5117,6 +5178,7 @@ bool IsAcceptedNotarizationInput(const CScript &scriptSig)
bool ValidateEarnedNotarization(struct CCcontract_info *cp, Eval* eval, const CTransaction &tx, uint32_t nIn, bool fulfilled)
{
// TODO: HARDENING ensure that earned notarization UTXOs are spent appropriately
// the spending transaction must be a finalization that either confirms or invalidates this notarization
return true;
}

88
src/pbaas/pbaas.cpp

@ -584,8 +584,8 @@ bool PrecheckCrossChainImport(const CTransaction &tx, int32_t outNum, CValidatio
return state.Error(strprintf("%s: Invalid currency import", __func__));
}
// TODO: HARDENING - imported currencies do need to conform to type constraints in order
// to benefit from reduced import fees
// imported currencies do need to conform to type constraints in order
// to benefit from reduced import fees. this happens on the precheck for currency definition
if ((oneTransfer.HasNextLeg() && oneTransfer.destination.gatewayID != ASSETCHAINS_CHAINID ?
nextLegFeeEquiv :
@ -3428,33 +3428,37 @@ bool CConnectedChains::ConfigureEthBridge(bool callToCheck)
map<string, vector<string>> settingsmulti;
// create config file for our notary chain if one does not exist already
if (ReadConfigFile("veth", settings, settingsmulti))
if (ReadConfigFile("veth", settings, settingsmulti) &&
settingsmulti.count("-rpchost") &&
settingsmulti.count("-rpcuser") &&
settingsmulti.count("-rpcport") &&
settingsmulti.count("-rpcpassword"))
{
// the Ethereum bridge, "VETH", serves as the root currency to VRSC and for Rinkeby to VRSCTEST
vethNotaryChain.rpcUserPass = PBAAS_USERPASS = settingsmulti.find("-rpcuser")->second[0] + ":" + settingsmulti.find("-rpcpassword")->second[0];
vethNotaryChain.rpcPort = PBAAS_PORT = atoi(settingsmulti.find("-rpcport")->second[0]);
PBAAS_HOST = settingsmulti.find("-rpchost")->second[0];
if (!PBAAS_HOST.size())
{
PBAAS_HOST = "127.0.0.1";
}
vethNotaryChain.rpcHost = PBAAS_HOST;
CNotarySystemInfo notarySystem;
CChainNotarizationData cnd;
if (!GetNotarizationData(gatewayID, cnd))
{
LogPrintf("%s: Failed to get notarization data for notary chain %s\n", __func__, vethNotaryChain.chainDefinition.name.c_str());
return false;
}
notarySystems.insert(std::make_pair(gatewayID,
CNotarySystemInfo(cnd.IsConfirmed() ? cnd.vtx[cnd.lastConfirmed].second.notarizationHeight : 0,
vethNotaryChain,
cnd.vtx.size() ? cnd.vtx[cnd.forks[cnd.bestChain].back()].second : CPBaaSNotarization(),
CNotarySystemInfo::TYPE_ETH,
CNotarySystemInfo::VERSION_CURRENT)));
return IsNotaryAvailable(callToCheck);
}
if (!PBAAS_HOST.size())
{
PBAAS_HOST = "127.0.0.1";
}
vethNotaryChain.rpcHost = PBAAS_HOST;
CNotarySystemInfo notarySystem;
CChainNotarizationData cnd;
if (!GetNotarizationData(gatewayID, cnd))
{
LogPrintf("%s: Failed to get notarization data for notary chain %s\n", __func__, vethNotaryChain.chainDefinition.name.c_str());
return false;
}
notarySystems.insert(std::make_pair(gatewayID,
CNotarySystemInfo(cnd.IsConfirmed() ? cnd.vtx[cnd.lastConfirmed].second.notarizationHeight : 0,
vethNotaryChain,
cnd.vtx.size() ? cnd.vtx[cnd.forks[cnd.bestChain].back()].second : CPBaaSNotarization(),
CNotarySystemInfo::TYPE_ETH,
CNotarySystemInfo::VERSION_CURRENT)));
return IsNotaryAvailable(callToCheck);
}
return false;
}
@ -4451,6 +4455,7 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &sourceSyst
else if (useProofs)
{
// make sure we have the latest, confirmed proof roots to prove this import
lastNotarization.proposer = proofNotarization.proposer;
lastNotarization.proofRoots[sourceSystemID] = proofNotarization.proofRoots[sourceSystemID];
if (lastNotarization.proofRoots.count(ASSETCHAINS_CHAINID))
{
@ -4589,20 +4594,19 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &sourceSyst
newLocalDepositsRequired.valueMap[destCurID] -= newPrimaryCurrency;
}
/*printf("%s: newNotarization:\n%s\n", __func__, newNotarization.ToUniValue().write(1,2).c_str());
printf("%s: ccx.totalAmounts: %s\ngatewayDepositsUsed: %s\nimportedCurrency: %s\nspentCurrencyOut: %s\n",
LogPrint("crosschainimports", "%s: newNotarization:\n%s\n", __func__, newNotarization.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: ccx.totalAmounts: %s\ngatewayDepositsUsed: %s\nimportedCurrency: %s\nspentCurrencyOut: %s\n",
__func__,
ccx.totalAmounts.ToUniValue().write(1,2).c_str(),
gatewayDepositsUsed.ToUniValue().write(1,2).c_str(),
importedCurrency.ToUniValue().write(1,2).c_str(),
spentCurrencyOut.ToUniValue().write(1,2).c_str());
printf("%s: incomingCurrency: %s\ncurrencyChange: %s\nnewLocalDepositsRequired: %s\n",
LogPrint("crosschainimports", "%s: incomingCurrency: %s\ncurrencyChange: %s\nnewLocalDepositsRequired: %s\n",
__func__,
incomingCurrency.ToUniValue().write(1,2).c_str(),
newLocalReserveDeposits.ToUniValue().write(1,2).c_str(),
newLocalDepositsRequired.ToUniValue().write(1,2).c_str());
//*/
// create the import
CCrossChainImport cci = CCrossChainImport(sourceSystemID,
@ -4825,9 +4829,8 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &sourceSyst
gatewayChange = (totalDepositsInput - gatewayDepositsUsed).CanonicalMap();
/*printf("%s: gatewayDepositsUsed: %s\n", __func__, gatewayDepositsUsed.ToUniValue().write(1,2).c_str());
printf("%s: gatewayChange: %s\n", __func__, gatewayChange.ToUniValue().write(1,2).c_str());
//*/
LogPrint("crosschainimports", "%s: gatewayDepositsUsed: %s\n", __func__, gatewayDepositsUsed.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: gatewayChange: %s\n", __func__, gatewayChange.ToUniValue().write(1,2).c_str());
// we should always be able to fulfill
// gateway despoit requirements, or this is an error
@ -4867,15 +4870,14 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &sourceSyst
}
}
/* printf("%s: newNotarization.currencyState: %s\n", __func__, newNotarization.currencyState.ToUniValue().write(1,2).c_str());
printf("%s: cci: %s\n", __func__, cci.ToUniValue().write(1,2).c_str());
printf("%s: spentcurrencyout: %s\n", __func__, spentCurrencyOut.ToUniValue().write(1,2).c_str());
printf("%s: newcurrencyin: %s\n", __func__, incomingCurrency.ToUniValue().write(1,2).c_str());
printf("%s: importedCurrency: %s\n", __func__, importedCurrency.ToUniValue().write(1,2).c_str());
printf("%s: localdepositrequirements: %s\n", __func__, newLocalDepositsRequired.ToUniValue().write(1,2).c_str());
printf("%s: checkImportedCurrency: %s\n", __func__, checkImportedCurrency.ToUniValue().write(1,2).c_str());
printf("%s: checkRequiredDeposits: %s\n", __func__, checkRequiredDeposits.ToUniValue().write(1,2).c_str());
//*/
LogPrint("crosschainimports", "%s: newNotarization.currencyState: %s\n", __func__, newNotarization.currencyState.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: cci: %s\n", __func__, cci.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: spentcurrencyout: %s\n", __func__, spentCurrencyOut.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: newcurrencyin: %s\n", __func__, incomingCurrency.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: importedCurrency: %s\n", __func__, importedCurrency.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: localdepositrequirements: %s\n", __func__, newLocalDepositsRequired.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: checkImportedCurrency: %s\n", __func__, checkImportedCurrency.ToUniValue().write(1,2).c_str());
LogPrint("crosschainimports", "%s: checkRequiredDeposits: %s\n", __func__, checkRequiredDeposits.ToUniValue().write(1,2).c_str());
// add local reserve deposit inputs and determine change
if (newLocalDepositsRequired.valueMap.size() ||
@ -4901,7 +4903,7 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &sourceSyst
newLocalReserveDeposits = ((totalDepositsInput + incomingCurrency) - spentCurrencyOut).CanonicalMap();
/* printf("%s: totalDepositsInput: %s\nincomingPlusDepositsMinusSpent: %s\n",
LogPrint("crosschainimports", "%s: totalDepositsInput: %s\nincomingPlusDepositsMinusSpent: %s\n",
__func__,
totalDepositsInput.ToUniValue().write(1,2).c_str(),
newLocalReserveDeposits.ToUniValue().write(1,2).c_str()); //*/
@ -4974,12 +4976,12 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &sourceSyst
// ins and outs are correct. now calculate the fee correctly here and set the transaction builder accordingly
// to prevent an automatic change output. we could just let it go and have a setting to stop creation of a change output,
// but this is a nice doublecheck requirement
/*printf("%s: reserveInMap:\n%s\nspentCurrencyOut:\n%s\nccx.totalAmounts:\n%s\nccx.totalFees:\n%s\n",
LogPrint("crosschainimports", "%s: reserveInMap:\n%s\nspentCurrencyOut:\n%s\nccx.totalAmounts:\n%s\nccx.totalFees:\n%s\n",
__func__,
reserveInMap.ToUniValue().write(1,2).c_str(),
spentCurrencyOut.ToUniValue().write(1,2).c_str(),
ccx.totalAmounts.ToUniValue().write(1,2).c_str(),
ccx.totalFees.ToUniValue().write(1,2).c_str()); //*/
ccx.totalFees.ToUniValue().write(1,2).c_str());
// pay the fee out to the miner
CReserveTransactionDescriptor rtxd(tb.mtx, view, nHeight + 1);
@ -4990,7 +4992,7 @@ bool CConnectedChains::CreateLatestImports(const CCurrencyDefinition &sourceSyst
tb.SetReserveFee(reserveFees);
}
if (LogAcceptCategory("imports"))
if (LogAcceptCategory("crosschainimports"))
{
UniValue jsonTx(UniValue::VOBJ);
uint256 hashBlk;

5
src/pbaas/pbaas.h

@ -256,7 +256,8 @@ public:
CCoinbaseCurrencyState currencyState; // state of the currency being notarized as of this notarization
CUTXORef prevNotarization; // reference of the prior notarization on this system with which we agree
uint256 hashPrevNotarization; // hash of the prior notarization on this system with which we agree, even one not accepted yet
uint256 hashPrevCrossNotarization; // (this is not the same notarization as the prev notarization or prev height)
// it is the hash of the prior notarization on the other chain with which we agree, even one not yet confirmed
uint32_t prevHeight; // height of previous notarization we agree with
std::map<uint160, CCoinbaseCurrencyState> currencyStates; // currency state of other currencies to be co-notarized for gateways
@ -313,7 +314,7 @@ public:
READWRITE(currencyState);
READWRITE(notarizationHeight);
READWRITE(prevNotarization);
READWRITE(hashPrevNotarization);
READWRITE(hashPrevCrossNotarization);
READWRITE(prevHeight);
std::vector<std::pair<uint160, CCoinbaseCurrencyState>> vecCurrencyStates;

248
src/pbaas/reserves.cpp

@ -426,141 +426,168 @@ bool CCrossChainImport::GetImportInfo(const CTransaction &importTx,
}
// TODO: HARDENING - review to ensure that if this is skipped an error is thrown when appropriate
if (!isPBaaSDefinitionOrLaunch &&
(pBaseImport->importCurrencyID == ASSETCHAINS_CHAINID ||
(!pBaseImport->importCurrencyID.IsNull() && pBaseImport->importCurrencyID == ConnectedChains.ThisChain().GatewayConverterID())))
// for example, if we are coming in from ETH to the Verus / ETH converter
bool passedCheck = isPBaaSDefinitionOrLaunch;
if (!passedCheck)
{
// next output should be export in evidence output followed by supplemental reserve transfers for the export
evidenceOutStart = importNotarizationOut + 1;
int afterEvidence;
CNotaryEvidence evidence(importTx, evidenceOutStart, afterEvidence, CNotaryEvidence::TYPE_IMPORT_PROOF);
if (!evidence.IsValid())
passedCheck = pBaseImport->importCurrencyID == ASSETCHAINS_CHAINID ||
(!pBaseImport->importCurrencyID.IsNull() && pBaseImport->importCurrencyID == ConnectedChains.ThisChain().GatewayConverterID());
if (!passedCheck && !pBaseImport->importCurrencyID.IsNull())
{
// TODO: remove the line assigning evidence just below, as it is only for debugging
evidence = CNotaryEvidence(importTx, evidenceOutStart, afterEvidence);
return state.Error(strprintf("%s: cannot retrieve export evidence for import", __func__));
for (auto &oneCur : ConnectedChains.notarySystems)
{
if (oneCur.second.notaryChain.chainDefinition.IsGateway() &&
pBaseImport->importCurrencyID == oneCur.second.notaryChain.chainDefinition.GatewayConverterID())
{
passedCheck = true;
break;
}
}
}
if (passedCheck)
{
// next output should be export in evidence output followed by supplemental reserve transfers for the export
evidenceOutStart = importNotarizationOut + 1;
int afterEvidence;
CNotaryEvidence evidence(importTx, evidenceOutStart, afterEvidence, CNotaryEvidence::TYPE_IMPORT_PROOF);
if (!evidence.IsValid())
{
// TODO: remove the line assigning evidence just below, as it is only for debugging
evidence = CNotaryEvidence(importTx, evidenceOutStart, afterEvidence);
std::set<int> validEvidenceTypes;
validEvidenceTypes.insert(CHAINOBJ_TRANSACTION_PROOF);
CNotaryEvidence transactionProof(sysCCITemp.sourceSystemID, evidence.output, evidence.state, evidence.GetSelectEvidence(validEvidenceTypes), CNotaryEvidence::TYPE_IMPORT_PROOF);
return state.Error(strprintf("%s: cannot retrieve export evidence for import", __func__));
}
/*
// reconstruct evidence if necessary
if (evidence.IsPartialTxProof() &&
evidence.evidence.size())
std::set<int> validEvidenceTypes;
validEvidenceTypes.insert(CHAINOBJ_TRANSACTION_PROOF);
CNotaryEvidence transactionProof(sysCCITemp.sourceSystemID, evidence.output, evidence.state, evidence.GetSelectEvidence(validEvidenceTypes), CNotaryEvidence::TYPE_IMPORT_PROOF);
// reconstruct multipart evidence if necessary
if (evidence.IsMultipartProof())
{
COptCCParams eP;
CNotaryEvidence supplementalEvidence;
while (importTx.vout.size() > (evidenceOutStart + 1) &&
importTx.vout[evidenceOutStart + 1].scriptPubKey.IsPayToCryptoCondition(eP) &&
eP.IsValid() &&
eP.evalCode == EVAL_NOTARY_EVIDENCE &&
eP.vData.size() &&
(supplementalEvidence = CNotaryEvidence(eP.vData[0])).IsValid() &&
supplementalEvidence.IsPartialTxProof() &&
supplementalEvidence.evidence.size() == 1)
/*
// reconstruct evidence if necessary
if (evidence.IsPartialTxProof() &&
evidence.evidence.size())
// reconstruct multipart evidence if necessary
if (evidence.IsMultipartProof())
{
evidenceOutStart++;
evidence.evidence.push_back(supplementalEvidence.evidence[0]);
COptCCParams eP;
CNotaryEvidence supplementalEvidence;
while (importTx.vout.size() > (evidenceOutStart + 1) &&
importTx.vout[evidenceOutStart + 1].scriptPubKey.IsPayToCryptoCondition(eP) &&
eP.IsValid() &&
eP.evalCode == EVAL_NOTARY_EVIDENCE &&
eP.vData.size() &&
(supplementalEvidence = CNotaryEvidence(eP.vData[0])).IsValid() &&
supplementalEvidence.IsPartialTxProof() &&
supplementalEvidence.evidence.size() == 1)
{
evidenceOutStart++;
evidence.evidence.push_back(supplementalEvidence.evidence[0]);
}
if (!eP.IsValid())
{
return state.Error(strprintf("%s: cannot reconstruct export evidence for import", __func__));
}
evidence.evidence = std::vector<CPartialTransactionProof>({CPartialTransactionProof(evidence.evidence)});
}
if (!eP.IsValid())
*/
CTransaction exportTx;
p = COptCCParams();
if (!(transactionProof.evidence.chainObjects.size() &&
!((CChainObject<CPartialTransactionProof> *)transactionProof.evidence.chainObjects[0])->object.GetPartialTransaction(exportTx).IsNull() &&
((CChainObject<CPartialTransactionProof> *)transactionProof.evidence.chainObjects[0])->object.TransactionHash() == pBaseImport->exportTxId &&
exportTx.vout.size() > pBaseImport->exportTxOutNum &&
exportTx.vout[pBaseImport->exportTxOutNum].scriptPubKey.IsPayToCryptoCondition(p) &&
p.IsValid() &&
p.evalCode == EVAL_CROSSCHAIN_EXPORT &&
p.vData.size() &&
(ccx = CCrossChainExport(p.vData[0])).IsValid()))
{
return state.Error(strprintf("%s: cannot reconstruct export evidence for import", __func__));
return state.Error(strprintf("%s: invalid export evidence for import", __func__));
}
evidence.evidence = std::vector<CPartialTransactionProof>({CPartialTransactionProof(evidence.evidence)});
}
*/
CTransaction exportTx;
p = COptCCParams();
if (!(transactionProof.evidence.chainObjects.size() &&
!((CChainObject<CPartialTransactionProof> *)transactionProof.evidence.chainObjects[0])->object.GetPartialTransaction(exportTx).IsNull() &&
((CChainObject<CPartialTransactionProof> *)transactionProof.evidence.chainObjects[0])->object.TransactionHash() == pBaseImport->exportTxId &&
exportTx.vout.size() > pBaseImport->exportTxOutNum &&
exportTx.vout[pBaseImport->exportTxOutNum].scriptPubKey.IsPayToCryptoCondition(p) &&
p.IsValid() &&
p.evalCode == EVAL_CROSSCHAIN_EXPORT &&
p.vData.size() &&
(ccx = CCrossChainExport(p.vData[0])).IsValid()))
{
return state.Error(strprintf("%s: invalid export evidence for import", __func__));
}
uint160 externalSystemID = ccx.sourceSystemID == ASSETCHAINS_CHAINID ?
((ccx.destSystemID == ASSETCHAINS_CHAINID) ? uint160() : ccx.destSystemID) :
ccx.sourceSystemID;
uint160 externalSystemID = ccx.sourceSystemID == ASSETCHAINS_CHAINID ?
((ccx.destSystemID == ASSETCHAINS_CHAINID) ? uint160() : ccx.destSystemID) :
ccx.sourceSystemID;
std::map<uint160, CProofRoot>::iterator proofIt;
if (!externalSystemID.IsNull() &&
(proofIt = importNotarization.proofRoots.find(externalSystemID)) != importNotarization.proofRoots.end())
{
switch (proofIt->second.type)
std::map<uint160, CProofRoot>::iterator proofIt;
if (!externalSystemID.IsNull() &&
(proofIt = importNotarization.proofRoots.find(externalSystemID)) != importNotarization.proofRoots.end())
{
case CProofRoot::TYPE_ETHEREUM:
switch (proofIt->second.type)
{
hashType = CCurrencyDefinition::EProofProtocol::PROOF_ETHNOTARIZATION;
break;
case CProofRoot::TYPE_ETHEREUM:
{
hashType = CCurrencyDefinition::EProofProtocol::PROOF_ETHNOTARIZATION;
break;
}
}
}
}
else if (!externalSystemID.IsNull())
{
return state.Error(strprintf("%s: no proof root to validate export for external system %s", __func__, EncodeDestination(CIdentityID(externalSystemID)).c_str()));
}
else if (!externalSystemID.IsNull())
{
return state.Error(strprintf("%s: no proof root to validate export for external system %s", __func__, EncodeDestination(CIdentityID(externalSystemID)).c_str()));
}
int32_t nextOutput;
CPBaaSNotarization xNotarization;
int primaryOutNumOut;
if (!ccx.GetExportInfo(importTx, evidenceOutStart, primaryOutNumOut, nextOutput, xNotarization, reserveTransfers, hashType))
{
//UniValue jsonTx(UniValue::VOBJ);
//TxToUniv(importTx, uint256(), jsonTx);
//printf("%s: importTx:\n%s\n", __func__, jsonTx.write(1,2).c_str());
return state.Error(strprintf("%s: invalid export evidence for import 1",__func__));
}
int32_t nextOutput;
CPBaaSNotarization xNotarization;
int primaryOutNumOut;
if (!ccx.GetExportInfo(importTx, evidenceOutStart, primaryOutNumOut, nextOutput, xNotarization, reserveTransfers, hashType))
{
//UniValue jsonTx(UniValue::VOBJ);
//TxToUniv(importTx, uint256(), jsonTx);
//printf("%s: importTx:\n%s\n", __func__, jsonTx.write(1,2).c_str());
return state.Error(strprintf("%s: invalid export evidence for import 1",__func__));
}
// evidence out end points to the last evidence out, not beyond
evidenceOutEnd = nextOutput - 1;
// evidence out end points to the last evidence out, not beyond
evidenceOutEnd = nextOutput - 1;
}
}
if (!passedCheck)
{
return state.Error(strprintf("%s: unable to verify cross-chain export as valid",__func__));
}
}
// if we may have an arbitrage reserve transfer, look for it
if (importNotarization.IsValid() &&
importNotarization.IsLaunchComplete() &&
!importNotarization.IsRefunding() &&
importNotarization.currencyState.IsValid() &&
importNotarization.currencyState.IsFractional() &&
ccx.IsValid() &&
hashReserveTransfers != ccx.hashReserveTransfers)
{
// if we don't have an arbitrage reserve transfer, this is an error that the hashes don't match
// if we do, they cannot match, so get it
CReserveTransfer arbitrageTransfer = GetArbitrageTransfer(importTx, numImportOut, state, nHeight);
if (!arbitrageTransfer.IsValid())
{
return state.Error(strprintf("%s: export and import hash mismatch without valid arbitrage transfer",__func__));
}
reserveTransfers.push_back(arbitrageTransfer);
CNativeHashWriter nhw1(hashType);
CNativeHashWriter nhw2(hashType);
for (int i = 0; i < reserveTransfers.size(); i++)
{
nhw1 << reserveTransfers[i];
// if this is not the last, add it into the 2nd hash, which should then match the export
if (i + 1 < reserveTransfers.size())
if (hashReserveTransfers != ccx.hashReserveTransfers)
{
if (importNotarization.IsValid() &&
importNotarization.IsLaunchComplete() &&
!importNotarization.IsRefunding() &&
importNotarization.currencyState.IsValid() &&
importNotarization.currencyState.IsFractional() &&
ccx.IsValid())
{
// if we don't have an arbitrage reserve transfer, this is an error that the hashes don't match
// if we do, they cannot match, so get it
CReserveTransfer arbitrageTransfer = GetArbitrageTransfer(importTx, numImportOut, state, nHeight);
if (!arbitrageTransfer.IsValid())
{
nhw2 << reserveTransfers[i];
return state.Error(strprintf("%s: export and import hash mismatch without valid arbitrage transfer",__func__));
}
reserveTransfers.push_back(arbitrageTransfer);
CNativeHashWriter nhw1(hashType);
CNativeHashWriter nhw2(hashType);
for (int i = 0; i < reserveTransfers.size(); i++)
{
nhw1 << reserveTransfers[i];
// if this is not the last, add it into the 2nd hash, which should then match the export
if (i + 1 < reserveTransfers.size())
{
nhw2 << reserveTransfers[i];
}
}
if (hashReserveTransfers != nhw1.GetHash() || ccx.hashReserveTransfers != nhw2.GetHash())
{
return state.Error(strprintf("%s: import hash of transfers does not match actual transfers with arbitrage",__func__));
}
}
if (hashReserveTransfers != nhw1.GetHash() || ccx.hashReserveTransfers != nhw2.GetHash())
else
{
return state.Error(strprintf("%s: import hash of transfers does not match actual transfers with arbitrage",__func__));
return state.Error(strprintf("%s: import hash of transfers does not match export transfers",__func__));
}
}
@ -2502,6 +2529,9 @@ CReserveTransactionDescriptor::CReserveTransactionDescriptor(const CTransaction
checkState.SetLaunchCompleteMarker(false);
}
// TODO: HARDENING - ensure that we match notarization state to account for burns and
// transactions that affect state without outputs
if (!rtxd.AddReserveTransferImportOutputs(sourceSystemDef,
ConnectedChains.thisChain,
importCurrencyDef,

2
src/rpc/misc.cpp

@ -2075,7 +2075,7 @@ UniValue getaddressbalance(const UniValue& params, bool fHelp)
{
UniValue currencyBal(UniValue::VOBJ);
UniValue currencyNames(UniValue::VOBJ);
for (auto &oneBalance : reserveBalance.valueMap)
for (auto &oneBalance : reserveReceived.valueMap)
{
std::string name = EncodeDestination(CIdentityID(oneBalance.first));
currencyBal.push_back(make_pair(name, ValueFromAmount(oneBalance.second)));

4
src/rpc/pbaasrpc.cpp

@ -8252,6 +8252,10 @@ extern void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue&
CCurrencyDefinition ValidateNewUnivalueCurrencyDefinition(const UniValue &uniObj, uint32_t height, const uint160 systemID, std::map<uint160, std::string> &requiredDefinitions, bool checkMempool)
{
CCurrencyDefinition newCurrency(uniObj);
if (find_value(uniObj, "launchsystemid").isNull() && newCurrency.GetID() != ASSETCHAINS_CHAINID && newCurrency.parent != ASSETCHAINS_CHAINID)
{
newCurrency.launchSystemID = systemID;
}
if (!newCurrency.IsValid())
{

24
src/rpc/rawtransaction.cpp

@ -178,16 +178,30 @@ void TxToJSONExpanded(const CTransaction& tx, const uint256 hashBlock, UniValue&
uint256 hash; CTransaction txFrom;
if (GetTransaction(txin.prevout.hash,txFrom,hash,false))
{
if (LogAcceptCategory("signaturehash"))
COptCCParams p;
BlockMap::iterator blockIdxIt = mapBlockIndex.find(hash);
if (!hash.IsNull() &&
blockIdxIt != mapBlockIndex.end() &&
LogAcceptCategory("signaturehash") &&
chainActive.Contains(blockIdxIt->second) &&
txFrom.vout[txin.prevout.n].scriptPubKey.IsPayToCryptoCondition(p) &&
p.IsValid())
{
// TODO: HARDENING - it would be good to add the signature hash for every input, but we need
// to reliably retrieve the hashtype (ie. SIGHASH_ALL, SIGHASH_SINGLE, etc.) from all transaction input types
// for now, this is temporary for debugging
// TODO: POST HARDENING - it would be good to add the signature hash for every input and improve
// description of signing and eval conditions, decoding the COptCCParams
// get signature hash and verify signature
auto consensusBranchID = CurrentEpochBranchId(blockIdxIt->second->GetHeight(), Params().GetConsensus());
CSmartTransactionSignatures smartSigs;
bool signedByDefaultKey = false;
std::vector<unsigned char> ffVec = GetFulfillmentVector(tx.vin[i].scriptSig);
smartSigs = CSmartTransactionSignatures(std::vector<unsigned char>(ffVec.begin(), ffVec.end()));
UniValue signatureHashInfo(UniValue::VOBJ);
SignatureHash(txFrom.vout[txin.prevout.n].scriptPubKey,
tx,
i,
SIGHASH_ALL,
smartSigs.sigHashType,
txFrom.vout[txin.prevout.n].nValue,
CurrentEpochBranchId(nHeight, Params().GetConsensus()),
nullptr,

12
src/script/script.cpp

@ -854,10 +854,17 @@ CCurrencyValueMap CScript::ReserveOutValue(COptCCParams &p, bool spendableOnly)
// larger in a way that matters is on testnet for now.
CCommitmentHash ch(p.vData[0]);
// TODO: HARDENING - once Verus Vault activates on mainnet, support currencies
if (ch.IsValid() && !_IsVerusMainnetActive())
if (ch.IsValid())
{
retVal = ch.reserveValues;
// TODO: HARDENING - once Verus Vault activates on mainnet, support currencies and remove this if statement just below
// until PBaaS, we should have no valid currency outputs on mainnet
if (_IsVerusMainnetActive() && retVal.valueMap.size())
{
LogPrintf("%s: invalid identity commitment output detected\n", __func__);
printf("%s: invalid identity commitment output detected\n", __func__);
}
}
}
}
@ -1146,6 +1153,7 @@ std::set<CIndexID> COptCCParams::GetIndexKeys() const
}
if (!checkNotarization.IsMirror())
{
// TODO: POST HARDENING consider whether this can use the native hash writer with an alternate hash
CNativeHashWriter hw;
hw << checkNotarization;
uint256 objHash = hw.GetHash();

2
src/script/serverchecker.cpp

@ -135,7 +135,7 @@ std::map<uint160, std::pair<int, std::vector<std::vector<unsigned char>>>> Serve
}
if (id.IsValidUnrevoked() && (isStake || sourceIsSelf || !id.IsLocked(spendHeight)))
{
// TODO: HARDENING - in next upgrade, consider adding limits on what can be modified in an ID
// TODO: POST HARDENING - in next upgrade, consider adding limits on what can be modified in an ID
std::vector<std::vector<unsigned char>> idAddrBytes;
for (auto &oneAddr : id.primaryAddresses)

2
src/version.h

@ -35,6 +35,6 @@ static const int MEMPOOL_GD_VERSION = 60002;
static const int NO_BLOOM_VERSION = 170004;
#define KOMODO_VERSION "0.2.1"
#define VERUS_VERSION "0.9.4-1"
#define VERUS_VERSION "0.9.4-2"
#endif // BITCOIN_VERSION_H

Loading…
Cancel
Save