-
Notifications
You must be signed in to change notification settings - Fork 179
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add RPC support for Beefy & MMR (#249)
* Add client support for Beefy & MMR * Fix lint errors * Fix tests * Add more unit tests * Add OptionalSignedCommitment type * Remove obsolete JSON marshalling code * update things * fix bugs * fixlint
- Loading branch information
Showing
13 changed files
with
680 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls | ||
// | ||
// Copyright 2021 Snowfork | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package beefy | ||
|
||
import ( | ||
"github.com/centrifuge/go-substrate-rpc-client/v4/client" | ||
) | ||
|
||
// Beefy exposes methods for retrieval of chain data | ||
type Beefy struct { | ||
client client.Client | ||
} | ||
|
||
// NewBeefy creates a new Chain struct | ||
func NewBeefy(cl client.Client) Beefy { | ||
return Beefy{cl} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package beefy | ||
|
||
import ( | ||
"os" | ||
"testing" | ||
|
||
"github.com/centrifuge/go-substrate-rpc-client/v4/client" | ||
"github.com/centrifuge/go-substrate-rpc-client/v4/config" | ||
) | ||
|
||
var beefy Beefy | ||
|
||
func TestMain(m *testing.M) { | ||
cl, err := client.Connect(config.Default().RPCURL) | ||
if err != nil { | ||
panic(err) | ||
} | ||
beefy = NewBeefy(cl) | ||
os.Exit(m.Run()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls | ||
// | ||
// Copyright 2021 Snowfork | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package beefy | ||
|
||
import ( | ||
"github.com/centrifuge/go-substrate-rpc-client/v4/types" | ||
) | ||
|
||
// GetFinalizedHead returns the hash of the latest BEEFY block | ||
func (b *Beefy) GetFinalizedHead() (types.Hash, error) { | ||
var res string | ||
|
||
err := b.client.Call(&res, "beefy_getFinalizedHead") | ||
if err != nil { | ||
return types.Hash{}, err | ||
} | ||
|
||
return types.NewHashFromHexString(res) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls | ||
// | ||
// Copyright 2019 Centrifuge GmbH | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package beefy | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestBeefy_GetFinalizedHead(t *testing.T) { | ||
t.Skip("API only available in Polkadot") | ||
_, err := beefy.GetFinalizedHead() | ||
assert.NoError(t, err) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls | ||
// | ||
// Copyright 2021 Snowfork | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package beefy | ||
|
||
import ( | ||
"context" | ||
"sync" | ||
|
||
"github.com/centrifuge/go-substrate-rpc-client/v4/config" | ||
gethrpc "github.com/centrifuge/go-substrate-rpc-client/v4/gethrpc" | ||
"github.com/centrifuge/go-substrate-rpc-client/v4/types" | ||
) | ||
|
||
// JustificationsSubscription is a subscription established through one of the Client's subscribe methods. | ||
type JustificationsSubscription struct { | ||
sub *gethrpc.ClientSubscription | ||
channel chan types.SignedCommitment | ||
quitOnce sync.Once // ensures quit is closed once | ||
} | ||
|
||
// Chan returns the subscription channel. | ||
// | ||
// The channel is closed when Unsubscribe is called on the subscription. | ||
func (s *JustificationsSubscription) Chan() <-chan types.SignedCommitment { | ||
return s.channel | ||
} | ||
|
||
// Err returns the subscription error channel. The intended use of Err is to schedule | ||
// resubscription when the client connection is closed unexpectedly. | ||
// | ||
// The error channel receives a value when the subscription has ended due | ||
// to an error. The received error is nil if Close has been called | ||
// on the underlying client and no other error has occurred. | ||
// | ||
// The error channel is closed when Unsubscribe is called on the subscription. | ||
func (s *JustificationsSubscription) Err() <-chan error { | ||
return s.sub.Err() | ||
} | ||
|
||
// Unsubscribe unsubscribes the notification and closes the error channel. | ||
// It can safely be called more than once. | ||
func (s *JustificationsSubscription) Unsubscribe() { | ||
s.sub.Unsubscribe() | ||
s.quitOnce.Do(func() { | ||
close(s.channel) | ||
}) | ||
} | ||
|
||
// SubscribeJustifications subscribes beefy justifications, returning a subscription that will | ||
// receive server notifications containing the Header. | ||
func (b *Beefy) SubscribeJustifications() (*JustificationsSubscription, error) { | ||
ctx, cancel := context.WithTimeout(context.Background(), config.Default().SubscribeTimeout) | ||
defer cancel() | ||
|
||
ch := make(chan types.SignedCommitment) | ||
|
||
sub, err := b.client.Subscribe(ctx, "beefy", "subscribeJustifications", "unsubscribeJustifications", | ||
"justifications", ch) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return &JustificationsSubscription{sub: sub, channel: ch}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package mmr | ||
|
||
import ( | ||
"github.com/centrifuge/go-substrate-rpc-client/v4/client" | ||
"github.com/centrifuge/go-substrate-rpc-client/v4/types" | ||
) | ||
|
||
// GenerateProof retrieves a MMR proof and leaf for the specified leave index, at the given blockHash (useful to query a | ||
// proof at an earlier block, likely with antoher MMR root) | ||
func (c *MMR) GenerateProof(leafIndex uint64, blockHash types.Hash) (types.GenerateMMRProofResponse, error) { | ||
return c.generateProof(leafIndex, &blockHash) | ||
} | ||
|
||
// GenerateProofLatest retrieves the latest MMR proof and leaf for the specified leave index | ||
func (c *MMR) GenerateProofLatest(leafIndex uint64) (types.GenerateMMRProofResponse, error) { | ||
return c.generateProof(leafIndex, nil) | ||
} | ||
|
||
func (c *MMR) generateProof(leafIndex uint64, blockHash *types.Hash) (types.GenerateMMRProofResponse, error) { | ||
var res types.GenerateMMRProofResponse | ||
err := client.CallWithBlockHash(c.client, &res, "mmr_generateProof", blockHash, leafIndex) | ||
if err != nil { | ||
return types.GenerateMMRProofResponse{}, err | ||
} | ||
|
||
return res, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package mmr | ||
|
||
import "github.com/centrifuge/go-substrate-rpc-client/v4/client" | ||
|
||
// MMR exposes methods for retrieval of MMR data | ||
type MMR struct { | ||
client client.Client | ||
} | ||
|
||
// NewMMR creates a new MMR struct | ||
func NewMMR(c client.Client) MMR { | ||
return MMR{client: c} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls | ||
// | ||
// Copyright 2019 Centrifuge GmbH | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
package teste2e | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
"time" | ||
|
||
gsrpc "github.com/centrifuge/go-substrate-rpc-client/v4" | ||
"github.com/centrifuge/go-substrate-rpc-client/v4/config" | ||
"github.com/stretchr/testify/assert" | ||
) | ||
|
||
func TestBeefy_SubscribeJustifications(t *testing.T) { | ||
if testing.Short() { | ||
t.Skip("skipping end-to-end test in short mode.") | ||
} | ||
|
||
api, err := gsrpc.NewSubstrateAPI(config.Default().RPCURL) | ||
assert.NoError(t, err) | ||
|
||
sub, err := api.RPC.Beefy.SubscribeJustifications() | ||
assert.NoError(t, err) | ||
defer sub.Unsubscribe() | ||
|
||
timeout := time.After(300 * time.Second) | ||
received := 0 | ||
|
||
for { | ||
select { | ||
case commitment := <-sub.Chan(): | ||
fmt.Printf("%#v\n", commitment) | ||
|
||
received++ | ||
|
||
if received >= 2 { | ||
return | ||
} | ||
case <-timeout: | ||
assert.FailNow(t, "timeout reached without getting 2 notifications from subscription") | ||
return | ||
} | ||
} | ||
} |
Oops, something went wrong.