Skip to content

Commit

Permalink
partially complete time lcok ,need complete func of TimeLock
Browse files Browse the repository at this point in the history
  • Loading branch information
Bin0J committed Sep 14, 2018
1 parent 13e42ce commit 7a0bb98
Show file tree
Hide file tree
Showing 5 changed files with 305 additions and 6 deletions.
60 changes: 56 additions & 4 deletions common/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,8 +363,10 @@ const (
GenNotationFunc = iota
// GenAssetFunc wacom
GenAssetFunc
// SendAsset wacom
SendAsset
// SendAssetFunc wacom
SendAssetFunc
// TimeLockFunc wacom
TimeLockFunc
)

// FSNCallParam wacom
Expand All @@ -388,6 +390,33 @@ type SendAssetParam struct {
Value *big.Int
}

// TimeLockType wacom
type TimeLockType uint

// TimeLockTypes wacom
const (
AssetToTimeLock TimeLockType = iota
TimeLockToTimeLock
TimeLockToAsset
)

const (
// TimeLockNow wacom
TimeLockNow uint64 = 0
// TimeLockForever wacom
TimeLockForever uint64 = 0xffffffffffffffff
)

// TimeLockParam wacom
type TimeLockParam struct {
Type TimeLockType
AssetID Hash
To Address
StartTime uint64
EndTime uint64
Value *big.Int
}

