Bitcoin Forum
December 14, 2024, 02:33:51 AM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: [ANNOUNCE] BitCoinJ/BitCoinSharp v0.2  (Read 5536 times)
Mike Hearn (OP)
Legendary
*
Offline Offline

Activity: 1526
Merit: 1134


View Profile
June 27, 2011, 08:49:44 PM
Last edit: June 27, 2011, 09:08:34 PM by Mike Hearn
 #1

[also sent to bitcoin-development@]

I'm pleased to announce BitCoinJ v0.2. There have been over 100 commits since the first release back in March, which have added:

  • Full support for block chain re-orgs, including recognition of dead transactions (that will never be included in the chain).
  • Persistence of the block chain using multiple, pluggable stores. A BoundedOverheadBlockStore is provided that is suitable for usage on mobile devices where low memory usage and instant startup time are requirements.
  • A much larger test suite
  • IRC, DNS  and seed list peer discovery
  • ASN.1 key export
  • Many many bugfixes and minor API improvements.

This release represents the work of many people. In particular I'd like to thank:

  • Andreas Schildbach
  • Miron Cuperman
  • Gary Rowe
  • Thilo Planz
  • Micheal Swiggs
  • Noa Resare
  • John Sample
  • Xiaofeng Guo

You can get it from the release-0.2 branch in Subversion or the downloads page.

BitCoinSharp

I'm also very pleased to announce that Nathan Baulch has created BitCoinSharp, a complete port of the library into C# which opens up low level Bitcoin development to .NET developers. You can start reading at the PingService:

  http://code.google.com/p/bitcoinsharp/source/browse/src/Examples/PingService.cs

TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1104


View Profile
June 27, 2011, 10:44:14 PM
 #2

Sorry for so many questions, but is a pretty useful library.

What is the thread safety model for this library?

Is everything thread unsafe unless told otherwise?

If you connect to 2 peers, can you set them to the same block chain?  That way if a block arrives from either peer, it will be incorporated into the chain.

How does the getBlock() method in Peer work.  Does it send a request to the peer and the Future resolves when it gets an answer?  If the peer dies, then it would never complete?

A getTransaction() method would be great for the Peer class.  That would require a new message though Sad.  In theory, you could add it and if bitcoinj gets popular, it would probably be incorporated into the official spec.  Bitcoinj enabled nodes would support the message.  If 1% of clients were bitcoinj nodes, then by, ahem, spamming 100 nodes, you would probably get a hit.

Transaction.verifyInput() has a "warning: not finished" message.  How much functionality has it?  Can it verify the 2 standard scripts?

The Block object doesn't have a way to get at the transactions in the block.  It could have an isHeader() method to indicate that it doesn't have all the information. 

A Block.attemptMine(int attempts) would be nice too, but that is probably outside the scope of the project.  That would need to be combined with a way to add transactions to a block.

It isn't possible to create transactions directly.  The constructor isn't public.  It could be done by sending a fake payload of.

I think "01 00 00 00 00 00 FF FF FF FF" would work. 

version = 00000001
inputs = 00
outputs = 00
lock time = FFFFFFFF

It is a hack though.

Script could also do with a default constructor and some script processing methods.  The script could be broken into pieces of some super class.  The OP_PUSHDATA1 opcode could be combined with the actual data.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
Mike Hearn (OP)
Legendary
*
Offline Offline

Activity: 1526
Merit: 1134


View Profile
June 28, 2011, 06:44:39 AM
 #3

Sorry for so many questions, but is a pretty useful library.

What is the thread safety model for this library?

The intention is that multiple threads can access block chain and wallet instances concurrently. However currently there's only ever one peer thread, so the thread safety hasn't been well tested and there are surely bugs.

Quote
If you connect to 2 peers, can you set them to the same block chain?  That way if a block arrives from either peer, it will be incorporated into the chain.

It's intended that will be possible. It may even work today. I haven't tried it yet.

Quote
How does the getBlock() method in Peer work.  Does it send a request to the peer and the Future resolves when it gets an answer?  If the peer dies, then it would never complete?

Correct. There are no timeouts on the future.

Quote
A getTransaction() method would be great for the Peer class.  That would require a new message though Sad

I think you can use getdata on a transaction if it's in memory. Otherwise yes, you're right. But what would it be used for?

