]> Git Repo - VerusCoin.git/commitdiff
Update without PBaaS for interim release
authorMichael Toutonghi <[email protected]>
Wed, 5 Jun 2019 23:18:18 +0000 (16:18 -0700)
committerMichael Toutonghi <[email protected]>
Wed, 5 Jun 2019 23:18:18 +0000 (16:18 -0700)
src/cc/CCcustom.cpp
src/cc/eval.cpp
src/cc/eval.h
src/komodo_bitcoind.h
src/pbaas/notarization.h
src/pbaas/pbaas.cpp
src/pbaas/pbaas.h
src/rpc/pbaasrpc.cpp
src/rpc/rawtransaction.cpp

index 19772a8f7e247bcb6bfb1f7f629a871da2923b25..ce8d607fc0183fae0f4e386e4c3f4d66c3e198a7 100644 (file)
@@ -330,9 +330,11 @@ struct CCcontract_info *CCinit(struct CCcontract_info *cp, uint8_t evalcode)
             cp->ismyvin = IsServiceRewardInput;
             break;
 
-        case EVAL_RESERVEIMPORT:
-        case EVAL_RESERVEEXPORT:
-        case EVAL_RESERVEOUTPUT:
+        case EVAL_INSTANTSPEND:
+        case EVAL_CROSSCHAIN_INPUT:
+        case EVAL_CROSSCHAIN_OUTPUT:
+        case EVAL_CROSSCHAIN_IMPORT:
+        case EVAL_CROSSCHAIN_EXPORT:
             assert(false);
             break;
 