// ToBytes wacom
func (p *FSNCallParam) ToBytes() ([]byte, error) {
return rlp.EncodeToBytes(p)
Expand All @@ -403,6 +432,11 @@ func (p *SendAssetParam) ToBytes() ([]byte, error) {
return rlp.EncodeToBytes(p)
}

// ToBytes wacom
func (p *TimeLockParam) ToBytes() ([]byte, error) {
return rlp.EncodeToBytes(p)
}

// ToAsset wacom
func (p *GenAssetParam) ToAsset() Asset {
return Asset{
Expand Down Expand Up @@ -439,11 +473,20 @@ type TimeLockItem struct {
}

// TimeLock wacom
type TimeLock []TimeLockItem
type TimeLock struct {
Items []TimeLockItem
}

// NewTimeLock wacom
func NewTimeLock(items ...TimeLockItem) *TimeLock {
return &TimeLock{
Items: items,
}
}

// IsEmpty wacom
func (z *TimeLock) IsEmpty() bool {
return len(*z) == 0
return len(z.Items) == 0
}

// Add wacom
Expand All @@ -458,5 +501,14 @@ func (z *TimeLock) Sub(x, y *TimeLock) *TimeLock {

// Set wacom
func (z *TimeLock) Set(x *TimeLock) *TimeLock {
if x != nil && x.Items != nil {
z.Items = make([]TimeLockItem, len(x.Items))
copy(z.Items, x.Items)
}
return z
}

// Cmp wacom
func (z *TimeLock) Cmp(x *TimeLock) int {
return 0
}
42 changes: 41 additions & 1 deletion core/state_transition.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ func (st *StateTransition) handleFsnCall() error {
}
st.state.AddBalance(st.msg.From(), asset.ID, asset.Total)
return nil
case common.SendAsset:
case common.SendAssetFunc:
sendAssetParam := common.SendAssetParam{}
rlp.DecodeBytes(param.Data, &sendAssetParam)
if st.state.GetBalance(sendAssetParam.AssetID, st.msg.From()).Cmp(sendAssetParam.Value) < 0 {
Expand All @@ -282,6 +282,46 @@ func (st *StateTransition) handleFsnCall() error {
st.state.SubBalance(st.msg.From(), sendAssetParam.AssetID, sendAssetParam.Value)
st.state.AddBalance(sendAssetParam.To, sendAssetParam.AssetID, sendAssetParam.Value)
return nil
case common.TimeLockFunc:
timeLockParam := common.TimeLockParam{}
rlp.DecodeBytes(param.Data, &timeLockParam)
if timeLockParam.Type == common.AssetToTimeLock {
timeLockParam.StartTime = common.TimeLockNow
timeLockParam.EndTime = common.TimeLockForever
}
needValue := common.NewTimeLock(common.TimeLockItem{
StartTime: timeLockParam.StartTime,
EndTime: timeLockParam.EndTime,
Value: timeLockParam.Value,
})
switch timeLockParam.Type {
case common.AssetToTimeLock:
if st.state.GetBalance(timeLockParam.AssetID, st.msg.From()).Cmp(timeLockParam.Value) < 0 {
return fmt.Errorf("not enough asset")
}
st.state.SubBalance(st.msg.From(), timeLockParam.AssetID, timeLockParam.Value)
totalValue := common.NewTimeLock(common.TimeLockItem{
StartTime: common.TimeLockNow,
EndTime: common.TimeLockForever,
Value: timeLockParam.Value,
})
st.state.AddTimeLockBalance(st.msg.From(), timeLockParam.AssetID, new(common.TimeLock).Sub(totalValue, needValue))
st.state.AddTimeLockBalance(timeLockParam.To, timeLockParam.AssetID, needValue)
return nil
case common.TimeLockToTimeLock:
case common.TimeLockToAsset:
if st.state.GetTimeLockBalance(timeLockParam.AssetID, st.msg.From()).Cmp(needValue) < 0 {
return fmt.Errorf("not enough time lock balance")
}
st.state.SubTimeLockBalance(st.msg.From(), timeLockParam.AssetID, needValue)
if timeLockParam.Type == common.TimeLockToTimeLock {
st.state.AddTimeLockBalance(timeLockParam.To, timeLockParam.AssetID, needValue)
} else {
st.state.AddBalance(timeLockParam.To, timeLockParam.AssetID, timeLockParam.Value)
}
return nil
}
return nil
}
return fmt.Errorf("Unsupport")
}
3 changes: 3 additions & 0 deletions core/vm/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,9 @@ type StateDB interface {
SubBalance(common.Address, common.Hash, *big.Int)
AddBalance(common.Address, common.Hash, *big.Int)
GetBalance(common.Hash, common.Address) *big.Int
SubTimeLockBalance(common.Address, common.Hash, *common.TimeLock)
AddTimeLockBalance(common.Address, common.Hash, *common.TimeLock)
GetTimeLockBalance(common.Hash, common.Address) *common.TimeLock
GetNonce(common.Address) uint64
SetNonce(common.Address, uint64)

Expand Down
145 changes: 144 additions & 1 deletion internal/ethapi/api_fsn.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ type SendAssetArgs struct {
Value *hexutil.Big `json:"value"`
}

// TimeLockArgs wacom
type TimeLockArgs struct {
SendAssetArgs
StartTime uint64 `json:"start"`
EndTime uint64 `json:"end"`
}

func (args *FusionBaseArgs) toSendArgs() SendTxArgs {
return SendTxArgs{
From: args.From,
Expand All @@ -54,6 +61,18 @@ func (args *SendAssetArgs) toData() ([]byte, error) {
return param.ToBytes()
}

func (args *TimeLockArgs) toData(typ common.TimeLockType) ([]byte, error) {
param := common.TimeLockParam{
Type: typ,
AssetID: args.AssetID,
To: args.To,
StartTime: args.StartTime,
EndTime: args.EndTime,
Value: args.Value.ToInt(),
}
return param.ToBytes()
}

func (args *GenAssetArgs) toData() ([]byte, error) {
param := common.GenAssetParam{
Name: args.Name,
Expand Down Expand Up @@ -86,6 +105,36 @@ func (s *PublicFusionAPI) GetBalance(ctx context.Context, assetID common.Hash, a
return b, state.Error()
}

// GetAllBalances wacom
func (s *PublicFusionAPI) GetAllBalances(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (map[common.Hash]*big.Int, error) {
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
if state == nil || err != nil {
return make(map[common.Hash]*big.Int), err
}
b := state.GetAllBalances(address)
return b, state.Error()
}

// GetTimeLockBalance wacom
func (s *PublicFusionAPI) GetTimeLockBalance(ctx context.Context, assetID common.Hash, address common.Address, blockNr rpc.BlockNumber) (*common.TimeLock, error) {
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
if state == nil || err != nil {
return new(common.TimeLock), err
}
b := state.GetTimeLockBalance(assetID, address)
return b, state.Error()
}

// GetAllTimeLockBalances wacom
func (s *PublicFusionAPI) GetAllTimeLockBalances(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (map[common.Hash]*common.TimeLock, error) {
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
if state == nil || err != nil {
return make(map[common.Hash]*common.TimeLock), err
}
b := state.GetAllTimeLockBalances(address)
return b, state.Error()
}

// GetNotation wacom
func (s *PublicFusionAPI) GetNotation(ctx context.Context, address common.Address, blockNr rpc.BlockNumber) (uint64, error) {
state, _, err := s.b.StateAndHeaderByNumber(ctx, blockNr)
Expand Down Expand Up @@ -214,7 +263,101 @@ func (s *PrivateFusionAPI) SendAsset(ctx context.Context, args SendAssetArgs, pa
if err != nil {
return common.Hash{}, err
}
var param = common.FSNCallParam{Func: common.SendAsset, Data: funcData}
var param = common.FSNCallParam{Func: common.SendAssetFunc, Data: funcData}
data, err := param.ToBytes()
if err != nil {
return common.Hash{}, err
}
var argsData = hexutil.Bytes(data)
sendArgs := args.toSendArgs()
sendArgs.To = &common.FSNCallAddress
sendArgs.Data = &argsData
return s.papi.SendTransaction(ctx, sendArgs, passwd)
}

// AssetToTimeLock ss
func (s *PrivateFusionAPI) AssetToTimeLock(ctx context.Context, args TimeLockArgs, passwd string) (common.Hash, error) {

state, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
if state == nil || err != nil {
return common.Hash{}, err
}

if state.GetBalance(args.AssetID, args.From).Cmp(args.Value.ToInt()) < 0 {
return common.Hash{}, fmt.Errorf("not enough asset")
}

funcData, err := args.toData(common.AssetToTimeLock)
if err != nil {
return common.Hash{}, err
}
var param = common.FSNCallParam{Func: common.TimeLockFunc, Data: funcData}
data, err := param.ToBytes()
if err != nil {
return common.Hash{}, err
}
var argsData = hexutil.Bytes(data)
sendArgs := args.toSendArgs()
sendArgs.To = &common.FSNCallAddress
sendArgs.Data = &argsData
return s.papi.SendTransaction(ctx, sendArgs, passwd)
}

// TimeLockToTimeLock ss
func (s *PrivateFusionAPI) TimeLockToTimeLock(ctx context.Context, args TimeLockArgs, passwd string) (common.Hash, error) {

state, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
if state == nil || err != nil {
return common.Hash{}, err
}

needValue := common.NewTimeLock(common.TimeLockItem{
StartTime: args.StartTime,
EndTime: args.EndTime,
Value: args.Value.ToInt(),
})

if state.GetTimeLockBalance(args.AssetID, args.From).Cmp(needValue) < 0 {
return common.Hash{}, fmt.Errorf("not enough time lock balance")
}

funcData, err := args.toData(common.TimeLockToTimeLock)
if err != nil {
return common.Hash{}, err
}
var param = common.FSNCallParam{Func: common.TimeLockFunc, Data: funcData}
data, err := param.ToBytes()
if err != nil {
return common.Hash{}, err
}
var argsData = hexutil.Bytes(data)
sendArgs := args.toSendArgs()
sendArgs.To = &common.FSNCallAddress
sendArgs.Data = &argsData
return s.papi.SendTransaction(ctx, sendArgs, passwd)
}

// TimeLockToAsset ss
func (s *PrivateFusionAPI) TimeLockToAsset(ctx context.Context, args TimeLockArgs, passwd string) (common.Hash, error) {
state, _, err := s.b.StateAndHeaderByNumber(ctx, rpc.LatestBlockNumber)
if state == nil || err != nil {
return common.Hash{}, err
}
args.StartTime = common.TimeLockNow
args.EndTime = common.TimeLockForever
needValue := common.NewTimeLock(common.TimeLockItem{
StartTime: args.StartTime,
EndTime: args.EndTime,
Value: args.Value.ToInt(),
})
if state.GetTimeLockBalance(args.AssetID, args.From).Cmp(needValue) < 0 {
return common.Hash{}, fmt.Errorf("not enough time lock balance")
}
funcData, err := args.toData(common.TimeLockToAsset)
if err != nil {
return common.Hash{}, err
}
var param = common.FSNCallParam{Func: common.TimeLockFunc, Data: funcData}
data, err := param.ToBytes()
if err != nil {
return common.Hash{}, err
Expand Down
Loading

0 comments on commit 7a0bb98

Please sign in to comment.