Beispiel #1
1
func floor(n *big.Rat) *big.Rat {
	f := &big.Rat{}
	z := new(big.Int)
	z.Div(n.Num(), n.Denom())
	f.SetInt(z)
	return f
}
Beispiel #2
0
// hostconfigcmd is the handler for the command `siac host config [setting] [value]`.
// Modifies host settings.
func hostconfigcmd(param, value string) {
	switch param {
	case "price":
		// convert price to hastings/byte/block
		p, ok := new(big.Rat).SetString(value)
		if !ok {
			die("Could not parse price")
		}
		p.Mul(p, big.NewRat(1e24/1e9, 4320))
		value = new(big.Int).Div(p.Num(), p.Denom()).String()
	case "totalstorage":
		// parse sizes of form 10GB, 10TB, 1TiB etc
		var err error
		value, err = parseSize(value)
		if err != nil {
			die("Could not parse totalstorage:", err)
		}
	case "minduration", "maxduration", "windowsize", "acceptingcontracts": // Other valid settings.
	default:
		// Reject invalid host config commands.
		die("\"" + param + "\" is not a host setting")
	}
	err := post("/host", param+"="+value)
	if err != nil {
		die("Could not update host settings:", err)
	}
	fmt.Println("Host settings updated.")
}
Beispiel #3
0
func hostconfigcmd(param, value string) {
	// convert price to hastings/byte/block
	if param == "price" {
		p, ok := new(big.Rat).SetString(value)
		if !ok {
			fmt.Println("could not parse price")
			return
		}
		p.Mul(p, big.NewRat(1e24/1e9, 4320))
		value = new(big.Int).Div(p.Num(), p.Denom()).String()
	}
	// parse sizes of form 10GB, 10TB, 1TiB etc
	if param == "totalstorage" {
		var err error
		value, err = parseSize(value)
		if err != nil {
			fmt.Println("could not parse " + param)
		}
	}
	err := post("/host", param+"="+value)
	if err != nil {
		fmt.Println("Could not update host settings:", err)
		return
	}
	fmt.Println("Host settings updated.")
}
Beispiel #4
0
// MulRat returns a new Currency value c = x * y, where y is a big.Rat.
func (x Currency) MulRat(y *big.Rat) (c Currency) {
	if y.Sign() < 0 {
		build.Critical(ErrNegativeCurrency)
	} else {
		c.i.Mul(&x.i, y.Num())
		c.i.Div(&c.i, y.Denom())
	}
	return
}
Beispiel #5
0
// Returns a new big.Int set to the ceiling of x.
func ratCeil(x *big.Rat) *big.Int {
	z := new(big.Int)
	m := new(big.Int)
	z.DivMod(x.Num(), x.Denom(), m)
	if m.Cmp(intZero) == 1 {
		z.Add(z, intOne)
	}
	return z
}
func CalcGasLimit(parent *types.Block) *big.Int {
	// ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024
	previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit())
	current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed()), big.NewRat(6, 5))
	curInt := new(big.Int).Div(current.Num(), current.Denom())

	result := new(big.Int).Add(previous, curInt)
	result.Div(result, big.NewInt(1024))
	return common.BigMax(params.GenesisGasLimit, result)
}
Beispiel #7
0
func Round(r *big.Rat) *big.Rat {
	d := new(big.Int).Set(r.Denom())
	n := new(big.Int).Set(r.Num())
	n.Mod(n, d)
	if new(big.Int).Mul(n, big.NewInt(2)).Cmp(d) >= 0 {
		r.Add(r, new(big.Rat).SetInt64(1))
	}
	r.Sub(r, new(big.Rat).SetFrac(n, d))
	return r
}
Beispiel #8
0
// RatToTarget converts a big.Rat to a Target.
func RatToTarget(r *big.Rat) (t Target) {
	if r.Num().Sign() < 0 {
		if build.DEBUG {
			panic(ErrNegativeTarget)
		}
	} else {
		i := new(big.Int).Div(r.Num(), r.Denom())
		t = IntToTarget(i)
	}
	return
}
Beispiel #9
0
func (sqe scaleQuoExact) Scale(x, y *Dec) Scale {
	rem := new(big.Rat).SetFrac(x.UnscaledBig(), y.UnscaledBig())
	f2, f5 := factor2(rem.Denom()), factor(rem.Denom(), bigInt[5])
	var f10 Scale
	if f2 > f5 {
		f10 = Scale(f2)
	} else {
		f10 = Scale(f5)
	}
	return x.Scale() - y.Scale() + f10
}
Beispiel #10
0
// MulRat returns a new Currency value c = x * y, where y is a big.Rat.
func (x Currency) MulRat(y *big.Rat) (c Currency) {
	if y.Sign() < 0 {
		if build.DEBUG {
			panic(ErrNegativeCurrency)
		}
	} else {
		c.i.Mul(&x.i, y.Num())
		c.i.Div(&c.i, y.Denom())
	}
	return
}
Beispiel #11
0
// Do the numerator and denominator of r provide a solution to the equation
// x**2 - D*(y**2) = 1?
func isSolution(D int, r *big.Rat) bool {
	S := big.NewInt(int64(D))
	x := r.Num()
	y := r.Denom()

	one := big.NewInt(1)
	two := big.NewInt(2)

	a := new(big.Int).Exp(x, two, nil)
	b := new(big.Int).Exp(y, two, nil)
	return new(big.Int).Sub(a, new(big.Int).Mul(S, b)).Cmp(one) == 0
}
Beispiel #12
0
// COMPATv0.4.0 - until the first 10e3 blocks have been archived, MulFloat is
// needed while verifying the first set of blocks.
//
// MulFloat returns a new Currency value y = c * x, where x is a float64.
// Behavior is undefined when x is negative.
func (x Currency) MulFloat(y float64) (c Currency) {
	if y < 0 {
		build.Critical(ErrNegativeCurrency)
	} else {
		cRat := new(big.Rat).Mul(
			new(big.Rat).SetInt(&x.i),
			new(big.Rat).SetFloat64(y),
		)
		c.i.Div(cRat.Num(), cRat.Denom())
	}
	return
}
Beispiel #13
0
func makeRat(x *big.Rat) Value {
	a := x.Num()
	b := x.Denom()
	if a.BitLen() < maxExp && b.BitLen() < maxExp {
		// ok to remain fraction
		return ratVal{x}
	}
	// components too large => switch to float
	fa := newFloat().SetInt(a)
	fb := newFloat().SetInt(b)
	return floatVal{fa.Quo(fa, fb)}
}
Beispiel #14
0
func (v value) toInt() *big.Int {
	switch v := v.v.(type) {
	case *big.Int:
		return v
	case *big.Rat:
		// TODO rounding?
		return new(big.Int).Quo(v.Num(), v.Denom())
	case float64:
		r := new(big.Rat).SetFloat64(v)
		if r == nil {
			fatalf("cannot convert %v to float64", v)
		}
		// TODO rounding?
		return new(big.Int).Quo(r.Num(), r.Denom())
	}
	panic(fmt.Errorf("unexpected type %T", v.v))
}
Beispiel #15
0
func (block *Block) CalcGasLimit(parent *Block) *big.Int {
	if block.Number.Cmp(big.NewInt(0)) == 0 {
		return ethutil.BigPow(10, 6)
	}

	// ((1024-1) * parent.gasLimit + (gasUsed * 6 / 5)) / 1024

	previous := new(big.Int).Mul(big.NewInt(1024-1), parent.GasLimit)
	current := new(big.Rat).Mul(new(big.Rat).SetInt(parent.GasUsed), big.NewRat(6, 5))
	curInt := new(big.Int).Div(current.Num(), current.Denom())

	result := new(big.Int).Add(previous, curInt)
	result.Div(result, big.NewInt(1024))

	min := big.NewInt(125000)

	return ethutil.BigMax(min, result)
}
Beispiel #16
0
func hostconfigcmd(param, value string) {
	// convert price to hastings/byte/block
	if param == "price" {
		p, ok := new(big.Rat).SetString(value)
		if !ok {
			fmt.Println("could not parse price")
			return
		}
		p.Mul(p, big.NewRat(1e24/1e9, 4320))
		value = new(big.Int).Div(p.Num(), p.Denom()).String()
	}
	err := post("/host/configure", param+"="+value)
	if err != nil {
		fmt.Println("Could not update host settings:", err)
		return
	}
	fmt.Println("Host settings updated.")
}
// bigRatToValue converts 'number' to an SQL value with SQL type: valueType.
// If valueType is integral it truncates 'number' to the integer part according to the
// semantics of the big.Rat.Int method.
func bigRatToValue(number *big.Rat, valueType querypb.Type) sqltypes.Value {
	var numberAsBytes []byte
	switch {
	case sqltypes.IsIntegral(valueType):
		// 'number.Num()' returns a reference to the numerator of 'number'.
		// We copy it here to avoid changing 'number'.
		truncatedNumber := new(big.Int).Set(number.Num())
		truncatedNumber.Quo(truncatedNumber, number.Denom())
		numberAsBytes = bigIntToSliceOfBytes(truncatedNumber)
	case sqltypes.IsFloat(valueType):
		// Truncate to the closest 'float'.
		// There's not much we can do if there isn't an exact representation.
		numberAsFloat64, _ := number.Float64()
		numberAsBytes = strconv.AppendFloat([]byte{}, numberAsFloat64, 'f', -1, 64)
	default:
		panic(fmt.Sprintf("Unsupported type: %v", valueType))
	}
	result, err := sqltypes.ValueFromBytes(valueType, numberAsBytes)
	if err != nil {
		panic(fmt.Sprintf("sqltypes.ValueFromBytes failed with: %v", err))
	}
	return result
}
Beispiel #18
0
// ratExponent returns the power of ten that x would display in scientific notation.
func ratExponent(x *big.Rat) int {
	if x.Sign() < 0 {
		x.Neg(x)
	}
	e := 0
	invert := false
	if x.Num().Cmp(x.Denom()) < 0 {
		invert = true
		x.Inv(x)
		e++
	}
	for x.Cmp(bigRatBillion) >= 0 {
		e += 9
		x.Quo(x, bigRatBillion)
	}
	for x.Cmp(bigRatTen) > 0 {
		e++
		x.Quo(x, bigRatTen)
	}
	if invert {
		return -e
	}
	return e
}
Beispiel #19
0
// See https://en.wikipedia.org/wiki/Farey_sequence
// The value of the new term in between neighbours 2/5 and 3/7 is found by
// computing the mediant of those neighbours. We can take result to be the next
// left-hand neighbour of 3/7 iteratively until the denominator reaches 1e6.
func mediant(x, y *big.Rat) *big.Rat {
	num := new(big.Int).Add(x.Num(), y.Num())
	denom := new(big.Int).Add(x.Denom(), y.Denom())
	return new(big.Rat).SetFrac(num, denom)
}
Beispiel #20
0
// Contract evaluation is done here.
func (bm *BlockManager) ProcContract(tx *ethutil.Transaction, block *ethutil.Block, cb TxCallback) {
	// Instruction pointer
	pc := 0
	blockInfo := bm.BlockInfo(block)

	contract := block.GetContract(tx.Hash())
	if contract == nil {
		fmt.Println("Contract not found")
		return
	}

	Pow256 := ethutil.BigPow(2, 256)

	//fmt.Printf("#   op   arg\n")
out:
	for {
		// 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?
		// Get the next instruction from the contract
		//op, _, _ := Instr(contract.state.Get(string(Encode(uint32(pc)))))
		nb := ethutil.NumberToBytes(uint64(pc), 32)
		o, _, _ := ethutil.Instr(contract.State().Get(string(nb)))
		op := OpCode(o)

		if !cb(0) {
			break
		}

		if Debug {
			//fmt.Printf("%-3d %-4s\n", pc, op.String())
		}

		switch op {
		case oSTOP:
			break out
		case oADD:
			x, y := bm.stack.Popn()
			// (x + y) % 2 ** 256
			base.Add(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oSUB:
			x, y := bm.stack.Popn()
			// (x - y) % 2 ** 256
			base.Sub(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oMUL:
			x, y := bm.stack.Popn()
			// (x * y) % 2 ** 256
			base.Mul(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oDIV:
			x, y := bm.stack.Popn()
			// floor(x / y)
			base.Div(x, y)
			// Pop result back on the stack
			bm.stack.Push(base)
		case oSDIV:
			x, y := bm.stack.Popn()
			// n > 2**255
			if x.Cmp(Pow256) > 0 {
				x.Sub(Pow256, x)
			}
			if y.Cmp(Pow256) > 0 {
				y.Sub(Pow256, y)
			}
			z := new(big.Int)
			z.Div(x, y)
			if z.Cmp(Pow256) > 0 {
				z.Sub(Pow256, z)
			}
			// Push result on to the stack
			bm.stack.Push(z)
		case oMOD:
			x, y := bm.stack.Popn()
			base.Mod(x, y)
			bm.stack.Push(base)
		case oSMOD:
			x, y := bm.stack.Popn()
			// n > 2**255
			if x.Cmp(Pow256) > 0 {
				x.Sub(Pow256, x)
			}
			if y.Cmp(Pow256) > 0 {
				y.Sub(Pow256, y)
			}
			z := new(big.Int)
			z.Mod(x, y)
			if z.Cmp(Pow256) > 0 {
				z.Sub(Pow256, z)
			}
			// Push result on to the stack
			bm.stack.Push(z)
		case oEXP:
			x, y := bm.stack.Popn()
			base.Exp(x, y, Pow256)

			bm.stack.Push(base)
		case oNEG:
			base.Sub(Pow256, bm.stack.Pop())
			bm.stack.Push(base)
		case oLT:
			x, y := bm.stack.Popn()
			// x < y
			if x.Cmp(y) < 0 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oLE:
			x, y := bm.stack.Popn()
			// x <= y
			if x.Cmp(y) < 1 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oGT:
			x, y := bm.stack.Popn()
			// x > y
			if x.Cmp(y) > 0 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oGE:
			x, y := bm.stack.Popn()
			// x >= y
			if x.Cmp(y) > -1 {
				bm.stack.Push(ethutil.BigTrue)
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oNOT:
			x, y := bm.stack.Popn()
			// x != y
			if x.Cmp(y) != 0 {
				bm.stack.Push(ethutil.BigTrue)
			} 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:
			bm.stack.Push(ethutil.BigD(tx.Sender()))
		case oTXVALUE:
			bm.stack.Push(tx.Value)
		case oTXDATAN:
			bm.stack.Push(big.NewInt(int64(len(tx.Data))))
		case oTXDATA:
			v := bm.stack.Pop()
			// v >= len(data)
			if v.Cmp(big.NewInt(int64(len(tx.Data)))) >= 0 {
				bm.stack.Push(ethutil.Big("0"))
			} else {
				bm.stack.Push(ethutil.Big(tx.Data[v.Uint64()]))
			}
		case oBLK_PREVHASH:
			bm.stack.Push(ethutil.Big(block.PrevHash))
		case oBLK_COINBASE:
			bm.stack.Push(ethutil.Big(block.Coinbase))
		case oBLK_TIMESTAMP:
			bm.stack.Push(big.NewInt(block.Time))
		case oBLK_NUMBER:
			bm.stack.Push(blockInfo.Number)
		case oBLK_DIFFICULTY:
			bm.stack.Push(block.Difficulty)
		case oBASEFEE:
			// e = 10^21
			e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0))
			d := new(big.Rat)
			d.SetInt(block.Difficulty)
			c := new(big.Rat)
			c.SetFloat64(0.5)
			// d = diff / 0.5
			d.Quo(d, c)
			// base = floor(d)
			base.Div(d.Num(), d.Denom())

			x := new(big.Int)
			x.Div(e, base)

			// x = floor(10^21 / floor(diff^0.5))
			bm.stack.Push(x)
		case oSHA256, oSHA3, oRIPEMD160:
			// This is probably save
			// ceil(pop / 32)
			length := int(math.Ceil(float64(bm.stack.Pop().Uint64()) / 32.0))
			// New buffer which will contain the concatenated popped items
			data := new(bytes.Buffer)
			for i := 0; i < length; i++ {
				// Encode the number to bytes and have it 32bytes long
				num := ethutil.NumberToBytes(bm.stack.Pop().Bytes(), 256)
				data.WriteString(string(num))
			}

			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())))
			}
		case oECMUL:
			y := bm.stack.Pop()
			x := bm.stack.Pop()
			//n := bm.stack.Pop()

			//if ethutil.Big(x).Cmp(ethutil.Big(y)) {
			data := new(bytes.Buffer)
			data.WriteString(x.String())
			data.WriteString(y.String())
			if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 {
				// TODO
			} else {
				// Invalid, push infinity
				bm.stack.Push(ethutil.Big("0"))
				bm.stack.Push(ethutil.Big("0"))
			}
			//} else {
			//	// Invalid, push infinity
			//	bm.stack.Push("0")
			//	bm.stack.Push("0")
			//}

		case oECADD:
		case oECSIGN:
		case oECRECOVER:
		case oECVALID:
		case oPUSH:
			pc++
			bm.stack.Push(bm.mem[strconv.Itoa(pc)])
		case oPOP:
			// Pop current value of the stack
			bm.stack.Pop()
		case oDUP:
			// Dup top stack
			x := bm.stack.Pop()
			bm.stack.Push(x)
			bm.stack.Push(x)
		case oSWAP:
			// Swap two top most values
			x, y := bm.stack.Popn()
			bm.stack.Push(y)
			bm.stack.Push(x)
		case oMLOAD:
			x := bm.stack.Pop()
			bm.stack.Push(bm.mem[x.String()])
		case oMSTORE:
			x, y := bm.stack.Popn()
			bm.mem[x.String()] = y
		case oSLOAD:
			// Load the value in storage and push it on the stack
			x := bm.stack.Pop()
			// decode the object as a big integer
			decoder := ethutil.NewRlpDecoder([]byte(contract.State().Get(x.String())))
			if !decoder.IsNil() {
				bm.stack.Push(decoder.AsBigInt())
			} else {
				bm.stack.Push(ethutil.BigFalse)
			}
		case oSSTORE:
			// Store Y at index X
			x, y := bm.stack.Popn()
			contract.State().Update(x.String(), string(ethutil.Encode(y)))
		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)
			pc = x
			pc--
		case oJMPI:
			x := bm.stack.Pop()
			// Set pc to x if it's non zero
			if x.Cmp(ethutil.BigFalse) != 0 {
				pc = int(x.Uint64())
				pc--
			}
		case oIND:
			bm.stack.Push(big.NewInt(int64(pc)))
		case oEXTRO:
			memAddr := bm.stack.Pop()
			contractAddr := bm.stack.Pop().Bytes()

			// Push the contract's memory on to the stack
			bm.stack.Push(getContractMemory(block, contractAddr, memAddr))
		case oBALANCE:
			// Pushes the balance of the popped value on to the stack
			d := block.State().Get(bm.stack.Pop().String())
			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++
	}

	bm.stack.Print()
}
Beispiel #21
0
// Creates a new fraction from a rational number (big.Rat)
func NewFractionFromRat(rat *big.Rat) *Fraction {
	// Ignore error since *big.Rat denom can't be 0
	frac, _ := NewFraction(rat.Num().Int64(), rat.Denom().Int64())
	return frac
}
Beispiel #22
0
func checkNumerator(x *big.Rat) bool {
	num, denom := x.Num(), x.Denom()
	return numDigits(num) > numDigits(denom)
}
Beispiel #23
0
func savePiState(iteration int, sum *big.Rat) {
	file, _ := os.OpenFile("pi_cache", os.O_WRONLY|os.O_CREATE, 400)
	enc := json.NewEncoder(file)
	enc.Encode(PiState{iteration, sum.Num().String(), sum.Denom().String()})
	file.Close()
}
Beispiel #24
0
func (vm *Vm) Process(contract *Contract, state *State, vars RuntimeVars) {
	vm.mem = make(map[string]*big.Int)
	vm.stack = NewStack()

	addr := vars.address // tx.Hash()[12:]
	// Instruction pointer
	pc := 0

	if contract == nil {
		fmt.Println("Contract not found")
		return
	}

	Pow256 := ethutil.BigPow(2, 256)

	if ethutil.Config.Debug {
		ethutil.Config.Log.Debugf("#   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)
		val := contract.GetMem(pc)
		//fmt.Printf("%x = %d, %v %x\n", r, len(r), v, nb)
		op := OpCode(val.Uint())

		var fee *big.Int = new(big.Int)
		var fee2 *big.Int = new(big.Int)
		if stepcount > 16 {
			fee.Add(fee, StepFee)
		}

		// Calculate the fees
		switch op {
		case oSSTORE:
			y, x := vm.stack.Peekn()
			val := contract.Addr(ethutil.BigToBytes(x, 256))
			if val.IsEmpty() && len(y.Bytes()) > 0 {
				fee2.Add(DataFee, StoreFee)
			} else {
				fee2.Sub(DataFee, 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)
		}

		tf := new(big.Int).Add(fee, fee2)
		if contract.Amount.Cmp(tf) < 0 {
			fmt.Println("Insufficient fees to continue running the contract", tf, contract.Amount)
			break
		}
		// Add the fee to the total fee. It's subtracted when we're done looping
		totalFee.Add(totalFee, tf)

		if ethutil.Config.Debug {
			ethutil.Config.Log.Debugf("%-3d %-4s", pc, op.String())
		}

		switch op {
		case oSTOP:
			fmt.Println("")
			break out
		case oADD:
			x, y := vm.stack.Popn()
			// (x + y) % 2 ** 256
			base.Add(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			vm.stack.Push(base)
		case oSUB:
			x, y := vm.stack.Popn()
			// (x - y) % 2 ** 256
			base.Sub(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			vm.stack.Push(base)
		case oMUL:
			x, y := vm.stack.Popn()
			// (x * y) % 2 ** 256
			base.Mul(x, y)
			base.Mod(base, Pow256)
			// Pop result back on the stack
			vm.stack.Push(base)
		case oDIV:
			x, y := vm.stack.Popn()
			// floor(x / y)
			base.Div(x, y)
			// Pop result back on the stack
			vm.stack.Push(base)
		case oSDIV:
			x, y := vm.stack.Popn()
			// n > 2**255
			if x.Cmp(Pow256) > 0 {
				x.Sub(Pow256, x)
			}
			if y.Cmp(Pow256) > 0 {
				y.Sub(Pow256, y)
			}
			z := new(big.Int)
			z.Div(x, y)
			if z.Cmp(Pow256) > 0 {
				z.Sub(Pow256, z)
			}
			// Push result on to the stack
			vm.stack.Push(z)
		case oMOD:
			x, y := vm.stack.Popn()
			base.Mod(x, y)
			vm.stack.Push(base)
		case oSMOD:
			x, y := vm.stack.Popn()
			// n > 2**255
			if x.Cmp(Pow256) > 0 {
				x.Sub(Pow256, x)
			}
			if y.Cmp(Pow256) > 0 {
				y.Sub(Pow256, y)
			}
			z := new(big.Int)
			z.Mod(x, y)
			if z.Cmp(Pow256) > 0 {
				z.Sub(Pow256, z)
			}
			// Push result on to the stack
			vm.stack.Push(z)
		case oEXP:
			x, y := vm.stack.Popn()
			base.Exp(x, y, Pow256)

			vm.stack.Push(base)
		case oNEG:
			base.Sub(Pow256, vm.stack.Pop())
			vm.stack.Push(base)
		case oLT:
			x, y := vm.stack.Popn()
			// x < y
			if x.Cmp(y) < 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oLE:
			x, y := vm.stack.Popn()
			// x <= y
			if x.Cmp(y) < 1 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oGT:
			x, y := vm.stack.Popn()
			// x > y
			if x.Cmp(y) > 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oGE:
			x, y := vm.stack.Popn()
			// x >= y
			if x.Cmp(y) > -1 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oNOT:
			x, y := vm.stack.Popn()
			// x != y
			if x.Cmp(y) != 0 {
				vm.stack.Push(ethutil.BigTrue)
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oMYADDRESS:
			vm.stack.Push(ethutil.BigD(addr))
		case oTXSENDER:
			vm.stack.Push(ethutil.BigD(vars.sender))
		case oTXVALUE:
			vm.stack.Push(vars.txValue)
		case oTXDATAN:
			vm.stack.Push(big.NewInt(int64(len(vars.txData))))
		case oTXDATA:
			v := vm.stack.Pop()
			// v >= len(data)
			if v.Cmp(big.NewInt(int64(len(vars.txData)))) >= 0 {
				vm.stack.Push(ethutil.Big("0"))
			} else {
				vm.stack.Push(ethutil.Big(vars.txData[v.Uint64()]))
			}
		case oBLK_PREVHASH:
			vm.stack.Push(ethutil.BigD(vars.prevHash))
		case oBLK_COINBASE:
			vm.stack.Push(ethutil.BigD(vars.coinbase))
		case oBLK_TIMESTAMP:
			vm.stack.Push(big.NewInt(vars.time))
		case oBLK_NUMBER:
			vm.stack.Push(big.NewInt(int64(vars.blockNumber)))
		case oBLK_DIFFICULTY:
			vm.stack.Push(vars.diff)
		case oBASEFEE:
			// e = 10^21
			e := big.NewInt(0).Exp(big.NewInt(10), big.NewInt(21), big.NewInt(0))
			d := new(big.Rat)
			d.SetInt(vars.diff)
			c := new(big.Rat)
			c.SetFloat64(0.5)
			// d = diff / 0.5
			d.Quo(d, c)
			// base = floor(d)
			base.Div(d.Num(), d.Denom())

			x := new(big.Int)
			x.Div(e, base)

			// x = floor(10^21 / floor(diff^0.5))
			vm.stack.Push(x)
		case oSHA256, oSHA3, oRIPEMD160:
			// This is probably save
			// ceil(pop / 32)
			length := int(math.Ceil(float64(vm.stack.Pop().Uint64()) / 32.0))
			// New buffer which will contain the concatenated popped items
			data := new(bytes.Buffer)
			for i := 0; i < length; i++ {
				// Encode the number to bytes and have it 32bytes long
				num := ethutil.NumberToBytes(vm.stack.Pop().Bytes(), 256)
				data.WriteString(string(num))
			}

			if op == oSHA256 {
				vm.stack.Push(base.SetBytes(ethutil.Sha256Bin(data.Bytes())))
			} else if op == oSHA3 {
				vm.stack.Push(base.SetBytes(ethutil.Sha3Bin(data.Bytes())))
			} else {
				vm.stack.Push(base.SetBytes(ethutil.Ripemd160(data.Bytes())))
			}
		case oECMUL:
			y := vm.stack.Pop()
			x := vm.stack.Pop()
			//n := vm.stack.Pop()

			//if ethutil.Big(x).Cmp(ethutil.Big(y)) {
			data := new(bytes.Buffer)
			data.WriteString(x.String())
			data.WriteString(y.String())
			if secp256k1.VerifyPubkeyValidity(data.Bytes()) == 1 {
				// TODO
			} else {
				// Invalid, push infinity
				vm.stack.Push(ethutil.Big("0"))
				vm.stack.Push(ethutil.Big("0"))
			}
			//} else {
			//	// Invalid, push infinity
			//	vm.stack.Push("0")
			//	vm.stack.Push("0")
			//}

		case oECADD:
		case oECSIGN:
		case oECRECOVER:
		case oECVALID:
		case oPUSH:
			pc++
			vm.stack.Push(contract.GetMem(pc).BigInt())
		case oPOP:
			// Pop current value of the stack
			vm.stack.Pop()
		case oDUP:
			// Dup top stack
			x := vm.stack.Pop()
			vm.stack.Push(x)
			vm.stack.Push(x)
		case oSWAP:
			// Swap two top most values
			x, y := vm.stack.Popn()
			vm.stack.Push(y)
			vm.stack.Push(x)
		case oMLOAD:
			x := vm.stack.Pop()
			vm.stack.Push(vm.mem[x.String()])
		case oMSTORE:
			x, y := vm.stack.Popn()
			vm.mem[x.String()] = y
		case oSLOAD:
			// Load the value in storage and push it on the stack
			x := vm.stack.Pop()
			// decode the object as a big integer
			decoder := contract.Addr(x.Bytes())
			if !decoder.IsNil() {
				vm.stack.Push(decoder.BigInt())
			} else {
				vm.stack.Push(ethutil.BigFalse)
			}
		case oSSTORE:
			// Store Y at index X
			y, x := vm.stack.Popn()
			addr := ethutil.BigToBytes(x, 256)
			fmt.Printf(" => %x (%v) @ %v", y.Bytes(), y, ethutil.BigD(addr))
			contract.SetAddr(addr, y)
			//contract.State().Update(string(idx), string(y))
		case oJMP:
			x := int(vm.stack.Pop().Uint64())
			// Set pc to x - 1 (minus one so the incrementing at the end won't effect it)
			pc = x
			pc--
		case oJMPI:
			x := vm.stack.Pop()
			// Set pc to x if it's non zero
			if x.Cmp(ethutil.BigFalse) != 0 {
				pc = int(x.Uint64())
				pc--
			}
		case oIND:
			vm.stack.Push(big.NewInt(int64(pc)))
		case oEXTRO:
			memAddr := vm.stack.Pop()
			contractAddr := vm.stack.Pop().Bytes()

			// Push the contract's memory on to the stack
			vm.stack.Push(contractMemory(state, contractAddr, memAddr))
		case oBALANCE:
			// Pushes the balance of the popped value on to the stack
			account := state.GetAccount(vm.stack.Pop().Bytes())
			vm.stack.Push(account.Amount)
		case oMKTX:
			addr, value := vm.stack.Popn()
			from, length := vm.stack.Popn()

			makeInlineTx(addr.Bytes(), value, from, length, contract, state)
		case oSUICIDE:
			recAddr := vm.stack.Pop().Bytes()
			// Purge all memory
			deletedMemory := contract.state.Purge()
			// Add refunds to the pop'ed address
			refund := new(big.Int).Mul(StoreFee, big.NewInt(int64(deletedMemory)))
			account := state.GetAccount(recAddr)
			account.Amount.Add(account.Amount, refund)
			// Update the refunding address
			state.UpdateAccount(recAddr, account)
			// Delete the contract
			state.trie.Update(string(addr), "")

			ethutil.Config.Log.Debugf("(%d) => %x\n", deletedMemory, recAddr)
			break out
		default:
			fmt.Printf("Invalid OPCODE: %x\n", op)
		}
		ethutil.Config.Log.Debugln("")
		//vm.stack.Print()
		pc++
	}

	state.UpdateContract(addr, contract)
}
Beispiel #25
0
// Sqrt returns a new Currency value y = sqrt(c). Result is rounded down to the
// nearest integer.
func (x Currency) Sqrt() (c Currency) {
	f, _ := new(big.Rat).SetInt(&x.i).Float64()
	sqrt := new(big.Rat).SetFloat64(math.Sqrt(f))
	c.i.Div(sqrt.Num(), sqrt.Denom())
	return
}
Beispiel #26
0
func (x *exporter) exportName(t interface{}) {
	switch t := t.(type) {
	case *types.Var:
		if t.Anonymous() || t.Name() == "" {
			x.write("? ")
		} else {
			x.write("%s ", t.Name())
		}
		x.exportName(t.Type())
	case exact.Value:
		switch t.Kind() {
		case exact.Float:
			x.exportName(&ast.BasicLit{Value: t.String()})
		default:
			x.write(t.String())
		}
	case *types.Basic:
		if t.Kind() == types.UnsafePointer {
			x.write("@\"unsafe\".Pointer")
		} else if t.Info()&types.IsUntyped == 0 {
			x.write(t.String())
		}
	case *types.TypeName:
		if t.Pkg() == nil {
			switch t.Name() {
			case "error":
				x.write("error")
				return
			case "Pointer":
				x.write("@\"unsafe\".Pointer")
				return
			}
		}
		if t.Pkg() == x.pkg || t.Pkg() == nil {
			x.write("@\"\".")
		} else {
			x.write("@\"%s\".", t.Pkg().Path())
		}
		x.write(t.Name())
	case *types.Named:
		x.exportName(t.Obj())
	case *types.Slice:
		x.write("[]")
		x.exportName(t.Elem())
	case *types.Pointer:
		x.write("*")
		x.exportName(t.Elem())
	case *types.Map:
		x.write("map[")
		x.exportName(t.Key())
		x.write("]")
		x.exportName(t.Elem())
	case *types.Chan:
		if t.Dir() == types.RecvOnly {
			x.write("<-")
		}
		x.write("chan")
		if t.Dir() == types.SendOnly {
			x.write("<-")
		}
		x.write(" ")
		x.exportName(t.Elem())
	case *ast.BasicLit:
		var b big.Rat

		fmt.Sscan(t.Value, &b)
		num, denom := b.Num(), b.Denom()

		if denom.Int64() == 1 {
			x.write("%d", num.Int64())
			return
		}

		// So yeah, this bit deserves a comment. We have a big.Rat number represented by its
		// numerator and denominator, and we want to turn this into a base 2 exponent form
		// where:
		//
		//			num / denom = x * 2^exp
		// 			(num / denum) / x = 2^exp
		// 			log2((num / denum) / x) = exp
		//
		// x and exp need to be integers as gc export data parses fractional numbers in the form of
		//
		// 		int_lit [ "p" int_lit ]
		//
		// Initially we just set x = 1 / denum turning the equation to
		//
		//			log2(num) = exp
		//
		// But we want exp to be an integer so it's rounded up, which is just the number of bits
		// needed to represent num.
		//
		// After this rounding however, x != 1 / denum, but we have the exact value of everything
		// else so we could just plug every known variable in:
		//
		//		num / denom = x * 2^exp
		//
		// But as exp is currently a positive value, x must be a fractional number which is
		// what we were trying to get rid of in the first place!
		//
		// So instead, we make x a large number that is divided by 2^exp which allows us to do this:
		//
		//		num / denom = x / 2^exp
		//		num / denom = x * 2^-exp
		//
		// And solving for x we get:
		//
		//		(num / denom) / 2^-exp = x
		//		(2^exp * num) / denom = x
		//
		// There's still a division in there though leading to a precision loss due to x and exp being constrained
		// to integer values. By making exp large enough we can add in precision that way. It needs to be at
		// least big enough to fit
		//
		//		newexp = log2(2^exp * denom) = log2(num) + log2(denom)
		//
		// and as it needs to be an integer value it also needs to be adjusted up to allow more fractional precision.
		//
		// I have no specific theoretical reason for choosing the fractional precision bits here, and it can be
		// changed if needed. One could say that the fractional accuracy in the final x number would be
		//
		// 		1/(2^fractional_accuracy_bits)
		//
		// and 23 is the number of fractional bits used by the IEEE_754-2008 binary32 format.
		const fractional_accuracy_bits = 23
		exp := num.BitLen() + denom.BitLen() + fractional_accuracy_bits
		exporter := x
		x := big.NewInt(2)
		x.Exp(x, big.NewInt(int64(exp)), nil)
		x.Mul(x, num)
		x.Div(x, denom)
		exporter.write("%dp-%d", x, exp)
	case *types.Tuple:
		for i := 0; i < t.Len(); i++ {
			if i > 0 {
				x.write(", ")
			}
			ta := t.At(i)
			n := ta.Name()
			if n == "" {
				n = "?"
			} else {
				n = `@"".` + n
			}
			x.write(n)
			x.write(" ")
			x.exportName(ta.Type())
		}
	case *types.Signature:
		if x.writeFunc {
			x.write("func")
		} else {
			x.writeFunc = true
		}
		x.write("(")
		if p := t.Params(); p != nil {
			if t.IsVariadic() {
				for i := 0; i < p.Len(); i++ {
					if i > 0 {
						x.write(", ")
					}
					ta := p.At(i)
					n := ta.Name()
					if n == "" {
						n = "?"
					} else {
						n = `@"".` + n
					}
					x.write(n)
					x.write(" ")
					ty := ta.Type()
					if i+1 == p.Len() {
						x.write("...")
						ty = ty.(*types.Slice).Elem()
					}
					x.exportName(ty)
				}
			} else {
				x.exportName(p)
			}
		}
		x.write(")")
		if r := t.Results(); r != nil {
			x.write("(")
			x.exportName(r)
			x.write(")")
		}
	case *types.Struct:
		x.write("struct { ")
		for i := 0; i < t.NumFields(); i++ {
			if i > 0 {
				x.write("; ")
			}
			f := t.Field(i)
			x.exportName(f)
		}
		x.write(" }")
	case *types.Array:
		x.write("[%d]", t.Len())
		x.exportName(t.Elem())
	case *types.Interface:
		x.write("interface { ")
		for i := 0; i < t.NumMethods(); i++ {
			if i > 0 {
				x.write("; ")
			}
			m := t.Method(i)
			x.write(m.Name())
			x.writeFunc = false
			x.exportName(m.Type())
		}
		x.write(" }")
	default:
		panic(fmt.Sprintf("UNHANDLED %T", t))
	}
}
Beispiel #27
0
func (f *frac) fromRat(r *big.Rat) {
	*f.Numerator = int32(r.Num().Int64())
	*f.Denominator = int32(r.Denom().Int64())
}