Skip to content

Commit

Permalink
use pertxout for name operations
Browse files Browse the repository at this point in the history
  • Loading branch information
vinced committed May 16, 2011
1 parent e98b6ae commit 2abfb67
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 75 deletions.
14 changes: 3 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ Please read DESIGN-namecoind.md before proceeding.
BUILDING
======================

Follow the bitcoin build instructions. Use "makefile" - it will generate namecoind. Usage is similar to bitcoind. There are only RPC calls for the new operations. A GUI is on the roadmap.
Building is only supported on Linux for now. Follow the bitcoin build instructions. Use "makefile.unix" - it will generate namecoind. Usage is similar to bitcoind, plus new RPC calls for the new operations. A GUI is on the roadmap.

RUNNING
======================
Expand Down Expand Up @@ -63,17 +63,9 @@ VALUES

Values for names in the d/ namespace are JSON encoded. The simplest value is of this form:

{'map': {'': '10.0.0.1'}}
{"map": {"": "10.0.0.1"}}

which maps all hosts in the domain example.bit to one IP address. But you can also delegate to your DNS servers:

{'map': {'': {'ns': ['10.0.0.1', '10.0.0.2']}}}

or even do a translation step before delegation:

{'map': {'': {'translate': 'bitcoin.org', 'ns': ['10.0.0.1', '10.0.0.2']}}}