index f884e3b12e17d71e62be14a027fe54a7396e535e..96cb12c25a398d9646ed1bbe6ed36970c62676c3 100644 (file)
@@ -73,15 +73,23 @@ bool Eval::Dispatch(const CC *cond, const CTransaction &txTo, unsigned int nIn)
     std::vector<uint8_t> vparams(cond->code+1, cond->code+cond->codeLength);
     switch ( ecode )
     {
-        case EVAL_STAKEGUARD:
         case EVAL_PBAASDEFINITION:
         case EVAL_SERVICEREWARD:
         case EVAL_EARNEDNOTARIZATION:
         case EVAL_ACCEPTEDNOTARIZATION:
         case EVAL_FINALIZENOTARIZATION:
-        case EVAL_RESERVEOUTPUT:
-        case EVAL_RESERVEEXPORT:
-        case EVAL_RESERVEIMPORT:
+        case EVAL_CROSSCHAIN_OUTPUT:
+        case EVAL_CROSSCHAIN_EXPORT:
+        case EVAL_CROSSCHAIN_IMPORT:
+        case EVAL_INSTANTSPEND:
+        case EVAL_CROSSCHAIN_INPUT:
+            if (!chainActive.LastTip() || CConstVerusSolutionVector::activationHeight.ActiveVersion(chainActive.LastTip()->GetHeight()) < CActivationHeight::SOLUTION_VERUSV3)
+            {
+                // if chain is not able to process this yet, don't drop through to do so
+                break;
+            }
+
+        case EVAL_STAKEGUARD:
             return(ProcessCC(cp,this, vparams, txTo, nIn));
             break;
 
index 4a3fb0127ee6d889986de7b2aa109813fa4fcc15..acf173729edf50b9a62f17895d90f1a6cc3ce8dc 100644 (file)
         EVAL(EVAL_EARNEDNOTARIZATION, 0x4)  \
         EVAL(EVAL_ACCEPTEDNOTARIZATION, 0x5)  \
         EVAL(EVAL_FINALIZENOTARIZATION, 0x6)  \
-        EVAL(EVAL_RESERVEOUTPUT, 0x7)  \
-        EVAL(EVAL_RESERVEEXPORT, 0x8)  \
-        EVAL(EVAL_RESERVEIMPORT, 0x9)  \
+        EVAL(EVAL_INSTANTSPEND, 0x7)  \
+        EVAL(EVAL_CROSSCHAIN_INPUT, 0x8)  \
+        EVAL(EVAL_CROSSCHAIN_OUTPUT, 0x9)  \
+        EVAL(EVAL_CROSSCHAIN_EXPORT, 0xa)  \
+        EVAL(EVAL_CROSSCHAIN_IMPORT, 0xb)  \
         EVAL(EVAL_IMPORTPAYOUT, 0xe1)  \
         EVAL(EVAL_IMPORTCOIN,   0xe2)  \
         EVAL(EVAL_ASSETS,   0xe3)  \
index 67b8f5d63224420bd68827c9994ab7ddf66b992c..fb5bc7601f83afa55cb89d1d8a1cbb244299c1d3 100644 (file)
@@ -1640,7 +1640,7 @@ bool verusCheckPOSBlock(int32_t slowflag, CBlock *pblock, int32_t height)
                                                 {
                                                     txnouttype tp;
                                                     std::vector<std::vector<unsigned char>> vvch = std::vector<std::vector<unsigned char>>();
-                                                    // solve all outputs to check that destinations all go only to the pk
+                                                    // solve all outputs to check that non-instantspend destinations all go only to the pk
                                                     // specified in the stake params
                                                     if ((!supportInstantSpend || !vout.scriptPubKey.IsInstantSpend()) &&
                                                         (!Solver(vout.scriptPubKey, tp, vvch) || 
index 0eeb0afe380d82ab0cb4a8e266ca4325675582d7..d2e8ee32a6dc47831d475ae4e7c62c7d530663f8 100644 (file)
@@ -203,6 +203,13 @@ public:
     {
         return ::AsVector(*this);
     }
+
+    UniValue ToUniValue() const
+    {
+        UniValue ret(UniValue::VOBJ);
+        ret.push_back(Pair("confirmedinput", confirmedInput));
+        return ret;
+    }
 };
 
 class CChainNotarizationData
index a5af056aa61c722df970726a64bbcda96443f797..e0ff8a74c771c9bf1952e37276baa6140a04bb1b 100644 (file)
@@ -404,6 +404,16 @@ CServiceReward::CServiceReward(const CTransaction &tx, bool validate)
 }
 
 
+CCrossChainInput::CCrossChainInput(const CTransaction &tx)
+{
+    // TODO - finish
+}
+
+CCrossChainInput::CCrossChainInput(const UniValue &obj)
+{
+    // TODO - finish
+}
+
 uint160 CPBaaSChainDefinition::GetChainID(std::string name)
 {
     const char *chainName = name.c_str();
index c78349220000aaa549b1f66006713e971df483cf..400ee7644dc9514d6cf5af9dfe5e67ecb7b768be 100644 (file)
@@ -54,7 +54,6 @@ static const uint32_t PBAAS_VERSION = 1;
 static const uint32_t PBAAS_VERSION_INVALID = 0;
 static const uint32_t PBAAS_NODESPERNOTARIZATION = 2;       // number of nodes to reference in each notarization
 static const int64_t PBAAS_MINNOTARIZATIONOUTPUT = 10000;   // enough for one fee worth to finalization and notarization thread
-static const int64_t PBAAS_MAXNOTARIZATIONINPUTS = 50;      // max inputs on a notarization tx
 static const int32_t PBAAS_MINSTARTBLOCKDELTA = 100;        // minimum number of blocks to wait for starting a chain after definition
 static const int32_t PBAAS_MAXPRIORBLOCKS = 16;             // maximum prior block commitments to include in prior blocks chain object
 
@@ -403,12 +402,13 @@ public:
     static const int64_t MIN_PER_BLOCK_NOTARIZATION = 1000000;  // 0.01 VRSC per block notarization minimum
     static const int64_t MIN_BILLING_PERIOD = 480;  // 8 hour minimum billing period for notarization, typically expect days/weeks/months
     static const int64_t DEFAULT_OUTPUT_VALUE = 100000;  // 0.001 VRSC default output value
+    static const int32_t OPTION_RESERVE = 1; // allows reserve conversion when set
 
     uint32_t nVersion;                      // version of this chain definition data structure to allow for extensions (not daemon version)
     std::string name;                       // chain name, maximum 64 characters
     CKeyID address;                         // non-purchased/converted premine and fee recipient address
     int64_t premine;                        // initial supply that is distributed to the premine output address, but not purchased
-    int64_t conversion;                     // factor / 100000000 for conversion of VRSC to coin on launch
+    int64_t conversion;                     // factor / 100000000 for conversion of VRSC to/from coin
     int64_t launchFee;                      // ratio of satoshis to send from contribution to convertible to fee address
     int32_t startBlock;                     // parent chain block # that must kickoff the notarization of block 0, cannot be before this block
     int32_t endBlock;                       // block after which this is considered end-of-lifed
@@ -633,30 +633,36 @@ public:
     }
 };
 
-// This is used on a PBaaS chain to manage reserves of VRSC. type of reserve is assumed to be $VRSC
-class CReserveOutput
+// this is used on either the VRSC chain or PBaaS chain to send transactions to an alternate chain, which will
+// be realized on the other chain using the specified output script.
+// To actually realize the transfer of funds to or from a PBaaS chain, inputs must be aggregated by a miner as inputs to
+// a CCrossChainExport transaction, which may then be imported to the PBaaS chain with one transaction proof proving all inputs
+// being converted to outputs in bulk. This avoids creating the overhead of many redundant transaction proofs
+// which can move a large number of smaller transactions across chains.
+class CCrossChainInput
 {
 public:
-    CAmount nValue;                         // amount of reserve coin in this output
-    CScript scrOut;                         // output script, spend is validated as with a normal bitcoin spend
+    CAmount finalValue;                         // difference between actual output of this tx and final is fee paid
+    CScript scriptPubKey;                       // output script, spend is validated as with a normal bitcoin spend
 
-    CReserveOutput(const std::vector<unsigned char> &asVector)
+    CCrossChainInput() : finalValue(-1) {}
+
+    CCrossChainInput(const std::vector<unsigned char> &asVector)
     {
         FromVector(asVector, *this);
     }
 
-    CReserveOutput(const CAmount value, const CScript &rScrOut)
-    {
-        nValue = value; 
-        scrOut = rScrOut;
-    }
+    CCrossChainInput(const CScript &rScrOut, const CAmount finalout) : scriptPubKey(rScrOut), finalValue(finalout) { }
+
+    CCrossChainInput(const CTransaction &tx);
+    CCrossChainInput(const UniValue &obj);
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream& s, Operation ser_action) {
-        READWRITE(VARINT(nValue));
-        READWRITE(*(CScriptBase*)(&scrOut));
+        READWRITE(finalValue);
+        READWRITE(*(CScriptBase*)(&scriptPubKey));
     }
 
     std::vector<unsigned char> AsVector()
@@ -666,26 +672,68 @@ public:
 
     bool IsValid()
     {
-        return scrOut.size() != 0;
+        return scriptPubKey.size() != 0 && finalValue >= 0;
+    }
+
+    UniValue ToUniValue()
+    {
+        UniValue ret(UniValue::VOBJ);
+        ret.push_back(Pair("finalvalue", finalValue));
+        ret.push_back(Pair("scriptpubkey", scriptPubKey.ToString()));
+        return ret;
     }
 };
 
