Types for storage market Modify deals.Provider to implement storagemarket.StorageProvider Inject storagemarket.StorageProvider Storage Provider interfaces Storage Client interfaces Add ValidatePublishedDeal to ClientNodeAdapter Remove FundManager from client Remove Wallet from client Remove StateManager, Events, Wallet from client Rebasing - Copy types.BigInt, use TokenAmount/BigInt for token amounts - Remove auto-imported log package - Move `checkAskSignature` to a client file. - Plumb contexts through fix(storagemarket): use publish cids Switch back to publish message cids to reduce the dependency surface area
242 lines
4.5 KiB
Go
242 lines
4.5 KiB
Go
// Copied from lotus until this can be extracted into shared types
|
|
|
|
package storagemarket
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"math/big"
|
|
|
|
"github.com/filecoin-project/lotus/build"
|
|
cbor "github.com/ipfs/go-ipld-cbor"
|
|
"github.com/polydawn/refmt/obj/atlas"
|
|
|
|
cbg "github.com/whyrusleeping/cbor-gen"
|
|
"golang.org/x/xerrors"
|
|
)
|
|
|
|
const BigIntMaxSerializedLen = 128 // is this big enough? or too big?
|
|
|
|
var TotalFilecoinInt = FromFil(build.TotalFilecoin)
|
|
|
|
func init() {
|
|
cbor.RegisterCborType(atlas.BuildEntry(BigInt{}).Transform().
|
|
TransformMarshal(atlas.MakeMarshalTransformFunc(
|
|
func(i BigInt) ([]byte, error) {
|
|
return i.cborBytes(), nil
|
|
})).
|
|
TransformUnmarshal(atlas.MakeUnmarshalTransformFunc(
|
|
func(x []byte) (BigInt, error) {
|
|
return fromCborBytes(x)
|
|
})).
|
|
Complete())
|
|
}
|
|
|
|
var EmptyInt = BigInt{}
|
|
|
|
type BigInt struct {
|
|
*big.Int
|
|
}
|
|
|
|
func NewInt(i uint64) BigInt {
|
|
return BigInt{big.NewInt(0).SetUint64(i)}
|
|
}
|
|
|
|
func FromFil(i uint64) BigInt {
|
|
return BigMul(NewInt(i), NewInt(build.FilecoinPrecision))
|
|
}
|
|
|
|
func BigFromBytes(b []byte) BigInt {
|
|
i := big.NewInt(0).SetBytes(b)
|
|
return BigInt{i}
|
|
}
|
|
|
|
func BigFromString(s string) (BigInt, error) {
|
|
v, ok := big.NewInt(0).SetString(s, 10)
|
|
if !ok {
|
|
return BigInt{}, fmt.Errorf("failed to parse string as a big int")
|
|
}
|
|
|
|
return BigInt{v}, nil
|
|
}
|
|
|
|
func BigMul(a, b BigInt) BigInt {
|
|
return BigInt{big.NewInt(0).Mul(a.Int, b.Int)}
|
|
}
|
|
|
|
func BigDiv(a, b BigInt) BigInt {
|
|
return BigInt{big.NewInt(0).Div(a.Int, b.Int)}
|
|
}
|
|
|
|
func BigMod(a, b BigInt) BigInt {
|
|
return BigInt{big.NewInt(0).Mod(a.Int, b.Int)}
|
|
}
|
|
|
|
func BigAdd(a, b BigInt) BigInt {
|
|
return BigInt{big.NewInt(0).Add(a.Int, b.Int)}
|
|
}
|
|
|
|
func BigSub(a, b BigInt) BigInt {
|
|
return BigInt{big.NewInt(0).Sub(a.Int, b.Int)}
|
|
}
|
|
|
|
func BigCmp(a, b BigInt) int {
|
|
return a.Int.Cmp(b.Int)
|
|
}
|
|
|
|
func (bi BigInt) Nil() bool {
|
|
return bi.Int == nil
|
|
}
|
|
|
|
// LessThan returns true if bi < o
|
|
func (bi BigInt) LessThan(o BigInt) bool {
|
|
return BigCmp(bi, o) < 0
|
|
}
|
|
|
|
// GreaterThan returns true if bi > o
|
|
func (bi BigInt) GreaterThan(o BigInt) bool {
|
|
return BigCmp(bi, o) > 0
|
|
}
|
|
|
|
// Equals returns true if bi == o
|
|
func (bi BigInt) Equals(o BigInt) bool {
|
|
return BigCmp(bi, o) == 0
|
|
}
|
|
|
|
func (bi *BigInt) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(bi.String())
|
|
}
|
|
|
|
func (bi *BigInt) UnmarshalJSON(b []byte) error {
|
|
var s string
|
|
if err := json.Unmarshal(b, &s); err != nil {
|
|
return err
|
|
}
|
|
|
|
i, ok := big.NewInt(0).SetString(s, 10)
|
|
if !ok {
|
|
if string(s) == "<nil>" {
|
|
return nil
|
|
}
|
|
return xerrors.Errorf("failed to parse bigint string: '%s'", string(b))
|
|
}
|
|
|
|
bi.Int = i
|
|
return nil
|
|
}
|
|
|
|
func (bi *BigInt) Scan(value interface{}) error {
|
|
switch value := value.(type) {
|
|
case string:
|
|
i, ok := big.NewInt(0).SetString(value, 10)
|
|
if !ok {
|
|
if value == "<nil>" {
|
|
return nil
|
|
}
|
|
return xerrors.Errorf("failed to parse bigint string: '%s'", value)
|
|
}
|
|
|
|
bi.Int = i
|
|
|
|
return nil
|
|
case int64:
|
|
bi.Int = big.NewInt(value)
|
|
return nil
|
|
default:
|
|
return xerrors.Errorf("non-string types unsupported: %T", value)
|
|
}
|
|
}
|
|
|
|
func (bi *BigInt) cborBytes() []byte {
|
|
if bi.Int == nil {
|
|
return []byte{}
|
|
}
|
|
|
|
switch {
|
|
case bi.Sign() > 0:
|
|
return append([]byte{0}, bi.Bytes()...)
|
|
case bi.Sign() < 0:
|
|
return append([]byte{1}, bi.Bytes()...)
|
|
default: // bi.Sign() == 0:
|
|
return []byte{}
|
|
}
|
|
}
|
|
|
|
func fromCborBytes(buf []byte) (BigInt, error) {
|
|
if len(buf) == 0 {
|
|
return NewInt(0), nil
|
|
}
|
|
|
|
var negative bool
|
|
switch buf[0] {
|
|
case 0:
|
|
negative = false
|
|
case 1:
|
|
negative = true
|
|
default:
|
|
return EmptyInt, fmt.Errorf("big int prefix should be either 0 or 1, got %d", buf[0])
|
|
}
|
|
|
|
i := big.NewInt(0).SetBytes(buf[1:])
|
|
if negative {
|
|
i.Neg(i)
|
|
}
|
|
|
|
return BigInt{i}, nil
|
|
}
|
|
|
|
func (bi *BigInt) MarshalCBOR(w io.Writer) error {
|
|
if bi.Int == nil {
|
|
zero := NewInt(0)
|
|
return zero.MarshalCBOR(w)
|
|
}
|
|
|
|
enc := bi.cborBytes()
|
|
|
|
header := cbg.CborEncodeMajorType(cbg.MajByteString, uint64(len(enc)))
|
|
if _, err := w.Write(header); err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := w.Write(enc); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (bi *BigInt) UnmarshalCBOR(br io.Reader) error {
|
|
maj, extra, err := cbg.CborReadHeader(br)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if maj != cbg.MajByteString {
|
|
return fmt.Errorf("cbor input for fil big int was not a byte string (%x)", maj)
|
|
}
|
|
|
|
if extra == 0 {
|
|
bi.Int = big.NewInt(0)
|
|
return nil
|
|
}
|
|
|
|
if extra > BigIntMaxSerializedLen {
|
|
return fmt.Errorf("big integer byte array too long")
|
|
}
|
|
|
|
buf := make([]byte, extra)
|
|
if _, err := io.ReadFull(br, buf); err != nil {
|
|
return err
|
|
}
|
|
|
|
i, err := fromCborBytes(buf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
*bi = i
|
|
|
|
return nil
|
|
}
|