in which case, foo.example.bit will be translated to foo.bitcoin.org before it is sent to your DNS servers.
A [full specification](http://dot-bit.org/Domain_names) is in progress.

DNS conduits
=============
Expand Down
10 changes: 7 additions & 3 deletions TODO-namecoin
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@
* other conflicts: update on expired name, firstupdate on expired name_new
* d7cc9e949d invalid number of args
* blockexplorer
* resolver
* IsMine hook to ensure modified clients don't spend namecoins by mistake as regular coins
* listtransactions decode
* IsMine hook to ensure modified clients don't spend namecoins by mistake as regular coins in case of future changes to IsMine
* listtransactions improved decode
* auto-send firstupdate after 6 blocks with persistent name/rand
* review threading
* sideloading resolver library
* reference DNS server
* cross-mining

Bugs

* CWalletTx::GetAmounts nFee is off by 0.01 for name txs because IsMine is false on the name output
* Reports of crashes, bdb was mentioned
101 changes: 41 additions & 60 deletions namecoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ extern int64 AmountFromValue(const Value& value);
extern Object JSONRPCError(int code, const string& message);
template<typename T> void ConvertTo(Value& value);

extern bool SelectCoins(int64 nTargetValue, set<CWalletTx*>& setCoinsRet);
extern bool SelectCoins(int64 nTargetValue, set<pair<CWalletTx*,unsigned int> >& setCoinsRet, int64& nValueRet);

static const int NAMECOIN_TX_VERSION = 0x7100;
static const int64 MIN_AMOUNT = CENT;
Expand Down Expand Up @@ -238,39 +238,25 @@ bool CreateTransactionWithInputTx(const vector<pair<CScript, int64> >& vecSend,
foreach (const PAIRTYPE(CScript, int64)& s, vecSend)
wtxNew.vout.push_back(CTxOut(s.second, s.first));

int64 nWtxinCredit;

if (wtxIn.fSpent)
{
// non-name outputs have been spent, only grab name output value
nWtxinCredit = wtxIn.vout[nTxOut].nValue;
printf("input credit / spent = %d\n", nWtxinCredit);
}
else
{
// no part of wtxIn was spent, grab the entire coin
nWtxinCredit = wtxIn.GetCredit();
printf("input credit / non-spent = %d\n", nWtxinCredit);
}
int64 nWtxinCredit = wtxIn.vout[nTxOut].nValue;

// Choose coins to use
set<CWalletTx*> setCoins;
if (!SelectCoins(nTotalValue - nWtxinCredit, setCoins))
return false;
set<pair<CWalletTx*, unsigned int> > setCoins;
int64 nValueIn = 0;
if (!SelectCoins(nTotalValue - nWtxinCredit, setCoins, nValueIn))
return false;

vector<CWalletTx*> vecCoins(setCoins.begin(), setCoins.end());
vector<pair<CWalletTx*, unsigned int> >
vecCoins(setCoins.begin(), setCoins.end());

foreach(CWalletTx* pcoin, vecCoins)
foreach(PAIRTYPE(CWalletTx*, unsigned int)& coin, vecCoins)
{
// wtxIn non-name outputs might have been spent
int64 nCredit = pcoin->GetCredit();
nValueIn += nCredit;
dPriority += (double)nCredit * pcoin->GetDepthInMainChain();
int64 nCredit = coin.first->vout[coin.second].nValue;
dPriority += (double)nCredit * coin.first->GetDepthInMainChain();
}

// Input tx always at first position
vecCoins.insert(vecCoins.begin(), &wtxIn);
vecCoins.insert(vecCoins.begin(), make_pair(&wtxIn, nTxOut));

nValueIn += nWtxinCredit;
dPriority += (double)nWtxinCredit * wtxIn.GetDepthInMainChain();
Expand Down Expand Up @@ -305,37 +291,24 @@ bool CreateTransactionWithInputTx(const vector<pair<CScript, int64> >& vecSend,
reservekey.ReturnKey();

// Fill vin
foreach(CWalletTx* pcoin, vecCoins)
for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
{
// three cases:
// * this is wtxIn name output, which can only be spent by this function - grab it
// * this is a wtxIn non-name output and the non-name part of the coin was already spent - skip
// * this is not wtxIn - we already checked it wasn't spent, grab it
if (pcoin == &wtxIn && nOut == nTxOut)
{
if (pcoin->vout[nOut].IsMine())
throw runtime_error("CreateTransactionWithInputTx() : wtxIn[nTxOut] already mine");
wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut));
}
else if (!pcoin->fSpent && pcoin->vout[nOut].IsMine())
wtxNew.vin.push_back(CTxIn(pcoin->GetHash(), nOut));
}
foreach(PAIRTYPE(CWalletTx*, unsigned int)& coin, vecCoins)
wtxNew.vin.push_back(CTxIn(coin.first->GetHash(), coin.second));

// Sign
int nIn = 0;
foreach(CWalletTx* pcoin, vecCoins)
for (int nOut = 0; nOut < pcoin->vout.size(); nOut++)
foreach(PAIRTYPE(CWalletTx*, unsigned int)& coin, vecCoins)
{
if (coin.first == &wtxIn && coin.second == nTxOut)
{
if (pcoin == &wtxIn && nOut == nTxOut)
{
if (!SignNameSignature(*pcoin, wtxNew, nIn++))
throw runtime_error("could not sign name coin output");
}
else if (!pcoin->fSpent && pcoin->vout[nOut].IsMine())
if (!SignSignature(*pcoin, wtxNew, nIn++))
return false;
if (!SignNameSignature(*coin.first, wtxNew, nIn++))
throw runtime_error("could not sign name coin output");
}
else
{
if (!SignSignature(*coin.first, wtxNew, nIn++))
return false;
}
}

// Limit size
unsigned int nBytes = ::GetSerializeSize(*(CTransaction*)&wtxNew, SER_NETWORK);
Expand Down Expand Up @@ -801,7 +774,7 @@ Value name_update(const Array& params, bool fHelp)

Value name_new(const Array& params, bool fHelp)
{
if (fHelp)
if (fHelp || params.size() != 1)
throw runtime_error(
"name_new <name>\n"
);
Expand Down Expand Up @@ -845,15 +818,20 @@ void UnspendInputs(CWalletTx& wtx)
continue;
}
CWalletTx& prev = mapWallet[txin.prevout.hash];
int nOut = txin.prevout.n;

setCoins.insert(&prev);
}
foreach(CWalletTx* pcoin, setCoins)
{
printf("UnspendInputs(): %s spent %d\n", pcoin->GetHash().ToString().c_str(), pcoin->fSpent);
pcoin->fSpent = false;
pcoin->WriteToDisk();
vWalletUpdated.push_back(pcoin->GetHash());
printf("UnspendInputs(): %s:%d spent %d\n", prev.GetHash().ToString().c_str(), nOut, prev.IsSpent(nOut));

if (nOut >= prev.vout.size())
throw runtime_error("CWalletTx::MarkSpent() : nOut out of range");
prev.vfSpent.resize(prev.vout.size());
if (prev.vfSpent[nOut])
{
prev.vfSpent[nOut] = false;
prev.fAvailableCreditCached = false;
prev.WriteToDisk();
}
vWalletUpdated.push_back(prev.GetHash());
}
}

Expand Down Expand Up @@ -894,6 +872,9 @@ Value deletetransaction(const Array& params, bool fHelp)

Value name_clean(const Array& params, bool fHelp)
{
if (fHelp || params.size())
throw runtime_error("name_clean\nClean unsatisfiable transactions from the wallet - including name_update on an already taken name\n");

CRITICAL_BLOCK(cs_main)
CRITICAL_BLOCK(cs_mapWallet)
{
Expand Down
2 changes: 1 addition & 1 deletion serialize.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CDataStream;
class CAutoFile;
static const unsigned int MAX_SIZE = 0x02000000;

static const int VERSION = 32250;
static const int VERSION = 32150;
static const char* pszSubVer = "";
static const bool VERSION_IS_BETA = true;

Expand Down

0 comments on commit 2abfb67

Please sign in to comment.