// Code generated by abigen. DO NOT EDIT.
// This file is a generated binding and any manual changes will be lost.

package contracts

import (
	"fmt"
	"math/big"
	"reflect"
	"strings"

	ethereum "github.com/erigontech/erigon"
	"github.com/erigontech/erigon/common"
	"github.com/erigontech/erigon/execution/abi"
	"github.com/erigontech/erigon/execution/abi/bind"
	"github.com/erigontech/erigon/execution/types"
	"github.com/erigontech/erigon/p2p/event"
)

// Reference imports to suppress errors if they are not otherwise used.
var (
	_ = big.NewInt
	_ = strings.NewReader
	_ = ethereum.NotFound
	_ = bind.Bind
	_ = common.Big1
	_ = types.BloomLookup
	_ = event.NewSubscription
	_ = fmt.Errorf
	_ = reflect.ValueOf
)

// IValidatorRegistryUpdate is an auto generated low-level Go binding around an user-defined struct.
type IValidatorRegistryUpdate struct {
	Message   []byte
	Signature []byte
}

// ValidatorRegistryABI is the input ABI used to generate the binding from.
const ValidatorRegistryABI = "[{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"Updated\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"getNumUpdates\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint256\",\"name\":\"i\",\"type\":\"uint256\"}],\"name\":\"getUpdate\",\"outputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"internalType\":\"structIValidatorRegistry.Update\",\"name\":\"\",\"type\":\"tuple\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"message\",\"type\":\"bytes\"},{\"internalType\":\"bytes\",\"name\":\"signature\",\"type\":\"bytes\"}],\"name\":\"update\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"}]"

// ValidatorRegistryBin is the compiled bytecode used for deploying new contracts.
var ValidatorRegistryBin = "0x6080604052348015600e575f5ffd5b506105d18061001c5f395ff3fe608060405234801561000f575f5ffd5b506004361061003e575f3560e01c8062c7c0191461004257806332cb25be146100575780633f37dce214610077575b5f5ffd5b5f546040519081526020015b60405180910390f35b61006a61006536600461029a565b61008c565b60405161004e91906102df565b61008a6100853660046103bf565b6101ef565b005b60408051808201909152606080825260208201525f82815481106100b2576100b2610424565b905f5260205f2090600202016040518060400160405290815f820180546100d890610438565b80601f016020809104026020016040519081016040528092919081815260200182805461010490610438565b801561014f5780601f106101265761010080835404028352916020019161014f565b820191905f5260205f20905b81548152906001019060200180831161013257829003601f168201915b5050505050815260200160018201805461016890610438565b80601f016020809104026020016040519081016040528092919081815260200182805461019490610438565b80156101df5780601f106101b6576101008083540402835291602001916101df565b820191905f5260205f20905b8154815290600101906020018083116101c257829003601f168201915b5050505050815250509050919050565b60408051808201909152828152602081018290525f8054600181018255908052815160029091027f290decd9548b62a8d60345a988386fc84ba6bc95484008f6362f93160ef3e5630190819061024590826104bc565b506020820151600182019061025a90826104bc565b5050507f9796f15c93411b364b7f09bb591d0f77aa4dc399cf0481b8de1c3ce9f10a3a87828260405161028e929190610577565b60405180910390a15050565b5f602082840312156102aa575f5ffd5b5035919050565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b602081525f8251604060208401526102fa60608401826102b1565b90506020840151601f1984830301604085015261031782826102b1565b95945050505050565b634e487b7160e01b5f52604160045260245ffd5b5f82601f830112610343575f5ffd5b813567ffffffffffffffff81111561035d5761035d610320565b604051601f8201601f19908116603f0116810167ffffffffffffffff8111828210171561038c5761038c610320565b6040528181528382016020018510156103a3575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f5f604083850312156103d0575f5ffd5b823567ffffffffffffffff8111156103e6575f5ffd5b6103f285828601610334565b925050602083013567ffffffffffffffff81111561040e575f5ffd5b61041a85828601610334565b9150509250929050565b634e487b7160e01b5f52603260045260245ffd5b600181811c9082168061044c57607f821691505b60208210810361046a57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f8211156104b757805f5260205f20601f840160051c810160208510156104955750805b601f840160051c820191505b818110156104b4575f81556001016104a1565b50505b505050565b815167ffffffffffffffff8111156104d6576104d6610320565b6104ea816104e48454610438565b84610470565b6020601f82116001811461051c575f83156105055750848201515b5f19600385901b1c1916600184901b1784556104b4565b5f84815260208120601f198516915b8281101561054b578785015182556020948501946001909201910161052b565b508482101561056857868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b604081525f61058960408301856102b1565b828103602084015261031781856102b156fea264697066735822122067d82a92125d8b8abb771d1653b4e7dc1bf7bb36c4a98edadd7c6310fa391c0c64736f6c634300081c0033"