-// import $VRSC from another chain transaction
-class CReserveImport
+// This is used on a PBaaS chain to transact with reserves of VRSC as a token that can freely convert between
+// the native coin and the token type. type of reserve is assumed to be $VRSC
+class CCrossChainOutput
 {
 public:
-    CAmount nValue;                         // amount of proxy coin in this output
-    CCrossChainProof transferProof;
+    uint160 chainID;                        // from what chain
+    CAmount nValue;                         // amount of token in this output
+    CScript scriptPubKey;                   // output script, spend is validated as with a normal spend
 
-    CReserveImport(const std::vector<unsigned char> &asVector)
+    CCrossChainOutput(uint160 cID, const CScript &rScrOut, const CAmount value) : chainID(cID), nValue(value), scriptPubKey(rScrOut) { }
+    CCrossChainOutput(const std::vector<unsigned char> &asVector)
     {
         FromVector(asVector, *this);
     }
 
-    CReserveImport(const CAmount value, CCrossChainProof &rTransferProof)
+    ADD_SERIALIZE_METHODS;
+
+    template <typename Stream, typename Operation>
+    inline void SerializationOp(Stream& s, Operation ser_action) {
+        READWRITE(chainID);
+        READWRITE(VARINT(nValue));
+        READWRITE(*(CScriptBase*)(&scriptPubKey));
+    }
+
+    std::vector<unsigned char> AsVector()
+    {
+        return ::AsVector(*this);
+    }
+
+    bool IsValid()
+    {
+        return scriptPubKey.size() != 0 && !chainID.IsNull() || nValue >= 0;
+    }
+};
+
+// import transactions from another chain
+// an import transaction on a fractional reserve chain will have an instant spend input of EVAL_CHAIN_IMPORT from the coinbase, 
+// which provides for import of a reserve currency or cross-chain token, or auto-conversion to the native currency.
+class CCrossChainImport
+{
+public:
+    uint160 chainID;                                            // usually the reserve currency, but here for generality
+    CAmount nValue;                                             // amount of proxy coin for final output (difference from actual output divided into 2 fees)
+
+    CCrossChainImport() : nValue(0) { }
+    CCrossChainImport(const CAmount value) : nValue(value) { }
+
+    CCrossChainImport(const std::vector<unsigned char> &asVector)
     {
-        nValue = value; 
-        transferProof = rTransferProof;
+        FromVector(asVector, *this);
     }
 
     ADD_SERIALIZE_METHODS;
@@ -693,7 +741,6 @@ public:
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream& s, Operation ser_action) {
         READWRITE(VARINT(nValue));
-        READWRITE(transferProof);
     }
 
     std::vector<unsigned char> AsVector()
