diff --git a/.circleci/config.yml b/.circleci/config.yml index 8c60d43..51d1bc9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -16,7 +16,7 @@ version: 2.1 executors: default: docker: - - image: circleci/golang:1.13 + - image: circleci/golang:1.15 user: root # go directory is owned by root working_directory: /go/src/github.com/lbryio/rosetta-lbry environment: diff --git a/Dockerfile b/Dockerfile index 462f226..3aa1922 100644 --- a/Dockerfile +++ b/Dockerfile @@ -60,9 +60,9 @@ RUN mkdir -p /app \ && chown -R nobody:nogroup /app WORKDIR /app -RUN apt-get update && apt-get install -y curl make gcc g++ git -ENV GOLANG_VERSION 1.15.2 -ENV GOLANG_DOWNLOAD_SHA256 b49fda1ca29a1946d6bb2a5a6982cf07ccd2aba849289508ee0f9918f6bb4552 +RUN apt-get update && apt-get install -y curl make gcc g++ +ENV GOLANG_VERSION 1.15.5 +ENV GOLANG_DOWNLOAD_SHA256 9a58494e8da722c3aef248c9227b0e9c528c7318309827780f16220998180a0d ENV GOLANG_DOWNLOAD_URL https://golang.org/dl/go$GOLANG_VERSION.linux-amd64.tar.gz RUN curl -fsSL "$GOLANG_DOWNLOAD_URL" -o golang.tar.gz \ diff --git a/bitcoin/client.go b/bitcoin/client.go index c1f1f18..2a7ee20 100644 --- a/bitcoin/client.go +++ b/bitcoin/client.go @@ -516,9 +516,8 @@ func (b *Client) parseTransactions( "block hash", block.Hash, "transaction hash", transaction.Hash, ) - for _, op := range txOps { - op.Status = SkippedStatus + op.Status = types.String(SkippedStatus) } } @@ -681,7 +680,7 @@ func (b *Client) parseOutputTransactionOperation( NetworkIndex: &networkIndex, }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: account, Amount: &types.Amount{ Value: strconv.FormatInt(int64(amount), 10), @@ -738,7 +737,7 @@ func (b *Client) parseInputTransactionOperation( NetworkIndex: &networkIndex, }, Type: InputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: accountCoin.Account, Amount: &types.Amount{ Value: newValue, @@ -800,7 +799,7 @@ func (b *Client) coinbaseTxOperation( NetworkIndex: &networkIndex, }, Type: CoinbaseOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Metadata: metadata, }, nil } diff --git a/bitcoin/client_test.go b/bitcoin/client_test.go index 7945261..dfc3a67 100644 --- a/bitcoin/client_test.go +++ b/bitcoin/client_test.go @@ -735,7 +735,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: CoinbaseOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Metadata: mustMarshalMap(&OperationMetadata{ Coinbase: "04ffff001d02fd04", Sequence: 4294967295, @@ -747,7 +747,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: &types.AccountIdentifier{ Address: "4104f5eeb2b10c944c6b9fbcfff94c35bdeecd93df977882babc7f3a2cf7f5c81d3b09a68db7f0e04f21de5d4230e75e6dbe7ad16eefe0d4325a62067dc6f369446aac", // nolint }, @@ -788,7 +788,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: &types.AccountIdentifier{ Address: "mmtKKnjqTPdkBnBMbNt5Yu2SCwpMaEshEL", // nolint }, @@ -820,7 +820,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(1), }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: &types.AccountIdentifier{ Address: "4852fe372ff7534c16713b3146bbc1e86379c70bea4d5c02fb1fa0112980a081:1", }, @@ -928,7 +928,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: CoinbaseOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Metadata: mustMarshalMap(&OperationMetadata{ Coinbase: "044c86041b020602", Sequence: 4294967295, @@ -940,7 +940,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: &types.AccountIdentifier{ Address: "34qkc2iac6RsyxZVfyE2S5U5WcRsbg2dpK", }, @@ -972,7 +972,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(1), }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: &types.AccountIdentifier{ Address: "6a24aa21a9ed10109f4b82aa3ed7ec9d02a2a90246478b3308c8b85daf62fe501d58d05727a4", }, @@ -1007,7 +1007,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: InputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Amount: &types.Amount{ Value: "-5000000000", Currency: MainnetCurrency, @@ -1035,7 +1035,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: &types.AccountIdentifier{ Address: "1JqDybm2nWTENrHvMyafbSXXtTk5Uv5QAn", }, @@ -1067,7 +1067,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(1), }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: &types.AccountIdentifier{ Address: "1EYTGtG4LnFfiMvjJdsU7GMGCQvsRSjYhx", }, @@ -1112,7 +1112,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: InputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Amount: &types.Amount{ Value: "-3467607", Currency: MainnetCurrency, @@ -1144,7 +1144,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(1), }, Type: InputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Amount: &types.Amount{ Value: "0", Currency: MainnetCurrency, @@ -1172,7 +1172,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(2), }, Type: InputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Amount: &types.Amount{ Value: "-556000000", Currency: MainnetCurrency, @@ -1200,7 +1200,7 @@ func TestParseBlock(t *testing.T) { NetworkIndex: int64Pointer(0), }, Type: OutputOpType, - Status: SuccessStatus, + Status: types.String(SuccessStatus), Account: &types.AccountIdentifier{ Address: "76a914c398efa9c392ba6013c5e04ee729755ef7f58b3288ac", }, diff --git a/go.mod b/go.mod index 0a1389c..c6e4cdb 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.13 require ( github.com/btcsuite/btcd v0.21.0-beta github.com/btcsuite/btcutil v1.0.2 - github.com/coinbase/rosetta v0.5.9 + github.com/coinbase/rosetta-sdk-go v0.6.1 github.com/dgraph-io/badger/v2 v2.2007.2 github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 github.com/stretchr/testify v1.6.1 diff --git a/go.sum b/go.sum index 68b7a14..57fef7a 100644 --- a/go.sum +++ b/go.sum @@ -62,8 +62,8 @@ github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/cloudflare-go v0.10.2-0.20190916151808-a80f83b9add9/go.mod h1:1MxXX1Ux4x6mqPmjkUgTP1CdXIBXKX7T+Jk9Gxrmx+U= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/coinbase/rosetta v0.5.9 h1:CuGQE3HFmYwdEACJnuOtVI9cofqPsGvq6FdFIzaOPKI= -github.com/coinbase/rosetta v0.5.9/go.mod h1:xd4wYUhV3LkY78SPH8BUhc88rXfn2jYgN9BfiSjbcvM= +github.com/coinbase/rosetta-sdk-go v0.6.1 h1:aOb5qstlX0uqP9HRC7wCY+YAZDzZbS2C/i3Qy/lR3xM= +github.com/coinbase/rosetta-sdk-go v0.6.1/go.mod h1:t36UuaD4p2DSXaSH9IwMasZDJ7UPxt9cQi6alS5OPTo= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= @@ -97,11 +97,11 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/ethereum/go-ethereum v1.9.23 h1:SIKhg/z4Q7AbvqcxuPYvMxf36che/Rq/Pp0IdYEkbtw= -github.com/ethereum/go-ethereum v1.9.23/go.mod h1:JIfVb6esrqALTExdz9hRYvrP0xBDf6wCncIu1hNwHpM= +github.com/ethereum/go-ethereum v1.9.24 h1:6AK+ORt3EMDO+FTjzXy/AQwHMbu52J2nYHIjyQX9azQ= +github.com/ethereum/go-ethereum v1.9.24/go.mod h1:JIfVb6esrqALTExdz9hRYvrP0xBDf6wCncIu1hNwHpM= github.com/fatih/color v1.3.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fjl/memsize v0.0.0-20180418122429-ca190fb6ffbc/go.mod h1:VvhXpOYNQvB+uIk2RvXzuaQtkQJzzIx6lSBe1xv7hi0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= @@ -185,16 +185,11 @@ github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77 h1:6xiz3+ZczT3M4 github.com/lucasjones/reggen v0.0.0-20180717132126-cdb49ff09d77/go.mod h1:5ELEyG+X8f+meRWHuqUOewBOhvHkl7M76pdGEansxW4= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/mattn/go-colorable v0.1.0/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= -github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.7 h1:bQGKb3vps/j0E9GfJQ03JyhRuxsvdAanXlT9BTw3mdw= -github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-ieproxy v0.0.0-20190610004146-91bb50d98149/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-isatty v0.0.5-0.20180830101745-3fb116b82035/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= @@ -268,6 +263,8 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ 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/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0= +github.com/tidwall/gjson v1.6.3 h1:aHoiiem0dr7GHkW001T1SMTJ7X5PvyekH5WX0whWGnI= +github.com/tidwall/gjson v1.6.3/go.mod h1:BaHyNc5bjzYkPqgLq7mdVzeiRtULKULXLgZFKsxEHI0= github.com/tidwall/match v1.0.1 h1:PnKP62LPNxHKTwvHHZZzdOAOCtsJTjo6dZLCwpKm5xc= github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU= @@ -357,7 +354,6 @@ golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -365,7 +361,6 @@ golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/indexer/indexer.go b/indexer/indexer.go index 002e2d5..2eb8016 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -255,7 +255,7 @@ func (i *Indexer) Sync(ctx context.Context) error { // If previously processed blocks exist in storage, they are fetched. // Otherwise, none are provided to the cache (the syncer will not attempt // a reorg if the cache is empty). - pastBlocks := i.blockStorage.CreateBlockCache(ctx) + pastBlocks := i.blockStorage.CreateBlockCache(ctx, syncer.DefaultPastBlockLimit) syncer := syncer.New( i.network, diff --git a/indexer/indexer_test.go b/indexer/indexer_test.go index 16c26f6..9436132 100644 --- a/indexer/indexer_test.go +++ b/indexer/indexer_test.go @@ -286,7 +286,7 @@ func TestIndexer_Transactions(t *testing.T) { Index: 0, NetworkIndex: &index0, }, - Status: lbry.SuccessStatus, + Status: types.String(lbry.SuccessStatus), Type: lbry.OutputOpType, Account: &types.AccountIdentifier{ Address: rawHash, @@ -505,7 +505,7 @@ func TestIndexer_Reorg(t *testing.T) { Index: 0, NetworkIndex: &index0, }, - Status: lbry.SuccessStatus, + Status: types.String(lbry.SuccessStatus), Type: lbry.OutputOpType, Account: &types.AccountIdentifier{ Address: rawHash, diff --git a/main.go b/main.go index bae990b..a2ff2fa 100644 --- a/main.go +++ b/main.go @@ -157,6 +157,7 @@ func main() { services.HistoricalBalanceLookup, []*types.NetworkIdentifier{cfg.Network}, nil, + services.MempoolCoins, ) if err != nil { logger.Fatalw("unable to create new server asserter", "error", err) diff --git a/services/account_service.go b/services/account_service.go index 14fb3d3..41de331 100644 --- a/services/account_service.go +++ b/services/account_service.go @@ -49,34 +49,7 @@ func (s *AccountAPIService) AccountBalance( return nil, wrapErr(ErrUnavailableOffline, nil) } - // If we are fetching the current balance, - // return all coins for an address and calculate - // the balance from those coins. - if request.BlockIdentifier == nil { - coins, block, err := s.i.GetCoins(ctx, request.AccountIdentifier) - if err != nil { - return nil, wrapErr(ErrUnableToGetCoins, err) - } - - balance := "0" - for _, coin := range coins { - balance, err = types.AddValues(balance, coin.Amount.Value) - if err != nil { - return nil, wrapErr(ErrUnableToParseIntermediateResult, err) - } - } - - return &types.AccountBalanceResponse{ - BlockIdentifier: block, - Coins: coins, - Balances: []*types.Amount{ - { - Value: balance, - Currency: s.config.Currency, - }, - }, - }, nil - } + // TODO: filter balances by request currencies // If we are fetching a historical balance, // use balance storage and don't return coins. @@ -97,3 +70,31 @@ func (s *AccountAPIService) AccountBalance( }, }, nil } + +// AccountCoins implements /account/coins. +func (s *AccountAPIService) AccountCoins( + ctx context.Context, + request *types.AccountCoinsRequest, +) (*types.AccountCoinsResponse, *types.Error) { + if s.config.Mode != configuration.Online { + return nil, wrapErr(ErrUnavailableOffline, nil) + } + + // TODO: filter coins by request currencies + + // TODO: support include_mempool query + // https://github.com/coinbase/rosetta-bitcoin/issues/36#issuecomment-724992022 + // Once mempoolcoins are supported also change the bool service/types.go:MempoolCoins to true + + coins, block, err := s.i.GetCoins(ctx, request.AccountIdentifier) + if err != nil { + return nil, wrapErr(ErrUnableToGetCoins, err) + } + + result := &types.AccountCoinsResponse{ + BlockIdentifier: block, + Coins: coins, + } + + return result, nil +} diff --git a/services/account_service_test.go b/services/account_service_test.go index f4ddfe0..4f90ab5 100644 --- a/services/account_service_test.go +++ b/services/account_service_test.go @@ -38,6 +38,10 @@ func TestAccountBalance_Offline(t *testing.T) { assert.Nil(t, bal) assert.Equal(t, ErrUnavailableOffline.Code, err.Code) + coins, err := servicer.AccountCoins(ctx, &types.AccountCoinsRequest{}) + assert.Nil(t, coins) + assert.Equal(t, ErrUnavailableOffline.Code, err.Code) + mockIndexer.AssertExpectations(t) } @@ -49,56 +53,33 @@ func TestAccountBalance_Online_Current(t *testing.T) { mockIndexer := &mocks.Indexer{} servicer := NewAccountAPIService(cfg, mockIndexer) ctx := context.Background() - account := &types.AccountIdentifier{ Address: "hello", } - - coins := []*types.Coin{ - { - Amount: &types.Amount{ - Value: "10", - }, - CoinIdentifier: &types.CoinIdentifier{ - Identifier: "coin 1", - }, - }, - { - Amount: &types.Amount{ - Value: "15", - }, - CoinIdentifier: &types.CoinIdentifier{ - Identifier: "coin 2", - }, - }, - { - Amount: &types.Amount{ - Value: "0", - }, - CoinIdentifier: &types.CoinIdentifier{ - Identifier: "coin 3", - }, - }, - } block := &types.BlockIdentifier{ Index: 1000, Hash: "block 1000", } - mockIndexer.On("GetCoins", ctx, account).Return(coins, block, nil).Once() + amount := &types.Amount{ + Value: "25", + Currency: lbry.MainnetCurrency, + } + mockIndexer.On( + "GetBalance", + ctx, + account, + lbry.MainnetCurrency, + (*types.PartialBlockIdentifier)(nil), + ).Return(amount, block, nil).Once() bal, err := servicer.AccountBalance(ctx, &types.AccountBalanceRequest{ AccountIdentifier: account, }) assert.Nil(t, err) - assert.Equal(t, &types.AccountBalanceResponse{ BlockIdentifier: block, - Coins: coins, Balances: []*types.Amount{ - { - Value: "25", - Currency: lbry.MainnetCurrency, - }, + amount, }, }, bal) @@ -149,3 +130,61 @@ func TestAccountBalance_Online_Historical(t *testing.T) { mockIndexer.AssertExpectations(t) } + +func TestAccountCoins_Online(t *testing.T) { + cfg := &configuration.Configuration{ + Mode: configuration.Online, + Currency: lbry.MainnetCurrency, + } + mockIndexer := &mocks.Indexer{} + servicer := NewAccountAPIService(cfg, mockIndexer) + ctx := context.Background() + + account := &types.AccountIdentifier{ + Address: "hello", + } + + coins := []*types.Coin{ + { + Amount: &types.Amount{ + Value: "10", + }, + CoinIdentifier: &types.CoinIdentifier{ + Identifier: "coin 1", + }, + }, + { + Amount: &types.Amount{ + Value: "15", + }, + CoinIdentifier: &types.CoinIdentifier{ + Identifier: "coin 2", + }, + }, + { + Amount: &types.Amount{ + Value: "0", + }, + CoinIdentifier: &types.CoinIdentifier{ + Identifier: "coin 3", + }, + }, + } + block := &types.BlockIdentifier{ + Index: 1000, + Hash: "block 1000", + } + mockIndexer.On("GetCoins", ctx, account).Return(coins, block, nil).Once() + + bal, err := servicer.AccountCoins(ctx, &types.AccountCoinsRequest{ + AccountIdentifier: account, + }) + assert.Nil(t, err) + + assert.Equal(t, &types.AccountCoinsResponse{ + BlockIdentifier: block, + Coins: coins, + }, bal) + + mockIndexer.AssertExpectations(t) +} diff --git a/services/network_service.go b/services/network_service.go index bed67df..832b9a8 100644 --- a/services/network_service.go +++ b/services/network_service.go @@ -92,13 +92,14 @@ func (s *NetworkAPIService) NetworkOptions( Version: &types.Version{ RosettaVersion: types.RosettaAPIVersion, NodeVersion: NodeVersion, - MiddlewareVersion: &MiddlewareVersion, + MiddlewareVersion: types.String(MiddlewareVersion), }, Allow: &types.Allow{ OperationStatuses: lbry.OperationStatuses, OperationTypes: lbry.OperationTypes, Errors: Errors, HistoricalBalanceLookup: HistoricalBalanceLookup, + MempoolCoins: MempoolCoins, }, }, nil } diff --git a/services/network_service_test.go b/services/network_service_test.go index 62f6869..26a39fe 100644 --- a/services/network_service_test.go +++ b/services/network_service_test.go @@ -27,7 +27,7 @@ import ( ) var ( - middlewareVersion = "0.0.6" + middlewareVersion = "0.0.7" defaultNetworkOptions = &types.NetworkOptionsResponse{ Version: &types.Version{ RosettaVersion: types.RosettaAPIVersion, diff --git a/services/types.go b/services/types.go index 9bfa507..ce8103e 100644 --- a/services/types.go +++ b/services/types.go @@ -31,18 +31,21 @@ const ( // that historical balance lookup is supported. HistoricalBalanceLookup = true + // MempoolCoins indicates that + // including mempool coins in the /account/coins + // response is not supported. + MempoolCoins = false + // inlineFetchLimit is the maximum number // of transactions to fetch inline. inlineFetchLimit = 100 -) -var ( // MiddlewareVersion is the version // of rosetta-lbry. We set this as a // variable instead of a constant because // we typically need the pointer of this // value. - MiddlewareVersion = "0.0.6" + MiddlewareVersion = "0.0.7" ) // Client is used by the servicers to get Peer information