Bitcoin Forum
May 12, 2024, 07:41:27 PM *
News: Latest Bitcoin Core release: 27.0 [Torrent]
 
  Home Help Search Login Register More  
  Show Posts
Pages: [1]
1  Bitcoin / Bitcoin Discussion / Re: Zitcoins on: August 14, 2010, 03:26:25 AM
Non-technical factors could still matter enough to change what technology the market decides on.  AFAIK, nobody is really making a huge profit on bitcoin itself at the moment.  If it were to become profitable for a powerful group to run a different system, I think they could do it.  Maybe if for whatever reason Titcoin worked better for the porn industry (a group that definitely sees the value in anonymous money transfer via Internet) and couple big porn sites started promoting and accepting Titcoin, they could get enough advertising together to make Titcoin seem more attractive to the typical end-user.  Or maybe Bob Zitman The Big Businessman decides to invest heavily in an e-currency exchange site, and drops a few million dollars on a PR campaign for Zitcoin (because he thinks he can make a lot more than a few million if enough people use his currency.)
2  Bitcoin / Development & Technical Discussion / Re: Reading/Writing Blocks and FLATDATA on: July 24, 2010, 02:53:05 AM
Thanks for clearing that up for me.

I keep making really elementary code mistakes....
3  Bitcoin / Development & Technical Discussion / Reading/Writing Blocks and FLATDATA on: July 24, 2010, 01:27:32 AM
I'm trying to understand the way Bitcoin stores block data - among other things I want to run some statistics on the block chain / transaction history and check just how anonymous Bitcoin really is.  So I went to the source to see how Bitcoin reads/writes block data to file.

(ETA: this is in 0.3.2)

In main.h we have:

Code: (CBlock::WriteToDisk)
bool WriteToDisk(bool fWriteTransactions, unsigned int& nFileRet, unsigned int& nBlockPosRet)
{
    // Open history file to append
    CAutoFile fileout = AppendBlockFile(nFileRet);
    if (!fileout)
        return error("CBlock::WriteToDisk() : AppendBlockFile failed");
    if (!fWriteTransactions)
        fileout.nType |= SER_BLOCKHEADERONLY;

    // Write index header
    unsigned int nSize = fileout.GetSerializeSize(*this);
    fileout << FLATDATA(pchMessageStart) << nSize;

    // Write block
    nBlockPosRet = ftell(fileout);
    if (nBlockPosRet == -1)
        return error("CBlock::WriteToDisk() : ftell failed");
    fileout << *this;

    // Flush stdio buffers and commit to disk before returning
    fflush(fileout);
#ifdef __WXMSW__
    _commit(_fileno(fileout));
#else
    fsync(fileno(fileout));
#endif

    return true;
}

and

Code: (CBlock::ReadFromDisk)
bool ReadFromDisk(unsigned int nFile, unsigned int nBlockPos, bool fReadTransactions=true)
{
    SetNull();

    // Open history file to read
    CAutoFile filein = OpenBlockFile(nFile, nBlockPos, "rb");
    if (!filein)
        return error("CBlock::ReadFromDisk() : OpenBlockFile failed");
    if (!fReadTransactions)
        filein.nType |= SER_BLOCKHEADERONLY;

    // Read block
    filein >> *this;

    // Check the header
    if (CBigNum().SetCompact(nBits) > bnProofOfWorkLimit)
        return error("CBlock::ReadFromDisk() : nBits errors in block header");
    if (GetHash() > CBigNum().SetCompact(nBits).getuint256())
        return error("CBlock::ReadFromDisk() : GetHash() errors in block header");

    return true;
}

FLATDATA is defined in serialize.h like so:
Code: (FLATDATA)
//
// Wrapper for serializing arrays and POD
// There's a clever template way to make arrays serialize normally, but MSVC6 doesn't support it
//
#define FLATDATA(obj)   REF(CFlatData((char*)&(obj), (char*)&(obj) + sizeof(obj)))
class CFlatData
{
protected:
    char* pbegin;
    char* pend;
public:
    CFlatData(void* pbeginIn, void* pendIn) : pbegin((char*)pbeginIn), pend((char*)pendIn) { }
    char* begin() { return pbegin; }
    const char* begin() const { return pbegin; }
    char* end() { return pend; }
    const char* end() const { return pend; }