@@ -703,34 +750,44 @@ public:
 
     bool IsValid()
     {
-        return nValue != 0 && transferProof.IsValid();
+        return nValue >= 0 && !chainID.IsNull();
     }
 };
 
-// send $VRSC or VRSCTOKEN to another chain
-class CReserveExport
+// send some amount of $VRSC as VRSCTOKEN to another chain for distribution to original senders, which are 
+// determined by the inputs to this transaction and stored in the opret of this transaction, so they can be
+// validated on the destination chain as one transaction, yet used as the output scripts of the transaction
+// itself
+// The export type determines how the coins are realized on the destination chain, but the destination
+// script will be used in any case.
+class CCrossChainExport
 {
 public:
+    enum EXPORT_TYPE {
+        EXPORT_INVALID = 0,
+        EXPORT_CONVERSION = 1,      // realized on the destination chain as the destination chain currency at market conversion rate
+        EXPORT_SEND = 2             // realized on destination chain as a representative reserve token, unconverted
+    };
+    uint8_t exportType;
     CAmount nValue;
-    uint256 chainDest;
+    uint160 chainID;
 
-    CReserveExport(const std::vector<unsigned char> &asVector)
+    CCrossChainExport() : exportType(EXPORT_INVALID), nValue(0) {}
+
+    CCrossChainExport(const std::vector<unsigned char> &asVector)
     {
         FromVector(asVector, *this);
     }
 
-    CReserveExport(const CAmount value, const uint256 &rChainDest)
-    {
-        nValue = value; 
-        chainDest = rChainDest;
-    }
+    CCrossChainExport(EXPORT_TYPE exporttype, const CAmount value, const uint160 &rChainDest) : exportType(exporttype), nValue(value), chainID(rChainDest) {}
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream& s, Operation ser_action) {
+        READWRITE(exportType);
         READWRITE(VARINT(nValue));
-        READWRITE(chainDest);
+        READWRITE(chainID);
     }
 
     std::vector<unsigned char> AsVector()
@@ -740,7 +797,7 @@ public:
 
     bool IsValid()
     {
-        return nValue != 0 && !chainDest.IsNull();
+        return exportType != EXPORT_INVALID && nValue >= 0 && !chainID.IsNull();
     }
 };
 
