Commit d55b361b19c3294d886b2953c505864d323045ac

Authored by Marius Hanne
1 parent 000f9aa47d
Exists in electrum

electrum server SPV commands

Showing 1 changed file with 35 additions and 0 deletions Side-by-side Diff

lib/bitcoin/electrum/server.rb
... ... @@ -39,6 +39,9 @@
39 39 if @subscribed_numblocks
40 40 respond({}, method: "blockchain.numblocks.subscribe", params: [depth])
41 41 end
  42 + if @subscribed_headers
  43 + respond({}, method: "blockchain.headers.subscribe", params: [get_header])
  44 + end
42 45 block.tx.each {|tx| check_tx(tx, block.hash) }
43 46 end
44 47 log.info { "client connected" }
45 48  
... ... @@ -59,12 +62,19 @@
59 62 when /blockchain.numblocks.subscribe/
60 63 @subscribed_numblocks = true
61 64 respond(pkt, result: store.get_depth)
  65 + when /blockchain.headers.subscribe/
  66 + @subscribed_headers = true
  67 + respond(pkt, result: get_header)
62 68 when /blockchain.address.get_history/
63 69 get_history(pkt)
64 70 when /server.peers/
65 71 respond(pkt, result: []) # TODO
66 72 when /blockchain.address.subscribe/
67 73 subscribe_address(pkt)
  74 + when /blockchain.transaction.get_merkle/
  75 + get_merkle(pkt)
  76 + when /blockchain.block.get_chunk/
  77 + get_chunk(pkt)
68 78 when /blockchain.transaction.broadcast/
69 79 tx = Bitcoin::P::Tx.new(pkt['params'].pack("H*"))
70 80 if @server.node.relay_tx(tx)
... ... @@ -135,6 +145,31 @@
135 145 hash = nil
136 146 end
137 147 respond(pkt, result: hash)
  148 + end
  149 +
  150 + def get_header
  151 + b = store.get_head
  152 + { nonce: b.nonce,
  153 + prev_block_hash: b.prev_block.reverse_hth,
  154 + timestamp: b.time, merkle_root: b.mrkl_root.reverse_hth,
  155 + block_height: b.depth, version: b.ver, bits: b.bits }
  156 + end
  157 +
  158 + def get_merkle pkt
  159 + hash = pkt['params'][0]
  160 + tx = store.get_tx(pkt['params'][0])
  161 + block = tx.get_block
  162 + respond(pkt, result: {pos: block.tx.index(tx), block_height: block.depth,
  163 + merkle: Bitcoin.hash_mrkl_tree(block.tx.map(&:hash), tx.hash) })
  164 + end
  165 +
  166 + def get_chunk pkt
  167 + i = pkt['params'][0]
  168 + r = store.db[:blk].where(chain: 0, depth: ((i * 2016)...((i + 1) * 2016))).map {|b|
  169 + [ b[:version], b[:prev_hash].reverse, b[:mrkl_root].reverse,
  170 + b[:time], b[:bits], b[:nonce] ].pack("Ia32a32III")
  171 + }.join.unpack("H*")[0]
  172 + respond(pkt, result: r)
138 173 end
139 174  
140 175 def check_tx tx, block_hash = "mempool:x"