Compare commits

...

5 commits

Author SHA1 Message Date
Thomas Zarebczan
3ba4c37047
LBRY
LBRY Updates
2020-12-08 00:08:02 -05:00
Thomas Zarebczan
0b1ea81c0f
Upstream merge 2020-11-17 03:36:34 -05:00
Thomas Zarebczan
2b2364e69c
Fix coinbase 2020-11-17 03:27:17 -05:00
Thomas Zarebczan
f9a35c2474
Merge pull request #2 from lbryio/lbry
LBRY changes
2020-11-17 03:20:55 -05:00
Thomas Zarebczan
f92c407370
LBRY changes
more


more
2020-11-17 03:20:36 -05:00
55 changed files with 753 additions and 463 deletions

View file

@ -18,7 +18,7 @@ executors:
docker: docker:
- image: circleci/golang:1.15 - image: circleci/golang:1.15
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"

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,47 @@
# 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 cmake libcap-dev libz-dev libbz2-dev python-setuptools python3-setuptools xz-utils ccache \
bsdmainutils curl ca-certificates; \
rm -rf /var/lib/apt/lists/*; \
/usr/sbin/update-ccache-symlinks;
# VERSION: Bitcoin Core 0.20.1 # VERSION: LBRYcrd 0.19.1.3
RUN git clone https://github.com/bitcoin/bitcoin \ RUN git clone https://github.com/lbryio/lbrycrd \
&& cd bitcoin \ && cd lbrycrd \
&& git checkout 7ff64311bee570874c4f0dfa18f518552188df08 && git checkout v0.19.1.3
RUN cd bitcoin \ ENV CXXFLAGS "${CXXFLAGS:--frecord-gcc-switches}"
RUN cd lbrycrd \
&& cd depends \
&& make -j$(getconf _NPROCESSORS_ONLN) HOST=x86_64-pc-linux-gnu NO_QT=1 V=1
ENV DEPS_DIR /app/lbrycrd/depends/x86_64-pc-linux-gnu
RUN echo $DEPS_DIR
ENV CONFIG_SITE ${DEPS_DIR}/share/config.site
RUN echo $CONFIG_SITE
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-static --with-pic --disable-shared --enable-glibc-back-compat --disable-tests --without-miniupnpc --without-gui --with-incompatible-bdb --disable-hardening --disable-zmq --disable-bench --disable-wallet \
&& make && make -j$(getconf _NPROCESSORS_ONLN)
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
@ -62,7 +80,7 @@ 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
@ -80,8 +98,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 +107,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 9246:9246 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 19246:19246 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)

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/coinbase/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,26 +0,0 @@
##
## bitcoin.conf configuration file. Lines beginning with # are comments.
##
# DO NOT USE THIS CONFIGURATION FILE IF YOU PLAN TO EXPOSE
# BITCOIND'S RPC PORT PUBLICALLY (THESE INSECURE CREDENTIALS
# COULD LEAD TO AN ATTACK). ROSETTA-BITCOIN USES THE RPC PORT
# FOR INDEXING AND TRANSACTION BROADCAST BUT NEVER PROVIDES THE
# CALLER ACCESS TO BITCOIND'S RPC PORT.
datadir=/data/bitcoind
bind=0.0.0.0
rpcbind=0.0.0.0
bantime=15
rpcallowip=0.0.0.0/0
rpcthreads=16
rpcworkqueue=1000
disablewallet=1
txindex=0
port=8333
rpcport=8332
rpcuser=rosetta
rpcpassword=rosetta
# allow manual pruning
prune=1

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
}
}

27
assets/lbry-mainnet.conf Normal file
View file

@ -0,0 +1,27 @@
##
## lbry.conf configuration file. Lines beginning with # are comments.
##
# DO NOT USE THIS CONFIGURATION FILE IF YOU PLAN TO EXPOSE
# LBRYCRDD'S RPC PORT PUBLICALLY (THESE INSECURE CREDENTIALS
# COULD LEAD TO AN ATTACK). ROSETTA-LBRY USES THE RPC PORT
# FOR INDEXING AND TRANSACTION BROADCAST BUT NEVER PROVIDES THE
# CALLER ACCESS TO LBRYCRDD'S RPC PORT.
datadir=/data/lbrycrdd
bind=0.0.0.0
rpcbind=0.0.0.0
bantime=15
rpcallowip=0.0.0.0/0
rpcthreads=30
disablewallet=1
txindex=0
port=9246
rpcport=9245
rpcuser=rosetta
rpcpassword=rosetta
rpcworkqueue=3000
dbcache=3000
# allow manual pruning
prune=1

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

@ -22,7 +22,7 @@ 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/coinbase/rosetta-sdk-go/storage"
@ -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,7 +20,7 @@ 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/coinbase/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/coinbase/rosetta-sdk-go/types"
@ -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.lbrycrddPath = path.Join(newDir, "lbrycrdd")
assert.Equal(t, test.cfg, cfg) assert.Equal(t, test.cfg, cfg)
assert.NoError(t, err) assert.NoError(t, err)
} }

23
go.mod
View file

@ -1,16 +1,33 @@
module github.com/coinbase/rosetta-bitcoin module github.com/lbryio/rosetta-lbry
go 1.13 go 1.13
require ( require (
4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a // indirect
4d63.com/gochecknoinits v0.0.0-20200108094044-eb73b47b9fc4 // indirect
dmitri.shuralyov.com/go/generated v0.0.0-20170818220700-b1254a446363 // indirect
github.com/alecthomas/gocyclo v0.0.0-20150208221726-aa8f8b160214 // indirect
github.com/alexkohler/nakedret v1.0.0 // indirect
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/client9/misspell v0.3.4 // indirect
github.com/coinbase/rosetta-sdk-go v0.6.1 github.com/coinbase/rosetta-sdk-go v0.6.1
github.com/dgraph-io/badger/v2 v2.2007.2 github.com/dgraph-io/badger/v2 v2.2007.2
github.com/golang/lint v0.0.0-20200302205851-738671d3881b // indirect
github.com/gordonklaus/ineffassign v0.0.0-20201107091007-3b93a8888063 // indirect
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 github.com/grpc-ecosystem/go-grpc-middleware v1.2.2
github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3 // indirect
github.com/mdempsky/maligned v0.0.0-20201101000000-d73c43cb16d0 // indirect
github.com/mdempsky/unconvert v0.0.0-20200228143138-95ecdbfc0b5f // indirect
github.com/mibk/dupl v1.0.0 // indirect
github.com/opennota/check v0.0.0-20180911053232-0c771f5545ff // indirect
github.com/stretchr/testify v1.6.1 github.com/stretchr/testify v1.6.1
github.com/stripe/safesql v0.2.0 // indirect
github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9 // indirect
github.com/walle/lll v1.0.1 // indirect
go.uber.org/zap v1.16.0 go.uber.org/zap v1.16.0
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9
golang.org/x/tools v0.0.0-20200904185747-39188db58858 // indirect
honnef.co/go/tools v0.0.1-2020.1.5 // indirect honnef.co/go/tools v0.0.1-2020.1.5 // indirect
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect
mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 // indirect
) )

49
go.sum
View file

@ -1,4 +1,10 @@
4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a h1:wFEQiK85fRsEVF0CRrPAos5LoAryUsIX1kPW/WrIqFw=
4d63.com/gochecknoglobals v0.0.0-20201008074935-acfc0b28355a/go.mod h1:Sk40JNJmh0koZukOjJfaBNLZazbZthFfHnLHIcZNS6A=
4d63.com/gochecknoinits v0.0.0-20200108094044-eb73b47b9fc4 h1:bf5qocEKjrY58JO2GwywfLsb1199lIVs7qHkiplwHy0=
4d63.com/gochecknoinits v0.0.0-20200108094044-eb73b47b9fc4/go.mod h1:4o1i5aXtIF5tJFt3UD1knCVmWOXg7fLYdHVu6jeNcnM=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
dmitri.shuralyov.com/go/generated v0.0.0-20170818220700-b1254a446363 h1:o4lAkfETerCnr1kF9/qwkwjICnU+YLHNDCM8h2xj7as=
dmitri.shuralyov.com/go/generated v0.0.0-20170818220700-b1254a446363/go.mod h1:WG7q7swWsS2f9PYpt5DoEP/EBYWx8We5UoRltn9vJl8=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4=
github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc= github.com/Azure/azure-pipeline-go v0.2.2/go.mod h1:4rQ/NZncSvGqNkkOsNpOU1tgoNuIlp9AfUH5G1tvCHc=
@ -25,8 +31,13 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE
github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg= github.com/StackExchange/wmi v0.0.0-20180116203802-5d049714c4a6/go.mod h1:3eOhrUMpNV+6aFIbp5/iudMxNCF27Vw2OZgy4xEx0Fg=
github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8= github.com/VictoriaMetrics/fastcache v1.5.7/go.mod h1:ptDBkNMQI4RtmVo8VS/XwRY6RoTu1dAWCbrk+6WsEM8=
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
github.com/alecthomas/gocyclo v0.0.0-20150208221726-aa8f8b160214 h1:YI/8G3uLbYyowJeOPVL6BMKe2wbL54h0FdEKmncU6lU=
github.com/alecthomas/gocyclo v0.0.0-20150208221726-aa8f8b160214/go.mod h1:Ef5UOtJdJ5rVFObdOVsrNgKV/Wf4I+daTCSk8GTrHIk=
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alexflint/go-arg v0.0.0-20160306200701-e71d6514f40a/go.mod h1:PHxo6ZWOLVMZZgWSAqBynb/KhIqoGO6WKwOVX7rM9dg=
github.com/alexkohler/nakedret v1.0.0 h1:S/bzOFhZHYUJp6qPmdXdFHS5nlWGFmLmoc8QOydvotE=
github.com/alexkohler/nakedret v1.0.0/go.mod h1:tfDQbtPt67HhBK/6P0yNktIX7peCxfOp0jO9007DrLE=
github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM= github.com/allegro/bigcache v1.2.1-0.20190218064605-e24eb225f156/go.mod h1:Cb/ax3seSYIx7SuZdm2G2xzfwmv3TPSk2ucNfQESPXM=
github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ= github.com/aristanetworks/goarista v0.0.0-20170210015632-ea17b1a17847/go.mod h1:D/tb0zPVXnP7fmsLZjtdUhSsumbK/ij54UXjjVgMGxQ=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
@ -118,6 +129,8 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE=
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/lint v0.0.0-20200302205851-738671d3881b h1:BOvdkG2qv61G8DSvnEEgkjT/+tkEyHPPUfz0uGXXELY=
github.com/golang/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:tluoj9z5200jBnyusfRPU2LqT6J+DAorxEvtC7LHB+E=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -145,6 +158,8 @@ github.com/google/go-cmp v0.5.2 h1:X2ev0eStA3AbceY54o37/0PQ/UWqKEiiO2dKL5OPaFM=
github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.1-0.20200604201612-c04b05f3adfa/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/gordonklaus/ineffassign v0.0.0-20201107091007-3b93a8888063 h1:dKprcOvlsvqfWn/iGvz+oYuC2axESeSMuF8dDrWMNsE=
github.com/gordonklaus/ineffassign v0.0.0-20201107091007-3b93a8888063/go.mod h1:cuNKsD1zp2v6XfE/orVX2QE1LC+i254ceGcVeDT3pTU=
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1-0.20190629185528-ae1634f6a989/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
@ -163,12 +178,16 @@ github.com/jackpal/go-nat-pmp v1.0.2-0.20160603034137-1fa385a6f458/go.mod h1:QPH
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89 h1:12K8AlpT0/6QUXSfV0yi4Q0jkbq8NDtIKFtF61AoqV0= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89 h1:12K8AlpT0/6QUXSfV0yi4Q0jkbq8NDtIKFtF61AoqV0=
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3 h1:7nkB9fLPMwtn/R6qfPcHileL/x9ydlhw8XyDrLI1ZXg=
github.com/jgautheron/goconst v0.0.0-20201117150253-ccae5bf973f3/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI= github.com/jrick/logrotate v1.0.0 h1:lQ1bL/n9mBNeIXoTUoYRlK4dHuNJVofX9oWqBtPnSzI=
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.1.1-0.20170430222011-975b5c4c7c21/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU= github.com/karalabe/usb v0.0.0-20190919080040-51dc0efba356/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/kisielk/errcheck v1.1.0 h1:ZqfnKyx9KGpRcW04j5nnPDgRgoXUeLh2YFBeFzphcA0=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23 h1:FOOIBWrEkLgmlgGfMuZT83xIwfPDxEI2OHu6xUmJMFE=
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
@ -195,6 +214,12 @@ github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Ky
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mdempsky/maligned v0.0.0-20201101000000-d73c43cb16d0 h1:+6XJvFZBYbNv/nSekNWFZyaGNMXcPnZ4n/HHoCXn+Ms=
github.com/mdempsky/maligned v0.0.0-20201101000000-d73c43cb16d0/go.mod h1:3UB4iTzhLciyWcrrvXSkrtCIU+IJ5GCfEmnleHRsxL4=
github.com/mdempsky/unconvert v0.0.0-20200228143138-95ecdbfc0b5f h1:Kc3s6QFyh9DLgInXpWKuG+8I7R7lXbnP7mcoOVIt6KY=
github.com/mdempsky/unconvert v0.0.0-20200228143138-95ecdbfc0b5f/go.mod h1:AmCV4WB3cDMZqgPk+OUQKumliiQS4ZYsBt3AXekyuAU=
github.com/mibk/dupl v1.0.0 h1:aZc3jqrF9n0tUHwHt/+jsRxA8cRgA0Gdl56M7W7PoqE=
github.com/mibk/dupl v1.0.0/go.mod h1:pCr4pNxxIbFGvtyCOi0c7LVjmV6duhKWV+ex5vh38ME=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8= github.com/mitchellh/mapstructure v1.3.3 h1:SzB1nHZ2Xi+17FP0zVQBHIZqvwRN9408fJO8h+eeNA8=
@ -214,6 +239,8 @@ github.com/onsi/gomega v1.4.1/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/opennota/check v0.0.0-20180911053232-0c771f5545ff h1:lRHufowVGvUvxGsPveAZOpSa/9T5Gpxg6d7UbHCA9MQ=
github.com/opennota/check v0.0.0-20180911053232-0c771f5545ff/go.mod h1:tydB+MZxWpY8M/NRu7jQhND/mXuLAPsKcSV6JkzofsA=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34= github.com/pborman/uuid v0.0.0-20170112150404-1b00554d8222/go.mod h1:VyrYX9gd7irzKovcSS6BIIEwPRkP2Wm2m9ufcdFSJ34=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@ -232,6 +259,7 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R
github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/prometheus/tsdb v0.6.2-0.20190402121629-4f204dcbc150/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho= github.com/rjeczalik/notify v0.9.1/go.mod h1:rKwnCoCGeuQnwBtTSPL9Dad03Vh2n40ePRrjvIXnJho=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= github.com/rs/cors v0.0.0-20160617231935-a62a804a8a00/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ= github.com/rs/xhandler v0.0.0-20160618193221-ed27b6fd6521/go.mod h1:RvLn4FgxWubrpZHtQLnOf6EwhN2hEMusxZOhcW9H3UQ=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
@ -260,6 +288,8 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stripe/safesql v0.2.0 h1:xiefmCDd8c35PVSGrL2FhBiaKxviXnGziBDOpOejeBE=
github.com/stripe/safesql v0.2.0/go.mod h1:q7b2n0JmzM1mVGfcYpanfVb2j23cXZeWFxcILPn3JV4=
github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM=
github.com/tidwall/gjson v1.6.1 h1:LRbvNuNuvAiISWg6gxLEFuCe72UKy5hDqhxW/8183ws= github.com/tidwall/gjson v1.6.1 h1:LRbvNuNuvAiISWg6gxLEFuCe72UKy5hDqhxW/8183ws=
github.com/tidwall/gjson v1.6.1/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0= github.com/tidwall/gjson v1.6.1/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0=
@ -271,6 +301,8 @@ github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tidwall/sjson v1.1.2 h1:NC5okI+tQ8OG/oyzchvwXXxRxCV/FVdhODbPKkQ25jQ= github.com/tidwall/sjson v1.1.2 h1:NC5okI+tQ8OG/oyzchvwXXxRxCV/FVdhODbPKkQ25jQ=
github.com/tidwall/sjson v1.1.2/go.mod h1:SEzaDwxiPzKzNfUEO4HbYF/m4UCSJDsGgNqsS1LvdoY= github.com/tidwall/sjson v1.1.2/go.mod h1:SEzaDwxiPzKzNfUEO4HbYF/m4UCSJDsGgNqsS1LvdoY=
github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9 h1:vY5WqiEon0ZSTGM3ayVVi+twaHKHDFUVloaQ/wug9/c=
github.com/tsenart/deadcode v0.0.0-20160724212837-210d2dc333e9/go.mod h1:q+QjxYvZ+fpjMXqs+XEriussHjSYqeXVnAdSV1tkMYk=
github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs= github.com/tyler-smith/go-bip39 v1.0.1-0.20181017060643-dbb3b84ba2ef/go.mod h1:sJ5fKU0s6JVwZjjcUEX2zFOnvq0ASQ2K9Zr6cf67kNs=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
@ -278,8 +310,11 @@ github.com/vmihailenco/msgpack/v5 v5.0.0-beta.9 h1:iBRIniTnWOo0kqkg3k3XR8Vn6OCkV
github.com/vmihailenco/msgpack/v5 v5.0.0-beta.9/go.mod h1:HVxBVPUK/+fZMonk4bi1islLa8V3cfnBug0+4dykPzo= github.com/vmihailenco/msgpack/v5 v5.0.0-beta.9/go.mod h1:HVxBVPUK/+fZMonk4bi1islLa8V3cfnBug0+4dykPzo=
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/walle/lll v1.0.1 h1:lbK8008fOXbQNYt8daBGUrjvElvlwlE7D7N/9dLP5IQ=
github.com/walle/lll v1.0.1/go.mod h1:lYxcXzoPhiAHR9eaq+Yv7RYg1nIipLloBCIfPUzfaWQ=
github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees= github.com/wsddn/go-ecdh v0.0.0-20161211032359-48726bab9208/go.mod h1:IotVbo4F+mw0EzQ08zFqg7pK3FebNXpaMsRy2RT+Ees=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk= go.uber.org/atomic v1.6.0 h1:Ezj3JGmsOnG1MoRWQkPBsKLe9DwWD9QeXzTRzzldNVk=
@ -324,6 +359,7 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b h1:GgiSbuUyC0BlbUmHQBgFqu32eiRR/CEYdjOjOd4zE6Y= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b h1:GgiSbuUyC0BlbUmHQBgFqu32eiRR/CEYdjOjOd4zE6Y=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180719180050-a680a1efc54d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -335,6 +371,7 @@ golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc h1:zK/HqS5bZxDptfPJNq8v7vJfXtkU7r9TLIoSr1bXaP4=
@ -343,12 +380,15 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202 h1:VvcQYSHwXgi7W+TpUR6A9g6Up
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA= golang.org/x/net v0.0.0-20200904194848-62affa334b73 h1:MXfv8rhZWmFeqX3GNZRsd6vOLoaCHjYEX3qkRo3YBUA=
golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208 h1:qwRHBd0NqMbJxfbotnDhm2ByMI1Shq4Y6oRJo21SGJA=
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -371,6 +411,7 @@ golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200824131525-c12d262b63d8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009 h1:W0lCpv29Hv0UaM1LXb9QlBHLNP8UFfcKjblhVCWftOM=
golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
@ -392,8 +433,12 @@ golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117012304-6edc0a871e69/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa h1:5E4dL8+NgFOgjwbTKz+OOEGGhP+ectTmF842l6KjupQ= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa h1:5E4dL8+NgFOgjwbTKz+OOEGGhP+ectTmF842l6KjupQ=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200225230052-807dcd883420/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20200904185747-39188db58858 h1:xLt+iB5ksWcZVxqc+g9K41ZHy+6MKWfXCDsjSThnsPA= golang.org/x/tools v0.0.0-20200904185747-39188db58858 h1:xLt+iB5ksWcZVxqc+g9K41ZHy+6MKWfXCDsjSThnsPA=
golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE=
golang.org/x/tools v0.0.0-20201030204249-4fc0492b8eca h1:KWfVIHfTHZf4IQhrLjrbG+kLyoSym7yYp0WgqtOVH9s=
golang.org/x/tools v0.0.0-20201030204249-4fc0492b8eca/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
@ -449,3 +494,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.5 h1:nI5egYTGJakVyOryqLs1cQO5dO0ksin5XXs2pspk75k= honnef.co/go/tools v0.0.1-2020.1.5 h1:nI5egYTGJakVyOryqLs1cQO5dO0ksin5XXs2pspk75k=
honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.5/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I=
mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc=
mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 h1:kAREL6MPwpsk1/PQPFD3Eg7WAQR5mPTWZJaBiG5LDbY=
mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc=

View file

@ -20,10 +20,10 @@ 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/asserter"
"github.com/coinbase/rosetta-sdk-go/storage" "github.com/coinbase/rosetta-sdk-go/storage"
@ -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 lbrycrdd 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 lbrycrdd...")
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 lbrycrdd 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 lbrycrdd", "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 lbrycrdd",
"prune height", pruneHeight, "prune height", pruneHeight,
"error", err, "error", err,
) )
} else { } else {
logger.Infow("pruned bitcoind", "prune height", prunedHeight) logger.Infow("pruned lbrycrdd", "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,9 +23,9 @@ 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/coinbase/rosetta-sdk-go/storage"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/coinbase/rosetta-sdk-go/types"
@ -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 lbrycrdd...
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: types.String(bitcoin.SuccessStatus), Status: types.String(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: types.String(bitcoin.SuccessStatus), Status: types.String(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

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,7 +26,7 @@ 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/coinbase/rosetta-sdk-go/storage"
@ -36,7 +36,7 @@ import (
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 lbrycrdd
// 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 lbrycrdd 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. // lbrycrdd.
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 lbrycrdd.
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")
@ -570,7 +570,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
@ -628,7 +628,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,
@ -657,7 +657,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. lbrycrdd
// 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.
// //
@ -699,17 +699,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 != ""
} }
@ -768,7 +768,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(
@ -804,7 +804,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"

172
lbry/config.go Normal file
View file

@ -0,0 +1,172 @@
package lbry
import (
"math/big"
"time"
"github.com/btcsuite/btcd/chaincfg"
"github.com/btcsuite/btcd/chaincfg/chainhash"
"github.com/btcsuite/btcd/wire"
)
func init() {
if err := chaincfg.Register(&LbryMainnetParams); err != nil {
panic(err)
}
if err := chaincfg.Register(&LbryTestnetParams); err != nil {
panic(err)
}
}
var (
bigOne = big.NewInt(1)
mainPowLimit = new(big.Int).Sub(new(big.Int).Lsh(bigOne, 224), bigOne)
)
const (
// DeploymentTestDummy ...
DeploymentTestDummy = iota
// DeploymentCSV ...
DeploymentCSV
// DeploymentSegwit ...
DeploymentSegwit
// DefinedDeployments ...
DefinedDeployments
)
// genesisCoinbaseTx is the coinbase transaction for the genesis blocks for
// the main network, regression test network, and test network (version 3).
var genesisCoinbaseTx = wire.MsgTx{
Version: 1,
TxIn: []*wire.TxIn{
{
PreviousOutPoint: wire.OutPoint{
Hash: chainhash.Hash{},
Index: 0xffffffff,
},
SignatureScript: []byte{
0x04, 0xff, 0xff, 0x00, 0x1d, 0x01, 0x04, 0x17,
0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x20, 0x74,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70,
0x20, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67,
},
Sequence: 0xffffffff,
},
},
TxOut: []*wire.TxOut{
{
Value: 0x12a05f200,
PkScript: []byte{ // ToDo
0x76, 0xa9, 0x14, 0x34, 0x59, 0x91, 0xdb, 0xf5,
0x7b, 0xfb, 0x01, 0x4b, 0x87, 0x00, 0x6a, 0xcd,
0xfa, 0xfb, 0xfc, 0x5f, 0xe8, 0x29, 0x2f, 0x88,
0xac,
},
},
},
LockTime: 0,
}
// https://github.com/lbryio/lbrycrd/blob/master/src/chainparams.cpp#L19
var genesisMerkleRoot = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
0xcc, 0x59, 0xe5, 0x9f, 0xf9, 0x7a, 0xc0, 0x92,
0xb5, 0x5e, 0x42, 0x3a, 0xa5, 0x49, 0x51, 0x51,
0xed, 0x6f, 0xb8, 0x05, 0x70, 0xa5, 0xbb, 0x78,
0xcd, 0x5b, 0xd1, 0xc3, 0x82, 0x1c, 0x21, 0xb8,
})
var genesisBlock = wire.MsgBlock{
Header: wire.BlockHeader{
Version: 1,
PrevBlock: chainhash.Hash{}, // 0000000000000000000000000000000000000000000000000000000000000000
MerkleRoot: genesisMerkleRoot, // b8211c82c3d15bcd78bba57005b86fed515149a53a425eb592c07af99fe559cc
Timestamp: time.Unix(1446058291, 0), // Wednesday, October 28, 2015 6:51:31 PM GMT
Bits: 0x1f00ffff,
Nonce: 1287,
},
Transactions: []*wire.MsgTx{&genesisCoinbaseTx},
}
var genesisHash = chainhash.Hash([chainhash.HashSize]byte{ // Make go vet happy.
0x63, 0xf4, 0x34, 0x6a, 0x4d, 0xb3, 0x4f, 0xdf,
0xce, 0x29, 0xa7, 0x0f, 0x5e, 0x8d, 0x11, 0xf0,
0x65, 0xf6, 0xb9, 0x16, 0x02, 0xb7, 0x03, 0x6c,
0x7f, 0x22, 0xf3, 0xa0, 0x3b, 0x28, 0x89, 0x9c,
})
func newHashFromStr(hexStr string) *chainhash.Hash {
hash, err := chainhash.NewHashFromStr(hexStr)
if err != nil {
panic(err)
}
return hash
}
// MainNetParams returns the chain configuration for mainnet
var LbryMainnetParams = chaincfg.Params{
Name: "mainnet",
Net: 0xfae4aaf1,
DefaultPort: "9246",
// Chain parameters
GenesisBlock: &genesisBlock,
GenesisHash: &genesisHash,
// Human-readable part for Bech32 encoded segwit addresses, as defined in
// BIP 173.
Bech32HRPSegwit: "lbc",
// Address encoding magics
PubKeyHashAddrID: 85,
ScriptHashAddrID: 122,
PrivateKeyID: 28,
WitnessPubKeyHashAddrID: 0x06, // starts with p2
WitnessScriptHashAddrID: 0x0A, // starts with 7Xh
BIP0034Height: 1,
BIP0065Height: 200000,
BIP0066Height: 200000,
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x88, 0xad, 0xe4}, // starts with xprv
HDPublicKeyID: [4]byte{0x04, 0x88, 0xb2, 0x1e}, // starts with xpub
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType: 0x8c,
}
// TestnetParams returns the chain configuration for testnet
var LbryTestnetParams = chaincfg.Params{
Name: "testnet",
Net: 0xfae4aae1,
DefaultPort: "19246",
// Chain parameters
GenesisBlock: &genesisBlock,
GenesisHash: &genesisHash,
// Human-readable part for Bech32 encoded segwit addresses, as defined in
// BIP 173.
Bech32HRPSegwit: "tlbc", // always bc for main net
// Address encoding magics
PubKeyHashAddrID: 111,
ScriptHashAddrID: 196,
PrivateKeyID: 239,
WitnessPubKeyHashAddrID: 0x06, // starts with p2
WitnessScriptHashAddrID: 0x0A, // starts with 7Xh
BIP0034Height: 1,
BIP0065Height: 200000,
BIP0066Height: 200000,
// BIP32 hierarchical deterministic extended key magics
HDPrivateKeyID: [4]byte{0x04, 0x35, 0x83, 0x94}, // starts with xprv
HDPublicKeyID: [4]byte{0x04, 0x35, 0x87, 0xcf}, // starts with xpub
// BIP44 coin type used in the hierarchical deterministic path for
// address generation.
HDCoinType: 0x8c,
}

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" lbrycrddLogger = "lbrycrdd"
bitcoindStdErrLogger = "bitcoind stderr" lbrycrddStdErrLogger = "lbrycrdd 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 lbrycrddLogger
if identifier == bitcoindLogger { if identifier == lbrycrddLogger {
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 // Startlbrycrdd starts a lbrycrdd 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 Startlbrycrdd(ctx context.Context, configPath string, g *errgroup.Group) error {
logger := utils.ExtractLogger(ctx, "bitcoind") logger := utils.ExtractLogger(ctx, "lbrycrdd")
cmd := exec.Command( cmd := exec.Command(
"/app/bitcoind", "/app/lbrycrdd",
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, lbrycrddLogger)
}) })
g.Go(func() error { g.Go(func() error {
return logPipe(ctx, stderr, bitcoindStdErrLogger) return logPipe(ctx, stderr, lbrycrddStdErrLogger)
}) })
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 lbrycrdd", err)
} }
g.Go(func() error { g.Go(func() error {
<-ctx.Done() <-ctx.Done()
logger.Warnw("sending interrupt to bitcoind") logger.Warnw("sending interrupt to lbrycrdd")
return cmd.Process.Signal(os.Interrupt) return cmd.Process.Signal(os.Interrupt)
}) })

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,8 +23,8 @@ import (
) )
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 LBC (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 lbrycrdd
// 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
@ -88,21 +88,21 @@ const (
var ( var (
// MainnetGenesisBlockIdentifier is the genesis block for mainnet. // MainnetGenesisBlockIdentifier is the genesis block for mainnet.
MainnetGenesisBlockIdentifier = &types.BlockIdentifier{ MainnetGenesisBlockIdentifier = &types.BlockIdentifier{
Hash: "000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f", Hash: "9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463",
} }
// MainnetParams are the params for mainnet. // MainnetParams are the params for mainnet.
MainnetParams = &chaincfg.MainNetParams MainnetParams = &LbryMainnetParams
// MainnetCurrency is the *types.Currency for mainnet. // MainnetCurrency is the *types.Currency for mainnet.
MainnetCurrency = &types.Currency{ MainnetCurrency = &types.Currency{
Symbol: "BTC", Symbol: "LBC",
Decimals: Decimals, Decimals: Decimals,
} }
// TestnetGenesisBlockIdentifier is the genesis block for testnet. // TestnetGenesisBlockIdentifier is the genesis block for testnet.
TestnetGenesisBlockIdentifier = &types.BlockIdentifier{ TestnetGenesisBlockIdentifier = &types.BlockIdentifier{
Hash: "000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943", Hash: "9c89283ba0f3227f6c03b70216b9f665f0118d5e0fa729cedf4fb34d6a34f463",
} }
// TestnetParams are the params for testnet. // TestnetParams are the params for testnet.
@ -110,7 +110,7 @@ var (
// TestnetCurrency is the *types.Currency for testnet. // TestnetCurrency is the *types.Currency for testnet.
TestnetCurrency = &types.Currency{ TestnetCurrency = &types.Currency{
Symbol: "tBTC", Symbol: "tLBC",
Decimals: Decimals, Decimals: Decimals,
} }
@ -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"

26
main.go
View file

@ -24,11 +24,11 @@ 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/asserter"
"github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/server"
@ -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,
@ -197,10 +197,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,7 +5,7 @@ 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"
@ -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

@ -5,7 +5,7 @@ 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"
@ -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,8 +165,8 @@ 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).

View file

@ -17,7 +17,7 @@ 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/coinbase/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/coinbase/rosetta-sdk-go/types"
@ -83,7 +83,7 @@ func (s *AccountAPIService) AccountCoins(
// TODO: filter coins by request currencies // TODO: filter coins by request currencies
// TODO: support include_mempool query // TODO: support include_mempool query
// https://github.com/coinbase/rosetta-bitcoin/issues/36#issuecomment-724992022 // https://github.com/coinbase/rosetta-sdk-go-bitcoin/issues/36#issuecomment-724992022
// Once mempoolcoins are supported also change the bool service/types.go:MempoolCoins to true // Once mempoolcoins are supported also change the bool service/types.go:MempoolCoins to true
coins, block, err := s.i.GetCoins(ctx, request.AccountIdentifier) coins, block, err := s.i.GetCoins(ctx, request.AccountIdentifier)

View file

@ -18,9 +18,9 @@ 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/coinbase/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -48,7 +48,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)
@ -62,14 +62,14 @@ func TestAccountBalance_Online_Current(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,
(*types.PartialBlockIdentifier)(nil), (*types.PartialBlockIdentifier)(nil),
).Return(amount, block, nil).Once() ).Return(amount, block, nil).Once()
bal, err := servicer.AccountBalance(ctx, &types.AccountBalanceRequest{ bal, err := servicer.AccountBalance(ctx, &types.AccountBalanceRequest{
@ -89,7 +89,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)
@ -106,14 +106,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{
@ -134,7 +134,7 @@ func TestAccountBalance_Online_Historical(t *testing.T) {
func TestAccountCoins_Online(t *testing.T) { func TestAccountCoins_Online(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)

View file

@ -17,7 +17,7 @@ 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/coinbase/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/coinbase/rosetta-sdk-go/types"

View file

@ -19,8 +19,8 @@ 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/coinbase/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"

View file

@ -24,8 +24,8 @@ 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"
@ -37,7 +37,7 @@ import (
) )
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(ErrLbrycrdd, fmt.Errorf("%w unable to submit transaction", err))
} }
return &types.TransactionIdentifierResponse{ return &types.TransactionIdentifierResponse{

View file

@ -19,9 +19,9 @@ 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/coinbase/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

@ -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,7 +17,7 @@ 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/coinbase/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/coinbase/rosetta-sdk-go/types"
@ -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(ErrLbrycrdd, err)
} }
transactionIdentifiers := make([]*types.TransactionIdentifier, len(mempoolTransactions)) transactionIdentifiers := make([]*types.TransactionIdentifier, len(mempoolTransactions))

View file

@ -18,8 +18,8 @@ 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/coinbase/rosetta-sdk-go/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"

View file

@ -17,8 +17,8 @@ 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/coinbase/rosetta-sdk-go/server"
"github.com/coinbase/rosetta-sdk-go/types" "github.com/coinbase/rosetta-sdk-go/types"
@ -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(ErrLbrycrdd, err)
} }
cachedBlockResponse, err := s.i.GetBlockLazy(ctx, nil) cachedBlockResponse, err := s.i.GetBlockLazy(ctx, nil)
@ -95,8 +95,8 @@ func (s *NetworkAPIService) NetworkOptions(
MiddlewareVersion: types.String(MiddlewareVersion), MiddlewareVersion: types.String(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,
MempoolCoins: MempoolCoins, MempoolCoins: MempoolCoins,

View file

@ -18,9 +18,9 @@ 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/coinbase/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,7 +17,7 @@ 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/coinbase/rosetta-sdk-go/asserter"
"github.com/coinbase/rosetta-sdk-go/server" "github.com/coinbase/rosetta-sdk-go/server"

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/coinbase/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.
@ -41,7 +41,7 @@ const (
inlineFetchLimit = 100 inlineFetchLimit = 100
// 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.
@ -75,7 +75,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,
@ -85,10 +85,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 {
@ -98,7 +98,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 {
@ -109,5 +109,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"`
} }