diff --git a/action/rlp_tx.go b/action/rlp_tx.go index 2d7c34613c..3b9d48665c 100644 --- a/action/rlp_tx.go +++ b/action/rlp_tx.go @@ -9,17 +9,18 @@ import ( "github.com/ethereum/go-ethereum/rlp" "github.com/iotexproject/go-pkgs/crypto" "github.com/iotexproject/go-pkgs/hash" + "github.com/iotexproject/iotex-proto/golang/iotextypes" "github.com/pkg/errors" "golang.org/x/crypto/sha3" ) -func rlpRawHash(rawTx *types.Transaction, chainID uint32) (hash.Hash256, error) { - h := types.NewEIP155Signer(big.NewInt(int64(chainID))).Hash(rawTx) +func rlpRawHash(rawTx *types.Transaction, signer types.Signer) (hash.Hash256, error) { + h := signer.Hash(rawTx) return hash.BytesToHash256(h[:]), nil } -func rlpSignedHash(tx *types.Transaction, chainID uint32, sig []byte) (hash.Hash256, error) { - signedTx, err := RawTxToSignedTx(tx, chainID, sig) +func rlpSignedHash(tx *types.Transaction, signer types.Signer, sig []byte) (hash.Hash256, error) { + signedTx, err := RawTxToSignedTx(tx, signer, sig) if err != nil { return hash.ZeroHash256, err } @@ -31,7 +32,7 @@ func rlpSignedHash(tx *types.Transaction, chainID uint32, sig []byte) (hash.Hash } // RawTxToSignedTx converts the raw tx to corresponding signed tx -func RawTxToSignedTx(rawTx *types.Transaction, chainID uint32, sig []byte) (*types.Transaction, error) { +func RawTxToSignedTx(rawTx *types.Transaction, signer types.Signer, sig []byte) (*types.Transaction, error) { if len(sig) != 65 { return nil, errors.Errorf("invalid signature length = %d, expecting 65", len(sig)) } @@ -41,9 +42,7 @@ func RawTxToSignedTx(rawTx *types.Transaction, chainID uint32, sig []byte) (*typ sc[64] -= 27 } - // TODO: currently all our web3 tx are EIP-155 protected tx - // in the future release, use proper signer for other supported tx types (EIP-1559, EIP-2930) - signedTx, err := rawTx.WithSignature(types.NewEIP155Signer(big.NewInt(int64(chainID))), sc) + signedTx, err := rawTx.WithSignature(signer, sc) if err != nil { return nil, err } @@ -83,3 +82,68 @@ func DecodeRawTx(rawData string, chainID uint32) (tx *types.Transaction, sig []b pubkey, err = crypto.RecoverPubkey(rawHash[:], sig) return } + +// DecodeEtherTx decodes raw data string into eth tx +func DecodeEtherTx(rawData string) (*types.Transaction, iotextypes.Encoding, []byte, crypto.PublicKey, error) { + var ( + tx types.Transaction + encoding iotextypes.Encoding + sig []byte + pubkey crypto.PublicKey + ) + //remove Hex prefix and decode string to byte + rawData = strings.Replace(rawData, "0x", "", -1) + rawData = strings.Replace(rawData, "0X", "", -1) + rawTxBytes, err := hex.DecodeString(rawData) + if err != nil { + return &tx, encoding, sig, pubkey, err + } + + // decode raw data into rlp tx + if err = tx.UnmarshalBinary(rawTxBytes); err != nil { + return &tx, encoding, sig, pubkey, err + } + + // extract correct V value + var ( + signer types.Signer + V, R, S = tx.RawSignatureValues() + ) + switch tx.Type() { + case types.LegacyTxType: + if tx.Protected() { + chainIdMul := tx.ChainId() + V = new(big.Int).Sub(V, chainIdMul.Lsh(chainIdMul, 1)) + V.Sub(V, big.NewInt(8)) + encoding = iotextypes.Encoding_ETHEREUM_EIP155 + signer = types.NewEIP155Signer(tx.ChainId()) + } else { + // tx has pre-EIP155 signature + encoding = iotextypes.Encoding_ETHEREUM_UNPROTECTED + signer = types.HomesteadSigner{} + } + case types.AccessListTxType: + // AL txs are defined to use 0 and 1 as their recovery + // id, add 27 to become equivalent to unprotected Homestead signatures. + V = new(big.Int).Add(V, big.NewInt(27)) + encoding = iotextypes.Encoding_ETHEREUM_ACCESSLIST + signer = types.NewEIP2930Signer(tx.ChainId()) + default: + return &tx, encoding, sig, pubkey, ErrNotSupported + } + + // construct signature + if V.BitLen() > 8 { + return &tx, encoding, sig, pubkey, ErrNotSupported + } + r, s := R.Bytes(), S.Bytes() + sig = make([]byte, 65) + copy(sig[32-len(r):32], r) + copy(sig[64-len(s):64], s) + sig[64] = byte(V.Uint64()) + + // recover public key + rawHash := signer.Hash(&tx) + pubkey, err = crypto.RecoverPubkey(rawHash[:], sig) + return &tx, encoding, sig, pubkey, err +} diff --git a/action/rlp_tx_test.go b/action/rlp_tx_test.go index 7098a92839..3f5764ad12 100644 --- a/action/rlp_tx_test.go +++ b/action/rlp_tx_test.go @@ -78,7 +78,8 @@ func TestGenerateRlp(t *testing.T) { require.Contains(err.Error(), v.err) continue } - h, err := rlpSignedHash(tx, _evmNetworkID, v.sig) + signer, err := EthSigner(iotextypes.Encoding_ETHEREUM_EIP155, _evmNetworkID) + h, err := rlpSignedHash(tx, signer, v.sig) if err != nil { require.Contains(err.Error(), v.err) } @@ -289,14 +290,18 @@ func TestRlpDecodeVerify(t *testing.T) { for _, v := range rlpTests { // decode received RLP tx - tx, sig, pubkey, err := DecodeRawTx(v.raw, _evmNetworkID) + tx, encoding, sig, pubkey, err := DecodeEtherTx(v.raw) require.NoError(err) + require.EqualValues(types.LegacyTxType, tx.Type()) + require.True(tx.Protected()) + require.EqualValues(1, encoding) + require.EqualValues(_evmNetworkID, tx.ChainId().Uint64()) require.Equal(v.pubkey, pubkey.HexString()) require.Equal(v.pkhash, hex.EncodeToString(pubkey.Hash())) // convert to our Execution pb := &iotextypes.Action{ - Encoding: iotextypes.Encoding_ETHEREUM_RLP, + Encoding: iotextypes.Encoding_ETHEREUM_EIP155, } pb.Core = convertToNativeProto(tx, v.actType) pb.SenderPubKey = pubkey.Bytes() @@ -389,17 +394,36 @@ func TestIssue3944(t *testing.T) { S: new(big.Int).SetBytes(sig[32:64]), }) + r.EqualValues(types.LegacyTxType, tx.Type()) + r.False(tx.Protected()) v, q, s := tx.RawSignatureValues() r.Equal(sig[:32], q.Bytes()) r.Equal(sig[32:64], s.Bytes()) r.Equal("1b", v.Text(16)) r.NotEqual(hash, tx.Hash().Hex()) // hash does not match with wrong V value in signature - tx1, err := RawTxToSignedTx(tx, 4690, sig) + signer, err := EthSigner(iotextypes.Encoding_ETHEREUM_EIP155, 4690) r.NoError(err) + tx1, err := RawTxToSignedTx(tx, signer, sig) + r.NoError(err) + r.True(tx1.Protected()) + r.EqualValues(4690, tx1.ChainId().Uint64()) v, q, s = tx1.RawSignatureValues() r.Equal(sig[:32], q.Bytes()) r.Equal(sig[32:64], s.Bytes()) r.Equal("9415", v.String()) // this is the correct V value corresponding to chainID = 4690 r.Equal(hash, tx1.Hash().Hex()) } + +func TestDetermine(t *testing.T) { + r := require.New(t) + + tx, encoding, sig, pubkey, err := DecodeEtherTx("0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222") + r.EqualValues(types.LegacyTxType, tx.Type()) + r.False(tx.Protected()) + r.EqualValues(2, encoding) + r.Zero(tx.ChainId().Uint64()) + r.Equal(65, len(sig)) + r.Equal("3fab184622dc19b6109349b94811493bf2a45362", hex.EncodeToString(pubkey.Hash())) + r.NoError(err) +} diff --git a/action/sealedenvelope.go b/action/sealedenvelope.go index d2107e2ede..d7bc2dbbef 100644 --- a/action/sealedenvelope.go +++ b/action/sealedenvelope.go @@ -2,7 +2,9 @@ package action import ( "encoding/hex" + "math/big" + "github.com/ethereum/go-ethereum/core/types" "github.com/iotexproject/go-pkgs/crypto" "github.com/iotexproject/go-pkgs/hash" "github.com/iotexproject/iotex-address/address" @@ -30,7 +32,7 @@ type SealedEnvelope struct { // an all-0 return value means the transaction is invalid func (sealed *SealedEnvelope) envelopeHash() (hash.Hash256, error) { switch sealed.encoding { - case iotextypes.Encoding_ETHEREUM_RLP: + case iotextypes.Encoding_ETHEREUM_EIP155, iotextypes.Encoding_ETHEREUM_UNPROTECTED, iotextypes.Encoding_ETHEREUM_ACCESSLIST: act, ok := sealed.Action().(EthCompatibleAction) if !ok { return hash.ZeroHash256, ErrInvalidAct @@ -39,7 +41,11 @@ func (sealed *SealedEnvelope) envelopeHash() (hash.Hash256, error) { if err != nil { return hash.ZeroHash256, err } - return rlpRawHash(tx, sealed.evmNetworkID) + signer, err := EthSigner(sealed.encoding, sealed.evmNetworkID) + if err != nil { + return hash.ZeroHash256, err + } + return rlpRawHash(tx, signer) case iotextypes.Encoding_IOTEX_PROTOBUF: return hash.Hash256b(byteutil.Must(proto.Marshal(sealed.Envelope.Proto()))), nil default: @@ -47,6 +53,19 @@ func (sealed *SealedEnvelope) envelopeHash() (hash.Hash256, error) { } } +func EthSigner(txType iotextypes.Encoding, chainID uint32) (types.Signer, error) { + switch txType { + case iotextypes.Encoding_ETHEREUM_EIP155: + return types.NewEIP155Signer(big.NewInt(int64(chainID))), nil + case iotextypes.Encoding_ETHEREUM_UNPROTECTED: + return types.HomesteadSigner{}, nil + case iotextypes.Encoding_ETHEREUM_ACCESSLIST: + return types.NewEIP2930Signer(big.NewInt(int64(chainID))), nil + default: + return nil, ErrInvalidAct + } +} + // Hash returns the hash value of SealedEnvelope. // an all-0 return value means the transaction is invalid func (sealed *SealedEnvelope) Hash() (hash.Hash256, error) { @@ -62,7 +81,7 @@ func (sealed *SealedEnvelope) Hash() (hash.Hash256, error) { func (sealed *SealedEnvelope) calcHash() (hash.Hash256, error) { switch sealed.encoding { - case iotextypes.Encoding_ETHEREUM_RLP: + case iotextypes.Encoding_ETHEREUM_EIP155, iotextypes.Encoding_ETHEREUM_UNPROTECTED, iotextypes.Encoding_ETHEREUM_ACCESSLIST: act, ok := sealed.Action().(EthCompatibleAction) if !ok { return hash.ZeroHash256, ErrInvalidAct @@ -71,7 +90,11 @@ func (sealed *SealedEnvelope) calcHash() (hash.Hash256, error) { if err != nil { return hash.ZeroHash256, err } - return rlpSignedHash(tx, sealed.evmNetworkID, sealed.Signature()) + signer, err := EthSigner(sealed.encoding, sealed.evmNetworkID) + if err != nil { + return hash.ZeroHash256, err + } + return rlpSignedHash(tx, signer, sealed.Signature()) case iotextypes.Encoding_IOTEX_PROTOBUF: return hash.Hash256b(byteutil.Must(proto.Marshal(sealed.Proto()))), nil default: @@ -134,9 +157,9 @@ func (sealed *SealedEnvelope) loadProto(pbAct *iotextypes.Action, evmID uint32) if err != nil { return err } - encoding := pbAct.GetEncoding() - switch encoding { - case iotextypes.Encoding_ETHEREUM_RLP: + sealed.encoding = pbAct.GetEncoding() + switch sealed.encoding { + case iotextypes.Encoding_ETHEREUM_EIP155, iotextypes.Encoding_ETHEREUM_UNPROTECTED, iotextypes.Encoding_ETHEREUM_ACCESSLIST: // verify action type can support RLP-encoding act, ok := elp.Action().(EthCompatibleAction) if !ok { @@ -146,14 +169,18 @@ func (sealed *SealedEnvelope) loadProto(pbAct *iotextypes.Action, evmID uint32) if err != nil { return err } - if _, err = rlpSignedHash(tx, evmID, pbAct.GetSignature()); err != nil { + signer, err := EthSigner(sealed.encoding, sealed.evmNetworkID) + if err != nil { + return err + } + if _, err = rlpSignedHash(tx, signer, pbAct.GetSignature()); err != nil { return err } sealed.evmNetworkID = evmID case iotextypes.Encoding_IOTEX_PROTOBUF: break default: - return errors.Errorf("unknown encoding type %v", encoding) + return errors.Errorf("unknown encoding type %v", sealed.encoding) } // clear 'sealed' and populate new value @@ -161,7 +188,6 @@ func (sealed *SealedEnvelope) loadProto(pbAct *iotextypes.Action, evmID uint32) sealed.srcPubkey = srcPub sealed.signature = make([]byte, sigSize) copy(sealed.signature, pbAct.GetSignature()) - sealed.encoding = encoding sealed.hash = hash.ZeroHash256 sealed.srcAddress = nil return nil diff --git a/action/sealedenvelope_test.go b/action/sealedenvelope_test.go index ec95509bfc..d9f2375d1d 100644 --- a/action/sealedenvelope_test.go +++ b/action/sealedenvelope_test.go @@ -62,7 +62,7 @@ func TestSealedEnvelope_InvalidType(t *testing.T) { SetAction(r). SetGasLimit(100000).Build() selp := FakeSeal(elp, identityset.PrivateKey(27).PublicKey()) - selp.encoding = iotextypes.Encoding_ETHEREUM_RLP + selp.encoding = iotextypes.Encoding_ETHEREUM_EIP155 hash1, err := selp.envelopeHash() require.Equal(hash1, hash.ZeroHash256) require.Contains(err.Error(), "invalid action type") @@ -148,7 +148,7 @@ func TestSealedEnvelope_Proto(t *testing.T) { err string }{ {0, _signByte, "invalid signature length ="}, - {3, _validSig, "unknown encoding type"}, + {iotextypes.Encoding_ETHEREUM_ACCESSLIST + 1, _validSig, "unknown encoding type"}, } { se.encoding = v.encoding se.signature = v.sig diff --git a/api/coreservice.go b/api/coreservice.go index 32951b9d42..f33141386a 100644 --- a/api/coreservice.go +++ b/api/coreservice.go @@ -125,6 +125,8 @@ type ( LogsInBlockByHash(filter *logfilter.LogFilter, blockHash hash.Hash256) ([]*action.Log, error) // LogsInRange filter logs among [start, end] blocks LogsInRange(filter *logfilter.LogFilter, start, end, paginationSize uint64) ([]*action.Log, []hash.Hash256, error) + // Genesis returns the genesis of the chain + Genesis() genesis.Genesis // EVMNetworkID returns the network id of evm EVMNetworkID() uint32 // ChainID returns the chain id of evm @@ -1588,6 +1590,11 @@ func (core *coreService) ActionsInActPool(actHashes []string) ([]action.SealedEn return ret, nil } +// Genesis returns the genesis of the chain +func (core *coreService) Genesis() genesis.Genesis { + return core.bc.Genesis() +} + // EVMNetworkID returns the network id of evm func (core *coreService) EVMNetworkID() uint32 { return core.bc.EvmNetworkID() diff --git a/api/web3server.go b/api/web3server.go index 44c6b7f3b0..0be5777e04 100644 --- a/api/web3server.go +++ b/api/web3server.go @@ -12,6 +12,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth/tracers/logger" + "github.com/iotexproject/go-pkgs/crypto" "github.com/iotexproject/go-pkgs/hash" "github.com/iotexproject/go-pkgs/util" "github.com/iotexproject/iotex-address/address" @@ -73,6 +74,7 @@ var ( errInvalidFormat = errors.New("invalid format of request") errNotImplemented = errors.New("method not implemented") errInvalidFilterID = errors.New("filter not found") + errInvalidEvmChainID = errors.New("invalid EVM chain ID") errInvalidBlock = errors.New("invalid block") errUnsupportedAction = errors.New("the type of action is not supported") errMsgBatchTooLarge = errors.New("batch too large") @@ -433,7 +435,24 @@ func (svr *web3Handler) sendRawTransaction(in *gjson.Result) (interface{}, error return nil, errInvalidFormat } // parse raw data string from json request - tx, sig, pubkey, err := action.DecodeRawTx(dataStr.String(), svr.coreService.EVMNetworkID()) + var ( + tx *types.Transaction + sig []byte + pubkey crypto.PublicKey + err error + encoding iotextypes.Encoding + cs = svr.coreService + ) + if g := cs.Genesis(); g.IsSumatra(cs.TipHeight()) { + tx, encoding, sig, pubkey, err = action.DecodeEtherTx(dataStr.String()) + if !tx.Protected() && tx.ChainId().Uint64() != uint64(cs.EVMNetworkID()) { + return nil, errInvalidEvmChainID + } + } else { + // before Sumatra height, all tx are EIP-155 format + tx, sig, pubkey, err = action.DecodeRawTx(dataStr.String(), cs.EVMNetworkID()) + encoding = iotextypes.Encoding_ETHEREUM_EIP155 + } if err != nil { return nil, err } @@ -445,9 +464,9 @@ func (svr *web3Handler) sendRawTransaction(in *gjson.Result) (interface{}, error Core: elp.Proto(), SenderPubKey: pubkey.Bytes(), Signature: sig, - Encoding: iotextypes.Encoding_ETHEREUM_RLP, + Encoding: encoding, } - actionHash, err := svr.coreService.SendAction(context.Background(), req) + actionHash, err := cs.SendAction(context.Background(), req) if err != nil { return nil, err } diff --git a/api/web3server_utils.go b/api/web3server_utils.go index 8faa4b456b..7214de5173 100644 --- a/api/web3server_utils.go +++ b/api/web3server_utils.go @@ -19,6 +19,7 @@ import ( "github.com/iotexproject/go-pkgs/util" "github.com/iotexproject/iotex-address/address" "github.com/iotexproject/iotex-proto/golang/iotexapi" + "github.com/iotexproject/iotex-proto/golang/iotextypes" "github.com/pkg/errors" "github.com/tidwall/gjson" "go.uber.org/zap" @@ -117,7 +118,11 @@ func (svr *web3Handler) getTransactionFromActionInfo(blkHash hash.Hash256, selp if err != nil { return nil, err } - tx, err := action.RawTxToSignedTx(ethTx, svr.coreService.EVMNetworkID(), selp.Signature()) + signer, err := action.EthSigner(iotextypes.Encoding(selp.Encoding()), svr.coreService.EVMNetworkID()) + if err != nil { + return nil, err + } + tx, err := action.RawTxToSignedTx(ethTx, signer, selp.Signature()) if err != nil { return nil, err } diff --git a/go.mod b/go.mod index 6b8849d3df..356c829b21 100644 --- a/go.mod +++ b/go.mod @@ -23,7 +23,7 @@ require ( github.com/iotexproject/iotex-address v0.2.8 github.com/iotexproject/iotex-antenna-go/v2 v2.5.1 github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d - github.com/iotexproject/iotex-proto v0.5.14 + github.com/iotexproject/iotex-proto v0.5.15-0.20231108184801-bc89358f2344 github.com/libp2p/go-libp2p-core v0.8.5 github.com/mackerelio/go-osstat v0.2.4 github.com/miguelmota/go-ethereum-hdwallet v0.1.1 diff --git a/go.sum b/go.sum index 04f3c46c55..45dc06ddad 100644 --- a/go.sum +++ b/go.sum @@ -511,8 +511,8 @@ github.com/iotexproject/iotex-antenna-go/v2 v2.5.1/go.mod h1:8pDZcM45M0gY6jm3PoM github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d h1:/j1xCAC9YiG/8UKqYvycS/v3ddVsb1G7AMyLXOjeYI0= github.com/iotexproject/iotex-election v0.3.5-0.20210611041425-20ddf674363d/go.mod h1:GRWevxtqQ4gPMrd7Qxhr29/7aTgvjiTp+rFI9KMMZEo= github.com/iotexproject/iotex-proto v0.5.0/go.mod h1:Xg6REkv+nTZN+OC22xXIQuqKdTWWHwOAJEXCoMpDwtI= -github.com/iotexproject/iotex-proto v0.5.14 h1:03UuHO5M1Dr6mjPk+72zoJfY2OEm93k9Z0oggHuzA6s= -github.com/iotexproject/iotex-proto v0.5.14/go.mod h1:wQpCk3Df0fPID+K8ohiICGj+cWRmcQ3wanT+aSrnIPo= +github.com/iotexproject/iotex-proto v0.5.15-0.20231108184801-bc89358f2344 h1:Io64R5K/xpDIvvRXVzRq8Z1QQr/C+MN9780Jj2aj6u8= +github.com/iotexproject/iotex-proto v0.5.15-0.20231108184801-bc89358f2344/go.mod h1:wQpCk3Df0fPID+K8ohiICGj+cWRmcQ3wanT+aSrnIPo= github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= diff --git a/test/mock/mock_apicoreservice/mock_apicoreservice.go b/test/mock/mock_apicoreservice/mock_apicoreservice.go index bcec385938..7d2dc60beb 100644 --- a/test/mock/mock_apicoreservice/mock_apicoreservice.go +++ b/test/mock/mock_apicoreservice/mock_apicoreservice.go @@ -18,6 +18,7 @@ import ( logfilter "github.com/iotexproject/iotex-core/api/logfilter" apitypes "github.com/iotexproject/iotex-core/api/types" block "github.com/iotexproject/iotex-core/blockchain/block" + genesis "github.com/iotexproject/iotex-core/blockchain/genesis" iotexapi "github.com/iotexproject/iotex-proto/golang/iotexapi" iotextypes "github.com/iotexproject/iotex-proto/golang/iotextypes" ) @@ -334,6 +335,20 @@ func (mr *MockCoreServiceMockRecorder) EstimateGasForNonExecution(arg0 interface return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "EstimateGasForNonExecution", reflect.TypeOf((*MockCoreService)(nil).EstimateGasForNonExecution), arg0) } +// Genesis mocks base method. +func (m *MockCoreService) Genesis() genesis.Genesis { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Genesis") + ret0, _ := ret[0].(genesis.Genesis) + return ret0 +} + +// Genesis indicates an expected call of Genesis. +func (mr *MockCoreServiceMockRecorder) Genesis() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Genesis", reflect.TypeOf((*MockCoreService)(nil).Genesis)) +} + // LogsInBlockByHash mocks base method. func (m *MockCoreService) LogsInBlockByHash(filter *logfilter.LogFilter, blockHash hash.Hash256) ([]*action.Log, error) { m.ctrl.T.Helper() diff --git a/test/mock/mock_blocksync/mock_blocksync.go b/test/mock/mock_blocksync/mock_blocksync.go index 220368100e..4099894d66 100644 --- a/test/mock/mock_blocksync/mock_blocksync.go +++ b/test/mock/mock_blocksync/mock_blocksync.go @@ -36,6 +36,20 @@ func (m *MockBlockSync) EXPECT() *MockBlockSyncMockRecorder { return m.recorder } +// BuildReport mocks base method. +func (m *MockBlockSync) BuildReport() string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "BuildReport") + ret0, _ := ret[0].(string) + return ret0 +} + +// BuildReport indicates an expected call of BuildReport. +func (mr *MockBlockSyncMockRecorder) BuildReport() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "BuildReport", reflect.TypeOf((*MockBlockSync)(nil).BuildReport)) +} + // ProcessBlock mocks base method. func (m *MockBlockSync) ProcessBlock(arg0 context.Context, arg1 string, arg2 *block.Block) error { m.ctrl.T.Helper()