aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2014-01-21 06:26:32 +0800
committerobscuren <geffobscura@gmail.com>2014-01-21 06:26:32 +0800
commit09df961abb69bb1c49a53e7d61e9c76a1ff0edcd (patch)
tree63d1e2c4df67bfd52922f61ee725edf5294961a1
parentb608a80ef154ac7847c3f6dbb8727f8d83aca735 (diff)
downloaddexon-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar
dexon-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.gz
dexon-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.bz2
dexon-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.lz
dexon-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.xz
dexon-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.zst
dexon-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.zip
Transaction processing. Implemented sending and receiving wei
-rw-r--r--block_manager.go50
-rw-r--r--block_manager_test.go104
-rw-r--r--peer.go2
-rw-r--r--server.go6
4 files changed, 96 insertions, 66 deletions
diff --git a/block_manager.go b/block_manager.go
index 9322d0d3a..87af9f293 100644
--- a/block_manager.go
+++ b/block_manager.go
@@ -10,6 +10,7 @@ import (
"math"
"math/big"
"strconv"
+ "time"
)
type BlockChain struct {
@@ -44,6 +45,7 @@ func (bc *BlockChain) GenesisBlock() *ethutil.Block {
}
type BlockManager struct {
+ server *Server
// The block chain :)
bc *BlockChain
@@ -56,11 +58,12 @@ type BlockManager struct {
mem map[string]*big.Int
}
-func NewBlockManager() *BlockManager {
+func NewBlockManager(s *Server) *BlockManager {
bm := &BlockManager{
- bc: NewBlockChain(),
- stack: NewStack(),
- mem: make(map[string]*big.Int),
+ server: s,
+ bc: NewBlockChain(),
+ stack: NewStack(),
+ mem: make(map[string]*big.Int),
}
// Set the last known block number based on the blockchains last
@@ -161,13 +164,16 @@ func (bm *BlockManager) CalculateTD(block *ethutil.Block) bool {
// an uncle or anything that isn't on the current block chain.
// Validation validates easy over difficult (dagger takes longer time = difficult)
func (bm *BlockManager) ValidateBlock(block *ethutil.Block) error {
+ // Genesis block
+ if bm.bc.LastBlock == nil && block.PrevHash == "" {
+ return nil
+ }
// TODO
// 2. Check if the difficulty is correct
// 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
- if bm.bc.LastBlock != nil && block.PrevHash == "" &&
- !bm.bc.HasBlock(block.PrevHash) {
+ if !bm.bc.HasBlock(block.PrevHash) {
return errors.New("Block's parent unknown")
}
@@ -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
- if bm.bc.LastBlock != nil && block.PrevHash == "" &&
- !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) {
+ if !DaggerVerify(ethutil.BigD(block.Hash()), block.Difficulty, block.Nonce) {
return errors.New("Block's nonce is invalid")
}
@@ -429,7 +444,7 @@ out:
// x = floor(10^21 / floor(diff^0.5))
bm.stack.Push(x)
- case oSHA256, oRIPEMD160:
+ case oSHA256, oSHA3, oRIPEMD160:
// This is probably save
// ceil(pop / 32)
length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0))
@@ -443,6 +458,8 @@ out:
if op == oSHA256 {
bm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())))
+ } else if op == oSHA3 {
+ bm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes())))
} else {
bm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())))
}
@@ -472,7 +489,6 @@ out:
case oECSIGN:
case oECRECOVER:
case oECVALID:
- case oSHA3:
case oPUSH:
pc++
bm.stack.Push(bm.mem[strconv.Itoa(pc)])
@@ -535,7 +551,21 @@ out:
ether := ethutil.NewEtherFromData([]byte(d))
bm.stack.Push(ether.Amount)
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:
+ //addr := bm.stack.Pop()
}
pc++
}
diff --git a/block_manager_test.go b/block_manager_test.go
index 3dcf572fd..5f200f3e7 100644
--- a/block_manager_test.go
+++ b/block_manager_test.go
@@ -1,77 +1,73 @@
package main
-/*
import (
- _"fmt"
- "testing"
+ _ "fmt"
+ "testing"
)
-
-/*
func TestVm(t *testing.T) {
- InitFees()
+ InitFees()
- db, _ := NewMemDatabase()
- Db = db
+ db, _ := NewMemDatabase()
+ Db = db
- ctrct := NewTransaction("", 200000000, []string{
- "PUSH", "1a2f2e",
- "PUSH", "hallo",
- "POP", // POP hallo
- "PUSH", "3",
- "LOAD", // Load hallo back on the stack
+ ctrct := NewTransaction("", 200000000, []string{
+ "PUSH", "1a2f2e",
+ "PUSH", "hallo",
+ "POP", // POP hallo
+ "PUSH", "3",
+ "LOAD", // Load hallo back on the stack
- "PUSH", "1",
- "PUSH", "2",
- "ADD",
+ "PUSH", "1",
+ "PUSH", "2",
+ "ADD",
- "PUSH", "2",
- "PUSH", "1",
- "SUB",
+ "PUSH", "2",
+ "PUSH", "1",
+ "SUB",
- "PUSH", "100000000000000000000000",
- "PUSH", "10000000000000",
- "SDIV",
+ "PUSH", "100000000000000000000000",
+ "PUSH", "10000000000000",
+ "SDIV",
- "PUSH", "105",
- "PUSH", "200",
- "MOD",
+ "PUSH", "105",
+ "PUSH", "200",
+ "MOD",
- "PUSH", "100000000000000000000000",
- "PUSH", "10000000000000",
- "SMOD",
+ "PUSH", "100000000000000000000000",
+ "PUSH", "10000000000000",
+ "SMOD",
- "PUSH", "5",
- "PUSH", "10",
- "LT",
+ "PUSH", "5",
+ "PUSH", "10",
+ "LT",
- "PUSH", "5",
- "PUSH", "5",
- "LE",
+ "PUSH", "5",
+ "PUSH", "5",
+ "LE",
- "PUSH", "50",
- "PUSH", "5",
- "GT",
+ "PUSH", "50",
+ "PUSH", "5",
+ "GT",
- "PUSH", "5",
- "PUSH", "5",
- "GE",
+ "PUSH", "5",
+ "PUSH", "5",
+ "GE",
- "PUSH", "10",
- "PUSH", "10",
- "NOT",
+ "PUSH", "10",
+ "PUSH", "10",
+ "NOT",
- "MYADDRESS",
- "TXSENDER",
+ "MYADDRESS",
+ "TXSENDER",
- "STOP",
- })
- tx := NewTransaction("1e8a42ea8cce13", 100, []string{})
+ "STOP",
+ })
+ tx := NewTransaction("1e8a42ea8cce13", 100, []string{})
- block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx})
- db.Put(block.Hash(), block.RlpEncode())
+ block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx})
+ db.Put(block.Hash(), block.RlpEncode())
- bm := NewBlockManager()
- bm.ProcessBlock( block )
+ bm := NewBlockManager()
+ bm.ProcessBlock(block)
}
-*/
diff --git a/peer.go b/peer.go
index 158541028..0f3422826 100644
--- a/peer.go
+++ b/peer.go
@@ -174,7 +174,7 @@ out:
log.Println(err)
}
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.MsgGetPeersTy:
p.requestedPeerList = true
diff --git a/server.go b/server.go
index 7a29d1bd9..3a35a43a2 100644
--- a/server.go
+++ b/server.go
@@ -32,6 +32,9 @@ type Server struct {
db *ethdb.MemDatabase
// Block manager for processing new blocks and managing the block chain
blockManager *BlockManager
+ // The transaction pool. Transaction can be pushed on this pool
+ // for later including in the blocks
+ txPool *TxPool
// Peers (NYI)
peers *list.List
// Nonce
@@ -50,11 +53,12 @@ func NewServer() (*Server, error) {
nonce, _ := ethutil.RandomUint64()
server := &Server{
shutdownChan: make(chan bool),
- blockManager: NewBlockManager(),
db: db,
peers: list.New(),
Nonce: nonce,
}
+ server.txPool = NewTxPool(server)
+ server.blockManager = NewBlockManager(server)
return server, nil
}