betprotocol functions

This commit is contained in:
Scott Sadler
2018-04-03 04:48:24 -03:00
parent 660b32c300
commit 375927407b
18 changed files with 371 additions and 55 deletions

240
src/cc/betprotocol.cpp Normal file
View File

@@ -0,0 +1,240 @@
#include <cryptoconditions.h>
#include "primitives/transaction.h"
class DisputeHeader
{
public:
int waitBlocks;
std::vector<unsigned char> vmParams;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(VARINT(waitBlocks));
READWRITE(vmParams);
}
};
static CScript CCPubKey(const CC *cond)
{
unsigned char buf[1000];
size_t len = cc_conditionBinary(cond, buf);
return CScript() << std::vector<unsigned char>(buf, buf+len) << OP_CHECKCRYPTOCONDITION;
}
static CScript CCSig(const CC *cond)
{
unsigned char buf[1000];
size_t len = cc_fulfillmentBinary(cond, buf, 1000);
auto ffill = std::vector<unsigned char>(buf, buf+len);
ffill.push_back(SIGHASH_ALL);
return CScript() << ffill;
}
static unsigned char* CopyPubKey(CPubKey pkIn)
{
auto *pk = malloc(33);
memcpy(pk, pkIn.begin(), 33); // TODO: compressed?
return pk;
}
class PokerProtocol
{
public:
CAmount MINFEE = 1;
std::vector<CPubKey> players;
DisputeHeader disputeHeader;
// on PANGEA
CC* MakeDisputeCond();
CMutableTransaction MakeSessionTx(CTxIn dealerInput);
CMutableTransaction MakeDisputeTx(uint256 signedSessionTxHash);
CMutableTransaction MakePostEvidenceTx(uint256 signedSessionTxHash,
CPubKey playerKey, std::vector<unsigned char> state);
// on KMD
CC* MakePayoutCond();
CMutableTransaction MakeStakeTx(CAmount totalPayout, std::vector<CTxIn> playerInputs,
uint256 signedSessionTx);
CMutableTransaction MakeAgreePayoutTx(std::vector<CTxOut> payouts,
CC *signedPayoutCond, uint256 signedStakeTxHash);
CMutableTransaction MakeImportPayoutTx(std::vector<CTxOut> payouts,
CC *signedPayoutCond, CTransaction signedDisputeTx);
}
CC* PokerProtocol::MakeDisputeCond()
{
CC *disputePoker = cond->subconditions[0] = cc_new(CC_Eval);
char err[1000];
std::vector<unsigned char> headerData;
disputeHeader >> CDataStream(headerData, SER_DISK, PROTOCOL_VERSION);
disputePoker->paramsBin = malloc(headerData.size());
memcpy(disputePoker->paramsBin, headerData.data());
disputePoker.paramsBinLength = headerData.size();
CC *spendSig = cond->subconditions[1] = cc_new(CC_Threshold);
spendSig->threshold = 1;
spendSig->size = players.size() + 1;
spendSig->subconditions = malloc(spendSig->size, sizeof(CC*));
for (int i=0; i<players.size()+1; i++) {
CC *sub = spendSig->subconditions[i] = cc_new(CC_Secp256k1);
sub->publicKey = CopyPubKey(players[i]);
}
CC *cond = cc_new(CC_Threshold);
cond->threshold = 2;
cond->size = 2;
cond->subconditions = calloc(2, sizeof(CC*));
cond->subconditions[0] = disputePoker;
cond->subconditions[1] = spendSig;
return cond;
}
CMutableTransaction PokerProtocol::MakeSessionTx(CTxIn dealerInput)
{
CMutableTransaction mtx;
mtx.vin.push_back(dealerInput);
CC *disputeCond = MakeDisputeCond(players, disputeHeader);
mtx.vout.push_back(CTxOut(MINFEE, CCPubKey(disputeCond)));
cc_free(disputeCond);
for (int i=0; i<players.size(); i++) {
CC *cond = cc_new(CC_Secp256k1);
cond->publicKey = CopyPubKey(players[i]);
mtx.vout.push_back(CTxOut(MINFEE, CCPubKey(cond)));
cc_free(cond);
}
return mtx;
}
CMutableTransaction PokerProtocol::MakeDisputeTx(uint256 signedSessionTxHash, CC *signedDisputeCond, uint256 vmResultHash)
{
CMutableTransaction mtx;
CC *disputeCond = MakeDisputeCond();
mtx.vin.push_back(CTxIn(signedSessionTxHash, 0, CCSig(signedDisputeCond)));
std::vector<unsigned char> result(vmResultHash.begin(), vmResultHash.begin()+32);
mtx.vout.push_back(CTxOut(0, CScript() << OP_RETURN << result));
return mtx;
}
CMutableTransaction PokerProtocol::MakePostEvidenceTx(uint256 signedSessionTxHash,
int playerIdx, std::vector<unsigned char> state)
{
CMutableTransaction mtx;
CC *cond = cc_new(CC_Secp256k1);
cond->publicKey = CopyPubKey(players[i]);
mtx.vin.push_back(CTxIn(signedSessionTxHash, playerIdx+1, CCSig(cond)));
mtx.vout.push_back(CTxOut(0, CScript() << OP_RETURN << state));
return mtx;
}
CC* CCNewThreshold(int t, std::vector<CC*> v)
{
CC *cond = cc_new(CC_Threshold);
cond->threshold = t;
cond->size = v.size();
cond->subconditions = calloc(1, sizeof(CC*));
memcpy(cond->subconditions, v.data(), v.size() * sizeof(CC*));
return cond;
}
CCNewSecp256k1(CPubKey &k)
{
cond = cc_new(CC_Secp256k1);
cond->publicKey = CopyPubKey(players[i]);
return cond;
}
CCNewEval(char *method, unsigned char* paramsBin, size_t len)
{
CC *cond = cc_new(CC_Eval);
strcpy(cond->method, method);
cond->paramsBin = malloc(32);
memcpy(cond->paramsBin, bin, len);
cond->paramsBinLength = len;
return cond;
}
CC* MakePayoutCond(uint256 signedSessionTx)
{
CC* agree;
{
// TODO: 2/3 majority
std::vector<CC*> subs;
for (int i=0; i<players.size(); i++)
subs[i] = CCNewSecp256k1(players[i]);
agree = CCNewThreshold(players.size(), subs);
}
CC *import;
{
CC *importEval = CCNewEval("ImportPayout", signedSessionTx.begin(), 32);
std::vector<CC*> subs;
for (int i=0; i<players.size(); i++)
subs[i] = CCNewSecp256k1(players[i]);
CC *oneof = CCNewThreshold(1, subs);
import = CCNewThreshold(2, {oneof, importEval});
}
return CCNewThreshold(1, {agree, import});
}
CMutableTransaction PokerProtocol::MakeStakeTx(CAmount totalPayout, std::vector<CTxIn> playerInputs,
uint256 signedSessionTx)
{
CMutableTransaction mtx;
mtx.vin = playerInputs;
CC *payoutCond = MakePayoutCond(signedSessionTx);push
mtx.vout.push_back(CTxOut(totalPayout, CCPubKey(payoutCond)));
cc_free(payoutCond);
return mtx;
}
CMutableTransaction PokerProtocol::MakeAgreePayoutTx(std::vector<CTxOut> payouts,
CC *signedPayoutCond, uint256 signedStakeTxHash)
{
CMutableTransaction mtx;
mtx.vin.push_back(CTxIn(signedStakeTxHash, 0, CCSig(signedPayoutCond)));
mtx.vouts = payouts;
return mtx;
}
CMutableTransaction PokerProtocol::MakeImportPayoutTx(std::vector<CTxOut> payouts,
CC *signedPayoutCond, CTransaction signedDisputeTx, uint256 signedStakeTxHash)
{
std::vector<unsigned char> vDisputeTx;
signedDisputeTx >> CDataStream(vDisputeTx, SER_DISK, PROTOCOL_VERSION);
CMutableTransaction mtx;
mtx.vin.push_back(CTxInput(signedStakeTxHash, 0, CCSig(signedPayoutCond)));
mtx.vout = payouts;
CMutableTransaction.vout.insert(0, CTxOutput(0, CScript() << OP_RETURN << "PROOF HERE"));
CMutableTransaction.vout.insert(1, CTxOutput(0, CScript() << OP_RETURN << vDisputeTx));
}

