aboutsummaryrefslogtreecommitdiffstats
path: root/ethchain
diff options
context:
space:
mode:
Diffstat (limited to 'ethchain')
-rw-r--r--ethchain/block.go53
-rw-r--r--ethchain/block_chain.go192
-rw-r--r--ethchain/error.go18
-rw-r--r--ethchain/fees.go2
-rw-r--r--ethchain/filter.go3
-rw-r--r--ethchain/state_manager.go100
-rw-r--r--ethchain/state_transition.go11
-rw-r--r--ethchain/transaction.go5
-rw-r--r--ethchain/transaction_pool.go9
-rw-r--r--ethchain/types.go244
10 files changed, 261 insertions, 376 deletions
diff --git a/ethchain/block.go b/ethchain/block.go
index 5765abd51..157be2a52 100644
--- a/ethchain/block.go
+++ b/ethchain/block.go
@@ -4,6 +4,7 @@ import (
"bytes"
"fmt"
"math/big"
+ "sort"
_ "strconv"
"time"
@@ -31,11 +32,45 @@ func (bi *BlockInfo) RlpEncode() []byte {
return ethutil.Encode([]interface{}{bi.Number, bi.Hash, bi.Parent})
}
+type Blocks []*Block
+
+func (self Blocks) AsSet() ethutil.UniqueSet {
+ set := make(ethutil.UniqueSet)
+ for _, block := range self {
+ set.Insert(block.Hash())
+ }
+
+ return set
+}
+
+type BlockBy func(b1, b2 *Block) bool
+
+func (self BlockBy) Sort(blocks Blocks) {
+ bs := blockSorter{
+ blocks: blocks,
+ by: self,
+ }
+ sort.Sort(bs)
+}
+
+type blockSorter struct {
+ blocks Blocks
+ by func(b1, b2 *Block) bool
+}
+
+func (self blockSorter) Len() int { return len(self.blocks) }
+func (self blockSorter) Swap(i, j int) {
+ self.blocks[i], self.blocks[j] = self.blocks[j], self.blocks[i]
+}
+func (self blockSorter) Less(i, j int) bool { return self.by(self.blocks[i], self.blocks[j]) }
+
+func Number(b1, b2 *Block) bool { return b1.Number.Cmp(b2.Number) < 0 }
+
type Block struct {
// Hash to the previous block
- PrevHash []byte
+ PrevHash ethutil.Bytes
// Uncles of this block
- Uncles []*Block
+ Uncles Blocks
UncleSha []byte
// The coin base address
Coinbase []byte
@@ -57,7 +92,7 @@ type Block struct {
// Extra data
Extra string
// Block Nonce for verification
- Nonce []byte
+ Nonce ethutil.Bytes
// List of transactions and/or contracts
transactions []*Transaction
receipts []*Receipt
@@ -106,8 +141,9 @@ func CreateBlock(root interface{},
}
// Returns a hash of the block
-func (block *Block) Hash() []byte {
- return ethcrypto.Sha3Bin(block.Value().Encode())
+func (block *Block) Hash() ethutil.Bytes {
+ return ethcrypto.Sha3Bin(ethutil.NewValue(block.header()).Encode())
+ //return ethcrypto.Sha3Bin(block.Value().Encode())
}
func (block *Block) HashNoNonce() []byte {
@@ -351,7 +387,7 @@ func (block *Block) header() []interface{} {
func (block *Block) String() string {
return fmt.Sprintf(`
- BLOCK(%x):
+ BLOCK(%x): Size: %v
PrevHash: %x
UncleSha: %x
Coinbase: %x
@@ -368,6 +404,7 @@ func (block *Block) String() string {
NumTx: %v
`,
block.Hash(),
+ block.Size(),
block.PrevHash,
block.UncleSha,
block.Coinbase,
@@ -384,3 +421,7 @@ func (block *Block) String() string {
len(block.transactions),
)
}
+
+func (self *Block) Size() ethutil.StorageSize {
+ return ethutil.StorageSize(len(self.RlpEncode()))
+}
diff --git a/ethchain/block_chain.go b/ethchain/block_chain.go
index 3445bbb87..7c9b60fc5 100644
--- a/ethchain/block_chain.go
+++ b/ethchain/block_chain.go
@@ -2,12 +2,10 @@ package ethchain
import (
"bytes"
- "math"
"math/big"
"github.com/ethereum/eth-go/ethlog"
"github.com/ethereum/eth-go/ethutil"
- "github.com/ethereum/eth-go/ethwire"
)
var chainlogger = ethlog.NewLogger("CHAIN")
@@ -60,24 +58,20 @@ func (bc *BlockChain) NewBlock(coinbase []byte) *Block {
block.MinGasPrice = big.NewInt(10000000000000)
- if bc.CurrentBlock != nil {
- var mul *big.Int
- if block.Time < lastBlockTime+42 {
- mul = big.NewInt(1)
+ parent := bc.CurrentBlock
+ if parent != nil {
+ diff := new(big.Int)
+
+ adjust := new(big.Int).Rsh(parent.Difficulty, 10)
+ if block.Time >= lastBlockTime+5 {
+ diff.Sub(parent.Difficulty, adjust)
} else {
- mul = big.NewInt(-1)
+ diff.Add(parent.Difficulty, adjust)
}
-
- diff := new(big.Int)
- diff.Add(diff, bc.CurrentBlock.Difficulty)
- diff.Div(diff, big.NewInt(1024))
- diff.Mul(diff, mul)
- diff.Add(diff, bc.CurrentBlock.Difficulty)
block.Difficulty = diff
-
block.Number = new(big.Int).Add(bc.CurrentBlock.Number, ethutil.Big1)
-
block.GasLimit = block.CalcGasLimit(bc.CurrentBlock)
+
}
return block
@@ -110,99 +104,6 @@ func (bc *BlockChain) CalculateBlockTD(block *Block) *big.Int {
return blockDiff
}
-func (bc *BlockChain) FindCanonicalChainFromMsg(msg *ethwire.Msg, commonBlockHash []byte) bool {
- var blocks []*Block
- for i := 0; i < (msg.Data.Len() - 1); i++ {
- block := NewBlockFromRlpValue(msg.Data.Get(i))
- blocks = append(blocks, block)
- }
- return bc.FindCanonicalChain(blocks, commonBlockHash)
-}
-
-// Is tasked by finding the CanonicalChain and resetting the chain if we are not the Conical one
-// Return true if we are the using the canonical chain false if not
-func (bc *BlockChain) FindCanonicalChain(blocks []*Block, commonBlockHash []byte) bool {
- // 1. Calculate TD of the current chain
- // 2. Calculate TD of the new chain
- // Reset state to the correct one
-
- chainDifficulty := new(big.Int)
-
- // Calculate the entire chain until the block we both have
- // Start with the newest block we got, all the way back to the common block we both know
- for _, block := range blocks {
- if bytes.Compare(block.Hash(), commonBlockHash) == 0 {
- chainlogger.Infoln("We have found the common parent block, breaking")
- break
- }
- chainDifficulty.Add(chainDifficulty, bc.CalculateBlockTD(block))
- }
-
- chainlogger.Infoln("Incoming chain difficulty:", chainDifficulty)
-
- curChainDifficulty := new(big.Int)
- block := bc.CurrentBlock
- for i := 0; block != nil; block = bc.GetBlock(block.PrevHash) {
- i++
- if bytes.Compare(block.Hash(), commonBlockHash) == 0 {
- chainlogger.Infoln("Found the common parent block")
- break
- }
- anOtherBlock := bc.GetBlock(block.PrevHash)
- if anOtherBlock == nil {
- // We do not want to count the genesis block for difficulty since that's not being sent
- chainlogger.Infoln("Found genesis block. Stop")
- break
- }
- curChainDifficulty.Add(curChainDifficulty, bc.CalculateBlockTD(block))
- }
-
- chainlogger.Infoln("Current chain difficulty:", curChainDifficulty)
- if chainDifficulty.Cmp(curChainDifficulty) == 1 {
- chainlogger.Infof("Resetting to block %x. Changing chain.")
- bc.ResetTillBlockHash(commonBlockHash)
- return false
- } else {
- chainlogger.Infoln("Current chain is longest chain. Ignoring incoming chain.")
- return true
- }
-}
-func (bc *BlockChain) ResetTillBlockHash(hash []byte) error {
- lastBlock := bc.CurrentBlock
- var returnTo *Block
- // Reset to Genesis if that's all the origin there is.
- if bytes.Compare(hash, bc.genesisBlock.Hash()) == 0 {
- returnTo = bc.genesisBlock
- bc.CurrentBlock = bc.genesisBlock
- bc.LastBlockHash = bc.genesisBlock.Hash()
- bc.LastBlockNumber = 1
- } else {
- returnTo = bc.GetBlock(hash)
- bc.CurrentBlock = returnTo
- bc.LastBlockHash = returnTo.Hash()
- bc.LastBlockNumber = returnTo.Number.Uint64()
- }
-
- // Manually reset the last sync block
- err := ethutil.Config.Db.Delete(lastBlock.Hash())
- if err != nil {
- return err
- }
-
- var block *Block
- for ; block != nil; block = bc.GetBlock(block.PrevHash) {
- if bytes.Compare(block.Hash(), hash) == 0 {
- chainlogger.Infoln("We have arrived at the the common parent block, breaking")
- break
- }
- err = ethutil.Config.Db.Delete(block.Hash())
- if err != nil {
- return err
- }
- }
- chainlogger.Infoln("Split chain deleted and reverted to common parent block.")
- return nil
-}
func (bc *BlockChain) GenesisBlock() *Block {
return bc.genesisBlock
@@ -228,66 +129,6 @@ func (self *BlockChain) GetChainHashesFromHash(hash []byte, max uint64) (chain [
return
}
-// Get chain return blocks from hash up to max in RLP format
-func (bc *BlockChain) GetChainFromHash(hash []byte, max uint64) []interface{} {
- var chain []interface{}
- // Get the current hash to start with
- currentHash := bc.CurrentBlock.Hash()
- // Get the last number on the block chain
- lastNumber := bc.CurrentBlock.Number.Uint64()
- // Get the parents number
- parentNumber := bc.GetBlock(hash).Number.Uint64()
- // Get the min amount. We might not have max amount of blocks
- count := uint64(math.Min(float64(lastNumber-parentNumber), float64(max)))
- startNumber := parentNumber + count
-
- num := lastNumber
- for num > startNumber {
- num--
-
- block := bc.GetBlock(currentHash)
- if block == nil {
- break
- }
- currentHash = block.PrevHash
- }
-
- for i := uint64(0); bytes.Compare(currentHash, hash) != 0 && num >= parentNumber && i < count; i++ {
- // Get the block of the chain
- block := bc.GetBlock(currentHash)
- if block == nil {
- chainlogger.Debugf("Unexpected error during GetChainFromHash: Unable to find %x\n", currentHash)
- break
- }
-
- currentHash = block.PrevHash
-
- chain = append(chain, block.Value().Val)
-
- num--
- }
-
- return chain
-}
-
-func (bc *BlockChain) GetChain(hash []byte, amount int) []*Block {
- genHash := bc.genesisBlock.Hash()
-
- block := bc.GetBlock(hash)
- var blocks []*Block
-
- for i := 0; i < amount && block != nil; block = bc.GetBlock(block.PrevHash) {
- blocks = append([]*Block{block}, blocks...)
-
- if bytes.Compare(genHash, block.Hash()) == 0 {
- break
- }
- i++
- }
-
- return blocks
-}
-
func AddTestNetFunds(block *Block) {
for _, addr := range []string{
"51ba59315b3a95761d0863b05ccc7a7f54703d99",
@@ -307,6 +148,9 @@ func AddTestNetFunds(block *Block) {
}
func (bc *BlockChain) setLastBlock() {
+ // Prep genesis
+ AddTestNetFunds(bc.genesisBlock)
+
data, _ := ethutil.Config.Db.Get([]byte("LastBlock"))
if len(data) != 0 {
block := NewBlockFromBytes(data)
@@ -315,13 +159,12 @@ func (bc *BlockChain) setLastBlock() {
bc.LastBlockNumber = block.Number.Uint64()
} else {
- AddTestNetFunds(bc.genesisBlock)
-
bc.genesisBlock.state.Trie.Sync()
// Prepare the genesis block
bc.Add(bc.genesisBlock)
fk := append([]byte("bloom"), bc.genesisBlock.Hash()...)
bc.Ethereum.Db().Put(fk, make([]byte, 255))
+ bc.CurrentBlock = bc.genesisBlock
}
// Set the last know difficulty (might be 0x0 as initial value, Genesis)
@@ -331,7 +174,7 @@ func (bc *BlockChain) setLastBlock() {
}
func (bc *BlockChain) SetTotalDifficulty(td *big.Int) {
- ethutil.Config.Db.Put([]byte("LastKnownTotalDifficulty"), td.Bytes())
+ ethutil.Config.Db.Put([]byte("LTD"), td.Bytes())
bc.TD = td
}
@@ -359,10 +202,13 @@ func (bc *BlockChain) GetBlock(hash []byte) *Block {
func (self *BlockChain) GetBlockByNumber(num uint64) *Block {
block := self.CurrentBlock
- for ; block.Number.Uint64() != num; block = self.GetBlock(block.PrevHash) {
+ for ; block != nil; block = self.GetBlock(block.PrevHash) {
+ if block.Number.Uint64() == num {
+ break
+ }
}
- if block.Number.Uint64() == 0 && num != 0 {
+ if block != nil && block.Number.Uint64() == 0 && num != 0 {
return nil
}
diff --git a/ethchain/error.go b/ethchain/error.go
index 2cf09a1ec..82949141a 100644
--- a/ethchain/error.go
+++ b/ethchain/error.go
@@ -25,6 +25,24 @@ func IsParentErr(err error) bool {
return ok
}
+type UncleErr struct {
+ Message string
+}
+
+func (err *UncleErr) Error() string {
+ return err.Message
+}
+
+func UncleError(str string) error {
+ return &UncleErr{Message: str}
+}
+
+func IsUncleErr(err error) bool {
+ _, ok := err.(*UncleErr)
+
+ return ok
+}
+
// Block validation error. If any validation fails, this error will be thrown
type ValidationErr struct {
Message string
diff --git a/ethchain/fees.go b/ethchain/fees.go
index 743be86a2..901357439 100644
--- a/ethchain/fees.go
+++ b/ethchain/fees.go
@@ -5,5 +5,3 @@ import (
)
var BlockReward *big.Int = big.NewInt(1.5e+18)
-var UncleReward *big.Int = big.NewInt(1.125e+18)
-var UncleInclusionReward *big.Int = big.NewInt(1.875e+17)
diff --git a/ethchain/filter.go b/ethchain/filter.go
index 5ed9af977..d9f1796f4 100644
--- a/ethchain/filter.go
+++ b/ethchain/filter.go
@@ -23,6 +23,9 @@ type Filter struct {
max int
altered []data
+
+ BlockCallback func(*Block)
+ MessageCallback func(ethstate.Messages)
}
// Create a new filter which uses a bloom filter on blocks to figure out whether a particular block
diff --git a/ethchain/state_manager.go b/ethchain/state_manager.go
index 08bd22d29..b0ea754f4 100644
--- a/ethchain/state_manager.go
+++ b/ethchain/state_manager.go
@@ -5,6 +5,7 @@ import (
"container/list"
"fmt"
"math/big"
+ "os"
"sync"
"time"
@@ -154,6 +155,10 @@ done:
if i < len(block.Receipts()) {
original := block.Receipts()[i]
if !original.Cmp(receipt) {
+ if ethutil.Config.Diff {
+ os.Exit(1)
+ }
+
return nil, nil, nil, fmt.Errorf("err diff #%d (r) %v ~ %x <=> (c) %v ~ %x (%x)\n", i+1, original.CumulativeGasUsed, original.PostState[0:4], receipt.CumulativeGasUsed, receipt.PostState[0:4], receipt.Tx.Hash())
}
}
@@ -217,13 +222,13 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
return err
}
- // I'm not sure, but I don't know if there should be thrown
- // any errors at this time.
- if err = sm.AccumelateRewards(state, block); err != nil {
+ if err = sm.AccumelateRewards(state, block, parent); err != nil {
statelogger.Errorln("Error accumulating reward", err)
return err
}
+ state.Update()
+
if !block.State().Cmp(state) {
err = fmt.Errorf("Invalid merkle root.\nrec: %x\nis: %x", block.State().Trie.Root, state.Trie.Root)
return
@@ -237,6 +242,8 @@ func (sm *StateManager) Process(block *Block, dontReact bool) (err error) {
// Add the block to the chain
sm.bc.Add(block)
+ sm.transState = state.Copy()
+
// Create a bloom bin for this block
filter := sm.createBloomFilter(state)
// Persist the data
@@ -305,14 +312,16 @@ func (sm *StateManager) ValidateBlock(block *Block) error {
// Check each uncle's previous hash. In order for it to be valid
// is if it has the same block hash as the current
- previousBlock := sm.bc.GetBlock(block.PrevHash)
- for _, uncle := range block.Uncles {
- if bytes.Compare(uncle.PrevHash, previousBlock.PrevHash) != 0 {
- return ValidationError("Mismatch uncle's previous hash. Expected %x, got %x", previousBlock.PrevHash, uncle.PrevHash)
+ parent := sm.bc.GetBlock(block.PrevHash)
+ /*
+ for _, uncle := range block.Uncles {
+ if bytes.Compare(uncle.PrevHash,parent.PrevHash) != 0 {
+ return ValidationError("Mismatch uncle's previous hash. Expected %x, got %x",parent.PrevHash, uncle.PrevHash)
+ }
}
- }
+ */
- diff := block.Time - previousBlock.Time
+ diff := block.Time - parent.Time
if diff < 0 {
return ValidationError("Block timestamp less then prev block %v (%v - %v)", diff, block.Time, sm.bc.CurrentBlock.Time)
}
@@ -332,36 +341,46 @@ func (sm *StateManager) ValidateBlock(block *Block) error {
return nil
}
-func CalculateBlockReward(block *Block, uncleLength int) *big.Int {
- base := new(big.Int)
- for i := 0; i < uncleLength; i++ {
- base.Add(base, UncleInclusionReward)
- }
+func (sm *StateManager) AccumelateRewards(state *ethstate.State, block, parent *Block) error {
+ reward := new(big.Int).Set(BlockReward)
- return base.Add(base, BlockReward)
-}
+ knownUncles := ethutil.Set(parent.Uncles)
+ nonces := ethutil.NewSet(block.Nonce)
+ for _, uncle := range block.Uncles {
+ if nonces.Include(uncle.Nonce) {
+ // Error not unique
+ return UncleError("Uncle not unique")
+ }
-func CalculateUncleReward(block *Block) *big.Int {
- return UncleReward
-}
+ uncleParent := sm.bc.GetBlock(uncle.PrevHash)
+ if uncleParent == nil {
+ return UncleError("Uncle's parent unknown")
+ }
-func (sm *StateManager) AccumelateRewards(state *ethstate.State, block *Block) error {
- // Get the account associated with the coinbase
- account := state.GetAccount(block.Coinbase)
- // Reward amount of ether to the coinbase address
- account.AddAmount(CalculateBlockReward(block, len(block.Uncles)))
+ if uncleParent.Number.Cmp(new(big.Int).Sub(parent.Number, big.NewInt(6))) < 0 {
+ return UncleError("Uncle too old")
+ }
- addr := make([]byte, len(block.Coinbase))
- copy(addr, block.Coinbase)
- state.UpdateStateObject(account)
+ if knownUncles.Include(uncle.Hash()) {
+ return UncleError("Uncle in chain")
+ }
+
+ nonces.Insert(uncle.Nonce)
+
+ r := new(big.Int)
+ r.Mul(BlockReward, big.NewInt(15)).Div(r, big.NewInt(16))
- for _, uncle := range block.Uncles {
uncleAccount := state.GetAccount(uncle.Coinbase)
- uncleAccount.AddAmount(CalculateUncleReward(uncle))
+ uncleAccount.AddAmount(r)
- state.UpdateStateObject(uncleAccount)
+ reward.Add(reward, new(big.Int).Div(BlockReward, big.NewInt(32)))
}
+ // Get the account associated with the coinbase
+ account := state.GetAccount(block.Coinbase)
+ // Reward amount of ether to the coinbase address
+ account.AddAmount(reward)
+
return nil
}
@@ -373,14 +392,6 @@ func (sm *StateManager) Stop() {
func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
bloomf := NewBloomFilter(nil)
- /*
- for addr, stateObject := range state.Manifest().ObjectChanges {
- // Set the bloom filter's bin
- bloomf.Set([]byte(addr))
-
- sm.Ethereum.Reactor().Post("object:"+addr, stateObject)
- }
- */
for _, msg := range state.Manifest().Messages {
bloomf.Set(msg.To)
bloomf.Set(msg.From)
@@ -388,17 +399,6 @@ func (sm *StateManager) createBloomFilter(state *ethstate.State) *BloomFilter {
sm.Ethereum.Reactor().Post("messages", state.Manifest().Messages)
- /*
- for stateObjectAddr, mappedObjects := range state.Manifest().StorageChanges {
- for addr, value := range mappedObjects {
- // Set the bloom filter's bin
- bloomf.Set(ethcrypto.Sha3Bin([]byte(stateObjectAddr + addr)))
-
- sm.Ethereum.Reactor().Post("storage:"+stateObjectAddr+":"+addr, &ethstate.StorageState{[]byte(stateObjectAddr), []byte(addr), value})
- }
- }
- */
-
return bloomf
}
@@ -418,7 +418,7 @@ func (sm *StateManager) GetMessages(block *Block) (messages []*ethstate.Message,
sm.ApplyDiff(state, parent, block)
- sm.AccumelateRewards(state, block)
+ sm.AccumelateRewards(state, block, parent)
return state.Manifest().Messages, nil
}
diff --git a/ethchain/state_transition.go b/ethchain/state_transition.go
index 9fbc160a5..c1180a641 100644
--- a/ethchain/state_transition.go
+++ b/ethchain/state_transition.go
@@ -140,7 +140,7 @@ func (self *StateTransition) preCheck() (err error) {
}
func (self *StateTransition) TransitionState() (err error) {
- statelogger.Infof("(~) %x\n", self.tx.Hash())
+ statelogger.Debugf("(~) %x\n", self.tx.Hash())
/*
defer func() {
@@ -278,6 +278,15 @@ func (self *StateTransition) Eval(msg *ethstate.Message, script []byte, context
ret, _, err = callerClosure.Call(vm, self.tx.Data)
+ if err == nil {
+ // Execute POSTs
+ for e := vm.Queue().Front(); e != nil; e = e.Next() {
+ msg := e.Value.(*ethvm.Message)
+
+ msg.Exec(msg.Addr(), transactor)
+ }
+ }
+
return
}
diff --git a/ethchain/transaction.go b/ethchain/transaction.go
index e1b48a3d3..e7e8f3a9f 100644
--- a/ethchain/transaction.go
+++ b/ethchain/transaction.go
@@ -13,7 +13,8 @@ import (
var ContractAddr = []byte{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
func IsContractAddr(addr []byte) bool {
- return bytes.Compare(addr, ContractAddr) == 0
+ return len(addr) == 0
+ //return bytes.Compare(addr, ContractAddr) == 0
}
type Transaction struct {
@@ -31,7 +32,7 @@ type Transaction struct {
}
func NewContractCreationTx(value, gas, gasPrice *big.Int, script []byte) *Transaction {
- return &Transaction{Recipient: ContractAddr, Value: value, Gas: gas, GasPrice: gasPrice, Data: script, contractCreation: true}
+ return &Transaction{Recipient: nil, Value: value, Gas: gas, GasPrice: gasPrice, Data: script, contractCreation: true}
}
func NewTransactionMessage(to []byte, value, gas, gasPrice *big.Int, data []byte) *Transaction {
diff --git a/ethchain/transaction_pool.go b/ethchain/transaction_pool.go
index b0d62fd91..9a6322432 100644
--- a/ethchain/transaction_pool.go
+++ b/ethchain/transaction_pool.go
@@ -72,8 +72,6 @@ type TxPool struct {
func NewTxPool(ethereum EthManager) *TxPool {
return &TxPool{
- //server: s,
- mutex: sync.Mutex{},
pool: list.New(),
queueChan: make(chan *Transaction, txPoolQueueSize),
quit: make(chan bool),
@@ -101,7 +99,7 @@ func (pool *TxPool) ValidateTransaction(tx *Transaction) error {
return fmt.Errorf("[TXPL] No last block on the block chain")
}
- if len(tx.Recipient) != 20 {
+ if len(tx.Recipient) != 0 && len(tx.Recipient) != 20 {
return fmt.Errorf("[TXPL] Invalid recipient. len = %d", len(tx.Recipient))
}
@@ -150,7 +148,10 @@ out:
// Call blocking version.
pool.addTransaction(tx)
- txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tx.Recipient[:4], tx.Value, tx.Hash())
+ tmp := make([]byte, 4)
+ copy(tmp, tx.Recipient)
+
+ txplogger.Debugf("(t) %x => %x (%v) %x\n", tx.Sender()[:4], tmp, tx.Value, tx.Hash())
// Notify the subscribers
pool.Ethereum.Reactor().Post("newTx:pre", tx)
diff --git a/ethchain/types.go b/ethchain/types.go
index 9e7269f74..45486b06c 100644
--- a/ethchain/types.go
+++ b/ethchain/types.go
@@ -27,10 +27,12 @@ const (
NOT = 0x0f
// 0x10 range - bit ops
- AND = 0x10
- OR = 0x11
- XOR = 0x12
- BYTE = 0x13
+ AND = 0x10
+ OR = 0x11
+ XOR = 0x12
+ BYTE = 0x13
+ ADDMOD = 0x14
+ MULMOD = 0x15
// 0x20 range - crypto
SHA3 = 0x20
@@ -47,6 +49,8 @@ const (
CODESIZE = 0x38
CODECOPY = 0x39
GASPRICE = 0x3a
+ EXTCODECOPY = 0x3b
+ EXTCODESIZE = 0x3c
// 0x40 range - block operations
PREVHASH = 0x40
@@ -57,9 +61,9 @@ const (
GASLIMIT = 0x45
// 0x50 range - 'storage' and execution
- POP = 0x50
- DUP = 0x51
- SWAP = 0x52
+ POP = 0x50
+ //DUP = 0x51
+ //SWAP = 0x52
MLOAD = 0x53
MSTORE = 0x54
MSTORE8 = 0x55
@@ -105,10 +109,46 @@ const (
PUSH31 = 0x7e
PUSH32 = 0x7f
+ DUP1 = 0x80
+ DUP2 = 0x81
+ DUP3 = 0x82
+ DUP4 = 0x83
+ DUP5 = 0x84
+ DUP6 = 0x85
+ DUP7 = 0x86
+ DUP8 = 0x87
+ DUP9 = 0x88
+ DUP10 = 0x89
+ DUP11 = 0x8a
+ DUP12 = 0x8b
+ DUP13 = 0x8c
+ DUP14 = 0x8d
+ DUP15 = 0x8e
+ DUP16 = 0x8f
+
+ SWAP1 = 0x90
+ SWAP2 = 0x91
+ SWAP3 = 0x92
+ SWAP4 = 0x93
+ SWAP5 = 0x94
+ SWAP6 = 0x95
+ SWAP7 = 0x96
+ SWAP8 = 0x97
+ SWAP9 = 0x98
+ SWAP10 = 0x99
+ SWAP11 = 0x9a
+ SWAP12 = 0x9b
+ SWAP13 = 0x9c
+ SWAP14 = 0x9d
+ SWAP15 = 0x9e
+ SWAP16 = 0x9f
+
// 0xf0 range - closures
- CREATE = 0xf0
- CALL = 0xf1
- RETURN = 0xf2
+ CREATE = 0xf0
+ CALL = 0xf1
+ RETURN = 0xf2
+ POST = 0xf3
+ CALLSTATELESS = 0xf4
// 0x70 range - other
LOG = 0xfe // XXX Unofficial
@@ -136,10 +176,12 @@ var opCodeToString = map[OpCode]string{
NOT: "NOT",
// 0x10 range - bit ops
- AND: "AND",
- OR: "OR",
- XOR: "XOR",
- BYTE: "BYTE",
+ AND: "AND",
+ OR: "OR",
+ XOR: "XOR",
+ BYTE: "BYTE",
+ ADDMOD: "ADDMOD",
+ MULMOD: "MULMOD",
// 0x20 range - crypto
SHA3: "SHA3",
@@ -158,17 +200,19 @@ var opCodeToString = map[OpCode]string{
GASPRICE: "TXGASPRICE",
// 0x40 range - block operations
- PREVHASH: "PREVHASH",
- COINBASE: "COINBASE",
- TIMESTAMP: "TIMESTAMP",
- NUMBER: "NUMBER",
- DIFFICULTY: "DIFFICULTY",
- GASLIMIT: "GASLIMIT",
+ PREVHASH: "PREVHASH",
+ COINBASE: "COINBASE",
+ TIMESTAMP: "TIMESTAMP",
+ NUMBER: "NUMBER",
+ DIFFICULTY: "DIFFICULTY",
+ GASLIMIT: "GASLIMIT",
+ EXTCODESIZE: "EXTCODESIZE",
+ EXTCODECOPY: "EXTCODECOPY",
// 0x50 range - 'storage' and execution
- POP: "POP",
- DUP: "DUP",
- SWAP: "SWAP",
+ POP: "POP",
+ //DUP: "DUP",
+ //SWAP: "SWAP",
MLOAD: "MLOAD",
MSTORE: "MSTORE",
MSTORE8: "MSTORE8",
@@ -214,10 +258,46 @@ var opCodeToString = map[OpCode]string{
PUSH31: "PUSH31",
PUSH32: "PUSH32",
+ DUP1: "DUP1",
+ DUP2: "DUP2",
+ DUP3: "DUP3",
+ DUP4: "DUP4",
+ DUP5: "DUP5",
+ DUP6: "DUP6",
+ DUP7: "DUP7",
+ DUP8: "DUP8",
+ DUP9: "DUP9",
+ DUP10: "DUP10",
+ DUP11: "DUP11",
+ DUP12: "DUP12",
+ DUP13: "DUP13",
+ DUP14: "DUP14",
+ DUP15: "DUP15",
+ DUP16: "DUP16",
+
+ SWAP1: "SWAP1",
+ SWAP2: "SWAP2",
+ SWAP3: "SWAP3",
+ SWAP4: "SWAP4",
+ SWAP5: "SWAP5",
+ SWAP6: "SWAP6",
+ SWAP7: "SWAP7",
+ SWAP8: "SWAP8",
+ SWAP9: "SWAP9",
+ SWAP10: "SWAP10",
+ SWAP11: "SWAP11",
+ SWAP12: "SWAP12",
+ SWAP13: "SWAP13",
+ SWAP14: "SWAP14",
+ SWAP15: "SWAP15",
+ SWAP16: "SWAP16",
+
// 0xf0 range
- CREATE: "CREATE",
- CALL: "CALL",
- RETURN: "RETURN",
+ CREATE: "CREATE",
+ CALL: "CALL",
+ RETURN: "RETURN",
+ POST: "POST",
+ CALLSTATELESS: "CALLSTATELESS",
// 0x70 range - other
LOG: "LOG",
@@ -232,115 +312,3 @@ func (o OpCode) String() string {
return str
}
-
-// Op codes for assembling
-var OpCodes = map[string]byte{
- // 0x0 range - arithmetic ops
- "STOP": 0x00,
- "ADD": 0x01,
- "MUL": 0x02,
- "SUB": 0x03,
- "DIV": 0x04,
- "SDIV": 0x05,
- "MOD": 0x06,
- "SMOD": 0x07,
- "EXP": 0x08,
- "NEG": 0x09,
- "LT": 0x0a,
- "GT": 0x0b,
- "EQ": 0x0c,
- "NOT": 0x0d,
-
- // 0x10 range - bit ops
- "AND": 0x10,
- "OR": 0x11,
- "XOR": 0x12,
- "BYTE": 0x13,
-
- // 0x20 range - crypto
- "SHA3": 0x20,
-
- // 0x30 range - closure state
- "ADDRESS": 0x30,
- "BALANCE": 0x31,
- "ORIGIN": 0x32,
- "CALLER": 0x33,
- "CALLVALUE": 0x34,
- "CALLDATALOAD": 0x35,
- "CALLDATASIZE": 0x36,
- "GASPRICE": 0x38,
-
- // 0x40 range - block operations
- "PREVHASH": 0x40,
- "COINBASE": 0x41,
- "TIMESTAMP": 0x42,
- "NUMBER": 0x43,
- "DIFFICULTY": 0x44,
- "GASLIMIT": 0x45,
-
- // 0x50 range - 'storage' and execution
- "POP": 0x51,
- "DUP": 0x52,
- "SWAP": 0x53,
- "MLOAD": 0x54,
- "MSTORE": 0x55,
- "MSTORE8": 0x56,
- "SLOAD": 0x57,
- "SSTORE": 0x58,
- "JUMP": 0x59,
- "JUMPI": 0x5a,
- "PC": 0x5b,
- "MSIZE": 0x5c,
-
- // 0x70 range - 'push'
- "PUSH1": 0x60,
- "PUSH2": 0x61,
- "PUSH3": 0x62,
- "PUSH4": 0x63,
- "PUSH5": 0x64,
- "PUSH6": 0x65,
- "PUSH7": 0x66,
- "PUSH8": 0x67,
- "PUSH9": 0x68,
- "PUSH10": 0x69,
- "PUSH11": 0x6a,
- "PUSH12": 0x6b,
- "PUSH13": 0x6c,
- "PUSH14": 0x6d,
- "PUSH15": 0x6e,
- "PUSH16": 0x6f,
- "PUSH17": 0x70,
- "PUSH18": 0x71,
- "PUSH19": 0x72,
- "PUSH20": 0x73,
- "PUSH21": 0x74,
- "PUSH22": 0x75,
- "PUSH23": 0x76,
- "PUSH24": 0x77,
- "PUSH25": 0x78,
- "PUSH26": 0x70,
- "PUSH27": 0x7a,
- "PUSH28": 0x7b,
- "PUSH29": 0x7c,
- "PUSH30": 0x7d,
- "PUSH31": 0x7e,
- "PUSH32": 0x7f,
-
- // 0xf0 range - closures
- "CREATE": 0xf0,
- "CALL": 0xf1,
- "RETURN": 0xf2,
-
- // 0x70 range - other
- "LOG": 0xfe,
- "SUICIDE": 0x7f,
-}
-
-func IsOpCode(s string) bool {
- for key, _ := range OpCodes {
- if key == s {
- return true
- }
- }
- return false
-}