Skip to content

Commit

Permalink
remove all domain specific asset verification
Browse files Browse the repository at this point in the history
  • Loading branch information
cedricfung committed Oct 14, 2023
1 parent 9f1e12d commit 75e749b
Show file tree
Hide file tree
Showing 22 changed files with 166 additions and 567 deletions.
10 changes: 10 additions & 0 deletions command.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,6 +706,16 @@ func getKeyCmd(c *cli.Context) error {
return err
}

func getAssetCmd(c *cli.Context) error {
data, err := callRPC(c.String("node"), "getasset", []any{
c.String("id"),
}, c.Bool("time"))
if err == nil {
fmt.Println(string(data))
}
return err
}

func listCustodianUpdatesCmd(c *cli.Context) error {
data, err := callRPC(c.String("node"), "listcustodianupdates", []any{}, c.Bool("time"))
if err == nil {
Expand Down
35 changes: 14 additions & 21 deletions common/asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,36 @@ package common

import (
"fmt"
"strings"

"github.com/MixinNetwork/mixin/crypto"
"github.com/MixinNetwork/mixin/domains/bitcoin"
"github.com/MixinNetwork/mixin/domains/ethereum"
)

var (
XINAssetId crypto.Hash
XINAsset *Asset
XINAssetId crypto.Hash
BitcoinAssetId crypto.Hash
EthereumAssetId crypto.Hash
)

type Asset struct {
ChainId crypto.Hash
Chain crypto.Hash
AssetKey string
}

func init() {
XINAssetId = crypto.Sha256Hash([]byte("c94ac88f-4671-3976-b60a-09064f1811e8"))
BitcoinAssetId = crypto.Sha256Hash([]byte("c6d0c728-2624-429b-8e0d-d9d19b6592fa"))
EthereumAssetId = crypto.Sha256Hash([]byte("43d61dcd-e413-450d-80b8-101d5e903357"))
XINAsset = &Asset{Chain: EthereumAssetId, AssetKey: "0xa974c709cfb4566686553a20790685a47aceaa33"}
}

func (a *Asset) Verify() error {
switch a.ChainId {
case ethereum.EthereumChainId:
return ethereum.VerifyAssetKey(a.AssetKey)
case bitcoin.BitcoinChainId:
return bitcoin.VerifyAssetKey(a.AssetKey)
default:
return fmt.Errorf("invalid chain id %s", a.ChainId)
if !a.Chain.HasValue() {
return fmt.Errorf("invalid asset chain %v", *a)
}
}

func (a *Asset) AssetId() crypto.Hash {
switch a.ChainId {
case ethereum.EthereumChainId:
return ethereum.GenerateAssetId(a.AssetKey)
case bitcoin.BitcoinChainId:
return bitcoin.GenerateAssetId(a.AssetKey)
default:
panic(a.ChainId)
if strings.TrimSpace(a.AssetKey) != a.AssetKey || len(a.AssetKey) == 0 {
return fmt.Errorf("invalid asset key %v", *a)
}
return nil
}
28 changes: 10 additions & 18 deletions common/deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"fmt"

"github.com/MixinNetwork/mixin/crypto"
"github.com/MixinNetwork/mixin/domains/bitcoin"
"github.com/MixinNetwork/mixin/domains/ethereum"
)

type DepositData struct {
Expand All @@ -18,13 +16,13 @@ type DepositData struct {

func (d *DepositData) Asset() *Asset {
return &Asset{
ChainId: d.Chain,
Chain: d.Chain,
AssetKey: d.AssetKey,
}
}

func (d *DepositData) UniqueKey() crypto.Hash {
index := fmt.Sprintf("%s:%d", d.Transaction, d.Index)
index := fmt.Sprintf("%s:%s:%d", d.Chain, d.Transaction, d.Index)
return crypto.Sha256Hash([]byte(index)).ForNetwork(d.Chain)
}

Expand All @@ -35,26 +33,20 @@ func (tx *Transaction) DepositData() *DepositData {
return tx.Inputs[0].Deposit
}

func (tx *Transaction) verifyDepositFormat() error {
func (tx *Transaction) verifyDepositFormat(store DataStore) error {
deposit := tx.Inputs[0].Deposit
if err := deposit.Asset().Verify(); err != nil {
asset := deposit.Asset()
if err := asset.Verify(); err != nil {
return fmt.Errorf("invalid asset data %s", err.Error())
}
if id := deposit.Asset().AssetId(); id != tx.Asset {
return fmt.Errorf("invalid asset %s %s", tx.Asset, id)
}
if deposit.Amount.Sign() <= 0 {
return fmt.Errorf("invalid amount %s", deposit.Amount.String())
}

chainId := deposit.Asset().ChainId
switch chainId {
case ethereum.EthereumChainId:
return ethereum.VerifyTransactionHash(deposit.Transaction)
case bitcoin.BitcoinChainId:
return bitcoin.VerifyTransactionHash(deposit.Transaction)
old, _, err := store.ReadAssetWithBalance(tx.Asset)
if err != nil || old == nil {
return err
}
return fmt.Errorf("invalid deposit chain id %s", chainId)
return fmt.Errorf("invalid asset info %s %v %v", tx.Asset, *old, *asset)
}

func (tx *SignedTransaction) validateDeposit(store DataStore, payloadHash crypto.Hash, sigs []map[uint16]*crypto.Signature, snapTime uint64) error {
Expand All @@ -70,7 +62,7 @@ func (tx *SignedTransaction) validateDeposit(store DataStore, payloadHash crypto
if len(sigs) != 1 || len(sigs[0]) != 1 {
return fmt.Errorf("invalid signatures count %d for deposit", len(sigs))
}
err := tx.verifyDepositFormat()
err := tx.verifyDepositFormat(store)
if err != nil {
return err
}
Expand Down
20 changes: 10 additions & 10 deletions common/deposit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"time"

"github.com/MixinNetwork/mixin/crypto"
"github.com/MixinNetwork/mixin/domains/ethereum"
"github.com/stretchr/testify/require"
)

Expand All @@ -23,8 +22,9 @@ func TestDeposit(t *testing.T) {
accounts = append(accounts, &a)
}

chainId, _ := crypto.HashFromString("8dd50817c082cdcdd6f167514928767a4b52426997bd6d4930eca101c5ff8a27")
assetKey := "0xa974c709cfb4566686553a20790685a47aceaa33"
assetID := ethereum.GenerateAssetId(assetKey)
assetID, _ := crypto.HashFromString("a99c2e0e2b1da4d648755ef19bd95139acbbe6564cfb06dec7cd34931ca72cdc")
transactionHash := "0x426ce53523b2f24d0f20707ef169f9cc5a1eea34287210873421bd1e5e5d2718"

receiver := &MixinKey{
Expand Down Expand Up @@ -53,14 +53,14 @@ func TestDeposit(t *testing.T) {
require.True(strings.Contains(err.Error(), "invalid inputs"))

tx.AddDepositInput(&DepositData{
Chain: ethereum.EthereumChainId,
Chain: chainId,
AssetKey: assetKey,
Transaction: transactionHash,
Index: 0,
Amount: NewIntegerFromString("1006"),
})
tx.AddDepositInput(&DepositData{
Chain: ethereum.EthereumChainId,
Chain: chainId,
AssetKey: assetKey,
Transaction: transactionHash,
Index: 1,
Expand All @@ -74,7 +74,7 @@ func TestDeposit(t *testing.T) {

tx = NewTransactionV5(assetID)
tx.AddDepositInput(&DepositData{
Chain: ethereum.EthereumChainId,
Chain: chainId,
AssetKey: assetKey,
Transaction: transactionHash,
Index: 0,
Expand All @@ -88,7 +88,7 @@ func TestDeposit(t *testing.T) {

tx = NewTransactionV5(assetID)
tx.AddDepositInput(&DepositData{
Chain: ethereum.EthereumChainId,
Chain: chainId,
AssetKey: assetKey,
Transaction: transactionHash,
Index: 0,
Expand All @@ -108,7 +108,7 @@ func TestDeposit(t *testing.T) {

tx = NewTransactionV5(assetID)
tx.AddDepositInput(&DepositData{
Chain: ethereum.EthereumChainId,
Chain: chainId,
AssetKey: assetKey,
Transaction: transactionHash,
Index: 0,
Expand All @@ -128,7 +128,7 @@ func TestDeposit(t *testing.T) {

tx = NewTransactionV5(assetID)
tx.AddDepositInput(&DepositData{
Chain: ethereum.EthereumChainId,
Chain: chainId,
AssetKey: assetKey,
Transaction: transactionHash,
Index: 0,
Expand All @@ -147,7 +147,7 @@ func TestDeposit(t *testing.T) {

tx = NewTransactionV5(assetID)
tx.AddDepositInput(&DepositData{
Chain: ethereum.EthereumChainId,
Chain: chainId,
AssetKey: assetKey,
Transaction: transactionHash,
Index: 0,
Expand All @@ -166,7 +166,7 @@ func TestDeposit(t *testing.T) {

tx = NewTransactionV5(assetID)
tx.AddDepositInput(&DepositData{
Chain: ethereum.EthereumChainId,
Chain: chainId,
AssetKey: assetKey,
Transaction: transactionHash,
Index: 0,
Expand Down
4 changes: 4 additions & 0 deletions common/encoding_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ func TestIntEncoding(t *testing.T) {
func TestEncoding(t *testing.T) {
require := require.New(t)

require.Equal("a99c2e0e2b1da4d648755ef19bd95139acbbe6564cfb06dec7cd34931ca72cdc", XINAssetId.String())
require.Equal("8dd50817c082cdcdd6f167514928767a4b52426997bd6d4930eca101c5ff8a27", EthereumAssetId.String())
require.Equal("fe6b7788944d328778f98e3e81588215b5a07de4f9a4a7de4db4535b404e65db", BitcoinAssetId.String())

raw := "777700052dc0ab2919c77daea5cfc0b37a2beea02142e8fdc4f60409fd40b256bb13ea290007eff98bbf1fd4632380b3f81bec40b54ceaa5d10e181b2c9e141da28b3d13c5460001000000000000a348712f7881be7a7bec9935d46578fd612a96e1cd0ac0f83520e2c0db0e98e2000100000000000030ad61194c5c3c19c0397d3ae98fb25ea4ead720fd49a86f2ab7b6db888ea61b00010000000000005981c0b5df48c066b4b3858ea949990c82cc27e030127d9eda70ff57fe9d9feb0001000000000000ad2fccec444b26794a13fb52f71348308de20f72a6dc4544195cef79f60910660001000000000000c817d2cac077b5ab21af4166f7451d9678a836db3f709b2903a971bf763b7f890001000000000000a4df50c83ed97db449ec856d660f4b0ef1f888bf2824800cf1bcf71418b32e580001000000000000000200a100060417bce6c8000000000000000000000000000000000000000000000000000000000000000000000000007777006b344b45397734746e65417472324257736d6877693645624231436257716779424248326f4367397677676e39346e5a5a4d6379694c7655347a596b6277703277754e4a595651556b77795a46664e3846726238345178556770673174656e574c61647834554552583270480000000000053be744043b00012f4d6a6fd5720be42930533d2efd2f5659f6179ea0e677edad599ef1dc6293b8ae2ebb91eac8ceb937f92c7dd5ffdb577b6506c6fbe0f2c7baf35d399dbc7bab0003fffe01000000000000001581a154c4107e519774e8784192b35a93ef68fff6ee0000"

val, _ := hex.DecodeString(raw)
Expand Down
5 changes: 5 additions & 0 deletions common/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,15 @@ type CustodianReader interface {
ReadCustodian(ts uint64) (*CustodianUpdateRequest, error)
}

type AssetReader interface {
ReadAssetWithBalance(id crypto.Hash) (*Asset, Integer, error)
}

type DataStore interface {
UTXOLockReader
UTXOLocker
GhostLocker
NodeReader
CustodianReader
AssetReader
}
6 changes: 0 additions & 6 deletions common/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,12 +223,6 @@ func (signed *SignedTransaction) SignRaw(key crypto.Key) error {
if in.Deposit == nil && in.Mint == nil {
return fmt.Errorf("invalid input format")
}
if in.Deposit != nil {
err := signed.verifyDepositFormat()
if err != nil {
return err
}
}
sig := key.Sign(msg)
sigs := map[uint16]*crypto.Signature{0: &sig}
signed.SignaturesMap = append(signed.SignaturesMap, sigs)
Expand Down
4 changes: 4 additions & 0 deletions common/transaction_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,10 @@ type storeImpl struct {
accounts []*Address
}

func (store storeImpl) ReadAssetWithBalance(_ crypto.Hash) (*Asset, Integer, error) {
return nil, Zero, nil
}

func (store storeImpl) ReadUTXOKeys(hash crypto.Hash, index int) (*UTXOKeys, error) {
utxo, err := store.ReadUTXOLock(hash, index)
if err != nil {
Expand Down
4 changes: 3 additions & 1 deletion common/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,12 @@ func (tx *SignedTransaction) validateInputs(store UTXOLockReader, hash crypto.Ha
keySigs := make(map[*crypto.Key]*crypto.Signature)

for i, in := range tx.Inputs {
if len(in.Genesis) > 0 {
return inputsFilter, inputAmount, fmt.Errorf("invalid genesis %v", in)
}
if in.Mint != nil {
return inputsFilter, in.Mint.Amount, nil
}

if in.Deposit != nil {
return inputsFilter, in.Deposit.Amount, nil
}
Expand Down
Loading

0 comments on commit 75e749b

Please sign in to comment.