Quote
Transaction.verifyInput() has a "warning: not finished" message.  How much functionality has it?  Can it verify the 2 standard scripts?

Lightweight/SPV clients don't verify transactions. They take inclusion in the chain as proof of validity. See here:

http://code.google.com/p/bitcoinj/wiki/SecurityModel

The verifyInput code dates from a time before I decided to implement this model and I'll delete it at some point. Verifying transactions means (at minimum) storing them all, which it does not do.

Quote
The Block object doesn't have a way to get at the transactions in the block.  It could have an isHeader() method to indicate that it doesn't have all the information. 

Right, that would be useful. Patches welcome.

Quote
A Block.attemptMine(int attempts) would be nice too, but that is probably outside the scope of the project.  That would need to be combined with a way to add transactions to a block.

There is already a solve() method which does mining, but it doesn't update the extraNonce so it's only useful for unit-test difficulties.

Quote
It isn't possible to create transactions directly.  The constructor isn't public.  It could be done by sending a fake payload.

We can make the bytestream constructor public.

Quote
Script could also do with a default constructor and some script processing methods.  The script could be broken into pieces of some super class.  The OP_PUSHDATA1 opcode could be combined with the actual data.

Yes, the Script class needs a lot of work. It'll probably get done in the context of supporting contracts.
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1104


View Profile
June 28, 2011, 11:17:14 AM
 #4

It's intended that will be possible. It may even work today. I haven't tried it yet.

Great.

Quote
Quote
A getTransaction() method would be great for the Peer class.  That would require a new message though Sad

I think you can use getdata on a transaction if it's in memory. Otherwise yes, you're right. But what would it be used for?

I was thinking that it would allow lightweight clients to verify transactions.  However, on further thought, it would need to indicate which is the matching block.

The message could return how many confirms there are for a particular transaction.  A transaction that was incorporated into the chain 100 blocks ago and was just spent but the spend hasn't been confirmed would return 100,0.  -1 could be used for "unknown transaction".

If the peer was trusted, then that would show the status of the transaction.

Quote
The verifyInput code dates from a time before I decided to implement this model and I'll delete it at some point. Verifying transactions means (at minimum) storing them all, which it does not do.

Not, if there is a way to ask the full nodes how many confirms a transaction has.

The method could require that you provide an array of the input transactions.

Quote
Quote
The Block object doesn't have a way to get at the transactions in the block.  It could have an isHeader() method to indicate that it doesn't have all the information. 

Right, that would be useful. Patches welcome.

What is your procedure for that?  Do contributors just submit their code as a patch file attachment on the issue list?  I know some projects require that contributors have to sign something first (to formally license the submission).

Quote
Quote
It isn't possible to create transactions directly.  The constructor isn't public.  It could be done by sending a fake payload.

We can make the bytestream constructor public.

I think the byte stream one is already public.  I was thinking of the one that just takes params and generates an empty transaction.

Why do you only have a readback for pending confirmations?  Is this to allow the client to resend them periodically?

Speaking of contracts, you could include a Wallet method that allows coins to be spent to a transaction, rather than broadcasting to the network.  This would allow a contract to be easily built up and give an already formed transaction.

Maybe there could be a "combine inputs" transaction which creates a transaction which has all the same inputs as a given transaction.  This would allow spending a transaction and then adding an arbitrary payload as output.

This could be combined with a "pay to wallet" method which takes a transaction and pays the output to the wallet.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
Mike Hearn (OP)
Legendary
*
Offline Offline

Activity: 1526
Merit: 1134


View Profile
June 28, 2011, 11:06:31 PM
 #5

Not, if there is a way to ask the full nodes how many confirms a transaction has.

You can't verify a transaction by merely checking the inputs are valid. It could be a double spend. The only way to prove it's not a double spend is to be aware of all transactions, so you can track which outputs are spent and which aren't.

Quote
What is your procedure for that?  Do contributors just submit their code as a patch file attachment on the issue list?  I know some projects require that contributors have to sign something first (to formally license the submission).

You have to (electronically) sign the Google CLA:

http://code.google.com/legal/individual-cla-v1.0.html

Quote
Why do you only have a readback for pending confirmations?  Is this to allow the client to resend them periodically?

I don't understand this question, sorry.

