LBRY changes #2

Merged
tzarebczan merged 1 commit from lbry into master 2020-11-17 09:20:56 +01:00
47 changed files with 543 additions and 493 deletions

View file

@ -18,7 +18,7 @@ executors:
docker: docker:
- image: circleci/golang:1.13 - image: circleci/golang:1.13
user: root # go directory is owned by root user: root # go directory is owned by root
working_directory: /go/src/github.com/coinbase/rosetta-bitcoin working_directory: /go/src/github.com/lbryio/rosetta-lbry
environment: environment:
- GO111MODULE: "on" - GO111MODULE: "on"
@ -69,7 +69,7 @@ jobs:
name: default name: default
steps: steps:
- *fast-checkout - *fast-checkout
- run: make coverage - run: make coverage
salus: salus:
machine: true machine: true
steps: steps:

View file

@ -1,3 +1,3 @@
rosetta-bitcoin rosetta-lbry
bitcoin-data lbry-data
cli-data cli-data

4
.gitignore vendored
View file

@ -1,3 +1,3 @@
rosetta-bitcoin rosetta-lbry
bitcoin-data lbry-data
cli-data cli-data

View file

@ -10,11 +10,11 @@ from further participation in this project, or potentially all Coinbase projects
## Bug Reports ## Bug Reports
* Ensure your issue [has not already been reported][1]. It may already be fixed! - Ensure your issue [has not already been reported][1]. It may already be fixed!
* Include the steps you carried out to produce the problem. - Include the steps you carried out to produce the problem.
* Include the behavior you observed along with the behavior you expected, and - Include the behavior you observed along with the behavior you expected, and
why you expected it. why you expected it.
* Include any relevant stack traces or debugging output. - Include any relevant stack traces or debugging output.
## Feature Requests ## Feature Requests
@ -27,18 +27,18 @@ The best way to see a feature added, however, is to submit a pull request.
## Pull Requests ## Pull Requests
* Before creating your pull request, it's usually worth asking if the code - Before creating your pull request, it's usually worth asking if the code
you're planning on writing will actually be considered for merging. You can you're planning on writing will actually be considered for merging. You can
do this by [opening an issue][1] and asking. It may also help give the do this by [opening an issue][1] and asking. It may also help give the
maintainers context for when the time comes to review your code. maintainers context for when the time comes to review your code.
* Ensure your [commit messages are well-written][2]. This can double as your - Ensure your [commit messages are well-written][2]. This can double as your
pull request message, so it pays to take the time to write a clear message. pull request message, so it pays to take the time to write a clear message.
* Add tests for your feature. You should be able to look at other tests for - Add tests for your feature. You should be able to look at other tests for
examples. If you're unsure, don't hesitate to [open an issue][1] and ask! examples. If you're unsure, don't hesitate to [open an issue][1] and ask!
* Submit your pull request! - Submit your pull request!
## Support Requests ## Support Requests
@ -48,6 +48,6 @@ be locked to prevent further discussion.
All support requests must be made via [our support team][3]. All support requests must be made via [our support team][3].
[1]: https://github.com/coinbase/rosetta-bitcoin/issues [1]: https://github.com/lbryio/rosetta-bitcoin/issues
[2]: https://chris.beams.io/posts/git-commit/#seven-rules [2]: https://chris.beams.io/posts/git-commit/#seven-rules
[3]: https://support.coinbase.com/customer/en/portal/articles/2288496-how-can-i-contact-coinbase-support- [3]: https://support.coinbase.com/customer/en/portal/articles/2288496-how-can-i-contact-coinbase-support-

View file

