lotus/chain/consensus/signatures.go
Aarsh Shah c9c070727a
feat: ETH compatibility in Filecoin : Support Homestead and EIP-155 Ethereum transactions("legacy" transactions) in Filecoin (#11969)
* poc for eth legacy tx

* print statements

* finished

* tests work

* remove print statements

* Remove all print statements

* remove extraneous changes

* cleaned up code and interface

* run make jen

* dont duplicate signature

* go mod tidy and remove prints

* clean up tests

* test for conversion

* changes as per review

* more unit tests for legacy txns

* Apply suggestions from code review

Co-authored-by: Rod Vagg <rod@vagg.org>

* address review comments from Rodd

* changes as per zen's 2nd review

* go mod tidy

* feat: ETH compatibility in Filecoin : Support EIP-155 Ethereum transactions in Filecoin (#11970)

* itests passing for 155 tx

* first working version for EIP-155 transactions

* green itest

* add docs

* tests

* remove print stmt

* remove print stmt

* validate signature

* changes as per zen's review

* correct signature verification

* gate tx by Network Version

* handle arajsek review

* fix imports order

* fix lint

* dont lock in mpool for network gating ETH messages

* sender can be an ID address

---------

Co-authored-by: Rod Vagg <rod@vagg.org>
2024-06-05 09:25:50 +04:00

71 lines
2.3 KiB
Go

package consensus
import (
"golang.org/x/xerrors"
"github.com/filecoin-project/go-address"
"github.com/filecoin-project/go-state-types/crypto"
"github.com/filecoin-project/go-state-types/network"
"github.com/filecoin-project/lotus/chain/types"
"github.com/filecoin-project/lotus/chain/types/ethtypes"
"github.com/filecoin-project/lotus/lib/sigs"
)
// AuthenticateMessage authenticates the message by verifying that the supplied
// SignedMessage was signed by the indicated Address, computing the correct
// signature payload depending on the signature type. The supplied Address type
// must be recognized by the registered verifier for the signature type.
func AuthenticateMessage(msg *types.SignedMessage, signer address.Address) error {
var digest []byte
signatureType := msg.Signature.Type
signatureCopy := msg.Signature
switch signatureType {
case crypto.SigTypeDelegated:
signatureCopy.Data = make([]byte, len(msg.Signature.Data))
copy(signatureCopy.Data, msg.Signature.Data)
ethTx, err := ethtypes.EthTransactionFromSignedFilecoinMessage(msg)
if err != nil {
return xerrors.Errorf("failed to reconstruct Ethereum transaction: %w", err)
}
filecoinMsg, err := ethTx.ToUnsignedFilecoinMessage(msg.Message.From)
if err != nil {
return xerrors.Errorf("failed to reconstruct Filecoin message: %w", err)
}
if !msg.Message.Equals(filecoinMsg) {
return xerrors.New("Ethereum transaction roundtrip mismatch")
}
rlpEncodedMsg, err := ethTx.ToRlpUnsignedMsg()
if err != nil {
return xerrors.Errorf("failed to encode RLP message: %w", err)
}
digest = rlpEncodedMsg
signatureCopy.Data, err = ethTx.ToVerifiableSignature(signatureCopy.Data)
if err != nil {
return xerrors.Errorf("failed to verify signature: %w", err)
}
default:
digest = msg.Message.Cid().Bytes()
}
if err := sigs.Verify(&signatureCopy, signer, digest); err != nil {
return xerrors.Errorf("invalid signature for message %s (type %d): %w", msg.Cid(), signatureType, err)
}
return nil
}
// IsValidSecpkSigType checks that a signature type is valid for the network
// version, for a "secpk" message.
func IsValidSecpkSigType(nv network.Version, typ crypto.SigType) bool {
switch {
case nv < network.Version18:
return typ == crypto.SigTypeSecp256k1
default:
return typ == crypto.SigTypeSecp256k1 || typ == crypto.SigTypeDelegated
}
}