-
Notifications
You must be signed in to change notification settings - Fork 116
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(rpc): Implement payment_queryInfo
RPC call
#1826
Changes from 25 commits
fcfe5f1
a8b0897
368316f
68f391a
2249715
78afa32
00ebedd
798f650
2ed73a5
9f84411
ec51ea2
04b3235
46f405f
d626e2a
b4c9c16
c637e45
a06b489
cc4e98a
49e8758
50bb099
d0c66e8
5352f96
6ff3daf
07e9c5c
e92f935
591d0aa
cb3d56d
dcf7f30
ea9ee3b
245148d
6ff3e44
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
package modules | ||
|
||
import ( | ||
"net/http" | ||
|
||
"github.com/ChainSafe/gossamer/lib/common" | ||
) | ||
|
||
// PaymentQueryInfoRequest represents the request to get the fee of a extrinsic in a given block | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! |
||
type PaymentQueryInfoRequest struct { | ||
// hex SCALE encoded extrinsic | ||
Ext string | ||
// hex optional block hash indicating the state | ||
Hash *common.Hash | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I belive changing to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I also have an open PR that removes all of the optional types, so I think we should avoid using them. If we need an option I think we should use *common.Hash so I am with you @EclesioMeloJunior |
||
} | ||
|
||
// PaymentQueryInfoResponse holds the response fields to the query info RPC method | ||
type PaymentQueryInfoResponse struct { | ||
Weight uint64 `json:"weight"` | ||
Class int `json:"class"` | ||
PartialFee string `json:"partialFee"` | ||
} | ||
|
||
// PaymentModule holds all the RPC implementation of polkadot payment rpc api | ||
type PaymentModule struct { | ||
blockAPI BlockAPI | ||
} | ||
|
||
// NewPaymentModule returns a pointer to PaymentModule | ||
func NewPaymentModule(blockAPI BlockAPI) *PaymentModule { | ||
return &PaymentModule{ | ||
blockAPI: blockAPI, | ||
} | ||
} | ||
|
||
// QueryInfo query the known data about the fee of an extrinsic at the given block | ||
func (p *PaymentModule) QueryInfo(_ *http.Request, req *PaymentQueryInfoRequest, res *PaymentQueryInfoResponse) error { | ||
var hash common.Hash | ||
if req.Hash == nil { | ||
hash = p.blockAPI.BestBlockHash() | ||
} else { | ||
hash = *req.Hash | ||
} | ||
|
||
r, err := p.blockAPI.GetRuntime(&hash) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
ext, err := common.HexToBytes(req.Ext) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
encQueryInfo, err := r.PaymentQueryInfo(ext) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if encQueryInfo != nil { | ||
*res = PaymentQueryInfoResponse{ | ||
Weight: encQueryInfo.Weight, | ||
Class: encQueryInfo.Class, | ||
PartialFee: encQueryInfo.PartialFee.String(), | ||
} | ||
} | ||
|
||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
package modules | ||
|
||
import ( | ||
"errors" | ||
"testing" | ||
|
||
"github.com/ChainSafe/gossamer/dot/rpc/modules/mocks" | ||
"github.com/ChainSafe/gossamer/dot/types" | ||
"github.com/ChainSafe/gossamer/pkg/scale" | ||
"github.com/stretchr/testify/mock" | ||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/ChainSafe/gossamer/lib/common" | ||
mocksruntime "github.com/ChainSafe/gossamer/lib/runtime/mocks" | ||
) | ||
|
||
func TestPaymentQueryInfo(t *testing.T) { | ||
state := newTestStateService(t) | ||
bestBlockHash := state.Block.BestBlockHash() | ||
|
||
t.Run("When there is no errors", func(t *testing.T) { | ||
mockedQueryInfo := &types.TransactionPaymentQueryInfo{ | ||
Weight: 0, | ||
Class: 0, | ||
PartialFee: scale.MaxUint128, | ||
} | ||
|
||
expected := PaymentQueryInfoResponse{ | ||
Weight: 0, | ||
Class: 0, | ||
PartialFee: scale.MaxUint128.String(), | ||
} | ||
|
||
runtimeMock := new(mocksruntime.MockInstance) | ||
runtimeMock.On("PaymentQueryInfo", mock.AnythingOfType("[]uint8")).Return(mockedQueryInfo, nil) | ||
|
||
blockAPIMock := new(mocks.MockBlockAPI) | ||
blockAPIMock.On("BestBlockHash").Return(bestBlockHash) | ||
|
||
blockAPIMock.On("GetRuntime", mock.AnythingOfType("*common.Hash")).Return(runtimeMock, nil) | ||
|
||
mod := &PaymentModule{ | ||
blockAPI: blockAPIMock, | ||
} | ||
|
||
var req PaymentQueryInfoRequest | ||
req.Ext = "0x0001" | ||
req.Hash = nil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No need to explicitly assign nil. The default value will be nil. |
||
|
||
var res PaymentQueryInfoResponse | ||
err := mod.QueryInfo(nil, &req, &res) | ||
|
||
require.NoError(t, err) | ||
require.Equal(t, expected, res) | ||
|
||
// should be called because req.Hash is nil | ||
blockAPIMock.AssertCalled(t, "BestBlockHash") | ||
blockAPIMock.AssertCalled(t, "GetRuntime", mock.AnythingOfType("*common.Hash")) | ||
runtimeMock.AssertCalled(t, "PaymentQueryInfo", mock.AnythingOfType("[]uint8")) | ||
}) | ||
|
||
t.Run("When could not get runtime", func(t *testing.T) { | ||
blockAPIMock := new(mocks.MockBlockAPI) | ||
blockAPIMock.On("BestBlockHash").Return(bestBlockHash) | ||
|
||
blockAPIMock.On("GetRuntime", mock.AnythingOfType("*common.Hash")). | ||
Return(nil, errors.New("mocked problems")) | ||
|
||
mod := &PaymentModule{ | ||
blockAPI: blockAPIMock, | ||
} | ||
|
||
var req PaymentQueryInfoRequest | ||
req.Ext = "0x0011" | ||
req.Hash = nil | ||
|
||
var res PaymentQueryInfoResponse | ||
err := mod.QueryInfo(nil, &req, &res) | ||
|
||
require.Error(t, err) | ||
require.Equal(t, res, PaymentQueryInfoResponse{}) | ||
|
||
blockAPIMock.AssertCalled(t, "BestBlockHash") | ||
blockAPIMock.AssertCalled(t, "GetRuntime", mock.AnythingOfType("*common.Hash")) | ||
}) | ||
|
||
t.Run("When PaymentQueryInfo returns error", func(t *testing.T) { | ||
runtimeMock := new(mocksruntime.MockInstance) | ||
runtimeMock.On("PaymentQueryInfo", mock.AnythingOfType("[]uint8")).Return(nil, errors.New("mocked error")) | ||
|
||
blockAPIMock := new(mocks.MockBlockAPI) | ||
blockAPIMock.On("GetRuntime", mock.AnythingOfType("*common.Hash")).Return(runtimeMock, nil) | ||
|
||
mod := &PaymentModule{ | ||
blockAPI: blockAPIMock, | ||
} | ||
|
||
mockedHash := common.NewHash([]byte{0x01, 0x02}) | ||
var req PaymentQueryInfoRequest | ||
req.Ext = "0x0000" | ||
req.Hash = &mockedHash | ||
|
||
var res PaymentQueryInfoResponse | ||
err := mod.QueryInfo(nil, &req, &res) | ||
|
||
require.Error(t, err) | ||
require.Equal(t, res, PaymentQueryInfoResponse{}) | ||
|
||
// should be called because req.Hash is nil | ||
blockAPIMock.AssertNotCalled(t, "BestBlockHash") | ||
blockAPIMock.AssertCalled(t, "GetRuntime", mock.AnythingOfType("*common.Hash")) | ||
runtimeMock.AssertCalled(t, "PaymentQueryInfo", mock.AnythingOfType("[]uint8")) | ||
}) | ||
|
||
t.Run("When PaymentQueryInfo returns a nil info", func(t *testing.T) { | ||
runtimeMock := new(mocksruntime.MockInstance) | ||
runtimeMock.On("PaymentQueryInfo", mock.AnythingOfType("[]uint8")).Return(nil, nil) | ||
|
||
blockAPIMock := new(mocks.MockBlockAPI) | ||
blockAPIMock.On("GetRuntime", mock.AnythingOfType("*common.Hash")).Return(runtimeMock, nil) | ||
|
||
mod := &PaymentModule{ | ||
blockAPI: blockAPIMock, | ||
} | ||
|
||
mockedHash := common.NewHash([]byte{0x01, 0x02}) | ||
var req PaymentQueryInfoRequest | ||
req.Ext = "0x0020" | ||
req.Hash = &mockedHash | ||
|
||
var res PaymentQueryInfoResponse | ||
err := mod.QueryInfo(nil, &req, &res) | ||
|
||
require.NoError(t, err) | ||
require.Equal(t, res, PaymentQueryInfoResponse{}) | ||
|
||
// should be called because req.Hash is nil | ||
blockAPIMock.AssertNotCalled(t, "BestBlockHash") | ||
blockAPIMock.AssertCalled(t, "GetRuntime", mock.AnythingOfType("*common.Hash")) | ||
runtimeMock.AssertCalled(t, "PaymentQueryInfo", mock.AnythingOfType("[]uint8")) | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done!