Commit 09df961a authored by obscuren's avatar obscuren

Transaction processing. Implemented sending and receiving wei

parent b608a80e
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"math" "math"
"math/big" "math/big"
"strconv" "strconv"
"time"
) )
type BlockChain struct { type BlockChain struct {
...@@ -44,6 +45,7 @@ func (bc *BlockChain) GenesisBlock() *ethutil.Block { ...@@ -44,6 +45,7 @@ func (bc *BlockChain) GenesisBlock() *ethutil.Block {
} }
type BlockManager struct { type BlockManager struct {
server *Server
// The block chain :) // The block chain :)
bc *BlockChain bc *BlockChain
...@@ -56,8 +58,9 @@ type BlockManager struct { ...@@ -56,8 +58,9 @@ type BlockManager struct {
mem map[string]*big.Int mem map[string]*big.Int
} }
func NewBlockManager() *BlockManager { func NewBlockManager(s *Server) *BlockManager {
bm := &BlockManager{ bm := &BlockManager{
server: s,
bc: NewBlockChain(), bc: NewBlockChain(),
stack: NewStack(), stack: NewStack(),
mem: make(map[string]*big.Int), mem: make(map[string]*big.Int),
...@@ -161,13 +164,16 @@ func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool { ...@@ -161,13 +164,16 @@ func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool {
// an uncle or anything that isn't on the current block chain. // an uncle or anything that isn't on the current block chain.
// Validation validates easy over difficult (dagger takes longer time = difficult) // Validation validates easy over difficult (dagger takes longer time = difficult)
func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error {
// Genesis block
if bm.bc.LastBlock == nil && block.PrevHash == "" {
return nil
}
// TODO // TODO
// 2. Check if the difficulty is correct // 2. Check if the difficulty is correct
// Check if we have the parent hash, if it isn't known we discard it // Check if we have the parent hash, if it isn't known we discard it
// Reasons might be catching up or simply an invalid block // Reasons might be catching up or simply an invalid block
if bm.bc.LastBlock != nil && block.PrevHash == "" && if !bm.bc.HasBlock(block.PrevHash) {
!bm.bc.HasBlock(block.PrevHash) {
return errors.New("Block's parent unknown") return errors.New("Block's parent unknown")
} }
...@@ -183,9 +189,18 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error { ...@@ -183,9 +189,18 @@ func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error {
} }
} }
diff := block.Time - bm.bc.LastBlock.Time
if diff < 0 {
return fmt.Errorf("Block timestamp less then prev block %v", diff)
}
// New blocks must be within the 15 minute range of the last block.
if diff > int64(15*time.Minute) {
return errors.New("Block is too far in the future of last block (> 15 minutes)")
}
// Verify the nonce of the block. Return an error if it's not valid // Verify the nonce of the block. Return an error if it's not valid
if bm.bc.LastBlock != nil && block.PrevHash == "" && if !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) {
!DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) {
return errors.New("Block's nonce is invalid") return errors.New("Block's nonce is invalid")
} }
...@@ -429,7 +444,7 @@ out: ...@@ -429,7 +444,7 @@ out:
// x = floor(10^21 / floor(diff^0.5)) // x = floor(10^21 / floor(diff^0.5))
bm.stack.Push(x) bm.stack.Push(x)
case oSHA256, oRIPEMD160: case oSHA256, oSHA3, oRIPEMD160:
// This is probably save // This is probably save
// ceil(pop / 32) // ceil(pop / 32)
length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0)) length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0))
...@@ -443,6 +458,8 @@ out: ...@@ -443,6 +458,8 @@ out:
if op == oSHA256 { if op == oSHA256 {
bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes()))) bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())))
} else if op == oSHA3 {
bm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes())))
} else { } else {
bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes()))) bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())))
} }
...@@ -472,7 +489,6 @@ out: ...@@ -472,7 +489,6 @@ out:
case oECSIGN: case oECSIGN:
case oECRECOVER: case oECRECOVER:
case oECVALID: case oECVALID:
case oSHA3:
case oPUSH: case oPUSH:
pc++ pc++
bm.stack.Push(bm.mem[strconv.Itoa(pc)]) bm.stack.Push(bm.mem[strconv.Itoa(pc)])
...@@ -535,7 +551,21 @@ out: ...@@ -535,7 +551,21 @@ out:
ether := ethutil.NewEtherFromData([]byte(d)) ether := ethutil.NewEtherFromData([]byte(d))
bm.stack.Push(ether.Amount) bm.stack.Push(ether.Amount)
case oMKTX: case oMKTX:
value, addr := bm.stack.Popn()
from, length := bm.stack.Popn()
j := 0
dataItems := make([]string, int(length.Uint64()))
for i := from.Uint64(); i < length.Uint64(); i++ {
dataItems[j] = string(bm.mem[strconv.Itoa(int(i))].Bytes())
j++
}
// TODO sign it?
tx := ethutil.NewTransaction(string(addr.Bytes()), value, dataItems)
// Add the transaction to the tx pool
bm.server.txPool.QueueTransaction(tx)
case oSUICIDE: case oSUICIDE:
//addr := bm.stack.Pop()
} }
pc++ pc++
} }
......
package main package main
/*
import ( import (
_"fmt" _ "fmt"
"testing" "testing"
) )
/*
func TestVm(t *testing.T) { func TestVm(t *testing.T) {
InitFees() InitFees()
...@@ -72,6 +69,5 @@ func TestVm(t *testing.T) { ...@@ -72,6 +69,5 @@ func TestVm(t *testing.T) {
db.Put(block.Hash(), block.RlpEncode()) db.Put(block.Hash(), block.RlpEncode())
bm := NewBlockManager() bm := NewBlockManager()
bm.ProcessBlock( block ) bm.ProcessBlock(block)
} }
*/
...@@ -174,7 +174,7 @@ out: ...@@ -174,7 +174,7 @@ out:
log.Println(err) log.Println(err)
} }
case ethwire.MsgTxTy: case ethwire.MsgTxTy:
//p.server.blockManager.AddToTransactionPool(ethutil.NewTransactionFromData(ethutil.Encode(msg.Data))) p.server.txPool.QueueTransaction(ethutil.NewTransactionFromData(ethutil.Encode(msg.Data)))
case ethwire.MsgInvTy: case ethwire.MsgInvTy:
case ethwire.MsgGetPeersTy: case ethwire.MsgGetPeersTy:
p.requestedPeerList = true p.requestedPeerList = true
......
...@@ -32,6 +32,9 @@ type Server struct { ...@@ -32,6 +32,9 @@ type Server struct {
db *ethdb.MemDatabase db *ethdb.MemDatabase
// Block manager for processing new blocks and managing the block chain // Block manager for processing new blocks and managing the block chain
blockManager *BlockManager blockManager *BlockManager
// The transaction pool. Transaction can be pushed on this pool
// for later including in the blocks
txPool *TxPool
// Peers (NYI) // Peers (NYI)
peers *list.List peers *list.List
// Nonce // Nonce
...@@ -50,11 +53,12 @@ func NewServer() (*Server, error) { ...@@ -50,11 +53,12 @@ func NewServer() (*Server, error) {
nonce, _ := ethutil.RandomUint64() nonce, _ := ethutil.RandomUint64()
server := &Server{ server := &Server{
shutdownChan: make(chan bool), shutdownChan: make(chan bool),
blockManager: NewBlockManager(),
db: db, db: db,
peers: list.New(), peers: list.New(),
Nonce: nonce, Nonce: nonce,
} }
server.txPool = NewTxPool(server)
server.blockManager = NewBlockManager(server)
return server, nil return server, nil
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment