Repository: hyperledger/firefly
Pull request #1204 (2023-03-07 05:13:33)

Re-poll immediately on full batch
After a rewind to recover from an missed batch (an occurrence of https://github.com/hyperledger/firefly-evmconnect/issues/53) I observed a slow recovery, and the logs seemed to show the Event Aggregator pausing for long periods rather than screaming through all the messages.

Investigating the code, I did not find anything that would prevent it waiting the full time in the case of having read a full page of events. This would mean when paging through old events a long way before the head, it could be very slow to recover.

> Note, you only notice this when in recovery mode after a rewind when events are not arriving frequently - as in that case there are no shoulder taps to naturally wake the event loop.
>
> Also, you only notice this when there is more than a full page (200) inflight pins to resolve, such that the aggregator has to keep spinning through those pages.


Patch:
diff --git a/db/migrations/postgres/000106_add_message_transactions.down.sql b/db/migrations/postgres/000106_add_message_transactions.down.sql
deleted file mode 100644
index fbbdef358..000000000
--- a/db/migrations/postgres/000106_add_message_transactions.down.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-BEGIN;
-ALTER TABLE messages DROP COLUMN tx_id;
-ALTER TABLE messages DROP COLUMN tx_parent_type;
-ALTER TABLE messages DROP COLUMN tx_parent_id;
-COMMIT;
diff --git a/db/migrations/postgres/000106_add_message_transactions.up.sql b/db/migrations/postgres/000106_add_message_transactions.up.sql
deleted file mode 100644
index bd46dccf4..000000000
--- a/db/migrations/postgres/000106_add_message_transactions.up.sql
+++ /dev/null
@@ -1,7 +0,0 @@
-BEGIN;
-ALTER TABLE messages ADD COLUMN tx_id UUID;
-UPDATE messages SET tx_id = batches.tx_id
-  FROM batches WHERE messages.batch_id = batches.id AND messages.tx_id IS NULL;
-ALTER TABLE messages ADD COLUMN tx_parent_type VARCHAR(64);
-ALTER TABLE messages ADD COLUMN tx_parent_id UUID;
-COMMIT;
diff --git a/db/migrations/sqlite/000106_add_message_transactions.down.sql b/db/migrations/sqlite/000106_add_message_transactions.down.sql
deleted file mode 100644
index 6a803891a..000000000
--- a/db/migrations/sqlite/000106_add_message_transactions.down.sql
+++ /dev/null
@@ -1,3 +0,0 @@
-ALTER TABLE messages DROP COLUMN tx_id;
-ALTER TABLE messages DROP COLUMN tx_parent_type;
-ALTER TABLE messages DROP COLUMN tx_parent_id;
diff --git a/db/migrations/sqlite/000106_add_message_transactions.up.sql b/db/migrations/sqlite/000106_add_message_transactions.up.sql
deleted file mode 100644
index e065768d4..000000000
--- a/db/migrations/sqlite/000106_add_message_transactions.up.sql
+++ /dev/null
@@ -1,5 +0,0 @@
-ALTER TABLE messages ADD COLUMN tx_id UUID;
-UPDATE messages SET tx_id = batches.tx_id
-  FROM batches WHERE messages.batch_id = batches.id AND messages.tx_id IS NULL;
-ALTER TABLE messages ADD COLUMN tx_parent_type VARCHAR(64);
-ALTER TABLE messages ADD COLUMN tx_parent_id UUID;
diff --git a/docs/reference/types/message.md b/docs/reference/types/message.md
index a9b0bf492..5dad802f1 100644
--- a/docs/reference/types/message.md
+++ b/docs/reference/types/message.md
@@ -60,7 +60,6 @@ nav_order: 16
 | `localNamespace` | The local namespace of the message | `string` |
 | `hash` | The hash of the message. Derived from the header, which includes the data hash | `Bytes32` |
 | `batch` | The UUID of the batch in which the message was pinned/transferred | [`UUID`](simpletypes#uuid) |
-| `txid` | The ID of the transaction used to order/deliver this message | [`UUID`](simpletypes#uuid) |
 | `state` | The current state of the message | `FFEnum`:<br/>`"staged"`<br/>`"ready"`<br/>`"sent"`<br/>`"pending"`<br/>`"confirmed"`<br/>`"rejected"` |
 | `confirmed` | The timestamp of when the message was confirmed/rejected | [`FFTime`](simpletypes#fftime) |
 | `data` | The list of data elements attached to the message | [`DataRef[]`](#dataref) |
@@ -82,15 +81,6 @@ nav_order: 16
 | `topics` | A message topic associates this message with an ordered stream of data. A custom topic should be assigned - using the default topic is discouraged | `string[]` |
 | `tag` | The message tag indicates the purpose of the message to the applications that process it | `string` |
 | `datahash` | A single hash representing all data in the message. Derived from the array of data ids+hashes attached to this message | `Bytes32` |
-| `txparent` | The parent transaction that originally triggered this message | [`TransactionRef`](#transactionref) |
-
-## TransactionRef
-
-| Field Name | Description | Type |
-|------------|-------------|------|
-| `type` | The type of the FireFly transaction | `FFEnum`: |
-| `id` | The UUID of the FireFly transaction | [`UUID`](simpletypes#uuid) |
-
 
 
 ## DataRef
diff --git a/docs/swagger/swagger.yaml b/docs/swagger/swagger.yaml
index 75050966e..44fbd5f34 100644
--- a/docs/swagger/swagger.yaml
+++ b/docs/swagger/swagger.yaml
@@ -5270,21 +5270,6 @@ paths:
         name: topics
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txid
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.id
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.type
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: txtype
@@ -5542,21 +5527,6 @@ paths:
         name: topics
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txid
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.id
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.type
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: txtype
@@ -5688,18 +5658,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -5755,11 +5713,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -5865,21 +5818,6 @@ paths:
         name: topics
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txid
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.id
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.type
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: txtype
@@ -8026,21 +7964,6 @@ paths:
         name: topics
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txid
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.id
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.type
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: txtype
@@ -8174,18 +8097,6 @@ paths:
                               assigned - using the default topic is discouraged
                             type: string
                           type: array
-                        txparent:
-                          description: The parent transaction that originally triggered
-                            this message
-                          properties:
-                            id:
-                              description: The UUID of the FireFly transaction
-                              format: uuid
-                              type: string
-                            type:
-                              description: The type of the FireFly transaction
-                              type: string
-                          type: object
                         txtype:
                           description: The type of transaction used to order/deliver
                             this message
@@ -8241,11 +8152,6 @@ paths:
                       - confirmed
                       - rejected
                       type: string
-                    txid:
-                      description: The ID of the transaction used to order/deliver
-                        this message
-                      format: uuid
-                      type: string
                   type: object
                 type: array
           description: Success
@@ -8443,18 +8349,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -8510,11 +8404,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -9071,18 +8960,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -9138,11 +9015,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         "202":
@@ -9225,18 +9097,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -9292,11 +9152,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -9549,18 +9404,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -9616,11 +9459,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         "202":
@@ -9709,18 +9547,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -9776,11 +9602,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -10109,18 +9930,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -10176,11 +9985,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -16007,21 +15811,6 @@ paths:
         name: topics
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txid
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.id
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.type
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: txtype
@@ -16293,21 +16082,6 @@ paths:
         name: topics
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txid
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.id
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.type
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: txtype
@@ -16439,18 +16213,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -16506,11 +16268,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -16623,21 +16380,6 @@ paths:
         name: topics
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txid
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.id
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.type
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: txtype
@@ -18896,21 +18638,6 @@ paths:
         name: topics
         schema:
           type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txid
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.id
-        schema:
-          type: string
-      - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
-        in: query
-        name: txparent.type
-        schema:
-          type: string
       - description: 'Data filter field. Prefixes supported: > >= < <= @ ^ ! !@ !^'
         in: query
         name: txtype
@@ -19044,18 +18771,6 @@ paths:
                               assigned - using the default topic is discouraged
                             type: string
                           type: array
-                        txparent:
-                          description: The parent transaction that originally triggered
-                            this message
-                          properties:
-                            id:
-                              description: The UUID of the FireFly transaction
-                              format: uuid
-                              type: string
-                            type:
-                              description: The type of the FireFly transaction
-                              type: string
-                          type: object
                         txtype:
                           description: The type of transaction used to order/deliver
                             this message
@@ -19111,11 +18826,6 @@ paths:
                       - confirmed
                       - rejected
                       type: string
-                    txid:
-                      description: The ID of the transaction used to order/deliver
-                        this message
-                      format: uuid
-                      type: string
                   type: object
                 type: array
           description: Success
@@ -19320,18 +19030,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -19387,11 +19085,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -20020,18 +19713,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -20087,11 +19768,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         "202":
@@ -20180,18 +19856,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -20247,11 +19911,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -20511,18 +20170,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -20578,11 +20225,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         "202":
@@ -20671,18 +20313,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -20738,11 +20368,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
@@ -21078,18 +20703,6 @@ paths:
                             - using the default topic is discouraged
                           type: string
                         type: array
-                      txparent:
-                        description: The parent transaction that originally triggered
-                          this message
-                        properties:
-                          id:
-                            description: The UUID of the FireFly transaction
-                            format: uuid
-                            type: string
-                          type:
-                            description: The type of the FireFly transaction
-                            type: string
-                        type: object
                       txtype:
                         description: The type of transaction used to order/deliver
                           this message
@@ -21145,11 +20758,6 @@ paths:
                     - confirmed
                     - rejected
                     type: string
-                  txid:
-                    description: The ID of the transaction used to order/deliver this
-                      message
-                    format: uuid
-                    type: string
                 type: object
           description: Success
         default:
diff --git a/go.mod b/go.mod
index a1b923b9c..730777f41 100644
--- a/go.mod
+++ b/go.mod
@@ -14,7 +14,7 @@ require (
 	github.com/golang-migrate/migrate/v4 v4.15.2
 	github.com/gorilla/mux v1.8.0
 	github.com/gorilla/websocket v1.5.0
-	github.com/hyperledger/firefly-common v1.2.3
+	github.com/hyperledger/firefly-common v1.2.1
 	github.com/hyperledger/firefly-signer v1.1.5
 	github.com/jarcoal/httpmock v1.2.0
 	github.com/karlseguin/ccache v2.0.3+incompatible
@@ -28,8 +28,8 @@ require (
 	github.com/spf13/viper v1.14.0
 	github.com/stretchr/testify v1.8.1
 	gitlab.com/hfuss/mux-prometheus v0.0.4
-	golang.org/x/net v0.7.0
-	golang.org/x/text v0.7.0
+	golang.org/x/net v0.4.0
+	golang.org/x/text v0.5.0
 	gopkg.in/yaml.v2 v2.4.0
 )
 
@@ -79,8 +79,8 @@ require (
 	github.com/x-cray/logrus-prefixed-formatter v0.5.2 // indirect
 	go.uber.org/atomic v1.10.0 // indirect
 	golang.org/x/crypto v0.4.0 // indirect
-	golang.org/x/sys v0.5.0 // indirect
-	golang.org/x/term v0.5.0 // indirect
+	golang.org/x/sys v0.3.0 // indirect
+	golang.org/x/term v0.3.0 // indirect
 	google.golang.org/protobuf v1.28.1 // indirect
 	gopkg.in/ini.v1 v1.67.0 // indirect
 	gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
diff --git a/go.sum b/go.sum
index d0bdc5d18..e199f70e2 100644
--- a/go.sum
+++ b/go.sum
@@ -674,8 +674,8 @@ github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0m
 github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
 github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
-github.com/hyperledger/firefly-common v1.2.3 h1:6vlCEVUHZn8QdXdu3qrzfKLnzXsBffAKjWFiT9uWhA4=
-github.com/hyperledger/firefly-common v1.2.3/go.mod h1:02hp5BYzAito5JMTjQZluk92xqhL0LxqEEHNENsVcFk=
+github.com/hyperledger/firefly-common v1.2.1 h1:h35T5Ask/ixlW70KZxHpPsO5QfdnKBFEyX+7L10lwoo=
+github.com/hyperledger/firefly-common v1.2.1/go.mod h1:aqaq2ZUzSlkwVC/TF+pwUkHxGDLYSE2DzdozZ1MIMeM=
 github.com/hyperledger/firefly-signer v1.1.5 h1:kCHe4O3tmYaMYf1hXrG40sIlpiGfOICmNNAcuMH5+jQ=
 github.com/hyperledger/firefly-signer v1.1.5/go.mod h1:XZP8ZXUZJSAPB6WUSM9RqRdpjnjm6Jsn0784WM4IKug=
 github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
@@ -1396,8 +1396,8 @@ golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220111093109-d55c255bac03/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
-golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU=
+golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
 golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
@@ -1552,15 +1552,15 @@ golang.org/x/sys v0.0.0-20220317061510-51cd9980dadf/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
-golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.5.0 h1:n2a8QNdAb0sZNpU9R1ALUXBbY+w51fCQDN+7EdxNBsY=
-golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI=
+golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1570,8 +1570,8 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
-golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM=
+golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
diff --git a/internal/assets/token_approval.go b/internal/assets/token_approval.go
index be8a796bf..435e630e1 100644
--- a/internal/assets/token_approval.go
+++ b/internal/assets/token_approval.go
@@ -95,20 +95,8 @@ func (s *approveSender) resolveAndSend(ctx context.Context, method sendMethod) (
 }
 
 func (s *approveSender) resolve(ctx context.Context) (err error) {
-	// Create a transaction and attach to the approval
-	txid, err := s.mgr.txHelper.SubmitNewTransaction(ctx, core.TransactionTypeTokenApproval, s.approval.IdempotencyKey)
-	if err != nil {
-		return err
-	}
-	s.approval.TX.ID = txid
-	s.approval.TX.Type = core.TransactionTypeTokenApproval
-
 	// Resolve the attached message
 	if s.approval.Message != nil {
-		s.approval.Message.Header.TxParent = &core.TransactionRef{
-			ID:   txid,
-			Type: core.TransactionTypeTokenApproval,
-		}
 		s.msgSender, err = s.buildApprovalMessage(ctx, s.approval.Message)
 		if err != nil {
 			return err
@@ -148,10 +136,17 @@ func (s *approveSender) sendInternal(ctx context.Context, method sendMethod) (er
 			return nil
 		}
 
+		txid, err := s.mgr.txHelper.SubmitNewTransaction(ctx, core.TransactionTypeTokenApproval, s.approval.IdempotencyKey)
+		if err != nil {
+			return err
+		}
+		s.approval.TX.ID = txid
+		s.approval.TX.Type = core.TransactionTypeTokenApproval
+
 		op = core.NewOperation(
 			plugin,
 			s.mgr.namespace,
-			s.approval.TX.ID,
+			txid,
 			core.TransactionTypeTokenApproval)
 		if err = txcommon.AddTokenApprovalInputs(op, &s.approval.TokenApproval); err == nil {
 			err = s.mgr.operations.AddOrReuseOperation(ctx, op)
@@ -200,21 +195,19 @@ func (am *assetManager) validateApproval(ctx context.Context, approval *core.Tok
 
 func (s *approveSender) buildApprovalMessage(ctx context.Context, in *core.MessageInOut) (syncasync.Sender, error) {
 	allowedTypes := []fftypes.FFEnum{
-		core.MessageTypeBroadcast,
-		core.MessageTypePrivate,
-		core.MessageTypeDeprecatedApprovalBroadcast,
-		core.MessageTypeDeprecatedApprovalPrivate,
+		core.MessageTypeApprovalBroadcast,
+		core.MessageTypeApprovalPrivate,
 	}
 	if in.Header.Type == "" {
-		in.Header.Type = core.MessageTypeBroadcast
+		in.Header.Type = core.MessageTypeApprovalBroadcast
 	}
 	switch in.Header.Type {
-	case core.MessageTypeBroadcast, core.MessageTypeDeprecatedApprovalBroadcast:
+	case core.MessageTypeApprovalBroadcast:
 		if s.mgr.broadcast == nil {
 			return nil, i18n.NewError(ctx, coremsgs.MsgMessagesNotSupported)
 		}
 		return s.mgr.broadcast.NewBroadcast(in), nil
-	case core.MessageTypePrivate, core.MessageTypeDeprecatedApprovalPrivate:
+	case core.MessageTypeApprovalPrivate:
 		if s.mgr.messaging == nil {
 			return nil, i18n.NewError(ctx, coremsgs.MsgMessagesNotSupported)
 		}
diff --git a/internal/assets/token_transfer.go b/internal/assets/token_transfer.go
index 1c3ef1663..86cc2e7a6 100644
--- a/internal/assets/token_transfer.go
+++ b/internal/assets/token_transfer.go
@@ -181,20 +181,8 @@ func (s *transferSender) resolveAndSend(ctx context.Context, method sendMethod)
 }
 
 func (s *transferSender) resolve(ctx context.Context) (err error) {
-	// Create a transaction and attach to the transfer
-	txid, err := s.mgr.txHelper.SubmitNewTransaction(ctx, core.TransactionTypeTokenTransfer, s.transfer.IdempotencyKey)
-	if err != nil {
-		return err
-	}
-	s.transfer.TX.ID = txid
-	s.transfer.TX.Type = core.TransactionTypeTokenTransfer
-
 	// Resolve the attached message
 	if s.transfer.Message != nil {
-		s.transfer.Message.Header.TxParent = &core.TransactionRef{
-			ID:   txid,
-			Type: core.TransactionTypeTokenTransfer,
-		}
 		s.msgSender, err = s.buildTransferMessage(ctx, s.transfer.Message)
 		if err != nil {
 			return err
@@ -237,10 +225,17 @@ func (s *transferSender) sendInternal(ctx context.Context, method sendMethod) (e
 			return nil
 		}
 
+		txid, err := s.mgr.txHelper.SubmitNewTransaction(ctx, core.TransactionTypeTokenTransfer, s.transfer.IdempotencyKey)
+		if err != nil {
+			return err
+		}
+		s.transfer.TX.ID = txid
+		s.transfer.TX.Type = core.TransactionTypeTokenTransfer
+
 		op = core.NewOperation(
 			plugin,
 			s.mgr.namespace,
-			s.transfer.TX.ID,
+			txid,
 			core.OpTypeTokenTransfer)
 		if err = txcommon.AddTokenTransferInputs(op, &s.transfer.TokenTransfer); err == nil {
 			err = s.mgr.operations.AddOrReuseOperation(ctx, op)
@@ -267,21 +262,19 @@ func (s *transferSender) sendInternal(ctx context.Context, method sendMethod) (e
 
 func (s *transferSender) buildTransferMessage(ctx context.Context, in *core.MessageInOut) (syncasync.Sender, error) {
 	allowedTypes := []fftypes.FFEnum{
-		core.MessageTypeBroadcast,
-		core.MessageTypePrivate,
-		core.MessageTypeDeprecatedTransferBroadcast,
-		core.MessageTypeDeprecatedTransferPrivate,
+		core.MessageTypeTransferBroadcast,
+		core.MessageTypeTransferPrivate,
 	}
 	if in.Header.Type == "" {
-		in.Header.Type = core.MessageTypeBroadcast
+		in.Header.Type = core.MessageTypeTransferBroadcast
 	}
 	switch in.Header.Type {
-	case core.MessageTypeBroadcast, core.MessageTypeDeprecatedTransferBroadcast:
+	case core.MessageTypeTransferBroadcast:
 		if s.mgr.broadcast == nil {
 			return nil, i18n.NewError(ctx, coremsgs.MsgMessagesNotSupported)
 		}
 		return s.mgr.broadcast.NewBroadcast(in), nil
-	case core.MessageTypePrivate, core.MessageTypeDeprecatedTransferPrivate:
+	case core.MessageTypeTransferPrivate:
 		if s.mgr.messaging == nil {
 			return nil, i18n.NewError(ctx, coremsgs.MsgMessagesNotSupported)
 		}
diff --git a/internal/batch/batch_processor.go b/internal/batch/batch_processor.go
index 011a6559d..2887b8745 100644
--- a/internal/batch/batch_processor.go
+++ b/internal/batch/batch_processor.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -614,7 +614,6 @@ func (bp *batchProcessor) markPayloadDispatched(state *DispatchState) error {
 			for i, msg := range state.Messages {
 				msgIDs[i] = msg.Header.ID
 				msg.BatchID = state.Persisted.ID
-				msg.TransactionID = state.Persisted.TX.ID
 				if bp.conf.txType == core.TransactionTypeBatchPin {
 					msg.State = core.MessageStateSent
 				} else {
@@ -635,16 +634,14 @@ func (bp *batchProcessor) markPayloadDispatched(state *DispatchState) error {
 			if bp.conf.txType == core.TransactionTypeBatchPin {
 				// Sent state waiting for confirm
 				allMsgsUpdate = database.MessageQueryFactory.NewUpdate(ctx).
-					Set("batch", state.Persisted.ID).    // Mark the batch they are in
-					Set("state", core.MessageStateSent). // Set them sent, so they won't be picked up and re-sent after restart/rewind
-					Set("txid", state.Persisted.TX.ID)
+					Set("batch", state.Persisted.ID).   // Mark the batch they are in
+					Set("state", core.MessageStateSent) // Set them sent, so they won't be picked up and re-sent after restart/rewind
 			} else {
 				// Immediate confirmation if no batch pinning
 				allMsgsUpdate = database.MessageQueryFactory.NewUpdate(ctx).
 					Set("batch", state.Persisted.ID).
 					Set("state", core.MessageStateConfirmed).
-					Set("confirmed", confirmTime).
-					Set("txid", state.Persisted.TX.ID)
+					Set("confirmed", confirmTime)
 			}
 
 			if err = bp.database.UpdateMessages(ctx, bp.bm.namespace, filter, allMsgsUpdate); err != nil {
diff --git a/internal/broadcast/manager.go b/internal/broadcast/manager.go
index d6db99676..f47234a8c 100644
--- a/internal/broadcast/manager.go
+++ b/internal/broadcast/manager.go
@@ -109,8 +109,8 @@ func NewBroadcastManager(ctx context.Context, ns *core.Namespace, di database.Pl
 			[]core.MessageType{
 				core.MessageTypeBroadcast,
 				core.MessageTypeDefinition,
-				core.MessageTypeDeprecatedTransferBroadcast,
-				core.MessageTypeDeprecatedApprovalBroadcast,
+				core.MessageTypeTransferBroadcast,
+				core.MessageTypeApprovalBroadcast,
 			}, bm.dispatchBatch, bo)
 	}
 
diff --git a/internal/coremsgs/en_struct_descriptions.go b/internal/coremsgs/en_struct_descriptions.go
index b6022c596..10ab03124 100644
--- a/internal/coremsgs/en_struct_descriptions.go
+++ b/internal/coremsgs/en_struct_descriptions.go
@@ -58,7 +58,6 @@ var (
 	MessageHeaderTopics    = ffm("MessageHeader.topics", "A message topic associates this message with an ordered stream of data. A custom topic should be assigned - using the default topic is discouraged")
 	MessageHeaderTag       = ffm("MessageHeader.tag", "The message tag indicates the purpose of the message to the applications that process it")
 	MessageHeaderDataHash  = ffm("MessageHeader.datahash", "A single hash representing all data in the message. Derived from the array of data ids+hashes attached to this message")
-	MessageTxParent        = ffm("MessageHeader.txparent", "The parent transaction that originally triggered this message")
 
 	// Message field descriptions
 	MessageHeader         = ffm("Message.header", "The message header contains all fields that are used to build the message hash")
@@ -69,7 +68,6 @@ var (
 	MessageConfirmed      = ffm("Message.confirmed", "The timestamp of when the message was confirmed/rejected")
 	MessageData           = ffm("Message.data", "The list of data elements attached to the message")
 	MessagePins           = ffm("Message.pins", "For private messages, a unique pin hash:nonce is assigned for each topic")
-	MessageTransactionID  = ffm("Message.txid", "The ID of the transaction used to order/deliver this message")
 	MessageIdempotencyKey = ffm("Message.idempotencyKey", "An optional unique identifier for a message. Cannot be duplicated within a namespace, thus allowing idempotent submission of messages to the API. Local only - not transferred when the message is sent to other members of the network")
 
 	// MessageInOut field descriptions
diff --git a/internal/database/sqlcommon/blob_sql.go b/internal/database/sqlcommon/blob_sql.go
index f702eb7c5..98a8fb8cb 100644
--- a/internal/database/sqlcommon/blob_sql.go
+++ b/internal/database/sqlcommon/blob_sql.go
@@ -88,7 +88,7 @@ func (s *SQLCommon) InsertBlobs(ctx context.Context, blobs []*core.Blob) (err er
 	}
 	defer s.RollbackTx(ctx, tx, autoCommit)
 
-	if s.Features().MultiRowInsert {
+	if s.features.MultiRowInsert {
 		query := sq.Insert(blobsTable).Columns(blobColumns...)
 		for _, blob := range blobs {
 			query = s.setBlobInsertValues(query, blob)
diff --git a/internal/database/sqlcommon/data_sql.go b/internal/database/sqlcommon/data_sql.go
index 4657874cc..d2faa656d 100644
--- a/internal/database/sqlcommon/data_sql.go
+++ b/internal/database/sqlcommon/data_sql.go
@@ -195,7 +195,7 @@ func (s *SQLCommon) InsertDataArray(ctx context.Context, dataArray core.DataArra
 	}
 	defer s.RollbackTx(ctx, tx, autoCommit)
 
-	if s.Features().MultiRowInsert {
+	if s.features.MultiRowInsert {
 		query := sq.Insert(dataTable).Columns(dataColumnsWithValue...)
 		for _, data := range dataArray {
 			query = s.setDataInsertValues(query, data)
diff --git a/internal/database/sqlcommon/event_sql.go b/internal/database/sqlcommon/event_sql.go
index 574add68e..2af652559 100644
--- a/internal/database/sqlcommon/event_sql.go
+++ b/internal/database/sqlcommon/event_sql.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -118,7 +118,7 @@ func (p *eventsPCA) PreCommit(ctx context.Context, tx *dbsql.TXWrapper) (err err
 		}
 	}
 
-	if p.s.Features().MultiRowInsert {
+	if p.s.features.MultiRowInsert {
 		query := sq.Insert(eventsTable).Columns(eventColumns...)
 		for _, event := range p.events {
 			query = p.s.setEventInsertValues(query, event)
diff --git a/internal/database/sqlcommon/message_sql.go b/internal/database/sqlcommon/message_sql.go
index c1339a4c4..a3e97659e 100644
--- a/internal/database/sqlcommon/message_sql.go
+++ b/internal/database/sqlcommon/message_sql.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -51,18 +51,12 @@ var (
 		"state",
 		"confirmed",
 		"tx_type",
-		"tx_id",
-		"tx_parent_type",
-		"tx_parent_id",
 		"batch_id",
 		"idempotency_key",
 	}
 	msgFilterFieldMap = map[string]string{
 		"type":           "mtype",
 		"txtype":         "tx_type",
-		"txid":           "tx_id",
-		"txparent.type":  "tx_parent_type",
-		"txparent.id":    "tx_parent_id",
 		"batch":          "batch_id",
 		"group":          "group_hash",
 		"idempotencykey": "idempotency_key",
@@ -73,13 +67,6 @@ const messagesTable = "messages"
 const messagesDataJoinTable = "messages_data"
 
 func (s *SQLCommon) attemptMessageUpdate(ctx context.Context, tx *dbsql.TXWrapper, message *core.Message) (int64, error) {
-	var txParentID *fftypes.UUID
-	var txParentType core.TransactionType
-	if message.Header.TxParent != nil {
-		txParentID = message.Header.TxParent.ID
-		txParentType = message.Header.TxParent.Type
-	}
-
 	return s.UpdateTx(ctx, messagesTable, tx,
 		sq.Update(messagesTable).
 			Set("cid", message.Header.CID).
@@ -96,9 +83,6 @@ func (s *SQLCommon) attemptMessageUpdate(ctx context.Context, tx *dbsql.TXWrappe
 			Set("state", message.State).
 			Set("confirmed", message.Confirmed).
 			Set("tx_type", message.Header.TxType).
-			Set("tx_id", message.TransactionID).
-			Set("tx_parent_type", txParentType).
-			Set("tx_parent_id", txParentID).
 			Set("batch_id", message.BatchID).
 			Set("idempotency_key", message.IdempotencyKey).
 			Where(sq.Eq{
@@ -113,13 +97,6 @@ func (s *SQLCommon) attemptMessageUpdate(ctx context.Context, tx *dbsql.TXWrappe
 }
 
 func (s *SQLCommon) setMessageInsertValues(query sq.InsertBuilder, message *core.Message) sq.InsertBuilder {
-	var txParentID *fftypes.UUID
-	var txParentType core.TransactionType
-	if message.Header.TxParent != nil {
-		txParentID = message.Header.TxParent.ID
-		txParentType = message.Header.TxParent.Type
-	}
-
 	return query.Values(
 		message.Header.ID,
 		message.Header.CID,
@@ -138,9 +115,6 @@ func (s *SQLCommon) setMessageInsertValues(query sq.InsertBuilder, message *core
 		message.State,
 		message.Confirmed,
 		message.Header.TxType,
-		message.TransactionID,
-		txParentType,
-		txParentID,
 		message.BatchID,
 		message.IdempotencyKey,
 	)
@@ -236,7 +210,8 @@ func (s *SQLCommon) InsertMessages(ctx context.Context, messages []*core.Message
 		return err
 	}
 	defer s.RollbackTx(ctx, tx, autoCommit)
-	if s.Features().MultiRowInsert {
+
+	if s.features.MultiRowInsert {
 		msgQuery := sq.Insert(messagesTable).Columns(msgColumns...)
 		dataRefQuery := sq.Insert(messagesDataJoinTable).Columns(
 			"namespace",
@@ -432,7 +407,6 @@ func (s *SQLCommon) loadDataRefs(ctx context.Context, namespace string, msgs []*
 
 func (s *SQLCommon) msgResult(ctx context.Context, row *sql.Rows) (*core.Message, error) {
 	var msg core.Message
-	var txParent core.TransactionRef
 	err := row.Scan(
 		&msg.Header.ID,
 		&msg.Header.CID,
@@ -451,9 +425,6 @@ func (s *SQLCommon) msgResult(ctx context.Context, row *sql.Rows) (*core.Message
 		&msg.State,
 		&msg.Confirmed,
 		&msg.Header.TxType,
-		&msg.TransactionID,
-		&txParent.Type,
-		&txParent.ID,
 		&msg.BatchID,
 		&msg.IdempotencyKey,
 		// Must be added to the list of columns in all selects
@@ -462,9 +433,6 @@ func (s *SQLCommon) msgResult(ctx context.Context, row *sql.Rows) (*core.Message
 	if err != nil {
 		return nil, i18n.WrapError(ctx, err, coremsgs.MsgDBReadErr, messagesTable)
 	}
-	if txParent.ID != nil {
-		msg.Header.TxParent = &txParent
-	}
 	return &msg, nil
 }
 
diff --git a/internal/database/sqlcommon/pin_sql.go b/internal/database/sqlcommon/pin_sql.go
index a2961aa40..794073b29 100644
--- a/internal/database/sqlcommon/pin_sql.go
+++ b/internal/database/sqlcommon/pin_sql.go
@@ -124,7 +124,7 @@ func (s *SQLCommon) InsertPins(ctx context.Context, pins []*core.Pin) error {
 	}
 	defer s.RollbackTx(ctx, tx, autoCommit)
 
-	if s.Features().MultiRowInsert {
+	if s.features.MultiRowInsert {
 		query := sq.Insert(pinsTable).Columns(pinColumns...)
 		for _, pin := range pins {
 			query = s.setPinInsertValues(query, pin)
diff --git a/internal/database/sqlcommon/sqlcommon.go b/internal/database/sqlcommon/sqlcommon.go
index 02dbdd8ee..1105604b8 100644
--- a/internal/database/sqlcommon/sqlcommon.go
+++ b/internal/database/sqlcommon/sqlcommon.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2022 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -33,6 +33,7 @@ type SQLCommon struct {
 	dbsql.Database
 	capabilities *database.Capabilities
 	callbacks    callbacks
+	features     dbsql.SQLFeatures
 }
 
 type callbacks struct {
diff --git a/internal/events/aggregator.go b/internal/events/aggregator.go
index 8ccfb7cb4..c7b1b4cd2 100644
--- a/internal/events/aggregator.go
+++ b/internal/events/aggregator.go
@@ -532,18 +532,6 @@ func (ag *aggregator) processMessage(ctx context.Context, manifest *core.BatchMa
 	return nil
 }
 
-func needsTokenTransfer(msg *core.Message) bool {
-	return (msg.Header.TxParent != nil && msg.Header.TxParent.Type == core.TransactionTypeTokenTransfer) ||
-		msg.Header.Type == core.MessageTypeDeprecatedTransferBroadcast ||
-		msg.Header.Type == core.MessageTypeDeprecatedTransferPrivate
-}
-
-func needsTokenApproval(msg *core.Message) bool {
-	return (msg.Header.TxParent != nil && msg.Header.TxParent.Type == core.TransactionTypeTokenApproval) ||
-		msg.Header.Type == core.MessageTypeDeprecatedApprovalBroadcast ||
-		msg.Header.Type == core.MessageTypeDeprecatedApprovalPrivate
-}
-
 func (ag *aggregator) attemptMessageDispatch(ctx context.Context, msg *core.Message, data core.DataArray, tx *fftypes.UUID, state *batchState, pin *core.Pin) (newState core.MessageState, dispatched bool, err error) {
 	var customCorrelator *fftypes.UUID
 
@@ -560,7 +548,7 @@ func (ag *aggregator) attemptMessageDispatch(ctx context.Context, msg *core.Mess
 		}
 
 		// For transfers, verify the transfer has come through
-		if needsTokenTransfer(msg) {
+		if msg.Header.Type == core.MessageTypeTransferBroadcast || msg.Header.Type == core.MessageTypeTransferPrivate {
 			fb := database.TokenTransferQueryFactory.NewFilter(ctx)
 			filter := fb.And(
 				fb.Eq("message", msg.Header.ID),
@@ -575,7 +563,7 @@ func (ag *aggregator) attemptMessageDispatch(ctx context.Context, msg *core.Mess
 		}
 
 		// For approvals, verify the approval has come through
-		if needsTokenApproval(msg) {
+		if msg.Header.Type == core.MessageTypeApprovalBroadcast || msg.Header.Type == core.MessageTypeApprovalPrivate {
 			fb := database.TokenApprovalQueryFactory.NewFilter(ctx)
 			filter := fb.And(
 				fb.Eq("message", msg.Header.ID),
diff --git a/internal/events/event_poller.go b/internal/events/event_poller.go
index 6ffcc4a9b..9d876b6c8 100644
--- a/internal/events/event_poller.go
+++ b/internal/events/event_poller.go
@@ -1,4 +1,4 @@
-// Copyright © 2022 Kaleido, Inc.
+// Copyright © 2023 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -283,9 +283,15 @@ func (ep *eventPoller) shoulderTap() {
 func (ep *eventPoller) waitForShoulderTapOrPollTimeout(lastEventCount int) bool {
 	l := log.L(ep.ctx)
 	longTimeoutDuration := ep.conf.eventPollTimeout
+
+	if lastEventCount >= ep.conf.eventBatchSize {
+		l.Tracef("Polling immediately due to full previous event batch")
+		return true
+	}
+
 	// For throughput optimized environments, we can set an eventBatchingTimeout to allow messages to arrive
 	// between polling cycles (at the cost of some dispatch latency)
-	if ep.conf.eventBatchTimeout > 0 && lastEventCount > 0 && lastEventCount < ep.conf.eventBatchSize {
+	if ep.conf.eventBatchTimeout > 0 && lastEventCount > 0 {
 		shortTimeout := time.NewTimer(ep.conf.eventBatchTimeout)
 		select {
 		case <-shortTimeout.C:
diff --git a/internal/events/persist_batch.go b/internal/events/persist_batch.go
index 7a9b5131f..4d0cff6fc 100644
--- a/internal/events/persist_batch.go
+++ b/internal/events/persist_batch.go
@@ -108,6 +108,7 @@ func (em *eventManager) validateAndPersistBatchContent(ctx context.Context, batc
 		if valid = em.validateBatchMessage(ctx, batch, i, msg); !valid {
 			return false, nil
 		}
+		msg.LocalNamespace = em.namespace.Name
 	}
 
 	// We require that the batch contains exactly the set of data that is in the messages - no more or less.
@@ -197,9 +198,7 @@ func (em *eventManager) validateBatchMessage(ctx context.Context, batch *core.Ba
 		log.L(ctx).Errorf("Mismatched key/author '%s'/'%s' on message entry %d in batch '%s'", msg.Header.Key, msg.Header.Author, i, batch.ID)
 		return false
 	}
-	msg.LocalNamespace = em.namespace.Name
 	msg.BatchID = batch.ID
-	msg.TransactionID = batch.Payload.TX.ID
 
 	l.Tracef("Batch '%s' message %d: %+v", batch.ID, i, msg)
 
diff --git a/internal/privatemessaging/privatemessaging.go b/internal/privatemessaging/privatemessaging.go
index f03f25230..060d2fb99 100644
--- a/internal/privatemessaging/privatemessaging.go
+++ b/internal/privatemessaging/privatemessaging.go
@@ -141,8 +141,8 @@ func NewPrivateMessaging(ctx context.Context, ns *core.Namespace, di database.Pl
 		[]core.MessageType{
 			core.MessageTypeGroupInit,
 			core.MessageTypePrivate,
-			core.MessageTypeDeprecatedTransferPrivate,
-			core.MessageTypeDeprecatedApprovalPrivate,
+			core.MessageTypeTransferPrivate,
+			core.MessageTypeApprovalPrivate,
 		},
 		pm.dispatchPinnedBatch, bo)
 
diff --git a/pkg/core/message.go b/pkg/core/message.go
index 91994e4ed..0e2925a13 100644
--- a/pkg/core/message.go
+++ b/pkg/core/message.go
@@ -42,14 +42,14 @@ var (
 	MessageTypePrivate = fftypes.FFEnumValue("messagetype", "private")
 	// MessageTypeGroupInit is a special private message that contains the definition of the group
 	MessageTypeGroupInit = fftypes.FFEnumValue("messagetype", "groupinit")
-	// MessageTypeDeprecatedTransferBroadcast is deprecated - use MessageTypeBroadcast (and refer to TxParent.Type)
-	MessageTypeDeprecatedTransferBroadcast = fftypes.FFEnumValue("messagetype", "transfer_broadcast")
-	// MessageTypeDeprecatedTransferPrivate is deprecated - use MessageTypePrivate (and refer to TxParent.Type)
-	MessageTypeDeprecatedTransferPrivate = fftypes.FFEnumValue("messagetype", "transfer_private")
-	// MessageTypeDeprecatedApprovalBroadcast is deprecated - use MessageTypeBroadcast (and refer to TxParent.Type)
-	MessageTypeDeprecatedApprovalBroadcast = fftypes.FFEnumValue("messagetype", "approval_broadcast")
-	// MessageTypeDeprecatedApprovalPrivate is a deprecated - use MessageTypePrivate (and refer to TxParent.Type)
-	MessageTypeDeprecatedApprovalPrivate = fftypes.FFEnumValue("messagetype", "approval_private")
+	// MessageTypeTransferBroadcast is a broadcast message to accompany/annotate a token transfer
+	MessageTypeTransferBroadcast = fftypes.FFEnumValue("messagetype", "transfer_broadcast")
+	// MessageTypeTransferPrivate is a private message to accompany/annotate a token transfer
+	MessageTypeTransferPrivate = fftypes.FFEnumValue("messagetype", "transfer_private")
+	// MessageTypeApprovalBroadcast is a broadcast message to accompany/annotate a token approval
+	MessageTypeApprovalBroadcast = fftypes.FFEnumValue("messagetype", "approval_broadcast")
+	// MessageTypeApprovalPrivate is a private message to accompany/annotate a token approval
+	MessageTypeApprovalPrivate = fftypes.FFEnumValue("messagetype", "approval_private")
 )
 
 // MessageState is the current transmission/confirmation state of a message
@@ -84,7 +84,6 @@ type MessageHeader struct {
 	Topics    fftypes.FFStringArray `ffstruct:"MessageHeader" json:"topics,omitempty"`
 	Tag       string                `ffstruct:"MessageHeader" json:"tag,omitempty"`
 	DataHash  *fftypes.Bytes32      `ffstruct:"MessageHeader" json:"datahash,omitempty" ffexcludeinput:"true"`
-	TxParent  *TransactionRef       `ffstruct:"MessageHeader" json:"txparent,omitempty" ffexcludeinput:"true"`
 }
 
 // Message is the envelope by which coordinated data exchange can happen between parties in the network
@@ -95,7 +94,6 @@ type Message struct {
 	LocalNamespace string                `ffstruct:"Message" json:"localNamespace,omitempty" ffexcludeinput:"true"`
 	Hash           *fftypes.Bytes32      `ffstruct:"Message" json:"hash,omitempty" ffexcludeinput:"true"`
 	BatchID        *fftypes.UUID         `ffstruct:"Message" json:"batch,omitempty" ffexcludeinput:"true"`
-	TransactionID  *fftypes.UUID         `ffstruct:"Message" json:"txid,omitempty" ffexcludeinput:"true"`
 	State          MessageState          `ffstruct:"Message" json:"state,omitempty" ffenum:"messagestate" ffexcludeinput:"true"`
 	Confirmed      *fftypes.FFTime       `ffstruct:"Message" json:"confirmed,omitempty" ffexcludeinput:"true"`
 	Data           DataRefs              `ffstruct:"Message" json:"data" ffexcludeinput:"true"`
diff --git a/pkg/database/plugin.go b/pkg/database/plugin.go
index 1f5bc3456..856b243e0 100644
--- a/pkg/database/plugin.go
+++ b/pkg/database/plugin.go
@@ -698,9 +698,6 @@ var MessageQueryFactory = &ffapi.QueryFields{
 	"sequence":       &ffapi.Int64Field{},
 	"txtype":         &ffapi.StringField{},
 	"batch":          &ffapi.UUIDField{},
-	"txid":           &ffapi.UUIDField{},
-	"txparent.type":  &ffapi.StringField{},
-	"txparent.id":    &ffapi.UUIDField{},
 }
 
 // BatchQueryFactory filter fields for batches


Test patch:
diff --git a/internal/assets/token_approval_test.go b/internal/assets/token_approval_test.go
index 7c93fab48..cc81d85db 100644
--- a/internal/assets/token_approval_test.go
+++ b/internal/assets/token_approval_test.go
@@ -139,8 +139,7 @@ func TestApprovalBadConnector(t *testing.T) {
 			Operator: "operator",
 			Key:      "key",
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Locator:   "F1",
@@ -150,17 +149,14 @@ func TestApprovalBadConnector(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "key", identity.KeyNormalizationBlockchainPlugin).Return("0x12345", nil)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.Regexp(t, "FF10272", err)
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalDefaultPoolSuccess(t *testing.T) {
@@ -226,11 +222,9 @@ func TestApprovalDefaultPoolNoPool(t *testing.T) {
 			Operator: "operator",
 			Key:      "key",
 		},
-		IdempotencyKey: "idem1",
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	fb := database.TokenPoolQueryFactory.NewFilter(context.Background())
 	f := fb.And()
 	f.Limit(1).Count(true)
@@ -243,13 +237,9 @@ func TestApprovalDefaultPoolNoPool(t *testing.T) {
 		info, _ := f.Finalize()
 		return info.Count && info.Limit == 1
 	}))).Return(tokenPools, filterResult, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.Regexp(t, "FF10292", err)
-
-	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalBadPool(t *testing.T) {
@@ -262,20 +252,16 @@ func TestApprovalBadPool(t *testing.T) {
 			Operator: "operator",
 			Key:      "key",
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
+	mim := am.identity.(*identitymanagermocks.Manager)
+	mim.On("ResolveInputSigningKey", context.Background(), "key", identity.KeyNormalizationBlockchainPlugin).Return("0x12345", nil)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(nil, fmt.Errorf("pop"))
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.EqualError(t, err, "pop")
-
-	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalUnconfirmedPool(t *testing.T) {
@@ -287,8 +273,7 @@ func TestApprovalUnconfirmedPool(t *testing.T) {
 			Approved: true,
 			Operator: "operator",
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Locator:   "F1",
@@ -297,15 +282,12 @@ func TestApprovalUnconfirmedPool(t *testing.T) {
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.Regexp(t, "FF10293", err)
 
 	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalIdentityFail(t *testing.T) {
@@ -317,8 +299,7 @@ func TestApprovalIdentityFail(t *testing.T) {
 			Approved: true,
 			Operator: "operator",
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Locator:   "F1",
@@ -328,17 +309,14 @@ func TestApprovalIdentityFail(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("", fmt.Errorf("pop"))
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.EqualError(t, err, "pop")
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalFail(t *testing.T) {
@@ -394,14 +372,24 @@ func TestApprovalTransactionFail(t *testing.T) {
 		Pool:           "pool1",
 		IdempotencyKey: "idem1",
 	}
+	pool := &core.TokenPool{
+		Locator:   "F1",
+		Connector: "magic-tokens",
+		State:     core.TokenPoolStateConfirmed,
+	}
 
+	mdi := am.database.(*databasemocks.Plugin)
+	mim := am.identity.(*identitymanagermocks.Manager)
 	mth := am.txHelper.(*txcommonmocks.Helper)
+	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("0x12345", nil)
+	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
 	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(nil, fmt.Errorf("pop"))
 
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.EqualError(t, err, "pop")
 
-	mth.AssertExpectations(t)
+	mim.AssertExpectations(t)
+	mdi.AssertExpectations(t)
 }
 
 func TestApprovalWithBroadcastMessage(t *testing.T) {
@@ -496,13 +484,8 @@ func TestApprovalWithBroadcastMessageDisabled(t *testing.T) {
 		IdempotencyKey: "idem1",
 	}
 
-	mth := am.txHelper.(*txcommonmocks.Helper)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
-
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.Regexp(t, "FF10415", err)
-
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalWithBroadcastMessageSendFail(t *testing.T) {
@@ -573,8 +556,7 @@ func TestApprovalWithBroadcastPrepareFail(t *testing.T) {
 			Operator: "B",
 			Approved: true,
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 		Message: &core.MessageInOut{
 			InlineData: core.InlineData{
 				{
@@ -586,17 +568,14 @@ func TestApprovalWithBroadcastPrepareFail(t *testing.T) {
 
 	mbm := am.broadcast.(*broadcastmocks.Manager)
 	mms := &syncasyncmocks.Sender{}
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mbm.On("NewBroadcast", approval.Message).Return(mms)
 	mms.On("Prepare", context.Background()).Return(fmt.Errorf("pop"))
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.EqualError(t, err, "pop")
 
 	mbm.AssertExpectations(t)
 	mms.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalWithPrivateMessage(t *testing.T) {
@@ -615,7 +594,7 @@ func TestApprovalWithPrivateMessage(t *testing.T) {
 			Message: core.Message{
 				Header: core.MessageHeader{
 					ID:   msgID,
-					Type: core.MessageTypePrivate,
+					Type: core.MessageTypeApprovalPrivate,
 				},
 				Hash: hash,
 			},
@@ -675,13 +654,12 @@ func TestApprovalWithPrivateMessageDisabled(t *testing.T) {
 			Operator: "B",
 			Approved: true,
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 		Message: &core.MessageInOut{
 			Message: core.Message{
 				Header: core.MessageHeader{
 					ID:   msgID,
-					Type: core.MessageTypeDeprecatedApprovalPrivate,
+					Type: core.MessageTypeApprovalPrivate,
 				},
 				Hash: hash,
 			},
@@ -693,13 +671,8 @@ func TestApprovalWithPrivateMessageDisabled(t *testing.T) {
 		},
 	}
 
-	mth := am.txHelper.(*txcommonmocks.Helper)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
-
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.Regexp(t, "FF10415", err)
-
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalWithInvalidMessage(t *testing.T) {
@@ -711,8 +684,7 @@ func TestApprovalWithInvalidMessage(t *testing.T) {
 			Operator: "B",
 			Approved: true,
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 		Message: &core.MessageInOut{
 			Message: core.Message{
 				Header: core.MessageHeader{
@@ -727,13 +699,8 @@ func TestApprovalWithInvalidMessage(t *testing.T) {
 		},
 	}
 
-	mth := am.txHelper.(*txcommonmocks.Helper)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
-
 	_, err := am.TokenApproval(context.Background(), approval, false)
 	assert.Regexp(t, "FF10287", err)
-
-	mth.AssertExpectations(t)
 }
 
 func TestApprovalOperationsFail(t *testing.T) {
@@ -911,8 +878,7 @@ func TestApprovalPrepare(t *testing.T) {
 			Operator: "operator",
 			Key:      "key",
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Locator:   "F1",
@@ -924,15 +890,12 @@ func TestApprovalPrepare(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "key", identity.KeyNormalizationBlockchainPlugin).Return("0x12345", nil)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenApproval, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	err := sender.Prepare(context.Background())
 	assert.NoError(t, err)
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
diff --git a/internal/assets/token_transfer_test.go b/internal/assets/token_transfer_test.go
index ed84218b2..d02078814 100644
--- a/internal/assets/token_transfer_test.go
+++ b/internal/assets/token_transfer_test.go
@@ -117,8 +117,7 @@ func TestMintTokensBadConnector(t *testing.T) {
 		TokenTransfer: core.TokenTransfer{
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Connector: "bad",
@@ -127,17 +126,14 @@ func TestMintTokensBadConnector(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("0x12345", nil)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.MintTokens(context.Background(), mint, false)
 	assert.Regexp(t, "FF10272.*bad", err)
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestMintTokenDefaultPoolSuccess(t *testing.T) {
@@ -198,11 +194,9 @@ func TestMintTokenDefaultPoolNoPools(t *testing.T) {
 		TokenTransfer: core.TokenTransfer{
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		IdempotencyKey: "idem1",
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	fb := database.TokenPoolQueryFactory.NewFilter(context.Background())
 	f := fb.And()
 	f.Limit(1).Count(true)
@@ -215,13 +209,11 @@ func TestMintTokenDefaultPoolNoPools(t *testing.T) {
 		info, _ := f.Finalize()
 		return info.Count && info.Limit == 1
 	}))).Return(tokenPools, filterResult, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.MintTokens(context.Background(), mint, false)
 	assert.Regexp(t, "FF10292", err)
 
 	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestMintTokenDefaultPoolMultiplePools(t *testing.T) {
@@ -232,11 +224,9 @@ func TestMintTokenDefaultPoolMultiplePools(t *testing.T) {
 		TokenTransfer: core.TokenTransfer{
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		IdempotencyKey: "idem1",
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	fb := database.TokenPoolQueryFactory.NewFilter(context.Background())
 	f := fb.And()
 	f.Limit(1).Count(true)
@@ -256,13 +246,11 @@ func TestMintTokenDefaultPoolMultiplePools(t *testing.T) {
 		info, _ := f.Finalize()
 		return info.Count && info.Limit == 1
 	}))).Return(tokenPools, filterResult, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.MintTokens(context.Background(), mint, false)
 	assert.Regexp(t, "FF10292", err)
 
 	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestMintTokensGetPoolsError(t *testing.T) {
@@ -273,19 +261,15 @@ func TestMintTokensGetPoolsError(t *testing.T) {
 		TokenTransfer: core.TokenTransfer{
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		IdempotencyKey: "idem1",
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mdi.On("GetTokenPools", context.Background(), "ns1", mock.Anything).Return(nil, nil, fmt.Errorf("pop"))
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.MintTokens(context.Background(), mint, false)
 	assert.EqualError(t, err, "pop")
 
 	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestMintTokensBadPool(t *testing.T) {
@@ -296,20 +280,16 @@ func TestMintTokensBadPool(t *testing.T) {
 		TokenTransfer: core.TokenTransfer{
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(nil, fmt.Errorf("pop"))
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.MintTokens(context.Background(), mint, false)
 	assert.EqualError(t, err, "pop")
 
 	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestMintTokensIdentityFail(t *testing.T) {
@@ -320,8 +300,7 @@ func TestMintTokensIdentityFail(t *testing.T) {
 		TokenTransfer: core.TokenTransfer{
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Connector: "magic-tokens",
@@ -330,17 +309,14 @@ func TestMintTokensIdentityFail(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("", fmt.Errorf("pop"))
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.MintTokens(context.Background(), mint, false)
 	assert.EqualError(t, err, "pop")
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestMintTokensFail(t *testing.T) {
@@ -506,8 +482,7 @@ func TestBurnTokensIdentityFail(t *testing.T) {
 		TokenTransfer: core.TokenTransfer{
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Connector: "magic-tokens",
@@ -516,17 +491,14 @@ func TestBurnTokensIdentityFail(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("", fmt.Errorf("pop"))
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.BurnTokens(context.Background(), burn, false)
 	assert.EqualError(t, err, "pop")
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestBurnTokensConfirm(t *testing.T) {
@@ -624,8 +596,7 @@ func TestTransferTokensUnconfirmedPool(t *testing.T) {
 			To:     "B",
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Locator:   "F1",
@@ -634,15 +605,12 @@ func TestTransferTokensUnconfirmedPool(t *testing.T) {
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.Regexp(t, "FF10293", err)
 
 	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestTransferTokensIdentityFail(t *testing.T) {
@@ -655,8 +623,7 @@ func TestTransferTokensIdentityFail(t *testing.T) {
 			To:     "B",
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Connector: "magic-tokens",
@@ -665,17 +632,14 @@ func TestTransferTokensIdentityFail(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("", fmt.Errorf("pop"))
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.EqualError(t, err, "pop")
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestTransferTokensNoFromOrTo(t *testing.T) {
@@ -683,8 +647,7 @@ func TestTransferTokensNoFromOrTo(t *testing.T) {
 	defer cancel()
 
 	transfer := &core.TokenTransferInput{
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Connector: "magic-tokens",
@@ -693,17 +656,14 @@ func TestTransferTokensNoFromOrTo(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("0x12345", nil)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.Regexp(t, "FF10280", err)
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestTransferTokensTransactionFail(t *testing.T) {
@@ -719,13 +679,24 @@ func TestTransferTokensTransactionFail(t *testing.T) {
 		Pool:           "pool1",
 		IdempotencyKey: "idem1",
 	}
+	pool := &core.TokenPool{
+		Locator:   "F1",
+		Connector: "magic-tokens",
+		State:     core.TokenPoolStateConfirmed,
+	}
 
+	mdi := am.database.(*databasemocks.Plugin)
+	mim := am.identity.(*identitymanagermocks.Manager)
 	mth := am.txHelper.(*txcommonmocks.Helper)
+	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("0x12345", nil)
+	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
 	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(nil, fmt.Errorf("pop"))
 
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.EqualError(t, err, "pop")
 
+	mim.AssertExpectations(t)
+	mdi.AssertExpectations(t)
 	mth.AssertExpectations(t)
 }
 
@@ -806,8 +777,7 @@ func TestTransferTokensWithBroadcastMessageDisabled(t *testing.T) {
 			To:     "B",
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 		Message: &core.MessageInOut{
 			Message: core.Message{
 				Header: core.MessageHeader{
@@ -823,13 +793,8 @@ func TestTransferTokensWithBroadcastMessageDisabled(t *testing.T) {
 		},
 	}
 
-	mth := am.txHelper.(*txcommonmocks.Helper)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
-
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.Regexp(t, "FF10415", err)
-
-	mth.AssertExpectations(t)
 }
 
 func TestTransferTokensWithBroadcastMessageSendFail(t *testing.T) {
@@ -902,8 +867,7 @@ func TestTransferTokensWithBroadcastPrepareFail(t *testing.T) {
 			To:     "B",
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 		Message: &core.MessageInOut{
 			InlineData: core.InlineData{
 				{
@@ -915,17 +879,14 @@ func TestTransferTokensWithBroadcastPrepareFail(t *testing.T) {
 
 	mbm := am.broadcast.(*broadcastmocks.Manager)
 	mms := &syncasyncmocks.Sender{}
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mbm.On("NewBroadcast", transfer.Message).Return(mms)
 	mms.On("Prepare", context.Background()).Return(fmt.Errorf("pop"))
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.EqualError(t, err, "pop")
 
 	mbm.AssertExpectations(t)
 	mms.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestTransferTokensWithPrivateMessage(t *testing.T) {
@@ -945,7 +906,7 @@ func TestTransferTokensWithPrivateMessage(t *testing.T) {
 			Message: core.Message{
 				Header: core.MessageHeader{
 					ID:   msgID,
-					Type: core.MessageTypePrivate,
+					Type: core.MessageTypeTransferPrivate,
 				},
 				Hash: hash,
 			},
@@ -1006,13 +967,12 @@ func TestTransferTokensWithPrivateMessageDisabled(t *testing.T) {
 			To:     "B",
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 		Message: &core.MessageInOut{
 			Message: core.Message{
 				Header: core.MessageHeader{
 					ID:   msgID,
-					Type: core.MessageTypeDeprecatedTransferPrivate,
+					Type: core.MessageTypeTransferPrivate,
 				},
 				Hash: hash,
 			},
@@ -1024,13 +984,8 @@ func TestTransferTokensWithPrivateMessageDisabled(t *testing.T) {
 		},
 	}
 
-	mth := am.txHelper.(*txcommonmocks.Helper)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
-
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.Regexp(t, "FF10415", err)
-
-	mth.AssertExpectations(t)
 }
 
 func TestTransferTokensWithInvalidMessage(t *testing.T) {
@@ -1043,8 +998,7 @@ func TestTransferTokensWithInvalidMessage(t *testing.T) {
 			To:     "B",
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 		Message: &core.MessageInOut{
 			Message: core.Message{
 				Header: core.MessageHeader{
@@ -1059,13 +1013,8 @@ func TestTransferTokensWithInvalidMessage(t *testing.T) {
 		},
 	}
 
-	mth := am.txHelper.(*txcommonmocks.Helper)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
-
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.Regexp(t, "FF10287", err)
-
-	mth.AssertExpectations(t)
 }
 
 func TestTransferTokensConfirm(t *testing.T) {
@@ -1203,20 +1152,16 @@ func TestTransferTokensPoolNotFound(t *testing.T) {
 			To:     "B",
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 
 	mdi := am.database.(*databasemocks.Plugin)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(nil, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	_, err := am.TransferTokens(context.Background(), transfer, false)
 	assert.Regexp(t, "FF10109", err)
 
 	mdi.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
 
 func TestTransferPrepare(t *testing.T) {
@@ -1230,8 +1175,7 @@ func TestTransferPrepare(t *testing.T) {
 			To:     "B",
 			Amount: *fftypes.NewFFBigInt(5),
 		},
-		Pool:           "pool1",
-		IdempotencyKey: "idem1",
+		Pool: "pool1",
 	}
 	pool := &core.TokenPool{
 		Connector: "magic-tokens",
@@ -1242,15 +1186,12 @@ func TestTransferPrepare(t *testing.T) {
 
 	mdi := am.database.(*databasemocks.Plugin)
 	mim := am.identity.(*identitymanagermocks.Manager)
-	mth := am.txHelper.(*txcommonmocks.Helper)
 	mim.On("ResolveInputSigningKey", context.Background(), "", identity.KeyNormalizationBlockchainPlugin).Return("0x12345", nil)
 	mdi.On("GetTokenPool", context.Background(), "ns1", "pool1").Return(pool, nil)
-	mth.On("SubmitNewTransaction", context.Background(), core.TransactionTypeTokenTransfer, core.IdempotencyKey("idem1")).Return(fftypes.NewUUID(), nil)
 
 	err := sender.Prepare(context.Background())
 	assert.NoError(t, err)
 
 	mdi.AssertExpectations(t)
 	mim.AssertExpectations(t)
-	mth.AssertExpectations(t)
 }
diff --git a/internal/broadcast/manager_test.go b/internal/broadcast/manager_test.go
index 5ed4d95d0..4b4080707 100644
--- a/internal/broadcast/manager_test.go
+++ b/internal/broadcast/manager_test.go
@@ -66,8 +66,8 @@ func newTestBroadcastCommon(t *testing.T, metricsEnabled bool) (*broadcastManage
 		[]core.MessageType{
 			core.MessageTypeBroadcast,
 			core.MessageTypeDefinition,
-			core.MessageTypeDeprecatedTransferBroadcast,
-			core.MessageTypeDeprecatedApprovalBroadcast,
+			core.MessageTypeTransferBroadcast,
+			core.MessageTypeApprovalBroadcast,
 		}, mock.Anything, mock.Anything).Return()
 	mom.On("RegisterHandler", mock.Anything, mock.Anything, mock.Anything)
 
diff --git a/internal/database/sqlcommon/blob_sql_test.go b/internal/database/sqlcommon/blob_sql_test.go
index 5324fda69..3c8df1fb2 100644
--- a/internal/database/sqlcommon/blob_sql_test.go
+++ b/internal/database/sqlcommon/blob_sql_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2021 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -124,10 +124,9 @@ func TestInsertBlobsBeginFail(t *testing.T) {
 }
 
 func TestInsertBlobsMultiRowOK(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 
 	blob1 := &core.Blob{Hash: fftypes.NewRandB32(), PayloadRef: "pay1"}
 	blob2 := &core.Blob{Hash: fftypes.NewRandB32(), PayloadRef: "pay2"}
@@ -145,10 +144,9 @@ func TestInsertBlobsMultiRowOK(t *testing.T) {
 }
 
 func TestInsertBlobsMultiRowFail(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 	blob1 := &core.Blob{Hash: fftypes.NewRandB32(), PayloadRef: "pay1"}
 	mock.ExpectBegin()
 	mock.ExpectQuery("INSERT.*").WillReturnError(fmt.Errorf("pop"))
diff --git a/internal/database/sqlcommon/data_sql_test.go b/internal/database/sqlcommon/data_sql_test.go
index a628ba539..6162a09ef 100644
--- a/internal/database/sqlcommon/data_sql_test.go
+++ b/internal/database/sqlcommon/data_sql_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2021 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -240,10 +240,9 @@ func TestInsertDataArrayBeginFail(t *testing.T) {
 }
 
 func TestInsertDataArrayMultiRowOK(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 
 	data1 := &core.Data{ID: fftypes.NewUUID(), Namespace: "ns1"}
 	data2 := &core.Data{ID: fftypes.NewUUID(), Namespace: "ns1"}
@@ -263,10 +262,9 @@ func TestInsertDataArrayMultiRowOK(t *testing.T) {
 }
 
 func TestInsertDataArrayMultiRowFail(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 	data1 := &core.Data{ID: fftypes.NewUUID(), Namespace: "ns1"}
 	mock.ExpectBegin()
 	mock.ExpectQuery("INSERT.*").WillReturnError(fmt.Errorf("pop"))
diff --git a/internal/database/sqlcommon/event_sql_test.go b/internal/database/sqlcommon/event_sql_test.go
index 134460deb..59d4264a2 100644
--- a/internal/database/sqlcommon/event_sql_test.go
+++ b/internal/database/sqlcommon/event_sql_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2021 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -133,10 +133,9 @@ func TestInsertEventFailCommit(t *testing.T) {
 }
 
 func TestInsertEventsPreCommitMultiRowOK(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 
 	ev1 := &core.Event{ID: fftypes.NewUUID(), Namespace: "ns1"}
 	ev2 := &core.Event{ID: fftypes.NewUUID(), Namespace: "ns1"}
@@ -163,10 +162,9 @@ func TestInsertEventsPreCommitMultiRowOK(t *testing.T) {
 }
 
 func TestInsertEventsPreCommitMultiRowFail(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 	ev1 := &core.Event{ID: fftypes.NewUUID(), Namespace: "ns1"}
 	mock.ExpectBegin()
 	mock.ExpectExec("<acquire lock ns1>").WillReturnResult(driver.ResultNoRows)
diff --git a/internal/database/sqlcommon/message_sql_test.go b/internal/database/sqlcommon/message_sql_test.go
index a0a2604e9..19ffa8e21 100644
--- a/internal/database/sqlcommon/message_sql_test.go
+++ b/internal/database/sqlcommon/message_sql_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2021 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -61,10 +61,6 @@ func TestUpsertE2EWithDB(t *testing.T) {
 			Group:     nil,
 			DataHash:  fftypes.NewRandB32(),
 			TxType:    core.TransactionTypeUnpinned,
-			TxParent: &core.TransactionRef{
-				Type: core.TransactionTypeTokenTransfer,
-				ID:   fftypes.NewUUID(),
-			},
 		},
 		Hash:      fftypes.NewRandB32(),
 		State:     core.MessageStateStaged,
@@ -113,10 +109,6 @@ func TestUpsertE2EWithDB(t *testing.T) {
 			Group:     gid,
 			DataHash:  fftypes.NewRandB32(),
 			TxType:    core.TransactionTypeBatchPin,
-			TxParent: &core.TransactionRef{
-				Type: core.TransactionTypeTokenTransfer,
-				ID:   fftypes.NewUUID(),
-			},
 		},
 		Hash:           fftypes.NewRandB32(),
 		Pins:           []string{fftypes.NewRandB32().String(), fftypes.NewRandB32().String()},
@@ -318,10 +310,9 @@ func TestInsertMessagesBeginFail(t *testing.T) {
 }
 
 func TestInsertMessagesMultiRowOK(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 
 	msg1 := &core.Message{Header: core.MessageHeader{ID: fftypes.NewUUID(), Namespace: "ns1"}, LocalNamespace: "ns1", Data: core.DataRefs{{ID: fftypes.NewUUID()}}}
 	msg2 := &core.Message{Header: core.MessageHeader{ID: fftypes.NewUUID(), Namespace: "ns1"}, LocalNamespace: "ns1", Data: core.DataRefs{{ID: fftypes.NewUUID()}}}
@@ -349,10 +340,9 @@ func TestInsertMessagesMultiRowOK(t *testing.T) {
 }
 
 func TestInsertMessagesMultiRowDataRefsFail(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 
 	msg1 := &core.Message{Header: core.MessageHeader{ID: fftypes.NewUUID(), Namespace: "ns1"}, Data: core.DataRefs{{ID: fftypes.NewUUID()}}}
 
@@ -366,10 +356,9 @@ func TestInsertMessagesMultiRowDataRefsFail(t *testing.T) {
 }
 
 func TestInsertMessagesMultiRowFail(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 	msg1 := &core.Message{Header: core.MessageHeader{ID: fftypes.NewUUID(), Namespace: "ns1"}}
 	mock.ExpectBegin()
 	mock.ExpectQuery("INSERT.*").WillReturnError(fmt.Errorf("pop"))
@@ -565,7 +554,7 @@ func TestGetMessageByIDLoadRefsFail(t *testing.T) {
 	cols := append([]string{}, msgColumns...)
 	cols = append(cols, "id()")
 	mock.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows(cols).
-		AddRow(msgID.String(), nil, core.MessageTypeBroadcast, "author1", "0x12345", 0, "ns1", "ns1", "t1", "c1", nil, b32.String(), b32.String(), b32.String(), "confirmed", 0, "pin", nil, "", nil, nil, "bob", 0))
+		AddRow(msgID.String(), nil, core.MessageTypeBroadcast, "author1", "0x12345", 0, "ns1", "ns1", "t1", "c1", nil, b32.String(), b32.String(), b32.String(), "confirmed", 0, "pin", nil, "bob", 0))
 	mock.ExpectQuery("SELECT .*").WillReturnError(fmt.Errorf("pop"))
 	_, err := s.GetMessageByID(context.Background(), "ns1", msgID)
 	assert.Regexp(t, "FF00176", err)
@@ -612,7 +601,7 @@ func TestGetMessagesLoadRefsFail(t *testing.T) {
 	cols := append([]string{}, msgColumns...)
 	cols = append(cols, "id()")
 	mock.ExpectQuery("SELECT .*").WillReturnRows(sqlmock.NewRows(cols).
-		AddRow(msgID.String(), nil, core.MessageTypeBroadcast, "author1", "0x12345", 0, "ns1", "ns1", "t1", "c1", nil, b32.String(), b32.String(), b32.String(), "confirmed", 0, "pin", nil, "", nil, nil, "bob", 0))
+		AddRow(msgID.String(), nil, core.MessageTypeBroadcast, "author1", "0x12345", 0, "ns1", "ns1", "t1", "c1", nil, b32.String(), b32.String(), b32.String(), "confirmed", 0, "pin", nil, "bob", 0))
 	mock.ExpectQuery("SELECT .*").WillReturnError(fmt.Errorf("pop"))
 	f := database.MessageQueryFactory.NewFilter(context.Background()).Gt("confirmed", "0")
 	_, _, err := s.GetMessages(context.Background(), "ns1", f)
diff --git a/internal/database/sqlcommon/pin_sql_test.go b/internal/database/sqlcommon/pin_sql_test.go
index 17749cf90..321042b5b 100644
--- a/internal/database/sqlcommon/pin_sql_test.go
+++ b/internal/database/sqlcommon/pin_sql_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2021 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -146,10 +146,9 @@ func TestInsertPinsBeginFail(t *testing.T) {
 }
 
 func TestInsertPinsMultiRowOK(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 
 	pin1 := &core.Pin{Namespace: "ns1", Hash: fftypes.NewRandB32()}
 	pin2 := &core.Pin{Namespace: "ns1", Hash: fftypes.NewRandB32()}
@@ -169,10 +168,9 @@ func TestInsertPinsMultiRowOK(t *testing.T) {
 }
 
 func TestInsertPinsMultiRowFail(t *testing.T) {
-	s := newMockProvider()
-	s.multiRowInsert = true
+	s, mock := newMockProvider().init()
+	s.features.MultiRowInsert = true
 	s.fakePSQLInsert = true
-	s, mock := s.init()
 	pin1 := &core.Pin{Hash: fftypes.NewRandB32()}
 	mock.ExpectBegin()
 	mock.ExpectQuery("INSERT.*").WillReturnError(fmt.Errorf("pop"))
diff --git a/internal/database/sqlcommon/provider_mock_test.go b/internal/database/sqlcommon/provider_mock_test.go
index 38faa5eb9..b3cdf5176 100644
--- a/internal/database/sqlcommon/provider_mock_test.go
+++ b/internal/database/sqlcommon/provider_mock_test.go
@@ -1,4 +1,4 @@
-// Copyright © 2023 Kaleido, Inc.
+// Copyright © 2021 Kaleido, Inc.
 //
 // SPDX-License-Identifier: Apache-2.0
 //
@@ -45,7 +45,6 @@ type mockProvider struct {
 	openError               error
 	getMigrationDriverError error
 	individualSort          bool
-	multiRowInsert          bool
 }
 
 func newMockProvider() *mockProvider {
@@ -60,7 +59,6 @@ func newMockProvider() *mockProvider {
 	mp.SQLCommon.InitConfig(mp, mp.config)
 	mp.config.Set(SQLConfMaxConnections, 10)
 	mp.mockDB, mp.mdb, _ = sqlmock.New()
-	mp.multiRowInsert = false
 	return mp
 }
 
@@ -86,7 +84,6 @@ func (mp *mockProvider) MigrationsDir() string {
 func (psql *mockProvider) Features() dbsql.SQLFeatures {
 	features := dbsql.DefaultSQLProviderFeatures()
 	features.UseILIKE = true
-	features.MultiRowInsert = psql.multiRowInsert
 	features.AcquireLock = func(lockName string) string {
 		return fmt.Sprintf(`<acquire lock %s>`, lockName)
 	}
diff --git a/internal/events/aggregator_test.go b/internal/events/aggregator_test.go
index 8e9fdbfed..f4da43bf6 100644
--- a/internal/events/aggregator_test.go
+++ b/internal/events/aggregator_test.go
@@ -1515,7 +1515,7 @@ func TestAttemptMessageDispatchMissingTransfers(t *testing.T) {
 	msg := &core.Message{
 		Header: core.MessageHeader{
 			ID:   fftypes.NewUUID(),
-			Type: core.MessageTypeDeprecatedTransferBroadcast,
+			Type: core.MessageTypeTransferBroadcast,
 			SignerRef: core.SignerRef{
 				Author: org1.DID,
 				Key:    "0x12345",
@@ -1541,7 +1541,7 @@ func TestAttemptMessageDispatchGetTransfersFail(t *testing.T) {
 	msg := &core.Message{
 		Header: core.MessageHeader{
 			ID:        fftypes.NewUUID(),
-			Type:      core.MessageTypeDeprecatedTransferBroadcast,
+			Type:      core.MessageTypeTransferBroadcast,
 			SignerRef: core.SignerRef{Key: "0x12345", Author: org1.DID},
 		},
 	}
@@ -1561,7 +1561,7 @@ func TestAttemptMessageDispatchTransferMismatch(t *testing.T) {
 	msg := &core.Message{
 		Header: core.MessageHeader{
 			ID:        fftypes.NewUUID(),
-			Type:      core.MessageTypeDeprecatedTransferBroadcast,
+			Type:      core.MessageTypeTransferBroadcast,
 			SignerRef: core.SignerRef{Key: "0x12345", Author: org1.DID},
 		},
 	}
@@ -1594,7 +1594,7 @@ func TestAttemptMessageDispatchGetApprovalsFail(t *testing.T) {
 	msg := &core.Message{
 		Header: core.MessageHeader{
 			ID:        fftypes.NewUUID(),
-			Type:      core.MessageTypeDeprecatedApprovalBroadcast,
+			Type:      core.MessageTypeApprovalBroadcast,
 			SignerRef: core.SignerRef{Key: "0x12345", Author: org1.DID},
 		},
 	}
@@ -1614,7 +1614,7 @@ func TestAttemptMessageDispatchApprovalMismatch(t *testing.T) {
 	msg := &core.Message{
 		Header: core.MessageHeader{
 			ID:        fftypes.NewUUID(),
-			Type:      core.MessageTypeDeprecatedApprovalBroadcast,
+			Type:      core.MessageTypeApprovalBroadcast,
 			SignerRef: core.SignerRef{Key: "0x12345", Author: org1.DID},
 		},
 	}
diff --git a/internal/events/event_poller_test.go b/internal/events/event_poller_test.go
index 68f39047f..9d9366525 100644
--- a/internal/events/event_poller_test.go
+++ b/internal/events/event_poller_test.go
@@ -280,12 +280,21 @@ func TestWaitForShoulderTapOrExitCloseBatch(t *testing.T) {
 	assert.False(t, ep.waitForShoulderTapOrPollTimeout(1))
 }
 
-func TestWaitForShoulderTapOrExitClosePoll(t *testing.T) {
+func TestWaitForShoulderTapImmediateRepollOnFullBatch(t *testing.T) {
 	mdi := &databasemocks.Plugin{}
 	ep, cancel := newTestEventPoller(t, mdi, nil, nil)
 	cancel()
 	ep.conf.eventBatchTimeout = 1 * time.Minute
 	ep.conf.eventBatchSize = 1
+	assert.True(t, ep.waitForShoulderTapOrPollTimeout(1))
+}
+
+func TestWaitForShoulderTapOrExitClosePoll(t *testing.T) {
+	mdi := &databasemocks.Plugin{}
+	ep, cancel := newTestEventPoller(t, mdi, nil, nil)
+	cancel()
+	ep.conf.eventBatchTimeout = 1 * time.Minute
+	ep.conf.eventBatchSize = 2
 	assert.False(t, ep.waitForShoulderTapOrPollTimeout(1))
 }
 
diff --git a/internal/privatemessaging/privatemessaging_test.go b/internal/privatemessaging/privatemessaging_test.go
index 2db370592..6218fb146 100644
--- a/internal/privatemessaging/privatemessaging_test.go
+++ b/internal/privatemessaging/privatemessaging_test.go
@@ -70,8 +70,8 @@ func newTestPrivateMessagingCommon(t *testing.T, metricsEnabled bool) (*privateM
 		[]core.MessageType{
 			core.MessageTypeGroupInit,
 			core.MessageTypePrivate,
-			core.MessageTypeDeprecatedTransferPrivate,
-			core.MessageTypeDeprecatedApprovalPrivate,
+			core.MessageTypeTransferPrivate,
+			core.MessageTypeApprovalPrivate,
 		}, mock.Anything, mock.Anything).Return()
 
 	mba.On("RegisterDispatcher",