Search Apps Documentation Source Content File Folder Download Copy Actions Download State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

connection.gno

6.04 Kb · 149 lines
  1package core
  2
  3import (
  4	"gno.land/p/onbloc/ibc/union/types"
  5	core "gno.land/r/onbloc/ibc/union/core"
  6)
  7
  8// connection.gno: the connection handshake logic. The admin gate stays on the
  9// proxy entrypoint; this realm holds the protocol logic. The Force* recovery
 10// variants (no proof verification) remain on the proxy as admin operations.
 11
 12// ConnectionOpenInit starts a connection in the Init state.
 13func (c *coreV1) ConnectionOpenInit(_ int, rlm realm, msg types.MsgConnectionOpenInit) {
 14	assertIsRlmCurrent(0, rlm)
 15
 16	connectionId := c.store.NextConnectionId(0, rlm)
 17	connection := core.NewConnection(types.ConnectionStateInit, msg.ClientId, msg.CounterpartyClientId, 0)
 18	c.store.SaveConnection(0, rlm, connectionId, connection)
 19	core.EmitConnectionOpenInit(0, rlm, connectionId, msg.ClientId, msg.CounterpartyClientId)
 20}
 21
 22// ConnectionOpenTry acknowledges a counterparty Init by proving it and moving to
 23// TryOpen.
 24func (c *coreV1) ConnectionOpenTry(_ int, rlm realm, msg types.MsgConnectionOpenTry) {
 25	assertIsRlmCurrent(0, rlm)
 26
 27	c.connectionOpenTry(0, rlm, msg, true)
 28}
 29
 30// ForceConnectionOpenTry is the admin recovery variant of ConnectionOpenTry that
 31// skips counterparty proof verification.
 32func (c *coreV1) ForceConnectionOpenTry(_ int, rlm realm, msg types.MsgConnectionOpenTry) {
 33	assertIsRlmCurrent(0, rlm)
 34
 35	c.connectionOpenTry(0, rlm, msg, false)
 36}
 37
 38func (c *coreV1) connectionOpenTry(_ int, rlm realm, msg types.MsgConnectionOpenTry, verify bool) {
 39	connectionId := c.store.NextConnectionId(0, rlm)
 40	connection := core.NewConnection(types.ConnectionStateTryOpen, msg.ClientId, msg.CounterpartyClientId, msg.CounterpartyConnectionId)
 41
 42	if verify {
 43		expectedConnection := core.NewConnection(types.ConnectionStateInit, msg.CounterpartyClientId, msg.ClientId, 0)
 44		key := types.ConnectionPath(msg.CounterpartyConnectionId)
 45		value := core.ConnectionValue(expectedConnection)
 46		c.verifyMembership(msg.ClientId, types.NewHeight(msg.ProofHeight), msg.ProofInit, key[:], value[:])
 47	}
 48
 49	c.store.SaveConnection(0, rlm, connectionId, connection)
 50	core.EmitConnectionOpenTry(0, rlm, connectionId, msg.ClientId, msg.CounterpartyClientId, msg.CounterpartyConnectionId)
 51}
 52
 53// ConnectionOpenAck proves the counterparty TryOpen and moves the local Init
 54// connection to Open.
 55func (c *coreV1) ConnectionOpenAck(_ int, rlm realm, msg types.MsgConnectionOpenAck) {
 56	assertIsRlmCurrent(0, rlm)
 57
 58	c.connectionOpenAck(0, rlm, msg, true)
 59}
 60
 61// ForceConnectionOpenAck is the admin recovery variant of ConnectionOpenAck that
 62// skips counterparty proof verification.
 63func (c *coreV1) ForceConnectionOpenAck(_ int, rlm realm, msg types.MsgConnectionOpenAck) {
 64	assertIsRlmCurrent(0, rlm)
 65
 66	c.connectionOpenAck(0, rlm, msg, false)
 67}
 68
 69func (c *coreV1) connectionOpenAck(_ int, rlm realm, msg types.MsgConnectionOpenAck, verify bool) {
 70	connection, ok := c.store.GetConnection(msg.ConnectionId)
 71	if !ok {
 72		panic(makeError(core.ErrConnectionNotFound, msg.ConnectionId.String()))
 73	}
 74
 75	if connection.State != types.ConnectionStateInit {
 76		panic(makeError(core.ErrInvalidConnectionState))
 77	}
 78
 79	if verify {
 80		expectedConnection := core.NewConnection(types.ConnectionStateTryOpen, connection.CounterpartyClientId, connection.ClientId, msg.ConnectionId)
 81		key := types.ConnectionPath(msg.CounterpartyConnectionId)
 82		value := core.ConnectionValue(expectedConnection)
 83		c.verifyMembership(connection.ClientId, types.NewHeight(msg.ProofHeight), msg.ProofTry, key[:], value[:])
 84	}
 85
 86	// Build a fresh connection rather than mutating the store-owned one (the
 87	// retrieved value is read-only under the borrow rule).
 88	updated := core.NewConnection(types.ConnectionStateOpen, connection.ClientId, connection.CounterpartyClientId, msg.CounterpartyConnectionId)
 89	c.store.SaveConnection(0, rlm, msg.ConnectionId, updated)
 90
 91	core.EmitConnectionOpenAck(0, rlm, msg.ConnectionId, connection.ClientId, connection.CounterpartyClientId, msg.CounterpartyConnectionId)
 92}
 93
 94// ConnectionOpenConfirm proves the counterparty Open and moves the local TryOpen
 95// connection to Open.
 96func (c *coreV1) ConnectionOpenConfirm(_ int, rlm realm, msg types.MsgConnectionOpenConfirm) {
 97	assertIsRlmCurrent(0, rlm)
 98
 99	c.connectionOpenConfirm(0, rlm, msg, true)
100}
101
102// ForceConnectionOpenConfirm is the admin recovery variant of
103// ConnectionOpenConfirm that skips counterparty proof verification.
104func (c *coreV1) ForceConnectionOpenConfirm(_ int, rlm realm, msg types.MsgConnectionOpenConfirm) {
105	assertIsRlmCurrent(0, rlm)
106
107	c.connectionOpenConfirm(0, rlm, msg, false)
108}
109
110func (c *coreV1) connectionOpenConfirm(_ int, rlm realm, msg types.MsgConnectionOpenConfirm, verify bool) {
111	connection, ok := c.store.GetConnection(msg.ConnectionId)
112	if !ok {
113		panic(makeError(core.ErrConnectionNotFound, msg.ConnectionId.String()))
114	}
115
116	if connection.State != types.ConnectionStateTryOpen {
117		panic(makeError(core.ErrInvalidConnectionState))
118	}
119
120	counterpartyConnectionId := connection.CounterpartyConnectionId
121
122	if verify {
123		expectedConnection := core.NewConnection(types.ConnectionStateOpen, connection.CounterpartyClientId, connection.ClientId, msg.ConnectionId)
124		key := types.ConnectionPath(counterpartyConnectionId)
125		value := core.ConnectionValue(expectedConnection)
126		c.verifyMembership(connection.ClientId, types.NewHeight(msg.ProofHeight), msg.ProofAck, key[:], value[:])
127	}
128
129	// Build a fresh connection rather than mutating the store-owned one.
130	updated := core.NewConnection(types.ConnectionStateOpen, connection.ClientId, connection.CounterpartyClientId, counterpartyConnectionId)
131	c.store.SaveConnection(0, rlm, msg.ConnectionId, updated)
132
133	core.EmitConnectionOpenConfirm(0, rlm, msg.ConnectionId, connection.ClientId, connection.CounterpartyClientId, counterpartyConnectionId)
134}
135
136// ensureConnectionState returns the connection for connectionId, requiring it to
137// be Open.
138func (c *coreV1) ensureConnectionState(connectionId types.ConnectionId) types.Connection {
139	connection, ok := c.store.GetConnection(connectionId)
140	if !ok {
141		panic(makeError(core.ErrConnectionNotFound, connectionId.String()))
142	}
143
144	if connection.State != types.ConnectionStateOpen {
145		panic(makeError(core.ErrInvalidConnectionState))
146	}
147
148	return connection
149}