aboutsummaryrefslogtreecommitdiffstats
path: root/block_manager.go
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 /block_manager.go
parentb608a80ef154ac7847c3f6dbb8727f8d83aca735 (diff)
downloadgo-tangerine-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar
go-tangerine-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.gz
go-tangerine-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.bz2
go-tangerine-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.lz
go-tangerine-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.xz
go-tangerine-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.tar.zst
go-tangerine-09df961abb69bb1c49a53e7d61e9c76a1ff0edcd.zip
Transaction processing. Implemented sending and receiving wei
Diffstat (limited to 'block_manager.go')
-rw-r--r--block_manager.go50
1 files changed, 40 insertions, 10 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++
}