- When a miner starts trying to hash a block of transactions, do they "choose" which transactions go in the block, or do they just throw in all transactions they've received that were not in the last block? I assume that they can, in theory, choose to ignore transactions that don't have fees, but does that really happen?
That depends on the miner. If you are mining in a pool, then the pool decides for you which transactions will be in the block. All they need to send you is the block header since that is all that needs to be hashed to reach the target difficulty.
If you are solo mining, the rules of the protocol allow you to choose the transactions if you want to write a program to do that. Most solo miners use software that selects based on the priority based rules in the reference client.
- While a miner is hashing a new block, which includes x transactions, how do they respond if a new transaction comes in? Do they include the new transactions and start hashing again, or do they ignore the new transactions?
I would expect that most miners would continue with the block header as is at least until all values in the nonce are used up. Beyond that I don't know if any pools or mining software reselect the transactions, but my guess is that they don't. Seems like an opportunity lost there to grab some high value transactions if any happen to come in.
I'm currently under the impression that a block being hashed has x transactions which would result (always) in a given hash, so the miner changes the nonce so that they can get a new hash. Is that correct?
Yes.
Could they, instead, re-order the listing of transactions in the block, and would that produce a new hash?
Yes but it would be slower because they'd have to re-calculate the merkle root each time they do that.
- How does the network resolve forks in the chain? By which I mean two miners come up with two different, valid solutions to the same block, and push their changes to the network. Some clients receive new Block A, and some get new Block B. Those clients now start working on the NEXT block even while the new blocks are propagating, etc. It would seem that one solution will spread out faster, but how do clients following the "bad" chain fix the error? Do they look at a timestamp and select the earliest? Do they select the block with the most transactions?
They end up in a race with some of the network looking for a block that builds on Block A, and some of the network looking for a block that builds on Block B. Which ever part of the network finds their block first broadcasts it out relaying through peers and when peers see that there is now a blockchain that is longer than the one they are working on, their block becomes orphaned and they adopt the new longer chain.