Merge branch 'jakm'
commit
df4ba50672
|
@ -245,6 +245,18 @@ type resSendRawTransaction struct {
|
|||
Result string `json:"result"`
|
||||
}
|
||||
|
||||
// getmempoolentry
|
||||
|
||||
type cmdGetMempoolEntry struct {
|
||||
Method string `json:"method"`
|
||||
Params []string `json:"params"`
|
||||
}
|
||||
|
||||
type resGetMempoolEntry struct {
|
||||
Error *RPCError `json:"error"`
|
||||
Result *MempoolEntry `json:"result"`
|
||||
}
|
||||
|
||||
// GetBestBlockHash returns hash of the tip of the best-block-chain.
|
||||
func (b *BitcoinRPC) GetBestBlockHash() (string, error) {
|
||||
|
||||
|
@ -538,6 +550,25 @@ func (b *BitcoinRPC) SendRawTransaction(tx string) (string, error) {
|
|||
return res.Result, nil
|
||||
}
|
||||
|
||||
func (b *BitcoinRPC) GetMempoolEntry(txid string) (*MempoolEntry, error) {
|
||||
glog.V(1).Info("rpc: getmempoolentry")
|
||||
|
||||
res := resGetMempoolEntry{}
|
||||
req := cmdGetMempoolEntry{
|
||||
Method: "getmempoolentry",
|
||||
Params: []string{txid},
|
||||
}
|
||||
err := b.call(&req, &res)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res.Error != nil {
|
||||
return nil, res.Error
|
||||
}
|
||||
return res.Result, nil
|
||||
}
|
||||
|
||||
func (b *BitcoinRPC) call(req interface{}, res interface{}) error {
|
||||
httpData, err := json.Marshal(req)
|
||||
if err != nil {
|
||||
|
|
|
@ -59,6 +59,21 @@ type BlockHeader struct {
|
|||
Confirmations int `json:"confirmations"`
|
||||
}
|
||||
|
||||
type MempoolEntry struct {
|
||||
Size uint32 `json:"size"`
|
||||
Fee float64 `json:"fee"`
|
||||
ModifiedFee float64 `json:"modifiedfee"`
|
||||
Time float64 `json:"time"`
|
||||
Height uint32 `json:"height"`
|
||||
DescendantCount uint32 `json:"descendantcount"`
|
||||
DescendantSize uint32 `json:"descendantsize"`
|
||||
DescendantFees uint32 `json:"descendantfees"`
|
||||
AncestorCount uint32 `json:"ancestorcount"`
|
||||
AncestorSize uint32 `json:"ancestorsize"`
|
||||
AncestorFees uint32 `json:"ancestorfees"`
|
||||
Depends []string `json:"depends"`
|
||||
}
|
||||
|
||||
type RPCError struct {
|
||||
Code int `json:"code"`
|
||||
Message string `json:"message"`
|
||||
|
@ -83,6 +98,7 @@ type BlockChain interface {
|
|||
ResyncMempool(onNewTxAddr func(txid string, addr string)) error
|
||||
GetMempoolTransactions(outputScript []byte) ([]string, error)
|
||||
GetMempoolSpentOutput(outputTxid string, vout uint32) string
|
||||
GetMempoolEntry(txid string) (*MempoolEntry, error)
|
||||
// parser
|
||||
GetChainParser() BlockChainParser
|
||||
}
|
||||
|
|
|
@ -3,13 +3,16 @@
|
|||
FROM debian:9
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
build-essential git wget pkg-config lxc-dev libzmq3-dev libgflags-dev libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev
|
||||
build-essential git wget pkg-config lxc-dev libzmq3-dev libgflags-dev \
|
||||
libsnappy-dev zlib1g-dev libbz2-dev liblz4-dev graphviz
|
||||
|
||||
ENV GOLANG_VERSION=go1.9.2.linux-amd64
|
||||
ENV GOPATH=/go
|
||||
ENV PATH=$PATH:$GOPATH/bin
|
||||
|
||||
# install and configure go
|
||||
RUN cd /opt && wget https://storage.googleapis.com/golang/$GOLANG_VERSION.tar.gz && tar xf $GOLANG_VERSION.tar.gz
|
||||
RUN cd /opt && wget https://storage.googleapis.com/golang/$GOLANG_VERSION.tar.gz && \
|
||||
tar xf $GOLANG_VERSION.tar.gz
|
||||
RUN ln -s /opt/go/bin/go /usr/bin/go
|
||||
RUN mkdir -p $GOPATH
|
||||
RUN echo -n "GO version: " && go version
|
||||
|
@ -19,18 +22,19 @@ RUN echo -n "GOPATH: " && echo $GOPATH
|
|||
RUN cd /opt && git clone https://github.com/facebook/rocksdb.git
|
||||
RUN cd /opt/rocksdb && CFLAGS=-fPIC CXXFLAGS=-fPIC make static_lib
|
||||
|
||||
# install gorocksdb
|
||||
RUN CGO_CFLAGS="-I/opt/rocksdb/include" CGO_LDFLAGS="-L/opt/rocksdb -lrocksdb -lstdc++ -lm -lz -lbz2 -lsnappy -llz4" go get github.com/tecbot/gorocksdb
|
||||
|
||||
RUN go get github.com/golang/glog
|
||||
RUN go get github.com/martinboehm/golang-socketio
|
||||
RUN go get github.com/btcsuite/btcd
|
||||
RUN go get github.com/gorilla/handlers
|
||||
RUN go get github.com/bsm/go-vlq
|
||||
RUN go get github.com/gorilla/handlers
|
||||
RUN go get github.com/gorilla/mux
|
||||
RUN go get github.com/pebbe/zmq4
|
||||
RUN go get github.com/pkg/profile
|
||||
RUN go get github.com/golang/dep/cmd/dep
|
||||
|
||||
# clone repo and ensure dependencies
|
||||
RUN cd $GOPATH/src && git clone https://github.com/jpochyla/blockbook.git
|
||||
RUN cd $GOPATH/src/blockbook && go build
|
||||
RUN cd $GOPATH/src/blockbook && dep ensure
|
||||
|
||||
# install gorocksdb
|
||||
RUN cd $GOPATH/src/blockbook/vendor/github.com/tecbot/gorocksdb && \
|
||||
CGO_CFLAGS="-I/opt/rocksdb/include" \
|
||||
CGO_LDFLAGS="-L/opt/rocksdb -lrocksdb -lstdc++ -lm -lz -lbz2 -lsnappy -llz4" \
|
||||
go install .
|
||||
|
||||
|
||||
WORKDIR $GOPATH/src/blockbook
|
||||
|
||||
CMD go build -o /out/blockbook
|
||||
|
|
|
@ -3,7 +3,14 @@ set -e
|
|||
|
||||
cd `dirname $0`
|
||||
|
||||
# prepare build image
|
||||
docker build -t blockbook-build .
|
||||
docker run -t -v $(pwd):/out blockbook-build /bin/cp /go/src/blockbook/blockbook /out/
|
||||
|
||||
if [ "$1" == "local" ]; then
|
||||
SRC_BIND="-v $(pwd)/..:/go/src/blockbook"
|
||||
fi
|
||||
|
||||
# build binary
|
||||
docker run -t --rm -v $(pwd):/out $SRC_BIND blockbook-build
|
||||
|
||||
strip blockbook
|
||||
|
|
|
@ -160,19 +160,26 @@ var onMessageHandlers = map[string]func(*SocketIoServer, json.RawMessage) (inter
|
|||
return s.getInfo()
|
||||
},
|
||||
"\"getDetailedTransaction\"": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) {
|
||||
txid, err := unmarshalGetDetailedTransaction(params)
|
||||
txid, err := unmarshalStringParameter(params)
|
||||
if err == nil {
|
||||
rv, err = s.getDetailedTransaction(txid)
|
||||
}
|
||||
return
|
||||
},
|
||||
"\"sendTransaction\"": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) {
|
||||
tx, err := unmarshalSendTransaction(params)
|
||||
tx, err := unmarshalStringParameter(params)
|
||||
if err == nil {
|
||||
rv, err = s.sendTransaction(tx)
|
||||
}
|
||||
return
|
||||
},
|
||||
"\"getMempoolEntry\"": func(s *SocketIoServer, params json.RawMessage) (rv interface{}, err error) {
|
||||
txid, err := unmarshalStringParameter(params)
|
||||
if err == nil {
|
||||
rv, err = s.getMempoolEntry(txid)
|
||||
}
|
||||
return
|
||||
},
|
||||
}
|
||||
|
||||
type resultError struct {
|
||||
|
@ -585,12 +592,12 @@ func (s *SocketIoServer) getInfo() (res resultGetInfo, err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func unmarshalGetDetailedTransaction(params []byte) (hash string, err error) {
|
||||
func unmarshalStringParameter(params []byte) (s string, err error) {
|
||||
p, err := unmarshalArray(params, 1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
hash, ok := p[0].(string)
|
||||
s, ok := p[0].(string)
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
|
@ -655,19 +662,6 @@ func (s *SocketIoServer) getDetailedTransaction(txid string) (res resultGetDetai
|
|||
return
|
||||
}
|
||||
|
||||
func unmarshalSendTransaction(params []byte) (tx string, err error) {
|
||||
p, err := unmarshalArray(params, 1)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
tx, ok := p[0].(string)
|
||||
if ok {
|
||||
return
|
||||
}
|
||||
err = errors.New("incorrect parameter")
|
||||
return
|
||||
}
|
||||
|
||||
type resultSendTransaction struct {
|
||||
Result string `json:"result"`
|
||||
}
|
||||
|
@ -681,6 +675,19 @@ func (s *SocketIoServer) sendTransaction(tx string) (res resultSendTransaction,
|
|||
return
|
||||
}
|
||||
|
||||
type resultGetMempoolEntry struct {
|
||||
Result *bchain.MempoolEntry `json:"result"`
|
||||
}
|
||||
|
||||
func (s *SocketIoServer) getMempoolEntry(txid string) (res resultGetMempoolEntry, err error) {
|
||||
entry, err := s.chain.GetMempoolEntry(txid)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
res.Result = entry
|
||||
return
|
||||
}
|
||||
|
||||
// onSubscribe expects two event subscriptions based on the req parameter (including the doublequotes):
|
||||
// "bitcoind/hashblock"
|
||||
// "bitcoind/addresstxid",["2MzTmvPJLZaLzD9XdN3jMtQA5NexC3rAPww","2NAZRJKr63tSdcTxTN3WaE9ZNDyXy6PgGuv"]
|
||||
|
|
|
@ -204,6 +204,23 @@
|
|||
document.getElementById('subscribeAddressTxidResult').innerText += JSON.stringify(result).replace(/,/g, ", ") + "\n";
|
||||
});
|
||||
}
|
||||
|
||||
function getMempoolEntry() {
|
||||
var hash = document.getElementById('getMempoolEntryHash').value;
|
||||
lookupMempoolEntry(hash, function (result) {
|
||||
console.log('getMempoolEntry sent successfully');
|
||||
console.log(result);
|
||||
document.getElementById('getMempoolEntryResult').innerText = JSON.stringify(result).replace(/,/g, ", ");
|
||||
});
|
||||
}
|
||||
|
||||
function lookupMempoolEntry(hash, f) {
|
||||
const method = 'getMempoolEntry';
|
||||
const params = [
|
||||
hash,
|
||||
];
|
||||
return socket.send({ method, params }, f);
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
|
@ -343,10 +360,24 @@
|
|||
<div class="col" id="subscribeAddressTxidResult">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<input class="btn btn-secondary" type="button" value="getMempoolEntry" onclick="getMempoolEntry()">
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<input type="text" class="form-control" id="getMempoolEntryHash" value="">
|
||||
</div>
|
||||
<div class="col">
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col" id="getMempoolEntryResult">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script>
|
||||
document.getElementById('serverAddress').value = window.location.protocol.replace("http", "ws") + "//" + window.location.host;
|
||||
</script>
|
||||
|
||||
</html>
|
||||
</html>
|
||||
|
|
Loading…
Reference in New Issue