Browse Source

Rvalidate

pull/4/head
jl777 5 years ago
parent
commit
2188a60318
  1. 1
      src/cc/CCinclude.h
  2. 25
      src/cc/cclib.cpp
  3. 119
      src/cc/dilithium.c

1
src/cc/CCinclude.h

@ -201,6 +201,7 @@ CScript EncodeTokenCreateOpRet(uint8_t funcid, std::vector<uint8_t> origpubkey,
CScript EncodeTokenImportOpRet(std::vector<uint8_t> origpubkey, std::string name, std::string description, uint256 srctokenid, std::vector<std::pair<uint8_t, vscript_t>> oprets);
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, std::pair<uint8_t, vscript_t> opretWithId);
CScript EncodeTokenOpRet(uint256 tokenid, std::vector<CPubKey> voutPubkeys, std::vector<std::pair<uint8_t, vscript_t>> oprets);
int64_t AddCClibtxfee(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk);
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description);
uint8_t DecodeTokenCreateOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description, std::vector<std::pair<uint8_t, vscript_t>> &oprets);
uint8_t DecodeTokenImportOpRet(const CScript &scriptPubKey, std::vector<uint8_t> &origpubkey, std::string &name, std::string &description, uint256 &srctokenid, std::vector<std::pair<uint8_t, vscript_t>> &oprets);

25
src/cc/cclib.cpp

@ -504,6 +504,31 @@ int64_t AddCClibInputs(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubK
return(totalinputs);
}
int64_t AddCClibtxfee(struct CCcontract_info *cp,CMutableTransaction &mtx,CPubKey pk)
{
char coinaddr[64]; int64_t txfee = 10000; uint256 txid,hashBlock; CTransaction vintx; int32_t vout;
std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> > unspentOutputs;
GetCCaddress(cp,coinaddr,pk);
SetCCunspents(unspentOutputs,coinaddr);
for (std::vector<std::pair<CAddressUnspentKey, CAddressUnspentValue> >::const_iterator it=unspentOutputs.begin(); it!=unspentOutputs.end(); it++)
{
txid = it->first.txhash;
vout = (int32_t)it->first.index;
//char str[65]; fprintf(stderr,"%s check %s/v%d %.8f vs %.8f\n",coinaddr,uint256_str(str,txid),vout,(double)it->second.satoshis/COIN,(double)threshold/COIN);
if ( it->second.satoshis < txfee )
continue;
if ( GetTransaction(txid,vintx,hashBlock,false) != 0 )
{
if ( (nValue= IsCClibvout(cp,vintx,vout,coinaddr)) != 0 && myIsutxo_spentinmempool(ignoretxid,ignorevin,txid,vout) == 0 )
{
mtx.vin.push_back(CTxIn(txid,vout,CScript()));
return(it->second.satoshis);
} //else fprintf(stderr,"nValue %.8f too small or already spent in mempool\n",(double)nValue/COIN);
} else fprintf(stderr,"couldnt get tx\n");
}
return(0);
}
std::string Faucet2Fund(struct CCcontract_info *cp,uint64_t txfee,int64_t funds)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());

119
src/cc/dilithium.c

