feat(mint):add mint multisign

This commit is contained in:
jzhe 2021-04-29 17:36:19 +08:00
parent 000f8ebeeb
commit 5ce03275c1
12 changed files with 1790 additions and 3212 deletions

6
go.mod
View File

@ -28,7 +28,7 @@ require (
github.com/magiconair/properties v1.8.4
github.com/meshplus/bitxhub-core v1.3.0
github.com/meshplus/bitxhub-kit v1.2.0
github.com/meshplus/bitxhub-model v1.2.1-0.20210429021628-d64a34d749b4
github.com/meshplus/bitxhub-model v1.2.1-0.20210429093929-9350a1a1d8a8
github.com/meshplus/bitxid v0.0.0-20210412025850-e0eaf0f9063a
github.com/meshplus/did-registry v0.0.0-20210413035015-509c6c3a0bae
github.com/meshplus/go-libp2p-cert v0.0.0-20210125063330-7c25fd5b7a49
@ -65,4 +65,8 @@ replace google.golang.org/grpc => google.golang.org/grpc v1.33.0
replace github.com/hyperledger/fabric => github.com/hyperledger/fabric v2.0.1+incompatible
replace (
github.com/meshplus/bitxhub-model => ../bitxhub-model
)
go 1.13

4
go.sum
View File

@ -838,8 +838,8 @@ github.com/meshplus/bitxhub-model v1.1.2-0.20201021152621-0b3c17c54b23/go.mod h1
github.com/meshplus/bitxhub-model v1.1.2-0.20210409090411-de23bd385c5f/go.mod h1:x3H+TL24wcByzHegenLfs+5PQkQGNsk8eCm31QJMa+Q=
github.com/meshplus/bitxhub-model v1.2.0 h1:Ac8ol1HZNLIegyZkU/DZGYkPeeAWp3ZgYsbJGNF2GV0=
github.com/meshplus/bitxhub-model v1.2.0/go.mod h1:QCYJy8fUQex0cvxqAZtGHJn31F5mwuXnE3Lyri15zUc=
github.com/meshplus/bitxhub-model v1.2.1-0.20210429021628-d64a34d749b4 h1:qfn8eq0RJyIsTbUkoXPKYsGIvW29pZl/bsWjGB6bLDE=
github.com/meshplus/bitxhub-model v1.2.1-0.20210429021628-d64a34d749b4/go.mod h1:2zFpbwQ/2y7JiTCsnLYSa3XTF1jTz0ElsQJhUksj2EE=
github.com/meshplus/bitxhub-model v1.2.1-0.20210429093929-9350a1a1d8a8 h1:NOBA9+XYVipRwyHDP330Ypu/+2TEEFTXoXHVwsI+aZE=
github.com/meshplus/bitxhub-model v1.2.1-0.20210429093929-9350a1a1d8a8/go.mod h1:2zFpbwQ/2y7JiTCsnLYSa3XTF1jTz0ElsQJhUksj2EE=
github.com/meshplus/bitxid v0.0.0-20210412025850-e0eaf0f9063a h1:c4ESPDa60Jd4zfzZIGGTyzhfaVM3vKN+xV2G9BwIDGQ=
github.com/meshplus/bitxid v0.0.0-20210412025850-e0eaf0f9063a/go.mod h1:vAldSRfDe2Qo7exsSTbchVmZWXPY7fhWQrRw18QJHho=
github.com/meshplus/did-registry v0.0.0-20210413035015-509c6c3a0bae h1:E4iaFwHAg1ScyiU9Bz3RY0wjfXNZzPH3O43DBTl9iWg=

View File

@ -12,14 +12,15 @@ import (
"github.com/meshplus/bitxhub-kit/storage/leveldb"
_ "github.com/meshplus/bitxhub/imports"
"github.com/meshplus/bitxhub/internal/executor"
"github.com/meshplus/bitxhub/internal/executor/oracle/appchain"
"github.com/meshplus/bitxhub/internal/ledger"
"github.com/meshplus/bitxhub/internal/ledger/genesis"
"github.com/meshplus/bitxhub/internal/loggers"
orderplg "github.com/meshplus/bitxhub/internal/plugins"
"github.com/meshplus/bitxhub/internal/repo"
"github.com/meshplus/bitxhub/internal/router"
"github.com/meshplus/bitxhub/internal/storages"
"github.com/meshplus/bitxhub/pkg/order"
"github.com/meshplus/bitxhub/pkg/order/etcdraft"
"github.com/meshplus/bitxhub/pkg/peermgr"
"github.com/sirupsen/logrus"
)
@ -51,7 +52,7 @@ func NewBitXHub(rep *repo.Repo) (*BitXHub, error) {
m := rep.NetworkConfig.GetVpInfos()
order, err := orderplg.New(
order, err := etcdraft.NewNode(
order.WithRepoRoot(repoRoot),
order.WithStoragePath(repo.GetStoragePath(repoRoot, "order")),
order.WithPluginPath(rep.Config.Plugin),
@ -108,6 +109,11 @@ func GenerateBitXHubWithoutOrder(rep *repo.Repo) (*BitXHub, error) {
return nil, fmt.Errorf("blockfile initialize: %w", err)
}
appchainClient, err := appchain.NewAppchainClient(repo.GetStoragePath(repoRoot, "eth_storage"), loggers.Logger(loggers.Executor))
if err != nil {
return nil, err
}
// 0. load ledger
rwLdg, err := ledger.New(rep, bcStorage, ldb, bf, nil, loggers.Logger(loggers.Executor))
if err != nil {
@ -128,12 +134,12 @@ func GenerateBitXHubWithoutOrder(rep *repo.Repo) (*BitXHub, error) {
}
// 1. create executor and view executor
txExec, err := executor.New(rwLdg, loggers.Logger(loggers.Executor), *rep.Config)
txExec, err := executor.New(rwLdg, loggers.Logger(loggers.Executor), appchainClient, *rep.Config)
if err != nil {
return nil, fmt.Errorf("create BlockExecutor: %w", err)
}
viewExec, err := executor.New(viewLdg, loggers.Logger(loggers.Executor), *rep.Config)
viewExec, err := executor.New(viewLdg, loggers.Logger(loggers.Executor), appchainClient, *rep.Config)
if err != nil {
return nil, fmt.Errorf("create ViewExecutor: %w", err)
}

View File

@ -1,17 +1,23 @@
package coreapi
import (
"bytes"
"crypto/sha256"
"encoding/json"
"fmt"
"strconv"
"strings"
"sync"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/crypto"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub-model/constant"
"github.com/meshplus/bitxhub-model/pb"
"github.com/meshplus/bitxhub/internal/coreapi/api"
"github.com/meshplus/bitxhub/internal/executor/contracts"
"github.com/meshplus/bitxhub/internal/executor/oracle/appchain"
"github.com/meshplus/bitxhub/internal/model"
"github.com/meshplus/bitxid"
"github.com/sirupsen/logrus"
@ -164,6 +170,8 @@ func (b *BrokerAPI) FetchSignsFromOtherPeers(id string, typ pb.GetMultiSignsRequ
address, sign, err = b.requestBlockHeaderSignFromPeer(pid, id)
case pb.GetMultiSignsRequest_MINT:
address, sign, err = b.requestMintSignFromPeer(pid, id)
case pb.GetMultiSignsRequest_BURN:
address, sign, err = b.requestBurnSignFromPeer(pid, id)
}
if err != nil {
@ -187,7 +195,7 @@ func (b *BrokerAPI) FetchSignsFromOtherPeers(id string, typ pb.GetMultiSignsRequ
func (b *BrokerAPI) requestAssetExchangeSignFromPeer(peerId uint64, assetExchangeId string) (string, []byte, error) {
req := pb.Message{
Type: pb.Message_FETCH_ASSET_EXCHANEG_SIGN,
Type: pb.Message_FETCH_ASSET_EXCHANGE_SIGN,
Data: []byte(assetExchangeId),
}
@ -252,10 +260,10 @@ func (b *BrokerAPI) requestBlockHeaderSignFromPeer(pid uint64, height string) (s
return data.Address, data.Signature, nil
}
func (b *BrokerAPI) requestMintSignFromPeer(pid uint64, height string) (string, []byte, error) {
func (b *BrokerAPI) requestMintSignFromPeer(pid uint64, hash string) (string, []byte, error) {
req := pb.Message{
Type: pb.Message_FETCH_MINT_SIGN,
Data: []byte(height),
Data: []byte(hash),
}
resp, err := b.bxh.PeerMgr.Send(pid, &req)
@ -275,6 +283,29 @@ func (b *BrokerAPI) requestMintSignFromPeer(pid uint64, height string) (string,
return data.Address, data.Signature, nil
}
func (b *BrokerAPI) requestBurnSignFromPeer(pid uint64, hash string) (string, []byte, error) {
req := pb.Message{
Type: pb.Message_FETCH_BURN_SIGN,
Data: []byte(hash),
}
resp, err := b.bxh.PeerMgr.Send(pid, &req)
if err != nil {
return "", nil, err
}
if resp == nil || resp.Type != pb.Message_FETCH_BURN_SIGN_ACK {
return "", nil, fmt.Errorf("invalid fetch minter sign resp")
}
data := model.MerkleWrapperSign{}
if err := data.Unmarshal(resp.Data); err != nil {
return "", nil, err
}
return data.Address, data.Signature, nil
}
func (b *BrokerAPI) GetSign(content string, typ pb.GetMultiSignsRequest_Type) (string, []byte, error) {
switch typ {
case pb.GetMultiSignsRequest_ASSET_EXCHANGE:
@ -312,12 +343,92 @@ func (b *BrokerAPI) GetSign(content string, typ pb.GetMultiSignsRequest_Type) (s
}
return b.bxh.GetPrivKey().Address, sign, nil
case pb.GetMultiSignsRequest_MINT:
return b.handleMultiSignsMintReq(content)
case pb.GetMultiSignsRequest_BURN:
return b.handleMultiSignsBurnReq(content)
default:
return "", nil, fmt.Errorf("unsupported get sign type")
}
}
func (b *BrokerAPI) handleMultiSignsMintReq(id string) (string, []byte, error) {
ok, _ := b.bxh.Ledger.GetState(constant.EthHeaderMgrContractAddr.Address(), []byte(contracts.MintKey(id)))
if !ok {
return "", nil, fmt.Errorf("cannot find minter record with id %s", id)
}
hash := common.HexToHash(id)
key := b.bxh.GetPrivKey()
sign, err := key.PrivKey.Sign(hash[:])
if err != nil {
return "", nil, fmt.Errorf("bitxhub sign: %w", err)
}
return key.Address, sign, nil
}
func (b *BrokerAPI) handleMultiSignsBurnReq(hash string) (string, []byte, error) {
receipt, err := b.bxh.Ledger.GetReceipt(types.NewHashByStr(hash))
if err != nil {
return "", nil, fmt.Errorf("cannot find receipt with hash %s", hash)
}
tx, err := b.bxh.Ledger.GetTransaction(types.NewHashByStr(hash))
if err != nil {
return "", nil, fmt.Errorf("cannot find transaction with hash %s", hash)
}
ok, interchainSwapAddr := b.bxh.Ledger.GetState(constant.EthHeaderMgrContractAddr.Address(), []byte(contracts.InterchainSwapAddrKey))
if !ok {
return "", nil, fmt.Errorf("cannot find interchainswap contract")
}
interchainAbi, err := abi.JSON(bytes.NewReader([]byte(appchain.InterchainSwapABI)))
if err != nil {
return "", nil, err
}
var burn *appchain.InterchainSwapBurn
for _, log := range receipt.GetEvmLogs() {
if !strings.EqualFold(log.Address.String(), common.BytesToAddress(interchainSwapAddr).String()) {
continue
}
if log.Removed {
continue
}
for _, topic := range log.Topics {
if strings.EqualFold(topic.String(), interchainAbi.Events["Burn"].ID.String()) {
if err := interchainAbi.UnpackIntoInterface(&burn, "Burn", log.Data); err != nil {
b.logger.Error(err)
continue
}
}
}
}
if burn == nil {
return "", nil, fmt.Errorf("not found burn log:%v", receipt.TxHash.Hash)
}
//abi.encodePacked
abiHash := crypto.Keccak256Hash(
burn.EthToken.Bytes(),
tx.GetFrom().Bytes(),
burn.Recipient.Bytes(),
common.LeftPadBytes(burn.Amount.Bytes(), 32),
receipt.TxHash.Bytes(),
)
prefixedHash := crypto.Keccak256Hash(
[]byte(fmt.Sprintf("\x19Ethereum Signed Message:\n%v", len(hash))),
abiHash.Bytes(),
)
key := b.bxh.GetPrivKey()
sign, err := key.PrivKey.Sign(prefixedHash[:])
if err != nil {
return "", nil, fmt.Errorf("bitxhub sign: %w", err)
}
return key.Address, sign, nil
}
func (b *BrokerAPI) getSign(content string) (string, []byte, error) {
hash := sha256.Sum256([]byte(content))
key := b.bxh.GetPrivKey()

View File

@ -7,23 +7,23 @@ import (
"strconv"
"strings"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/meshplus/bitxhub-core/boltvm"
"github.com/meshplus/bitxhub/internal/executor/oracle/appchain"
"github.com/sirupsen/logrus"
)
const (
EscrowsAddrKey = "escrows_addr_key"
MINT_HASH_PREFIX = "mint"
EscrowsAddrKey = "escrows_addr_key"
InterchainSwapAddrKey = "interchain_swap_addr_key"
MINT_HASH_PREFIX = "mint"
ETH_TX_HASH_PREFIX = "eth-hash"
)
type EscrowsAddr struct {
EscrowsAddr string `json:"addr"`
type ContractAddr struct {
Addr string `json:"addr"`
}
type EthHeaderManager struct {
@ -31,11 +31,7 @@ type EthHeaderManager struct {
oracle *appchain.EthLightChainOracle
}
func NewEthHeaderManager(path string, logger logrus.FieldLogger) *EthHeaderManager {
ropstenOracle, err := appchain.NewRopstenOracle(path, logger)
if err != nil {
panic(err)
}
func NewEthHeaderManager(ropstenOracle *appchain.EthLightChainOracle) *EthHeaderManager {
return &EthHeaderManager{oracle: ropstenOracle}
}
@ -43,17 +39,36 @@ func (ehm *EthHeaderManager) SetEscrowAddr(addr string) *boltvm.Response {
//TODO:add governance
ok := common.IsHexAddress(addr)
if ok {
escrowsAddr := EscrowsAddr{addr}
escrowsAddr := ContractAddr{addr}
ehm.SetObject(EscrowsAddrKey, escrowsAddr)
}
return boltvm.Success([]byte(addr))
}
func (ehm *EthHeaderManager) GetEscrowAddr() *boltvm.Response {
var escrowsAddr EscrowsAddr
var escrowsAddr ContractAddr
ok := ehm.GetObject(EscrowsAddrKey, escrowsAddr)
if ok {
return boltvm.Success([]byte(escrowsAddr.EscrowsAddr))
return boltvm.Success([]byte(escrowsAddr.Addr))
}
return boltvm.Error("not found")
}
func (ehm *EthHeaderManager) SetInterchainSwapAddr(addr string) *boltvm.Response {
//TODO:add governance
ok := common.IsHexAddress(addr)
if ok {
interchainSwapAddr := ContractAddr{addr}
ehm.SetObject(InterchainSwapAddrKey, interchainSwapAddr)
}
return boltvm.Success([]byte(addr))
}
func (ehm *EthHeaderManager) GetInterchainSwapAddr() *boltvm.Response {
var interchainSwapAddr ContractAddr
ok := ehm.GetObject(InterchainSwapAddrKey, interchainSwapAddr)
if ok {
return boltvm.Success([]byte(interchainSwapAddr.Addr))
}
return boltvm.Error("not found")
}
@ -101,6 +116,11 @@ func (ehm *EthHeaderManager) PreMint(receiptData []byte, proofData []byte) *bolt
if err != nil {
return boltvm.Error(err.Error())
}
ok, v := ehm.Get(EthTxKey(receipt.TxHash.String()))
if ok {
return boltvm.Success(v)
}
err = ehm.oracle.VerifyProof(&receipt, proofData)
if err != nil {
return boltvm.Error(err.Error())
@ -116,6 +136,7 @@ func (ehm *EthHeaderManager) PreMint(receiptData []byte, proofData []byte) *bolt
escrowsLockEvent.RelayToken.Bytes(),
escrowsLockEvent.Locker.Bytes(),
escrowsLockEvent.Recipient.Bytes(),
receipt.TxHash.Bytes(),
common.LeftPadBytes(escrowsLockEvent.Amount.Bytes(), 32),
)
prefixedHash := crypto.Keccak256Hash(
@ -123,22 +144,31 @@ func (ehm *EthHeaderManager) PreMint(receiptData []byte, proofData []byte) *bolt
hash.Bytes(),
)
ehm.SetObject(MintKey(prefixedHash.String()), escrowsLockEvent)
ehm.Set(EthTxKey(receipt.TxHash.String()), prefixedHash.Bytes())
return boltvm.Success(prefixedHash.Bytes())
}
func (ehm *EthHeaderManager) GetPrefixedHash(hash string) *boltvm.Response {
ok, v := ehm.Get(EthTxKey(hash))
if ok {
return boltvm.Success(v)
}
return boltvm.Error(fmt.Sprintf("not found prefixed hash by %v", hash))
}
func (ehm *EthHeaderManager) unpackEscrowsLock(receipt *types.Receipt) (*appchain.EscrowsLock, error) {
escrowsAbi, err := abi.JSON(bytes.NewReader([]byte(appchain.EscrowsABI)))
if err != nil {
return nil, err
}
var escrowsAddr EscrowsAddr
var escrowsAddr ContractAddr
ok := ehm.GetObject(EscrowsAddrKey, escrowsAddr)
if !ok {
return nil, fmt.Errorf("not found the escrows contract address")
}
var lock *appchain.EscrowsLock
for _, log := range receipt.Logs {
if !strings.EqualFold(log.Address.String(), escrowsAddr.EscrowsAddr) {
if !strings.EqualFold(log.Address.String(), escrowsAddr.Addr) {
continue
}
@ -162,3 +192,7 @@ func (ehm *EthHeaderManager) unpackEscrowsLock(receipt *types.Receipt) (*appchai
func MintKey(hash string) string {
return fmt.Sprintf("%s-%s", MINT_HASH_PREFIX, hash)
}
func EthTxKey(hash string) string {
return fmt.Sprintf("%s-%s", ETH_TX_HASH_PREFIX, hash)
}

View File

@ -15,6 +15,7 @@ import (
"github.com/meshplus/bitxhub-model/constant"
"github.com/meshplus/bitxhub-model/pb"
"github.com/meshplus/bitxhub/internal/executor/contracts"
"github.com/meshplus/bitxhub/internal/executor/oracle/appchain"
"github.com/meshplus/bitxhub/internal/ledger"
"github.com/meshplus/bitxhub/internal/model/events"
"github.com/meshplus/bitxhub/internal/repo"
@ -33,6 +34,7 @@ var _ Executor = (*BlockExecutor)(nil)
// BlockExecutor executes block from order
type BlockExecutor struct {
client *appchain.Client
ledger ledger.Ledger
logger logrus.FieldLogger
blockC chan *BlockWrapper
@ -56,8 +58,7 @@ type BlockExecutor struct {
}
// New creates executor instance
func New(chainLedger ledger.Ledger, logger logrus.FieldLogger, config repo.Config) (*BlockExecutor, error) {
func New(chainLedger ledger.Ledger, logger logrus.FieldLogger, client *appchain.Client, config repo.Config) (*BlockExecutor, error) {
ibtpVerify := proof.New(chainLedger, logger)
txsExecutor, err := agency.GetExecutorConstructor(config.Executor.Type)
if err != nil {
@ -67,6 +68,7 @@ func New(chainLedger ledger.Ledger, logger logrus.FieldLogger, config repo.Confi
ctx, cancel := context.WithCancel(context.Background())
blockExecutor := &BlockExecutor{
client: client,
ledger: chainLedger,
logger: logger,
ctx: ctx,
@ -285,7 +287,7 @@ func (exec *BlockExecutor) registerBoltContracts() map[string]agency.Contract {
Enabled: true,
Name: "ethereum header service",
Address: constant.EthHeaderMgrContractAddr.Address().String(),
Contract: contracts.NewEthHeaderManager(exec.config.RepoRoot, exec.logger),
Contract: contracts.NewEthHeaderManager(exec.client.EthOracle),
},
}

View File

@ -0,0 +1,19 @@
package appchain
import (
"fmt"
"github.com/sirupsen/logrus"
)
type Client struct {
EthOracle *EthLightChainOracle
}
func NewAppchainClient(path string, logger logrus.FieldLogger) (*Client, error) {
ropstenOracle, err := NewRopstenOracle(path, false, logger)
if err != nil {
return nil, fmt.Errorf("create eth ropsten error:%w", err)
}
return &Client{EthOracle: ropstenOracle}, nil
}

File diff suppressed because one or more lines are too long

View File

@ -27,11 +27,12 @@ type EthLightChainOracle struct {
}
const (
MinConfirmNum = 15
// block 10105112
RopstenHeader = "{\"parentHash\":\"0x4672d904ca88bdb365f83bc6050344fdcb672ce8e639e727f8c69247634e73f0\",\"sha3Uncles\":\"0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347\",\"miner\":\"0x1cdb00d07b721b98da52532db9a7d82d2a4bf2e0\",\"stateRoot\":\"0x823fbc8d2cf2d9c32832c6c1bd451ea84acdd79e39e88a7061215746a0794f40\",\"transactionsRoot\":\"0x65abe72faaaa113cf0a9374cefde93bc64cd264e2931ba95ee27c8d62499e63d\",\"receiptsRoot\":\"0xfac424a8e1a45789a5456fe1bc58228d93c28871df42dd789434e4de65f7e2e9\",\"logsBloom\":\"0x00200000000000000000000080000000000000000000000080010000000000000000000000000000020000000000000000000000000000000000000000200000000000000008000000000008000000200000000800000000000000020002000000000000080000000000000000000000000000000000000000000010000000000800000000000000014000000000000000000000000000080000004000000000020000000000000140000000000000000000001000000000001000000000000000000002000000200004000000002200000000000000003000000000020020000010000000000000000000000201000000000080000000000000000400000000\",\"difficulty\":\"0x729df1d\",\"number\":\"0x9a3118\",\"gasLimit\":\"0x98f36f\",\"gasUsed\":\"0x2fd96\",\"timestamp\":\"0x608506bf\",\"extraData\":\"0xd683010a01846765746886676f312e3136856c696e7578\",\"mixHash\":\"0x62c65e608f10001004171345c230a231afed11dad637b93545f600b71adb0f5d\",\"nonce\":\"0x7ea6f1aedb5ea8c1\",\"hash\":\"0x0d37ff8f4a8f1adcfd16add9cf8726e17a8097baa9a50d3b5fd51849476f7ec3\"}\n"
)
var MinConfirmNum uint64 = 15
// TODO: need to start with special header height
func NewRinkebyOracle(storagePath string, logger logrus.FieldLogger) (*EthLightChainOracle, error) {
appchainBlockHeaderPath := filepath.Join(storagePath, "eth_rinkeby")
@ -50,9 +51,8 @@ func NewRinkebyOracle(storagePath string, logger logrus.FieldLogger) (*EthLightC
}
// NewRopstenOracle inits with ropsten block 10105112, receives above the 10105112 headers
func NewRopstenOracle(storagePath string, logger logrus.FieldLogger) (*EthLightChainOracle, error) {
appchainBlockHeaderPath := filepath.Join(storagePath, "eth_ropsten")
db, err := leveldb.New(appchainBlockHeaderPath, 256, 0, "", false)
func NewRopstenOracle(storagePath string, readOnly bool, logger logrus.FieldLogger) (*EthLightChainOracle, error) {
db, err := leveldb.New(storagePath, 256, 0, "", readOnly)
if err != nil {
return nil, err
}
@ -75,7 +75,7 @@ func NewRopstenOracle(storagePath string, logger logrus.FieldLogger) (*EthLightC
lc, err := light.NewLightChain(les.NewLesOdr(database, light.DefaultServerIndexerConfig, nil, nil),
core.DefaultRopstenGenesisBlock().Config, ethash.New(ethash.Config{}, nil, false), params.RopstenTrustedCheckpoint)
if err != nil {
return nil, err
return nil, fmt.Errorf("new light client error:%v", err)
}
return &EthLightChainOracle{lc: lc, logger: logger}, nil

View File

@ -6,14 +6,11 @@ import (
"os"
"testing"
"github.com/meshplus/bitxhub-kit/log"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/light"
"github.com/ethereum/go-ethereum/rlp"
"github.com/ethereum/go-ethereum/trie"
"github.com/ethereum/go-ethereum/core/types"
"github.com/meshplus/bitxhub-kit/log"
"github.com/stretchr/testify/require"
)
@ -58,7 +55,7 @@ func TestRopstenLightClient(t *testing.T) {
require.Nil(t, err)
defer os.RemoveAll(repoRoot)
oracle, err := NewRopstenOracle(repoRoot, log.NewWithModule("test"))
oracle, err := NewRopstenOracle(repoRoot, false, log.NewWithModule("test"))
require.Nil(t, err)
currentHeader := oracle.CurrentHeader()
@ -90,7 +87,7 @@ func TestVerifyProof(t *testing.T) {
receipt2 = "{\"root\":\"0x\",\"status\":\"0x1\",\"cumulativeGasUsed\":\"0x2fd96\",\"logsBloom\":\"0x00200000000000000000000080000000000000000000000080010000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000000000008000000200000000800000000000000000000000000000000080000000000000000000000000000000000000000000010000000000000000000000000004000000000000000000000000000080000004000000000000000000000000140000000000000000000001000000000001000000000000000000002000000200000000000002000000000000000001000000000020020000000000000000000000000000200000000000080000000000000000400000000\",\"logs\":[{\"address\":\"0x2d80502854fc7304c3e3457084de549f5016b73f\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x0000000000000000000000004183d62963434056e75e9854bc4ba92aa43a2d08\",\"0x000000000000000000000000dc914190feeb16d6f7c5d9a22826d515be5c5857\"],\"data\":\"0x00000000000000000000000000000000000000000000000000000000000b4cc6\",\"blockNumber\":\"0x9a3118\",\"transactionHash\":\"0x37fc9bf0e945443c862efe5405d9a179dced048c3baed58751f00d84ba64701c\",\"transactionIndex\":\"0x2\",\"blockHash\":\"0x0d37ff8f4a8f1adcfd16add9cf8726e17a8097baa9a50d3b5fd51849476f7ec3\",\"logIndex\":\"0x2\",\"removed\":false},{\"address\":\"0x0d9c8723b343a8368bebe0b5e89273ff8d712e3c\",\"topics\":[\"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef\",\"0x000000000000000000000000dc914190feeb16d6f7c5d9a22826d515be5c5857\",\"0x0000000000000000000000004183d62963434056e75e9854bc4ba92aa43a2d08\"],\"data\":\"0x0000000000000000000000000000000000000000000000000000000015ee0375\",\"blockNumber\":\"0x9a3118\",\"transactionHash\":\"0x37fc9bf0e945443c862efe5405d9a179dced048c3baed58751f00d84ba64701c\",\"transactionIndex\":\"0x2\",\"blockHash\":\"0x0d37ff8f4a8f1adcfd16add9cf8726e17a8097baa9a50d3b5fd51849476f7ec3\",\"logIndex\":\"0x3\",\"removed\":false},{\"address\":\"0xdc914190feeb16d6f7c5d9a22826d515be5c5857\",\"topics\":[\"0x1c411e9a96e071241c2f21f7726b17ae89e3cab4c78be50e062b03a9fffbbad1\"],\"data\":\"0x00000000000000000000000000000000000000000000000000001a4f9e78bc5e0000000000000000000000000000000000000000000000000000000d8457df78\",\"blockNumber\":\"0x9a3118\",\"transactionHash\":\"0x37fc9bf0e945443c862efe5405d9a179dced048c3baed58751f00d84ba64701c\",\"transactionIndex\":\"0x2\",\"blockHash\":\"0x0d37ff8f4a8f1adcfd16add9cf8726e17a8097baa9a50d3b5fd51849476f7ec3\",\"logIndex\":\"0x4\",\"removed\":false},{\"address\":\"0xdc914190feeb16d6f7c5d9a22826d515be5c5857\",\"topics\":[\"0xd78ad95fa46c994b6551d0da85fc275fe613ce37657fb8d5e3d130840159d822\",\"0x0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d\",\"0x0000000000000000000000004183d62963434056e75e9854bc4ba92aa43a2d08\"],\"data\":\"0x000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000b4cc60000000000000000000000000000000000000000000000000000000015ee03750000000000000000000000000000000000000000000000000000000000000000\",\"blockNumber\":\"0x9a3118\",\"transactionHash\":\"0x37fc9bf0e945443c862efe5405d9a179dced048c3baed58751f00d84ba64701c\",\"transactionIndex\":\"0x2\",\"blockHash\":\"0x0d37ff8f4a8f1adcfd16add9cf8726e17a8097baa9a50d3b5fd51849476f7ec3\",\"logIndex\":\"0x5\",\"removed\":false}],\"transactionHash\":\"0x37fc9bf0e945443c862efe5405d9a179dced048c3baed58751f00d84ba64701c\",\"contractAddress\":\"0x0000000000000000000000000000000000000000\",\"gasUsed\":\"0x19858\",\"blockHash\":\"0x0d37ff8f4a8f1adcfd16add9cf8726e17a8097baa9a50d3b5fd51849476f7ec3\",\"blockNumber\":\"0x9a3118\",\"transactionIndex\":\"0x2\"}\n"
)
receiptList := []string{receipt0, receipt1, receipt2}
oracle, err := NewRopstenOracle(repoRoot, log.NewWithModule("test"))
oracle, err := NewRopstenOracle(repoRoot, false, log.NewWithModule("test"))
require.Nil(t, err)
receipts := make([]*types.Receipt, 0, len(receiptList))
@ -119,6 +116,7 @@ func TestVerifyProof(t *testing.T) {
proof, err := rlp.EncodeToBytes(nodeSet.NodeList())
require.Nil(t, err)
err = VerifyProof(receipts[index], header, proof)
MinConfirmNum = 0
err = oracle.VerifyProof(receipts[index], proof)
require.Nil(t, err)
}

File diff suppressed because one or more lines are too long

View File

@ -1,10 +1,19 @@
package peermgr
import (
"bytes"
"crypto/sha256"
"encoding/json"
"fmt"
"strconv"
"strings"
"github.com/ethereum/go-ethereum/accounts/abi"
"github.com/ethereum/go-ethereum/crypto"
"github.com/meshplus/bitxhub-kit/types"
"github.com/meshplus/bitxhub/internal/executor/oracle/appchain"
"github.com/ethereum/go-ethereum/common"
"github.com/meshplus/bitxhub-model/constant"
"github.com/meshplus/bitxhub-model/pb"
@ -36,12 +45,14 @@ func (swarm *Swarm) handleMessage(s network.Stream, data []byte) {
go swarm.orderMessageFeed.Send(events.OrderMessageEvent{Data: m.Data})
case pb.Message_FETCH_BLOCK_SIGN:
swarm.handleFetchBlockSignMessage(s, m.Data)
case pb.Message_FETCH_ASSET_EXCHANEG_SIGN:
case pb.Message_FETCH_ASSET_EXCHANGE_SIGN:
swarm.handleFetchAssetExchangeSignMessage(s, m.Data)
case pb.Message_FETCH_IBTP_SIGN:
swarm.handleFetchIBTPSignMessage(s, m.Data)
case pb.Message_FETCH_MINT_SIGN:
swarm.handleFetchMinterSignMessage(s, m.Data)
swarm.handleFetchMintSignMessage(s, m.Data)
case pb.Message_FETCH_BURN_SIGN:
swarm.handleFetchBurnSignMessage(s, m.Data)
case pb.Message_CHECK_MASTER_PIER:
swarm.handleAskPierMaster(s, m.Data)
case pb.Message_CHECK_MASTER_PIER_ACK:
@ -280,7 +291,7 @@ func (swarm *Swarm) handleFetchIBTPSignMessage(s network.Stream, data []byte) {
}
}
func (swarm *Swarm) handleFetchMinterSignMessage(s network.Stream, data []byte) {
func (swarm *Swarm) handleFetchMintSignMessage(s network.Stream, data []byte) {
handle := func(id string) (string, []byte, error) {
swarm.logger.WithField("mint id", id).Debug("Handle fetching minter sign message")
@ -289,7 +300,7 @@ func (swarm *Swarm) handleFetchMinterSignMessage(s network.Stream, data []byte)
return "", nil, fmt.Errorf("cannot find minter record with id %s", id)
}
hash := sha256.Sum256([]byte(fmt.Sprintf("%s", id)))
hash := common.HexToHash(id)
key := swarm.repo.Key
sign, err := key.PrivKey.Sign(hash[:])
if err != nil {
@ -326,6 +337,95 @@ func (swarm *Swarm) handleFetchMinterSignMessage(s network.Stream, data []byte)
}
}
func (swarm *Swarm) handleFetchBurnSignMessage(s network.Stream, data []byte) {
handle := func(hash string) (string, []byte, error) {
receipt, err := swarm.ledger.GetReceipt(types.NewHashByStr(hash))
if err != nil {
return "", nil, fmt.Errorf("cannot find receipt with hash %s", hash)
}
tx, err := swarm.ledger.GetTransaction(types.NewHashByStr(hash))
if err != nil {
return "", nil, fmt.Errorf("cannot find transaction with hash %s", hash)
}
ok, interchainSwapAddr := swarm.ledger.GetState(constant.EthHeaderMgrContractAddr.Address(), []byte(contracts.InterchainSwapAddrKey))
if !ok {
return "", nil, fmt.Errorf("cannot find interchainswap contract")
}
interchainAbi, err := abi.JSON(bytes.NewReader([]byte(appchain.InterchainSwapABI)))
if err != nil {
return "", nil, err
}
var burn *appchain.InterchainSwapBurn
for _, log := range receipt.GetEvmLogs() {
if !strings.EqualFold(log.Address.String(), common.BytesToAddress(interchainSwapAddr).String()) {
continue
}
if log.Removed {
continue
}
for _, topic := range log.Topics {
if strings.EqualFold(topic.String(), interchainAbi.Events["Burn"].ID.String()) {
if err := interchainAbi.UnpackIntoInterface(&burn, "Burn", log.Data); err != nil {
swarm.logger.Error(err)
continue
}
}
}
}
if burn == nil {
return "", nil, fmt.Errorf("not found burn log:%v", receipt.TxHash.Hash)
}
//abi.encodePacked
abiHash := crypto.Keccak256Hash(
burn.EthToken.Bytes(),
tx.GetFrom().Bytes(),
burn.Recipient.Bytes(),
common.LeftPadBytes(burn.Amount.Bytes(), 32),
receipt.TxHash.Bytes(),
)
prefixedHash := crypto.Keccak256Hash(
[]byte(fmt.Sprintf("\x19Ethereum Signed Message:\n%v", len(hash))),
abiHash.Bytes(),
)
key := swarm.repo.Key
sign, err := key.PrivKey.Sign(prefixedHash[:])
if err != nil {
return "", nil, fmt.Errorf("bitxhub sign: %w", err)
}
return key.Address, sign, nil
}
address, signed, err := handle(string(data))
if err != nil {
swarm.logger.Errorf("handle fetch-burn-sign: %s", err)
return
}
m := model.MerkleWrapperSign{
Address: address,
Signature: signed,
}
body, err := m.Marshal()
if err != nil {
swarm.logger.Errorf("marshal merkle wrapper sign: %s", err)
return
}
msg := &pb.Message{
Type: pb.Message_FETCH_BURN_SIGN_ACK,
Data: body,
}
if err := swarm.SendWithStream(s, msg); err != nil {
swarm.logger.Errorf("send burn sign back: %s", err)
}
}
func (swarm *Swarm) handleGetBlocksPack(s network.Stream, msg *pb.Message) error {
req := &pb.GetBlocksRequest{}
if err := req.Unmarshal(msg.Data); err != nil {