mirror of
https://github.com/discountry/ritmex-bot.git
synced 2026-09-11 09:18:08 +00:00
feat: 添加 Lighter 适配器及相关功能,支持 trailing stops 和新的交易逻辑
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
package goldilocks
|
||||
|
||||
//go:noescape
|
||||
func branchHint()
|
||||
@@ -0,0 +1,3 @@
|
||||
TEXT ·branchHint(SB),$0
|
||||
NOP
|
||||
RET
|
||||
@@ -0,0 +1,198 @@
|
||||
package goldilocks
|
||||
|
||||
// Partially wraps and extends the functionality of the goldilocks field package.
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
g "github.com/consensys/gnark-crypto/field/goldilocks"
|
||||
)
|
||||
|
||||
type Element = g.Element
|
||||
|
||||
const Bytes = 8
|
||||
|
||||
func NewElement(value uint64) Element {
|
||||
return g.NewElement(value)
|
||||
}
|
||||
|
||||
func reverseBytes(b []byte) []byte {
|
||||
res := make([]byte, len(b))
|
||||
for i, j := 0, len(b)-1; i < j; i, j = i+1, j-1 {
|
||||
res[i], res[j] = b[j], b[i]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func ArrayFromCanonicalLittleEndianBytes(in []byte) ([]Element, error) {
|
||||
missing := 8 - len(in)%8
|
||||
if missing == 8 {
|
||||
missing = 0
|
||||
}
|
||||
|
||||
ret := make([]Element, 0)
|
||||
for i := 0; i < len(in); {
|
||||
nextStart := i + 8
|
||||
|
||||
if nextStart > len(in) {
|
||||
nextStart = len(in)
|
||||
}
|
||||
|
||||
slice := make([]byte, 8)
|
||||
copy(slice[:], in[i:nextStart])
|
||||
if len(slice) < 8 {
|
||||
slice = append(slice, make([]byte, missing)...)
|
||||
}
|
||||
|
||||
elem, err := FromCanonicalLittleEndianBytes(slice)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert bytes to field element. bytes: %v, error: %w", slice, err)
|
||||
}
|
||||
ret = append(ret, *elem)
|
||||
i = nextStart
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func ToLittleEndianBytes(e ...Element) []byte {
|
||||
res := make([]byte, 0)
|
||||
for _, elem := range e {
|
||||
bytes := elem.Bytes()
|
||||
res = append(res, reverseBytes(bytes[:])...)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func FromCanonicalLittleEndianBytes(in []byte) (*Element, error) {
|
||||
elem := g.NewElement(0)
|
||||
err := elem.SetBytesCanonical(reverseBytes(in))
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to convert bytes to field element: %w", err)
|
||||
}
|
||||
return &elem, nil
|
||||
}
|
||||
|
||||
func ArrayToLittleEndianBytes(e []Element) []byte {
|
||||
res := make([]byte, 0)
|
||||
for _, elem := range e {
|
||||
res = append(res, ToLittleEndianBytes(elem)...)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func ToString(e ...Element) string {
|
||||
res := ""
|
||||
for _, elem := range e {
|
||||
res += elem.String() + " "
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func FromBool(value bool) Element {
|
||||
if value {
|
||||
return One()
|
||||
}
|
||||
return Zero()
|
||||
}
|
||||
|
||||
func FromInt64Abs(value int64) Element {
|
||||
return FromUint64(uint64(value & 0x7FFFFFFFFFFFFFFF))
|
||||
}
|
||||
|
||||
func FromInt64(value int64) Element {
|
||||
elem := g.NewElement(0)
|
||||
elem.SetInt64(value)
|
||||
return elem
|
||||
}
|
||||
|
||||
func FromUint64(value uint64) Element {
|
||||
elem := g.NewElement(0)
|
||||
elem.SetUint64(value)
|
||||
return elem
|
||||
}
|
||||
|
||||
func FromUint32(value uint32) Element {
|
||||
return FromUint64(uint64(value))
|
||||
}
|
||||
|
||||
func Equals(a, b *Element) bool {
|
||||
return a.Equal(b)
|
||||
}
|
||||
|
||||
func Modulus() uint64 {
|
||||
return g.Modulus().Uint64()
|
||||
}
|
||||
|
||||
func Zero() Element {
|
||||
return g.NewElement(0)
|
||||
}
|
||||
|
||||
func One() Element {
|
||||
return g.NewElement(1)
|
||||
}
|
||||
|
||||
func Neg(e Element) Element {
|
||||
res := g.NewElement(0)
|
||||
res.Neg(&e)
|
||||
return res
|
||||
}
|
||||
|
||||
func NegOne() *Element {
|
||||
res := Neg(One())
|
||||
return &res
|
||||
}
|
||||
|
||||
func Sample() Element {
|
||||
elem := g.NewElement(0)
|
||||
elem.SetRandom()
|
||||
return elem
|
||||
}
|
||||
|
||||
func RandArray(count int) []Element {
|
||||
ret := make([]Element, count)
|
||||
for i := 0; i < count; i++ {
|
||||
ret[i] = Sample()
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func Add(elems ...Element) Element {
|
||||
res := g.NewElement(0)
|
||||
for _, elem := range elems {
|
||||
res.Add(&res, &elem)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func Sub(a, b *Element) Element {
|
||||
res := g.NewElement(0)
|
||||
res.Sub(a, b)
|
||||
return res
|
||||
}
|
||||
|
||||
func Mul(elems ...*Element) Element {
|
||||
res := g.NewElement(1)
|
||||
for _, elem := range elems {
|
||||
res.Mul(&res, elem)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func Sqrt(elem *Element) *Element {
|
||||
elemCopy := DeepCopy(elem)
|
||||
return elemCopy.Sqrt(&elemCopy)
|
||||
}
|
||||
|
||||
// Powers starting from 1
|
||||
func Powers(e *Element, count int) []Element {
|
||||
ret := make([]Element, count)
|
||||
ret[0] = g.One()
|
||||
for i := 1; i < int(count); i++ {
|
||||
ret[i].Mul(&ret[i-1], e)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func DeepCopy(source *Element) Element {
|
||||
return Element{source[0]}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package goldilocks
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"encoding/binary"
|
||||
"math/big"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
type GoldilocksField uint64
|
||||
|
||||
const EPSILON = uint64((1 << 32) - 1)
|
||||
const ORDER = uint64(0xffffffff00000001)
|
||||
|
||||
var ORDER_BIG, _ = new(big.Int).SetString("0xffffffff00000001", 16)
|
||||
|
||||
func NonCannonicalGoldilocksField(x int64) GoldilocksField {
|
||||
if x < 0 {
|
||||
return NegF(GoldilocksField(-x))
|
||||
}
|
||||
|
||||
return GoldilocksField(x)
|
||||
}
|
||||
|
||||
func ZeroF() GoldilocksField {
|
||||
return 0
|
||||
}
|
||||
|
||||
func OneF() GoldilocksField {
|
||||
return 1
|
||||
}
|
||||
|
||||
func NegOneF() GoldilocksField {
|
||||
return GoldilocksField(ORDER - 1)
|
||||
}
|
||||
|
||||
func (z GoldilocksField) IsZero() bool {
|
||||
return z.ToCanonicalUint64() == 0
|
||||
}
|
||||
|
||||
func (z GoldilocksField) ToCanonicalUint64() uint64 {
|
||||
x := uint64(z)
|
||||
if x >= ORDER {
|
||||
x -= ORDER
|
||||
}
|
||||
|
||||
return x
|
||||
}
|
||||
|
||||
func AddF(lhs, rhs GoldilocksField) GoldilocksField {
|
||||
sum, over := bits.Add64(uint64(lhs), uint64(rhs), 0)
|
||||
sum, over = bits.Add64(sum, over*EPSILON, 0)
|
||||
if over == 1 {
|
||||
branchHint()
|
||||
sum += EPSILON // this can't overflow
|
||||
}
|
||||
|
||||
return GoldilocksField(sum)
|
||||
}
|
||||
|
||||
func DoubleF(lhs GoldilocksField) GoldilocksField {
|
||||
return AddF(lhs, lhs)
|
||||
}
|
||||
|
||||
func SubF(lhs, rhs GoldilocksField) GoldilocksField {
|
||||
diff, borrow := bits.Sub64(uint64(lhs), uint64(rhs), 0)
|
||||
diff, borrow = bits.Sub64(diff, borrow*EPSILON, 0)
|
||||
if borrow == 1 {
|
||||
branchHint()
|
||||
diff -= EPSILON // this can't underflow
|
||||
}
|
||||
|
||||
return GoldilocksField(diff)
|
||||
}
|
||||
|
||||
func MulF(lhs, rhs GoldilocksField) GoldilocksField {
|
||||
x_hi, x_lo := bits.Mul64(uint64(lhs), uint64(rhs))
|
||||
|
||||
x_hi_hi := x_hi >> 32
|
||||
x_hi_lo := x_hi & EPSILON
|
||||
|
||||
t0, borrow := bits.Sub64(x_lo, x_hi_hi, 0)
|
||||
if borrow == 1 {
|
||||
branchHint()
|
||||
t0 -= EPSILON
|
||||
}
|
||||
t1 := x_hi_lo * EPSILON
|
||||
|
||||
sum, over := bits.Add64(t0, t1, 0)
|
||||
t2 := sum + EPSILON*over
|
||||
return GoldilocksField(t2)
|
||||
}
|
||||
|
||||
func SquareF(x GoldilocksField) GoldilocksField {
|
||||
return MulF(x, x)
|
||||
}
|
||||
|
||||
func ExpPowerOf2(x GoldilocksField, n uint) GoldilocksField {
|
||||
z := x
|
||||
for i := uint(0); i < n; i++ {
|
||||
z = SquareF(z)
|
||||
}
|
||||
|
||||
return z
|
||||
}
|
||||
|
||||
func NegF(x GoldilocksField) GoldilocksField {
|
||||
z := GoldilocksField(0)
|
||||
if !x.IsZero() {
|
||||
z = GoldilocksField(ORDER - x.ToCanonicalUint64())
|
||||
}
|
||||
|
||||
return z
|
||||
}
|
||||
|
||||
func SampleF() GoldilocksField {
|
||||
rng, err := rand.Int(rand.Reader, ORDER_BIG)
|
||||
if err != nil {
|
||||
panic("failed to read random bytes into buffer")
|
||||
}
|
||||
return GoldilocksField(rng.Uint64())
|
||||
}
|
||||
|
||||
func ToLittleEndianBytesF(z GoldilocksField) []byte {
|
||||
res := make([]byte, Bytes)
|
||||
binary.LittleEndian.PutUint64(res, z.ToCanonicalUint64())
|
||||
return res
|
||||
}
|
||||
|
||||
func FromCanonicalLittleEndianBytesF(b []byte) GoldilocksField {
|
||||
return GoldilocksField(binary.LittleEndian.Uint64(b))
|
||||
}
|
||||
|
||||
// func (z *GoldilocksField) Inverse(x *GoldilocksField) *GoldilocksField {
|
||||
// if x.IsZero() {
|
||||
// z.SetZero()
|
||||
// return z
|
||||
// }
|
||||
|
||||
// var tmp *GoldilocksField
|
||||
|
||||
// t2 := *tmp.Square(x).Mul(tmp, x)
|
||||
// t3 := *tmp.Square(&t2).Mul(tmp, x)
|
||||
// t6 := *tmp.ExpPowerOf2(&t3, 3).Mul(tmp, &t3)
|
||||
// t12 := *tmp.ExpPowerOf2(&t6, 6).Mul(tmp, &t6)
|
||||
// t24 := *tmp.ExpPowerOf2(&t12, 12).Mul(tmp, &t12)
|
||||
// t30 := *tmp.ExpPowerOf2(&t24, 6).Mul(tmp, &t6)
|
||||
// t31 := *tmp.Square(&t30).Mul(tmp, x)
|
||||
// t63 := *tmp.ExpPowerOf2(&t31, 32).Mul(tmp, &t31)
|
||||
|
||||
// z.Square(&t63).Mul(z, x)
|
||||
|
||||
// return z
|
||||
// }
|
||||
Reference in New Issue
Block a user