Skip to content

Commit

Permalink
Merge pull request #2204 from leszko/2203-support-l1-l2-contracts
Browse files Browse the repository at this point in the history
Support both L1 and L2 contract interfaces
  • Loading branch information
yondonfu committed Jan 24, 2022
2 parents f033ae0 + a12606c commit fcaa4da
Show file tree
Hide file tree
Showing 7 changed files with 3,679 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG_PENDING.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#### General
- \#2180 Generate contract bindings related to L2 Arbitrum upgrade (@leszko)
- \#2204 Support both L1 and L2 contract interfaces (@leszko)
- \#2202 Add `rinkeby-one-rinkeby` network (@leszko)

#### Broadcaster
Expand Down
22 changes: 22 additions & 0 deletions eth/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ type LivepeerEthClient interface {
Unbond(amount *big.Int) (*types.Transaction, error)
WithdrawStake(unbondingLockID *big.Int) (*types.Transaction, error)
WithdrawFees(addr ethcommon.Address, amount *big.Int) (*types.Transaction, error)
// for L1 contracts backwards-compatibility
L1WithdrawFees() (*types.Transaction, error)
ClaimEarnings(endRound *big.Int) (*types.Transaction, error)
GetTranscoder(addr ethcommon.Address) (*lpTypes.Transcoder, error)
GetDelegator(addr ethcommon.Address) (*lpTypes.Delegator, error)
Expand Down Expand Up @@ -141,6 +143,9 @@ type client struct {
*contracts.MinterSession
*contracts.LivepeerTokenFaucetSession

// for L1 contracts backwards-compatibility
l1BondingManagerSession *contracts.L1BondingManagerSession

gasLimit uint64
gasPrice *big.Int

Expand Down Expand Up @@ -243,6 +248,18 @@ func (c *client) setContracts(opts *bind.TransactOpts) error {
TransactOpts: *opts,
}

// for L1 contracts backwards-compatibility
l1BondingManager, err := contracts.NewL1BondingManager(bondingManagerAddr, c.backend)
if err != nil {
glog.Errorf("Error creating L1BondingManager binding: %v", err)
return err
}

c.l1BondingManagerSession = &contracts.L1BondingManagerSession{
Contract: l1BondingManager,
TransactOpts: *opts,
}

glog.V(common.SHORT).Infof("BondingManager: %v", c.bondingManagerAddr.Hex())

brokerAddr, err := c.GetContract(crypto.Keccak256Hash([]byte("TicketBroker")))
Expand Down Expand Up @@ -802,6 +819,11 @@ func (c *client) Reward() (*types.Transaction, error) {
return c.RewardWithHint(hints.PosPrev, hints.PosNext)
}

// for L1 contracts backwards-compatibility
func (c *client) L1WithdrawFees() (*types.Transaction, error) {
return c.l1BondingManagerSession.WithdrawFees()
}

// Helpers

// simulateTranscoderPoolUpdate simulates an update to the transcoder pool and returns the positional hints for a transcoder accordingly.
Expand Down
3,544 changes: 3,544 additions & 0 deletions eth/contracts/l1BondingManager.go

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions eth/stubclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,12 @@ func (m *MockClient) WithdrawFees(addr ethcommon.Address, amount *big.Int) (*typ
return mockTransaction(args, 0), args.Error(1)
}

// for L1 contracts backwards-compatibility
func (m *MockClient) L1WithdrawFees() (*types.Transaction, error) {
args := m.Called()
return mockTransaction(args, 0), args.Error(1)
}

func (m *MockClient) Senders(addr common.Address) (sender struct {
Deposit *big.Int
WithdrawRound *big.Int
Expand Down Expand Up @@ -287,6 +293,11 @@ func (e *StubClient) WithdrawStake(*big.Int) (*types.Transaction, error) {
func (e *StubClient) WithdrawFees(addr ethcommon.Address, amount *big.Int) (*types.Transaction, error) {
return nil, nil
}

// for L1 contracts backwards-compatibility
func (e *StubClient) L1WithdrawFees() (*types.Transaction, error) {
return nil, nil
}
func (e *StubClient) ClaimEarnings(endRound *big.Int) (*types.Transaction, error) {
return nil, nil
}
Expand Down
40 changes: 33 additions & 7 deletions server/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"net/http"

ethcommon "github.com/ethereum/go-ethereum/common"
ethtypes "github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/signer/core/apitypes"
"github.com/golang/glog"
"github.com/livepeer/go-livepeer/common"
Expand All @@ -15,6 +16,9 @@ import (
"github.com/livepeer/go-livepeer/pm"
)

const MainnetChainId = 1
const RinkebyChainId = 4

func respondOk(w http.ResponseWriter, msg []byte) {
w.WriteHeader(http.StatusOK)
if msg != nil {
Expand Down Expand Up @@ -366,18 +370,40 @@ func voteHandler(client eth.LivepeerEthClient) http.Handler {
)
}

func withdrawFeesHandler(client eth.LivepeerEthClient) http.Handler {
func withdrawFeesHandler(client eth.LivepeerEthClient, getChainId func() (int64, error)) http.Handler {
return mustHaveClient(client, http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
amount, err := common.ParseBigInt(r.FormValue("amount"))
// for L1 contracts backwards-compatibility
var tx *ethtypes.Transaction
chainId, err := getChainId()
if err != nil {
respondWith400(w, fmt.Sprintf("invalid amount: %v", err))
respondWith500(w, err.Error())
return
}
if chainId == MainnetChainId || chainId == RinkebyChainId {
// L1 contracts
tx, err = client.L1WithdrawFees()
if err != nil {
respondWith500(w, fmt.Sprintf("could not execute WithdrawFees: %v", err))
return
}
} else {
// L2 contracts
amountStr := r.FormValue("amount")
if amountStr == "" {
respondWith400(w, "missing form param: amount")
return
}
amount, err := common.ParseBigInt(amountStr)
if err != nil {
respondWith400(w, fmt.Sprintf("invalid amount: %v", err))
return
}

tx, err := client.WithdrawFees(client.Account().Address, amount)
if err != nil {
respondWith500(w, fmt.Sprintf("could not execute WithdrawFees: %v", err))
return
tx, err = client.WithdrawFees(client.Account().Address, amount)
if err != nil {
respondWith500(w, fmt.Sprintf("could not execute WithdrawFees: %v", err))
return
}
}

err = client.CheckTx(tx)
Expand Down
60 changes: 55 additions & 5 deletions server/handlers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -893,7 +893,7 @@ func TestVoteHandler(t *testing.T) {
}

func TestWithdrawFeesHandler_MissingClient(t *testing.T) {
handler := withdrawFeesHandler(nil)
handler := withdrawFeesHandler(nil, stubChainIdProvider)

resp := httpPostFormResp(handler, nil)
body, _ := ioutil.ReadAll(resp.Body)
Expand All @@ -905,7 +905,7 @@ func TestWithdrawFeesHandler_MissingClient(t *testing.T) {

func TestWithdrawFeesHandler_InvalidAmount(t *testing.T) {
client := &eth.MockClient{}
handler := withdrawFeesHandler(client)
handler := withdrawFeesHandler(client, stubChainIdProvider)

form := url.Values{
"amount": {"foo"},
Expand All @@ -920,7 +920,7 @@ func TestWithdrawFeesHandler_InvalidAmount(t *testing.T) {

func TestWithdrawFeesHandler_TransactionSubmissionError(t *testing.T) {
client := &eth.MockClient{}
handler := withdrawFeesHandler(client)
handler := withdrawFeesHandler(client, stubChainIdProvider)

addr := ethcommon.Address{}
client.On("Account").Return(accounts.Account{Address: addr})
Expand All @@ -939,7 +939,7 @@ func TestWithdrawFeesHandler_TransactionSubmissionError(t *testing.T) {

func TestWithdrawFeesHandler_TransactionWaitError(t *testing.T) {
client := &eth.MockClient{}
handler := withdrawFeesHandler(client)
handler := withdrawFeesHandler(client, stubChainIdProvider)

addr := ethcommon.Address{}
client.On("Account").Return(accounts.Account{Address: addr})
Expand All @@ -959,7 +959,7 @@ func TestWithdrawFeesHandler_TransactionWaitError(t *testing.T) {

func TestWithdrawFeesHandler_Success(t *testing.T) {
client := &eth.MockClient{}
handler := withdrawFeesHandler(client)
handler := withdrawFeesHandler(client, stubChainIdProvider)

addr := ethcommon.Address{}
client.On("Account").Return(accounts.Account{Address: addr})
Expand All @@ -975,6 +975,56 @@ func TestWithdrawFeesHandler_Success(t *testing.T) {
assert.Equal(http.StatusOK, resp.StatusCode)
}

func stubChainIdProvider() (int64, error) {
return 12345, nil
}

func TestL1WithdrawFeesHandler_TransactionSubmissionError(t *testing.T) {
client := &eth.MockClient{}
handler := withdrawFeesHandler(client, stubL1ChainIdProvider)

client.On("L1WithdrawFees").Return(nil, errors.New("WithdrawFees error"))

resp := httpPostFormResp(handler, nil)
body, _ := ioutil.ReadAll(resp.Body)

assert := assert.New(t)
assert.Equal(http.StatusInternalServerError, resp.StatusCode)
assert.Equal("could not execute WithdrawFees: WithdrawFees error", strings.TrimSpace(string(body)))
}

func TestL1WithdrawFeesHandler_TransactionWaitError(t *testing.T) {
client := &eth.MockClient{}
handler := withdrawFeesHandler(client, stubL1ChainIdProvider)

client.On("L1WithdrawFees").Return(nil, nil)
client.On("CheckTx").Return(errors.New("CheckTx error"))

resp := httpPostFormResp(handler, nil)
body, _ := ioutil.ReadAll(resp.Body)

assert := assert.New(t)
assert.Equal(http.StatusInternalServerError, resp.StatusCode)
assert.Equal("could not execute WithdrawFees: CheckTx error", strings.TrimSpace(string(body)))
}

func TestL1WithdrawFeesHandler_Success(t *testing.T) {
client := &eth.MockClient{}
handler := withdrawFeesHandler(client, stubL1ChainIdProvider)

client.On("L1WithdrawFees").Return(nil, nil)
client.On("CheckTx", mock.Anything).Return(nil)

resp := httpPostFormResp(handler, nil)

assert := assert.New(t)
assert.Equal(http.StatusOK, resp.StatusCode)
}

func stubL1ChainIdProvider() (int64, error) {
return 1, nil
}

func httpPostFormResp(handler http.Handler, body io.Reader) *http.Response {
headers := map[string]string{
"Content-Type": "application/x-www-form-urlencoded",
Expand Down
14 changes: 13 additions & 1 deletion server/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -675,9 +675,21 @@ func (s *LivepeerServer) cliWebServerHandlers(bindAddr string) *http.ServeMux {
}
})

mux.Handle("/withdrawFees", mustHaveFormParams(withdrawFeesHandler(s.LivepeerNode.Eth), "amount"))
// for L1 contracts backwards-compatibility
getChainId := func() (int64, error) {
if s.LivepeerNode.Database == nil {
return 0, errors.New("missing Livepeer database")
}
chainId, err := s.LivepeerNode.Database.ChainID()
if err != nil {
return 0, errors.New("Error getting eth network ID")
}
return chainId.Int64(), nil
}
mux.Handle("/withdrawFees", withdrawFeesHandler(s.LivepeerNode.Eth, getChainId))

mux.HandleFunc("/claimEarnings", func(w http.ResponseWriter, r *http.Request) {
s.LivepeerNode.Database.ChainID()
if s.LivepeerNode.Eth != nil {
claim := func() error {
init, err := s.LivepeerNode.Eth.CurrentRoundInitialized()
Expand Down

0 comments on commit fcaa4da

Please sign in to comment.