Commit Graph

65 Commits

Author SHA1 Message Date
Anton Kaliaev
a14ff5cb30 rpc: refactor lib folder (#4836)
Closes https://github.com/tendermint/tendermint/issues/3857

Moves `lib/` folder to `jsonrpc/`.

Renames:

**packages**

`rpc` package -> `jsonrpc` package
`rpcclient` package -> `client` package
`rpcserver` package -> `server` package

**structs and interfaces**

```
JSONRPCClient to Client
JSONRPCRequestBatch to RequestBatch
JSONRPCCaller to Caller
```

**functions**

```
StartHTTPServer to Serve
StartHTTPAndTLSServer to ServeTLS

rpc/jsonrpc/client: rename NewURIClient to NewURI

NewJSONRPCClient to New
NewJSONRPCClientWithHTTPClient to NewWithHTTPClient
NewWSClient to NewWS
```

**misc**

- unexpose `ResponseWriterWrapper`
- remove unused http_params.go
2020-05-13 16:40:57 +04:00
Anton Kaliaev
b7b721c484 change use of errors.Wrap to fmt.Errorf with %w verb
Closes #4603

Commands used (VIM):

```
:args `rg -l errors.Wrap`
:argdo normal @q | update
```

where q is a macros rewriting the `errors.Wrap` to `fmt.Errorf`.
2020-05-12 03:35:47 +00:00
Anton Kaliaev
d202fab478 types: simplify VerifyCommitTrusting
Closes #4783 

It looks like we're validating Commit twice. Also, height and blockID params were coming from the commit, so no need to pass them separately.
2020-05-07 09:24:31 +00:00
Anton Kaliaev
25890a6635 types: sort validators by voting power
thus enabling faster commit verification assuming non uniform distribution of power.

Closes #2478

spec: https://github.com/tendermint/spec/pull/91
2020-05-06 07:37:36 +00:00
Erik Grinaker
3e1c88fda8 lite: fix HTTP provider error handling
Fixes #4739, kind of. See #4740 for the proper fix.

---

For contributor use:

- [x] Wrote tests
- [x] Updated CHANGELOG_PENDING.md
- [x] Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
- [x] Updated relevant documentation (`docs/`) and code comments
- [x] Re-reviewed `Files changed` in the Github PR explorer
- [x] Applied Appropriate Labels
2020-04-25 12:34:01 +00:00
Alexander Bezobchuk
9f29672e23 types: implement Header#ValidateBasic (#4638)
- Move core stateless validation of the Header type to a ValidateBasic method.
- Call header.ValidateBasic during a SignedHeader validation.
- Call header.ValidateBasic during a PhantomValidatorEvidence validation.
- Call header.ValidateBasic during a LunaticValidatorEvidence validation.

lite tests are skipped since the package is deprecated, no need to waste time on it

closes: #4572

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-04-24 11:45:38 +04:00
Anton Kaliaev
41c11ad2c1 evidence: handling evidence from light client(s) (#4532)
Closes: #4530

This PR contains logic for both submitting an evidence by the light client (lite2 package) and receiving it on the Tendermint side (/broadcast_evidence RPC and/or EvidenceReactor#Receive). Upon receiving the ConflictingHeadersEvidence (introduced by this PR), the Tendermint validates it, then breaks it down into smaller pieces (DuplicateVoteEvidence, LunaticValidatorEvidence, PhantomValidatorEvidence, PotentialAmnesiaEvidence). Afterwards, each piece of evidence is verified against the state of the full node and added to the pool, from which it's reaped upon block creation.

* rpc/client: do not pass height param if height ptr is nil

* rpc/core: validate incoming evidence!

* only accept ConflictingHeadersEvidence if one

of the headers is committed from this full node's perspective

This simplifies the code. Plus, if there are multiple forks, we'll
likely to receive multiple ConflictingHeadersEvidence anyway.

* swap CommitSig with Vote in LunaticValidatorEvidence

Vote is needed to validate signature

* no need to embed client

http is a provider and should not be used as a client
2020-04-22 11:29:05 +04:00
Anton Kaliaev
349556c6d9 lite2/rpc: verify block results and validators (#4703)
Closes: #4695

Verify /block_results and /validators responses from an HTTP client using the light client.

Added count and total to /validators response.

Refs #3113
2020-04-20 16:38:34 +04:00
Anton Kaliaev
26c9134f35 lite2: verify ConsensusHash in rpc client
______

For contributor use:

- [ ] Wrote tests
- [ ] Updated CHANGELOG_PENDING.md
- [ ] Linked to Github issue with discussion and accepted design OR link to spec that describes this work.
- [ ] Updated relevant documentation (`docs/`) and code comments
- [x] Re-reviewed `Files changed` in the Github PR explorer
2020-04-20 05:56:18 +00:00
Marko
499f9ed153 lint: add review dog (#4652)
* lint: add review dog

- golangci is being deprecated on the 15th

Signed-off-by: Marko Baricevic <marbar3778@yahoo.com>
2020-04-07 10:28:26 +02:00
Alexander Bezobchuk
c11013f094 lite2: Default to http scheme in provider.New (#4649)
Closes: #4643
2020-04-06 21:06:33 +04:00
Erik Grinaker
fdf9c7ae64 rpc/client: split out client packages (#4628)
* rpc/client: initial split into directories

* lite2: split out test package

* rpc/client: simplify client constructurs

* updated docs

* updated changelog
2020-04-02 13:25:30 +00:00
Anton Kaliaev
6c88d2ba1f lite2: make maxClockDrift an option (#4616)
Closes #4607
2020-03-31 16:33:33 +04:00
Callum Waters
5c380cdacb lite2: use bisection for some of backward verification (#4575)
Closes: #4537

Uses SignedHeaderBefore to find header before unverified header and then bisection to verify the header. Only when header is between first and last trusted header height else if before the first trusted header height then regular backwards verification is used.
2020-03-31 16:20:22 +04:00
Callum Waters
a25faed5f0 lite2: cache headers in bisection (#4562)
Closes: #4546

The algorithm uses an array to store the headers and validators and populates it at every bisection (which is an unsuccessful verification). When a successful verification finally occurs it updates the new trusted header, trims that header from the cache (the array) and sets the depth pointer back to 0. Instead of retrieving new headers it will use the cached headers, incrementing in depth until it reaches the end of the cache which by then it will start to retrieve new headers from the provider. 

Mathematically, this method doesn't properly bisect after the first round but it will always choose a pivot header that is within 1/8th of the upper header's height. I.e. if we are trying to jump 128 headers, the maximum offset from bisection height (64) is 64 + 16(128/8) = 80, therefore a better heuristic would be to obtain the new pivot header height as the middle of these two numbers which would therefore mean to multiply it by 9/16ths instead of 1/2  (sorry this might be a bit more complicated in writing but I can try better explain if someone is interested). Therefore I would also, upon consensus, propose that we change the pivot height to 9/16th's of the previous height
2020-03-26 12:38:02 +01:00
Marko
044f1bf288 format: add format cmd & goimport repo (#4586)
* format: add format cmd & goimport repo

- replaced format command
- added goimports to format command
- ran goimports

Signed-off-by: Marko Baricevic <marbar3778@yahoo.com>

* fix outliers & undo proto file changes
2020-03-23 09:19:26 +01:00
Callum Waters
038aff1fdb lite2: add benchmarking tests (#4514)
Closes #4392
Refs #4504
2020-03-12 10:57:06 +04:00
Callum Waters
b6f0aa3a88 lite2: replace primary when providing invalid header (#4523)
Closes: #4420 

Created a new error ErrInvalidHeaderwhich can be formed during the verification process verifier.go and will result in the replacement of the primary provider with a witness by executing: replacePrimaryProvider()

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-03-06 23:05:20 +04:00
Anton Kaliaev
d3f965ba68 lite2: indicate success/failure of Update (#4536)
error itself is not enough since it only signals if there were any
errors. Either (types.SignedHeader) or (success bool) is needed to
indicate the status of the operation. Returning a header is optimal
since most of the clients will want to get a newly verified header
anyway.
2020-03-06 17:10:28 +04:00
Anton Kaliaev
431618cef6 lite2: remove auto update (#4535)
We first introduced auto-update as a separate struct AutoClient, which
was wrapping Client and calling Update periodically.

// AutoClient can auto update itself by fetching headers every N seconds.
type AutoClient struct {
    base         *Client
    updatePeriod time.Duration
    quit         chan struct{}

    trustedHeaders chan *types.SignedHeader
    errs           chan error
}

// NewAutoClient creates a new client and starts a polling goroutine.
func NewAutoClient(base *Client, updatePeriod time.Duration) *AutoClient {
    c := &AutoClient{
        base:           base,
        updatePeriod:   updatePeriod,
        quit:           make(chan struct{}),
        trustedHeaders: make(chan *types.SignedHeader),
        errs:           make(chan error),
    }
    go c.autoUpdate()
    return c
}

// TrustedHeaders returns a channel onto which new trusted headers are posted.
func (c *AutoClient) TrustedHeaders() <-chan *types.SignedHeader {
    return c.trustedHeaders
}

// Err returns a channel onto which errors are posted.
func (c *AutoClient) Errs() <-chan error {
    return c.errs
}

// Stop stops the client.
func (c *AutoClient) Stop() {
    close(c.quit)
}

func (c *AutoClient) autoUpdate() {
    ticker := time.NewTicker(c.updatePeriod)
    defer ticker.Stop()

    for {
        select {
        case <-ticker.C:
            lastTrustedHeight, err := c.base.LastTrustedHeight()
            if err != nil {
                c.errs <- err
                continue
            }

            if lastTrustedHeight == -1 {
                // no headers yet => wait
                continue
            }

            newTrustedHeader, err := c.base.Update(time.Now())
            if err != nil {
                c.errs <- err
                continue
            }

            if newTrustedHeader != nil {
                 c.trustedHeaders <- newTrustedHeader
            }
        case <-c.quit:
            return
        }
    }
}

Later we merged it into the Client itself with the assumption that most clients will want it.

But now I am not sure. Neither IBC nor cosmos/relayer are using it. It increases complexity (Start/Stop methods).

That said, I think it makes sense to remove it until we see a need for it (until we better understand usage behavior). We can always introduce it later 😅. Maybe in the form of AutoClient.
2020-03-06 13:33:07 +04:00
Callum Waters
ff786515b8 lite: add helper functions for initiating the light client (#4486)
* add new net client

* hijack example test

* lint fixes

* reorganised file structure

* renamed funcs and added documentation

* implemented suggested changes

* restored example tests

* edited comments

* Update lite2/setup.go

Co-Authored-By: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com>

* Update lite2/client.go

* lite cmds use HTTP client

* better naming

* Delete go.sum

* Delete go.mod

* restore go mod

* restore go.sum

* fix double import

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
Co-authored-by: Bot from GolangCI <42910462+golangcibot@users.noreply.github.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2020-03-03 12:00:06 +00:00
Anton Kaliaev
9bf8f41ac9 lite2: fix tendermint lite sub command (#4505)
* lite2: fix tendermint lite sub command

- better logging
- chainID as an argument
- more examples

* one more log msg

* lite2: fire update right away after start

* turn off auto update in verification tests

Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
2020-03-02 06:51:36 +00:00
Anton Kaliaev
3f883bb80a lite2: actually run example tests + clock drift (#4487)
Closes: #4488

## Commits:

* run example tests

* introduce max clock drift

clockDrift variable from the spec.
10s should cover most of the clients.

References:

- http://vancouver-webpages.com/time/web.html
- https://blog.codinghorror.com/keeping-time-on-the-pc/

* fix ExampleClient_Update

* add test

* increase clock drift

* fix linter warning
2020-02-27 17:26:28 +01:00
Anton Kaliaev
b5f6bfa4f9 lite2: return height as 2nd return param in TrustedValidatorSet (#4479)
Closes #4473
2020-02-27 16:10:01 +01:00
Callum Waters
6be0e13823 lite2: prune-headers (#4478)
closes #4469

Improved speed of cleanup by using SignedHeaderAfter instead of TrustedHeader to jump from header to header.

Prune() is now called when a new header and validator set are saved and is a function dealt by the database itself

## Commits:

* prune headers and vals

* modified cleanup and tests

* fixes after my own review

* implement Prune func

* make db ops concurrently safe

* use Iterator in SignedHeaderAfter

we should iterate from height+1, not from the end!

* simplify cleanup

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-02-27 14:57:17 +01:00
Anton Kaliaev
6daea31f50 lite2: remove expiration checks on functions that don't require them (#4477)
closes: #4455

Verifying backwards checks that the trustedHeader hasn't expired both before and after the loop in case of verifying many headers (a longer operation), but not during the loop itself.

TrustedHeader() no longer checks whether the header saved in the store has expired.

Tests have been updated to reflect the changes

## Commits:

* verify headers backwards out of trust period

* removed expiration check in trusted header func

* modified tests to reflect changes

* wrote new tests for backwards verification

* modified TrustedHeader and TrustedValSet functions

* condensed test functions

* condensed test functions further

* fix build error

* update doc

* add comments

* remove unnecessary declaration

* extract latestHeight check into a separate func

Co-authored-by: Callum Waters <cmwaters19@gmail.com>
2020-02-26 16:15:05 +01:00
Callum Waters
9231b52e0d lite2: cross-check first header and update tests (#4471)
closes #4464
2020-02-26 12:56:20 +01:00
Anton Kaliaev
c4f7256766 lite2: store current validator set (#4472)
Before we were storing trustedHeader (height=1) and trustedNextVals
(height=2).

After this change, we will be storing trustedHeader (height=1) and
trustedVals (height=1). This a) simplifies the code b) fixes #4399
inconsistent pairing issue c) gives a relayer access to the current
validator set #4470.

The only downside is more jumps during bisection. If validator set
changes between trustedHeader and the next header (by 2/3 or more), the
light client will be forced to download the next header and check that
2/3+ signed the transition. But we don't expect validator set change too
much and too often, so it's an acceptable compromise.

Closes #4470 and #4399
2020-02-26 10:20:51 +01:00
Callum Waters
f934ca82fc lite2: don't save intermediate headers (#4452)
closes #4426

The sequence and bisection methods no longer save the intermediate headers and validator sets that they require to verify a currently untrusted header.

## Commits:

* sequence and bisection don't save intermediate headers and vals

* check the next validator hash matches the header

* check expired header at start of backwards verification

* added tests

* handled cleanup warning

* lint fix

* removed redundant code

* tweaked minor errors

* avoided premature trusting of nextVals

* fix test error

* updated trustedHeader and Vals together

* fixed bisection error

* fixed sequence error for different vals and made test

* fixes after my own review

* reorder vars to be consistent

with the rest of the code

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-02-24 11:10:41 +01:00
Callum Waters
2c7af01cb6 lite2: return already verified headers and verify earlier headers (#4428)
closes #4413 and #4419

When VerifyHeaderAtHeight() is called, TrustedHeader is initially run to check if the header has already been verified and returns the Header.

If the new header height is less than the lite clients latestTrustedHeader height, than backwards verification is performed else either sequence or bisection

Refactored a test to reflect the changes

* use trustedHeader func for already verified Headers

* remove fetch missing header from TrustedHeader

* check for already trusted Header in VerifyHeaderAtHeight

* replace updateTrustedHeaderAndVals to updateTrustedHeaderAndNextVals

* rename trustedHeader and trustedNextVals

* refactored backwards and included it in VerifyHeader

* cleaned up test to match changes

* lite2: fixes after my own review

Refs https://github.com/tendermint/tendermint/pull/4428#pullrequestreview-361730169

* fix ineffectual assignment

* lite2: check that header exists in VerifyHeader

* extract function

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-02-20 15:45:11 +01:00
Callum Waters
1874a97170 lite: modified bisection to loop (#4400)
refs #4329

As opposed to using recursion to implement the bisection method of verifying a header, which could have problems with memory allocation (especially for smaller devices), the bisection algorithm now uses a for loop.

* modified bisection to loop

* made lint changes

* made lint changes

* move note to VerifyHeader

since it applies both for sequence and bisection

* test bisection jumps to header signed by 1/3+

 of old validator set

* update labels in debug log calls

* copy tc

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-02-19 15:18:52 +01:00
Callum Waters
f5901ea460 lite2: divide verify functions (#4412)
Closes #4398

* divided verify functions

* extacted method

* renamed functions. Created standard Verify function

* checked non-adjacency. separated VerifyCommit

* lint fixes

* fix godoc documentation for VerifyAdjacent and VerifyNonAdjacent

* add a comment about VerifyCommit being the last check

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-02-18 16:10:04 +01:00
Anton Kaliaev
c56fd04ab4 lite2: disconnect from bad nodes (#4388)
Closes #4385

* extract TrustOptions into its own file

* print trusted hash before asking whenever to rollback or not

so the user could reset the light client with the trusted header

* do not return an error if rollback is aborted

reason: we trust the old header presumably, so can continue from it.

* add note about time of initial header

* improve logging and add comments

* cross-check newHeader after LC verified it

* check if header is not nil

so we don't crash on the next line

* remove witness if it sends us incorrect header

* require at least one witness

* fix build and tests

* rename tests and assert for specific error

* wrote a test

* fix linter errors

* only check 1/3 if headers diverge
2020-02-14 17:04:56 +01:00
Callum Waters
58620af5e0 lite2: modified sequence method to match bisection (#4403)
Currently the sequence function always starts from the trustedHeader and trustedNextVals stored in the lite client. Whereas the bisection one allows the method to be started from any combination of header and validator set. I opened up the sequence verification method to do the same
2020-02-14 14:52:50 +01:00
Anton Kaliaev
774aff5f7d docs: update Light Client Protocol page (#4405)
* docs: update Light Client Protocol page

Closes #4331

* one way to get hash & height
2020-02-14 11:22:17 +01:00
Anton Kaliaev
16aae3a361 Merge branch 'master' into callum/clean-lite-tests 2020-02-11 17:35:10 +01:00
Anton Kaliaev
ab6ac6d435 lite2: improve string output of all existing providers (#4387)
before:
&http{AFBSD743A...}

after:
http{https://127.0.0.1:26657}

Co-authored-by: Marko <marbar3778@yahoo.com>
2020-02-11 17:30:26 +01:00
Callum Michael Waters
4787f7c2dd refactored lite client tests 2020-02-11 17:17:48 +01:00
Callum Waters
da813e4e36 lite2: manage witness dropout (#4380)
* witnesses are dropped after no response

* test witness dropout

* corrected import structure

* moved non responsiveness check to compare function

* removed dropout test as witnesses are never dropped

* created test to compare witnesses
2020-02-11 10:41:58 +01:00
Anton Kaliaev
aeb6cc475e lite2: return if there are no headers in RemoveNoLongerTrustedHeaders (#4378) 2020-02-07 16:31:46 +01:00
Anton Kaliaev
b2832c66af lite2: validate TrustOptions, add NewClientFromTrustedStore (#4374)
* validate trust options

* add NewClientFromTrustedStore func

* make maxRetryAttempts an option

Closes #4370

* hash size should be equal to tmhash.Size

* make maxRetryAttempts uint

* make maxRetryAttempts uint16

maxRetryAttempts possible - 68 years

* we do not store trustingPeriod

* added test to create client from trusted store

* remove header and vals from primary

to make sure we're restoring them from the DB
2020-02-07 14:37:20 +01:00
Callum Waters
af37db39b0 lite2: cross-check new header with all witnesses (#4373)
As opposed to checking a random witness, all witnesses provided should be used as a reference against the header provided by the primary node. This increases security (at the tradeoff of speed) but also gives control to the user. The more witnesses provided, the more secure the lite client can be.
2020-02-06 15:36:13 +01:00
Callum Waters
bb7a80ec7e lite2: fetch missing headers (#4362)
Closes #4328

When TrustedHeader(height) is called, if the height is less than the trusted height but the header is not in the trusted store then a function finds the previous lowest height with a trusted header and performs a forwards sequential verification to the header of the height that was given. If no error is found it updates the trusted store with the header and validator set for that height and can then return them to the user.

Commits:

* drafted trusted header

* created function to find previous trusted height

* updates missing headers less than the trusted height

* minor cosmetic tweaks

* incorporated suggestions

* lite2: implement Backwards verification

and add SignedHeaderAfter func to Store interface

Refs https://github.com/tendermint/tendermint/issues/4328#issuecomment-581878549

* remove unused method

* write tests

* start with next height in SignedHeaderAfter func

* fix linter errors

* address Callum's comments

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-02-06 12:30:37 +01:00
Callum Waters
df3eee455c lite2: replace primary provider with alternative when unavailable (#4354)
Closes issue #4338

Uses a wrapper function around both the signedHeader and validatorSet calls to the primary provider which attempts to retrieve the information 5 times before deeming the provider unavailable and replacing the primary provider with the first alternative before trying recursively again (until all alternatives are depleted)

Employs a mutex lock for any operations involving the providers of the light client to ensure no operations occurs whilst the new primary is chosen.

Commits:

* created swapProvider function

* eliminates old primary provider after replacement. Uses a mutex when changing providers

* renamed to replaceProvider

* created wrapped functions for signed header and val set

* created test for primary provider replacement

* implemented suggested revisions

* created Witnesses() and Primary()

* modified backoffAndJitterTime

* modified backoffAndJitterTime

* changed backoff base and jitter to functional arguments

* implemented suggested changes

* removed backoff function

* changed exp function to match go version

* halved the backoff time

* removed seeding and added comments

* fixed incorrect test

* extract backoff timeout calc into a function

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-02-04 13:02:20 +01:00
Anton Kaliaev
1edb542f99 lite2: make witnesses mandatory (#4358)
* lite2: make witnesses mandatory

at least one witness is required

* lite2: return an error if there are no witnesses

https://github.com/tendermint/tendermint/pull/4358#pullrequestreview-350635444

* cmd/lite: add witnesses flag

* fix linter errors
2020-02-03 13:59:16 +01:00
Callum Waters
71d50f7ab5 lite2: panic if witness is on another chain (#4356)
Closes #4350

Checks that the chain ID of the witness and that of the lite client are the same before updating the witness list.
2020-01-30 11:21:17 +04:00
Anton Kaliaev
79b99f052b lite2: batch save & delete operations in DB store (#4345)
Closes #4330
2020-01-29 10:14:32 +04:00
Callum Waters
85244a42ea lite2: refactor cleanup() (#4343)
* lite2: add Start method

There are few reasons to do that:

1) separation of state and dynamics (some users will want to delay
   starting the light client; does not matter we should not allow them
   to create a light client object)
2) less important, but some users might not need autoUpdateRoutine and
   removeNoLongerTrustedHeadersRoutine routines

* lite2: wait till routines are finished in Stop

because they are started in Start, it feels more natural to wait for
them to finish in Stop.

* lite2: add TrustedValidatorSet func

* refactor cleanup code

* changed restore header and val function to handle negative height

* reverted restoreTrustedHeaderAndNextVals() functionality

Co-authored-by: Anton Kaliaev <anton.kalyaev@gmail.com>
2020-01-28 20:16:16 +04:00
Anton Kaliaev
6f93cfa548 lite2: rename alternative providers to witnesses (#4344)
Closes #4341
2020-01-28 14:30:14 +04:00
Anton Kaliaev
d90dc9db26 rpc: add sort_order option to tx_search (#4342)
I have added order_by which can be "asc" or "desc" (should be in string format) in the tx_search RPC method.

Fixes: #3333

Author: @princesinha19
2020-01-27 21:20:56 +04:00