// DeployValidatorRegistry deploys a new Ethereum contract, binding an instance of ValidatorRegistry to it.
func DeployValidatorRegistry(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, types.Transaction, *ValidatorRegistry, error) {
	parsed, err := abi.JSON(strings.NewReader(ValidatorRegistryABI))
	if err != nil {
		return common.Address{}, nil, nil, err
	}

	address, tx, contract, err := bind.DeployContract(auth, parsed, common.FromHex(ValidatorRegistryBin), backend)
	if err != nil {
		return common.Address{}, nil, nil, err
	}
	return address, tx, &ValidatorRegistry{ValidatorRegistryCaller: ValidatorRegistryCaller{contract: contract}, ValidatorRegistryTransactor: ValidatorRegistryTransactor{contract: contract}, ValidatorRegistryFilterer: ValidatorRegistryFilterer{contract: contract}}, nil
}

// ValidatorRegistry is an auto generated Go binding around an Ethereum contract.
type ValidatorRegistry struct {
	ValidatorRegistryCaller     // Read-only binding to the contract
	ValidatorRegistryTransactor // Write-only binding to the contract
	ValidatorRegistryFilterer   // Log filterer for contract events
}

// ValidatorRegistryCaller is an auto generated read-only Go binding around an Ethereum contract.
type ValidatorRegistryCaller struct {
	contract *bind.BoundContract // Generic contract wrapper for the low level calls
}

// ValidatorRegistryTransactor is an auto generated write-only Go binding around an Ethereum contract.
type ValidatorRegistryTransactor struct {
	contract *bind.BoundContract // Generic contract wrapper for the low level calls
}

// ValidatorRegistryFilterer is an auto generated log filtering Go binding around an Ethereum contract events.
type ValidatorRegistryFilterer struct {
	contract *bind.BoundContract // Generic contract wrapper for the low level calls
}

// ValidatorRegistrySession is an auto generated Go binding around an Ethereum contract,
// with pre-set call and transact options.
type ValidatorRegistrySession struct {
	Contract     *ValidatorRegistry // Generic contract binding to set the session for
	CallOpts     bind.CallOpts      // Call options to use throughout this session
	TransactOpts bind.TransactOpts  // Transaction auth options to use throughout this session
}

// ValidatorRegistryCallerSession is an auto generated read-only Go binding around an Ethereum contract,
// with pre-set call options.
type ValidatorRegistryCallerSession struct {
	Contract *ValidatorRegistryCaller // Generic contract caller binding to set the session for
	CallOpts bind.CallOpts            // Call options to use throughout this session
}

// ValidatorRegistryTransactorSession is an auto generated write-only Go binding around an Ethereum contract,
// with pre-set transact options.
type ValidatorRegistryTransactorSession struct {
	Contract     *ValidatorRegistryTransactor // Generic contract transactor binding to set the session for
	TransactOpts bind.TransactOpts            // Transaction auth options to use throughout this session
}

// ValidatorRegistryRaw is an auto generated low-level Go binding around an Ethereum contract.
type ValidatorRegistryRaw struct {
	Contract *ValidatorRegistry // Generic contract binding to access the raw methods on
}

// ValidatorRegistryCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract.
type ValidatorRegistryCallerRaw struct {
	Contract *ValidatorRegistryCaller // Generic read-only contract binding to access the raw methods on
}

// ValidatorRegistryTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract.
type ValidatorRegistryTransactorRaw struct {
	Contract *ValidatorRegistryTransactor // Generic write-only contract binding to access the raw methods on
}

// NewValidatorRegistry creates a new instance of ValidatorRegistry, bound to a specific deployed contract.
func NewValidatorRegistry(address common.Address, backend bind.ContractBackend) (*ValidatorRegistry, error) {
	contract, err := bindValidatorRegistry(address, backend, backend, backend)
	if err != nil {
		return nil, err
	}
	return &ValidatorRegistry{ValidatorRegistryCaller: ValidatorRegistryCaller{contract: contract}, ValidatorRegistryTransactor: ValidatorRegistryTransactor{contract: contract}, ValidatorRegistryFilterer: ValidatorRegistryFilterer{contract: contract}}, nil
}