Quote
Speaking of contracts, you could include a Wallet method that allows coins to be spent to a transaction, rather than broadcasting to the network.  This would allow a contract to be easily built up and give an already formed transaction.

Maybe there could be a "combine inputs" transaction which creates a transaction which has all the same inputs as a given transaction.  This would allow spending a transaction and then adding an arbitrary payload as output.

This could be combined with a "pay to wallet" method which takes a transaction and pays the output to the wallet.

Yes, there are many ways to do it. That way sounds reasonable. Gary Rowe is interested in contracts as well, you could maybe team up with him.
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1104


View Profile
June 28, 2011, 11:23:17 PM
Last edit: June 28, 2011, 11:54:31 PM by TierNolan
 #6

You can't verify a transaction by merely checking the inputs are valid. It could be a double spend. The only way to prove it's not a double spend is to be aware of all transactions, so you can track which outputs are spent and which aren't.

If the node tells you which block has it, you could scan back to just that block, if it isn't to far.  That could be practical for a lightweight client, if the transaction didn't occur to far back the chain.

Quote
Why do you only have a readback for pending confirmations?  Is this to allow the client to resend them periodically?

I don't understand this question, sorry.
[/quote]

Sorry, I meant that in Wallet, the only transactions you can read-back are the pending ones with getPendingTransactions(), it doesn't have a method for finding any other transactions.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
Mike Hearn (OP)
Legendary
*
Offline Offline

Activity: 1526
Merit: 1134


View Profile
June 29, 2011, 05:24:45 PM
 #7

The pools are an implementation detail of how the wallet works, that's why. There should be an API for reading all transactions in the wallet together, but just exposing the pools isn't the right way to do it.
BitterTea
Sr. Member
****
Offline Offline

Activity: 294
Merit: 252



View Profile
July 01, 2011, 07:00:39 AM
 #8

You can't verify a transaction by merely checking the inputs are valid. It could be a double spend. The only way to prove it's not a double spend is to be aware of all transactions, so you can track which outputs are spent and which aren't.

If the node tells you which block has it, you could scan back to just that block, if it isn't to far.  That could be practical for a lightweight client, if the transaction didn't occur to far back the chain.

BitcoinJ stores serialized StoredBlock objects to disk, without transaction data. The transactions are scanned and discarded in the ConnectBlock method.
TierNolan
Legendary
*
Offline Offline

Activity: 1232
Merit: 1104


View Profile
July 01, 2011, 09:19:01 AM
 #9

BitcoinJ stores serialized StoredBlock objects to disk, without transaction data. The transactions are scanned and discarded in the ConnectBlock method.


Right, realisation dawns Smiley, because it is purely for tracking your own transactions. 

The block chain headers are the only thing that is stored.  When it starts up again, it just checks new blocks for references to those transactions.

1LxbG5cKXzTwZg9mjL3gaRE835uNQEteWF
BitterTea
Sr. Member
****
Offline Offline

Activity: 294
Merit: 252



View Profile
July 01, 2011, 09:26:05 AM
 #10

BitcoinJ stores serialized StoredBlock objects to disk, without transaction data. The transactions are scanned and discarded in the ConnectBlock method.


Right, realisation dawns Smiley, because it is purely for tracking your own transactions. 

The block chain headers are the only thing that is stored.  When it starts up again, it just checks new blocks for references to those transactions.

Yeah, that's right. I'm wondering if it wouldn't be that difficult to create a new block type (FullBlock?) and associated storage mechanism. Mike would know better than I, though, I'm only just starting to play with BitcoinSharp.
Mike Hearn (OP)
Legendary
*
Offline Offline

Activity: 1526
Merit: 1134


View Profile
July 01, 2011, 11:10:36 AM
 #11

Full mode is a lot of work. You have to store all transactions in a database, load all the dependencies for each transaction, run the scripts, update the spent pointers and more.

There seems to be a lot of interest in making BitCoinJ a full Bitcoin implementation. But there's plenty of work to do on light mode before those two visions diverge.
BitterTea
Sr. Member
****
Offline Offline

Activity: 294
Merit: 252



View Profile
July 01, 2011, 06:20:43 PM
 #12

Full mode is a lot of work. You have to store all transactions in a database, load all the dependencies for each transaction, run the scripts, update the spent pointers and more.

There seems to be a lot of interest in making BitCoinJ a full Bitcoin implementation. But there's plenty of work to do on light mode before those two visions diverge.

