Skip to content
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

perf: avoid unnecessary unmarshaling of BTC PK #441

Merged
merged 9 commits into from
Feb 1, 2024
Merged

Conversation

SebastianElvis
Copy link
Member

@SebastianElvis SebastianElvis commented Feb 1, 2024

Improper fix for the sake of deadline. This fix is not proper because BIP340PubKey is used in both client side and KVStore thus is no longer assumed to always correspond to a valid BTC PK without performing verification upon unmarshal. Proper fix will be introduced in #438


Based on the profiling result at https://github.com/babylonchain/babylon/files/14107742/profile001.pdf, the BeginBlock of BTC staking module has a performance issue -- 100000 BTC delegations will make its execution time to 2-3 seconds on a laptop, and most of the time is spent on unmarshaling BTC PK. The unmarshaling aims to ensure the BTC PK is legitimate when unmarshaling bytes into a BIP340 PK.

This PR proposes an optimisation that we perform this check only upon receiving relevant messages (create finality provider, create BTC delegation, submit covenant signatures). Once these stuff are included in DB the BTC PKs are guaranteed to be legitimate so we don't need to check BTC PK format again.

Tried benchmarking locally and this gives us 8x speedup, compared to results in #437.

➜  babylon git:(fix-btcstaking-opcost) ✗ go test -benchmem -run=^$ -bench=. github.com/babylonchain/babylon/x/btcstaking/keeper 
goos: linux
goarch: amd64
pkg: github.com/babylonchain/babylon/x/btcstaking/keeper
cpu: AMD Ryzen 7 7735HS with Radeon Graphics        
BenchmarkBeginBlock_100_10-16                 37          32560658 ns/op         9587270 B/op     210782 allocs/op
--- BENCH: BenchmarkBeginBlock_100_10-16
    store.go:206: <nil> DBG loadVersion ver=0
    store.go:244: <nil> DBG loadVersion commitID hash= key="KVStoreKey{0xc0013bc040, btcstaking}" ver=0
    store.go:62: <nil> INF Upgrading IAVL storage for faster queries + execution on live state. This may take a while commit=436F6D6D697449447B5B5D3A307D store_key="KVStoreKey{0xc0013bc040, btcstaking}" version=0
    store.go:76: <nil> DBG Finished loading IAVL tree
    store.go:206: <nil> DBG loadVersion ver=0
    store.go:244: <nil> DBG loadVersion commitID hash= key="KVStoreKey{0xc003088090, btcstaking}" ver=0
    store.go:62: <nil> INF Upgrading IAVL storage for faster queries + execution on live state. This may take a while commit=436F6D6D697449447B5B5D3A307D store_key="KVStoreKey{0xc003088090, btcstaking}" version=0
    store.go:76: <nil> DBG Finished loading IAVL tree
    store.go:206: <nil> DBG loadVersion ver=0
    store.go:244: <nil> DBG loadVersion commitID hash= key="KVStoreKey{0xc004c06040, btcstaking}" ver=0
        ... [output truncated]
PASS
ok      github.com/babylonchain/babylon/x/btcstaking/keeper     78.128s

@SebastianElvis SebastianElvis marked this pull request as ready for review February 1, 2024 12:04
@@ -61,6 +64,9 @@ func (m *MsgCreateBTCDelegation) ValidateBasic() error {
if m.BtcPk == nil {
return fmt.Errorf("empty delegator BTC public key")
}
if _, err := m.BtcPk.ToBTCPK(); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we also check m.FpBtcPkList i.e keys of finality providers ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not necessary as the message handler will check whether the given FP BTC PKs are known to DB. If the PKs are malformed then the message will be rejected anyway.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh you are right.

Although before the change in this pr, those pk-s were validated before even they got to message handler and before the check in db. So this pr introduce small change to message processing in case of invalid fp public key.
Not big deal though probably, although we will need to think on it when doing proper fix later.

Copy link
Member Author

@SebastianElvis SebastianElvis Feb 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although before the change in this pr, those pk-s were validated before even they got to message handler and before the check in db.

Actually Cosmos Sdk v0.50 removed native support for ValidateBasic before handler and currently we invoke it manually at the beginning of msg handler 😅

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thats one thing, but from what I understand Unmarshal method in protobuf, when when we had this if _, err := newPK.ToBTCPK(); err != nil { validation in it, it meant when node received data from the network and was decoding custom type it called this validation.

It essentialy meant that everywhere we had BIP340PubkeyByte type, which we decoded from bytes we could be sure it was valid public key.

@@ -61,6 +64,9 @@ func (m *MsgCreateBTCDelegation) ValidateBasic() error {
if m.BtcPk == nil {
return fmt.Errorf("empty delegator BTC public key")
}
if _, err := m.BtcPk.ToBTCPK(); err != nil {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ahh you are right.

Although before the change in this pr, those pk-s were validated before even they got to message handler and before the check in db. So this pr introduce small change to message processing in case of invalid fp public key.
Not big deal though probably, although we will need to think on it when doing proper fix later.

@vitsalis vitsalis merged commit 08452a1 into dev Feb 1, 2024
4 checks passed
@KonradStaniec KonradStaniec deleted the opt-unmarshal-pk-2 branch February 1, 2024 13:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants