dgenr8 on master
Add macro THROW_UNLESS Express… Pass block time instead of head… Add function 'GetBIP135BitByNam… and 3 more (compare)
dagurval on master
[Qt] show client user agent in … [Qt] simple mempool info in deb… Added Transactions Per Second o… and 9 more (compare)
dagurval on master
Bump to pre-release version L Merge pull request #515 from bi… (compare)
dgenr8 on master
[rpc] Add 'blockstatus' to bloc… Merge pull request #513 from da… (compare)
I'm contemplating adding a protocol message to Bitcoin Verde that is focused around helping SPV wallets sync. Currently the wallet will have the node do a lot of the heavy lifting to filter blocks--a lot of which is wasted effort since very few blocks will have relevant transactions/outputs for each wallet.
Since Bitcoin Verde indexes addresses, my first thought was to just provide a message that returns a list of "blocks of interest" based on a set of addresses. This query is very efficient for Bitcoin Verde, but non-indexing nodes can never implement this. Additionally, it greatly disregards any semblance of privacy for the wallet.
The current theory I'm toying with is creating a bloom filter for each block; the bloom filter shall contain each address in each input/output. The block's bloom filter is stored on disk and can be served along the block header during the SPV's sync.
When downloaded with the header, the SPV wallet can apply its addresses to each bloom filter for a match; if there's a match then the wallet may query the node for the merkle block.
Furthermore, if the bloom filter becomes standardized (static nonce/algorithm determining its parameters), this could also help to reduce malicious nodes' ability to omit matches to SPV--if a merkle block is returned without any matches for the address but the bloom filter matched, the SPV wallet could suspect the node is omitting matching merkle branches and query a second node. The false-positive nature of the bloom filter obviously prevents the wallet from being certain that the second node isn't also lying (since the bloom filter match could be an innocent false positive), but it at least can reduce its ability of succeeding. A standardized bloom filter parameter format also prevents a malicious node always returning a BloomFilter.MatchNone filter.
Regarding extra disk usage: assuming 500 transactions per block (on average¹), with a 0.001 false positive probability, the bloom filter is about a 900 bytes per block. At ~600k blocks, that's about 515MB for the chain's filters (+45MB for the headers).
If the SPV wallet prioritizes minimizing data usage over privacy, the SPV could send its list of addresses to to the node and then return a list of block hashes that match the on-disk filters. This would still be more efficient for the node than our current paradigm, which requires the node load each full block and apply each transaction's scripts and hashes to the filter provided by the wallet.
¹ I calculated ~500 tx/block with the following Bitcoin Verde db query:
select avg(t.tx_count) from (select block_id, count(*) as tx_count from block_transactions group by block_id) as t;, which returned 486.3725.
I'd love to hear your guys' thoughts on whether this would be worth the effort or if you guys can improve on the idea. Tomorrow, I'll post this to reddit and let them rip apart the idea there for feedback too.
There was a small error in my assumptions for calculating the bloom filter size: I only assumed 1 entry per transaction--it should really be about 3 (1 input address, 2 output addresses). With those parameters, we get a filter that is about 2.75KB, which might be pushing the network size we'd want.. but accepting more false positives (0.01 instead of 0.001) brings us to 1.75KB, so a little less than double the original estimates. 1GB in network is probably too much for most SPV wallets, I believe... But for the privacy-oriented maybe not. ...again, those not interested in privacy could rely on submitting their addresses to the node directly, and letting the node do the filter processing.
I think that concludes my napkin math.
Oh jeez... you guys are like my dedicated reference node for Bitcoin Verde.
It's been nice having you around :-).
Is the intent behind deprecating XT to urge ABC to implement BIP 100?
No, there is no ulterior motive. A decision to continue or not needed to be announced before the fork time.
Has ABC not done this already?
ABC does not believe in hashpower signalling
Pby a negated
java.lang.IllegalArgumentException: The multiplicator cannot be negative at org.bouncycastle.math.ec.ECPoint.multiply(Unknown Source) at com.softwareverde.bitcoin.secp256k1.Schnorr.verifySignature(Schnorr.java:92) at com.softwareverde.bitcoin.secp256k1.SchnorrTests.should_validate_bitcoin_abc_test_vector_4a(SchnorrTests.java:88) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.junit.runner.JUnitCore.run(JUnitCore.java:160) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Also, tom harding might waot to have a look at naybc, it doesn't looks like it's doing good.