200 lines
8.2 KiB
C++
200 lines
8.2 KiB
C++
/******************************************************************************
|
|
* Copyright © 2014-2019 The SuperNET Developers. *
|
|
* *
|
|
* See the AUTHORS, DEVELOPER-AGREEMENT and LICENSE files at *
|
|
* the top-level directory of this distribution for the individual copyright *
|
|
* holder information and the developer policies on copyright and licensing. *
|
|
* *
|
|
* Unless otherwise agreed in a custom licensing agreement, no part of the *
|
|
* SuperNET software, including this file may be copied, modified, propagated *
|
|
* or distributed except according to the terms contained in the LICENSE file *
|
|
* *
|
|
* Removal or modification of this copyright notice is prohibited. *
|
|
* *
|
|
******************************************************************************/
|
|
|
|
#include "cc/eval.h"
|
|
#include "cc/utils.h"
|
|
#include "importcoin.h"
|
|
#include "crosschain.h"
|
|
#include "primitives/transaction.h"
|
|
#include "cc/CCinclude.h"
|
|
|
|
/*
|
|
* CC Eval method for import coin.
|
|
*
|
|
* This method should control every parameter of the ImportCoin transaction, since it has no signature
|
|
* to protect it from malleability.
|
|
|
|
##### 0xffffffff is a special CCid for single chain/dual daemon imports
|
|
*/
|
|
|
|
extern std::string ASSETCHAINS_SELFIMPORT;
|
|
extern uint16_t ASSETCHAINS_CODAPORT,ASSETCHAINS_BEAMPORT;
|
|
extern uint8_t ASSETCHAINS_OVERRIDE_PUBKEY33[33];
|
|
|
|
int32_t GetSelfimportProof(std::string source,CMutableTransaction &mtx,CScript &scriptPubKey,TxProof &proof,uint64_t burnAmount,std::vector<uint8_t> rawtx,uint256 txid,std::vector<uint8_t> rawproof) // find burnTx with hash from "other" daemon
|
|
{
|
|
MerkleBranch newBranch; CMutableTransaction tmpmtx; CTransaction tx,vintx; uint256 blockHash; char destaddr[64],pkaddr[64];
|
|
tmpmtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(),komodo_nextheight());
|
|
if ( source == "BEAM" )
|
|
{
|
|
if ( ASSETCHAINS_BEAMPORT == 0 )
|
|
return(-1);
|
|
// confirm via ASSETCHAINS_BEAMPORT that burnTx/hash is a valid BEAM burn
|
|
// return(0);
|
|
}
|
|
else if ( source == "CODA" )
|
|
{
|
|
if ( ASSETCHAINS_CODAPORT == 0 )
|
|
return(-1);
|
|
// confirm via ASSETCHAINS_CODAPORT that burnTx/hash is a valid CODA burn
|
|
// return(0);
|
|
}
|
|
else
|
|
{
|
|
if ( !E_UNMARSHAL(rawtx, ss >> tx) )
|
|
return(-1);
|
|
scriptPubKey = tx.vout[0].scriptPubKey;
|
|
mtx = tx;
|
|
mtx.fOverwintered = tmpmtx.fOverwintered;
|
|
mtx.nExpiryHeight = tmpmtx.nExpiryHeight;
|
|
mtx.nVersionGroupId = tmpmtx.nVersionGroupId;
|
|
mtx.nVersion = tmpmtx.nVersion;
|
|
mtx.vout.clear();
|
|
mtx.vout.resize(1);
|
|
mtx.vout[0].nValue = burnAmount;
|
|
mtx.vout[0].scriptPubKey = scriptPubKey;
|
|
if ( tx.GetHash() != txid )
|
|
return(-1);
|
|
if ( source == "PUBKEY" )
|
|
{
|
|
// make sure vin0 is signed by ASSETCHAINS_OVERRIDE_PUBKEY33
|
|
if ( myGetTransaction(tx.vin[0].prevout.hash,vintx,blockHash) == 0 )
|
|
return(-1);
|
|
if ( tx.vin[0].prevout.n < vintx.vout.size() && Getscriptaddress(destaddr,vintx.vout[tx.vin[0].prevout.n].scriptPubKey) != 0 )
|
|
{
|
|
pubkey2addr(pkaddr,ASSETCHAINS_OVERRIDE_PUBKEY33);
|
|
if ( strcmp(pkaddr,destaddr) == 0 )
|
|
{
|
|
proof = std::make_pair(txid,newBranch);
|
|
return(0);
|
|
}
|
|
fprintf(stderr,"mismatched vin0[%d] -> %s vs %s\n",tx.vin[0].prevout.n,destaddr,pkaddr);
|
|
}
|
|
}
|
|
else if ( source == ASSETCHAINS_SELFIMPORT )
|
|
{
|
|
// source is external coin is the assetchains symbol in the burnTx OP_RETURN
|
|
// burnAmount, rawtx and rawproof should be enough for gatewaysdeposit equivalent
|
|
}
|
|
}
|
|
return(-1);
|
|
}
|
|
|
|
// use proof from the above functions to validate the import
|
|
|
|
int32_t CheckBEAMimport(TxProof proof,std::vector<uint8_t> rawproof,CTransaction burnTx,std::vector<CTxOut> payouts)
|
|
{
|
|
// check with dual-BEAM daemon via ASSETCHAINS_BEAMPORT for validity of burnTx
|
|
return(-1);
|
|
}
|
|
|
|
int32_t CheckCODAimport(TxProof proof,std::vector<uint8_t> rawproof,CTransaction burnTx,std::vector<CTxOut> payouts)
|
|
{
|
|
// check with dual-CODA daemon via ASSETCHAINS_CODAPORT for validity of burnTx
|
|
return(-1);
|
|
}
|
|
|
|
int32_t CheckGATEWAYimport(TxProof proof,std::vector<uint8_t> rawproof,CTransaction burnTx,std::vector<CTxOut> payouts)
|
|
{
|
|
// ASSETCHAINS_SELFIMPORT is coin
|
|
// check for valid burn from external coin blockchain and if valid return(0);
|
|
return(-1);
|
|
}
|
|
|
|
int32_t CheckPUBKEYimport(TxProof proof,std::vector<uint8_t> rawproof,CTransaction burnTx,std::vector<CTxOut> payouts)
|
|
{
|
|
// if burnTx has ASSETCHAINS_PUBKEY vin, it is valid return(0);
|
|
fprintf(stderr,"proof txid.%s\n",proof.first.GetHex().c_str());
|
|
return(0);
|
|
return(-1);
|
|
}
|
|
|
|
bool Eval::ImportCoin(const std::vector<uint8_t> params,const CTransaction &importTx,unsigned int nIn)
|
|
{
|
|
TxProof proof; CTransaction burnTx; std::vector<CTxOut> payouts; uint64_t txfee = 10000;
|
|
uint32_t targetCcid; std::string targetSymbol; uint256 payoutsHash; std::vector<uint8_t> rawproof;
|
|
if ( importTx.vout.size() < 2 )
|
|
return Invalid("too-few-vouts");
|
|
// params
|
|
if (!UnmarshalImportTx(importTx, proof, burnTx, payouts))
|
|
return Invalid("invalid-params");
|
|
// Control all aspects of this transaction
|
|
// It should not be at all malleable
|
|
if (MakeImportCoinTransaction(proof, burnTx, payouts).GetHash() != importTx.GetHash())
|
|
return Invalid("non-canonical");
|
|
// burn params
|
|
if (!UnmarshalBurnTx(burnTx, targetSymbol, &targetCcid, payoutsHash,rawproof))
|
|
return Invalid("invalid-burn-tx");
|
|
// check burn amount
|
|
{
|
|
uint64_t burnAmount = burnTx.vout.back().nValue;
|
|
if (burnAmount == 0)
|
|
return Invalid("invalid-burn-amount");
|
|
uint64_t totalOut = 0;
|
|
for (int i=0; i<importTx.vout.size(); i++)
|
|
totalOut += importTx.vout[i].nValue;
|
|
if (totalOut > burnAmount || totalOut < burnAmount-txfee )
|
|
return Invalid("payout-too-high-or-too-low");
|
|
}
|
|
// Check burntx shows correct outputs hash
|
|
if (payoutsHash != SerializeHash(payouts))
|
|
return Invalid("wrong-payouts");
|
|
if (targetCcid < KOMODO_FIRSTFUNGIBLEID)
|
|
return Invalid("chain-not-fungible");
|
|
// Check proof confirms existance of burnTx
|
|
if ( targetCcid != 0xffffffff )
|
|
{
|
|
if ( targetCcid != GetAssetchainsCC() || targetSymbol != GetAssetchainsSymbol() )
|
|
return Invalid("importcoin-wrong-chain");
|
|
uint256 target = proof.second.Exec(burnTx.GetHash());
|
|
if (!CheckMoMoM(proof.first, target))
|
|
return Invalid("momom-check-fail");
|
|
}
|
|
else
|
|
{
|
|
if ( targetSymbol == "BEAM" )
|
|
{
|
|
if ( ASSETCHAINS_BEAMPORT == 0 )
|
|
return Invalid("BEAM-import-without-port");
|
|
else if ( CheckBEAMimport(proof,rawproof,burnTx,payouts) < 0 )
|
|
return Invalid("BEAM-import-failure");
|
|
}
|
|
else if ( targetSymbol == "CODA" )
|
|
{
|
|
if ( ASSETCHAINS_CODAPORT == 0 )
|
|
return Invalid("CODA-import-without-port");
|
|
else if ( CheckCODAimport(proof,rawproof,burnTx,payouts) < 0 )
|
|
return Invalid("CODA-import-failure");
|
|
}
|
|
else if ( targetSymbol == "PUBKEY" )
|
|
{
|
|
if ( ASSETCHAINS_SELFIMPORT != "PUBKEY" )
|
|
return Invalid("PUBKEY-import-when-notPUBKEY");
|
|
else if ( CheckPUBKEYimport(proof,rawproof,burnTx,payouts) < 0 )
|
|
return Invalid("PUBKEY-import-failure");
|
|
}
|
|
else
|
|
{
|
|
if ( targetSymbol != ASSETCHAINS_SELFIMPORT )
|
|
return Invalid("invalid-gateway-import-coin");
|
|
else if ( CheckGATEWAYimport(proof,rawproof,burnTx,payouts) < 0 )
|
|
return Invalid("GATEWAY-import-failure");
|
|
}
|
|
}
|
|
return Valid();
|
|
}
|
|
|
|
|