Skip to content

Commit

Permalink
feat: added shanghai contract
Browse files Browse the repository at this point in the history
  • Loading branch information
freemanzMrojo committed Jan 17, 2025
1 parent 8e1e907 commit 7a32234
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 1 deletion.
71 changes: 71 additions & 0 deletions environments/local/local_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@ package local
import (
"encoding/json"
"fmt"
"math"
"strings"
"testing"
"time"

"github.com/ethereum/go-ethereum/common/hexutil"
"github.com/ethereum/go-ethereum/crypto"
"github.com/stretchr/testify/require"
"github.com/vechain/networkhub/network"
"github.com/vechain/networkhub/preset"
"github.com/vechain/networkhub/utils/client"
"github.com/vechain/networkhub/utils/common"
"github.com/vechain/networkhub/utils/datagen"
"github.com/vechain/thor/v2/thor"
"github.com/vechain/thor/v2/tx"
)

var genesis = `{
Expand Down Expand Up @@ -254,6 +260,7 @@ func TestFourNodesGalactica(t *testing.T) {
timeout := time.After(1 * time.Minute)
tick := time.Tick(5 * time.Second)

clients := make([]*client.Client, 0)
outer:
for {
select {
Expand All @@ -264,8 +271,72 @@ outer:
c := client.NewClient("http://" + node.GetAPIAddr())
peers, err := c.GetPeers()
require.True(t, err == nil && len(peers) == 3)
clients = append(clients, c)
}
break outer
}
}

deployAndAssertShanghaiContract(t, clients[0], preset.Account1)
}

// https://github.com/vechain/thor-e2e-tests/blob/main/contracts/shanghai/SimpleCounterShanghai.sol
const shanghaiContractBytecode = "0x608060405234801561000f575f80fd5b505f805561016e806100205f395ff3fe608060405234801561000f575f80fd5b506004361061003f575f3560e01c80635b34b966146100435780638ada066e1461004d5780638bb5d9c314610061575b5f80fd5b61004b610074565b005b5f5460405190815260200160405180910390f35b61004b61006f3660046100fd565b6100c3565b5f8054908061008283610114565b91905055507f3cf8b50771c17d723f2cb711ca7dadde485b222e13c84ba0730a14093fad6d5c5f546040516100b991815260200190565b60405180910390a1565b5f8190556040518181527f3cf8b50771c17d723f2cb711ca7dadde485b222e13c84ba0730a14093fad6d5c9060200160405180910390a150565b5f6020828403121561010d575f80fd5b5035919050565b5f6001820161013157634e487b7160e01b5f52601160045260245ffd5b506001019056fea2646970667358221220aa73e6082b52bca8243902c639e5386b481c2183e8400f34731c4edb93d87f6764736f6c63430008180033"

func DecodedShanghaiContract() []byte {
contractBytecode, err := hexutil.Decode(shanghaiContractBytecode)
if err != nil {
panic(err)
}
return contractBytecode
}

func deployAndAssertShanghaiContract(t *testing.T, client *client.Client, acc *common.Account) {
tag, err := client.ChainTag()
require.NoError(t, err)

// Combine the bytecode and constructor data
contractData := DecodedShanghaiContract()

deployContractTx := new(tx.Builder).
ChainTag(tag).
Expiration(math.MaxUint32).
Gas(10_000_000).
GasPriceCoef(128).
BlockRef(tx.NewBlockRef(0)).
Nonce(datagen.RandUInt64()).
Clause(
tx.NewClause(nil).WithData(contractData),
).Build()

depContractInspectResults, err := client.InspectTxClauses(deployContractTx, acc.Address)
require.NoError(t, err)
for _, respClause := range depContractInspectResults {
require.False(t, respClause.Reverted || respClause.VMError != "")
}

// Send a transaction
signedTxHash, err := crypto.Sign(deployContractTx.SigningHash().Bytes(), acc.PrivateKey)
require.NoError(t, err)
issuedTx, err := client.SendTransaction(deployContractTx.WithSignature(signedTxHash))
require.NoError(t, err)

// Retrieve transaction receipt - GET /transactions/{id}/receipt
var contractAddr *thor.Address
err = common.Retry(func() error {
receipt, err := client.GetTransactionReceipt(issuedTx.ID)
if err != nil {
return fmt.Errorf("unable to retrieve tx receipt - %w", err)
}

if receipt.Reverted {
return fmt.Errorf("transaction was reverted - %+v", receipt)
}

contractAddr = receipt.Outputs[0].ContractAddress
return nil
}, 3*time.Second, 5)

require.NoError(t, err)
require.NotNil(t, contractAddr)
}
6 changes: 5 additions & 1 deletion utils/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type Client struct {
}

func NewClient(url string) *Client {
// todo, depending on the url return a http or a ws client
// TODO: depending on the url return a http or a ws client
return &Client{
conn: http.NewClient(url),
}
Expand Down Expand Up @@ -104,6 +104,10 @@ func (c *Client) GetPeers() ([]*node.PeerStats, error) {
return c.conn.GetPeers()
}

func (c *Client) ChainTag() (byte, error) {
return c.conn.ChainTag()
}

func convertToBatchCallData(tx *tx.Transaction, addr *thor.Address) *accounts.BatchCallData {
cls := make(accounts.Clauses, len(tx.Clauses()))
for i, c := range tx.Clauses() {
Expand Down
8 changes: 8 additions & 0 deletions utils/client/http/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,3 +190,11 @@ func (c *Client) GetPeers() ([]*node.PeerStats, error) {

return peers, nil
}

func (c *Client) ChainTag() (byte, error) {
blockSummary, err := c.GetBlock("0")
if err != nil {
return 0, err
}
return blockSummary.ID[31], nil
}
15 changes: 15 additions & 0 deletions utils/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package common
import (
"crypto/ecdsa"
"fmt"
"time"

"github.com/ethereum/go-ethereum/crypto"
"github.com/vechain/thor/v2/thor"
Expand All @@ -25,6 +26,20 @@ func NewAccount(pkString string) *Account {
}
}

// Retry retries the given function fn until it succeeds or the maximum number of retries is reached.
// It waits for retryPeriod between each retry.
func Retry(fn func() error, retryPeriod time.Duration, maxRetries int) error {
var err error
for i := 0; i < maxRetries; i++ {
err = fn()
if err == nil {
return nil
}
time.Sleep(retryPeriod)
}
return err
}

type Account struct {
Address *thor.Address
PrivateKey *ecdsa.PrivateKey
Expand Down

0 comments on commit 7a32234

Please sign in to comment.