From 5e9ed1b72385ffbb451d0dcaf1d2e40e79288472 Mon Sep 17 00:00:00 2001 From: Scott Nadal Date: Sun, 18 Mar 2012 19:39:22 -0700 Subject: [PATCH] PPCoin: Add block signature --- src/main.cpp | 6 +++++ src/main.h | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- src/script.cpp | 2 +- src/script.h | 4 +++ 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 60d0704..4f6a717 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1429,6 +1429,10 @@ bool CBlock::CheckBlock() const if (hashMerkleRoot != BuildMerkleTree()) return DoS(100, error("CheckBlock() : hashMerkleRoot mismatch")); + // Check block signature + if (!CheckBlockSignature()) + return DoS(100, error("CheckBlock() : bad block signature")); + return true; } @@ -3204,6 +3208,8 @@ void static BitcoinMiner(CWallet *pwallet) // Found a solution pblock->nNonce = ByteReverse(nNonceFound); assert(hash == pblock->GetHash()); + // should be able to sign block - assert here for now + assert(pblock->SignBlock(*pwalletMain)); SetThreadPriority(THREAD_PRIORITY_NORMAL); CheckWork(pblock.get(), *pwalletMain, reservekey); diff --git a/src/main.h b/src/main.h index 2e443bf..d8fd222 100644 --- a/src/main.h +++ b/src/main.h @@ -807,6 +807,10 @@ public: unsigned int nBits; unsigned int nNonce; + // ppcoin: block signature (not considered part of header) + // signed by coin base txout[0]'s owner + std::vector vchBlockSig; + // network and disk std::vector vtx; @@ -834,9 +838,15 @@ public: // ConnectBlock depends on vtx being last so it can calculate offset if (!(nType & (SER_GETHASH|SER_BLOCKHEADERONLY))) + { + READWRITE(vchBlockSig); READWRITE(vtx); + } else if (fRead) + { + const_cast(this)->vchBlockSig.clear(); const_cast(this)->vtx.clear(); + } ) void SetNull() @@ -847,6 +857,7 @@ public: nTime = 0; nBits = 0; nNonce = 0; + vchBlockSig.clear(); vtx.clear(); vMerkleTree.clear(); nDoS = 0; @@ -992,12 +1003,13 @@ public: void print() const { - printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vtx=%d)\n", + printf("CBlock(hash=%s, ver=%d, hashPrevBlock=%s, hashMerkleRoot=%s, nTime=%u, nBits=%08x, nNonce=%u, vchBlockSig=%s, vtx=%d)\n", GetHash().ToString().substr(0,20).c_str(), nVersion, hashPrevBlock.ToString().substr(0,20).c_str(), hashMerkleRoot.ToString().substr(0,10).c_str(), nTime, nBits, nNonce, + HexStr(vchBlockSig.begin(), vchBlockSig.end(), true).c_str(), vtx.size()); for (int i = 0; i < vtx.size(); i++) { @@ -1011,6 +1023,51 @@ public: } + bool SignBlock(const CKeyStore& keystore) + { + std::vector > vSolution; + + if (!Solver(vtx[0].vout[0].scriptPubKey, vSolution)) + return false; + BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEY) + { + // Sign + const valtype& vchPubKey = item.second; + CKey key; + if (!keystore.GetKey(Hash160(vchPubKey), key)) + return false; + if (key.GetPubKey() != vchPubKey) + return false; + return key.Sign(GetHash(), vchBlockSig); + } + } + return false; + } + + bool CheckBlockSignature() const + { + std::vector > vSolution; + + if (!Solver(vtx[0].vout[0].scriptPubKey, vSolution)) + return false; + BOOST_FOREACH(PAIRTYPE(opcodetype, valtype)& item, vSolution) + { + if (item.first == OP_PUBKEY) + { + const valtype& vchPubKey = item.second; + CKey key; + if (!key.SetPubKey(vchPubKey)) + return false; + if (vchBlockSig.empty()) + return false; + return key.Verify(GetHash(), vchBlockSig); + } + } + return false; + } + bool DisconnectBlock(CTxDB& txdb, CBlockIndex* pindex); bool ConnectBlock(CTxDB& txdb, CBlockIndex* pindex); bool ReadFromDisk(const CBlockIndex* pindex, bool fReadTransactions=true); diff --git a/src/script.cpp b/src/script.cpp index 12d3f9e..4e588f8 100644 --- a/src/script.cpp +++ b/src/script.cpp @@ -3,6 +3,7 @@ // Distributed under the MIT/X11 software license, see the accompanying // file license.txt or http://www.opensource.org/licenses/mit-license.php. #include "headers.h" +#include "script.h" using namespace std; using namespace boost; @@ -11,7 +12,6 @@ bool CheckSig(vector vchSig, vector vchPubKey, CSc -typedef vector valtype; static const valtype vchFalse(0); static const valtype vchZero(0); static const valtype vchTrue(1, 1); diff --git a/src/script.h b/src/script.h index e61ea2f..3d40964 100644 --- a/src/script.h +++ b/src/script.h @@ -13,6 +13,8 @@ #include +typedef std::vector valtype; + class CTransaction; enum @@ -699,5 +701,7 @@ bool IsMine(const CKeyStore& keystore, const CScript& scriptPubKey); bool ExtractAddress(const CScript& scriptPubKey, const CKeyStore* pkeystore, CBitcoinAddress& addressRet); bool SignSignature(const CKeyStore& keystore, const CTransaction& txFrom, CTransaction& txTo, unsigned int nIn, int nHashType=SIGHASH_ALL, CScript scriptPrereq=CScript()); bool VerifySignature(const CTransaction& txFrom, const CTransaction& txTo, unsigned int nIn, int nHashType=0); +bool Solver(const CScript& scriptPubKey, std::vector >& vSolutionRet); + #endif -- 1.7.1