mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-19 18:32:23 +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.
|
||||
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,
|
||||
// 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
|
||||
// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock
|
||||
// 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
|
||||
// by the Ethereum prefix scheme
|
||||
|
|
|
|||
7
accounts/external/backend.go
vendored
7
accounts/external/backend.go
vendored
|
|
@ -18,6 +18,7 @@ package external
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"math/big"
|
||||
"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")
|
||||
}
|
||||
|
||||
// SignCliqueHeader implements accounts.Wallet, attempting to sign the given clique header
|
||||
func (api *ExternalSigner) SignCliqueHeader(account accounts.Account, header *types.Header) ([]byte, error) {
|
||||
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
||||
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
|
||||
// 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) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package keystore
|
||||
|
||||
import (
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"math/big"
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
// SignCliqueHeader implements accounts.Wallet, attempting to sign the given clique header
|
||||
func (w *keystoreWallet) SignCliqueHeader(account accounts.Account, header *types.Header) ([]byte, error) {
|
||||
return w.signHash(account, accounts.CliqueHash(header).Bytes())
|
||||
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
||||
func (w *keystoreWallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) {
|
||||
return w.signHash(account, crypto.Keccak256(data))
|
||||
}
|
||||
|
||||
func (w *keystoreWallet) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ package usbwallet
|
|||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/crypto"
|
||||
"io"
|
||||
"math/big"
|
||||
"sync"
|
||||
|
|
@ -501,9 +502,9 @@ func (w *wallet) signHash(account accounts.Account, hash []byte) ([]byte, error)
|
|||
return nil, accounts.ErrNotSupported
|
||||
}
|
||||
|
||||
// SignCliqueHeader implements accounts.Wallet, attempting to sign the given clique header
|
||||
func (w *wallet) SignCliqueHeader(account accounts.Account, header *types.Header) ([]byte, error) {
|
||||
return w.signHash(account, accounts.CliqueHash(header).Bytes())
|
||||
// SignData signs keccak256(data). The mimetype parameter describes the type of data being signed
|
||||
func (w *wallet) SignData(account accounts.Account, mimeType string, data []byte) ([]byte, error) {
|
||||
return w.signHash(account, crypto.Keccak256(data))
|
||||
}
|
||||
|
||||
func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@ package clique
|
|||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||
"github.com/ethereum/go-ethereum/rlp"
|
||||
"math/big"
|
||||
"math/rand"
|
||||
"sync"
|
||||
|
|
@ -136,7 +138,7 @@ var (
|
|||
|
||||
// SignerFn is a signer callback function to request a header to be signed by a
|
||||
// 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.
|
||||
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:]
|
||||
|
||||
// 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 {
|
||||
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))
|
||||
}
|
||||
// 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 {
|
||||
return err
|
||||
}
|
||||
|
|
@ -630,7 +632,7 @@ func (c *Clique) Seal(chain consensus.ChainReader, block *types.Block, results c
|
|||
select {
|
||||
case results <- block.WithSeal(header):
|
||||
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.
|
||||
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.
|
||||
|
|
@ -678,3 +704,31 @@ func (c *Clique) APIs(chain consensus.ChainReader) []rpc.API {
|
|||
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)
|
||||
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
|
||||
// introduced to speed sync times.
|
||||
|
|
|
|||
Loading…
Reference in a new issue