2020-09-16 21:03:14 +02:00
|
|
|
// Copyright 2020 Coinbase, Inc.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
package services
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2020-10-27 20:42:58 +01:00
|
|
|
"fmt"
|
2020-09-16 21:03:14 +02:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/coinbase/rosetta-bitcoin/configuration"
|
|
|
|
mocks "github.com/coinbase/rosetta-bitcoin/mocks/services"
|
|
|
|
|
|
|
|
"github.com/coinbase/rosetta-sdk-go/types"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
|
|
)
|
|
|
|
|
|
|
|
func TestBlockService_Offline(t *testing.T) {
|
|
|
|
cfg := &configuration.Configuration{
|
|
|
|
Mode: configuration.Offline,
|
|
|
|
}
|
|
|
|
mockIndexer := &mocks.Indexer{}
|
|
|
|
servicer := NewBlockAPIService(cfg, mockIndexer)
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
block, err := servicer.Block(ctx, &types.BlockRequest{})
|
|
|
|
assert.Nil(t, block)
|
|
|
|
assert.Equal(t, ErrUnavailableOffline.Code, err.Code)
|
|
|
|
assert.Equal(t, ErrUnavailableOffline.Message, err.Message)
|
|
|
|
|
|
|
|
blockTransaction, err := servicer.BlockTransaction(ctx, &types.BlockTransactionRequest{})
|
|
|
|
assert.Nil(t, blockTransaction)
|
2020-10-27 20:42:58 +01:00
|
|
|
assert.Equal(t, ErrUnavailableOffline.Code, err.Code)
|
|
|
|
assert.Equal(t, ErrUnavailableOffline.Message, err.Message)
|
2020-09-16 21:03:14 +02:00
|
|
|
|
|
|
|
mockIndexer.AssertExpectations(t)
|
|
|
|
}
|
|
|
|
|
2020-10-27 20:42:58 +01:00
|
|
|
func TestBlockService_Online_Inline(t *testing.T) {
|
2020-09-16 21:03:14 +02:00
|
|
|
cfg := &configuration.Configuration{
|
|
|
|
Mode: configuration.Online,
|
|
|
|
}
|
|
|
|
mockIndexer := &mocks.Indexer{}
|
|
|
|
servicer := NewBlockAPIService(cfg, mockIndexer)
|
|
|
|
ctx := context.Background()
|
|
|
|
|
2020-10-27 19:14:53 +01:00
|
|
|
rawBlock := &types.Block{
|
2020-09-16 21:03:14 +02:00
|
|
|
BlockIdentifier: &types.BlockIdentifier{
|
|
|
|
Index: 100,
|
|
|
|
Hash: "block 100",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
transaction := &types.Transaction{
|
|
|
|
TransactionIdentifier: &types.TransactionIdentifier{
|
|
|
|
Hash: "tx1",
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2020-10-27 19:14:53 +01:00
|
|
|
block := &types.Block{
|
|
|
|
BlockIdentifier: &types.BlockIdentifier{
|
|
|
|
Index: 100,
|
|
|
|
Hash: "block 100",
|
|
|
|
},
|
|
|
|
Transactions: []*types.Transaction{
|
|
|
|
transaction,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
blockResponse := &types.BlockResponse{
|
|
|
|
Block: block,
|
|
|
|
}
|
|
|
|
|
2020-09-16 21:03:14 +02:00
|
|
|
t.Run("nil identifier", func(t *testing.T) {
|
|
|
|
mockIndexer.On(
|
|
|
|
"GetBlockLazy",
|
|
|
|
ctx,
|
|
|
|
(*types.PartialBlockIdentifier)(nil),
|
|
|
|
).Return(
|
2020-10-27 19:14:53 +01:00
|
|
|
&types.BlockResponse{
|
|
|
|
Block: rawBlock,
|
|
|
|
OtherTransactions: []*types.TransactionIdentifier{
|
|
|
|
{
|
|
|
|
Hash: "tx1",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
).Once()
|
|
|
|
mockIndexer.On(
|
|
|
|
"GetBlockTransaction",
|
|
|
|
ctx,
|
|
|
|
blockResponse.Block.BlockIdentifier,
|
|
|
|
transaction.TransactionIdentifier,
|
|
|
|
).Return(
|
|
|
|
transaction,
|
2020-09-16 21:03:14 +02:00
|
|
|
nil,
|
|
|
|
).Once()
|
|
|
|
b, err := servicer.Block(ctx, &types.BlockRequest{})
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, blockResponse, b)
|
|
|
|
})
|
|
|
|
|
|
|
|
t.Run("populated identifier", func(t *testing.T) {
|
|
|
|
pbIdentifier := types.ConstructPartialBlockIdentifier(block.BlockIdentifier)
|
2020-10-27 19:14:53 +01:00
|
|
|
mockIndexer.On(
|
|
|
|
"GetBlockLazy",
|
|
|
|
ctx,
|
|
|
|
pbIdentifier,
|
|
|
|
).Return(
|
|
|
|
&types.BlockResponse{
|
|
|
|
Block: rawBlock,
|
|
|
|
OtherTransactions: []*types.TransactionIdentifier{
|
|
|
|
{
|
|
|
|
Hash: "tx1",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
nil,
|
|
|
|
).Once()
|
2020-09-16 21:03:14 +02:00
|
|
|
mockIndexer.On(
|
|
|
|
"GetBlockTransaction",
|
|
|
|
ctx,
|
|
|
|
blockResponse.Block.BlockIdentifier,
|
|
|
|
transaction.TransactionIdentifier,
|
|
|
|
).Return(
|
|
|
|
transaction,
|
|
|
|
nil,
|
|
|
|
).Once()
|
2020-10-27 19:14:53 +01:00
|
|
|
b, err := servicer.Block(ctx, &types.BlockRequest{
|
|
|
|
BlockIdentifier: pbIdentifier,
|
2020-09-16 21:03:14 +02:00
|
|
|
})
|
|
|
|
assert.Nil(t, err)
|
2020-10-27 19:14:53 +01:00
|
|
|
assert.Equal(t, blockResponse, b)
|
2020-09-16 21:03:14 +02:00
|
|
|
})
|
|
|
|
|
|
|
|
mockIndexer.AssertExpectations(t)
|
|
|
|
}
|
2020-10-27 20:42:58 +01:00
|
|
|
|
|
|
|
func TestBlockService_Online_External(t *testing.T) {
|
|
|
|
cfg := &configuration.Configuration{
|
|
|
|
Mode: configuration.Online,
|
|
|
|
}
|
|
|
|
mockIndexer := &mocks.Indexer{}
|
|
|
|
servicer := NewBlockAPIService(cfg, mockIndexer)
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
blockResponse := &types.BlockResponse{
|
|
|
|
Block: &types.Block{
|
|
|
|
BlockIdentifier: &types.BlockIdentifier{
|
|
|
|
Index: 100,
|
|
|
|
Hash: "block 100",
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
otherTxs := []*types.TransactionIdentifier{}
|
|
|
|
for i := 0; i < 200; i++ {
|
|
|
|
otherTxs = append(otherTxs, &types.TransactionIdentifier{
|
|
|
|
Hash: fmt.Sprintf("tx%d", i),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
blockResponse.OtherTransactions = otherTxs
|
|
|
|
|
|
|
|
mockIndexer.On(
|
|
|
|
"GetBlockLazy",
|
|
|
|
ctx,
|
|
|
|
(*types.PartialBlockIdentifier)(nil),
|
|
|
|
).Return(
|
|
|
|
blockResponse,
|
|
|
|
nil,
|
|
|
|
).Once()
|
|
|
|
b, err := servicer.Block(ctx, &types.BlockRequest{})
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, blockResponse, b)
|
|
|
|
|
|
|
|
for _, otherTx := range b.OtherTransactions {
|
|
|
|
tx := &types.Transaction{
|
|
|
|
TransactionIdentifier: otherTx,
|
|
|
|
}
|
|
|
|
mockIndexer.On(
|
|
|
|
"GetBlockTransaction",
|
|
|
|
ctx,
|
|
|
|
blockResponse.Block.BlockIdentifier,
|
|
|
|
otherTx,
|
|
|
|
).Return(
|
|
|
|
tx,
|
|
|
|
nil,
|
|
|
|
).Once()
|
|
|
|
|
|
|
|
bTx, err := servicer.BlockTransaction(ctx, &types.BlockTransactionRequest{
|
|
|
|
BlockIdentifier: blockResponse.Block.BlockIdentifier,
|
|
|
|
TransactionIdentifier: otherTx,
|
|
|
|
})
|
|
|
|
assert.Nil(t, err)
|
|
|
|
assert.Equal(t, &types.BlockTransactionResponse{
|
|
|
|
Transaction: tx,
|
|
|
|
}, bTx)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
mockIndexer.AssertExpectations(t)
|
|
|
|
}
|