Skip to content

Commit

Permalink
generalize header interface
Browse files Browse the repository at this point in the history
  • Loading branch information
Ganesha Upadhyaya authored and Ganesha Upadhyaya committed Oct 27, 2023
1 parent 2844778 commit baef0b9
Show file tree
Hide file tree
Showing 4 changed files with 27 additions and 48 deletions.
12 changes: 6 additions & 6 deletions p2p/p2p.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ The Subscriber encompasses the behavior necessary to subscribe/unsubscribe from

|Method|Input|Output|Description|
|--|--|--|--|
| Subscribe | | `Subscription[H], error` | Subscribe creates long-living Subscription for validated Headers. Multiple Subscriptions can be created. |
| SetVerifier | `func(context.Context, H) error` | error | SetVerifier registers verification func for all Subscriptions. Registered func screens incoming headers before they are forwarded to Subscriptions. Only one func can be set.|
| Subscribe | | Subscription[H], error | Subscribe creates long-living Subscription for validated Headers. Multiple Subscriptions can be created. |
| SetVerifier | func(context.Context, H) error | error | SetVerifier registers verification func for all Subscriptions. Registered func screens incoming headers before they are forwarded to Subscriptions. Only one func can be set.|

The `Subscribe()` method allows listening to any new headers that are published to the P2P network. The `SetVerifier()` method allows for setting a custom verifier that will be executed upon receiving any new headers from the P2P network. This is a very useful customization for the consumers of go-header library to pass any custom logic as part of the pubsub. While multiple simultaneous subscriptions are possible via `Subscribe()` interface, only a single verifier can be set using the `SetVerifier` interface method.

Expand Down Expand Up @@ -62,10 +62,10 @@ The exchange client implements the following `Getter` interface which contains t

|Method|Input|Output|Description|
|--|--|--|--|
| Head | `context.Context, ...HeadOption[H]` | `H, error` | Head returns the latest known chain header. Note that "chain head" is subjective to the component reporting it. |
| Get | `context.Context, Hash` | `H, error` | Get returns the Header corresponding to the given hash. |
| GetByHeight | `context.Context, uint64` | `H, error` | GetByHeight returns the Header corresponding to the given block height. |
| GetRangeByHeight | `ctx context.Context, from H, to uint64` | `[]H, error` | GetRangeByHeight requests the header range from the provided Header and verifies that the returned headers are adjacent to each other. Expected to return the range [from.Height()+1:to).|
| Head | context.Context, ...HeadOption[H] | H, error | Head returns the latest known chain header. Note that "chain head" is subjective to the component reporting it. |
| Get | context.Context, Hash | H, error | Get returns the Header corresponding to the given hash. |
| GetByHeight | context.Context, uint64 | H, error | GetByHeight returns the Header corresponding to the given block height. |
| GetRangeByHeight | ctx context.Context, from H, to uint64 | []H, error | GetRangeByHeight requests the header range from the provided Header and verifies that the returned headers are adjacent to each other. Expected to return the range [from.Height()+1:to).|

`Head()` method requests the latest header from trusted or tracked peers. The `Head()` call also allows passing an optional `TrustedHead`, which allows the caller to specify a trusted head against which the untrusted head is verified. By default, `Head()` requests only trusted peers and if `TrustedHead` is provided untrusted tracked peers are also requested, limited to [maxUntrustedHeadRequests][maxUntrustedHeadRequests]. The `Head()` requests utilize 90% of the set deadline (in the form of context deadline) for requests and the remaining for determining the best head from gathered responses. Upon receiving headers from peers (either trusted or tracked), the best head is determined as the head:

Expand Down
46 changes: 13 additions & 33 deletions specs/src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,39 +14,19 @@ go-header is a library for syncing blockchain data, such as block headers, over

The go-header library makes it easy to be used by other projects by defining a clear interface (as described below). An example usage is defined in [headertest/dummy_header.go][dummy header]