    unsigned int GetSerializeSize(int, int=0) const
    {
        return pend - pbegin;
    }

    template<typename Stream>
    void Serialize(Stream& s, int, int=0) const
    {
        s.write(pbegin, pend - pbegin);
    }

    template<typename Stream>
    void Unserialize(Stream& s, int, int=0)
    {
        s.read(pbegin, pend - pbegin);
    }
};

Now - and I apologize if I'm reading this wrong, this is a little more advanced C/C++ code than I'm used to - as I understand it, the FLATDATA call interprets the raw bytes of a CBlock object as an array (stream??) of characters.  The CBlock::WriteToDisk method writes the constant 4-byte message header (0xf9, 0xbe, 0xb4, 0xd9), the size of the CBlock object in bytes, and then the FLATDATA of the CBlock it's writing to disk - which is just the raw bytes of the CBlock object.  So after the header, the data written to file is byte-for-byte the same as the CBlock object represented in memory.  Also, if I'm reading it correctly, CBlock::ReadFromFile copies those bytes directly into the space allocated for a CBlock object in memory to re-create the block.  Is this correct?

Related question - I am under the impression that the exact way an instance of a C++ class is represented internally not guaranteed under standards; compiling a program with different compilers or different optimization flags can change the order in which member variables are stored in memory, and some debug mode compilers even add a few bytes between member variables to make memory inspection easier.  I'm not positive about this, it's just something I've picked up and never seriously questioned.
4  Bitcoin / Bitcoin Discussion / Re: Is Bitcoin that really decentralized, as you believe? on: July 23, 2010, 02:47:09 PM
At this point, if someone released a new client with better features and that was backwards compatible with the old clients, I think people just might adopt it in favor of the old client ... even if it also accepted more rapid block creation or whatever.  Especially if this hypothetical client were to be released by Satoshi and put on the main page.  Once we get a fuller ecosystem with a whole bunch of clients (think how many clients implement Bittorrent) that will be hard - if not impossible - to do.

The official rules of bitcoin aren't written in stone, they're written into the clients.  As long as it is possible that 50%+ of the network could switch to a new client, it is possible that bitcoin could radically change.
5  Bitcoin / Development & Technical Discussion / Re: Scalability and transaction rate on: July 23, 2010, 04:53:45 AM
Thanks for your analysis Hepatizon! It was about what I was expecting.

However, I don't think this is quite correct.

For one thing, the way the blocks are currently set up, it takes linear time with respect to the total number of transactions (and I think more than that in memory) to verify one transaction.  So after 10 years of bitcoin, you need to either go through all 10 years worth of transactions, or have a snapshot of all the account balances of every user ever and work from there. 

It appears that each new transaction has direct links to each prior transaction being used as an input. To validate a transaction you only need to validate the immediate dependancies. You don't need to validate those dependancies' dependancies as they were previously validated as part of the block chain. That means closer to constant time rather than linear.

You're right - I keep forgetting that the actual coins are tracked rather that just the account balance.  So yeah, you only need to go back find whoever last owned the coins in question and verify that they're the same person sending them.  Which is technically linear time in that if the first coin ever was hoarded for ten years you really would need to go through the entire ten year block chain (unless you indexed it, which would be easy as all the coins are numbered) to see who had it - but in practice it would be closer to constant time because most people won't hoard bitcoins.  (Unless they figure out that deflation is all but guaranteed...)  For some reason I keep thinking that you would need to verify the account balance of the sender, and that would require verifying the account balance of everyone who has sent the sender money, and everyone who sent them money, and so forth.
6  Bitcoin / Bitcoin Discussion / Re: Official Bitcoin Unicode Character? on: July 22, 2010, 03:45:26 PM
No, there's a whole set of letters and numbers with circles around them in the Unicode standard.  I honestly have no idea why they're there, but I guess they're coming in handy for us.

