Skip to content

Commit

Permalink
Cache swept deposits (#3811)
Browse files Browse the repository at this point in the history
The current logic always fetches swept deposits from the chain using
Ethereum RPC server. This can be optimized. Swept deposits are final and
no further changes occur regarding their state. That means swept
deposits can be cached. This allows reducing network load and speeding
up processed that needs to check a large number of deposits (e.g.
deposit sweep and moving funds proposal generators). We use a time cache
to evict unused keys over time and optimize memory consumption.
  • Loading branch information
lukasz-zimnoch committed Apr 24, 2024
2 parents c3cef04 + 3404496 commit 8c2fc66
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 16 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ require (
github.com/ipfs/go-log v1.0.5
github.com/ipfs/go-log/v2 v2.5.1
github.com/jbenet/goprocess v0.1.4
github.com/keep-network/keep-common v1.7.1-0.20231107101149-559db3d3849e
github.com/keep-network/keep-common v1.7.1-0.20240424094333-bd36cd25bb74
github.com/libp2p/go-addr-util v0.2.0
github.com/libp2p/go-libp2p v0.32.2
github.com/libp2p/go-libp2p-kad-dht v0.25.2
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -493,8 +493,8 @@ github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8
github.com/karalabe/usb v0.0.2/go.mod h1:Od972xHfMJowv7NGVDiWVxk2zxnWgjLlJzE+F4F7AGU=
github.com/keep-network/go-electrum v0.0.0-20240206170935-6038cb594daa h1:AKTJr+STc4rP9NcN2ppP9Zft3GbYechFW8q/S8UNQrQ=
github.com/keep-network/go-electrum v0.0.0-20240206170935-6038cb594daa/go.mod h1:eiMFzdvS+x8Voi0bmiZtVfJ3zMNRUnPNDnhCQR0tudo=
github.com/keep-network/keep-common v1.7.1-0.20231107101149-559db3d3849e h1:6kXLtv3TfObPoBNSAMqpMefOyK01y6X4zghau6F5NDg=
github.com/keep-network/keep-common v1.7.1-0.20231107101149-559db3d3849e/go.mod h1:OmaZrnZODf6RJ95yUn2kBjy8Z4u2npPJQkSiyimluto=
github.com/keep-network/keep-common v1.7.1-0.20240424094333-bd36cd25bb74 h1:cG2BiQJj6+v86duIAuDd6sPJZqLVWaOPxzt3nWQQaAo=
github.com/keep-network/keep-common v1.7.1-0.20240424094333-bd36cd25bb74/go.mod h1:OmaZrnZODf6RJ95yUn2kBjy8Z4u2npPJQkSiyimluto=
github.com/kilic/bls12-381 v0.1.0/go.mod h1:vDTTHJONJ6G+P2R74EhnyotQDTliQDnFEwhdmfzw1ig=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
Expand Down
49 changes: 36 additions & 13 deletions pkg/chain/ethereum/tbtc.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"crypto/elliptic"
"encoding/binary"
"fmt"
"github.com/keep-network/keep-common/pkg/cache"
"math/big"
"reflect"
"sort"
Expand Down Expand Up @@ -40,6 +41,10 @@ const (
WalletProposalValidatorContractName = "WalletProposalValidator"
)

const (
sweptDepositsCachePeriod = 7 * 24 * time.Hour
)

// TbtcChain represents a TBTC-specific chain handle.
type TbtcChain struct {
*baseChain
Expand All @@ -50,6 +55,8 @@ type TbtcChain struct {
sortitionPool *ecdsacontract.EcdsaSortitionPool
walletProposalValidator *tbtccontract.WalletProposalValidator
redemptionWatchtower *tbtccontract.RedemptionWatchtower

sweptDepositsCache *cache.GenericTimeCache[*tbtc.DepositChainRequest]
}

// NewTbtcChain construct a new instance of the TBTC-specific Ethereum
Expand Down Expand Up @@ -237,6 +244,7 @@ func newTbtcChain(
sortitionPool: sortitionPool,
walletProposalValidator: walletProposalValidator,
redemptionWatchtower: redemptionWatchtower,
sweptDepositsCache: cache.NewGenericTimeCache[*tbtc.DepositChainRequest](sweptDepositsCachePeriod),
}, nil
}

Expand Down Expand Up @@ -1126,8 +1134,14 @@ func (tc *TbtcChain) GetDepositRequest(
fundingOutputIndex uint32,
) (*tbtc.DepositChainRequest, bool, error) {
depositKey := buildDepositKey(fundingTxHash, fundingOutputIndex)
depositCacheKey := depositKey.Text(16)

tc.sweptDepositsCache.Sweep()
if cachedRequest, ok := tc.sweptDepositsCache.Get(depositCacheKey); ok {
return cachedRequest, true, nil
}

depositRequest, err := tc.bridge.Deposits(depositKey)
chainRequest, err := tc.bridge.Deposits(depositKey)
if err != nil {
return nil, false, fmt.Errorf(
"cannot get deposit request for key [0x%x]: [%v]",
Expand All @@ -1137,30 +1151,39 @@ func (tc *TbtcChain) GetDepositRequest(
}

// Deposit not found.
if depositRequest.RevealedAt == 0 {
if chainRequest.RevealedAt == 0 {
return nil, false, nil
}

var vault *chain.Address
if depositRequest.Vault != [20]byte{} {
v := chain.Address(depositRequest.Vault.Hex())
if chainRequest.Vault != [20]byte{} {
v := chain.Address(chainRequest.Vault.Hex())
vault = &v
}

var extraData *[32]byte
if depositRequest.ExtraData != [32]byte{} {
extraData = &depositRequest.ExtraData
if chainRequest.ExtraData != [32]byte{} {
extraData = &chainRequest.ExtraData
}

return &tbtc.DepositChainRequest{
Depositor: chain.Address(depositRequest.Depositor.Hex()),
Amount: depositRequest.Amount,
RevealedAt: time.Unix(int64(depositRequest.RevealedAt), 0),
request := &tbtc.DepositChainRequest{
Depositor: chain.Address(chainRequest.Depositor.Hex()),
Amount: chainRequest.Amount,
RevealedAt: time.Unix(int64(chainRequest.RevealedAt), 0),
Vault: vault,
TreasuryFee: depositRequest.TreasuryFee,
SweptAt: time.Unix(int64(depositRequest.SweptAt), 0),
TreasuryFee: chainRequest.TreasuryFee,
SweptAt: time.Unix(int64(chainRequest.SweptAt), 0),
ExtraData: extraData,
}, true, nil
}

// If the request was swept on-chain, there is a guarantee that no
// further changes will occur regarding its parameters.
// Such a request can be cached.
if isSwept := request.SweptAt.Unix() != 0; isSwept {
tc.sweptDepositsCache.Add(depositCacheKey, request)
}

return request, true, nil
}

func (tc *TbtcChain) PastNewWalletRegisteredEvents(
Expand Down

0 comments on commit 8c2fc66

Please sign in to comment.