mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-27 14:35:52 +00:00
Bugfixes and new code. Ledger unit test now successfully creates a local
account, creates an initial ledger, closes the initial ledger and opens a new ledger, creates a second account, and adds a transaction to transfer funds to the open ledger.
This commit is contained in:
@@ -5,9 +5,13 @@ AccountState::AccountState(const std::vector<unsigned char>& v)
|
|||||||
{
|
{
|
||||||
Serializer s(v);
|
Serializer s(v);
|
||||||
mValid=false;
|
mValid=false;
|
||||||
if(!s.get160(mAccountID, 0)) return;
|
if(!s.get160(mAccountID, 0)) { assert(false); return; }
|
||||||
if(!s.get64(mBalance, 20)) return;
|
if(!s.get64(mBalance, 20)) { assert(false); return; }
|
||||||
if(!s.get32(mAccountSeq, 28)) return;
|
if(!s.get32(mAccountSeq, 28)) { assert(false); return; }
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cerr << "SerializeAccount >> " << mAccountID.GetHex() << ", " << mBalance << ", " << mAccountSeq <<
|
||||||
|
std::endl;
|
||||||
|
#endif
|
||||||
mValid=true;
|
mValid=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,5 +24,12 @@ std::vector<unsigned char> AccountState::getRaw() const
|
|||||||
s.add160(mAccountID);
|
s.add160(mAccountID);
|
||||||
s.add64(mBalance);
|
s.add64(mBalance);
|
||||||
s.add32(mAccountSeq);
|
s.add32(mAccountSeq);
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cerr << "SerializeAccount << " << mAccountID.GetHex() << ", " << mBalance << ", " << mAccountSeq <<
|
||||||
|
std::endl;
|
||||||
|
uint64 test;
|
||||||
|
assert(s.get64(test, 20));
|
||||||
|
assert(test==mBalance);
|
||||||
|
#endif
|
||||||
return s.getData();
|
return s.getData();
|
||||||
}
|
}
|
||||||
|
|||||||
50
Ledger.cpp
50
Ledger.cpp
@@ -32,7 +32,8 @@ Ledger::Ledger(const uint256 &parentHash, const uint256 &transHash, const uint25
|
|||||||
updateHash();
|
updateHash();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ledger::Ledger(Ledger &prevLedger, uint64 ts) : mTimeStamp(ts), mClosed(false)
|
Ledger::Ledger(Ledger &prevLedger, uint64 ts) : mTimeStamp(ts), mClosed(false),
|
||||||
|
mTransactionMap(new SHAMap()), mAccountStateMap(prevLedger.mAccountStateMap)
|
||||||
{
|
{
|
||||||
prevLedger.updateHash();
|
prevLedger.updateHash();
|
||||||
mParentHash=prevLedger.mHash;
|
mParentHash=prevLedger.mHash;
|
||||||
@@ -87,6 +88,7 @@ bool Ledger::addAccountState(AccountState::pointer state)
|
|||||||
|
|
||||||
bool Ledger::addTransaction(Transaction::pointer trans)
|
bool Ledger::addTransaction(Transaction::pointer trans)
|
||||||
{ // low-level - just add to table
|
{ // low-level - just add to table
|
||||||
|
assert(!!trans->getID());
|
||||||
SHAMapItem::pointer item(new SHAMapItem(trans->getID(), trans->getSigned()->getData()));
|
SHAMapItem::pointer item(new SHAMapItem(trans->getID(), trans->getSigned()->getData()));
|
||||||
return mTransactionMap->addGiveItem(item);
|
return mTransactionMap->addGiveItem(item);
|
||||||
}
|
}
|
||||||
@@ -109,8 +111,17 @@ Transaction::pointer Ledger::getTransaction(const uint256& transID)
|
|||||||
Ledger::TransResult Ledger::applyTransaction(Transaction::pointer trans)
|
Ledger::TransResult Ledger::applyTransaction(Transaction::pointer trans)
|
||||||
{
|
{
|
||||||
ScopedLock l(mLock);
|
ScopedLock l(mLock);
|
||||||
if(trans->getSourceLedger()<mLedgerSeq) return TR_BADLSEQ;
|
if(trans->getSourceLedger()>mLedgerSeq) return TR_BADLSEQ;
|
||||||
if(trans->getAmount()<trans->getFee()) return TR_TOOSMALL;
|
|
||||||
|
if(trans->getAmount()<trans->getFee())
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cerr << "Transaction for " << trans->getAmount() << ", but fee is " <<
|
||||||
|
trans->getFee() << std::endl;
|
||||||
|
#endif
|
||||||
|
return TR_TOOSMALL;
|
||||||
|
}
|
||||||
|
|
||||||
if(!mTransactionMap || !mAccountStateMap) return TR_ERROR;
|
if(!mTransactionMap || !mAccountStateMap) return TR_ERROR;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -132,7 +143,18 @@ Ledger::TransResult Ledger::applyTransaction(Transaction::pointer trans)
|
|||||||
if(!fromAccount || !toAccount) return TR_BADACCT;
|
if(!fromAccount || !toAccount) return TR_BADACCT;
|
||||||
|
|
||||||
// pass sanity checks?
|
// pass sanity checks?
|
||||||
if(fromAccount->getBalance()<trans->getAmount()) return TR_INSUFF;
|
if(fromAccount->getBalance()<trans->getAmount())
|
||||||
|
{
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cerr << "Transaction for " << trans->getAmount() << ", but account has " <<
|
||||||
|
fromAccount->getBalance() << std::endl;
|
||||||
|
#endif
|
||||||
|
return TR_INSUFF;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
if(fromAccount->getSeq()!=trans->getFromAccountSeq())
|
||||||
|
std::cerr << "aSeq=" << fromAccount->getSeq() << ", tSeq=" << trans->getFromAccountSeq() << std::endl;
|
||||||
|
#endif
|
||||||
if(fromAccount->getSeq()>trans->getFromAccountSeq()) return TR_PASTASEQ;
|
if(fromAccount->getSeq()>trans->getFromAccountSeq()) return TR_PASTASEQ;
|
||||||
if(fromAccount->getSeq()<trans->getFromAccountSeq()) return TR_PREASEQ;
|
if(fromAccount->getSeq()<trans->getFromAccountSeq()) return TR_PREASEQ;
|
||||||
|
|
||||||
@@ -226,13 +248,27 @@ bool Ledger::unitTest(void)
|
|||||||
std::cerr << "Account2: " << la2.GetHex() << std::endl;
|
std::cerr << "Account2: " << la2.GetHex() << std::endl;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Ledger newLedger(la1, 10000);
|
Ledger::pointer ledger(new Ledger(la1, 100000));
|
||||||
|
l1.mAmount=100000;
|
||||||
|
|
||||||
|
ledger=Ledger::pointer(new Ledger(*ledger, 0));
|
||||||
|
|
||||||
AccountState::pointer as=newLedger.getAccountState(la1);
|
AccountState::pointer as=ledger->getAccountState(la1);
|
||||||
assert(as);
|
assert(as);
|
||||||
as=newLedger.getAccountState(la2);
|
assert(as->getBalance()==100000);
|
||||||
|
assert(as->getSeq()==0);
|
||||||
|
as=ledger->getAccountState(la2);
|
||||||
assert(!as);
|
assert(!as);
|
||||||
|
|
||||||
|
Transaction::pointer t(new Transaction(NEW, l1, l1.mSeqNum, l2.getAddress(), 2500, 0, 1));
|
||||||
|
assert(!!t->getID());
|
||||||
|
|
||||||
|
Ledger::TransResult tr=ledger->applyTransaction(t);
|
||||||
|
#ifdef DEBUG
|
||||||
|
std::cerr << "Transaction: " << tr << std::endl;
|
||||||
|
#endif
|
||||||
|
assert(tr==TR_SUCCESS);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,33 +7,32 @@
|
|||||||
int Serializer::add16(uint16 i)
|
int Serializer::add16(uint16 i)
|
||||||
{
|
{
|
||||||
int ret=mData.size();
|
int ret=mData.size();
|
||||||
for(int j=0; j<sizeof(i); j++)
|
mData.push_back((unsigned char)(i>>8));
|
||||||
{
|
mData.push_back((unsigned char)(i&0xff));
|
||||||
mData.push_back((unsigned char) (i&0xff));
|
|
||||||
i>>=8;
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Serializer::add32(uint32 i)
|
int Serializer::add32(uint32 i)
|
||||||
{
|
{
|
||||||
int ret=mData.size();
|
int ret=mData.size();
|
||||||
for(int j=0; j<sizeof(i); j++)
|
mData.push_back((unsigned char)(i>>24));
|
||||||
{
|
mData.push_back((unsigned char)((i>>16)&0xff));
|
||||||
mData.push_back((unsigned char) (i&0xff));
|
mData.push_back((unsigned char)((i>>8)&0xff));
|
||||||
i>>=8;
|
mData.push_back((unsigned char)(i&0xff));
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Serializer::add64(uint64 i)
|
int Serializer::add64(uint64 i)
|
||||||
{
|
{
|
||||||
int ret=mData.size();
|
int ret=mData.size();
|
||||||
for(int j=0; j<sizeof(i); j++)
|
mData.push_back((unsigned char)(i>>56));
|
||||||
{
|
mData.push_back((unsigned char)((i>>48)&0xff));
|
||||||
mData.push_back((unsigned char) (i&0xff));
|
mData.push_back((unsigned char)((i>>40)&0xff));
|
||||||
i>>=8;
|
mData.push_back((unsigned char)((i>>32)&0xff));
|
||||||
}
|
mData.push_back((unsigned char)((i>>24)&0xff));
|
||||||
|
mData.push_back((unsigned char)((i>>16)&0xff));
|
||||||
|
mData.push_back((unsigned char)((i>>8)&0xff));
|
||||||
|
mData.push_back((unsigned char)(i&0xff));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,59 +59,51 @@ int Serializer::addRaw(const std::vector<unsigned char> &vector)
|
|||||||
|
|
||||||
bool Serializer::get16(uint16& o, int offset) const
|
bool Serializer::get16(uint16& o, int offset) const
|
||||||
{
|
{
|
||||||
o=0;
|
if((offset+2)>mData.size()) return false;
|
||||||
if((offset+sizeof(o))>mData.size()) return false;
|
o=mData.at(offset++);
|
||||||
for(int i=0, o=0; i<sizeof(o); i++)
|
o<<=8; o|=mData.at(offset);
|
||||||
{
|
|
||||||
o<<=8;
|
|
||||||
o|=mData.at(offset++);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::get32(uint32& o, int offset) const
|
bool Serializer::get32(uint32& o, int offset) const
|
||||||
{
|
{
|
||||||
o=0;
|
if((offset+4)>mData.size()) return false;
|
||||||
if((offset+sizeof(o))>mData.size()) return false;
|
o=mData.at(offset++);
|
||||||
for(int i=0, o=0; i<sizeof(o); i++)
|
o<<=8; o|=mData.at(offset++); o<<=8; o|=mData.at(offset++);
|
||||||
{
|
o<<=8; o|=mData.at(offset);
|
||||||
o<<=8;
|
|
||||||
o|=mData.at(offset++);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::get64(uint64& o, int offset) const
|
bool Serializer::get64(uint64& o, int offset) const
|
||||||
{
|
{
|
||||||
o=0;
|
if((offset+8)>mData.size()) return false;
|
||||||
if((offset+sizeof(o))>mData.size()) return false;
|
o=mData.at(offset++);
|
||||||
for(int i=0, o=0; i<sizeof(o); i++)
|
o<<=8; o|=mData.at(offset++); o<<=8; o|=mData.at(offset++);
|
||||||
{
|
o<<=8; o|=mData.at(offset++); o<<=8; o|=mData.at(offset++);
|
||||||
o<<=8;
|
o<<=8; o|=mData.at(offset++); o<<=8; o|=mData.at(offset++);
|
||||||
o|=mData.at(offset++);
|
o<<=8; o|=mData.at(offset);
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::get160(uint160& o, int offset) const
|
bool Serializer::get160(uint160& o, int offset) const
|
||||||
{
|
{
|
||||||
if((offset+sizeof(o))>mData.size()) return false;
|
if((offset+20)>mData.size()) return false;
|
||||||
memcpy(&o, &(mData.front())+offset, sizeof(o));
|
memcpy(&o, &(mData.front())+offset, 20);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Serializer::get256(uint256& o, int offset) const
|
bool Serializer::get256(uint256& o, int offset) const
|
||||||
{
|
{
|
||||||
if((offset+sizeof(o))>mData.size()) return false;
|
if((offset+32)>mData.size()) return false;
|
||||||
memcpy(&o, &(mData.front())+offset, sizeof(o));
|
memcpy(&o, &(mData.front())+offset, 32);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint256 Serializer::get256(int offset) const
|
uint256 Serializer::get256(int offset) const
|
||||||
{
|
{
|
||||||
uint256 ret;
|
uint256 ret;
|
||||||
if((offset+sizeof(ret))>mData.size()) return ret;
|
if((offset+32)>mData.size()) return ret;
|
||||||
memcpy(&ret, &(mData.front())+offset, sizeof(ret));
|
memcpy(&ret, &(mData.front())+offset, 32);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,20 +26,20 @@ Transaction::Transaction(TransStatus status, LocalAccount& fromLocalAccount, uin
|
|||||||
Transaction::Transaction(const std::vector<unsigned char> &t, bool validate) : mStatus(INVALID)
|
Transaction::Transaction(const std::vector<unsigned char> &t, bool validate) : mStatus(INVALID)
|
||||||
{
|
{
|
||||||
Serializer s(t);
|
Serializer s(t);
|
||||||
if(s.getLength()<145) return;
|
if(s.getLength()<145) { assert(false); return; }
|
||||||
if(!s.get160(mAccountTo, 0)) return;
|
if(!s.get160(mAccountTo, 0)) { assert(false); return; }
|
||||||
if(!s.get64(mAmount, 20)) return;
|
if(!s.get64(mAmount, 20)) { assert(false); return; }
|
||||||
if(!s.get32(mFromAccountSeq, 28)) return;
|
if(!s.get32(mFromAccountSeq, 28)) { assert(false); return; }
|
||||||
if(!s.get32(mSourceLedger, 32)) return;
|
if(!s.get32(mSourceLedger, 32)) { assert(false); return; }
|
||||||
if(!s.get32(mIdent, 36)) return;
|
if(!s.get32(mIdent, 36)) { assert(false); return; }
|
||||||
if(!s.getRaw(mSignature, 69, 72)) return;
|
if(!s.getRaw(mSignature, 69, 72)) { assert(false); return; }
|
||||||
|
|
||||||
std::vector<unsigned char> pubKey;
|
std::vector<unsigned char> pubKey;
|
||||||
if(!s.getRaw(pubKey, 40, 33)) return;
|
if(!s.getRaw(pubKey, 40, 33)) { assert(false); return; }
|
||||||
if(!mFromPubKey.SetPubKey(pubKey)) return;
|
if(!mFromPubKey.SetPubKey(pubKey)) { assert(false); return; }
|
||||||
updateID();
|
updateID();
|
||||||
|
|
||||||
if(validate && !checkSign()) return;
|
if(validate && !checkSign()) { assert(false); return; }
|
||||||
|
|
||||||
mStatus=NEW;
|
mStatus=NEW;
|
||||||
}
|
}
|
||||||
@@ -47,12 +47,23 @@ Transaction::Transaction(const std::vector<unsigned char> &t, bool validate) : m
|
|||||||
bool Transaction::sign(LocalAccount& fromLocalAccount)
|
bool Transaction::sign(LocalAccount& fromLocalAccount)
|
||||||
{
|
{
|
||||||
if( (mAmount==0) || (mSourceLedger==0) || (mAccountTo==0) )
|
if( (mAmount==0) || (mSourceLedger==0) || (mAccountTo==0) )
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
if(mAccountFrom!=fromLocalAccount.mAddress.GetHash160())
|
if(mAccountFrom!=fromLocalAccount.mAddress.GetHash160())
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
Serializer::pointer signBuf=getRaw(true);
|
Serializer::pointer signBuf=getRaw(true);
|
||||||
|
assert(signBuf->getLength()==73+4);
|
||||||
if(!signBuf->makeSignature(mSignature, fromLocalAccount.peekPrivKey()))
|
if(!signBuf->makeSignature(mSignature, fromLocalAccount.peekPrivKey()))
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
assert(mSignature.size()==72);
|
||||||
updateID();
|
updateID();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -71,6 +82,7 @@ Serializer::pointer Transaction::getRaw(bool prefix) const
|
|||||||
{
|
{
|
||||||
Serializer::pointer ret(new Serializer(77));
|
Serializer::pointer ret(new Serializer(77));
|
||||||
if(prefix) ret->add32(0x54584e00u);
|
if(prefix) ret->add32(0x54584e00u);
|
||||||
|
ret->add160(mAccountTo);
|
||||||
ret->addRaw(mFromPubKey.GetPubKey());
|
ret->addRaw(mFromPubKey.GetPubKey());
|
||||||
ret->add64(mAmount);
|
ret->add64(mAmount);
|
||||||
ret->add32(mFromAccountSeq);
|
ret->add32(mFromAccountSeq);
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ We could have made something that inherited from the protobuf transaction but th
|
|||||||
|
|
||||||
enum TransStatus
|
enum TransStatus
|
||||||
{
|
{
|
||||||
NEW, // just received / generated
|
NEW =0, // just received / generated
|
||||||
INVALID, // no valid signature, insufficient funds
|
INVALID =1, // no valid signature, insufficient funds
|
||||||
INCLUDED, // added to the current ledger
|
INCLUDED =2, // added to the current ledger
|
||||||
CONFLICTED, // losing to a conflicting transaction
|
CONFLICTED =3, // losing to a conflicting transaction
|
||||||
COMMITTED, // known to be in a ledger
|
COMMITTED =4, // known to be in a ledger
|
||||||
HELD, // not valid now, maybe later
|
HELD =5, // not valid now, maybe later
|
||||||
REMOVED // taken out of a ledger
|
REMOVED =6 // taken out of a ledger
|
||||||
};
|
};
|
||||||
|
|
||||||
class Account;
|
class Account;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <boost/foreach.hpp>
|
#include <boost/foreach.hpp>
|
||||||
|
|
||||||
LocalAccount::LocalAccount(bool)
|
LocalAccount::LocalAccount(bool) : mAmount(0), mSeqNum(0)
|
||||||
{
|
{
|
||||||
mPrivateKey.MakeNewKey();
|
mPrivateKey.MakeNewKey();
|
||||||
mPublicKey.SetPubKey(mPrivateKey.GetPubKey());
|
mPublicKey.SetPubKey(mPrivateKey.GetPubKey());
|
||||||
|
|||||||
17
key.h
17
key.h
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
#include <openssl/ec.h>
|
#include <openssl/ec.h>
|
||||||
#include <openssl/ecdsa.h>
|
#include <openssl/ecdsa.h>
|
||||||
@@ -176,10 +177,13 @@ public:
|
|||||||
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
|
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);
|
||||||
if (!nSize)
|
if (!nSize)
|
||||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
|
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed");
|
||||||
CPrivKey vchPrivKey(nSize, 0);
|
assert(nSize<=279);
|
||||||
|
CPrivKey vchPrivKey(279, 0);
|
||||||
unsigned char* pbegin = &vchPrivKey[0];
|
unsigned char* pbegin = &vchPrivKey[0];
|
||||||
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
|
if (i2d_ECPrivateKey(pkey, &pbegin) != nSize)
|
||||||
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
|
throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size");
|
||||||
|
assert(vchPrivKey.size()<=279);
|
||||||
|
while(vchPrivKey.size()<279) vchPrivKey.push_back((unsigned char)0);
|
||||||
return vchPrivKey;
|
return vchPrivKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -196,12 +200,15 @@ public:
|
|||||||
std::vector<unsigned char> GetPubKey() const
|
std::vector<unsigned char> GetPubKey() const
|
||||||
{
|
{
|
||||||
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
|
unsigned int nSize = i2o_ECPublicKey(pkey, NULL);
|
||||||
|
assert(nSize<=33);
|
||||||
if (!nSize)
|
if (!nSize)
|
||||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey failed");
|
||||||
std::vector<unsigned char> vchPubKey(nSize, 0);
|
std::vector<unsigned char> vchPubKey(33, 0);
|
||||||
unsigned char* pbegin = &vchPubKey[0];
|
unsigned char* pbegin = &vchPubKey[0];
|
||||||
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
if (i2o_ECPublicKey(pkey, &pbegin) != nSize)
|
||||||
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
throw key_error("CKey::GetPubKey() : i2o_ECPublicKey returned unexpected size");
|
||||||
|
assert(vchPubKey.size()<=33);
|
||||||
|
while(vchPubKey.size()<33) vchPubKey.push_back((unsigned char)0);
|
||||||
return vchPubKey;
|
return vchPubKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -212,6 +219,12 @@ public:
|
|||||||
unsigned int nSize = 0;
|
unsigned int nSize = 0;
|
||||||
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
|
if (!ECDSA_sign(0, (unsigned char*)&hash, sizeof(hash), pchSig, &nSize, pkey))
|
||||||
return false;
|
return false;
|
||||||
|
while(nSize<72)
|
||||||
|
{ // enlarge to 72 bytes
|
||||||
|
pchSig[nSize]=0;
|
||||||
|
nSize++;
|
||||||
|
}
|
||||||
|
assert(nSize==72);
|
||||||
vchSig.resize(nSize);
|
vchSig.resize(nSize);
|
||||||
memcpy(&vchSig[0], pchSig, nSize);
|
memcpy(&vchSig[0], pchSig, nSize);
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
Reference in New Issue
Block a user