http://www.unicode.org/charts/PDF/U2460.pdf
7  Bitcoin / Development & Technical Discussion / Re: Different architecture proposal? on: July 22, 2010, 03:14:00 PM
I've been thinking exactly along these lines.  The main bitcoin process should NOT be tied to the UI at all (and, while a wxWidgets UI is a great way to bootstrap the project, it's NOT a good solution for the long term).

In fact, I'd go so far as to say that one of the next major steps for the bitcoin system is two fold:
  • Create a proper spec of the protocol (if one exists outside of the source code at this point, I haven't found it)
  • Create a second, independent implementation of the protocol

Without a second, independent implementation, you can't be sure that the protocol is correctly documented.

Perhaps the "reference" implementation (which we're all currently using) doesn't need to change, but if I were designing a bitcoin client, it's be structured a LOT differently than the current client.

I second this.  In particular, I would like to see a lightweight client that only handles transactions and doesn't do any CPU-intensive hashing or verifications.  Simply announcing a transaction is something that is well within the capabilities of a cell phone or netbook.  You could even designate a "trusted source" to keep track of your account information - so your cell phone could just ask your home computer how much you had in your wallet rather than trying to figure it out itself.

I'd be willing to make another implementation of the protocol if I can figure out what it is.  The source code is documented ... poorly.
8  Bitcoin / Development & Technical Discussion / Re: Scalability and transaction rate on: July 22, 2010, 03:03:22 PM
As far as I can tell, it's a completely connected network.  And it kind of has to be for the security to work - the main idea is that an attacker needs nearly 50% of the computing power of the entire network to inject false transaction information into (or delete honest transactions from) the network.  If there was a propagation system, you'd only need to to have about 50%+ of whatever the lowest rung is, and then the rung would be duped into transmitting your false information, possibly beating out the other lowest rungs to dupe the next higher up rung, and so on.

The bottleneck was my first reaction when I read about bitcoin.  For one thing, the way the blocks are currently set up, it takes linear time with respect to the total number of transactions (and I think more than that in memory) to verify one transaction.  So after 10 years of bitcoin, you need to either go through all 10 years worth of transactions, or have a snapshot of all the account balances of every user ever and work from there.  And since the blocks form a straight chain, all of those 35,000 transactions need to go into the same block (if block generation continues to average one per ten minutes).  There's currently no way to split that up and have the network work on 350 blocks with 100 transactions each simultaneously, because each block needs the hash of the previous block.  That seems particularly silly with the way bitcoin transactions are verified.  If everyone waits for one to three blocks to verify a transaction before spending their bitcoins, that means that none of the 35,000 transactions in one ten minute period can depend on each other, and most shouldn't even depend on the previous block.  And as far as I can tell, there's no way for the network to speed up block creation in response to transaction overload - if the network ever hit the point where transactions were being made faster than they were being hashed into blocks, the problem would snowball until enough people quit bitcoin out of frustration that the number of transactions dropped below block creation speed.  And if block creation were to speed up (via difficulty decrease) then the reward for hashing a new block would have to go down to maintain the planned rate of bitcoin introduction.  The nodes would have to know that during the Great Bitstorm of August 2013 blocks only netted the creator 2.5 bitcoins - and they'd have to figure it out during the Great Bitstorm of August 2013.

Also, there's a potential problem if block creation speed were to exceed the speed of information on the network.  Chains could be built faster than they would be distributed to the rest of the network, which could mean that two different network segments could work on two different chains simultaneously.

And of course it's worse than 35,000 transactions / ten minutes - we'd probably see something like 50-60k+ transactions during peak hours (depending on how geographically distributed the network is) and much less during the off hours.  There would be a need to dynamically throttle proof-of-work difficulty and coin reward hour-by-hour.  Since bitcoin is computer based, there'll probably eventually be a fair number of automated systems buying and selling bitcoins - a sudden sharp fluctuation in stock markets or currency exchange rates could set those off all at once.  (Although the verification system might help with this, since you can't do microsecond scale trading with bitcoins.)
9  Bitcoin / Development & Technical Discussion / Re: Messing with queries on: July 19, 2010, 02:52:41 PM
So, how does the Bitcoin client determine which nodes to connect to?  I haven't gone through the source thoroughly enough to figure it out yet, but as far as I can tell it either asks the IRC channel who is online and queries those nodes, or sends a request to IRC directly and then gets a response from an arbitrary node?  I think?

I have two main concerns:
1.  Is there any 'first-responder' bias in determining which node to ask for block data from?  If there is, then a malicious user with access to a very low-latency connection could disrupt the network by responding extremely quickly to any request with some form of false data - perhaps simply by saying that no new block has been hashed yet - and get disproportionate influence over the consensus this way.  If HighSpeedCheater can supply information so fast that he responds first 99% of the time to your query, then you need to do 68-69 queries just to get 50/50 odds that you reach a single node that isn't a HighSpeedCheater sockpuppet - and that node itself might be fooled by HighSpeedCheater and unwittingly be repeating false information.  Probably unrealistic for an individual to pull this off, but I can see a big, widely distributed system like a botnet or Google being able to do it.  Even then, nodes could get around it just by checking everything 140x as much as they used to.

Nodes send an inv message to all peers when they get a new block; if a node gets an inv message for an unknown block, it will always request it (initially from the node that announced it, but I believe it moves on to others if that one fails to respond). So all it takes is one connection to a 'good' node and you'll get the real block chain. Additionally, when a connection is established, each node queries the other for its 'best' block, and asks for it if it's unknown.

Okay.  I was confused by this in the function ProcessMessage

Code:
// Ask the first connected node for block updates
        static int nAskedForBlocks;
        if (!pfrom->fClient && (nAskedForBlocks < 1 || vNodes.size() <= 1))
        {
            nAskedForBlocks++;
            pfrom->PushGetBlocks(pindexBest, uint256(0));
        }

I forgot static means that nAskedForBlocks is persistent across function calls.  If it wasn't then the client would ask for blocks from every node that sends it a message.
10  Bitcoin / Development & Technical Discussion / Re: Messing with queries on: July 19, 2010, 02:14:14 PM
There's also the possibility that the entire transaction chain could fork if the latency between any two approximately equal computing groups becomes larger than the average block-creation time.  Suppose that there is roughly the same about of computing power dedicated to hashing Bitcoin blocks in two groups, say the US and Russia.  If - and I can only see this happening if the time between new blocks is very short - it takes more time for a US node to ask a Russian node what the longest block chain is (and vice versa) than it takes for the Russian (or US) Bitcoin network to generate a new block, then chains could develop local to Russia and the US.  Suppose a node in the US and Russia successfully hash the next block at about the same time, call them blocks 1001us and 1001ru.  The network resolves the discrepancy by seeing whether 1002us or 1002ru gets hashed first.  But since there's a delay in getting information from one country to the other, every node in the US that checks a Russian node for their longest chain length gets out-of-date information, so it will see an older, shorter chain than the chain it gets from local, lower latency nodes.  And the same thing happens to the Russians, with the end effect that American nodes keep working on the branch containing 1001us because they can only see an older, shorter version of the 10001ru branch, while the Russians work on theirs for the same reason.  As long as the chain grows faster than the speed of information, neither chain will ever dominate the other.

Since the block production difficulty is automatically calibrated so that blocks come approximately 10 minutes apart from each other, it's unlikely that latency will ever get that high. In any case, though, all it takes is one or two blocks found in quick succession on one chain to throw things out of balance enough for the network to converge on one chain. This also won't affect normal transactions very much - they'll still go through, and generated coins are unusable until 120 blocks go by (by which point a winner should have emerged). The only risk is that someone might spend the same coin once on each of the two chains, to a different recipient - this could result in some confusion, but if you wait for 10-20 blocks to go by before accepting the transaction as 'confirmed', the risk of a fork should be acceptably low.

I don't think this scenario is particularly likely, especially not with the ~10 minutes between block creation.  It could only happen if the block creation speed was raised considerably, and even then it would require two very equal computing groups.  If it was 52-48 split I think the 52% group would eventually win out - I need to run some simulations.  I'd also need to check how stable the two forks would be, and about how long it would take for one to trump the other.  So file this under "bizarre doomsday scenario that's nearly impossible and might not even be that bad if it happens."  As far as block creation time - I could see it having to be reduced substantially.  Each block has a maximum size; if there is a constant time between blocks, then the maximum number of transactions that can be processed per unit time is (max block size) / (avg transaction size) / (block creation time).  If BC takes off and we approach that number, then either max block size needs to go up or block creation time needs to go down.  We'd have to choose option B a lot of times in a row for this scenario to become possible.
11  Bitcoin / Development & Technical Discussion / Messing with queries on: July 19, 2010, 05:56:44 AM
The Bitcoin network accepts blocks as valid if enough of the nodes accept the block as valid.  The inherent security in this is that an attacker trying to manipulate which blocks are accepted as valid or not would need computing power approaching 50% of the entire network.  But it is infeasible to actually query all or even most of the entire network (or at least it will be once the Bitcoin network becomes larger) so in reality each node must take a sample of the network.  If the sample is large enough and randomly distributed over the entire network, there is no problem.  But if a given node preferentially connects to a smaller subset of nodes, then that node is vulnerable - an attacker need only compromise that smaller subset.  Obviously it is in the interests of each node operator to ensure that his node is truly unbiased in determining which node to get block data from.

So, how does the Bitcoin client determine which nodes to connect to?  I haven't gone through the source thoroughly enough to figure it out yet, but as far as I can tell it either asks the IRC channel who is online and queries those nodes, or sends a request to IRC directly and then gets a response from an arbitrary node?  I think?

I have two main concerns:
1.  Is there any 'first-responder' bias in determining which node to ask for block data from?  If there is, then a malicious user with access to a very low-latency connection could disrupt the network by responding extremely quickly to any request with some form of false data - perhaps simply by saying that no new block has been hashed yet - and get disproportionate influence over the consensus this way.  If HighSpeedCheater can supply information so fast that he responds first 99% of the time to your query, then you need to do 68-69 queries just to get 50/50 odds that you reach a single node that isn't a HighSpeedCheater sockpuppet - and that node itself might be fooled by HighSpeedCheater and unwittingly be repeating false information.  Probably unrealistic for an individual to pull this off, but I can see a big, widely distributed system like a botnet or Google being able to do it.  Even then, nodes could get around it just by checking everything 140x as much as they used to.

2.  Can a 'broadcaster' node influence which nodes it responds to?  For example, could Alice set up her system so that every time Bob asks for the most recent block chain, she is the one (or disproportionately more likely to be the one) to answer him?  If so, then Bob is basically at Alice's mercy unless he can figure out which addresses Alice is using faster than she can create new sockpuppets.

There's also the possibility that the entire transaction chain could fork if the latency between any two approximately equal computing groups becomes larger than the average block-creation time.  Suppose that there is roughly the same about of computing power dedicated to hashing Bitcoin blocks in two groups, say the US and Russia.  If - and I can only see this happening if the time between new blocks is very short - it takes more time for a US node to ask a Russian node what the longest block chain is (and vice versa) than it takes for the Russian (or US) Bitcoin network to generate a new block, then chains could develop local to Russia and the US.  Suppose a node in the US and Russia successfully hash the next block at about the same time, call them blocks 1001us and 1001ru.  The network resolves the discrepancy by seeing whether 1002us or 1002ru gets hashed first.  But since there's a delay in getting information from one country to the other, every node in the US that checks a Russian node for their longest chain length gets out-of-date information, so it will see an older, shorter chain than the chain it gets from local, lower latency nodes.  And the same thing happens to the Russians, with the end effect that American nodes keep working on the branch containing 1001us because they can only see an older, shorter version of the 10001ru branch, while the Russians work on theirs for the same reason.  As long as the chain grows faster than the speed of information, neither chain will ever dominate the other.
12  Bitcoin / Bitcoin Discussion / Re: Official Bitcoin Unicode Character? on: July 19, 2010, 05:47:36 AM
My only concern with the slashed-8 is that at first glance it looks a lot like slash-S $.  S and 8 are only one small line apart, and putting the line down the middle makes them look even closer.  That, and an 8 would work better for Bytecoins than Bitcoins.
13  Bitcoin / Bitcoin Discussion / Re: Official Bitcoin Unicode Character? on: July 19, 2010, 03:47:08 AM
I propose something along these lines:


         

A C (or stylized C) with something representing a bit inside.  At some point an actual fontist / graphic designer would need to work on it, though.
14  Bitcoin / Bitcoin Discussion / Re: Which transactions go into which blocks? on: July 19, 2010, 02:45:10 AM
Is the timestamp on the transaction, or just the block?
15  Bitcoin / Bitcoin Discussion / Re: Which transactions go into which blocks? on: July 18, 2010, 09:09:49 PM
The other question - and I know this must have been answered somewhere and I just couldn't find it - what determines transaction uniqueness?  Say Alice buys a widget from Bob for 31.42 bc.  Alice then decides she wants another widget, and places a new order - with the same keys for both buyer and seller - for another 31.42 bc.  What makes these two transactions distinct?  If a node sees one transaction for 31.42 from A to B, then sees a transaction for 31.42 from A to B, what tips it off that these are two distinct transactions rather than the same transaction detected twice?
A few things make those 31.42BTC transactions unique:

+ The timestamps in them will be different.
+ The input transactions will be different (you can think of those as being different 'coins' going in to make the payment).
+ And if the input transactions don't add up to exactly 31.42 (and they probably won't), they'll have different output transactions for returning any change to Alice.

