check my code- - Message header
(4) message start
(12) command
(4) size
The message start string is designed to be unlikely to occur in normal data.
The characters are rarely used upper ascii, not valid as UTF-8, and produce
a large 4-byte int at any alignment.
Check start string
Check the command string for errors
Must be all zeros after the first zero
Message size
disk only
socket
flood
inventory based relay
broadcast and subscription
fClient = false; set by version message
Push a version message
We're using mapAskFor as a priority queue,
the key is the earliest time the request can be sent
Patch in the size
printf("%02x ", vSend[i] & 0xff);
Put on lists to offer to the other nodes
Save original serialized message so newer versions are preserved
Expire old relay messages
Global state
mapNextTx is only used anymore to track disk tx outpoints used by memory txes
mapKeys
mapWallet
Inserts only if not already there, returns tx inserted or tx found
debug print
Merge
Write to disk
Notify UI
Refresh UI
Reaccept any txes of ours that aren't already in a block
Rebroadcast any of our txes that aren't in a block yet
CTransaction
Load the block this tx is in
Update the tx's hashBlock
Locate the transaction
Fill in merkle branch
Is the tx in a block that's in the main chain
Relinquish previous transactions' posNext pointers
Get prev tx from disk
Version -1 tells unserialize to set version so we write back same version
Relinquish posNext pointer
Write back
Put a blocked-off copy of this transaction in the test pool
Remove transaction from index
Resurect single transaction objects
Take over previous transactions' posNext pointers
Get prev tx from single transactions in memory
Get prev tx from disk
Version -1 tells unserialize to set version so we write back same version
If tx will only be connected in a reorg,
then these outpoints will be checked at that time
Verify signature
Check for conflicts
Flag outpoints as used
Write back
Tally transaction fees
Add transaction to test pool
Add transaction to disk index
Delete redundant single transaction objects
Coinbase is only valid in a block, not as a loose transaction
Check for conflicts with in-memory transactions
and allow replacing with a newer version of the same transaction
Check against previous transactions
Store transaction in memory
If updated, erase old tx from wallet
Find the block it claims to be in
Get merkle root
Make sure the merkle branch connects to this block
CBlock and CBlockIndex
Cache
Go back 30 days
Load first and last block
Limit one change per timespan
Work back to the first block in the orphan chain
issue here: it doesn't know the version
Watch for transactions paying to me
Find the fork
List of what to disconnect
List of what to connect
Pretest the reorg
Invalid block, delete the rest of this branch
Disconnect shorter branch
Connect longer branch
Add to block index
New best
Adding to current best branch
New best branch
New best link
Relay wallet transactions that haven't gotten in yet
Scan ahead to the next pchMessageStart, which should normally be immediately
at the file pointer.  Leaves file pointer at end of pchMessageStart.
FAT32 filesize max 4GB, fseek and ftell max 2GB, so we must stay under 2GB
Load from disk
debug
Genesis Block:
GetHash()      = 0x000006b15d1327d67e971d1de9116bd60a3a01556c91b6ebaa416ebc0cfaa646
hashPrevBlock  = 0x0000000000000000000000000000000000000000000000000000000000000000
hashMerkleRoot = 0x769a5e93fac273fd825da42d39ead975b5d712b2d50953f35a4fdebdec8083e3
txNew.vin[0].scriptSig      = 247422313
txNew.vout[0].nValue        = 10000
...            txNew.vout[0].scriptPubKey  = OP_CODESEPARATOR 0x31D18A083F381B4BDE37B649AACF8CD0AFD88C53A3587ECD...
nTime          = 1221069728
nBits          = 20
nNonce         = 141755
CBlock(hashPrevBlock=000000, hashMerkleRoot=769a5e, nTime=1221069728, nBits=20, nNonce=141755, vtx=1)
CTransaction(vin.size=1, vout.size=1, nLockTime=0)
CTxIn(COutPoint(000000, -1), coinbase 04695dbf0e)
CTxOut(nValue=10000, nSequence=4294967295, scriptPubKey=51b0, posNext=null)
vMerkleTree: 769a5e
Genesis block
debug print
Start new block file
Read index header
Read block header
Skip transactions
break; is this all we want to do if there's a file error like this?
Add to block index without updating disk
precompute tree structure
test
mapNext[pindex->pprev].push_back(pindex);
print split or gap
print columns
print item
put the main timechain first
iterate children
Size limits
Check timestamp
Check proof of work matches claimed amount
First transaction must be coinbase, the rest must not be
Check transactions
Check merkleroot
Check for duplicate
Get prev block index
Check timestamp against prev
Check proof of work
Check transaction inputs and verify signatures
Write block to history file
Add atoms to user reviews for coins created
Check for duplicate
Preliminary checks
If don't already have its previous block, shunt it off to holding area until we get it
Ask this guy to fill in what we're missing
Store to disk
Now process any orphan blocks that depended on this one
Messages
Don't know what it is, just say we already got one
Message format
(4) message start
(12) command
(4) size
(x) data
Scan for message start
Read header
Message size
Rewind and wait for rest of message
need a mechanism to give up waiting for overlong message size error
Copy message to its own buffer
Process message
Can only do this once
Ask the first connected node for block updates
Must have a version message before anything else
Store the new addresses
Put on lists to send to other nodes
Send block from disk
Send stream from relay memory
Find the first block the caller has in the main chain
Send the rest of the chain
Find the owner's new transactions
Upgrade transaction to a fully supported CWalletTx
debug print
need to expand the time range if not enough found
int64 nSince = GetAdjustedTime() - 60 * 60; in the last hour
we have a chance to check the order here
Keep giving the same key to the same ip until they use it
Send back approval of order and pubkey to use
Broadcast
Send back confirmation
Ignore unknown commands for extensibility
Don't send anything until we get their version message
Message: addr
Message: inventory
Message: getdata
BitcoinMiner
Create coinbase tx
CBigNum bnNonce; this nonce is so multiple processes working for the same keyUser
BN_rand_range(&bnNonce, &CBigNum(INT_MAX));  don't cover the same ground
Create new block
Add our coinbase tx as first transaction
Collect the latest transactions into the block
Find if all dependencies are in this or previous blocks
if (nTransactionFee < 0) could require a tx fee here
Add tx to block
Update last few things
Prebuild hash buffer
Get time of previous block
Search
debug print
Process this block the same as if we had received it from another node
Update nTime every few seconds
Actions
List of values less than target
Solve subset sum by stochastic approximation
If the next larger is still closer, return it
Choose coins to use
Fill vout[0] to the payee
Fill vout[1] back to self with any change
Use the same key as one of the coins
Fill vout[1] to ourself
Fill vin
Fill vtxPrev by copying from previous transactions vtxPrev
Add tx to wallet, because if it has change it's also ours,
otherwise just for transaction history.
Mark old coins as spent
Broadcast
This must not fail. The transaction has already been signed and recorded.
static const int64 TRANSACTIONFEE = 1 * CENT; /change this to a user options setting, optional fee can be zero
static const unsigned int MINPROOFOFWORK = 40; /need to decide the right difficulty to start with
static const unsigned int MINPROOFOFWORK = 20;  /ridiculously easy for testing
An input of a transaction.  It contains the location of the previous
transaction's output that it claims and a signature that matches the
output's public key.
An output of a transaction.  It contains the public key that the next input
must be able to sign with to claim it.
disk only
CDiskTxPos posNext;  so far this is only used as a flag, nothing uses the location
The basic transaction that is broadcasted on the network and contained in
blocks.  A transaction can contain multiple inputs and outputs.
Set version on stream for writing back same version
Basic checks that don't depend on any context
Check for negative values
Read transaction
Return file pointer
A transaction with a merkle branch linking it to the timechain
A transaction with a bunch of additional info that only the owner cares
about.  It includes any unrecorded transactions needed to link it back
to the timechain.
probably need to sign the order info so know it came from payer
would be nice for it to return the version number it reads, maybe use a reference
Nodes collect new transactions into a block, hash them into a hash tree,
and scan through nonce values to make the block's hash satisfy proof-of-work
requirements.  When they solve the proof-of-work, they broadcast the block
to everyone and the block is added to the timechain.  The first transaction
in the block is a special one that creates a new coin owned by the creator
of the block.
Blocks are appended to blk0001.dat files on disk.  Their location on disk
is indexed by CBlockIndex objects in memory.
header
network and disk
memory only
ConnectBlock depends on vtx being last so it can calculate offset
Open history file to append
Write index header
Write block
Open history file to read
Read block
Check the header
The timechain is a tree shaped structure starting with the
genesis block at the root, with each block potentially having multiple
candidates to be the next block.  pprev and pnext link a path through the
main/longest chain.  A blockindex may have multiple pprev pointing back
to it, but pnext will only point forward to the longest branch, or will
be null if the block is not part of the longest chain.
Open history file
Overwrite with empty null block
Describes a place in the timechain to another node such that if the
other node doesn't have the same branch, it can find a recent common trunk.
The further back it is, the further before the branch point it may be.
Exponentially larger steps back
Find the first block the caller has in the main chain
Find the first block the caller has in the main chain
Global state variables
New address
Services have been added
If the dialog might get closed before the reply comes back,
call this in the destructor so it doesn't get called after it's deleted.
Look for an existing connection
Connect
debug print
debug print
Add node
todo: need to set last failed connect time, and increment a failed to connect counter
debug print
All of a nodes broadcasts and subscriptions are automatically torn down
when it goes down, so a node has to stay up to keep its broadcast going.
Cancel and delete unsourced broadcasts
Cancel subscriptions
Disconnect nodes
Disconnect duplicate connections
In case two nodes connect to each other at once,
the lower ip disconnects its outbound connection
Disconnect unused nodes
remove from vNodes
hold in disconnected pool until all refs are released
Delete disconnected nodes
wait until threads are done using it
Find which sockets have data to receive
timeout.tv_usec = 50000; frequency to poll pnode->vSend
debug
Accept new connections
Service each socket
Receive
typical socket buffer is 8K-64K
socket closed gracefully
socket error
Send
number of connections may still need to be increased before release
Initiate network connections
Make a list of unique class C's
Taking advantage of mapAddresses being in sorted order,
with IPs of the same class C grouped together.
The IP selection process is designed to limit vulnerability to address flooding.
Any class C (a.b.c.?) has an equal chance of being chosen, then an IP is
chosen within the class C.  An attacker may be able to allocate many IPs, but
they would normally be concentrated in blocks of class C's.  They can hog the
attention within their class C, but not the whole IP address space overall.
A lone node in a class C will get as much attention as someone holding all 255
IPs in another class C.
Choose a random class C
Organize all addresses in the class C by IP
Choose a random IP in the class C
Once we've chosen an IP, we'll try every given port before moving on
Advertise our address
Get as many addresses as we can
should the one on the receiving end do this too?
Subscribe our local subscription list
Wait
Poll the connected nodes for messages
Receive messages
Send messages
Wait and allow messages to bunch up
todo: start one thread per processor, use getenv("NUMBER_OF_PROCESSORS")
Sockets startup
Get local host ip
Create socket for listening for incoming connections
Set to nonblocking, incomming connections will also inherit this
The sockaddr_in structure specifies the address family,
IP address, and port for the socket that is being bound
Listen for incoming connections
Start threads
Sockets shutdown