mirror of
https://github.com/tendermint/tendermint.git
synced 2026-05-28 10:00:21 +00:00
rpc/client: take context as first param (#5347)
Closes #5145 also applies to light/client
This commit is contained in:
@@ -9,6 +9,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
|
||||
- CLI/RPC/Config
|
||||
- [config] \#5315 Rename `prof_laddr` to `pprof_laddr` and move it to `rpc` section (@melekes)
|
||||
- [rpc] \#5315 Remove `/unsafe_start_cpu_profiler`, `/unsafe_stop_cpu_profiler` and `/unsafe_write_heap_profile`. Please use pprof functionality instead (@melekes)
|
||||
- [rpc/client, rpc/jsonrpc/client] \#5347 All client methods now accept `context.Context` as 1st param (@melekes)
|
||||
|
||||
- Apps
|
||||
|
||||
@@ -23,6 +24,7 @@ Friendly reminder, we have a [bug bounty program](https://hackerone.com/tendermi
|
||||
- [evidence] [\#5361](https://github.com/tendermint/tendermint/pull/5361) Add LightClientAttackEvidence and change evidence interface (@cmwaters)
|
||||
- [params] \#5319 Remove `ProofofTrialPeriod` from evidence params (@marbar3778)
|
||||
- [crypto/secp256k1] \#5280 `secp256k1` has been removed from the Tendermint repo. (@marbar3778)
|
||||
- [light] \#5347 `NewClient`, `NewHTTPClient`, `VerifyHeader` and `VerifyLightBlockAtHeight` now accept `context.Context` as 1st param (@melekes)
|
||||
- [state] \#5348 Define an Interface for the state store. (@marbar3778)
|
||||
|
||||
- Blockchain Protocol
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package debug
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
@@ -15,7 +16,7 @@ import (
|
||||
// dumpStatus gets node status state dump from the Tendermint RPC and writes it
|
||||
// to file. It returns an error upon failure.
|
||||
func dumpStatus(rpc *rpchttp.HTTP, dir, filename string) error {
|
||||
status, err := rpc.Status()
|
||||
status, err := rpc.Status(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get node status: %w", err)
|
||||
}
|
||||
@@ -26,7 +27,7 @@ func dumpStatus(rpc *rpchttp.HTTP, dir, filename string) error {
|
||||
// dumpNetInfo gets network information state dump from the Tendermint RPC and
|
||||
// writes it to file. It returns an error upon failure.
|
||||
func dumpNetInfo(rpc *rpchttp.HTTP, dir, filename string) error {
|
||||
netInfo, err := rpc.NetInfo()
|
||||
netInfo, err := rpc.NetInfo(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get node network information: %w", err)
|
||||
}
|
||||
@@ -37,7 +38,7 @@ func dumpNetInfo(rpc *rpchttp.HTTP, dir, filename string) error {
|
||||
// dumpConsensusState gets consensus state dump from the Tendermint RPC and
|
||||
// writes it to file. It returns an error upon failure.
|
||||
func dumpConsensusState(rpc *rpchttp.HTTP, dir, filename string) error {
|
||||
consDump, err := rpc.DumpConsensusState()
|
||||
consDump, err := rpc.DumpConsensusState(context.Background())
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get node consensus dump: %w", err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
@@ -36,7 +37,7 @@ that, it will present the same interface as a full Tendermint node.
|
||||
Furthermore to the chainID, a fresh instance of a light client will
|
||||
need a primary RPC address, a trusted hash and height and witness RPC addresses
|
||||
(if not using sequential verification). To restart the node, thereafter
|
||||
only the chainID is required.
|
||||
only the chainID is required.
|
||||
|
||||
`,
|
||||
RunE: runProxy,
|
||||
@@ -148,6 +149,7 @@ func runProxy(cmd *cobra.Command, args []string) error {
|
||||
var c *light.Client
|
||||
if trustedHeight > 0 && len(trustedHash) > 0 { // fresh installation
|
||||
c, err = light.NewHTTPClient(
|
||||
context.Background(),
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: trustingPeriod,
|
||||
|
||||
@@ -2,6 +2,7 @@ package light
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
@@ -151,6 +152,7 @@ type Client struct {
|
||||
//
|
||||
// See all Option(s) for the additional configuration.
|
||||
func NewClient(
|
||||
ctx context.Context,
|
||||
chainID string,
|
||||
trustOptions TrustOptions,
|
||||
primary provider.Provider,
|
||||
@@ -169,14 +171,14 @@ func NewClient(
|
||||
|
||||
if c.latestTrustedBlock != nil {
|
||||
c.logger.Info("Checking trusted light block using options")
|
||||
if err := c.checkTrustedHeaderUsingOptions(trustOptions); err != nil {
|
||||
if err := c.checkTrustedHeaderUsingOptions(ctx, trustOptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if c.latestTrustedBlock == nil || c.latestTrustedBlock.Height < trustOptions.Height {
|
||||
c.logger.Info("Downloading trusted light block using options")
|
||||
if err := c.initializeWithTrustOptions(trustOptions); err != nil {
|
||||
if err := c.initializeWithTrustOptions(ctx, trustOptions); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -277,11 +279,11 @@ func (c *Client) restoreTrustedLightBlock() error {
|
||||
//
|
||||
// The intuition here is the user is always right. I.e. if she decides to reset
|
||||
// the light client with an older header, there must be a reason for it.
|
||||
func (c *Client) checkTrustedHeaderUsingOptions(options TrustOptions) error {
|
||||
func (c *Client) checkTrustedHeaderUsingOptions(ctx context.Context, options TrustOptions) error {
|
||||
var primaryHash []byte
|
||||
switch {
|
||||
case options.Height > c.latestTrustedBlock.Height:
|
||||
h, err := c.lightBlockFromPrimary(c.latestTrustedBlock.Height)
|
||||
h, err := c.lightBlockFromPrimary(ctx, c.latestTrustedBlock.Height)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -336,9 +338,9 @@ func (c *Client) checkTrustedHeaderUsingOptions(options TrustOptions) error {
|
||||
|
||||
// initializeWithTrustOptions fetches the weakly-trusted light block from
|
||||
// primary provider.
|
||||
func (c *Client) initializeWithTrustOptions(options TrustOptions) error {
|
||||
func (c *Client) initializeWithTrustOptions(ctx context.Context, options TrustOptions) error {
|
||||
// 1) Fetch and verify the light block.
|
||||
l, err := c.lightBlockFromPrimary(options.Height)
|
||||
l, err := c.lightBlockFromPrimary(ctx, options.Height)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -405,7 +407,7 @@ func (c *Client) compareWithLatestHeight(height int64) (int64, error) {
|
||||
// Update attempts to advance the state by downloading the latest light
|
||||
// block and verifying it. It returns a new light block on a successful
|
||||
// update. Otherwise, it returns nil (plus an error, if any).
|
||||
func (c *Client) Update(now time.Time) (*types.LightBlock, error) {
|
||||
func (c *Client) Update(ctx context.Context, now time.Time) (*types.LightBlock, error) {
|
||||
lastTrustedHeight, err := c.LastTrustedHeight()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get last trusted height: %w", err)
|
||||
@@ -416,13 +418,13 @@ func (c *Client) Update(now time.Time) (*types.LightBlock, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
latestBlock, err := c.lightBlockFromPrimary(0)
|
||||
latestBlock, err := c.lightBlockFromPrimary(ctx, 0)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if latestBlock.Height > lastTrustedHeight {
|
||||
err = c.verifyLightBlock(latestBlock, now)
|
||||
err = c.verifyLightBlock(ctx, latestBlock, now)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -443,7 +445,7 @@ func (c *Client) Update(now time.Time) (*types.LightBlock, error) {
|
||||
// primary.
|
||||
//
|
||||
// It will replace the primary provider if an error from a request to the provider occurs
|
||||
func (c *Client) VerifyLightBlockAtHeight(height int64, now time.Time) (*types.LightBlock, error) {
|
||||
func (c *Client) VerifyLightBlockAtHeight(ctx context.Context, height int64, now time.Time) (*types.LightBlock, error) {
|
||||
if height <= 0 {
|
||||
return nil, errors.New("negative or zero height")
|
||||
}
|
||||
@@ -457,12 +459,12 @@ func (c *Client) VerifyLightBlockAtHeight(height int64, now time.Time) (*types.L
|
||||
}
|
||||
|
||||
// Request the light block from primary
|
||||
l, err := c.lightBlockFromPrimary(height)
|
||||
l, err := c.lightBlockFromPrimary(ctx, height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return l, c.verifyLightBlock(l, now)
|
||||
return l, c.verifyLightBlock(ctx, l, now)
|
||||
}
|
||||
|
||||
// VerifyHeader verifies a new header against the trusted state. It returns
|
||||
@@ -493,7 +495,7 @@ func (c *Client) VerifyLightBlockAtHeight(height int64, now time.Time) (*types.L
|
||||
// If, at any moment, a LightBlock is not found by the primary provider as part of
|
||||
// verification then the provider will be replaced by another and the process will
|
||||
// restart.
|
||||
func (c *Client) VerifyHeader(newHeader *types.Header, now time.Time) error {
|
||||
func (c *Client) VerifyHeader(ctx context.Context, newHeader *types.Header, now time.Time) error {
|
||||
if newHeader == nil {
|
||||
return errors.New("nil header")
|
||||
}
|
||||
@@ -514,7 +516,7 @@ func (c *Client) VerifyHeader(newHeader *types.Header, now time.Time) error {
|
||||
}
|
||||
|
||||
// Request the header and the vals.
|
||||
l, err = c.lightBlockFromPrimary(newHeader.Height)
|
||||
l, err = c.lightBlockFromPrimary(ctx, newHeader.Height)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to retrieve light block from primary to verify against: %w", err)
|
||||
}
|
||||
@@ -523,14 +525,14 @@ func (c *Client) VerifyHeader(newHeader *types.Header, now time.Time) error {
|
||||
return fmt.Errorf("light block header %X does not match newHeader %X", l.Hash(), newHeader.Hash())
|
||||
}
|
||||
|
||||
return c.verifyLightBlock(l, now)
|
||||
return c.verifyLightBlock(ctx, l, now)
|
||||
}
|
||||
|
||||
func (c *Client) verifyLightBlock(newLightBlock *types.LightBlock, now time.Time) error {
|
||||
func (c *Client) verifyLightBlock(ctx context.Context, newLightBlock *types.LightBlock, now time.Time) error {
|
||||
c.logger.Info("VerifyHeader", "height", newLightBlock.Height, "hash", hash2str(newLightBlock.Hash()))
|
||||
|
||||
var (
|
||||
verifyFunc func(trusted *types.LightBlock, new *types.LightBlock, now time.Time) error
|
||||
verifyFunc func(ctx context.Context, trusted *types.LightBlock, new *types.LightBlock, now time.Time) error
|
||||
err error
|
||||
)
|
||||
|
||||
@@ -551,7 +553,7 @@ func (c *Client) verifyLightBlock(newLightBlock *types.LightBlock, now time.Time
|
||||
switch {
|
||||
// Verifying forwards
|
||||
case newLightBlock.Height >= c.latestTrustedBlock.Height:
|
||||
err = verifyFunc(c.latestTrustedBlock, newLightBlock, now)
|
||||
err = verifyFunc(ctx, c.latestTrustedBlock, newLightBlock, now)
|
||||
|
||||
// Verifying backwards
|
||||
case newLightBlock.Height < firstBlockHeight:
|
||||
@@ -560,7 +562,7 @@ func (c *Client) verifyLightBlock(newLightBlock *types.LightBlock, now time.Time
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get first light block: %w", err)
|
||||
}
|
||||
err = c.backwards(firstBlock.Header, newLightBlock.Header)
|
||||
err = c.backwards(ctx, firstBlock.Header, newLightBlock.Header)
|
||||
|
||||
// Verifying between first and last trusted light block
|
||||
default:
|
||||
@@ -569,7 +571,7 @@ func (c *Client) verifyLightBlock(newLightBlock *types.LightBlock, now time.Time
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't get signed header before height %d: %w", newLightBlock.Height, err)
|
||||
}
|
||||
err = verifyFunc(closestBlock, newLightBlock, now)
|
||||
err = verifyFunc(ctx, closestBlock, newLightBlock, now)
|
||||
}
|
||||
if err != nil {
|
||||
c.logger.Error("Can't verify", "err", err)
|
||||
@@ -582,6 +584,7 @@ func (c *Client) verifyLightBlock(newLightBlock *types.LightBlock, now time.Time
|
||||
|
||||
// see VerifyHeader
|
||||
func (c *Client) verifySequential(
|
||||
ctx context.Context,
|
||||
trustedBlock *types.LightBlock,
|
||||
newLightBlock *types.LightBlock,
|
||||
now time.Time) error {
|
||||
@@ -597,7 +600,7 @@ func (c *Client) verifySequential(
|
||||
if height == newLightBlock.Height { // last light block
|
||||
interimBlock = newLightBlock
|
||||
} else { // intermediate light blocks
|
||||
interimBlock, err = c.lightBlockFromPrimary(height)
|
||||
interimBlock, err = c.lightBlockFromPrimary(ctx, height)
|
||||
if err != nil {
|
||||
return ErrVerificationFailed{From: verifiedBlock.Height, To: height, Reason: err}
|
||||
}
|
||||
@@ -633,7 +636,7 @@ func (c *Client) verifySequential(
|
||||
return err
|
||||
}
|
||||
|
||||
replacementBlock, fErr := c.lightBlockFromPrimary(newLightBlock.Height)
|
||||
replacementBlock, fErr := c.lightBlockFromPrimary(ctx, newLightBlock.Height)
|
||||
if fErr != nil {
|
||||
c.logger.Error("Can't fetch light block from primary", "err", fErr)
|
||||
// return original error
|
||||
@@ -672,6 +675,7 @@ func (c *Client) verifySequential(
|
||||
// light client tries again to verify the new light block in the middle, the light
|
||||
// client does not need to ask for all the same light blocks again.
|
||||
func (c *Client) verifySkipping(
|
||||
ctx context.Context,
|
||||
source provider.Provider,
|
||||
trustedBlock *types.LightBlock,
|
||||
newLightBlock *types.LightBlock,
|
||||
@@ -715,7 +719,7 @@ func (c *Client) verifySkipping(
|
||||
if depth == len(blockCache)-1 {
|
||||
pivotHeight := verifiedBlock.Height + (blockCache[depth].Height-verifiedBlock.
|
||||
Height)*verifySkippingNumerator/verifySkippingDenominator
|
||||
interimBlock, providerErr := source.LightBlock(pivotHeight)
|
||||
interimBlock, providerErr := source.LightBlock(ctx, pivotHeight)
|
||||
if providerErr != nil {
|
||||
return nil, ErrVerificationFailed{From: verifiedBlock.Height, To: pivotHeight, Reason: providerErr}
|
||||
}
|
||||
@@ -732,11 +736,12 @@ func (c *Client) verifySkipping(
|
||||
// verifySkippingAgainstPrimary does verifySkipping plus it compares new header with
|
||||
// witnesses and replaces primary if it sends the light client an invalid header
|
||||
func (c *Client) verifySkippingAgainstPrimary(
|
||||
ctx context.Context,
|
||||
trustedBlock *types.LightBlock,
|
||||
newLightBlock *types.LightBlock,
|
||||
now time.Time) error {
|
||||
|
||||
trace, err := c.verifySkipping(c.primary, trustedBlock, newLightBlock, now)
|
||||
trace, err := c.verifySkipping(ctx, c.primary, trustedBlock, newLightBlock, now)
|
||||
|
||||
switch errors.Unwrap(err).(type) {
|
||||
case ErrInvalidHeader:
|
||||
@@ -757,7 +762,7 @@ func (c *Client) verifySkippingAgainstPrimary(
|
||||
return err
|
||||
}
|
||||
|
||||
replacementBlock, fErr := c.lightBlockFromPrimary(newLightBlock.Height)
|
||||
replacementBlock, fErr := c.lightBlockFromPrimary(ctx, newLightBlock.Height)
|
||||
if fErr != nil {
|
||||
c.logger.Error("Can't fetch light block from primary", "err", fErr)
|
||||
// return original error
|
||||
@@ -773,14 +778,14 @@ func (c *Client) verifySkippingAgainstPrimary(
|
||||
}
|
||||
|
||||
// attempt to verify the header again
|
||||
return c.verifySkippingAgainstPrimary(trustedBlock, replacementBlock, now)
|
||||
return c.verifySkippingAgainstPrimary(ctx, trustedBlock, replacementBlock, now)
|
||||
case nil:
|
||||
// Compare header with the witnesses to ensure it's not a fork.
|
||||
// More witnesses we have, more chance to notice one.
|
||||
//
|
||||
// CORRECTNESS ASSUMPTION: there's at least 1 correct full node
|
||||
// (primary or one of the witnesses).
|
||||
if cmpErr := c.detectDivergence(trace, now); cmpErr != nil {
|
||||
if cmpErr := c.detectDivergence(ctx, trace, now); cmpErr != nil {
|
||||
return cmpErr
|
||||
}
|
||||
default:
|
||||
@@ -892,6 +897,7 @@ func (c *Client) updateTrustedLightBlock(l *types.LightBlock) error {
|
||||
// headers before a trusted header. If a sent header is invalid the primary is
|
||||
// replaced with another provider and the operation is repeated.
|
||||
func (c *Client) backwards(
|
||||
ctx context.Context,
|
||||
trustedHeader *types.Header,
|
||||
newHeader *types.Header) error {
|
||||
|
||||
@@ -901,7 +907,7 @@ func (c *Client) backwards(
|
||||
)
|
||||
|
||||
for verifiedHeader.Height > newHeader.Height {
|
||||
interimBlock, err := c.lightBlockFromPrimary(verifiedHeader.Height - 1)
|
||||
interimBlock, err := c.lightBlockFromPrimary(ctx, verifiedHeader.Height-1)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to obtain the header at height #%d: %w", verifiedHeader.Height-1, err)
|
||||
}
|
||||
@@ -960,9 +966,9 @@ func (c *Client) replacePrimaryProvider() error {
|
||||
// lightBlockFromPrimary retrieves the lightBlock from the primary provider
|
||||
// at the specified height. Handles dropout by the primary provider by swapping
|
||||
// with an alternative provider.
|
||||
func (c *Client) lightBlockFromPrimary(height int64) (*types.LightBlock, error) {
|
||||
func (c *Client) lightBlockFromPrimary(ctx context.Context, height int64) (*types.LightBlock, error) {
|
||||
c.providerMutex.Lock()
|
||||
l, err := c.primary.LightBlock(height)
|
||||
l, err := c.primary.LightBlock(ctx, height)
|
||||
c.providerMutex.Unlock()
|
||||
if err != nil {
|
||||
c.logger.Debug("Error on light block request from primary", "error", err)
|
||||
@@ -971,7 +977,7 @@ func (c *Client) lightBlockFromPrimary(height int64) (*types.LightBlock, error)
|
||||
return nil, fmt.Errorf("%v. Tried to replace primary but: %w", err.Error(), replaceErr)
|
||||
}
|
||||
// replace primary and request a light block again
|
||||
return c.lightBlockFromPrimary(height)
|
||||
return c.lightBlockFromPrimary(ctx, height)
|
||||
}
|
||||
return l, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package light_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -22,11 +23,12 @@ import (
|
||||
// Remember that none of these benchmarks account for network latency.
|
||||
var (
|
||||
benchmarkFullNode = mockp.New(genMockNode(chainID, 1000, 100, 1, bTime))
|
||||
genesisBlock, _ = benchmarkFullNode.LightBlock(1)
|
||||
genesisBlock, _ = benchmarkFullNode.LightBlock(context.Background(), 1)
|
||||
)
|
||||
|
||||
func BenchmarkSequence(b *testing.B) {
|
||||
c, err := light.NewClient(
|
||||
context.Background(),
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 24 * time.Hour,
|
||||
@@ -45,7 +47,7 @@ func BenchmarkSequence(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
_, err = c.VerifyLightBlockAtHeight(1000, bTime.Add(1000*time.Minute))
|
||||
_, err = c.VerifyLightBlockAtHeight(context.Background(), 1000, bTime.Add(1000*time.Minute))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -54,6 +56,7 @@ func BenchmarkSequence(b *testing.B) {
|
||||
|
||||
func BenchmarkBisection(b *testing.B) {
|
||||
c, err := light.NewClient(
|
||||
context.Background(),
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 24 * time.Hour,
|
||||
@@ -71,7 +74,7 @@ func BenchmarkBisection(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
_, err = c.VerifyLightBlockAtHeight(1000, bTime.Add(1000*time.Minute))
|
||||
_, err = c.VerifyLightBlockAtHeight(context.Background(), 1000, bTime.Add(1000*time.Minute))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
@@ -79,8 +82,9 @@ func BenchmarkBisection(b *testing.B) {
|
||||
}
|
||||
|
||||
func BenchmarkBackwards(b *testing.B) {
|
||||
trustedBlock, _ := benchmarkFullNode.LightBlock(0)
|
||||
trustedBlock, _ := benchmarkFullNode.LightBlock(context.Background(), 0)
|
||||
c, err := light.NewClient(
|
||||
context.Background(),
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 24 * time.Hour,
|
||||
@@ -98,7 +102,7 @@ func BenchmarkBackwards(b *testing.B) {
|
||||
b.ResetTimer()
|
||||
|
||||
for n := 0; n < b.N; n++ {
|
||||
_, err = c.VerifyLightBlockAtHeight(1, bTime)
|
||||
_, err = c.VerifyLightBlockAtHeight(context.Background(), 1, bTime)
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package light_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -23,6 +24,7 @@ const (
|
||||
)
|
||||
|
||||
var (
|
||||
ctx = context.Background()
|
||||
keys = genPrivKeys(4)
|
||||
vals = keys.ToValidators(20, 10)
|
||||
bTime, _ = time.Parse(time.RFC3339, "2006-01-02T15:04:05Z")
|
||||
@@ -111,7 +113,7 @@ func TestValidateTrustOptions(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMock(t *testing.T) {
|
||||
l, _ := fullNode.LightBlock(3)
|
||||
l, _ := fullNode.LightBlock(ctx, 3)
|
||||
assert.Equal(t, int64(3), l.Height)
|
||||
}
|
||||
|
||||
@@ -216,6 +218,7 @@ func TestClient_SequentialVerification(t *testing.T) {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
mockp.New(
|
||||
@@ -240,7 +243,7 @@ func TestClient_SequentialVerification(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = c.VerifyLightBlockAtHeight(3, bTime.Add(3*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 3, bTime.Add(3*time.Hour))
|
||||
if tc.verifyErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
@@ -340,6 +343,7 @@ func TestClient_SkippingVerification(t *testing.T) {
|
||||
tc := tc
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
mockp.New(
|
||||
@@ -363,7 +367,7 @@ func TestClient_SkippingVerification(t *testing.T) {
|
||||
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = c.VerifyLightBlockAtHeight(3, bTime.Add(3*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 3, bTime.Add(3*time.Hour))
|
||||
if tc.verifyErr {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
@@ -378,9 +382,10 @@ func TestClient_SkippingVerification(t *testing.T) {
|
||||
// the appropriate range
|
||||
func TestClientLargeBisectionVerification(t *testing.T) {
|
||||
veryLargeFullNode := mockp.New(genMockNode(chainID, 100, 3, 0, bTime))
|
||||
trustedLightBlock, err := veryLargeFullNode.LightBlock(5)
|
||||
trustedLightBlock, err := veryLargeFullNode.LightBlock(ctx, 5)
|
||||
require.NoError(t, err)
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Hour,
|
||||
@@ -393,15 +398,16 @@ func TestClientLargeBisectionVerification(t *testing.T) {
|
||||
light.SkippingVerification(light.DefaultTrustLevel),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
h, err := c.Update(bTime.Add(100 * time.Minute))
|
||||
h, err := c.Update(ctx, bTime.Add(100*time.Minute))
|
||||
assert.NoError(t, err)
|
||||
h2, err := veryLargeFullNode.LightBlock(100)
|
||||
h2, err := veryLargeFullNode.LightBlock(ctx, 100)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, h, h2)
|
||||
}
|
||||
|
||||
func TestClientBisectionBetweenTrustedHeaders(t *testing.T) {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Hour,
|
||||
@@ -415,7 +421,7 @@ func TestClientBisectionBetweenTrustedHeaders(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = c.VerifyLightBlockAtHeight(3, bTime.Add(2*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 3, bTime.Add(2*time.Hour))
|
||||
require.NoError(t, err)
|
||||
|
||||
// confirm that the client already doesn't have the light block
|
||||
@@ -423,12 +429,13 @@ func TestClientBisectionBetweenTrustedHeaders(t *testing.T) {
|
||||
require.Error(t, err)
|
||||
|
||||
// verify using bisection the light block between the two trusted light blocks
|
||||
_, err = c.VerifyLightBlockAtHeight(2, bTime.Add(1*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 2, bTime.Add(1*time.Hour))
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
func TestClient_Cleanup(t *testing.T) {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
fullNode,
|
||||
@@ -458,6 +465,7 @@ func TestClientRestoresTrustedHeaderAfterStartup1(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
fullNode,
|
||||
@@ -494,6 +502,7 @@ func TestClientRestoresTrustedHeaderAfterStartup1(t *testing.T) {
|
||||
)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Hour,
|
||||
@@ -525,6 +534,7 @@ func TestClientRestoresTrustedHeaderAfterStartup2(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Hour,
|
||||
@@ -570,6 +580,7 @@ func TestClientRestoresTrustedHeaderAfterStartup2(t *testing.T) {
|
||||
)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Hour,
|
||||
@@ -603,6 +614,7 @@ func TestClientRestoresTrustedHeaderAfterStartup3(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
fullNode,
|
||||
@@ -657,6 +669,7 @@ func TestClientRestoresTrustedHeaderAfterStartup3(t *testing.T) {
|
||||
)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Hour,
|
||||
@@ -686,6 +699,7 @@ func TestClientRestoresTrustedHeaderAfterStartup3(t *testing.T) {
|
||||
|
||||
func TestClient_Update(t *testing.T) {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
fullNode,
|
||||
@@ -696,7 +710,7 @@ func TestClient_Update(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// should result in downloading & verifying header #3
|
||||
l, err := c.Update(bTime.Add(2 * time.Hour))
|
||||
l, err := c.Update(ctx, bTime.Add(2*time.Hour))
|
||||
assert.NoError(t, err)
|
||||
if assert.NotNil(t, l) {
|
||||
assert.EqualValues(t, 3, l.Height)
|
||||
@@ -706,6 +720,7 @@ func TestClient_Update(t *testing.T) {
|
||||
|
||||
func TestClient_Concurrency(t *testing.T) {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
fullNode,
|
||||
@@ -715,7 +730,7 @@ func TestClient_Concurrency(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = c.VerifyLightBlockAtHeight(2, bTime.Add(2*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 2, bTime.Add(2*time.Hour))
|
||||
require.NoError(t, err)
|
||||
|
||||
var wg sync.WaitGroup
|
||||
@@ -746,6 +761,7 @@ func TestClient_Concurrency(t *testing.T) {
|
||||
|
||||
func TestClientReplacesPrimaryWithWitnessIfPrimaryIsUnavailable(t *testing.T) {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
deadNode,
|
||||
@@ -756,7 +772,7 @@ func TestClientReplacesPrimaryWithWitnessIfPrimaryIsUnavailable(t *testing.T) {
|
||||
)
|
||||
|
||||
require.NoError(t, err)
|
||||
_, err = c.Update(bTime.Add(2 * time.Hour))
|
||||
_, err = c.Update(ctx, bTime.Add(2*time.Hour))
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.NotEqual(t, c.Primary(), deadNode)
|
||||
@@ -765,8 +781,9 @@ func TestClientReplacesPrimaryWithWitnessIfPrimaryIsUnavailable(t *testing.T) {
|
||||
|
||||
func TestClient_BackwardsVerification(t *testing.T) {
|
||||
{
|
||||
trustHeader, _ := largeFullNode.LightBlock(6)
|
||||
trustHeader, _ := largeFullNode.LightBlock(ctx, 6)
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Minute,
|
||||
@@ -781,28 +798,28 @@ func TestClient_BackwardsVerification(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// 1) verify before the trusted header using backwards => expect no error
|
||||
h, err := c.VerifyLightBlockAtHeight(5, bTime.Add(6*time.Minute))
|
||||
h, err := c.VerifyLightBlockAtHeight(ctx, 5, bTime.Add(6*time.Minute))
|
||||
require.NoError(t, err)
|
||||
if assert.NotNil(t, h) {
|
||||
assert.EqualValues(t, 5, h.Height)
|
||||
}
|
||||
|
||||
// 2) untrusted header is expired but trusted header is not => expect no error
|
||||
h, err = c.VerifyLightBlockAtHeight(3, bTime.Add(8*time.Minute))
|
||||
h, err = c.VerifyLightBlockAtHeight(ctx, 3, bTime.Add(8*time.Minute))
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, h)
|
||||
|
||||
// 3) already stored headers should return the header without error
|
||||
h, err = c.VerifyLightBlockAtHeight(5, bTime.Add(6*time.Minute))
|
||||
h, err = c.VerifyLightBlockAtHeight(ctx, 5, bTime.Add(6*time.Minute))
|
||||
assert.NoError(t, err)
|
||||
assert.NotNil(t, h)
|
||||
|
||||
// 4a) First verify latest header
|
||||
_, err = c.VerifyLightBlockAtHeight(9, bTime.Add(9*time.Minute))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 9, bTime.Add(9*time.Minute))
|
||||
require.NoError(t, err)
|
||||
|
||||
// 4b) Verify backwards using bisection => expect no error
|
||||
_, err = c.VerifyLightBlockAtHeight(7, bTime.Add(9*time.Minute))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 7, bTime.Add(9*time.Minute))
|
||||
assert.NoError(t, err)
|
||||
// shouldn't have verified this header in the process
|
||||
_, err = c.TrustedLightBlock(8)
|
||||
@@ -810,7 +827,7 @@ func TestClient_BackwardsVerification(t *testing.T) {
|
||||
|
||||
// 5) Try bisection method, but closest header (at 7) has expired
|
||||
// so expect error
|
||||
_, err = c.VerifyLightBlockAtHeight(8, bTime.Add(12*time.Minute))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 8, bTime.Add(12*time.Minute))
|
||||
assert.Error(t, err)
|
||||
|
||||
}
|
||||
@@ -848,6 +865,7 @@ func TestClient_BackwardsVerification(t *testing.T) {
|
||||
|
||||
for idx, tc := range testCases {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 1 * time.Hour,
|
||||
@@ -861,7 +879,7 @@ func TestClient_BackwardsVerification(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err, idx)
|
||||
|
||||
_, err = c.VerifyLightBlockAtHeight(2, bTime.Add(1*time.Hour).Add(1*time.Second))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 2, bTime.Add(1*time.Hour).Add(1*time.Second))
|
||||
assert.Error(t, err, idx)
|
||||
}
|
||||
}
|
||||
@@ -917,10 +935,11 @@ func TestClientRemovesWitnessIfItSendsUsIncorrectHeader(t *testing.T) {
|
||||
},
|
||||
)
|
||||
|
||||
lb1, _ := badProvider1.LightBlock(2)
|
||||
lb1, _ := badProvider1.LightBlock(ctx, 2)
|
||||
require.NotEqual(t, lb1.Hash(), l1.Hash())
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
fullNode,
|
||||
@@ -934,14 +953,14 @@ func TestClientRemovesWitnessIfItSendsUsIncorrectHeader(t *testing.T) {
|
||||
assert.EqualValues(t, 2, len(c.Witnesses()))
|
||||
|
||||
// witness behaves incorrectly -> removed from list, no error
|
||||
l, err := c.VerifyLightBlockAtHeight(2, bTime.Add(2*time.Hour))
|
||||
l, err := c.VerifyLightBlockAtHeight(ctx, 2, bTime.Add(2*time.Hour))
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, len(c.Witnesses()))
|
||||
// light block should still be verified
|
||||
assert.EqualValues(t, 2, l.Height)
|
||||
|
||||
// remaining witnesses don't have light block -> error
|
||||
_, err = c.VerifyLightBlockAtHeight(3, bTime.Add(2*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 3, bTime.Add(2*time.Hour))
|
||||
if assert.Error(t, err) {
|
||||
assert.Equal(t, light.ErrFailedHeaderCrossReferencing, err)
|
||||
}
|
||||
@@ -970,6 +989,7 @@ func TestClient_TrustedValidatorSet(t *testing.T) {
|
||||
)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
fullNode,
|
||||
@@ -980,13 +1000,14 @@ func TestClient_TrustedValidatorSet(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, 2, len(c.Witnesses()))
|
||||
|
||||
_, err = c.VerifyLightBlockAtHeight(2, bTime.Add(2*time.Hour).Add(1*time.Second))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 2, bTime.Add(2*time.Hour).Add(1*time.Second))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(c.Witnesses()))
|
||||
}
|
||||
|
||||
func TestClientPrunesHeadersAndValidatorSets(t *testing.T) {
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
fullNode,
|
||||
@@ -999,7 +1020,7 @@ func TestClientPrunesHeadersAndValidatorSets(t *testing.T) {
|
||||
_, err = c.TrustedLightBlock(1)
|
||||
require.NoError(t, err)
|
||||
|
||||
h, err := c.Update(bTime.Add(2 * time.Hour))
|
||||
h, err := c.Update(ctx, bTime.Add(2*time.Hour))
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, int64(3), h.Height)
|
||||
|
||||
@@ -1059,6 +1080,7 @@ func TestClientEnsureValidHeadersAndValSets(t *testing.T) {
|
||||
tc.vals,
|
||||
)
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
badNode,
|
||||
@@ -1068,7 +1090,7 @@ func TestClientEnsureValidHeadersAndValSets(t *testing.T) {
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = c.VerifyLightBlockAtHeight(3, bTime.Add(2*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 3, bTime.Add(2*time.Hour))
|
||||
if tc.err {
|
||||
assert.Error(t, err)
|
||||
} else {
|
||||
|
||||
@@ -2,6 +2,7 @@ package light
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
@@ -25,7 +26,7 @@ import (
|
||||
//
|
||||
// If there are no conflictinge headers, the light client deems the verified target header
|
||||
// trusted and saves it to the trusted store.
|
||||
func (c *Client) detectDivergence(primaryTrace []*types.LightBlock, now time.Time) error {
|
||||
func (c *Client) detectDivergence(ctx context.Context, primaryTrace []*types.LightBlock, now time.Time) error {
|
||||
if primaryTrace == nil || len(primaryTrace) < 2 {
|
||||
return errors.New("nil or single block primary trace")
|
||||
}
|
||||
@@ -48,7 +49,7 @@ func (c *Client) detectDivergence(primaryTrace []*types.LightBlock, now time.Tim
|
||||
// and compare it with the header from the primary
|
||||
errc := make(chan error, len(c.witnesses))
|
||||
for i, witness := range c.witnesses {
|
||||
go c.compareNewHeaderWithWitness(errc, lastVerifiedHeader, witness, i)
|
||||
go c.compareNewHeaderWithWitness(ctx, errc, lastVerifiedHeader, witness, i)
|
||||
}
|
||||
|
||||
// handle errors from the header comparisons as they come in
|
||||
@@ -66,8 +67,13 @@ func (c *Client) detectDivergence(primaryTrace []*types.LightBlock, now time.Tim
|
||||
// We combine these actions together, verifying the witnesses headers and outputting the trace
|
||||
// which captures the bifurcation point and if successful provides the information to create
|
||||
supportingWitness := c.witnesses[e.WitnessIndex]
|
||||
witnessTrace, primaryBlock, err := c.examineConflictingHeaderAgainstTrace(primaryTrace, e.Block.SignedHeader,
|
||||
supportingWitness, now)
|
||||
witnessTrace, primaryBlock, err := c.examineConflictingHeaderAgainstTrace(
|
||||
ctx,
|
||||
primaryTrace,
|
||||
e.Block.SignedHeader,
|
||||
supportingWitness,
|
||||
now,
|
||||
)
|
||||
if err != nil {
|
||||
c.logger.Info("Error validating witness's divergent header", "witness", supportingWitness, "err", err)
|
||||
witnessesToRemove = append(witnessesToRemove, e.WitnessIndex)
|
||||
@@ -90,13 +96,18 @@ func (c *Client) detectDivergence(primaryTrace []*types.LightBlock, now time.Tim
|
||||
}
|
||||
c.logger.Error("Attack detected. Sending evidence againt primary by witness", "ev", ev,
|
||||
"primary", c.primary, "witness", supportingWitness)
|
||||
c.sendEvidence(ev, supportingWitness)
|
||||
c.sendEvidence(ctx, ev, supportingWitness)
|
||||
|
||||
// This may not be valid because the witness itself is at fault. So now we reverse it, examining the
|
||||
// trace provided by the witness and holding the primary as the source of truth. Note: primary may not
|
||||
// respond but this is okay as we will halt anyway.
|
||||
primaryTrace, witnessBlock, err := c.examineConflictingHeaderAgainstTrace(witnessTrace, primaryBlock.SignedHeader,
|
||||
c.primary, now)
|
||||
primaryTrace, witnessBlock, err := c.examineConflictingHeaderAgainstTrace(
|
||||
ctx,
|
||||
witnessTrace,
|
||||
primaryBlock.SignedHeader,
|
||||
c.primary,
|
||||
now,
|
||||
)
|
||||
if err != nil {
|
||||
c.logger.Info("Error validating primary's divergent header", "primary", c.primary, "err", err)
|
||||
continue
|
||||
@@ -117,7 +128,7 @@ func (c *Client) detectDivergence(primaryTrace []*types.LightBlock, now time.Tim
|
||||
}
|
||||
c.logger.Error("Sending evidence against witness by primary", "ev", ev,
|
||||
"primary", c.primary, "witness", supportingWitness)
|
||||
c.sendEvidence(ev, c.primary)
|
||||
c.sendEvidence(ctx, ev, c.primary)
|
||||
// We return the error and don't process anymore witnesses
|
||||
return e
|
||||
|
||||
@@ -154,10 +165,10 @@ func (c *Client) detectDivergence(primaryTrace []*types.LightBlock, now time.Tim
|
||||
// 2: errBadWitness -> the witness has either not responded, doesn't have the header or has given us an invalid one
|
||||
// Note: In the case of an invalid header we remove the witness
|
||||
// 3: nil -> the hashes of the two headers match
|
||||
func (c *Client) compareNewHeaderWithWitness(errc chan error, h *types.SignedHeader,
|
||||
func (c *Client) compareNewHeaderWithWitness(ctx context.Context, errc chan error, h *types.SignedHeader,
|
||||
witness provider.Provider, witnessIndex int) {
|
||||
|
||||
lightBlock, err := witness.LightBlock(h.Height)
|
||||
lightBlock, err := witness.LightBlock(ctx, h.Height)
|
||||
if err != nil {
|
||||
errc <- errBadWitness{Reason: err, WitnessIndex: witnessIndex}
|
||||
return
|
||||
@@ -172,8 +183,8 @@ func (c *Client) compareNewHeaderWithWitness(errc chan error, h *types.SignedHea
|
||||
}
|
||||
|
||||
// sendEvidence sends evidence to a provider on a best effort basis.
|
||||
func (c *Client) sendEvidence(ev *types.LightClientAttackEvidence, receiver provider.Provider) {
|
||||
err := receiver.ReportEvidence(ev)
|
||||
func (c *Client) sendEvidence(ctx context.Context, ev *types.LightClientAttackEvidence, receiver provider.Provider) {
|
||||
err := receiver.ReportEvidence(ctx, ev)
|
||||
if err != nil {
|
||||
c.logger.Error("Failed to report evidence to provider", "ev", ev, "provider", receiver)
|
||||
}
|
||||
@@ -188,6 +199,7 @@ func (c *Client) sendEvidence(ev *types.LightClientAttackEvidence, receiver prov
|
||||
// 2. The source stops responding, doesn't have the block or sends an invalid header in which case we
|
||||
// return the error and remove the witness
|
||||
func (c *Client) examineConflictingHeaderAgainstTrace(
|
||||
ctx context.Context,
|
||||
trace []*types.LightBlock,
|
||||
divergentHeader *types.SignedHeader,
|
||||
source provider.Provider, now time.Time) ([]*types.LightBlock, *types.LightBlock, error) {
|
||||
@@ -197,7 +209,7 @@ func (c *Client) examineConflictingHeaderAgainstTrace(
|
||||
for idx, traceBlock := range trace {
|
||||
// The first block in the trace MUST be the same to the light block that the source produces
|
||||
// else we cannot continue with verification.
|
||||
sourceBlock, err := source.LightBlock(traceBlock.Height)
|
||||
sourceBlock, err := source.LightBlock(ctx, traceBlock.Height)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
@@ -213,7 +225,7 @@ func (c *Client) examineConflictingHeaderAgainstTrace(
|
||||
|
||||
// we check that the source provider can verify a block at the same height of the
|
||||
// intermediate height
|
||||
trace, err := c.verifySkipping(source, previouslyVerifiedBlock, sourceBlock, now)
|
||||
trace, err := c.verifySkipping(ctx, source, previouslyVerifiedBlock, sourceBlock, now)
|
||||
if err != nil {
|
||||
return nil, nil, fmt.Errorf("verifySkipping of conflicting header failed: %w", err)
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ func TestLightClientAttackEvidence_Lunatic(t *testing.T) {
|
||||
primary := mockp.New(chainID, primaryHeaders, primaryValidators)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Hour,
|
||||
@@ -60,7 +61,7 @@ func TestLightClientAttackEvidence_Lunatic(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check verification returns an error.
|
||||
_, err = c.VerifyLightBlockAtHeight(10, bTime.Add(1*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 10, bTime.Add(1*time.Hour))
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "does not match primary")
|
||||
}
|
||||
@@ -118,6 +119,7 @@ func TestLightClientAttackEvidence_Equivocation(t *testing.T) {
|
||||
primary := mockp.New(chainID, primaryHeaders, primaryValidators)
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 4 * time.Hour,
|
||||
@@ -133,7 +135,7 @@ func TestLightClientAttackEvidence_Equivocation(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// Check verification returns an error.
|
||||
_, err = c.VerifyLightBlockAtHeight(10, bTime.Add(1*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 10, bTime.Add(1*time.Hour))
|
||||
if assert.Error(t, err) {
|
||||
assert.Contains(t, err.Error(), "does not match primary")
|
||||
}
|
||||
@@ -162,11 +164,12 @@ func TestLightClientAttackEvidence_Equivocation(t *testing.T) {
|
||||
|
||||
func TestClientDivergentTraces(t *testing.T) {
|
||||
primary := mockp.New(genMockNode(chainID, 10, 5, 2, bTime))
|
||||
firstBlock, err := primary.LightBlock(1)
|
||||
firstBlock, err := primary.LightBlock(ctx, 1)
|
||||
require.NoError(t, err)
|
||||
witness := mockp.New(genMockNode(chainID, 10, 5, 2, bTime))
|
||||
|
||||
c, err := light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Height: 1,
|
||||
@@ -183,7 +186,7 @@ func TestClientDivergentTraces(t *testing.T) {
|
||||
|
||||
// 1. Different nodes therefore a divergent header is produced but the
|
||||
// light client can't verify it because it has a different trusted header.
|
||||
_, err = c.VerifyLightBlockAtHeight(10, bTime.Add(1*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 10, bTime.Add(1*time.Hour))
|
||||
assert.Error(t, err)
|
||||
assert.Equal(t, 0, len(c.Witnesses()))
|
||||
|
||||
@@ -191,6 +194,7 @@ func TestClientDivergentTraces(t *testing.T) {
|
||||
// verification should be successful and all the witnesses should remain
|
||||
|
||||
c, err = light.NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Height: 1,
|
||||
@@ -204,7 +208,7 @@ func TestClientDivergentTraces(t *testing.T) {
|
||||
light.MaxRetryAttempts(1),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
_, err = c.VerifyLightBlockAtHeight(10, bTime.Add(1*time.Hour))
|
||||
_, err = c.VerifyLightBlockAtHeight(ctx, 10, bTime.Add(1*time.Hour))
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 3, len(c.Witnesses()))
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package light_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
stdlog "log"
|
||||
@@ -40,7 +41,7 @@ func ExampleClient_Update() {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
|
||||
block, err := primary.LightBlock(2)
|
||||
block, err := primary.LightBlock(context.Background(), 2)
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
@@ -51,6 +52,7 @@ func ExampleClient_Update() {
|
||||
}
|
||||
|
||||
c, err := light.NewClient(
|
||||
context.Background(),
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 504 * time.Hour, // 21 days
|
||||
@@ -77,7 +79,7 @@ func ExampleClient_Update() {
|
||||
// monotonic component (see types/time/time.go) b) single instance is being
|
||||
// run.
|
||||
// https://github.com/tendermint/tendermint/issues/4489
|
||||
h, err := c.Update(time.Now().Add(30 * time.Minute))
|
||||
h, err := c.Update(context.Background(), time.Now().Add(30*time.Minute))
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
@@ -111,7 +113,7 @@ func ExampleClient_VerifyLightBlockAtHeight() {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
|
||||
block, err := primary.LightBlock(2)
|
||||
block, err := primary.LightBlock(context.Background(), 2)
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
@@ -122,6 +124,7 @@ func ExampleClient_VerifyLightBlockAtHeight() {
|
||||
}
|
||||
|
||||
c, err := light.NewClient(
|
||||
context.Background(),
|
||||
chainID,
|
||||
light.TrustOptions{
|
||||
Period: 504 * time.Hour, // 21 days
|
||||
@@ -142,7 +145,7 @@ func ExampleClient_VerifyLightBlockAtHeight() {
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = c.VerifyLightBlockAtHeight(3, time.Now())
|
||||
_, err = c.VerifyLightBlockAtHeight(context.Background(), 3, time.Now())
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package http
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"regexp"
|
||||
@@ -61,18 +62,18 @@ func (p *http) String() string {
|
||||
|
||||
// LightBlock fetches a LightBlock at the given height and checks the
|
||||
// chainID matches.
|
||||
func (p *http) LightBlock(height int64) (*types.LightBlock, error) {
|
||||
func (p *http) LightBlock(ctx context.Context, height int64) (*types.LightBlock, error) {
|
||||
h, err := validateHeight(height)
|
||||
if err != nil {
|
||||
return nil, provider.ErrBadLightBlock{Reason: err}
|
||||
}
|
||||
|
||||
sh, err := p.signedHeader(h)
|
||||
sh, err := p.signedHeader(ctx, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
vs, err := p.validatorSet(h)
|
||||
vs, err := p.validatorSet(ctx, h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -91,12 +92,12 @@ func (p *http) LightBlock(height int64) (*types.LightBlock, error) {
|
||||
}
|
||||
|
||||
// ReportEvidence calls `/broadcast_evidence` endpoint.
|
||||
func (p *http) ReportEvidence(ev types.Evidence) error {
|
||||
_, err := p.client.BroadcastEvidence(ev)
|
||||
func (p *http) ReportEvidence(ctx context.Context, ev types.Evidence) error {
|
||||
_, err := p.client.BroadcastEvidence(ctx, ev)
|
||||
return err
|
||||
}
|
||||
|
||||
func (p *http) validatorSet(height *int64) (*types.ValidatorSet, error) {
|
||||
func (p *http) validatorSet(ctx context.Context, height *int64) (*types.ValidatorSet, error) {
|
||||
var (
|
||||
maxPerPage = 100
|
||||
vals = []*types.Validator{}
|
||||
@@ -105,7 +106,7 @@ func (p *http) validatorSet(height *int64) (*types.ValidatorSet, error) {
|
||||
|
||||
for len(vals)%maxPerPage == 0 {
|
||||
for attempt := 1; attempt <= maxRetryAttempts; attempt++ {
|
||||
res, err := p.client.Validators(height, &page, &maxPerPage)
|
||||
res, err := p.client.Validators(ctx, height, &page, &maxPerPage)
|
||||
if err != nil {
|
||||
// TODO: standardize errors on the RPC side
|
||||
if regexpMissingHeight.MatchString(err.Error()) {
|
||||
@@ -138,9 +139,9 @@ func (p *http) validatorSet(height *int64) (*types.ValidatorSet, error) {
|
||||
return valSet, nil
|
||||
}
|
||||
|
||||
func (p *http) signedHeader(height *int64) (*types.SignedHeader, error) {
|
||||
func (p *http) signedHeader(ctx context.Context, height *int64) (*types.SignedHeader, error) {
|
||||
for attempt := 1; attempt <= maxRetryAttempts; attempt++ {
|
||||
commit, err := p.client.Commit(height)
|
||||
commit, err := p.client.Commit(ctx, height)
|
||||
if err != nil {
|
||||
// TODO: standardize errors on the RPC side
|
||||
if regexpMissingHeight.MatchString(err.Error()) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package http_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
@@ -65,7 +66,7 @@ func TestProvider(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// let's get the highest block
|
||||
sh, err := p.LightBlock(0)
|
||||
sh, err := p.LightBlock(context.Background(), 0)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, sh.Height < 1000)
|
||||
|
||||
@@ -74,16 +75,16 @@ func TestProvider(t *testing.T) {
|
||||
|
||||
// historical queries now work :)
|
||||
lower := sh.Height - 3
|
||||
sh, err = p.LightBlock(lower)
|
||||
sh, err = p.LightBlock(context.Background(), lower)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, lower, sh.Height)
|
||||
|
||||
// fetching missing heights (both future and pruned) should return appropriate errors
|
||||
_, err = p.LightBlock(1000)
|
||||
_, err = p.LightBlock(context.Background(), 1000)
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, provider.ErrLightBlockNotFound, err)
|
||||
|
||||
_, err = p.LightBlock(1)
|
||||
_, err = p.LightBlock(context.Background(), 1)
|
||||
require.Error(t, err)
|
||||
assert.Equal(t, provider.ErrLightBlockNotFound, err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/tendermint/tendermint/light/provider"
|
||||
@@ -22,10 +23,10 @@ func (p *deadMock) ChainID() string { return p.chainID }
|
||||
|
||||
func (p *deadMock) String() string { return "deadMock" }
|
||||
|
||||
func (p *deadMock) LightBlock(height int64) (*types.LightBlock, error) {
|
||||
func (p *deadMock) LightBlock(_ context.Context, height int64) (*types.LightBlock, error) {
|
||||
return nil, errNoResp
|
||||
}
|
||||
|
||||
func (p *deadMock) ReportEvidence(ev types.Evidence) error {
|
||||
func (p *deadMock) ReportEvidence(_ context.Context, ev types.Evidence) error {
|
||||
return errNoResp
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
@@ -48,7 +49,7 @@ func (p *Mock) String() string {
|
||||
return fmt.Sprintf("Mock{headers: %s, vals: %v}", headers.String(), vals.String())
|
||||
}
|
||||
|
||||
func (p *Mock) LightBlock(height int64) (*types.LightBlock, error) {
|
||||
func (p *Mock) LightBlock(_ context.Context, height int64) (*types.LightBlock, error) {
|
||||
var lb *types.LightBlock
|
||||
if height == 0 && len(p.headers) > 0 {
|
||||
sh := p.headers[int64(len(p.headers))]
|
||||
@@ -79,7 +80,7 @@ func (p *Mock) LightBlock(height int64) (*types.LightBlock, error) {
|
||||
return lb, nil
|
||||
}
|
||||
|
||||
func (p *Mock) ReportEvidence(ev types.Evidence) error {
|
||||
func (p *Mock) ReportEvidence(_ context.Context, ev types.Evidence) error {
|
||||
p.evidenceToReport[string(ev.Hash())] = ev
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package provider
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
@@ -20,8 +22,8 @@ type Provider interface {
|
||||
// issues, an error will be returned.
|
||||
// If there's no LightBlock for the given height, ErrLightBlockNotFound
|
||||
// error is returned.
|
||||
LightBlock(height int64) (*types.LightBlock, error)
|
||||
LightBlock(ctx context.Context, height int64) (*types.LightBlock, error)
|
||||
|
||||
// ReportEvidence reports an evidence of misbehavior.
|
||||
ReportEvidence(ev types.Evidence) error
|
||||
ReportEvidence(context.Context, types.Evidence) error
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ type rpcHealthFunc func(ctx *rpctypes.Context) (*ctypes.ResultHealth, error)
|
||||
|
||||
func makeHealthFunc(c *lrpc.Client) rpcHealthFunc {
|
||||
return func(ctx *rpctypes.Context) (*ctypes.ResultHealth, error) {
|
||||
return c.Health()
|
||||
return c.Health(ctx.Context())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ type rpcStatusFunc func(ctx *rpctypes.Context) (*ctypes.ResultStatus, error)
|
||||
// nolint: interfacer
|
||||
func makeStatusFunc(c *lrpc.Client) rpcStatusFunc {
|
||||
return func(ctx *rpctypes.Context) (*ctypes.ResultStatus, error) {
|
||||
return c.Status()
|
||||
return c.Status(ctx.Context())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ type rpcNetInfoFunc func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*ct
|
||||
|
||||
func makeNetInfoFunc(c *lrpc.Client) rpcNetInfoFunc {
|
||||
return func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*ctypes.ResultNetInfo, error) {
|
||||
return c.NetInfo()
|
||||
return c.NetInfo(ctx.Context())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ type rpcBlockchainInfoFunc func(ctx *rpctypes.Context, minHeight, maxHeight int6
|
||||
|
||||
func makeBlockchainInfoFunc(c *lrpc.Client) rpcBlockchainInfoFunc {
|
||||
return func(ctx *rpctypes.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||
return c.BlockchainInfo(minHeight, maxHeight)
|
||||
return c.BlockchainInfo(ctx.Context(), minHeight, maxHeight)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ type rpcGenesisFunc func(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error)
|
||||
|
||||
func makeGenesisFunc(c *lrpc.Client) rpcGenesisFunc {
|
||||
return func(ctx *rpctypes.Context) (*ctypes.ResultGenesis, error) {
|
||||
return c.Genesis()
|
||||
return c.Genesis(ctx.Context())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ type rpcBlockFunc func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultBloc
|
||||
|
||||
func makeBlockFunc(c *lrpc.Client) rpcBlockFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultBlock, error) {
|
||||
return c.Block(height)
|
||||
return c.Block(ctx.Context(), height)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ type rpcBlockByHashFunc func(ctx *rpctypes.Context, hash []byte) (*ctypes.Result
|
||||
|
||||
func makeBlockByHashFunc(c *lrpc.Client) rpcBlockByHashFunc {
|
||||
return func(ctx *rpctypes.Context, hash []byte) (*ctypes.ResultBlock, error) {
|
||||
return c.BlockByHash(hash)
|
||||
return c.BlockByHash(ctx.Context(), hash)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ type rpcBlockResultsFunc func(ctx *rpctypes.Context, height *int64) (*ctypes.Res
|
||||
|
||||
func makeBlockResultsFunc(c *lrpc.Client) rpcBlockResultsFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultBlockResults, error) {
|
||||
return c.BlockResults(height)
|
||||
return c.BlockResults(ctx.Context(), height)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ type rpcCommitFunc func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultCom
|
||||
|
||||
func makeCommitFunc(c *lrpc.Client) rpcCommitFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultCommit, error) {
|
||||
return c.Commit(height)
|
||||
return c.Commit(ctx.Context(), height)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ type rpcTxFunc func(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.Res
|
||||
|
||||
func makeTxFunc(c *lrpc.Client) rpcTxFunc {
|
||||
return func(ctx *rpctypes.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
return c.Tx(hash, prove)
|
||||
return c.Tx(ctx.Context(), hash, prove)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ type rpcTxSearchFunc func(ctx *rpctypes.Context, query string, prove bool,
|
||||
func makeTxSearchFunc(c *lrpc.Client) rpcTxSearchFunc {
|
||||
return func(ctx *rpctypes.Context, query string, prove bool, page, perPage *int, orderBy string) (
|
||||
*ctypes.ResultTxSearch, error) {
|
||||
return c.TxSearch(query, prove, page, perPage, orderBy)
|
||||
return c.TxSearch(ctx.Context(), query, prove, page, perPage, orderBy)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ type rpcValidatorsFunc func(ctx *rpctypes.Context, height *int64,
|
||||
|
||||
func makeValidatorsFunc(c *lrpc.Client) rpcValidatorsFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
|
||||
return c.Validators(height, page, perPage)
|
||||
return c.Validators(ctx.Context(), height, page, perPage)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -153,7 +153,7 @@ type rpcDumpConsensusStateFunc func(ctx *rpctypes.Context) (*ctypes.ResultDumpCo
|
||||
|
||||
func makeDumpConsensusStateFunc(c *lrpc.Client) rpcDumpConsensusStateFunc {
|
||||
return func(ctx *rpctypes.Context) (*ctypes.ResultDumpConsensusState, error) {
|
||||
return c.DumpConsensusState()
|
||||
return c.DumpConsensusState(ctx.Context())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,7 +161,7 @@ type rpcConsensusStateFunc func(ctx *rpctypes.Context) (*ctypes.ResultConsensusS
|
||||
|
||||
func makeConsensusStateFunc(c *lrpc.Client) rpcConsensusStateFunc {
|
||||
return func(ctx *rpctypes.Context) (*ctypes.ResultConsensusState, error) {
|
||||
return c.ConsensusState()
|
||||
return c.ConsensusState(ctx.Context())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,7 +169,7 @@ type rpcConsensusParamsFunc func(ctx *rpctypes.Context, height *int64) (*ctypes.
|
||||
|
||||
func makeConsensusParamsFunc(c *lrpc.Client) rpcConsensusParamsFunc {
|
||||
return func(ctx *rpctypes.Context, height *int64) (*ctypes.ResultConsensusParams, error) {
|
||||
return c.ConsensusParams(height)
|
||||
return c.ConsensusParams(ctx.Context(), height)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,7 +177,7 @@ type rpcUnconfirmedTxsFunc func(ctx *rpctypes.Context, limit *int) (*ctypes.Resu
|
||||
|
||||
func makeUnconfirmedTxsFunc(c *lrpc.Client) rpcUnconfirmedTxsFunc {
|
||||
return func(ctx *rpctypes.Context, limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return c.UnconfirmedTxs(limit)
|
||||
return c.UnconfirmedTxs(ctx.Context(), limit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ type rpcNumUnconfirmedTxsFunc func(ctx *rpctypes.Context) (*ctypes.ResultUnconfi
|
||||
|
||||
func makeNumUnconfirmedTxsFunc(c *lrpc.Client) rpcNumUnconfirmedTxsFunc {
|
||||
return func(ctx *rpctypes.Context) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return c.NumUnconfirmedTxs()
|
||||
return c.NumUnconfirmedTxs(ctx.Context())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ type rpcBroadcastTxCommitFunc func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.
|
||||
|
||||
func makeBroadcastTxCommitFunc(c *lrpc.Client) rpcBroadcastTxCommitFunc {
|
||||
return func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
return c.BroadcastTxCommit(tx)
|
||||
return c.BroadcastTxCommit(ctx.Context(), tx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ type rpcBroadcastTxSyncFunc func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.Re
|
||||
|
||||
func makeBroadcastTxSyncFunc(c *lrpc.Client) rpcBroadcastTxSyncFunc {
|
||||
return func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.BroadcastTxSync(tx)
|
||||
return c.BroadcastTxSync(ctx.Context(), tx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -209,7 +209,7 @@ type rpcBroadcastTxAsyncFunc func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.R
|
||||
|
||||
func makeBroadcastTxAsyncFunc(c *lrpc.Client) rpcBroadcastTxAsyncFunc {
|
||||
return func(ctx *rpctypes.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.BroadcastTxAsync(tx)
|
||||
return c.BroadcastTxAsync(ctx.Context(), tx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ type rpcABCIQueryFunc func(ctx *rpctypes.Context, path string, data bytes.HexByt
|
||||
|
||||
func makeABCIQueryFunc(c *lrpc.Client) rpcABCIQueryFunc {
|
||||
return func(ctx *rpctypes.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQuery(path, data)
|
||||
return c.ABCIQuery(ctx.Context(), path, data)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ type rpcABCIInfoFunc func(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error)
|
||||
|
||||
func makeABCIInfoFunc(c *lrpc.Client) rpcABCIInfoFunc {
|
||||
return func(ctx *rpctypes.Context) (*ctypes.ResultABCIInfo, error) {
|
||||
return c.ABCIInfo()
|
||||
return c.ABCIInfo(ctx.Context())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,6 +234,6 @@ type rpcBroadcastEvidenceFunc func(ctx *rpctypes.Context, ev types.Evidence) (*c
|
||||
// nolint: interfacer
|
||||
func makeBroadcastEvidenceFunc(c *lrpc.Client) rpcBroadcastEvidenceFunc {
|
||||
return func(ctx *rpctypes.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
return c.BroadcastEvidence(ev)
|
||||
return c.BroadcastEvidence(ctx.Context(), ev)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,24 +61,24 @@ func (c *Client) OnStop() {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) Status() (*ctypes.ResultStatus, error) {
|
||||
return c.next.Status()
|
||||
func (c *Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
|
||||
return c.next.Status(ctx)
|
||||
}
|
||||
|
||||
func (c *Client) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
return c.next.ABCIInfo()
|
||||
func (c *Client) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
|
||||
return c.next.ABCIInfo(ctx)
|
||||
}
|
||||
|
||||
func (c *Client) ABCIQuery(path string, data tmbytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQueryWithOptions(path, data, rpcclient.DefaultABCIQueryOptions)
|
||||
func (c *Client) ABCIQuery(ctx context.Context, path string, data tmbytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.DefaultABCIQueryOptions)
|
||||
}
|
||||
|
||||
// GetWithProofOptions is useful if you want full access to the ABCIQueryOptions.
|
||||
// XXX Usage of path? It's not used, and sometimes it's /, sometimes /key, sometimes /store.
|
||||
func (c *Client) ABCIQueryWithOptions(path string, data tmbytes.HexBytes,
|
||||
func (c *Client) ABCIQueryWithOptions(ctx context.Context, path string, data tmbytes.HexBytes,
|
||||
opts rpcclient.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
|
||||
res, err := c.next.ABCIQueryWithOptions(path, data, opts)
|
||||
res, err := c.next.ABCIQueryWithOptions(ctx, path, data, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -97,7 +97,7 @@ func (c *Client) ABCIQueryWithOptions(path string, data tmbytes.HexBytes,
|
||||
|
||||
// Update the light client if we're behind.
|
||||
// NOTE: AppHash for height H is in header H+1.
|
||||
l, err := c.updateLightClientIfNeededTo(resp.Height + 1)
|
||||
l, err := c.updateLightClientIfNeededTo(ctx, resp.Height+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -129,44 +129,44 @@ func (c *Client) ABCIQueryWithOptions(path string, data tmbytes.HexBytes,
|
||||
return &ctypes.ResultABCIQuery{Response: resp}, nil
|
||||
}
|
||||
|
||||
func (c *Client) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
return c.next.BroadcastTxCommit(tx)
|
||||
func (c *Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
return c.next.BroadcastTxCommit(ctx, tx)
|
||||
}
|
||||
|
||||
func (c *Client) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.next.BroadcastTxAsync(tx)
|
||||
func (c *Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.next.BroadcastTxAsync(ctx, tx)
|
||||
}
|
||||
|
||||
func (c *Client) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.next.BroadcastTxSync(tx)
|
||||
func (c *Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.next.BroadcastTxSync(ctx, tx)
|
||||
}
|
||||
|
||||
func (c *Client) UnconfirmedTxs(limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return c.next.UnconfirmedTxs(limit)
|
||||
func (c *Client) UnconfirmedTxs(ctx context.Context, limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return c.next.UnconfirmedTxs(ctx, limit)
|
||||
}
|
||||
|
||||
func (c *Client) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return c.next.NumUnconfirmedTxs()
|
||||
func (c *Client) NumUnconfirmedTxs(ctx context.Context) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return c.next.NumUnconfirmedTxs(ctx)
|
||||
}
|
||||
|
||||
func (c *Client) CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error) {
|
||||
return c.next.CheckTx(tx)
|
||||
func (c *Client) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) {
|
||||
return c.next.CheckTx(ctx, tx)
|
||||
}
|
||||
|
||||
func (c *Client) NetInfo() (*ctypes.ResultNetInfo, error) {
|
||||
return c.next.NetInfo()
|
||||
func (c *Client) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) {
|
||||
return c.next.NetInfo(ctx)
|
||||
}
|
||||
|
||||
func (c *Client) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
||||
return c.next.DumpConsensusState()
|
||||
func (c *Client) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) {
|
||||
return c.next.DumpConsensusState(ctx)
|
||||
}
|
||||
|
||||
func (c *Client) ConsensusState() (*ctypes.ResultConsensusState, error) {
|
||||
return c.next.ConsensusState()
|
||||
func (c *Client) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) {
|
||||
return c.next.ConsensusState(ctx)
|
||||
}
|
||||
|
||||
func (c *Client) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error) {
|
||||
res, err := c.next.ConsensusParams(height)
|
||||
func (c *Client) ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error) {
|
||||
res, err := c.next.ConsensusParams(ctx, height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -180,7 +180,7 @@ func (c *Client) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams,
|
||||
}
|
||||
|
||||
// Update the light client if we're behind.
|
||||
l, err := c.updateLightClientIfNeededTo(res.BlockHeight)
|
||||
l, err := c.updateLightClientIfNeededTo(ctx, res.BlockHeight)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -194,14 +194,14 @@ func (c *Client) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams,
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) Health() (*ctypes.ResultHealth, error) {
|
||||
return c.next.Health()
|
||||
func (c *Client) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
|
||||
return c.next.Health(ctx)
|
||||
}
|
||||
|
||||
// BlockchainInfo calls rpcclient#BlockchainInfo and then verifies every header
|
||||
// returned.
|
||||
func (c *Client) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||
res, err := c.next.BlockchainInfo(minHeight, maxHeight)
|
||||
func (c *Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||
res, err := c.next.BlockchainInfo(ctx, minHeight, maxHeight)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -219,7 +219,7 @@ func (c *Client) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlock
|
||||
// Update the light client if we're behind.
|
||||
if len(res.BlockMetas) > 0 {
|
||||
lastHeight := res.BlockMetas[len(res.BlockMetas)-1].Header.Height
|
||||
if _, err := c.updateLightClientIfNeededTo(lastHeight); err != nil {
|
||||
if _, err := c.updateLightClientIfNeededTo(ctx, lastHeight); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
@@ -239,13 +239,13 @@ func (c *Client) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlock
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) Genesis() (*ctypes.ResultGenesis, error) {
|
||||
return c.next.Genesis()
|
||||
func (c *Client) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) {
|
||||
return c.next.Genesis(ctx)
|
||||
}
|
||||
|
||||
// Block calls rpcclient#Block and then verifies the result.
|
||||
func (c *Client) Block(height *int64) (*ctypes.ResultBlock, error) {
|
||||
res, err := c.next.Block(height)
|
||||
func (c *Client) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) {
|
||||
res, err := c.next.Block(ctx, height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -263,7 +263,7 @@ func (c *Client) Block(height *int64) (*ctypes.ResultBlock, error) {
|
||||
}
|
||||
|
||||
// Update the light client if we're behind.
|
||||
l, err := c.updateLightClientIfNeededTo(res.Block.Height)
|
||||
l, err := c.updateLightClientIfNeededTo(ctx, res.Block.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -278,8 +278,8 @@ func (c *Client) Block(height *int64) (*ctypes.ResultBlock, error) {
|
||||
}
|
||||
|
||||
// BlockByHash calls rpcclient#BlockByHash and then verifies the result.
|
||||
func (c *Client) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
|
||||
res, err := c.next.BlockByHash(hash)
|
||||
func (c *Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) {
|
||||
res, err := c.next.BlockByHash(ctx, hash)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -297,7 +297,7 @@ func (c *Client) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
|
||||
}
|
||||
|
||||
// Update the light client if we're behind.
|
||||
l, err := c.updateLightClientIfNeededTo(res.Block.Height)
|
||||
l, err := c.updateLightClientIfNeededTo(ctx, res.Block.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -313,10 +313,10 @@ func (c *Client) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
|
||||
|
||||
// BlockResults returns the block results for the given height. If no height is
|
||||
// provided, the results of the block preceding the latest are returned.
|
||||
func (c *Client) BlockResults(height *int64) (*ctypes.ResultBlockResults, error) {
|
||||
func (c *Client) BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error) {
|
||||
var h int64
|
||||
if height == nil {
|
||||
res, err := c.next.Status()
|
||||
res, err := c.next.Status(ctx)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't get latest height: %w", err)
|
||||
}
|
||||
@@ -327,7 +327,7 @@ func (c *Client) BlockResults(height *int64) (*ctypes.ResultBlockResults, error)
|
||||
h = *height
|
||||
}
|
||||
|
||||
res, err := c.next.BlockResults(&h)
|
||||
res, err := c.next.BlockResults(ctx, &h)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -338,7 +338,7 @@ func (c *Client) BlockResults(height *int64) (*ctypes.ResultBlockResults, error)
|
||||
}
|
||||
|
||||
// Update the light client if we're behind.
|
||||
trustedBlock, err := c.updateLightClientIfNeededTo(h + 1)
|
||||
trustedBlock, err := c.updateLightClientIfNeededTo(ctx, h+1)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -374,8 +374,8 @@ func (c *Client) BlockResults(height *int64) (*ctypes.ResultBlockResults, error)
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) Commit(height *int64) (*ctypes.ResultCommit, error) {
|
||||
res, err := c.next.Commit(height)
|
||||
func (c *Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
|
||||
res, err := c.next.Commit(ctx, height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -389,7 +389,7 @@ func (c *Client) Commit(height *int64) (*ctypes.ResultCommit, error) {
|
||||
}
|
||||
|
||||
// Update the light client if we're behind.
|
||||
l, err := c.updateLightClientIfNeededTo(res.Height)
|
||||
l, err := c.updateLightClientIfNeededTo(ctx, res.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -405,8 +405,8 @@ func (c *Client) Commit(height *int64) (*ctypes.ResultCommit, error) {
|
||||
|
||||
// Tx calls rpcclient#Tx method and then verifies the proof if such was
|
||||
// requested.
|
||||
func (c *Client) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
res, err := c.next.Tx(hash, prove)
|
||||
func (c *Client) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
res, err := c.next.Tx(ctx, hash, prove)
|
||||
if err != nil || !prove {
|
||||
return res, err
|
||||
}
|
||||
@@ -417,7 +417,7 @@ func (c *Client) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
}
|
||||
|
||||
// Update the light client if we're behind.
|
||||
l, err := c.updateLightClientIfNeededTo(res.Height)
|
||||
l, err := c.updateLightClientIfNeededTo(ctx, res.Height)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -426,17 +426,17 @@ func (c *Client) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
return res, res.Proof.Validate(l.DataHash)
|
||||
}
|
||||
|
||||
func (c *Client) TxSearch(query string, prove bool, page, perPage *int, orderBy string) (
|
||||
func (c *Client) TxSearch(ctx context.Context, query string, prove bool, page, perPage *int, orderBy string) (
|
||||
*ctypes.ResultTxSearch, error) {
|
||||
return c.next.TxSearch(query, prove, page, perPage, orderBy)
|
||||
return c.next.TxSearch(ctx, query, prove, page, perPage, orderBy)
|
||||
}
|
||||
|
||||
// Validators fetches and verifies validators.
|
||||
//
|
||||
// WARNING: only full validator sets are verified (when length of validators is
|
||||
// less than +perPage+. +perPage+ default is 30, max is 100).
|
||||
func (c *Client) Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
|
||||
res, err := c.next.Validators(height, page, perPage)
|
||||
func (c *Client) Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
|
||||
res, err := c.next.Validators(ctx, height, page, perPage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -454,7 +454,7 @@ func (c *Client) Validators(height *int64, page, perPage *int) (*ctypes.ResultVa
|
||||
}
|
||||
|
||||
// Update the light client if we're behind.
|
||||
l, err := c.updateLightClientIfNeededTo(updateHeight)
|
||||
l, err := c.updateLightClientIfNeededTo(ctx, updateHeight)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -480,8 +480,8 @@ func (c *Client) Validators(height *int64, page, perPage *int) (*ctypes.ResultVa
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (c *Client) BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
return c.next.BroadcastEvidence(ev)
|
||||
func (c *Client) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
return c.next.BroadcastEvidence(ctx, ev)
|
||||
}
|
||||
|
||||
func (c *Client) Subscribe(ctx context.Context, subscriber, query string,
|
||||
@@ -497,8 +497,8 @@ func (c *Client) UnsubscribeAll(ctx context.Context, subscriber string) error {
|
||||
return c.next.UnsubscribeAll(ctx, subscriber)
|
||||
}
|
||||
|
||||
func (c *Client) updateLightClientIfNeededTo(height int64) (*types.LightBlock, error) {
|
||||
l, err := c.lc.VerifyLightBlockAtHeight(height, time.Now())
|
||||
func (c *Client) updateLightClientIfNeededTo(ctx context.Context, height int64) (*types.LightBlock, error) {
|
||||
l, err := c.lc.VerifyLightBlockAtHeight(ctx, height, time.Now())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to update light client to %d: %w", height, err)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package light
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/tendermint/tendermint/light/provider"
|
||||
@@ -15,6 +16,7 @@ import (
|
||||
// See all Option(s) for the additional configuration.
|
||||
// See NewClient.
|
||||
func NewHTTPClient(
|
||||
ctx context.Context,
|
||||
chainID string,
|
||||
trustOptions TrustOptions,
|
||||
primaryAddress string,
|
||||
@@ -28,6 +30,7 @@ func NewHTTPClient(
|
||||
}
|
||||
|
||||
return NewClient(
|
||||
ctx,
|
||||
chainID,
|
||||
trustOptions,
|
||||
providers[len(providers)-1],
|
||||
|
||||
@@ -564,7 +564,10 @@ func startStateSync(ssR *statesync.Reactor, bcR fastSyncReactor, conR *cs.Reacto
|
||||
|
||||
if stateProvider == nil {
|
||||
var err error
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
stateProvider, err = statesync.NewLightClientStateProvider(
|
||||
ctx,
|
||||
state.ChainID, state.Version, state.InitialHeight,
|
||||
config.RPCServers, light.TrustOptions{
|
||||
Period: config.TrustPeriod,
|
||||
|
||||
@@ -126,12 +126,13 @@ func testTxEventsSent(t *testing.T, broadcastMethod string) {
|
||||
var (
|
||||
txres *ctypes.ResultBroadcastTx
|
||||
err error
|
||||
ctx = context.Background()
|
||||
)
|
||||
switch broadcastMethod {
|
||||
case "async":
|
||||
txres, err = c.BroadcastTxAsync(tx)
|
||||
txres, err = c.BroadcastTxAsync(ctx, tx)
|
||||
case "sync":
|
||||
txres, err = c.BroadcastTxSync(tx)
|
||||
txres, err = c.BroadcastTxSync(ctx, tx)
|
||||
default:
|
||||
panic(fmt.Sprintf("Unknown broadcastMethod %s", broadcastMethod))
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package client_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -119,18 +120,18 @@ func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
|
||||
correct, fakes := makeEvidences(t, pv, chainID)
|
||||
t.Logf("client %d", i)
|
||||
|
||||
result, err := c.BroadcastEvidence(correct)
|
||||
result, err := c.BroadcastEvidence(context.Background(), correct)
|
||||
require.NoError(t, err, "BroadcastEvidence(%s) failed", correct)
|
||||
assert.Equal(t, correct.Hash(), result.Hash, "expected result hash to match evidence hash")
|
||||
|
||||
status, err := c.Status()
|
||||
status, err := c.Status(context.Background())
|
||||
require.NoError(t, err)
|
||||
err = client.WaitForHeight(c, status.SyncInfo.LatestBlockHeight+2, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
ed25519pub := pv.Key.PubKey.(ed25519.PubKey)
|
||||
rawpub := ed25519pub.Bytes()
|
||||
result2, err := c.ABCIQuery("/val", rawpub)
|
||||
result2, err := c.ABCIQuery(context.Background(), "/val", rawpub)
|
||||
require.NoError(t, err)
|
||||
qres := result2.Response
|
||||
require.True(t, qres.IsOK())
|
||||
@@ -146,7 +147,7 @@ func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
|
||||
require.Equal(t, int64(9), v.Power, "Stored Power not equal with expected, value %v", string(qres.Value))
|
||||
|
||||
for _, fake := range fakes {
|
||||
_, err := c.BroadcastEvidence(fake)
|
||||
_, err := c.BroadcastEvidence(context.Background(), fake)
|
||||
require.Error(t, err, "BroadcastEvidence(%s) succeeded, but the evidence was fake", fake)
|
||||
}
|
||||
}
|
||||
@@ -154,7 +155,7 @@ func TestBroadcastEvidence_DuplicateVoteEvidence(t *testing.T) {
|
||||
|
||||
func TestBroadcastEmptyEvidence(t *testing.T) {
|
||||
for _, c := range GetClients() {
|
||||
_, err := c.BroadcastEvidence(nil)
|
||||
_, err := c.BroadcastEvidence(context.Background(), nil)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package client_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
@@ -31,7 +32,7 @@ func ExampleHTTP_simple() {
|
||||
|
||||
// Broadcast the transaction and wait for it to commit (rather use
|
||||
// c.BroadcastTxSync though in production).
|
||||
bres, err := c.BroadcastTxCommit(tx)
|
||||
bres, err := c.BroadcastTxCommit(context.Background(), tx)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -40,7 +41,7 @@ func ExampleHTTP_simple() {
|
||||
}
|
||||
|
||||
// Now try to fetch the value for the key
|
||||
qres, err := c.ABCIQuery("/key", k)
|
||||
qres, err := c.ABCIQuery(context.Background(), "/key", k)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
@@ -95,26 +96,26 @@ func ExampleHTTP_batching() {
|
||||
for _, tx := range txs {
|
||||
// Broadcast the transaction and wait for it to commit (rather use
|
||||
// c.BroadcastTxSync though in production).
|
||||
if _, err := batch.BroadcastTxCommit(tx); err != nil {
|
||||
if _, err := batch.BroadcastTxCommit(context.Background(), tx); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Send the batch of 2 transactions
|
||||
if _, err := batch.Send(); err != nil {
|
||||
if _, err := batch.Send(context.Background()); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Now let's query for the original results as a batch
|
||||
keys := [][]byte{k1, k2}
|
||||
for _, key := range keys {
|
||||
if _, err := batch.ABCIQuery("/key", key); err != nil {
|
||||
if _, err := batch.ABCIQuery(context.Background(), "/key", key); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// Send the 2 queries and keep the results
|
||||
results, err := batch.Send()
|
||||
results, err := batch.Send(context.Background())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func WaitForHeight(c StatusClient, h int64, waiter Waiter) error {
|
||||
}
|
||||
delta := int64(1)
|
||||
for delta > 0 {
|
||||
s, err := c.Status()
|
||||
s, err := c.Status(context.Background())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -183,8 +183,8 @@ func (c *HTTP) NewBatch() *BatchHTTP {
|
||||
// compilation of the batched requests and send them off using the client as a
|
||||
// single request. On success, this returns a list of the deserialized results
|
||||
// from each request in the sent batch.
|
||||
func (b *BatchHTTP) Send() ([]interface{}, error) {
|
||||
return b.rpcBatch.Send()
|
||||
func (b *BatchHTTP) Send(ctx context.Context) ([]interface{}, error) {
|
||||
return b.rpcBatch.Send(ctx)
|
||||
}
|
||||
|
||||
// Clear will empty out this batch of requests and return the number of requests
|
||||
@@ -201,9 +201,9 @@ func (b *BatchHTTP) Count() int {
|
||||
//-----------------------------------------------------------------------------
|
||||
// baseRPCClient
|
||||
|
||||
func (c *baseRPCClient) Status() (*ctypes.ResultStatus, error) {
|
||||
func (c *baseRPCClient) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
|
||||
result := new(ctypes.ResultStatus)
|
||||
_, err := c.caller.Call("status", map[string]interface{}{}, result)
|
||||
_, err := c.caller.Call(ctx, "status", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -211,9 +211,9 @@ func (c *baseRPCClient) Status() (*ctypes.ResultStatus, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
func (c *baseRPCClient) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
|
||||
result := new(ctypes.ResultABCIInfo)
|
||||
_, err := c.caller.Call("abci_info", map[string]interface{}{}, result)
|
||||
_, err := c.caller.Call(ctx, "abci_info", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -221,16 +221,21 @@ func (c *baseRPCClient) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQueryWithOptions(path, data, rpcclient.DefaultABCIQueryOptions)
|
||||
func (c *baseRPCClient) ABCIQuery(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.DefaultABCIQueryOptions)
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) ABCIQueryWithOptions(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
opts rpcclient.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
result := new(ctypes.ResultABCIQuery)
|
||||
_, err := c.caller.Call("abci_query",
|
||||
_, err := c.caller.Call(ctx, "abci_query",
|
||||
map[string]interface{}{"path": path, "data": data, "height": opts.Height, "prove": opts.Prove},
|
||||
result)
|
||||
if err != nil {
|
||||
@@ -240,115 +245,138 @@ func (c *baseRPCClient) ABCIQueryWithOptions(
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
func (c *baseRPCClient) BroadcastTxCommit(
|
||||
ctx context.Context,
|
||||
tx types.Tx,
|
||||
) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
result := new(ctypes.ResultBroadcastTxCommit)
|
||||
_, err := c.caller.Call("broadcast_tx_commit", map[string]interface{}{"tx": tx}, result)
|
||||
_, err := c.caller.Call(ctx, "broadcast_tx_commit", map[string]interface{}{"tx": tx}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.broadcastTX("broadcast_tx_async", tx)
|
||||
func (c *baseRPCClient) BroadcastTxAsync(
|
||||
ctx context.Context,
|
||||
tx types.Tx,
|
||||
) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.broadcastTX(ctx, "broadcast_tx_async", tx)
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.broadcastTX("broadcast_tx_sync", tx)
|
||||
func (c *baseRPCClient) BroadcastTxSync(
|
||||
ctx context.Context,
|
||||
tx types.Tx,
|
||||
) (*ctypes.ResultBroadcastTx, error) {
|
||||
return c.broadcastTX(ctx, "broadcast_tx_sync", tx)
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) broadcastTX(route string, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (c *baseRPCClient) broadcastTX(
|
||||
ctx context.Context,
|
||||
route string,
|
||||
tx types.Tx,
|
||||
) (*ctypes.ResultBroadcastTx, error) {
|
||||
result := new(ctypes.ResultBroadcastTx)
|
||||
_, err := c.caller.Call(route, map[string]interface{}{"tx": tx}, result)
|
||||
_, err := c.caller.Call(ctx, route, map[string]interface{}{"tx": tx}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) UnconfirmedTxs(limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
func (c *baseRPCClient) UnconfirmedTxs(
|
||||
ctx context.Context,
|
||||
limit *int,
|
||||
) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
result := new(ctypes.ResultUnconfirmedTxs)
|
||||
params := make(map[string]interface{})
|
||||
if limit != nil {
|
||||
params["limit"] = limit
|
||||
}
|
||||
_, err := c.caller.Call("unconfirmed_txs", params, result)
|
||||
_, err := c.caller.Call(ctx, "unconfirmed_txs", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
func (c *baseRPCClient) NumUnconfirmedTxs(ctx context.Context) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
result := new(ctypes.ResultUnconfirmedTxs)
|
||||
_, err := c.caller.Call("num_unconfirmed_txs", map[string]interface{}{}, result)
|
||||
_, err := c.caller.Call(ctx, "num_unconfirmed_txs", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error) {
|
||||
func (c *baseRPCClient) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) {
|
||||
result := new(ctypes.ResultCheckTx)
|
||||
_, err := c.caller.Call("check_tx", map[string]interface{}{"tx": tx}, result)
|
||||
_, err := c.caller.Call(ctx, "check_tx", map[string]interface{}{"tx": tx}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) NetInfo() (*ctypes.ResultNetInfo, error) {
|
||||
func (c *baseRPCClient) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) {
|
||||
result := new(ctypes.ResultNetInfo)
|
||||
_, err := c.caller.Call("net_info", map[string]interface{}{}, result)
|
||||
_, err := c.caller.Call(ctx, "net_info", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
||||
func (c *baseRPCClient) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) {
|
||||
result := new(ctypes.ResultDumpConsensusState)
|
||||
_, err := c.caller.Call("dump_consensus_state", map[string]interface{}{}, result)
|
||||
_, err := c.caller.Call(ctx, "dump_consensus_state", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) ConsensusState() (*ctypes.ResultConsensusState, error) {
|
||||
func (c *baseRPCClient) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) {
|
||||
result := new(ctypes.ResultConsensusState)
|
||||
_, err := c.caller.Call("consensus_state", map[string]interface{}{}, result)
|
||||
_, err := c.caller.Call(ctx, "consensus_state", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error) {
|
||||
func (c *baseRPCClient) ConsensusParams(
|
||||
ctx context.Context,
|
||||
height *int64,
|
||||
) (*ctypes.ResultConsensusParams, error) {
|
||||
result := new(ctypes.ResultConsensusParams)
|
||||
params := make(map[string]interface{})
|
||||
if height != nil {
|
||||
params["height"] = height
|
||||
}
|
||||
_, err := c.caller.Call("consensus_params", params, result)
|
||||
_, err := c.caller.Call(ctx, "consensus_params", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) Health() (*ctypes.ResultHealth, error) {
|
||||
func (c *baseRPCClient) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
|
||||
result := new(ctypes.ResultHealth)
|
||||
_, err := c.caller.Call("health", map[string]interface{}{}, result)
|
||||
_, err := c.caller.Call(ctx, "health", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||
func (c *baseRPCClient) BlockchainInfo(
|
||||
ctx context.Context,
|
||||
minHeight,
|
||||
maxHeight int64,
|
||||
) (*ctypes.ResultBlockchainInfo, error) {
|
||||
result := new(ctypes.ResultBlockchainInfo)
|
||||
_, err := c.caller.Call("blockchain",
|
||||
_, err := c.caller.Call(ctx, "blockchain",
|
||||
map[string]interface{}{"minHeight": minHeight, "maxHeight": maxHeight},
|
||||
result)
|
||||
if err != nil {
|
||||
@@ -357,80 +385,90 @@ func (c *baseRPCClient) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.Resu
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) Genesis() (*ctypes.ResultGenesis, error) {
|
||||
func (c *baseRPCClient) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) {
|
||||
result := new(ctypes.ResultGenesis)
|
||||
_, err := c.caller.Call("genesis", map[string]interface{}{}, result)
|
||||
_, err := c.caller.Call(ctx, "genesis", map[string]interface{}{}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) Block(height *int64) (*ctypes.ResultBlock, error) {
|
||||
func (c *baseRPCClient) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) {
|
||||
result := new(ctypes.ResultBlock)
|
||||
params := make(map[string]interface{})
|
||||
if height != nil {
|
||||
params["height"] = height
|
||||
}
|
||||
_, err := c.caller.Call("block", params, result)
|
||||
_, err := c.caller.Call(ctx, "block", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
|
||||
func (c *baseRPCClient) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) {
|
||||
result := new(ctypes.ResultBlock)
|
||||
params := map[string]interface{}{
|
||||
"hash": hash,
|
||||
}
|
||||
_, err := c.caller.Call("block_by_hash", params, result)
|
||||
_, err := c.caller.Call(ctx, "block_by_hash", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) BlockResults(height *int64) (*ctypes.ResultBlockResults, error) {
|
||||
func (c *baseRPCClient) BlockResults(
|
||||
ctx context.Context,
|
||||
height *int64,
|
||||
) (*ctypes.ResultBlockResults, error) {
|
||||
result := new(ctypes.ResultBlockResults)
|
||||
params := make(map[string]interface{})
|
||||
if height != nil {
|
||||
params["height"] = height
|
||||
}
|
||||
_, err := c.caller.Call("block_results", params, result)
|
||||
_, err := c.caller.Call(ctx, "block_results", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) Commit(height *int64) (*ctypes.ResultCommit, error) {
|
||||
func (c *baseRPCClient) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
|
||||
result := new(ctypes.ResultCommit)
|
||||
params := make(map[string]interface{})
|
||||
if height != nil {
|
||||
params["height"] = height
|
||||
}
|
||||
_, err := c.caller.Call("commit", params, result)
|
||||
_, err := c.caller.Call(ctx, "commit", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
func (c *baseRPCClient) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
result := new(ctypes.ResultTx)
|
||||
params := map[string]interface{}{
|
||||
"hash": hash,
|
||||
"prove": prove,
|
||||
}
|
||||
_, err := c.caller.Call("tx", params, result)
|
||||
_, err := c.caller.Call(ctx, "tx", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) TxSearch(query string, prove bool, page, perPage *int, orderBy string) (
|
||||
func (c *baseRPCClient) TxSearch(
|
||||
ctx context.Context,
|
||||
query string,
|
||||
prove bool,
|
||||
page,
|
||||
perPage *int,
|
||||
orderBy string,
|
||||
) (
|
||||
*ctypes.ResultTxSearch, error) {
|
||||
result := new(ctypes.ResultTxSearch)
|
||||
params := map[string]interface{}{
|
||||
@@ -444,14 +482,19 @@ func (c *baseRPCClient) TxSearch(query string, prove bool, page, perPage *int, o
|
||||
if perPage != nil {
|
||||
params["per_page"] = perPage
|
||||
}
|
||||
_, err := c.caller.Call("tx_search", params, result)
|
||||
_, err := c.caller.Call(ctx, "tx_search", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
|
||||
func (c *baseRPCClient) Validators(
|
||||
ctx context.Context,
|
||||
height *int64,
|
||||
page,
|
||||
perPage *int,
|
||||
) (*ctypes.ResultValidators, error) {
|
||||
result := new(ctypes.ResultValidators)
|
||||
params := make(map[string]interface{})
|
||||
if page != nil {
|
||||
@@ -463,16 +506,19 @@ func (c *baseRPCClient) Validators(height *int64, page, perPage *int) (*ctypes.R
|
||||
if height != nil {
|
||||
params["height"] = height
|
||||
}
|
||||
_, err := c.caller.Call("validators", params, result)
|
||||
_, err := c.caller.Call(ctx, "validators", params, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (c *baseRPCClient) BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
func (c *baseRPCClient) BroadcastEvidence(
|
||||
ctx context.Context,
|
||||
ev types.Evidence,
|
||||
) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
result := new(ctypes.ResultBroadcastEvidence)
|
||||
_, err := c.caller.Call("broadcast_evidence", map[string]interface{}{"evidence": ev}, result)
|
||||
_, err := c.caller.Call(ctx, "broadcast_evidence", map[string]interface{}{"evidence": ev}, result)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -50,48 +50,49 @@ type Client interface {
|
||||
// is easier to mock.
|
||||
type ABCIClient interface {
|
||||
// Reading from abci app
|
||||
ABCIInfo() (*ctypes.ResultABCIInfo, error)
|
||||
ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error)
|
||||
ABCIQueryWithOptions(path string, data bytes.HexBytes,
|
||||
ABCIInfo(context.Context) (*ctypes.ResultABCIInfo, error)
|
||||
ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error)
|
||||
ABCIQueryWithOptions(ctx context.Context, path string, data bytes.HexBytes,
|
||||
opts ABCIQueryOptions) (*ctypes.ResultABCIQuery, error)
|
||||
|
||||
// Writing to abci app
|
||||
BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error)
|
||||
BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error)
|
||||
BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error)
|
||||
BroadcastTxCommit(context.Context, types.Tx) (*ctypes.ResultBroadcastTxCommit, error)
|
||||
BroadcastTxAsync(context.Context, types.Tx) (*ctypes.ResultBroadcastTx, error)
|
||||
BroadcastTxSync(context.Context, types.Tx) (*ctypes.ResultBroadcastTx, error)
|
||||
}
|
||||
|
||||
// SignClient groups together the functionality needed to get valid signatures
|
||||
// and prove anything about the chain.
|
||||
type SignClient interface {
|
||||
Block(height *int64) (*ctypes.ResultBlock, error)
|
||||
BlockByHash(hash []byte) (*ctypes.ResultBlock, error)
|
||||
BlockResults(height *int64) (*ctypes.ResultBlockResults, error)
|
||||
Commit(height *int64) (*ctypes.ResultCommit, error)
|
||||
Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error)
|
||||
Tx(hash []byte, prove bool) (*ctypes.ResultTx, error)
|
||||
TxSearch(query string, prove bool, page, perPage *int, orderBy string) (*ctypes.ResultTxSearch, error)
|
||||
Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error)
|
||||
BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error)
|
||||
BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error)
|
||||
Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error)
|
||||
Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error)
|
||||
Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error)
|
||||
TxSearch(ctx context.Context, query string, prove bool, page, perPage *int,
|
||||
orderBy string) (*ctypes.ResultTxSearch, error)
|
||||
}
|
||||
|
||||
// HistoryClient provides access to data from genesis to now in large chunks.
|
||||
type HistoryClient interface {
|
||||
Genesis() (*ctypes.ResultGenesis, error)
|
||||
BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error)
|
||||
Genesis(context.Context) (*ctypes.ResultGenesis, error)
|
||||
BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error)
|
||||
}
|
||||
|
||||
// StatusClient provides access to general chain info.
|
||||
type StatusClient interface {
|
||||
Status() (*ctypes.ResultStatus, error)
|
||||
Status(context.Context) (*ctypes.ResultStatus, error)
|
||||
}
|
||||
|
||||
// NetworkClient is general info about the network state. May not be needed
|
||||
// usually.
|
||||
type NetworkClient interface {
|
||||
NetInfo() (*ctypes.ResultNetInfo, error)
|
||||
DumpConsensusState() (*ctypes.ResultDumpConsensusState, error)
|
||||
ConsensusState() (*ctypes.ResultConsensusState, error)
|
||||
ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error)
|
||||
Health() (*ctypes.ResultHealth, error)
|
||||
NetInfo(context.Context) (*ctypes.ResultNetInfo, error)
|
||||
DumpConsensusState(context.Context) (*ctypes.ResultDumpConsensusState, error)
|
||||
ConsensusState(context.Context) (*ctypes.ResultConsensusState, error)
|
||||
ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error)
|
||||
Health(context.Context) (*ctypes.ResultHealth, error)
|
||||
}
|
||||
|
||||
// EventsClient is reactive, you can subscribe to any message, given the proper
|
||||
@@ -113,15 +114,15 @@ type EventsClient interface {
|
||||
|
||||
// MempoolClient shows us data about current mempool state.
|
||||
type MempoolClient interface {
|
||||
UnconfirmedTxs(limit *int) (*ctypes.ResultUnconfirmedTxs, error)
|
||||
NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error)
|
||||
CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error)
|
||||
UnconfirmedTxs(ctx context.Context, limit *int) (*ctypes.ResultUnconfirmedTxs, error)
|
||||
NumUnconfirmedTxs(context.Context) (*ctypes.ResultUnconfirmedTxs, error)
|
||||
CheckTx(context.Context, types.Tx) (*ctypes.ResultCheckTx, error)
|
||||
}
|
||||
|
||||
// EvidenceClient is used for submitting an evidence of the malicious
|
||||
// behaviour.
|
||||
type EvidenceClient interface {
|
||||
BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error)
|
||||
BroadcastEvidence(context.Context, types.Evidence) (*ctypes.ResultBroadcastEvidence, error)
|
||||
}
|
||||
|
||||
// RemoteClient is a Client, which can also return the remote network address.
|
||||
|
||||
@@ -67,115 +67,128 @@ func (c *Local) SetLogger(l log.Logger) {
|
||||
c.Logger = l
|
||||
}
|
||||
|
||||
func (c *Local) Status() (*ctypes.ResultStatus, error) {
|
||||
func (c *Local) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
|
||||
return core.Status(c.ctx)
|
||||
}
|
||||
|
||||
func (c *Local) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
func (c *Local) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
|
||||
return core.ABCIInfo(c.ctx)
|
||||
}
|
||||
|
||||
func (c *Local) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQueryWithOptions(path, data, rpcclient.DefaultABCIQueryOptions)
|
||||
func (c *Local) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQueryWithOptions(ctx, path, data, rpcclient.DefaultABCIQueryOptions)
|
||||
}
|
||||
|
||||
func (c *Local) ABCIQueryWithOptions(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
opts rpcclient.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
return core.ABCIQuery(c.ctx, path, data, opts.Height, opts.Prove)
|
||||
}
|
||||
|
||||
func (c *Local) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
func (c *Local) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
return core.BroadcastTxCommit(c.ctx, tx)
|
||||
}
|
||||
|
||||
func (c *Local) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (c *Local) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return core.BroadcastTxAsync(c.ctx, tx)
|
||||
}
|
||||
|
||||
func (c *Local) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (c *Local) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return core.BroadcastTxSync(c.ctx, tx)
|
||||
}
|
||||
|
||||
func (c *Local) UnconfirmedTxs(limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
func (c *Local) UnconfirmedTxs(ctx context.Context, limit *int) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return core.UnconfirmedTxs(c.ctx, limit)
|
||||
}
|
||||
|
||||
func (c *Local) NumUnconfirmedTxs() (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
func (c *Local) NumUnconfirmedTxs(ctx context.Context) (*ctypes.ResultUnconfirmedTxs, error) {
|
||||
return core.NumUnconfirmedTxs(c.ctx)
|
||||
}
|
||||
|
||||
func (c *Local) CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error) {
|
||||
func (c *Local) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) {
|
||||
return core.CheckTx(c.ctx, tx)
|
||||
}
|
||||
|
||||
func (c *Local) NetInfo() (*ctypes.ResultNetInfo, error) {
|
||||
func (c *Local) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) {
|
||||
return core.NetInfo(c.ctx)
|
||||
}
|
||||
|
||||
func (c *Local) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
||||
func (c *Local) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) {
|
||||
return core.DumpConsensusState(c.ctx)
|
||||
}
|
||||
|
||||
func (c *Local) ConsensusState() (*ctypes.ResultConsensusState, error) {
|
||||
func (c *Local) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) {
|
||||
return core.ConsensusState(c.ctx)
|
||||
}
|
||||
|
||||
func (c *Local) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error) {
|
||||
func (c *Local) ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error) {
|
||||
return core.ConsensusParams(c.ctx, height)
|
||||
}
|
||||
|
||||
func (c *Local) Health() (*ctypes.ResultHealth, error) {
|
||||
func (c *Local) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
|
||||
return core.Health(c.ctx)
|
||||
}
|
||||
|
||||
func (c *Local) DialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
|
||||
func (c *Local) DialSeeds(ctx context.Context, seeds []string) (*ctypes.ResultDialSeeds, error) {
|
||||
return core.UnsafeDialSeeds(c.ctx, seeds)
|
||||
}
|
||||
|
||||
func (c *Local) DialPeers(peers []string, persistent, unconditional, private bool) (*ctypes.ResultDialPeers, error) {
|
||||
func (c *Local) DialPeers(
|
||||
ctx context.Context,
|
||||
peers []string,
|
||||
persistent,
|
||||
unconditional,
|
||||
private bool,
|
||||
) (*ctypes.ResultDialPeers, error) {
|
||||
return core.UnsafeDialPeers(c.ctx, peers, persistent, unconditional, private)
|
||||
}
|
||||
|
||||
func (c *Local) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||
func (c *Local) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||
return core.BlockchainInfo(c.ctx, minHeight, maxHeight)
|
||||
}
|
||||
|
||||
func (c *Local) Genesis() (*ctypes.ResultGenesis, error) {
|
||||
func (c *Local) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) {
|
||||
return core.Genesis(c.ctx)
|
||||
}
|
||||
|
||||
func (c *Local) Block(height *int64) (*ctypes.ResultBlock, error) {
|
||||
func (c *Local) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) {
|
||||
return core.Block(c.ctx, height)
|
||||
}
|
||||
|
||||
func (c *Local) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
|
||||
func (c *Local) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) {
|
||||
return core.BlockByHash(c.ctx, hash)
|
||||
}
|
||||
|
||||
func (c *Local) BlockResults(height *int64) (*ctypes.ResultBlockResults, error) {
|
||||
func (c *Local) BlockResults(ctx context.Context, height *int64) (*ctypes.ResultBlockResults, error) {
|
||||
return core.BlockResults(c.ctx, height)
|
||||
}
|
||||
|
||||
func (c *Local) Commit(height *int64) (*ctypes.ResultCommit, error) {
|
||||
func (c *Local) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
|
||||
return core.Commit(c.ctx, height)
|
||||
}
|
||||
|
||||
func (c *Local) Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
|
||||
func (c *Local) Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
|
||||
return core.Validators(c.ctx, height, page, perPage)
|
||||
}
|
||||
|
||||
func (c *Local) Tx(hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
func (c *Local) Tx(ctx context.Context, hash []byte, prove bool) (*ctypes.ResultTx, error) {
|
||||
return core.Tx(c.ctx, hash, prove)
|
||||
}
|
||||
|
||||
func (c *Local) TxSearch(query string, prove bool, page, perPage *int, orderBy string) (
|
||||
*ctypes.ResultTxSearch, error) {
|
||||
func (c *Local) TxSearch(
|
||||
ctx context.Context,
|
||||
query string,
|
||||
prove bool,
|
||||
page,
|
||||
perPage *int,
|
||||
orderBy string,
|
||||
) (*ctypes.ResultTxSearch, error) {
|
||||
return core.TxSearch(c.ctx, query, prove, page, perPage, orderBy)
|
||||
}
|
||||
|
||||
func (c *Local) BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
func (c *Local) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
return core.BroadcastEvidence(c.ctx, ev)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
abci "github.com/tendermint/tendermint/abci/types"
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
"github.com/tendermint/tendermint/proxy"
|
||||
@@ -22,15 +24,16 @@ var (
|
||||
_ client.ABCIClient = (*ABCIRecorder)(nil)
|
||||
)
|
||||
|
||||
func (a ABCIApp) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
func (a ABCIApp) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
|
||||
return &ctypes.ResultABCIInfo{Response: a.App.Info(proxy.RequestInfo)}, nil
|
||||
}
|
||||
|
||||
func (a ABCIApp) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return a.ABCIQueryWithOptions(path, data, client.DefaultABCIQueryOptions)
|
||||
func (a ABCIApp) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return a.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions)
|
||||
}
|
||||
|
||||
func (a ABCIApp) ABCIQueryWithOptions(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
@@ -46,7 +49,7 @@ func (a ABCIApp) ABCIQueryWithOptions(
|
||||
// NOTE: Caller should call a.App.Commit() separately,
|
||||
// this function does not actually wait for a commit.
|
||||
// TODO: Make it wait for a commit and set res.Height appropriately.
|
||||
func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
func (a ABCIApp) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
res := ctypes.ResultBroadcastTxCommit{}
|
||||
res.CheckTx = a.App.CheckTx(abci.RequestCheckTx{Tx: tx})
|
||||
if res.CheckTx.IsErr() {
|
||||
@@ -57,7 +60,7 @@ func (a ABCIApp) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit
|
||||
return &res, nil
|
||||
}
|
||||
|
||||
func (a ABCIApp) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (a ABCIApp) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx})
|
||||
// and this gets written in a background thread...
|
||||
if !c.IsErr() {
|
||||
@@ -72,7 +75,7 @@ func (a ABCIApp) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (a ABCIApp) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (a ABCIApp) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
c := a.App.CheckTx(abci.RequestCheckTx{Tx: tx})
|
||||
// and this gets written in a background thread...
|
||||
if !c.IsErr() {
|
||||
@@ -97,7 +100,7 @@ type ABCIMock struct {
|
||||
Broadcast Call
|
||||
}
|
||||
|
||||
func (m ABCIMock) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
func (m ABCIMock) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
|
||||
res, err := m.Info.GetResponse(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -105,11 +108,12 @@ func (m ABCIMock) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
return &ctypes.ResultABCIInfo{Response: res.(abci.ResponseInfo)}, nil
|
||||
}
|
||||
|
||||
func (m ABCIMock) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return m.ABCIQueryWithOptions(path, data, client.DefaultABCIQueryOptions)
|
||||
func (m ABCIMock) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return m.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions)
|
||||
}
|
||||
|
||||
func (m ABCIMock) ABCIQueryWithOptions(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
@@ -121,7 +125,7 @@ func (m ABCIMock) ABCIQueryWithOptions(
|
||||
return &ctypes.ResultABCIQuery{Response: resQuery}, nil
|
||||
}
|
||||
|
||||
func (m ABCIMock) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
func (m ABCIMock) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
res, err := m.BroadcastCommit.GetResponse(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -129,7 +133,7 @@ func (m ABCIMock) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommi
|
||||
return res.(*ctypes.ResultBroadcastTxCommit), nil
|
||||
}
|
||||
|
||||
func (m ABCIMock) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (m ABCIMock) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
res, err := m.Broadcast.GetResponse(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -137,7 +141,7 @@ func (m ABCIMock) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, erro
|
||||
return res.(*ctypes.ResultBroadcastTx), nil
|
||||
}
|
||||
|
||||
func (m ABCIMock) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (m ABCIMock) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
res, err := m.Broadcast.GetResponse(tx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -170,8 +174,8 @@ func (r *ABCIRecorder) addCall(call Call) {
|
||||
r.Calls = append(r.Calls, call)
|
||||
}
|
||||
|
||||
func (r *ABCIRecorder) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
res, err := r.Client.ABCIInfo()
|
||||
func (r *ABCIRecorder) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
|
||||
res, err := r.Client.ABCIInfo(ctx)
|
||||
r.addCall(Call{
|
||||
Name: "abci_info",
|
||||
Response: res,
|
||||
@@ -180,15 +184,20 @@ func (r *ABCIRecorder) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (r *ABCIRecorder) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return r.ABCIQueryWithOptions(path, data, client.DefaultABCIQueryOptions)
|
||||
func (r *ABCIRecorder) ABCIQuery(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
) (*ctypes.ResultABCIQuery, error) {
|
||||
return r.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions)
|
||||
}
|
||||
|
||||
func (r *ABCIRecorder) ABCIQueryWithOptions(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
res, err := r.Client.ABCIQueryWithOptions(path, data, opts)
|
||||
res, err := r.Client.ABCIQueryWithOptions(ctx, path, data, opts)
|
||||
r.addCall(Call{
|
||||
Name: "abci_query",
|
||||
Args: QueryArgs{path, data, opts.Height, opts.Prove},
|
||||
@@ -198,8 +207,8 @@ func (r *ABCIRecorder) ABCIQueryWithOptions(
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (r *ABCIRecorder) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
res, err := r.Client.BroadcastTxCommit(tx)
|
||||
func (r *ABCIRecorder) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
res, err := r.Client.BroadcastTxCommit(ctx, tx)
|
||||
r.addCall(Call{
|
||||
Name: "broadcast_tx_commit",
|
||||
Args: tx,
|
||||
@@ -209,8 +218,8 @@ func (r *ABCIRecorder) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTx
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (r *ABCIRecorder) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
res, err := r.Client.BroadcastTxAsync(tx)
|
||||
func (r *ABCIRecorder) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
res, err := r.Client.BroadcastTxAsync(ctx, tx)
|
||||
r.addCall(Call{
|
||||
Name: "broadcast_tx_async",
|
||||
Args: tx,
|
||||
@@ -220,8 +229,8 @@ func (r *ABCIRecorder) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx,
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (r *ABCIRecorder) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
res, err := r.Client.BroadcastTxSync(tx)
|
||||
func (r *ABCIRecorder) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
res, err := r.Client.BroadcastTxSync(ctx, tx)
|
||||
r.addCall(Call{
|
||||
Name: "broadcast_tx_sync",
|
||||
Args: tx,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mock_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"testing"
|
||||
@@ -45,12 +46,12 @@ func TestABCIMock(t *testing.T) {
|
||||
}
|
||||
|
||||
// now, let's try to make some calls
|
||||
_, err := m.ABCIInfo()
|
||||
_, err := m.ABCIInfo(context.Background())
|
||||
require.NotNil(err)
|
||||
assert.Equal("foobar", err.Error())
|
||||
|
||||
// query always returns the response
|
||||
_query, err := m.ABCIQueryWithOptions("/", nil, client.ABCIQueryOptions{Prove: false})
|
||||
_query, err := m.ABCIQueryWithOptions(context.Background(), "/", nil, client.ABCIQueryOptions{Prove: false})
|
||||
query := _query.Response
|
||||
require.Nil(err)
|
||||
require.NotNil(query)
|
||||
@@ -59,18 +60,18 @@ func TestABCIMock(t *testing.T) {
|
||||
assert.Equal(height, query.Height)
|
||||
|
||||
// non-commit calls always return errors
|
||||
_, err = m.BroadcastTxSync(goodTx)
|
||||
_, err = m.BroadcastTxSync(context.Background(), goodTx)
|
||||
require.NotNil(err)
|
||||
assert.Equal("must commit", err.Error())
|
||||
_, err = m.BroadcastTxAsync(goodTx)
|
||||
_, err = m.BroadcastTxAsync(context.Background(), goodTx)
|
||||
require.NotNil(err)
|
||||
assert.Equal("must commit", err.Error())
|
||||
|
||||
// commit depends on the input
|
||||
_, err = m.BroadcastTxCommit(badTx)
|
||||
_, err = m.BroadcastTxCommit(context.Background(), badTx)
|
||||
require.NotNil(err)
|
||||
assert.Equal("bad tx", err.Error())
|
||||
bres, err := m.BroadcastTxCommit(goodTx)
|
||||
bres, err := m.BroadcastTxCommit(context.Background(), goodTx)
|
||||
require.Nil(err, "%+v", err)
|
||||
assert.EqualValues(0, bres.CheckTx.Code)
|
||||
assert.EqualValues("stand", bres.CheckTx.Data)
|
||||
@@ -94,10 +95,15 @@ func TestABCIRecorder(t *testing.T) {
|
||||
|
||||
require.Equal(0, len(r.Calls))
|
||||
|
||||
_, err := r.ABCIInfo()
|
||||
_, err := r.ABCIInfo(context.Background())
|
||||
assert.Nil(err, "expected no err on info")
|
||||
|
||||
_, err = r.ABCIQueryWithOptions("path", bytes.HexBytes("data"), client.ABCIQueryOptions{Prove: false})
|
||||
_, err = r.ABCIQueryWithOptions(
|
||||
context.Background(),
|
||||
"path",
|
||||
bytes.HexBytes("data"),
|
||||
client.ABCIQueryOptions{Prove: false},
|
||||
)
|
||||
assert.NotNil(err, "expected error on query")
|
||||
require.Equal(2, len(r.Calls))
|
||||
|
||||
@@ -125,11 +131,11 @@ func TestABCIRecorder(t *testing.T) {
|
||||
|
||||
// now add some broadcasts (should all err)
|
||||
txs := []types.Tx{{1}, {2}, {3}}
|
||||
_, err = r.BroadcastTxCommit(txs[0])
|
||||
_, err = r.BroadcastTxCommit(context.Background(), txs[0])
|
||||
assert.NotNil(err, "expected err on broadcast")
|
||||
_, err = r.BroadcastTxSync(txs[1])
|
||||
_, err = r.BroadcastTxSync(context.Background(), txs[1])
|
||||
assert.NotNil(err, "expected err on broadcast")
|
||||
_, err = r.BroadcastTxAsync(txs[2])
|
||||
_, err = r.BroadcastTxAsync(context.Background(), txs[2])
|
||||
assert.NotNil(err, "expected err on broadcast")
|
||||
|
||||
require.Equal(5, len(r.Calls))
|
||||
@@ -159,14 +165,14 @@ func TestABCIApp(t *testing.T) {
|
||||
m := mock.ABCIApp{app}
|
||||
|
||||
// get some info
|
||||
info, err := m.ABCIInfo()
|
||||
info, err := m.ABCIInfo(context.Background())
|
||||
require.Nil(err)
|
||||
assert.Equal(`{"size":0}`, info.Response.GetData())
|
||||
|
||||
// add a key
|
||||
key, value := "foo", "bar"
|
||||
tx := fmt.Sprintf("%s=%s", key, value)
|
||||
res, err := m.BroadcastTxCommit(types.Tx(tx))
|
||||
res, err := m.BroadcastTxCommit(context.Background(), types.Tx(tx))
|
||||
require.Nil(err)
|
||||
assert.True(res.CheckTx.IsOK())
|
||||
require.NotNil(res.DeliverTx)
|
||||
@@ -179,7 +185,12 @@ func TestABCIApp(t *testing.T) {
|
||||
}
|
||||
|
||||
// check the key
|
||||
_qres, err := m.ABCIQueryWithOptions("/key", bytes.HexBytes(key), client.ABCIQueryOptions{Prove: true})
|
||||
_qres, err := m.ABCIQueryWithOptions(
|
||||
context.Background(),
|
||||
"/key",
|
||||
bytes.HexBytes(key),
|
||||
client.ABCIQueryOptions{Prove: true},
|
||||
)
|
||||
qres := _qres.Response
|
||||
require.Nil(err)
|
||||
assert.EqualValues(value, qres.Value)
|
||||
|
||||
@@ -15,6 +15,7 @@ want to directly call a tendermint node in process, you can use the
|
||||
*/
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
|
||||
"github.com/tendermint/tendermint/libs/bytes"
|
||||
@@ -79,93 +80,100 @@ func (c Call) GetResponse(args interface{}) (interface{}, error) {
|
||||
return nil, c.Error
|
||||
}
|
||||
|
||||
func (c Client) Status() (*ctypes.ResultStatus, error) {
|
||||
func (c Client) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
|
||||
return core.Status(&rpctypes.Context{})
|
||||
}
|
||||
|
||||
func (c Client) ABCIInfo() (*ctypes.ResultABCIInfo, error) {
|
||||
func (c Client) ABCIInfo(ctx context.Context) (*ctypes.ResultABCIInfo, error) {
|
||||
return core.ABCIInfo(&rpctypes.Context{})
|
||||
}
|
||||
|
||||
func (c Client) ABCIQuery(path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQueryWithOptions(path, data, client.DefaultABCIQueryOptions)
|
||||
func (c Client) ABCIQuery(ctx context.Context, path string, data bytes.HexBytes) (*ctypes.ResultABCIQuery, error) {
|
||||
return c.ABCIQueryWithOptions(ctx, path, data, client.DefaultABCIQueryOptions)
|
||||
}
|
||||
|
||||
func (c Client) ABCIQueryWithOptions(
|
||||
ctx context.Context,
|
||||
path string,
|
||||
data bytes.HexBytes,
|
||||
opts client.ABCIQueryOptions) (*ctypes.ResultABCIQuery, error) {
|
||||
return core.ABCIQuery(&rpctypes.Context{}, path, data, opts.Height, opts.Prove)
|
||||
}
|
||||
|
||||
func (c Client) BroadcastTxCommit(tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
func (c Client) BroadcastTxCommit(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTxCommit, error) {
|
||||
return core.BroadcastTxCommit(&rpctypes.Context{}, tx)
|
||||
}
|
||||
|
||||
func (c Client) BroadcastTxAsync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (c Client) BroadcastTxAsync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return core.BroadcastTxAsync(&rpctypes.Context{}, tx)
|
||||
}
|
||||
|
||||
func (c Client) BroadcastTxSync(tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
func (c Client) BroadcastTxSync(ctx context.Context, tx types.Tx) (*ctypes.ResultBroadcastTx, error) {
|
||||
return core.BroadcastTxSync(&rpctypes.Context{}, tx)
|
||||
}
|
||||
|
||||
func (c Client) CheckTx(tx types.Tx) (*ctypes.ResultCheckTx, error) {
|
||||
func (c Client) CheckTx(ctx context.Context, tx types.Tx) (*ctypes.ResultCheckTx, error) {
|
||||
return core.CheckTx(&rpctypes.Context{}, tx)
|
||||
}
|
||||
|
||||
func (c Client) NetInfo() (*ctypes.ResultNetInfo, error) {
|
||||
func (c Client) NetInfo(ctx context.Context) (*ctypes.ResultNetInfo, error) {
|
||||
return core.NetInfo(&rpctypes.Context{})
|
||||
}
|
||||
|
||||
func (c Client) ConsensusState() (*ctypes.ResultConsensusState, error) {
|
||||
func (c Client) ConsensusState(ctx context.Context) (*ctypes.ResultConsensusState, error) {
|
||||
return core.ConsensusState(&rpctypes.Context{})
|
||||
}
|
||||
|
||||
func (c Client) DumpConsensusState() (*ctypes.ResultDumpConsensusState, error) {
|
||||
func (c Client) DumpConsensusState(ctx context.Context) (*ctypes.ResultDumpConsensusState, error) {
|
||||
return core.DumpConsensusState(&rpctypes.Context{})
|
||||
}
|
||||
|
||||
func (c Client) ConsensusParams(height *int64) (*ctypes.ResultConsensusParams, error) {
|
||||
func (c Client) ConsensusParams(ctx context.Context, height *int64) (*ctypes.ResultConsensusParams, error) {
|
||||
return core.ConsensusParams(&rpctypes.Context{}, height)
|
||||
}
|
||||
|
||||
func (c Client) Health() (*ctypes.ResultHealth, error) {
|
||||
func (c Client) Health(ctx context.Context) (*ctypes.ResultHealth, error) {
|
||||
return core.Health(&rpctypes.Context{})
|
||||
}
|
||||
|
||||
func (c Client) DialSeeds(seeds []string) (*ctypes.ResultDialSeeds, error) {
|
||||
func (c Client) DialSeeds(ctx context.Context, seeds []string) (*ctypes.ResultDialSeeds, error) {
|
||||
return core.UnsafeDialSeeds(&rpctypes.Context{}, seeds)
|
||||
}
|
||||
|
||||
func (c Client) DialPeers(peers []string, persistent, unconditional, private bool) (*ctypes.ResultDialPeers, error) {
|
||||
func (c Client) DialPeers(
|
||||
ctx context.Context,
|
||||
peers []string,
|
||||
persistent,
|
||||
unconditional,
|
||||
private bool,
|
||||
) (*ctypes.ResultDialPeers, error) {
|
||||
return core.UnsafeDialPeers(&rpctypes.Context{}, peers, persistent, unconditional, private)
|
||||
}
|
||||
|
||||
func (c Client) BlockchainInfo(minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||
func (c Client) BlockchainInfo(ctx context.Context, minHeight, maxHeight int64) (*ctypes.ResultBlockchainInfo, error) {
|
||||
return core.BlockchainInfo(&rpctypes.Context{}, minHeight, maxHeight)
|
||||
}
|
||||
|
||||
func (c Client) Genesis() (*ctypes.ResultGenesis, error) {
|
||||
func (c Client) Genesis(ctx context.Context) (*ctypes.ResultGenesis, error) {
|
||||
return core.Genesis(&rpctypes.Context{})
|
||||
}
|
||||
|
||||
func (c Client) Block(height *int64) (*ctypes.ResultBlock, error) {
|
||||
func (c Client) Block(ctx context.Context, height *int64) (*ctypes.ResultBlock, error) {
|
||||
return core.Block(&rpctypes.Context{}, height)
|
||||
}
|
||||
|
||||
func (c Client) BlockByHash(hash []byte) (*ctypes.ResultBlock, error) {
|
||||
func (c Client) BlockByHash(ctx context.Context, hash []byte) (*ctypes.ResultBlock, error) {
|
||||
return core.BlockByHash(&rpctypes.Context{}, hash)
|
||||
}
|
||||
|
||||
func (c Client) Commit(height *int64) (*ctypes.ResultCommit, error) {
|
||||
func (c Client) Commit(ctx context.Context, height *int64) (*ctypes.ResultCommit, error) {
|
||||
return core.Commit(&rpctypes.Context{}, height)
|
||||
}
|
||||
|
||||
func (c Client) Validators(height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
|
||||
func (c Client) Validators(ctx context.Context, height *int64, page, perPage *int) (*ctypes.ResultValidators, error) {
|
||||
return core.Validators(&rpctypes.Context{}, height, page, perPage)
|
||||
}
|
||||
|
||||
func (c Client) BroadcastEvidence(ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
func (c Client) BroadcastEvidence(ctx context.Context, ev types.Evidence) (*ctypes.ResultBroadcastEvidence, error) {
|
||||
return core.BroadcastEvidence(&rpctypes.Context{}, ev)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package mock
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/tendermint/tendermint/rpc/client"
|
||||
ctypes "github.com/tendermint/tendermint/rpc/core/types"
|
||||
)
|
||||
@@ -15,7 +17,7 @@ var (
|
||||
_ client.StatusClient = (*StatusRecorder)(nil)
|
||||
)
|
||||
|
||||
func (m *StatusMock) Status() (*ctypes.ResultStatus, error) {
|
||||
func (m *StatusMock) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
|
||||
res, err := m.GetResponse(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -41,8 +43,8 @@ func (r *StatusRecorder) addCall(call Call) {
|
||||
r.Calls = append(r.Calls, call)
|
||||
}
|
||||
|
||||
func (r *StatusRecorder) Status() (*ctypes.ResultStatus, error) {
|
||||
res, err := r.Client.Status()
|
||||
func (r *StatusRecorder) Status(ctx context.Context) (*ctypes.ResultStatus, error) {
|
||||
res, err := r.Client.Status(ctx)
|
||||
r.addCall(Call{
|
||||
Name: "status",
|
||||
Response: res,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package mock_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
@@ -29,7 +30,7 @@ func TestStatus(t *testing.T) {
|
||||
require.Equal(0, len(r.Calls))
|
||||
|
||||
// make sure response works proper
|
||||
status, err := r.Status()
|
||||
status, err := r.Status(context.Background())
|
||||
require.Nil(err, "%+v", err)
|
||||
assert.EqualValues("block", status.SyncInfo.LatestBlockHash)
|
||||
assert.EqualValues(10, status.SyncInfo.LatestBlockHeight)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package client_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
@@ -25,6 +26,10 @@ import (
|
||||
"github.com/tendermint/tendermint/types"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx = context.Background()
|
||||
)
|
||||
|
||||
func getHTTPClient() *rpchttp.HTTP {
|
||||
rpcAddr := rpctest.GetConfig().RPC.ListenAddress
|
||||
c, err := rpchttp.New(rpcAddr, "/websocket")
|
||||
@@ -70,7 +75,7 @@ func TestCustomHTTPClient(t *testing.T) {
|
||||
remote := rpctest.GetConfig().RPC.ListenAddress
|
||||
c, err := rpchttp.NewWithClient(remote, "/websocket", http.DefaultClient)
|
||||
require.Nil(t, err)
|
||||
status, err := c.Status()
|
||||
status, err := c.Status(context.Background())
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, status)
|
||||
}
|
||||
@@ -94,7 +99,7 @@ func TestCorsEnabled(t *testing.T) {
|
||||
func TestStatus(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
moniker := rpctest.GetConfig().Moniker
|
||||
status, err := c.Status()
|
||||
status, err := c.Status(context.Background())
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
assert.Equal(t, moniker, status.NodeInfo.Moniker)
|
||||
}
|
||||
@@ -105,7 +110,7 @@ func TestInfo(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
// status, err := c.Status()
|
||||
// require.Nil(t, err, "%+v", err)
|
||||
info, err := c.ABCIInfo()
|
||||
info, err := c.ABCIInfo(context.Background())
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
// TODO: this is not correct - fix merkleeyes!
|
||||
// assert.EqualValues(t, status.SyncInfo.LatestBlockHeight, info.Response.LastBlockHeight)
|
||||
@@ -117,7 +122,7 @@ func TestNetInfo(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
nc, ok := c.(client.NetworkClient)
|
||||
require.True(t, ok, "%d", i)
|
||||
netinfo, err := nc.NetInfo()
|
||||
netinfo, err := nc.NetInfo(context.Background())
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
assert.True(t, netinfo.Listening)
|
||||
assert.Equal(t, 0, len(netinfo.Peers))
|
||||
@@ -129,7 +134,7 @@ func TestDumpConsensusState(t *testing.T) {
|
||||
// FIXME: fix server so it doesn't panic on invalid input
|
||||
nc, ok := c.(client.NetworkClient)
|
||||
require.True(t, ok, "%d", i)
|
||||
cons, err := nc.DumpConsensusState()
|
||||
cons, err := nc.DumpConsensusState(context.Background())
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
assert.NotEmpty(t, cons.RoundState)
|
||||
assert.Empty(t, cons.Peers)
|
||||
@@ -141,7 +146,7 @@ func TestConsensusState(t *testing.T) {
|
||||
// FIXME: fix server so it doesn't panic on invalid input
|
||||
nc, ok := c.(client.NetworkClient)
|
||||
require.True(t, ok, "%d", i)
|
||||
cons, err := nc.ConsensusState()
|
||||
cons, err := nc.ConsensusState(context.Background())
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
assert.NotEmpty(t, cons.RoundState)
|
||||
}
|
||||
@@ -151,7 +156,7 @@ func TestHealth(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
nc, ok := c.(client.NetworkClient)
|
||||
require.True(t, ok, "%d", i)
|
||||
_, err := nc.Health()
|
||||
_, err := nc.Health(context.Background())
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
}
|
||||
}
|
||||
@@ -160,7 +165,7 @@ func TestGenesisAndValidators(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
|
||||
// make sure this is the right genesis file
|
||||
gen, err := c.Genesis()
|
||||
gen, err := c.Genesis(context.Background())
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
// get the genesis validator
|
||||
require.Equal(t, 1, len(gen.Genesis.Validators))
|
||||
@@ -168,7 +173,7 @@ func TestGenesisAndValidators(t *testing.T) {
|
||||
|
||||
// get the current validators
|
||||
h := int64(1)
|
||||
vals, err := c.Validators(&h, nil, nil)
|
||||
vals, err := c.Validators(context.Background(), &h, nil, nil)
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
require.Equal(t, 1, len(vals.Validators))
|
||||
require.Equal(t, 1, vals.Count)
|
||||
@@ -185,14 +190,14 @@ func TestABCIQuery(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
// write something
|
||||
k, v, tx := MakeTxKV()
|
||||
bres, err := c.BroadcastTxCommit(tx)
|
||||
bres, err := c.BroadcastTxCommit(context.Background(), tx)
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
apph := bres.Height + 1 // this is where the tx will be applied to the state
|
||||
|
||||
// wait before querying
|
||||
err = client.WaitForHeight(c, apph, nil)
|
||||
require.NoError(t, err)
|
||||
res, err := c.ABCIQuery("/key", k)
|
||||
res, err := c.ABCIQuery(context.Background(), "/key", k)
|
||||
qres := res.Response
|
||||
if assert.Nil(t, err) && assert.True(t, qres.IsOK()) {
|
||||
assert.EqualValues(t, v, qres.Value)
|
||||
@@ -206,19 +211,19 @@ func TestAppCalls(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
|
||||
// get an offset of height to avoid racing and guessing
|
||||
s, err := c.Status()
|
||||
s, err := c.Status(context.Background())
|
||||
require.NoError(err)
|
||||
// sh is start height or status height
|
||||
sh := s.SyncInfo.LatestBlockHeight
|
||||
|
||||
// look for the future
|
||||
h := sh + 20
|
||||
_, err = c.Block(&h)
|
||||
_, err = c.Block(context.Background(), &h)
|
||||
require.Error(err) // no block yet
|
||||
|
||||
// write something
|
||||
k, v, tx := MakeTxKV()
|
||||
bres, err := c.BroadcastTxCommit(tx)
|
||||
bres, err := c.BroadcastTxCommit(context.Background(), tx)
|
||||
require.NoError(err)
|
||||
require.True(bres.DeliverTx.IsOK())
|
||||
txh := bres.Height
|
||||
@@ -228,7 +233,7 @@ func TestAppCalls(t *testing.T) {
|
||||
err = client.WaitForHeight(c, apph, nil)
|
||||
require.NoError(err)
|
||||
|
||||
_qres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Prove: false})
|
||||
_qres, err := c.ABCIQueryWithOptions(context.Background(), "/key", k, client.ABCIQueryOptions{Prove: false})
|
||||
require.NoError(err)
|
||||
qres := _qres.Response
|
||||
if assert.True(qres.IsOK()) {
|
||||
@@ -237,24 +242,24 @@ func TestAppCalls(t *testing.T) {
|
||||
}
|
||||
|
||||
// make sure we can lookup the tx with proof
|
||||
ptx, err := c.Tx(bres.Hash, true)
|
||||
ptx, err := c.Tx(context.Background(), bres.Hash, true)
|
||||
require.NoError(err)
|
||||
assert.EqualValues(txh, ptx.Height)
|
||||
assert.EqualValues(tx, ptx.Tx)
|
||||
|
||||
// and we can even check the block is added
|
||||
block, err := c.Block(&apph)
|
||||
block, err := c.Block(context.Background(), &apph)
|
||||
require.NoError(err)
|
||||
appHash := block.Block.Header.AppHash
|
||||
assert.True(len(appHash) > 0)
|
||||
assert.EqualValues(apph, block.Block.Header.Height)
|
||||
|
||||
blockByHash, err := c.BlockByHash(block.BlockID.Hash)
|
||||
blockByHash, err := c.BlockByHash(context.Background(), block.BlockID.Hash)
|
||||
require.NoError(err)
|
||||
require.Equal(block, blockByHash)
|
||||
|
||||
// now check the results
|
||||
blockResults, err := c.BlockResults(&txh)
|
||||
blockResults, err := c.BlockResults(context.Background(), &txh)
|
||||
require.Nil(err, "%d: %+v", i, err)
|
||||
assert.Equal(txh, blockResults.Height)
|
||||
if assert.Equal(1, len(blockResults.TxsResults)) {
|
||||
@@ -263,7 +268,7 @@ func TestAppCalls(t *testing.T) {
|
||||
}
|
||||
|
||||
// check blockchain info, now that we know there is info
|
||||
info, err := c.BlockchainInfo(apph, apph)
|
||||
info, err := c.BlockchainInfo(context.Background(), apph, apph)
|
||||
require.NoError(err)
|
||||
assert.True(info.LastHeight >= apph)
|
||||
if assert.Equal(1, len(info.BlockMetas)) {
|
||||
@@ -275,7 +280,7 @@ func TestAppCalls(t *testing.T) {
|
||||
}
|
||||
|
||||
// and get the corresponding commit with the same apphash
|
||||
commit, err := c.Commit(&apph)
|
||||
commit, err := c.Commit(context.Background(), &apph)
|
||||
require.NoError(err)
|
||||
cappHash := commit.Header.AppHash
|
||||
assert.Equal(appHash, cappHash)
|
||||
@@ -283,12 +288,12 @@ func TestAppCalls(t *testing.T) {
|
||||
|
||||
// compare the commits (note Commit(2) has commit from Block(3))
|
||||
h = apph - 1
|
||||
commit2, err := c.Commit(&h)
|
||||
commit2, err := c.Commit(context.Background(), &h)
|
||||
require.NoError(err)
|
||||
assert.Equal(block.Block.LastCommit, commit2.Commit)
|
||||
|
||||
// and we got a proof that works!
|
||||
_pres, err := c.ABCIQueryWithOptions("/key", k, client.ABCIQueryOptions{Prove: true})
|
||||
_pres, err := c.ABCIQueryWithOptions(context.Background(), "/key", k, client.ABCIQueryOptions{Prove: true})
|
||||
require.NoError(err)
|
||||
pres := _pres.Response
|
||||
assert.True(pres.IsOK())
|
||||
@@ -306,7 +311,7 @@ func TestBroadcastTxSync(t *testing.T) {
|
||||
|
||||
for i, c := range GetClients() {
|
||||
_, _, tx := MakeTxKV()
|
||||
bres, err := c.BroadcastTxSync(tx)
|
||||
bres, err := c.BroadcastTxSync(context.Background(), tx)
|
||||
require.Nil(err, "%d: %+v", i, err)
|
||||
require.Equal(bres.Code, abci.CodeTypeOK) // FIXME
|
||||
|
||||
@@ -324,7 +329,7 @@ func TestBroadcastTxCommit(t *testing.T) {
|
||||
mempool := node.Mempool()
|
||||
for i, c := range GetClients() {
|
||||
_, _, tx := MakeTxKV()
|
||||
bres, err := c.BroadcastTxCommit(tx)
|
||||
bres, err := c.BroadcastTxCommit(context.Background(), tx)
|
||||
require.Nil(err, "%d: %+v", i, err)
|
||||
require.True(bres.CheckTx.IsOK())
|
||||
require.True(bres.DeliverTx.IsOK())
|
||||
@@ -351,7 +356,7 @@ func TestUnconfirmedTxs(t *testing.T) {
|
||||
for _, c := range GetClients() {
|
||||
mc := c.(client.MempoolClient)
|
||||
limit := 1
|
||||
res, err := mc.UnconfirmedTxs(&limit)
|
||||
res, err := mc.UnconfirmedTxs(context.Background(), &limit)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, 1, res.Count)
|
||||
@@ -382,7 +387,7 @@ func TestNumUnconfirmedTxs(t *testing.T) {
|
||||
for i, c := range GetClients() {
|
||||
mc, ok := c.(client.MempoolClient)
|
||||
require.True(t, ok, "%d", i)
|
||||
res, err := mc.NumUnconfirmedTxs()
|
||||
res, err := mc.NumUnconfirmedTxs(context.Background())
|
||||
require.Nil(t, err, "%d: %+v", i, err)
|
||||
|
||||
assert.Equal(t, mempoolSize, res.Count)
|
||||
@@ -399,7 +404,7 @@ func TestCheckTx(t *testing.T) {
|
||||
for _, c := range GetClients() {
|
||||
_, _, tx := MakeTxKV()
|
||||
|
||||
res, err := c.CheckTx(tx)
|
||||
res, err := c.CheckTx(context.Background(), tx)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, abci.CodeTypeOK, res.Code)
|
||||
|
||||
@@ -411,7 +416,7 @@ func TestTx(t *testing.T) {
|
||||
// first we broadcast a tx
|
||||
c := getHTTPClient()
|
||||
_, _, tx := MakeTxKV()
|
||||
bres, err := c.BroadcastTxCommit(tx)
|
||||
bres, err := c.BroadcastTxCommit(context.Background(), tx)
|
||||
require.Nil(t, err, "%+v", err)
|
||||
|
||||
txHeight := bres.Height
|
||||
@@ -439,7 +444,7 @@ func TestTx(t *testing.T) {
|
||||
|
||||
// now we query for the tx.
|
||||
// since there's only one tx, we know index=0.
|
||||
ptx, err := c.Tx(tc.hash, tc.prove)
|
||||
ptx, err := c.Tx(context.Background(), tc.hash, tc.prove)
|
||||
|
||||
if !tc.valid {
|
||||
require.NotNil(t, err)
|
||||
@@ -466,11 +471,11 @@ func TestTxSearchWithTimeout(t *testing.T) {
|
||||
timeoutClient := getHTTPClientWithTimeout(10)
|
||||
|
||||
_, _, tx := MakeTxKV()
|
||||
_, err := timeoutClient.BroadcastTxCommit(tx)
|
||||
_, err := timeoutClient.BroadcastTxCommit(context.Background(), tx)
|
||||
require.NoError(t, err)
|
||||
|
||||
// query using a compositeKey (see kvstore application)
|
||||
result, err := timeoutClient.TxSearch("app.creator='Cosmoshi Netowoko'", false, nil, nil, "asc")
|
||||
result, err := timeoutClient.TxSearch(context.Background(), "app.creator='Cosmoshi Netowoko'", false, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Greater(t, len(result.Txs), 0, "expected a lot of transactions")
|
||||
}
|
||||
@@ -481,13 +486,13 @@ func TestTxSearch(t *testing.T) {
|
||||
// first we broadcast a few txs
|
||||
for i := 0; i < 10; i++ {
|
||||
_, _, tx := MakeTxKV()
|
||||
_, err := c.BroadcastTxCommit(tx)
|
||||
_, err := c.BroadcastTxCommit(context.Background(), tx)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
||||
// since we're not using an isolated test server, we'll have lingering transactions
|
||||
// from other tests as well
|
||||
result, err := c.TxSearch("tx.height >= 0", true, nil, nil, "asc")
|
||||
result, err := c.TxSearch(context.Background(), "tx.height >= 0", true, nil, nil, "asc")
|
||||
require.NoError(t, err)
|
||||
txCount := len(result.Txs)
|
||||
|
||||
@@ -499,7 +504,7 @@ func TestTxSearch(t *testing.T) {
|
||||
t.Logf("client %d", i)
|
||||
|
||||
// now we query for the tx.
|
||||
result, err := c.TxSearch(fmt.Sprintf("tx.hash='%v'", find.Hash), true, nil, nil, "asc")
|
||||
result, err := c.TxSearch(context.Background(), fmt.Sprintf("tx.hash='%v'", find.Hash), true, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Len(t, result.Txs, 1)
|
||||
require.Equal(t, find.Hash, result.Txs[0].Hash)
|
||||
@@ -517,50 +522,51 @@ func TestTxSearch(t *testing.T) {
|
||||
}
|
||||
|
||||
// query by height
|
||||
result, err = c.TxSearch(fmt.Sprintf("tx.height=%d", find.Height), true, nil, nil, "asc")
|
||||
result, err = c.TxSearch(context.Background(), fmt.Sprintf("tx.height=%d", find.Height), true, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Len(t, result.Txs, 1)
|
||||
|
||||
// query for non existing tx
|
||||
result, err = c.TxSearch(fmt.Sprintf("tx.hash='%X'", anotherTxHash), false, nil, nil, "asc")
|
||||
result, err = c.TxSearch(context.Background(), fmt.Sprintf("tx.hash='%X'", anotherTxHash), false, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Len(t, result.Txs, 0)
|
||||
|
||||
// query using a compositeKey (see kvstore application)
|
||||
result, err = c.TxSearch("app.creator='Cosmoshi Netowoko'", false, nil, nil, "asc")
|
||||
result, err = c.TxSearch(context.Background(), "app.creator='Cosmoshi Netowoko'", false, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Greater(t, len(result.Txs), 0, "expected a lot of transactions")
|
||||
|
||||
// query using an index key
|
||||
result, err = c.TxSearch("app.index_key='index is working'", false, nil, nil, "asc")
|
||||
result, err = c.TxSearch(context.Background(), "app.index_key='index is working'", false, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Greater(t, len(result.Txs), 0, "expected a lot of transactions")
|
||||
|
||||
// query using an noindex key
|
||||
result, err = c.TxSearch("app.noindex_key='index is working'", false, nil, nil, "asc")
|
||||
result, err = c.TxSearch(context.Background(), "app.noindex_key='index is working'", false, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Equal(t, len(result.Txs), 0, "expected a lot of transactions")
|
||||
|
||||
// query using a compositeKey (see kvstore application) and height
|
||||
result, err = c.TxSearch("app.creator='Cosmoshi Netowoko' AND tx.height<10000", true, nil, nil, "asc")
|
||||
result, err = c.TxSearch(context.Background(),
|
||||
"app.creator='Cosmoshi Netowoko' AND tx.height<10000", true, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Greater(t, len(result.Txs), 0, "expected a lot of transactions")
|
||||
|
||||
// query a non existing tx with page 1 and txsPerPage 1
|
||||
perPage := 1
|
||||
result, err = c.TxSearch("app.creator='Cosmoshi Neetowoko'", true, nil, &perPage, "asc")
|
||||
result, err = c.TxSearch(context.Background(), "app.creator='Cosmoshi Neetowoko'", true, nil, &perPage, "asc")
|
||||
require.Nil(t, err)
|
||||
require.Len(t, result.Txs, 0)
|
||||
|
||||
// check sorting
|
||||
result, err = c.TxSearch("tx.height >= 1", false, nil, nil, "asc")
|
||||
result, err = c.TxSearch(context.Background(), "tx.height >= 1", false, nil, nil, "asc")
|
||||
require.Nil(t, err)
|
||||
for k := 0; k < len(result.Txs)-1; k++ {
|
||||
require.LessOrEqual(t, result.Txs[k].Height, result.Txs[k+1].Height)
|
||||
require.LessOrEqual(t, result.Txs[k].Index, result.Txs[k+1].Index)
|
||||
}
|
||||
|
||||
result, err = c.TxSearch("tx.height >= 1", false, nil, nil, "desc")
|
||||
result, err = c.TxSearch(context.Background(), "tx.height >= 1", false, nil, nil, "desc")
|
||||
require.Nil(t, err)
|
||||
for k := 0; k < len(result.Txs)-1; k++ {
|
||||
require.GreaterOrEqual(t, result.Txs[k].Height, result.Txs[k+1].Height)
|
||||
@@ -576,7 +582,7 @@ func TestTxSearch(t *testing.T) {
|
||||
|
||||
for page := 1; page <= pages; page++ {
|
||||
page := page
|
||||
result, err := c.TxSearch("tx.height >= 1", false, &page, &perPage, "asc")
|
||||
result, err := c.TxSearch(context.Background(), "tx.height >= 1", false, &page, &perPage, "asc")
|
||||
require.NoError(t, err)
|
||||
if page < pages {
|
||||
require.Len(t, result.Txs, perPage)
|
||||
@@ -607,12 +613,12 @@ func testBatchedJSONRPCCalls(t *testing.T, c *rpchttp.HTTP) {
|
||||
k2, v2, tx2 := MakeTxKV()
|
||||
|
||||
batch := c.NewBatch()
|
||||
r1, err := batch.BroadcastTxCommit(tx1)
|
||||
r1, err := batch.BroadcastTxCommit(context.Background(), tx1)
|
||||
require.NoError(t, err)
|
||||
r2, err := batch.BroadcastTxCommit(tx2)
|
||||
r2, err := batch.BroadcastTxCommit(context.Background(), tx2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, batch.Count())
|
||||
bresults, err := batch.Send()
|
||||
bresults, err := batch.Send(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, bresults, 2)
|
||||
require.Equal(t, 0, batch.Count())
|
||||
@@ -628,12 +634,12 @@ func testBatchedJSONRPCCalls(t *testing.T, c *rpchttp.HTTP) {
|
||||
err = client.WaitForHeight(c, apph, nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
q1, err := batch.ABCIQuery("/key", k1)
|
||||
q1, err := batch.ABCIQuery(context.Background(), "/key", k1)
|
||||
require.NoError(t, err)
|
||||
q2, err := batch.ABCIQuery("/key", k2)
|
||||
q2, err := batch.ABCIQuery(context.Background(), "/key", k2)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, 2, batch.Count())
|
||||
qresults, err := batch.Send()
|
||||
qresults, err := batch.Send(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, qresults, 2)
|
||||
require.Equal(t, 0, batch.Count())
|
||||
@@ -657,9 +663,9 @@ func TestBatchedJSONRPCCallsCancellation(t *testing.T) {
|
||||
_, _, tx2 := MakeTxKV()
|
||||
|
||||
batch := c.NewBatch()
|
||||
_, err := batch.BroadcastTxCommit(tx1)
|
||||
_, err := batch.BroadcastTxCommit(context.Background(), tx1)
|
||||
require.NoError(t, err)
|
||||
_, err = batch.BroadcastTxCommit(tx2)
|
||||
_, err = batch.BroadcastTxCommit(context.Background(), tx2)
|
||||
require.NoError(t, err)
|
||||
// we should have 2 requests waiting
|
||||
require.Equal(t, 2, batch.Count())
|
||||
@@ -672,7 +678,7 @@ func TestBatchedJSONRPCCallsCancellation(t *testing.T) {
|
||||
func TestSendingEmptyRequestBatch(t *testing.T) {
|
||||
c := getHTTPClient()
|
||||
batch := c.NewBatch()
|
||||
_, err := batch.Send()
|
||||
_, err := batch.Send(ctx)
|
||||
require.Error(t, err, "sending an empty batch of JSON RPC requests should result in an error")
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package client
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -78,12 +79,12 @@ func (u parsedURL) GetTrimmedURL() string {
|
||||
// HTTPClient is a common interface for JSON-RPC HTTP clients.
|
||||
type HTTPClient interface {
|
||||
// Call calls the given method with the params and returns a result.
|
||||
Call(method string, params map[string]interface{}, result interface{}) (interface{}, error)
|
||||
Call(ctx context.Context, method string, params map[string]interface{}, result interface{}) (interface{}, error)
|
||||
}
|
||||
|
||||
// Caller implementers can facilitate calling the JSON-RPC endpoint.
|
||||
type Caller interface {
|
||||
Call(method string, params map[string]interface{}, result interface{}) (interface{}, error)
|
||||
Call(ctx context.Context, method string, params map[string]interface{}, result interface{}) (interface{}, error)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------
|
||||
@@ -151,7 +152,9 @@ func NewWithHTTPClient(remote string, client *http.Client) (*Client, error) {
|
||||
|
||||
// Call issues a POST HTTP request. Requests are JSON encoded. Content-Type:
|
||||
// text/json.
|
||||
func (c *Client) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||
func (c *Client) Call(ctx context.Context, method string,
|
||||
params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||
|
||||
id := c.nextRequestID()
|
||||
|
||||
request, err := types.MapToRequest(id, method, params)
|
||||
@@ -165,7 +168,7 @@ func (c *Client) Call(method string, params map[string]interface{}, result inter
|
||||
}
|
||||
|
||||
requestBuf := bytes.NewBuffer(requestBytes)
|
||||
httpRequest, err := http.NewRequest(http.MethodPost, c.address, requestBuf)
|
||||
httpRequest, err := http.NewRequestWithContext(ctx, http.MethodPost, c.address, requestBuf)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("request failed: %w", err)
|
||||
}
|
||||
@@ -195,7 +198,7 @@ func (c *Client) NewRequestBatch() *RequestBatch {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) sendBatch(requests []*jsonRPCBufferedRequest) ([]interface{}, error) {
|
||||
func (c *Client) sendBatch(ctx context.Context, requests []*jsonRPCBufferedRequest) ([]interface{}, error) {
|
||||
reqs := make([]types.RPCRequest, 0, len(requests))
|
||||
results := make([]interface{}, 0, len(requests))
|
||||
for _, req := range requests {
|
||||
@@ -206,12 +209,12 @@ func (c *Client) sendBatch(requests []*jsonRPCBufferedRequest) ([]interface{}, e
|
||||
// serialize the array of requests into a single JSON object
|
||||
requestBytes, err := json.Marshal(reqs)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to marshal requests: %w", err)
|
||||
return nil, fmt.Errorf("json marshal: %w", err)
|
||||
}
|
||||
|
||||
httpRequest, err := http.NewRequest(http.MethodPost, c.address, bytes.NewBuffer(requestBytes))
|
||||
httpRequest, err := http.NewRequestWithContext(ctx, http.MethodPost, c.address, bytes.NewBuffer(requestBytes))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("request failed: %w", err)
|
||||
return nil, fmt.Errorf("new request: %w", err)
|
||||
}
|
||||
httpRequest.Header.Set("Content-Type", "text/json")
|
||||
if c.username != "" || c.password != "" {
|
||||
@@ -219,13 +222,13 @@ func (c *Client) sendBatch(requests []*jsonRPCBufferedRequest) ([]interface{}, e
|
||||
}
|
||||
httpResponse, err := c.client.Do(httpRequest)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("post failed: %w", err)
|
||||
return nil, fmt.Errorf("post: %w", err)
|
||||
}
|
||||
defer httpResponse.Body.Close()
|
||||
|
||||
responseBytes, err := ioutil.ReadAll(httpResponse.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response body: %w", err)
|
||||
return nil, fmt.Errorf("read response body: %w", err)
|
||||
}
|
||||
|
||||
// collect ids to check responses IDs in unmarshalResponseBytesArray
|
||||
@@ -293,18 +296,19 @@ func (b *RequestBatch) clear() int {
|
||||
// Send will attempt to send the current batch of enqueued requests, and then
|
||||
// will clear out the requests once done. On success, this returns the
|
||||
// deserialized list of results from each of the enqueued requests.
|
||||
func (b *RequestBatch) Send() ([]interface{}, error) {
|
||||
func (b *RequestBatch) Send(ctx context.Context) ([]interface{}, error) {
|
||||
b.mtx.Lock()
|
||||
defer func() {
|
||||
b.clear()
|
||||
b.mtx.Unlock()
|
||||
}()
|
||||
return b.client.sendBatch(b.requests)
|
||||
return b.client.sendBatch(ctx, b.requests)
|
||||
}
|
||||
|
||||
// Call enqueues a request to call the given RPC method with the specified
|
||||
// parameters, in the same way that the `Client.Call` function would.
|
||||
func (b *RequestBatch) Call(
|
||||
_ context.Context,
|
||||
method string,
|
||||
params map[string]interface{},
|
||||
result interface{},
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
package client
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
types "github.com/tendermint/tendermint/rpc/jsonrpc/types"
|
||||
)
|
||||
@@ -49,21 +51,34 @@ func NewURI(remote string) (*URIClient, error) {
|
||||
}
|
||||
|
||||
// Call issues a POST form HTTP request.
|
||||
func (c *URIClient) Call(method string, params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||
func (c *URIClient) Call(ctx context.Context, method string,
|
||||
params map[string]interface{}, result interface{}) (interface{}, error) {
|
||||
|
||||
values, err := argsToURLValues(params)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to encode params: %w", err)
|
||||
}
|
||||
|
||||
resp, err := c.client.PostForm(c.address+"/"+method, values)
|
||||
req, err := http.NewRequestWithContext(
|
||||
ctx,
|
||||
http.MethodPost,
|
||||
c.address+"/"+method,
|
||||
strings.NewReader(values.Encode()),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("post form failed: %w", err)
|
||||
return nil, fmt.Errorf("new request: %w", err)
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("post: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
responseBytes, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to read response body: %w", err)
|
||||
return nil, fmt.Errorf("read response body: %w", err)
|
||||
}
|
||||
|
||||
return unmarshalResponseBytes(responseBytes, URIClientRequestID, result)
|
||||
|
||||
@@ -37,6 +37,10 @@ const (
|
||||
testVal = "acbd"
|
||||
)
|
||||
|
||||
var (
|
||||
ctx = context.Background()
|
||||
)
|
||||
|
||||
type ResultEcho struct {
|
||||
Value string `json:"value"`
|
||||
}
|
||||
@@ -156,7 +160,7 @@ func echoViaHTTP(cl client.Caller, val string) (string, error) {
|
||||
"arg": val,
|
||||
}
|
||||
result := new(ResultEcho)
|
||||
if _, err := cl.Call("echo", params, result); err != nil {
|
||||
if _, err := cl.Call(ctx, "echo", params, result); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return result.Value, nil
|
||||
@@ -167,7 +171,7 @@ func echoIntViaHTTP(cl client.Caller, val int) (int, error) {
|
||||
"arg": val,
|
||||
}
|
||||
result := new(ResultEchoInt)
|
||||
if _, err := cl.Call("echo_int", params, result); err != nil {
|
||||
if _, err := cl.Call(ctx, "echo_int", params, result); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return result.Value, nil
|
||||
@@ -178,7 +182,7 @@ func echoBytesViaHTTP(cl client.Caller, bytes []byte) ([]byte, error) {
|
||||
"arg": bytes,
|
||||
}
|
||||
result := new(ResultEchoBytes)
|
||||
if _, err := cl.Call("echo_bytes", params, result); err != nil {
|
||||
if _, err := cl.Call(ctx, "echo_bytes", params, result); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return result.Value, nil
|
||||
@@ -189,7 +193,7 @@ func echoDataBytesViaHTTP(cl client.Caller, bytes tmbytes.HexBytes) (tmbytes.Hex
|
||||
"arg": bytes,
|
||||
}
|
||||
result := new(ResultEchoDataBytes)
|
||||
if _, err := cl.Call("echo_data_bytes", params, result); err != nil {
|
||||
if _, err := cl.Call(ctx, "echo_data_bytes", params, result); err != nil {
|
||||
return []byte{}, err
|
||||
}
|
||||
return result.Value, nil
|
||||
|
||||
@@ -43,7 +43,7 @@ func waitForRPC() {
|
||||
}
|
||||
result := new(ctypes.ResultStatus)
|
||||
for {
|
||||
_, err := client.Call("status", map[string]interface{}{}, result)
|
||||
_, err := client.Call(context.Background(), "status", map[string]interface{}{}, result)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
package mocks
|
||||
|
||||
import (
|
||||
context "context"
|
||||
|
||||
mock "github.com/stretchr/testify/mock"
|
||||
state "github.com/tendermint/tendermint/state"
|
||||
|
||||
@@ -14,13 +16,13 @@ type StateProvider struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
// AppHash provides a mock function with given fields: height
|
||||
func (_m *StateProvider) AppHash(height uint64) ([]byte, error) {
|
||||
ret := _m.Called(height)
|
||||
// AppHash provides a mock function with given fields: ctx, height
|
||||
func (_m *StateProvider) AppHash(ctx context.Context, height uint64) ([]byte, error) {
|
||||
ret := _m.Called(ctx, height)
|
||||
|
||||
var r0 []byte
|
||||
if rf, ok := ret.Get(0).(func(uint64) []byte); ok {
|
||||
r0 = rf(height)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, uint64) []byte); ok {
|
||||
r0 = rf(ctx, height)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).([]byte)
|
||||
@@ -28,8 +30,8 @@ func (_m *StateProvider) AppHash(height uint64) ([]byte, error) {
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(uint64) error); ok {
|
||||
r1 = rf(height)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok {
|
||||
r1 = rf(ctx, height)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -37,13 +39,13 @@ func (_m *StateProvider) AppHash(height uint64) ([]byte, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// Commit provides a mock function with given fields: height
|
||||
func (_m *StateProvider) Commit(height uint64) (*types.Commit, error) {
|
||||
ret := _m.Called(height)
|
||||
// Commit provides a mock function with given fields: ctx, height
|
||||
func (_m *StateProvider) Commit(ctx context.Context, height uint64) (*types.Commit, error) {
|
||||
ret := _m.Called(ctx, height)
|
||||
|
||||
var r0 *types.Commit
|
||||
if rf, ok := ret.Get(0).(func(uint64) *types.Commit); ok {
|
||||
r0 = rf(height)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, uint64) *types.Commit); ok {
|
||||
r0 = rf(ctx, height)
|
||||
} else {
|
||||
if ret.Get(0) != nil {
|
||||
r0 = ret.Get(0).(*types.Commit)
|
||||
@@ -51,8 +53,8 @@ func (_m *StateProvider) Commit(height uint64) (*types.Commit, error) {
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(uint64) error); ok {
|
||||
r1 = rf(height)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok {
|
||||
r1 = rf(ctx, height)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
@@ -60,20 +62,20 @@ func (_m *StateProvider) Commit(height uint64) (*types.Commit, error) {
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
// State provides a mock function with given fields: height
|
||||
func (_m *StateProvider) State(height uint64) (state.State, error) {
|
||||
ret := _m.Called(height)
|
||||
// State provides a mock function with given fields: ctx, height
|
||||
func (_m *StateProvider) State(ctx context.Context, height uint64) (state.State, error) {
|
||||
ret := _m.Called(ctx, height)
|
||||
|
||||
var r0 state.State
|
||||
if rf, ok := ret.Get(0).(func(uint64) state.State); ok {
|
||||
r0 = rf(height)
|
||||
if rf, ok := ret.Get(0).(func(context.Context, uint64) state.State); ok {
|
||||
r0 = rf(ctx, height)
|
||||
} else {
|
||||
r0 = ret.Get(0).(state.State)
|
||||
}
|
||||
|
||||
var r1 error
|
||||
if rf, ok := ret.Get(1).(func(uint64) error); ok {
|
||||
r1 = rf(height)
|
||||
if rf, ok := ret.Get(1).(func(context.Context, uint64) error); ok {
|
||||
r1 = rf(ctx, height)
|
||||
} else {
|
||||
r1 = ret.Error(1)
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
package statesync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"time"
|
||||
|
||||
tmsync "github.com/tendermint/tendermint/libs/sync"
|
||||
"github.com/tendermint/tendermint/p2p"
|
||||
@@ -76,7 +78,10 @@ func newSnapshotPool(stateProvider StateProvider) *snapshotPool {
|
||||
// returns true if this was a new, non-blacklisted snapshot. The snapshot height is verified using
|
||||
// the light client, and the expected app hash is set for the snapshot.
|
||||
func (p *snapshotPool) Add(peer p2p.Peer, snapshot *snapshot) (bool, error) {
|
||||
appHash, err := p.stateProvider.AppHash(snapshot.Height)
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer cancel()
|
||||
|
||||
appHash, err := p.stateProvider.AppHash(ctx, snapshot.Height)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func TestSnapshot_Key(t *testing.T) {
|
||||
|
||||
func TestSnapshotPool_Add(t *testing.T) {
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", uint64(1)).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, uint64(1)).Return([]byte("app_hash"), nil)
|
||||
|
||||
peer := &p2pmocks.Peer{}
|
||||
peer.On("ID").Return(p2p.ID("id"))
|
||||
@@ -80,7 +80,7 @@ func TestSnapshotPool_Add(t *testing.T) {
|
||||
|
||||
func TestSnapshotPool_GetPeer(t *testing.T) {
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
pool := newSnapshotPool(stateProvider)
|
||||
|
||||
s := &snapshot{Height: 1, Format: 1, Chunks: 1, Hash: []byte{1}}
|
||||
@@ -116,7 +116,7 @@ func TestSnapshotPool_GetPeer(t *testing.T) {
|
||||
|
||||
func TestSnapshotPool_GetPeers(t *testing.T) {
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
pool := newSnapshotPool(stateProvider)
|
||||
|
||||
s := &snapshot{Height: 1, Format: 1, Chunks: 1, Hash: []byte{1}}
|
||||
@@ -140,7 +140,7 @@ func TestSnapshotPool_GetPeers(t *testing.T) {
|
||||
|
||||
func TestSnapshotPool_Ranked_Best(t *testing.T) {
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
pool := newSnapshotPool(stateProvider)
|
||||
|
||||
// snapshots in expected order (best to worst). Highest height wins, then highest format.
|
||||
@@ -185,7 +185,7 @@ func TestSnapshotPool_Ranked_Best(t *testing.T) {
|
||||
|
||||
func TestSnapshotPool_Reject(t *testing.T) {
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
pool := newSnapshotPool(stateProvider)
|
||||
peer := &p2pmocks.Peer{}
|
||||
peer.On("ID").Return(p2p.ID("id"))
|
||||
@@ -215,7 +215,7 @@ func TestSnapshotPool_Reject(t *testing.T) {
|
||||
|
||||
func TestSnapshotPool_RejectFormat(t *testing.T) {
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
pool := newSnapshotPool(stateProvider)
|
||||
peer := &p2pmocks.Peer{}
|
||||
peer.On("ID").Return(p2p.ID("id"))
|
||||
@@ -246,7 +246,7 @@ func TestSnapshotPool_RejectFormat(t *testing.T) {
|
||||
|
||||
func TestSnapshotPool_RejectPeer(t *testing.T) {
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
pool := newSnapshotPool(stateProvider)
|
||||
|
||||
peerA := &p2pmocks.Peer{}
|
||||
@@ -288,7 +288,7 @@ func TestSnapshotPool_RejectPeer(t *testing.T) {
|
||||
|
||||
func TestSnapshotPool_RemovePeer(t *testing.T) {
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
pool := newSnapshotPool(stateProvider)
|
||||
|
||||
peerA := &p2pmocks.Peer{}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package statesync
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -26,11 +27,11 @@ import (
|
||||
// to the state.State object, not the state machine.
|
||||
type StateProvider interface {
|
||||
// AppHash returns the app hash after the given height has been committed.
|
||||
AppHash(height uint64) ([]byte, error)
|
||||
AppHash(ctx context.Context, height uint64) ([]byte, error)
|
||||
// Commit returns the commit at the given height.
|
||||
Commit(height uint64) (*types.Commit, error)
|
||||
Commit(ctx context.Context, height uint64) (*types.Commit, error)
|
||||
// State returns a state object at the given height.
|
||||
State(height uint64) (sm.State, error)
|
||||
State(ctx context.Context, height uint64) (sm.State, error)
|
||||
}
|
||||
|
||||
// lightClientStateProvider is a state provider using the light client.
|
||||
@@ -44,6 +45,7 @@ type lightClientStateProvider struct {
|
||||
|
||||
// NewLightClientStateProvider creates a new StateProvider using a light client and RPC clients.
|
||||
func NewLightClientStateProvider(
|
||||
ctx context.Context,
|
||||
chainID string,
|
||||
version tmstate.Version,
|
||||
initialHeight int64,
|
||||
@@ -69,7 +71,7 @@ func NewLightClientStateProvider(
|
||||
providerRemotes[provider] = server
|
||||
}
|
||||
|
||||
lc, err := light.NewClient(chainID, trustOptions, providers[0], providers[1:],
|
||||
lc, err := light.NewClient(ctx, chainID, trustOptions, providers[0], providers[1:],
|
||||
lightdb.New(dbm.NewMemDB(), ""), light.Logger(logger), light.MaxRetryAttempts(5))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -83,12 +85,12 @@ func NewLightClientStateProvider(
|
||||
}
|
||||
|
||||
// AppHash implements StateProvider.
|
||||
func (s *lightClientStateProvider) AppHash(height uint64) ([]byte, error) {
|
||||
func (s *lightClientStateProvider) AppHash(ctx context.Context, height uint64) ([]byte, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
// We have to fetch the next height, which contains the app hash for the previous height.
|
||||
header, err := s.lc.VerifyLightBlockAtHeight(int64(height+1), time.Now())
|
||||
header, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+1), time.Now())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -96,10 +98,10 @@ func (s *lightClientStateProvider) AppHash(height uint64) ([]byte, error) {
|
||||
}
|
||||
|
||||
// Commit implements StateProvider.
|
||||
func (s *lightClientStateProvider) Commit(height uint64) (*types.Commit, error) {
|
||||
func (s *lightClientStateProvider) Commit(ctx context.Context, height uint64) (*types.Commit, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
header, err := s.lc.VerifyLightBlockAtHeight(int64(height), time.Now())
|
||||
header, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height), time.Now())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -107,7 +109,7 @@ func (s *lightClientStateProvider) Commit(height uint64) (*types.Commit, error)
|
||||
}
|
||||
|
||||
// State implements StateProvider.
|
||||
func (s *lightClientStateProvider) State(height uint64) (sm.State, error) {
|
||||
func (s *lightClientStateProvider) State(ctx context.Context, height uint64) (sm.State, error) {
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
@@ -128,15 +130,15 @@ func (s *lightClientStateProvider) State(height uint64) (sm.State, error) {
|
||||
//
|
||||
// We need to fetch the NextValidators from height+2 because if the application changed
|
||||
// the validator set at the snapshot height then this only takes effect at height+2.
|
||||
lastLightBlock, err := s.lc.VerifyLightBlockAtHeight(int64(height), time.Now())
|
||||
lastLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height), time.Now())
|
||||
if err != nil {
|
||||
return sm.State{}, err
|
||||
}
|
||||
curLightBlock, err := s.lc.VerifyLightBlockAtHeight(int64(height+1), time.Now())
|
||||
curLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+1), time.Now())
|
||||
if err != nil {
|
||||
return sm.State{}, err
|
||||
}
|
||||
nextLightBlock, err := s.lc.VerifyLightBlockAtHeight(int64(height+2), time.Now())
|
||||
nextLightBlock, err := s.lc.VerifyLightBlockAtHeight(ctx, int64(height+2), time.Now())
|
||||
if err != nil {
|
||||
return sm.State{}, err
|
||||
}
|
||||
@@ -161,7 +163,7 @@ func (s *lightClientStateProvider) State(height uint64) (sm.State, error) {
|
||||
return sm.State{}, fmt.Errorf("unable to create RPC client: %w", err)
|
||||
}
|
||||
rpcclient := lightrpc.NewClient(primaryRPC, s.lc)
|
||||
result, err := rpcclient.ConsensusParams(&nextLightBlock.Height)
|
||||
result, err := rpcclient.ConsensusParams(ctx, &nextLightBlock.Height)
|
||||
if err != nil {
|
||||
return sm.State{}, fmt.Errorf("unable to fetch consensus parameters for height %v: %w",
|
||||
nextLightBlock.Height, err)
|
||||
|
||||
@@ -241,12 +241,15 @@ func (s *syncer) Sync(snapshot *snapshot, chunks *chunkQueue) (sm.State, *types.
|
||||
go s.fetchChunks(ctx, snapshot, chunks)
|
||||
}
|
||||
|
||||
pctx, pcancel := context.WithTimeout(context.Background(), 10*time.Second)
|
||||
defer pcancel()
|
||||
|
||||
// Optimistically build new state, so we don't discover any light client failures at the end.
|
||||
state, err := s.stateProvider.State(snapshot.Height)
|
||||
state, err := s.stateProvider.State(pctx, snapshot.Height)
|
||||
if err != nil {
|
||||
return sm.State{}, nil, fmt.Errorf("failed to build new state: %w", err)
|
||||
}
|
||||
commit, err := s.stateProvider.Commit(snapshot.Height)
|
||||
commit, err := s.stateProvider.Commit(pctx, snapshot.Height)
|
||||
if err != nil {
|
||||
return sm.State{}, nil, fmt.Errorf("failed to fetch commit: %w", err)
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ func setupOfferSyncer(t *testing.T) (*syncer, *proxymocks.AppConnSnapshot) {
|
||||
connQuery := &proxymocks.AppConnQuery{}
|
||||
connSnapshot := &proxymocks.AppConnSnapshot{}
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
syncer := newSyncer(log.NewNopLogger(), connSnapshot, connQuery, stateProvider, "")
|
||||
return syncer, connSnapshot
|
||||
}
|
||||
@@ -77,10 +77,10 @@ func TestSyncer_SyncAny(t *testing.T) {
|
||||
s := &snapshot{Height: 1, Format: 1, Chunks: 3, Hash: []byte{1, 2, 3}}
|
||||
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", uint64(1)).Return(state.AppHash, nil)
|
||||
stateProvider.On("AppHash", uint64(2)).Return([]byte("app_hash_2"), nil)
|
||||
stateProvider.On("Commit", uint64(1)).Return(commit, nil)
|
||||
stateProvider.On("State", uint64(1)).Return(state, nil)
|
||||
stateProvider.On("AppHash", mock.Anything, uint64(1)).Return(state.AppHash, nil)
|
||||
stateProvider.On("AppHash", mock.Anything, uint64(2)).Return([]byte("app_hash_2"), nil)
|
||||
stateProvider.On("Commit", mock.Anything, uint64(1)).Return(commit, nil)
|
||||
stateProvider.On("State", mock.Anything, uint64(1)).Return(state, nil)
|
||||
connSnapshot := &proxymocks.AppConnSnapshot{}
|
||||
connQuery := &proxymocks.AppConnQuery{}
|
||||
|
||||
@@ -406,7 +406,7 @@ func TestSyncer_applyChunks_Results(t *testing.T) {
|
||||
connQuery := &proxymocks.AppConnQuery{}
|
||||
connSnapshot := &proxymocks.AppConnSnapshot{}
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
syncer := newSyncer(log.NewNopLogger(), connSnapshot, connQuery, stateProvider, "")
|
||||
|
||||
body := []byte{1, 2, 3}
|
||||
@@ -457,7 +457,7 @@ func TestSyncer_applyChunks_RefetchChunks(t *testing.T) {
|
||||
connQuery := &proxymocks.AppConnQuery{}
|
||||
connSnapshot := &proxymocks.AppConnSnapshot{}
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
syncer := newSyncer(log.NewNopLogger(), connSnapshot, connQuery, stateProvider, "")
|
||||
|
||||
chunks, err := newChunkQueue(&snapshot{Height: 1, Format: 1, Chunks: 3}, "")
|
||||
@@ -520,7 +520,7 @@ func TestSyncer_applyChunks_RejectSenders(t *testing.T) {
|
||||
connQuery := &proxymocks.AppConnQuery{}
|
||||
connSnapshot := &proxymocks.AppConnSnapshot{}
|
||||
stateProvider := &mocks.StateProvider{}
|
||||
stateProvider.On("AppHash", mock.Anything).Return([]byte("app_hash"), nil)
|
||||
stateProvider.On("AppHash", mock.Anything, mock.Anything).Return([]byte("app_hash"), nil)
|
||||
syncer := newSyncer(log.NewNopLogger(), connSnapshot, connQuery, stateProvider, "")
|
||||
|
||||
// Set up three peers across two snapshots, and ask for one of them to be banned.
|
||||
|
||||
Reference in New Issue
Block a user