Shortly after I wrote that I was reading the issue tracker and came across the discussion on the matter. I didn't realize storing transactions would be that difficult, but using a graph DB sounded interesting.
Mike Hearn (OP)
Legendary
*
Offline Offline

Activity: 1526
Merit: 1134


View Profile
July 02, 2011, 10:09:17 AM
Last edit: July 29, 2011, 10:35:50 AM by Mike Hearn
 #13

It's not difficult really. It's just a bunch of work to make sure all the loose ends are handled. There are quite a few rules that are not checked/enforced today because we assume the most difficult chain is valid.
TYDIRocks
Full Member
***
Offline Offline

Activity: 213
Merit: 100


View Profile
July 28, 2011, 05:31:08 PM
 #14

I'm not the best coder so I have a question with bitcoinsharp

Do I need to include all 3 dlls in my project? I'm also having trouble with this line:

Quote
final NetworkParameters params = testNet ? NetworkParameters.testNet() : NetworkParameters.prodNet();

I'm coding this in vb.net so the code isn't exactly the same.

Import new address/private keys with ease: https://bitcointalk.org/index.php?topic=101161
titeuf_87
Member
**
Offline Offline

Activity: 111
Merit: 10


View Profile
July 28, 2011, 06:28:58 PM
 #15

In vb.net that would be the following:
Code:
dim params as NetworkParameters = if(testNet, NetworkParameters.testNet(), NetworkParameters.prodNet())

This is what is called a ternary operation.

15kfBM3TQ4PGzL7cKncU3su2pH7ZJmiLtr
TYDIRocks
Full Member
***
Offline Offline

Activity: 213
Merit: 100


View Profile
July 28, 2011, 06:33:03 PM
 #16

In vb.net that would be the following:
Code:
dim params as NetworkParameters = if(testNet, NetworkParameters.testNet(), NetworkParameters.prodNet())

This is what is called a ternary operation.

Okay and could you help me with the line before that:

Quote
boolean testNet = args.length > 0 && args[0].equalsIgnoreCase("testnet");

Also, do I need to include all 3 dlls?

Import new address/private keys with ease: https://bitcointalk.org/index.php?topic=101161
titeuf_87
Member
**
Offline Offline

Activity: 111
Merit: 10


View Profile
July 28, 2011, 07:52:55 PM
 #17

&& in C# is the and operator in vb.net. Also vb.net uses round brackets for arrays instead of square ones.
Code:
dim testNet as boolean = args.length > 0 and args(0).equalsIgnoreCase("testnet")

As for the dlls: you'll certainly need to add BitCoinSharp.dll to your project. I think that just adding that one and keeping the other dll's in the same folder should be good enough.
I can't test it though since I don't have a vb.net or even a c# compiler here at home.

15kfBM3TQ4PGzL7cKncU3su2pH7ZJmiLtr
TYDIRocks
Full Member
***
Offline Offline

Activity: 213
Merit: 100


View Profile
July 28, 2011, 07:59:48 PM
 #18

&& in C# is the and operator in vb.net. Also vb.net uses round brackets for arrays instead of square ones.
Code:
dim testNet as boolean = args.length > 0 and args(0).equalsIgnoreCase("testnet")

As for the dlls: you'll certainly need to add BitCoinSharp.dll to your project. I think that just adding that one and keeping the other dll's in the same folder should be good enough.
I can't test it though since I don't have a vb.net or even a c# compiler here at home.

"args.length" was actually the only problem I had. For some reason i can't put that.

Import new address/private keys with ease: https://bitcointalk.org/index.php?topic=101161
titeuf_87
Member
**
Offline Offline

Activity: 111
Merit: 10


View Profile
July 28, 2011, 08:38:25 PM
 #19

"args.length" was actually the only problem I had. For some reason i can't put that.

Length is the standard way in .NET to get the size of an array back. Paste the error you get and the code surrounding it? The error is probably where the args variable is declared.

Also I just realized something: in this case you should be using AndAlso instead of and. This short-circuits the and so that if the first part is False (the array is empty), the second part will never be evaluated.

Also, please PM me this or start a new topic for this? This isn't really related to BitCoinSharp, so let's not derail the topic Smiley

15kfBM3TQ4PGzL7cKncU3su2pH7ZJmiLtr
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!