Added synchronisation of transactions across remote pools
This commit is contained in:
parent
e47230f82d
commit
3616080db4
@ -12,15 +12,16 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Console struct {
|
type Console struct {
|
||||||
db *ethdb.MemDatabase
|
db *ethdb.MemDatabase
|
||||||
trie *ethutil.Trie
|
trie *ethutil.Trie
|
||||||
|
server *Server
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewConsole() *Console {
|
func NewConsole(s *Server) *Console {
|
||||||
db, _ := ethdb.NewMemDatabase()
|
db, _ := ethdb.NewMemDatabase()
|
||||||
trie := ethutil.NewTrie(db, "")
|
trie := ethutil.NewTrie(db, "")
|
||||||
|
|
||||||
return &Console{db: db, trie: trie}
|
return &Console{db: db, trie: trie, server: s}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Console) ValidateInput(action string, argumentLength int) error {
|
func (i *Console) ValidateInput(action string, argumentLength int) error {
|
||||||
@ -43,6 +44,9 @@ func (i *Console) ValidateInput(action string, argumentLength int) error {
|
|||||||
case action == "encode" && argumentLength != 1:
|
case action == "encode" && argumentLength != 1:
|
||||||
err = true
|
err = true
|
||||||
expArgCount = 1
|
expArgCount = 1
|
||||||
|
case action == "tx" && argumentLength != 2:
|
||||||
|
err = true
|
||||||
|
expArgCount = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
if err {
|
if err {
|
||||||
@ -105,6 +109,10 @@ func (i *Console) ParseInput(input string) bool {
|
|||||||
fmt.Printf("%q\n", d)
|
fmt.Printf("%q\n", d)
|
||||||
case "encode":
|
case "encode":
|
||||||
fmt.Printf("%q\n", ethutil.Encode(tokens[1]))
|
fmt.Printf("%q\n", ethutil.Encode(tokens[1]))
|
||||||
|
case "tx":
|
||||||
|
tx := ethutil.NewTransaction(tokens[1], ethutil.Big(tokens[2]), []string{""})
|
||||||
|
|
||||||
|
i.server.txPool.QueueTransaction(tx)
|
||||||
case "exit", "quit", "q":
|
case "exit", "quit", "q":
|
||||||
return false
|
return false
|
||||||
case "help":
|
case "help":
|
||||||
|
77
ethereum.go
77
ethereum.go
@ -7,6 +7,7 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"path"
|
||||||
"runtime"
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -44,36 +45,54 @@ func main() {
|
|||||||
|
|
||||||
Init()
|
Init()
|
||||||
|
|
||||||
if StartConsole {
|
ethutil.ReadConfig()
|
||||||
console := NewConsole()
|
|
||||||
console.Start()
|
|
||||||
} else {
|
|
||||||
log.Println("Starting Ethereum")
|
|
||||||
server, err := NewServer()
|
|
||||||
|
|
||||||
if err != nil {
|
server, err := NewServer()
|
||||||
log.Println(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
RegisterInterupts(server)
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
if StartMining {
|
return
|
||||||
log.Println("Mining started")
|
|
||||||
dagger := &Dagger{}
|
|
||||||
|
|
||||||
go func() {
|
|
||||||
for {
|
|
||||||
res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 36))
|
|
||||||
log.Println("Res dagger", res)
|
|
||||||
//server.Broadcast("blockmine", ethutil.Encode(res.String()))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
|
|
||||||
server.Start()
|
|
||||||
|
|
||||||
// Wait for shutdown
|
|
||||||
server.WaitForShutdown()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if StartConsole {
|
||||||
|
err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm)
|
||||||
|
// Error is OK if the error is ErrExist
|
||||||
|
if err != nil && !os.IsExist(err) {
|
||||||
|
log.Panic("Unable to create EXECPATH. Exiting")
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO The logger will eventually be a non blocking logger. Logging is a expensive task
|
||||||
|
// Log to file only
|
||||||
|
file, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "debug.log"), os.O_RDWR|os.O_CREATE, os.ModePerm)
|
||||||
|
if err != nil {
|
||||||
|
log.Panic("Unable to set proper logger", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
ethutil.Config.Log = log.New(file, "", 0)
|
||||||
|
|
||||||
|
console := NewConsole(server)
|
||||||
|
go console.Start()
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("Starting Ethereum")
|
||||||
|
|
||||||
|
RegisterInterupts(server)
|
||||||
|
|
||||||
|
if StartMining {
|
||||||
|
log.Println("Mining started")
|
||||||
|
dagger := &Dagger{}
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
res := dagger.Search(ethutil.Big("01001"), ethutil.BigPow(2, 36))
|
||||||
|
log.Println("Res dagger", res)
|
||||||
|
//server.Broadcast("blockmine", ethutil.Encode(res.String()))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
server.Start()
|
||||||
|
|
||||||
|
// Wait for shutdown
|
||||||
|
server.WaitForShutdown()
|
||||||
}
|
}
|
||||||
|
6
peer.go
6
peer.go
@ -62,7 +62,7 @@ func NewOutboundPeer(addr string, server *Server) *Peer {
|
|||||||
server: server,
|
server: server,
|
||||||
inbound: false,
|
inbound: false,
|
||||||
connected: 0,
|
connected: 0,
|
||||||
disconnect: 1,
|
disconnect: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up the connection in another goroutine so we don't block the main thread
|
// Set up the connection in another goroutine so we don't block the main thread
|
||||||
@ -169,12 +169,12 @@ out:
|
|||||||
// Version message
|
// Version message
|
||||||
p.handleHandshake(msg)
|
p.handleHandshake(msg)
|
||||||
case ethwire.MsgBlockTy:
|
case ethwire.MsgBlockTy:
|
||||||
err := p.server.blockManager.ProcessBlock(ethutil.NewBlock(ethutil.Encode(msg.Data)))
|
err := p.server.blockManager.ProcessBlock(ethutil.NewBlock(msg.Data))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
}
|
}
|
||||||
case ethwire.MsgTxTy:
|
case ethwire.MsgTxTy:
|
||||||
p.server.txPool.QueueTransaction(ethutil.NewTransactionFromData(ethutil.Encode(msg.Data)))
|
p.server.txPool.QueueTransaction(ethutil.NewTransactionFromData(msg.Data))
|
||||||
case ethwire.MsgInvTy:
|
case ethwire.MsgInvTy:
|
||||||
case ethwire.MsgGetPeersTy:
|
case ethwire.MsgGetPeersTy:
|
||||||
p.requestedPeerList = true
|
p.requestedPeerList = true
|
||||||
|
34
server.go
34
server.go
@ -48,7 +48,7 @@ func NewServer() (*Server, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
ethutil.SetConfig(db)
|
ethutil.Config.Db = db
|
||||||
|
|
||||||
nonce, _ := ethutil.RandomUint64()
|
nonce, _ := ethutil.RandomUint64()
|
||||||
server := &Server{
|
server := &Server{
|
||||||
@ -152,28 +152,30 @@ func (s *Server) Start() {
|
|||||||
|
|
||||||
s.Stop()
|
s.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
|
||||||
} else {
|
} else {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Starting accepting connections
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
conn, err := ln.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
go s.AddPeer(conn)
|
||||||
|
}
|
||||||
|
}()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start the reaping processes
|
// Start the reaping processes
|
||||||
go s.ReapDeadPeers()
|
go s.ReapDeadPeers()
|
||||||
|
|
||||||
go func() {
|
// Start the tx pool
|
||||||
for {
|
s.txPool.Start()
|
||||||
conn, err := ln.Accept()
|
|
||||||
if err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
go s.AddPeer(conn)
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
|
|
||||||
// TMP
|
// TMP
|
||||||
/*
|
/*
|
||||||
@ -196,6 +198,8 @@ func (s *Server) Stop() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
s.shutdownChan <- true
|
s.shutdownChan <- true
|
||||||
|
|
||||||
|
s.txPool.Stop()
|
||||||
}
|
}
|
||||||
|
|
||||||
// This function will wait for a shutdown and resumes main thread execution
|
// This function will wait for a shutdown and resumes main thread execution
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"container/list"
|
"container/list"
|
||||||
"errors"
|
"errors"
|
||||||
"github.com/ethereum/ethutil-go"
|
"github.com/ethereum/ethutil-go"
|
||||||
|
"github.com/ethereum/ethwire-go"
|
||||||
"log"
|
"log"
|
||||||
"math/big"
|
"math/big"
|
||||||
"sync"
|
"sync"
|
||||||
@ -56,9 +58,11 @@ func NewTxPool(s *Server) *TxPool {
|
|||||||
// Blocking function. Don't use directly. Use QueueTransaction instead
|
// Blocking function. Don't use directly. Use QueueTransaction instead
|
||||||
func (pool *TxPool) addTransaction(tx *ethutil.Transaction) {
|
func (pool *TxPool) addTransaction(tx *ethutil.Transaction) {
|
||||||
pool.mutex.Lock()
|
pool.mutex.Lock()
|
||||||
defer pool.mutex.Unlock()
|
|
||||||
|
|
||||||
pool.pool.PushBack(tx)
|
pool.pool.PushBack(tx)
|
||||||
|
pool.mutex.Unlock()
|
||||||
|
|
||||||
|
// Broadcast the transaction to the rest of the peers
|
||||||
|
pool.server.Broadcast(ethwire.MsgTxTy, tx.RlpEncode())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process transaction validates the Tx and processes funds from the
|
// Process transaction validates the Tx and processes funds from the
|
||||||
@ -89,7 +93,12 @@ func (pool *TxPool) processTransaction(tx *ethutil.Transaction) error {
|
|||||||
// Make sure there's enough in the sender's account. Having insufficient
|
// Make sure there's enough in the sender's account. Having insufficient
|
||||||
// funds won't invalidate this transaction but simple ignores it.
|
// funds won't invalidate this transaction but simple ignores it.
|
||||||
if sender.Amount.Cmp(tx.Value) < 0 {
|
if sender.Amount.Cmp(tx.Value) < 0 {
|
||||||
return errors.New("Insufficient amount in sender's account")
|
if Debug {
|
||||||
|
log.Println("Insufficient amount in sender's account. Adding 1 ETH for debug")
|
||||||
|
sender.Amount = ethutil.BigPow(10, 18)
|
||||||
|
} else {
|
||||||
|
return errors.New("Insufficient amount in sender's account")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subtract the amount from the senders account
|
// Subtract the amount from the senders account
|
||||||
@ -121,6 +130,15 @@ out:
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case tx := <-pool.queueChan:
|
case tx := <-pool.queueChan:
|
||||||
|
hash := tx.Hash()
|
||||||
|
foundTx := FindTx(pool.pool, func(tx *ethutil.Transaction, e *list.Element) bool {
|
||||||
|
return bytes.Compare(tx.Hash(), hash) == 0
|
||||||
|
})
|
||||||
|
|
||||||
|
if foundTx != nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
// Process the transaction
|
// Process the transaction
|
||||||
err := pool.processTransaction(tx)
|
err := pool.processTransaction(tx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -144,8 +162,6 @@ func (pool *TxPool) Flush() {
|
|||||||
pool.mutex.Lock()
|
pool.mutex.Lock()
|
||||||
|
|
||||||
defer pool.mutex.Unlock()
|
defer pool.mutex.Unlock()
|
||||||
|
|
||||||
pool.mutex.Unlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (pool *TxPool) Start() {
|
func (pool *TxPool) Start() {
|
||||||
|
Loading…
Reference in New Issue
Block a user