View File

@@ -3,27 +3,10 @@
#include "chain.h"
#include "main.h"
#include "cc/eval.h"
#include "cc/importpayout.h"
#include "cryptoconditions/include/cryptoconditions.h"
class MomProof
{
public:
uint256 notaryHash;
int nPos; // Position of imported tx in MoM
std::vector<uint256> branch;
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(notaryHash);
READWRITE(VARINT(nPos));
READWRITE(branch);
}
};
extern int32_t komodo_notaries(uint8_t pubkeys[64][33],int32_t height,uint32_t timestamp);
bool DerefNotaryPubkey(const COutPoint &prevout, char *pk33)
@@ -89,11 +72,7 @@ bool GetMoM(const uint256 notaryHash, uint256 &mom)
return 1;
}
uint256 ExecMerkle(uint256 hash, const std::vector<uint256>& vMerkleBranch, int nIndex)
{
return CBlock::CheckMerkleBranch(hash, vMerkleBranch, nIndex);
}
#define ExecMerkle CBlock::CheckMerkleBranch
/*
@@ -157,13 +136,13 @@ bool CheckImportPayout(const CC *cond, const CTransaction *payoutTx, int nIn)
std::vector<unsigned char> vchMomProof;
if (!GetOpReturnData(payoutTx->vout[0].scriptPubKey, vchMomProof)) return 0;
MomProof momProof;
MoMProof momProof;
CDataStream(vchMomProof, SER_DISK, PROTOCOL_VERSION) >> momProof;
uint256 mom;
if (!GetMoM(momProof.notaryHash, mom)) return 0;
if (!GetMoM(momProof.notarisationHash, mom)) return 0;
uint256 proofResult = ExecMerkle(disputeTx.GetHash(), momProof.branch, momProof.nPos);
uint256 proofResult = ExecMerkle(disputeTx.GetHash(), momProof.branch, momProof.nIndex);
if (proofResult != mom) return 0;
}

26
src/cc/importpayout.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef KOMODO_TXPROOF_H
#define KOMODO_TXPROOF_H
class MoMProof
{
public:
int nIndex;
std::vector<uint256> branch;
uint256 notarisationHash;
MoMProof() {}
MoMProof(int i, std::vector<uint256> b, uint256 n) : notarisationHash(n), nIndex(i), branch(b) {}
ADD_SERIALIZE_METHODS;
template <typename Stream, typename Operation>
inline void SerializationOp(Stream& s, Operation ser_action, int nType, int nVersion) {
READWRITE(VARINT(nIndex));
READWRITE(branch);
READWRITE(notarisationHash);
}
};
#endif /* KOMODO_TXPROOF_H */