@@ -748,29 +805,28 @@ public:
 class CReserveExchange
 {
 public:
-    CScript scrOut;                         // output script for resulting coinbase output
+    uint32_t flags;                         // control of direction and constraints
+    CScript scriptPubKey;                   // output script for resulting coinbase output
     CAmount nLimit;                         // lowest or highest price to sell or buy coin output, may fail if including this tx in block makes price out of range
     uint32_t nValidBefore;                  // if not filled in this block, mine tx, but refund input
-    uint256 chainID;                        // currently supports convert from or to reserve according to conversion rules, this is ouput type
+    uint160 chainID;                        // currently supports convert from or to reserve according to conversion rules, this is ouput type
 
     CReserveExchange(const std::vector<unsigned char> &asVector)
     {
         FromVector(asVector, *this);
     }
 
-    CReserveExchange(const CScript &rScrOut, const CAmount Limit, uint32_t ValidBefore, uint256 ChainID)
-    {
-        scrOut = rScrOut;
-        nLimit = Limit;
-        nValidBefore = ValidBefore;
-        chainID = ChainID;
-    }
+    CReserveExchange() : flags(0), nLimit(0), nValidBefore(0) { }
+
+    CReserveExchange(uint32_t Flags, const CScript &rScrOut, const CAmount Limit, uint32_t ValidBefore, uint160 ChainID) : 
+        flags(Flags), scriptPubKey(rScrOut), nLimit(Limit), nValidBefore(ValidBefore), chainID(ChainID) { }
 
     ADD_SERIALIZE_METHODS;
 
     template <typename Stream, typename Operation>
     inline void SerializationOp(Stream& s, Operation ser_action) {
-        READWRITE(*(CScriptBase*)(&scrOut));
+        READWRITE(flags);
+        READWRITE(*(CScriptBase*)(&scriptPubKey));
         READWRITE(VARINT(nLimit));
         READWRITE(nValidBefore);
         READWRITE(chainID);
@@ -784,7 +840,7 @@ public:
     bool IsValid()
     {
         // this needs an actual check
-        return nValidBefore != 0 && scrOut.size() != 0 && !chainID.IsNull();
+        return nValidBefore != 0 && scriptPubKey.size() != 0 && !chainID.IsNull();
     }
 };
 
index 6b12c6a8aad5dd5e66bb4bed25558731f9e00698..3b9b37eabfdb41c5811b02777fccf1264d27b32f 100644 (file)
@@ -143,6 +143,15 @@ bool GetChainDefinition(uint160 chainID, CPBaaSChainDefinition &chainDef)
         return true;
     }
 
+    if (!IsVerusActive())
+    {
+        if (ConnectedChains.NotaryChain().IsValid() && (chainID == ConnectedChains.NotaryChain().chainDefinition.GetChainID()))
+        {
+            chainDef = ConnectedChains.NotaryChain().chainDefinition;
+            return true;
+        }
+    }
+
     // make the chain definition output
     cp = CCinit(&CC, EVAL_PBAASDEFINITION);
 
@@ -1402,6 +1411,132 @@ UniValue getcrossnotarization(const UniValue& params, bool fHelp)
     return ret;
 }
 