@ -2929,6 +2929,29 @@ int32_t main(void)
void calc_rmd160_sha256(uint8_t rmd160[20],uint8_t *data,int32_t datalen);
char *bitcoin_address(char *coinaddr,uint8_t addrtype,uint8_t *pubkey_or_rmd160,int32_t len);
struct dilithium_handle
{
UT_hash_handle hh;
uint256 destpubtxid;
char handle[32];
} *Dilithium_handles;
struct dilithium_handle *dilithium_handlenew(std::string handle)
{
struct dilithium_handle *hashstr = 0;
if ( handle.size() < sizeof(Dilithium_handles[0].handle)-1 )
{
HASH_FIND(hh,Dilithium_handles,handle,(int32_t)handle.size(),hashstr);
if ( hashstr == 0 )
{
hashstr = calloc(1,sizeof(*hashstr));
strncpy(hashstr->handle,handle.c_str(),sizeof(hashstr->handle));
HASH_ADD_KEYPTR(hh,Dilithium_handles,hashstr->handle,(int32_t)handle.size(),hashstr);
}
}
return(hashstr);
}
int32_t dilithium_Qmsghash(uint8_t *msg,CTransaction tx,int32_t numvouts,std::vector<uint256> voutpubtxids)
{
CScript data; uint256 hash; int32_t i,numvins,len = 0; std::vector<uint256> vintxids; std::vector<int32_t> vinprevns; std::vector<CTxOut> vouts;
@ -3110,12 +3133,20 @@ UniValue dilithium_keypair(uint64_t txfee,struct CCcontract_info *cp,cJSON *para
return(result);
}
CPubKey Faucet_pubkeyget()
{
struct CCcontract_info *cp,C;
cp = CCinit(&C,EVAL_FAUCET);
return(GetUnspendable(cp,0));
}
UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
{
CMutableTransaction mtx = CreateNewContextualCMutableTransaction(Params().GetConsensus(), komodo_nextheight());
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey mypk,dilithiumpk; uint8_t seed[SEEDBYTES],pk[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES]; char coinaddr[64],str[CRYPTO_SECRETKEYBYTES*2+1]; std::vector<uint8_t> bigpub; int32_t i,n,warningflag = 0;
UniValue result(UniValue::VOBJ); std::string rawtx; CPubKey faucetpk,mypk,dilithiumpk; uint8_t seed[SEEDBYTES],pk[CRYPTO_PUBLICKEYBYTES],sk[CRYPTO_SECRETKEYBYTES]; char coinaddr[64],str[CRYPTO_SECRETKEYBYTES*2+1]; int64_t CCchange,inputs; std::vector<uint8_t> bigpub; int32_t i,n,warningflag = 0;
if ( txfee == 0 )
txfee = DILITHIUM_TXFEE;
faucetpk = Faucet_pubkeyget();
mypk = pubkey2pk(Mypubkey());
dilithiumpk = GetUnspendable(cp,0);
if ( params != 0 && ((n= cJSON_GetArraySize(params)) == 1 || n == 2) )
@ -3132,14 +3163,23 @@ UniValue dilithium_register(uint64_t txfee,struct CCcontract_info *cp,cJSON *par
result.push_back(Pair("skaddr",dilithium_addr(coinaddr,sk,CRYPTO_SECRETKEYBYTES)));
for (i=0; i<CRYPTO_PUBLICKEYBYTES; i++)
bigpub.push_back(pk[i]);
if ( AddNormalinputs(mtx,mypk,3*txfee,64) >= 3*txfee )
if ( (inputs= AddCClibtxfee(cp,mtx,dilithiumpk)) > 0 )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,dilithiumpk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_registeropret(handle,mypk,bigpub));
return(musig_rawtxresult(result,rawtx));
} else return(cclib_error(result,"couldnt find enough funds"));
} else return(cclib_error(result,"not enough parameters"));
if ( inputs > txfee )
CCchange = (inputs - txfee);
else CCchange = 0;
if ( AddNormalinputs(mtx,mypk,COIN+3*txfee,64) >= 3*txfee )
{
mtx.vout.push_back(MakeCC1vout(cp->evalcode,2*txfee,dilithiumpk));
mtx.vout.push_back(MakeCC1vout(cp->evalcode,txfee,mypk));
mtx.vout.push_back(MakeCC1vout(EVAL_FAUCET,COIN,faucetpk));
if ( CCchange != 0 )
mtx.vout.push_back(MakeCC1vout(cp->evalcode,CCchange,dilithiumpk));
rawtx = FinalizeCCTx(0,cp,mtx,mypk,txfee,dilithium_registeropret(handle,mypk,bigpub));
return(musig_rawtxresult(result,rawtx));
} else return(cclib_error(result,"couldnt find enough funds"));
} else return(cclib_error(result,"not enough parameters"));
} else return(cclib_error(result,"not dilithiumpk funds"));
}
UniValue dilithium_sign(uint64_t txfee,struct CCcontract_info *cp,cJSON *params)
@ -3452,6 +3492,65 @@ bool dilithium_Qvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,co
} else return eval->Invalid("unexpected zero signerpubtxid");
}
bool dilithium_Rvalidate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
{
static int32_t didinit;
std::vector<std::pair<CAddressIndexKey, CAmount> > txids;
uint256 txid,hashBlock; int32_t numvouts; struct dilithium_handle *hashstr; std::string handle; std::vector<uint8_t> bigpub; CTransaction txi; CPubKey pub33,dilithiumpk; CTxOut vout,vout0; char CCaddr[64];
dilithiumpk = GetUnspendable(cp,0);
if ( didinit == 0 )
{
GetCCaddress(cp,CCaddr,dilithiumpk);
SetCCtxids(txids,CCaddr);
for (std::vector<std::pair<CAddressIndexKey, CAmount> >::const_iterator it=txids.begin(); it!=txids.end(); it++)
{
txid = it->first.txhash;
if ( myGetTransaction(txid,txi,hashBlock) != 0 && (numvouts= txi.vout.size()) > 1 )
{
if ( dilithium_registeropretdecode(handle,pub33,bigpub,txi.vout[numvouts-1].scriptPubKey) == 'R' )
{
if ( (hashstr= dilithium_handlenew(handle)) != 0 )
{
if ( hashstr->destpubtxid != txid )
{
if ( hashstr->destpubtxid != zeroid )
fprintf(stderr,"overwriting %s %s with %s\n",handle.c_str(),hashstr->destpubtxid.GetHex().c_str(),txid.GetHex().c_str());
fprintf(stderr,"%s <- %s\n",handle.c_str(),txid.GetHex().c_str());
hashstr->destpubtxid = txid;
}
}
}
}
}
didinit = 1;
}
if ( (numvouts= tx.vout.size()) <= 1 )
return eval->Invalid("not enough vouts for registration tx");
else if ( dilithium_registeropretdecode(handle,pub33,bigpub,tx.vout[numvouts-1].scriptPubKey) == 'R' )
{
// relies on all current block tx to be put into mempool
txid = tx.GetHash();
vout0 = MakeCC1vout(cp->evalcode,2*DILITHIUM_TXFEE,dilithiumpk);
vout = MakeCC1vout(EVAL_FAUCET,COIN,Faucet_pubkeyget());
if ( tx.vout[0] != vout0 )
return eval->Invalid("mismatched vout0 for register");
else if ( tx.vout[1].nValue != DILITHIUM_TXFEE )
return eval->Invalid("vout1 for register not txfee");
else if ( tx.vout[2] != vout )
return eval->Invalid("register not sending to faucet");
else if ( (hashstr= dilithium_handlenew(handle)) == 0 )
return eval->Invalid("error creating dilithium handle");
else if ( hashstr->destpubtxid == zeroid )
{
hashstr->destpubtxid = txid;
return(true);
}
else if ( hashstr->destpubtxid == txid )
return(true);
else return eval->Invalid("duplicate dilithium handle rejected");
} else return eval->Invalid("couldnt decode register opret");
}
bool dilithium_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,const CTransaction tx)
{
CPubKey destpub33; std::string handle; uint256 hashBlock,destpubtxid,checktxid; CTransaction vintx; int32_t numvouts,mlen,smlen=CRYPTO_BYTES+32; std::vector<uint8_t> sig,vopret; uint8_t msg[32],msg2[CRYPTO_BYTES+32],pk[CRYPTO_PUBLICKEYBYTES],*script;
@ -3459,7 +3558,9 @@ bool dilithium_validate(struct CCcontract_info *cp,int32_t height,Eval *eval,con
numvouts = tx.vout.size();
GetOpReturnData(tx.vout[numvouts-1].scriptPubKey,vopret);
script = (uint8_t *)vopret.data();
if ( script[1] == 'Q' )
if ( script[1] == 'R' )
return(dilithium_Rvalidate(cp,height,eval,tx));
else if ( script[1] == 'Q' )
return(dilithium_Qvalidate(cp,height,eval,tx));
else if ( tx.vout.size() != 2 )
return eval->Invalid("numvouts != 2");

Loading…
Cancel
Save