diff --git a/ethchain/block_manager.go b/ethchain/block_manager.go index 33df338ff8..1fcc06be41 100644 --- a/ethchain/block_manager.go +++ b/ethchain/block_manager.go @@ -301,12 +301,12 @@ func (bm *BlockManager) ProcessContract(tx *Transaction, block *Block) { // Contract evaluation is done here. func (bm *BlockManager) ProcContract(tx *Transaction, block *Block, cb TxCallback) { - + addr := tx.Hash()[12:] // Instruction pointer pc := 0 blockInfo := bm.bc.BlockInfo(block) - contract := block.GetContract(tx.Hash()) + contract := block.GetContract(addr) if contract == nil { fmt.Println("Contract not found") @@ -318,8 +318,12 @@ func (bm *BlockManager) ProcContract(tx *Transaction, block *Block, cb TxCallbac if ethutil.Config.Debug { fmt.Printf("# op\n") } + + stepcount := 0 + totalFee := new(big.Int) out: for { + stepcount++ // The base big int for all calculations. Use this for any results. base := new(big.Int) // XXX Should Instr return big int slice instead of string slice? @@ -331,12 +335,40 @@ out: o := v.Uint() op := OpCode(o) + var fee *big.Int = new(big.Int) + if stepcount > 16 { + fee.Add(fee, StepFee) + } + + // Calculate the fees + switch op { + /* + FIXME (testnet requires no funds yet) + case oSSTORE: + fee.Add(fee, StoreFee) + case oSLOAD: + fee.Add(fee, StoreFee) + */ + case oEXTRO, oBALANCE: + fee.Add(fee, ExtroFee) + case oSHA256, oRIPEMD160, oECMUL, oECADD, oECSIGN, oECRECOVER, oECVALID: + fee.Add(fee, CryptoFee) + case oMKTX: + fee.Add(fee, ContractFee) + } + + if contract.Amount.Cmp(fee) < 0 { + break + } + // Add the fee to the total fee. It's subtracted when we're done looping + totalFee.Add(totalFee, fee) + if !cb(0) { break } if ethutil.Config.Debug { - fmt.Printf("%-3d %-4s\n", pc, op.String()) + fmt.Printf("%-3d %-4s", pc, op.String()) } switch op { @@ -453,10 +485,6 @@ out: } else { bm.stack.Push(ethutil.BigFalse) } - - // Please note that the following code contains some - // ugly string casting. This will have to change to big - // ints. TODO :) case oMYADDRESS: bm.stack.Push(ethutil.BigD(tx.Hash())) case oTXSENDER: @@ -579,11 +607,10 @@ out: } case oSSTORE: // Store Y at index X - x, y := bm.stack.Popn() + y, x := bm.stack.Popn() idx := ethutil.BigToBytes(x, 256) - val := ethutil.NewValue(y) - //fmt.Printf("STORING VALUE: %v @ %v\n", val.BigInt(), ethutil.BigD(idx)) - contract.State().Update(string(idx), string(val.Encode())) + fmt.Printf(" => %x (%v) @ %v", y.Bytes(), y, ethutil.BigD(idx)) + contract.State().Update(string(idx), string(y.Bytes())) case oJMP: x := int(bm.stack.Pop().Uint64()) // Set pc to x - 1 (minus one so the incrementing at the end won't effect it) @@ -628,9 +655,12 @@ out: default: fmt.Println("Invalid OPCODE", op) } - //bm.stack.Print() + fmt.Println("") + bm.stack.Print() pc++ } + + block.UpdateContract(addr, contract) } // Returns an address from the specified contract's address