View File

@@ -17,7 +17,7 @@ make
## Status
JSON interface not particularly safe. The rest is getting there.
JSON interface may not be particularly safe. The rest is pretty good now.
## Embedding

View File

@@ -16,7 +16,7 @@ struct CCType;
enum CCTypeId {
CC_Condition = -1,
CC_Anon = -1,
CC_Preimage = 0,
CC_Prefix = 1,
CC_Threshold = 2,

View File

@@ -17,8 +17,7 @@ static CC *mkAnon(const Condition_t *asnCond) {
printf("Unknown ASN type: %i", asnCond->present);
return 0;
}
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_AnonType;
CC *cond = cc_new(CC_Anon);
cond->conditionType = realType;
const CompoundSha256Condition_t *deets = &asnCond->choice.thresholdSha256;
memcpy(cond->fingerprint, deets->fingerprint.buf, 32);

View File

@@ -255,7 +255,7 @@ CC *cc_readConditionBinary(const unsigned char *cond_bin, size_t length) {
int cc_isAnon(const CC *cond) {
return cond->type->typeId == CC_Condition;
return cond->type->typeId == CC_Anon;
}
@@ -281,9 +281,10 @@ char *cc_typeName(const CC *cond) {
return cc_isAnon(cond) ? cond->conditionType->name : cond->type->name;
}
CC *cc_new(int typeId) {
CC *cond = malloc(sizeof(CC*));
cond->type = CCTypeRegistry[type];
CC *cond = calloc(1, sizeof(CC));
cond->type = CCTypeRegistry[typeId];
return cond;
}

View File

@@ -104,8 +104,7 @@ static CC *ed25519FromJSON(const cJSON *params, unsigned char *err) {
}
}
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_Ed25519Type;
CC *cond = cc_new(CC_Ed25519);
cond->publicKey = pk;
cond->signature = sig;
return cond;
@@ -125,8 +124,7 @@ static void ed25519ToJSON(const CC *cond, cJSON *params) {
static CC *ed25519FromFulfillment(const Fulfillment_t *ffill) {
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_Ed25519Type;
CC *cond = cc_new(CC_Ed25519);
cond->publicKey = malloc(32);
memcpy(cond->publicKey, ffill->choice.ed25519Sha256.publicKey.buf, 32);
cond->signature = malloc(64);

View File

@@ -42,11 +42,10 @@ static CC *evalFromJSON(const cJSON *params, unsigned char *err) {
return NULL;
}
CC *cond = calloc(1, sizeof(CC));
CC *cond = cc_new(CC_Eval);
strcpy(cond->method, method_item->valuestring);
cond->paramsBin = paramsBin;
cond->paramsBinLength = paramsBinLength;
cond->type = &CC_EvalType;
return cond;
}
@@ -64,8 +63,7 @@ static void evalToJSON(const CC *cond, cJSON *params) {
static CC *evalFromFulfillment(const Fulfillment_t *ffill) {
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_EvalType;
CC *cond = cc_new(CC_Eval);
EvalFulfillment_t *eval = &ffill->choice.evalSha256;

View File

@@ -42,8 +42,7 @@ static CC *prefixFromFulfillment(const Fulfillment_t *ffill) {
PrefixFulfillment_t *p = ffill->choice.prefixSha256;
CC *sub = fulfillmentToCC(p->subfulfillment);
if (!sub) return 0;
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_PrefixType;
CC *cond = cc_new(CC_Prefix);
cond->maxMessageLength = p->maxMessageLength;
cond->prefix = calloc(1, p->prefix.size);
memcpy(cond->prefix, p->prefix.buf, p->prefix.size);
@@ -88,8 +87,7 @@ static CC *prefixFromJSON(const cJSON *params, unsigned char *err) {
return NULL;
}
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_PrefixType;
CC *cond = cc_new(CC_Prefix);
cond->maxMessageLength = (unsigned long) mml_item->valuedouble;
cond->subcondition = sub;

View File

@@ -18,8 +18,7 @@ static CC *preimageFromJSON(const cJSON *params, unsigned char *err) {
}
unsigned char *preimage_b64 = preimage_item->valuestring;
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_PreimageType;
CC *cond = cc_new(CC_Preimage);
cond->preimage = base64_decode(preimage_b64, &cond->preimageLength);
return cond;
}
@@ -45,8 +44,7 @@ static unsigned char *preimageFingerprint(const CC *cond) {
static CC *preimageFromFulfillment(const Fulfillment_t *ffill) {
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_PreimageType;
CC *cond = cc_new(CC_Preimage);
PreimageFulfillment_t p = ffill->choice.preimageSha256;
cond->preimage = calloc(1, p.preimage.size);
memcpy(cond->preimage, p.preimage.buf, p.preimage.size);

View File

@@ -202,8 +202,7 @@ static CC *cc_secp256k1Condition(const unsigned char *publicKey, const unsigned
memcpy(sig, signature, SECP256K1_SIG_SIZE);
}
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_Secp256k1Type;
CC *cond = cc_new(CC_Secp256k1);
cond->publicKey = pk;
cond->signature = sig;
return cond;

View File

@@ -119,8 +119,7 @@ static CC *thresholdFromFulfillment(const Fulfillment_t *ffill) {
}
}
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_ThresholdType;
CC *cond = cc_new(CC_Threshold);
cond->threshold = threshold;
cond->size = size;
cond->subconditions = subconditions;
@@ -173,8 +172,7 @@ static CC *thresholdFromJSON(const cJSON *params, unsigned char *err) {
return NULL;
}
CC *cond = calloc(1, sizeof(CC));
cond->type = &CC_ThresholdType;
CC *cond = cc_new(CC_Threshold);
cond->threshold = (long) threshold_item->valuedouble;
cond->size = cJSON_GetArraySize(subfulfillments_item);
cond->subconditions = calloc(cond->size, sizeof(CC*));

View File

@@ -419,6 +419,7 @@ int32_t komodo_notarized_height(uint256 *hashp,uint256 *txidp)
}
}
int32_t komodo_MoMdata(int32_t *notarized_htp,uint256 *MoMp,uint256 *kmdtxidp,int32_t height)
{
int32_t i; char symbol[KOMODO_ASSETCHAIN_MAXLEN],dest[KOMODO_ASSETCHAIN_MAXLEN]; struct komodo_state *sp; struct notarized_checkpoint *np = 0;

View File

@@ -8,6 +8,7 @@
#include "chainparams.h"
#include "checkpoints.h"
#include "consensus/validation.h"
#include "cc/importpayout.h"
#include "main.h"
#include "primitives/transaction.h"
#include "rpcserver.h"
@@ -621,6 +622,83 @@ UniValue height_MoM(const UniValue& params, bool fHelp)
return ret;
}
UniValue txMoMproof(const UniValue& params, bool fHelp)
{
uint256 hash, notarisationHash, MoM;
int32_t notarisedHeight, depth;
CBlockIndex* blockIndex;
std::vector<uint256> branch;
int nIndex;
// parse params and get notarisation data for tx
{
if ( fHelp || params.size() != 1)
throw runtime_error("txmomproof needs a txid");
uint256 hash(uint256S(params[0].get_str()));
uint256 blockHash;
CTransaction tx;
if (!GetTransaction(hash, tx, blockHash, true))
throw runtime_error("cannot find transaction");
blockIndex = mapBlockIndex[blockHash];
depth = komodo_MoM(&notarisedHeight, &MoM, &notarisationHash, blockIndex->nHeight);
if (!depth)
throw runtime_error("notarisation not found");
// index of block in MoM leaves
nIndex = notarisedHeight - blockIndex->nHeight;
}
// build merkle chain from blocks to MoM
{
// since the merkle branch code is tied up in a block class
// and we want to make a merkle branch for something that isnt transactions
CBlock fakeBlock;
for (int i=0; i<depth; i++) {
uint256 mRoot = chainActive[notarisedHeight - i]->hashMerkleRoot;
CTransaction fakeTx;
// first value in CTransaction memory is it's hash
memcpy((void*)&fakeTx, mRoot.begin(), 32);
fakeBlock.vtx.push_back(fakeTx);
}
branch = fakeBlock.GetMerkleBranch(nIndex);
}
// Now get the tx merkle branch
{
CBlock block;
if (fHavePruned && !(blockIndex->nStatus & BLOCK_HAVE_DATA) && blockIndex->nTx > 0)
throw JSONRPCError(RPC_INTERNAL_ERROR, "Block not available (pruned data)");
if(!ReadBlockFromDisk(block, blockIndex))
throw JSONRPCError(RPC_INTERNAL_ERROR, "Can't read block from disk");
// Locate the transaction in the block
int nTxIndex;
for (nTxIndex = 0; nTxIndex < (int)block.vtx.size(); nTxIndex++)
if (block.vtx[nTxIndex].GetHash() == hash)
break;
if (nTxIndex == (int)block.vtx.size())
throw JSONRPCError(RPC_INTERNAL_ERROR, "Error locating tx in block");
// concatenate branches
std::vector<uint256> txBranch = block.GetMerkleBranch(nTxIndex);
nIndex = nIndex << txBranch.size() + nTxIndex;
branch.insert(branch.begin(), txBranch.begin(), txBranch.end());
}
// Encode and return
CDataStream ssProof(SER_NETWORK, PROTOCOL_VERSION);
ssProof << MoMProof(nIndex, branch, notarisationHash);
return HexStr(ssProof.begin(), ssProof.end());
}
UniValue minerids(const UniValue& params, bool fHelp)
{
uint32_t timestamp = 0; UniValue ret(UniValue::VOBJ); UniValue a(UniValue::VARR); uint8_t minerids[2000],pubkeys[65][33]; int32_t i,j,n,numnotaries,tally[129];

View File

@@ -126,6 +126,7 @@ static const CRPCConvertParam vRPCConvertParams[] =
{ "paxpending", 0 },
{ "notaries", 2 },
{ "height_MoM", 1 },
{ "txMoMproof", 1 },
{ "minerids", 1 },
{ "kvsearch", 1 },
{ "kvupdate", 4 },

View File

@@ -297,6 +297,7 @@ static const CRPCCommand vRPCCommands[] =
{ "blockchain", "paxprices", &paxprices, true },
{ "blockchain", "notaries", &notaries, true },
{ "blockchain", "height_MoM", &height_MoM, true },
{ "blockchain", "txMoMproof", &txMoMproof, true },
{ "blockchain", "minerids", &minerids, true },
{ "blockchain", "kvsearch", &kvsearch, true },
{ "blockchain", "kvupdate", &kvupdate, true },

View File

@@ -305,6 +305,7 @@ extern UniValue z_getpaymentdisclosure(const UniValue& params, bool fHelp); // i
extern UniValue z_validatepaymentdisclosure(const UniValue &params, bool fHelp); // in rpcdisclosure.cpp
extern UniValue height_MoM(const UniValue& params, bool fHelp);
extern UniValue txMoMproof(const UniValue& params, bool fHelp);
extern UniValue notaries(const UniValue& params, bool fHelp);
extern UniValue minerids(const UniValue& params, bool fHelp);
extern UniValue kvsearch(const UniValue& params, bool fHelp);