// NewValidatorRegistryCaller creates a new read-only instance of ValidatorRegistry, bound to a specific deployed contract.
func NewValidatorRegistryCaller(address common.Address, caller bind.ContractCaller) (*ValidatorRegistryCaller, error) {
	contract, err := bindValidatorRegistry(address, caller, nil, nil)
	if err != nil {
		return nil, err
	}
	return &ValidatorRegistryCaller{contract: contract}, nil
}

// NewValidatorRegistryTransactor creates a new write-only instance of ValidatorRegistry, bound to a specific deployed contract.
func NewValidatorRegistryTransactor(address common.Address, transactor bind.ContractTransactor) (*ValidatorRegistryTransactor, error) {
	contract, err := bindValidatorRegistry(address, nil, transactor, nil)
	if err != nil {
		return nil, err
	}
	return &ValidatorRegistryTransactor{contract: contract}, nil
}

// NewValidatorRegistryFilterer creates a new log filterer instance of ValidatorRegistry, bound to a specific deployed contract.
func NewValidatorRegistryFilterer(address common.Address, filterer bind.ContractFilterer) (*ValidatorRegistryFilterer, error) {
	contract, err := bindValidatorRegistry(address, nil, nil, filterer)
	if err != nil {
		return nil, err
	}
	return &ValidatorRegistryFilterer{contract: contract}, nil
}

// bindValidatorRegistry binds a generic wrapper to an already deployed contract.
func bindValidatorRegistry(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) {
	parsed, err := abi.JSON(strings.NewReader(ValidatorRegistryABI))
	if err != nil {
		return nil, err
	}
	return bind.NewBoundContract(address, parsed, caller, transactor, filterer), nil
}

// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_ValidatorRegistry *ValidatorRegistryRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
	return _ValidatorRegistry.Contract.ValidatorRegistryCaller.contract.Call(opts, result, method, params...)
}

// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_ValidatorRegistry *ValidatorRegistryRaw) Transfer(opts *bind.TransactOpts) (types.Transaction, error) {
	return _ValidatorRegistry.Contract.ValidatorRegistryTransactor.contract.Transfer(opts)
}