@ -12,29 +12,46 @@
# See the License for the specific language governing permissions and # See the License for the specific language governing permissions and
# limitations under the License. # limitations under the License.
# Build bitcoind # Build LBRYCrdd
FROM ubuntu:18.04 as bitcoind-builder FROM ubuntu:18.04 as lbrycrdd-builder
ENV LANG C.UTF-8
RUN mkdir -p /app \ RUN mkdir -p /app \
&& chown -R nobody:nogroup /app && chown -R nobody:nogroup /app
WORKDIR /app WORKDIR /app
# Source: https://github.com/bitcoin/bitcoin/blob/master/doc/build-unix.md#ubuntu--debian # Source: https://github.com/lbryio/lbrycrd/blob/v19_master/packaging/docker-for-gcc/Dockerfile
RUN apt-get update && apt-get install -y make gcc g++ autoconf autotools-dev bsdmainutils build-essential git libboost-all-dev \ RUN set -xe; \
libcurl4-openssl-dev libdb++-dev libevent-dev libssl-dev libtool pkg-config python python-pip libzmq3-dev wget apt-get update; \
apt-get install --no-install-recommends -y build-essential libtool autotools-dev automake pkg-config git wget apt-utils \
librsvg2-bin libtiff-tools cmake imagemagick libcap-dev libz-dev libbz2-dev python-setuptools python3-setuptools xz-utils ccache g++-multilib \
g++-mingw-w64-i686 mingw-w64-i686-dev bsdmainutils curl ca-certificates g++-mingw-w64-x86-64 mingw-w64-x86-64-dev \
clang-8 lldb-8 lld-8 libc++-8-dev libboost-all-dev libcurl4-openssl-dev libssl-devlibdb++-dev libevent-dev \
libssl-dev libtool pkg-config python python-pip libzmq3-dev; \
rm -rf /var/lib/apt/lists/*;
# VERSION: Bitcoin Core 0.20.1 RUN update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang-cpp-8 80; \
RUN git clone https://github.com/bitcoin/bitcoin \ update-alternatives --install /usr/bin/clang clang /usr/bin/clang-8 80; \
&& cd bitcoin \ update-alternatives --install /usr/bin/c++ c++ /usr/bin/clang++ 80; \
&& git checkout 7ff64311bee570874c4f0dfa18f518552188df08 update-alternatives --install /usr/bin/cc cc /usr/bin/clang 80; \
update-alternatives --set x86_64-w64-mingw32-g++ /usr/bin/x86_64-w64-mingw32-g++-posix; \
update-alternatives --set i686-w64-mingw32-g++ /usr/bin/i686-w64-mingw32-g++-posix; \
/usr/sbin/update-ccache-symlinks; \
cd /usr/include/c++ && ln -s /usr/lib/llvm-8/include/c++/v1; \
cd /usr/lib/llvm-8/lib && ln -s libc++abi.so.1 libc++abi.so;
RUN cd bitcoin \ # VERSION: LBRYcrd 0.17.4.6
RUN git clone https://github.com/lbryio/lbrycrd \
&& cd lbrycrd \
&& git checkout v17_master
RUN cd lbrycrd \
&& ./autogen.sh \ && ./autogen.sh \
&& ./configure --enable-glibc-back-compat --disable-tests --without-miniupnpc --without-gui --with-incompatible-bdb --disable-hardening --disable-zmq --disable-bench --disable-wallet \ && ./configure --enable-glibc-back-compat --disable-tests --without-miniupnpc --without-gui --with-incompatible-bdb --disable-hardening --disable-zmq --disable-bench --disable-wallet \
&& make && make
RUN mv bitcoin/src/bitcoind /app/bitcoind \ RUN mv lbrycrd/src/lbrycrdd /app/lbrycrdd \
&& rm -rf bitcoin && rm -rf lbrycrd
# Build Rosetta Server Components # Build Rosetta Server Components
FROM ubuntu:18.04 as rosetta-builder FROM ubuntu:18.04 as rosetta-builder
@ -43,7 +60,7 @@ RUN mkdir -p /app \
&& chown -R nobody:nogroup /app && chown -R nobody:nogroup /app
WORKDIR /app WORKDIR /app
RUN apt-get update && apt-get install -y curl make gcc g++ RUN apt-get update && apt-get install -y curl make gcc g++ git
ENV GOLANG_VERSION 1.15.2 ENV GOLANG_VERSION 1.15.2
ENV GOLANG_DOWNLOAD_SHA256 b49fda1ca29a1946d6bb2a5a6982cf07ccd2aba849289508ee0f9918f6bb4552 ENV GOLANG_DOWNLOAD_SHA256 b49fda1ca29a1946d6bb2a5a6982cf07ccd2aba849289508ee0f9918f6bb4552
ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz
@ -58,13 +75,13 @@ ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH" RUN mkdir -p "$GOPATH/src" "$GOPATH/bin" && chmod -R 777 "$GOPATH"
# Use native remote build context to build in any directory # Use native remote build context to build in any directory
COPY . src COPY . src
RUN cd src \ RUN cd src \
&& go build \ && go build \
&& cd .. \ && cd .. \
&& mv src/rosetta-bitcoin /app/rosetta-bitcoin \ && mv src/rosetta-lbry /app/rosetta-lbry \
&& mv src/assets/* /app \ && mv src/assets/* /app \
&& rm -rf src && rm -rf src
## Build Final Image ## Build Final Image
FROM ubuntu:18.04 FROM ubuntu:18.04
@ -80,8 +97,8 @@ RUN mkdir -p /app \
WORKDIR /app WORKDIR /app
# Copy binary from bitcoind-builder # Copy binary from lbrycrdd-builder
COPY --from=bitcoind-builder /app/bitcoind /app/bitcoind COPY --from=lbrycrdd-builder /app/lbrycrdd /app/lbrycrdd
# Copy binary from rosetta-builder # Copy binary from rosetta-builder
COPY --from=rosetta-builder /app/* /app/ COPY --from=rosetta-builder /app/* /app/
@ -89,4 +106,4 @@ COPY --from=rosetta-builder /app/* /app/
# Set permissions for everything added to /app # Set permissions for everything added to /app
RUN chmod -R 755 /app/* RUN chmod -R 755 /app/*
CMD ["/app/rosetta-bitcoin"] CMD ["/app/rosetta-lbry"]

View file

@ -9,7 +9,7 @@ GOLINES_CMD=go run github.com/segmentio/golines
GOLINT_CMD=go run golang.org/x/lint/golint GOLINT_CMD=go run golang.org/x/lint/golint
GOVERALLS_CMD=go run github.com/mattn/goveralls GOVERALLS_CMD=go run github.com/mattn/goveralls
GOIMPORTS_CMD=go run golang.org/x/tools/cmd/goimports GOIMPORTS_CMD=go run golang.org/x/tools/cmd/goimports
GO_PACKAGES=./services/... ./indexer/... ./bitcoin/... ./configuration/... GO_PACKAGES=./services/... ./indexer/... ./lbry/... ./configuration/...
GO_FOLDERS=$(shell echo ${GO_PACKAGES} | sed -e "s/\.\///g" | sed -e "s/\/\.\.\.//g") GO_FOLDERS=$(shell echo ${GO_PACKAGES} | sed -e "s/\.\///g" | sed -e "s/\/\.\.\.//g")
TEST_SCRIPT=go test ${GO_PACKAGES} TEST_SCRIPT=go test ${GO_PACKAGES}
LINT_SETTINGS=golint,misspell,gocyclo,gocritic,whitespace,goconst,gocognit,bodyclose,unconvert,lll,unparam LINT_SETTINGS=golint,misspell,gocyclo,gocritic,whitespace,goconst,gocognit,bodyclose,unconvert,lll,unparam
@ -20,27 +20,27 @@ deps:
go get ./... go get ./...
build: build:
docker build -t rosetta-bitcoin:latest https://github.com/coinbase/rosetta-bitcoin.git docker build -t rosetta-lbry:latest https://github.com/lbryio/rosetta-lbry.git
build-local: build-local:
docker build -t rosetta-bitcoin:latest . docker build -t rosetta-lbry:latest .
build-release: build-release:
# make sure to always set version with vX.X.X # make sure to always set version with vX.X.X
docker build -t rosetta-bitcoin:$(version) .; docker build -t rosetta-lbry:$(version) .;
docker save rosetta-bitcoin:$(version) | gzip > rosetta-bitcoin-$(version).tar.gz; docker save rosetta-lbry:$(version) | gzip > rosetta-lbry-$(version).tar.gz;
run-mainnet-online: run-mainnet-online:
docker run -d --rm --ulimit "nofile=${NOFILE}:${NOFILE}" -v "${PWD}/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=MAINNET" -e "PORT=8080" -p 8080:8080 -p 8333:8333 rosetta-bitcoin:latest docker run -d --rm --ulimit "nofile=${NOFILE}:${NOFILE}" -v "${PWD}/lbry-data:/data" -e "MODE=ONLINE" -e "NETWORK=MAINNET" -e "PORT=8080" -p 8080:8080 -p 8333:8333 rosetta-lbry:latest
run-mainnet-offline: run-mainnet-offline:
docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=MAINNET" -e "PORT=8081" -p 8081:8081 rosetta-bitcoin:latest docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=MAINNET" -e "PORT=8081" -p 8081:8081 rosetta-lbry:latest
run-testnet-online: run-testnet-online:
docker run -d --rm --ulimit "nofile=${NOFILE}:${NOFILE}" -v "${PWD}/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=TESTNET" -e "PORT=8080" -p 8080:8080 -p 18333:18333 rosetta-bitcoin:latest docker run -d --rm --ulimit "nofile=${NOFILE}:${NOFILE}" -v "${PWD}/lbry-data:/data" -e "MODE=ONLINE" -e "NETWORK=TESTNET" -e "PORT=8080" -p 8080:8080 -p 18333:18333 rosetta-lbry:latest
run-testnet-offline: run-testnet-offline:
docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=TESTNET" -e "PORT=8081" -p 8081:8081 rosetta-bitcoin:latest docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=TESTNET" -e "PORT=8081" -p 8081:8081 rosetta-lbry:latest
train: train:
./zstd-train.sh $(network) transaction $(data-directory) ./zstd-train.sh $(network) transaction $(data-directory)
@ -71,7 +71,7 @@ check-format:
test: test:
${TEST_SCRIPT} ${TEST_SCRIPT}
coverage: coverage:
if [ "${COVERALLS_TOKEN}" ]; then ${TEST_SCRIPT} -coverprofile=c.out -covermode=count; ${GOVERALLS_CMD} -coverprofile=c.out -repotoken ${COVERALLS_TOKEN}; fi if [ "${COVERALLS_TOKEN}" ]; then ${TEST_SCRIPT} -coverprofile=c.out -covermode=count; ${GOVERALLS_CMD} -coverprofile=c.out -repotoken ${COVERALLS_TOKEN}; fi
coverage-local: coverage-local:

View file

@ -7,11 +7,11 @@
Rosetta Bitcoin Rosetta Bitcoin
</h3> </h3>
<p align="center"> <p align="center">
<a href="https://circleci.com/gh/coinbase/rosetta-bitcoin/tree/master"><img src="https://circleci.com/gh/coinbase/rosetta-bitcoin/tree/master.svg?style=shield" /></a> <a href="https://circleci.com/gh/lbryio/rosetta-bitcoin/tree/master"><img src="https://circleci.com/gh/lbryio/rosetta-bitcoin/tree/master.svg?style=shield" /></a>
<a href="https://coveralls.io/github/coinbase/rosetta-bitcoin"><img src="https://coveralls.io/repos/github/coinbase/rosetta-bitcoin/badge.svg" /></a> <a href="https://coveralls.io/github/lbryio/rosetta-bitcoin"><img src="https://coveralls.io/repos/github/lbryio/rosetta-bitcoin/badge.svg" /></a>
<a href="https://goreportcard.com/report/github.com/coinbase/rosetta-bitcoin"><img src="https://goreportcard.com/badge/github.com/coinbase/rosetta-bitcoin" /></a> <a href="https://goreportcard.com/report/github.com/lbryio/rosetta-bitcoin"><img src="https://goreportcard.com/badge/github.com/lbryio/rosetta-bitcoin" /></a>
<a href="https://github.com/coinbase/rosetta-bitcoin/blob/master/LICENSE.txt"><img src="https://img.shields.io/github/license/coinbase/rosetta-bitcoin.svg" /></a> <a href="https://github.com/lbryio/rosetta-bitcoin/blob/master/LICENSE.txt"><img src="https://img.shields.io/github/license/lbryio/rosetta-bitcoin.svg" /></a>
<a href="https://pkg.go.dev/github.com/coinbase/rosetta-bitcoin?tab=overview"><img src="https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=shield" /></a> <a href="https://pkg.go.dev/github.com/lbryio/rosetta-bitcoin?tab=overview"><img src="https://img.shields.io/badge/go.dev-reference-007d9c?logo=go&logoColor=white&style=shield" /></a>
</p> </p>
<p align="center"><b> <p align="center"><b>
@ -20,16 +20,19 @@ USE AT YOUR OWN RISK! COINBASE ASSUMES NO RESPONSIBILITY NOR LIABILITY IF THERE
</b></p> </b></p>
## Overview ## Overview
`rosetta-bitcoin` provides a reference implementation of the Rosetta API for `rosetta-bitcoin` provides a reference implementation of the Rosetta API for
Bitcoin in Golang. If you haven't heard of the Rosetta API, you can find more Bitcoin in Golang. If you haven't heard of the Rosetta API, you can find more
information [here](https://rosetta-api.org). information [here](https://rosetta-api.org).
## Features ## Features
* Rosetta API implementation (both Data API and Construction API)
* UTXO cache for all accounts (accessible using `/account/balance`) - Rosetta API implementation (both Data API and Construction API)
* Stateless, offline, curve-based transaction construction from any SegWit-Bech32 Address - UTXO cache for all accounts (accessible using `/account/balance`)
- Stateless, offline, curve-based transaction construction from any SegWit-Bech32 Address
## Usage ## Usage
As specified in the [Rosetta API Principles](https://www.rosetta-api.org/docs/automated_deployment.html), As specified in the [Rosetta API Principles](https://www.rosetta-api.org/docs/automated_deployment.html),
all Rosetta implementations must be deployable via Docker and support running via either an all Rosetta implementations must be deployable via Docker and support running via either an
[`online` or `offline` mode](https://www.rosetta-api.org/docs/node_deployment.html#multiple-modes). [`online` or `offline` mode](https://www.rosetta-api.org/docs/node_deployment.html#multiple-modes).
@ -38,59 +41,77 @@ all Rosetta implementations must be deployable via Docker and support running vi
DOCKER [HERE](https://www.docker.com/get-started).** DOCKER [HERE](https://www.docker.com/get-started).**
### Install ### Install
Running the following commands will create a Docker image called `rosetta-bitcoin:latest`. Running the following commands will create a Docker image called `rosetta-bitcoin:latest`.
#### From GitHub #### From GitHub
To download the pre-built Docker image from the latest release, run: To download the pre-built Docker image from the latest release, run:
```text ```text
curl -sSfL https://raw.githubusercontent.com/coinbase/rosetta-bitcoin/master/install.sh | sh -s curl -sSfL https://raw.githubusercontent.com/lbryio/rosetta-bitcoin/master/install.sh | sh -s
``` ```
_Do not try to install rosetta-bitcoin using GitHub Packages!_ _Do not try to install rosetta-bitcoin using GitHub Packages!_
#### From Source #### From Source
After cloning this repository, run: After cloning this repository, run:
```text ```text
make build-local make build-local
``` ```
### Run ### Run
Running the following commands will start a Docker container in Running the following commands will start a Docker container in
[detached mode](https://docs.docker.com/engine/reference/run/#detached--d) with [detached mode](https://docs.docker.com/engine/reference/run/#detached--d) with
a data directory at `<working directory>/bitcoin-data` and the Rosetta API accessible a data directory at `<working directory>/bitcoin-data` and the Rosetta API accessible
at port `8080`. at port `8080`.
#### Mainnet:Online #### Mainnet:Online
```text ```text
docker run -d --rm --ulimit "nofile=100000:100000" -v "$(pwd)/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=MAINNET" -e "PORT=8080" -p 8080:8080 -p 8333:8333 rosetta-bitcoin:latest docker run -d --rm --ulimit "nofile=100000:100000" -v "$(pwd)/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=MAINNET" -e "PORT=8080" -p 8080:8080 -p 8333:8333 rosetta-bitcoin:latest
``` ```
_If you cloned the repository, you can run `make run-mainnet-online`._ _If you cloned the repository, you can run `make run-mainnet-online`._
#### Mainnet:Offline #### Mainnet:Offline
```text ```text
docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=MAINNET" -e "PORT=8081" -p 8081:8081 rosetta-bitcoin:latest docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=MAINNET" -e "PORT=8081" -p 8081:8081 rosetta-bitcoin:latest
``` ```
_If you cloned the repository, you can run `make run-mainnet-offline`._ _If you cloned the repository, you can run `make run-mainnet-offline`._
#### Testnet:Online #### Testnet:Online
```text ```text
docker run -d --rm --ulimit "nofile=100000:100000" -v "$(pwd)/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=TESTNET" -e "PORT=8080" -p 8080:8080 -p 18333:18333 rosetta-bitcoin:latest docker run -d --rm --ulimit "nofile=100000:100000" -v "$(pwd)/bitcoin-data:/data" -e "MODE=ONLINE" -e "NETWORK=TESTNET" -e "PORT=8080" -p 8080:8080 -p 18333:18333 rosetta-bitcoin:latest
``` ```
_If you cloned the repository, you can run `make run-testnet-online`._ _If you cloned the repository, you can run `make run-testnet-online`._
#### Testnet:Offline #### Testnet:Offline
```text ```text
docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=TESTNET" -e "PORT=8081" -p 8081:8081 rosetta-bitcoin:latest docker run -d --rm -e "MODE=OFFLINE" -e "NETWORK=TESTNET" -e "PORT=8081" -p 8081:8081 rosetta-bitcoin:latest
``` ```
_If you cloned the repository, you can run `make run-testnet-offline`._ _If you cloned the repository, you can run `make run-testnet-offline`._
## System Requirements ## System Requirements
`rosetta-bitcoin` has been tested on an [AWS c5.2xlarge instance](https://aws.amazon.com/ec2/instance-types/c5). `rosetta-bitcoin` has been tested on an [AWS c5.2xlarge instance](https://aws.amazon.com/ec2/instance-types/c5).
This instance type has 8 vCPU and 16 GB of RAM. This instance type has 8 vCPU and 16 GB of RAM.
### Network Settings ### Network Settings
To increase the load `rosetta-bitcoin` can handle, it is recommended to tune your OS To increase the load `rosetta-bitcoin` can handle, it is recommended to tune your OS
settings to allow for more connections. On a linux-based OS, you can run the following settings to allow for more connections. On a linux-based OS, you can run the following
commands ([source](http://www.tweaked.io/guide/kernel)): commands ([source](http://www.tweaked.io/guide/kernel)):
```text ```text
sysctl -w net.ipv4.tcp_tw_reuse=1 sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.core.rmem_max=16777216 sysctl -w net.core.rmem_max=16777216
@ -99,6 +120,7 @@ sysctl -w net.ipv4.tcp_max_syn_backlog=10000
sysctl -w net.core.somaxconn=10000 sysctl -w net.core.somaxconn=10000
sysctl -p (when done) sysctl -p (when done)
``` ```
_We have not tested `rosetta-bitcoin` with `net.ipv4.tcp_tw_recycle` and do not recommend _We have not tested `rosetta-bitcoin` with `net.ipv4.tcp_tw_recycle` and do not recommend
enabling it._ enabling it._
@ -106,6 +128,7 @@ You should also modify your open file settings to `100000`. This can be done on
with the command: `ulimit -n 100000`. with the command: `ulimit -n 100000`.
### Memory-Mapped Files ### Memory-Mapped Files
`rosetta-bitcoin` uses [memory-mapped files](https://en.wikipedia.org/wiki/Memory-mapped_file) to `rosetta-bitcoin` uses [memory-mapped files](https://en.wikipedia.org/wiki/Memory-mapped_file) to
persist data in the `indexer`. As a result, you **must** run `rosetta-bitcoin` on a 64-bit persist data in the `indexer`. As a result, you **must** run `rosetta-bitcoin` on a 64-bit
architecture (the virtual address space easily exceeds 100s of GBs). architecture (the virtual address space easily exceeds 100s of GBs).
@ -114,10 +137,12 @@ If you receive a kernel OOM, you may need to increase the allocated size of swap
on your OS. There is a great tutorial for how to do this on Linux [here](https://linuxize.com/post/create-a-linux-swap-file/). on your OS. There is a great tutorial for how to do this on Linux [here](https://linuxize.com/post/create-a-linux-swap-file/).
## Architecture ## Architecture
`rosetta-bitcoin` uses the `syncer`, `storage`, `parser`, and `server` package `rosetta-bitcoin` uses the `syncer`, `storage`, `parser`, and `server` package
from [`rosetta-sdk-go`](https://github.com/coinbase/rosetta-sdk-go) instead from [`rosetta-sdk-go`](https://github.com/lbryio/rosetta-sdk-go) instead
of a new Bitcoin-specific implementation of packages of similar functionality. Below of a new Bitcoin-specific implementation of packages of similar functionality. Below
you can find a high-level overview of how everything fits together: you can find a high-level overview of how everything fits together:
```text ```text
+------------------------------------------------------------------+ +------------------------------------------------------------------+
| | | |
@ -157,17 +182,20 @@ you can find a high-level overview of how everything fits together:
``` ```
### Optimizations ### Optimizations
* Automatically prune bitcoind while indexing blocks
* Reduce sync time with concurrent block indexing - Automatically prune bitcoind while indexing blocks
* Use [Zstandard compression](https://github.com/facebook/zstd) to reduce the size of data stored on disk - Reduce sync time with concurrent block indexing
without needing to write a manual byte-level encoding - Use [Zstandard compression](https://github.com/facebook/zstd) to reduce the size of data stored on disk
without needing to write a manual byte-level encoding
#### Concurrent Block Syncing #### Concurrent Block Syncing
To speed up indexing, `rosetta-bitcoin` uses concurrent block processing To speed up indexing, `rosetta-bitcoin` uses concurrent block processing
with a "wait free" design (using channels instead of sleeps to signal with a "wait free" design (using channels instead of sleeps to signal
which threads are unblocked). This allows `rosetta-bitcoin` to fetch which threads are unblocked). This allows `rosetta-bitcoin` to fetch
multiple inputs from disk while it waits for inputs that appeared multiple inputs from disk while it waits for inputs that appeared
in recently processed blocks to save to disk. in recently processed blocks to save to disk.
```text ```text
+----------+ +----------+
| bitcoind | | bitcoind |
@ -205,30 +233,35 @@ in recently processed blocks to save to disk.
``` ```
## Testing with rosetta-cli ## Testing with rosetta-cli
To validate `rosetta-bitcoin`, [install `rosetta-cli`](https://github.com/coinbase/rosetta-cli#install)
To validate `rosetta-bitcoin`, [install `rosetta-cli`](https://github.com/lbryio/rosetta-cli#install)
and run one of the following commands: and run one of the following commands:
* `rosetta-cli check:data --configuration-file rosetta-cli-conf/testnet/config.json`
* `rosetta-cli check:construction --configuration-file rosetta-cli-conf/testnet/config.json` - `rosetta-cli check:data --configuration-file rosetta-cli-conf/testnet/config.json`
* `rosetta-cli check:data --configuration-file rosetta-cli-conf/mainnet/config.json` - `rosetta-cli check:construction --configuration-file rosetta-cli-conf/testnet/config.json`
- `rosetta-cli check:data --configuration-file rosetta-cli-conf/mainnet/config.json`
## Future Work ## Future Work
* Publish benchamrks for sync speed, storage usage, and load testing
* [Rosetta API `/mempool/transaction`](https://www.rosetta-api.org/docs/MempoolApi.html#mempooltransaction) implementation - Publish benchamrks for sync speed, storage usage, and load testing
* Add CI test using `rosetta-cli` to run on each PR (likely on a regtest network) - [Rosetta API `/mempool/transaction`](https://www.rosetta-api.org/docs/MempoolApi.html#mempooltransaction) implementation
* Add performance mode to use unlimited RAM (implementation currently optimized to use <= 16 GB of RAM) - Add CI test using `rosetta-cli` to run on each PR (likely on a regtest network)
* Support Multi-Sig Sends - Add performance mode to use unlimited RAM (implementation currently optimized to use <= 16 GB of RAM)
- Support Multi-Sig Sends
_Please reach out on our [community](https://community.rosetta-api.org) if you want to tackle anything on this list!_ _Please reach out on our [community](https://community.rosetta-api.org) if you want to tackle anything on this list!_
## Development ## Development
* `make deps` to install dependencies
* `make test` to run tests - `make deps` to install dependencies
* `make lint` to lint the source code - `make test` to run tests
* `make salus` to check for security concerns - `make lint` to lint the source code
* `make build-local` to build a Docker image from the local context - `make salus` to check for security concerns
* `make coverage-local` to generate a coverage report - `make build-local` to build a Docker image from the local context
- `make coverage-local` to generate a coverage report
## License ## License
This project is available open source under the terms of the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0). This project is available open source under the terms of the [Apache 2.0 License](https://opensource.org/licenses/Apache-2.0).
© 2020 Coinbase © 2020 Coinbase

View file

@ -1,17 +0,0 @@
{
"network": {
"blockchain": "Bitcoin",
"network": "Mainnet"
},
"online_url": "http://localhost:8080",
"data_directory": "",
"http_timeout": 10,
"sync_concurrency": 8,
"transaction_concurrency": 16,
"tip_delay": 300,
"disable_memory_limit": false,
"log_configuration": false,
"data": {
"historical_balance_disabled": true
}
}

View file

@ -1,14 +1,14 @@
## ##
## bitcoin.conf configuration file. Lines beginning with # are comments. ## lbry.conf configuration file. Lines beginning with # are comments.
## ##
# DO NOT USE THIS CONFIGURATION FILE IF YOU PLAN TO EXPOSE # DO NOT USE THIS CONFIGURATION FILE IF YOU PLAN TO EXPOSE
# BITCOIND'S RPC PORT PUBLICALLY (THESE INSECURE CREDENTIALS # LBRYCRDD'S RPC PORT PUBLICALLY (THESE INSECURE CREDENTIALS
# COULD LEAD TO AN ATTACK). ROSETTA-BITCOIN USES THE RPC PORT # COULD LEAD TO AN ATTACK). ROSETTA-LBRY USES THE RPC PORT
# FOR INDEXING AND TRANSACTION BROADCAST BUT NEVER PROVIDES THE # FOR INDEXING AND TRANSACTION BROADCAST BUT NEVER PROVIDES THE
# CALLER ACCESS TO BITCOIND'S RPC PORT. # CALLER ACCESS TO LBRYCRDD'S RPC PORT.
datadir=/data/bitcoind datadir=/data/lbrycrdd
bind=0.0.0.0 bind=0.0.0.0
rpcbind=0.0.0.0 rpcbind=0.0.0.0
bantime=15 bantime=15
@ -17,8 +17,8 @@ rpcthreads=16
rpcworkqueue=1000 rpcworkqueue=1000
disablewallet=1 disablewallet=1
txindex=0 txindex=0
port=8333 port=9246
rpcport=8332 rpcport=9245
rpcuser=rosetta rpcuser=rosetta
rpcpassword=rosetta rpcpassword=rosetta

View file

@ -1,14 +1,14 @@
## ##
## bitcoin.conf configuration file. Lines beginning with # are comments. ## lbry.conf configuration file. Lines beginning with # are comments.
## ##
# DO NOT USE THIS CONFIGURATION FILE IF YOU PLAN TO EXPOSE # DO NOT USE THIS CONFIGURATION FILE IF YOU PLAN TO EXPOSE
# BITCOIND'S RPC PORT PUBLICALLY (THESE INSECURE CREDENTIALS # LBRYCRDD'S RPC PORT PUBLICALLY (THESE INSECURE CREDENTIALS
# COULD LEAD TO AN ATTACK). ROSETTA-BITCOIN USES THE RPC PORT # COULD LEAD TO AN ATTACK). ROSETTA-LBRY USES THE RPC PORT
# FOR INDEXING AND TRANSACTION BROADCAST BUT NEVER PROVIDES THE # FOR INDEXING AND TRANSACTION BROADCAST BUT NEVER PROVIDES THE
# CALLER ACCESS TO BITCOIND'S RPC PORT. # CALLER ACCESS TO LBRYCRDD'S RPC PORT.
datadir=/data/bitcoind datadir=/data/lbrycrdd
bantime=15 bantime=15
rpcallowip=0.0.0.0/0 rpcallowip=0.0.0.0/0
rpcthreads=16 rpcthreads=16
@ -23,7 +23,7 @@ prune=1
testnet=1 testnet=1
[test] [test]
port=18333 port=19246
bind=0.0.0.0 bind=0.0.0.0
rpcport=18332 rpcport=19245
rpcbind=0.0.0.0 rpcbind=0.0.0.0

17
assets/lbry.json Normal file
View file

@ -0,0 +1,17 @@
{
"network": {
"blockchain": "LBRY",
"network": "Mainnet"
},
"online_url": "http://localhost:8080",
"data_directory": "",
"http_timeout": 10,
"sync_concurrency": 8,
"transaction_concurrency": 16,
"tip_delay": 300,
"disable_memory_limit": false,
"log_configuration": false,
"data": {
"historical_balance_disabled": true
}
}

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package bitcoin package lbry
import ( import (
"bytes" "bytes"
@ -26,17 +26,17 @@ import (
"strconv" "strconv"
"time" "time"
bitcoinUtils "github.com/coinbase/rosetta-bitcoin/utils" lbryUtils "github.com/lbryio/rosetta-lbry/utils"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/lbryio/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/coinbase/rosetta-sdk-go/utils" "github.com/lbryio/rosetta-sdk-go/utils"
) )
const ( const (
// genesisBlockIndex is the height of the block we consider to be the // genesisBlockIndex is the height of the block we consider to be the
// genesis block of the bitcoin blockchain for polling // genesis block of the lbry blockchain for polling
genesisBlockIndex = 0 genesisBlockIndex = 0
// requestID is the JSON-RPC request ID we use for making requests. // requestID is the JSON-RPC request ID we use for making requests.
@ -57,28 +57,28 @@ const (
type requestMethod string type requestMethod string
const ( const (
// https://bitcoin.org/en/developer-reference#getblock // https://lbry.org/en/developer-reference#getblock
requestMethodGetBlock requestMethod = "getblock" requestMethodGetBlock requestMethod = "getblock"
// https://bitcoin.org/en/developer-reference#getblockhash // https://lbry.org/en/developer-reference#getblockhash
requestMethodGetBlockHash requestMethod = "getblockhash" requestMethodGetBlockHash requestMethod = "getblockhash"
// https://bitcoin.org/en/developer-reference#getblockchaininfo // https://lbry.org/en/developer-reference#getblockchaininfo
requestMethodGetBlockchainInfo requestMethod = "getblockchaininfo" requestMethodGetBlockchainInfo requestMethod = "getblockchaininfo"
// https://developer.bitcoin.org/reference/rpc/getpeerinfo.html // https://developer.lbry.org/reference/rpc/getpeerinfo.html
requestMethodGetPeerInfo requestMethod = "getpeerinfo" requestMethodGetPeerInfo requestMethod = "getpeerinfo"
// https://developer.bitcoin.org/reference/rpc/pruneblockchain.html // https://developer.lbry.org/reference/rpc/pruneblockchain.html
requestMethodPruneBlockchain requestMethod = "pruneblockchain" requestMethodPruneBlockchain requestMethod = "pruneblockchain"
// https://developer.bitcoin.org/reference/rpc/sendrawtransaction.html // https://developer.lbry.org/reference/rpc/sendrawtransaction.html
requestMethodSendRawTransaction requestMethod = "sendrawtransaction" requestMethodSendRawTransaction requestMethod = "sendrawtransaction"
// https://developer.bitcoin.org/reference/rpc/estimatesmartfee.html // https://developer.lbry.org/reference/rpc/estimatesmartfee.html
requestMethodEstimateSmartFee requestMethod = "estimatesmartfee" requestMethodEstimateSmartFee requestMethod = "estimatesmartfee"
// https://developer.bitcoin.org/reference/rpc/getrawmempool.html // https://developer.lbry.org/reference/rpc/getrawmempool.html
requestMethodRawMempool requestMethod = "getrawmempool" requestMethodRawMempool requestMethod = "getrawmempool"
// blockNotFoundErrCode is the RPC error code when a block cannot be found // blockNotFoundErrCode is the RPC error code when a block cannot be found
@ -90,11 +90,11 @@ const (
dialTimeout = 5 * time.Second dialTimeout = 5 * time.Second
// timeMultiplier is used to multiply the time // timeMultiplier is used to multiply the time
// returned in Bitcoin blocks to be milliseconds. // returned in lbry blocks to be milliseconds.
timeMultiplier = 1000 timeMultiplier = 1000
// rpc credentials are fixed in rosetta-bitcoin // rpc credentials are fixed in rosetta-lbry
// because we never expose access to the raw bitcoind // because we never expose access to the raw lbryd
// endpoints (that could be used perform an attack, like // endpoints (that could be used perform an attack, like
// changing our peers). // changing our peers).
rpcUsername = "rosetta" rpcUsername = "rosetta"
@ -110,10 +110,10 @@ var (
ErrJSONRPCError = errors.New("JSON-RPC error") ErrJSONRPCError = errors.New("JSON-RPC error")
) )
// Client is used to fetch blocks from bitcoind and // Client is used to fetch blocks from lbryd and
// to parse Bitcoin block data into Rosetta types. // to parse lbry block data into Rosetta types.
// //
// We opted not to use existing Bitcoin RPC libraries // We opted not to use existing lbry RPC libraries
// because they don't allow providing context // because they don't allow providing context
// in each request. // in each request.
type Client struct { type Client struct {
@ -131,7 +131,7 @@ func LocalhostURL(rpcPort int) string {
return fmt.Sprintf("http://localhost:%d", rpcPort) return fmt.Sprintf("http://localhost:%d", rpcPort)
} }
// NewClient creates a new Bitcoin client. // NewClient creates a new lbry client.
func NewClient( func NewClient(
baseURL string, baseURL string,
genesisBlockIdentifier *types.BlockIdentifier, genesisBlockIdentifier *types.BlockIdentifier,
@ -162,7 +162,7 @@ func newHTTPClient(timeout time.Duration) *http.Client {
} }
// NetworkStatus returns the *types.NetworkStatusResponse for // NetworkStatus returns the *types.NetworkStatusResponse for
// bitcoind. // lbryd.
func (b *Client) NetworkStatus(ctx context.Context) (*types.NetworkStatusResponse, error) { func (b *Client) NetworkStatus(ctx context.Context) (*types.NetworkStatusResponse, error) {
rawBlock, err := b.getBlock(ctx, nil) rawBlock, err := b.getBlock(ctx, nil)
if err != nil { if err != nil {
@ -241,7 +241,7 @@ func (b *Client) GetRawBlock(
return block, coins, nil return block, coins, nil
} }
// ParseBlock returns a parsed bitcoin block given a raw bitcoin // ParseBlock returns a parsed lbry block given a raw lbry
// block and a map of transactions containing inputs. // block and a map of transactions containing inputs.
func (b *Client) ParseBlock( func (b *Client) ParseBlock(
ctx context.Context, ctx context.Context,
@ -264,7 +264,7 @@ func (b *Client) ParseBlock(
} }
// SendRawTransaction submits a serialized transaction // SendRawTransaction submits a serialized transaction
// to bitcoind. // to lbryd.
func (b *Client) SendRawTransaction( func (b *Client) SendRawTransaction(
ctx context.Context, ctx context.Context,
serializedTx string, serializedTx string,
@ -301,14 +301,14 @@ func (b *Client) SuggestedFeeRate(
} }
// PruneBlockchain prunes up to the provided height. // PruneBlockchain prunes up to the provided height.
// https://bitcoincore.org/en/doc/0.20.0/rpc/blockchain/pruneblockchain // https://lbrycore.org/en/doc/0.20.0/rpc/blockchain/pruneblockchain
func (b *Client) PruneBlockchain( func (b *Client) PruneBlockchain(
ctx context.Context, ctx context.Context,
height int64, height int64,
) (int64, error) { ) (int64, error) {
// Parameters: // Parameters:
// 1. Height // 1. Height
// https://developer.bitcoin.org/reference/rpc/pruneblockchain.html#argument-1-height // https://developer.lbry.org/reference/rpc/pruneblockchain.html#argument-1-height
params := []interface{}{height} params := []interface{}{height}
response := &pruneBlockchainResponse{} response := &pruneBlockchainResponse{}
@ -362,7 +362,7 @@ func (b *Client) getBlock(
// Parameters: // Parameters:
// 1. Block hash (string, required) // 1. Block hash (string, required)
// 2. Verbosity (integer, optional, default=1) // 2. Verbosity (integer, optional, default=1)
// https://bitcoin.org/en/developer-reference#getblock // https://lbry.org/en/developer-reference#getblock
params := []interface{}{hash, blockVerbosity} params := []interface{}{hash, blockVerbosity}
response := &blockResponse{} response := &blockResponse{}
@ -448,14 +448,14 @@ func (b *Client) parseBlockData(block *Block) (*types.Block, error) {
// getHashFromIndex performs the `getblockhash` JSON-RPC request for the specified // getHashFromIndex performs the `getblockhash` JSON-RPC request for the specified
// block index, and returns the hash. // block index, and returns the hash.
// https://bitcoin.org/en/developer-reference#getblockhash // https://lbry.org/en/developer-reference#getblockhash
func (b *Client) getHashFromIndex( func (b *Client) getHashFromIndex(
ctx context.Context, ctx context.Context,
index int64, index int64,
) (string, error) { ) (string, error) {
// Parameters: // Parameters:
// 1. Block height (numeric, required) // 1. Block height (numeric, required)
// https://bitcoin.org/en/developer-reference#getblockhash // https://lbry.org/en/developer-reference#getblockhash
params := []interface{}{index} params := []interface{}{index}
response := &blockHashResponse{} response := &blockHashResponse{}
@ -472,9 +472,9 @@ func (b *Client) getHashFromIndex(
// skipTransactionOperations is used to skip operations on transactions that // skipTransactionOperations is used to skip operations on transactions that
// contain duplicate UTXOs (which are no longer possible after BIP-30). This // contain duplicate UTXOs (which are no longer possible after BIP-30). This
// function mirrors the behavior of a similar commit in bitcoin-core. // function mirrors the behavior of a similar commit in lbry-core.
// //
// Source: https://github.com/bitcoin/bitcoin/commit/ab91bf39b7c11e9c86bb2043c24f0f377f1cf514 // Source: https://github.com/lbry/lbry/commit/ab91bf39b7c11e9c86bb2043c24f0f377f1cf514
func skipTransactionOperations(blockNumber int64, blockHash string, transactionHash string) bool { func skipTransactionOperations(blockNumber int64, blockHash string, transactionHash string) bool {
if blockNumber == 91842 && blockHash == "00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec" && if blockNumber == 91842 && blockHash == "00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec" &&
transactionHash == "d5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599" { transactionHash == "d5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599" {
@ -495,7 +495,7 @@ func (b *Client) parseTransactions(
block *Block, block *Block,
coins map[string]*storage.AccountCoin, coins map[string]*storage.AccountCoin,
) ([]*types.Transaction, error) { ) ([]*types.Transaction, error) {
logger := bitcoinUtils.ExtractLogger(ctx, "client") logger := lbryUtils.ExtractLogger(ctx, "client")
if block == nil { if block == nil {
return nil, errors.New("error parsing nil block") return nil, errors.New("error parsing nil block")
@ -571,7 +571,7 @@ func (b *Client) parseTxOperations(
txOps := []*types.Operation{} txOps := []*types.Operation{}
for networkIndex, input := range tx.Inputs { for networkIndex, input := range tx.Inputs {
if bitcoinIsCoinbaseInput(input, txIndex, networkIndex) { if lbryIsCoinbaseInput(input, txIndex, networkIndex) {
txOp, err := b.coinbaseTxOperation(input, int64(len(txOps)), int64(networkIndex)) txOp, err := b.coinbaseTxOperation(input, int64(len(txOps)), int64(networkIndex))
if err != nil { if err != nil {
return nil, err return nil, err
@ -629,7 +629,7 @@ func (b *Client) parseTxOperations(
} }
// parseOutputTransactionOperation returns the types.Operation for the specified // parseOutputTransactionOperation returns the types.Operation for the specified
// `bitcoinOutput` transaction output. // `lbryOutput` transaction output.
func (b *Client) parseOutputTransactionOperation( func (b *Client) parseOutputTransactionOperation(
output *Output, output *Output,
txHash string, txHash string,
@ -658,7 +658,7 @@ func (b *Client) parseOutputTransactionOperation(
CoinAction: types.CoinCreated, CoinAction: types.CoinCreated,
} }
// If we are unable to parse the output account (i.e. bitcoind // If we are unable to parse the output account (i.e. lbryd
// returns a blank/nonstandard ScriptPubKey), we create an address as the // returns a blank/nonstandard ScriptPubKey), we create an address as the
// concatenation of the tx hash and index. // concatenation of the tx hash and index.
// //
@ -700,17 +700,17 @@ func (b *Client) getInputTxHash(
txIndex int, txIndex int,
inputIndex int, inputIndex int,
) (string, int64, bool) { ) (string, int64, bool) {
if bitcoinIsCoinbaseInput(input, txIndex, inputIndex) { if lbryIsCoinbaseInput(input, txIndex, inputIndex) {
return "", -1, false return "", -1, false
} }
return input.TxHash, input.Vout, true return input.TxHash, input.Vout, true
} }
// bitcoinIsCoinbaseInput returns whether the specified input is // lbryIsCoinbaseInput returns whether the specified input is
// the coinbase input. The coinbase input is always the first input in the first // the coinbase input. The coinbase input is always the first input in the first
// transaction, and does not contain a previous transaction hash. // transaction, and does not contain a previous transaction hash.
func bitcoinIsCoinbaseInput(input *Input, txIndex int, inputIndex int) bool { func lbryIsCoinbaseInput(input *Input, txIndex int, inputIndex int) bool {
return txIndex == 0 && inputIndex == 0 && input.TxHash == "" && input.Coinbase != "" return txIndex == 0 && inputIndex == 0 && input.TxHash == "" && input.Coinbase != ""
} }
@ -769,7 +769,7 @@ func (b *Client) parseAmount(amount float64) (uint64, error) {
return uint64(atomicAmount), nil return uint64(atomicAmount), nil
} }
// parseOutputAccount parses a bitcoinScriptPubKey and returns an account // parseOutputAccount parses a lbryScriptPubKey and returns an account
// identifier. The account identifier's address corresponds to the first // identifier. The account identifier's address corresponds to the first
// address encoded in the script. // address encoded in the script.
func (b *Client) parseOutputAccount( func (b *Client) parseOutputAccount(
@ -805,7 +805,7 @@ func (b *Client) coinbaseTxOperation(
}, nil }, nil
} }
// post makes a HTTP request to a Bitcoin node // post makes a HTTP request to a lbry node
func (b *Client) post( func (b *Client) post(
ctx context.Context, ctx context.Context,
method requestMethod, method requestMethod,

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package bitcoin package lbry
import ( import (
"context" "context"
@ -24,8 +24,8 @@ import (
"net/http/httptest" "net/http/httptest"
"testing" "testing"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/lbryio/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package bitcoin package lbry
import ( import (
"bufio" "bufio"
@ -23,14 +23,14 @@ import (
"os/exec" "os/exec"
"strings" "strings"
"github.com/coinbase/rosetta-bitcoin/utils" "github.com/lbryio/rosetta-lbry/utils"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
const ( const (
bitcoindLogger = "bitcoind" lbrydLogger = "lbryd"
bitcoindStdErrLogger = "bitcoind stderr" lbrydStdErrLogger = "lbryd stderr"
) )
func logPipe(ctx context.Context, pipe io.ReadCloser, identifier string) error { func logPipe(ctx context.Context, pipe io.ReadCloser, identifier string) error {
@ -51,8 +51,8 @@ func logPipe(ctx context.Context, pipe io.ReadCloser, identifier string) error {
message = messages[1] message = messages[1]
} }
// Print debug log if from bitcoindLogger // Print debug log if from lbrydLogger
if identifier == bitcoindLogger { if identifier == lbrydLogger {
logger.Debugw(message) logger.Debugw(message)
continue continue
} }
@ -61,12 +61,12 @@ func logPipe(ctx context.Context, pipe io.ReadCloser, identifier string) error {
} }
} }
// StartBitcoind starts a bitcoind daemon in another goroutine // Startlbryd starts a lbryd daemon in another goroutine
// and logs the results to the console. // and logs the results to the console.
func StartBitcoind(ctx context.Context, configPath string, g *errgroup.Group) error { func Startlbryd(ctx context.Context, configPath string, g *errgroup.Group) error {
logger := utils.ExtractLogger(ctx, "bitcoind") logger := utils.ExtractLogger(ctx, "lbryd")
cmd := exec.Command( cmd := exec.Command(
"/app/bitcoind", "/app/lbryd",
fmt.Sprintf("--conf=%s", configPath), fmt.Sprintf("--conf=%s", configPath),
) // #nosec G204 ) // #nosec G204
@ -81,21 +81,21 @@ func StartBitcoind(ctx context.Context, configPath string, g *errgroup.Group) er
} }
g.Go(func() error { g.Go(func() error {
return logPipe(ctx, stdout, bitcoindLogger) return logPipe(ctx, stdout, lbrydLogger)
}) })
g.Go(func() error { g.Go(func() error {
return logPipe(ctx, stderr, bitcoindStdErrLogger) return logPipe(ctx, stderr, lbrydStdErrLogger)
}) })
if err := cmd.Start(); err != nil { if err := cmd.Start(); err != nil {
return fmt.Errorf("%w: unable to start bitcoind", err) return fmt.Errorf("%w: unable to start lbryd", err)
} }
g.Go(func() error { g.Go(func() error {
<-ctx.Done() <-ctx.Done()
logger.Warnw("sending interrupt to bitcoind") logger.Warnw("sending interrupt to lbryd")
return cmd.Process.Signal(os.Interrupt) return cmd.Process.Signal(os.Interrupt)
}) })

View file

@ -12,19 +12,19 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package bitcoin package lbry
import ( import (
"fmt" "fmt"
"strings" "strings"
"github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
const ( const (
// Blockchain is Bitcoin. // Blockchain is lbry.
Blockchain string = "Bitcoin" Blockchain string = "lbry"
// MainnetNetwork is the value of the network // MainnetNetwork is the value of the network
// in MainnetNetworkIdentifier. // in MainnetNetworkIdentifier.
@ -38,9 +38,9 @@ const (
// used in Currency. // used in Currency.
Decimals = 8 Decimals = 8
// SatoshisInBitcoin is the number of // SatoshisInlbry is the number of
// Satoshis in 1 BTC (10^8). // Satoshis in 1 BTC (10^8).
SatoshisInBitcoin = 100000000 SatoshisInlbry = 100000000
// InputOpType is used to describe // InputOpType is used to describe
// INPUT. // INPUT.
@ -55,7 +55,7 @@ const (
CoinbaseOpType = "COINBASE" CoinbaseOpType = "COINBASE"
// SuccessStatus is the status of all // SuccessStatus is the status of all
// Bitcoin operations because anything // lbry operations because anything
// on-chain is considered successful. // on-chain is considered successful.
SuccessStatus = "SUCCESS" SuccessStatus = "SUCCESS"
@ -66,17 +66,17 @@ const (
SkippedStatus = "SKIPPED" SkippedStatus = "SKIPPED"
// TransactionHashLength is the length // TransactionHashLength is the length
// of any transaction hash in Bitcoin. // of any transaction hash in lbry.
TransactionHashLength = 64 TransactionHashLength = 64
// NullData is returned by bitcoind // NullData is returned by lbryd
// as the ScriptPubKey.Type for OP_RETURN // as the ScriptPubKey.Type for OP_RETURN
// locking scripts. // locking scripts.
NullData = "nulldata" NullData = "nulldata"
) )
// Fee estimate constants // Fee estimate constants
// Source: https://bitcoinops.org/en/tools/calc-size/ // Source: https://lbryops.org/en/tools/calc-size/
const ( const (
MinFeeRate = float64(0.00001) // nolint:gomnd MinFeeRate = float64(0.00001) // nolint:gomnd
TransactionOverhead = 12 // 4 version, 2 segwit flag, 1 vin, 1 vout, 4 lock time TransactionOverhead = 12 // 4 version, 2 segwit flag, 1 vin, 1 vout, 4 lock time
@ -135,7 +135,7 @@ var (
) )
// ScriptPubKey is a script placed on the output operations // ScriptPubKey is a script placed on the output operations
// of a Bitcoin transaction that must be satisfied to spend // of a lbry transaction that must be satisfied to spend
// the output. // the output.
type ScriptPubKey struct { type ScriptPubKey struct {
ASM string `json:"asm"` ASM string `json:"asm"`
@ -146,14 +146,14 @@ type ScriptPubKey struct {
} }
// ScriptSig is a script on the input operations of a // ScriptSig is a script on the input operations of a
// Bitcoin transaction that satisfies the ScriptPubKey // lbry transaction that satisfies the ScriptPubKey
// on an output being spent. // on an output being spent.
type ScriptSig struct { type ScriptSig struct {
ASM string `json:"asm"` ASM string `json:"asm"`
Hex string `json:"hex"` Hex string `json:"hex"`
} }
// BlockchainInfo is information about the Bitcoin network. // BlockchainInfo is information about the lbry network.
// This struct only contains the information necessary for // This struct only contains the information necessary for
// this implementation. // this implementation.
type BlockchainInfo struct { type BlockchainInfo struct {
@ -176,7 +176,7 @@ type PeerInfo struct {
SyncedHeaders int64 `json:"synced_headers"` SyncedHeaders int64 `json:"synced_headers"`
} }
// Block is a raw Bitcoin block (with verbosity == 2). // Block is a raw lbry block (with verbosity == 2).
type Block struct { type Block struct {
Hash string `json:"hash"` Hash string `json:"hash"`
Height int64 `json:"height"` Height int64 `json:"height"`
@ -223,7 +223,7 @@ type BlockMetadata struct {
Difficulty float64 `json:"difficulty,omitempty"` Difficulty float64 `json:"difficulty,omitempty"`
} }
// Transaction is a raw Bitcoin transaction. // Transaction is a raw lbry transaction.
type Transaction struct { type Transaction struct {
Hex string `json:"hex"` Hex string `json:"hex"`
Hash string `json:"txid"` Hash string `json:"txid"`
@ -260,7 +260,7 @@ type TransactionMetadata struct {
Weight int64 `json:"weight,omitempty"` Weight int64 `json:"weight,omitempty"`
} }
// Input is a raw input in a Bitcoin transaction. // Input is a raw input in a lbry transaction.
type Input struct { type Input struct {
TxHash string `json:"txid"` TxHash string `json:"txid"`
Vout int64 `json:"vout"` Vout int64 `json:"vout"`
@ -284,7 +284,7 @@ func (i Input) Metadata() (map[string]interface{}, error) {
return types.MarshalMap(m) return types.MarshalMap(m)
} }
// Output is a raw output in a Bitcoin transaction. // Output is a raw output in a lbry transaction.
type Output struct { type Output struct {
Value float64 `json:"value"` Value float64 `json:"value"`
Index int64 `json:"n"` Index int64 `json:"n"`
@ -301,7 +301,7 @@ func (o Output) Metadata() (map[string]interface{}, error) {
} }
// OperationMetadata is a collection of useful // OperationMetadata is a collection of useful
// metadata from Bitcoin inputs and outputs. // metadata from lbry inputs and outputs.
type OperationMetadata struct { type OperationMetadata struct {
// Coinbase Metadata // Coinbase Metadata
Coinbase string `json:"coinbase,omitempty"` Coinbase string `json:"coinbase,omitempty"`
@ -499,7 +499,7 @@ func (r rawMempoolResponse) Err() error {
// CoinIdentifier converts a tx hash and vout into // CoinIdentifier converts a tx hash and vout into
// the canonical CoinIdentifier.Identifier used in // the canonical CoinIdentifier.Identifier used in
// rosetta-bitcoin. // rosetta-lbry.
func CoinIdentifier(hash string, vout int64) string { func CoinIdentifier(hash string, vout int64) string {
return fmt.Sprintf("%s:%d", hash, vout) return fmt.Sprintf("%s:%d", hash, vout)
} }

View file

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
package bitcoin package lbry
import ( import (
"fmt" "fmt"
@ -23,7 +23,7 @@ import (
"github.com/btcsuite/btcd/chaincfg/chainhash" "github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
// ParseCoinIdentifier returns the corresponding hash and index associated // ParseCoinIdentifier returns the corresponding hash and index associated

View file

@ -22,11 +22,11 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/lbry"
"github.com/btcsuite/btcd/chaincfg" "github.com/btcsuite/btcd/chaincfg"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/lbryio/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
// Mode is the setting that determines if // Mode is the setting that determines if
@ -42,34 +42,34 @@ const (
// to make outbound connections. // to make outbound connections.
Offline Mode = "OFFLINE" Offline Mode = "OFFLINE"
// Mainnet is the Bitcoin Mainnet. // Mainnet is the lbry Mainnet.
Mainnet string = "MAINNET" Mainnet string = "MAINNET"
// Testnet is Bitcoin Testnet3. // Testnet is lbry Testnet3.
Testnet string = "TESTNET" Testnet string = "TESTNET"
// mainnetConfigPath is the path of the Bitcoin // mainnetConfigPath is the path of the lbry
// configuration file for mainnet. // configuration file for mainnet.
mainnetConfigPath = "/app/bitcoin-mainnet.conf" mainnetConfigPath = "/app/lbry-mainnet.conf"
// testnetConfigPath is the path of the Bitcoin // testnetConfigPath is the path of the lbry
// configuration file for testnet. // configuration file for testnet.
testnetConfigPath = "/app/bitcoin-testnet.conf" testnetConfigPath = "/app/lbry-testnet.conf"
// Zstandard compression dictionaries // Zstandard compression dictionaries
transactionNamespace = "transaction" transactionNamespace = "transaction"
testnetTransactionDictionary = "/app/testnet-transaction.zstd" testnetTransactionDictionary = "/app/testnet-transaction.zstd"
mainnetTransactionDictionary = "/app/mainnet-transaction.zstd" mainnetTransactionDictionary = "/app/mainnet-transaction.zstd"
mainnetRPCPort = 8332 mainnetRPCPort = 9245
testnetRPCPort = 18332 testnetRPCPort = 19245
// min prune depth is 288: // min prune depth is 288:
// https://github.com/bitcoin/bitcoin/blob/ad2952d17a2af419a04256b10b53c7377f826a27/src/validation.h#L84 // https://github.com/lbry/lbry/blob/ad2952d17a2af419a04256b10b53c7377f826a27/src/validation.h#L84
pruneDepth = int64(10000) //nolint pruneDepth = int64(10000) //nolint
// min prune height (on mainnet): // min prune height (on mainnet):
// https://github.com/bitcoin/bitcoin/blob/62d137ac3b701aae36c1aa3aa93a83fd6357fde6/src/chainparams.cpp#L102 // https://github.com/lbry/lbry/blob/62d137ac3b701aae36c1aa3aa93a83fd6357fde6/src/chainparams.cpp#L102
minPruneHeight = int64(100000) //nolint minPruneHeight = int64(100000) //nolint
// attempt to prune once an hour // attempt to prune once an hour
@ -79,8 +79,8 @@ const (
// persistent data. // persistent data.
DataDirectory = "/data" DataDirectory = "/data"
bitcoindPath = "bitcoind" LBRYcrdPath = "LBRYcrd"
indexerPath = "indexer" indexerPath = "indexer"
// allFilePermissions specifies anyone can do anything // allFilePermissions specifies anyone can do anything
// to the file. // to the file.
@ -120,7 +120,7 @@ type Configuration struct {
ConfigPath string ConfigPath string
Pruning *PruningConfiguration Pruning *PruningConfiguration
IndexerPath string IndexerPath string
BitcoindPath string LBRYcrdPath string
Compressors []*storage.CompressorEntry Compressors []*storage.CompressorEntry
} }
@ -143,9 +143,9 @@ func LoadConfiguration(baseDirectory string) (*Configuration, error) {
return nil, fmt.Errorf("%w: unable to create indexer path", err) return nil, fmt.Errorf("%w: unable to create indexer path", err)
} }
config.BitcoindPath = path.Join(baseDirectory, bitcoindPath) config.LBRYcrdPath = path.Join(baseDirectory, LBRYcrdPath)
if err := ensurePathExists(config.BitcoindPath); err != nil { if err := ensurePathExists(config.LBRYcrdPath); err != nil {
return nil, fmt.Errorf("%w: unable to create bitcoind path", err) return nil, fmt.Errorf("%w: unable to create LBRYcrd path", err)
} }
case Offline: case Offline:
config.Mode = Offline config.Mode = Offline
@ -159,12 +159,12 @@ func LoadConfiguration(baseDirectory string) (*Configuration, error) {
switch networkValue { switch networkValue {
case Mainnet: case Mainnet:
config.Network = &types.NetworkIdentifier{ config.Network = &types.NetworkIdentifier{
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
Network: bitcoin.MainnetNetwork, Network: lbry.MainnetNetwork,
} }
config.GenesisBlockIdentifier = bitcoin.MainnetGenesisBlockIdentifier config.GenesisBlockIdentifier = lbry.MainnetGenesisBlockIdentifier
config.Params = bitcoin.MainnetParams config.Params = lbry.MainnetParams
config.Currency = bitcoin.MainnetCurrency config.Currency = lbry.MainnetCurrency
config.ConfigPath = mainnetConfigPath config.ConfigPath = mainnetConfigPath
config.RPCPort = mainnetRPCPort config.RPCPort = mainnetRPCPort
config.Compressors = []*storage.CompressorEntry{ config.Compressors = []*storage.CompressorEntry{
@ -175,12 +175,12 @@ func LoadConfiguration(baseDirectory string) (*Configuration, error) {
} }
case Testnet: case Testnet:
config.Network = &types.NetworkIdentifier{ config.Network = &types.NetworkIdentifier{
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
Network: bitcoin.TestnetNetwork, Network: lbry.TestnetNetwork,
} }
config.GenesisBlockIdentifier = bitcoin.TestnetGenesisBlockIdentifier config.GenesisBlockIdentifier = lbry.TestnetGenesisBlockIdentifier
config.Params = bitcoin.TestnetParams config.Params = lbry.TestnetParams
config.Currency = bitcoin.TestnetCurrency config.Currency = lbry.TestnetCurrency
config.ConfigPath = testnetConfigPath config.ConfigPath = testnetConfigPath
config.RPCPort = testnetRPCPort config.RPCPort = testnetRPCPort
config.Compressors = []*storage.CompressorEntry{ config.Compressors = []*storage.CompressorEntry{

View file

@ -20,11 +20,11 @@ import (
"path" "path"
"testing" "testing"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/lbry"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/lbryio/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/coinbase/rosetta-sdk-go/utils" "github.com/lbryio/rosetta-sdk-go/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -56,12 +56,12 @@ func TestLoadConfiguration(t *testing.T) {
cfg: &Configuration{ cfg: &Configuration{
Mode: Online, Mode: Online,
Network: &types.NetworkIdentifier{ Network: &types.NetworkIdentifier{
Network: bitcoin.MainnetNetwork, Network: lbry.MainnetNetwork,
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
}, },
Params: bitcoin.MainnetParams, Params: lbry.MainnetParams,
Currency: bitcoin.MainnetCurrency, Currency: lbry.MainnetCurrency,
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
Port: 1000, Port: 1000,
RPCPort: mainnetRPCPort, RPCPort: mainnetRPCPort,
ConfigPath: mainnetConfigPath, ConfigPath: mainnetConfigPath,
@ -85,12 +85,12 @@ func TestLoadConfiguration(t *testing.T) {
cfg: &Configuration{ cfg: &Configuration{
Mode: Online, Mode: Online,
Network: &types.NetworkIdentifier{ Network: &types.NetworkIdentifier{
Network: bitcoin.TestnetNetwork, Network: lbry.TestnetNetwork,
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
}, },
Params: bitcoin.TestnetParams, Params: lbry.TestnetParams,
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
GenesisBlockIdentifier: bitcoin.TestnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.TestnetGenesisBlockIdentifier,
Port: 1000, Port: 1000,
RPCPort: testnetRPCPort, RPCPort: testnetRPCPort,
ConfigPath: testnetConfigPath, ConfigPath: testnetConfigPath,
@ -143,7 +143,7 @@ func TestLoadConfiguration(t *testing.T) {
assert.Contains(t, err.Error(), test.err.Error()) assert.Contains(t, err.Error(), test.err.Error())
} else { } else {
test.cfg.IndexerPath = path.Join(newDir, "indexer") test.cfg.IndexerPath = path.Join(newDir, "indexer")
test.cfg.BitcoindPath = path.Join(newDir, "bitcoind") test.cfg.lbrydPath = path.Join(newDir, "lbryd")
assert.Equal(t, test.cfg, cfg) assert.Equal(t, test.cfg, cfg)
assert.NoError(t, err) assert.NoError(t, err)
} }

4
go.mod
View file

@ -1,11 +1,11 @@
module github.com/coinbase/rosetta-bitcoin module github.com/lbryio/rosetta-lbry
go 1.13 go 1.13
require ( require (
github.com/btcsuite/btcd v0.21.0-beta github.com/btcsuite/btcd v0.21.0-beta
github.com/btcsuite/btcutil v1.0.2 github.com/btcsuite/btcutil v1.0.2
github.com/coinbase/rosetta-sdk-go v0.5.9 github.com/lbryio/rosetta-sdk-go v0.5.9
github.com/dgraph-io/badger/v2 v2.2007.2 github.com/dgraph-io/badger/v2 v2.2007.2
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 github.com/grpc-ecosystem/go-grpc-middleware v1.2.2
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1

4
go.sum
View file

@ -62,8 +62,8 @@ github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJ
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coinbase/rosetta-sdk-go v0.5.9 h1:CuGQE3HFmYwdEACJnuOtVI9cofqPsGvq6FdFIzaOPKI= github.com/lbryio/rosetta-sdk-go v0.5.9 h1:CuGQE3HFmYwdEACJnuOtVI9cofqPsGvq6FdFIzaOPKI=
github.com/coinbase/rosetta-sdk-go v0.5.9/go.mod h1:xd4wYUhV3LkY78SPH8BUhc88rXfn2jYgN9BfiSjbcvM= github.com/lbryio/rosetta-sdk-go v0.5.9/go.mod h1:xd4wYUhV3LkY78SPH8BUhc88rXfn2jYgN9BfiSjbcvM=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=

View file

@ -17,9 +17,9 @@ package indexer
import ( import (
"context" "context"
"github.com/coinbase/rosetta-sdk-go/parser" "github.com/lbryio/rosetta-sdk-go/parser"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/lbryio/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
var _ storage.BalanceStorageHandler = (*BalanceStorageHandler)(nil) var _ storage.BalanceStorageHandler = (*BalanceStorageHandler)(nil)

View file

@ -17,10 +17,10 @@ package indexer
import ( import (
"context" "context"
"github.com/coinbase/rosetta-sdk-go/asserter" "github.com/lbryio/rosetta-sdk-go/asserter"
"github.com/coinbase/rosetta-sdk-go/parser" "github.com/lbryio/rosetta-sdk-go/parser"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/lbryio/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
var _ storage.BalanceStorageHelper = (*BalanceStorageHelper)(nil) var _ storage.BalanceStorageHelper = (*BalanceStorageHelper)(nil)

View file

@ -17,8 +17,8 @@ package indexer
import ( import (
"context" "context"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/lbryio/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
var _ storage.CoinStorageHelper = (*CoinStorageHelper)(nil) var _ storage.CoinStorageHelper = (*CoinStorageHelper)(nil)

View file

@ -20,18 +20,18 @@ import (
"fmt" "fmt"
"time" "time"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/lbry"
"github.com/coinbase/rosetta-bitcoin/services" "github.com/lbryio/rosetta-lbry/services"
"github.com/coinbase/rosetta-bitcoin/utils" "github.com/lbryio/rosetta-lbry/utils"
"github.com/coinbase/rosetta-sdk-go/asserter"
"github.com/coinbase/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/syncer"
"github.com/coinbase/rosetta-sdk-go/types"
sdkUtils "github.com/coinbase/rosetta-sdk-go/utils"
"github.com/dgraph-io/badger/v2" "github.com/dgraph-io/badger/v2"
"github.com/dgraph-io/badger/v2/options" "github.com/dgraph-io/badger/v2/options"
"github.com/lbryio/rosetta-sdk-go/asserter"
"github.com/lbryio/rosetta-sdk-go/storage"
"github.com/lbryio/rosetta-sdk-go/syncer"
"github.com/lbryio/rosetta-sdk-go/types"
sdkUtils "github.com/lbryio/rosetta-sdk-go/utils"
) )
const ( const (
@ -66,10 +66,10 @@ var (
type Client interface { type Client interface {
NetworkStatus(context.Context) (*types.NetworkStatusResponse, error) NetworkStatus(context.Context) (*types.NetworkStatusResponse, error)
PruneBlockchain(context.Context, int64) (int64, error) PruneBlockchain(context.Context, int64) (int64, error)
GetRawBlock(context.Context, *types.PartialBlockIdentifier) (*bitcoin.Block, []string, error) GetRawBlock(context.Context, *types.PartialBlockIdentifier) (*lbry.Block, []string, error)
ParseBlock( ParseBlock(
context.Context, context.Context,
*bitcoin.Block, *lbry.Block,
map[string]*storage.AccountCoin, map[string]*storage.AccountCoin,
) (*types.Block, error) ) (*types.Block, error)
} }
@ -180,8 +180,8 @@ func Initialize(
asserter, err := asserter.NewClientWithOptions( asserter, err := asserter.NewClientWithOptions(
config.Network, config.Network,
config.GenesisBlockIdentifier, config.GenesisBlockIdentifier,
bitcoin.OperationTypes, lbry.OperationTypes,
bitcoin.OperationStatuses, lbry.OperationStatuses,
services.Errors, services.Errors,
nil, nil,
) )
@ -219,7 +219,7 @@ func Initialize(
return i, nil return i, nil
} }
// waitForNode returns once bitcoind is ready to serve // waitForNode returns once lbryd is ready to serve
// block queries. // block queries.
func (i *Indexer) waitForNode(ctx context.Context) error { func (i *Indexer) waitForNode(ctx context.Context) error {
logger := utils.ExtractLogger(ctx, "indexer") logger := utils.ExtractLogger(ctx, "indexer")
@ -229,15 +229,15 @@ func (i *Indexer) waitForNode(ctx context.Context) error {
return nil return nil
} }
logger.Infow("waiting for bitcoind...") logger.Infow("waiting for lbryd...")
if err := sdkUtils.ContextSleep(ctx, nodeWaitSleep); err != nil { if err := sdkUtils.ContextSleep(ctx, nodeWaitSleep); err != nil {
return err return err
} }
} }
} }
// Sync attempts to index Bitcoin blocks using // Sync attempts to index lbry blocks using
// the bitcoin.Client until stopped. // the lbry.Client until stopped.
func (i *Indexer) Sync(ctx context.Context) error { func (i *Indexer) Sync(ctx context.Context) error {
if err := i.waitForNode(ctx); err != nil { if err := i.waitForNode(ctx); err != nil {
return fmt.Errorf("%w: failed to wait for node", err) return fmt.Errorf("%w: failed to wait for node", err)
@ -270,7 +270,7 @@ func (i *Indexer) Sync(ctx context.Context) error {
return syncer.Sync(ctx, startIndex, indexPlaceholder) return syncer.Sync(ctx, startIndex, indexPlaceholder)
} }
// Prune attempts to prune blocks in bitcoind every // Prune attempts to prune blocks in lbryd every
// pruneFrequency. // pruneFrequency.
func (i *Indexer) Prune(ctx context.Context) error { func (i *Indexer) Prune(ctx context.Context) error {
logger := utils.ExtractLogger(ctx, "pruner") logger := utils.ExtractLogger(ctx, "pruner")
@ -289,25 +289,25 @@ func (i *Indexer) Prune(ctx context.Context) error {
continue continue
} }
// Must meet pruning conditions in bitcoin core // Must meet pruning conditions in lbry core
// Source: // Source:
// https://github.com/bitcoin/bitcoin/blob/a63a26f042134fa80356860c109edb25ac567552/src/rpc/blockchain.cpp#L953-L960 // https://github.com/lbry/lbry/blob/a63a26f042134fa80356860c109edb25ac567552/src/rpc/blockchain.cpp#L953-L960
pruneHeight := head.Index - i.pruningConfig.Depth pruneHeight := head.Index - i.pruningConfig.Depth
if pruneHeight <= i.pruningConfig.MinHeight { if pruneHeight <= i.pruningConfig.MinHeight {
logger.Infow("waiting to prune", "min prune height", i.pruningConfig.MinHeight) logger.Infow("waiting to prune", "min prune height", i.pruningConfig.MinHeight)
continue continue
} }
logger.Infow("attempting to prune bitcoind", "prune height", pruneHeight) logger.Infow("attempting to prune lbryd", "prune height", pruneHeight)
prunedHeight, err := i.client.PruneBlockchain(ctx, pruneHeight) prunedHeight, err := i.client.PruneBlockchain(ctx, pruneHeight)
if err != nil { if err != nil {
logger.Warnw( logger.Warnw(
"unable to prune bitcoind", "unable to prune lbryd",
"prune height", pruneHeight, "prune height", pruneHeight,
"error", err, "error", err,
) )
} else { } else {
logger.Infow("pruned bitcoind", "prune height", prunedHeight) logger.Infow("pruned lbryd", "prune height", prunedHeight)
} }
} }
} }
@ -418,7 +418,7 @@ func (i *Indexer) NetworkStatus(
func (i *Indexer) findCoin( func (i *Indexer) findCoin(
ctx context.Context, ctx context.Context,
btcBlock *bitcoin.Block, btcBlock *lbry.Block,
coinIdentifier string, coinIdentifier string,
) (*types.Coin, *types.AccountIdentifier, error) { ) (*types.Coin, *types.AccountIdentifier, error) {
for ctx.Err() == nil { for ctx.Err() == nil {
@ -480,7 +480,7 @@ func (i *Indexer) findCoin(
// Put Transaction in WaitTable if doesn't already exist (could be // Put Transaction in WaitTable if doesn't already exist (could be
// multiple listeners) // multiple listeners)
transactionHash := bitcoin.TransactionHash(coinIdentifier) transactionHash := lbry.TransactionHash(coinIdentifier)
val, ok := i.waiter.Get(transactionHash, false) val, ok := i.waiter.Get(transactionHash, false)
if !ok { if !ok {
val = &waitTableEntry{ val = &waitTableEntry{
@ -503,7 +503,7 @@ func (i *Indexer) findCoin(
func (i *Indexer) checkHeaderMatch( func (i *Indexer) checkHeaderMatch(
ctx context.Context, ctx context.Context,
btcBlock *bitcoin.Block, btcBlock *lbry.Block,
) error { ) error {
headBlock, err := i.blockStorage.GetHeadBlockIdentifier(ctx) headBlock, err := i.blockStorage.GetHeadBlockIdentifier(ctx)
if err != nil && !errors.Is(err, storage.ErrHeadBlockNotFound) { if err != nil && !errors.Is(err, storage.ErrHeadBlockNotFound) {
@ -523,7 +523,7 @@ func (i *Indexer) checkHeaderMatch(
func (i *Indexer) findCoins( func (i *Indexer) findCoins(
ctx context.Context, ctx context.Context,
btcBlock *bitcoin.Block, btcBlock *lbry.Block,
coins []string, coins []string,
) (map[string]*storage.AccountCoin, error) { ) (map[string]*storage.AccountCoin, error) {
if err := i.checkHeaderMatch(ctx, btcBlock); err != nil { if err := i.checkHeaderMatch(ctx, btcBlock); err != nil {
@ -562,7 +562,7 @@ func (i *Indexer) findCoins(
shouldAbort := false shouldAbort := false
for _, coinIdentifier := range remainingCoins { for _, coinIdentifier := range remainingCoins {
// Wait on Channel // Wait on Channel
txHash := bitcoin.TransactionHash(coinIdentifier) txHash := lbry.TransactionHash(coinIdentifier)
entry, ok := i.waiter.Get(txHash, true) entry, ok := i.waiter.Get(txHash, true)
if !ok { if !ok {
return nil, fmt.Errorf("transaction %s not in waiter", txHash) return nil, fmt.Errorf("transaction %s not in waiter", txHash)
@ -624,7 +624,7 @@ func (i *Indexer) Block(
blockIdentifier *types.PartialBlockIdentifier, blockIdentifier *types.PartialBlockIdentifier,
) (*types.Block, error) { ) (*types.Block, error) {
// get raw block // get raw block
var btcBlock *bitcoin.Block var btcBlock *lbry.Block
var coins []string var coins []string
var err error var err error
@ -672,14 +672,14 @@ func (i *Indexer) Block(
func (i *Indexer) GetScriptPubKeys( func (i *Indexer) GetScriptPubKeys(
ctx context.Context, ctx context.Context,
coins []*types.Coin, coins []*types.Coin,
) ([]*bitcoin.ScriptPubKey, error) { ) ([]*lbry.ScriptPubKey, error) {
databaseTransaction := i.database.NewDatabaseTransaction(ctx, false) databaseTransaction := i.database.NewDatabaseTransaction(ctx, false)
defer databaseTransaction.Discard(ctx) defer databaseTransaction.Discard(ctx)
scripts := make([]*bitcoin.ScriptPubKey, len(coins)) scripts := make([]*lbry.ScriptPubKey, len(coins))
for j, coin := range coins { for j, coin := range coins {
coinIdentifier := coin.CoinIdentifier coinIdentifier := coin.CoinIdentifier
transactionHash, networkIndex, err := bitcoin.ParseCoinIdentifier(coinIdentifier) transactionHash, networkIndex, err := lbry.ParseCoinIdentifier(coinIdentifier)
if err != nil { if err != nil {
return nil, fmt.Errorf("%w: unable to parse coin identifier", err) return nil, fmt.Errorf("%w: unable to parse coin identifier", err)
} }
@ -698,7 +698,7 @@ func (i *Indexer) GetScriptPubKeys(
} }
for _, op := range transaction.Operations { for _, op := range transaction.Operations {
if op.Type != bitcoin.OutputOpType { if op.Type != lbry.OutputOpType {
continue continue
} }
@ -706,7 +706,7 @@ func (i *Indexer) GetScriptPubKeys(
continue continue
} }
var opMetadata bitcoin.OperationMetadata var opMetadata lbry.OperationMetadata
if err := types.UnmarshalMap(op.Metadata, &opMetadata); err != nil { if err := types.UnmarshalMap(op.Metadata, &opMetadata); err != nil {
return nil, fmt.Errorf( return nil, fmt.Errorf(
"%w: unable to unmarshal operation metadata %+v", "%w: unable to unmarshal operation metadata %+v",

View file

@ -23,13 +23,13 @@ import (
"testing" "testing"
"time" "time"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/lbry"
mocks "github.com/coinbase/rosetta-bitcoin/mocks/indexer" mocks "github.com/lbryio/rosetta-lbry/mocks/indexer"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/lbryio/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/coinbase/rosetta-sdk-go/utils" "github.com/lbryio/rosetta-sdk-go/utils"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock" "github.com/stretchr/testify/mock"
) )
@ -60,10 +60,10 @@ func TestIndexer_Pruning(t *testing.T) {
minHeight := int64(200) minHeight := int64(200)
cfg := &configuration.Configuration{ cfg := &configuration.Configuration{
Network: &types.NetworkIdentifier{ Network: &types.NetworkIdentifier{
Network: bitcoin.MainnetNetwork, Network: lbry.MainnetNetwork,
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
}, },
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
Pruning: &configuration.PruningConfiguration{ Pruning: &configuration.PruningConfiguration{
Frequency: 50 * time.Millisecond, Frequency: 50 * time.Millisecond,
Depth: pruneDepth, Depth: pruneDepth,
@ -75,7 +75,7 @@ func TestIndexer_Pruning(t *testing.T) {
i, err := Initialize(ctx, cancel, cfg, mockClient) i, err := Initialize(ctx, cancel, cfg, mockClient)
assert.NoError(t, err) assert.NoError(t, err)
// Waiting for bitcoind... // Waiting for lbryd...
mockClient.On("NetworkStatus", ctx).Return(nil, errors.New("not ready")).Once() mockClient.On("NetworkStatus", ctx).Return(nil, errors.New("not ready")).Once()
mockClient.On("NetworkStatus", ctx).Return(&types.NetworkStatusResponse{}, nil).Once() mockClient.On("NetworkStatus", ctx).Return(&types.NetworkStatusResponse{}, nil).Once()
@ -84,7 +84,7 @@ func TestIndexer_Pruning(t *testing.T) {
CurrentBlockIdentifier: &types.BlockIdentifier{ CurrentBlockIdentifier: &types.BlockIdentifier{
Index: 1000, Index: 1000,
}, },
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
}, nil) }, nil)
// Timeout on first request // Timeout on first request
@ -132,7 +132,7 @@ func TestIndexer_Pruning(t *testing.T) {
parentIdentifier.Hash = getBlockHash(0) parentIdentifier.Hash = getBlockHash(0)
} }
block := &bitcoin.Block{ block := &lbry.Block{
Hash: identifier.Hash, Hash: identifier.Hash,
Height: identifier.Index, Height: identifier.Index,
PreviousBlockHash: parentIdentifier.Hash, PreviousBlockHash: parentIdentifier.Hash,
@ -225,10 +225,10 @@ func TestIndexer_Transactions(t *testing.T) {
mockClient := &mocks.Client{} mockClient := &mocks.Client{}
cfg := &configuration.Configuration{ cfg := &configuration.Configuration{
Network: &types.NetworkIdentifier{ Network: &types.NetworkIdentifier{
Network: bitcoin.MainnetNetwork, Network: lbry.MainnetNetwork,
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
}, },
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
IndexerPath: newDir, IndexerPath: newDir,
} }
@ -240,13 +240,13 @@ func TestIndexer_Transactions(t *testing.T) {
CurrentBlockIdentifier: &types.BlockIdentifier{ CurrentBlockIdentifier: &types.BlockIdentifier{
Index: 1000, Index: 1000,
}, },
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
}, nil) }, nil)
// Add blocks // Add blocks
waitForCheck := make(chan struct{}) waitForCheck := make(chan struct{})
type coinBankEntry struct { type coinBankEntry struct {
Script *bitcoin.ScriptPubKey Script *lbry.ScriptPubKey
Coin *types.Coin Coin *types.Coin
Account *types.AccountIdentifier Account *types.AccountIdentifier
} }
@ -271,7 +271,7 @@ func TestIndexer_Transactions(t *testing.T) {
rawHash := fmt.Sprintf("block %d transaction %d", i, j) rawHash := fmt.Sprintf("block %d transaction %d", i, j)
hash := fmt.Sprintf("%x", sha256.Sum256([]byte(rawHash))) hash := fmt.Sprintf("%x", sha256.Sum256([]byte(rawHash)))
coinIdentifier := fmt.Sprintf("%s:%d", hash, index0) coinIdentifier := fmt.Sprintf("%s:%d", hash, index0)
scriptPubKey := &bitcoin.ScriptPubKey{ scriptPubKey := &lbry.ScriptPubKey{
ASM: coinIdentifier, ASM: coinIdentifier,
} }
marshal, err := types.MarshalMap(scriptPubKey) marshal, err := types.MarshalMap(scriptPubKey)
@ -286,14 +286,14 @@ func TestIndexer_Transactions(t *testing.T) {
Index: 0, Index: 0,
NetworkIndex: &index0, NetworkIndex: &index0,
}, },
Status: bitcoin.SuccessStatus, Status: lbry.SuccessStatus,
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: rawHash, Address: rawHash,
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: fmt.Sprintf("%d", rand.Intn(1000)), Value: fmt.Sprintf("%d", rand.Intn(1000)),
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
CoinChange: &types.CoinChange{ CoinChange: &types.CoinChange{
CoinAction: types.CoinCreated, CoinAction: types.CoinCreated,
@ -323,7 +323,7 @@ func TestIndexer_Transactions(t *testing.T) {
transactions = append(transactions, tx) transactions = append(transactions, tx)
} }
block := &bitcoin.Block{ block := &lbry.Block{
Hash: identifier.Hash, Hash: identifier.Hash,
Height: identifier.Index, Height: identifier.Index,
PreviousBlockHash: parentIdentifier.Hash, PreviousBlockHash: parentIdentifier.Hash,
@ -402,13 +402,13 @@ func TestIndexer_Transactions(t *testing.T) {
if currBlock.BlockIdentifier.Index == 1000 { if currBlock.BlockIdentifier.Index == 1000 {
// Ensure ScriptPubKeys are accessible. // Ensure ScriptPubKeys are accessible.
allCoins := []*types.Coin{} allCoins := []*types.Coin{}
expectedPubKeys := []*bitcoin.ScriptPubKey{} expectedPubKeys := []*lbry.ScriptPubKey{}
for k, v := range coinBank { for k, v := range coinBank {
allCoins = append(allCoins, &types.Coin{ allCoins = append(allCoins, &types.Coin{
CoinIdentifier: &types.CoinIdentifier{Identifier: k}, CoinIdentifier: &types.CoinIdentifier{Identifier: k},
Amount: &types.Amount{ Amount: &types.Amount{
Value: fmt.Sprintf("-%s", v.Coin.Amount.Value), Value: fmt.Sprintf("-%s", v.Coin.Amount.Value),
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
}) })
expectedPubKeys = append(expectedPubKeys, v.Script) expectedPubKeys = append(expectedPubKeys, v.Script)
@ -443,10 +443,10 @@ func TestIndexer_Reorg(t *testing.T) {
mockClient := &mocks.Client{} mockClient := &mocks.Client{}
cfg := &configuration.Configuration{ cfg := &configuration.Configuration{
Network: &types.NetworkIdentifier{ Network: &types.NetworkIdentifier{
Network: bitcoin.MainnetNetwork, Network: lbry.MainnetNetwork,
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
}, },
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
IndexerPath: newDir, IndexerPath: newDir,
} }
@ -458,13 +458,13 @@ func TestIndexer_Reorg(t *testing.T) {
CurrentBlockIdentifier: &types.BlockIdentifier{ CurrentBlockIdentifier: &types.BlockIdentifier{
Index: 1000, Index: 1000,
}, },
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
}, nil) }, nil)
// Add blocks // Add blocks
waitForCheck := make(chan struct{}) waitForCheck := make(chan struct{})
type coinBankEntry struct { type coinBankEntry struct {
Script *bitcoin.ScriptPubKey Script *lbry.ScriptPubKey
Coin *types.Coin Coin *types.Coin
Account *types.AccountIdentifier Account *types.AccountIdentifier
} }
@ -490,7 +490,7 @@ func TestIndexer_Reorg(t *testing.T) {
rawHash := fmt.Sprintf("block %d transaction %d", i, j) rawHash := fmt.Sprintf("block %d transaction %d", i, j)
hash := fmt.Sprintf("%x", sha256.Sum256([]byte(rawHash))) hash := fmt.Sprintf("%x", sha256.Sum256([]byte(rawHash)))
coinIdentifier := fmt.Sprintf("%s:%d", hash, index0) coinIdentifier := fmt.Sprintf("%s:%d", hash, index0)
scriptPubKey := &bitcoin.ScriptPubKey{ scriptPubKey := &lbry.ScriptPubKey{
ASM: coinIdentifier, ASM: coinIdentifier,
} }
marshal, err := types.MarshalMap(scriptPubKey) marshal, err := types.MarshalMap(scriptPubKey)
@ -505,14 +505,14 @@ func TestIndexer_Reorg(t *testing.T) {
Index: 0, Index: 0,
NetworkIndex: &index0, NetworkIndex: &index0,
}, },
Status: bitcoin.SuccessStatus, Status: lbry.SuccessStatus,
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: rawHash, Address: rawHash,
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: fmt.Sprintf("%d", rand.Intn(1000)), Value: fmt.Sprintf("%d", rand.Intn(1000)),
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
CoinChange: &types.CoinChange{ CoinChange: &types.CoinChange{
CoinAction: types.CoinCreated, CoinAction: types.CoinCreated,
@ -541,7 +541,7 @@ func TestIndexer_Reorg(t *testing.T) {
transactions = append(transactions, tx) transactions = append(transactions, tx)
} }
block := &bitcoin.Block{ block := &lbry.Block{
Hash: identifier.Hash, Hash: identifier.Hash,
Height: identifier.Index, Height: identifier.Index,
PreviousBlockHash: parentIdentifier.Hash, PreviousBlockHash: parentIdentifier.Hash,
@ -685,10 +685,10 @@ func TestIndexer_HeaderReorg(t *testing.T) {
mockClient := &mocks.Client{} mockClient := &mocks.Client{}
cfg := &configuration.Configuration{ cfg := &configuration.Configuration{
Network: &types.NetworkIdentifier{ Network: &types.NetworkIdentifier{
Network: bitcoin.MainnetNetwork, Network: lbry.MainnetNetwork,
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
}, },
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
IndexerPath: newDir, IndexerPath: newDir,
} }
@ -700,7 +700,7 @@ func TestIndexer_HeaderReorg(t *testing.T) {
CurrentBlockIdentifier: &types.BlockIdentifier{ CurrentBlockIdentifier: &types.BlockIdentifier{
Index: 1000, Index: 1000,
}, },
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
}, nil) }, nil)
// Add blocks // Add blocks
@ -720,7 +720,7 @@ func TestIndexer_HeaderReorg(t *testing.T) {
} }
transactions := []*types.Transaction{} transactions := []*types.Transaction{}
block := &bitcoin.Block{ block := &lbry.Block{
Hash: identifier.Hash, Hash: identifier.Hash,
Height: identifier.Index, Height: identifier.Index,
PreviousBlockHash: parentIdentifier.Hash, PreviousBlockHash: parentIdentifier.Hash,
@ -747,7 +747,7 @@ func TestIndexer_HeaderReorg(t *testing.T) {
mock.Anything, mock.Anything,
&types.PartialBlockIdentifier{Index: &identifier.Index}, &types.PartialBlockIdentifier{Index: &identifier.Index},
).Return( ).Return(
&bitcoin.Block{ &lbry.Block{
Hash: identifier.Hash, Hash: identifier.Hash,
Height: identifier.Index, Height: identifier.Index,
PreviousBlockHash: "blah", PreviousBlockHash: "blah",

View file

@ -20,7 +20,7 @@ set -e
usage() { usage() {
this=$1 this=$1
cat <<EOF cat <<EOF
$this: download pre-compiled Docker images for coinbase/rosetta-bitcoin $this: download pre-compiled Docker images for lbryio/rosetta-lbry
Usage: $this [-d] Usage: $this [-d]
-d turns on debug logging -d turns on debug logging
@ -44,8 +44,8 @@ execute() {
log_info "downloading image into ${tmpdir}" log_info "downloading image into ${tmpdir}"
http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}" "" "1" http_download "${tmpdir}/${TARBALL}" "${TARBALL_URL}" "" "1"
docker load --input "${tmpdir}/${TARBALL}" docker load --input "${tmpdir}/${TARBALL}"
docker tag "rosetta-bitcoin:${TAG}" "rosetta-bitcoin:latest" docker tag "rosetta-lbry:${TAG}" "rosetta-lbry:latest"
log_info "loaded rosetta-bitcoin:${TAG} and tagged as rosetta-bitcoin:latest" log_info "loaded rosetta-lbry:${TAG} and tagged as rosetta-lbry:latest"
rm -rf "${tmpdir}" rm -rf "${tmpdir}"
log_info "removed temporary directory ${tmpdir}" log_info "removed temporary directory ${tmpdir}"
} }
@ -196,10 +196,10 @@ End of functions from https://github.com/client9/shlib
------------------------------------------------------------------------ ------------------------------------------------------------------------
EOF EOF
BINARY=rosetta-bitcoin BINARY=rosetta-lbry
FORMAT=tar.gz FORMAT=tar.gz
OWNER=coinbase OWNER=coinbase
REPO="rosetta-bitcoin" REPO="rosetta-lbry"
PREFIX="$OWNER/$REPO" PREFIX="$OWNER/$REPO"
# use in logging routines # use in logging routines

32
main.go
View file

@ -24,16 +24,16 @@ import (
"syscall" "syscall"
"time" "time"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/indexer"
"github.com/coinbase/rosetta-bitcoin/indexer" "github.com/lbryio/rosetta-lbry/lbry"
"github.com/coinbase/rosetta-bitcoin/services" "github.com/lbryio/rosetta-lbry/services"
"github.com/coinbase/rosetta-bitcoin/utils" "github.com/lbryio/rosetta-lbry/utils"
"github.com/coinbase/rosetta-sdk-go/asserter"
"github.com/coinbase/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
"github.com/lbryio/rosetta-sdk-go/asserter"
"github.com/lbryio/rosetta-sdk-go/server"
"github.com/lbryio/rosetta-sdk-go/types"
"go.uber.org/zap" "go.uber.org/zap"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
@ -79,15 +79,15 @@ func startOnlineDependencies(
cancel context.CancelFunc, cancel context.CancelFunc,
cfg *configuration.Configuration, cfg *configuration.Configuration,
g *errgroup.Group, g *errgroup.Group,
) (*bitcoin.Client, *indexer.Indexer, error) { ) (*lbry.Client, *indexer.Indexer, error) {
client := bitcoin.NewClient( client := lbry.NewClient(
bitcoin.LocalhostURL(cfg.RPCPort), lbry.LocalhostURL(cfg.RPCPort),
cfg.GenesisBlockIdentifier, cfg.GenesisBlockIdentifier,
cfg.Currency, cfg.Currency,
) )
g.Go(func() error { g.Go(func() error {
return bitcoin.StartBitcoind(ctx, cfg.ConfigPath, g) return lbry.Startlbrycrdd(ctx, cfg.ConfigPath, g)
}) })
i, err := indexer.Initialize( i, err := indexer.Initialize(
@ -142,7 +142,7 @@ func main() {
}) })
var i *indexer.Indexer var i *indexer.Indexer
var client *bitcoin.Client var client *lbry.Client
if cfg.Mode == configuration.Online { if cfg.Mode == configuration.Online {
client, i, err = startOnlineDependencies(ctx, cancel, cfg, g) client, i, err = startOnlineDependencies(ctx, cancel, cfg, g)
if err != nil { if err != nil {
@ -153,7 +153,7 @@ func main() {
// The asserter automatically rejects incorrectly formatted // The asserter automatically rejects incorrectly formatted
// requests. // requests.
asserter, err := asserter.NewServer( asserter, err := asserter.NewServer(
bitcoin.OperationTypes, lbry.OperationTypes,
services.HistoricalBalanceLookup, services.HistoricalBalanceLookup,
[]*types.NetworkIdentifier{cfg.Network}, []*types.NetworkIdentifier{cfg.Network},
nil, nil,
@ -196,10 +196,10 @@ func main() {
} }
if signalReceived { if signalReceived {
logger.Fatalw("rosetta-bitcoin halted") logger.Fatalw("rosetta-lbry halted")
} }
if err != nil { if err != nil {
logger.Fatalw("rosetta-bitcoin sync failed", "error", err) logger.Fatalw("rosetta-lbry sync failed", "error", err)
} }
} }

View file

@ -5,13 +5,13 @@ package indexer
import ( import (
context "context" context "context"
bitcoin "github.com/coinbase/rosetta-bitcoin/bitcoin" lbry "github.com/lbryio/rosetta-lbry/lbry"
mock "github.com/stretchr/testify/mock" mock "github.com/stretchr/testify/mock"
storage "github.com/coinbase/rosetta-sdk-go/storage" storage "github.com/lbryio/rosetta-sdk-go/storage"
types "github.com/coinbase/rosetta-sdk-go/types" types "github.com/lbryio/rosetta-sdk-go/types"
) )
// Client is an autogenerated mock type for the Client type // Client is an autogenerated mock type for the Client type
@ -20,15 +20,15 @@ type Client struct {
} }
// GetRawBlock provides a mock function with given fields: _a0, _a1 // GetRawBlock provides a mock function with given fields: _a0, _a1
func (_m *Client) GetRawBlock(_a0 context.Context, _a1 *types.PartialBlockIdentifier) (*bitcoin.Block, []string, error) { func (_m *Client) GetRawBlock(_a0 context.Context, _a1 *types.PartialBlockIdentifier) (*lbry.Block, []string, error) {
ret := _m.Called(_a0, _a1) ret := _m.Called(_a0, _a1)
var r0 *bitcoin.Block var r0 *lbry.Block
if rf, ok := ret.Get(0).(func(context.Context, *types.PartialBlockIdentifier) *bitcoin.Block); ok { if rf, ok := ret.Get(0).(func(context.Context, *types.PartialBlockIdentifier) *lbry.Block); ok {
r0 = rf(_a0, _a1) r0 = rf(_a0, _a1)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).(*bitcoin.Block) r0 = ret.Get(0).(*lbry.Block)
} }
} }
@ -75,11 +75,11 @@ func (_m *Client) NetworkStatus(_a0 context.Context) (*types.NetworkStatusRespon
} }
// ParseBlock provides a mock function with given fields: _a0, _a1, _a2 // ParseBlock provides a mock function with given fields: _a0, _a1, _a2
func (_m *Client) ParseBlock(_a0 context.Context, _a1 *bitcoin.Block, _a2 map[string]*storage.AccountCoin) (*types.Block, error) { func (_m *Client) ParseBlock(_a0 context.Context, _a1 *lbry.Block, _a2 map[string]*storage.AccountCoin) (*types.Block, error) {
ret := _m.Called(_a0, _a1, _a2) ret := _m.Called(_a0, _a1, _a2)
var r0 *types.Block var r0 *types.Block
if rf, ok := ret.Get(0).(func(context.Context, *bitcoin.Block, map[string]*storage.AccountCoin) *types.Block); ok { if rf, ok := ret.Get(0).(func(context.Context, *lbry.Block, map[string]*storage.AccountCoin) *types.Block); ok {
r0 = rf(_a0, _a1, _a2) r0 = rf(_a0, _a1, _a2)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
@ -88,7 +88,7 @@ func (_m *Client) ParseBlock(_a0 context.Context, _a1 *bitcoin.Block, _a2 map[st
} }
var r1 error var r1 error
if rf, ok := ret.Get(1).(func(context.Context, *bitcoin.Block, map[string]*storage.AccountCoin) error); ok { if rf, ok := ret.Get(1).(func(context.Context, *lbry.Block, map[string]*storage.AccountCoin) error); ok {
r1 = rf(_a0, _a1, _a2) r1 = rf(_a0, _a1, _a2)
} else { } else {
r1 = ret.Error(1) r1 = ret.Error(1)

View file

@ -7,7 +7,7 @@ import (
mock "github.com/stretchr/testify/mock" mock "github.com/stretchr/testify/mock"
types "github.com/coinbase/rosetta-sdk-go/types" types "github.com/lbryio/rosetta-sdk-go/types"
) )
// Client is an autogenerated mock type for the Client type // Client is an autogenerated mock type for the Client type

View file

@ -5,11 +5,11 @@ package services
import ( import (
context "context" context "context"
bitcoin "github.com/coinbase/rosetta-bitcoin/bitcoin" lbry "github.com/lbryio/rosetta-lbry/lbry"
mock "github.com/stretchr/testify/mock" mock "github.com/stretchr/testify/mock"
types "github.com/coinbase/rosetta-sdk-go/types" types "github.com/lbryio/rosetta-sdk-go/types"
) )
// Indexer is an autogenerated mock type for the Indexer type // Indexer is an autogenerated mock type for the Indexer type
@ -128,15 +128,15 @@ func (_m *Indexer) GetCoins(_a0 context.Context, _a1 *types.AccountIdentifier) (
} }
// GetScriptPubKeys provides a mock function with given fields: _a0, _a1 // GetScriptPubKeys provides a mock function with given fields: _a0, _a1
func (_m *Indexer) GetScriptPubKeys(_a0 context.Context, _a1 []*types.Coin) ([]*bitcoin.ScriptPubKey, error) { func (_m *Indexer) GetScriptPubKeys(_a0 context.Context, _a1 []*types.Coin) ([]*lbry.ScriptPubKey, error) {
ret := _m.Called(_a0, _a1) ret := _m.Called(_a0, _a1)
var r0 []*bitcoin.ScriptPubKey var r0 []*lbry.ScriptPubKey
if rf, ok := ret.Get(0).(func(context.Context, []*types.Coin) []*bitcoin.ScriptPubKey); ok { if rf, ok := ret.Get(0).(func(context.Context, []*types.Coin) []*lbry.ScriptPubKey); ok {
r0 = rf(_a0, _a1) r0 = rf(_a0, _a1)
} else { } else {
if ret.Get(0) != nil { if ret.Get(0) != nil {
r0 = ret.Get(0).([]*bitcoin.ScriptPubKey) r0 = ret.Get(0).([]*lbry.ScriptPubKey)
} }
} }

View file

@ -1,6 +1,6 @@
{ {
"network": { "network": {
"blockchain": "Bitcoin", "blockchain": "LBRY",
"network": "Mainnet" "network": "Mainnet"
}, },
"data_directory": "cli-data", "data_directory": "cli-data",

View file

@ -1,6 +1,6 @@
{ {
"network": { "network": {
"blockchain": "Bitcoin", "blockchain": "LBRY",
"network": "Testnet3" "network": "Testnet3"
}, },
"data_directory": "cli-data", "data_directory": "cli-data",
@ -11,7 +11,7 @@
"memory_limit_disabled": true, "memory_limit_disabled": true,
"compression_disabled": true, "compression_disabled": true,
"construction": { "construction": {
"constructor_dsl_file": "bitcoin.ros", "constructor_dsl_file": "lbry.ros",
"end_conditions": { "end_conditions": {
"create_account": 10, "create_account": 10,
"transfer": 10 "transfer": 10

View file

@ -1,6 +1,6 @@
request_funds(1){ request_funds(1){
find_account{ find_account{
currency = {"symbol":"tBTC", "decimals":8}; currency = {"symbol":"tLBC", "decimals":8};
random_account = find_balance({ random_account = find_balance({
"minimum_balance":{ "minimum_balance":{
"value": "0", "value": "0",
@ -27,7 +27,7 @@ request_funds(1){
create_account(1){ create_account(1){
create{ create{
network = {"network":"Testnet3", "blockchain":"Bitcoin"}; network = {"network":"Testnet3", "blockchain":"LBRY"};
key = generate_key({"curve_type": "secp256k1"}); key = generate_key({"curve_type": "secp256k1"});
account = derive({ account = derive({
"network_identifier": {{network}}, "network_identifier": {{network}},
@ -44,8 +44,8 @@ create_account(1){
transfer(10){ transfer(10){
transfer_dry_run{ transfer_dry_run{
transfer_dry_run.network = {"network":"Testnet3", "blockchain":"Bitcoin"}; transfer_dry_run.network = {"network":"Testnet3", "blockchain":"LBRY"};
currency = {"symbol":"tBTC", "decimals":8}; currency = {"symbol":"tLBC", "decimals":8};
// We set the max_fee_amount to know how much buffer we should // We set the max_fee_amount to know how much buffer we should
// leave for fee payment when selecting a sender account. // leave for fee payment when selecting a sender account.
@ -165,10 +165,10 @@ transfer(10){
return_funds(10){ return_funds(10){
transfer_dry_run{ transfer_dry_run{
transfer_dry_run.network = {"network":"Testnet3", "blockchain":"Bitcoin"}; transfer_dry_run.network = {"network":"Testnet3", "blockchain":"LBRY"};
currency = {"symbol":"tBTC", "decimals":8}; currency = {"symbol":"tLBC", "decimals":8};
// We look for a sender that is able to pay the // We look for a sender that is able to pay the
// max_fee_amount + min_utxo size (reserved_amount is max_fee_amount + min_utxo size). // max_fee_amount + min_utxo size (reserved_amount is max_fee_amount + min_utxo size).
max_fee_amount = "1200"; max_fee_amount = "1200";
reserved_amount = "1800"; reserved_amount = "1800";

View file

@ -17,10 +17,10 @@ package services
import ( import (
"context" "context"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-sdk-go/server" "github.com/lbryio/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
// AccountAPIService implements the server.AccountAPIServicer interface. // AccountAPIService implements the server.AccountAPIServicer interface.

View file

@ -18,11 +18,11 @@ import (
"context" "context"
"testing" "testing"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/lbry"
mocks "github.com/coinbase/rosetta-bitcoin/mocks/services" mocks "github.com/lbryio/rosetta-lbry/mocks/services"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -44,7 +44,7 @@ func TestAccountBalance_Offline(t *testing.T) {
func TestAccountBalance_Online_Current(t *testing.T) { func TestAccountBalance_Online_Current(t *testing.T) {
cfg := &configuration.Configuration{ cfg := &configuration.Configuration{
Mode: configuration.Online, Mode: configuration.Online,
Currency: bitcoin.MainnetCurrency, Currency: lbry.MainnetCurrency,
} }
mockIndexer := &mocks.Indexer{} mockIndexer := &mocks.Indexer{}
servicer := NewAccountAPIService(cfg, mockIndexer) servicer := NewAccountAPIService(cfg, mockIndexer)
@ -97,7 +97,7 @@ func TestAccountBalance_Online_Current(t *testing.T) {
Balances: []*types.Amount{ Balances: []*types.Amount{
{ {
Value: "25", Value: "25",
Currency: bitcoin.MainnetCurrency, Currency: lbry.MainnetCurrency,
}, },
}, },
}, bal) }, bal)
@ -108,7 +108,7 @@ func TestAccountBalance_Online_Current(t *testing.T) {
func TestAccountBalance_Online_Historical(t *testing.T) { func TestAccountBalance_Online_Historical(t *testing.T) {
cfg := &configuration.Configuration{ cfg := &configuration.Configuration{
Mode: configuration.Online, Mode: configuration.Online,
Currency: bitcoin.MainnetCurrency, Currency: lbry.MainnetCurrency,
} }
mockIndexer := &mocks.Indexer{} mockIndexer := &mocks.Indexer{}
servicer := NewAccountAPIService(cfg, mockIndexer) servicer := NewAccountAPIService(cfg, mockIndexer)
@ -125,14 +125,14 @@ func TestAccountBalance_Online_Historical(t *testing.T) {
} }
amount := &types.Amount{ amount := &types.Amount{
Value: "25", Value: "25",
Currency: bitcoin.MainnetCurrency, Currency: lbry.MainnetCurrency,
} }
mockIndexer.On( mockIndexer.On(
"GetBalance", "GetBalance",
ctx, ctx,
account, account,
bitcoin.MainnetCurrency, lbry.MainnetCurrency,
partialBlock, partialBlock,
).Return(amount, block, nil).Once() ).Return(amount, block, nil).Once()
bal, err := servicer.AccountBalance(ctx, &types.AccountBalanceRequest{ bal, err := servicer.AccountBalance(ctx, &types.AccountBalanceRequest{

View file

@ -17,10 +17,10 @@ package services
import ( import (
"context" "context"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-sdk-go/server" "github.com/lbryio/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
// BlockAPIService implements the server.BlockAPIServicer interface. // BlockAPIService implements the server.BlockAPIServicer interface.

View file

@ -19,10 +19,10 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/configuration"
mocks "github.com/coinbase/rosetta-bitcoin/mocks/services" mocks "github.com/lbryio/rosetta-lbry/mocks/services"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View file

@ -24,20 +24,20 @@ import (
"math/big" "math/big"
"strconv" "strconv"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/lbry"
"github.com/btcsuite/btcd/btcec" "github.com/btcsuite/btcd/btcec"
"github.com/btcsuite/btcd/txscript" "github.com/btcsuite/btcd/txscript"
"github.com/btcsuite/btcd/wire" "github.com/btcsuite/btcd/wire"
"github.com/btcsuite/btcutil" "github.com/btcsuite/btcutil"
"github.com/coinbase/rosetta-sdk-go/parser" "github.com/lbryio/rosetta-sdk-go/parser"
"github.com/coinbase/rosetta-sdk-go/server" "github.com/lbryio/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
const ( const (
// bytesInKB is the number of bytes in a KB. In Bitcoin, this is // bytesInKB is the number of bytes in a KB. In lbry, this is
// considered to be 1000. // considered to be 1000.
bytesInKb = float64(1000) // nolint:gomnd bytesInKb = float64(1000) // nolint:gomnd
@ -88,22 +88,22 @@ func (s *ConstructionAPIService) ConstructionDerive(
// estimateSize returns the estimated size of a transaction in vBytes. // estimateSize returns the estimated size of a transaction in vBytes.
func (s *ConstructionAPIService) estimateSize(operations []*types.Operation) float64 { func (s *ConstructionAPIService) estimateSize(operations []*types.Operation) float64 {
size := bitcoin.TransactionOverhead size := lbry.TransactionOverhead
for _, operation := range operations { for _, operation := range operations {
switch operation.Type { switch operation.Type {
case bitcoin.InputOpType: case lbry.InputOpType:
size += bitcoin.InputSize size += lbry.InputSize
case bitcoin.OutputOpType: case lbry.OutputOpType:
size += bitcoin.OutputOverhead size += lbry.OutputOverhead
addr, err := btcutil.DecodeAddress(operation.Account.Address, s.config.Params) addr, err := btcutil.DecodeAddress(operation.Account.Address, s.config.Params)
if err != nil { if err != nil {
size += bitcoin.P2PKHScriptPubkeySize size += lbry.P2PKHScriptPubkeySize
continue continue
} }
script, err := txscript.PayToAddrScript(addr) script, err := txscript.PayToAddrScript(addr)
if err != nil { if err != nil {
size += bitcoin.P2PKHScriptPubkeySize size += lbry.P2PKHScriptPubkeySize
continue continue
} }
@ -123,7 +123,7 @@ func (s *ConstructionAPIService) ConstructionPreprocess(
descriptions := &parser.Descriptions{ descriptions := &parser.Descriptions{
OperationDescriptions: []*parser.OperationDescription{ OperationDescriptions: []*parser.OperationDescription{
{ {
Type: bitcoin.InputOpType, Type: lbry.InputOpType,
Account: &parser.AccountDescription{ Account: &parser.AccountDescription{
Exists: true, Exists: true,
}, },
@ -192,12 +192,12 @@ func (s *ConstructionAPIService) ConstructionMetadata(
if options.FeeMultiplier != nil { if options.FeeMultiplier != nil {
feePerKB *= *options.FeeMultiplier feePerKB *= *options.FeeMultiplier
} }
if feePerKB < bitcoin.MinFeeRate { if feePerKB < lbry.MinFeeRate {
feePerKB = bitcoin.MinFeeRate feePerKB = lbry.MinFeeRate
} }
// Calculated the estimated fee in Satoshis // Calculated the estimated fee in Satoshis
satoshisPerB := (feePerKB * float64(bitcoin.SatoshisInBitcoin)) / bytesInKb satoshisPerB := (feePerKB * float64(lbry.SatoshisInlbry)) / bytesInKb
estimatedFee := satoshisPerB * options.EstimatedSize estimatedFee := satoshisPerB * options.EstimatedSize
suggestedFee := &types.Amount{ suggestedFee := &types.Amount{
Value: fmt.Sprintf("%d", int64(estimatedFee)), Value: fmt.Sprintf("%d", int64(estimatedFee)),
@ -228,7 +228,7 @@ func (s *ConstructionAPIService) ConstructionPayloads(
descriptions := &parser.Descriptions{ descriptions := &parser.Descriptions{
OperationDescriptions: []*parser.OperationDescription{ OperationDescriptions: []*parser.OperationDescription{
{ {
Type: bitcoin.InputOpType, Type: lbry.InputOpType,
Account: &parser.AccountDescription{ Account: &parser.AccountDescription{
Exists: true, Exists: true,
}, },
@ -241,7 +241,7 @@ func (s *ConstructionAPIService) ConstructionPayloads(
CoinAction: types.CoinSpent, CoinAction: types.CoinSpent,
}, },
{ {
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &parser.AccountDescription{ Account: &parser.AccountDescription{
Exists: true, Exists: true,
}, },
@ -267,7 +267,7 @@ func (s *ConstructionAPIService) ConstructionPayloads(
return nil, wrapErr(ErrUnclearIntent, errors.New("CoinChange cannot be nil")) return nil, wrapErr(ErrUnclearIntent, errors.New("CoinChange cannot be nil"))
} }
transactionHash, index, err := bitcoin.ParseCoinIdentifier(input.CoinChange.CoinIdentifier) transactionHash, index, err := lbry.ParseCoinIdentifier(input.CoinChange.CoinIdentifier)
if err != nil { if err != nil {
return nil, wrapErr(ErrInvalidCoin, err) return nil, wrapErr(ErrInvalidCoin, err)
} }
@ -324,7 +324,7 @@ func (s *ConstructionAPIService) ConstructionPayloads(
return nil, wrapErr(ErrUnableToDecodeScriptPubKey, err) return nil, wrapErr(ErrUnableToDecodeScriptPubKey, err)
} }
class, _, err := bitcoin.ParseSingleAddress(s.config.Params, script) class, _, err := lbry.ParseSingleAddress(s.config.Params, script)
if err != nil { if err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToDecodeAddress, ErrUnableToDecodeAddress,
@ -413,7 +413,7 @@ func (s *ConstructionAPIService) ConstructionCombine(
if err := json.Unmarshal(decodedTx, &unsigned); err != nil { if err := json.Unmarshal(decodedTx, &unsigned); err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToParseIntermediateResult, ErrUnableToParseIntermediateResult,
fmt.Errorf("%w unable to unmarshal bitcoin transaction", err), fmt.Errorf("%w unable to unmarshal lbry transaction", err),
) )
} }
@ -439,7 +439,7 @@ func (s *ConstructionAPIService) ConstructionCombine(
return nil, wrapErr(ErrUnableToDecodeScriptPubKey, err) return nil, wrapErr(ErrUnableToDecodeScriptPubKey, err)
} }
class, _, err := bitcoin.ParseSingleAddress(s.config.Params, decodedScript) class, _, err := lbry.ParseSingleAddress(s.config.Params, decodedScript)
if err != nil { if err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToDecodeAddress, ErrUnableToDecodeAddress,
@ -499,7 +499,7 @@ func (s *ConstructionAPIService) ConstructionHash(
if err := json.Unmarshal(decodedTx, &signed); err != nil { if err := json.Unmarshal(decodedTx, &signed); err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToParseIntermediateResult, ErrUnableToParseIntermediateResult,
fmt.Errorf("%w unable to unmarshal signed bitcoin transaction", err), fmt.Errorf("%w unable to unmarshal signed lbry transaction", err),
) )
} }
@ -541,7 +541,7 @@ func (s *ConstructionAPIService) parseUnsignedTransaction(
if err := json.Unmarshal(decodedTx, &unsigned); err != nil { if err := json.Unmarshal(decodedTx, &unsigned); err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToParseIntermediateResult, ErrUnableToParseIntermediateResult,
fmt.Errorf("%w unable to unmarshal bitcoin transaction", err), fmt.Errorf("%w unable to unmarshal lbry transaction", err),
) )
} }
@ -569,7 +569,7 @@ func (s *ConstructionAPIService) parseUnsignedTransaction(
Index: int64(len(ops)), Index: int64(len(ops)),
NetworkIndex: &networkIndex, NetworkIndex: &networkIndex,
}, },
Type: bitcoin.InputOpType, Type: lbry.InputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: unsigned.InputAddresses[i], Address: unsigned.InputAddresses[i],
}, },
@ -592,7 +592,7 @@ func (s *ConstructionAPIService) parseUnsignedTransaction(
for i, output := range tx.TxOut { for i, output := range tx.TxOut {
networkIndex := int64(i) networkIndex := int64(i)
_, addr, err := bitcoin.ParseSingleAddress(s.config.Params, output.PkScript) _, addr, err := lbry.ParseSingleAddress(s.config.Params, output.PkScript)
if err != nil { if err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToDecodeAddress, ErrUnableToDecodeAddress,
@ -605,7 +605,7 @@ func (s *ConstructionAPIService) parseUnsignedTransaction(
Index: int64(len(ops)), Index: int64(len(ops)),
NetworkIndex: &networkIndex, NetworkIndex: &networkIndex,
}, },
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: addr.String(), Address: addr.String(),
}, },
@ -637,7 +637,7 @@ func (s *ConstructionAPIService) parseSignedTransaction(
if err := json.Unmarshal(decodedTx, &signed); err != nil { if err := json.Unmarshal(decodedTx, &signed); err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToParseIntermediateResult, ErrUnableToParseIntermediateResult,
fmt.Errorf("%w unable to unmarshal signed bitcoin transaction", err), fmt.Errorf("%w unable to unmarshal signed lbry transaction", err),
) )
} }
@ -668,7 +668,7 @@ func (s *ConstructionAPIService) parseSignedTransaction(
) )
} }
_, addr, err := bitcoin.ParseSingleAddress(s.config.Params, pkScript.Script()) _, addr, err := lbry.ParseSingleAddress(s.config.Params, pkScript.Script())
if err != nil { if err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToDecodeAddress, ErrUnableToDecodeAddress,
@ -685,7 +685,7 @@ func (s *ConstructionAPIService) parseSignedTransaction(
Index: int64(len(ops)), Index: int64(len(ops)),
NetworkIndex: &networkIndex, NetworkIndex: &networkIndex,
}, },
Type: bitcoin.InputOpType, Type: lbry.InputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: addr.EncodeAddress(), Address: addr.EncodeAddress(),
}, },
@ -708,7 +708,7 @@ func (s *ConstructionAPIService) parseSignedTransaction(
for i, output := range tx.TxOut { for i, output := range tx.TxOut {
networkIndex := int64(i) networkIndex := int64(i)
_, addr, err := bitcoin.ParseSingleAddress(s.config.Params, output.PkScript) _, addr, err := lbry.ParseSingleAddress(s.config.Params, output.PkScript)
if err != nil { if err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToDecodeAddress, ErrUnableToDecodeAddress,
@ -721,7 +721,7 @@ func (s *ConstructionAPIService) parseSignedTransaction(
Index: int64(len(ops)), Index: int64(len(ops)),
NetworkIndex: &networkIndex, NetworkIndex: &networkIndex,
}, },
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: addr.String(), Address: addr.String(),
}, },
@ -771,13 +771,13 @@ func (s *ConstructionAPIService) ConstructionSubmit(
if err := json.Unmarshal(decodedTx, &signed); err != nil { if err := json.Unmarshal(decodedTx, &signed); err != nil {
return nil, wrapErr( return nil, wrapErr(
ErrUnableToParseIntermediateResult, ErrUnableToParseIntermediateResult,
fmt.Errorf("%w unable to unmarshal signed bitcoin transaction", err), fmt.Errorf("%w unable to unmarshal signed lbry transaction", err),
) )
} }
txHash, err := s.client.SendRawTransaction(ctx, signed.Transaction) txHash, err := s.client.SendRawTransaction(ctx, signed.Transaction)
if err != nil { if err != nil {
return nil, wrapErr(ErrBitcoind, fmt.Errorf("%w unable to submit transaction", err)) return nil, wrapErr(Errlbryd, fmt.Errorf("%w unable to submit transaction", err))
} }
return &types.TransactionIdentifierResponse{ return &types.TransactionIdentifierResponse{

View file

@ -19,11 +19,11 @@ import (
"encoding/hex" "encoding/hex"
"testing" "testing"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/lbry"
mocks "github.com/coinbase/rosetta-bitcoin/mocks/services" mocks "github.com/lbryio/rosetta-lbry/mocks/services"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -47,15 +47,15 @@ func forceMarshalMap(t *testing.T, i interface{}) map[string]interface{} {
func TestConstructionService(t *testing.T) { func TestConstructionService(t *testing.T) {
networkIdentifier = &types.NetworkIdentifier{ networkIdentifier = &types.NetworkIdentifier{
Network: bitcoin.TestnetNetwork, Network: lbry.TestnetNetwork,
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
} }
cfg := &configuration.Configuration{ cfg := &configuration.Configuration{
Mode: configuration.Online, Mode: configuration.Online,
Network: networkIdentifier, Network: networkIdentifier,
Params: bitcoin.TestnetParams, Params: lbry.TestnetParams,
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
} }
mockIndexer := &mocks.Indexer{} mockIndexer := &mocks.Indexer{}
@ -88,13 +88,13 @@ func TestConstructionService(t *testing.T) {
OperationIdentifier: &types.OperationIdentifier{ OperationIdentifier: &types.OperationIdentifier{
Index: 0, Index: 0,
}, },
Type: bitcoin.InputOpType, Type: lbry.InputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: "tb1qcqzmqzkswhfshzd8kedhmtvgnxax48z4fklhvm", Address: "tb1qcqzmqzkswhfshzd8kedhmtvgnxax48z4fklhvm",
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: "-1000000", Value: "-1000000",
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
CoinChange: &types.CoinChange{ CoinChange: &types.CoinChange{
CoinIdentifier: &types.CoinIdentifier{ CoinIdentifier: &types.CoinIdentifier{
@ -107,26 +107,26 @@ func TestConstructionService(t *testing.T) {
OperationIdentifier: &types.OperationIdentifier{ OperationIdentifier: &types.OperationIdentifier{
Index: 1, Index: 1,
}, },
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: "tb1q3r8xjf0c2yazxnq9ey3wayelygfjxpfqjvj5v7", Address: "tb1q3r8xjf0c2yazxnq9ey3wayelygfjxpfqjvj5v7",
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: "954843", Value: "954843",
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
}, },
{ {
OperationIdentifier: &types.OperationIdentifier{ OperationIdentifier: &types.OperationIdentifier{
Index: 2, Index: 2,
}, },
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: "tb1qjsrjvk2ug872pdypp33fjxke62y7awpgefr6ua", Address: "tb1qjsrjvk2ug872pdypp33fjxke62y7awpgefr6ua",
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: "44657", Value: "44657",
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
}, },
} }
@ -148,7 +148,7 @@ func TestConstructionService(t *testing.T) {
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: "-1000000", Value: "-1000000",
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
}, },
}, },
@ -161,7 +161,7 @@ func TestConstructionService(t *testing.T) {
// Test Metadata // Test Metadata
metadata := &constructionMetadata{ metadata := &constructionMetadata{
ScriptPubKeys: []*bitcoin.ScriptPubKey{ ScriptPubKeys: []*lbry.ScriptPubKey{
{ {
ASM: "0 c005b00ad075d30b89a7b65b7dad8899ba6a9c55", ASM: "0 c005b00ad075d30b89a7b65b7dad8899ba6a9c55",
Hex: "0014c005b00ad075d30b89a7b65b7dad8899ba6a9c55", Hex: "0014c005b00ad075d30b89a7b65b7dad8899ba6a9c55",
@ -188,7 +188,7 @@ func TestConstructionService(t *testing.T) {
ctx, ctx,
defaultConfirmationTarget, defaultConfirmationTarget,
).Return( ).Return(
bitcoin.MinFeeRate*10, lbry.MinFeeRate*10,
nil, nil,
).Once() ).Once()
metadataResponse, err := servicer.ConstructionMetadata(ctx, &types.ConstructionMetadataRequest{ metadataResponse, err := servicer.ConstructionMetadata(ctx, &types.ConstructionMetadataRequest{
@ -201,7 +201,7 @@ func TestConstructionService(t *testing.T) {
SuggestedFee: []*types.Amount{ SuggestedFee: []*types.Amount{
{ {
Value: "1065", // 1,420 * 0.75 Value: "1065", // 1,420 * 0.75
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
}, },
}, metadataResponse) }, metadataResponse)
@ -220,7 +220,7 @@ func TestConstructionService(t *testing.T) {
ctx, ctx,
defaultConfirmationTarget, defaultConfirmationTarget,
).Return( ).Return(
bitcoin.MinFeeRate, lbry.MinFeeRate,
nil, nil,
).Once() ).Once()
metadataResponse, err = servicer.ConstructionMetadata(ctx, &types.ConstructionMetadataRequest{ metadataResponse, err = servicer.ConstructionMetadata(ctx, &types.ConstructionMetadataRequest{
@ -233,7 +233,7 @@ func TestConstructionService(t *testing.T) {
SuggestedFee: []*types.Amount{ SuggestedFee: []*types.Amount{
{ {
Value: "142", // we don't go below minimum fee rate Value: "142", // we don't go below minimum fee rate
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
}, },
}, metadataResponse) }, metadataResponse)
@ -253,13 +253,13 @@ func TestConstructionService(t *testing.T) {
Index: 0, Index: 0,
NetworkIndex: &val0, NetworkIndex: &val0,
}, },
Type: bitcoin.InputOpType, Type: lbry.InputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: "tb1qcqzmqzkswhfshzd8kedhmtvgnxax48z4fklhvm", Address: "tb1qcqzmqzkswhfshzd8kedhmtvgnxax48z4fklhvm",
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: "-1000000", Value: "-1000000",
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
CoinChange: &types.CoinChange{ CoinChange: &types.CoinChange{
CoinIdentifier: &types.CoinIdentifier{ CoinIdentifier: &types.CoinIdentifier{
@ -273,13 +273,13 @@ func TestConstructionService(t *testing.T) {
Index: 1, Index: 1,
NetworkIndex: &val0, NetworkIndex: &val0,
}, },
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: "tb1q3r8xjf0c2yazxnq9ey3wayelygfjxpfqjvj5v7", Address: "tb1q3r8xjf0c2yazxnq9ey3wayelygfjxpfqjvj5v7",
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: "954843", Value: "954843",
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
}, },
{ {
@ -287,13 +287,13 @@ func TestConstructionService(t *testing.T) {
Index: 2, Index: 2,
NetworkIndex: &val1, NetworkIndex: &val1,
}, },
Type: bitcoin.OutputOpType, Type: lbry.OutputOpType,
Account: &types.AccountIdentifier{ Account: &types.AccountIdentifier{
Address: "tb1qjsrjvk2ug872pdypp33fjxke62y7awpgefr6ua", Address: "tb1qjsrjvk2ug872pdypp33fjxke62y7awpgefr6ua",
}, },
Amount: &types.Amount{ Amount: &types.Amount{
Value: "44657", Value: "44657",
Currency: bitcoin.TestnetCurrency, Currency: lbry.TestnetCurrency,
}, },
}, },
} }
@ -376,11 +376,11 @@ func TestConstructionService(t *testing.T) {
}, hashResponse) }, hashResponse)
// Test Submit // Test Submit
bitcoinTransaction := "010000000001017f9cf50b02dd5258f80cd5c3437302e027dd1336172a20cdc80305c5a55741b10100000000ffffffff02db910e000000000016001488ce6925f8513a234c05c922ee933f221323052071ae000000000000160014940726595c41fca0b4810c62991ad9d289eeb82802473044022025876ec8b9f51d343a5a56ac549c0c828005ef45ebe9da166db645c09157223f02204cd08b7278a8889a81135915bce10d1ef3bb92b217f81a0de7e79ffb3dfd6ac501210325c9a4252789b31dbb3454ec647e9516e7c596bcde2bd5da71a60fab8644e43800000000" // nolint lbryTransaction := "010000000001017f9cf50b02dd5258f80cd5c3437302e027dd1336172a20cdc80305c5a55741b10100000000ffffffff02db910e000000000016001488ce6925f8513a234c05c922ee933f221323052071ae000000000000160014940726595c41fca0b4810c62991ad9d289eeb82802473044022025876ec8b9f51d343a5a56ac549c0c828005ef45ebe9da166db645c09157223f02204cd08b7278a8889a81135915bce10d1ef3bb92b217f81a0de7e79ffb3dfd6ac501210325c9a4252789b31dbb3454ec647e9516e7c596bcde2bd5da71a60fab8644e43800000000" // nolint
mockClient.On( mockClient.On(
"SendRawTransaction", "SendRawTransaction",
ctx, ctx,
bitcoinTransaction, lbryTransaction,
).Return( ).Return(
transactionIdentifier.Hash, transactionIdentifier.Hash,
nil, nil,

View file

@ -15,7 +15,7 @@
package services package services
import ( import (
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
var ( var (
@ -25,7 +25,7 @@ var (
ErrUnimplemented, ErrUnimplemented,
ErrUnavailableOffline, ErrUnavailableOffline,
ErrNotReady, ErrNotReady,
ErrBitcoind, ErrLbrycrdd,
ErrBlockNotFound, ErrBlockNotFound,
ErrUnableToDerive, ErrUnableToDerive,
ErrUnclearIntent, ErrUnclearIntent,
@ -57,19 +57,19 @@ var (
Message: "Endpoint unavailable offline", Message: "Endpoint unavailable offline",
} }
// ErrNotReady is returned when bitcoind is not // ErrNotReady is returned when Lbrycrdd is not
// yet ready to serve queries. // yet ready to serve queries.
ErrNotReady = &types.Error{ ErrNotReady = &types.Error{
Code: 2, //nolint Code: 2, //nolint
Message: "Bitcoind is not ready", Message: "Lbrycrdd is not ready",
Retriable: true, Retriable: true,
} }
// ErrBitcoind is returned when bitcoind // ErrLbrycrdd is returned when lbrycrdd
// errors on a request. // errors on a request.
ErrBitcoind = &types.Error{ ErrLbrycrdd = &types.Error{
Code: 3, //nolint Code: 3, //nolint
Message: "Bitcoind error", Message: "LBRYcrdd error",
} }
// ErrBlockNotFound is returned when a block // ErrBlockNotFound is returned when a block
@ -104,7 +104,7 @@ var (
// ErrScriptPubKeysMissing is returned when // ErrScriptPubKeysMissing is returned when
// the indexer cannot populate the required // the indexer cannot populate the required
// bitcoin.ScriptPubKeys to construct a transaction. // lbry.ScriptPubKeys to construct a transaction.
ErrScriptPubKeysMissing = &types.Error{ ErrScriptPubKeysMissing = &types.Error{
Code: 8, //nolint Code: 8, //nolint
Message: "Missing ScriptPubKeys", Message: "Missing ScriptPubKeys",
@ -125,7 +125,7 @@ var (
} }
// ErrUnableToDecodeScriptPubKey is returned when a // ErrUnableToDecodeScriptPubKey is returned when a
// bitcoin.ScriptPubKey cannot be parsed during construction. // lbry.ScriptPubKey cannot be parsed during construction.
ErrUnableToDecodeScriptPubKey = &types.Error{ ErrUnableToDecodeScriptPubKey = &types.Error{
Code: 11, //nolint Code: 11, //nolint
Message: "Unable to decode ScriptPubKey", Message: "Unable to decode ScriptPubKey",

View file

@ -17,10 +17,10 @@ package services
import ( import (
"context" "context"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-sdk-go/server" "github.com/lbryio/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
// MempoolAPIService implements the server.MempoolAPIServicer interface. // MempoolAPIService implements the server.MempoolAPIServicer interface.
@ -51,7 +51,7 @@ func (s *MempoolAPIService) Mempool(
mempoolTransactions, err := s.client.RawMempool(ctx) mempoolTransactions, err := s.client.RawMempool(ctx)
if err != nil { if err != nil {
return nil, wrapErr(ErrBitcoind, err) return nil, wrapErr(Errlbryd, err)
} }
transactionIdentifiers := make([]*types.TransactionIdentifier, len(mempoolTransactions)) transactionIdentifiers := make([]*types.TransactionIdentifier, len(mempoolTransactions))

View file

@ -18,10 +18,10 @@ import (
"context" "context"
"testing" "testing"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/configuration"
mocks "github.com/coinbase/rosetta-bitcoin/mocks/services" mocks "github.com/lbryio/rosetta-lbry/mocks/services"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View file

@ -17,11 +17,11 @@ package services
import ( import (
"context" "context"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/lbry"
"github.com/coinbase/rosetta-sdk-go/server" "github.com/lbryio/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
// NetworkAPIService implements the server.NetworkAPIServicer interface. // NetworkAPIService implements the server.NetworkAPIServicer interface.
@ -67,7 +67,7 @@ func (s *NetworkAPIService) NetworkStatus(
peers, err := s.client.GetPeers(ctx) peers, err := s.client.GetPeers(ctx)
if err != nil { if err != nil {
return nil, wrapErr(ErrBitcoind, err) return nil, wrapErr(Errlbryd, err)
} }
cachedBlockResponse, err := s.i.GetBlockLazy(ctx, nil) cachedBlockResponse, err := s.i.GetBlockLazy(ctx, nil)
@ -95,8 +95,8 @@ func (s *NetworkAPIService) NetworkOptions(
MiddlewareVersion: &MiddlewareVersion, MiddlewareVersion: &MiddlewareVersion,
}, },
Allow: &types.Allow{ Allow: &types.Allow{
OperationStatuses: bitcoin.OperationStatuses, OperationStatuses: lbry.OperationStatuses,
OperationTypes: bitcoin.OperationTypes, OperationTypes: lbry.OperationTypes,
Errors: Errors, Errors: Errors,
HistoricalBalanceLookup: HistoricalBalanceLookup, HistoricalBalanceLookup: HistoricalBalanceLookup,
}, },

View file

@ -18,11 +18,11 @@ import (
"context" "context"
"testing" "testing"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/lbry"
mocks "github.com/coinbase/rosetta-bitcoin/mocks/services" mocks "github.com/lbryio/rosetta-lbry/mocks/services"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -35,16 +35,16 @@ var (
MiddlewareVersion: &middlewareVersion, MiddlewareVersion: &middlewareVersion,
}, },
Allow: &types.Allow{ Allow: &types.Allow{
OperationStatuses: bitcoin.OperationStatuses, OperationStatuses: lbry.OperationStatuses,
OperationTypes: bitcoin.OperationTypes, OperationTypes: lbry.OperationTypes,
Errors: Errors, Errors: Errors,
HistoricalBalanceLookup: HistoricalBalanceLookup, HistoricalBalanceLookup: HistoricalBalanceLookup,
}, },
} }
networkIdentifier = &types.NetworkIdentifier{ networkIdentifier = &types.NetworkIdentifier{
Network: bitcoin.MainnetNetwork, Network: lbry.MainnetNetwork,
Blockchain: bitcoin.Blockchain, Blockchain: lbry.Blockchain,
} }
) )
@ -81,7 +81,7 @@ func TestNetworkEndpoints_Online(t *testing.T) {
cfg := &configuration.Configuration{ cfg := &configuration.Configuration{
Mode: configuration.Online, Mode: configuration.Online,
Network: networkIdentifier, Network: networkIdentifier,
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
} }
mockIndexer := &mocks.Indexer{} mockIndexer := &mocks.Indexer{}
mockClient := &mocks.Client{} mockClient := &mocks.Client{}
@ -104,7 +104,7 @@ func TestNetworkEndpoints_Online(t *testing.T) {
} }
mockClient.On("GetPeers", ctx).Return([]*types.Peer{ mockClient.On("GetPeers", ctx).Return([]*types.Peer{
{ {
PeerID: "77.93.223.9:8333", PeerID: "34.231.101.5:9246",
}, },
}, nil) }, nil)
mockIndexer.On( mockIndexer.On(
@ -118,11 +118,11 @@ func TestNetworkEndpoints_Online(t *testing.T) {
networkStatus, err := servicer.NetworkStatus(ctx, nil) networkStatus, err := servicer.NetworkStatus(ctx, nil)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, &types.NetworkStatusResponse{ assert.Equal(t, &types.NetworkStatusResponse{
GenesisBlockIdentifier: bitcoin.MainnetGenesisBlockIdentifier, GenesisBlockIdentifier: lbry.MainnetGenesisBlockIdentifier,
CurrentBlockIdentifier: blockResponse.Block.BlockIdentifier, CurrentBlockIdentifier: blockResponse.Block.BlockIdentifier,
Peers: []*types.Peer{ Peers: []*types.Peer{
{ {
PeerID: "77.93.223.9:8333", PeerID: "34.231.101.5:9246",
}, },
}, },
}, networkStatus) }, networkStatus)

View file

@ -17,10 +17,10 @@ package services
import ( import (
"net/http" "net/http"
"github.com/coinbase/rosetta-bitcoin/configuration" "github.com/lbryio/rosetta-lbry/configuration"
"github.com/coinbase/rosetta-sdk-go/asserter" "github.com/lbryio/rosetta-sdk-go/asserter"
"github.com/coinbase/rosetta-sdk-go/server" "github.com/lbryio/rosetta-sdk-go/server"
) )
// NewBlockchainRouter creates a Mux http.Handler from a collection // NewBlockchainRouter creates a Mux http.Handler from a collection

View file

@ -17,15 +17,15 @@ package services
import ( import (
"context" "context"
"github.com/coinbase/rosetta-bitcoin/bitcoin" "github.com/lbryio/rosetta-lbry/lbry"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/lbryio/rosetta-sdk-go/types"
) )
const ( const (
// NodeVersion is the version of // NodeVersion is the version of
// bitcoin core we are using. // lbry core we are using.
NodeVersion = "0.20.1" NodeVersion = "0.17.4.6"
// HistoricalBalanceLookup indicates // HistoricalBalanceLookup indicates
// that historical balance lookup is supported. // that historical balance lookup is supported.
@ -38,7 +38,7 @@ const (
var ( var (
// MiddlewareVersion is the version // MiddlewareVersion is the version
// of rosetta-bitcoin. We set this as a // of rosetta-lbry. We set this as a
// variable instead of a constant because // variable instead of a constant because
// we typically need the pointer of this // we typically need the pointer of this
// value. // value.
@ -72,7 +72,7 @@ type Indexer interface {
GetScriptPubKeys( GetScriptPubKeys(
context.Context, context.Context,
[]*types.Coin, []*types.Coin,
) ([]*bitcoin.ScriptPubKey, error) ) ([]*lbry.ScriptPubKey, error)
GetBalance( GetBalance(
context.Context, context.Context,
*types.AccountIdentifier, *types.AccountIdentifier,
@ -82,10 +82,10 @@ type Indexer interface {
} }
type unsignedTransaction struct { type unsignedTransaction struct {
Transaction string `json:"transaction"` Transaction string `json:"transaction"`
ScriptPubKeys []*bitcoin.ScriptPubKey `json:"scriptPubKeys"` ScriptPubKeys []*lbry.ScriptPubKey `json:"scriptPubKeys"`
InputAmounts []string `json:"input_amounts"` InputAmounts []string `json:"input_amounts"`
InputAddresses []string `json:"input_addresses"` InputAddresses []string `json:"input_addresses"`
} }
type preprocessOptions struct { type preprocessOptions struct {
@ -95,7 +95,7 @@ type preprocessOptions struct {
} }
type constructionMetadata struct { type constructionMetadata struct {
ScriptPubKeys []*bitcoin.ScriptPubKey `json:"script_pub_keys"` ScriptPubKeys []*lbry.ScriptPubKey `json:"script_pub_keys"`
} }
type signedTransaction struct { type signedTransaction struct {
@ -106,5 +106,5 @@ type signedTransaction struct {
// ParseOperationMetadata is returned from // ParseOperationMetadata is returned from
// ConstructionParse. // ConstructionParse.
type ParseOperationMetadata struct { type ParseOperationMetadata struct {
ScriptPubKey *bitcoin.ScriptPubKey `json:"scriptPubKey"` ScriptPubKey *lbry.ScriptPubKey `json:"scriptPubKey"`
} }

View file

@ -18,8 +18,8 @@ import (
"context" "context"
"time" "time"
sdkUtils "github.com/coinbase/rosetta-sdk-go/utils"
"github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap" "github.com/grpc-ecosystem/go-grpc-middleware/logging/zap/ctxzap"
sdkUtils "github.com/lbryio/rosetta-sdk-go/utils"
"go.uber.org/zap" "go.uber.org/zap"
) )