```
type Header[H any] interface {
// New creates new instance of a header.
New() H
// IsZero reports whether Header is a zero value of it's concrete type.
IsZero() bool
// ChainID returns identifier of the chain.
ChainID() string
// Hash returns hash of a header.
Hash() Hash
// Height returns the height of a header.
Height() uint64
// LastHeader returns the hash of last header before this header (aka. previous header hash).
LastHeader() Hash
// Time returns time when header was created.
Time() time.Time
// Verify validates given untrusted Header against trusted Header.
Verify(H) error
// Validate performs stateless validation to check for missed/incorrect fields.
Validate() error
encoding.BinaryMarshaler
encoding.BinaryUnmarshaler
}
```
|Method|Input|Output|Description|
|--|--|--|--|
| New | | H | New creates new instance of a header. |
| IsZero | | bool | IsZero reports whether Header is a zero value of it's concrete type. |
| ChainID | | string | ChainID returns identifier of the chain. |
| Hash | | Hash | Hash returns hash of a header. |
| Height | | uint64 | Height returns the height of a header. |
| LastHeader | | Hash | LastHeader returns the hash of last header before this header (aka. previous header hash). |
| Time | | time.Time | Time returns time when header was created. |
| Verify | H | error | Verify validates given untrusted Header against trusted Header. |
| Validate | | error | Validate performs stateless validation to check for missed/incorrect fields. |
| MarshalBinary | | []byte, error| MarshalBinary encodes the receiver into a binary form and returns the result. |
| UnmarshalBinary | []byte | error | UnmarshalBinary must be able to decode the form generated by MarshalBinary. UnmarshalBinary must copy the data if it wishes to retain the data after returning.|

# References

Expand Down
10 changes: 5 additions & 5 deletions store/store.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ Store encompasses the behavior necessary to store and retrieve headers from a no

|Method|Input|Output|Description|
|--|--|--|--|
| Init | `context.Context, H` | `error` | Init initializes Store with the given head, meaning it is initialized with the genesis header. |
| Height | | `uint64` | Height reports current height of the chain head. |
| Has | `context.Context, Hash` | `bool, error` | Has checks whether Header is already stored. |
| HasAt | `context.Context, uint64` | `bool` | HasAt checks whether Header at the given height is already stored. |
| Append | `context.Context, ...H` | `error` | Append stores and verifies the given Header(s). It requires them to be adjacent and in ascending order, as it applies them contiguously on top of the current head height. It returns the amount of successfully applied headers, so caller can understand what given header was invalid, if any. |
| Init | context.Context, H | error | Init initializes Store with the given head, meaning it is initialized with the genesis header. |
| Height | | uint64 | Height reports current height of the chain head. |
| Has | context.Context, Hash | bool, error | Has checks whether Header is already stored. |
| HasAt | context.Context, uint64 | bool | HasAt checks whether Header at the given height is already stored. |
| Append | context.Context, ...H | error | Append stores and verifies the given Header(s). It requires them to be adjacent and in ascending order, as it applies them contiguously on top of the current head height. It returns the amount of successfully applied headers, so caller can understand what given header was invalid, if any. |

A new store is created by passing a [datastore][go-datastore] instance and an optional head. If the head is not passed while creating a new store, `Init` method can be used to later initialize the store with head. The store must have a head before start. The head is considered trusted header and generally it is the genesis header. A custom store prefix can be passed during the store initialization. Further, a set of parameters can be passed during the store initialization to configure the store as described below.

Expand Down
7 changes: 3 additions & 4 deletions sync/sync.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,9 @@ Known subjective head is considered network head if it is recent (`now - timesta

The header interface defines a `Verify` method which gets invoked when any new header is received via `incomingNetworkHead`.

```
// Verify validates given untrusted Header against trusted Header.
Verify(H) error
```
|Method|Input|Output|Description|
|--|--|--|--|
| Verify | H | error | Verify validates given untrusted Header against trusted Header. |

## syncLoop

Expand Down

0 comments on commit baef0b9

Please sign in to comment.