// Transact invokes the (paid) contract method with params as input values.
func (_ValidatorRegistry *ValidatorRegistryRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (types.Transaction, error) {
	return _ValidatorRegistry.Contract.ValidatorRegistryTransactor.contract.Transact(opts, method, params...)
}

// Call invokes the (constant) contract method with params as input values and
// sets the output to result. The result type might be a single field for simple
// returns, a slice of interfaces for anonymous returns and a struct for named
// returns.
func (_ValidatorRegistry *ValidatorRegistryCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error {
	return _ValidatorRegistry.Contract.contract.Call(opts, result, method, params...)
}

// Transfer initiates a plain transaction to move funds to the contract, calling
// its default method if one is available.
func (_ValidatorRegistry *ValidatorRegistryTransactorRaw) Transfer(opts *bind.TransactOpts) (types.Transaction, error) {
	return _ValidatorRegistry.Contract.contract.Transfer(opts)
}

// Transact invokes the (paid) contract method with params as input values.
func (_ValidatorRegistry *ValidatorRegistryTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (types.Transaction, error) {
	return _ValidatorRegistry.Contract.contract.Transact(opts, method, params...)
}

// GetNumUpdates is a free data retrieval call binding the contract method 0x00c7c019.
//
// Solidity: function getNumUpdates() view returns(uint256)
func (_ValidatorRegistry *ValidatorRegistryCaller) GetNumUpdates(opts *bind.CallOpts) (*big.Int, error) {
	var out []interface{}
	err := _ValidatorRegistry.contract.Call(opts, &out, "getNumUpdates")

	if err != nil {
		return *new(*big.Int), err
	}

	out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int)

	return out0, err

}

// GetNumUpdates is a free data retrieval call binding the contract method 0x00c7c019.
//
// Solidity: function getNumUpdates() view returns(uint256)
func (_ValidatorRegistry *ValidatorRegistrySession) GetNumUpdates() (*big.Int, error) {
	return _ValidatorRegistry.Contract.GetNumUpdates(&_ValidatorRegistry.CallOpts)
}

// GetNumUpdates is a free data retrieval call binding the contract method 0x00c7c019.
//
// Solidity: function getNumUpdates() view returns(uint256)
func (_ValidatorRegistry *ValidatorRegistryCallerSession) GetNumUpdates() (*big.Int, error) {
	return _ValidatorRegistry.Contract.GetNumUpdates(&_ValidatorRegistry.CallOpts)
}

// GetUpdate is a free data retrieval call binding the contract method 0x32cb25be.
//
// Solidity: function getUpdate(uint256 i) view returns((bytes,bytes))
func (_ValidatorRegistry *ValidatorRegistryCaller) GetUpdate(opts *bind.CallOpts, i *big.Int) (IValidatorRegistryUpdate, error) {
	var out []interface{}
	err := _ValidatorRegistry.contract.Call(opts, &out, "getUpdate", i)

	if err != nil {
		return *new(IValidatorRegistryUpdate), err
	}

	out0 := *abi.ConvertType(out[0], new(IValidatorRegistryUpdate)).(*IValidatorRegistryUpdate)

	return out0, err

}

// GetUpdate is a free data retrieval call binding the contract method 0x32cb25be.
//
// Solidity: function getUpdate(uint256 i) view returns((bytes,bytes))
func (_ValidatorRegistry *ValidatorRegistrySession) GetUpdate(i *big.Int) (IValidatorRegistryUpdate, error) {
	return _ValidatorRegistry.Contract.GetUpdate(&_ValidatorRegistry.CallOpts, i)
}

// GetUpdate is a free data retrieval call binding the contract method 0x32cb25be.
//
// Solidity: function getUpdate(uint256 i) view returns((bytes,bytes))
func (_ValidatorRegistry *ValidatorRegistryCallerSession) GetUpdate(i *big.Int) (IValidatorRegistryUpdate, error) {
	return _ValidatorRegistry.Contract.GetUpdate(&_ValidatorRegistry.CallOpts, i)
}

// Update is a paid mutator transaction binding the contract method 0x3f37dce2.
//
// Solidity: function update(bytes message, bytes signature) returns()
func (_ValidatorRegistry *ValidatorRegistryTransactor) Update(opts *bind.TransactOpts, message []byte, signature []byte) (types.Transaction, error) {
	return _ValidatorRegistry.contract.Transact(opts, "update", message, signature)
}

// Update is a paid mutator transaction binding the contract method 0x3f37dce2.
//
// Solidity: function update(bytes message, bytes signature) returns()
func (_ValidatorRegistry *ValidatorRegistrySession) Update(message []byte, signature []byte) (types.Transaction, error) {
	return _ValidatorRegistry.Contract.Update(&_ValidatorRegistry.TransactOpts, message, signature)
}

// Update is a paid mutator transaction binding the contract method 0x3f37dce2.
//
// Solidity: function update(bytes message, bytes signature) returns()
func (_ValidatorRegistry *ValidatorRegistryTransactorSession) Update(message []byte, signature []byte) (types.Transaction, error) {
	return _ValidatorRegistry.Contract.Update(&_ValidatorRegistry.TransactOpts, message, signature)
}

// ValidatorRegistryUpdateParams is an auto generated read-only Go binding of transcaction calldata params
type ValidatorRegistryUpdateParams struct {
	Param_message   []byte
	Param_signature []byte
}

// Parse Update method from calldata of a transaction
//
// Solidity: function update(bytes message, bytes signature) returns()
func ParseValidatorRegistryUpdateParams(calldata []byte) (*ValidatorRegistryUpdateParams, error) {
	if len(calldata) <= 4 {
		return nil, fmt.Errorf("invalid calldata input")
	}

	_abi, err := abi.JSON(strings.NewReader(ValidatorRegistryABI))
	if err != nil {
		return nil, fmt.Errorf("failed to get abi of registry metadata: %w", err)
	}

	out, err := _abi.Methods["update"].Inputs.Unpack(calldata[4:])
	if err != nil {
		return nil, fmt.Errorf("failed to unpack update params data: %w", err)
	}

	var paramsResult = new(ValidatorRegistryUpdateParams)
	value := reflect.ValueOf(paramsResult).Elem()

	if value.NumField() != len(out) {
		return nil, fmt.Errorf("failed to match calldata with param field number")
	}

	out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte)
	out1 := *abi.ConvertType(out[1], new([]byte)).(*[]byte)

	return &ValidatorRegistryUpdateParams{
		Param_message: out0, Param_signature: out1,
	}, nil
}

// ValidatorRegistryUpdatedIterator is returned from FilterUpdated and is used to iterate over the raw logs and unpacked data for Updated events raised by the ValidatorRegistry contract.
type ValidatorRegistryUpdatedIterator struct {
	Event *ValidatorRegistryUpdated // Event containing the contract specifics and raw log

	contract *bind.BoundContract // Generic contract to use for unpacking event data
	event    string              // Event name to use for unpacking event data

	logs chan types.Log        // Log channel receiving the found contract events
	sub  ethereum.Subscription // Subscription for errors, completion and termination
	done bool                  // Whether the subscription completed delivering logs
	fail error                 // Occurred error to stop iteration
}

// Next advances the iterator to the subsequent event, returning whether there
// are any more events found. In case of a retrieval or parsing error, false is
// returned and Error() can be queried for the exact failure.
func (it *ValidatorRegistryUpdatedIterator) Next() bool {
	// If the iterator failed, stop iterating
	if it.fail != nil {
		return false
	}
	// If the iterator completed, deliver directly whatever's available
	if it.done {
		select {
		case log := <-it.logs:
			it.Event = new(ValidatorRegistryUpdated)
			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
		}
	}
	// Iterator still in progress, wait for either a data or an error event
	select {
	case log := <-it.logs:
		it.Event = new(ValidatorRegistryUpdated)
		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()
	}
}

// Error returns any retrieval or parsing error occurred during filtering.
func (it *ValidatorRegistryUpdatedIterator) Error() error {
	return it.fail
}

// Close terminates the iteration process, releasing any pending underlying
// resources.
func (it *ValidatorRegistryUpdatedIterator) Close() error {
	it.sub.Unsubscribe()
	return nil
}

// ValidatorRegistryUpdated represents a Updated event raised by the ValidatorRegistry contract.
type ValidatorRegistryUpdated struct {
	Message   []byte
	Signature []byte
	Raw       types.Log // Blockchain specific contextual infos
}

func (_ValidatorRegistry *ValidatorRegistryFilterer) UpdatedEventID() common.Hash {
	return common.HexToHash("0x9796f15c93411b364b7f09bb591d0f77aa4dc399cf0481b8de1c3ce9f10a3a87")
}

// FilterUpdated is a free log retrieval operation binding the contract event 0x9796f15c93411b364b7f09bb591d0f77aa4dc399cf0481b8de1c3ce9f10a3a87.
//
// Solidity: event Updated(bytes message, bytes signature)
func (_ValidatorRegistry *ValidatorRegistryFilterer) FilterUpdated(opts *bind.FilterOpts) (*ValidatorRegistryUpdatedIterator, error) {

	logs, sub, err := _ValidatorRegistry.contract.FilterLogs(opts, "Updated")
	if err != nil {
		return nil, err
	}
	return &ValidatorRegistryUpdatedIterator{contract: _ValidatorRegistry.contract, event: "Updated", logs: logs, sub: sub}, nil
}

// WatchUpdated is a free log subscription operation binding the contract event 0x9796f15c93411b364b7f09bb591d0f77aa4dc399cf0481b8de1c3ce9f10a3a87.
//
// Solidity: event Updated(bytes message, bytes signature)
func (_ValidatorRegistry *ValidatorRegistryFilterer) WatchUpdated(opts *bind.WatchOpts, sink chan<- *ValidatorRegistryUpdated) (event.Subscription, error) {

	logs, sub, err := _ValidatorRegistry.contract.WatchLogs(opts, "Updated")
	if err != nil {
		return nil, err
	}
	return event.NewSubscription(func(quit <-chan struct{}) error {
		defer sub.Unsubscribe()
		for {
			select {
			case log := <-logs:
				// New log arrived, parse the event and forward to the user
				event := new(ValidatorRegistryUpdated)
				if err := _ValidatorRegistry.contract.UnpackLog(event, "Updated", 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
}

// ParseUpdated is a log parse operation binding the contract event 0x9796f15c93411b364b7f09bb591d0f77aa4dc399cf0481b8de1c3ce9f10a3a87.
//
// Solidity: event Updated(bytes message, bytes signature)
func (_ValidatorRegistry *ValidatorRegistryFilterer) ParseUpdated(log types.Log) (*ValidatorRegistryUpdated, error) {
	event := new(ValidatorRegistryUpdated)
	if err := _ValidatorRegistry.contract.UnpackLog(event, "Updated", log); err != nil {
		return nil, err
	}
	event.Raw = log
	return event, nil
}
