From 78531daeee375dff1a187c03eba117d3ebbed92e Mon Sep 17 00:00:00 2001 From: "Abdelrahman Soliman (Boda)" <2677789+asoliman92@users.noreply.github.com> Date: Thu, 11 Jul 2024 21:46:36 +0400 Subject: [PATCH] CCIP Integration tests - wiring contracts [CCIP-2698] (#1148) This is first phase of setting up full integration tests for the new setup. Test is setting up 3 chains (let's call them A, B, C), each chain deploys and starts 2 ping pong contracts for the other 2. A ---deploy+start---> (pingPongB, pingPongC) B ---deploy+start---> (pingPongA, pingPongC) C ---deploy+start---> (pingPongA, pingPongB) and then checks that each ping pong contract emitted `CCIPSendRequested` event from the expected source to destination. Test fails if any wiring between contracts is not correct. Note: This setup is missing token pools to simplify it a little bit. It will be added in future PR when we start testing sending tokens. https://smartcontract-it.atlassian.net/browse/CCIP-2698 --------- Co-authored-by: Will Winder --- .../scripts/native_solc_compile_all_ccip | 1 + .../generated/nonce_manager/nonce_manager.go | 264 +++++++-- ...rapper-dependency-versions-do-not-edit.txt | 2 +- core/gethwrappers/ccip/go_generate.go | 1 + .../plugins/ccip_integration_tests/helpers.go | 518 ++++++++++++++++++ .../ccip_integration_tests/ping_pong_test.go | 95 ++++ 6 files changed, 833 insertions(+), 48 deletions(-) create mode 100644 core/services/ocr3/plugins/ccip_integration_tests/helpers.go create mode 100644 core/services/ocr3/plugins/ccip_integration_tests/ping_pong_test.go diff --git a/contracts/scripts/native_solc_compile_all_ccip b/contracts/scripts/native_solc_compile_all_ccip index 3cfecbc056..51102b33a1 100755 --- a/contracts/scripts/native_solc_compile_all_ccip +++ b/contracts/scripts/native_solc_compile_all_ccip @@ -77,6 +77,7 @@ compileContract ccip/tokenAdminRegistry/TokenAdminRegistry.sol compileContract ccip/tokenAdminRegistry/RegistryModuleOwnerCustom.sol compileContract ccip/capability/CCIPConfig.sol compileContract ccip/capability/interfaces/IOCR3ConfigEncoder.sol +compileContract ccip/NonceManager.sol # Test helpers compileContract ccip/test/helpers/BurnMintERC677Helper.sol diff --git a/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go b/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go index 717aeb336d..14979b4fe3 100644 --- a/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go +++ b/core/gethwrappers/ccip/generated/nonce_manager/nonce_manager.go @@ -36,17 +36,18 @@ type AuthorizedCallersAuthorizedCallerArgs struct { } type NonceManagerPreviousRamps struct { - PrevOnRamp common.Address + PrevOnRamp common.Address + PrevOffRamp common.Address } type NonceManagerPreviousRampsArgs struct { - RemotChainSelector uint64 - PrevRamps NonceManagerPreviousRamps + RemoteChainSelector uint64 + PrevRamps NonceManagerPreviousRamps } var NonceManagerMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"PreviousRampAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"name\":\"PreviousOnRampUpdated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remotChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamps\",\"type\":\"tuple\"}],\"internalType\":\"structNonceManager.PreviousRampsArgs[]\",\"name\":\"previousRampsArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPreviousRampsUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getIncrementedOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getPreviousRamps\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", - Bin: "0x60806040523480156200001157600080fd5b5060405162001659380380620016598339810160408190526200003491620004b0565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620000f6565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001a1565b5050620005d0565b336001600160a01b03821603620001505760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000231576000828281518110620001ca57620001ca62000582565b60209081029190910101519050620001e4600282620002f0565b1562000227576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001a9565b50815160005b8151811015620002ea57600082828151811062000258576200025862000582565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000296576040516342bcdf7f60e11b815260040160405180910390fd5b620002a360028262000310565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000237565b50505050565b600062000307836001600160a01b03841662000327565b90505b92915050565b600062000307836001600160a01b0384166200042b565b60008181526001830160205260408120548015620004205760006200034e60018362000598565b8554909150600090620003649060019062000598565b9050818114620003d057600086600001828154811062000388576200038862000582565b9060005260206000200154905080876000018481548110620003ae57620003ae62000582565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620003e457620003e4620005ba565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200030a565b60009150506200030a565b600081815260018301602052604081205462000474575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200030a565b5060006200030a565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b0381168114620004ab57600080fd5b919050565b60006020808385031215620004c457600080fd5b82516001600160401b0380821115620004dc57600080fd5b818501915085601f830112620004f157600080fd5b8151818111156200050657620005066200047d565b8060051b604051601f19603f830116810181811085821117156200052e576200052e6200047d565b6040529182528482019250838101850191888311156200054d57600080fd5b938501935b828510156200057657620005668562000493565b8452938501939285019262000552565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200030a57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b61107980620005e06000396000f3fe608060405234801561001057600080fd5b50600436106100a35760003560e01c806379ba50971161007657806391a2749a1161005b57806391a2749a146101b5578063d18be31b146101c8578063f2fde38b146101db57600080fd5b806379ba5097146101855780638da5cb5b1461018d57600080fd5b80631ce2b142146100a85780632451a627146100bd578063294b5630146100db57806331b89ff314610159575b600080fd5b6100bb6100b6366004610c1d565b6101ee565b005b6100c5610363565b6040516100d29190610c92565b60405180910390f35b6101346100e9366004610d02565b604080516020808201835260009182905267ffffffffffffffff9390931681526004835281902081519283019091525473ffffffffffffffffffffffffffffffffffffffff16815290565b604051905173ffffffffffffffffffffffffffffffffffffffff1681526020016100d2565b61016c610167366004610d1f565b610374565b60405167ffffffffffffffff90911681526020016100d2565b6100bb61038b565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100d2565b6100bb6101c3366004610eba565b61048d565b61016c6101d6366004610d1f565b6104a1565b6100bb6101e9366004610f61565b610543565b6101f6610554565b60005b8181101561035e573683838381811061021457610214610f7e565b604002919091019150600090506004816102316020850185610d02565b67ffffffffffffffff1681526020810191909152604001600020805490915073ffffffffffffffffffffffffffffffffffffffff161561029d576040517fc6117ae200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6102ad6040830160208401610f61565b81547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff919091161781556102fa6020830183610d02565b815460405173ffffffffffffffffffffffffffffffffffffffff909116815267ffffffffffffffff91909116907f89d2355e2829b1e15855fec87fb400638aebc9f03728949d702d3b5d4ea999549060200160405180910390a250506001016101f9565b505050565b606061036f60026105d7565b905090565b60006103818484846105e4565b90505b9392505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610411576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b610495610554565b61049e81610732565b50565b60006104ab6108c4565b60006104b88585856105e4565b6104c3906001610fdc565b67ffffffffffffffff861660009081526005602052604090819020905191925082916104f29087908790610ffd565b908152604051908190036020019020805467ffffffffffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905590509392505050565b61054b610554565b61049e81610907565b60005473ffffffffffffffffffffffffffffffffffffffff1633146105d5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e6572000000000000000000006044820152606401610408565b565b60606000610384836109fc565b67ffffffffffffffff831660009081526005602052604080822090518291906106109086908690610ffd565b9081526040519081900360200190205467ffffffffffffffff16905060008190036103815767ffffffffffffffff851660009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1680156107295773ffffffffffffffffffffffffffffffffffffffff811663856c824761069386880188610f61565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa1580156106fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610720919061100d565b92505050610384565b50949350505050565b602081015160005b81518110156107cd57600082828151811061075757610757610f7e565b60200260200101519050610775816002610a5890919063ffffffff16565b156107c45760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b5060010161073a565b50815160005b81518110156108be5760008282815181106107f0576107f0610f7e565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610860576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61086b600282610a83565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a1506001016107d3565b50505050565b6108cf600233610aa5565b6105d5576040517fd86ad9cf000000000000000000000000000000000000000000000000000000008152336004820152602401610408565b3373ffffffffffffffffffffffffffffffffffffffff821603610986576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c660000000000000000006044820152606401610408565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b606081600001805480602002602001604051908101604052809291908181526020018280548015610a4c57602002820191906000526020600020905b815481526020019060010190808311610a38575b50505050509050919050565b6000610a7a8373ffffffffffffffffffffffffffffffffffffffff8416610ad4565b90505b92915050565b6000610a7a8373ffffffffffffffffffffffffffffffffffffffff8416610bce565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610a7a565b60008181526001830160205260408120548015610bbd576000610af860018361102a565b8554909150600090610b0c9060019061102a565b9050818114610b71576000866000018281548110610b2c57610b2c610f7e565b9060005260206000200154905080876000018481548110610b4f57610b4f610f7e565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610b8257610b8261103d565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610a7d565b6000915050610a7d565b5092915050565b6000818152600183016020526040812054610c1557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610a7d565b506000610a7d565b60008060208385031215610c3057600080fd5b823567ffffffffffffffff80821115610c4857600080fd5b818501915085601f830112610c5c57600080fd5b813581811115610c6b57600080fd5b8660208260061b8501011115610c8057600080fd5b60209290920196919550909350505050565b6020808252825182820181905260009190848201906040850190845b81811015610ce057835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610cae565b50909695505050505050565b67ffffffffffffffff8116811461049e57600080fd5b600060208284031215610d1457600080fd5b813561038481610cec565b600080600060408486031215610d3457600080fd5b8335610d3f81610cec565b9250602084013567ffffffffffffffff80821115610d5c57600080fd5b818601915086601f830112610d7057600080fd5b813581811115610d7f57600080fd5b876020828501011115610d9157600080fd5b6020830194508093505050509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461049e57600080fd5b600082601f830112610e0657600080fd5b8135602067ffffffffffffffff80831115610e2357610e23610da4565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f83011681018181108482111715610e6657610e66610da4565b6040529384526020818701810194908101925087851115610e8657600080fd5b6020870191505b84821015610eaf578135610ea081610dd3565b83529183019190830190610e8d565b979650505050505050565b600060208284031215610ecc57600080fd5b813567ffffffffffffffff80821115610ee457600080fd5b9083019060408286031215610ef857600080fd5b604051604081018181108382111715610f1357610f13610da4565b604052823582811115610f2557600080fd5b610f3187828601610df5565b825250602083013582811115610f4657600080fd5b610f5287828601610df5565b60208301525095945050505050565b600060208284031215610f7357600080fd5b813561038481610dd3565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115610bc757610bc7610fad565b8183823760009101908152919050565b60006020828403121561101f57600080fd5b815161038481610cec565b81810381811115610a7d57610a7d610fad565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", + ABI: "[{\"inputs\":[{\"internalType\":\"address[]\",\"name\":\"authorizedCallers\",\"type\":\"address[]\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"PreviousRampAlreadySet\",\"type\":\"error\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"UnauthorizedCaller\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ZeroAddressNotAllowed\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerAdded\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"caller\",\"type\":\"address\"}],\"name\":\"AuthorizedCallerRemoved\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferRequested\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"address\",\"name\":\"from\",\"type\":\"address\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"OwnershipTransferred\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"indexed\":false,\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamp\",\"type\":\"tuple\"}],\"name\":\"PreviousRampsUpdated\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"nonce\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"SkippedIncorrectNonce\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"acceptOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"address[]\",\"name\":\"addedCallers\",\"type\":\"address[]\"},{\"internalType\":\"address[]\",\"name\":\"removedCallers\",\"type\":\"address[]\"}],\"internalType\":\"structAuthorizedCallers.AuthorizedCallerArgs\",\"name\":\"authorizedCallerArgs\",\"type\":\"tuple\"}],\"name\":\"applyAuthorizedCallerUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"uint64\",\"name\":\"remoteChainSelector\",\"type\":\"uint64\"},{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"prevRamps\",\"type\":\"tuple\"}],\"internalType\":\"structNonceManager.PreviousRampsArgs[]\",\"name\":\"previousRampsArgs\",\"type\":\"tuple[]\"}],\"name\":\"applyPreviousRampsUpdates\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"getAllAuthorizedCallers\",\"outputs\":[{\"internalType\":\"address[]\",\"name\":\"\",\"type\":\"address[]\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"getInboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getIncrementedOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"destChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"sender\",\"type\":\"address\"}],\"name\":\"getOutboundNonce\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"chainSelector\",\"type\":\"uint64\"}],\"name\":\"getPreviousRamps\",\"outputs\":[{\"components\":[{\"internalType\":\"address\",\"name\":\"prevOnRamp\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"prevOffRamp\",\"type\":\"address\"}],\"internalType\":\"structNonceManager.PreviousRamps\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"sourceChainSelector\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"expectedNonce\",\"type\":\"uint64\"},{\"internalType\":\"bytes\",\"name\":\"sender\",\"type\":\"bytes\"}],\"name\":\"incrementInboundNonce\",\"outputs\":[{\"internalType\":\"bool\",\"name\":\"\",\"type\":\"bool\"}],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"owner\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"to\",\"type\":\"address\"}],\"name\":\"transferOwnership\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]", + Bin: "0x60806040523480156200001157600080fd5b5060405162001ad538038062001ad58339810160408190526200003491620004b0565b8033806000816200008c5760405162461bcd60e51b815260206004820152601860248201527f43616e6e6f7420736574206f776e657220746f207a65726f000000000000000060448201526064015b60405180910390fd5b600080546001600160a01b0319166001600160a01b0384811691909117909155811615620000bf57620000bf81620000f6565b5050604080518082018252838152815160008152602080820190935291810191909152620000ee9150620001a1565b5050620005d0565b336001600160a01b03821603620001505760405162461bcd60e51b815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c66000000000000000000604482015260640162000083565b600180546001600160a01b0319166001600160a01b0383811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b602081015160005b815181101562000231576000828281518110620001ca57620001ca62000582565b60209081029190910101519050620001e4600282620002f0565b1562000227576040516001600160a01b03821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b50600101620001a9565b50815160005b8151811015620002ea57600082828151811062000258576200025862000582565b6020026020010151905060006001600160a01b0316816001600160a01b03160362000296576040516342bcdf7f60e11b815260040160405180910390fd5b620002a360028262000310565b506040516001600160a01b03821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010162000237565b50505050565b600062000307836001600160a01b03841662000327565b90505b92915050565b600062000307836001600160a01b0384166200042b565b60008181526001830160205260408120548015620004205760006200034e60018362000598565b8554909150600090620003649060019062000598565b9050818114620003d057600086600001828154811062000388576200038862000582565b9060005260206000200154905080876000018481548110620003ae57620003ae62000582565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080620003e457620003e4620005ba565b6001900381819060005260206000200160009055905585600101600086815260200190815260200160002060009055600193505050506200030a565b60009150506200030a565b600081815260018301602052604081205462000474575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556200030a565b5060006200030a565b634e487b7160e01b600052604160045260246000fd5b80516001600160a01b0381168114620004ab57600080fd5b919050565b60006020808385031215620004c457600080fd5b82516001600160401b0380821115620004dc57600080fd5b818501915085601f830112620004f157600080fd5b8151818111156200050657620005066200047d565b8060051b604051601f19603f830116810181811085821117156200052e576200052e6200047d565b6040529182528482019250838101850191888311156200054d57600080fd5b938501935b828510156200057657620005668562000493565b8452938501939285019262000552565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b818103818111156200030a57634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6114f580620005e06000396000f3fe608060405234801561001057600080fd5b50600436106100c95760003560e01c806391a2749a11610081578063e0e03cae1161005b578063e0e03cae14610228578063ea458c0c1461024b578063f2fde38b1461025e57600080fd5b806391a2749a146101d6578063bf18402a146101e9578063c92236251461021557600080fd5b806379ba5097116100b257806379ba50971461019157806384d8acf71461019b5780638da5cb5b146101ae57600080fd5b80632451a627146100ce578063294b5630146100ec575b600080fd5b6100d6610271565b6040516100e39190610f2e565b60405180910390f35b61015d6100fa366004610f9e565b60408051808201909152600080825260208201525067ffffffffffffffff166000908152600460209081526040918290208251808401909352805473ffffffffffffffffffffffffffffffffffffffff9081168452600190910154169082015290565b60408051825173ffffffffffffffffffffffffffffffffffffffff90811682526020938401511692810192909252016100e3565b610199610282565b005b6101996101a9366004610fbb565b610384565b60005460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100e3565b6101996101e4366004611146565b610560565b6101fc6101f73660046111ed565b610574565b60405167ffffffffffffffff90911681526020016100e3565b6101fc61022336600461126f565b610589565b61023b6102363660046112c4565b6105a0565b60405190151581526020016100e3565b6101fc6102593660046111ed565b6106a9565b61019961026c366004611329565b61073d565b606061027d600261074e565b905090565b60015473ffffffffffffffffffffffffffffffffffffffff163314610308576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4d7573742062652070726f706f736564206f776e65720000000000000000000060448201526064015b60405180910390fd5b60008054337fffffffffffffffffffffffff00000000000000000000000000000000000000008083168217845560018054909116905560405173ffffffffffffffffffffffffffffffffffffffff90921692909183917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a350565b61038c61075b565b60005b8181101561055b57368383838181106103aa576103aa611346565b606002919091019150600090506004816103c76020850185610f9e565b67ffffffffffffffff1681526020810191909152604001600020805490915073ffffffffffffffffffffffffffffffffffffffff161515806104225750600181015473ffffffffffffffffffffffffffffffffffffffff1615155b15610459576040517fc6117ae200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6104696040830160208401611329565b81547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff919091161781556104b96060830160408401611329565b6001820180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905561050d6020830183610f9e565b67ffffffffffffffff167fa2e43edcbc4fd175ae4bebbe3fd6139871ed1f1783cd4a1ace59b90d302c3319836020016040516105499190611375565b60405180910390a2505060010161038f565b505050565b61056861075b565b610571816107de565b50565b60006105808383610970565b90505b92915050565b6000610596848484610a8d565b90505b9392505050565b60006105aa610bde565b60006105b7868585610a8d565b6105c29060016113ec565b90508467ffffffffffffffff168167ffffffffffffffff1614610626577f606ff8179e5e3c059b82df931acc496b7b6053e8879042f8267f930e0595f69f86868686604051610614949392919061140d565b60405180910390a160009150506106a1565b67ffffffffffffffff86166000908152600660205260409081902090518291906106539087908790611479565b908152604051908190036020019020805467ffffffffffffffff929092167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905550600190505b949350505050565b60006106b3610bde565b60006106bf8484610970565b6106ca9060016113ec565b67ffffffffffffffff808616600090815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff89168452909152902080549183167fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090921691909117905591505092915050565b61074561075b565b61057181610c21565b6060600061059983610d16565b60005473ffffffffffffffffffffffffffffffffffffffff1633146107dc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4f6e6c792063616c6c61626c65206279206f776e65720000000000000000000060448201526064016102ff565b565b602081015160005b815181101561087957600082828151811061080357610803611346565b60200260200101519050610821816002610d7290919063ffffffff16565b156108705760405173ffffffffffffffffffffffffffffffffffffffff821681527fc3803387881faad271c47728894e3e36fac830ffc8602ca6fc07733cbda775809060200160405180910390a15b506001016107e6565b50815160005b815181101561096a57600082828151811061089c5761089c611346565b60200260200101519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361090c576040517f8579befe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610917600282610d94565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527feb1b9b92e50b7f88f9ff25d56765095ac6e91540eee214906f4036a908ffbdef9060200160405180910390a15060010161087f565b50505050565b67ffffffffffffffff808316600090815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120549091168082036105805767ffffffffffffffff841660009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff168015610a85576040517f856c824700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff858116600483015282169063856c824790602401602060405180830381865afa158015610a58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a7c9190611489565b92505050610583565b509392505050565b67ffffffffffffffff83166000908152600660205260408082209051829190610ab99086908690611479565b9081526040519081900360200190205467ffffffffffffffff16905060008190036105965767ffffffffffffffff851660009081526004602052604090206001015473ffffffffffffffffffffffffffffffffffffffff168015610bd55773ffffffffffffffffffffffffffffffffffffffff811663856c8247610b3f86880188611329565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152602401602060405180830381865afa158015610ba8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bcc9190611489565b92505050610599565b50949350505050565b610be9600233610db6565b6107dc576040517fd86ad9cf0000000000000000000000000000000000000000000000000000000081523360048201526024016102ff565b3373ffffffffffffffffffffffffffffffffffffffff821603610ca0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f43616e6e6f74207472616e7366657220746f2073656c6600000000000000000060448201526064016102ff565b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821790925560008054604051929316917fed8889f560326eb138920d842192f0eb3dd22b4f139c87a2c57538e05bae12789190a350565b606081600001805480602002602001604051908101604052809291908181526020018280548015610d6657602002820191906000526020600020905b815481526020019060010190808311610d52575b50505050509050919050565b60006105808373ffffffffffffffffffffffffffffffffffffffff8416610de5565b60006105808373ffffffffffffffffffffffffffffffffffffffff8416610edf565b73ffffffffffffffffffffffffffffffffffffffff811660009081526001830160205260408120541515610580565b60008181526001830160205260408120548015610ece576000610e096001836114a6565b8554909150600090610e1d906001906114a6565b9050818114610e82576000866000018281548110610e3d57610e3d611346565b9060005260206000200154905080876000018481548110610e6057610e60611346565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080610e9357610e936114b9565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610583565b6000915050610583565b5092915050565b6000818152600183016020526040812054610f2657508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610583565b506000610583565b6020808252825182820181905260009190848201906040850190845b81811015610f7c57835173ffffffffffffffffffffffffffffffffffffffff1683529284019291840191600101610f4a565b50909695505050505050565b67ffffffffffffffff8116811461057157600080fd5b600060208284031215610fb057600080fd5b813561058081610f88565b60008060208385031215610fce57600080fd5b823567ffffffffffffffff80821115610fe657600080fd5b818501915085601f830112610ffa57600080fd5b81358181111561100957600080fd5b86602060608302850101111561101e57600080fd5b60209290920196919550909350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff8116811461057157600080fd5b600082601f83011261109257600080fd5b8135602067ffffffffffffffff808311156110af576110af611030565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f830116810181811084821117156110f2576110f2611030565b604052938452602081870181019490810192508785111561111257600080fd5b6020870191505b8482101561113b57813561112c8161105f565b83529183019190830190611119565b979650505050505050565b60006020828403121561115857600080fd5b813567ffffffffffffffff8082111561117057600080fd5b908301906040828603121561118457600080fd5b60405160408101818110838211171561119f5761119f611030565b6040528235828111156111b157600080fd5b6111bd87828601611081565b8252506020830135828111156111d257600080fd5b6111de87828601611081565b60208301525095945050505050565b6000806040838503121561120057600080fd5b823561120b81610f88565b9150602083013561121b8161105f565b809150509250929050565b60008083601f84011261123857600080fd5b50813567ffffffffffffffff81111561125057600080fd5b60208301915083602082850101111561126857600080fd5b9250929050565b60008060006040848603121561128457600080fd5b833561128f81610f88565b9250602084013567ffffffffffffffff8111156112ab57600080fd5b6112b786828701611226565b9497909650939450505050565b600080600080606085870312156112da57600080fd5b84356112e581610f88565b935060208501356112f581610f88565b9250604085013567ffffffffffffffff81111561131157600080fd5b61131d87828801611226565b95989497509550505050565b60006020828403121561133b57600080fd5b81356105808161105f565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6040810182356113848161105f565b73ffffffffffffffffffffffffffffffffffffffff90811683526020840135906113ad8261105f565b8082166020850152505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff818116838216019080821115610ed857610ed86113bd565b600067ffffffffffffffff8087168352808616602084015250606060408301528260608301528284608084013760006080848401015260807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f850116830101905095945050505050565b8183823760009101908152919050565b60006020828403121561149b57600080fd5b815161058081610f88565b81810381811115610583576105836113bd565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea164736f6c6343000818000a", } var NonceManagerABI = NonceManagerMetaData.ABI @@ -207,7 +208,29 @@ func (_NonceManager *NonceManagerCallerSession) GetAllAuthorizedCallers() ([]com return _NonceManager.Contract.GetAllAuthorizedCallers(&_NonceManager.CallOpts) } -func (_NonceManager *NonceManagerCaller) GetOutboundNonce(opts *bind.CallOpts, destChainSelector uint64, sender []byte) (uint64, error) { +func (_NonceManager *NonceManagerCaller) GetInboundNonce(opts *bind.CallOpts, sourceChainSelector uint64, sender []byte) (uint64, error) { + var out []interface{} + err := _NonceManager.contract.Call(opts, &out, "getInboundNonce", sourceChainSelector, sender) + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +func (_NonceManager *NonceManagerSession) GetInboundNonce(sourceChainSelector uint64, sender []byte) (uint64, error) { + return _NonceManager.Contract.GetInboundNonce(&_NonceManager.CallOpts, sourceChainSelector, sender) +} + +func (_NonceManager *NonceManagerCallerSession) GetInboundNonce(sourceChainSelector uint64, sender []byte) (uint64, error) { + return _NonceManager.Contract.GetInboundNonce(&_NonceManager.CallOpts, sourceChainSelector, sender) +} + +func (_NonceManager *NonceManagerCaller) GetOutboundNonce(opts *bind.CallOpts, destChainSelector uint64, sender common.Address) (uint64, error) { var out []interface{} err := _NonceManager.contract.Call(opts, &out, "getOutboundNonce", destChainSelector, sender) @@ -221,11 +244,11 @@ func (_NonceManager *NonceManagerCaller) GetOutboundNonce(opts *bind.CallOpts, d } -func (_NonceManager *NonceManagerSession) GetOutboundNonce(destChainSelector uint64, sender []byte) (uint64, error) { +func (_NonceManager *NonceManagerSession) GetOutboundNonce(destChainSelector uint64, sender common.Address) (uint64, error) { return _NonceManager.Contract.GetOutboundNonce(&_NonceManager.CallOpts, destChainSelector, sender) } -func (_NonceManager *NonceManagerCallerSession) GetOutboundNonce(destChainSelector uint64, sender []byte) (uint64, error) { +func (_NonceManager *NonceManagerCallerSession) GetOutboundNonce(destChainSelector uint64, sender common.Address) (uint64, error) { return _NonceManager.Contract.GetOutboundNonce(&_NonceManager.CallOpts, destChainSelector, sender) } @@ -309,18 +332,30 @@ func (_NonceManager *NonceManagerTransactorSession) ApplyPreviousRampsUpdates(pr return _NonceManager.Contract.ApplyPreviousRampsUpdates(&_NonceManager.TransactOpts, previousRampsArgs) } -func (_NonceManager *NonceManagerTransactor) GetIncrementedOutboundNonce(opts *bind.TransactOpts, destChainSelector uint64, sender []byte) (*types.Transaction, error) { +func (_NonceManager *NonceManagerTransactor) GetIncrementedOutboundNonce(opts *bind.TransactOpts, destChainSelector uint64, sender common.Address) (*types.Transaction, error) { return _NonceManager.contract.Transact(opts, "getIncrementedOutboundNonce", destChainSelector, sender) } -func (_NonceManager *NonceManagerSession) GetIncrementedOutboundNonce(destChainSelector uint64, sender []byte) (*types.Transaction, error) { +func (_NonceManager *NonceManagerSession) GetIncrementedOutboundNonce(destChainSelector uint64, sender common.Address) (*types.Transaction, error) { return _NonceManager.Contract.GetIncrementedOutboundNonce(&_NonceManager.TransactOpts, destChainSelector, sender) } -func (_NonceManager *NonceManagerTransactorSession) GetIncrementedOutboundNonce(destChainSelector uint64, sender []byte) (*types.Transaction, error) { +func (_NonceManager *NonceManagerTransactorSession) GetIncrementedOutboundNonce(destChainSelector uint64, sender common.Address) (*types.Transaction, error) { return _NonceManager.Contract.GetIncrementedOutboundNonce(&_NonceManager.TransactOpts, destChainSelector, sender) } +func (_NonceManager *NonceManagerTransactor) IncrementInboundNonce(opts *bind.TransactOpts, sourceChainSelector uint64, expectedNonce uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.contract.Transact(opts, "incrementInboundNonce", sourceChainSelector, expectedNonce, sender) +} + +func (_NonceManager *NonceManagerSession) IncrementInboundNonce(sourceChainSelector uint64, expectedNonce uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.Contract.IncrementInboundNonce(&_NonceManager.TransactOpts, sourceChainSelector, expectedNonce, sender) +} + +func (_NonceManager *NonceManagerTransactorSession) IncrementInboundNonce(sourceChainSelector uint64, expectedNonce uint64, sender []byte) (*types.Transaction, error) { + return _NonceManager.Contract.IncrementInboundNonce(&_NonceManager.TransactOpts, sourceChainSelector, expectedNonce, sender) +} + func (_NonceManager *NonceManagerTransactor) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) { return _NonceManager.contract.Transact(opts, "transferOwnership", to) } @@ -839,8 +874,8 @@ func (_NonceManager *NonceManagerFilterer) ParseOwnershipTransferred(log types.L return event, nil } -type NonceManagerPreviousOnRampUpdatedIterator struct { - Event *NonceManagerPreviousOnRampUpdated +type NonceManagerPreviousRampsUpdatedIterator struct { + Event *NonceManagerPreviousRampsUpdated contract *bind.BoundContract event string @@ -851,7 +886,7 @@ type NonceManagerPreviousOnRampUpdatedIterator struct { fail error } -func (it *NonceManagerPreviousOnRampUpdatedIterator) Next() bool { +func (it *NonceManagerPreviousRampsUpdatedIterator) Next() bool { if it.fail != nil { return false @@ -860,7 +895,7 @@ func (it *NonceManagerPreviousOnRampUpdatedIterator) Next() bool { if it.done { select { case log := <-it.logs: - it.Event = new(NonceManagerPreviousOnRampUpdated) + it.Event = new(NonceManagerPreviousRampsUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -875,7 +910,7 @@ func (it *NonceManagerPreviousOnRampUpdatedIterator) Next() bool { select { case log := <-it.logs: - it.Event = new(NonceManagerPreviousOnRampUpdated) + it.Event = new(NonceManagerPreviousRampsUpdated) if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { it.fail = err return false @@ -890,43 +925,162 @@ func (it *NonceManagerPreviousOnRampUpdatedIterator) Next() bool { } } -func (it *NonceManagerPreviousOnRampUpdatedIterator) Error() error { +func (it *NonceManagerPreviousRampsUpdatedIterator) Error() error { return it.fail } -func (it *NonceManagerPreviousOnRampUpdatedIterator) Close() error { +func (it *NonceManagerPreviousRampsUpdatedIterator) Close() error { it.sub.Unsubscribe() return nil } -type NonceManagerPreviousOnRampUpdated struct { - DestChainSelector uint64 - PrevOnRamp common.Address - Raw types.Log +type NonceManagerPreviousRampsUpdated struct { + RemoteChainSelector uint64 + PrevRamp NonceManagerPreviousRamps + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterPreviousRampsUpdated(opts *bind.FilterOpts, remoteChainSelector []uint64) (*NonceManagerPreviousRampsUpdatedIterator, error) { + + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) + } + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "PreviousRampsUpdated", remoteChainSelectorRule) + if err != nil { + return nil, err + } + return &NonceManagerPreviousRampsUpdatedIterator{contract: _NonceManager.contract, event: "PreviousRampsUpdated", logs: logs, sub: sub}, nil } -func (_NonceManager *NonceManagerFilterer) FilterPreviousOnRampUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*NonceManagerPreviousOnRampUpdatedIterator, error) { +func (_NonceManager *NonceManagerFilterer) WatchPreviousRampsUpdated(opts *bind.WatchOpts, sink chan<- *NonceManagerPreviousRampsUpdated, remoteChainSelector []uint64) (event.Subscription, error) { - var destChainSelectorRule []interface{} - for _, destChainSelectorItem := range destChainSelector { - destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) + var remoteChainSelectorRule []interface{} + for _, remoteChainSelectorItem := range remoteChainSelector { + remoteChainSelectorRule = append(remoteChainSelectorRule, remoteChainSelectorItem) } - logs, sub, err := _NonceManager.contract.FilterLogs(opts, "PreviousOnRampUpdated", destChainSelectorRule) + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "PreviousRampsUpdated", remoteChainSelectorRule) if err != nil { return nil, err } - return &NonceManagerPreviousOnRampUpdatedIterator{contract: _NonceManager.contract, event: "PreviousOnRampUpdated", logs: logs, sub: sub}, nil + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + + event := new(NonceManagerPreviousRampsUpdated) + if err := _NonceManager.contract.UnpackLog(event, "PreviousRampsUpdated", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +func (_NonceManager *NonceManagerFilterer) ParsePreviousRampsUpdated(log types.Log) (*NonceManagerPreviousRampsUpdated, error) { + event := new(NonceManagerPreviousRampsUpdated) + if err := _NonceManager.contract.UnpackLog(event, "PreviousRampsUpdated", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +type NonceManagerSkippedIncorrectNonceIterator struct { + Event *NonceManagerSkippedIncorrectNonce + + contract *bind.BoundContract + event string + + logs chan types.Log + sub ethereum.Subscription + done bool + fail error +} + +func (it *NonceManagerSkippedIncorrectNonceIterator) Next() bool { + + if it.fail != nil { + return false + } + + if it.done { + select { + case log := <-it.logs: + it.Event = new(NonceManagerSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + + select { + case log := <-it.logs: + it.Event = new(NonceManagerSkippedIncorrectNonce) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } } -func (_NonceManager *NonceManagerFilterer) WatchPreviousOnRampUpdated(opts *bind.WatchOpts, sink chan<- *NonceManagerPreviousOnRampUpdated, destChainSelector []uint64) (event.Subscription, error) { +func (it *NonceManagerSkippedIncorrectNonceIterator) Error() error { + return it.fail +} - var destChainSelectorRule []interface{} - for _, destChainSelectorItem := range destChainSelector { - destChainSelectorRule = append(destChainSelectorRule, destChainSelectorItem) +func (it *NonceManagerSkippedIncorrectNonceIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +type NonceManagerSkippedIncorrectNonce struct { + SourceChainSelector uint64 + Nonce uint64 + Sender []byte + Raw types.Log +} + +func (_NonceManager *NonceManagerFilterer) FilterSkippedIncorrectNonce(opts *bind.FilterOpts) (*NonceManagerSkippedIncorrectNonceIterator, error) { + + logs, sub, err := _NonceManager.contract.FilterLogs(opts, "SkippedIncorrectNonce") + if err != nil { + return nil, err } + return &NonceManagerSkippedIncorrectNonceIterator{contract: _NonceManager.contract, event: "SkippedIncorrectNonce", logs: logs, sub: sub}, nil +} + +func (_NonceManager *NonceManagerFilterer) WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *NonceManagerSkippedIncorrectNonce) (event.Subscription, error) { - logs, sub, err := _NonceManager.contract.WatchLogs(opts, "PreviousOnRampUpdated", destChainSelectorRule) + logs, sub, err := _NonceManager.contract.WatchLogs(opts, "SkippedIncorrectNonce") if err != nil { return nil, err } @@ -936,8 +1090,8 @@ func (_NonceManager *NonceManagerFilterer) WatchPreviousOnRampUpdated(opts *bind select { case log := <-logs: - event := new(NonceManagerPreviousOnRampUpdated) - if err := _NonceManager.contract.UnpackLog(event, "PreviousOnRampUpdated", log); err != nil { + event := new(NonceManagerSkippedIncorrectNonce) + if err := _NonceManager.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { return err } event.Raw = log @@ -958,9 +1112,9 @@ func (_NonceManager *NonceManagerFilterer) WatchPreviousOnRampUpdated(opts *bind }), nil } -func (_NonceManager *NonceManagerFilterer) ParsePreviousOnRampUpdated(log types.Log) (*NonceManagerPreviousOnRampUpdated, error) { - event := new(NonceManagerPreviousOnRampUpdated) - if err := _NonceManager.contract.UnpackLog(event, "PreviousOnRampUpdated", log); err != nil { +func (_NonceManager *NonceManagerFilterer) ParseSkippedIncorrectNonce(log types.Log) (*NonceManagerSkippedIncorrectNonce, error) { + event := new(NonceManagerSkippedIncorrectNonce) + if err := _NonceManager.contract.UnpackLog(event, "SkippedIncorrectNonce", log); err != nil { return nil, err } event.Raw = log @@ -977,8 +1131,10 @@ func (_NonceManager *NonceManager) ParseLog(log types.Log) (generated.AbigenLog, return _NonceManager.ParseOwnershipTransferRequested(log) case _NonceManager.abi.Events["OwnershipTransferred"].ID: return _NonceManager.ParseOwnershipTransferred(log) - case _NonceManager.abi.Events["PreviousOnRampUpdated"].ID: - return _NonceManager.ParsePreviousOnRampUpdated(log) + case _NonceManager.abi.Events["PreviousRampsUpdated"].ID: + return _NonceManager.ParsePreviousRampsUpdated(log) + case _NonceManager.abi.Events["SkippedIncorrectNonce"].ID: + return _NonceManager.ParseSkippedIncorrectNonce(log) default: return nil, fmt.Errorf("abigen wrapper received unknown log topic: %v", log.Topics[0]) @@ -1001,8 +1157,12 @@ func (NonceManagerOwnershipTransferred) Topic() common.Hash { return common.HexToHash("0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0") } -func (NonceManagerPreviousOnRampUpdated) Topic() common.Hash { - return common.HexToHash("0x89d2355e2829b1e15855fec87fb400638aebc9f03728949d702d3b5d4ea99954") +func (NonceManagerPreviousRampsUpdated) Topic() common.Hash { + return common.HexToHash("0xa2e43edcbc4fd175ae4bebbe3fd6139871ed1f1783cd4a1ace59b90d302c3319") +} + +func (NonceManagerSkippedIncorrectNonce) Topic() common.Hash { + return common.HexToHash("0x606ff8179e5e3c059b82df931acc496b7b6053e8879042f8267f930e0595f69f") } func (_NonceManager *NonceManager) Address() common.Address { @@ -1012,7 +1172,9 @@ func (_NonceManager *NonceManager) Address() common.Address { type NonceManagerInterface interface { GetAllAuthorizedCallers(opts *bind.CallOpts) ([]common.Address, error) - GetOutboundNonce(opts *bind.CallOpts, destChainSelector uint64, sender []byte) (uint64, error) + GetInboundNonce(opts *bind.CallOpts, sourceChainSelector uint64, sender []byte) (uint64, error) + + GetOutboundNonce(opts *bind.CallOpts, destChainSelector uint64, sender common.Address) (uint64, error) GetPreviousRamps(opts *bind.CallOpts, chainSelector uint64) (NonceManagerPreviousRamps, error) @@ -1024,7 +1186,9 @@ type NonceManagerInterface interface { ApplyPreviousRampsUpdates(opts *bind.TransactOpts, previousRampsArgs []NonceManagerPreviousRampsArgs) (*types.Transaction, error) - GetIncrementedOutboundNonce(opts *bind.TransactOpts, destChainSelector uint64, sender []byte) (*types.Transaction, error) + GetIncrementedOutboundNonce(opts *bind.TransactOpts, destChainSelector uint64, sender common.Address) (*types.Transaction, error) + + IncrementInboundNonce(opts *bind.TransactOpts, sourceChainSelector uint64, expectedNonce uint64, sender []byte) (*types.Transaction, error) TransferOwnership(opts *bind.TransactOpts, to common.Address) (*types.Transaction, error) @@ -1052,11 +1216,17 @@ type NonceManagerInterface interface { ParseOwnershipTransferred(log types.Log) (*NonceManagerOwnershipTransferred, error) - FilterPreviousOnRampUpdated(opts *bind.FilterOpts, destChainSelector []uint64) (*NonceManagerPreviousOnRampUpdatedIterator, error) + FilterPreviousRampsUpdated(opts *bind.FilterOpts, remoteChainSelector []uint64) (*NonceManagerPreviousRampsUpdatedIterator, error) + + WatchPreviousRampsUpdated(opts *bind.WatchOpts, sink chan<- *NonceManagerPreviousRampsUpdated, remoteChainSelector []uint64) (event.Subscription, error) + + ParsePreviousRampsUpdated(log types.Log) (*NonceManagerPreviousRampsUpdated, error) + + FilterSkippedIncorrectNonce(opts *bind.FilterOpts) (*NonceManagerSkippedIncorrectNonceIterator, error) - WatchPreviousOnRampUpdated(opts *bind.WatchOpts, sink chan<- *NonceManagerPreviousOnRampUpdated, destChainSelector []uint64) (event.Subscription, error) + WatchSkippedIncorrectNonce(opts *bind.WatchOpts, sink chan<- *NonceManagerSkippedIncorrectNonce) (event.Subscription, error) - ParsePreviousOnRampUpdated(log types.Log) (*NonceManagerPreviousOnRampUpdated, error) + ParseSkippedIncorrectNonce(log types.Log) (*NonceManagerSkippedIncorrectNonce, error) ParseLog(log types.Log) (generated.AbigenLog, error) diff --git a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt index 26c576c9c9..aa162a70ec 100644 --- a/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt +++ b/core/gethwrappers/ccip/generation/generated-wrapper-dependency-versions-do-not-edit.txt @@ -22,7 +22,7 @@ mock_usdc_token_messenger: ../../../contracts/solc/v0.8.24/MockE2EUSDCTokenMesse mock_usdc_token_transmitter: ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.abi ../../../contracts/solc/v0.8.24/MockE2EUSDCTransmitter/MockE2EUSDCTransmitter.bin 33bdad70822e889de7c720ed20085cf9cd3f8eba8b68f26bd6535197749595fe mock_v3_aggregator_contract: ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.abi ../../../contracts/solc/v0.8.24/MockV3Aggregator/MockV3Aggregator.bin 518e19efa2ff52b0fefd8e597b05765317ee7638189bfe34ca43de2f6599faf4 multi_aggregate_rate_limiter: ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.abi ../../../contracts/solc/v0.8.24/MultiAggregateRateLimiter/MultiAggregateRateLimiter.bin abb0ecb1ed8621f26e43b39f5fa25f3d0b6d6c184fa37c404c4389605ecb74e7 -nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin cdc11c1ab4c1c3fd77f30215e9c579404a6e60eb9adc213d73ca0773c3bb5784 +nonce_manager: ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin 78b58f4f192db7496e2b6de805d6a2c918b98d4fa62f3c7ed145ef3b5657a40d ocr3_config_encoder: ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin e21180898e1ad54a045ee20add85a2793c681425ea06f66d1a9e5cab128b6487 ping_pong_demo: ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin 1588313bb5e781d181a825247d30828f59007700f36b4b9b00391592b06ff4b4 price_registry: ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin 0b3e253684d7085aa11f9179b71453b9db9d11cabea41605d5b4ac4128f85bfb diff --git a/core/gethwrappers/ccip/go_generate.go b/core/gethwrappers/ccip/go_generate.go index a5eaa37523..948fb7a5f7 100644 --- a/core/gethwrappers/ccip/go_generate.go +++ b/core/gethwrappers/ccip/go_generate.go @@ -30,6 +30,7 @@ package ccip //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.abi ../../../contracts/solc/v0.8.24/PriceRegistry/PriceRegistry.bin PriceRegistry price_registry //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.abi ../../../contracts/solc/v0.8.24/CCIPConfig/CCIPConfig.bin CCIPConfig ccip_config //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.abi ../../../contracts/solc/v0.8.24/IOCR3ConfigEncoder/IOCR3ConfigEncoder.bin IOCR3ConfigEncoder ocr3_config_encoder +//go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.abi ../../../contracts/solc/v0.8.24/NonceManager/NonceManager.bin NonceManager nonce_manager //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.abi ../../../contracts/solc/v0.8.24/MaybeRevertMessageReceiver/MaybeRevertMessageReceiver.bin MaybeRevertMessageReceiver maybe_revert_message_receiver //go:generate go run ../generation/generate/wrap.go ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.abi ../../../contracts/solc/v0.8.24/PingPongDemo/PingPongDemo.bin PingPongDemo ping_pong_demo diff --git a/core/services/ocr3/plugins/ccip_integration_tests/helpers.go b/core/services/ocr3/plugins/ccip_integration_tests/helpers.go new file mode 100644 index 0000000000..2a4e85560c --- /dev/null +++ b/core/services/ocr3/plugins/ccip_integration_tests/helpers.go @@ -0,0 +1,518 @@ +package ccip_integration_tests + +import ( + "encoding/hex" + "math/big" + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + "github.com/ethereum/go-ethereum/accounts/abi/bind/backends" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core" + + "github.com/smartcontractkit/chainlink/v2/core/chains/evm/assets" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ccip_config" + + chainsel "github.com/smartcontractkit/chain-selectors" + + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/arm_proxy_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_offramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/evm_2_evm_multi_onramp" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/mock_arm_contract" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/nonce_manager" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/price_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/router" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/token_admin_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/weth9" + kcr "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/keystone/generated/capabilities_registry" + "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/shared/generated/link_token" + "github.com/smartcontractkit/chainlink/v2/core/internal/testutils" + + "github.com/stretchr/testify/require" +) + +var ( + homeChainID = chainsel.GETH_TESTNET.EvmChainID +) + +const ( + CapabilityLabelledName = "ccip" + CapabilityVersion = "v1.0.0" +) + +func e18Mult(amount uint64) *big.Int { + return new(big.Int).Mul(uintBigInt(amount), uintBigInt(1e18)) +} + +func uintBigInt(i uint64) *big.Int { + return new(big.Int).SetUint64(i) +} + +type homeChain struct { + backend *backends.SimulatedBackend + owner *bind.TransactOpts + chainID uint64 + capabilityRegistry *kcr.CapabilitiesRegistry + ccipConfigContract common.Address +} + +type onchainUniverse struct { + backend *backends.SimulatedBackend + owner *bind.TransactOpts + chainID uint64 + linkToken *link_token.LinkToken + weth *weth9.WETH9 + router *router.Router + rmnProxy *arm_proxy_contract.ARMProxyContract + rmn *mock_arm_contract.MockARMContract + onramp *evm_2_evm_multi_onramp.EVM2EVMMultiOnRamp + offramp *evm_2_evm_multi_offramp.EVM2EVMMultiOffRamp + priceRegistry *price_registry.PriceRegistry + tokenAdminRegistry *token_admin_registry.TokenAdminRegistry + nonceManager *nonce_manager.NonceManager +} + +type chainBase struct { + backend *backends.SimulatedBackend + owner *bind.TransactOpts +} + +// createUniverses does the following: +// 1. Creates 1 home chain and `numChains`-1 non-home chains +// 2. Sets up home chain with the capability registry and the CCIP config contract +// 2. Deploys the CCIP contracts to all chains. +// 3. Sets up the initial configurations for the contracts on all chains. +// 4. Wires the chains together. +func createUniverses( + t *testing.T, + numUniverses int, +) (homeChainUni homeChain, universes map[uint64]onchainUniverse) { + chains := createChains(t, numUniverses) + + homeChainBase, ok := chains[homeChainID] + require.True(t, ok, "home chain backend not available") + // Set up home chain first + homeChainUniverse := setupHomeChain(t, homeChainBase.owner, homeChainBase.backend) + + // deploy the ccip contracts on all chains + universes = make(map[uint64]onchainUniverse) + for chainID, base := range chains { + owner := base.owner + backend := base.backend + // deploy the CCIP contracts + linkToken := deployLinkToken(t, owner, backend, chainID) + rmn := deployMockARMContract(t, owner, backend, chainID) + rmnProxy := deployARMProxyContract(t, owner, backend, rmn.Address(), chainID) + weth := deployWETHContract(t, owner, backend, chainID) + rout := deployRouter(t, owner, backend, weth.Address(), rmnProxy.Address(), chainID) + priceRegistry := deployPriceRegistry(t, owner, backend, linkToken.Address(), weth.Address(), chainID) + tokenAdminRegistry := deployTokenAdminRegistry(t, owner, backend, chainID) + nonceManager := deployNonceManager(t, owner, backend, chainID) + + //====================================================================== + // OnRamp + //====================================================================== + onRampAddr, _, _, err := evm_2_evm_multi_onramp.DeployEVM2EVMMultiOnRamp( + owner, + backend, + evm_2_evm_multi_onramp.EVM2EVMMultiOnRampStaticConfig{ + LinkToken: linkToken.Address(), + ChainSelector: chainID, + RmnProxy: rmnProxy.Address(), + MaxFeeJuelsPerMsg: big.NewInt(1e18), + NonceManager: nonceManager.Address(), + TokenAdminRegistry: tokenAdminRegistry.Address(), + }, + evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDynamicConfig{ + Router: rout.Address(), + PriceRegistry: priceRegistry.Address(), + //`withdrawFeeTokens` onRamp function is not part of the message flow + // so we can set this to any address + FeeAggregator: testutils.NewAddress(), + }, + // Destination chain configs will be set up later once we have all chains + []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{}, + // PremiumMultiplier is always needed if the onramp is enabled + []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampPremiumMultiplierWeiPerEthArgs{ + { + PremiumMultiplierWeiPerEth: 9e17, //0.9 ETH + Token: linkToken.Address(), + }, + { + PremiumMultiplierWeiPerEth: 1e18, + Token: weth.Address(), + }, + }, + //TODO: We'll need to have TransferFeeConfigArgs when we start testing with sending tokens + []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampTokenTransferFeeConfigArgs{}, + ) + require.NoErrorf(t, err, "failed to deploy onramp on chain id %d", chainID) + backend.Commit() + onramp, err := evm_2_evm_multi_onramp.NewEVM2EVMMultiOnRamp(onRampAddr, backend) + require.NoError(t, err) + + //====================================================================== + // OffRamp + //====================================================================== + offrampAddr, _, _, err := evm_2_evm_multi_offramp.DeployEVM2EVMMultiOffRamp( + owner, + backend, + evm_2_evm_multi_offramp.EVM2EVMMultiOffRampStaticConfig{ + ChainSelector: chainID, + RmnProxy: rmnProxy.Address(), + TokenAdminRegistry: tokenAdminRegistry.Address(), + NonceManager: nonceManager.Address(), + }, + // Source chain configs will be set up later once we have all chains + []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{}, + ) + require.NoErrorf(t, err, "failed to deploy offramp on chain id %d", chainID) + backend.Commit() + offramp, err := evm_2_evm_multi_offramp.NewEVM2EVMMultiOffRamp(offrampAddr, backend) + require.NoError(t, err) + + universe := onchainUniverse{ + backend: backend, + owner: owner, + chainID: chainID, + linkToken: linkToken, + weth: weth, + router: rout, + rmnProxy: rmnProxy, + rmn: rmn, + onramp: onramp, + offramp: offramp, + priceRegistry: priceRegistry, + tokenAdminRegistry: tokenAdminRegistry, + nonceManager: nonceManager, + } + // Set up the initial configurations for the contracts + setupUniverseBasics(t, universe) + + universes[chainID] = universe + } + + // Once we have all chains created and contracts deployed, we can set up the initial configurations and wire chains together + connectUniverses(t, universes) + + return homeChainUniverse, universes +} + +// Creates 1 home chain and `numChains`-1 non-home chains +func createChains(t *testing.T, numChains int) map[uint64]chainBase { + chains := make(map[uint64]chainBase) + + homeChainOwner := testutils.MustNewSimTransactor(t) + chains[homeChainID] = chainBase{ + owner: homeChainOwner, + backend: backends.NewSimulatedBackend(core.GenesisAlloc{ + homeChainOwner.From: core.GenesisAccount{ + Balance: assets.Ether(10_000).ToInt(), + }, + }, 30e6), + } + + for chainID := chainsel.TEST_90000001.EvmChainID; len(chains) < numChains && chainID < chainsel.TEST_90000020.EvmChainID; chainID++ { + owner := testutils.MustNewSimTransactor(t) + chains[chainID] = chainBase{ + owner: owner, + backend: backends.NewSimulatedBackend(core.GenesisAlloc{ + owner.From: core.GenesisAccount{ + Balance: assets.Ether(10_000).ToInt(), + }, + }, 30e6), + } + } + + return chains +} + +func setupHomeChain(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend) homeChain { + // deploy the capability registry on the home chain + crAddress, _, _, err := kcr.DeployCapabilitiesRegistry(owner, backend) + require.NoError(t, err, "failed to deploy capability registry on home chain") + backend.Commit() + + capabilityRegistry, err := kcr.NewCapabilitiesRegistry(crAddress, backend) + require.NoError(t, err) + + ccAddress, _, _, err := ccip_config.DeployCCIPConfig(owner, backend, crAddress) + require.NoError(t, err) + backend.Commit() + + capabilityConfig, err := ccip_config.NewCCIPConfig(ccAddress, backend) + require.NoError(t, err) + + _, err = capabilityRegistry.AddCapabilities(owner, []kcr.CapabilitiesRegistryCapability{ + { + LabelledName: CapabilityLabelledName, + Version: CapabilityVersion, + CapabilityType: 2, // consensus. not used (?) + ResponseType: 0, // report. not used (?) + ConfigurationContract: ccAddress, + }, + }) + require.NoError(t, err, "failed to add capabilities to the capability registry") + backend.Commit() + + return homeChain{ + backend: backend, + owner: owner, + chainID: homeChainID, + capabilityRegistry: capabilityRegistry, + ccipConfigContract: capabilityConfig.Address(), + } +} + +func connectUniverses( + t *testing.T, + universes map[uint64]onchainUniverse, +) { + for _, uni := range universes { + wireRouter(t, uni, universes) + wireOnRamp(t, uni, universes) + wireOffRamp(t, uni, universes) + initRemoteChainsGasPrices(t, uni, universes) + } +} + +// setupUniverseBasics sets up the initial configurations for the CCIP contracts on a single chain. +// 1. Mint 1000 LINK to the owner +// 2. Set the price registry with local token prices +// 3. Authorize the onRamp and offRamp on the nonce manager +func setupUniverseBasics(t *testing.T, uni onchainUniverse) { + //============================================================================= + // Universe specific updates/configs + // These updates are specific to each universe and are set up here + // These updates don't depend on other chains + //============================================================================= + owner := uni.owner + //============================================================================= + // Mint 1000 LINK to owner + //============================================================================= + _, err := uni.linkToken.GrantMintRole(owner, owner.From) + require.NoError(t, err) + _, err = uni.linkToken.Mint(owner, owner.From, e18Mult(1000)) + require.NoError(t, err) + uni.backend.Commit() + + //============================================================================= + // Price updates for tokens + // These are the prices of the fee tokens of local chain in USD + //============================================================================= + tokenPriceUpdates := []price_registry.InternalTokenPriceUpdate{ + { + SourceToken: uni.linkToken.Address(), + UsdPerToken: e18Mult(20), + }, + { + SourceToken: uni.weth.Address(), + UsdPerToken: e18Mult(4000), + }, + } + _, err = uni.priceRegistry.UpdatePrices(owner, price_registry.InternalPriceUpdates{ + TokenPriceUpdates: tokenPriceUpdates, + }) + require.NoErrorf(t, err, "failed to apply price registry updates on chain id %d", uni.chainID) + uni.backend.Commit() + + //============================================================================= + // Authorize OnRamp & OffRamp on NonceManager + // Otherwise the onramp will not be able to call the nonceManager to get next Nonce + //============================================================================= + authorizedCallersAuthorizedCallerArgs := nonce_manager.AuthorizedCallersAuthorizedCallerArgs{ + AddedCallers: []common.Address{ + uni.onramp.Address(), + uni.offramp.Address(), + }, + } + _, err = uni.nonceManager.ApplyAuthorizedCallerUpdates(owner, authorizedCallersAuthorizedCallerArgs) + require.NoError(t, err) + uni.backend.Commit() +} + +// As we can't change router contract. The contract was expecting onRamp and offRamp per lane and not per chain +// In the new architecture we have only one onRamp and one offRamp per chain. +// hence we add the mapping for all remote chains to the onRamp/offRamp contract of the local chain +func wireRouter(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + owner := uni.owner + var ( + routerOnrampUpdates []router.RouterOnRamp + routerOfframpUpdates []router.RouterOffRamp + ) + for remoteChainID := range universes { + if remoteChainID == uni.chainID { + continue + } + routerOnrampUpdates = append(routerOnrampUpdates, router.RouterOnRamp{ + DestChainSelector: remoteChainID, + OnRamp: uni.onramp.Address(), + }) + routerOfframpUpdates = append(routerOfframpUpdates, router.RouterOffRamp{ + SourceChainSelector: remoteChainID, + OffRamp: uni.offramp.Address(), + }) + } + _, err := uni.router.ApplyRampUpdates(owner, routerOnrampUpdates, []router.RouterOffRamp{}, routerOfframpUpdates) + require.NoErrorf(t, err, "failed to apply ramp updates on router on chain id %d", uni.chainID) + uni.backend.Commit() +} + +// Setting OnRampDestChainConfigs +func wireOnRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + owner := uni.owner + var onrampDestChainConfigArgs []evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs + for remoteChainID := range universes { + if remoteChainID == uni.chainID { + continue + } + onrampDestChainConfigArgs = append(onrampDestChainConfigArgs, evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainConfigArgs{ + DestChainSelector: remoteChainID, + DynamicConfig: defaultOnRampDynamicConfig(t), + }) + } + _, err := uni.onramp.ApplyDestChainConfigUpdates(owner, onrampDestChainConfigArgs) + require.NoErrorf(t, err, "failed to apply dest chain config updates on onramp on chain id %d", uni.chainID) + uni.backend.Commit() +} + +// Setting OffRampSourceChainConfigs +func wireOffRamp(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + owner := uni.owner + var offrampSourceChainConfigArgs []evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs + for remoteChainID, remoteUniverse := range universes { + if remoteChainID == uni.chainID { + continue + } + offrampSourceChainConfigArgs = append(offrampSourceChainConfigArgs, evm_2_evm_multi_offramp.EVM2EVMMultiOffRampSourceChainConfigArgs{ + SourceChainSelector: remoteChainID, // for each destination chain, add a source chain config + IsEnabled: true, + OnRamp: remoteUniverse.onramp.Address().Bytes(), + }) + } + _, err := uni.offramp.ApplySourceChainConfigUpdates(owner, offrampSourceChainConfigArgs) + require.NoErrorf(t, err, "failed to apply source chain config updates on offramp on chain id %d", uni.chainID) + uni.backend.Commit() +} + +// initRemoteChainsGasPrices sets the gas prices for all chains except the local chain in the local price registry +func initRemoteChainsGasPrices(t *testing.T, uni onchainUniverse, universes map[uint64]onchainUniverse) { + var gasPriceUpdates []price_registry.InternalGasPriceUpdate + for remoteChainID := range universes { + if remoteChainID == uni.chainID { + continue + } + gasPriceUpdates = append(gasPriceUpdates, + price_registry.InternalGasPriceUpdate{ + DestChainSelector: remoteChainID, + UsdPerUnitGas: big.NewInt(2e12), + }, + ) + } + _, err := uni.priceRegistry.UpdatePrices(uni.owner, price_registry.InternalPriceUpdates{ + GasPriceUpdates: gasPriceUpdates, + }) + require.NoError(t, err) +} + +func defaultOnRampDynamicConfig(t *testing.T) evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainDynamicConfig { + // https://github.com/smartcontractkit/ccip/blob/c4856b64bd766f1ddbaf5d13b42d3c4b12efde3a/contracts/src/v0.8/ccip/libraries/Internal.sol#L337-L337 + /* + ```Solidity + // bytes4(keccak256("CCIP ChainFamilySelector EVM")) + bytes4 public constant CHAIN_FAMILY_SELECTOR_EVM = 0x2812d52c; + ``` + */ + evmFamilySelector, err := hex.DecodeString("2812d52c") + require.NoError(t, err) + return evm_2_evm_multi_onramp.EVM2EVMMultiOnRampDestChainDynamicConfig{ + IsEnabled: true, + MaxNumberOfTokensPerMsg: 10, + MaxDataBytes: 256, + MaxPerMsgGasLimit: 3_000_000, + DestGasOverhead: 50_000, + DefaultTokenFeeUSDCents: 1, + DestGasPerPayloadByte: 10, + DestDataAvailabilityOverheadGas: 0, + DestGasPerDataAvailabilityByte: 100, + DestDataAvailabilityMultiplierBps: 1, + DefaultTokenDestGasOverhead: 50_000, + DefaultTokenDestBytesOverhead: 32, + DefaultTxGasLimit: 200_000, + GasMultiplierWeiPerEth: 1, + NetworkFeeUSDCents: 1, + ChainFamilySelector: [4]byte(evmFamilySelector), + } +} + +func deployLinkToken(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *link_token.LinkToken { + linkAddr, _, _, err := link_token.DeployLinkToken(owner, backend) + require.NoErrorf(t, err, "failed to deploy link token on chain id %d", chainID) + backend.Commit() + linkToken, err := link_token.NewLinkToken(linkAddr, backend) + require.NoError(t, err) + return linkToken +} + +func deployMockARMContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *mock_arm_contract.MockARMContract { + rmnAddr, _, _, err := mock_arm_contract.DeployMockARMContract(owner, backend) + require.NoErrorf(t, err, "failed to deploy mock arm on chain id %d", chainID) + backend.Commit() + rmn, err := mock_arm_contract.NewMockARMContract(rmnAddr, backend) + require.NoError(t, err) + return rmn +} + +func deployARMProxyContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, rmnAddr common.Address, chainID uint64) *arm_proxy_contract.ARMProxyContract { + rmnProxyAddr, _, _, err := arm_proxy_contract.DeployARMProxyContract(owner, backend, rmnAddr) + require.NoErrorf(t, err, "failed to deploy arm proxy on chain id %d", chainID) + backend.Commit() + rmnProxy, err := arm_proxy_contract.NewARMProxyContract(rmnProxyAddr, backend) + require.NoError(t, err) + return rmnProxy +} + +func deployWETHContract(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *weth9.WETH9 { + wethAddr, _, _, err := weth9.DeployWETH9(owner, backend) + require.NoErrorf(t, err, "failed to deploy weth contract on chain id %d", chainID) + backend.Commit() + weth, err := weth9.NewWETH9(wethAddr, backend) + require.NoError(t, err) + return weth +} + +func deployRouter(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, wethAddr, rmnProxyAddr common.Address, chainID uint64) *router.Router { + routerAddr, _, _, err := router.DeployRouter(owner, backend, wethAddr, rmnProxyAddr) + require.NoErrorf(t, err, "failed to deploy router on chain id %d", chainID) + backend.Commit() + rout, err := router.NewRouter(routerAddr, backend) + require.NoError(t, err) + return rout +} + +func deployPriceRegistry(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, linkAddr, wethAddr common.Address, chainID uint64) *price_registry.PriceRegistry { + priceRegistryAddr, _, _, err := price_registry.DeployPriceRegistry(owner, backend, []common.Address{}, []common.Address{linkAddr, wethAddr}, 24*60*60, []price_registry.PriceRegistryTokenPriceFeedUpdate{}) + require.NoErrorf(t, err, "failed to deploy price registry on chain id %d", chainID) + backend.Commit() + priceRegistry, err := price_registry.NewPriceRegistry(priceRegistryAddr, backend) + require.NoError(t, err) + return priceRegistry +} + +func deployTokenAdminRegistry(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *token_admin_registry.TokenAdminRegistry { + tarAddr, _, _, err := token_admin_registry.DeployTokenAdminRegistry(owner, backend) + require.NoErrorf(t, err, "failed to deploy token admin registry on chain id %d", chainID) + backend.Commit() + tokenAdminRegistry, err := token_admin_registry.NewTokenAdminRegistry(tarAddr, backend) + require.NoError(t, err) + return tokenAdminRegistry +} + +func deployNonceManager(t *testing.T, owner *bind.TransactOpts, backend *backends.SimulatedBackend, chainID uint64) *nonce_manager.NonceManager { + nonceManagerAddr, _, _, err := nonce_manager.DeployNonceManager(owner, backend, []common.Address{owner.From}) + require.NoErrorf(t, err, "failed to deploy nonce_manager on chain id %d", chainID) + backend.Commit() + nonceManager, err := nonce_manager.NewNonceManager(nonceManagerAddr, backend) + require.NoError(t, err) + return nonceManager +} diff --git a/core/services/ocr3/plugins/ccip_integration_tests/ping_pong_test.go b/core/services/ocr3/plugins/ccip_integration_tests/ping_pong_test.go new file mode 100644 index 0000000000..1b1e96693a --- /dev/null +++ b/core/services/ocr3/plugins/ccip_integration_tests/ping_pong_test.go @@ -0,0 +1,95 @@ +package ccip_integration_tests + +import ( + "testing" + + "github.com/ethereum/go-ethereum/accounts/abi/bind" + gethcommon "github.com/ethereum/go-ethereum/common" + + "github.com/stretchr/testify/require" + + "golang.org/x/exp/maps" + + pp "github.com/smartcontractkit/chainlink/v2/core/gethwrappers/ccip/generated/ping_pong_demo" +) + +/* +* Test is setting up 3 chains (let's call them A, B, C), each chain deploys and starts 2 ping pong contracts for the other 2. +* A ---deploy+start---> (pingPongB, pingPongC) +* B ---deploy+start---> (pingPongA, pingPongC) +* C ---deploy+start---> (pingPongA, pingPongB) +* and then checks that each ping pong contract emitted `CCIPSendRequested` event from the expected source to destination. +* Test fails if any wiring between contracts is not correct. + */ +func TestPingPong(t *testing.T) { + _, universes := createUniverses(t, 3) + pingPongs := initializePingPongContracts(t, universes) + for chainID, universe := range universes { + for otherChain, pingPong := range pingPongs[chainID] { + t.Log("PingPong From: ", chainID, " To: ", otherChain) + _, err := pingPong.StartPingPong(universe.owner) + require.NoError(t, err) + universe.backend.Commit() + + logIter, err := universe.onramp.FilterCCIPSendRequested(&bind.FilterOpts{Start: 0}, nil) + require.NoError(t, err) + // Iterate until latest event + for logIter.Next() { + } + log := logIter.Event + require.Equal(t, otherChain, log.DestChainSelector) + require.Equal(t, pingPong.Address(), log.Message.Sender) + chainPingPongAddr := pingPongs[otherChain][chainID].Address().Bytes() + // With chain agnostic addresses we need to pad the address to the correct length if the receiver is zero prefixed + paddedAddr := gethcommon.LeftPadBytes(chainPingPongAddr, len(log.Message.Receiver)) + require.Equal(t, paddedAddr, log.Message.Receiver) + } + } +} + +// InitializeContracts initializes ping pong contracts on all chains and +// connects them all to each other. +func initializePingPongContracts( + t *testing.T, + chainUniverses map[uint64]onchainUniverse, +) map[uint64]map[uint64]*pp.PingPongDemo { + pingPongs := make(map[uint64]map[uint64]*pp.PingPongDemo) + chainIDs := maps.Keys(chainUniverses) + // For each chain initialize N ping pong contracts, where N is the (number of chains - 1) + for chainID, universe := range chainUniverses { + pingPongs[chainID] = make(map[uint64]*pp.PingPongDemo) + for _, chainToConnect := range chainIDs { + if chainToConnect == chainID { + continue // don't connect chain to itself + } + backend := universe.backend + owner := universe.owner + pingPongAddr, _, _, err := pp.DeployPingPongDemo(owner, backend, universe.router.Address(), universe.linkToken.Address()) + require.NoError(t, err) + backend.Commit() + pingPong, err := pp.NewPingPongDemo(pingPongAddr, backend) + require.NoError(t, err) + backend.Commit() + // Fund the ping pong contract with LINK + _, err = universe.linkToken.Transfer(owner, pingPong.Address(), e18Mult(10)) + backend.Commit() + require.NoError(t, err) + pingPongs[chainID][chainToConnect] = pingPong + } + } + + // Set up each ping pong contract to its counterpart on the other chain + for chainID, universe := range chainUniverses { + for chainToConnect, pingPong := range pingPongs[chainID] { + _, err := pingPong.SetCounterpart( + universe.owner, + chainUniverses[chainToConnect].chainID, + // This is the address of the ping pong contract on the other chain + pingPongs[chainToConnect][chainID].Address(), + ) + require.NoError(t, err) + universe.backend.Commit() + } + } + return pingPongs +}