+UniValue sendtochain(const UniValue& params, bool fHelp)
+{
+    if (fHelp || params.size() != 1)
+    {
+        throw runtime_error(
+            "sendtochain '[{\"name\": \"PBAASCHAIN\", \"paymentaddress\": \"RRehdmUV7oEAqoZnzEGBH34XysnWaBatct\", \"amount\": 5.0}]'\n"
+            "\nThis sends a Verus output as a JSON object or lists of Verus outputs as a list of objects to multiple chains or back.\n"
+            "\nFunds are sourced automatically from the current wallet, which must be present, as in sendtoaddress.\n"
+
+            "\nArguments\n"
+            "       {\n"
+            "           \"chain\"          : \"xxxx\",  (string, required) unique Verus ecosystem-wide name/symbol of this PBaaS chain\n"
+            "           \"paymentaddress\" : \"Rxxx\",  (string, required) premine and launch fee recipient\n"
+            "           \"amount\"         : \"n\",     (int64,  required) amount of coins that will be premined and distributed to premine address\n"
+            "           \"convert\"        : \"false\", (bool,   optional) auto-convert to PBaaS currency at current price\n"
+            "       }\n"
+
+            "\nResult:\n"
+            "       \"txid\" : \"transactionid\" (string) The transaction id.\n"
+
+            "\nExamples:\n"
+            + HelpExampleCli("sendtochain", "'[{\"name\": \"PBAASCHAIN\", \"paymentaddress\": \"RRehdmUV7oEAqoZnzEGBH34XysnWaBatct\", \"amount\": 5.0}]'")
+            + HelpExampleRpc("sendtochain", "'[{\"name\": \"PBAASCHAIN\", \"paymentaddress\": \"RRehdmUV7oEAqoZnzEGBH34XysnWaBatct\", \"amount\": 5.0}]'")
+        );
+    }
+
+    // each object represents a send, and all sends are aggregated into one transaction to improve potential for scaling when moving funds between
+    // and across multiple chains.
+    //
+    // each output will require an additional standard cross-chain fee that will be divided evenly in two ways,
+    // between the transaction aggregator -- the miner or staker who creates the aggregating export, 
+    // and the transaction importer on the alternate chain who posts each exported bundle.
+    //
+    vector<CRecipient> outputs;
+    vector<bool> vConvert;
+
+    if (params.size() != 1 || (!params[0].isArray() && !params[0].isObject()))
+    {
+        throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameters. Must provide a single object or single list of objects that represent valid outputs. see help.");
+    }
+
+    const UniValue *pOutputArr = &params[0];
+    UniValue substArr(UniValue::VARR);
+    if (params[0].isObject())
+    {
+        substArr.push_back(params[0]);
+        pOutputArr = &substArr;
+    }
+    const UniValue &objArr = *pOutputArr;
+
+    // convert all entries to CRecipient
+    // any failure fails all
+    for (int i = 0; i < objArr.size(); i++)
+    {
+        // default double fee for miner of chain definition tx
+        // one output for definition, one for finalization
+        string name = uni_get_str(find_value(params[0], "chain"), "");
+        string paymentAddr = uni_get_str(find_value(params[0], "paymentaddress"), "");
+        CAmount amount = uni_get_int64(find_value(params[0], "amount"), -1);
+        bool convert = uni_get_int(find_value(params[0], "convert"), false);
+
+        if (name == "" || paymentAddr == "" || amount < 0)
+        {
+            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid parameters for object #" + to_string(i));
+        }
+
+        CBitcoinAddress ba(DecodeDestination(paymentAddr));
+        CKeyID kID;
+
+        if (!ba.IsValid() || !ba.GetKeyID(kID))
+        {
+            throw JSONRPCError(RPC_INVALID_PARAMETER, "Invalid payment address in object #" + to_string(i));
+        }
+
+        uint160 chainID = CCrossChainRPCData::GetChainID(name);
+        CPBaaSChainDefinition chainDef;
+        // validate that the target chain is still running
+        if (!GetChainDefinition(chainID, chainDef) || !chainDef.IsValid())
+        {
+            throw JSONRPCError(RPC_INVALID_PARAMETER, "Chain specified in object #" + to_string(i) + " is not a valid chain");
+        }
+
+        // validate that the entry is a valid chain being notarized
+        CChainNotarizationData nData;
+        if (GetNotarizationData(chainID, IsVerusActive() ? EVAL_ACCEPTEDNOTARIZATION : EVAL_ACCEPTEDNOTARIZATION, nData))
+        {
+            // if the chain is being notarized and cannot confirm before its end, refuse to send
+            // also, if it hasn't been notarized as recently as the active notarization threshold, refuse as well
+            // TODO: define threshold, for now, only check that last notarization is at least minimum confirmation
+            // distance
+            if ((nData.vtx.size() && 
+                (nData.vtx[nData.bestChain].second.notarizationHeight + (CPBaaSNotarization::MIN_BLOCKS_BETWEEN_ACCEPTED * CPBaaSNotarization::FINAL_CONFIRMATIONS) >
+                    chainDef.endBlock)) ||
+                (!chainDef.eraOptions.size() || !(chainDef.eraOptions[0] & CPBaaSChainDefinition::OPTION_RESERVE)))
+            {
+                throw JSONRPCError(RPC_INVALID_PARAMETER, "Chain specified in object #" + to_string(i) + " is not a valid chain");
+            }
+        }
+        else
+        {
+            throw JSONRPCError(RPC_INVALID_PARAMETER, "Chain specified in object #" + to_string(i) + " is not notarized");
+        }
+
+        // make the output script, either a normal output or a conversion
+
+        CCcontract_info CC;
+        CCcontract_info *cp;
+        cp = CCinit(&CC, EVAL_CROSSCHAIN_INPUT);
+
+        CPubKey pk = CPubKey(ParseHex(CC.CChexstr));
+        // TODO: determine dests properly
+        std::vector<CTxDestination> dests = std::vector<CTxDestination>({CKeyID(chainDef.GetConditionID(EVAL_CROSSCHAIN_INPUT))});
+        CCrossChainInput cci; // TODO fill with payment script and amount (adjust amount for fees)
+        CTxOut ccOut = MakeCC1of1Vout(EVAL_CROSSCHAIN_INPUT, amount, pk, dests, cci);
+        outputs.push_back(CRecipient({ccOut.scriptPubKey, amount, false}));
+    }
+    // send the specified amount to chain ID as an EVAL_CROSSCHAIN_INPUT to the chain ID
+    // the transaction holds the ultimate destination address, and until the transaction
+    // is packaged into an EVAL_CROSSCHAIN_EXPORT bundle, the output can be spent by
+    // the original sender
+    // once bundled, transaction outputs can be transferred to the other chain through a proof of the bundle by anyone and is considered irreversible
+    // all bundled outputs can be moved to and spent on the destination chain as soon as a notarization of the same block
+    // or later has been confirmed. bundling transactions can be done at any time, but moving an export bundle
+    // happens only after is is in a block behind a confirmed notarization.
+}
+
 UniValue definechain(const UniValue& params, bool fHelp)
 {
     if (fHelp || params.size() != 1)
@@ -2075,6 +2210,6 @@ static const CRPCCommand commands[] =
 
 void RegisterPBaaSRPCCommands(CRPCTable &tableRPC)
 {
-    for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
-        tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
+    //for (unsigned int vcidx = 0; vcidx < ARRAYLEN(commands); vcidx++)
+    //    tableRPC.appendCommand(commands[vcidx].name, &commands[vcidx]);
 }
index eecfab83c9c1971d970d79253fe376ad05916227..51391782c209c69c1d05ce4829e510d50c0697ec 100644 (file)
 #include "script/sign.h"
 #include "script/standard.h"
 #include "uint256.h"
+
+#include "cc/CCinclude.h"
+#include "cc/eval.h"
+#include "pbaas/notarization.h"
+
 #ifdef ENABLE_WALLET
 #include "wallet/wallet.h"
 #endif
@@ -334,6 +339,65 @@ void TxToJSON(const CTransaction& tx, const uint256 hashBlock, UniValue& entry)
         ScriptPubKeyToJSON(txout.scriptPubKey, o, true);
         out.push_back(Pair("scriptPubKey", o));
         vout.push_back(out);
+        COptCCParams p;
+        if (IsPayToCryptoCondition(txout.scriptPubKey, p) && p.version >= COptCCParams::VERSION_V2)
+        {
+            switch(p.evalCode)
+            {
+                case EVAL_PBAASDEFINITION:
+                {
+                    CPBaaSChainDefinition definition;
+
+                    if (p.vData.size() && (definition = CPBaaSChainDefinition(p.vData[0])).IsValid())
+                    {
+                        out.push_back(Pair("pbaasChainDefinition", definition.ToUniValue()));
+                    }
+                    break;
+                }
+
+                case EVAL_SERVICEREWARD:
+                {
+                    CServiceReward reward;
+
+                    if (p.vData.size() && (reward = CServiceReward(p.vData[0])).IsValid())
+                    {
+                        out.push_back(Pair("pbaasServiceReward", reward.ToUniValue()));
+                    }
+                    break;
+                }
+
+                case EVAL_EARNEDNOTARIZATION:
+                case EVAL_ACCEPTEDNOTARIZATION:
+                {
+                    CPBaaSNotarization notarization;
+
+                    if (p.vData.size() && (notarization = CPBaaSNotarization(p.vData[0])).IsValid())
+                    {
+                        out.push_back(Pair("pbaasNotarization", notarization.ToUniValue()));
+                    }
+                    break;
+                }
+
+                case EVAL_FINALIZENOTARIZATION:
+                {
+                    CNotarizationFinalization finalization;
+
+                    if (p.vData.size() && (finalization = CNotarizationFinalization(p.vData[0])).IsValid())
+                    {
+                        out.push_back(Pair("pbaasFinalization", finalization.ToUniValue()));
+                    }
+                    break;
+                }
+
+                case EVAL_INSTANTSPEND:
+                case EVAL_CROSSCHAIN_INPUT:
+                case EVAL_CROSSCHAIN_OUTPUT:
+                case EVAL_CROSSCHAIN_EXPORT:
+                case EVAL_CROSSCHAIN_IMPORT:
+                case EVAL_STAKEGUARD:
+                    break;
+            }
+        }
     }
     entry.push_back(Pair("vout", vout));
 
This page took 0.051878 seconds and 4 git commands to generate.