-
Notifications
You must be signed in to change notification settings - Fork 56
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9f62073
commit 443677d
Showing
4 changed files
with
325 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package solver | ||
|
||
import "context" | ||
|
||
func (r *reactor) accept(ctx context.Context, chainID uint64, reqID reqID) error { | ||
// TODO(corver): submit accept tx | ||
|
||
return nil | ||
} | ||
|
||
func (r *reactor) reject(ctx context.Context, chainID uint64, reqID reqID, reason string) error { | ||
// TODO(corver): submit reject tx | ||
|
||
return nil | ||
} | ||
|
||
func (r *reactor) submit(ctx context.Context, chainID uint64, reqID reqID) error { | ||
// TODO(corver): submit submit tx | ||
|
||
return nil | ||
} | ||
|
||
func (r *reactor) claim(ctx context.Context, chainID uint64, reqID reqID) error { | ||
// TODO(corver): submit claim tx | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package solver | ||
|
||
import ( | ||
"github.com/ethereum/go-ethereum/common" | ||
"math/big" | ||
) | ||
|
||
type BindingsCall struct { | ||
DestChainId uint64 | ||
Value *big.Int | ||
Address common.Address | ||
Data []byte | ||
} | ||
|
||
type BindingsDeposit struct { | ||
Amount *big.Int | ||
Token common.Address | ||
IsNative bool | ||
} | ||
|
||
type BindingsEventRequested struct { | ||
ID reqID | ||
From common.Address | ||
Call BindingsCall | ||
Deposits []BindingsDeposit | ||
|
||
Height uint64 | ||
} | ||
|
||
type BindingsEventAccepted struct { | ||
ID reqID | ||
By common.Address | ||
} | ||
|
||
type BindingsEventRejected struct { | ||
ID reqID | ||
By common.Address | ||
} | ||
|
||
type BindingsEventReverted struct { | ||
ID reqID | ||
} | ||
|
||
type BindingsEventFulfilled struct { | ||
ID reqID | ||
} | ||
|
||
type BindingsEventClaimed struct { | ||
ID reqID | ||
} | ||
|
||
var ( | ||
BindingsEventRequestedTopic common.Hash | ||
BindingsEventAcceptedTopic common.Hash | ||
BindingsEventRejectedTopic common.Hash | ||
BindingsEventRevertedTopic common.Hash | ||
BindingsEventFulfilledTopic common.Hash | ||
BindingsEventClaimedTopic common.Hash | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package solver | ||
|
||
import ( | ||
"context" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
) | ||
|
||
func parseRequestedEvent(log types.Log) (reqID, eventVisitor, error) { | ||
var e BindingsEventRequested | ||
// TODO(corver): use bindings to parse log into bindings type. | ||
|
||
// Requested triggers logic to either accepted or rejected | ||
visistor := func(ctx context.Context, f *reactor, chainID uint64) (action, error) { | ||
return f.ProcessRequested(ctx, chainID, e) | ||
} | ||
|
||
return e.ID, visistor, nil | ||
} | ||
|
||
func parseAcceptedEvent(log types.Log) (reqID, eventVisitor, error) { | ||
var e BindingsEventAccepted | ||
// TODO(corver): use bindings to parse log into bindings type. | ||
|
||
// Accepted directly maps to submit. | ||
visistor := func(context.Context, *reactor, uint64) (action, error) { | ||
return action{ | ||
Type: actionTypeSubmit, | ||
}, nil | ||
} | ||
|
||
return e.ID, visistor, nil | ||
} | ||
|
||
func parseRejectedEvent(log types.Log) (reqID, eventVisitor, error) { | ||
var e BindingsEventRejected | ||
// TODO(corver): use bindings to parse log into bindings type. | ||
|
||
// Rejected triggers no transition. | ||
visistor := func(context.Context, *reactor, uint64) (action, error) { | ||
return action{ | ||
Type: actionTypeNone, | ||
}, nil | ||
} | ||
|
||
return e.ID, visistor, nil | ||
} | ||
|
||
func parseRevertedEvent(log types.Log) (reqID, eventVisitor, error) { | ||
var e BindingsEventReverted | ||
// TODO(corver): use bindings to parse log into bindings type. | ||
|
||
// Reverted triggers no transition. | ||
visistor := func(context.Context, *reactor, uint64) (action, error) { | ||
return action{ | ||
Type: actionTypeNone, | ||
}, nil | ||
} | ||
|
||
return e.ID, visistor, nil | ||
} | ||
|
||
func parseFulfilledEvent(log types.Log) (reqID, eventVisitor, error) { | ||
var e BindingsEventFulfilled | ||
// TODO(corver): use bindings to parse log into bindings type. | ||
|
||
// Fulfilled triggers claim action directly. | ||
visistor := func(context.Context, *reactor, uint64) (action, error) { | ||
return action{ | ||
Type: actionTypeClaim, | ||
}, nil | ||
} | ||
|
||
return e.ID, visistor, nil | ||
} | ||
|
||
func parseClaimedEvent(log types.Log) (reqID, eventVisitor, error) { | ||
var e BindingsEventClaimed | ||
// TODO(corver): use bindings to parse log into bindings type. | ||
|
||
// Claimed triggers no transition. | ||
visistor := func(context.Context, *reactor, uint64) (action, error) { | ||
return action{ | ||
Type: actionTypeNone, | ||
}, nil | ||
} | ||
|
||
return e.ID, visistor, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
package solver | ||
|
||
import ( | ||
"context" | ||
"github.com/ethereum/go-ethereum/common" | ||
"github.com/ethereum/go-ethereum/core/types" | ||
"github.com/omni-network/omni/lib/errors" | ||
"github.com/omni-network/omni/lib/log" | ||
"sync" | ||
) | ||
|
||
type reqID common.Hash | ||
|
||
type eventVisitor func(ctx context.Context, r *reactor, chainID uint64) (action, error) | ||
|
||
type action struct { | ||
Type actionType | ||
RejectReason string | ||
} | ||
|
||
type actionType int32 | ||
type eventType int32 | ||
|
||
const ( | ||
actionTypeNone actionType = 0 | ||
actionTypeAccept actionType = 1 | ||
actionTypeReject actionType = 2 | ||
actionTypeSubmit actionType = 3 | ||
actionTypeClaim actionType = 4 | ||
|
||
eventTypeRequested eventType = 1 | ||
eventTypeReverted eventType = 2 | ||
eventTypeAccepted eventType = 3 | ||
eventTypeRejected eventType = 4 | ||
eventTypeSubmitted eventType = 5 | ||
eventTypeFulfilled eventType = 6 | ||
eventTypeClaimed eventType = 7 | ||
) | ||
|
||
type event struct { | ||
Type eventType | ||
Parse func(log types.Log) (reqID, eventVisitor, error) | ||
} | ||
|
||
var eventsByTopic = map[common.Hash]event{ | ||
BindingsEventRequestedTopic: { | ||
Type: eventTypeRequested, | ||
Parse: parseRequestedEvent, | ||
}, | ||
BindingsEventAcceptedTopic: { | ||
Type: eventTypeAccepted, | ||
Parse: parseAcceptedEvent, | ||
}, | ||
BindingsEventRejectedTopic: { | ||
Type: eventTypeRejected, | ||
Parse: parseRejectedEvent, | ||
}, | ||
BindingsEventRevertedTopic: { | ||
Type: eventTypeReverted, | ||
Parse: parseRevertedEvent, | ||
}, | ||
BindingsEventFulfilledTopic: { | ||
Type: eventTypeFulfilled, | ||
Parse: parseFulfilledEvent, | ||
}, | ||
BindingsEventClaimedTopic: { | ||
Type: eventTypeClaimed, | ||
Parse: parseClaimedEvent, | ||
}, | ||
} | ||
|
||
type reactor struct { | ||
mu sync.Mutex | ||
} | ||
|
||
// ProcessEvents is the callback provided to xchain.Provider::StreamEventLogs filtering all inbox contract events. | ||
func (r *reactor) ProcessEvents(ctx context.Context, chainID uint64, _ uint64, elogs []types.Log) error { | ||
for _, elog := range elogs { | ||
event, ok := eventsByTopic[elog.Topics[0]] | ||
if !ok { | ||
return errors.New("unknown event [BUG]") | ||
} | ||
|
||
reqID, visit, err := event.Parse(elog) | ||
if err != nil { | ||
return errors.Wrap(err, "parse event") | ||
} | ||
|
||
ctx := log.WithCtx(ctx, "req_id", reqID) | ||
|
||
current, _, err := r.getCurrentStatus(ctx, chainID, reqID) | ||
if err != nil { | ||
return errors.Wrap(err, "current status") | ||
} else if event.Type != current { | ||
log.Warn(ctx, "Ignoring mismatching old event", nil, "actual", current, "event", event.Type) | ||
continue | ||
} | ||
|
||
act, err := visit(ctx, r, chainID) | ||
if err != nil { | ||
return errors.Wrap(err, "visit") | ||
} | ||
|
||
switch act.Type { | ||
case actionTypeAccept: | ||
if err := r.accept(ctx, chainID, reqID); err != nil { | ||
return errors.Wrap(err, "accept") | ||
} | ||
case actionTypeReject: | ||
if err := r.reject(ctx, chainID, reqID, act.RejectReason); err != nil { | ||
return errors.Wrap(err, "reject") | ||
} | ||
case actionTypeSubmit: | ||
if err := r.submit(ctx, chainID, reqID); err != nil { | ||
return errors.Wrap(err, "submit") | ||
} | ||
case actionTypeClaim: | ||
if err := r.claim(ctx, chainID, reqID); err != nil { | ||
return errors.Wrap(err, "claim") | ||
} | ||
} | ||
} | ||
|
||
return nil | ||
|
||
} | ||
|
||
// ProcessRequested return either a reject or accept action for the provided requested event. | ||
func (r *reactor) ProcessRequested(ctx context.Context, chainID uint64, requestedEvent BindingsEventRequested) (action, error) { | ||
if reason, reject, err := r.shouldReject(ctx, chainID, requestedEvent); err != nil { | ||
return action{}, err | ||
} else if reject { | ||
return action{ | ||
Type: actionTypeReject, | ||
RejectReason: reason, | ||
}, nil | ||
} | ||
|
||
return action{ | ||
Type: actionTypeAccept, | ||
}, nil | ||
} | ||
|
||
// shouldReject returns a reject reason or false or an error. | ||
func (r *reactor) shouldReject(ctx context.Context, chainID uint64, requestedEvent BindingsEventRequested) (string, bool, error) { | ||
return "", false, nil | ||
} | ||
|
||
func (r *reactor) getCurrentStatus(ctx context.Context, chainID uint64, id reqID) (eventType, bool, error) { | ||
return 0, true, nil | ||
} |