Transaction processing. Implemented sending and receiving wei
This commit is contained in:
parent
b608a80ef1
commit
09df961abb
@ -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 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type BlockManager struct {
|
type BlockManager struct {
|
||||||
|
server *Server
|
||||||
// The block chain :)
|
// The block chain :)
|
||||||
bc *BlockChain
|
bc *BlockChain
|
||||||
|
|
||||||
@ -56,11 +58,12 @@ 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{
|
||||||
bc: NewBlockChain(),
|
server: s,
|
||||||
stack: NewStack(),
|
bc: NewBlockChain(),
|
||||||
mem: make(map[string]*big.Int),
|
stack: NewStack(),
|
||||||
|
mem: make(map[string]*big.Int),
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the last known block number based on the blockchains last
|
// 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.
|
// 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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
|||||||
|
|
||||||
// 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:
|
|||||||
|
|
||||||
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:
|
|||||||
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:
|
|||||||
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++
|
||||||
}
|
}
|
||||||
|
@ -1,77 +1,73 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
/*
|
|
||||||
import (
|
import (
|
||||||
_"fmt"
|
_ "fmt"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
func TestVm(t *testing.T) {
|
func TestVm(t *testing.T) {
|
||||||
InitFees()
|
InitFees()
|
||||||
|
|
||||||
db, _ := NewMemDatabase()
|
db, _ := NewMemDatabase()
|
||||||
Db = db
|
Db = db
|
||||||
|
|
||||||
ctrct := NewTransaction("", 200000000, []string{
|
ctrct := NewTransaction("", 200000000, []string{
|
||||||
"PUSH", "1a2f2e",
|
"PUSH", "1a2f2e",
|
||||||
"PUSH", "hallo",
|
"PUSH", "hallo",
|
||||||
"POP", // POP hallo
|
"POP", // POP hallo
|
||||||
"PUSH", "3",
|
"PUSH", "3",
|
||||||
"LOAD", // Load hallo back on the stack
|
"LOAD", // Load hallo back on the stack
|
||||||
|
|
||||||
"PUSH", "1",
|
"PUSH", "1",
|
||||||
"PUSH", "2",
|
"PUSH", "2",
|
||||||
"ADD",
|
"ADD",
|
||||||
|
|
||||||
"PUSH", "2",
|
"PUSH", "2",
|
||||||
"PUSH", "1",
|
"PUSH", "1",
|
||||||
"SUB",
|
"SUB",
|
||||||
|
|
||||||
"PUSH", "100000000000000000000000",
|
"PUSH", "100000000000000000000000",
|
||||||
"PUSH", "10000000000000",
|
"PUSH", "10000000000000",
|
||||||
"SDIV",
|
"SDIV",
|
||||||
|
|
||||||
"PUSH", "105",
|
"PUSH", "105",
|
||||||
"PUSH", "200",
|
"PUSH", "200",
|
||||||
"MOD",
|
"MOD",
|
||||||
|
|
||||||
"PUSH", "100000000000000000000000",
|
"PUSH", "100000000000000000000000",
|
||||||
"PUSH", "10000000000000",
|
"PUSH", "10000000000000",
|
||||||
"SMOD",
|
"SMOD",
|
||||||
|
|
||||||
"PUSH", "5",
|
"PUSH", "5",
|
||||||
"PUSH", "10",
|
"PUSH", "10",
|
||||||
"LT",
|
"LT",
|
||||||
|
|
||||||
"PUSH", "5",
|
"PUSH", "5",
|
||||||
"PUSH", "5",
|
"PUSH", "5",
|
||||||
"LE",
|
"LE",
|
||||||
|
|
||||||
"PUSH", "50",
|
"PUSH", "50",
|
||||||
"PUSH", "5",
|
"PUSH", "5",
|
||||||
"GT",
|
"GT",
|
||||||
|
|
||||||
"PUSH", "5",
|
"PUSH", "5",
|
||||||
"PUSH", "5",
|
"PUSH", "5",
|
||||||
"GE",
|
"GE",
|
||||||
|
|
||||||
"PUSH", "10",
|
"PUSH", "10",
|
||||||
"PUSH", "10",
|
"PUSH", "10",
|
||||||
"NOT",
|
"NOT",
|
||||||
|
|
||||||
"MYADDRESS",
|
"MYADDRESS",
|
||||||
"TXSENDER",
|
"TXSENDER",
|
||||||
|
|
||||||
"STOP",
|
"STOP",
|
||||||
})
|
})
|
||||||
tx := NewTransaction("1e8a42ea8cce13", 100, []string{})
|
tx := NewTransaction("1e8a42ea8cce13", 100, []string{})
|
||||||
|
|
||||||
block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx})
|
block := CreateBlock("", 0, "", "c014ba53", 0, 0, "", []*Transaction{ctrct, tx})
|
||||||
db.Put(block.Hash(), block.RlpEncode())
|
db.Put(block.Hash(), block.RlpEncode())
|
||||||
|
|
||||||
bm := NewBlockManager()
|
bm := NewBlockManager()
|
||||||
bm.ProcessBlock( block )
|
bm.ProcessBlock(block)
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
2
peer.go
2
peer.go
@ -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 {
|
|||||||
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) {
|
|||||||
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
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user