mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-20 02:42:27 +00:00
accounts: remove clique-specific signing method, replace with more generic
This commit is contained in:
parent
762482ef2c
commit
bfa4fb0521
6 changed files with 74 additions and 17 deletions
|
|
@ -91,7 +91,7 @@ type Wallet interface {
|
||||||
// chain state reader.
|
// chain state reader.
|
||||||
SelfDerive(base DerivationPath, chain ethereum.ChainStateReader)
|
SelfDerive(base DerivationPath, chain ethereum.ChainStateReader)
|
||||||
|
|
||||||
// SignCliqueHeader requests the wallet to sign the hash of a given Clique header
|
// SignData requests the wallet to sign the hash of the given data
|
||||||
// It looks up the account specified either solely via its address contained within,
|
// It looks up the account specified either solely via its address contained within,
|
||||||
// or optionally with the aid of any location metadata from the embedded URL field.
|
// or optionally with the aid of any location metadata from the embedded URL field.
|
||||||
//
|
//
|
||||||
|
|
@ -101,7 +101,7 @@ type Wallet interface {
|
||||||
// about which fields or actions are needed. The user may retry by providing
|
// about which fields or actions are needed. The user may retry by providing
|
||||||
// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock
|
// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock
|
||||||
// the account in a keystore).
|
// the account in a keystore).
|
||||||
SignCliqueHeader(account Account, header *types.Header) ([]byte, error)
|
SignData(account Account, mimeType string, data []byte) ([]byte, error)
|
||||||
|
|
||||||
// Signtext requests the wallet to sign the hash of a given piece of data, prefixed
|
// Signtext requests the wallet to sign the hash of a given piece of data, prefixed
|
||||||
// by the Ethereum prefix scheme
|
// by the Ethereum prefix scheme
|
||||||
|
|
|
||||||
7
accounts/external/backend.go
vendored
7
accounts/external/backend.go
vendored
|
|
@ -18,6 +18,7 @@ package external
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
|
@ -151,11 +152,11 @@ func (api *ExternalSigner) signHash(account accounts.Account, hash []byte) ([]by
|
||||||
return []byte{}, fmt.Errorf("operation not supported on external signers")
|
return []byte{}, fmt.Errorf("operation not supported on external signers")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignCliqueHeader implements accounts.Wallet, attempting to sign the given clique header
|
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
||||||
func (api *ExternalSigner) SignCliqueHeader(account accounts.Account, header *types.Header) ([]byte, error) {
|
func (api *ExternalSigner) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) {
|
||||||
// TODO! Replace this with a call to clef SignData with correct mime-type for Clique, once we
|
// TODO! Replace this with a call to clef SignData with correct mime-type for Clique, once we
|
||||||
// have that in place
|
// have that in place
|
||||||
return api.signHash(account, accounts.CliqueHash(header).Bytes())
|
return api.signHash(account, crypto.Keccak256(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *ExternalSigner) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
func (api *ExternalSigner) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package keystore
|
package keystore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"math/big"
|
"math/big"
|
||||||
|
|
||||||
ethereum "github.com/ethereum/go-ethereum"
|
ethereum "github.com/ethereum/go-ethereum"
|
||||||
|
|
@ -91,9 +92,9 @@ func (w *keystoreWallet) signHash(account accounts.Account, hash []byte) ([]byte
|
||||||
return w.keystore.SignHash(account, hash)
|
return w.keystore.SignHash(account, hash)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignCliqueHeader implements accounts.Wallet, attempting to sign the given clique header
|
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
||||||
func (w *keystoreWallet) SignCliqueHeader(account accounts.Account, header *types.Header) ([]byte, error) {
|
func (w *keystoreWallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) {
|
||||||
return w.signHash(account, accounts.CliqueHash(header).Bytes())
|
return w.signHash(account, crypto.Keccak256(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ package usbwallet
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto"
|
||||||
"io"
|
"io"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -501,9 +502,9 @@ func (w *wallet) signHash(account accounts.Account, hash []byte) ([]byte, error)
|
||||||
return nil, accounts.ErrNotSupported
|
return nil, accounts.ErrNotSupported
|
||||||
}
|
}
|
||||||
|
|
||||||
// SignCliqueHeader implements accounts.Wallet, attempting to sign the given clique header
|
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
||||||
func (w *wallet) SignCliqueHeader(account accounts.Account, header *types.Header) ([]byte, error) {
|
func (w *wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) {
|
||||||
return w.signHash(account, accounts.CliqueHash(header).Bytes())
|
return w.signHash(account, crypto.Keccak256(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,8 @@ package clique
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
|
"github.com/ethereum/go-ethereum/rlp"
|
||||||
"math/big"
|
"math/big"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
@ -136,7 +138,7 @@ var (
|
||||||
|
|
||||||
// SignerFn is a signer callback function to request a header to be signed by a
|
// SignerFn is a signer callback function to request a header to be signed by a
|
||||||
// backing account.
|
// backing account.
|
||||||
type SignerFn func(accounts.Account, *types.Header) ([]byte, error)
|
type SignerFn func(accounts.Account, string, []byte) ([]byte, error)
|
||||||
|
|
||||||
// ecrecover extracts the Ethereum account address from a signed header.
|
// ecrecover extracts the Ethereum account address from a signed header.
|
||||||
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, error) {
|
||||||
|
|
@ -152,7 +154,7 @@ func ecrecover(header *types.Header, sigcache *lru.ARCCache) (common.Address, er
|
||||||
signature := header.Extra[len(header.Extra)-extraSeal:]
|
signature := header.Extra[len(header.Extra)-extraSeal:]
|
||||||
|
|
||||||
// Recover the public key and the Ethereum address
|
// Recover the public key and the Ethereum address
|
||||||
pubkey, err := crypto.Ecrecover(accounts.CliqueHash(header).Bytes(), signature)
|
pubkey, err := crypto.Ecrecover(SealHash(header).Bytes(), signature)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return common.Address{}, err
|
return common.Address{}, err
|
||||||
}
|
}
|
||||||
|
|
@ -613,7 +615,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results c
|
||||||
log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
|
log.Trace("Out-of-turn signing requested", "wiggle", common.PrettyDuration(wiggle))
|
||||||
}
|
}
|
||||||
// Sign all the things!
|
// Sign all the things!
|
||||||
sighash, err := signFn(accounts.Account{Address: signer}, header)
|
sighash, err := signFn(accounts.Account{Address: signer}, "application/x-clique-header", CliqueRLP(header))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -630,7 +632,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results c
|
||||||
select {
|
select {
|
||||||
case results <- block.WithSeal(header):
|
case results <- block.WithSeal(header):
|
||||||
default:
|
default:
|
||||||
log.Warn("Sealing result is not read by miner", "sealhash", c.SealHash(header))
|
log.Warn("Sealing result is not read by miner", "sealhash", SealHash(header))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
|
|
@ -660,7 +662,31 @@ func CalcDifficulty(snap *Snapshot, signer common.Address) *big.Int {
|
||||||
|
|
||||||
// SealHash returns the hash of a block prior to it being sealed.
|
// SealHash returns the hash of a block prior to it being sealed.
|
||||||
func (c *Clique) SealHash(header *types.Header) common.Hash {
|
func (c *Clique) SealHash(header *types.Header) common.Hash {
|
||||||
return accounts.CliqueHash(header)
|
return SealHash(header)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SealHash returns the hash of a block prior to it being sealed.
|
||||||
|
func SealHash(header *types.Header) (hash common.Hash) {
|
||||||
|
hasher := sha3.NewKeccak256()
|
||||||
|
rlp.Encode(hasher, []interface{}{
|
||||||
|
header.ParentHash,
|
||||||
|
header.UncleHash,
|
||||||
|
header.Coinbase,
|
||||||
|
header.Root,
|
||||||
|
header.TxHash,
|
||||||
|
header.ReceiptHash,
|
||||||
|
header.Bloom,
|
||||||
|
header.Difficulty,
|
||||||
|
header.Number,
|
||||||
|
header.GasLimit,
|
||||||
|
header.GasUsed,
|
||||||
|
header.Time,
|
||||||
|
header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
|
||||||
|
header.MixDigest,
|
||||||
|
header.Nonce,
|
||||||
|
})
|
||||||
|
hasher.Sum(hash[:0])
|
||||||
|
return hash
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close implements consensus.Engine. It's a noop for clique as there are no background threads.
|
// Close implements consensus.Engine. It's a noop for clique as there are no background threads.
|
||||||
|
|
@ -678,3 +704,31 @@ func (c *Clique) APIs(chain consensus.ChainReader) []rpc.API {
|
||||||
Public: false,
|
Public: false,
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CliqueRLP returns the rlp bytes which needs to be signed for the proof-of-authority
|
||||||
|
// sealing. The RLP to sign consists of the entire header apart from the 65 byte signature
|
||||||
|
// contained at the end of the extra data.
|
||||||
|
//
|
||||||
|
// Note, the method requires the extra data to be at least 65 bytes, otherwise it
|
||||||
|
// panics. This is done to avoid accidentally using both forms (signature present
|
||||||
|
// or not), which could be abused to produce different hashes for the same header.
|
||||||
|
func CliqueRLP(header *types.Header) []byte {
|
||||||
|
data, _ := rlp.EncodeToBytes([]interface{}{
|
||||||
|
header.ParentHash,
|
||||||
|
header.UncleHash,
|
||||||
|
header.Coinbase,
|
||||||
|
header.Root,
|
||||||
|
header.TxHash,
|
||||||
|
header.ReceiptHash,
|
||||||
|
header.Bloom,
|
||||||
|
header.Difficulty,
|
||||||
|
header.Number,
|
||||||
|
header.GasLimit,
|
||||||
|
header.GasUsed,
|
||||||
|
header.Time,
|
||||||
|
header.Extra[:len(header.Extra)-65], // Yes, this will panic if extra is too short
|
||||||
|
header.MixDigest,
|
||||||
|
header.Nonce,
|
||||||
|
})
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -432,7 +432,7 @@ func (s *Ethereum) StartMining(threads int) error {
|
||||||
log.Error("Etherbase account unavailable locally", "err", err)
|
log.Error("Etherbase account unavailable locally", "err", err)
|
||||||
return fmt.Errorf("signer missing: %v", err)
|
return fmt.Errorf("signer missing: %v", err)
|
||||||
}
|
}
|
||||||
clique.Authorize(eb, wallet.SignCliqueHeader)
|
clique.Authorize(eb, wallet.SignData)
|
||||||
}
|
}
|
||||||
// If mining is started, we can disable the transaction rejection mechanism
|
// If mining is started, we can disable the transaction rejection mechanism
|
||||||
// introduced to speed sync times.
|
// introduced to speed sync times.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue