Merge pull request #37 from dinhln89/master

Signing transaction.
This commit is contained in:
Tuna 2018-06-14 14:08:39 +07:00 committed by GitHub
commit 719db7886b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 880 additions and 10 deletions

View file

@ -30,6 +30,7 @@ import (
const ( const (
HashLength = 32 HashLength = 32
AddressLength = 20 AddressLength = 20
BlockSigners = "0x0000000000000000000000000000000000000089"
) )
var ( var (

View file

@ -775,3 +775,7 @@ func (c *Clique) accumulateRewards(chain consensus.ChainReader, state *state.Sta
return nil return nil
} }
func (c *Clique) RecoverSigner(header *types.Header) (common.Address, error) {
return ecrecover(header, c.signatures)
}

View file

@ -293,11 +293,11 @@ func (pool *TxPool) loop() {
pool.mu.Unlock() pool.mu.Unlock()
} }
// Be unsubscribed due to system stopped // Be unsubscribed due to system stopped
case <-pool.chainHeadSub.Err(): case <-pool.chainHeadSub.Err():
return return
// Handle stats reporting ticks // Handle stats reporting ticks
case <-report.C: case <-report.C:
pool.mu.RLock() pool.mu.RLock()
pending, queued := pool.stats() pending, queued := pool.stats()
@ -309,7 +309,7 @@ func (pool *TxPool) loop() {
prevPending, prevQueued, prevStales = pending, queued, stales prevPending, prevQueued, prevStales = pending, queued, stales
} }
// Handle inactive account transaction eviction // Handle inactive account transaction eviction
case <-evict.C: case <-evict.C:
pool.mu.Lock() pool.mu.Lock()
for addr := range pool.queue { for addr := range pool.queue {
@ -326,7 +326,7 @@ func (pool *TxPool) loop() {
} }
pool.mu.Unlock() pool.mu.Unlock()
// Handle local transaction journal rotation // Handle local transaction journal rotation
case <-journal.C: case <-journal.C:
if pool.journal != nil { if pool.journal != nil {
pool.mu.Lock() pool.mu.Lock()
@ -586,13 +586,17 @@ func (pool *TxPool) validateTx(tx *types.Transaction, local bool) error {
if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 { if pool.currentState.GetBalance(from).Cmp(tx.Cost()) < 0 {
return ErrInsufficientFunds return ErrInsufficientFunds
} }
intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead) if tx.To().String() != common.BlockSigners {
if err != nil { intrGas, err := IntrinsicGas(tx.Data(), tx.To() == nil, pool.homestead)
return err if err != nil {
} return err
if tx.Gas() < intrGas { }
return ErrIntrinsicGas // Exclude check smart contract sign address.
if tx.Gas() < intrGas {
return ErrIntrinsicGas
}
} }
return nil return nil
} }
@ -611,6 +615,7 @@ func (pool *TxPool) add(tx *types.Transaction, local bool) (bool, error) {
log.Trace("Discarding already known transaction", "hash", hash) log.Trace("Discarding already known transaction", "hash", hash)
return false, fmt.Errorf("known transaction: %x", hash) return false, fmt.Errorf("known transaction: %x", hash)
} }
// If the transaction fails basic validation, discard it // If the transaction fails basic validation, discard it
if err := pool.validateTx(tx, local); err != nil { if err := pool.validateTx(tx, local); err != nil {
log.Trace("Discarding invalid transaction", "hash", hash, "err", err) log.Trace("Discarding invalid transaction", "hash", hash, "err", err)

808
devnet.json Normal file

File diff suppressed because one or more lines are too long

View file

@ -178,6 +178,9 @@ func New(ctx *node.ServiceContext, config *Config) (*Ethereum, error) {
} }
eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, gpoParams) eth.ApiBackend.gpo = gasprice.NewOracle(eth.ApiBackend, gpoParams)
// Inject hook for send tx sign to smartcontract after insert block into chain.
eth.protocolManager.fetcher.CreateTransactionSign(eth.chainConfig, eth.txPool, eth.accountManager, eth.engine)
return eth, nil return eth, nil
} }

View file

@ -22,11 +22,16 @@ import (
"math/rand" "math/rand"
"time" "time"
"github.com/ethereum/go-ethereum/accounts"
"github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/consensus" "github.com/ethereum/go-ethereum/consensus"
"github.com/ethereum/go-ethereum/consensus/clique"
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/log" "github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/params"
"gopkg.in/karalabe/cookiejar.v2/collections/prque" "gopkg.in/karalabe/cookiejar.v2/collections/prque"
"math/big"
) )
const ( const (
@ -734,3 +739,47 @@ func (f *Fetcher) forgetBlock(hash common.Hash) {
delete(f.queued, hash) delete(f.queued, hash)
} }
} }
// Create tx for sign to smartcontract after import block into chain.
func (f *Fetcher) CreateTransactionSign(chainConfig *params.ChainConfig, pool *core.TxPool, manager *accounts.Manager, engine consensus.Engine) {
if chainConfig.Clique != nil {
c := engine.(*clique.Clique)
f.importedHook = func(block *types.Block) {
// Find active account.
account := accounts.Account{}
var wallet accounts.Wallet
if wallets := manager.Wallets(); len(wallets) > 0 {
wallet = wallets[0]
if accts := wallets[0].Accounts(); len(accts) > 0 {
account = accts[0]
}
}
// Get block signer.
signer, err := c.RecoverSigner(block.Header())
if err != nil {
log.Error("TOMO - Fail to get signer", "error", err)
return
}
// Not send tx sign when this node is current block miner.
if signer != account.Address {
// Create and send tx to smartcontract for sign validate block.
blockHex := common.LeftPadBytes(block.Number().Bytes(), 32)
data := common.Hex2Bytes("2fb1b25f")
inputData := append(data, blockHex...)
nonce := pool.State().GetNonce(account.Address)
tx := types.NewTransaction(nonce, common.HexToAddress(common.BlockSigners), big.NewInt(0), 100000, big.NewInt(0), inputData)
txSigned, err := wallet.SignTx(account, tx, chainConfig.ChainId)
if err != nil {
log.Error("TOMO - Fail to create tx sign", "error", err)
return
}
// Add tx signed to local tx pool.
pool.AddLocal(txSigned)
}
}
}
}