Skip to content

Commit

Permalink
a few renamings; better comments and unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
ws4charlie committed Oct 24, 2024
1 parent 55091d8 commit 7a2880b
Show file tree
Hide file tree
Showing 14 changed files with 132 additions and 103 deletions.
18 changes: 9 additions & 9 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,13 @@ var AllE2ETests = []runner.E2ETest{
/*
Bitcoin tests
*/
runner.NewE2ETest(
TestBitcoinDonationName,
"donate Bitcoin to TSS address", []runner.ArgDefinition{
{Description: "amount in btc", DefaultValue: "0.1"},
},
TestBitcoinDonation,
),
runner.NewE2ETest(
TestExtractBitcoinInscriptionMemoName,
"extract memo from BTC inscription", []runner.ArgDefinition{
Expand Down Expand Up @@ -501,26 +508,19 @@ var AllE2ETests = []runner.E2ETest{
},
TestBitcoinDepositAndCallRevert,
),
runner.NewE2ETest(
TestBitcoinDonationName,
"donate Bitcoin to TSS address", []runner.ArgDefinition{
{Description: "amount in btc", DefaultValue: "0.001"},
},
TestBitcoinDonation,
),
runner.NewE2ETest(
TestBitcoinStdMemoDepositName,
"deposit Bitcoin into ZEVM with standard memo",
[]runner.ArgDefinition{
{Description: "amount in btc", DefaultValue: "0.1"},
{Description: "amount in btc", DefaultValue: "0.2"},
},
TestBitcoinStdMemoDeposit,
),
runner.NewE2ETest(
TestBitcoinStdMemoDepositAndCallName,
"deposit Bitcoin into ZEVM and call a contract with standard memo",
[]runner.ArgDefinition{
{Description: "amount in btc", DefaultValue: "0.1"},
{Description: "amount in btc", DefaultValue: "0.5"},
},
TestBitcoinStdMemoDepositAndCall,
),
Expand Down
4 changes: 2 additions & 2 deletions e2e/e2etests/test_bitcoin_deposit_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ func TestBitcoinDepositAndCall(r *runner.E2ERunner, args []string) {
utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined)

// check if example contract has been called, 'bar' value should be set to amount
amoutSats, err := zetabitcoin.GetSatoshis(amount)
amountSats, err := zetabitcoin.GetSatoshis(amount)
require.NoError(r, err)
utils.MustHaveCalledExampleContract(r, contract, big.NewInt(amoutSats))
utils.MustHaveCalledExampleContract(r, contract, big.NewInt(amountSats))
}
4 changes: 2 additions & 2 deletions e2e/e2etests/test_bitcoin_donation.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ func TestBitcoinDonation(r *runner.E2ERunner, args []string) {
txHash, err := r.SendToTSSFromDeployerWithMemo(amountTotal, utxos, memo)
require.NoError(r, err)

// ASSERT after 20 seconds
time.Sleep(time.Second * 20)
// ASSERT after 4 Zeta blocks
time.Sleep(constant.ZetaBlockTime * 4)
req := &crosschaintypes.QueryInboundHashToCctxDataRequest{InboundHash: txHash.String()}
_, err = r.CctxClient.InTxHashToCctxData(r.Ctx, req)
require.Error(r, err)
Expand Down
4 changes: 2 additions & 2 deletions e2e/e2etests/test_bitcoin_std_deposit_and_call.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ func TestBitcoinStdMemoDepositAndCall(r *runner.E2ERunner, args []string) {
utils.RequireCCTXStatus(r, cctx, crosschaintypes.CctxStatus_OutboundMined)

// check if example contract has been called, 'bar' value should be set to amount
amoutSats, err := zetabitcoin.GetSatoshis(amount)
amountSats, err := zetabitcoin.GetSatoshis(amount)
require.NoError(r, err)
utils.MustHaveCalledExampleContract(r, contract, big.NewInt(amoutSats))
utils.MustHaveCalledExampleContract(r, contract, big.NewInt(amountSats))
}
2 changes: 1 addition & 1 deletion e2e/e2etests/test_bitcoin_std_deposit_and_call_revert.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,5 @@ func TestBitcoinStdMemoDepositAndCallRevert(r *runner.E2ERunner, args []string)
assert.Equal(r, r.BTCDeployerAddress.EncodeAddress(), receiver)
assert.Positive(r, value)

r.Logger.Print("Sent %f BTC to TSS to call non-existing contract, got refund of %d satoshis", amount, value)
r.Logger.Info("Sent %f BTC to TSS to call non-existing contract, got refund of %d satoshis", amount, value)
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ func TestBitcoinStdMemoDepositAndCallRevertOtherAddress(r *runner.E2ERunner, arg
assert.Equal(r, revertAddress, receiver)
assert.Positive(r, value)

r.Logger.Print(
r.Logger.Info(
"Sent %f BTC to TSS to call non-existing contract, got refund of %d satoshis to other address",
amount,
value,
Expand Down
2 changes: 1 addition & 1 deletion e2e/runner/bitcoin.go
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ func (r *E2ERunner) QueryOutboundReceiverAndAmount(txid string) (string, int64)
// query outbound raw transaction
revertTx, err := r.BtcRPCClient.GetRawTransaction(txHash)
require.NoError(r, err, revertTx)
require.True(r, len(revertTx.MsgTx().TxOut) >= 2)
require.True(r, len(revertTx.MsgTx().TxOut) >= 2, "bitcoin outbound must have at least two outputs")

// parse receiver address from pkScript
txOutput := revertTx.MsgTx().TxOut[1]
Expand Down
20 changes: 11 additions & 9 deletions e2e/utils/zetacore.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,13 +187,22 @@ func WaitCCTXMinedByIndex(

type WaitOpts func(c *waitConfig)

// MatchStatus waits for a specific CCTX status.
// MatchStatus is the WaitOpts that matches CCTX with the given status.
func MatchStatus(s crosschaintypes.CctxStatus) WaitOpts {
return Matches(func(tx crosschaintypes.CrossChainTx) bool {
return tx.CctxStatus != nil && tx.CctxStatus.Status == s
})
}

// MatchReverted is the WaitOpts that matches reverted CCTX.
func MatchReverted() WaitOpts {
return Matches(func(tx crosschaintypes.CrossChainTx) bool {
return tx.GetCctxStatus().Status == crosschaintypes.CctxStatus_Reverted &&
len(tx.OutboundParams) == 2 &&
tx.OutboundParams[1].Hash != ""
})
}

// Matches adds a filter to WaitCctxByInboundHash that checks cctxs match provided callback.
// ALL cctxs should match this filter.
func Matches(fn func(tx crosschaintypes.CrossChainTx) bool) WaitOpts {
Expand All @@ -211,15 +220,8 @@ func WaitCctxRevertedByInboundHash(
hash string,
c CCTXClient,
) crosschaintypes.CrossChainTx {
// criteria for reverted cctx
searchForCCTXReverted := Matches(func(tx crosschaintypes.CrossChainTx) bool {
return tx.GetCctxStatus().Status == crosschaintypes.CctxStatus_Reverted &&
len(tx.OutboundParams) == 2 &&
tx.OutboundParams[1].Hash != ""
})

// wait for cctx to be reverted
cctxs := WaitCctxByInboundHash(ctx, t, hash, c, searchForCCTXReverted)
cctxs := WaitCctxByInboundHash(ctx, t, hash, c, MatchReverted())
require.Len(t, cctxs, 1)

return cctxs[0]
Expand Down
7 changes: 6 additions & 1 deletion pkg/memo/memo.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ import (
"github.com/pkg/errors"
)

const (
// version0 is the latest version of the memo
version0 uint8 = 0
)

// InboundMemo represents the inbound memo structure for non-EVM chains
type InboundMemo struct {
// Header contains the memo header
Expand Down Expand Up @@ -37,7 +42,7 @@ func (m *InboundMemo) EncodeToBytes() ([]byte, error) {
// encode fields based on version
var data []byte
switch m.Version {
case 0:
case version0:
data, err = m.FieldsV0.Pack(m.OpCode, m.EncodingFmt, dataFlags)
default:
return nil, fmt.Errorf("invalid memo version: %d", m.Version)
Expand Down
39 changes: 23 additions & 16 deletions zetaclient/chains/bitcoin/observer/event.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ type BTCInboundEvent struct {
TxHash string
}

// IsProcessable checks if the inbound event is processable
func (event *BTCInboundEvent) CheckProcessability() InboundProcessability {
// Processability returns the processability of the inbound event
func (event *BTCInboundEvent) Processability() InboundProcessability {
// compliance check on sender and receiver addresses
if config.ContainRestrictedAddress(event.FromAddress, event.ToAddress) {
return InboundProcessabilityComplianceViolation
Expand All @@ -88,8 +88,8 @@ func (event *BTCInboundEvent) CheckProcessability() InboundProcessability {
return InboundProcessabilityGood
}

// DecodeEventMemoBytes decodes the memo bytes as either standard or legacy memo
func (ob *Observer) DecodeEventMemoBytes(event *BTCInboundEvent) error {
// DecodeMemoBytes decodes the contained memo bytes as either standard or legacy memo
func (event *BTCInboundEvent) DecodeMemoBytes(chainID int64) error {
var (
err error
memoStd *memo.InboundMemo
Expand All @@ -103,7 +103,7 @@ func (ob *Observer) DecodeEventMemoBytes(event *BTCInboundEvent) error {

// try to decode the standard memo as the preferred format
// the standard memo is NOT enabled for Bitcoin mainnet
if ob.Chain().ChainId != chains.BitcoinMainnet.ChainId {
if chainID != chains.BitcoinMainnet.ChainId {
memoStd, err = memo.DecodeFromBytes(event.MemoBytes)
}

Expand All @@ -115,14 +115,15 @@ func (ob *Observer) DecodeEventMemoBytes(event *BTCInboundEvent) error {
}

// NoAssetCall will be disabled for Bitcoin until full V2 support
// https://github.com/zeta-chain/node/issues/2711
if memoStd.OpCode == memo.OpCodeCall {
return errors.New("NoAssetCall is disabled")
}

// ensure the revert address is valid and supported
revertAddress := memoStd.RevertOptions.RevertAddress
if revertAddress != "" {
btcAddress, err := chains.DecodeBtcAddress(revertAddress, ob.Chain().ChainId)
btcAddress, err := chains.DecodeBtcAddress(revertAddress, chainID)
if err != nil {
return errors.Wrapf(err, "invalid revert address in memo: %s", revertAddress)
}
Expand Down Expand Up @@ -151,10 +152,9 @@ func (ob *Observer) DecodeEventMemoBytes(event *BTCInboundEvent) error {
}

// CheckEventProcessability checks if the inbound event is processable
func (ob *Observer) CheckEventProcessability(event *BTCInboundEvent) bool {
func (ob *Observer) CheckEventProcessability(event BTCInboundEvent) bool {
// check if the event is processable
result := event.CheckProcessability()
switch result {
switch result := event.Processability(); result {
case InboundProcessabilityGood:
return true
case InboundProcessabilityDonation:
Expand All @@ -168,13 +168,17 @@ func (ob *Observer) CheckEventProcessability(event *BTCInboundEvent) bool {
compliance.PrintComplianceLog(ob.logger.Inbound, ob.logger.Compliance,
false, ob.Chain().ChainId, event.TxHash, event.FromAddress, event.ToAddress, "BTC")
return false
default:
ob.Logger().Inbound.Error().Msgf("unreachable code got InboundProcessability: %v", result)
return false

Check warning on line 173 in zetaclient/chains/bitcoin/observer/event.go

View check run for this annotation

Codecov / codecov/patch

zetaclient/chains/bitcoin/observer/event.go#L171-L173

Added lines #L171 - L173 were not covered by tests
}

return true
}

// NewInboundVoteV1 creates a MsgVoteInbound message for inbound that uses legacy memo
func (ob *Observer) NewInboundVoteV1(event *BTCInboundEvent, amountSats *big.Int) *crosschaintypes.MsgVoteInbound {
// NewInboundVoteFromLegacyMemo creates a MsgVoteInbound message for inbound that uses legacy memo
func (ob *Observer) NewInboundVoteFromLegacyMemo(
event *BTCInboundEvent,
amountSats *big.Int,
) *crosschaintypes.MsgVoteInbound {
message := hex.EncodeToString(event.MemoBytes)

return crosschaintypes.NewMsgVoteInbound(
Expand All @@ -197,10 +201,13 @@ func (ob *Observer) NewInboundVoteV1(event *BTCInboundEvent, amountSats *big.Int
)
}

// NewInboundVoteMemoStd creates a MsgVoteInbound message for inbound that uses standard memo
// TODO: rename this function as 'EventToInboundVoteV2' to use ProtocolContractVersion_V2 and enable more options
// NewInboundVoteFromStdMemo creates a MsgVoteInbound message for inbound that uses standard memo
// TODO: upgrade to ProtocolContractVersion_V2 and enable more options
// https://github.com/zeta-chain/node/issues/2711
func (ob *Observer) NewInboundVoteMemoStd(event *BTCInboundEvent, amountSats *big.Int) *crosschaintypes.MsgVoteInbound {
func (ob *Observer) NewInboundVoteFromStdMemo(
event *BTCInboundEvent,
amountSats *big.Int,
) *crosschaintypes.MsgVoteInbound {
// replace 'sender' with 'revertAddress' if specified in the memo, so that
// zetacore will refund to the address specified by the user in the revert options.
sender := event.FromAddress
Expand Down
27 changes: 10 additions & 17 deletions zetaclient/chains/bitcoin/observer/event_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ func createTestBtcEvent(
net *chaincfg.Params,
memo []byte,
memoStd *memo.InboundMemo,
) *observer.BTCInboundEvent {
return &observer.BTCInboundEvent{
) observer.BTCInboundEvent {
return observer.BTCInboundEvent{
FromAddress: sample.BtcAddressP2WPKH(t, net),
ToAddress: sample.EthAddress().Hex(),
MemoBytes: memo,
Expand Down Expand Up @@ -111,20 +111,13 @@ func Test_CheckProcessability(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := tt.event.CheckProcessability()
result := tt.event.Processability()
require.Equal(t, tt.expected, result)
})
}
}

func Test_DecodeEventMemoBytes(t *testing.T) {
// can use any bitcoin chain for testing
chain := chains.BitcoinTestnet
params := mocks.MockChainParams(chain.ChainId, 10)

// create test observer
ob := MockBTCObserver(t, chain, params, nil)

// test cases
tests := []struct {
name string
Expand Down Expand Up @@ -229,7 +222,7 @@ func Test_DecodeEventMemoBytes(t *testing.T) {

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := ob.DecodeEventMemoBytes(tt.event)
err := tt.event.DecodeMemoBytes(chains.BitcoinTestnet.ChainId)
if tt.errMsg != "" {
require.Contains(t, err.Error(), tt.errMsg)
return
Expand Down Expand Up @@ -257,7 +250,7 @@ func Test_DecodeEventMemoBytes(t *testing.T) {

func Test_CheckEventProcessability(t *testing.T) {
// can use any bitcoin chain for testing
chain := chains.BitcoinTestnet
chain := chains.BitcoinMainnet
params := mocks.MockChainParams(chain.ChainId, 10)

// create test observer
Expand All @@ -272,7 +265,7 @@ func Test_CheckEventProcessability(t *testing.T) {
// test cases
tests := []struct {
name string
event *observer.BTCInboundEvent
event observer.BTCInboundEvent
result bool
}{
{
Expand Down Expand Up @@ -304,7 +297,7 @@ func Test_CheckEventProcessability(t *testing.T) {
}
}

func Test_NewInboundVoteV1(t *testing.T) {
func Test_NewInboundVoteFromLegacyMemo(t *testing.T) {
// can use any bitcoin chain for testing
chain := chains.BitcoinMainnet
params := mocks.MockChainParams(chain.ChainId, 10)
Expand Down Expand Up @@ -341,12 +334,12 @@ func Test_NewInboundVoteV1(t *testing.T) {
}

// create new inbound vote V1
vote := ob.NewInboundVoteV1(event, amountSats)
vote := ob.NewInboundVoteFromLegacyMemo(&event, amountSats)
require.Equal(t, expectedVote, *vote)
})
}

func Test_NewInboundVoteMemoStd(t *testing.T) {
func Test_NewInboundVoteFromStdMemo(t *testing.T) {
// can use any bitcoin chain for testing
chain := chains.BitcoinMainnet
params := mocks.MockChainParams(chain.ChainId, 10)
Expand Down Expand Up @@ -395,7 +388,7 @@ func Test_NewInboundVoteMemoStd(t *testing.T) {
}

// create new inbound vote V1 with standard memo
vote := ob.NewInboundVoteMemoStd(event, amountSats)
vote := ob.NewInboundVoteFromStdMemo(&event, amountSats)
require.Equal(t, expectedVote, *vote)
})
}
Loading

0 comments on commit 7a2880b

Please sign in to comment.