The programming error that cost Mt. Gox 2609 Bitcoins
righto.com
righto.com
Lose testcoins, not Bitcoins.
http://blog.magicaltux.net/2009/09/19/striving-for-a-better-...
Incidentally, this is why "test first" is more than just a methodology for selling high-priced consultants. At least it lets you see your tests fail and then pass, rather than just pass. Lots of common patterns pass in the presence of incorrect code.
An example that a coworker was complaining to me about recently:
void testFooBarException() {
try {
thisShouldThrowFooBarException()
} catch (FooBarException ignored) {}
}
Can you spot the bug? The test still passes even if thisShouldThrowFooBarException doesn't throw an exception. Oops.I personally avoid this by checking that I can make the test fail when I expect it to fail, by editing some values or commenting something out. But that doesn't scale, that only saves you once.
Something to think about.
void testFooBarException() {
try {
thisShouldThrowFooBarException()
fail() // Should have thrown exception
} catch (FooBarException ignored) {}
}
If you're feeling super fancy, you can even do some asserts in the catch block to make sure the FooBarException has an expected exception message. assertRaises(FooBarException, thisShouldThrowFooBarException)
Impossible to mistype, and states exactly what should happen. @Test(expected = FooBarException.class)
void testFooBarException() {
thisShouldThrowFooBarException()
} /**
* Tests that thisShouldThrowFooBarException throws FooBarException
*
* @expectedException FooBarException
*/
public function testFooBarException() {
thisShouldThrowFooBarException();
}
but I much prefer /**
* Tests that thisShouldThrowFooBarException throws FooBarException
*/
public function testFooBarException() {
$this->setExpectedException('FooBarException');
thisShouldThrowFooBarException();
}
Much more explicit and you're less likely to miss it when trying to grok someone else's unittest. @Test(expectedExceptions = FooBarException.class)
public void test() {
thisShouldThrow();
}
If the method doesn't throw or throws the wrong kind of exception, this test will fail. @Test(expectedExceptions = FooException.class)
public void test() {
firstDoThis();
thenThat();
thenSomeMore();
thisShouldThrow();
}
Now you're only asserting that any of these statements throw, anywhere in the code under test. That's significantly weaker and I've seen it mask real problems in code.I think using plain try something/fail/catch is clearer, or using Closures and an assertThrows if your language supports it.
shouldn't you be automating that? :-D
Whenever I do this, I feel awful, because:
> But that doesn't scale, that only saves you once
You need to fuzz test your tests. (I always forget the name of the awesome Java tool for this....) If you can randomly mutate your test code (negate boolean conditional, etc) and your tests still pass, they fail.
EDIT: NIH is pretty bad overall, but it's especially terrible in crypto, where 'useless' and 'useful' take on something akin to binary values, rather than a continuum.
This was the guy who wrote his own SSH server (in PHP, FWIW) and put it into production, right? This whole thing is a disaster waiting to happen.
I missed something. Which guy?
My conspiracy theories side tells me this: imagine that you own a bank that is not guarded by any rules laws or regulations, that most money is deposited anonymously or semi-anonymously, and it is deposited in unmarked banknotes. And its worth $500k.
Now, fast forward to today and you keep keys to $400,000,000 vault. Only rules haven't changed. Now, given the overall complexity of bitcoins algorithm, the fact that mt gox is (afaik) not even registered in a country with solid laws, wouldn't you grab the money and "run", even though running means only pointing out there was a glitch in the system and filing for bankruptcy protection?
If any of this is true, then here is your (sad) reasoning why we need government oversight when it comes to dealing with someones property, being it even bits on someones hard drive.
I (a German) laugh my behind off when I read that as a mail-order business one is expected (and fined if noncompliant to the letter) to the tax codes of villages so small that they would not even count as a village in Germany. And if you're shipping inside the European Union, well, just properly declare the VAT and be done with it.
Second, if you want to avoid even this annoyance, you can start your business in one of the five states with no sales taxes including New Hampshire or Oregon, meaning you never have to collect any sales taxes. Third, if you do have offices in other states, you can buy some relatively cheap software that takes care of billing for you.
I'm not saying this system is perfect or even that it'll continue given the pro-Internet tax forces in Congress, but nevertheless I don't think your description is accurate.
This doesn't exist in the U.S. financial system. Maybe it should, but honestly it is such a stronger requirement than anything close to what we have currently, and I imagine it would be impossible to enact on a resistant market (try defining "independent security experts"... oy).
In this case there is even plenty of evidence that it won't work: Government regulated banks have simply discovered less obvious means to run off with the plunder.
What we really need is strong stance from the bitcoin foundation against any service that offers to hold user's wallet keys.
I'm also curious as to what's stopping you from using the same proof-of-burn repeatedly. If I burn some coins 2 months ago, and then prove to someone today that I burned then, why can't I turn around and use the exact same burn as a proof for someone else tomorrow?
At the moment in these sorts of cases usually a payee just keeps the money; the advantage would be in reducing perverse incentives.
If spammers kept opening HN accounts, HN could say "burn $5 to open a new account" to reduce demand. That would avoid HN having an incentive to ban people for profit.
Or the state could say "speeding fine? burn $200" to discourage people from speeding. That would avoid the state having an incentive to increase crime to generate fine revenue.
Or a college could say "want your exam paper re-graded? burn $50" to discourage requests just for the sake of it. That would avoid the college having an incentive to grade people badly.
To resolve a disputed transaction on an auction site, the site could require the buyer to destroy the goods and the seller to burn the money, so there would be no profit from filing false disputes.
I wonder how feasible it would be to have a service that provides proof-of-burn for real-world money? Effectively, allow people to pay the company money, company then provides burner with a receipt referencing this proof-of-burn. The burner can then provide that receipt to the party that wishes the burn, and the party can verify with this service that the money was indeed burnt (and this verification then marks the burn as having been "used", so to speak). The company could do something like take a small fee from the burnt money (to actually pay for the service), and donate the rest to charity (and maybe even provide the donation receipt to the burner, so they can treat it as a charitable gift for tax purposes).
The big obstacle here is how to ensure that the money is irrevocably burnt, but that's a solvable problem (check or wire transfer, perhaps, or even waiting long enough after a credit card payment to prevent chargeback, although I think that's a rather long time).
The downside here is that you need a middleman to run the whole operation, and irrevocably paying them takes a bit of effort and time.
The upside is the money isn't actually destroyed, it's instead given to charity.
Can you guarantee that, over time, the program sequence will not halt even if the individual programs in fact do halt.
"Halting" would have to be defined differently, i.e. with the capacity to resume.
Am I missing something?
Given that the scripts are usually used to verify basic transactions, though, you could probably provide a few basic rules and autogenerate appropriate tests.
It seems to me that the obvious issue is sending invalid transactions. If these are not handled and the bitcoins are lost that means that bitcoin itself must eventually disappear because some percentage of transactions will be bad and over time, the sum of all of these will lead to enough losses to ensure that there is no practical value to the remaining bitcoins.
It seems to me that programs can be guaranteed not to halt a lot more than they can be guaranteed to halt.
As far as I know, the only reason 21,000,000*100,000,000 units was chosen was to fit comfortably in the 52-bit mantissa of a 64-bit IEEE 754 floating point number.
Edit: Apparently I just made that up... But it makes sense! Edit 2: Apparently some other devs believe this is the case as well.
There's talk about it being possible to move the decimal point with a protocol update, but I'm not sure about how the logistics of that would work, or just how far it's possible to move it.
The main reason for choosing variable-precision numbers for general-purpose computing is that they have a very wide dynamic range that can adjust automatically, which makes them easier to use in more situations. In financial applications, that advantage doesn't really apply; banks don't often encounter situations where customers are worried about a ten thousandth of a cent, and they never encounter situations where it's suddenly OK to only track a transaction with dollar-level precision.
Meanwhile there are some risks to using arbitrary-precision math too. If BTC used floats, then that might result in it being vulnerable to attacks that are able to take advantage of rounding errors in floating-point math. If BTC used infinite-precision decimals, then that might result in it being vulnerable to attacks that work by creating ridiculously high-precision numbers that implementations have a hard time dealing with.
The Bitcoin code itself actually frequently uses decimal64 as well as uint64_t.