Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions contracts/contracts/lib/access/ownable_2step.tolk
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import "./../utils.tolk";

// Exit codes

// TODO: follow namespaced exitcodes structure
/// Matches the exit code for `TactExitCodeAccessDenied` from `@stdlib`.
const ERROR_ONLY_CALLABLE_BY_OWNER = 132;

Expand Down
7 changes: 5 additions & 2 deletions contracts/contracts/lib/utils.tolk
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,11 @@ const BOUNCE_MSG_SIZE_MAX = 256;

/// Returns the global ID of the current blockchain (chain ID).
fun globalId(): int {
// Notice: configParam(19)! will be available (non-null)
return blockchain.configParam(19)!.beginParse().loadInt(32);
// Notice: configParam(19) should be available (TVM upgrade 04/24), but not set in mylocalton
val param = blockchain.configParam(19);
return param != null
? param!.beginParse().loadInt(32)
: -1; // default
}

/// Extracts the (potential) bounced body from the given slice (message body).
Expand Down
20 changes: 8 additions & 12 deletions contracts/contracts/mcms/mcms.tolk
Original file line number Diff line number Diff line change
Expand Up @@ -693,7 +693,7 @@ fun MCMS<T>.setRoot(
var _break = false;
var group = signer.group;
while (!_break) {
var votes = 1;
var votes: uint8 = 1;
{
var current = groupVoteCounts.get(group);
if (current.isFound) {
Expand Down Expand Up @@ -988,7 +988,7 @@ fun MCMS<T>.setConfig(
if (count.isFound) {
value = count.loadValue() + 1;
}
groupChildrenCounts.set(g, value);
groupChildrenCounts.set(g, value as uint8);
}

// second, we iterate backwards so as to check each group and propagate counts from
Expand All @@ -998,7 +998,7 @@ fun MCMS<T>.setConfig(
repeat(NUM_GROUPS) {
val i = NUM_GROUPS - 1 - j;
// ensure we have a well-formed group tree. the root should have itself as parent
var gp: int = 0; // default parent for root group
var gp: uint8 = 0; // default parent for root group
{
var value = groupParents.get(i);
if (value.isFound) {
Expand All @@ -1009,7 +1009,7 @@ fun MCMS<T>.setConfig(
throw MCMS_Error.GroupTreeNotWellFormed;
}

var gq = 0; // default quorum for groups without a set quorum
var gq: uint8 = 0; // default quorum for groups without a set quorum
{
var value = groupQuorums.get(i);
if (value.isFound) {
Expand Down Expand Up @@ -1039,7 +1039,7 @@ fun MCMS<T>.setConfig(
throw MCMS_Error.OutOfBoundsGroupQuorum;
}

var current = 0;
var current: uint8 = 0;
{
var value = groupChildrenCounts.get(gp);
if (value.isFound) {
Expand Down Expand Up @@ -1130,11 +1130,7 @@ fun MCMS<T>.setConfig(
bounce: false,
value: 0,
dest: sender,
body: MCMS_ConfigSet{
queryId: queryId,
config: Config.fromCell(self.data.config),
isRootCleared: clearRoot
}
body: MCMS_ConfigSet{ queryId, config, isRootCleared: clearRoot }
});
reply.send(SEND_MODE_REGULAR | SEND_MODE_CARRY_ALL_REMAINING_MESSAGE_VALUE);
}
Expand Down Expand Up @@ -1209,7 +1205,7 @@ fun MCMS<T>.submitErrorReport(
opLeafHash: hashedLeaf,
opTxHash,
errorTxHash,
errorCode: errorCode,
errorCode,
root,
matchesPendingOp,
}
Expand Down Expand Up @@ -1249,7 +1245,7 @@ fun MCMS<T>._execute(self, target: address, value: coins, data: cell): void {
// Send a message to the target with the provided value and data
val op = createMessage({
bounce: true,
value: value,
value,
dest: target,
body: data
});
Expand Down
2 changes: 1 addition & 1 deletion contracts/contracts/mcms/rbac_timelock.tolk
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,7 @@ fun Timelock<T>.execute(self, call: Timelock_Call): void {
dest: call.target,
body: call.data
});
op.send(SEND_MODE_PAY_FEES_SEPARATELY);
op.send(SEND_MODE_PAY_FEES_SEPARATELY | SEND_MODE_BOUNCE_ON_ACTION_FAIL);
}

/// Hook before execution of an operation's calls.
Expand Down
2 changes: 1 addition & 1 deletion contracts/tests/mcms/ManyChainMultiSigSetConfig.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,7 @@ describe('MCMS - ManyChainMultiSigSetConfigTest', () => {

// Verify root metadata shows override flag
const rootMetadata = await baseTest.bind.mcms.getRootMetadata()
expect(rootMetadata.chainId).toBe(-239n) // TODO: blockchain global chain ID (will need to be signed int)
expect(rootMetadata.chainId).toBe(-239n) // Note: global chain ID (signed int)
expect(rootMetadata.multiSig).toEqualAddress(baseTest.bind.mcms.address)
expect(rootMetadata.overridePreviousRoot).toBe(true)

Expand Down
27 changes: 22 additions & 5 deletions pkg/bindings/mcms/mcms/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ type SetConfig struct {
// Query ID of the change request.
QueryID uint64 `tlb:"## 64"`

SignerKeys common.SnakeData[SignerKey] `tlb:"^"` // vec<uint256>
SignerGroups common.SnakeData[uint8] `tlb:"^"` // vec<uint8>
GroupQuorums *cell.Dictionary `tlb:"dict 8"` // map<uint8, uint8> (indexed, iterable backwards)
GroupParents *cell.Dictionary `tlb:"dict 8"` // map<uint8, uint8> (indexed, iterable backwards)
ClearRoot bool `tlb:"bool"`
SignerKeys common.SnakeData[SignerKey] `tlb:"^"` // vec<uint256>
SignerGroups common.SnakeData[SignerGroup] `tlb:"^"` // vec<uint8>
GroupQuorums *cell.Dictionary `tlb:"dict 8"` // map<uint8, uint8> (indexed, iterable backwards)
GroupParents *cell.Dictionary `tlb:"dict 8"` // map<uint8, uint8> (indexed, iterable backwards)
ClearRoot bool `tlb:"bool"`
}

// Submit an oracle error report, which marks the current root as invalid.
Expand Down Expand Up @@ -227,6 +227,23 @@ type SignerKey struct {
Value *big.Int `tlb:"## 256"` // The value of the struct
}

type SignerGroup struct {
Value uint8 `tlb:"## 8"` // The value of the struct
}

// Length of serialized signer structure in bytes.
const LenSignerBytes = (256 + 8 + 8) / 8

// Signer information
type Signer struct {
// The public key of the signer.
Key *big.Int `tlb:"## 256"`
// The index of the signer in data.config.signers
Index uint8 `tlb:"## 8"` // 0 <= index < MAX_NUM_SIGNERS
// 0 <= group < NUM_GROUPS. Each signer can only be in one group.
Group uint8 `tlb:"## 8"`
}

// Signing groups are arranged in a tree. Each group is an interior node and has its own quorum.
// Signers are the leaves of the tree. A signer/leaf node is successful iff it furnishes a valid
// signature. A group/interior node is successful iff a quorum of its children are successful.
Expand Down
8 changes: 4 additions & 4 deletions pkg/ccip/bindings/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ type TypeAndVersion struct {
Version string `tlb:"str"`
}

func (t *TypeAndVersion) FromResult(result *ton.ExecutionResult) error {
func (t *TypeAndVersion) UnmarshalResult(result *ton.ExecutionResult) error {
typ, err := result.Slice(0)
if err != nil {
return err
Expand Down Expand Up @@ -98,7 +98,7 @@ func (t *TypeAndVersion) FromResult(result *ton.ExecutionResult) error {
}

func (t *TypeAndVersion) FetchResult(ctx context.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, _ []interface{}) error {
return FetchResultHelper(ctx, client, block, contractAddr, VersionGetter, nil, t.FromResult)
return FetchResultHelper(ctx, client, block, contractAddr, VersionGetter, nil, t)
}

// Ownable2Step represents a two-step ownership structure, where an owner can set a pending owner.
Expand Down Expand Up @@ -486,7 +486,7 @@ func FetchResultHelper(
contractAddr *address.Address,
method string,
opts []interface{},
fromResult func(*ton.ExecutionResult) error,
v tvm.ResultUnmarshaler,
) error {
var result *ton.ExecutionResult
var err error
Expand All @@ -500,5 +500,5 @@ func FetchResultHelper(
return err
}

return fromResult(result)
return tvm.LoadFromResult(v, result)
}
12 changes: 6 additions & 6 deletions pkg/ccip/bindings/feequoter/fee_quoter.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ type DestChainConfig struct {
NetworkFeeUsdCents uint32 `tlb:"## 32"`
}

func (c *DestChainConfig) FromResult(result *ton.ExecutionResult) error {
func (c *DestChainConfig) UnmarshalResult(result *ton.ExecutionResult) error {
isEnabledInt, err := result.Int(0)
if err != nil {
return err
Expand Down Expand Up @@ -199,7 +199,7 @@ func (c *DestChainConfig) FromResult(result *ton.ExecutionResult) error {
}

func (c *DestChainConfig) FetchResult(ctx context.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, destChainSelector []interface{}) error {
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, ccipcommon.DestChainConfigGetter, destChainSelector, c.FromResult)
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, ccipcommon.DestChainConfigGetter, destChainSelector, c)
}

type TokenTransferFeeConfig struct {
Expand All @@ -217,7 +217,7 @@ type TimestampedPrice struct {
}

// TODO: we can't parse ton.ExecutionResult via tlb, implement as a tlb feature upstream
func (p *TimestampedPrice) FromResult(result *ton.ExecutionResult) error {
func (p *TimestampedPrice) UnmarshalResult(result *ton.ExecutionResult) error {
value, err := result.Int(0)
if err != nil {
return err
Expand All @@ -235,7 +235,7 @@ func (p *TimestampedPrice) FromResult(result *ton.ExecutionResult) error {
}

func (p *TimestampedPrice) FetchResult(ctx context.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, opts []interface{}) error {
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, tokenPriceGetter, opts, p.FromResult)
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, tokenPriceGetter, opts, p)
}

type TokenPriceUpdate struct {
Expand Down Expand Up @@ -301,7 +301,7 @@ type StaticConfig struct {
StalenessThreshold uint32
}

func (s *StaticConfig) FromResult(result *ton.ExecutionResult) error {
func (s *StaticConfig) UnmarshalResult(result *ton.ExecutionResult) error {
maxFeeJuelsPerMsg, err := result.Int(0)
if err != nil {
return err
Expand All @@ -327,5 +327,5 @@ func (s *StaticConfig) FromResult(result *ton.ExecutionResult) error {
}

func (s *StaticConfig) FetchResult(ctx context.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, _ []interface{}) error {
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, StaticConfigGetter, nil, s.FromResult)
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, StaticConfigGetter, nil, s)
}
8 changes: 4 additions & 4 deletions pkg/ccip/bindings/offramp/offramp.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ type Config struct {
PermissionlessExecutionThresholdSeconds uint32 `tlb:"## 32"`
}

func (c *Config) FromResult(result *ton.ExecutionResult) error {
func (c *Config) UnmarshalResult(result *ton.ExecutionResult) error {
cs, err := result.Int(0)
if err != nil {
return fmt.Errorf("failed to get ChainSelector: %w", err)
Expand Down Expand Up @@ -188,7 +188,7 @@ func (c *Config) FromResult(result *ton.ExecutionResult) error {
}

func (c *Config) FetchResult(ctx context.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, _ []interface{}) error {
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, configGetter, nil, c.FromResult)
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, configGetter, nil, c)
}

// SourceChainConfig represents the configuration for a specific source chain
Expand All @@ -200,7 +200,7 @@ type SourceChainConfig struct {
OnRamp ccipcommon.CrossChainAddress `tlb:"."`
}

func (c *SourceChainConfig) FromResult(result *ton.ExecutionResult) error {
func (c *SourceChainConfig) UnmarshalResult(result *ton.ExecutionResult) error {
routerAddressSlice, err := result.Slice(0)
if err != nil {
return fmt.Errorf("failed to get router address slice: %w", err)
Expand Down Expand Up @@ -248,5 +248,5 @@ func (c *SourceChainConfig) FromResult(result *ton.ExecutionResult) error {
}

func (c *SourceChainConfig) FetchResult(ctx context.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, opts []interface{}) error {
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, ccipcommon.SrcChainConfigGetter, opts, c.FromResult)
return ccipcommon.FetchResultHelper(ctx, client, block, contractAddr, ccipcommon.SrcChainConfigGetter, opts, c)
}
8 changes: 4 additions & 4 deletions pkg/ccip/bindings/onramp/onramp.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ type DestChainConfig struct {
AllowedSender *cell.Dictionary `tlb:"dict 267"` // it's not documented anywhere, but the address in cell uses 267 bits
}

func (c *DestChainConfig) FromResult(result *ton.ExecutionResult) error {
func (c *DestChainConfig) UnmarshalResult(result *ton.ExecutionResult) error {
routerAddressSlice, err := result.Slice(0)
if err != nil {
return err
Expand Down Expand Up @@ -194,7 +194,7 @@ func (c *DestChainConfig) FromResult(result *ton.ExecutionResult) error {
}

func (c *DestChainConfig) FetchResult(ctx context2.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, destChainSelector []interface{}) error {
return common.FetchResultHelper(ctx, client, block, contractAddr, common.DestChainConfigGetter, destChainSelector, c.FromResult)
return common.FetchResultHelper(ctx, client, block, contractAddr, common.DestChainConfigGetter, destChainSelector, c)
}

// DynamicConfig holds the dynamic configuration for the CCIP system, including fee quoter, fee aggregator, and allow list admin.
Expand All @@ -204,7 +204,7 @@ type DynamicConfig struct {
AllowListAdmin *address.Address `tlb:"addr"`
}

func (c *DynamicConfig) FromResult(result *ton.ExecutionResult) error {
func (c *DynamicConfig) UnmarshalResult(result *ton.ExecutionResult) error {
feeQuoterAddressSlice, err := result.Slice(0)
if err != nil {
return err
Expand Down Expand Up @@ -238,5 +238,5 @@ func (c *DynamicConfig) FromResult(result *ton.ExecutionResult) error {
}

func (c *DynamicConfig) FetchResult(ctx context2.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, _ *any) error {
return common.FetchResultHelper(ctx, client, block, contractAddr, dynamicConfigGetter, nil, c.FromResult)
return common.FetchResultHelper(ctx, client, block, contractAddr, dynamicConfigGetter, nil, c)
}
3 changes: 2 additions & 1 deletion pkg/ccip/chainaccessor/ton_accessor.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"github.com/smartcontractkit/chainlink-ton/pkg/logpoller/types"
"github.com/smartcontractkit/chainlink-ton/pkg/logpoller/types/query"
"github.com/smartcontractkit/chainlink-ton/pkg/ton/hash"
"github.com/smartcontractkit/chainlink-ton/pkg/ton/tvm"
)

var ErrNoBindings = errors.New("no bindings found")
Expand Down Expand Up @@ -351,7 +352,7 @@ func (a *TONAccessor) GetTokenPriceUSD(ctx context.Context, rawTokenAddress ccip
return ccipocr3.TimestampedUnixBig{}, err
}
var timestampedPrice feequoter.TimestampedPrice
err = timestampedPrice.FromResult(result)
err = tvm.LoadFromResult(&timestampedPrice, result)
if err != nil {
return ccipocr3.TimestampedUnixBig{}, err
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/ccip/common/configfetcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"golang.org/x/sync/errgroup"

"github.com/smartcontractkit/chainlink-ton/pkg/ton/parser"
"github.com/smartcontractkit/chainlink-ton/pkg/ton/tvm"

"github.com/smartcontractkit/chainlink-ton/pkg/ccip/bindings/feequoter"
"github.com/smartcontractkit/chainlink-ton/pkg/ccip/bindings/offramp"
Expand All @@ -26,10 +27,9 @@ const (

// ConfigFetcher is an interface for fetching and parsing contract configurations.
type ConfigFetcher interface {
tvm.ResultUnmarshaler
// FetchResult fetches the configuration from the contract at the specified block and address.
FetchResult(ctx context.Context, client ton.APIClientWrapped, block *ton.BlockIDExt, contractAddr *address.Address, opts []interface{}) error
// FromResult parses the configuration from the execution result.
FromResult(result *ton.ExecutionResult) error
}

// FetchOnRampDestChainConfig retrieves destination chain configurations from the on-ramp contract.
Expand Down
3 changes: 2 additions & 1 deletion pkg/ton/debug/explorer/explorer.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"github.com/smartcontractkit/chainlink-ton/pkg/ton/debug"
"github.com/smartcontractkit/chainlink-ton/pkg/ton/debug/visualizations/sequence"
"github.com/smartcontractkit/chainlink-ton/pkg/ton/tracetracking"
"github.com/smartcontractkit/chainlink-ton/pkg/ton/tvm"
)

func GenerateExplorerCmd(lggr *logger.Logger, contracts map[string]debug.TypeAndVersion, client *ton.APIClient) *cobra.Command {
Expand Down Expand Up @@ -441,7 +442,7 @@ func (c *client) queryActorIfNotVisited(ctx context.Context, block *ton.BlockIDE

defer func() {
}()
if err = typeVersion.FromResult(result); err != nil {
if err = tvm.LoadFromResult(&typeVersion, result); err != nil {
return fmt.Errorf("failed to parse typeAndVersion: %w", err)
}
visited[addr.String()] = true
Expand Down
11 changes: 11 additions & 0 deletions pkg/ton/tvm/result.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package tvm

import "github.com/xssnick/tonutils-go/ton"

type ResultUnmarshaler interface {
UnmarshalResult(*ton.ExecutionResult) error
}

func LoadFromResult(v ResultUnmarshaler, res *ton.ExecutionResult) error {
return v.UnmarshalResult(res)
}
Loading