By the way: all that stuff is hashed together to give each transaction a unique 256-bit transaction ID (which you never see, but is used internally so Bitcoin can quickly figure out if it has already seen this transaction before).

Ah, that works.
16  Bitcoin / Bitcoin Discussion / Which transactions go into which blocks? on: July 18, 2010, 03:44:33 PM
I read the paper and did a brief forum search, so I apologize if this has already been asked/answered.

How do nodes determine when to include a particular transaction into a block?

There scenario I'm wondering about is this:
Alice tries to double-spend her coins.  As luck would have it, two different nodes simultaneously hash the next block, 1001, each containing one transaction of Alice's double spending attempt.  Call them 1001a and 1001b.  Then, a node working on 1001a hashes the next block, 1002, and every node sees that the chain containing 1000 -> 1001a -> 1002 is the longest (and most likely to be honest) and halts work on 1001b.  One of Alice's two forks in her double-spending attempts is ignored, and her attempt therefore fails.  The guy who was running the node that made 1001b sees that he almost made 50 bc and gets annoyed, but I guess that's acceptable.

But what happens to the other transactions that were in block 1001b but not in 1001a?  Do they get lost as well?  Suppose Bob also bought something at about the same time as Alice, and his transaction ended up being hashed in 1001b (but not 1001a) as well.  I assume that what happens next is that after chain 1002 gets accepted as legitimate, a node working on 1003 overhears Alice's and Bob's transactions, and then checks to see if the two are already in the chain.  It will find that Alice's transaction is fake, and ignore it, and that Bob's transaction isn't in the chain yet, and add that to the block-in-progress.  But then that means that every transaction has to keep echoing around for at least a few blocks to make sure that it ends up in the accepted chain - and every node that overhears a transaction has to check to make sure it isn't already in the list.

The other question - and I know this must have been answered somewhere and I just couldn't find it - what determines transaction uniqueness?  Say Alice buys a widget from Bob for 31.42 bc.  Alice then decides she wants another widget, and places a new order - with the same keys for both buyer and seller - for another 31.42 bc.  What makes these two transactions distinct?  If a node sees one transaction for 31.42 from A to B, then sees a transaction for 31.42 from A to B, what tips it off that these are two distinct transactions rather than the same transaction detected twice?
Pages: [1]
Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!